diff --git a/package-lock.json b/package-lock.json index 8332d616..594c0ba3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26353,9 +26353,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -28786,7 +28786,7 @@ "react-router": "^6.30.1", "react-router-dom": "^6.30.1", "rimraf": "^6.0.1", - "typescript": "^5.8.3" + "typescript": "^5.9.2" }, "peerDependencies": { "react": "^17 || ^18 || ^19", @@ -31695,7 +31695,7 @@ "react-router": "^6.30.1", "react-router-dom": "^6.30.1", "rimraf": "^6.0.1", - "typescript": "^5.8.3" + "typescript": "^5.9.2" } }, "@patternfly/react-icons": { @@ -47058,9 +47058,9 @@ "dev": true }, "typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true }, "uglify-js": { diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx index e219c773..25d64c68 100644 --- a/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx +++ b/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/DataViewTableTreeExample.tsx @@ -4,6 +4,7 @@ import { DataViewTable, DataViewTh, DataViewTrTree } from '@patternfly/react-dat import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks'; import { FolderIcon, FolderOpenIcon, LeafIcon } from '@patternfly/react-icons'; + interface Repository { name: string; branches: string | null; diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/Table.md b/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/Table.md index 513846ac..b5c771c9 100644 --- a/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/Table.md +++ b/packages/module/patternfly-docs/content/extensions/data-view/examples/Table/Table.md @@ -39,6 +39,8 @@ To define rows and columns for your table, use these props: It is also possible to disable row selection using the `isSelectDisabled` function, which can be passed to the wrapping `DataView` component through the `selection` prop. +If you want to have all expandable nodes open on initial load pass the `expandAll` prop to the DataViewTable component + ### Table example ```js file="./DataViewTableExample.tsx" diff --git a/packages/module/src/DataViewTableTree/DataViewTableTree.test.tsx b/packages/module/src/DataViewTableTree/DataViewTableTree.test.tsx index b36a30b3..f76d40b3 100644 --- a/packages/module/src/DataViewTableTree/DataViewTableTree.test.tsx +++ b/packages/module/src/DataViewTableTree/DataViewTableTree.test.tsx @@ -101,6 +101,15 @@ describe('DataViewTableTree component', () => { expect(container).toMatchSnapshot(); }); + test('should render tree table with all expandable nodes expanded', () => { + const { container } = render( + + } expandedIcon={} collapsedIcon={} /> + + ); + expect(container).toMatchSnapshot(); + }); + test('should render tree table with a loading state', () => { const { container } = render( diff --git a/packages/module/src/DataViewTableTree/DataViewTableTree.tsx b/packages/module/src/DataViewTableTree/DataViewTableTree.tsx index 8c313c21..8865edd8 100644 --- a/packages/module/src/DataViewTableTree/DataViewTableTree.tsx +++ b/packages/module/src/DataViewTableTree/DataViewTableTree.tsx @@ -1,4 +1,4 @@ -import { FC, useState, useMemo, ReactNode } from 'react'; +import { FC, useState, useMemo, useEffect, ReactNode } from 'react'; import { Table, TableProps, @@ -67,6 +67,8 @@ export interface DataViewTableTreeProps extends Omit = ({ leafIcon = null, expandedIcon = null, collapsedIcon = null, + expandAll = false, ouiaId = 'DataViewTableTree', ...props }: DataViewTableTreeProps) => { @@ -87,6 +90,33 @@ export const DataViewTableTree: FC = ({ const [ expandedNodeIds, setExpandedNodeIds ] = useState([]); const [ expandedDetailsNodeNames, setExpandedDetailsNodeIds ] = useState([]); + // Helper function to collect all node IDs that have children (are expandable) + const getExpandableNodeIds = (nodes: DataViewTrTree[]): string[] => { + const expandableIds: string[] = []; + + const traverse = (nodeList: DataViewTrTree[]) => { + nodeList.forEach(node => { + if (node.children && node.children.length > 0) { + expandableIds.push(node.id); + traverse(node.children); + } + }); + }; + + traverse(nodes); + return expandableIds; + }; + + // Effect to handle expandAll behavior + useEffect(() => { + if (expandAll) { + const expandableIds = getExpandableNodeIds(rows); + setExpandedNodeIds(expandableIds); + } else { + setExpandedNodeIds([]); + } + }, [ expandAll, rows ]); + const activeHeadState = useMemo(() => activeState ? headStates?.[activeState] : undefined, [ activeState, headStates ]); const activeBodyState = useMemo(() => activeState ? bodyStates?.[activeState] : undefined, [ activeState, bodyStates ]); diff --git a/packages/module/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap b/packages/module/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap index 44964c7d..7a1387ee 100644 --- a/packages/module/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap +++ b/packages/module/src/DataViewTableTree/__snapshots__/DataViewTableTree.test.tsx.snap @@ -1045,6 +1045,971 @@ exports[`DataViewTableTree component should render tree table with a loading sta `; +exports[`DataViewTableTree component should render tree table with all expandable nodes expanded 1`] = ` +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Repositories + + Branches + + Pull requests + + Workspaces + + Last commit +
+
+ + + + + + +
+ + + + + Repository one + +
+ + + +
+
+ Branch one + + Pull request one + + Workspace one + + Timestamp one +
+
+ + + + + + +
+ + + + + Repository four + +
+ + + +
+
+ Branch four + + Pull request four + + Workspace four + + Timestamp four +
+
+
+
+`; + exports[`DataViewTableTree component should render tree table with an empty state 1`] = `