Skip to content

Commit

Permalink
add nodeData attribute to Tree rows (#1537)
Browse files Browse the repository at this point in the history
* add nodeData attribute to Tree rows

* add label to Tree Node
  • Loading branch information
heswell authored Nov 10, 2024
1 parent 1ee1b43 commit 7d922f5
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 28 deletions.
7 changes: 6 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 @@ -86,7 +86,7 @@ export class TreeDataSource extends BaseDataSource {
this._config = {
...this._config,
columns,
groupBy: columns,
groupBy: columns.slice(1),
};
}
}
Expand Down
27 changes: 26 additions & 1 deletion vuu-ui/packages/vuu-datatable/src/tree-table/TreeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { Table } from "@finos/vuu-table";
import { TreeDataSource } from "@finos/vuu-data-local";
import { useEffect, useMemo, useRef } from "react";
import { TableConfig } from "@finos/vuu-table-types";
import { TreeSourceNode } from "@finos/vuu-utils";
import {
isRowSelected,
metadataKeys,
type RowToObjectMapper,
type TreeSourceNode,
} from "@finos/vuu-utils";

const { DEPTH, IS_LEAF, KEY, IDX } = metadataKeys;

export interface TreeTableProps
extends Omit<TableProps, "config" | "dataSource"> {
Expand All @@ -14,6 +21,23 @@ export interface TreeTableProps
source: TreeSourceNode[];
}

const rowToTreeNodeObject: RowToObjectMapper = (row, columnMap) => {
const { [IS_LEAF]: isLeaf, [KEY]: key, [IDX]: index, [DEPTH]: depth } = row;
const firstColIdx = columnMap.nodeData;
const labelColIdx = firstColIdx + depth;

return {
key,
index,
isGroupRow: !isLeaf,
isSelected: isRowSelected(row),
data: {
label: row[labelColIdx],
nodeData: row[firstColIdx],
},
};
};

