diff --git a/package-lock.json b/package-lock.json index f2674650..5e6314a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", - "@mui/x-tree-view": "^6.17.0", + "@mui/x-tree-view": "^7.5.0", "@react-hook/window-size": "^3.1.1", "@types/autosuggest-highlight": "^3.2.3", "@types/eslint": "^8.56.7", @@ -105,6 +105,7 @@ "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", + "@mui/x-tree-view": "^7.5.0", "ag-grid-community": "^31.0.0", "ag-grid-react": "^31.2.0", "notistack": "^3.0.1", @@ -2167,9 +2168,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -4356,16 +4357,17 @@ } }, "node_modules/@mui/x-tree-view": { - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-6.17.0.tgz", - "integrity": "sha512-09dc2D+Rjg2z8KOaxbUXyPi0aw7fm2jurEtV8Xw48xJ00joLWd5QJm1/v4CarEvaiyhTQzHImNqdgeJW8ZQB6g==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.5.0.tgz", + "integrity": "sha512-Oy+awMPMN8M6QE6fzKwrQSG/7Rh0sEDvEc7TyENP7h75J2LPy5qqztCgRTlliEG1/Iq+aC4yFoIsJnEUH+M4gw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.23.2", - "@mui/base": "^5.0.0-beta.20", - "@mui/utils": "^5.14.14", - "@types/react-transition-group": "^4.4.8", - "clsx": "^2.0.0", + "@babel/runtime": "^7.24.5", + "@mui/base": "^5.0.0-beta.40", + "@mui/system": "^5.15.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, @@ -4374,13 +4376,12 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", - "@mui/material": "^5.8.6", - "@mui/system": "^5.8.0", + "@mui/material": "^5.15.14", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" } @@ -7132,9 +7133,9 @@ } }, "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } diff --git a/package.json b/package.json index 93cb663f..7d5ad826 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", + "@mui/x-tree-view": "^7.5.0", "ag-grid-community": "^31.0.0", "ag-grid-react": "^31.2.0", "notistack": "^3.0.1", @@ -74,7 +75,7 @@ "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", - "@mui/x-tree-view": "^6.17.0", + "@mui/x-tree-view": "^7.5.0", "@react-hook/window-size": "^3.1.1", "@types/autosuggest-highlight": "^3.2.3", "@types/eslint": "^8.56.7", diff --git a/src/components/ReportViewer/report-item.tsx b/src/components/ReportViewer/report-item.tsx index 7d922f3f..52ea9523 100644 --- a/src/components/ReportViewer/report-item.tsx +++ b/src/components/ReportViewer/report-item.tsx @@ -8,7 +8,7 @@ import { PropsWithChildren, ReactNode, useContext } from 'react'; import { Box, Theme, Typography } from '@mui/material'; import { alpha, styled } from '@mui/system'; -import { TreeItem, TreeItemProps } from '@mui/lab'; +import { TreeItem, TreeItemProps } from '@mui/x-tree-view'; import { Label } from '@mui/icons-material'; import ReportTreeViewContext from './report-tree-view-context'; @@ -81,7 +81,6 @@ const styles = { }; export interface ReportItemProps extends TreeItemProps { - nodeId: string; labelText: ReactNode; labelIconColor: string; className?: any; @@ -91,7 +90,7 @@ const ReportItem = (props: PropsWithChildren) => { // using a context because TreeItem uses useMemo on this. See report-viewer.js for the provider const { isHighlighted } = useContext(ReportTreeViewContext); - const highlighted = isHighlighted ? isHighlighted(props.nodeId) : false; + const highlighted = isHighlighted ? isHighlighted(props.itemId) : false; const { labelText, labelIconColor, className, ...other } = props; diff --git a/src/components/ReportViewer/report-viewer.tsx b/src/components/ReportViewer/report-viewer.tsx index a5478c75..4d9b16d1 100644 --- a/src/components/ReportViewer/report-viewer.tsx +++ b/src/components/ReportViewer/report-viewer.tsx @@ -24,7 +24,7 @@ import { Grid } from '@mui/material'; import LogTable from './log-table'; import ReportTreeViewContext from './report-tree-view-context'; import LogReportItem from './log-report-item'; -import { TreeView } from '@mui/x-tree-view'; +import { SimpleTreeView } from '@mui/x-tree-view'; import { Report } from './report.type'; import { LogSeverities } from './log-severity'; @@ -40,6 +40,10 @@ const styles = { }, }; +function EmptyIcon() { + return
; +} + export interface ReportViewerProps { jsonReport: Report; maxSubReports?: number; @@ -90,7 +94,7 @@ export default function ReportViewer({ labelIconColor={logReport.getHighestSeverity().colorName} key={logReport.getId().toString()} sx={styles.treeItem} - nodeId={logReport.getId().toString()} + itemId={logReport.getId().toString()} > {logReport .getSubReports() @@ -121,14 +125,14 @@ export default function ReportViewer({ } }; - const handleSelectNode = (event: SyntheticEvent, nodeId: string) => { + const handleSelectNode = (event: SyntheticEvent, nodeId: string | null) => { selectNode(nodeId); }; - const selectNode = (nodeId: string) => { + const selectNode = (nodeId: string | null) => { if (selectedNode !== nodeId) { setSelectedNode(nodeId); - setLogs(allReports.current[nodeId].getAllLogs()); + nodeId && setLogs(allReports.current[nodeId].getAllLogs()); setHighlightedReportId(null); } }; @@ -186,18 +190,20 @@ export default function ReportViewer({ accordingly */} {/*TODO do we need to useMemo/useCallback these props to avoid rerenders ?*/} - } - defaultExpandIcon={} - defaultEndIcon={
} - onNodeToggle={handleToggleNode} - onNodeSelect={handleSelectNode} - selected={selectedNode} - expanded={expandedNodes} + slots={{ + expandIcon: ArrowRightIcon, + collapseIcon: ArrowDropDownIcon, + endIcon: EmptyIcon, + }} + onExpandedItemsChange={handleToggleNode} + onSelectedItemsChange={handleSelectNode} + selectedItems={selectedNode} + expandedItems={expandedNodes} > {treeView.current} - + diff --git a/src/components/TreeViewFinder/TreeViewFinder.tsx b/src/components/TreeViewFinder/TreeViewFinder.tsx index 65229dca..f94489b0 100644 --- a/src/components/TreeViewFinder/TreeViewFinder.tsx +++ b/src/components/TreeViewFinder/TreeViewFinder.tsx @@ -32,7 +32,11 @@ import { ModalProps, } from '@mui/material'; -import { TreeItem, TreeView, TreeViewClasses } from '@mui/x-tree-view'; +import { + TreeItem, + SimpleTreeView, + SimpleTreeViewClasses, +} from '@mui/x-tree-view'; import { Check as CheckIcon, ChevronRight as ChevronRightIcon, @@ -95,7 +99,7 @@ export interface TreeViewFinderProps { selected?: string[]; expanded?: string[]; multiSelect?: boolean; - classes?: Partial; + classes?: Partial; className?: string; // dialog props @@ -299,7 +303,7 @@ const TreeViewFinder = (props: TreeViewFinderProps) => { /* User Interaction management */ const handleNodeSelect = ( _e: React.SyntheticEvent, - values: string | string[] + values: string | string[] | null ) => { // Default management if (multiSelect && Array.isArray(values)) { @@ -309,7 +313,7 @@ const TreeViewFinder = (props: TreeViewFinderProps) => { } else { if (!Array.isArray(values)) { // Toggle selection to allow unselection - if (selected?.includes(values)) { + if (!values || selected?.includes(values)) { setSelected([]); } else { setSelected( @@ -396,22 +400,24 @@ const TreeViewFinder = (props: TreeViewFinderProps) => { return ( - ) : null - } - collapseIcon={ - showChevron(node) ? ( - - ) : null - } + slots={{ + expandIcon: showChevron(node) + ? ChevronRightIcon + : undefined, + collapseIcon: showChevron(node) + ? ExpandMoreIcon + : undefined, + }} + slotProps={{ + expandIcon: { + className: composeClasses(classes, cssIcon), + }, + collapseIcon: { + className: composeClasses(classes, cssIcon), + }, + }} ref={(element) => { if (selectedProp?.includes(node.id)) { scrollRef.current.push(element); @@ -433,12 +439,13 @@ const TreeViewFinder = (props: TreeViewFinderProps) => { if (!multiSelect) { return { multiSelect: false as const, - selected: selected && selected.length > 0 ? selected.at(0) : '', + selectedItems: + selected && selected.length > 0 ? selected.at(0) : '', }; } return { multiSelect: true as const, - selected: selected ?? [], + selectedItems: selected ?? [], }; }; @@ -475,12 +482,12 @@ const TreeViewFinder = (props: TreeViewFinderProps) => { )} - @@ -489,7 +496,7 @@ const TreeViewFinder = (props: TreeViewFinderProps) => { .sort(sortMethod) .map((child) => renderTree(child)) : null} - +