Untitled
unknown
plain_text
a year ago
4.5 kB
16
Indexable
interface Item { id: string; index: number; isRoot?: boolean; level: number; // Track the depth for rendering children: Item[]; } class TreeNode { data: Item; children: TreeNode[]; constructor(data: Item) { this.data = data; this.children = []; // Initialize level at the TreeNode for rendering purposes this.data.level = this.data.level ?? 0; } addChild(child: TreeNode): void { child.data.level = this.data.level + 1; // Increment child level based on parent this.children.push(child); } } class Forest { roots: TreeNode[]; constructor() { this.roots = []; } addNode(newNodeData: Item, parentId: string | null): void { const newNode = new TreeNode(newNodeData); if (parentId === null) { this.roots.push(newNode); } else { let parentFound = false; for (const root of this.roots) { const parent = this.findNode(root, parentId); if (parent) { parent.addChild(newNode); parentFound = true; break; } } if (!parentFound) { throw new Error(`Parent with id ${parentId} not found.`); } } } findNode(current: TreeNode | null, id: string): TreeNode | null { if (!current) return null; if (current.data.id === id) { return current; } for (const child of current.children) { const result = this.findNode(child, id); if (result) { return result; } } return null; } flatten(): Item[] { return this.roots.flatMap(root => flat(root)); } } function flat(node: TreeNode | null): Item[] { let result: Item[] = []; if (node) { result.push(node.data); node.children.forEach(child => { result = result.concat(flat(child)); }); } return result; } // Initialize the forest and add nodes const forest = new Forest(); forest.addNode({ id: "item1", index: 0, isRoot: true, children: [], level: 0 }, null); forest.addNode({ id: "item1child1", index: 1, children: [], level: 1 }, "item1"); forest.addNode({ id: "item1child2", index: 2, children: [], level: 1 }, "item1"); forest.addNode({ id: "item2", index: 3, isRoot: true, children: [], level: 0 }, null); forest.addNode({ id: "item2child1", index: 4, children: [], level: 1 }, "item2"); forest.addNode({ id: "item2child2", index: 5, children: [], level: 1 }, "item2"); forest.addNode({ id: "item2child2child1", index: 6, children: [], level: 2 }, "item2child2"); forest.addNode({ id: "item2child1child1", index: 7, children: [], level: 2 }, "item2child1"); forest.addNode({ id: "item2child1child1child1", index: 8, children: [], level: 3 }, "item2child1child1"); // Flatten the forest for rendering let items = forest.flatten(); const { DetailsList, Selection, SelectionMode, CheckboxVisibility } = window.FluentUIReact; let defaultRenderFn; const getColumns = (level: number) => { return [ { key: "id", minWidth: 20, name: "ID", onRender: (item: Item) => <span style={{paddingLeft: `${20 * item.level}px`}}>{item.id}</span> } ]; }; const RowWithChildren = (props: any) => { return defaultRenderFn({ ...props, itemIndex: props.item.index, key: props.item.id, columns: getColumns(props.item.level), styles: { root: { paddingLeft: `${20 * props.item.level}px` } }, }); }; const onRenderRow = (props: any, defaultRender: any) => { defaultRenderFn = defaultRender; return <RowWithChildren {...props} item={props.item} level={props.item.level} />; }; const Content = () => { const [count, setCount] = React.useState(0); const selection = new Selection({ onSelectionChanged: () => { setCount(selection.getSelection().length); }, getKey: (item: Item) => item.id }); const styles = { root: { selectors: { ".ms-List-cell:empty": { display: "none" } } }, }; return ( <div> <span>{count} rows selected</span> <DetailsList items={items} columns={getColumns(0)} onRenderRow={onRenderRow} selection={selection} selectionMode={SelectionMode.multiple} selectionPreservedOnEmptyClick={true} checkboxVisibility={CheckboxVisibility.always} styles={styles} /> </div> ); }; ReactDOM.render(<Content />, document.getElementById("content"));
Editor is loading...
Leave a Comment