export const TreeTable = ({
config,
source: sourceProp,
Expand Down Expand Up @@ -54,6 +78,7 @@ export const TreeTable = ({
dataSource={dataSourceRef.current}
groupToggleTarget="toggle-icon"
navigationStyle="tree"
rowToObject={rowToTreeNodeObject}
showColumnHeaderMenus={false}
selectionModel="single"
selectionBookendWidth={0}
Expand Down
17 changes: 16 additions & 1 deletion vuu-ui/packages/vuu-table/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
dragStrategy,
reduceSizeHeight,
} from "@finos/vuu-ui-controls";
import { metadataKeys, useId } from "@finos/vuu-utils";
import { metadataKeys, RowToObjectMapper, useId } from "@finos/vuu-utils";
import { useForkRef } from "@salt-ds/core";
import { useComponentCssInjection } from "@salt-ds/styles";
import { useWindow } from "@salt-ds/window";
Expand Down Expand Up @@ -174,6 +174,17 @@ export interface TableProps
onSelectionChange?: SelectionChangeHandler;
renderBufferSize?: number;

/**
* When a row is selected and onSelect provided, onSelect will be invoked with a
* DataSourceRowObject, derived from the internal representation of a data row,
* DataSourceRow. The data attribute of DataSourceRowObject is a simple map of
* column.name : value.
* This prop allows a custom function to be provided to make the conversion from
* DataSourceRow to DataSourceRowObject. It will very rarely be needed. It is
* used by the Treetable.
*/
rowToObject?: RowToObjectMapper;

/**
* Only applicable to grouped data. If there are selected rows which are not top-level
* items and group items above are not already expanded, expand all group items in
Expand Down Expand Up @@ -267,6 +278,7 @@ const TableCore = ({
renderBufferSize = 0,
revealSelected,
rowHeight,
rowToObject,
scrollingApiRef,
selectionBookendWidth = 0,
selectionModel = "extended",
Expand Down Expand Up @@ -339,6 +351,7 @@ const TableCore = ({
renderBufferSize,
revealSelected,
rowHeight,
rowToObject,
scrollingApiRef,
selectionBookendWidth,
selectionModel,
Expand Down Expand Up @@ -511,6 +524,7 @@ export const Table = forwardRef(function Table(
renderBufferSize,
revealSelected,
rowHeight: rowHeightProp,
rowToObject,
scrollingApiRef,
selectionBookendWidth = 4,
selectionModel,
Expand Down Expand Up @@ -656,6 +670,7 @@ export const Table = forwardRef(function Table(
}
revealSelected={revealSelected}
rowHeight={rowHeight}
rowToObject={rowToObject}
scrollingApiRef={scrollingApiRef}
selectionBookendWidth={selectionBookendWidth}
selectionModel={selectionModel}
Expand Down
10 changes: 6 additions & 4 deletions vuu-ui/packages/vuu-table/src/useTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export interface TableHookProps
| "onRowClick"
| "renderBufferSize"
| "revealSelected"
| "rowToObject"
| "scrollingApiRef"
| "selectionBookendWidth"
| "showColumnHeaders"
Expand Down Expand Up @@ -173,6 +174,7 @@ export const useTable = ({
renderBufferSize = 0,
revealSelected,
rowHeight = 20,
rowToObject = asDataSourceRowObject,
scrollingApiRef,
selectionBookendWidth,
selectionModel,
Expand Down Expand Up @@ -666,10 +668,10 @@ export const useTable = ({
const handleSelect = useCallback<TableRowSelectHandlerInternal>(
(row) => {
if (onSelect) {
onSelect(row === null ? null : asDataSourceRowObject(row, columnMap));
onSelect(row === null ? null : rowToObject(row, columnMap));
}
},
[columnMap, onSelect],
[columnMap, onSelect, rowToObject],
);

const {
Expand Down Expand Up @@ -707,9 +709,9 @@ export const useTable = ({
const handleRowClick = useCallback<TableRowClickHandlerInternal>(
(evt, row, rangeSelect, keepExistingSelection) => {
selectionHookOnRowClick(evt, row, rangeSelect, keepExistingSelection);
onRowClickProp?.(evt, asDataSourceRowObject(row, columnMap));
onRowClickProp?.(evt, rowToObject(row, columnMap));
},
[columnMap, onRowClickProp, selectionHookOnRowClick],
[columnMap, onRowClickProp, rowToObject, selectionHookOnRowClick],
);

const handleKeyDown = useCallback(
Expand Down
7 changes: 6 additions & 1 deletion vuu-ui/packages/vuu-utils/src/row-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,14 @@ export const virtualRowPositioning = (
true,
];

export const asDataSourceRowObject = (
export type RowToObjectMapper = (
row: DataSourceRow,
columnMap: ColumnMap,
) => DataSourceRowObject;

export const asDataSourceRowObject: RowToObjectMapper = (
row,
columnMap,
): DataSourceRowObject => {
const { [IS_LEAF]: isLeaf, [KEY]: key, [IDX]: index } = row;

Expand Down
16 changes: 3 additions & 13 deletions vuu-ui/packages/vuu-utils/src/tree-types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
export interface TreeSourceNode {
export interface TreeSourceNode<T = unknown> {
nodeData?: T;
id: string;
icon?: string;
header?: boolean;
label: string;
childNodes?: TreeSourceNode[];
}
export interface NormalisedTreeSourceNode extends TreeSourceNode {
childNodes?: NormalisedTreeSourceNode[];
count: number;
expanded?: boolean;
index: number;
level: number;
}

export interface NonLeafNode extends NormalisedTreeSourceNode {
childNodes: NormalisedTreeSourceNode[];
childNodes?: TreeSourceNode<T>[];
}
8 changes: 6 additions & 2 deletions vuu-ui/packages/vuu-utils/src/tree-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export const treeToDataSourceRows = (
const columns: ColumnDescriptor[] = [];

columns.push(
{
name: "nodeData",
type: "json",
},
{
getIcon: iconProvider?.getIcon,
name: "Level 1",
Expand Down Expand Up @@ -52,11 +56,11 @@ const addChildValues = (
});
}
for (let i = 0; i < treeSourceNodes.length; i++, index.value += 1) {
const { childNodes, icon, label } = treeSourceNodes[i];
const { childNodes, icon, label, nodeData } = treeSourceNodes[i];
const blanks = Array(depth - 1).fill("");
const fullKey = `${keyBase}|${label}`;
// prettier-ignore
const row = [index.value, index.value, false,false,depth,0,fullKey,0, ...blanks, label ] as DataSourceRow;
const row = [index.value, index.value, false,false,depth,0,fullKey,0, nodeData, ...blanks, label ] as DataSourceRow;
if (icon) {
iconProvider?.setIcon(fullKey, icon);
}
Expand Down
34 changes: 34 additions & 0 deletions vuu-ui/showcase/src/examples/DataTable/TreeTable.examples.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { TreeTable } from "@finos/vuu-datatable";

import showcaseData from "./Tree.data";
import { useMemo } from "react";
import { TreeSourceNode } from "@finos/vuu-utils";
import { TableRowSelectHandler } from "@finos/vuu-table-types";

let displaySequence = 1;

Expand Down Expand Up @@ -45,3 +48,34 @@ export const ShowcaseTreeSelectedAutoReveal = () => {
);
};
ShowcaseTreeSelectedAutoReveal.displaySequence = displaySequence++;

const addDataNodes = (
treeNodes: TreeSourceNode[],
index = { value: 0 },
): Array<TreeSourceNode<string>> => {
return treeNodes?.map<TreeSourceNode<string>>(({ childNodes, ...rest }) => ({
...rest,
nodeData: `node-${index.value++}`,
childNodes: childNodes ? addDataNodes(childNodes, index) : undefined,
}));
};

export const ShowcaseTreeNodeOptions = () => {
const source = useMemo(() => {
return addDataNodes(showcaseData);
}, []);

const onSelect: TableRowSelectHandler = (row) => {
console.log({ row });
};

return (
<TreeTable
onSelect={onSelect}
rowHeight={30}
showColumnHeaders={false}
source={source}
/>
);
};
ShowcaseTreeNodeOptions.displaySequence = displaySequence++;
4 changes: 2 additions & 2 deletions vuu-ui/tools/vuu-showcase/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { IFrame } from "./components";
import {
ExamplesModule,
byDisplaySequence,
keyFromPath,
keysFromPath,
loadTheme,
pathFromKey,
} from "./showcase-utils";
Expand Down Expand Up @@ -148,7 +148,7 @@ export const App = ({ stories }: AppProps) => {
className="ShowcaseNav"
data-resizeable
rowHeight={30}
defaultSelectedKeyValues={[keyFromPath(pathname)]}
defaultSelectedKeyValues={keysFromPath(pathname)}
// selected={[pathname.slice(1)]}
showColumnHeaders={false}
onSelect={handleChange}
Expand Down
9 changes: 7 additions & 2 deletions vuu-ui/tools/vuu-showcase/src/showcase-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@ export const byDisplaySequence = ([, f1]: VuuTuple, [, f2]: VuuTuple) => {
};

export const pathFromKey = (key: string) => key.slice(5).split("|").join("/");
export const keyFromPath = (path: string) =>
`$root${path.split("/").join("|")}`;
export const keysFromPath = (path: string) => {
if (path === "/") {
return undefined;
} else {
return [`$root${path.split("/").join("|")}`];
}
};

export const pathToExample = (path: string): [string[], string] => {
const endOfImportPath = path.lastIndexOf("/");
Expand Down

0 comments on commit 7d922f5

Please sign in to comment.