@itwin/presentation-hierarchies-react 2.0.0-alpha.6 → 2.0.0-alpha.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1151 -11
- package/README.md +93 -160
- package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts +49 -0
- package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/FlatTreeNode.js +96 -0
- package/lib/presentation-hierarchies-react/FlatTreeNode.js.map +1 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.d.ts +24 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.js +40 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.js.map +1 -0
- package/lib/presentation-hierarchies-react/Renderers.d.ts +92 -0
- package/lib/presentation-hierarchies-react/Renderers.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/TreeNode.d.ts +80 -0
- package/lib/presentation-hierarchies-react/TreeNode.d.ts.map +1 -0
- package/lib/{esm/presentation-hierarchies-react → presentation-hierarchies-react}/UseIModelTree.d.ts +28 -15
- package/lib/presentation-hierarchies-react/UseIModelTree.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseIModelTree.js +183 -0
- package/lib/presentation-hierarchies-react/UseIModelTree.js.map +1 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.d.ts +30 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.js +57 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.js.map +1 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.d.ts +23 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.js +124 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.js.map +1 -0
- package/lib/presentation-hierarchies-react/UseTree.d.ts +112 -0
- package/lib/presentation-hierarchies-react/UseTree.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseTree.js +298 -0
- package/lib/presentation-hierarchies-react/UseTree.js.map +1 -0
- package/lib/presentation-hierarchies-react/Utils.js +56 -0
- package/lib/presentation-hierarchies-react/Utils.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/DisposePolyfill.js +10 -0
- package/lib/presentation-hierarchies-react/internal/DisposePolyfill.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.d.ts +9 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.js +12 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeActions.js +294 -0
- package/lib/presentation-hierarchies-react/internal/TreeActions.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeLoader.js +98 -0
- package/lib/presentation-hierarchies-react/internal/TreeLoader.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeModel.d.ts +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeModel.js +115 -0
- package/lib/presentation-hierarchies-react/internal/TreeModel.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +35 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js +141 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/Utils.js +42 -0
- package/lib/presentation-hierarchies-react/internal/Utils.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts +40 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js +387 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts +21 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js +185 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.d.ts +49 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.js +88 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts +38 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js +77 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts +29 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js +91 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts +31 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js +155 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.css +25 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts +14 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js +540 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts +75 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.js +417 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react-extract.d.ts +17 -0
- package/lib/presentation-hierarchies-react-extract.js +16 -0
- package/lib/presentation-hierarchies-react-stratakit.d.ts +8 -0
- package/lib/presentation-hierarchies-react-stratakit.js +8 -0
- package/lib/presentation-hierarchies-react.d.ts +11 -0
- package/lib/presentation-hierarchies-react.js +8 -0
- package/lib/public/locales/en/PresentationHierarchies_1.0.json +26 -0
- package/package.json +78 -56
- package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts +0 -75
- package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/TreeNode.js +0 -12
- package/lib/esm/presentation-hierarchies-react/TreeNode.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts +0 -15
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js +0 -22
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.js +0 -62
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts +0 -46
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js +0 -98
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts +0 -132
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.js +0 -242
- package/lib/esm/presentation-hierarchies-react/UseTree.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.d.ts +0 -2
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.js +0 -11
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts +0 -53
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js +0 -307
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts +0 -44
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js +0 -94
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts +0 -70
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js +0 -153
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +0 -28
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js +0 -128
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/Utils.d.ts +0 -23
- package/lib/esm/presentation-hierarchies-react/internal/Utils.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/Utils.js +0 -58
- package/lib/esm/presentation-hierarchies-react/internal/Utils.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.d.ts +0 -21
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.js +0 -30
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts +0 -73
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js +0 -34
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts +0 -25
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js +0 -40
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts +0 -23
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js +0 -72
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts +0 -40
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js +0 -80
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts +0 -30
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js +0 -48
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react.d.ts +0 -13
- package/lib/esm/presentation-hierarchies-react.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react.js +0 -16
- package/lib/esm/presentation-hierarchies-react.js.map +0 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
//#region src/presentation-hierarchies-react/internal/TreeModel.ts
|
|
2
|
+
let TreeModel;
|
|
3
|
+
(function(_TreeModel) {
|
|
4
|
+
function expandNode(model, nodeId, isExpanded) {
|
|
5
|
+
const node = model.idToNode.get(nodeId);
|
|
6
|
+
if (!node) return "none";
|
|
7
|
+
node.isExpanded = isExpanded;
|
|
8
|
+
if (!isExpanded) return "none";
|
|
9
|
+
if (node.error?.type === "ChildrenLoad") {
|
|
10
|
+
node.isLoading = true;
|
|
11
|
+
TreeModel.removeSubTree(model, nodeId);
|
|
12
|
+
return "reloadChildren";
|
|
13
|
+
}
|
|
14
|
+
if (!node.children) return "none";
|
|
15
|
+
if (!model.parentChildMap.get(node.id)) {
|
|
16
|
+
node.isLoading = true;
|
|
17
|
+
return "loadChildren";
|
|
18
|
+
}
|
|
19
|
+
return "none";
|
|
20
|
+
}
|
|
21
|
+
_TreeModel.expandNode = expandNode;
|
|
22
|
+
function addHierarchyPart(model, rootId, hierarchyPart) {
|
|
23
|
+
removeSubTree(model, rootId);
|
|
24
|
+
model.rootNode.error = hierarchyPart.rootNode.error;
|
|
25
|
+
for (const [parentId, children] of hierarchyPart.parentChildMap) model.parentChildMap.set(parentId, children);
|
|
26
|
+
for (const [nodeId, node] of hierarchyPart.idToNode) model.idToNode.set(nodeId, node);
|
|
27
|
+
const parentNode = rootId !== void 0 ? model.idToNode.get(rootId) : model.rootNode;
|
|
28
|
+
/* c8 ignore next 3*/
|
|
29
|
+
if (!parentNode) return;
|
|
30
|
+
parentNode.isLoading = false;
|
|
31
|
+
}
|
|
32
|
+
_TreeModel.addHierarchyPart = addHierarchyPart;
|
|
33
|
+
function removeSubTree(model, parentId) {
|
|
34
|
+
clearNodeError(model, parentId);
|
|
35
|
+
const currentChildren = model.parentChildMap.get(parentId);
|
|
36
|
+
if (!currentChildren) return;
|
|
37
|
+
model.parentChildMap.delete(parentId);
|
|
38
|
+
for (const childId of currentChildren) {
|
|
39
|
+
const childNode = model.idToNode.get(childId);
|
|
40
|
+
if (childNode) removeSubTree(model, childNode.id);
|
|
41
|
+
model.idToNode.delete(childId);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
_TreeModel.removeSubTree = removeSubTree;
|
|
45
|
+
function setHierarchyLimit(model, nodeId, limit) {
|
|
46
|
+
return updateForReload(model, nodeId, (node) => {
|
|
47
|
+
node.hierarchyLimit = limit;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
_TreeModel.setHierarchyLimit = setHierarchyLimit;
|
|
51
|
+
function setInstanceFilter(model, nodeId, filter) {
|
|
52
|
+
return updateForReload(model, nodeId, (node) => {
|
|
53
|
+
if (filter && node.id !== void 0) node.isExpanded = true;
|
|
54
|
+
node.instanceFilter = filter;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
_TreeModel.setInstanceFilter = setInstanceFilter;
|
|
58
|
+
function selectNodes(model, nodeIds, changeType) {
|
|
59
|
+
if (changeType === "replace") {
|
|
60
|
+
for (const [nodeId, node] of model.idToNode) node.isSelected = !!nodeIds.find((id) => id === nodeId);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
for (const nodeId of nodeIds) {
|
|
64
|
+
const modelNode = model.idToNode.get(nodeId);
|
|
65
|
+
if (!modelNode) return;
|
|
66
|
+
modelNode.isSelected = changeType === "add";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
_TreeModel.selectNodes = selectNodes;
|
|
70
|
+
function isNodeSelected(model, nodeId) {
|
|
71
|
+
const currentNode = model.idToNode.get(nodeId);
|
|
72
|
+
return !!currentNode && !!currentNode.isSelected;
|
|
73
|
+
}
|
|
74
|
+
_TreeModel.isNodeSelected = isNodeSelected;
|
|
75
|
+
function getNode(model, nodeId) {
|
|
76
|
+
if (!nodeId) return model.rootNode;
|
|
77
|
+
return model.idToNode.get(nodeId);
|
|
78
|
+
}
|
|
79
|
+
_TreeModel.getNode = getNode;
|
|
80
|
+
function setIsLoading(model, nodeId, isLoading) {
|
|
81
|
+
if (nodeId === void 0) {
|
|
82
|
+
model.rootNode.isLoading = isLoading;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const modelNode = model.idToNode.get(nodeId);
|
|
86
|
+
/* c8 ignore next 3*/
|
|
87
|
+
if (!modelNode) return;
|
|
88
|
+
modelNode.isLoading = isLoading;
|
|
89
|
+
}
|
|
90
|
+
_TreeModel.setIsLoading = setIsLoading;
|
|
91
|
+
})(TreeModel || (TreeModel = {}));
|
|
92
|
+
function updateForReload(model, nodeId, update) {
|
|
93
|
+
TreeModel.removeSubTree(model, nodeId);
|
|
94
|
+
if (nodeId === void 0) {
|
|
95
|
+
update(model.rootNode);
|
|
96
|
+
model.rootNode.isLoading = true;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
const modelNode = model.idToNode.get(nodeId);
|
|
100
|
+
if (!modelNode) return false;
|
|
101
|
+
update(modelNode);
|
|
102
|
+
if (modelNode.isExpanded) {
|
|
103
|
+
modelNode.isLoading = true;
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
function clearNodeError(model, parentId) {
|
|
109
|
+
const node = !parentId ? model.rootNode : model.idToNode.get(parentId);
|
|
110
|
+
if (node) node.error = void 0;
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { TreeModel };
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=TreeModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeModel.js","names":["GenericInstanceFilter","HierarchyNode","ErrorInfo","SelectionChangeType","TreeModelRootNode","id","nodeData","hierarchyLimit","instanceFilter","isLoading","error","TreeModelHierarchyNode","label","children","isExpanded","isSelected","TreeModel","parentChildMap","Map","idToNode","rootNode","expandNode","model","nodeId","node","get","type","removeSubTree","addHierarchyPart","rootId","hierarchyPart","parentId","set","parentNode","undefined","clearNodeError","currentChildren","delete","childId","childNode","setHierarchyLimit","limit","updateForReload","setInstanceFilter","filter","selectNodes","nodeIds","Array","changeType","find","modelNode","isNodeSelected","currentNode","getNode","setIsLoading","update"],"sources":["../../../src/presentation-hierarchies-react/internal/TreeModel.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport type { GenericInstanceFilter, HierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport type { ErrorInfo } from \"../TreeNode.js\";\nimport type { SelectionChangeType } from \"../UseSelectionHandler.js\";\n\n/** @internal */\nexport interface TreeModelRootNode {\n id: undefined;\n nodeData: undefined;\n hierarchyLimit?: number | \"unbounded\";\n instanceFilter?: GenericInstanceFilter;\n isLoading?: boolean;\n error?: ErrorInfo;\n}\n\n/** @internal */\nexport interface TreeModelHierarchyNode {\n id: string;\n nodeData: HierarchyNode;\n label: string;\n children: boolean;\n isLoading?: boolean;\n isExpanded?: boolean;\n isSelected?: boolean;\n hierarchyLimit?: number | \"unbounded\";\n instanceFilter?: GenericInstanceFilter;\n error?: ErrorInfo;\n}\n\n/** @internal */\nexport interface TreeModel {\n parentChildMap: Map<string | undefined, string[]>;\n idToNode: Map<string, TreeModelHierarchyNode>;\n rootNode: TreeModelRootNode;\n}\n\n/** @internal */\nexport namespace TreeModel {\n export function expandNode(\n model: TreeModel,\n nodeId: string,\n isExpanded: boolean,\n ): \"none\" | \"loadChildren\" | \"reloadChildren\" {\n const node = model.idToNode.get(nodeId);\n if (!node) {\n return \"none\";\n }\n\n node.isExpanded = isExpanded;\n if (!isExpanded) {\n return \"none\";\n }\n\n if (node.error?.type === \"ChildrenLoad\") {\n node.isLoading = true;\n // remove subtree if there `ChildrenLoad` error info in order to attempt reloading children\n TreeModel.removeSubTree(model, nodeId);\n return \"reloadChildren\";\n }\n\n if (!node.children) {\n return \"none\";\n }\n\n const children = model.parentChildMap.get(node.id);\n if (!children) {\n node.isLoading = true;\n return \"loadChildren\";\n }\n\n return \"none\";\n }\n\n /** @internal */\n export function addHierarchyPart(model: TreeModel, rootId: string | undefined, hierarchyPart: TreeModel): void {\n removeSubTree(model, rootId);\n model.rootNode.error = hierarchyPart.rootNode.error;\n\n for (const [parentId, children] of hierarchyPart.parentChildMap) {\n model.parentChildMap.set(parentId, children);\n }\n\n for (const [nodeId, node] of hierarchyPart.idToNode) {\n model.idToNode.set(nodeId, node);\n }\n\n const parentNode = rootId !== undefined ? model.idToNode.get(rootId) : model.rootNode;\n /* c8 ignore next 3*/\n if (!parentNode) {\n return;\n }\n parentNode.isLoading = false;\n }\n\n export function removeSubTree(model: TreeModel, parentId: string | undefined): void {\n clearNodeError(model, parentId);\n const currentChildren = model.parentChildMap.get(parentId);\n if (!currentChildren) {\n return;\n }\n model.parentChildMap.delete(parentId);\n\n for (const childId of currentChildren) {\n const childNode = model.idToNode.get(childId);\n if (childNode) {\n removeSubTree(model, childNode.id);\n }\n model.idToNode.delete(childId);\n }\n }\n\n export function setHierarchyLimit(\n model: TreeModel,\n nodeId: string | undefined,\n limit?: number | \"unbounded\",\n ): boolean {\n return updateForReload(model, nodeId, (node) => {\n node.hierarchyLimit = limit;\n });\n }\n\n export function setInstanceFilter(\n model: TreeModel,\n nodeId: string | undefined,\n filter?: GenericInstanceFilter,\n ): boolean {\n return updateForReload(model, nodeId, (node) => {\n if (filter && node.id !== undefined) {\n node.isExpanded = true;\n }\n node.instanceFilter = filter;\n });\n }\n\n export function selectNodes(model: TreeModel, nodeIds: Array<string>, changeType: SelectionChangeType) {\n if (changeType === \"replace\") {\n for (const [nodeId, node] of model.idToNode) {\n node.isSelected = !!nodeIds.find((id) => id === nodeId);\n }\n return;\n }\n for (const nodeId of nodeIds) {\n const modelNode = model.idToNode.get(nodeId);\n if (!modelNode) {\n return;\n }\n modelNode.isSelected = changeType === \"add\";\n }\n }\n\n export function isNodeSelected(model: TreeModel, nodeId: string): boolean {\n const currentNode = model.idToNode.get(nodeId);\n return !!currentNode && !!currentNode.isSelected;\n }\n\n export function getNode(\n model: TreeModel,\n nodeId: string | undefined,\n ): TreeModelHierarchyNode | TreeModelRootNode | undefined {\n if (!nodeId) {\n return model.rootNode;\n }\n return model.idToNode.get(nodeId);\n }\n\n export function setIsLoading(model: TreeModel, nodeId: string | undefined, isLoading: boolean) {\n if (nodeId === undefined) {\n model.rootNode.isLoading = isLoading;\n return;\n }\n const modelNode = model.idToNode.get(nodeId);\n /* c8 ignore next 3*/\n if (!modelNode) {\n return;\n }\n modelNode.isLoading = isLoading;\n }\n}\n\nfunction updateForReload(\n model: TreeModel,\n nodeId: string | undefined,\n update: (node: TreeModelHierarchyNode | TreeModelRootNode) => void,\n) {\n TreeModel.removeSubTree(model, nodeId);\n if (nodeId === undefined) {\n update(model.rootNode);\n model.rootNode.isLoading = true;\n return true;\n }\n\n const modelNode = model.idToNode.get(nodeId);\n if (!modelNode) {\n return false;\n }\n\n update(modelNode);\n if (modelNode.isExpanded) {\n modelNode.isLoading = true;\n return true;\n }\n return false;\n}\n\nfunction clearNodeError(model: TreeModel, parentId: string | undefined) {\n const node = !parentId ? model.rootNode : model.idToNode.get(parentId);\n if (node) {\n node.error = undefined;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GenericNodeKey, NonGroupingHierarchyNode } from "@itwin/presentation-hierarchies";
|
|
2
|
+
import { Selectable, SelectionStorage } from "@itwin/unified-selection";
|
|
3
|
+
|
|
4
|
+
//#region src/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts
|
|
5
|
+
/** @public */
|
|
6
|
+
interface UseUnifiedTreeSelectionProps {
|
|
7
|
+
/**
|
|
8
|
+
* Identifier to distinguish this source of changes to the unified selection from another ones in the application.
|
|
9
|
+
*/
|
|
10
|
+
sourceName: string;
|
|
11
|
+
/**
|
|
12
|
+
* An optional function that allows customizing the `Selectable` object that gets created for generic hierarchy nodes. When
|
|
13
|
+
* not supplied, the `Selectable` is created using the following signature:
|
|
14
|
+
* ```ts
|
|
15
|
+
* {
|
|
16
|
+
* identifier: treeModelNodeId,
|
|
17
|
+
* data: node,
|
|
18
|
+
* async *loadInstanceKeys() {},
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param node Hierarchy node to create a selectable for.
|
|
23
|
+
* @param treeModelNodeId ID of the hierarchy node in the internal tree model. This ID uniquely identifies the node in the whole hierarchy, as opposed to `GenericNodeKey.id` contained within the `node`, which may not be unique.
|
|
24
|
+
*/
|
|
25
|
+
createSelectableForGenericNode?: (node: NonGroupingHierarchyNode & {
|
|
26
|
+
key: GenericNodeKey;
|
|
27
|
+
}, treeModelNodeId: string) => Selectable;
|
|
28
|
+
/**
|
|
29
|
+
* Unified selection storage to use for listening, getting and changing active selection.
|
|
30
|
+
*/
|
|
31
|
+
selectionStorage: SelectionStorage;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { UseUnifiedTreeSelectionProps };
|
|
35
|
+
//# sourceMappingURL=UseUnifiedSelection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UseUnifiedSelection.d.ts","names":[],"sources":["../../../src/presentation-hierarchies-react/internal/UseUnifiedSelection.ts"],"mappings":";;;;;UAuBiB,4BAAA;EAuBV;;;EAnBL,UAAA;EAAA;;;;;;;;;;;;;;EAgBA,8BAAA,IACE,IAAA,EAAM,wBAAA;IAA6B,GAAA,EAAK,cAAA;EAAA,GACxC,eAAA,aACG,UAAA;;;;EAKL,gBAAA,EAAkB,gBAAA;AAAA"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { c } from "react-compiler-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { HierarchyNode } from "@itwin/presentation-hierarchies";
|
|
4
|
+
import { assert } from "@itwin/core-bentley";
|
|
5
|
+
import { Selectables } from "@itwin/unified-selection";
|
|
6
|
+
//#region src/presentation-hierarchies-react/internal/UseUnifiedSelection.ts
|
|
7
|
+
/** @internal */
|
|
8
|
+
function useUnifiedTreeSelection(t0) {
|
|
9
|
+
const $ = c(6);
|
|
10
|
+
const { sourceName, selectionStorage, getTreeModelNode, createSelectableForGenericNode: t1 } = t0;
|
|
11
|
+
const createSelectableForGenericNode = t1 === void 0 ? defaultCreateSelectableForGenericNode : t1;
|
|
12
|
+
const [options, setOptions] = useState(_temp3);
|
|
13
|
+
let t2;
|
|
14
|
+
let t3;
|
|
15
|
+
if ($[0] !== createSelectableForGenericNode || $[1] !== getTreeModelNode || $[2] !== selectionStorage || $[3] !== sourceName) {
|
|
16
|
+
t2 = () => {
|
|
17
|
+
setOptions(createOptions(sourceName, selectionStorage, createSelectableForGenericNode, getTreeModelNode));
|
|
18
|
+
return selectionStorage.selectionChangeEvent.addListener((args) => {
|
|
19
|
+
if (args.level > 0) return;
|
|
20
|
+
setOptions(createOptions(sourceName, selectionStorage, createSelectableForGenericNode, getTreeModelNode));
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
t3 = [
|
|
24
|
+
selectionStorage,
|
|
25
|
+
createSelectableForGenericNode,
|
|
26
|
+
getTreeModelNode,
|
|
27
|
+
sourceName
|
|
28
|
+
];
|
|
29
|
+
$[0] = createSelectableForGenericNode;
|
|
30
|
+
$[1] = getTreeModelNode;
|
|
31
|
+
$[2] = selectionStorage;
|
|
32
|
+
$[3] = sourceName;
|
|
33
|
+
$[4] = t2;
|
|
34
|
+
$[5] = t3;
|
|
35
|
+
} else {
|
|
36
|
+
t2 = $[4];
|
|
37
|
+
t3 = $[5];
|
|
38
|
+
}
|
|
39
|
+
useEffect(t2, t3);
|
|
40
|
+
return options;
|
|
41
|
+
}
|
|
42
|
+
function _temp3() {
|
|
43
|
+
return {
|
|
44
|
+
isNodeSelected: _temp,
|
|
45
|
+
selectNodes: _temp2
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function _temp2() {}
|
|
49
|
+
function _temp() {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
const defaultCreateSelectableForGenericNode = (node, treeModelNodeId) => ({
|
|
53
|
+
identifier: treeModelNodeId,
|
|
54
|
+
data: node,
|
|
55
|
+
async *loadInstanceKeys() {}
|
|
56
|
+
});
|
|
57
|
+
function createOptions(source, storage, createSelectableForGenericNode, getNode) {
|
|
58
|
+
return {
|
|
59
|
+
isNodeSelected: (nodeId) => {
|
|
60
|
+
const node = getNode(nodeId);
|
|
61
|
+
if (!node || node.id === void 0) return false;
|
|
62
|
+
for (const [imodelKey, nodeSelectables] of groupNodeSelectablesByIModelKey(node, createSelectableForGenericNode)) {
|
|
63
|
+
const storageSelectables = storage.getSelection({
|
|
64
|
+
imodelKey,
|
|
65
|
+
level: 0
|
|
66
|
+
});
|
|
67
|
+
if (Selectables.hasAny(storageSelectables, nodeSelectables)) return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
},
|
|
71
|
+
selectNodes: (nodeIds, changeType) => {
|
|
72
|
+
const imodelSelectables = /* @__PURE__ */ new Map();
|
|
73
|
+
for (const nodeId of nodeIds) {
|
|
74
|
+
const node = getNode(nodeId);
|
|
75
|
+
if (!node || node.id === void 0) return;
|
|
76
|
+
for (const [imodelKey, nodeSelectables] of groupNodeSelectablesByIModelKey(node, createSelectableForGenericNode)) {
|
|
77
|
+
let selectablesList = imodelSelectables.get(imodelKey);
|
|
78
|
+
if (!selectablesList) {
|
|
79
|
+
selectablesList = [];
|
|
80
|
+
imodelSelectables.set(imodelKey, selectablesList);
|
|
81
|
+
}
|
|
82
|
+
nodeSelectables.forEach((selectable) => selectablesList.push(selectable));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
imodelSelectables.forEach((selectables, imodelKey) => {
|
|
86
|
+
const actionProps = {
|
|
87
|
+
imodelKey,
|
|
88
|
+
source,
|
|
89
|
+
selectables,
|
|
90
|
+
level: 0
|
|
91
|
+
};
|
|
92
|
+
switch (changeType) {
|
|
93
|
+
case "add":
|
|
94
|
+
storage.addToSelection(actionProps);
|
|
95
|
+
return;
|
|
96
|
+
case "remove":
|
|
97
|
+
storage.removeFromSelection(actionProps);
|
|
98
|
+
return;
|
|
99
|
+
case "replace":
|
|
100
|
+
storage.replaceSelection(actionProps);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function groupNodeSelectablesByIModelKey(modelNode, createSelectableForGenericNode) {
|
|
108
|
+
const hierarchyNode = modelNode.nodeData;
|
|
109
|
+
if (HierarchyNode.isInstancesNode(hierarchyNode)) return groupIModelInstanceKeys(hierarchyNode.key.instanceKeys);
|
|
110
|
+
if (HierarchyNode.isGroupingNode(hierarchyNode)) {
|
|
111
|
+
const groupingNodeSelectables = /* @__PURE__ */ new Map();
|
|
112
|
+
groupIModelInstanceKeys(hierarchyNode.groupedInstanceKeys).forEach((instanceKeys, imodelKey) => {
|
|
113
|
+
groupingNodeSelectables.set(imodelKey, [{
|
|
114
|
+
identifier: modelNode.id,
|
|
115
|
+
data: hierarchyNode,
|
|
116
|
+
async *loadInstanceKeys() {
|
|
117
|
+
for (const key of instanceKeys) yield key;
|
|
118
|
+
}
|
|
119
|
+
}]);
|
|
120
|
+
});
|
|
121
|
+
return groupingNodeSelectables;
|
|
122
|
+
}
|
|
123
|
+
assert(HierarchyNode.isGeneric(hierarchyNode));
|
|
124
|
+
return new Map([["", [createSelectableForGenericNode(hierarchyNode, modelNode.id)]]]);
|
|
125
|
+
}
|
|
126
|
+
function groupIModelInstanceKeys(instanceKeys) {
|
|
127
|
+
return instanceKeys.reduce((imodelSelectables, key) => {
|
|
128
|
+
const imodelKey = key.imodelKey ?? "";
|
|
129
|
+
let selectablesList = imodelSelectables.get(imodelKey);
|
|
130
|
+
if (!selectablesList) {
|
|
131
|
+
selectablesList = [];
|
|
132
|
+
imodelSelectables.set(imodelKey, selectablesList);
|
|
133
|
+
}
|
|
134
|
+
selectablesList.push(key);
|
|
135
|
+
return imodelSelectables;
|
|
136
|
+
}, /* @__PURE__ */ new Map());
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { useUnifiedTreeSelection };
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=UseUnifiedSelection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UseUnifiedSelection.js","names":["useEffect","useState","assert","HierarchyNode","Selectables","GenericNodeKey","InstancesNodeKey","NonGroupingHierarchyNode","InstanceKey","Selectable","SelectionStorage","SelectionChangeType","TreeModelHierarchyNode","TreeModelRootNode","TreeSelectionOptions","isNodeSelected","nodeId","selectNodes","nodeIds","Array","changeType","UseUnifiedTreeSelectionProps","sourceName","createSelectableForGenericNode","node","key","treeModelNodeId","selectionStorage","useUnifiedTreeSelection","t0","$","_c","getTreeModelNode","t1","undefined","defaultCreateSelectableForGenericNode","options","setOptions","_temp3","t2","t3","createOptions","selectionChangeEvent","addListener","args","level","_temp","_temp2","NonNullable","identifier","data","loadInstanceKeys","source","storage","getNode","id","imodelKey","nodeSelectables","groupNodeSelectablesByIModelKey","storageSelectables","getSelection","hasAny","imodelSelectables","Map","selectablesList","get","set","forEach","selectable","push","selectables","actionProps","addToSelection","removeFromSelection","replaceSelection","modelNode","hierarchyNode","nodeData","isInstancesNode","groupIModelInstanceKeys","instanceKeys","isGroupingNode","groupingNodeSelectables","groupedInstanceKeys","isGeneric","reduce"],"sources":["../../../src/presentation-hierarchies-react/internal/UseUnifiedSelection.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useEffect, useState } from \"react\";\nimport { assert } from \"@itwin/core-bentley\";\nimport { HierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport { Selectables } from \"@itwin/unified-selection\";\n\nimport type { GenericNodeKey, InstancesNodeKey, NonGroupingHierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport type { InstanceKey } from \"@itwin/presentation-shared\";\nimport type { Selectable, SelectionStorage } from \"@itwin/unified-selection\";\nimport type { SelectionChangeType } from \"../UseSelectionHandler.js\";\nimport type { TreeModelHierarchyNode, TreeModelRootNode } from \"./TreeModel.js\";\n\n/** @internal */\nexport interface TreeSelectionOptions {\n isNodeSelected: (nodeId: string) => boolean;\n selectNodes: (nodeIds: Array<string>, changeType: SelectionChangeType) => void;\n}\n\n/** @public */\nexport interface UseUnifiedTreeSelectionProps {\n /**\n * Identifier to distinguish this source of changes to the unified selection from another ones in the application.\n */\n sourceName: string;\n\n /**\n * An optional function that allows customizing the `Selectable` object that gets created for generic hierarchy nodes. When\n * not supplied, the `Selectable` is created using the following signature:\n * ```ts\n * {\n * identifier: treeModelNodeId,\n * data: node,\n * async *loadInstanceKeys() {},\n * }\n * ```\n *\n * @param node Hierarchy node to create a selectable for.\n * @param treeModelNodeId ID of the hierarchy node in the internal tree model. This ID uniquely identifies the node in the whole hierarchy, as opposed to `GenericNodeKey.id` contained within the `node`, which may not be unique.\n */\n createSelectableForGenericNode?: (\n node: NonGroupingHierarchyNode & { key: GenericNodeKey },\n treeModelNodeId: string,\n ) => Selectable;\n\n /**\n * Unified selection storage to use for listening, getting and changing active selection.\n */\n selectionStorage: SelectionStorage;\n}\n\n/** @internal */\nexport function useUnifiedTreeSelection({\n sourceName,\n selectionStorage,\n getTreeModelNode,\n createSelectableForGenericNode = defaultCreateSelectableForGenericNode,\n}: UseUnifiedTreeSelectionProps & {\n getTreeModelNode: (nodeId: string) => TreeModelHierarchyNode | TreeModelRootNode | undefined;\n}): TreeSelectionOptions {\n const [options, setOptions] = useState<TreeSelectionOptions>(() => ({\n isNodeSelected: /* c8 ignore next */ () => false,\n selectNodes: /* c8 ignore next */ () => {},\n }));\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setOptions(createOptions(sourceName, selectionStorage, createSelectableForGenericNode, getTreeModelNode));\n return selectionStorage.selectionChangeEvent.addListener((args) => {\n if (args.level > 0) {\n return;\n }\n setOptions(createOptions(sourceName, selectionStorage, createSelectableForGenericNode, getTreeModelNode));\n });\n }, [selectionStorage, createSelectableForGenericNode, getTreeModelNode, sourceName]);\n\n return options;\n}\n\nconst defaultCreateSelectableForGenericNode: NonNullable<\n UseUnifiedTreeSelectionProps[\"createSelectableForGenericNode\"]\n> = (node, treeModelNodeId): Selectable => ({ identifier: treeModelNodeId, data: node, async *loadInstanceKeys() {} });\n\nfunction createOptions(\n source: string,\n storage: SelectionStorage,\n createSelectableForGenericNode: NonNullable<UseUnifiedTreeSelectionProps[\"createSelectableForGenericNode\"]>,\n getNode: (nodeId: string) => TreeModelHierarchyNode | TreeModelRootNode | undefined,\n): TreeSelectionOptions {\n return {\n isNodeSelected: (nodeId: string) => {\n const node = getNode(nodeId);\n if (!node || node.id === undefined) {\n return false;\n }\n for (const [imodelKey, nodeSelectables] of groupNodeSelectablesByIModelKey(\n node,\n createSelectableForGenericNode,\n )) {\n const storageSelectables = storage.getSelection({ imodelKey, level: 0 });\n if (Selectables.hasAny(storageSelectables, nodeSelectables)) {\n return true;\n }\n }\n return false;\n },\n\n selectNodes: (nodeIds: Array<string>, changeType: SelectionChangeType) => {\n const imodelSelectables = new Map<string, Selectable[]>();\n for (const nodeId of nodeIds) {\n const node = getNode(nodeId);\n if (!node || node.id === undefined) {\n return;\n }\n for (const [imodelKey, nodeSelectables] of groupNodeSelectablesByIModelKey(\n node,\n createSelectableForGenericNode,\n )) {\n let selectablesList = imodelSelectables.get(imodelKey);\n if (!selectablesList) {\n selectablesList = [];\n imodelSelectables.set(imodelKey, selectablesList);\n }\n nodeSelectables.forEach((selectable) => selectablesList.push(selectable));\n }\n }\n imodelSelectables.forEach((selectables, imodelKey) => {\n const actionProps = { imodelKey, source, selectables, level: 0 };\n switch (changeType) {\n case \"add\":\n storage.addToSelection(actionProps);\n return;\n case \"remove\":\n storage.removeFromSelection(actionProps);\n return;\n case \"replace\":\n storage.replaceSelection(actionProps);\n return;\n }\n });\n },\n };\n}\n\nfunction groupNodeSelectablesByIModelKey(\n modelNode: TreeModelHierarchyNode,\n createSelectableForGenericNode: NonNullable<UseUnifiedTreeSelectionProps[\"createSelectableForGenericNode\"]>,\n): Map<string, Selectable[]> {\n const hierarchyNode = modelNode.nodeData;\n if (HierarchyNode.isInstancesNode(hierarchyNode)) {\n return groupIModelInstanceKeys(hierarchyNode.key.instanceKeys);\n }\n if (HierarchyNode.isGroupingNode(hierarchyNode)) {\n const groupingNodeSelectables = new Map<string, Selectable[]>();\n groupIModelInstanceKeys(hierarchyNode.groupedInstanceKeys).forEach((instanceKeys, imodelKey) => {\n groupingNodeSelectables.set(imodelKey, [\n {\n identifier: modelNode.id,\n data: hierarchyNode,\n async *loadInstanceKeys() {\n for (const key of instanceKeys) {\n yield key;\n }\n },\n },\n ]);\n });\n return groupingNodeSelectables;\n }\n assert(HierarchyNode.isGeneric(hierarchyNode));\n // note: generic nodes aren't associated with an imodel\n return new Map([[\"\", [createSelectableForGenericNode(hierarchyNode, modelNode.id)]]]);\n}\n\nfunction groupIModelInstanceKeys(instanceKeys: InstancesNodeKey[\"instanceKeys\"]) {\n return instanceKeys.reduce((imodelSelectables, key) => {\n const imodelKey = key.imodelKey ?? \"\";\n let selectablesList = imodelSelectables.get(imodelKey);\n if (!selectablesList) {\n selectablesList = [];\n imodelSelectables.set(imodelKey, selectablesList);\n }\n selectablesList.push(key);\n return imodelSelectables;\n }, new Map<string, InstanceKey[]>());\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import "./DisposePolyfill.js";
|
|
2
|
+
import { HierarchyNodeKey } from "@itwin/presentation-hierarchies";
|
|
3
|
+
//#region src/presentation-hierarchies-react/internal/Utils.ts
|
|
4
|
+
/** @internal */
|
|
5
|
+
function createNodeId(node) {
|
|
6
|
+
return [...node.parentKeys.map(serializeNodeKey), serializeNodeKey(node.key)].join(";");
|
|
7
|
+
}
|
|
8
|
+
function serializeNodeKey(key) {
|
|
9
|
+
return convertObjectValuesToString(key);
|
|
10
|
+
}
|
|
11
|
+
function convertObjectValuesToString(obj) {
|
|
12
|
+
return Object.entries(obj).map(([, value]) => {
|
|
13
|
+
if (typeof value === "object") return convertObjectValuesToString(value);
|
|
14
|
+
return String(value);
|
|
15
|
+
}).join(",");
|
|
16
|
+
}
|
|
17
|
+
/** @internal */
|
|
18
|
+
function sameNodes(lhs, rhs) {
|
|
19
|
+
if (HierarchyNodeKey.compare(lhs.key, rhs.key) !== 0) return false;
|
|
20
|
+
if (lhs.parentKeys.length !== rhs.parentKeys.length) return false;
|
|
21
|
+
for (let i = lhs.parentKeys.length - 1; i >= 0; --i) if (HierarchyNodeKey.compare(lhs.parentKeys[i], rhs.parentKeys[i]) !== 0) return false;
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
/** @internal */
|
|
25
|
+
const MAX_LIMIT_OVERRIDE = 1e4;
|
|
26
|
+
/**
|
|
27
|
+
* A helper that disposes the given object, if it's disposable.
|
|
28
|
+
*
|
|
29
|
+
* The first option is to dispose using the deprecated `dispose` method if it exists on the object.
|
|
30
|
+
* If not, we use the new `Symbol.dispose` method. If that doesn't exist either, the object is
|
|
31
|
+
* considered as non-disposable and nothing is done with it.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
function safeDispose(disposable) {
|
|
36
|
+
if ("dispose" in disposable) disposable.dispose();
|
|
37
|
+
else if (Symbol.dispose in disposable) disposable[Symbol.dispose]();
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { MAX_LIMIT_OVERRIDE, createNodeId, safeDispose, sameNodes };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=Utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Utils.js","names":["HierarchyNodeKey","HierarchyNode","createNodeId","node","Pick","parentKeys","map","serializeNodeKey","key","join","convertObjectValuesToString","obj","Object","entries","value","String","sameNodes","lhs","rhs","compare","length","i","MAX_LIMIT_OVERRIDE","safeDispose","disposable","Symbol","dispose"],"sources":["../../../src/presentation-hierarchies-react/internal/Utils.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./DisposePolyfill.js\";\n\nimport { HierarchyNodeKey } from \"@itwin/presentation-hierarchies\";\n\nimport type { HierarchyNode } from \"@itwin/presentation-hierarchies\";\n\n/** @internal */\nexport function createNodeId(node: Pick<HierarchyNode, \"key\" | \"parentKeys\">) {\n return [...node.parentKeys.map(serializeNodeKey), serializeNodeKey(node.key)].join(\";\");\n}\n\nfunction serializeNodeKey(key: HierarchyNodeKey): string {\n return convertObjectValuesToString(key);\n}\n\nfunction convertObjectValuesToString(obj: object): string {\n return Object.entries(obj)\n .map(([, value]) => {\n if (typeof value === \"object\") {\n return convertObjectValuesToString(value);\n }\n return String(value);\n })\n .join(\",\");\n}\n\n/** @internal */\nexport function sameNodes(lhs: HierarchyNode, rhs: HierarchyNode): boolean {\n if (HierarchyNodeKey.compare(lhs.key, rhs.key) !== 0) {\n return false;\n }\n\n if (lhs.parentKeys.length !== rhs.parentKeys.length) {\n return false;\n }\n\n for (let i = lhs.parentKeys.length - 1; i >= 0; --i) {\n if (HierarchyNodeKey.compare(lhs.parentKeys[i], rhs.parentKeys[i]) !== 0) {\n return false;\n }\n }\n return true;\n}\n\n/** @internal */\nexport const MAX_LIMIT_OVERRIDE = 10000;\n\n/**\n * A helper that disposes the given object, if it's disposable.\n *\n * The first option is to dispose using the deprecated `dispose` method if it exists on the object.\n * If not, we use the new `Symbol.dispose` method. If that doesn't exist either, the object is\n * considered as non-disposable and nothing is done with it.\n *\n * @internal\n */\nexport function safeDispose(disposable: {} | { [Symbol.dispose]: () => void } | { dispose: () => void }) {\n if (\"dispose\" in disposable) {\n disposable.dispose();\n } else if (Symbol.dispose in disposable) {\n disposable[Symbol.dispose]();\n }\n}\n"],"mappings":";;;;AAYA,SAAgBE,aAAaC,MAAiD;AAC5E,QAAO,CAAC,GAAGA,KAAKE,WAAWC,IAAIC,iBAAiB,EAAEA,iBAAiBJ,KAAKK,IAAI,CAAC,CAACC,KAAK,IAAI;;AAGzF,SAASF,iBAAiBC,KAA+B;AACvD,QAAOE,4BAA4BF,IAAI;;AAGzC,SAASE,4BAA4BC,KAAqB;AACxD,QAAOC,OAAOC,QAAQF,IAAI,CACvBL,KAAK,GAAGQ,WAAW;AAClB,MAAI,OAAOA,UAAU,SACnB,QAAOJ,4BAA4BI,MAAM;AAE3C,SAAOC,OAAOD,MAAM;GACpB,CACDL,KAAK,IAAI;;;AAId,SAAgBO,UAAUC,KAAoBC,KAA6B;AACzE,KAAIlB,iBAAiBmB,QAAQF,IAAIT,KAAKU,IAAIV,IAAI,KAAK,EACjD,QAAO;AAGT,KAAIS,IAAIZ,WAAWe,WAAWF,IAAIb,WAAWe,OAC3C,QAAO;AAGT,MAAK,IAAIC,IAAIJ,IAAIZ,WAAWe,SAAS,GAAGC,KAAK,GAAG,EAAEA,EAChD,KAAIrB,iBAAiBmB,QAAQF,IAAIZ,WAAWgB,IAAIH,IAAIb,WAAWgB,GAAG,KAAK,EACrE,QAAO;AAGX,QAAO;;;AAIT,MAAaC,qBAAqB;;;;;;;;;;AAWlC,SAAgBC,YAAYC,YAA6E;AACvG,KAAI,aAAaA,WACfA,YAAWE,SAAS;UACXD,OAAOC,WAAWF,WAC3BA,YAAWC,OAAOC,UAAU"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ErrorInfo, TreeNode } from "../TreeNode.js";
|
|
2
|
+
import { HierarchyLevelDetails, TreeRendererProps } from "../Renderers.js";
|
|
3
|
+
import { JSX } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts
|
|
6
|
+
/** @alpha */
|
|
7
|
+
interface ErrorItemRendererProps extends Pick<TreeRendererProps, "getHierarchyLevelDetails"> {
|
|
8
|
+
/** The tree node associated with the error. Used for displaying the node label in error messages and for scrolling to the node. */
|
|
9
|
+
treeNode: Omit<TreeNode, "errors">;
|
|
10
|
+
/** The error to render. */
|
|
11
|
+
error: ErrorInfo;
|
|
12
|
+
/** A callback to reload a hierarchy level when an error occurs and `retry` button is clicked. */
|
|
13
|
+
reloadTree: (options: {
|
|
14
|
+
parentNodeId: string | undefined;
|
|
15
|
+
}) => void;
|
|
16
|
+
/** A callback to scroll to the node associated with the error. */
|
|
17
|
+
scrollToNode: (treeNode: Omit<TreeNode, "errors">) => void;
|
|
18
|
+
/** A callback to initiate filtering of the given hierarchy level. */
|
|
19
|
+
filterHierarchyLevel?: (hierarchyLevelDetails: HierarchyLevelDetails) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders StrataKit `<ErrorRegion.Item />` for all supported error types:
|
|
23
|
+
* - `ResultSetTooLarge` - renders `resultLimitExceeded` message with actions to increase limit or apply filtering
|
|
24
|
+
* - `NoFilterMatches` - renders `noFilteredChildren` message with action to change filter
|
|
25
|
+
* - `ChildrenLoad` - renders `failedToCreateHierarchy` message with action to retry loading
|
|
26
|
+
* - `Unknown` - renders message set on error object.
|
|
27
|
+
*
|
|
28
|
+
* @alpha
|
|
29
|
+
*/
|
|
30
|
+
declare function ErrorItemRenderer({
|
|
31
|
+
treeNode,
|
|
32
|
+
error,
|
|
33
|
+
getHierarchyLevelDetails,
|
|
34
|
+
filterHierarchyLevel,
|
|
35
|
+
reloadTree,
|
|
36
|
+
scrollToNode
|
|
37
|
+
}: ErrorItemRendererProps): JSX.Element;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { ErrorItemRenderer, ErrorItemRendererProps };
|
|
40
|
+
//# sourceMappingURL=ErrorItemRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorItemRenderer.d.ts","names":[],"sources":["../../../src/presentation-hierarchies-react/stratakit/ErrorItemRenderer.tsx"],"mappings":";;;;;;UAeiB,sBAAA,SAA+B,IAAA,CAAK,iBAAA;EAApC;EAEf,QAAA,EAAU,IAAA,CAAK,QAAA;;EAEf,KAAA,EAAO,SAAA;EAFQ;EAIf,UAAA,GAAa,OAAA;IAAW,YAAA;EAAA;EAEC;EAAzB,YAAA,GAAe,QAAA,EAAU,IAAA,CAAK,QAAA;EARgB;EAU9C,oBAAA,IAAwB,qBAAA,EAAuB,qBAAA;AAAA;;;;;;;;;;iBAYjC,iBAAA,CAAA;EACd,QAAA;EACA,KAAA;EACA,wBAAA;EACA,oBAAA;EACA,UAAA;EACA;AAAA,GACC,sBAAA,GAAyB,GAAA,CAAI,OAAA"}
|