Skip to content

Commit

Permalink
Rest data source (#1510)
Browse files Browse the repository at this point in the history
* fix issue in ArrayDataSource not refreshing after resume

* rest datasource experiment

* add pagination

* add TablePicker, RestDataSource first cut, fix table issues

* initial search capability in TablePicker

* fix table fixed size rendering
  • Loading branch information
heswell authored Oct 1, 2024
1 parent f13ca85 commit 308ee37
Show file tree
Hide file tree
Showing 51 changed files with 1,447 additions and 599 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ export class ArrayDataSource
#links: LinkDescriptorWithLabel[] | undefined;
#range: VuuRange = NULL_RANGE;
#selectedRowsCount = 0;
#size = 0;
#status: DataSourceStatus = "initialising";
#title: string | undefined;

Expand Down Expand Up @@ -163,7 +162,6 @@ export class ArrayDataSource
this.rangeChangeRowset = rangeChangeRowset;
this.tableSchema = buildTableSchema(columnDescriptors, keyColumn);
this.viewport = viewport || uuid();
this.#size = data.length;
this.#title = title;

const columns = columnDescriptors.map((col) => col.name);
Expand Down Expand Up @@ -243,6 +241,13 @@ export class ArrayDataSource
} else if (this.#range !== NULL_RANGE) {
this.sendRowsToClient();
}

if (this.range.to !== 0) {
const pageCount = Math.ceil(
this.size / (this.range.to - this.range.from),
);
this.emit("page-count", pageCount);
}
}
}

Expand All @@ -259,13 +264,19 @@ export class ArrayDataSource
}
}

resume() {
resume(callback?: SubscribeCallback) {
const isSuspended = this.#status === "suspended";
info?.(`resume #${this.viewport}, current status ${this.#status}`);
if (callback) {
this.clientCallback = callback;
}

if (isSuspended) {
this.#status = "subscribed";
}
this.emit("resumed", this.viewport);

this.sendRowsToClient(true);
}

disable() {
Expand Down Expand Up @@ -305,6 +316,10 @@ export class ArrayDataSource
}
}

get pageSize() {
return this.#range.to - this.#range.from;
}

get links() {
return this.#links;
}
Expand Down Expand Up @@ -472,7 +487,6 @@ export class ArrayDataSource
}

get size() {
// return this.#size;
return this.processedData?.length ?? this.#data.length;
}

Expand Down Expand Up @@ -605,6 +619,7 @@ export class ArrayDataSource
this.clientCallback?.({
clientViewportId: this.viewport,
mode: "batch",
range: this.#range,
rows: rowsWithinViewport,
size: data.length,
type: "viewport-update",
Expand Down
1 change: 1 addition & 0 deletions vuu-ui/packages/vuu-data-react/src/data-editing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from "./get-data-item-edit-control";
export * from "./EditForm";
export * from "./edit-rule-validation-checker";
export * from "./UnsavedChangesReport";
export * from "./useEditForm";
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { RestDataSource, ConnectionManager } from "@finos/vuu-data-remote";
import { DataSourceProvider } from "@finos/vuu-utils";
import { ReactNode } from "react";

const getServerAPI = () => ConnectionManager.serverAPI;

export const RestDataSourceProvider = ({
children,
url,
}: {
children: ReactNode;
url: string;
}) => {
// url is a static property
RestDataSource.url = url;
return (
<DataSourceProvider
VuuDataSource={RestDataSource}
getServerAPI={getServerAPI}
isLocalData={false}
>
{children}
</DataSourceProvider>
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
DataSource,
DataSourceConfig,
TableSchema,
TableSchema
} from "@finos/vuu-data-types";
import { isConfigChanged, resetRange, useDataSource } from "@finos/vuu-utils";
import { useViewContext } from "@finos/vuu-layout";
Expand All @@ -15,7 +15,7 @@ const NO_CONFIG: SessionDataSourceConfig = {};

export const useSessionDataSource = ({
dataSourceSessionKey = "data-source",
tableSchema,
tableSchema
}: {
dataSourceSessionKey?: string;
tableSchema: TableSchema;
Expand Down Expand Up @@ -70,7 +70,7 @@ export const useSessionDataSource = ({
table: tableSchema.table,
...dataSourceConfigFromState,
columns,
title,
title
});
ds.on("config", handleDataSourceConfigChange);
saveSession?.(ds, "data-source");
Expand All @@ -85,7 +85,7 @@ export const useSessionDataSource = ({
saveSession,
tableSchema.columns,
tableSchema.table,
title,
title
]);

return dataSource;
Expand Down
1 change: 1 addition & 0 deletions vuu-ui/packages/vuu-data-remote/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export { default as ConnectionManager } from "./ConnectionManager";
export * from "./constants";
export * from "./data-source";
export * from "./message-utils";
export * from "./rest-data/rest-data-source";
export * from "./vuu-data-source";
export type { WebSocketConnectionState } from "./WebSocketConnection";
81 changes: 81 additions & 0 deletions vuu-ui/packages/vuu-data-remote/src/rest-data/moving-window.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { DataSourceRow } from "@finos/vuu-data-types";
import { isRowSelectedLast, metadataKeys, WindowRange } from "@finos/vuu-utils";
import { VuuRange } from "@finos/vuu-protocol-types";

const { SELECTED } = metadataKeys;

export class MovingWindow {
public data: DataSourceRow[];
public rowCount = 0;
private range: WindowRange;

constructor({ from, to }: VuuRange) {
this.range = new WindowRange(from, to);
//internal data is always 0 based, we add range.from to determine an offset
this.data = new Array(Math.max(0, to - from));
this.rowCount = 0;
}

setRowCount = (rowCount: number) => {
if (rowCount < this.data.length) {
this.data.length = rowCount;
}

this.rowCount = rowCount;
};

add(data: DataSourceRow) {
const [index] = data;
if (this.isWithinRange(index)) {
const internalIndex = index - this.range.from;
this.data[internalIndex] = data;

// Hack until we can deal with this more elegantly. When we have a block
// select operation, first row is selected (and updated via server), then
// remaining rows are selected when we select the block-end row. We get an
// update for all rows except first. Because we're extending the select status
// on the client, we have to adjust the first row selected (its still selected
// but is no longer the 'last selected row in block')
// Maybe answer is to apply ALL the selection status code here, not in Viewport
if (data[SELECTED]) {
const previousRow = this.data[internalIndex - 1];
if (isRowSelectedLast(previousRow)) {
this.data[internalIndex - 1] = previousRow.slice() as DataSourceRow;
this.data[internalIndex - 1][SELECTED] -= 4;
}
}
}
}

getAtIndex(index: number) {
return this.range.isWithin(index) &&
this.data[index - this.range.from] != null
? this.data[index - this.range.from]
: undefined;
}

isWithinRange(index: number) {
return this.range.isWithin(index);
}

setRange({ from, to }: VuuRange) {
if (from !== this.range.from || to !== this.range.to) {
const [overlapFrom, overlapTo] = this.range.overlap(from, to);
const newData = new Array(Math.max(0, to - from));
for (let i = overlapFrom; i < overlapTo; i++) {
const data = this.getAtIndex(i);
if (data) {
const index = i - from;
newData[index] = data;
}
}
this.data = newData;
this.range.from = from;
this.range.to = to;
}
}

getSelectedRows() {
return this.data.filter((row) => row[SELECTED] !== 0);
}
}
Loading

0 comments on commit 308ee37

Please sign in to comment.