diff --git a/package-lock.json b/package-lock.json index 42db077f3..bc5fc96fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -111,7 +111,7 @@ "@mui/icons-material": "^5.16.14", "@mui/lab": "5.0.0-alpha.175", "@mui/material": "^5.16.14", - "@mui/x-tree-view": "^7.29.1", + "@mui/x-tree-view": "^8.21.0", "ag-grid-community": "^33.0.3", "ag-grid-react": "^33.0.4", "notistack": "^3.0.2", @@ -2377,6 +2377,29 @@ "node": ">=6.9.0" } }, + "node_modules/@base-ui-components/utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@base-ui-components/utils/-/utils-0.1.2.tgz", + "integrity": "sha512-aEitDGpMsYO2qnSpYOwZNykn9Rzn2ioyEVk2fyDRH7t+TIHVKpp9CeV7SPTq43M9mMSDxQ+7UeZJVkrj2dCVIQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.28.4", + "@floating-ui/utils": "^0.2.10", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "^17 || ^18 || ^19", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -3420,7 +3443,6 @@ "version": "0.2.10", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", - "dev": true, "license": "MIT" }, "node_modules/@formatjs/ecma402-abstract": { @@ -4750,13 +4772,15 @@ } }, "node_modules/@mui/x-internals": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.29.0.tgz", - "integrity": "sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.21.0.tgz", + "integrity": "sha512-tOU6iKi9phIQXWVzQvslKR/y5q+L/NKiBpSqtTDMV7aAxm2mOtCiO6POH2je1nw8iromrQAJfpV9pXDDRgZ01w==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.7", - "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0" + "@babel/runtime": "^7.28.4", + "@mui/utils": "^7.3.5", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.6.0" }, "engines": { "node": ">=14.0.0" @@ -4769,17 +4793,67 @@ "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/@mui/x-internals/node_modules/@mui/types": { + "version": "7.4.9", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.9.tgz", + "integrity": "sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-internals/node_modules/@mui/utils": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.6.tgz", + "integrity": "sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/types": "^7.4.9", + "@types/prop-types": "^15.7.15", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/x-tree-view": { - "version": "7.29.10", - "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.29.10.tgz", - "integrity": "sha512-/ZcM582yIaQN2PmadIlQYRJzc3yXV7bh463J4GHtTmFw+PEjzUfzETBWe3VxmU3EPgIFzVQPjqAAJwylmQSJOg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-8.21.0.tgz", + "integrity": "sha512-3P9UrUzlPI4B4padvIVtu0G2QLbOf0ylcaUu3u/XRxPIsEqLyjOorwsxJ+y39jpvmv6DUR47VPKmldqTaU/j8w==", "license": "MIT", "peer": true, "dependencies": { - "@babel/runtime": "^7.25.7", - "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0", - "@mui/x-internals": "7.29.0", - "@types/react-transition-group": "^4.4.11", + "@babel/runtime": "^7.28.4", + "@base-ui-components/utils": "0.1.2", + "@mui/utils": "^7.3.5", + "@mui/x-internals": "8.21.0", + "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" @@ -4808,6 +4882,55 @@ } } }, + "node_modules/@mui/x-tree-view/node_modules/@mui/types": { + "version": "7.4.9", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.9.tgz", + "integrity": "sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-tree-view/node_modules/@mui/utils": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.6.tgz", + "integrity": "sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/types": "^7.4.9", + "@types/prop-types": "^15.7.15", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", diff --git a/package.json b/package.json index c5f612562..10e882b83 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@mui/icons-material": "^5.16.14", "@mui/lab": "5.0.0-alpha.175", "@mui/material": "^5.16.14", - "@mui/x-tree-view": "^7.29.1", + "@mui/x-tree-view": "^8.21.0", "ag-grid-community": "^33.0.3", "ag-grid-react": "^33.0.4", "notistack": "^3.0.2", diff --git a/src/components/treeViewFinder/TreeViewFinder.tsx b/src/components/treeViewFinder/TreeViewFinder.tsx index c48bb7ef6..9148ce792 100644 --- a/src/components/treeViewFinder/TreeViewFinder.tsx +++ b/src/components/treeViewFinder/TreeViewFinder.tsx @@ -19,7 +19,7 @@ import { styled, Typography, } from '@mui/material'; -import { TreeItem, SimpleTreeView, SimpleTreeViewClasses } from '@mui/x-tree-view'; +import { SimpleTreeView, SimpleTreeViewClasses, TreeItem } from '@mui/x-tree-view'; import { Check as CheckIcon, ChevronRight as ChevronRightIcon, @@ -28,7 +28,8 @@ import { import type { UUID } from 'node:crypto'; import { makeComposeClasses, type MuiStyles, toNestedGlobalSelectors } from '../../utils/styles'; import { CancelButton } from '../inputs/reactHookForm/utils/CancelButton'; -import { ElementType } from '../../utils'; +import { ElementAttributes, ElementType } from '../../utils'; +import { doesNodeHasChildren } from './TreeViewUtils'; // As a bunch of individual variables to try to make it easier // to track that they are all used. Not sure, maybe group them in an object ? @@ -261,7 +262,7 @@ function TreeViewFinderComponant(props: Readonly) { .filter((node) => node !== null) as TreeViewFinderNodeProps[]; }; - const handleNodeToggle = (_e: React.SyntheticEvent, itemIds: string[]) => { + const handleNodeToggle = (_e: React.SyntheticEvent | null, itemIds: string[]) => { // onTreeBrowse proc only on last node clicked and only when expanded itemIds.every((itemId) => { if (!expanded?.includes(itemId)) { @@ -322,7 +323,7 @@ function TreeViewFinderComponant(props: Readonly) { }, [expanded, selectedProp, expandedProp, data, autoScrollAllowed]); /* User Interaction management */ - const handleNodeSelect = (_e: React.SyntheticEvent, values: string | string[] | null) => { + const handleNodeSelect = (_e: React.SyntheticEvent | null, values: string | string[] | null) => { // Default management if (multiSelect && Array.isArray(values)) { setSelected(values.filter((itemId) => isSelectable(mapPrintedNodes[itemId]))); @@ -394,7 +395,8 @@ function TreeViewFinderComponant(props: Readonly) { } let childrenNodes = null; const showExpandIcon = showChevron(node); - if (Array.isArray(node.children) && node.children.length > 0) { + if (doesNodeHasChildren(node as unknown as ElementAttributes)) { + // @ts-ignore checked above childrenNodes = node.children.toSorted(sortMethod).map(renderTree); } else if (showExpandIcon) { childrenNodes = []; // simulate placeholder so expand icon is shown diff --git a/src/components/treeViewFinder/TreeViewUtils.ts b/src/components/treeViewFinder/TreeViewUtils.ts new file mode 100644 index 000000000..58738a7c3 --- /dev/null +++ b/src/components/treeViewFinder/TreeViewUtils.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2025, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { ElementAttributes } from '../../utils'; + +export function doesNodeHasChildren(node: ElementAttributes) { + return Array.isArray(node.children) && node.children.length > 0; +} diff --git a/src/components/treeViewFinder/index.ts b/src/components/treeViewFinder/index.ts index 9094d2bd5..8f109af44 100644 --- a/src/components/treeViewFinder/index.ts +++ b/src/components/treeViewFinder/index.ts @@ -5,3 +5,4 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ export * from './TreeViewFinder'; +export * from './TreeViewUtils';