@itwin/grouping-mapping-widget 0.2.0 → 0.2.3
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/README.md +7 -2
- package/lib/cjs/widget/GroupingMappingWidget.d.ts +2 -2
- package/lib/cjs/widget/GroupingMappingWidget.js +4 -3
- package/lib/cjs/widget/GroupingMappingWidget.js.map +1 -1
- package/lib/cjs/widget/components/ActionPanel.js +5 -3
- package/lib/cjs/widget/components/ActionPanel.js.map +1 -1
- package/lib/cjs/widget/components/CalculatedPropertyAction.js +8 -2
- package/lib/cjs/widget/components/CalculatedPropertyAction.js.map +1 -1
- package/lib/cjs/widget/components/CalculatedPropertyTable.js +3 -2
- package/lib/cjs/widget/components/CalculatedPropertyTable.js.map +1 -1
- package/lib/cjs/widget/components/ConfirmMappingsImport.js +30 -12
- package/lib/cjs/widget/components/ConfirmMappingsImport.js.map +1 -1
- package/lib/cjs/widget/components/ConfirmMappingsImport.scss +0 -7
- package/lib/cjs/widget/components/CustomCalculationAction.js +3 -1
- package/lib/cjs/widget/components/CustomCalculationAction.js.map +1 -1
- package/lib/cjs/widget/components/CustomCalculationTable.js +4 -3
- package/lib/cjs/widget/components/CustomCalculationTable.js.map +1 -1
- package/lib/cjs/widget/components/DeleteModal.js +7 -6
- package/lib/cjs/widget/components/DeleteModal.js.map +1 -1
- package/lib/cjs/widget/components/DeleteModal.scss +6 -0
- package/lib/cjs/widget/components/GroupAction.js +98 -28
- package/lib/cjs/widget/components/GroupAction.js.map +1 -1
- package/lib/cjs/widget/components/GroupAction.scss +23 -0
- package/lib/cjs/widget/components/GroupPropertyAction.js +68 -34
- package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
- package/lib/cjs/widget/components/GroupPropertyTable.js +3 -2
- package/lib/cjs/widget/components/GroupPropertyTable.js.map +1 -1
- package/lib/cjs/widget/components/GroupQueryBuilderContext.d.ts +2 -0
- package/lib/cjs/widget/components/GroupQueryBuilderContext.js +2 -0
- package/lib/cjs/widget/components/GroupQueryBuilderContext.js.map +1 -1
- package/lib/cjs/widget/components/Grouping.js +69 -12
- package/lib/cjs/widget/components/Grouping.js.map +1 -1
- package/lib/cjs/widget/components/Mapping.js +2 -1
- package/lib/cjs/widget/components/Mapping.js.map +1 -1
- package/lib/cjs/widget/components/MappingAction.js +2 -1
- package/lib/cjs/widget/components/MappingAction.js.map +1 -1
- package/lib/cjs/widget/components/MappingImportWizardModal.js +1 -1
- package/lib/cjs/widget/components/MappingImportWizardModal.js.map +1 -1
- package/lib/cjs/widget/components/MappingImportWizardModal.scss +1 -1
- package/lib/cjs/widget/components/PropertyMenu.js +22 -12
- package/lib/cjs/widget/components/PropertyMenu.js.map +1 -1
- package/lib/cjs/widget/components/PropertyMenu.scss +3 -0
- package/lib/cjs/widget/components/QueryBuilder.d.ts +1 -1
- package/lib/cjs/widget/components/QueryBuilder.js +11 -5
- package/lib/cjs/widget/components/QueryBuilder.js.map +1 -1
- package/lib/cjs/widget/components/SelectMappings.js +3 -1
- package/lib/cjs/widget/components/SelectMappings.js.map +1 -1
- package/lib/cjs/widget/components/SelectProject.scss +1 -1
- package/lib/cjs/widget/components/property-grid/PrimitivePropertyRenderer.js +7 -3
- package/lib/cjs/widget/components/property-grid/PrimitivePropertyRenderer.js.map +1 -1
- package/lib/cjs/widget/components/property-grid/PropertyGrid.scss +3 -3
- package/lib/cjs/widget/components/property-grid/PropertyRender.d.ts +1 -1
- package/lib/cjs/widget/components/property-grid/PropertyRender.js +5 -8
- package/lib/cjs/widget/components/property-grid/PropertyRender.js.map +1 -1
- package/lib/cjs/widget/components/property-grid/PropertyView.d.ts +2 -0
- package/lib/cjs/widget/components/property-grid/PropertyView.js +14 -11
- package/lib/cjs/widget/components/property-grid/PropertyView.js.map +1 -1
- package/lib/cjs/widget/components/property-grid/PropertyView.scss +19 -4
- package/lib/cjs/widget/components/utils.d.ts +2 -0
- package/lib/cjs/widget/components/utils.js +45 -4
- package/lib/cjs/widget/components/utils.js.map +1 -1
- package/lib/cjs/widget/components/utils.scss +5 -0
- package/lib/cjs/widget/components/viewerUtils.js +1 -1
- package/lib/cjs/widget/components/viewerUtils.js.map +1 -1
- package/lib/esm/widget/GroupingMappingWidget.d.ts +2 -2
- package/lib/esm/widget/GroupingMappingWidget.js +5 -4
- package/lib/esm/widget/GroupingMappingWidget.js.map +1 -1
- package/lib/esm/widget/components/ActionPanel.js +6 -4
- package/lib/esm/widget/components/ActionPanel.js.map +1 -1
- package/lib/esm/widget/components/CalculatedPropertyAction.js +9 -3
- package/lib/esm/widget/components/CalculatedPropertyAction.js.map +1 -1
- package/lib/esm/widget/components/CalculatedPropertyTable.js +3 -2
- package/lib/esm/widget/components/CalculatedPropertyTable.js.map +1 -1
- package/lib/esm/widget/components/ConfirmMappingsImport.js +30 -12
- package/lib/esm/widget/components/ConfirmMappingsImport.js.map +1 -1
- package/lib/esm/widget/components/ConfirmMappingsImport.scss +0 -7
- package/lib/esm/widget/components/CustomCalculationAction.js +4 -2
- package/lib/esm/widget/components/CustomCalculationAction.js.map +1 -1
- package/lib/esm/widget/components/CustomCalculationTable.js +4 -3
- package/lib/esm/widget/components/CustomCalculationTable.js.map +1 -1
- package/lib/esm/widget/components/DeleteModal.js +8 -7
- package/lib/esm/widget/components/DeleteModal.js.map +1 -1
- package/lib/esm/widget/components/DeleteModal.scss +6 -0
- package/lib/esm/widget/components/GroupAction.js +100 -30
- package/lib/esm/widget/components/GroupAction.js.map +1 -1
- package/lib/esm/widget/components/GroupAction.scss +23 -0
- package/lib/esm/widget/components/GroupPropertyAction.js +69 -35
- package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
- package/lib/esm/widget/components/GroupPropertyTable.js +3 -2
- package/lib/esm/widget/components/GroupPropertyTable.js.map +1 -1
- package/lib/esm/widget/components/GroupQueryBuilderContext.d.ts +2 -0
- package/lib/esm/widget/components/GroupQueryBuilderContext.js +2 -0
- package/lib/esm/widget/components/GroupQueryBuilderContext.js.map +1 -1
- package/lib/esm/widget/components/Grouping.js +71 -14
- package/lib/esm/widget/components/Grouping.js.map +1 -1
- package/lib/esm/widget/components/Mapping.js +3 -2
- package/lib/esm/widget/components/Mapping.js.map +1 -1
- package/lib/esm/widget/components/MappingAction.js +3 -2
- package/lib/esm/widget/components/MappingAction.js.map +1 -1
- package/lib/esm/widget/components/MappingImportWizardModal.js +1 -1
- package/lib/esm/widget/components/MappingImportWizardModal.js.map +1 -1
- package/lib/esm/widget/components/MappingImportWizardModal.scss +1 -1
- package/lib/esm/widget/components/PropertyMenu.js +23 -13
- package/lib/esm/widget/components/PropertyMenu.js.map +1 -1
- package/lib/esm/widget/components/PropertyMenu.scss +3 -0
- package/lib/esm/widget/components/QueryBuilder.d.ts +1 -1
- package/lib/esm/widget/components/QueryBuilder.js +11 -5
- package/lib/esm/widget/components/QueryBuilder.js.map +1 -1
- package/lib/esm/widget/components/SelectMappings.js +3 -1
- package/lib/esm/widget/components/SelectMappings.js.map +1 -1
- package/lib/esm/widget/components/SelectProject.scss +1 -1
- package/lib/esm/widget/components/property-grid/PrimitivePropertyRenderer.js +7 -3
- package/lib/esm/widget/components/property-grid/PrimitivePropertyRenderer.js.map +1 -1
- package/lib/esm/widget/components/property-grid/PropertyGrid.scss +3 -3
- package/lib/esm/widget/components/property-grid/PropertyRender.d.ts +1 -1
- package/lib/esm/widget/components/property-grid/PropertyRender.js +5 -8
- package/lib/esm/widget/components/property-grid/PropertyRender.js.map +1 -1
- package/lib/esm/widget/components/property-grid/PropertyView.d.ts +2 -0
- package/lib/esm/widget/components/property-grid/PropertyView.js +14 -11
- package/lib/esm/widget/components/property-grid/PropertyView.js.map +1 -1
- package/lib/esm/widget/components/property-grid/PropertyView.scss +19 -4
- package/lib/esm/widget/components/utils.d.ts +2 -0
- package/lib/esm/widget/components/utils.js +43 -4
- package/lib/esm/widget/components/utils.js.map +1 -1
- package/lib/esm/widget/components/utils.scss +5 -0
- package/lib/esm/widget/components/viewerUtils.js +1 -1
- package/lib/esm/widget/components/viewerUtils.js.map +1 -1
- package/package.json +4 -4
- package/lib/cjs/widget/icons/DatabaseInfo.d.ts +0 -5
- package/lib/cjs/widget/icons/DatabaseInfo.js +0 -19
- package/lib/cjs/widget/icons/DatabaseInfo.js.map +0 -1
- package/lib/cjs/widget/icons/DatabaseInfo.scss +0 -12
- package/lib/esm/widget/icons/DatabaseInfo.d.ts +0 -5
- package/lib/esm/widget/icons/DatabaseInfo.js +0 -14
- package/lib/esm/widget/icons/DatabaseInfo.js.map +0 -1
- package/lib/esm/widget/icons/DatabaseInfo.scss +0 -12
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Presentation, } from "@itwin/presentation-frontend";
|
|
2
2
|
import { useActiveIModelConnection } from "@itwin/appui-react";
|
|
3
|
-
import { Fieldset, LabeledInput, Small } from "@itwin/itwinui-react";
|
|
3
|
+
import { Button, Fieldset, LabeledInput, LabeledTextarea, RadioTile, RadioTileGroup, Small, Text, toaster } from "@itwin/itwinui-react";
|
|
4
4
|
import React, { useCallback, useEffect, useState } from "react";
|
|
5
5
|
import { reportingClientApi } from "../../api/reportingClient";
|
|
6
|
-
import { fetchIdsFromQuery, handleInputChange, WidgetHeader } from "./utils";
|
|
6
|
+
import { fetchIdsFromQuery, handleError, handleInputChange, LoadingSpinner, WidgetHeader } from "./utils";
|
|
7
7
|
import "./GroupAction.scss";
|
|
8
8
|
import ActionPanel from "./ActionPanel";
|
|
9
9
|
import useValidator, { NAME_REQUIREMENTS } from "../hooks/useValidator";
|
|
@@ -11,6 +11,7 @@ import { GroupQueryBuilderContainer } from "./GroupQueryBuilderContainer";
|
|
|
11
11
|
import { GroupQueryBuilderContext } from "./GroupQueryBuilderContext";
|
|
12
12
|
import { QueryBuilder } from "./QueryBuilder";
|
|
13
13
|
import { clearEmphasizedElements, visualizeElementsById, zoomToElements, } from "./viewerUtils";
|
|
14
|
+
import { SvgCursor, SvgSearch } from "@itwin/itwinui-icons-react";
|
|
14
15
|
const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
|
|
15
16
|
var _a, _b, _c;
|
|
16
17
|
const iModelConnection = useActiveIModelConnection();
|
|
@@ -22,21 +23,21 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
|
|
|
22
23
|
const [simpleQuery, setSimpleQuery] = useState("");
|
|
23
24
|
const [validator, showValidationMessage] = useValidator();
|
|
24
25
|
const [isLoading, setIsLoading] = useState(false);
|
|
26
|
+
const [isRendering, setIsRendering] = useState(false);
|
|
25
27
|
const [currentPropertyList, setCurrentPropertyList] = React.useState([]);
|
|
26
28
|
const [queryBuilder, setQueryBuilder] = React.useState(new QueryBuilder(undefined));
|
|
29
|
+
const [groupByType, setGroupByType] = React.useState("Selection");
|
|
30
|
+
const [searchInput, setSearchInput] = React.useState("");
|
|
31
|
+
const changeGroupByType = (event) => {
|
|
32
|
+
const { target: { value }, } = event;
|
|
33
|
+
setGroupByType(value);
|
|
34
|
+
Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
|
|
35
|
+
setQuery("");
|
|
36
|
+
};
|
|
27
37
|
useEffect(() => {
|
|
28
38
|
const removeListener = Presentation.selection.selectionChange.addListener(async (evt, selectionProvider) => {
|
|
29
39
|
const selection = selectionProvider.getSelection(evt.imodel, evt.level);
|
|
30
|
-
const query = `SELECT ECInstanceId FROM ${selection.instanceKeys.keys().next().value}
|
|
31
|
-
// Selects all instances of the class
|
|
32
|
-
// const ids = await fetchIdsFromQuery(query, iModelConnection);
|
|
33
|
-
// const keySet = await manufactureKeys(ids, iModelConnection);
|
|
34
|
-
// Presentation.selection.replaceSelection(
|
|
35
|
-
// "GroupingMappingWidget",
|
|
36
|
-
// iModelConnection,
|
|
37
|
-
// keySet
|
|
38
|
-
// );
|
|
39
|
-
// setSelectionInstanceKeys(selection.instanceKeys);
|
|
40
|
+
const query = selection.instanceKeys.size > 0 ? `SELECT ECInstanceId FROM ${selection.instanceKeys.keys().next().value}` : "";
|
|
40
41
|
setSimpleQuery(query);
|
|
41
42
|
});
|
|
42
43
|
return () => {
|
|
@@ -45,19 +46,70 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
|
|
|
45
46
|
}, [iModelConnection]);
|
|
46
47
|
useEffect(() => {
|
|
47
48
|
const reemphasize = async () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
try {
|
|
50
|
+
clearEmphasizedElements();
|
|
51
|
+
if (!query || query === "") {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
setIsRendering(true);
|
|
55
|
+
const ids = await fetchIdsFromQuery(query !== null && query !== void 0 ? query : "", iModelConnection);
|
|
56
|
+
const resolvedHiliteIds = await visualizeElementsById(ids, "red", iModelConnection);
|
|
57
|
+
await zoomToElements(resolvedHiliteIds);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
toaster.negative("Sorry, we have failed to generate a valid query. 😔");
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
setIsRendering(false);
|
|
51
64
|
}
|
|
52
|
-
const ids = await fetchIdsFromQuery(query !== null && query !== void 0 ? query : "", iModelConnection);
|
|
53
|
-
const resolvedHiliteIds = await visualizeElementsById(ids, "red", iModelConnection);
|
|
54
|
-
await zoomToElements(resolvedHiliteIds);
|
|
55
65
|
};
|
|
56
66
|
void reemphasize();
|
|
57
67
|
}, [iModelConnection, query]);
|
|
58
68
|
useEffect(() => {
|
|
59
69
|
Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
|
|
60
70
|
}, [iModelConnection]);
|
|
71
|
+
const isWrappedInQuotes = (text) => {
|
|
72
|
+
return text.startsWith(`"`) && text.endsWith(`"`);
|
|
73
|
+
};
|
|
74
|
+
// Temporary until ECViews become available for use.
|
|
75
|
+
const generateSearchQuery = (searchQuery) => {
|
|
76
|
+
const generatedSearchQuery = searchQuery.length > 0 ? `SELECT
|
|
77
|
+
be.ecinstanceid
|
|
78
|
+
FROM
|
|
79
|
+
generic.physicalobject be
|
|
80
|
+
JOIN
|
|
81
|
+
biscore.geometricelement3disincategory ce
|
|
82
|
+
ON be.ecinstanceid = ce.sourceecinstanceid
|
|
83
|
+
JOIN
|
|
84
|
+
bis.ELEMENT de
|
|
85
|
+
ON ce.targetecinstanceid = de.ecinstanceid
|
|
86
|
+
WHERE
|
|
87
|
+
(${searchQuery.map((token, index) => `${index === 0 ? "" : isWrappedInQuotes(token) ? "AND" : "OR"}
|
|
88
|
+
de.codevalue LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`).join(" ")}
|
|
89
|
+
)
|
|
90
|
+
UNION
|
|
91
|
+
SELECT
|
|
92
|
+
de.ecinstanceid
|
|
93
|
+
FROM
|
|
94
|
+
biscore.geometricelement3d AS de
|
|
95
|
+
JOIN
|
|
96
|
+
ecdbmeta.ecclassdef AS be
|
|
97
|
+
ON de.ecclassid = be.ecinstanceid
|
|
98
|
+
WHERE
|
|
99
|
+
(${searchQuery.map((token, index) => `${index === 0 ? "" : isWrappedInQuotes(token) ? "AND" : "OR"}
|
|
100
|
+
be.name LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`).join(" ")}
|
|
101
|
+
)
|
|
102
|
+
UNION
|
|
103
|
+
SELECT
|
|
104
|
+
be.ecinstanceid
|
|
105
|
+
FROM
|
|
106
|
+
generic.physicalobject be
|
|
107
|
+
WHERE
|
|
108
|
+
(${searchQuery.map((token, index) => `${index === 0 ? "" : isWrappedInQuotes(token) ? "AND" : "OR"}
|
|
109
|
+
be.userlabel LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`).join(" ")}
|
|
110
|
+
)` : "";
|
|
111
|
+
setQuery(generatedSearchQuery.trim());
|
|
112
|
+
};
|
|
61
113
|
const save = useCallback(async () => {
|
|
62
114
|
var _a;
|
|
63
115
|
if (!validator.allValid()) {
|
|
@@ -76,7 +128,8 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
|
|
|
76
128
|
Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
|
|
77
129
|
await goBack();
|
|
78
130
|
}
|
|
79
|
-
catch {
|
|
131
|
+
catch (error) {
|
|
132
|
+
handleError(error.status);
|
|
80
133
|
setIsLoading(false);
|
|
81
134
|
}
|
|
82
135
|
}, [
|
|
@@ -121,22 +174,39 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
|
|
|
121
174
|
handleInputChange(event, details, setDetails);
|
|
122
175
|
validator.showMessageFor("description");
|
|
123
176
|
} })),
|
|
124
|
-
React.createElement(Fieldset, { legend: 'Group By', className: '
|
|
125
|
-
React.createElement(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
177
|
+
React.createElement(Fieldset, { legend: 'Group By', className: 'query-builder-container' },
|
|
178
|
+
React.createElement(RadioTileGroup, { className: "radio-group-tile", required: true },
|
|
179
|
+
React.createElement(RadioTile, { name: "groupby", icon: React.createElement(SvgCursor, null), onChange: changeGroupByType, defaultChecked: true, value: "Selection", label: "Selection", disabled: isLoading || isRendering }),
|
|
180
|
+
React.createElement(RadioTile, { icon: React.createElement(SvgSearch, null), name: "groupby", onChange: changeGroupByType, value: "Query Keywords", label: "Query Keywords", disabled: isLoading || isRendering })),
|
|
181
|
+
groupByType === "Selection" ?
|
|
182
|
+
React.createElement(GroupQueryBuilderContext.Provider, { value: {
|
|
183
|
+
currentPropertyList,
|
|
184
|
+
setCurrentPropertyList,
|
|
185
|
+
query,
|
|
186
|
+
setQuery,
|
|
187
|
+
queryBuilder,
|
|
188
|
+
setQueryBuilder,
|
|
189
|
+
isLoading,
|
|
190
|
+
isRendering,
|
|
191
|
+
} },
|
|
192
|
+
React.createElement(GroupQueryBuilderContainer, null)) :
|
|
193
|
+
React.createElement("div", { className: "search-form" },
|
|
194
|
+
React.createElement(Text, null, "Generate a query by keywords. Keywords wrapped in double quotes will be considered a required criteria."),
|
|
195
|
+
React.createElement(LabeledTextarea, { label: "Query Keywords", required: true, value: searchInput, onChange: (event) => setSearchInput(event.target.value), disabled: isLoading || isRendering, placeholder: `ex: wall curtain "panel" facade` }),
|
|
196
|
+
React.createElement("div", { className: "search-actions" },
|
|
197
|
+
isRendering &&
|
|
198
|
+
React.createElement(LoadingSpinner, null),
|
|
199
|
+
React.createElement(Button, { disabled: isLoading || isRendering, onClick: () => generateSearchQuery(searchInput ? searchInput.split(" ") : []) }, "Apply"),
|
|
200
|
+
React.createElement(Button, { disabled: isLoading || isRendering, onClick: () => {
|
|
201
|
+
setQuery("");
|
|
202
|
+
setSearchInput("");
|
|
203
|
+
} }, "Clear"))))),
|
|
134
204
|
React.createElement(ActionPanel, { onSave: async () => {
|
|
135
205
|
await save();
|
|
136
206
|
}, onCancel: async () => {
|
|
137
207
|
Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
|
|
138
208
|
await goBack();
|
|
139
|
-
}, disabled: !(details.groupName && details.description && (query || simpleQuery)), isLoading: isLoading })));
|
|
209
|
+
}, disabled: !(details.groupName && details.description && (query || simpleQuery) && !isRendering && !isLoading), isLoading: isLoading })));
|
|
140
210
|
};
|
|
141
211
|
export default GroupAction;
|
|
142
212
|
//# sourceMappingURL=GroupAction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupAction.js","sourceRoot":"","sources":["../../../../src/widget/components/GroupAction.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 type { IModelConnection } from \"@itwin/core-frontend\";\nimport type {\n ISelectionProvider,\n SelectionChangeEventArgs} from \"@itwin/presentation-frontend\";\nimport {\n Presentation,\n} from \"@itwin/presentation-frontend\";\nimport { useActiveIModelConnection } from \"@itwin/appui-react\";\nimport { Fieldset, LabeledInput, Small } from \"@itwin/itwinui-react\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { reportingClientApi } from \"../../api/reportingClient\";\nimport { fetchIdsFromQuery, handleInputChange, WidgetHeader } from \"./utils\";\nimport type { Group } from \"./Grouping\";\nimport \"./GroupAction.scss\";\nimport ActionPanel from \"./ActionPanel\";\nimport useValidator, { NAME_REQUIREMENTS } from \"../hooks/useValidator\";\nimport type { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { GroupQueryBuilderContainer } from \"./GroupQueryBuilderContainer\";\nimport { GroupQueryBuilderContext } from \"./GroupQueryBuilderContext\";\nimport { QueryBuilder } from \"./QueryBuilder\";\nimport {\n clearEmphasizedElements,\n visualizeElementsById,\n zoomToElements,\n} from \"./viewerUtils\";\n\ninterface GroupActionProps {\n iModelId: string;\n mappingId: string;\n group?: Group;\n goBack: () => Promise<void>;\n}\n\nconst GroupAction = ({\n iModelId,\n mappingId,\n group,\n goBack,\n}: GroupActionProps) => {\n const iModelConnection = useActiveIModelConnection() as IModelConnection;\n const [details, setDetails] = useState({\n groupName: group?.groupName ?? \"\",\n description: group?.description ?? \"\",\n });\n const [query, setQuery] = useState<string>(\"\");\n const [simpleQuery, setSimpleQuery] = useState<string>(\"\");\n const [validator, showValidationMessage] = useValidator();\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [currentPropertyList, setCurrentPropertyList] = React.useState<\n PropertyRecord[]\n >([]);\n const [queryBuilder, setQueryBuilder] = React.useState<QueryBuilder>(\n new QueryBuilder(undefined),\n );\n\n useEffect(() => {\n const removeListener = Presentation.selection.selectionChange.addListener(\n async (\n evt: SelectionChangeEventArgs,\n selectionProvider: ISelectionProvider,\n ) => {\n const selection = selectionProvider.getSelection(evt.imodel, evt.level);\n const query = `SELECT ECInstanceId FROM ${selection.instanceKeys.keys().next().value\n }`;\n // Selects all instances of the class\n // const ids = await fetchIdsFromQuery(query, iModelConnection);\n // const keySet = await manufactureKeys(ids, iModelConnection);\n // Presentation.selection.replaceSelection(\n // \"GroupingMappingWidget\",\n // iModelConnection,\n // keySet\n // );\n // setSelectionInstanceKeys(selection.instanceKeys);\n setSimpleQuery(query);\n },\n );\n return () => {\n removeListener();\n };\n }, [iModelConnection]);\n\n useEffect(() => {\n const reemphasize = async () => {\n clearEmphasizedElements();\n if (!query || query === \"\") {\n return;\n }\n const ids = await fetchIdsFromQuery(query ?? \"\", iModelConnection);\n const resolvedHiliteIds = await visualizeElementsById(\n ids,\n \"red\",\n iModelConnection,\n );\n await zoomToElements(resolvedHiliteIds);\n };\n\n void reemphasize();\n }, [iModelConnection, query]);\n\n useEffect(() => {\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n }, [iModelConnection]);\n\n const save = useCallback(async () => {\n if (!validator.allValid()) {\n showValidationMessage(true);\n return;\n }\n try {\n setIsLoading(true);\n const currentQuery = query || simpleQuery;\n\n group\n ? await reportingClientApi.updateGroup(\n iModelId,\n mappingId,\n group.id ?? \"\",\n { ...details, query: currentQuery },\n )\n : await reportingClientApi.createGroup(iModelId, mappingId, {\n ...details,\n query: currentQuery,\n });\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n await goBack();\n } catch {\n setIsLoading(false);\n }\n }, [\n details,\n goBack,\n group,\n iModelConnection,\n iModelId,\n mappingId,\n query,\n showValidationMessage,\n simpleQuery,\n validator,\n ]);\n\n return (\n <>\n <WidgetHeader\n title={group ? group.groupName ?? \"\" : \"Add Group\"}\n returnFn={async () => {\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n await goBack();\n }}\n />\n <div className='group-add-modify-container'>\n <Fieldset legend='Group Details' className='group-details'>\n <Small className='field-legend'>\n Asterisk * indicates mandatory fields.\n </Small>\n <LabeledInput\n id='groupName'\n name='groupName'\n label='Name'\n value={details.groupName}\n required\n onChange={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"groupName\");\n }}\n message={validator.message(\n \"groupName\",\n details.groupName,\n NAME_REQUIREMENTS,\n )}\n status={\n validator.message(\n \"groupName\",\n details.groupName,\n NAME_REQUIREMENTS,\n )\n ? \"negative\"\n : undefined\n }\n onBlur={() => {\n validator.showMessageFor(\"groupName\");\n }}\n onBlurCapture={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"groupName\");\n }}\n />\n <LabeledInput\n id='description'\n required\n name='description'\n label='Description'\n value={details.description}\n onChange={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"description\");\n }}\n message={validator.message(\n \"description\",\n details.description,\n \"required\",\n )}\n status={\n validator.message(\"description\", details.description, \"required\")\n ? \"negative\"\n : undefined\n }\n onBlur={() => {\n validator.showMessageFor(\"description\");\n }}\n onBlurCapture={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"description\");\n }}\n />\n </Fieldset>\n\n <Fieldset legend='Group By' className='find-similar'>\n <GroupQueryBuilderContext.Provider\n value={{\n currentPropertyList,\n setCurrentPropertyList,\n query,\n setQuery,\n queryBuilder,\n setQueryBuilder,\n }}\n >\n <GroupQueryBuilderContainer />\n </GroupQueryBuilderContext.Provider>\n </Fieldset>\n </div>\n <ActionPanel\n onSave={async () => {\n await save();\n }}\n onCancel={async () => {\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n await goBack();\n }}\n disabled={\n !(details.groupName && details.description && (query || simpleQuery))\n }\n isLoading={isLoading}\n />\n </>\n );\n};\n\nexport default GroupAction;\n"]}
|
|
1
|
+
{"version":3,"file":"GroupAction.js","sourceRoot":"","sources":["../../../../src/widget/components/GroupAction.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 type { IModelConnection } from \"@itwin/core-frontend\";\nimport type {\n ISelectionProvider,\n SelectionChangeEventArgs,\n} from \"@itwin/presentation-frontend\";\nimport {\n Presentation,\n} from \"@itwin/presentation-frontend\";\nimport { useActiveIModelConnection } from \"@itwin/appui-react\";\nimport { Button, Fieldset, LabeledInput, LabeledTextarea, RadioTile, RadioTileGroup, Small, Text, toaster } from \"@itwin/itwinui-react\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { reportingClientApi } from \"../../api/reportingClient\";\nimport { fetchIdsFromQuery, handleError, handleInputChange, LoadingSpinner, WidgetHeader } from \"./utils\";\nimport type { Group } from \"./Grouping\";\nimport \"./GroupAction.scss\";\nimport ActionPanel from \"./ActionPanel\";\nimport useValidator, { NAME_REQUIREMENTS } from \"../hooks/useValidator\";\nimport type { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { GroupQueryBuilderContainer } from \"./GroupQueryBuilderContainer\";\nimport { GroupQueryBuilderContext } from \"./GroupQueryBuilderContext\";\nimport { QueryBuilder } from \"./QueryBuilder\";\nimport {\n clearEmphasizedElements,\n visualizeElementsById,\n zoomToElements,\n} from \"./viewerUtils\";\nimport { SvgCursor, SvgSearch } from \"@itwin/itwinui-icons-react\";\n\ninterface GroupActionProps {\n iModelId: string;\n mappingId: string;\n group?: Group;\n goBack: () => Promise<void>;\n}\n\nconst GroupAction = ({\n iModelId,\n mappingId,\n group,\n goBack,\n}: GroupActionProps) => {\n const iModelConnection = useActiveIModelConnection() as IModelConnection;\n const [details, setDetails] = useState({\n groupName: group?.groupName ?? \"\",\n description: group?.description ?? \"\",\n });\n const [query, setQuery] = useState<string>(\"\");\n const [simpleQuery, setSimpleQuery] = useState<string>(\"\");\n const [validator, showValidationMessage] = useValidator();\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [isRendering, setIsRendering] = useState<boolean>(false);\n const [currentPropertyList, setCurrentPropertyList] = React.useState<\n PropertyRecord[]\n >([]);\n const [queryBuilder, setQueryBuilder] = React.useState<QueryBuilder>(\n new QueryBuilder(undefined),\n );\n const [groupByType, setGroupByType] = React.useState(\"Selection\");\n const [searchInput, setSearchInput] = React.useState(\"\");\n\n const changeGroupByType = (event: React.ChangeEvent<HTMLInputElement>) => {\n const {\n target: { value },\n } = event;\n setGroupByType(value);\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n setQuery(\"\");\n };\n\n useEffect(() => {\n const removeListener = Presentation.selection.selectionChange.addListener(\n async (\n evt: SelectionChangeEventArgs,\n selectionProvider: ISelectionProvider,\n ) => {\n const selection = selectionProvider.getSelection(evt.imodel, evt.level);\n const query = selection.instanceKeys.size > 0 ? `SELECT ECInstanceId FROM ${selection.instanceKeys.keys().next().value\n }` : \"\";\n setSimpleQuery(query);\n },\n );\n return () => {\n removeListener();\n };\n }, [iModelConnection]);\n\n useEffect(() => {\n const reemphasize = async () => {\n try {\n clearEmphasizedElements();\n if (!query || query === \"\") {\n return;\n }\n\n setIsRendering(true);\n const ids = await fetchIdsFromQuery(query ?? \"\", iModelConnection);\n const resolvedHiliteIds = await visualizeElementsById(\n ids,\n \"red\",\n iModelConnection,\n );\n await zoomToElements(resolvedHiliteIds);\n } catch {\n toaster.negative(\"Sorry, we have failed to generate a valid query. 😔\");\n } finally {\n setIsRendering(false);\n }\n };\n\n void reemphasize();\n }, [iModelConnection, query]);\n\n useEffect(() => {\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n }, [iModelConnection]);\n\n const isWrappedInQuotes = (text: string) => {\n return text.startsWith(`\"`) && text.endsWith(`\"`);\n };\n // Temporary until ECViews become available for use.\n const generateSearchQuery = (searchQuery: string[]) => {\n const generatedSearchQuery = searchQuery.length > 0 ? `SELECT\n be.ecinstanceid\n FROM\n generic.physicalobject be\n JOIN\n biscore.geometricelement3disincategory ce\n ON be.ecinstanceid = ce.sourceecinstanceid\n JOIN\n bis.ELEMENT de\n ON ce.targetecinstanceid = de.ecinstanceid\n WHERE\n (${searchQuery.map((token, index) =>\n `${index === 0 ? \"\" : isWrappedInQuotes(token) ? \"AND\" : \"OR\"}\n de.codevalue LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`\n ).join(\" \")}\n )\n UNION\n SELECT\n de.ecinstanceid\n FROM\n biscore.geometricelement3d AS de\n JOIN\n ecdbmeta.ecclassdef AS be\n ON de.ecclassid = be.ecinstanceid\n WHERE\n (${searchQuery.map((token, index) =>\n `${index === 0 ? \"\" : isWrappedInQuotes(token) ? \"AND\" : \"OR\"}\n be.name LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`\n ).join(\" \")}\n )\n UNION\n SELECT\n be.ecinstanceid\n FROM\n generic.physicalobject be\n WHERE\n (${searchQuery.map((token, index) =>\n `${index === 0 ? \"\" : isWrappedInQuotes(token) ? \"AND\" : \"OR\"}\n be.userlabel LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`\n ).join(\" \")}\n )` : \"\";\n setQuery(generatedSearchQuery.trim());\n\n };\n\n const save = useCallback(async () => {\n if (!validator.allValid()) {\n showValidationMessage(true);\n return;\n }\n try {\n setIsLoading(true);\n const currentQuery = query || simpleQuery;\n\n group\n ? await reportingClientApi.updateGroup(\n iModelId,\n mappingId,\n group.id ?? \"\",\n { ...details, query: currentQuery },\n )\n : await reportingClientApi.createGroup(iModelId, mappingId, {\n ...details,\n query: currentQuery,\n });\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n await goBack();\n } catch (error: any) {\n handleError(error.status);\n setIsLoading(false);\n }\n }, [\n details,\n goBack,\n group,\n iModelConnection,\n iModelId,\n mappingId,\n query,\n showValidationMessage,\n simpleQuery,\n validator,\n ]);\n\n return (\n <>\n <WidgetHeader\n title={group ? group.groupName ?? \"\" : \"Add Group\"}\n returnFn={async () => {\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n await goBack();\n }}\n />\n <div className='group-add-modify-container'>\n <Fieldset legend='Group Details' className='group-details'>\n <Small className='field-legend'>\n Asterisk * indicates mandatory fields.\n </Small>\n <LabeledInput\n id='groupName'\n name='groupName'\n label='Name'\n value={details.groupName}\n required\n onChange={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"groupName\");\n }}\n message={validator.message(\n \"groupName\",\n details.groupName,\n NAME_REQUIREMENTS,\n )}\n status={\n validator.message(\n \"groupName\",\n details.groupName,\n NAME_REQUIREMENTS,\n )\n ? \"negative\"\n : undefined\n }\n onBlur={() => {\n validator.showMessageFor(\"groupName\");\n }}\n onBlurCapture={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"groupName\");\n }}\n />\n <LabeledInput\n id='description'\n required\n name='description'\n label='Description'\n value={details.description}\n onChange={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"description\");\n }}\n message={validator.message(\n \"description\",\n details.description,\n \"required\",\n )}\n status={\n validator.message(\"description\", details.description, \"required\")\n ? \"negative\"\n : undefined\n }\n onBlur={() => {\n validator.showMessageFor(\"description\");\n }}\n onBlurCapture={(event) => {\n handleInputChange(event, details, setDetails);\n validator.showMessageFor(\"description\");\n }}\n />\n </Fieldset>\n <Fieldset legend='Group By' className='query-builder-container'>\n <RadioTileGroup\n className=\"radio-group-tile\"\n required>\n <RadioTile\n name={\"groupby\"}\n icon={<SvgCursor />}\n onChange={changeGroupByType}\n defaultChecked\n value={\"Selection\"}\n label={\"Selection\"}\n disabled={isLoading || isRendering}\n />\n <RadioTile\n icon={<SvgSearch />}\n name={\"groupby\"}\n onChange={changeGroupByType}\n value={\"Query Keywords\"}\n label={\"Query Keywords\"}\n disabled={isLoading || isRendering}\n />\n </RadioTileGroup>\n {groupByType === \"Selection\" ?\n <GroupQueryBuilderContext.Provider\n value={{\n currentPropertyList,\n setCurrentPropertyList,\n query,\n setQuery,\n queryBuilder,\n setQueryBuilder,\n isLoading,\n isRendering,\n }}\n >\n <GroupQueryBuilderContainer />\n </GroupQueryBuilderContext.Provider> :\n <div className=\"search-form\">\n <Text>Generate a query by keywords. Keywords wrapped in double quotes will be considered a required criteria.</Text>\n <LabeledTextarea\n label=\"Query Keywords\"\n required\n value={searchInput}\n onChange={(event) => setSearchInput(event.target.value)}\n disabled={isLoading || isRendering}\n placeholder={`ex: wall curtain \"panel\" facade`} />\n <div className=\"search-actions\">\n {isRendering &&\n <LoadingSpinner />\n }\n <Button disabled={isLoading || isRendering} onClick={() => generateSearchQuery(searchInput ? searchInput.split(\" \") : [])}>Apply</Button>\n <Button disabled={isLoading || isRendering} onClick={() => {\n setQuery(\"\");\n setSearchInput(\"\");\n }}>Clear</Button>\n </div>\n </div>\n }\n </Fieldset>\n </div>\n <ActionPanel\n onSave={async () => {\n await save();\n }}\n onCancel={async () => {\n Presentation.selection.clearSelection(\n \"GroupingMappingWidget\",\n iModelConnection,\n );\n await goBack();\n }}\n disabled={\n !(details.groupName && details.description && (query || simpleQuery) && !isRendering && !isLoading)\n }\n isLoading={isLoading}\n />\n </>\n );\n};\n\nexport default GroupAction;\n"]}
|
|
@@ -16,4 +16,27 @@
|
|
|
16
16
|
flex-direction: column;
|
|
17
17
|
gap: $iui-baseline;
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
.query-builder-container {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
gap: $iui-baseline;
|
|
24
|
+
|
|
25
|
+
.radio-group-tile {
|
|
26
|
+
display: flex;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.search-form {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
gap: $iui-baseline;
|
|
34
|
+
margin-top: $iui-baseline;
|
|
35
|
+
> .search-actions {
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: flex-end;
|
|
38
|
+
gap: $iui-s;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
19
42
|
}
|
|
@@ -7,7 +7,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
7
7
|
import { reportingClientApi } from "../../api/reportingClient";
|
|
8
8
|
import ActionPanel from "./ActionPanel";
|
|
9
9
|
import useValidator, { NAME_REQUIREMENTS } from "../hooks/useValidator";
|
|
10
|
-
import { WidgetHeader } from "./utils";
|
|
10
|
+
import { handleError, WidgetHeader } from "./utils";
|
|
11
11
|
import "./GroupPropertyAction.scss";
|
|
12
12
|
export const quantityTypesSelectionOptions = [
|
|
13
13
|
{ value: "Area", label: "Area" },
|
|
@@ -38,11 +38,17 @@ const extractPrimitive = (propertiesField, classToPropertiesMapping, navigation)
|
|
|
38
38
|
const label = navigation
|
|
39
39
|
? `${propertiesField.label} (${navigation === null || navigation === void 0 ? void 0 : navigation.navigationName})`
|
|
40
40
|
: propertiesField.label;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
// Ignore hardcoded BisCore navigation properties
|
|
42
|
+
if (propertiesField.type.typeName === "navigation") {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
(_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
|
|
47
|
+
name: propertyName,
|
|
48
|
+
label,
|
|
49
|
+
type: propertiesField.properties[0].property.type,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
46
52
|
};
|
|
47
53
|
const extractStructProperties = (name, className, classToPropertiesMapping, members) => {
|
|
48
54
|
var _a;
|
|
@@ -63,6 +69,7 @@ const extractStructProperties = (name, className, classToPropertiesMapping, memb
|
|
|
63
69
|
}
|
|
64
70
|
};
|
|
65
71
|
const extractProperties = (properties, classToPropertiesMapping, navigation) => {
|
|
72
|
+
var _a, _b;
|
|
66
73
|
for (const property of properties) {
|
|
67
74
|
switch (property.type.valueFormat) {
|
|
68
75
|
case PropertyValueFormat.Primitive: {
|
|
@@ -79,19 +86,8 @@ const extractProperties = (properties, classToPropertiesMapping, navigation) =>
|
|
|
79
86
|
}
|
|
80
87
|
switch (nestedContentField.relationshipMeaning) {
|
|
81
88
|
case RelationshipMeaning.SameInstance: {
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
if (!nestedContentField.pathToPrimaryClass) {
|
|
85
|
-
const columnName = property.properties[0]
|
|
86
|
-
.property.name;
|
|
87
|
-
const className = property.properties[0]
|
|
88
|
-
.property.classInfo.name;
|
|
89
|
-
extractStructProperties(navigation
|
|
90
|
-
? `${navigation.navigationName}.${columnName}`
|
|
91
|
-
: columnName, navigation ? navigation.rootClassName : className, classToPropertiesMapping, property.type.members);
|
|
92
|
-
// Check for aspects. Ignore them if coming from navigation.
|
|
93
|
-
}
|
|
94
|
-
else if (!navigation &&
|
|
89
|
+
// Check for aspects. Ignore them if coming from navigation.
|
|
90
|
+
if (!navigation &&
|
|
95
91
|
(nestedContentField.pathToPrimaryClass[0].relationshipInfo
|
|
96
92
|
.name === "BisCore:ElementOwnsUniqueAspect" ||
|
|
97
93
|
nestedContentField.pathToPrimaryClass[0].relationshipInfo
|
|
@@ -115,9 +111,33 @@ const extractProperties = (properties, classToPropertiesMapping, navigation) =>
|
|
|
115
111
|
navigationName: "TypeDefinition",
|
|
116
112
|
rootClassName: className,
|
|
117
113
|
});
|
|
114
|
+
// Hardcoded BisCore navigation properties for the type definition.
|
|
115
|
+
(_a = classToPropertiesMapping.get(className)) === null || _a === void 0 ? void 0 : _a.push({
|
|
116
|
+
name: "TypeDefinition.Model.ModeledElement.UserLabel",
|
|
117
|
+
label: "Model UserLabel (TypeDefinition)",
|
|
118
|
+
type: "string",
|
|
119
|
+
});
|
|
120
|
+
(_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
|
|
121
|
+
name: "TypeDefinition.Model.ModeledElement.CodeValue",
|
|
122
|
+
label: "Model CodeValue (TypeDefinition)",
|
|
123
|
+
type: "string",
|
|
124
|
+
});
|
|
118
125
|
}
|
|
119
126
|
break;
|
|
120
127
|
}
|
|
128
|
+
default: {
|
|
129
|
+
// Some elements don't have a path to primary class or relationship meaning..
|
|
130
|
+
// Most likely a simple struct property
|
|
131
|
+
if (!nestedContentField.pathToPrimaryClass) {
|
|
132
|
+
const columnName = property.properties[0]
|
|
133
|
+
.property.name;
|
|
134
|
+
const className = property.properties[0]
|
|
135
|
+
.property.classInfo.name;
|
|
136
|
+
extractStructProperties(navigation
|
|
137
|
+
? `${navigation.navigationName}.${columnName}`
|
|
138
|
+
: columnName, navigation ? navigation.rootClassName : className, classToPropertiesMapping, property.type.members);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
121
141
|
}
|
|
122
142
|
}
|
|
123
143
|
}
|
|
@@ -135,7 +155,7 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
135
155
|
const [isLoading, setIsLoading] = useState(false);
|
|
136
156
|
useEffect(() => {
|
|
137
157
|
const getContent = async () => {
|
|
138
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
158
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
139
159
|
setIsLoading(true);
|
|
140
160
|
const ruleSet = {
|
|
141
161
|
id: "element-properties",
|
|
@@ -145,18 +165,9 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
145
165
|
specifications: [
|
|
146
166
|
{
|
|
147
167
|
specType: ContentSpecificationTypes.SelectedNodeInstances,
|
|
148
|
-
// relationshipPaths: [
|
|
149
|
-
// {
|
|
150
|
-
// relationship: {
|
|
151
|
-
// schemaName: "BisCore",
|
|
152
|
-
// className: "ElementMultiAspect",
|
|
153
|
-
// },
|
|
154
|
-
// direction: RelationshipDirection.Forward,
|
|
155
|
-
// },
|
|
156
|
-
// ],
|
|
157
168
|
},
|
|
158
169
|
],
|
|
159
|
-
}
|
|
170
|
+
}
|
|
160
171
|
],
|
|
161
172
|
};
|
|
162
173
|
const requestOptions = {
|
|
@@ -172,13 +183,35 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
172
183
|
// Map properties to their classes
|
|
173
184
|
const classToPropertiesMapping = new Map();
|
|
174
185
|
extractProperties(properties, classToPropertiesMapping);
|
|
186
|
+
const rootClassName = keySet.instanceKeys.keys().next().value;
|
|
187
|
+
// Hardcoded BisCore navigation properties.
|
|
188
|
+
(_b = classToPropertiesMapping.get(rootClassName)) === null || _b === void 0 ? void 0 : _b.push({
|
|
189
|
+
name: "Model.ModeledElement.UserLabel",
|
|
190
|
+
label: "Model UserLabel",
|
|
191
|
+
type: "string",
|
|
192
|
+
});
|
|
193
|
+
(_c = classToPropertiesMapping.get(rootClassName)) === null || _c === void 0 ? void 0 : _c.push({
|
|
194
|
+
name: "Model.ModeledElement.CodeValue",
|
|
195
|
+
label: "Model CodeValue",
|
|
196
|
+
type: "string",
|
|
197
|
+
});
|
|
198
|
+
(_d = classToPropertiesMapping.get(rootClassName)) === null || _d === void 0 ? void 0 : _d.push({
|
|
199
|
+
name: "Category.CodeValue",
|
|
200
|
+
label: "Category CodeValue",
|
|
201
|
+
type: "string",
|
|
202
|
+
});
|
|
203
|
+
(_e = classToPropertiesMapping.get(rootClassName)) === null || _e === void 0 ? void 0 : _e.push({
|
|
204
|
+
name: "Category.UserLabel",
|
|
205
|
+
label: "Category UserLabel",
|
|
206
|
+
type: "string",
|
|
207
|
+
});
|
|
175
208
|
setClassToPropertiesMapping(classToPropertiesMapping);
|
|
176
209
|
let newEcProperties;
|
|
177
210
|
// Fetch already existing ec properties then add all classes from presentation
|
|
178
211
|
if (groupPropertyId) {
|
|
179
212
|
// TODO Error handling
|
|
180
213
|
const response = await reportingClientApi.getGroupProperty(iModelId, mappingId, groupId, groupPropertyId);
|
|
181
|
-
newEcProperties = (
|
|
214
|
+
newEcProperties = (_g = (_f = response.property) === null || _f === void 0 ? void 0 : _f.ecProperties) !== null && _g !== void 0 ? _g : [];
|
|
182
215
|
let keys = Array.from(classToPropertiesMapping.keys()).reverse();
|
|
183
216
|
for (const ecProperty of newEcProperties) {
|
|
184
217
|
keys = keys.filter((key) => `${ecProperty.ecSchemaName}:${ecProperty.ecClassName}` !== key);
|
|
@@ -190,9 +223,9 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
190
223
|
ecPropertyName: "",
|
|
191
224
|
ecPropertyType: "",
|
|
192
225
|
})));
|
|
193
|
-
setPropertyName((
|
|
194
|
-
setDataType((
|
|
195
|
-
setQuantityType((
|
|
226
|
+
setPropertyName((_j = (_h = response.property) === null || _h === void 0 ? void 0 : _h.propertyName) !== null && _j !== void 0 ? _j : "");
|
|
227
|
+
setDataType((_l = (_k = response.property) === null || _k === void 0 ? void 0 : _k.dataType) !== null && _l !== void 0 ? _l : "");
|
|
228
|
+
setQuantityType((_o = (_m = response.property) === null || _m === void 0 ? void 0 : _m.quantityType) !== null && _o !== void 0 ? _o : "");
|
|
196
229
|
}
|
|
197
230
|
else {
|
|
198
231
|
newEcProperties = Array.from(classToPropertiesMapping)
|
|
@@ -232,7 +265,8 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
232
265
|
: await reportingClientApi.createGroupProperty(iModelId, mappingId, groupId, groupProperty);
|
|
233
266
|
await returnFn();
|
|
234
267
|
}
|
|
235
|
-
catch {
|
|
268
|
+
catch (error) {
|
|
269
|
+
handleError(error.status);
|
|
236
270
|
setIsLoading(false);
|
|
237
271
|
}
|
|
238
272
|
};
|