@itwin/tree-widget-react 1.1.3 → 1.2.1
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 +16 -1
- package/lib/cjs/components/trees/VisibilityTreeBase.scss +27 -27
- package/lib/cjs/components/trees/common/TreeRenderer.scss +25 -15
- package/lib/cjs/components/trees/models-tree/ModelsTree.d.ts +2 -2
- package/lib/cjs/components/trees/models-tree/ModelsTree.js +14 -2
- package/lib/cjs/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/cjs/e2e-tests/TreeWidget.test.js +13 -9
- package/lib/cjs/e2e-tests/TreeWidget.test.js.map +1 -1
- package/lib/cjs/e2e-tests/utils.d.ts +1 -0
- package/lib/cjs/e2e-tests/utils.js +12 -1
- package/lib/cjs/e2e-tests/utils.js.map +1 -1
- package/lib/esm/components/trees/VisibilityTreeBase.scss +27 -27
- package/lib/esm/components/trees/common/TreeRenderer.scss +25 -15
- package/lib/esm/components/trees/models-tree/ModelsTree.d.ts +2 -2
- package/lib/esm/components/trees/models-tree/ModelsTree.js +14 -2
- package/lib/esm/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/esm/e2e-tests/TreeWidget.test.js +14 -10
- package/lib/esm/e2e-tests/TreeWidget.test.js.map +1 -1
- package/lib/esm/e2e-tests/utils.d.ts +1 -0
- package/lib/esm/e2e-tests/utils.js +10 -0
- package/lib/esm/e2e-tests/utils.js.map +1 -1
- package/package.json +17 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# Change Log - @itwin/tree-widget-react
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Fri, 01 Dec 2023 13:46:38 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 1.2.1
|
|
6
|
+
Fri, 01 Dec 2023 13:46:38 GMT
|
|
7
|
+
|
|
8
|
+
### Patches
|
|
9
|
+
|
|
10
|
+
- Fix padding for icons when elements are enlarged.
|
|
11
|
+
- Fix progress indicator sizing in `enlarged` layout
|
|
12
|
+
|
|
13
|
+
## 1.2.0
|
|
14
|
+
Tue, 19 Sep 2023 14:55:43 GMT
|
|
15
|
+
|
|
16
|
+
### Minor changes
|
|
17
|
+
|
|
18
|
+
- `ModelsTree`: Add an option to pass `modelsVisibilityHandler` as a factory function.
|
|
4
19
|
|
|
5
20
|
## 1.1.3
|
|
6
21
|
Tue, 29 Aug 2023 13:48:47 GMT
|
|
@@ -5,6 +5,23 @@
|
|
|
5
5
|
|
|
6
6
|
.tree-widget-visibility-tree-base {
|
|
7
7
|
.tree-widget-tree-nodes-list {
|
|
8
|
+
&.enlarge {
|
|
9
|
+
.without-expander {
|
|
10
|
+
.visibility-tree-checkbox-container + * {
|
|
11
|
+
margin-left: var(--enlarged-node-expander-additional-padding);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.visibility-tree-checkbox-container {
|
|
16
|
+
height: var(--enlarged-node-height);
|
|
17
|
+
width: var(--enlarged-node-height);
|
|
18
|
+
|
|
19
|
+
.visibility-tree-checkbox {
|
|
20
|
+
--iui-checkbox-target-size: var(--enlarged-node-height);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
.core-tree-node {
|
|
9
26
|
&.with-checkbox {
|
|
10
27
|
> .contents {
|
|
@@ -14,28 +31,13 @@
|
|
|
14
31
|
|
|
15
32
|
&.disable-expander {
|
|
16
33
|
> .contents {
|
|
34
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
17
35
|
> .core-tree-expansionToggle {
|
|
18
36
|
display: none;
|
|
19
37
|
}
|
|
20
38
|
}
|
|
21
39
|
}
|
|
22
40
|
|
|
23
|
-
&.is-selected {
|
|
24
|
-
> .contents {
|
|
25
|
-
> .visibility-tree-checkbox-container {
|
|
26
|
-
background-color: var(--iui-color-background-accent-muted);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
&:not(.is-selected) {
|
|
32
|
-
> .contents:hover {
|
|
33
|
-
> .visibility-tree-checkbox-container {
|
|
34
|
-
background-color: var(--iui-color-background-hover);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
41
|
.visibility-tree-checkbox-container {
|
|
40
42
|
height: var(--iui-size-l);
|
|
41
43
|
width: var(--iui-size-l);
|
|
@@ -58,23 +60,21 @@
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
}
|
|
62
63
|
|
|
63
|
-
&.enlarge {
|
|
64
|
-
.core-tree-node {
|
|
65
|
-
.visibility-tree-checkbox-container {
|
|
66
|
-
height: var(--enlarged-node-height);
|
|
67
|
-
width: var(--enlarged-node-height);
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
&.is-selected {
|
|
66
|
+
> .contents {
|
|
67
|
+
> .visibility-tree-checkbox-container {
|
|
68
|
+
background-color: var(--iui-color-background-accent-muted);
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
.
|
|
76
|
-
.
|
|
77
|
-
|
|
73
|
+
&:not(.is-selected) {
|
|
74
|
+
> .contents:hover {
|
|
75
|
+
> .visibility-tree-checkbox-container {
|
|
76
|
+
background-color: var(--iui-color-background-hover);
|
|
77
|
+
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -20,31 +20,37 @@
|
|
|
20
20
|
height: 100%;
|
|
21
21
|
width: 100%;
|
|
22
22
|
|
|
23
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
23
24
|
.ReactWindow__VariableSizeList {
|
|
24
|
-
>div {
|
|
25
|
+
> div {
|
|
25
26
|
min-width: max-content !important; // to override inline class
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
.core-tree-node {
|
|
31
|
+
&.without-expander {
|
|
32
|
+
>.contents {
|
|
33
|
+
>.core-tree-node-icon {
|
|
34
|
+
margin-left: 5px;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
&.enlarge {
|
|
30
41
|
--enlarged-node-height: calc(var(--iui-size-l) + var(--iui-size-m) + var(--iui-size-3xs));
|
|
31
42
|
--enlarged-node-icon-size: var(--iui-size-m);
|
|
32
43
|
--enlarged-node-icon-padding: calc(var(--enlarged-node-height) - var(--enlarged-node-icon-size));
|
|
33
|
-
--enlarged-node-expander-additional-padding: calc(var(--iui-size-
|
|
44
|
+
--enlarged-node-expander-additional-padding: calc(var(--iui-size-l) - var(--iui-size-3xs) / 2);
|
|
34
45
|
|
|
35
46
|
.core-tree-node {
|
|
36
|
-
|
|
37
|
-
>.contents {
|
|
38
|
-
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
>.contents {
|
|
47
|
+
> .contents {
|
|
43
48
|
height: var(--enlarged-node-height);
|
|
44
49
|
font-size: var(--iui-font-size-2);
|
|
45
50
|
|
|
51
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
46
52
|
.core-tree-expansionToggle {
|
|
47
|
-
|
|
53
|
+
> .icon {
|
|
48
54
|
height: var(--enlarged-node-height);
|
|
49
55
|
width: var(--enlarged-node-height);
|
|
50
56
|
padding: calc(var(--enlarged-node-icon-padding) / 2);
|
|
@@ -56,11 +62,14 @@
|
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
&.without-expander {
|
|
66
|
+
> .contents {
|
|
67
|
+
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
.iui-progress-indicator-radial {
|
|
60
|
-
|
|
61
|
-
width: var(--enlarged-node-height);
|
|
62
|
-
padding: calc(var(--enlarged-node-icon-padding) / 2 - 1px); // need to reduce padding by `1px` to make sure icon is centered
|
|
63
|
-
margin: 0;
|
|
72
|
+
margin: 0 calc(var(--enlarged-node-icon-padding) / 2);
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
}
|
|
@@ -74,6 +83,7 @@
|
|
|
74
83
|
flex-direction: column;
|
|
75
84
|
position: relative;
|
|
76
85
|
|
|
86
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
77
87
|
.filteredTreeOverlay {
|
|
78
88
|
position: absolute;
|
|
79
89
|
top: 0;
|
|
@@ -99,4 +109,4 @@
|
|
|
99
109
|
font-weight: bold;
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
|
-
}
|
|
112
|
+
}
|
|
@@ -5,7 +5,7 @@ import { ModelsVisibilityHandler } from "./ModelsVisibilityHandler";
|
|
|
5
5
|
import type { SingleSchemaClassSpecification } from "@itwin/presentation-common";
|
|
6
6
|
import type { Viewport } from "@itwin/core-frontend";
|
|
7
7
|
import type { BaseFilterableTreeProps } from "../common/Types";
|
|
8
|
-
import type { ModelsTreeSelectionPredicate } from "./ModelsVisibilityHandler";
|
|
8
|
+
import type { ModelsTreeSelectionPredicate, ModelsVisibilityHandlerProps } from "./ModelsVisibilityHandler";
|
|
9
9
|
/**
|
|
10
10
|
* Props for configuring the hierarchy in [[ModelsTree]].
|
|
11
11
|
* @public
|
|
@@ -46,7 +46,7 @@ export interface ModelsTreeProps extends BaseFilterableTreeProps {
|
|
|
46
46
|
/**
|
|
47
47
|
* Custom visibility handler.
|
|
48
48
|
*/
|
|
49
|
-
modelsVisibilityHandler?: ModelsVisibilityHandler;
|
|
49
|
+
modelsVisibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler);
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* A tree component that shows a subject - model - category - element
|
|
@@ -101,8 +101,20 @@ function useModelsTreeNodeLoader(props) {
|
|
|
101
101
|
}
|
|
102
102
|
function useVisibilityHandler(rulesetId, iModel, activeView, visibilityHandler, filteredDataProvider, hierarchyAutoUpdateEnabled) {
|
|
103
103
|
const subjectModelIdsCache = (0, react_1.useMemo)(() => new ModelsVisibilityHandler_1.SubjectModelIdsCache(iModel), [iModel]);
|
|
104
|
-
const
|
|
105
|
-
|
|
104
|
+
const disposableVisibilityHandler = (0, core_react_1.useDisposable)((0, react_1.useCallback)(() => {
|
|
105
|
+
const visibilityHandlerProps = {
|
|
106
|
+
rulesetId,
|
|
107
|
+
viewport: activeView,
|
|
108
|
+
hierarchyAutoUpdateEnabled,
|
|
109
|
+
subjectModelIdsCache,
|
|
110
|
+
};
|
|
111
|
+
return typeof visibilityHandler === "function"
|
|
112
|
+
? visibilityHandler(visibilityHandlerProps)
|
|
113
|
+
: new ModelsVisibilityHandler_1.ModelsVisibilityHandler(visibilityHandlerProps);
|
|
114
|
+
}, [visibilityHandler, rulesetId, activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache]));
|
|
115
|
+
const handler = typeof visibilityHandler === "function" || visibilityHandler === undefined
|
|
116
|
+
? disposableVisibilityHandler
|
|
117
|
+
: visibilityHandler;
|
|
106
118
|
(0, react_1.useEffect)(() => {
|
|
107
119
|
handler && handler.setFilteredDataProvider(filteredDataProvider);
|
|
108
120
|
}, [handler, filteredDataProvider]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTree.tsx"],"names":[],"mappings":"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","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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { ControlledTree, SelectionMode, useTreeModel } from \"@itwin/components-react\";\nimport { useDisposable } from \"@itwin/core-react\";\nimport { isPresentationTreeNodeItem, usePresentationTreeNodeLoader } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { ClassGroupingOption } from \"../common/Types\";\nimport { addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { VisibilityTreeEventHandler } from \"../VisibilityTreeEventHandler\";\nimport { createVisibilityTreeRenderer, useVisibilityTreeFiltering, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { ModelsVisibilityHandler, SubjectModelIdsCache } from \"./ModelsVisibilityHandler\";\nimport { addModelsTreeNodeItemIcons, createRuleset, createSearchRuleset } from \"./Utils\";\n\nimport type { SingleSchemaClassSpecification } from \"@itwin/presentation-common\";\nimport type { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport type { IFilteredPresentationTreeDataProvider, IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps } from \"../common/Types\";\nimport type { ModelsTreeSelectionPredicate } from \"./ModelsVisibilityHandler\";\n\nconst PAGING_SIZE = 20;\n\n/**\n * Props for configuring the hierarchy in [[ModelsTree]].\n * @public\n */\nexport interface ModelsTreeHierarchyConfiguration {\n /** Should the tree group displayed element nodes by class. Defaults to `ClassGroupingOption.No`. */\n enableElementsClassGrouping?: ClassGroupingOption;\n /**\n * Defines the `bis.GeometricElement3d` sub-class that should be used to load element nodes.\n * Defaults to `bis.GeometricElement3d`. It's expected for the given class to derive from it.\n */\n elementClassSpecification?: SingleSchemaClassSpecification;\n /** Should the tree show models without elements. */\n showEmptyModels?: boolean;\n}\n\n/**\n * Props for [[ModelsTree]] component.\n * @public\n */\nexport interface ModelsTreeProps extends BaseFilterableTreeProps {\n /**\n * Predicate which indicates whether node can be selected or no\n */\n selectionPredicate?: ModelsTreeSelectionPredicate;\n /**\n * Active view used to determine and control visibility\n */\n activeView: Viewport;\n /**\n * Configuration options for the hierarchy loaded in the component.\n */\n hierarchyConfig?: ModelsTreeHierarchyConfiguration;\n /**\n * Auto-update the hierarchy when data in the iModel changes.\n * @alpha\n */\n enableHierarchyAutoUpdate?: boolean;\n /**\n * Custom visibility handler.\n */\n modelsVisibilityHandler?: ModelsVisibilityHandler;\n}\n\n/**\n * A tree component that shows a subject - model - category - element\n * hierarchy along with checkboxes that represent and allow changing\n * the display of those instances.\n * @public\n */\nexport function ModelsTree(props: ModelsTreeProps) {\n const { nodeLoader, onItemsRendered } = useModelsTreeNodeLoader(props);\n const { filteredNodeLoader, isFiltering, nodeHighlightingProps } = useVisibilityTreeFiltering(nodeLoader, props.filterInfo, props.onFilterApplied);\n const filterApplied = filteredNodeLoader !== nodeLoader;\n\n const { activeView, modelsVisibilityHandler, selectionPredicate } = props;\n\n const visibilityHandler = useVisibilityHandler(\n nodeLoader.dataProvider.rulesetId,\n props.iModel,\n activeView,\n modelsVisibilityHandler,\n getFilteredDataProvider(filteredNodeLoader.dataProvider),\n props.enableHierarchyAutoUpdate);\n const eventHandler = useDisposable(useCallback(() => new VisibilityTreeEventHandler({\n nodeLoader: filteredNodeLoader,\n visibilityHandler,\n selectionPredicate: (node) => !selectionPredicate || !isPresentationTreeNodeItem(node) ? true : selectionPredicate(node.key, ModelsVisibilityHandler.getNodeType(node)),\n }), [filteredNodeLoader, visibilityHandler, selectionPredicate]));\n\n const treeModel = useTreeModel(filteredNodeLoader.modelSource);\n const treeRenderer = createVisibilityTreeRenderer({\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: true,\n descriptionEnabled: false,\n levelOffset: 10,\n disableRootNodeCollapse: true,\n },\n });\n\n const overlay = isFiltering ? <div className=\"filteredTreeOverlay\" /> : undefined;\n\n // istanbul ignore next\n const noFilteredDataRenderer = useCallback(() => {\n return <VisibilityTreeNoFilteredData\n title={TreeWidget.translate(\"modelTree.noModelFound\")}\n message={TreeWidget.translate(\"modelTree.noMatchingModelNames\")}\n />;\n }, []);\n\n return (\n <div className={classNames(\"tree-widget-visibility-tree-base\", \"tree-widget-tree-container\")}>\n <ControlledTree\n nodeLoader={filteredNodeLoader}\n model={treeModel}\n selectionMode={props.selectionMode || SelectionMode.None}\n eventsHandler={eventHandler}\n treeRenderer={treeRenderer}\n nodeHighlightingProps={nodeHighlightingProps}\n noDataRenderer={filterApplied ? noFilteredDataRenderer : undefined}\n onItemsRendered={onItemsRendered}\n width={props.width}\n height={props.height}\n />\n {overlay}\n </div>\n );\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([\n addCustomTreeNodeItemLabelRenderer,\n addTreeNodeItemCheckbox,\n addModelsTreeNodeItemIcons,\n]);\n\nfunction useModelsTreeNodeLoader(props: ModelsTreeProps) {\n const rulesets = {\n general: useMemo(() => createRuleset({\n enableElementsClassGrouping: !!props.hierarchyConfig?.enableElementsClassGrouping,\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.enableElementsClassGrouping, props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n search: useMemo(() => createSearchRuleset({\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n };\n\n const { nodeLoader, onItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.general,\n appendChildrenCountForGroupingNodes: (props.hierarchyConfig?.enableElementsClassGrouping === ClassGroupingOption.YesWithCounts),\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n const { nodeLoader: searchNodeLoader, onItemsRendered: onSearchItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.search,\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n\n const activeNodeLoader = props.filterInfo?.filter ? searchNodeLoader : nodeLoader;\n const activeItemsRenderedCallback = props.filterInfo?.filter ? onSearchItemsRendered : onItemsRendered;\n\n return {\n nodeLoader: activeNodeLoader,\n onItemsRendered: activeItemsRenderedCallback,\n };\n}\n\nfunction useVisibilityHandler(\n rulesetId: string,\n iModel: IModelConnection,\n activeView: Viewport,\n visibilityHandler?: ModelsVisibilityHandler,\n filteredDataProvider?: IFilteredPresentationTreeDataProvider,\n hierarchyAutoUpdateEnabled?: boolean,\n) {\n const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);\n\n const defaultVisibilityHandler = useDisposable(useCallback(\n () =>\n new ModelsVisibilityHandler({ rulesetId, viewport: activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache }),\n [rulesetId, activeView, subjectModelIdsCache, hierarchyAutoUpdateEnabled])\n );\n\n const handler = visibilityHandler ?? defaultVisibilityHandler;\n\n useEffect(() => {\n handler && handler.setFilteredDataProvider(filteredDataProvider);\n }, [handler, filteredDataProvider]);\n\n return handler;\n}\n\nconst isFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): dataProvider is IFilteredPresentationTreeDataProvider => {\n const filteredProvider = dataProvider as IFilteredPresentationTreeDataProvider;\n return filteredProvider.nodeMatchesFilter !== undefined && filteredProvider.getActiveMatch !== undefined && filteredProvider.countFilteringResults !== undefined;\n};\n\nconst getFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): IFilteredPresentationTreeDataProvider | undefined => {\n return isFilteredDataProvider(dataProvider) ? dataProvider : undefined;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTree.tsx"],"names":[],"mappings":"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","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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { ControlledTree, SelectionMode, useTreeModel } from \"@itwin/components-react\";\nimport { useDisposable } from \"@itwin/core-react\";\nimport { isPresentationTreeNodeItem, usePresentationTreeNodeLoader } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { ClassGroupingOption } from \"../common/Types\";\nimport { addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { VisibilityTreeEventHandler } from \"../VisibilityTreeEventHandler\";\nimport { createVisibilityTreeRenderer, useVisibilityTreeFiltering, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { ModelsVisibilityHandler, SubjectModelIdsCache } from \"./ModelsVisibilityHandler\";\nimport { addModelsTreeNodeItemIcons, createRuleset, createSearchRuleset } from \"./Utils\";\n\nimport type { SingleSchemaClassSpecification } from \"@itwin/presentation-common\";\nimport type { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport type { IFilteredPresentationTreeDataProvider, IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps } from \"../common/Types\";\nimport type { ModelsTreeSelectionPredicate, ModelsVisibilityHandlerProps } from \"./ModelsVisibilityHandler\";\n\nconst PAGING_SIZE = 20;\n\n/**\n * Props for configuring the hierarchy in [[ModelsTree]].\n * @public\n */\nexport interface ModelsTreeHierarchyConfiguration {\n /** Should the tree group displayed element nodes by class. Defaults to `ClassGroupingOption.No`. */\n enableElementsClassGrouping?: ClassGroupingOption;\n /**\n * Defines the `bis.GeometricElement3d` sub-class that should be used to load element nodes.\n * Defaults to `bis.GeometricElement3d`. It's expected for the given class to derive from it.\n */\n elementClassSpecification?: SingleSchemaClassSpecification;\n /** Should the tree show models without elements. */\n showEmptyModels?: boolean;\n}\n\n/**\n * Props for [[ModelsTree]] component.\n * @public\n */\nexport interface ModelsTreeProps extends BaseFilterableTreeProps {\n /**\n * Predicate which indicates whether node can be selected or no\n */\n selectionPredicate?: ModelsTreeSelectionPredicate;\n /**\n * Active view used to determine and control visibility\n */\n activeView: Viewport;\n /**\n * Configuration options for the hierarchy loaded in the component.\n */\n hierarchyConfig?: ModelsTreeHierarchyConfiguration;\n /**\n * Auto-update the hierarchy when data in the iModel changes.\n * @alpha\n */\n enableHierarchyAutoUpdate?: boolean;\n /**\n * Custom visibility handler.\n */\n modelsVisibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler);\n}\n\n/**\n * A tree component that shows a subject - model - category - element\n * hierarchy along with checkboxes that represent and allow changing\n * the display of those instances.\n * @public\n */\nexport function ModelsTree(props: ModelsTreeProps) {\n const { nodeLoader, onItemsRendered } = useModelsTreeNodeLoader(props);\n const { filteredNodeLoader, isFiltering, nodeHighlightingProps } = useVisibilityTreeFiltering(nodeLoader, props.filterInfo, props.onFilterApplied);\n const filterApplied = filteredNodeLoader !== nodeLoader;\n\n const { activeView, modelsVisibilityHandler, selectionPredicate } = props;\n\n const visibilityHandler = useVisibilityHandler(\n nodeLoader.dataProvider.rulesetId,\n props.iModel,\n activeView,\n modelsVisibilityHandler,\n getFilteredDataProvider(filteredNodeLoader.dataProvider),\n props.enableHierarchyAutoUpdate);\n const eventHandler = useDisposable(useCallback(() => new VisibilityTreeEventHandler({\n nodeLoader: filteredNodeLoader,\n visibilityHandler,\n selectionPredicate: (node) => !selectionPredicate || !isPresentationTreeNodeItem(node) ? true : selectionPredicate(node.key, ModelsVisibilityHandler.getNodeType(node)),\n }), [filteredNodeLoader, visibilityHandler, selectionPredicate]));\n\n const treeModel = useTreeModel(filteredNodeLoader.modelSource);\n const treeRenderer = createVisibilityTreeRenderer({\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: true,\n descriptionEnabled: false,\n levelOffset: 10,\n disableRootNodeCollapse: true,\n },\n });\n\n const overlay = isFiltering ? <div className=\"filteredTreeOverlay\" /> : undefined;\n\n // istanbul ignore next\n const noFilteredDataRenderer = useCallback(() => {\n return <VisibilityTreeNoFilteredData\n title={TreeWidget.translate(\"modelTree.noModelFound\")}\n message={TreeWidget.translate(\"modelTree.noMatchingModelNames\")}\n />;\n }, []);\n\n return (\n <div className={classNames(\"tree-widget-visibility-tree-base\", \"tree-widget-tree-container\")}>\n <ControlledTree\n nodeLoader={filteredNodeLoader}\n model={treeModel}\n selectionMode={props.selectionMode || SelectionMode.None}\n eventsHandler={eventHandler}\n treeRenderer={treeRenderer}\n nodeHighlightingProps={nodeHighlightingProps}\n noDataRenderer={filterApplied ? noFilteredDataRenderer : undefined}\n onItemsRendered={onItemsRendered}\n width={props.width}\n height={props.height}\n />\n {overlay}\n </div>\n );\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([\n addCustomTreeNodeItemLabelRenderer,\n addTreeNodeItemCheckbox,\n addModelsTreeNodeItemIcons,\n]);\n\nfunction useModelsTreeNodeLoader(props: ModelsTreeProps) {\n const rulesets = {\n general: useMemo(() => createRuleset({\n enableElementsClassGrouping: !!props.hierarchyConfig?.enableElementsClassGrouping,\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.enableElementsClassGrouping, props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n search: useMemo(() => createSearchRuleset({\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n };\n\n const { nodeLoader, onItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.general,\n appendChildrenCountForGroupingNodes: (props.hierarchyConfig?.enableElementsClassGrouping === ClassGroupingOption.YesWithCounts),\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n const { nodeLoader: searchNodeLoader, onItemsRendered: onSearchItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.search,\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n\n const activeNodeLoader = props.filterInfo?.filter ? searchNodeLoader : nodeLoader;\n const activeItemsRenderedCallback = props.filterInfo?.filter ? onSearchItemsRendered : onItemsRendered;\n\n return {\n nodeLoader: activeNodeLoader,\n onItemsRendered: activeItemsRenderedCallback,\n };\n}\n\nfunction useVisibilityHandler(\n rulesetId: string,\n iModel: IModelConnection,\n activeView: Viewport,\n visibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler),\n filteredDataProvider?: IFilteredPresentationTreeDataProvider,\n hierarchyAutoUpdateEnabled?: boolean,\n) {\n const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);\n\n const disposableVisibilityHandler = useDisposable(useCallback(\n () => {\n const visibilityHandlerProps: ModelsVisibilityHandlerProps = {\n rulesetId,\n viewport: activeView,\n hierarchyAutoUpdateEnabled,\n subjectModelIdsCache,\n };\n\n return typeof visibilityHandler === \"function\"\n ? visibilityHandler(visibilityHandlerProps)\n : new ModelsVisibilityHandler(visibilityHandlerProps);\n },\n [visibilityHandler, rulesetId, activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache])\n );\n\n const handler = typeof visibilityHandler === \"function\" || visibilityHandler === undefined\n ? disposableVisibilityHandler\n : visibilityHandler;\n\n useEffect(() => {\n handler && handler.setFilteredDataProvider(filteredDataProvider);\n }, [handler, filteredDataProvider]);\n\n return handler;\n}\n\nconst isFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): dataProvider is IFilteredPresentationTreeDataProvider => {\n const filteredProvider = dataProvider as IFilteredPresentationTreeDataProvider;\n return filteredProvider.nodeMatchesFilter !== undefined && filteredProvider.getActiveMatch !== undefined && filteredProvider.countFilteringResults !== undefined;\n};\n\nconst getFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): IFilteredPresentationTreeDataProvider | undefined => {\n return isFilteredDataProvider(dataProvider) ? dataProvider : undefined;\n};\n"]}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
8
|
};
|
|
5
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const test_1 = require("@playwright/test");
|
|
7
10
|
const assert_1 = __importDefault(require("assert"));
|
|
11
|
+
const test_1 = require("@playwright/test");
|
|
8
12
|
const utils_1 = require("./utils");
|
|
9
13
|
let treeWidget;
|
|
10
14
|
test_1.test.beforeEach(async ({ page, baseURL }) => {
|
|
@@ -16,31 +20,31 @@ test_1.test.beforeEach(async ({ page, baseURL }) => {
|
|
|
16
20
|
await treeWidget.waitFor();
|
|
17
21
|
});
|
|
18
22
|
test_1.test.describe("should match image snapshot", () => {
|
|
19
|
-
(0, test_1.test)("initial tree", async () => {
|
|
23
|
+
(0, test_1.test)("initial tree", async ({ page }) => {
|
|
20
24
|
// wait for element to be visible in the tree
|
|
21
25
|
await (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel").getByRole("checkbox", { name: "Visible", exact: true }).waitFor();
|
|
22
|
-
await (0,
|
|
26
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
23
27
|
});
|
|
24
|
-
(0, test_1.test)("expanded tree node", async () => {
|
|
28
|
+
(0, test_1.test)("expanded tree node", async ({ page }) => {
|
|
25
29
|
const node = (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel");
|
|
26
30
|
await node.getByTestId("tree-node-expansion-toggle").click();
|
|
27
31
|
// wait for node at the bottom to be visible/loaded
|
|
28
32
|
await (0, utils_1.locateNode)(treeWidget, "Tag-Category").waitFor();
|
|
29
|
-
await (0,
|
|
33
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
30
34
|
});
|
|
31
|
-
(0, test_1.test)("selected node", async () => {
|
|
35
|
+
(0, test_1.test)("selected node", async ({ page }) => {
|
|
32
36
|
const node = (0, utils_1.locateNode)(treeWidget, "BayTown");
|
|
33
37
|
await node.click();
|
|
34
38
|
// wait for node to become selected
|
|
35
39
|
await (0, test_1.expect)(node).toHaveClass(/is-selected/);
|
|
36
|
-
await (0,
|
|
40
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
37
41
|
});
|
|
38
|
-
(0, test_1.test)("search", async () => {
|
|
42
|
+
(0, test_1.test)("search", async ({ page }) => {
|
|
39
43
|
await treeWidget.getByText("BayTown").waitFor();
|
|
40
44
|
await treeWidget.getByTitle("Search for something").click();
|
|
41
45
|
await treeWidget.getByPlaceholder("Search...").fill("Model");
|
|
42
46
|
await treeWidget.locator(".components-activehighlight").waitFor();
|
|
43
|
-
await (0,
|
|
47
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
44
48
|
});
|
|
45
49
|
});
|
|
46
50
|
//# sourceMappingURL=TreeWidget.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;AAGhG,oDAA4B;AAC5B,2CAAgD;AAChD,mCAAqF;AAErF,IAAI,UAAmB,CAAC;AACxB,WAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAC1C,IAAA,gBAAM,EAAC,OAAO,CAAC,CAAC;IAChB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,8BAA8B;IAC9B,MAAM,IAAA,wBAAgB,EAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,UAAU,GAAG,IAAA,oBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,WAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAEhD,IAAA,WAAI,EAAC,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtC,6CAA6C;QAC7C,MAAM,IAAA,kBAAU,EAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACvH,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAI,EAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;QAE7D,mDAAmD;QACnD,MAAM,IAAA,kBAAU,EAAC,UAAU,EAAE,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAI,EAAC,eAAe,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,mCAAmC;QACnC,MAAM,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAI,EAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAChC,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,UAAU,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,UAAU,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC","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 { Locator } from \"@playwright/test\";\nimport assert from \"assert\";\nimport { expect, test } from \"@playwright/test\";\nimport { expandStagePanel, locateNode, locateWidget, takeScreenshot } from \"./utils\";\n\nlet treeWidget: Locator;\ntest.beforeEach(async ({ page, baseURL }) => {\n assert(baseURL);\n await page.goto(baseURL);\n // expand panel size to ~300px\n await expandStagePanel(page, \"right\", 100);\n treeWidget = locateWidget(page, \"tree\");\n await treeWidget.waitFor();\n});\n\ntest.describe(\"should match image snapshot\", () => {\n\n test(\"initial tree\", async ({ page }) => {\n // wait for element to be visible in the tree\n await locateNode(treeWidget, \"ProcessPhysicalModel\").getByRole(\"checkbox\", { name: \"Visible\", exact: true }).waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"expanded tree node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await node.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"selected node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"BayTown\");\n await node.click();\n\n // wait for node to become selected\n await expect(node).toHaveClass(/is-selected/);\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"search\", async ({ page }) => {\n await treeWidget.getByText(\"BayTown\").waitFor();\n await treeWidget.getByTitle(\"Search for something\").click();\n await treeWidget.getByPlaceholder(\"Search...\").fill(\"Model\");\n await treeWidget.locator(\".components-activehighlight\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n});\n"]}
|
|
@@ -4,5 +4,6 @@ export declare const locateWidget: (page: Page | Locator, widgetName: string) =>
|
|
|
4
4
|
type PanelSide = "left" | "right" | "top" | "bottom";
|
|
5
5
|
export declare const locatePanel: (page: Page, side: PanelSide) => Locator;
|
|
6
6
|
export declare const expandStagePanel: (page: Page, side: PanelSide, px: number) => Promise<void>;
|
|
7
|
+
export declare function takeScreenshot(page: Page, component: Locator): Promise<void>;
|
|
7
8
|
export {};
|
|
8
9
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
8
|
};
|
|
5
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.expandStagePanel = exports.locatePanel = exports.locateWidget = exports.locateNode = void 0;
|
|
10
|
+
exports.takeScreenshot = exports.expandStagePanel = exports.locatePanel = exports.locateWidget = exports.locateNode = void 0;
|
|
7
11
|
const assert_1 = __importDefault(require("assert"));
|
|
12
|
+
const test_1 = require("@playwright/test");
|
|
8
13
|
const locateNode = (tree, name) => tree.getByRole("treeitem", { name });
|
|
9
14
|
exports.locateNode = locateNode;
|
|
10
15
|
const locateWidget = (page, widgetName) => page.locator(`.${widgetName}-widget`);
|
|
@@ -37,4 +42,10 @@ const expandStagePanel = async (page, side, px) => {
|
|
|
37
42
|
await page.mouse.up();
|
|
38
43
|
};
|
|
39
44
|
exports.expandStagePanel = expandStagePanel;
|
|
45
|
+
async function takeScreenshot(page, component) {
|
|
46
|
+
const boundingBox = await component.boundingBox();
|
|
47
|
+
(0, assert_1.default)(boundingBox);
|
|
48
|
+
await (0, test_1.expect)(page).toHaveScreenshot({ clip: boundingBox });
|
|
49
|
+
}
|
|
50
|
+
exports.takeScreenshot = takeScreenshot;
|
|
40
51
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;;AAEhG,oDAA4B;AAC5B,2CAA0C;AAInC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAA1F,QAAA,UAAU,cAAgF;AAChG,MAAM,YAAY,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAAnG,QAAA,YAAY,gBAAuF;AAGzG,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAAjG,QAAA,WAAW,eAAsF;AAEvG,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAE,IAAe,EAAE,EAAU,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,IAAA,mBAAW,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,WAAW;SAChC,OAAO,CAAC,oBAAoB,CAAC;SAC7B,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,EAAE,CAAC;IACjB,IAAA,gBAAM,EAAC,SAAS,CAAC,CAAC;IAElB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAExB,QAAQ,IAAI,EAAE;QACZ,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;KACT;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AA1BW,QAAA,gBAAgB,oBA0B3B;AAEK,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAkB;IACjE,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAClD,IAAA,gBAAM,EAAC,WAAW,CAAC,CAAC;IACpB,MAAM,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC;AAJD,wCAIC","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 assert from \"assert\";\nimport { expect } from \"@playwright/test\";\n\nimport type { Locator, Page } from \"@playwright/test\";\n\nexport const locateNode = (tree: Page | Locator, name: string) => tree.getByRole(\"treeitem\", { name });\nexport const locateWidget = (page: Page | Locator, widgetName: string) => page.locator(`.${widgetName}-widget`);\n\ntype PanelSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport const locatePanel = (page: Page, side: PanelSide) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);\n\nexport const expandStagePanel = async (page: Page, side: PanelSide, px: number) => {\n const widgetPanel = locatePanel(page, side);\n const handlePos = await widgetPanel\n .locator(\".nz-grip-container\")\n .locator(\".nz-handle\")\n .boundingBox();\n assert(handlePos);\n\n await page.mouse.move(handlePos.x, handlePos.y);\n await page.mouse.down();\n\n switch (side) {\n case \"left\":\n await page.mouse.move(handlePos.x + px, handlePos.y);\n break;\n case \"right\":\n await page.mouse.move(handlePos.x - px, handlePos.y);\n break;\n case \"top\":\n await page.mouse.move(handlePos.x, handlePos.y - px);\n break;\n case \"bottom\":\n await page.mouse.move(handlePos.x, handlePos.y + px);\n break;\n }\n await page.mouse.up();\n};\n\nexport async function takeScreenshot(page: Page, component: Locator) {\n const boundingBox = await component.boundingBox();\n assert(boundingBox);\n await expect(page).toHaveScreenshot({ clip: boundingBox });\n}\n"]}
|
|
@@ -5,6 +5,23 @@
|
|
|
5
5
|
|
|
6
6
|
.tree-widget-visibility-tree-base {
|
|
7
7
|
.tree-widget-tree-nodes-list {
|
|
8
|
+
&.enlarge {
|
|
9
|
+
.without-expander {
|
|
10
|
+
.visibility-tree-checkbox-container + * {
|
|
11
|
+
margin-left: var(--enlarged-node-expander-additional-padding);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.visibility-tree-checkbox-container {
|
|
16
|
+
height: var(--enlarged-node-height);
|
|
17
|
+
width: var(--enlarged-node-height);
|
|
18
|
+
|
|
19
|
+
.visibility-tree-checkbox {
|
|
20
|
+
--iui-checkbox-target-size: var(--enlarged-node-height);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
.core-tree-node {
|
|
9
26
|
&.with-checkbox {
|
|
10
27
|
> .contents {
|
|
@@ -14,28 +31,13 @@
|
|
|
14
31
|
|
|
15
32
|
&.disable-expander {
|
|
16
33
|
> .contents {
|
|
34
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
17
35
|
> .core-tree-expansionToggle {
|
|
18
36
|
display: none;
|
|
19
37
|
}
|
|
20
38
|
}
|
|
21
39
|
}
|
|
22
40
|
|
|
23
|
-
&.is-selected {
|
|
24
|
-
> .contents {
|
|
25
|
-
> .visibility-tree-checkbox-container {
|
|
26
|
-
background-color: var(--iui-color-background-accent-muted);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
&:not(.is-selected) {
|
|
32
|
-
> .contents:hover {
|
|
33
|
-
> .visibility-tree-checkbox-container {
|
|
34
|
-
background-color: var(--iui-color-background-hover);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
41
|
.visibility-tree-checkbox-container {
|
|
40
42
|
height: var(--iui-size-l);
|
|
41
43
|
width: var(--iui-size-l);
|
|
@@ -58,23 +60,21 @@
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
}
|
|
62
63
|
|
|
63
|
-
&.enlarge {
|
|
64
|
-
.core-tree-node {
|
|
65
|
-
.visibility-tree-checkbox-container {
|
|
66
|
-
height: var(--enlarged-node-height);
|
|
67
|
-
width: var(--enlarged-node-height);
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
&.is-selected {
|
|
66
|
+
> .contents {
|
|
67
|
+
> .visibility-tree-checkbox-container {
|
|
68
|
+
background-color: var(--iui-color-background-accent-muted);
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
.
|
|
76
|
-
.
|
|
77
|
-
|
|
73
|
+
&:not(.is-selected) {
|
|
74
|
+
> .contents:hover {
|
|
75
|
+
> .visibility-tree-checkbox-container {
|
|
76
|
+
background-color: var(--iui-color-background-hover);
|
|
77
|
+
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -20,31 +20,37 @@
|
|
|
20
20
|
height: 100%;
|
|
21
21
|
width: 100%;
|
|
22
22
|
|
|
23
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
23
24
|
.ReactWindow__VariableSizeList {
|
|
24
|
-
>div {
|
|
25
|
+
> div {
|
|
25
26
|
min-width: max-content !important; // to override inline class
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
.core-tree-node {
|
|
31
|
+
&.without-expander {
|
|
32
|
+
>.contents {
|
|
33
|
+
>.core-tree-node-icon {
|
|
34
|
+
margin-left: 5px;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
&.enlarge {
|
|
30
41
|
--enlarged-node-height: calc(var(--iui-size-l) + var(--iui-size-m) + var(--iui-size-3xs));
|
|
31
42
|
--enlarged-node-icon-size: var(--iui-size-m);
|
|
32
43
|
--enlarged-node-icon-padding: calc(var(--enlarged-node-height) - var(--enlarged-node-icon-size));
|
|
33
|
-
--enlarged-node-expander-additional-padding: calc(var(--iui-size-
|
|
44
|
+
--enlarged-node-expander-additional-padding: calc(var(--iui-size-l) - var(--iui-size-3xs) / 2);
|
|
34
45
|
|
|
35
46
|
.core-tree-node {
|
|
36
|
-
|
|
37
|
-
>.contents {
|
|
38
|
-
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
>.contents {
|
|
47
|
+
> .contents {
|
|
43
48
|
height: var(--enlarged-node-height);
|
|
44
49
|
font-size: var(--iui-font-size-2);
|
|
45
50
|
|
|
51
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
46
52
|
.core-tree-expansionToggle {
|
|
47
|
-
|
|
53
|
+
> .icon {
|
|
48
54
|
height: var(--enlarged-node-height);
|
|
49
55
|
width: var(--enlarged-node-height);
|
|
50
56
|
padding: calc(var(--enlarged-node-icon-padding) / 2);
|
|
@@ -56,11 +62,14 @@
|
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
&.without-expander {
|
|
66
|
+
> .contents {
|
|
67
|
+
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
.iui-progress-indicator-radial {
|
|
60
|
-
|
|
61
|
-
width: var(--enlarged-node-height);
|
|
62
|
-
padding: calc(var(--enlarged-node-icon-padding) / 2 - 1px); // need to reduce padding by `1px` to make sure icon is centered
|
|
63
|
-
margin: 0;
|
|
72
|
+
margin: 0 calc(var(--enlarged-node-icon-padding) / 2);
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
}
|
|
@@ -74,6 +83,7 @@
|
|
|
74
83
|
flex-direction: column;
|
|
75
84
|
position: relative;
|
|
76
85
|
|
|
86
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
77
87
|
.filteredTreeOverlay {
|
|
78
88
|
position: absolute;
|
|
79
89
|
top: 0;
|
|
@@ -99,4 +109,4 @@
|
|
|
99
109
|
font-weight: bold;
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
|
-
}
|
|
112
|
+
}
|
|
@@ -5,7 +5,7 @@ import { ModelsVisibilityHandler } from "./ModelsVisibilityHandler";
|
|
|
5
5
|
import type { SingleSchemaClassSpecification } from "@itwin/presentation-common";
|
|
6
6
|
import type { Viewport } from "@itwin/core-frontend";
|
|
7
7
|
import type { BaseFilterableTreeProps } from "../common/Types";
|
|
8
|
-
import type { ModelsTreeSelectionPredicate } from "./ModelsVisibilityHandler";
|
|
8
|
+
import type { ModelsTreeSelectionPredicate, ModelsVisibilityHandlerProps } from "./ModelsVisibilityHandler";
|
|
9
9
|
/**
|
|
10
10
|
* Props for configuring the hierarchy in [[ModelsTree]].
|
|
11
11
|
* @public
|
|
@@ -46,7 +46,7 @@ export interface ModelsTreeProps extends BaseFilterableTreeProps {
|
|
|
46
46
|
/**
|
|
47
47
|
* Custom visibility handler.
|
|
48
48
|
*/
|
|
49
|
-
modelsVisibilityHandler?: ModelsVisibilityHandler;
|
|
49
|
+
modelsVisibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler);
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* A tree component that shows a subject - model - category - element
|
|
@@ -94,8 +94,20 @@ function useModelsTreeNodeLoader(props) {
|
|
|
94
94
|
}
|
|
95
95
|
function useVisibilityHandler(rulesetId, iModel, activeView, visibilityHandler, filteredDataProvider, hierarchyAutoUpdateEnabled) {
|
|
96
96
|
const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);
|
|
97
|
-
const
|
|
98
|
-
|
|
97
|
+
const disposableVisibilityHandler = useDisposable(useCallback(() => {
|
|
98
|
+
const visibilityHandlerProps = {
|
|
99
|
+
rulesetId,
|
|
100
|
+
viewport: activeView,
|
|
101
|
+
hierarchyAutoUpdateEnabled,
|
|
102
|
+
subjectModelIdsCache,
|
|
103
|
+
};
|
|
104
|
+
return typeof visibilityHandler === "function"
|
|
105
|
+
? visibilityHandler(visibilityHandlerProps)
|
|
106
|
+
: new ModelsVisibilityHandler(visibilityHandlerProps);
|
|
107
|
+
}, [visibilityHandler, rulesetId, activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache]));
|
|
108
|
+
const handler = typeof visibilityHandler === "function" || visibilityHandler === undefined
|
|
109
|
+
? disposableVisibilityHandler
|
|
110
|
+
: visibilityHandler;
|
|
99
111
|
useEffect(() => {
|
|
100
112
|
handler && handler.setFilteredDataProvider(filteredDataProvider);
|
|
101
113
|
}, [handler, filteredDataProvider]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTree.tsx"],"names":[],"mappings":"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","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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { ControlledTree, SelectionMode, useTreeModel } from \"@itwin/components-react\";\nimport { useDisposable } from \"@itwin/core-react\";\nimport { isPresentationTreeNodeItem, usePresentationTreeNodeLoader } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { ClassGroupingOption } from \"../common/Types\";\nimport { addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { VisibilityTreeEventHandler } from \"../VisibilityTreeEventHandler\";\nimport { createVisibilityTreeRenderer, useVisibilityTreeFiltering, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { ModelsVisibilityHandler, SubjectModelIdsCache } from \"./ModelsVisibilityHandler\";\nimport { addModelsTreeNodeItemIcons, createRuleset, createSearchRuleset } from \"./Utils\";\n\nimport type { SingleSchemaClassSpecification } from \"@itwin/presentation-common\";\nimport type { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport type { IFilteredPresentationTreeDataProvider, IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps } from \"../common/Types\";\nimport type { ModelsTreeSelectionPredicate } from \"./ModelsVisibilityHandler\";\n\nconst PAGING_SIZE = 20;\n\n/**\n * Props for configuring the hierarchy in [[ModelsTree]].\n * @public\n */\nexport interface ModelsTreeHierarchyConfiguration {\n /** Should the tree group displayed element nodes by class. Defaults to `ClassGroupingOption.No`. */\n enableElementsClassGrouping?: ClassGroupingOption;\n /**\n * Defines the `bis.GeometricElement3d` sub-class that should be used to load element nodes.\n * Defaults to `bis.GeometricElement3d`. It's expected for the given class to derive from it.\n */\n elementClassSpecification?: SingleSchemaClassSpecification;\n /** Should the tree show models without elements. */\n showEmptyModels?: boolean;\n}\n\n/**\n * Props for [[ModelsTree]] component.\n * @public\n */\nexport interface ModelsTreeProps extends BaseFilterableTreeProps {\n /**\n * Predicate which indicates whether node can be selected or no\n */\n selectionPredicate?: ModelsTreeSelectionPredicate;\n /**\n * Active view used to determine and control visibility\n */\n activeView: Viewport;\n /**\n * Configuration options for the hierarchy loaded in the component.\n */\n hierarchyConfig?: ModelsTreeHierarchyConfiguration;\n /**\n * Auto-update the hierarchy when data in the iModel changes.\n * @alpha\n */\n enableHierarchyAutoUpdate?: boolean;\n /**\n * Custom visibility handler.\n */\n modelsVisibilityHandler?: ModelsVisibilityHandler;\n}\n\n/**\n * A tree component that shows a subject - model - category - element\n * hierarchy along with checkboxes that represent and allow changing\n * the display of those instances.\n * @public\n */\nexport function ModelsTree(props: ModelsTreeProps) {\n const { nodeLoader, onItemsRendered } = useModelsTreeNodeLoader(props);\n const { filteredNodeLoader, isFiltering, nodeHighlightingProps } = useVisibilityTreeFiltering(nodeLoader, props.filterInfo, props.onFilterApplied);\n const filterApplied = filteredNodeLoader !== nodeLoader;\n\n const { activeView, modelsVisibilityHandler, selectionPredicate } = props;\n\n const visibilityHandler = useVisibilityHandler(\n nodeLoader.dataProvider.rulesetId,\n props.iModel,\n activeView,\n modelsVisibilityHandler,\n getFilteredDataProvider(filteredNodeLoader.dataProvider),\n props.enableHierarchyAutoUpdate);\n const eventHandler = useDisposable(useCallback(() => new VisibilityTreeEventHandler({\n nodeLoader: filteredNodeLoader,\n visibilityHandler,\n selectionPredicate: (node) => !selectionPredicate || !isPresentationTreeNodeItem(node) ? true : selectionPredicate(node.key, ModelsVisibilityHandler.getNodeType(node)),\n }), [filteredNodeLoader, visibilityHandler, selectionPredicate]));\n\n const treeModel = useTreeModel(filteredNodeLoader.modelSource);\n const treeRenderer = createVisibilityTreeRenderer({\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: true,\n descriptionEnabled: false,\n levelOffset: 10,\n disableRootNodeCollapse: true,\n },\n });\n\n const overlay = isFiltering ? <div className=\"filteredTreeOverlay\" /> : undefined;\n\n // istanbul ignore next\n const noFilteredDataRenderer = useCallback(() => {\n return <VisibilityTreeNoFilteredData\n title={TreeWidget.translate(\"modelTree.noModelFound\")}\n message={TreeWidget.translate(\"modelTree.noMatchingModelNames\")}\n />;\n }, []);\n\n return (\n <div className={classNames(\"tree-widget-visibility-tree-base\", \"tree-widget-tree-container\")}>\n <ControlledTree\n nodeLoader={filteredNodeLoader}\n model={treeModel}\n selectionMode={props.selectionMode || SelectionMode.None}\n eventsHandler={eventHandler}\n treeRenderer={treeRenderer}\n nodeHighlightingProps={nodeHighlightingProps}\n noDataRenderer={filterApplied ? noFilteredDataRenderer : undefined}\n onItemsRendered={onItemsRendered}\n width={props.width}\n height={props.height}\n />\n {overlay}\n </div>\n );\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([\n addCustomTreeNodeItemLabelRenderer,\n addTreeNodeItemCheckbox,\n addModelsTreeNodeItemIcons,\n]);\n\nfunction useModelsTreeNodeLoader(props: ModelsTreeProps) {\n const rulesets = {\n general: useMemo(() => createRuleset({\n enableElementsClassGrouping: !!props.hierarchyConfig?.enableElementsClassGrouping,\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.enableElementsClassGrouping, props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n search: useMemo(() => createSearchRuleset({\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n };\n\n const { nodeLoader, onItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.general,\n appendChildrenCountForGroupingNodes: (props.hierarchyConfig?.enableElementsClassGrouping === ClassGroupingOption.YesWithCounts),\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n const { nodeLoader: searchNodeLoader, onItemsRendered: onSearchItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.search,\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n\n const activeNodeLoader = props.filterInfo?.filter ? searchNodeLoader : nodeLoader;\n const activeItemsRenderedCallback = props.filterInfo?.filter ? onSearchItemsRendered : onItemsRendered;\n\n return {\n nodeLoader: activeNodeLoader,\n onItemsRendered: activeItemsRenderedCallback,\n };\n}\n\nfunction useVisibilityHandler(\n rulesetId: string,\n iModel: IModelConnection,\n activeView: Viewport,\n visibilityHandler?: ModelsVisibilityHandler,\n filteredDataProvider?: IFilteredPresentationTreeDataProvider,\n hierarchyAutoUpdateEnabled?: boolean,\n) {\n const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);\n\n const defaultVisibilityHandler = useDisposable(useCallback(\n () =>\n new ModelsVisibilityHandler({ rulesetId, viewport: activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache }),\n [rulesetId, activeView, subjectModelIdsCache, hierarchyAutoUpdateEnabled])\n );\n\n const handler = visibilityHandler ?? defaultVisibilityHandler;\n\n useEffect(() => {\n handler && handler.setFilteredDataProvider(filteredDataProvider);\n }, [handler, filteredDataProvider]);\n\n return handler;\n}\n\nconst isFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): dataProvider is IFilteredPresentationTreeDataProvider => {\n const filteredProvider = dataProvider as IFilteredPresentationTreeDataProvider;\n return filteredProvider.nodeMatchesFilter !== undefined && filteredProvider.getActiveMatch !== undefined && filteredProvider.countFilteringResults !== undefined;\n};\n\nconst getFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): IFilteredPresentationTreeDataProvider | undefined => {\n return isFilteredDataProvider(dataProvider) ? dataProvider : undefined;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTree.tsx"],"names":[],"mappings":";AAAA;;;+FAG+F;AAE/F,OAAO,4BAA4B,CAAC;AACpC,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAC3G,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kCAAkC,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,MAAM,iBAAiB,CAAC;AACjI,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACnI,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAQzF,MAAM,WAAW,GAAG,EAAE,CAAC;AA8CvB;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,qBAAqB,EAAE,GAAG,0BAA0B,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACnJ,MAAM,aAAa,GAAG,kBAAkB,KAAK,UAAU,CAAC;IAExD,MAAM,EAAE,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC;IAE1E,MAAM,iBAAiB,GAAG,oBAAoB,CAC5C,UAAU,CAAC,YAAY,CAAC,SAAS,EACjC,KAAK,CAAC,MAAM,EACZ,UAAU,EACV,uBAAuB,EACvB,uBAAuB,CAAC,kBAAkB,CAAC,YAAY,CAAC,EACxD,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,aAAa,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,0BAA0B,CAAC;QAClF,UAAU,EAAE,kBAAkB;QAC9B,iBAAiB;QACjB,kBAAkB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,kBAAkB,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,uBAAuB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;KACxK,CAAC,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG,YAAY,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,4BAA4B,CAAC;QAChD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,iBAAiB,EAAE;YACjB,YAAY,EAAE,IAAI;YAClB,kBAAkB,EAAE,KAAK;YACzB,WAAW,EAAE,EAAE;YACf,uBAAuB,EAAE,IAAI;SAC9B;KACF,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,qBAAqB,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAElF,uBAAuB;IACvB,MAAM,sBAAsB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9C,OAAO,KAAC,4BAA4B,IAClC,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,wBAAwB,CAAC,EACrD,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,gCAAgC,CAAC,GAC/D,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,eAAK,SAAS,EAAE,UAAU,CAAC,kCAAkC,EAAE,4BAA4B,CAAC,aAC1F,KAAC,cAAc,IACb,UAAU,EAAE,kBAAkB,EAC9B,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,EACxD,aAAa,EAAE,YAAY,EAC3B,YAAY,EAAE,YAAY,EAC1B,qBAAqB,EAAE,qBAAqB,EAC5C,cAAc,EAAE,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,EAClE,eAAe,EAAE,eAAe,EAChC,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,MAAM,EAAE,KAAK,CAAC,MAAM,GACpB,EACD,OAAO,IACJ,CACP,CAAC;AACJ,CAAC;AAED,MAAM,qBAAqB,GAAG,iCAAiC,CAAC;IAC9D,kCAAkC;IAClC,uBAAuB;IACvB,0BAA0B;CAC3B,CAAC,CAAC;AAEH,SAAS,uBAAuB,CAAC,KAAsB;IACrD,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC;YACnC,2BAA2B,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE,2BAA2B;YACjF,yBAAyB,EAAE,KAAK,CAAC,eAAe,EAAE,yBAAyB;YAC3E,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,eAAe;SACxD,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,2BAA2B,EAAE,KAAK,CAAC,eAAe,EAAE,yBAAyB,EAAE,KAAK,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;QACnJ,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC;YACxC,yBAAyB,EAAE,KAAK,CAAC,eAAe,EAAE,yBAAyB;YAC3E,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,eAAe;SACxD,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,yBAAyB,EAAE,KAAK,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;KAChG,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,6BAA6B,CAAC;QACpE,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,mCAAmC,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,2BAA2B,KAAK,mBAAmB,CAAC,aAAa,CAAC;QAC/H,UAAU,EAAE,WAAW;QACvB,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;QAC1D,qBAAqB;KACtB,CAAC,CAAC;IACH,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,EAAE,GAAG,6BAA6B,CAAC;QAC7G,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,QAAQ,CAAC,MAAM;QACxB,UAAU,EAAE,WAAW;QACvB,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;QAC1D,qBAAqB;KACtB,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC;IAClF,MAAM,2BAA2B,GAAG,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,eAAe,CAAC;IAEvG,OAAO;QACL,UAAU,EAAE,gBAAgB;QAC5B,eAAe,EAAE,2BAA2B;KAC7C,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAAiB,EACjB,MAAwB,EACxB,UAAoB,EACpB,iBAAgH,EAChH,oBAA4D,EAC5D,0BAAoC;IAEpC,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvF,MAAM,2BAA2B,GAAG,aAAa,CAAC,WAAW,CAC3D,GAAG,EAAE;QACH,MAAM,sBAAsB,GAAiC;YAC3D,SAAS;YACT,QAAQ,EAAE,UAAU;YACpB,0BAA0B;YAC1B,oBAAoB;SACrB,CAAC;QAEF,OAAO,OAAO,iBAAiB,KAAK,UAAU;YAC5C,CAAC,CAAC,iBAAiB,CAAC,sBAAsB,CAAC;YAC3C,CAAC,CAAC,IAAI,uBAAuB,CAAC,sBAAsB,CAAC,CAAC;IAC1D,CAAC,EACD,CAAC,iBAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,0BAA0B,EAAE,oBAAoB,CAAC,CAAC,CAC9F,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,iBAAiB,KAAK,UAAU,IAAI,iBAAiB,KAAK,SAAS;QACxF,CAAC,CAAC,2BAA2B;QAC7B,CAAC,CAAC,iBAAiB,CAAC;IAEtB,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,IAAI,OAAO,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IACnE,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAEpC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,sBAAsB,GAAG,CAAC,YAAmF,EAAyD,EAAE;IAC5K,MAAM,gBAAgB,GAAG,YAAqD,CAAC;IAC/E,OAAO,gBAAgB,CAAC,iBAAiB,KAAK,SAAS,IAAI,gBAAgB,CAAC,cAAc,KAAK,SAAS,IAAI,gBAAgB,CAAC,qBAAqB,KAAK,SAAS,CAAC;AACnK,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,YAAmF,EAAqD,EAAE;IACzK,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;AACzE,CAAC,CAAC","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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { ControlledTree, SelectionMode, useTreeModel } from \"@itwin/components-react\";\nimport { useDisposable } from \"@itwin/core-react\";\nimport { isPresentationTreeNodeItem, usePresentationTreeNodeLoader } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { ClassGroupingOption } from \"../common/Types\";\nimport { addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { VisibilityTreeEventHandler } from \"../VisibilityTreeEventHandler\";\nimport { createVisibilityTreeRenderer, useVisibilityTreeFiltering, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { ModelsVisibilityHandler, SubjectModelIdsCache } from \"./ModelsVisibilityHandler\";\nimport { addModelsTreeNodeItemIcons, createRuleset, createSearchRuleset } from \"./Utils\";\n\nimport type { SingleSchemaClassSpecification } from \"@itwin/presentation-common\";\nimport type { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport type { IFilteredPresentationTreeDataProvider, IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps } from \"../common/Types\";\nimport type { ModelsTreeSelectionPredicate, ModelsVisibilityHandlerProps } from \"./ModelsVisibilityHandler\";\n\nconst PAGING_SIZE = 20;\n\n/**\n * Props for configuring the hierarchy in [[ModelsTree]].\n * @public\n */\nexport interface ModelsTreeHierarchyConfiguration {\n /** Should the tree group displayed element nodes by class. Defaults to `ClassGroupingOption.No`. */\n enableElementsClassGrouping?: ClassGroupingOption;\n /**\n * Defines the `bis.GeometricElement3d` sub-class that should be used to load element nodes.\n * Defaults to `bis.GeometricElement3d`. It's expected for the given class to derive from it.\n */\n elementClassSpecification?: SingleSchemaClassSpecification;\n /** Should the tree show models without elements. */\n showEmptyModels?: boolean;\n}\n\n/**\n * Props for [[ModelsTree]] component.\n * @public\n */\nexport interface ModelsTreeProps extends BaseFilterableTreeProps {\n /**\n * Predicate which indicates whether node can be selected or no\n */\n selectionPredicate?: ModelsTreeSelectionPredicate;\n /**\n * Active view used to determine and control visibility\n */\n activeView: Viewport;\n /**\n * Configuration options for the hierarchy loaded in the component.\n */\n hierarchyConfig?: ModelsTreeHierarchyConfiguration;\n /**\n * Auto-update the hierarchy when data in the iModel changes.\n * @alpha\n */\n enableHierarchyAutoUpdate?: boolean;\n /**\n * Custom visibility handler.\n */\n modelsVisibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler);\n}\n\n/**\n * A tree component that shows a subject - model - category - element\n * hierarchy along with checkboxes that represent and allow changing\n * the display of those instances.\n * @public\n */\nexport function ModelsTree(props: ModelsTreeProps) {\n const { nodeLoader, onItemsRendered } = useModelsTreeNodeLoader(props);\n const { filteredNodeLoader, isFiltering, nodeHighlightingProps } = useVisibilityTreeFiltering(nodeLoader, props.filterInfo, props.onFilterApplied);\n const filterApplied = filteredNodeLoader !== nodeLoader;\n\n const { activeView, modelsVisibilityHandler, selectionPredicate } = props;\n\n const visibilityHandler = useVisibilityHandler(\n nodeLoader.dataProvider.rulesetId,\n props.iModel,\n activeView,\n modelsVisibilityHandler,\n getFilteredDataProvider(filteredNodeLoader.dataProvider),\n props.enableHierarchyAutoUpdate);\n const eventHandler = useDisposable(useCallback(() => new VisibilityTreeEventHandler({\n nodeLoader: filteredNodeLoader,\n visibilityHandler,\n selectionPredicate: (node) => !selectionPredicate || !isPresentationTreeNodeItem(node) ? true : selectionPredicate(node.key, ModelsVisibilityHandler.getNodeType(node)),\n }), [filteredNodeLoader, visibilityHandler, selectionPredicate]));\n\n const treeModel = useTreeModel(filteredNodeLoader.modelSource);\n const treeRenderer = createVisibilityTreeRenderer({\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: true,\n descriptionEnabled: false,\n levelOffset: 10,\n disableRootNodeCollapse: true,\n },\n });\n\n const overlay = isFiltering ? <div className=\"filteredTreeOverlay\" /> : undefined;\n\n // istanbul ignore next\n const noFilteredDataRenderer = useCallback(() => {\n return <VisibilityTreeNoFilteredData\n title={TreeWidget.translate(\"modelTree.noModelFound\")}\n message={TreeWidget.translate(\"modelTree.noMatchingModelNames\")}\n />;\n }, []);\n\n return (\n <div className={classNames(\"tree-widget-visibility-tree-base\", \"tree-widget-tree-container\")}>\n <ControlledTree\n nodeLoader={filteredNodeLoader}\n model={treeModel}\n selectionMode={props.selectionMode || SelectionMode.None}\n eventsHandler={eventHandler}\n treeRenderer={treeRenderer}\n nodeHighlightingProps={nodeHighlightingProps}\n noDataRenderer={filterApplied ? noFilteredDataRenderer : undefined}\n onItemsRendered={onItemsRendered}\n width={props.width}\n height={props.height}\n />\n {overlay}\n </div>\n );\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([\n addCustomTreeNodeItemLabelRenderer,\n addTreeNodeItemCheckbox,\n addModelsTreeNodeItemIcons,\n]);\n\nfunction useModelsTreeNodeLoader(props: ModelsTreeProps) {\n const rulesets = {\n general: useMemo(() => createRuleset({\n enableElementsClassGrouping: !!props.hierarchyConfig?.enableElementsClassGrouping,\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.enableElementsClassGrouping, props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n search: useMemo(() => createSearchRuleset({\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }), [props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels]),\n };\n\n const { nodeLoader, onItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.general,\n appendChildrenCountForGroupingNodes: (props.hierarchyConfig?.enableElementsClassGrouping === ClassGroupingOption.YesWithCounts),\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n const { nodeLoader: searchNodeLoader, onItemsRendered: onSearchItemsRendered } = usePresentationTreeNodeLoader({\n imodel: props.iModel,\n ruleset: rulesets.search,\n pagingSize: PAGING_SIZE,\n enableHierarchyAutoUpdate: props.enableHierarchyAutoUpdate,\n customizeTreeNodeItem,\n });\n\n const activeNodeLoader = props.filterInfo?.filter ? searchNodeLoader : nodeLoader;\n const activeItemsRenderedCallback = props.filterInfo?.filter ? onSearchItemsRendered : onItemsRendered;\n\n return {\n nodeLoader: activeNodeLoader,\n onItemsRendered: activeItemsRenderedCallback,\n };\n}\n\nfunction useVisibilityHandler(\n rulesetId: string,\n iModel: IModelConnection,\n activeView: Viewport,\n visibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler),\n filteredDataProvider?: IFilteredPresentationTreeDataProvider,\n hierarchyAutoUpdateEnabled?: boolean,\n) {\n const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);\n\n const disposableVisibilityHandler = useDisposable(useCallback(\n () => {\n const visibilityHandlerProps: ModelsVisibilityHandlerProps = {\n rulesetId,\n viewport: activeView,\n hierarchyAutoUpdateEnabled,\n subjectModelIdsCache,\n };\n\n return typeof visibilityHandler === \"function\"\n ? visibilityHandler(visibilityHandlerProps)\n : new ModelsVisibilityHandler(visibilityHandlerProps);\n },\n [visibilityHandler, rulesetId, activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache])\n );\n\n const handler = typeof visibilityHandler === \"function\" || visibilityHandler === undefined\n ? disposableVisibilityHandler\n : visibilityHandler;\n\n useEffect(() => {\n handler && handler.setFilteredDataProvider(filteredDataProvider);\n }, [handler, filteredDataProvider]);\n\n return handler;\n}\n\nconst isFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): dataProvider is IFilteredPresentationTreeDataProvider => {\n const filteredProvider = dataProvider as IFilteredPresentationTreeDataProvider;\n return filteredProvider.nodeMatchesFilter !== undefined && filteredProvider.getActiveMatch !== undefined && filteredProvider.countFilteringResults !== undefined;\n};\n\nconst getFilteredDataProvider = (dataProvider: IPresentationTreeDataProvider | IFilteredPresentationTreeDataProvider): IFilteredPresentationTreeDataProvider | undefined => {\n return isFilteredDataProvider(dataProvider) ? dataProvider : undefined;\n};\n"]}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2
5
|
import assert from "assert";
|
|
3
|
-
import {
|
|
6
|
+
import { expect, test } from "@playwright/test";
|
|
7
|
+
import { expandStagePanel, locateNode, locateWidget, takeScreenshot } from "./utils";
|
|
4
8
|
let treeWidget;
|
|
5
9
|
test.beforeEach(async ({ page, baseURL }) => {
|
|
6
10
|
assert(baseURL);
|
|
@@ -11,31 +15,31 @@ test.beforeEach(async ({ page, baseURL }) => {
|
|
|
11
15
|
await treeWidget.waitFor();
|
|
12
16
|
});
|
|
13
17
|
test.describe("should match image snapshot", () => {
|
|
14
|
-
test("initial tree", async () => {
|
|
18
|
+
test("initial tree", async ({ page }) => {
|
|
15
19
|
// wait for element to be visible in the tree
|
|
16
20
|
await locateNode(treeWidget, "ProcessPhysicalModel").getByRole("checkbox", { name: "Visible", exact: true }).waitFor();
|
|
17
|
-
await
|
|
21
|
+
await takeScreenshot(page, treeWidget);
|
|
18
22
|
});
|
|
19
|
-
test("expanded tree node", async () => {
|
|
23
|
+
test("expanded tree node", async ({ page }) => {
|
|
20
24
|
const node = locateNode(treeWidget, "ProcessPhysicalModel");
|
|
21
25
|
await node.getByTestId("tree-node-expansion-toggle").click();
|
|
22
26
|
// wait for node at the bottom to be visible/loaded
|
|
23
27
|
await locateNode(treeWidget, "Tag-Category").waitFor();
|
|
24
|
-
await
|
|
28
|
+
await takeScreenshot(page, treeWidget);
|
|
25
29
|
});
|
|
26
|
-
test("selected node", async () => {
|
|
30
|
+
test("selected node", async ({ page }) => {
|
|
27
31
|
const node = locateNode(treeWidget, "BayTown");
|
|
28
32
|
await node.click();
|
|
29
33
|
// wait for node to become selected
|
|
30
34
|
await expect(node).toHaveClass(/is-selected/);
|
|
31
|
-
await
|
|
35
|
+
await takeScreenshot(page, treeWidget);
|
|
32
36
|
});
|
|
33
|
-
test("search", async () => {
|
|
37
|
+
test("search", async ({ page }) => {
|
|
34
38
|
await treeWidget.getByText("BayTown").waitFor();
|
|
35
39
|
await treeWidget.getByTitle("Search for something").click();
|
|
36
40
|
await treeWidget.getByPlaceholder("Search...").fill("Model");
|
|
37
41
|
await treeWidget.locator(".components-activehighlight").waitFor();
|
|
38
|
-
await
|
|
42
|
+
await takeScreenshot(page, treeWidget);
|
|
39
43
|
});
|
|
40
44
|
});
|
|
41
45
|
//# sourceMappingURL=TreeWidget.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAErF,IAAI,UAAmB,CAAC;AACxB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAC1C,MAAM,CAAC,OAAO,CAAC,CAAC;IAChB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,8BAA8B;IAC9B,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAEhD,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtC,6CAA6C;QAC7C,MAAM,UAAU,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACvH,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;QAE7D,mDAAmD;QACnD,MAAM,UAAU,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,mCAAmC;QACnC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAChC,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,UAAU,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,UAAU,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC","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 { Locator } from \"@playwright/test\";\nimport assert from \"assert\";\nimport { expect, test } from \"@playwright/test\";\nimport { expandStagePanel, locateNode, locateWidget, takeScreenshot } from \"./utils\";\n\nlet treeWidget: Locator;\ntest.beforeEach(async ({ page, baseURL }) => {\n assert(baseURL);\n await page.goto(baseURL);\n // expand panel size to ~300px\n await expandStagePanel(page, \"right\", 100);\n treeWidget = locateWidget(page, \"tree\");\n await treeWidget.waitFor();\n});\n\ntest.describe(\"should match image snapshot\", () => {\n\n test(\"initial tree\", async ({ page }) => {\n // wait for element to be visible in the tree\n await locateNode(treeWidget, \"ProcessPhysicalModel\").getByRole(\"checkbox\", { name: \"Visible\", exact: true }).waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"expanded tree node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await node.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"selected node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"BayTown\");\n await node.click();\n\n // wait for node to become selected\n await expect(node).toHaveClass(/is-selected/);\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"search\", async ({ page }) => {\n await treeWidget.getByText(\"BayTown\").waitFor();\n await treeWidget.getByTitle(\"Search for something\").click();\n await treeWidget.getByPlaceholder(\"Search...\").fill(\"Model\");\n await treeWidget.locator(\".components-activehighlight\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n});\n"]}
|
|
@@ -4,5 +4,6 @@ export declare const locateWidget: (page: Page | Locator, widgetName: string) =>
|
|
|
4
4
|
type PanelSide = "left" | "right" | "top" | "bottom";
|
|
5
5
|
export declare const locatePanel: (page: Page, side: PanelSide) => Locator;
|
|
6
6
|
export declare const expandStagePanel: (page: Page, side: PanelSide, px: number) => Promise<void>;
|
|
7
|
+
export declare function takeScreenshot(page: Page, component: Locator): Promise<void>;
|
|
7
8
|
export {};
|
|
8
9
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1
5
|
import assert from "assert";
|
|
6
|
+
import { expect } from "@playwright/test";
|
|
2
7
|
export const locateNode = (tree, name) => tree.getByRole("treeitem", { name });
|
|
3
8
|
export const locateWidget = (page, widgetName) => page.locator(`.${widgetName}-widget`);
|
|
4
9
|
export const locatePanel = (page, side) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);
|
|
@@ -27,4 +32,9 @@ export const expandStagePanel = async (page, side, px) => {
|
|
|
27
32
|
}
|
|
28
33
|
await page.mouse.up();
|
|
29
34
|
};
|
|
35
|
+
export async function takeScreenshot(page, component) {
|
|
36
|
+
const boundingBox = await component.boundingBox();
|
|
37
|
+
assert(boundingBox);
|
|
38
|
+
await expect(page).toHaveScreenshot({ clip: boundingBox });
|
|
39
|
+
}
|
|
30
40
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACvG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAGhH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAE9G,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAE,IAAe,EAAE,EAAU,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,WAAW;SAChC,OAAO,CAAC,oBAAoB,CAAC;SAC7B,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,EAAE,CAAC;IACjB,MAAM,CAAC,SAAS,CAAC,CAAC;IAElB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAExB,QAAQ,IAAI,EAAE;QACZ,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;KACT;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAkB;IACjE,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,CAAC,WAAW,CAAC,CAAC;IACpB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC","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 assert from \"assert\";\nimport { expect } from \"@playwright/test\";\n\nimport type { Locator, Page } from \"@playwright/test\";\n\nexport const locateNode = (tree: Page | Locator, name: string) => tree.getByRole(\"treeitem\", { name });\nexport const locateWidget = (page: Page | Locator, widgetName: string) => page.locator(`.${widgetName}-widget`);\n\ntype PanelSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport const locatePanel = (page: Page, side: PanelSide) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);\n\nexport const expandStagePanel = async (page: Page, side: PanelSide, px: number) => {\n const widgetPanel = locatePanel(page, side);\n const handlePos = await widgetPanel\n .locator(\".nz-grip-container\")\n .locator(\".nz-handle\")\n .boundingBox();\n assert(handlePos);\n\n await page.mouse.move(handlePos.x, handlePos.y);\n await page.mouse.down();\n\n switch (side) {\n case \"left\":\n await page.mouse.move(handlePos.x + px, handlePos.y);\n break;\n case \"right\":\n await page.mouse.move(handlePos.x - px, handlePos.y);\n break;\n case \"top\":\n await page.mouse.move(handlePos.x, handlePos.y - px);\n break;\n case \"bottom\":\n await page.mouse.move(handlePos.x, handlePos.y + px);\n break;\n }\n await page.mouse.up();\n};\n\nexport async function takeScreenshot(page: Page, component: Locator) {\n const boundingBox = await component.boundingBox();\n assert(boundingBox);\n await expect(page).toHaveScreenshot({ clip: boundingBox });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/tree-widget-react",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Tree Widget React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Bentley",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@itwin/appui-abstract": "^4.0.0",
|
|
35
|
-
"@itwin/appui-layout-react": "^4.
|
|
36
|
-
"@itwin/appui-react": "^4.
|
|
35
|
+
"@itwin/appui-layout-react": "^4.5.0",
|
|
36
|
+
"@itwin/appui-react": "^4.5.0",
|
|
37
37
|
"@itwin/build-tools": "^4.0.0",
|
|
38
|
-
"@itwin/components-react": "^4.
|
|
38
|
+
"@itwin/components-react": "^4.5.0",
|
|
39
39
|
"@itwin/core-backend": "^4.0.0",
|
|
40
40
|
"@itwin/core-bentley": "^4.0.0",
|
|
41
41
|
"@itwin/core-common": "^4.0.0",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"@itwin/core-markup": "^4.0.0",
|
|
46
46
|
"@itwin/core-orbitgt": "^4.0.0",
|
|
47
47
|
"@itwin/core-quantity": "^4.0.0",
|
|
48
|
-
"@itwin/core-react": "^4.
|
|
48
|
+
"@itwin/core-react": "^4.5.0",
|
|
49
49
|
"@itwin/core-telemetry": "^4.0.0",
|
|
50
50
|
"@itwin/ecschema-metadata": "^4.0.0",
|
|
51
51
|
"@itwin/eslint-plugin": "^4.0.0-dev.38",
|
|
52
|
-
"@itwin/imodel-components-react": "^4.
|
|
52
|
+
"@itwin/imodel-components-react": "^4.5.0",
|
|
53
53
|
"@itwin/presentation-backend": "^4.0.0",
|
|
54
54
|
"@itwin/presentation-common": "^4.0.0",
|
|
55
55
|
"@itwin/presentation-components": "^4.1.0",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"cross-env": "^7.0.3",
|
|
83
83
|
"deep-equal": "^1.0.0",
|
|
84
84
|
"eslint": "^8.41.0",
|
|
85
|
-
"eslint-plugin-unused-imports": "^2.0.0",
|
|
86
85
|
"eslint-plugin-react": "^7.32.2",
|
|
86
|
+
"eslint-plugin-unused-imports": "^2.0.0",
|
|
87
87
|
"ignore-styles": "^5.0.1",
|
|
88
88
|
"jsdom": "^22.1.0",
|
|
89
89
|
"jsdom-global": "3.0.2",
|
|
@@ -98,6 +98,8 @@
|
|
|
98
98
|
"sinon": "^15.1.0",
|
|
99
99
|
"sinon-chai": "^3.7.0",
|
|
100
100
|
"source-map-support": "^0.5.6",
|
|
101
|
+
"stylelint": "^15.11.0",
|
|
102
|
+
"stylelint-config-standard-scss": "^11.1.0",
|
|
101
103
|
"typemoq": "^2.1.0",
|
|
102
104
|
"typescript": "~5.0.0",
|
|
103
105
|
"xmlhttprequest": "^1.8.0"
|
|
@@ -119,6 +121,7 @@
|
|
|
119
121
|
},
|
|
120
122
|
"scripts": {
|
|
121
123
|
"start:test-viewer": "node ./scripts/start-test-viewer.js",
|
|
124
|
+
"start:test-viewer:watch": "node ./scripts/start-test-viewer.js --watch",
|
|
122
125
|
"build": "npm run -s dual-build && npm run -s copy:assets",
|
|
123
126
|
"dual-build": "npm run -s build:cjs && npm run -s build:esm",
|
|
124
127
|
"build:cjs": "tsc 1>&2 --outDir lib/cjs",
|
|
@@ -129,11 +132,15 @@
|
|
|
129
132
|
"copy:esm": "cpx \"./src/**/*.{scss,json}\" ./lib/esm",
|
|
130
133
|
"cover": "nyc npm run test",
|
|
131
134
|
"extract-api": "betools extract-api --entry=tree-widget-react",
|
|
132
|
-
"lint": "eslint
|
|
133
|
-
"lint:
|
|
135
|
+
"lint": "npm run lint:eslint && npm run lint:stylelint",
|
|
136
|
+
"lint:eslint": "eslint -f visualstudio \"./src/**/*.{ts,tsx}\" 1>&2",
|
|
137
|
+
"lint:stylelint": "stylelint \"./src/**/*.scss\"",
|
|
138
|
+
"lint:fix": "npm run lint:eslint -- --fix && npm run lint:stylelint -- --fix",
|
|
134
139
|
"pseudolocalize": "betools pseudolocalize --englishDir ./public/locales/en --out ./lib/public/locales/en-PSEUDO",
|
|
135
140
|
"test": "mocha \"./lib/cjs/test/**/*.test.js\"",
|
|
136
|
-
"test:e2e": "
|
|
141
|
+
"test:e2e": "",
|
|
142
|
+
"//test:e2e": "node ../../../common/scripts/run-e2e-with-docker.js tree-widget",
|
|
143
|
+
"test:e2e:local": "node ../../../common/scripts/run-e2e-tests.js",
|
|
137
144
|
"test:e2e:debug": "cross-env PWDEBUG=1 playwright test --ui",
|
|
138
145
|
"clean": "rimraf lib .rush/temp/package-deps*.json",
|
|
139
146
|
"rebuild": "npm run clean && npm run build"
|