@itwin/tree-widget-react 0.1.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/LICENSE.md +9 -0
- package/README.md +32 -0
- package/lib/cjs/TreeWidget.d.ts +27 -0
- package/lib/cjs/TreeWidget.js +57 -0
- package/lib/cjs/TreeWidget.js.map +1 -0
- package/lib/cjs/components/IconButton.d.ts +14 -0
- package/lib/cjs/components/IconButton.js +42 -0
- package/lib/cjs/components/IconButton.js.map +1 -0
- package/lib/cjs/components/IconButton.scss +73 -0
- package/lib/cjs/components/TreeFilteringState.d.ts +16 -0
- package/lib/cjs/components/TreeFilteringState.js +67 -0
- package/lib/cjs/components/TreeFilteringState.js.map +1 -0
- package/lib/cjs/components/TreeWidgetComponent.d.ts +8 -0
- package/lib/cjs/components/TreeWidgetComponent.js +41 -0
- package/lib/cjs/components/TreeWidgetComponent.js.map +1 -0
- package/lib/cjs/components/TreeWidgetComponent.scss +64 -0
- package/lib/cjs/components/TreeWidgetControl.d.ts +25 -0
- package/lib/cjs/components/TreeWidgetControl.js +64 -0
- package/lib/cjs/components/TreeWidgetControl.js.map +1 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.d.ts +19 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.js +81 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.js.map +1 -0
- package/lib/cjs/components/header/TreeHeader.d.ts +14 -0
- package/lib/cjs/components/header/TreeHeader.js +43 -0
- package/lib/cjs/components/header/TreeHeader.js.map +1 -0
- package/lib/cjs/components/header/TreeHeader.scss +19 -0
- package/lib/cjs/components/rulesets/ClassificationSystems.json +122 -0
- package/lib/cjs/components/search-bar/Popup.d.ts +50 -0
- package/lib/cjs/components/search-bar/Popup.js +246 -0
- package/lib/cjs/components/search-bar/Popup.js.map +1 -0
- package/lib/cjs/components/search-bar/Popup.scss +316 -0
- package/lib/cjs/components/search-bar/SearchBar.d.ts +53 -0
- package/lib/cjs/components/search-bar/SearchBar.js +97 -0
- package/lib/cjs/components/search-bar/SearchBar.js.map +1 -0
- package/lib/cjs/components/search-bar/SearchBar.scss +110 -0
- package/lib/cjs/components/search-bar/SearchBox.d.ts +76 -0
- package/lib/cjs/components/search-bar/SearchBox.js +184 -0
- package/lib/cjs/components/search-bar/SearchBox.js.map +1 -0
- package/lib/cjs/components/search-bar/SearchBox.scss +91 -0
- package/lib/cjs/components/trees/CategoriesTree.d.ts +9 -0
- package/lib/cjs/components/trees/CategoriesTree.js +76 -0
- package/lib/cjs/components/trees/CategoriesTree.js.map +1 -0
- package/lib/cjs/components/trees/CategoriesTree.scss +13 -0
- package/lib/cjs/components/trees/ClassificationsTree.d.ts +6 -0
- package/lib/cjs/components/trees/ClassificationsTree.js +43 -0
- package/lib/cjs/components/trees/ClassificationsTree.js.map +1 -0
- package/lib/cjs/components/trees/ModelsTree.d.ts +10 -0
- package/lib/cjs/components/trees/ModelsTree.js +135 -0
- package/lib/cjs/components/trees/ModelsTree.js.map +1 -0
- package/lib/cjs/components/trees/ModelsTree.scss +14 -0
- package/lib/cjs/components/trees/SpatialTree.d.ts +3 -0
- package/lib/cjs/components/trees/SpatialTree.js +41 -0
- package/lib/cjs/components/trees/SpatialTree.js.map +1 -0
- package/lib/cjs/components/trees/TreeWithRuleset.d.ts +35 -0
- package/lib/cjs/components/trees/TreeWithRuleset.js +108 -0
- package/lib/cjs/components/trees/TreeWithRuleset.js.map +1 -0
- package/lib/cjs/components/trees/TreeWithRulesetTree.scss +17 -0
- package/lib/cjs/components/trees/index.d.ts +6 -0
- package/lib/cjs/components/trees/index.js +22 -0
- package/lib/cjs/components/trees/index.js.map +1 -0
- package/lib/cjs/tree-widget-react.d.ts +7 -0
- package/lib/cjs/tree-widget-react.js +23 -0
- package/lib/cjs/tree-widget-react.js.map +1 -0
- package/lib/esm/TreeWidget.d.ts +27 -0
- package/lib/esm/TreeWidget.js +53 -0
- package/lib/esm/TreeWidget.js.map +1 -0
- package/lib/esm/components/IconButton.d.ts +14 -0
- package/lib/esm/components/IconButton.js +16 -0
- package/lib/esm/components/IconButton.js.map +1 -0
- package/lib/esm/components/IconButton.scss +73 -0
- package/lib/esm/components/TreeFilteringState.d.ts +16 -0
- package/lib/esm/components/TreeFilteringState.js +44 -0
- package/lib/esm/components/TreeFilteringState.js.map +1 -0
- package/lib/esm/components/TreeWidgetComponent.d.ts +8 -0
- package/lib/esm/components/TreeWidgetComponent.js +18 -0
- package/lib/esm/components/TreeWidgetComponent.js.map +1 -0
- package/lib/esm/components/TreeWidgetComponent.scss +64 -0
- package/lib/esm/components/TreeWidgetControl.d.ts +25 -0
- package/lib/esm/components/TreeWidgetControl.js +57 -0
- package/lib/esm/components/TreeWidgetControl.js.map +1 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.d.ts +19 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.js +74 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.js.map +1 -0
- package/lib/esm/components/header/TreeHeader.d.ts +14 -0
- package/lib/esm/components/header/TreeHeader.js +20 -0
- package/lib/esm/components/header/TreeHeader.js.map +1 -0
- package/lib/esm/components/header/TreeHeader.scss +19 -0
- package/lib/esm/components/rulesets/ClassificationSystems.json +122 -0
- package/lib/esm/components/search-bar/Popup.d.ts +50 -0
- package/lib/esm/components/search-bar/Popup.js +220 -0
- package/lib/esm/components/search-bar/Popup.js.map +1 -0
- package/lib/esm/components/search-bar/Popup.scss +316 -0
- package/lib/esm/components/search-bar/SearchBar.d.ts +53 -0
- package/lib/esm/components/search-bar/SearchBar.js +71 -0
- package/lib/esm/components/search-bar/SearchBar.js.map +1 -0
- package/lib/esm/components/search-bar/SearchBar.scss +110 -0
- package/lib/esm/components/search-bar/SearchBox.d.ts +76 -0
- package/lib/esm/components/search-bar/SearchBox.js +158 -0
- package/lib/esm/components/search-bar/SearchBox.js.map +1 -0
- package/lib/esm/components/search-bar/SearchBox.scss +91 -0
- package/lib/esm/components/trees/CategoriesTree.d.ts +9 -0
- package/lib/esm/components/trees/CategoriesTree.js +53 -0
- package/lib/esm/components/trees/CategoriesTree.js.map +1 -0
- package/lib/esm/components/trees/CategoriesTree.scss +13 -0
- package/lib/esm/components/trees/ClassificationsTree.d.ts +6 -0
- package/lib/esm/components/trees/ClassificationsTree.js +17 -0
- package/lib/esm/components/trees/ClassificationsTree.js.map +1 -0
- package/lib/esm/components/trees/ModelsTree.d.ts +10 -0
- package/lib/esm/components/trees/ModelsTree.js +112 -0
- package/lib/esm/components/trees/ModelsTree.js.map +1 -0
- package/lib/esm/components/trees/ModelsTree.scss +14 -0
- package/lib/esm/components/trees/SpatialTree.d.ts +3 -0
- package/lib/esm/components/trees/SpatialTree.js +18 -0
- package/lib/esm/components/trees/SpatialTree.js.map +1 -0
- package/lib/esm/components/trees/TreeWithRuleset.d.ts +35 -0
- package/lib/esm/components/trees/TreeWithRuleset.js +83 -0
- package/lib/esm/components/trees/TreeWithRuleset.js.map +1 -0
- package/lib/esm/components/trees/TreeWithRulesetTree.scss +17 -0
- package/lib/esm/components/trees/index.d.ts +6 -0
- package/lib/esm/components/trees/index.js +10 -0
- package/lib/esm/components/trees/index.js.map +1 -0
- package/lib/esm/tree-widget-react.d.ts +7 -0
- package/lib/esm/tree-widget-react.js +11 -0
- package/lib/esm/tree-widget-react.js.map +1 -0
- package/lib/public/locales/en/TreeWidget.json +16 -0
- package/package.json +97 -0
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
/** @module SearchBox */
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import classnames from "classnames";
|
|
8
|
+
import { IconButton } from "../IconButton";
|
|
9
|
+
import "./SearchBox.scss";
|
|
10
|
+
import { TreeWidget } from "../../TreeWidget";
|
|
11
|
+
/**
|
|
12
|
+
* Enumeration of possible component contexts
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export var InputContext;
|
|
16
|
+
(function (InputContext) {
|
|
17
|
+
/** Component is ready to filter */
|
|
18
|
+
InputContext[InputContext["ReadyToFilter"] = 0] = "ReadyToFilter";
|
|
19
|
+
/** Component's parent is currently filtering */
|
|
20
|
+
InputContext[InputContext["FilteringInProgress"] = 1] = "FilteringInProgress";
|
|
21
|
+
/** Component's parent has finished filtering */
|
|
22
|
+
InputContext[InputContext["FilteringFinished"] = 2] = "FilteringFinished";
|
|
23
|
+
/** Component's parent has finished filtering, but ResultSelector(stepping through results) is not enabled */
|
|
24
|
+
InputContext[InputContext["FilteringFinishedWithNoStepping"] = 3] = "FilteringFinishedWithNoStepping";
|
|
25
|
+
})(InputContext || (InputContext = {}));
|
|
26
|
+
export class SearchBox extends React.PureComponent {
|
|
27
|
+
constructor(props) {
|
|
28
|
+
super(props);
|
|
29
|
+
this._inputElement = null;
|
|
30
|
+
this._timeoutId = 0;
|
|
31
|
+
this._trackChange = (_event) => {
|
|
32
|
+
let searchText = "";
|
|
33
|
+
// istanbul ignore else
|
|
34
|
+
if (this._inputElement)
|
|
35
|
+
searchText = this._inputElement.value;
|
|
36
|
+
this.setState((_prevState) => {
|
|
37
|
+
return { searchText };
|
|
38
|
+
}, () => {
|
|
39
|
+
if (this.props.valueChangedDelay) {
|
|
40
|
+
this._unsetTimeout();
|
|
41
|
+
this._timeoutId = window.setTimeout(() => {
|
|
42
|
+
this.setState({
|
|
43
|
+
context: InputContext.ReadyToFilter,
|
|
44
|
+
selectedIndex: 0,
|
|
45
|
+
});
|
|
46
|
+
this.props.onSelectedChanged(0);
|
|
47
|
+
this.props.onFilterStart(this.state.searchText);
|
|
48
|
+
}, this.props.valueChangedDelay);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.setState({ context: InputContext.ReadyToFilter });
|
|
52
|
+
this.props.onFilterStart(this.state.searchText);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
this._handleKeyDown = (e) => {
|
|
57
|
+
switch (e.key) {
|
|
58
|
+
case "Escape":
|
|
59
|
+
// istanbul ignore else
|
|
60
|
+
if (this.props.onEscPressed)
|
|
61
|
+
this.props.onEscPressed();
|
|
62
|
+
break;
|
|
63
|
+
case "Enter":
|
|
64
|
+
// istanbul ignore else
|
|
65
|
+
if (this.props.onEnterPressed)
|
|
66
|
+
this.props.onEnterPressed();
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
this._handleIconClick = (_event) => {
|
|
71
|
+
// istanbul ignore else
|
|
72
|
+
if (this._inputElement) {
|
|
73
|
+
const clear = this.state.searchText !== "";
|
|
74
|
+
this._inputElement.value = "";
|
|
75
|
+
// istanbul ignore else
|
|
76
|
+
if (clear && this.props.onClear)
|
|
77
|
+
this.props.onClear();
|
|
78
|
+
this._inputElement.focus();
|
|
79
|
+
}
|
|
80
|
+
this._trackChange();
|
|
81
|
+
if (this.props.onIconClick)
|
|
82
|
+
this.props.onIconClick();
|
|
83
|
+
};
|
|
84
|
+
this._unsetTimeout = () => {
|
|
85
|
+
if (this._timeoutId) {
|
|
86
|
+
window.clearTimeout(this._timeoutId);
|
|
87
|
+
this._timeoutId = 0;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
this._onPrevClick = () => {
|
|
91
|
+
if (this.state.selectedIndex > 1) {
|
|
92
|
+
this.props.onSelectedChanged(this.state.selectedIndex - 1);
|
|
93
|
+
this.setState((state) => ({ selectedIndex: state.selectedIndex - 1 }));
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
this._onNextClick = () => {
|
|
97
|
+
if (this.state.selectedIndex < this.props.resultCount) {
|
|
98
|
+
this.props.onSelectedChanged(this.state.selectedIndex + 1);
|
|
99
|
+
this.setState((state) => ({ selectedIndex: state.selectedIndex + 1 }));
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
this.state = {
|
|
103
|
+
searchText: this.props.searchText,
|
|
104
|
+
context: InputContext.ReadyToFilter,
|
|
105
|
+
selectedIndex: 0,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
focus() {
|
|
109
|
+
// istanbul ignore else
|
|
110
|
+
if (this._inputElement) {
|
|
111
|
+
this._inputElement.focus();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async componentDidUpdate(prevProps) {
|
|
115
|
+
if (prevProps.searchText !== this.props.searchText) {
|
|
116
|
+
const searchText = this.props.searchText;
|
|
117
|
+
this.setState({ searchText });
|
|
118
|
+
}
|
|
119
|
+
this.focus();
|
|
120
|
+
}
|
|
121
|
+
componentWillUnmount() {
|
|
122
|
+
this._unsetTimeout();
|
|
123
|
+
}
|
|
124
|
+
/** @internal */
|
|
125
|
+
static getDerivedStateFromProps(props, state) {
|
|
126
|
+
if (state.context === InputContext.FilteringInProgress &&
|
|
127
|
+
!props.filteringInProgress) {
|
|
128
|
+
if (state.searchText)
|
|
129
|
+
return { context: InputContext.FilteringFinished };
|
|
130
|
+
else
|
|
131
|
+
return { context: InputContext.FilteringFinishedWithNoStepping };
|
|
132
|
+
}
|
|
133
|
+
else if (state.context === InputContext.ReadyToFilter &&
|
|
134
|
+
props.filteringInProgress) {
|
|
135
|
+
return { context: InputContext.FilteringInProgress };
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
render() {
|
|
140
|
+
const { autoFocus, className, style, resultCount, placeholder, } = this.props;
|
|
141
|
+
const { searchText, selectedIndex } = this.state;
|
|
142
|
+
const searchClassName = classnames("tree-widget-searchbox", className);
|
|
143
|
+
const showCount = resultCount > 0;
|
|
144
|
+
const isPrevEnabled = selectedIndex > 1;
|
|
145
|
+
const isNextEnabled = selectedIndex < resultCount;
|
|
146
|
+
return (React.createElement("div", { className: searchClassName, style: style },
|
|
147
|
+
React.createElement("input", { value: searchText, ref: (el) => {
|
|
148
|
+
this._inputElement = el;
|
|
149
|
+
}, autoFocus: autoFocus, onChange: this._trackChange, onKeyDown: this._handleKeyDown, onPaste: this._trackChange, onCut: this._trackChange, placeholder: placeholder ? placeholder : TreeWidget.translate("searchbox.search") }),
|
|
150
|
+
React.createElement("div", { className: "searchbox-stepping-container" },
|
|
151
|
+
showCount && (React.createElement("span", { className: "searchbox-stepping-count" }, `${selectedIndex}/${resultCount}`)),
|
|
152
|
+
React.createElement("div", { className: "searchbox-separator" }),
|
|
153
|
+
React.createElement(IconButton, { className: "searchbox-step-button", icon: "icon-chevron-up", disabled: !isPrevEnabled, onClick: this._onPrevClick, title: "Previous" }),
|
|
154
|
+
React.createElement(IconButton, { className: "searchbox-step-button", icon: "icon-chevron-down", disabled: !isNextEnabled, onClick: this._onNextClick, title: "Next" })),
|
|
155
|
+
React.createElement("span", { className: "searchbox-step-button icon icon-close searchbox-close-button", onClick: this._handleIconClick })));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=SearchBox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchBox.js","sourceRoot":"","sources":["../../../../src/components/search-bar/SearchBox.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/** @module SearchBox */\n\nimport * as React from \"react\";\nimport classnames from \"classnames\";\nimport { CommonProps } from \"@itwin/core-react\";\nimport { IconButton } from \"../IconButton\";\nimport \"./SearchBox.scss\";\nimport { TreeWidget } from \"../../TreeWidget\";\n\nexport interface SearchBoxProps extends CommonProps {\n /** value to set SearchBox */\n searchText?: string;\n /** placeholder value to show in gray before anything is entered in */\n placeholder?: string;\n /** frequency to poll for changes in value */\n valueChangedDelay?: number;\n /** listens for <Enter> keypress */\n onEnterPressed?: () => void;\n /** listens for <Esc> keypress */\n onEscPressed?: () => void;\n /** listens for onClick event for Clear (x) icon */\n onClear?: () => void;\n /** Search or clear icon click */\n onIconClick?: () => void;\n /** Filtering is cleared after everything's loaded */\n onFilterStart: (newFilter: string) => void;\n /** Filtering is cleared after everything's loaded */\n onFilterClear?: () => void;\n /** Filtering is cleared after everything's loaded */\n onFilterCancel?: () => void;\n /** Tells the component if parent component is still handling the filtering */\n filteringInProgress?: boolean;\n /** Total number of results/entries */\n resultCount: number;\n /** Callback to currently selected result/entry change */\n onSelectedChanged: (index: number) => void;\n /** Specify that the <input> element should automatically get focus */\n autoFocus?: boolean;\n}\n\n/**\n * Enumeration of possible component contexts\n * @internal\n */\nexport enum InputContext {\n /** Component is ready to filter */\n ReadyToFilter,\n /** Component's parent is currently filtering */\n FilteringInProgress,\n /** Component's parent has finished filtering */\n FilteringFinished,\n /** Component's parent has finished filtering, but ResultSelector(stepping through results) is not enabled */\n FilteringFinishedWithNoStepping,\n}\n\ninterface SearchBoxState {\n searchText?: string;\n /** @internal */\n context: InputContext;\n /** Currently selected index */\n selectedIndex: number;\n}\n\nexport class SearchBox extends React.PureComponent<\n SearchBoxProps,\n SearchBoxState\n> {\n private _inputElement: HTMLInputElement | null = null;\n private _timeoutId: number = 0;\n\n constructor(props: SearchBoxProps) {\n super(props);\n\n this.state = {\n searchText: this.props.searchText,\n context: InputContext.ReadyToFilter,\n selectedIndex: 0,\n };\n }\n\n public focus() {\n // istanbul ignore else\n if (this._inputElement) {\n this._inputElement.focus();\n }\n }\n\n private _trackChange = (_event?: any): void => {\n let searchText = \"\";\n\n // istanbul ignore else\n if (this._inputElement) searchText = this._inputElement.value;\n\n this.setState(\n (_prevState) => {\n return { searchText };\n },\n () => {\n if (this.props.valueChangedDelay) {\n this._unsetTimeout();\n this._timeoutId = window.setTimeout(() => {\n this.setState({\n context: InputContext.ReadyToFilter,\n selectedIndex: 0,\n });\n this.props.onSelectedChanged(0);\n this.props.onFilterStart(this.state.searchText!);\n }, this.props.valueChangedDelay);\n } else {\n this.setState({ context: InputContext.ReadyToFilter });\n this.props.onFilterStart(this.state.searchText!);\n }\n }\n );\n };\n\n private _handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case \"Escape\":\n // istanbul ignore else\n if (this.props.onEscPressed) this.props.onEscPressed();\n break;\n case \"Enter\":\n // istanbul ignore else\n if (this.props.onEnterPressed) this.props.onEnterPressed();\n break;\n }\n };\n\n private _handleIconClick = (_event: React.MouseEvent<HTMLElement>): void => {\n // istanbul ignore else\n if (this._inputElement) {\n const clear = this.state.searchText !== \"\";\n this._inputElement.value = \"\";\n // istanbul ignore else\n if (clear && this.props.onClear) this.props.onClear();\n this._inputElement.focus();\n }\n this._trackChange();\n if (this.props.onIconClick) this.props.onIconClick();\n };\n\n private _unsetTimeout = (): void => {\n if (this._timeoutId) {\n window.clearTimeout(this._timeoutId);\n this._timeoutId = 0;\n }\n };\n\n public async componentDidUpdate(prevProps: SearchBoxProps) {\n if (prevProps.searchText !== this.props.searchText) {\n const searchText = this.props.searchText;\n this.setState({ searchText });\n }\n\n this.focus();\n }\n\n public componentWillUnmount() {\n this._unsetTimeout();\n }\n\n /** @internal */\n public static getDerivedStateFromProps(\n props: SearchBoxProps,\n state: SearchBoxState\n ) {\n if (\n state.context === InputContext.FilteringInProgress &&\n !props.filteringInProgress\n ) {\n if (state.searchText) return { context: InputContext.FilteringFinished };\n else return { context: InputContext.FilteringFinishedWithNoStepping };\n } else if (\n state.context === InputContext.ReadyToFilter &&\n props.filteringInProgress\n ) {\n return { context: InputContext.FilteringInProgress };\n }\n return null;\n }\n\n private _onPrevClick = () => {\n if (this.state.selectedIndex > 1) {\n this.props.onSelectedChanged(this.state.selectedIndex - 1);\n this.setState((state) => ({ selectedIndex: state.selectedIndex - 1 }));\n }\n };\n\n private _onNextClick = () => {\n if (this.state.selectedIndex < this.props.resultCount) {\n this.props.onSelectedChanged(this.state.selectedIndex + 1);\n this.setState((state) => ({ selectedIndex: state.selectedIndex + 1 }));\n }\n };\n\n public render() {\n const {\n autoFocus,\n className,\n style,\n resultCount,\n placeholder,\n } = this.props;\n const { searchText, selectedIndex } = this.state;\n const searchClassName = classnames(\"tree-widget-searchbox\", className);\n const showCount = resultCount > 0;\n const isPrevEnabled = selectedIndex > 1;\n const isNextEnabled = selectedIndex < resultCount;\n\n return (\n <div className={searchClassName} style={style}>\n <input\n value={searchText}\n ref={(el) => {\n this._inputElement = el;\n }}\n autoFocus={autoFocus}\n onChange={this._trackChange}\n onKeyDown={this._handleKeyDown}\n onPaste={this._trackChange}\n onCut={this._trackChange}\n placeholder={\n placeholder ? placeholder : TreeWidget.translate(\"searchbox.search\")\n }\n />\n <div className=\"searchbox-stepping-container\">\n {showCount && (\n <span className=\"searchbox-stepping-count\">{`${selectedIndex}/${resultCount}`}</span>\n )}\n <div className=\"searchbox-separator\" />\n <IconButton\n className=\"searchbox-step-button\"\n icon=\"icon-chevron-up\"\n disabled={!isPrevEnabled}\n onClick={this._onPrevClick}\n title=\"Previous\"\n />\n <IconButton\n className=\"searchbox-step-button\"\n icon=\"icon-chevron-down\"\n disabled={!isNextEnabled}\n onClick={this._onNextClick}\n title=\"Next\"\n />\n </div>\n <span\n className=\"searchbox-step-button icon icon-close searchbox-close-button\"\n onClick={this._handleIconClick}\n />\n </div>\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
@import "~@itwin/core-react/lib/esm/core-react/index";
|
|
6
|
+
|
|
7
|
+
.tree-widget-searchbox {
|
|
8
|
+
@include uicore-font-family;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
position: relative;
|
|
12
|
+
//default values (height, width, font-size, color)
|
|
13
|
+
height: 34px;
|
|
14
|
+
width: 12em;
|
|
15
|
+
font-size: $uicore-font-size;
|
|
16
|
+
color: $buic-text-color-reverse;
|
|
17
|
+
background: $buic-background-control;
|
|
18
|
+
border: 1px solid $buic-inputs-border;
|
|
19
|
+
|
|
20
|
+
input {
|
|
21
|
+
padding: 0 $uicore-s;
|
|
22
|
+
height: 100%;
|
|
23
|
+
width: 100%;
|
|
24
|
+
flex: 1;
|
|
25
|
+
background: $buic-background-control;
|
|
26
|
+
margin-right: $uicore-s;
|
|
27
|
+
color: $buic-text-color;
|
|
28
|
+
font-size: inherit;
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
border: 0;
|
|
31
|
+
|
|
32
|
+
&::placeholder {
|
|
33
|
+
color: $buic-foreground-disabled;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:focus-within,
|
|
37
|
+
&:focus,
|
|
38
|
+
&:active,
|
|
39
|
+
&[disabled],
|
|
40
|
+
&[disabled]:hover,
|
|
41
|
+
&[disabled]:active,
|
|
42
|
+
&[disabled]:focus {
|
|
43
|
+
border: 0;
|
|
44
|
+
outline: none;
|
|
45
|
+
outline-width: 0;
|
|
46
|
+
box-shadow: none;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.searchbox-stepping-container {
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
right: 32px;
|
|
54
|
+
height: 100%;
|
|
55
|
+
|
|
56
|
+
.searchbox-stepping-count {
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
color: $buic-text-color;
|
|
59
|
+
margin-right: $uicore-xs;
|
|
60
|
+
position: relative;
|
|
61
|
+
word-wrap: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.searchbox-separator {
|
|
65
|
+
height: 75%;
|
|
66
|
+
width: 1px;
|
|
67
|
+
margin: 0 $uicore-s;
|
|
68
|
+
background: $buic-inputs-border;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.searchbox-step-button {
|
|
73
|
+
height: 100%;
|
|
74
|
+
width: 32px;
|
|
75
|
+
display: flex;
|
|
76
|
+
align-items: center;
|
|
77
|
+
justify-content: center;
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
color: $buic-icon-color;
|
|
80
|
+
font-size: $uicore-font-size-small;
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
|
|
83
|
+
&:hover {
|
|
84
|
+
color: $buic-accessory-primary;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.searchbox-close-button {
|
|
89
|
+
z-index: 1000;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IModelConnection, Viewport } from "@itwin/core-frontend";
|
|
2
|
+
import "./CategoriesTree.scss";
|
|
3
|
+
export interface CategoriesTreeComponentProps {
|
|
4
|
+
iModel: IModelConnection;
|
|
5
|
+
allViewports?: boolean;
|
|
6
|
+
activeView?: Viewport;
|
|
7
|
+
}
|
|
8
|
+
export declare function CategoriesTreeComponent(props: CategoriesTreeComponentProps): JSX.Element;
|
|
9
|
+
//# sourceMappingURL=CategoriesTree.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import React, { useCallback, useState } from "react";
|
|
6
|
+
import { IModelApp, } from "@itwin/core-frontend";
|
|
7
|
+
import { CategoryTree, toggleAllCategories, getCategories, } from "@itwin/appui-react";
|
|
8
|
+
import { useTreeFilteringState } from "../TreeFilteringState";
|
|
9
|
+
import "./CategoriesTree.scss";
|
|
10
|
+
import { TreeHeaderComponent } from "../header/TreeHeader";
|
|
11
|
+
import { CategoryVisibilityHandler } from "@itwin/appui-react";
|
|
12
|
+
import { useResizeObserver } from "@itwin/core-react";
|
|
13
|
+
export function CategoriesTreeComponent(props) {
|
|
14
|
+
const { searchOptions, filterString, activeMatchIndex, onFilterApplied, filteredProvider, } = useTreeFilteringState();
|
|
15
|
+
const [height, setHeight] = useState(0);
|
|
16
|
+
const [width, setWidth] = useState(0);
|
|
17
|
+
const handleResize = useCallback((w, h) => {
|
|
18
|
+
setHeight(h);
|
|
19
|
+
setWidth(w);
|
|
20
|
+
}, []);
|
|
21
|
+
const ref = useResizeObserver(handleResize);
|
|
22
|
+
const showAll = useCallback(async () => {
|
|
23
|
+
return toggleAllCategories(IModelApp.viewManager, props.iModel, true, undefined, true, filteredProvider);
|
|
24
|
+
}, [props.iModel, filteredProvider]);
|
|
25
|
+
const hideAll = useCallback(async () => {
|
|
26
|
+
return toggleAllCategories(IModelApp.viewManager, props.iModel, false, undefined, true, filteredProvider);
|
|
27
|
+
}, [props.iModel, filteredProvider]);
|
|
28
|
+
const invert = useCallback(async () => {
|
|
29
|
+
const activeView = IModelApp.viewManager.getFirstOpenView();
|
|
30
|
+
if (!activeView) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const ids = await getCategories(props.iModel, activeView, filteredProvider);
|
|
34
|
+
let enabled = [];
|
|
35
|
+
let disabled = [];
|
|
36
|
+
for (const id of ids) {
|
|
37
|
+
if (activeView.view.viewsCategory(id)) {
|
|
38
|
+
enabled.push(id);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
disabled.push(id);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Disable enabled
|
|
45
|
+
CategoryVisibilityHandler.enableCategory(IModelApp.viewManager, props.iModel, enabled, false, true);
|
|
46
|
+
// Enable disabled
|
|
47
|
+
CategoryVisibilityHandler.enableCategory(IModelApp.viewManager, props.iModel, disabled, true, true);
|
|
48
|
+
}, [props.iModel, filteredProvider]);
|
|
49
|
+
return (React.createElement(React.Fragment, null,
|
|
50
|
+
React.createElement(TreeHeaderComponent, { searchOptions: searchOptions, showAll: showAll, hideAll: hideAll, invert: invert }),
|
|
51
|
+
React.createElement("div", { ref: ref, style: { width: "100%", height: "100%" } }, width && height && (React.createElement(CategoryTree, { ...props, filterInfo: { filter: filterString, activeMatchIndex }, onFilterApplied: onFilterApplied, width: width, height: height })))));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=CategoriesTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../src/components/trees/CategoriesTree.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*--------------------------------------------------------------------------------------------*/\nimport React, { useCallback, useState } from \"react\";\nimport {\n IModelApp,\n IModelConnection,\n Viewport,\n} from \"@itwin/core-frontend\";\nimport {\n CategoryTree,\n toggleAllCategories,\n getCategories,\n} from \"@itwin/appui-react\";\nimport { useTreeFilteringState } from \"../TreeFilteringState\";\nimport \"./CategoriesTree.scss\";\nimport { TreeHeaderComponent } from \"../header/TreeHeader\";\nimport { CategoryVisibilityHandler } from \"@itwin/appui-react\";\nimport { useResizeObserver } from \"@itwin/core-react\";\n\nexport interface CategoriesTreeComponentProps {\n iModel: IModelConnection;\n allViewports?: boolean;\n activeView?: Viewport;\n}\n\nexport function CategoriesTreeComponent(props: CategoriesTreeComponentProps) {\n const {\n searchOptions,\n filterString,\n activeMatchIndex,\n onFilterApplied,\n filteredProvider,\n } = useTreeFilteringState();\n\n const [height, setHeight] = useState(0);\n const [width, setWidth] = useState(0);\n const handleResize = useCallback((w: number, h: number) => {\n setHeight(h);\n setWidth(w);\n }, []);\n const ref = useResizeObserver<HTMLDivElement>(handleResize);\n\n const showAll = useCallback(async () => {\n return toggleAllCategories(\n IModelApp.viewManager,\n props.iModel,\n true,\n undefined,\n true,\n filteredProvider\n );\n }, [props.iModel, filteredProvider]);\n\n const hideAll = useCallback(async () => {\n return toggleAllCategories(\n IModelApp.viewManager,\n props.iModel,\n false,\n undefined,\n true,\n filteredProvider\n );\n }, [props.iModel, filteredProvider]);\n\n const invert = useCallback(async () => {\n const activeView = IModelApp.viewManager.getFirstOpenView();\n if (!activeView) {\n return;\n }\n\n const ids = await getCategories(props.iModel, activeView, filteredProvider);\n let enabled: string[] = [];\n let disabled: string[] = [];\n for (const id of ids) {\n if (activeView.view.viewsCategory(id)) {\n enabled.push(id);\n } else {\n disabled.push(id);\n }\n }\n // Disable enabled\n CategoryVisibilityHandler.enableCategory(\n IModelApp.viewManager,\n props.iModel,\n enabled,\n false,\n true\n );\n // Enable disabled\n CategoryVisibilityHandler.enableCategory(\n IModelApp.viewManager,\n props.iModel,\n disabled,\n true,\n true\n );\n }, [props.iModel, filteredProvider]);\n\n return (\n <>\n <TreeHeaderComponent\n searchOptions={searchOptions}\n showAll={showAll}\n hideAll={hideAll}\n invert={invert}\n />\n <div ref={ref} style={{ width: \"100%\", height: \"100%\" }}>\n {width && height && (\n <CategoryTree\n {...props}\n filterInfo={{ filter: filterString, activeMatchIndex }}\n onFilterApplied={onFilterApplied}\n width={width}\n height={height}\n />\n )}\n </div>\n </>\n );\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
@import "~@itwin/core-react/lib/esm/core-react/index";
|
|
6
|
+
|
|
7
|
+
.tree-widget-category-tree-search-bar {
|
|
8
|
+
margin-bottom: $uicore-s;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.tree-widget-category-tree-toolbar-icon {
|
|
12
|
+
color: $buic-icon-color;
|
|
13
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IModelConnection } from "@itwin/core-frontend";
|
|
2
|
+
export interface ClassificationsTreeComponentProps {
|
|
3
|
+
iModel: IModelConnection;
|
|
4
|
+
}
|
|
5
|
+
export declare function ClassificationsTreeComponent(props: ClassificationsTreeComponentProps): JSX.Element;
|
|
6
|
+
//# sourceMappingURL=ClassificationsTree.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { SimpleTreeWithRuleset } from "./TreeWithRuleset";
|
|
7
|
+
import { PresentationTreeDataProvider } from "@itwin/presentation-components";
|
|
8
|
+
import classificationRules from "../rulesets/ClassificationSystems.json";
|
|
9
|
+
export function ClassificationsTreeComponent(props) {
|
|
10
|
+
const dataProvider = new PresentationTreeDataProvider({
|
|
11
|
+
imodel: props.iModel,
|
|
12
|
+
ruleset: classificationRules.id,
|
|
13
|
+
pagingSize: 20,
|
|
14
|
+
});
|
|
15
|
+
return (React.createElement(SimpleTreeWithRuleset, { imodel: props.iModel, ruleSet: classificationRules, dataProvider: dataProvider }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=ClassificationsTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClassificationsTree.js","sourceRoot":"","sources":["../../../../src/components/trees/ClassificationsTree.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,mBAAmB,MAAM,wCAAwC,CAAC;AAMzE,MAAM,UAAU,4BAA4B,CAC1C,KAAwC;IAExC,MAAM,YAAY,GAAG,IAAI,4BAA4B,CAAC;QACpD,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,mBAAmB,CAAC,EAAE;QAC/B,UAAU,EAAE,EAAE;KACf,CAAC,CAAC;IAEH,OAAO,CACL,oBAAC,qBAAqB,IACpB,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,OAAO,EAAE,mBAA8B,EACvC,YAAY,EAAE,YAAY,GAC1B,CACH,CAAC;AACJ,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*--------------------------------------------------------------------------------------------*/\nimport * as React from \"react\";\nimport { Ruleset } from \"@itwin/presentation-common\";\nimport { SimpleTreeWithRuleset } from \"./TreeWithRuleset\";\nimport { IModelConnection } from \"@itwin/core-frontend\";\nimport { PresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport classificationRules from \"../rulesets/ClassificationSystems.json\";\n\nexport interface ClassificationsTreeComponentProps {\n iModel: IModelConnection;\n}\n\nexport function ClassificationsTreeComponent(\n props: ClassificationsTreeComponentProps\n) {\n const dataProvider = new PresentationTreeDataProvider({\n imodel: props.iModel,\n ruleset: classificationRules.id,\n pagingSize: 20,\n });\n\n return (\n <SimpleTreeWithRuleset\n imodel={props.iModel}\n ruleSet={classificationRules as Ruleset}\n dataProvider={dataProvider}\n />\n );\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IModelConnection, Viewport } from "@itwin/core-frontend";
|
|
2
|
+
import "./ModelsTree.scss";
|
|
3
|
+
export interface ModelTreeProps {
|
|
4
|
+
iModel: IModelConnection;
|
|
5
|
+
allViewports?: boolean;
|
|
6
|
+
activeView?: Viewport;
|
|
7
|
+
enableElementsClassGrouping?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const ModelsTreeComponent: (props: ModelTreeProps) => JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=ModelsTree.d.ts.map
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
6
|
+
import { ModelsTree, ClassGroupingOption, useActiveViewport } from "@itwin/appui-react";
|
|
7
|
+
import { useTreeFilteringState } from "../TreeFilteringState";
|
|
8
|
+
import "./ModelsTree.scss";
|
|
9
|
+
import { TreeHeaderComponent } from "../header/TreeHeader";
|
|
10
|
+
import { useResizeObserver } from "@itwin/core-react";
|
|
11
|
+
export const ModelsTreeComponent = (props) => {
|
|
12
|
+
const { iModel } = props;
|
|
13
|
+
const [is2dToggleActive, setIs2dToggleActive] = useState(false);
|
|
14
|
+
const [is3dToggleActive, setIs3dToggleActive] = useState(false);
|
|
15
|
+
const [icon2dToggle, setIcon2dToggle] = useState("icon-visibility");
|
|
16
|
+
const [icon3dToggle, setIcon3dToggle] = useState("icon-visibility");
|
|
17
|
+
const [available2dModels, setAvailable2dModels] = useState([]);
|
|
18
|
+
const [available3dModels, setAvailable3dModels] = useState([]);
|
|
19
|
+
const [availableModels, setAvailableModels] = useState([]);
|
|
20
|
+
const viewport = useActiveViewport();
|
|
21
|
+
const { searchOptions, filterString, activeMatchIndex, onFilterApplied } = useTreeFilteringState();
|
|
22
|
+
const [height, setHeight] = useState(0);
|
|
23
|
+
const [width, setWidth] = useState(0);
|
|
24
|
+
const handleResize = useCallback((w, h) => {
|
|
25
|
+
setHeight(h);
|
|
26
|
+
setWidth(w);
|
|
27
|
+
}, []);
|
|
28
|
+
const ref = useResizeObserver(handleResize);
|
|
29
|
+
const queryModels = useCallback(async (vp) => {
|
|
30
|
+
if (vp === undefined)
|
|
31
|
+
return [];
|
|
32
|
+
const queryParams = {
|
|
33
|
+
from: "BisCore.GeometricModel3d",
|
|
34
|
+
wantPrivate: false,
|
|
35
|
+
};
|
|
36
|
+
const modelProps = await iModel.models.queryProps(queryParams);
|
|
37
|
+
return modelProps
|
|
38
|
+
.map(({ id, isPlanProjection }) => ({ id, isPlanProjection }))
|
|
39
|
+
.filter(({ id }) => id);
|
|
40
|
+
}, [iModel]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
queryModels(viewport)
|
|
43
|
+
.then((modelInfos) => {
|
|
44
|
+
setAvailableModels(modelInfos.map(({ id }) => id));
|
|
45
|
+
const { models2d, models3d } = modelInfos.reduce((acc, { id, isPlanProjection }) => {
|
|
46
|
+
isPlanProjection ? acc.models2d.push(id) : acc.models3d.push(id);
|
|
47
|
+
return acc;
|
|
48
|
+
}, { models2d: [], models3d: [] });
|
|
49
|
+
setAvailable2dModels(models2d);
|
|
50
|
+
setAvailable3dModels(models3d);
|
|
51
|
+
})
|
|
52
|
+
.catch((_e) => {
|
|
53
|
+
setAvailableModels([]);
|
|
54
|
+
});
|
|
55
|
+
}, [queryModels, viewport]);
|
|
56
|
+
const invert = useCallback(async () => {
|
|
57
|
+
if (availableModels.length === 0)
|
|
58
|
+
return;
|
|
59
|
+
const notViewedModels = [];
|
|
60
|
+
const models = [];
|
|
61
|
+
availableModels.forEach((id) => {
|
|
62
|
+
if (viewport === null || viewport === void 0 ? void 0 : viewport.viewsModel(id))
|
|
63
|
+
models.push(id);
|
|
64
|
+
else
|
|
65
|
+
notViewedModels.push(id);
|
|
66
|
+
});
|
|
67
|
+
await (viewport === null || viewport === void 0 ? void 0 : viewport.addViewedModels(notViewedModels));
|
|
68
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.changeModelDisplay(models, false);
|
|
69
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.invalidateScene();
|
|
70
|
+
}, [viewport, availableModels]);
|
|
71
|
+
const hideAll = useCallback(() => {
|
|
72
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.changeModelDisplay(availableModels, false);
|
|
73
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.invalidateScene();
|
|
74
|
+
}, [viewport, availableModels]);
|
|
75
|
+
const showAll = useCallback(async () => {
|
|
76
|
+
await (viewport === null || viewport === void 0 ? void 0 : viewport.addViewedModels(availableModels));
|
|
77
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.invalidateScene();
|
|
78
|
+
}, [viewport, availableModels]);
|
|
79
|
+
const viewToggle2D = useCallback(async () => {
|
|
80
|
+
if (is2dToggleActive) {
|
|
81
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.changeModelDisplay(available2dModels, false);
|
|
82
|
+
setIs2dToggleActive(false);
|
|
83
|
+
setIcon2dToggle("icon-visibility-hide-2");
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
await (viewport === null || viewport === void 0 ? void 0 : viewport.addViewedModels(available2dModels));
|
|
87
|
+
setIs2dToggleActive(true);
|
|
88
|
+
setIcon2dToggle("icon-visibility");
|
|
89
|
+
}
|
|
90
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.invalidateScene();
|
|
91
|
+
}, [is2dToggleActive, viewport, available2dModels]);
|
|
92
|
+
const viewToggle3D = useCallback(async () => {
|
|
93
|
+
if (is3dToggleActive) {
|
|
94
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.changeModelDisplay(available3dModels, false);
|
|
95
|
+
setIs3dToggleActive(false);
|
|
96
|
+
setIcon3dToggle("icon-visibility-hide-2");
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
await (viewport === null || viewport === void 0 ? void 0 : viewport.addViewedModels(available3dModels));
|
|
100
|
+
setIs3dToggleActive(true);
|
|
101
|
+
setIcon3dToggle("icon-visibility");
|
|
102
|
+
}
|
|
103
|
+
viewport === null || viewport === void 0 ? void 0 : viewport.invalidateScene();
|
|
104
|
+
}, [is3dToggleActive, viewport, available3dModels]);
|
|
105
|
+
return (!(iModel && viewport) ? null : (React.createElement(React.Fragment, null,
|
|
106
|
+
React.createElement(TreeHeaderComponent, { searchOptions: searchOptions, showAll: showAll, hideAll: hideAll, invert: invert, toggle2D: viewToggle2D, toggle2DIcon: icon2dToggle, toggle3D: viewToggle3D, toggle3DIcon: icon3dToggle }),
|
|
107
|
+
React.createElement("div", { className: "tree-widget-models-tree-container" },
|
|
108
|
+
React.createElement("div", { ref: ref, style: { width: "100%", height: "100%" } }, width && height && (React.createElement(ModelsTree, { ...props, filterInfo: { filter: filterString, activeMatchIndex }, onFilterApplied: onFilterApplied, activeView: viewport, enableElementsClassGrouping: props.enableElementsClassGrouping
|
|
109
|
+
? ClassGroupingOption.YesWithCounts
|
|
110
|
+
: ClassGroupingOption.No, width: width, height: height })))))));
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=ModelsTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../src/components/trees/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 React, { useCallback, useEffect, useState } from \"react\";\nimport { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport { ModelsTree, ClassGroupingOption, useActiveViewport } from \"@itwin/appui-react\";\nimport { useTreeFilteringState } from \"../TreeFilteringState\";\nimport \"./ModelsTree.scss\";\nimport {\n GeometricModel3dProps,\n ModelQueryParams,\n} from \"@itwin/core-common\";\nimport { TreeHeaderComponent } from \"../header/TreeHeader\";\nimport { useResizeObserver } from \"@itwin/core-react\";\n\nexport interface ModelTreeProps {\n iModel: IModelConnection;\n allViewports?: boolean;\n activeView?: Viewport;\n enableElementsClassGrouping?: boolean;\n}\n\ninterface TreeViewModelInfo {\n id: string;\n isPlanProjection?: boolean;\n}\n\nexport const ModelsTreeComponent = (props: ModelTreeProps) => {\n const { iModel } = props;\n\n const [is2dToggleActive, setIs2dToggleActive] = useState<boolean>(false);\n const [is3dToggleActive, setIs3dToggleActive] = useState<boolean>(false);\n const [icon2dToggle, setIcon2dToggle] = useState<string>(\"icon-visibility\");\n const [icon3dToggle, setIcon3dToggle] = useState<string>(\"icon-visibility\");\n\n const [available2dModels, setAvailable2dModels] = useState<string[]>([]);\n const [available3dModels, setAvailable3dModels] = useState<string[]>([]);\n const [availableModels, setAvailableModels] = useState<string[]>([]);\n\n const viewport = useActiveViewport();\n\n const { searchOptions, filterString, activeMatchIndex, onFilterApplied } =\n useTreeFilteringState();\n\n const [height, setHeight] = useState(0);\n const [width, setWidth] = useState(0);\n const handleResize = useCallback((w: number, h: number) => {\n setHeight(h);\n setWidth(w);\n }, []);\n const ref = useResizeObserver<HTMLDivElement>(handleResize);\n\n const queryModels = useCallback(async (\n vp: Viewport | undefined\n ): Promise<TreeViewModelInfo[]> => {\n if (vp === undefined) return [];\n\n const queryParams: ModelQueryParams = {\n from: \"BisCore.GeometricModel3d\",\n wantPrivate: false,\n };\n const modelProps = await iModel.models.queryProps(queryParams);\n return modelProps\n .map(({ id, isPlanProjection }: GeometricModel3dProps) => ({ id, isPlanProjection }))\n .filter(({ id }) => id) as TreeViewModelInfo[];\n }, [iModel]);\n\n useEffect(() => {\n queryModels(viewport)\n .then((modelInfos: TreeViewModelInfo[]) => {\n setAvailableModels(modelInfos.map(({ id }) => id));\n\n const { models2d, models3d } = modelInfos.reduce((acc, { id, isPlanProjection }) => {\n isPlanProjection ? acc.models2d.push(id) : acc.models3d.push(id);\n return acc;\n }, { models2d: [] as string[], models3d: [] as string[] });\n\n setAvailable2dModels(models2d);\n setAvailable3dModels(models3d);\n })\n .catch((_e) => {\n setAvailableModels([]);\n });\n }, [queryModels, viewport]);\n\n const invert = useCallback(async () => {\n if (availableModels.length === 0) return;\n const notViewedModels: string[] = [];\n const models: string[] = [];\n availableModels.forEach((id: string) => {\n if (viewport?.viewsModel(id)) models.push(id);\n else notViewedModels.push(id);\n });\n await viewport?.addViewedModels(notViewedModels);\n viewport?.changeModelDisplay(models, false);\n viewport?.invalidateScene();\n }, [viewport, availableModels]);\n\n const hideAll = useCallback(() => {\n viewport?.changeModelDisplay(availableModels, false);\n viewport?.invalidateScene();\n }, [viewport, availableModels]);\n\n const showAll = useCallback(async () => {\n await viewport?.addViewedModels(availableModels);\n viewport?.invalidateScene();\n }, [viewport, availableModels]);\n\n const viewToggle2D = useCallback(async () => {\n if (is2dToggleActive) {\n viewport?.changeModelDisplay(available2dModels, false);\n setIs2dToggleActive(false);\n setIcon2dToggle(\"icon-visibility-hide-2\");\n } else {\n await viewport?.addViewedModels(available2dModels);\n setIs2dToggleActive(true);\n setIcon2dToggle(\"icon-visibility\");\n }\n viewport?.invalidateScene();\n }, [is2dToggleActive, viewport, available2dModels]);\n\n const viewToggle3D = useCallback(async () => {\n if (is3dToggleActive) {\n viewport?.changeModelDisplay(available3dModels, false);\n setIs3dToggleActive(false);\n setIcon3dToggle(\"icon-visibility-hide-2\");\n } else {\n await viewport?.addViewedModels(available3dModels);\n setIs3dToggleActive(true);\n setIcon3dToggle(\"icon-visibility\");\n }\n viewport?.invalidateScene();\n }, [is3dToggleActive, viewport, available3dModels]);\n\n return (!(iModel && viewport) ? null : (\n <>\n <TreeHeaderComponent\n searchOptions={searchOptions}\n showAll={showAll}\n hideAll={hideAll}\n invert={invert}\n toggle2D={viewToggle2D}\n toggle2DIcon={icon2dToggle}\n toggle3D={viewToggle3D}\n toggle3DIcon={icon3dToggle}\n />\n <div className=\"tree-widget-models-tree-container\">\n <div ref={ref} style={{ width: \"100%\", height: \"100%\" }}>\n {width && height && (\n <ModelsTree\n {...props}\n filterInfo={{ filter: filterString, activeMatchIndex }}\n onFilterApplied={onFilterApplied}\n activeView={viewport}\n enableElementsClassGrouping={\n props.enableElementsClassGrouping\n ? ClassGroupingOption.YesWithCounts\n : ClassGroupingOption.No\n }\n width={width}\n height={height}\n />\n )}\n </div>\n </div>\n </>\n ));\n};\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
|
|
6
|
+
@import "~@itwin/core-react/lib/esm/core-react/index";
|
|
7
|
+
|
|
8
|
+
.tree-widget-models-tree-container {
|
|
9
|
+
flex: 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.tree-widget-models-tree-toolbar-icon {
|
|
13
|
+
color: $buic-icon-color;
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { SpatialContainmentTree, } from "@itwin/appui-react";
|
|
6
|
+
import { useResizeObserver } from "@itwin/core-react";
|
|
7
|
+
import React, { useCallback, useState } from "react";
|
|
8
|
+
export const SpatialTreeComponent = (props) => {
|
|
9
|
+
const [height, setHeight] = useState(0);
|
|
10
|
+
const [width, setWidth] = useState(0);
|
|
11
|
+
const handleResize = useCallback((w, h) => {
|
|
12
|
+
setHeight(h);
|
|
13
|
+
setWidth(w);
|
|
14
|
+
}, []);
|
|
15
|
+
const ref = useResizeObserver(handleResize);
|
|
16
|
+
return (React.createElement("div", { ref: ref, style: { width: "100%", height: "100%" } }, width && height && (React.createElement(SpatialContainmentTree, { ...props, width: width, height: height }))));
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=SpatialTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpatialTree.js","sourceRoot":"","sources":["../../../../src/components/trees/SpatialTree.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,OAAO,EACL,sBAAsB,GAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAErD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,KAA4D,EAC5D,EAAE;IACF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE;QACxD,SAAS,CAAC,CAAC,CAAC,CAAC;QACb,QAAQ,CAAC,CAAC,CAAC,CAAC;IACd,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,MAAM,GAAG,GAAG,iBAAiB,CAAiB,YAAY,CAAC,CAAC;IAE5D,OAAO,CACL,6BAAK,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IACpD,KAAK,IAAI,MAAM,IAAI,CAClB,oBAAC,sBAAsB,OAAK,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAI,CACpE,CACG,CACP,CAAC;AACJ,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*--------------------------------------------------------------------------------------------*/\nimport {\n SpatialContainmentTree,\n SpatialContainmentTreeProps,\n} from \"@itwin/appui-react\";\nimport { useResizeObserver } from \"@itwin/core-react\";\nimport React, { useCallback, useState } from \"react\";\n\nexport const SpatialTreeComponent = (\n props: Omit<SpatialContainmentTreeProps, \"width\" | \"height\">\n) => {\n const [height, setHeight] = useState(0);\n const [width, setWidth] = useState(0);\n const handleResize = useCallback((w: number, h: number) => {\n setHeight(h);\n setWidth(w);\n }, []);\n const ref = useResizeObserver<HTMLDivElement>(handleResize);\n\n return (\n <div ref={ref} style={{ width: \"100%\", height: \"100%\" }}>\n {width && height && (\n <SpatialContainmentTree {...props} width={width} height={height} />\n )}\n </div>\n );\n};\n"]}
|