Skip to content

Commit

Permalink
Merge pull request #1546 from finos/linked-table-filter
Browse files Browse the repository at this point in the history
Linked table filter
  • Loading branch information
heswell authored Nov 22, 2024
2 parents f06f84f + 44790a0 commit 76ba8d8
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 79 deletions.
4 changes: 3 additions & 1 deletion vuu-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,10 @@ export class ArrayDataSource
});
}

this.setRange(resetRange(this.#range), true);

this.emit("config", this._config, this.range, undefined, configChanges);
if (this.#status === "subscribed") {
this.setRange(resetRange(this.#range), true);
this.emit("config", this._config, this.range, undefined, configChanges);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ export class ServerProxy {
// Resend requests for links from other viewports already on page, they may be linkable to this viewport
Array.from(this.viewports.entries())
.filter(
([id, { disabled }]) => id !== serverViewportId && !disabled,
([id, { disabled, status }]) =>
id !== serverViewportId && !disabled && status === "subscribed",
)
.forEach(([vpId]) => {
this.sendMessageToServer({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const parentOrderData: VuuRowDataItemType[][] = [];

const instrumentMap = buildDataColumnMap(schemas, "instruments");

const PARENT_ORDER_COUNT = 100_000;
const CHILD_ORDER_COUNT = 500_000;
const PARENT_ORDER_COUNT = 75_000;
const CHILD_ORDER_COUNT = 200_000;

const avgChildOrderPerOrder = Math.round(
CHILD_ORDER_COUNT / PARENT_ORDER_COUNT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
}

.vuuLinkedTableView-view {
overflow: hidden;
padding: var(--salt-spacing-100);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {

import css from "./LinkedTableView.css";
import { TableLayoutToggleButton } from "./TableLayoutToggleButton";
import { Filter } from "@finos/vuu-filter-types";

const classBase = "vuuLinkedTableView";

Expand Down Expand Up @@ -47,10 +48,25 @@ export type LinkedDataSources = {

/**
* Displays a vertical 'tower' of Tables with a hierarchical relationship.
* Selection of row(s) on tables higher in the hierarchy drives the population
* of data in tables below. (could be two-way ?)
* Currently supported levels are:
* - tier 1 - parent table(s)
* - tier 2 - child table(s)
* -tier 3 (optional) - grandchild table(s)
*
* Selection of row(s) on tables higher in the hierarchy drives the display
* of data in tables below. Currently this is one-way, top-down only
*/
export interface LinkedTableViewProps extends HTMLAttributes<HTMLDivElement> {
/**
* Optional filter to allow externally controlled filter to be applied. This will
* be applied to tier 1 table(s).
* If applicable, it will also be applied to tier2/tier3 table(s) when no selection
* is in effect from parent table, 'If applicable' means if the filter column is
* available on tier 2/tier 3 tables).
* If a filter is provided and it cannot be applied - because
* column name of filter is not available in tier 1 table, an exception will be thrown.
*/
filter?: Filter;
linkedDataSources: LinkedDataSources;
}
const LinkedTables = ({
Expand All @@ -65,13 +81,14 @@ const LinkedTables = ({
window: targetWindow,
});

const { activeTabs, tableConfig, ...config } = useLinkedTableView({
const { tableConfig, ...config } = useLinkedTableView({
linkedDataSources,
});

const getLinkedTables = (
tdsConfig: TableDataSourceConfig | TableDataSourceConfig[],
{
activeTab,
onChangeTabbedView,
onTabChange,
tabbedView,
Expand Down Expand Up @@ -99,7 +116,7 @@ const LinkedTables = ({
}}
>
<div className={`${classBase}-header`}>
<Tabstrip activeTabIndex={activeTabs[1]} onActiveChange={onTabChange}>
<Tabstrip activeTabIndex={activeTab} onActiveChange={onTabChange}>
{tdsConfig.map(({ title }, i) => (
<Tab key={i} label={title} />
))}
Expand All @@ -112,7 +129,7 @@ const LinkedTables = ({
</div>
</div>
<Stack
active={activeTabs[1]}
active={activeTab}
data-resizeable
key={levelConfig.key}
showTabs={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,13 @@ export const useLinkedTableView = ({
);

return {
activeTabs,
level1: {
activeTab: activeTabs[0],
key: "level1",
onTabChange: handleTabChangeLevel1,
},
level2: {
activeTab: activeTabs[1],
collapsed: collapsed[0],
key: "level2",
onChangeTabbedView: handleChangeTabbedView2,
Expand All @@ -268,6 +269,7 @@ export const useLinkedTableView = ({
tabbedView: tabbedView[0],
},
level3: {
activeTab: activeTabs[2],
collapsed: collapsed[1],
key: "level3",
onChangeTabbedView: handleChangeTabbedView3,
Expand All @@ -287,6 +289,7 @@ export type LevelsConfig = {
};

export type LevelConfig = {
activeTab: number;
key: string;
collapsed?: boolean;
onChangeTabbedView?: (evt: SyntheticEvent<HTMLElement>) => void;
Expand Down
77 changes: 24 additions & 53 deletions vuu-ui/packages/vuu-layout/src/flexbox/useSplitterResizing.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { getUniqueId } from "@finos/vuu-utils";
import React, {
ReactElement,
useCallback,
useMemo,
useRef,
useState,
} from "react";
import React, { ReactElement, useCallback, useMemo, useRef } from "react";
import { Placeholder } from "../placeholder";
import { Splitter } from "./Splitter";

Expand Down Expand Up @@ -33,15 +27,10 @@ export const useSplitterResizing = ({
style,
}: SplitterHookProps): SplitterHookResult => {
const rootRef = useRef<HTMLDivElement>(null);
const flexElementsRef = useRef<HTMLDivElement[]>();
const metaRef = useRef<ContentMeta[]>();
const contentRef = useRef<ReactElement[]>();
const assignedKeys = useRef([]);
const [, forceUpdate] = useState({});

const setContent = (content: ReactElement[]) => {
contentRef.current = content;
forceUpdate({});
};
const assignedKeys = useRef<string[]>([]);

const isColumn = style?.flexDirection === "column";
const dimension = isColumn ? "height" : "width";
Expand Down Expand Up @@ -84,28 +73,24 @@ export const useSplitterResizing = ({

if (rootRef.current) {
rootRef.current.classList.add("vuuSplitterResizing");
console.log({ root: rootRef.current });
flexElementsRef.current = Array.from(
rootRef.current.querySelectorAll<HTMLDivElement>(":scope > div"),
);
}
}
}
},
[dimension],
);

const handleDrag = useCallback(
(idx, distance) => {
if (contentRef.current && metaRef.current) {
setContent(
resizeContent(
contentRef.current,
metaRef.current,
distance,
dimension,
),
);
}
},
[dimension],
);
const handleDrag = useCallback((idx, distance) => {
const { current: flexElements = [] } = flexElementsRef;

if (contentRef.current && metaRef.current) {
resizeElements(flexElements, metaRef.current, distance /*, dimension*/);
}
}, []);

const handleDragEnd = useCallback(() => {
const contentMeta = metaRef.current;
Expand Down Expand Up @@ -157,8 +142,8 @@ function buildContent(
children: ReactElement[],
dimension: "width" | "height",
createSplitter: SplitterFactory,
keys: any[],
): [any[], ContentMeta[]] {
keys: string[],
): [ReactElement[], ContentMeta[]] {
const childMeta = gatherChildMeta(children, dimension);
const splitterAndPlaceholderPositions =
findSplitterAndPlaceholderPositions(childMeta);
Expand Down Expand Up @@ -189,37 +174,23 @@ function buildContent(
return [content, meta];
}

function resizeContent(
content: ReactElement[],
function resizeElements(
flexElements: HTMLDivElement[],
contentMeta: ContentMeta[],
distance: number,
dimension: "width" | "height",
) {
const metaUpdated = updateMeta(contentMeta, distance);
if (!metaUpdated) {
return content;
return;
}

return content.map((child, idx) => {
flexElements.forEach((element, idx) => {
const meta = contentMeta[idx];
const { currentSize, flexOpen, flexBasis } = meta;
const { currentSize, flexOpen, flexBasis, splitter } = meta;
const hasCurrentSize = currentSize !== undefined;
if (hasCurrentSize || flexOpen) {
const { flexBasis: actualFlexBasis } = child.props.style || {};
if (!splitter && (hasCurrentSize || flexOpen)) {
const size = hasCurrentSize ? meta.currentSize : flexBasis;
if (size !== actualFlexBasis) {
return React.cloneElement(child, {
style: {
...child.props.style,
flexBasis: size,
[dimension]: "auto",
},
});
} else {
return child;
}
} else {
return child;
element.style.flexBasis = `${size}px`;
}
});
}
Expand Down Expand Up @@ -262,7 +233,7 @@ function createPlaceholder(index: number) {
return React.createElement(Placeholder, {
shim: index === 0,
key: `placeholder-${index}`,
} as any);
});
}

function measureElement(
Expand Down
10 changes: 10 additions & 0 deletions vuu-ui/packages/vuu-table/src/useDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const useDataSource = ({
// setRange calls at this point so dataWindow range will
//not yet be set. If the dataWindow range is already set,
// this is a no-op.
console.log("resumed");
const { range } = dataSource;
if (range.to !== 0) {
dataWindow.setRange(dataSource.range);
Expand Down Expand Up @@ -81,6 +82,10 @@ export const useDataSource = ({
const size = dataWindow.data.length;
dataWindow.setRowCount(message.size);
if (dataWindow.data.length < size) {
if (isMounted.current === false) {
console.log("setting state whilst unmounted");
}

forceUpdate({});
}
}
Expand All @@ -101,6 +106,11 @@ export const useDataSource = ({
onSizeChange?.(0);
dataWindow.setRowCount(0);
setData([]);

if (isMounted.current === false) {
console.log("setting state whilst unmounted");
}

forceUpdate({});
} else {
console.log(`useDataSource unexpected message ${message.type}`);
Expand Down
17 changes: 13 additions & 4 deletions vuu-ui/packages/vuu-table/src/useTable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
DataSourceConfig,
DataSourceConfigChangeHandler,
DataSourceRow,
DataSourceSubscribedMessage,
SelectionChangeHandler,
Expand Down Expand Up @@ -346,8 +347,8 @@ export const useTable = ({
[dataSource],
);

useEffect(() => {
dataSource.on("config", (config, range, confirmed, changes) => {
const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(
(config, range, confirmed, changes) => {
const scrollSensitiveChanges =
changes?.filterChanged || changes?.groupByChanged;
if (scrollSensitiveChanges && range.from > 0) {
Expand All @@ -361,8 +362,16 @@ export const useTable = ({
...config,
confirmed,
});
});
}, [dataSource, dispatchTableModelAction]);
},
[dispatchTableModelAction],
);

useEffect(() => {
dataSource.on("config", handleConfigChange);
return () => {
dataSource.removeListener("config", handleConfigChange);
};
}, [dataSource, dispatchTableModelAction, handleConfigChange]);

const handleCreateCalculatedColumn = useCallback(
(column: ColumnDescriptor) => {
Expand Down
3 changes: 2 additions & 1 deletion vuu-ui/packages/vuu-ui-controls/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"@salt-ds/core": "1.37.1",
"@salt-ds/icons": "1.12.1",
"@salt-ds/styles": "0.2.1",
"@salt-ds/window": "0.1.1"
"@salt-ds/window": "0.1.1",
"tabbable": "^6.0.0"
},
"peerDependencies": {
"@internationalized/date": "^3.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@

.vuuSplitButton-cta {
--split-background: var(--background, var(--salt-actionable-accented-bold-background));
--split-background-active: var(--salt-actionable-accented-bold-background-active;
--split-background-active: var(--salt-actionable-accented-bold-background-active);
--split-color-active: var(--salt-actionable-bold-foreground-active);
}
.vuuSplitButton-cta:hover:not(.vuuSplitButton-disabled) {
Expand Down
Loading

0 comments on commit 76ba8d8

Please sign in to comment.