diff --git a/package.json b/package.json index abfd9693..c906052a 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@mui/x-date-pickers": "^7.29.4", - "@nosferatu500/react-sortable-tree": "^3.0.6", + "@mui/x-tree-view": "^8.12.0", "ag-grid-community": "~34.2.0", "ag-grid-react": "~34.2.0", "clsx": "^2.1.1", diff --git a/rollup.config.mjs b/rollup.config.mjs index 63b662d1..a5f56728 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -28,11 +28,7 @@ export default { external: [ 'react', 'react-dom', - 'react-dnd', 'prop-types', - 'react-dnd-html5-backend', - '@nosferatu500/react-dnd-scrollzone', - 'react-virtualized', '@mui/material', '@mui/icons-material', '@mui/styles', diff --git a/src/charts/ScenarioManagerTreeList/ScenarioManagerTreeList.js b/src/charts/ScenarioManagerTreeList/ScenarioManagerTreeList.js index 9ae754fc..283f198b 100644 --- a/src/charts/ScenarioManagerTreeList/ScenarioManagerTreeList.js +++ b/src/charts/ScenarioManagerTreeList/ScenarioManagerTreeList.js @@ -1,7 +1,6 @@ // Copyright (c) Cosmo Tech. // Licensed under the MIT license. -import '@nosferatu500/react-sortable-tree/style.css'; -import React, { useEffect, useMemo, useState, useRef, useReducer } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { UnfoldMore as UnfoldMoreIcon, @@ -13,16 +12,9 @@ import { ScenarioUtils } from '@cosmotech/core'; import { SearchBar } from '../../inputs'; import { FadingTooltip } from '../../misc'; import { ScenarioSortableTree } from './components'; +import { DEFAULT_LABELS } from './labels'; import useStyles from './style'; -const initNodesDict = (scenarios, defaultExpanded) => { - const nodesDict = {}; - scenarios.forEach((scenario) => { - nodesDict[scenario.id] = defaultExpanded; - }); - return nodesDict; -}; - const filterMatchesName = (scenario, searchStr) => scenario.name.toLowerCase().indexOf(searchStr.toLowerCase()) !== -1; const filterMatchesValidationStatus = (labels, scenario, searchStr) => { if (!scenario.validationStatus) return false; @@ -41,47 +33,13 @@ const filterMatchesTag = (scenario, searchString) => const filterMatchesOwner = (scenario, searchString) => scenario.ownerName?.toLowerCase().includes(searchString.toLowerCase()); -const DEFAULT_LABELS = { - status: 'Run status:', - runTemplateLabel: 'Run type:', - successful: 'Successful', - running: 'Running', - dataingestioninprogress: 'Transferring results', - failed: 'Failed', - created: 'Created', - delete: 'Delete this scenario', - edit: 'Edit scenario name', - scenarioRename: { - title: 'Scenario name', - errors: { - emptyScenarioName: 'Scenario name cannot be empty', - forbiddenCharsInScenarioName: - 'Scenario name has to start with a letter, and can only contain ' + - 'letters, digits, spaces, underscores, hyphens and dots.', - }, - }, - deleteDialog: { - description: - 'This operation is irreversible. Dataset(s) will not be removed, but the scenario parameters will be lost. ' + - 'If this scenario has children, they will be moved to a new parent. ' + - 'The new parent will be the parent of the deleted scenario.', - cancel: 'Cancel', - confirm: 'Confirm', - }, - dataset: 'Dataset:', - noDataset: 'None', - datasetNotFound: 'Not Found', - searchField: 'Filter', - toolbar: { - expandAll: 'Expand all', - expandTree: 'Expand tree', - collapseAll: 'Collapse all', - }, - validationStatus: { - rejected: 'Rejected', - validated: 'Validated', - }, -}; +const doesScenarioMatchFilter = (labels, scenario, searchStr) => + filterMatchesName(scenario, searchStr) || + filterMatchesValidationStatus(labels, scenario, searchStr) || + filterMatchesRunStatus(labels, scenario, searchStr) || + filterMatchesDescription(scenario, searchStr) || + filterMatchesTag(scenario, searchStr) || + filterMatchesOwner(scenario, searchStr); export const ScenarioManagerTreeList = (props) => { const classes = useStyles(); @@ -92,12 +50,9 @@ export const ScenarioManagerTreeList = (props) => { deleteScenario, onScenarioRename, checkScenarioNameValue = () => null, - userId, - buildSearchInfo, buildDatasetInfo, labels: tmpLabels, buildScenarioNameToDelete, - showDeleteIcon, canUserDeleteScenario, canUserRenameScenario = () => true, canUpdateScenario, @@ -105,29 +60,14 @@ export const ScenarioManagerTreeList = (props) => { } = props; const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...tmpLabels }), [tmpLabels]); - - if (buildSearchInfo) { - console.warn( - '"buildSearchInfo" prop is deprecated in ScenarioManagerTreeList. Please consider removing this prop.' - ); - } - if (showDeleteIcon != null) { - console.warn( - '"showDeleteIcon" prop is deprecated in ScenarioManagerTreeList. Please use "canUserDeleteScenario" instead.' - ); - } + const allScenarioIds = useMemo(() => scenarios.map((scenario) => scenario.id), [scenarios]); const [searchText, setSearchText] = useState(''); - const nodesExpandedChildren = useRef(initNodesDict(scenarios, true)); - const nodesExpandedDetails = useRef(initNodesDict(scenarios, false)); + const [treeExpandedNodes, setTreeExpandedNodes] = useState(allScenarioIds); + const [detailExpandedNodes, setDetailExpandedNodes] = useState([]); const formatScenariosToScenariosTree = (scenariosToFormat) => { - const scenarioTree = scenariosToFormat.map((scenario) => { - const displayDeleteIcon = - canUserDeleteScenario != null - ? canUserDeleteScenario(scenario) - : showDeleteIcon !== false && scenario.ownerId === userId; - + const scenarioList = scenariosToFormat.map((scenario) => { labels.dataset = buildDatasetInfo(scenario.datasetList); return { @@ -137,7 +77,7 @@ export const ScenarioManagerTreeList = (props) => { scenarioNodeProps: { datasets, scenario, - showDeleteIcon: displayDeleteIcon, + showDeleteIcon: canUserDeleteScenario(scenario), onScenarioRedirect, deleteScenario, checkScenarioNameValue, @@ -150,7 +90,7 @@ export const ScenarioManagerTreeList = (props) => { }, }; }); - return ScenarioUtils.getScenarioTree(scenarioTree, (scenA, scenB) => scenA.name.localeCompare(scenB.name)); + return ScenarioUtils.getScenarioTree(scenarioList, (scenA, scenB) => scenA.name.localeCompare(scenB.name)); }; const scenarioTreeFull = useMemo( @@ -167,22 +107,17 @@ export const ScenarioManagerTreeList = (props) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [scenarios, searchText, labels]); - const [refreshTick, forceRefresh] = useReducer((x) => x + 1, 0); - const collapseAll = () => { - nodesExpandedChildren.current = initNodesDict(scenarios, false); - nodesExpandedDetails.current = initNodesDict(scenarios, false); - forceRefresh(); + setTreeExpandedNodes([]); + setDetailExpandedNodes([]); }; const expandTree = () => { - nodesExpandedChildren.current = initNodesDict(scenarios, true); - nodesExpandedDetails.current = initNodesDict(scenarios, false); - forceRefresh(); + setTreeExpandedNodes(allScenarioIds); + setDetailExpandedNodes([]); }; const expandAll = () => { - nodesExpandedChildren.current = initNodesDict(scenarios, true); - nodesExpandedDetails.current = initNodesDict(scenarios, true); - forceRefresh(); + setTreeExpandedNodes(allScenarioIds); + setDetailExpandedNodes(allScenarioIds); }; const filterScenarios = (searchStr) => { @@ -192,15 +127,7 @@ export const ScenarioManagerTreeList = (props) => { return; } // Otherwise, filter scenarios based on their name - const filtered = scenarios.filter( - (scenario) => - filterMatchesName(scenario, searchStr) || - filterMatchesValidationStatus(labels, scenario, searchStr) || - filterMatchesRunStatus(labels, scenario, searchStr) || - filterMatchesDescription(scenario, searchStr) || - filterMatchesTag(scenario, searchStr) || - filterMatchesOwner(scenario, searchStr) - ); + const filtered = scenarios.filter((scenario) => doesScenarioMatchFilter(labels, scenario, searchStr)); // Format list and set as tree data setScenariosTree(formatScenariosToScenariosTree(filtered)); }; @@ -233,15 +160,16 @@ export const ScenarioManagerTreeList = (props) => {
- {scenariosTree.map((scenarioTree) => { + {scenariosTree.map((rootScenario) => { return ( ); })} @@ -279,25 +207,10 @@ ScenarioManagerTreeList.propTypes = { * Function bound to handle a scenario movement (moving a scenario = changing its parent) */ moveScenario: PropTypes.func.isRequired, - /** - * Current user id - */ - userId: PropTypes.string.isRequired, - /** - * DEPRECATED: Function building scenario search label - */ - buildSearchInfo: PropTypes.func, /** * Function building scenario dataset label */ buildDatasetInfo: PropTypes.func.isRequired, - /** - * DEPRECATED: this prop is deprecated, use 'canUserDeleteScenario' instead - * Boolean value to define whether scenario delete buttons must be shown in ScenarioNode elements: - * - false: delete buttons are always hidden - * - true: delete buttons are shown if the user id matches the scenario owner id - */ - showDeleteIcon: PropTypes.bool, /** * Function returning whether the current user can delete a given scenario. This function receives as parameter * the scenario data and must return a boolean. diff --git a/src/charts/ScenarioManagerTreeList/components/ScenarioSortableTree/ScenarioSortableTree.js b/src/charts/ScenarioManagerTreeList/components/ScenarioSortableTree/ScenarioSortableTree.js index 98d6b311..56f7645d 100644 --- a/src/charts/ScenarioManagerTreeList/components/ScenarioSortableTree/ScenarioSortableTree.js +++ b/src/charts/ScenarioManagerTreeList/components/ScenarioSortableTree/ScenarioSortableTree.js @@ -1,91 +1,82 @@ // Copyright (c) Cosmo Tech. // Licensed under the MIT license. -import SortableTree from '@nosferatu500/react-sortable-tree'; -import React, { useEffect, useState, useRef } from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { Paper } from '@mui/material'; +import { styled } from '@mui/material/styles'; +import { SimpleTreeView, TreeItem, treeItemClasses } from '@mui/x-tree-view'; import clsx from 'clsx'; import { ScenarioNode } from '../../../../cards'; -import { SHRUNK_NODE_HEIGHT, EXPANDED_NODE_HEIGHT } from '../../../../cards/ScenarioNode/constants'; + +const CustomTreeItem = styled(TreeItem)(({ theme }) => ({ + [`& .${treeItemClasses.content}`]: { + borderRadius: theme.spacing(0.5), + padding: theme.spacing(0.5, 1), + margin: theme.spacing(0.2, 0), + [`& .${treeItemClasses.label}`]: { + fontSize: '0.8rem', + fontWeight: 500, + }, + }, + [`& .${treeItemClasses.groupTransition}`]: { + marginLeft: 15, + paddingLeft: theme.spacing(2), + borderLeft: `1px dashed ${theme.palette.text.primary}`, + }, + ...theme.applyStyles('light', { + color: theme.palette.grey[800], + }), +})); + +// Ignore MUI events in the MUI tree items to prevent keyboard navigation based on scenario names (this feature breaks +// input fields in the scenario node cards, plus the scenario manager view renders several trees, which means users +// can't navigate to all scenarios with only keyboard anyway) +const ignoreMuiEvents = (event) => (event.defaultMuiPrevented = true); export const ScenarioSortableTree = ({ - nodesExpandedChildrenRef, - nodesExpandedDetailsRef, + treeExpandedNodes, + setTreeExpandedNodes, + detailExpandedNodes, + setDetailExpandedNodes, scenarioTree, classes, - refreshTick, }) => { - const [nodesExpandedChildren, setNodesExpandedChildren] = useState(nodesExpandedChildrenRef.current); - const [nodesExpandedDetails, setNodesExpandedDetails] = useState(nodesExpandedDetailsRef.current); - - const changeNodesExpandedChildren = ({ node, expanded }) => { - const newValue = { - ...nodesExpandedChildrenRef.current, - [node.id]: expanded, - }; - nodesExpandedChildrenRef.current = newValue; - setNodesExpandedChildren(newValue); - }; - - const changeNodesExpandedDetails = (scenarioId, expanded) => { - const newValue = { - ...nodesExpandedDetailsRef.current, - [scenarioId]: expanded, - }; - nodesExpandedDetailsRef.current = newValue; - setNodesExpandedDetails(newValue); + const toggleNodeAccordionState = (scenarioId, newIsExpanded) => { + if (newIsExpanded) setDetailExpandedNodes((prevNodeIds) => [...prevNodeIds, scenarioId]); + else setDetailExpandedNodes((prevNodeIds) => prevNodeIds.filter((nodeId) => nodeId !== scenarioId)); }; const formatScenarioTreeNodeToRtsNode = (scenarioTreeNode) => { - const { scenarioNodeProps, children: treeNodeChildren, ...rtsScenario } = scenarioTreeNode; + const { scenarioNodeProps, children: treeNodeChildren } = scenarioTreeNode; - rtsScenario.expanded = nodesExpandedChildren[rtsScenario.id]; - rtsScenario.expandedDetail = nodesExpandedDetails[rtsScenario.id]; - rtsScenario.title = ( + const itemId = scenarioTreeNode.id; + const itemLabel = ( changeNodesExpandedDetails(rtsScenario.id, newIsExpanded)} + isExpanded={detailExpandedNodes.includes(itemId)} + setIsExpanded={(newIsExpanded) => toggleNodeAccordionState(itemId, newIsExpanded)} {...scenarioNodeProps} /> ); if (treeNodeChildren && treeNodeChildren.length > 0) { - rtsScenario.children = treeNodeChildren.map((treeNodeChild) => formatScenarioTreeNodeToRtsNode(treeNodeChild)); + const children = treeNodeChildren.map((treeNodeChild) => formatScenarioTreeNodeToRtsNode(treeNodeChild)); + + return ( + + {children} + + ); } - return rtsScenario; + return ; }; - const [treeData, setTreeData] = useState(formatScenarioTreeNodeToRtsNode(scenarioTree)); - - const updateTreeData = () => { - setTreeData(formatScenarioTreeNodeToRtsNode(scenarioTree)); - }; + const [treeData, setTreeData] = useState([formatScenarioTreeNodeToRtsNode(scenarioTree)]); - const refreshTickOnLoad = useRef(refreshTick); useEffect(() => { - // prevent double render on load - if (refreshTick !== refreshTickOnLoad.current) { - setNodesExpandedChildren(nodesExpandedChildrenRef.current); - setNodesExpandedDetails(nodesExpandedDetailsRef.current); - } + setTreeData([formatScenarioTreeNodeToRtsNode(scenarioTree)]); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [refreshTick]); - - useEffect(() => { - updateTreeData(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [scenarioTree, nodesExpandedChildren, nodesExpandedDetails]); - - const generateNodeProps = () => { - return { - className: classes.scenarioCard, - }; - }; - - const ignoreEvent = (event) => { - event.preventDefault(); - }; + }, [scenarioTree, detailExpandedNodes]); return ( - node.id} - onVisibilityToggle={changeNodesExpandedChildren} - canDrag={false} - onChange={() => null} - canDrop={() => false} - isVirtualized={false} // Required to prevent bug when rowHeight is a function - rowHeight={({ treeIndex, node, path }) => { - return 12 + (node.expandedDetail ? EXPANDED_NODE_HEIGHT : SHRUNK_NODE_HEIGHT); - }} - /> + setTreeExpandedNodes(itemIds)} + expansionTrigger="iconContainer" + > + {treeData} + ); }; ScenarioSortableTree.propTypes = { /** - * react ref object contains all nodes with children expended + * array of ids of the scenarios with children tree collapsed */ - nodesExpandedChildrenRef: PropTypes.shape({ current: PropTypes.any }).isRequired, + treeExpandedNodes: PropTypes.array.isRequired, + setTreeExpandedNodes: PropTypes.func.isRequired, /** - * react ref object contains all nodes details expended + * array of ids of the scenarios with accordion details expanded */ - nodesExpandedDetailsRef: PropTypes.shape({ current: PropTypes.any }).isRequired, + detailExpandedNodes: PropTypes.array.isRequired, + setDetailExpandedNodes: PropTypes.func.isRequired, /** * classes for styles */ @@ -131,8 +116,4 @@ ScenarioSortableTree.propTypes = { * tree of scenario */ scenarioTree: PropTypes.object.isRequired, - /** - * a refresh tick number for force tree to refresh by refs values - */ - refreshTick: PropTypes.number.isRequired, }; diff --git a/src/charts/ScenarioManagerTreeList/labels.js b/src/charts/ScenarioManagerTreeList/labels.js new file mode 100644 index 00000000..517706db --- /dev/null +++ b/src/charts/ScenarioManagerTreeList/labels.js @@ -0,0 +1,44 @@ +// Copyright (c) Cosmo Tech. +// Licensed under the MIT license. + +export const DEFAULT_LABELS = { + status: 'Run status:', + runTemplateLabel: 'Run type:', + successful: 'Successful', + running: 'Running', + dataingestioninprogress: 'Transferring results', + failed: 'Failed', + created: 'Created', + delete: 'Delete this scenario', + edit: 'Edit scenario name', + scenarioRename: { + title: 'Scenario name', + errors: { + emptyScenarioName: 'Scenario name cannot be empty', + forbiddenCharsInScenarioName: + 'Scenario name has to start with a letter, and can only contain ' + + 'letters, digits, spaces, underscores, hyphens and dots.', + }, + }, + deleteDialog: { + description: + 'This operation is irreversible. Dataset(s) will not be removed, but the scenario parameters will be lost. ' + + 'If this scenario has children, they will be moved to a new parent. ' + + 'The new parent will be the parent of the deleted scenario.', + cancel: 'Cancel', + confirm: 'Confirm', + }, + dataset: 'Dataset:', + noDataset: 'None', + datasetNotFound: 'Not Found', + searchField: 'Filter', + toolbar: { + expandAll: 'Expand all', + expandTree: 'Expand tree', + collapseAll: 'Collapse all', + }, + validationStatus: { + rejected: 'Rejected', + validated: 'Validated', + }, +}; diff --git a/yarn.lock b/yarn.lock index ccfb6a39..e1743f52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1658,7 +1658,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.7": version: 7.24.4 resolution: "@babel/runtime@npm:7.24.4" dependencies: @@ -1683,6 +1683,13 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.28.2, @babel/runtime@npm:^7.28.3": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 10c0/792ce7af9750fb9b93879cc9d1db175701c4689da890e6ced242ea0207c9da411ccf16dc04e689cc01158b28d7898c40d75598f4559109f761c12ce01e959bf7 + languageName: node + linkType: hard + "@babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0": version: 7.24.0 resolution: "@babel/template@npm:7.24.0" @@ -1795,6 +1802,25 @@ __metadata: languageName: node linkType: hard +"@base-ui-components/utils@npm:0.1.1": + version: 0.1.1 + resolution: "@base-ui-components/utils@npm:0.1.1" + dependencies: + "@babel/runtime": "npm:^7.28.3" + "@floating-ui/utils": "npm:^0.2.10" + reselect: "npm:^5.1.1" + use-sync-external-store: "npm:^1.5.0" + peerDependencies: + "@types/react": ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/1f6dc33f8dd7544f1d84cff61dbbe24c32e0279d77a7ce34cada97e6279420c2789d4ec92f8d41507cd1cc5fb492eea03fc33fc645ebede3d5063cbc1e721e0c + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -1845,7 +1871,7 @@ __metadata: "@mui/material": "npm:^6.5.0" "@mui/styles": "npm:^6.5.0" "@mui/x-date-pickers": "npm:^7.29.4" - "@nosferatu500/react-sortable-tree": "npm:^3.0.6" + "@mui/x-tree-view": "npm:^8.12.0" "@rollup/plugin-babel": "npm:^6.0.4" "@rollup/plugin-commonjs": "npm:^28.0.6" "@rollup/plugin-image": "npm:^3.0.3" @@ -2329,6 +2355,13 @@ __metadata: languageName: node linkType: hard +"@floating-ui/utils@npm:^0.2.10": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: 10c0/e9bc2a1730ede1ee25843937e911ab6e846a733a4488623cd353f94721b05ec2c9ec6437613a2ac9379a94c2fd40c797a2ba6fa1df2716f5ce4aa6ddb1cf9ea4 + languageName: node + linkType: hard + "@humanfs/core@npm:^0.19.1": version: 0.19.1 resolution: "@humanfs/core@npm:0.19.1" @@ -3091,6 +3124,20 @@ __metadata: languageName: node linkType: hard +"@mui/types@npm:^7.4.6": + version: 7.4.6 + resolution: "@mui/types@npm:7.4.6" + dependencies: + "@babel/runtime": "npm:^7.28.3" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/baa901e410591d0216b3f959cdbf5a1ee2ce560726d2fba1c700b40f64c1be3e63bd799f1b30a7d0bc8cc45a46d782928ea28d9906d64438f21e305884c48a99 + languageName: node + linkType: hard + "@mui/types@npm:~7.2.24": version: 7.2.24 resolution: "@mui/types@npm:7.2.24" @@ -3161,6 +3208,26 @@ __metadata: languageName: node linkType: hard +"@mui/utils@npm:^7.3.2": + version: 7.3.2 + resolution: "@mui/utils@npm:7.3.2" + dependencies: + "@babel/runtime": "npm:^7.28.3" + "@mui/types": "npm:^7.4.6" + "@types/prop-types": "npm:^15.7.15" + clsx: "npm:^2.1.1" + prop-types: "npm:^15.8.1" + react-is: "npm:^19.1.1" + 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 + checksum: 10c0/5a88ff08a823b976421f8d61098d56d527d95c222800d5b3f71acff795e7b0db6b02e40228773a6ed7ee22d8eaa607d816215b5a4b6497c21aaa9668c2699b56 + languageName: node + linkType: hard + "@mui/x-date-pickers@npm:^7.29.4": version: 7.29.4 resolution: "@mui/x-date-pickers@npm:7.29.4" @@ -3221,6 +3288,48 @@ __metadata: languageName: node linkType: hard +"@mui/x-internals@npm:8.12.0": + version: 8.12.0 + resolution: "@mui/x-internals@npm:8.12.0" + dependencies: + "@babel/runtime": "npm:^7.28.2" + "@mui/utils": "npm:^7.3.2" + reselect: "npm:^5.1.1" + use-sync-external-store: "npm:^1.5.0" + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/6a81bdc2cedaa2ddde2df7eb76378d7665e925090cd88905908cb02451db105e5225619b827741e3e6686c5b79c56a7a65e077736fffa754e8fd5b866f4081df + languageName: node + linkType: hard + +"@mui/x-tree-view@npm:^8.12.0": + version: 8.12.0 + resolution: "@mui/x-tree-view@npm:8.12.0" + dependencies: + "@babel/runtime": "npm:^7.28.2" + "@base-ui-components/utils": "npm:0.1.1" + "@mui/utils": "npm:^7.3.2" + "@mui/x-internals": "npm:8.12.0" + "@types/react-transition-group": "npm:^4.4.12" + clsx: "npm:^2.1.1" + prop-types: "npm:^15.8.1" + react-transition-group: "npm:^4.4.5" + peerDependencies: + "@emotion/react": ^11.9.0 + "@emotion/styled": ^11.8.1 + "@mui/material": ^5.15.14 || ^6.0.0 || ^7.0.0 + "@mui/system": ^5.15.14 || ^6.0.0 || ^7.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 10c0/d286f4780963b90fd385f42979917c7c01beaad72ecb78045c20f3873ca4ae64d5ce3cbb080fcbbfe5dc665a36b3c026f6a35eeede1f895e47fe7a4255334ed2 + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:^0.2.11": version: 0.2.12 resolution: "@napi-rs/wasm-runtime@npm:0.2.12" @@ -3266,42 +3375,6 @@ __metadata: languageName: node linkType: hard -"@nosferatu500/react-dnd-scrollzone@npm:^1.0.14": - version: 1.0.14 - resolution: "@nosferatu500/react-dnd-scrollzone@npm:1.0.14" - dependencies: - hoist-non-react-statics: "npm:^3.3.2" - lodash.throttle: "npm:^4.1.1" - prop-types: "npm:^15.7.2" - raf: "npm:^3.4.1" - react-display-name: "npm:^0.2.5" - peerDependencies: - react: ^17.0.2 - react-dnd: ^11.1.3 - react-dom: ^17.0.2 - checksum: 10c0/045842dfc6c2f1502e7c5b015c13d3e388530ad21c0cd99babdc00ef7438d6caab201fa4537c917f8ee09f1b5a91220d2bde5d867f418fc2f627be88659e50b0 - languageName: node - linkType: hard - -"@nosferatu500/react-sortable-tree@npm:^3.0.6": - version: 3.0.6 - resolution: "@nosferatu500/react-sortable-tree@npm:3.0.6" - dependencies: - "@nosferatu500/react-dnd-scrollzone": "npm:^1.0.14" - lodash.isequal: "npm:^4.5.0" - prop-types: "npm:^15.7.2" - react-dnd: "npm:^14.0.2" - react-dnd-html5-backend: "npm:^14.0.0" - react-lifecycles-compat: "npm:^3.0.4" - react-virtualized: "npm:^9.22.3" - peerDependencies: - react: ^17.0.0 - react-dnd: ^11.1.3 - react-dom: ^17.0.0 - checksum: 10c0/006a4edfd51c6b8000b4023cf151148b166a71650018ff92c5ff1213eeecbfdca440ef8f75552fdda9383dc45f6e9adc4b7d7b599a230b88ed0567958203866f - languageName: node - linkType: hard - "@npmcli/agent@npm:^2.0.0": version: 2.2.2 resolution: "@npmcli/agent@npm:2.2.2" @@ -3352,27 +3425,6 @@ __metadata: languageName: node linkType: hard -"@react-dnd/asap@npm:^4.0.0": - version: 4.0.1 - resolution: "@react-dnd/asap@npm:4.0.1" - checksum: 10c0/9e78ea5a281c87c35f08839d100f0fddf6001f37da2366ff6d8ea0f426302e213675fe7f70825660603cc8bc81e41768bd18000df966564787fd64d7c4478c7c - languageName: node - linkType: hard - -"@react-dnd/invariant@npm:^2.0.0": - version: 2.0.0 - resolution: "@react-dnd/invariant@npm:2.0.0" - checksum: 10c0/32219873b096a4bc6bfab9e9ca3007f90770ad4365deee2277eed303413f9936fd828ec46884aae31267df8dde16edf9bffc99c149a38b0fee829380670fadef - languageName: node - linkType: hard - -"@react-dnd/shallowequal@npm:^2.0.0": - version: 2.0.0 - resolution: "@react-dnd/shallowequal@npm:2.0.0" - checksum: 10c0/3251e70e2575d18aaadf995066341c04ed6a1e692895fa71a925fd34daaeca294e7565daf9151dee7fd992de65ed36ba75517c73bc504ddd0d0adfdc59854cc4 - languageName: node - linkType: hard - "@rollup/plugin-babel@npm:^6.0.4": version: 6.0.4 resolution: "@rollup/plugin-babel@npm:6.0.4" @@ -5152,13 +5204,6 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.0.4": - version: 1.2.1 - resolution: "clsx@npm:1.2.1" - checksum: 10c0/34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27 - languageName: node - linkType: hard - "clsx@npm:^2.1.0": version: 2.1.0 resolution: "clsx@npm:2.1.0" @@ -5752,17 +5797,6 @@ __metadata: languageName: node linkType: hard -"dnd-core@npm:14.0.1": - version: 14.0.1 - resolution: "dnd-core@npm:14.0.1" - dependencies: - "@react-dnd/asap": "npm:^4.0.0" - "@react-dnd/invariant": "npm:^2.0.0" - redux: "npm:^4.1.1" - checksum: 10c0/449c5b7101003937e1aff3bbdb4e2deb6cd59f235a43f3e5e0d82ced5d3c982038cde00bf211d5ce6a263b3a7705fa231e9019431b890a80cc9a78be154fadee - languageName: node - linkType: hard - "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -5786,7 +5820,7 @@ __metadata: languageName: node linkType: hard -"dom-helpers@npm:^5.0.1, dom-helpers@npm:^5.1.3": +"dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" dependencies: @@ -9888,13 +9922,6 @@ __metadata: languageName: node linkType: hard -"performance-now@npm:^2.1.0": - version: 2.1.0 - resolution: "performance-now@npm:2.1.0" - checksum: 10c0/22c54de06f269e29f640e0e075207af57de5052a3d15e360c09b9a8663f393f6f45902006c1e71aa8a5a1cdfb1a47fe268826f8496d6425c362f00f5bc3e85d9 - languageName: node - linkType: hard - "picocolors@npm:1.1.1, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -10492,7 +10519,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -10524,15 +10551,6 @@ __metadata: languageName: node linkType: hard -"raf@npm:^3.4.1": - version: 3.4.1 - resolution: "raf@npm:3.4.1" - dependencies: - performance-now: "npm:^2.1.0" - checksum: 10c0/337f0853c9e6a77647b0f499beedafea5d6facfb9f2d488a624f88b03df2be72b8a0e7f9118a3ff811377d534912039a3311815700d2b6d2313f82f736f9eb6e - languageName: node - linkType: hard - "react-cytoscapejs@npm:^2.0.0": version: 2.0.0 resolution: "react-cytoscapejs@npm:2.0.0" @@ -10545,47 +10563,6 @@ __metadata: languageName: node linkType: hard -"react-display-name@npm:^0.2.5": - version: 0.2.5 - resolution: "react-display-name@npm:0.2.5" - checksum: 10c0/9c598283f2a545c01ba7fc81409b3fcd528d91925872e4033ffc51a9f675a3006acb9ec056877cc4fc0a9516cf7a769eb9c9e51dba6be1ff8d7dbd516dac397a - languageName: node - linkType: hard - -"react-dnd-html5-backend@npm:^14.0.0": - version: 14.1.0 - resolution: "react-dnd-html5-backend@npm:14.1.0" - dependencies: - dnd-core: "npm:14.0.1" - checksum: 10c0/d10327fc72147250b0e93876b773a2843b60586299dbbc415e045f2e86dd931c5ffc5b2056bb99aa900af1d54a7306b4f28aab30ce5b7297a71da15e41c89d37 - languageName: node - linkType: hard - -"react-dnd@npm:^14.0.2": - version: 14.0.5 - resolution: "react-dnd@npm:14.0.5" - dependencies: - "@react-dnd/invariant": "npm:^2.0.0" - "@react-dnd/shallowequal": "npm:^2.0.0" - dnd-core: "npm:14.0.1" - fast-deep-equal: "npm:^3.1.3" - hoist-non-react-statics: "npm:^3.3.2" - peerDependencies: - "@types/hoist-non-react-statics": ">= 3.3.1" - "@types/node": ">= 12" - "@types/react": ">= 16" - react: ">= 16.14" - peerDependenciesMeta: - "@types/hoist-non-react-statics": - optional: true - "@types/node": - optional: true - "@types/react": - optional: true - checksum: 10c0/8785299e8aaf8d358ddbc68518206c6733855ae883e95e5c2ff74f36328c4a7dad8b796b614d7ef0d62a77b15656d80c145f7c1c0f1d6928d86e5ac18cc6f8b6 - languageName: node - linkType: hard - "react-dom@npm:^18.3.1": version: 18.3.1 resolution: "react-dom@npm:18.3.1" @@ -10654,10 +10631,10 @@ __metadata: languageName: node linkType: hard -"react-lifecycles-compat@npm:^3.0.4": - version: 3.0.4 - resolution: "react-lifecycles-compat@npm:3.0.4" - checksum: 10c0/1d0df3c85af79df720524780f00c064d53a9dd1899d785eddb7264b378026979acbddb58a4b7e06e7d0d12aa1494fd5754562ee55d32907b15601068dae82c27 +"react-is@npm:^19.1.1": + version: 19.1.1 + resolution: "react-is@npm:19.1.1" + checksum: 10c0/3dba763fcd69835ae263dcd6727d7ffcc44c1d616f04b7329e67aefdc66a567af4f8dcecdd29454c7a707c968aa1eb85083a83fb616f01675ef25e71cf082f97 languageName: node linkType: hard @@ -10699,23 +10676,6 @@ __metadata: languageName: node linkType: hard -"react-virtualized@npm:^9.22.3": - version: 9.22.5 - resolution: "react-virtualized@npm:9.22.5" - dependencies: - "@babel/runtime": "npm:^7.7.2" - clsx: "npm:^1.0.4" - dom-helpers: "npm:^5.1.3" - loose-envify: "npm:^1.4.0" - prop-types: "npm:^15.7.2" - react-lifecycles-compat: "npm:^3.0.4" - peerDependencies: - react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 - react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 - checksum: 10c0/b0444b472f317dce61119c07426c5e9ebfe5125d049996678da922717715a1aa83df755aa36877f4b1718aa2e181d22f15ebb807ee356418c56f922f865628c1 - languageName: node - linkType: hard - "react@npm:^18.3.1": version: 18.3.1 resolution: "react@npm:18.3.1" @@ -10735,15 +10695,6 @@ __metadata: languageName: node linkType: hard -"redux@npm:^4.1.1": - version: 4.2.1 - resolution: "redux@npm:4.2.1" - dependencies: - "@babel/runtime": "npm:^7.9.2" - checksum: 10c0/136d98b3d5dbed1cd6279c8c18a6a74c416db98b8a432a46836bdd668475de6279a2d4fd9d1363f63904e00f0678a8a3e7fa532c897163340baf1e71bb42c742 - languageName: node - linkType: hard - "reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": version: 1.0.10 resolution: "reflect.getprototypeof@npm:1.0.10" @@ -10896,6 +10847,13 @@ __metadata: languageName: node linkType: hard +"reselect@npm:^5.1.1": + version: 5.1.1 + resolution: "reselect@npm:5.1.1" + checksum: 10c0/219c30da122980f61853db3aebd173524a2accd4b3baec770e3d51941426c87648a125ca08d8c57daa6b8b086f2fdd2703cb035dd6231db98cdbe1176a71f489 + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -12371,6 +12329,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.5.0": + version: 1.5.0 + resolution: "use-sync-external-store@npm:1.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/1b8663515c0be34fa653feb724fdcce3984037c78dd4a18f68b2c8be55cc1a1084c578d5b75f158d41b5ddffc2bf5600766d1af3c19c8e329bb20af2ec6f52f4 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.2": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2"