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"