@itwin/grouping-mapping-widget 0.7.0 → 0.8.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/lib/cjs/widget/components/BlockingOverlay.js +1 -2
- package/lib/cjs/widget/components/BlockingOverlay.js.map +1 -1
- package/lib/cjs/widget/components/BlockingOverlay.scss +8 -10
- package/lib/cjs/widget/components/GroupPropertyAction.d.ts +1 -1
- package/lib/cjs/widget/components/GroupPropertyAction.js +149 -302
- package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
- package/lib/cjs/widget/components/GroupPropertyAction.scss +82 -8
- package/lib/cjs/widget/components/GroupPropertyUtils.d.ts +21 -0
- package/lib/cjs/widget/components/GroupPropertyUtils.js +287 -0
- package/lib/cjs/widget/components/GroupPropertyUtils.js.map +1 -0
- package/lib/cjs/widget/components/GroupingMapping.scss +4 -1
- package/lib/cjs/widget/components/HorizontalTile.d.ts +5 -3
- package/lib/cjs/widget/components/HorizontalTile.js +9 -6
- package/lib/cjs/widget/components/HorizontalTile.js.map +1 -1
- package/lib/cjs/widget/components/HorizontalTile.scss +46 -22
- package/lib/cjs/widget/components/SelectProject.js +2 -0
- package/lib/cjs/widget/components/SelectProject.js.map +1 -1
- package/lib/cjs/widget/components/SortableHorizontalTile.d.ts +8 -0
- package/lib/cjs/widget/components/SortableHorizontalTile.js +51 -0
- package/lib/cjs/widget/components/SortableHorizontalTile.js.map +1 -0
- package/lib/esm/widget/components/BlockingOverlay.js +1 -2
- package/lib/esm/widget/components/BlockingOverlay.js.map +1 -1
- package/lib/esm/widget/components/BlockingOverlay.scss +8 -10
- package/lib/esm/widget/components/GroupPropertyAction.d.ts +1 -1
- package/lib/esm/widget/components/GroupPropertyAction.js +151 -304
- package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
- package/lib/esm/widget/components/GroupPropertyAction.scss +82 -8
- package/lib/esm/widget/components/GroupPropertyUtils.d.ts +21 -0
- package/lib/esm/widget/components/GroupPropertyUtils.js +280 -0
- package/lib/esm/widget/components/GroupPropertyUtils.js.map +1 -0
- package/lib/esm/widget/components/GroupingMapping.scss +4 -1
- package/lib/esm/widget/components/HorizontalTile.d.ts +5 -3
- package/lib/esm/widget/components/HorizontalTile.js +9 -6
- package/lib/esm/widget/components/HorizontalTile.js.map +1 -1
- package/lib/esm/widget/components/HorizontalTile.scss +46 -22
- package/lib/esm/widget/components/SelectProject.js +2 -0
- package/lib/esm/widget/components/SelectProject.js.map +1 -1
- package/lib/esm/widget/components/SortableHorizontalTile.d.ts +8 -0
- package/lib/esm/widget/components/SortableHorizontalTile.js +30 -0
- package/lib/esm/widget/components/SortableHorizontalTile.js.map +1 -0
- package/package.json +8 -3
|
@@ -14,8 +14,7 @@ const utils_1 = require("./utils");
|
|
|
14
14
|
require("./BlockingOverlay.scss");
|
|
15
15
|
const BlockingOverlay = ({ isVisible }) => {
|
|
16
16
|
return (react_1.default.createElement("div", { className: classnames_1.default("gmw-group-mapping-blocking-overlay", isVisible && "gmw-visible") },
|
|
17
|
-
react_1.default.createElement(
|
|
18
|
-
react_1.default.createElement(utils_1.LoadingSpinner, null))));
|
|
17
|
+
react_1.default.createElement(utils_1.LoadingSpinner, null)));
|
|
19
18
|
};
|
|
20
19
|
exports.BlockingOverlay = BlockingOverlay;
|
|
21
20
|
//# sourceMappingURL=BlockingOverlay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockingOverlay.js","sourceRoot":"","sources":["../../../../src/widget/components/BlockingOverlay.tsx"],"names":[],"mappings":";;;;;;AAAA;;;+FAG+F;AAC/F,4DAAoC;AACpC,kDAA0B;AAC1B,mCAAyC;AACzC,kCAAgC;AAMzB,MAAM,eAAe,GAAG,CAAC,EAAE,SAAS,EAAwB,EAAE,EAAE;IACrE,OAAO,CACL,uCAAK,SAAS,EAAE,oBAAU,CAAC,oCAAoC,EAAE,SAAS,IAAI,aAAa,CAAC;QAC1F,
|
|
1
|
+
{"version":3,"file":"BlockingOverlay.js","sourceRoot":"","sources":["../../../../src/widget/components/BlockingOverlay.tsx"],"names":[],"mappings":";;;;;;AAAA;;;+FAG+F;AAC/F,4DAAoC;AACpC,kDAA0B;AAC1B,mCAAyC;AACzC,kCAAgC;AAMzB,MAAM,eAAe,GAAG,CAAC,EAAE,SAAS,EAAwB,EAAE,EAAE;IACrE,OAAO,CACL,uCAAK,SAAS,EAAE,oBAAU,CAAC,oCAAoC,EAAE,SAAS,IAAI,aAAa,CAAC;QAC1F,8BAAC,sBAAc,OAAG,CACd,CACP,CAAC;AACJ,CAAC,CAAC;AANW,QAAA,eAAe,mBAM1B","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 classnames from \"classnames\";\nimport React from \"react\";\nimport { LoadingSpinner } from \"./utils\";\nimport \"./BlockingOverlay.scss\";\n\nexport interface BlockingOverlayProps {\n isVisible: boolean;\n}\n\nexport const BlockingOverlay = ({ isVisible }: BlockingOverlayProps) => {\n return (\n <div className={classnames(\"gmw-group-mapping-blocking-overlay\", isVisible && \"gmw-visible\")}>\n <LoadingSpinner />\n </div>\n );\n};\n"]}
|
|
@@ -2,14 +2,18 @@
|
|
|
2
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
@import
|
|
5
|
+
@import "~@itwin/itwinui-css/scss/variables";
|
|
6
6
|
|
|
7
7
|
.gmw-group-mapping-blocking-overlay {
|
|
8
8
|
background-color: black;
|
|
9
9
|
position: absolute;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
align-items: center;
|
|
13
|
+
top: $iui-baseline;
|
|
14
|
+
bottom: $iui-baseline;
|
|
15
|
+
right: $iui-s;
|
|
16
|
+
left: $iui-s;
|
|
13
17
|
opacity: 60%;
|
|
14
18
|
z-index: 9999;
|
|
15
19
|
visibility: hidden;
|
|
@@ -18,9 +22,3 @@
|
|
|
18
22
|
visibility: visible;
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
|
-
|
|
22
|
-
.gmw-group-mapping-blocking-overlay-spinner {
|
|
23
|
-
display: flex;
|
|
24
|
-
justify-content: center;
|
|
25
|
-
height: inherit;
|
|
26
|
-
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { KeySet } from "@itwin/presentation-common";
|
|
3
3
|
import type { SelectOption } from "@itwin/itwinui-react";
|
|
4
|
-
import "./GroupPropertyAction.scss";
|
|
5
4
|
import { QuantityType } from "@itwin/insights-client";
|
|
5
|
+
import "./GroupPropertyAction.scss";
|
|
6
6
|
interface GroupPropertyActionProps {
|
|
7
7
|
iModelId: string;
|
|
8
8
|
mappingId: string;
|
|
@@ -23,19 +23,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.quantityTypesSelectionOptions = void 0;
|
|
26
|
+
/*---------------------------------------------------------------------------------------------
|
|
27
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
28
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
29
|
+
*--------------------------------------------------------------------------------------------*/
|
|
30
|
+
const server_1 = require("react-dom/server");
|
|
26
31
|
const presentation_common_1 = require("@itwin/presentation-common");
|
|
27
|
-
const presentation_frontend_1 = require("@itwin/presentation-frontend");
|
|
28
32
|
const appui_react_1 = require("@itwin/appui-react");
|
|
29
|
-
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
|
|
30
33
|
const itwinui_react_1 = require("@itwin/itwinui-react");
|
|
31
34
|
const react_1 = __importStar(require("react"));
|
|
32
35
|
const ActionPanel_1 = __importDefault(require("./ActionPanel"));
|
|
33
36
|
const useValidator_1 = __importStar(require("../hooks/useValidator"));
|
|
34
37
|
const utils_1 = require("./utils");
|
|
35
|
-
require("./GroupPropertyAction.scss");
|
|
36
|
-
const insights_client_1 = require("@itwin/insights-client");
|
|
37
38
|
const MappingClientContext_1 = require("./context/MappingClientContext");
|
|
38
39
|
const GroupingApiConfigContext_1 = require("./context/GroupingApiConfigContext");
|
|
40
|
+
const HorizontalTile_1 = require("./HorizontalTile");
|
|
41
|
+
const insights_client_1 = require("@itwin/insights-client");
|
|
42
|
+
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
|
|
43
|
+
const core_1 = require("@dnd-kit/core");
|
|
44
|
+
const sortable_1 = require("@dnd-kit/sortable");
|
|
45
|
+
const SortableHorizontalTile_1 = __importDefault(require("./SortableHorizontalTile"));
|
|
46
|
+
const react_split_1 = __importDefault(require("react-split"));
|
|
47
|
+
require("./GroupPropertyAction.scss");
|
|
48
|
+
const GroupPropertyUtils_1 = require("./GroupPropertyUtils");
|
|
39
49
|
exports.quantityTypesSelectionOptions = [
|
|
40
50
|
{ value: insights_client_1.QuantityType.Area, label: "Area" },
|
|
41
51
|
{ value: insights_client_1.QuantityType.Distance, label: "Distance" },
|
|
@@ -46,130 +56,6 @@ exports.quantityTypesSelectionOptions = [
|
|
|
46
56
|
{ value: insights_client_1.QuantityType.Volume, label: "Volume" },
|
|
47
57
|
{ value: insights_client_1.QuantityType.Undefined, label: "No Quantity Type" },
|
|
48
58
|
];
|
|
49
|
-
const extractPrimitive = (propertiesField, classToPropertiesMapping, navigation) => {
|
|
50
|
-
var _a, _b;
|
|
51
|
-
// There are rare cases which only happens in multiple selections where it returns more than one.
|
|
52
|
-
// This also checks if this property comes from a navigation property
|
|
53
|
-
const className = (_a = navigation === null || navigation === void 0 ? void 0 : navigation.rootClassName) !== null && _a !== void 0 ? _a : propertiesField.properties[0].property.classInfo.name;
|
|
54
|
-
// Sometimes class names are not defined. Type error. Not guaranteed.
|
|
55
|
-
if (!className) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (!classToPropertiesMapping.has(className)) {
|
|
59
|
-
classToPropertiesMapping.set(className, []);
|
|
60
|
-
}
|
|
61
|
-
// Gets property name. Appends path if from navigation.
|
|
62
|
-
const propertyName = navigation
|
|
63
|
-
? `${navigation.navigationName}.${propertiesField.properties[0].property.name}`
|
|
64
|
-
: propertiesField.properties[0].property.name;
|
|
65
|
-
const label = navigation
|
|
66
|
-
? `${propertiesField.label} (${navigation === null || navigation === void 0 ? void 0 : navigation.navigationName})`
|
|
67
|
-
: propertiesField.label;
|
|
68
|
-
// Ignore hardcoded BisCore navigation properties
|
|
69
|
-
if (propertiesField.type.typeName === "navigation") {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
(_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
|
|
74
|
-
name: propertyName,
|
|
75
|
-
label,
|
|
76
|
-
type: propertiesField.properties[0].property.type,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
const extractStructProperties = (name, className, classToPropertiesMapping, members) => {
|
|
81
|
-
var _a;
|
|
82
|
-
for (const member of members) {
|
|
83
|
-
if (member.type.valueFormat === presentation_common_1.PropertyValueFormat.Primitive) {
|
|
84
|
-
if (!classToPropertiesMapping.has(className)) {
|
|
85
|
-
classToPropertiesMapping.set(className, []);
|
|
86
|
-
}
|
|
87
|
-
(_a = classToPropertiesMapping.get(className)) === null || _a === void 0 ? void 0 : _a.push({
|
|
88
|
-
name: `${name}.${member.name}`,
|
|
89
|
-
label: member.label,
|
|
90
|
-
type: member.type.typeName,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
else if (member.type.valueFormat === presentation_common_1.PropertyValueFormat.Struct) {
|
|
94
|
-
extractStructProperties(`${name}.${member.name}`, className, classToPropertiesMapping, member.type.members);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
const extractProperties = (properties, classToPropertiesMapping, navigation) => {
|
|
99
|
-
var _a, _b;
|
|
100
|
-
for (const property of properties) {
|
|
101
|
-
switch (property.type.valueFormat) {
|
|
102
|
-
case presentation_common_1.PropertyValueFormat.Primitive: {
|
|
103
|
-
extractPrimitive(property, classToPropertiesMapping, navigation);
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
// Get structs
|
|
107
|
-
case presentation_common_1.PropertyValueFormat.Struct: {
|
|
108
|
-
const nestedContentField = property;
|
|
109
|
-
// Only handling single path and not handling nested content fields within navigations
|
|
110
|
-
if (nestedContentField.pathToPrimaryClass &&
|
|
111
|
-
nestedContentField.pathToPrimaryClass.length > 1) {
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
switch (nestedContentField.relationshipMeaning) {
|
|
115
|
-
case presentation_common_1.RelationshipMeaning.SameInstance: {
|
|
116
|
-
// Check for aspects. Ignore them if coming from navigation.
|
|
117
|
-
if (!navigation &&
|
|
118
|
-
(nestedContentField.pathToPrimaryClass[0].relationshipInfo
|
|
119
|
-
.name === "BisCore:ElementOwnsUniqueAspect" ||
|
|
120
|
-
nestedContentField.pathToPrimaryClass[0].relationshipInfo
|
|
121
|
-
.name === "BisCore:ElementOwnsMultiAspects")) {
|
|
122
|
-
const className = nestedContentField.contentClassInfo.name;
|
|
123
|
-
if (!classToPropertiesMapping.has(className)) {
|
|
124
|
-
classToPropertiesMapping.set(className, []);
|
|
125
|
-
}
|
|
126
|
-
extractProperties(nestedContentField.nestedFields, classToPropertiesMapping, navigation);
|
|
127
|
-
}
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
// Navigation properties
|
|
131
|
-
case presentation_common_1.RelationshipMeaning.RelatedInstance: {
|
|
132
|
-
if (
|
|
133
|
-
// Deal with a TypeDefinition
|
|
134
|
-
nestedContentField.pathToPrimaryClass[0].relationshipInfo.name ===
|
|
135
|
-
"BisCore:GeometricElement3dHasTypeDefinition") {
|
|
136
|
-
const className = nestedContentField.pathToPrimaryClass[0].targetClassInfo.name;
|
|
137
|
-
extractProperties(nestedContentField.nestedFields, classToPropertiesMapping, {
|
|
138
|
-
navigationName: "TypeDefinition",
|
|
139
|
-
rootClassName: className,
|
|
140
|
-
});
|
|
141
|
-
// Hardcoded BisCore navigation properties for the type definition.
|
|
142
|
-
(_a = classToPropertiesMapping.get(className)) === null || _a === void 0 ? void 0 : _a.push({
|
|
143
|
-
name: "TypeDefinition.Model.ModeledElement.UserLabel",
|
|
144
|
-
label: "Model UserLabel (TypeDefinition)",
|
|
145
|
-
type: "string",
|
|
146
|
-
});
|
|
147
|
-
(_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
|
|
148
|
-
name: "TypeDefinition.Model.ModeledElement.CodeValue",
|
|
149
|
-
label: "Model CodeValue (TypeDefinition)",
|
|
150
|
-
type: "string",
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
default: {
|
|
156
|
-
// Some elements don't have a path to primary class or relationship meaning..
|
|
157
|
-
// Most likely a simple struct property
|
|
158
|
-
if (!nestedContentField.pathToPrimaryClass) {
|
|
159
|
-
const columnName = property.properties[0]
|
|
160
|
-
.property.name;
|
|
161
|
-
const className = property.properties[0]
|
|
162
|
-
.property.classInfo.name;
|
|
163
|
-
extractStructProperties(navigation
|
|
164
|
-
? `${navigation.navigationName}.${columnName}`
|
|
165
|
-
: columnName, navigation ? navigation.rootClassName : className, classToPropertiesMapping, property.type.members);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
59
|
const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, groupPropertyName, keySet, returnFn, }) => {
|
|
174
60
|
const iModelConnection = appui_react_1.useActiveIModelConnection();
|
|
175
61
|
const { getAccessToken } = GroupingApiConfigContext_1.useGroupingMappingApiConfig();
|
|
@@ -177,117 +63,75 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
177
63
|
const [propertyName, setPropertyName] = react_1.useState("");
|
|
178
64
|
const [dataType, setDataType] = react_1.useState(insights_client_1.DataType.Undefined);
|
|
179
65
|
const [quantityType, setQuantityType] = react_1.useState(insights_client_1.QuantityType.Undefined);
|
|
180
|
-
const [
|
|
181
|
-
const [
|
|
66
|
+
const [selectedProperties, setSelectedProperties] = react_1.useState([]);
|
|
67
|
+
const [propertiesMetaData, setPropertiesMetaData] = react_1.useState([]);
|
|
68
|
+
const [propertiesNotFoundAlert, setPropertiesNotFoundAlert] = react_1.useState(false);
|
|
182
69
|
const [validator, showValidationMessage] = useValidator_1.default();
|
|
183
|
-
const [propertyAlert, setPropertyAlert] = react_1.useState(false);
|
|
184
70
|
const [isLoading, setIsLoading] = react_1.useState(false);
|
|
71
|
+
const [searchInput, setSearchInput] = react_1.useState("");
|
|
72
|
+
const [activeSearchInput, setActiveSearchInput] = react_1.useState("");
|
|
73
|
+
const [searched, setSearched] = react_1.useState(false);
|
|
74
|
+
const [activeDragProperty, setActiveDragProperty] = react_1.useState();
|
|
75
|
+
const sensors = core_1.useSensors(core_1.useSensor(core_1.PointerSensor), core_1.useSensor(core_1.KeyboardSensor, {
|
|
76
|
+
coordinateGetter: sortable_1.sortableKeyboardCoordinates,
|
|
77
|
+
}));
|
|
78
|
+
const [showModal, setShowModal] = react_1.useState(false);
|
|
79
|
+
const handleDragStart = react_1.useCallback((event) => {
|
|
80
|
+
const { active } = event;
|
|
81
|
+
const activeProperty = selectedProperties.find((p) => active.id === p.key);
|
|
82
|
+
setActiveDragProperty(activeProperty);
|
|
83
|
+
}, [selectedProperties]);
|
|
84
|
+
const handleDragEnd = react_1.useCallback((event) => {
|
|
85
|
+
const { active, over } = event;
|
|
86
|
+
if (over && (active.id !== over.id)) {
|
|
87
|
+
setSelectedProperties((items) => {
|
|
88
|
+
const oldIndex = selectedProperties.findIndex((p) => active.id === p.key);
|
|
89
|
+
const newIndex = selectedProperties.findIndex((p) => over.id === p.key);
|
|
90
|
+
return sortable_1.arrayMove(items, oldIndex, newIndex);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
setActiveDragProperty(undefined);
|
|
94
|
+
}, [selectedProperties]);
|
|
95
|
+
const filteredProperties = react_1.useMemo(() => propertiesMetaData.filter((p) => [p.displayLabel, p.categoryLabel, p.actualECClassName]
|
|
96
|
+
.map((l) => l.toLowerCase())
|
|
97
|
+
.some((l) => l.includes(activeSearchInput.toLowerCase()))), [activeSearchInput, propertiesMetaData]);
|
|
185
98
|
react_1.useEffect(() => {
|
|
186
|
-
const
|
|
187
|
-
var _a
|
|
99
|
+
const generateProperties = async () => {
|
|
100
|
+
var _a;
|
|
188
101
|
setIsLoading(true);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
specifications: [
|
|
195
|
-
{
|
|
196
|
-
specType: presentation_common_1.ContentSpecificationTypes.SelectedNodeInstances,
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
}
|
|
200
|
-
],
|
|
201
|
-
};
|
|
202
|
-
const requestOptions = {
|
|
203
|
-
imodel: iModelConnection,
|
|
204
|
-
keys: keySet,
|
|
205
|
-
rulesetOrId: ruleSet,
|
|
206
|
-
displayType: presentation_common_1.DefaultContentDisplayTypes.PropertyPane,
|
|
207
|
-
};
|
|
208
|
-
const content = await presentation_frontend_1.Presentation.presentation.getContentDescriptor(requestOptions);
|
|
209
|
-
// Only primitives and structs for now
|
|
210
|
-
const properties = (_a = content === null || content === void 0 ? void 0 : content.fields.filter((field) => field.type.valueFormat === presentation_common_1.PropertyValueFormat.Primitive ||
|
|
102
|
+
if (!iModelConnection)
|
|
103
|
+
return;
|
|
104
|
+
const descriptor = await GroupPropertyUtils_1.fetchPresentationDescriptor(iModelConnection, keySet);
|
|
105
|
+
// Only allow primitives and structs
|
|
106
|
+
const propertyFields = (_a = descriptor === null || descriptor === void 0 ? void 0 : descriptor.fields.filter((field) => field.type.valueFormat === presentation_common_1.PropertyValueFormat.Primitive ||
|
|
211
107
|
field.type.valueFormat === presentation_common_1.PropertyValueFormat.Struct)) !== null && _a !== void 0 ? _a : [];
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
extractProperties(properties, classToPropertiesMapping);
|
|
215
|
-
const rootClassName = keySet.instanceKeys.keys().next().value;
|
|
216
|
-
// Hardcoded BisCore navigation properties.
|
|
217
|
-
(_b = classToPropertiesMapping.get(rootClassName)) === null || _b === void 0 ? void 0 : _b.push({
|
|
218
|
-
name: "Model.ModeledElement.UserLabel",
|
|
219
|
-
label: "Model UserLabel",
|
|
220
|
-
type: "string",
|
|
221
|
-
});
|
|
222
|
-
(_c = classToPropertiesMapping.get(rootClassName)) === null || _c === void 0 ? void 0 : _c.push({
|
|
223
|
-
name: "Model.ModeledElement.CodeValue",
|
|
224
|
-
label: "Model CodeValue",
|
|
225
|
-
type: "string",
|
|
226
|
-
});
|
|
227
|
-
(_d = classToPropertiesMapping.get(rootClassName)) === null || _d === void 0 ? void 0 : _d.push({
|
|
228
|
-
name: "Category.CodeValue",
|
|
229
|
-
label: "Category CodeValue",
|
|
230
|
-
type: "string",
|
|
231
|
-
});
|
|
232
|
-
(_e = classToPropertiesMapping.get(rootClassName)) === null || _e === void 0 ? void 0 : _e.push({
|
|
233
|
-
name: "Category.UserLabel",
|
|
234
|
-
label: "Category UserLabel",
|
|
235
|
-
type: "string",
|
|
236
|
-
});
|
|
237
|
-
setClassToPropertiesMapping(classToPropertiesMapping);
|
|
238
|
-
let newEcProperties;
|
|
239
|
-
// Fetch already existing ec properties then add all classes from presentation
|
|
108
|
+
const propertiesMetaData = GroupPropertyUtils_1.convertPresentationFields(propertyFields);
|
|
109
|
+
setPropertiesMetaData(propertiesMetaData);
|
|
240
110
|
if (groupPropertyId) {
|
|
241
111
|
const accessToken = await getAccessToken();
|
|
242
112
|
let response;
|
|
243
113
|
try {
|
|
244
114
|
response = await mappingClient.getGroupProperty(accessToken, iModelId, mappingId, groupId, groupPropertyId);
|
|
115
|
+
setPropertyName(response.propertyName);
|
|
116
|
+
setDataType(response.dataType);
|
|
117
|
+
setQuantityType(response.quantityType);
|
|
118
|
+
const properties = GroupPropertyUtils_1.findProperties(response.ecProperties, propertiesMetaData);
|
|
119
|
+
if (properties.length === 0) {
|
|
120
|
+
setPropertiesNotFoundAlert(true);
|
|
121
|
+
}
|
|
122
|
+
setSelectedProperties(properties);
|
|
245
123
|
}
|
|
246
124
|
catch (error) {
|
|
247
125
|
utils_1.handleError(error.status);
|
|
248
126
|
}
|
|
249
|
-
if (!response) {
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
newEcProperties = response.ecProperties;
|
|
253
|
-
let keys = Array.from(classToPropertiesMapping.keys()).reverse();
|
|
254
|
-
for (const ecProperty of newEcProperties) {
|
|
255
|
-
keys = keys.filter((key) => `${ecProperty.ecSchemaName}:${ecProperty.ecClassName}` !== key);
|
|
256
|
-
}
|
|
257
|
-
newEcProperties.push(...keys.map((key) => ({
|
|
258
|
-
ecSchemaName: key.split(":")[0],
|
|
259
|
-
ecClassName: key.split(":")[1],
|
|
260
|
-
// Placeholders for properties
|
|
261
|
-
ecPropertyName: "",
|
|
262
|
-
ecPropertyType: insights_client_1.DataType.Undefined,
|
|
263
|
-
})));
|
|
264
|
-
setPropertyName(response.propertyName);
|
|
265
|
-
setDataType(response.dataType);
|
|
266
|
-
setQuantityType(response.quantityType);
|
|
267
127
|
}
|
|
268
|
-
else {
|
|
269
|
-
newEcProperties = Array.from(classToPropertiesMapping)
|
|
270
|
-
.map(([key]) => ({
|
|
271
|
-
ecSchemaName: key.split(":")[0],
|
|
272
|
-
ecClassName: key.split(":")[1],
|
|
273
|
-
// Placeholders for properties
|
|
274
|
-
ecPropertyName: "",
|
|
275
|
-
ecPropertyType: insights_client_1.DataType.Undefined,
|
|
276
|
-
}))
|
|
277
|
-
.reverse();
|
|
278
|
-
}
|
|
279
|
-
setEcProperties(newEcProperties);
|
|
280
128
|
setIsLoading(false);
|
|
281
129
|
};
|
|
282
|
-
void
|
|
130
|
+
void generateProperties();
|
|
283
131
|
}, [getAccessToken, mappingClient, groupId, groupPropertyId, iModelConnection, iModelId, keySet, mappingId]);
|
|
284
132
|
const onSave = async () => {
|
|
285
|
-
|
|
286
|
-
if (!filteredEcProperties.length || !validator.allValid()) {
|
|
133
|
+
if (!validator.allValid()) {
|
|
287
134
|
showValidationMessage(true);
|
|
288
|
-
if (!filteredEcProperties.length) {
|
|
289
|
-
setPropertyAlert(true);
|
|
290
|
-
}
|
|
291
135
|
return;
|
|
292
136
|
}
|
|
293
137
|
try {
|
|
@@ -297,7 +141,7 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
297
141
|
propertyName,
|
|
298
142
|
dataType,
|
|
299
143
|
quantityType,
|
|
300
|
-
ecProperties:
|
|
144
|
+
ecProperties: selectedProperties.map((p) => GroupPropertyUtils_1.convertToECProperties(p)).flat(),
|
|
301
145
|
};
|
|
302
146
|
groupPropertyId
|
|
303
147
|
? await mappingClient.updateGroupProperty(accessToken, iModelId, mappingId, groupId, groupPropertyId, groupProperty)
|
|
@@ -309,52 +153,29 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
309
153
|
setIsLoading(false);
|
|
310
154
|
}
|
|
311
155
|
};
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
type = insights_client_1.DataType.Integer;
|
|
323
|
-
break;
|
|
324
|
-
default:
|
|
325
|
-
type = property.type;
|
|
326
|
-
}
|
|
327
|
-
updatedEcProperties[index].ecPropertyType = type;
|
|
328
|
-
return updatedEcProperties;
|
|
329
|
-
});
|
|
156
|
+
const startSearch = react_1.useCallback(() => {
|
|
157
|
+
if (!searchInput)
|
|
158
|
+
return;
|
|
159
|
+
setActiveSearchInput(searchInput);
|
|
160
|
+
setSearched(true);
|
|
161
|
+
}, [searchInput]);
|
|
162
|
+
const clearSearch = react_1.useCallback(() => {
|
|
163
|
+
setSearchInput("");
|
|
164
|
+
setActiveSearchInput("");
|
|
165
|
+
setSearched(false);
|
|
330
166
|
}, []);
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}),
|
|
339
|
-
label: property.label,
|
|
340
|
-
}))) !== null && _b !== void 0 ? _b : [];
|
|
341
|
-
});
|
|
342
|
-
}, [classToPropertiesMapping, ecProperties]);
|
|
343
|
-
const getValue = react_1.useCallback((ecProperty, index) => {
|
|
344
|
-
var _a;
|
|
345
|
-
const property = (_a = classToPropertiesMapping === null || classToPropertiesMapping === void 0 ? void 0 : classToPropertiesMapping.get(`${ecProperty.ecSchemaName}:${ecProperty.ecClassName}`)) === null || _a === void 0 ? void 0 : _a.find((property) => property.name === ecProperties[index].ecPropertyName);
|
|
346
|
-
const result = JSON.stringify({
|
|
347
|
-
name: property === null || property === void 0 ? void 0 : property.name,
|
|
348
|
-
type: property === null || property === void 0 ? void 0 : property.type,
|
|
349
|
-
});
|
|
350
|
-
return result;
|
|
351
|
-
}, [classToPropertiesMapping, ecProperties]);
|
|
352
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
167
|
+
react_1.useEffect(() => {
|
|
168
|
+
if (searchInput.length === 0) {
|
|
169
|
+
setSearched(false);
|
|
170
|
+
clearSearch();
|
|
171
|
+
}
|
|
172
|
+
}, [searchInput, setSearched, clearSearch]);
|
|
173
|
+
return (react_1.default.createElement(core_1.DndContext, { sensors: sensors, collisionDetection: core_1.closestCenter, onDragStart: handleDragStart, onDragEnd: handleDragEnd },
|
|
353
174
|
react_1.default.createElement(utils_1.WidgetHeader, { title: groupPropertyName !== null && groupPropertyName !== void 0 ? groupPropertyName : "Add Property", returnFn: async () => returnFn(false) }),
|
|
354
175
|
react_1.default.createElement("div", { className: 'gmw-group-property-action-container' },
|
|
355
|
-
react_1.default.createElement(itwinui_react_1.Fieldset, { className: 'gmw-property-options', legend: 'Property Details' },
|
|
176
|
+
react_1.default.createElement(itwinui_react_1.Fieldset, { disabled: isLoading, className: 'gmw-property-options', legend: 'Property Details' },
|
|
356
177
|
react_1.default.createElement(itwinui_react_1.Small, { className: 'gmw-field-legend' }, "Asterisk * indicates mandatory fields."),
|
|
357
|
-
react_1.default.createElement(itwinui_react_1.LabeledInput, { id: 'propertyName', label: 'Property Name', value: propertyName, required: true,
|
|
178
|
+
react_1.default.createElement(itwinui_react_1.LabeledInput, { id: 'propertyName', label: 'Property Name', value: propertyName, required: true, onChange: (event) => {
|
|
358
179
|
setPropertyName(event.target.value);
|
|
359
180
|
validator.showMessageFor("propertyName");
|
|
360
181
|
}, message: validator.message("propertyName", propertyName, useValidator_1.NAME_REQUIREMENTS), status: validator.message("propertyName", propertyName, useValidator_1.NAME_REQUIREMENTS)
|
|
@@ -362,7 +183,7 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
362
183
|
: undefined, onBlur: () => {
|
|
363
184
|
validator.showMessageFor("propertyName");
|
|
364
185
|
} }),
|
|
365
|
-
react_1.default.createElement(itwinui_react_1.LabeledSelect, { label: "Data Type", id: 'dataType',
|
|
186
|
+
react_1.default.createElement(itwinui_react_1.LabeledSelect, { label: "Data Type", id: 'dataType', options: [
|
|
366
187
|
{ value: insights_client_1.DataType.Boolean, label: "Boolean" },
|
|
367
188
|
{ value: insights_client_1.DataType.Number, label: "Number" },
|
|
368
189
|
{ value: insights_client_1.DataType.String, label: "String" },
|
|
@@ -374,45 +195,71 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
|
|
|
374
195
|
: undefined, onBlur: () => {
|
|
375
196
|
validator.showMessageFor("dataType");
|
|
376
197
|
}, onShow: () => { }, onHide: () => { } }),
|
|
377
|
-
react_1.default.createElement(itwinui_react_1.LabeledSelect, { label: 'Quantity Type',
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
react_1.default.createElement(itwinui_react_1.Text,
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
react_1.default.createElement(itwinui_icons_react_1.
|
|
414
|
-
|
|
415
|
-
|
|
198
|
+
react_1.default.createElement(itwinui_react_1.LabeledSelect, { label: 'Quantity Type', options: exports.quantityTypesSelectionOptions, value: quantityType, onChange: setQuantityType, onShow: () => { }, onHide: () => { } })),
|
|
199
|
+
propertiesNotFoundAlert &&
|
|
200
|
+
react_1.default.createElement(itwinui_react_1.Alert, { type: "warning" }, "Warning: Could not match saved properties from the current generated list. It does not confirm or deny validity. Overwriting will occur if a new selection is made and saved."),
|
|
201
|
+
react_1.default.createElement(itwinui_react_1.Fieldset, { className: 'gmw-property-view-container', legend: "Mapped Properties" },
|
|
202
|
+
react_1.default.createElement("div", { className: "gmw-property-view-button" },
|
|
203
|
+
react_1.default.createElement(itwinui_react_1.Button, { onClick: async () => setShowModal(true), disabled: isLoading }, "Select Properties")),
|
|
204
|
+
react_1.default.createElement("div", { className: "gmw-properties-list" }, selectedProperties.length === 0 && !isLoading ?
|
|
205
|
+
react_1.default.createElement("div", { className: "gmw-empty-selection" },
|
|
206
|
+
react_1.default.createElement(itwinui_react_1.Text, null, "No properties selected."),
|
|
207
|
+
react_1.default.createElement(itwinui_react_1.Text, null, "Press the \"Select Properties\" button for options.")) :
|
|
208
|
+
selectedProperties.map((property) => (react_1.default.createElement(HorizontalTile_1.HorizontalTile, { key: property.key, title: `${property.displayLabel} (${property.propertyType})`, titleTooltip: `${property.actualECClassName}`, subText: property.categoryLabel, actionGroup: null })))))),
|
|
209
|
+
react_1.default.createElement(ActionPanel_1.default, { onSave: onSave, onCancel: async () => returnFn(false), isLoading: isLoading, isSavingDisabled: selectedProperties.length === 0 || !propertyName || !dataType }),
|
|
210
|
+
react_1.default.createElement(itwinui_react_1.Modal, { title: "Properties Selection", isOpen: showModal, onClose: () => {
|
|
211
|
+
setShowModal(false);
|
|
212
|
+
clearSearch();
|
|
213
|
+
}, closeOnExternalClick: false },
|
|
214
|
+
react_1.default.createElement(react_split_1.default, { expandToMin: false, className: "gmw-property-selection-container", gutterAlign: "center", gutterSize: 2, gutter: () => {
|
|
215
|
+
// Expects HTMLElement
|
|
216
|
+
const dragHangle = server_1.renderToStaticMarkup(react_1.default.createElement("div", { className: "gmw-gutter-drag-icon" },
|
|
217
|
+
react_1.default.createElement(itwinui_icons_react_1.SvgMoreVerticalSmall, null)));
|
|
218
|
+
const gutter = document.createElement("div");
|
|
219
|
+
gutter.className = `gmw-gutter`;
|
|
220
|
+
gutter.innerHTML = dragHangle;
|
|
221
|
+
return gutter;
|
|
222
|
+
}, direction: "horizontal" },
|
|
223
|
+
react_1.default.createElement(itwinui_react_1.Surface, { className: "gmw-available-properties", elevation: 1 },
|
|
224
|
+
react_1.default.createElement("div", { className: "gmw-available-properties-header" },
|
|
225
|
+
react_1.default.createElement(itwinui_react_1.Label, { as: "span" }, "Available Properties"),
|
|
226
|
+
react_1.default.createElement(itwinui_react_1.LabeledInput, { displayStyle: "inline", iconDisplayStyle: "inline", className: "gmw-available-prop-search", value: searchInput, size: "small", placeholder: "Search....", onChange: (event) => {
|
|
227
|
+
const { target: { value }, } = event;
|
|
228
|
+
setSearchInput(value);
|
|
229
|
+
}, onKeyDown: (event) => {
|
|
230
|
+
if (event.key === "Enter") {
|
|
231
|
+
startSearch();
|
|
232
|
+
}
|
|
233
|
+
}, svgIcon: searched ? (react_1.default.createElement(itwinui_react_1.IconButton, { onClick: clearSearch, styleType: "borderless" },
|
|
234
|
+
react_1.default.createElement(itwinui_icons_react_1.SvgClose, null))) : (react_1.default.createElement(itwinui_react_1.IconButton, { onClick: startSearch, styleType: "borderless" },
|
|
235
|
+
react_1.default.createElement(itwinui_icons_react_1.SvgSearch, null))) })),
|
|
236
|
+
filteredProperties.length === 0 ?
|
|
237
|
+
react_1.default.createElement("div", { className: "gmw-empty-selection" },
|
|
238
|
+
react_1.default.createElement(itwinui_react_1.Text, null, "No properties available. ")) :
|
|
239
|
+
react_1.default.createElement("div", { className: "gmw-properties-list" }, filteredProperties.map((property) => (react_1.default.createElement(HorizontalTile_1.HorizontalTile, { key: property.key, title: `${property.displayLabel} (${property.propertyType})`, titleTooltip: `${property.actualECClassName}`, subText: property.categoryLabel, actionGroup: null, selected: selectedProperties.some((p) => property.key === p.key), onClick: () => setSelectedProperties((sp) => sp.some((p) => property.key === p.key)
|
|
240
|
+
? sp.filter((p) => property.key !== p.key)
|
|
241
|
+
: [...sp, property]) }))))),
|
|
242
|
+
react_1.default.createElement(itwinui_react_1.Surface, { className: "gmw-selected-properties", elevation: 1 },
|
|
243
|
+
react_1.default.createElement(itwinui_react_1.Label, { as: "span" }, "Selected Properties"),
|
|
244
|
+
selectedProperties.length === 0 ?
|
|
245
|
+
react_1.default.createElement("div", { className: "gmw-empty-selection" },
|
|
246
|
+
react_1.default.createElement(itwinui_react_1.Text, null, "No properties selected."),
|
|
247
|
+
react_1.default.createElement(itwinui_react_1.Text, null, "Add some by clicking on the properties shown left.")) :
|
|
248
|
+
react_1.default.createElement("div", { className: "gmw-properties-list" },
|
|
249
|
+
react_1.default.createElement(sortable_1.SortableContext, { items: selectedProperties.map((p) => p.key), strategy: sortable_1.verticalListSortingStrategy }, selectedProperties.map((property) => react_1.default.createElement(SortableHorizontalTile_1.default, { key: property.key, id: property.key, title: `${property.displayLabel} (${property.propertyType})`, titleTooltip: `${property.actualECClassName}`, subText: property.categoryLabel, actionGroup: react_1.default.createElement("div", null,
|
|
250
|
+
react_1.default.createElement(itwinui_react_1.IconButton, { styleType: "borderless", title: "Remove", onClick: () => {
|
|
251
|
+
setSelectedProperties((sp) => sp.filter((p) => property.key !== p.key));
|
|
252
|
+
} },
|
|
253
|
+
react_1.default.createElement(itwinui_icons_react_1.SvgRemove, null))) })))))),
|
|
254
|
+
react_1.default.createElement(itwinui_react_1.ModalButtonBar, null,
|
|
255
|
+
react_1.default.createElement(itwinui_react_1.Button, { onClick: () => {
|
|
256
|
+
setShowModal(false);
|
|
257
|
+
clearSearch();
|
|
258
|
+
}, styleType: "high-visibility" }, "Close"))),
|
|
259
|
+
react_1.default.createElement(core_1.DragOverlay, { zIndex: 9999 }, activeDragProperty ?
|
|
260
|
+
react_1.default.createElement(HorizontalTile_1.HorizontalTile, { title: `${activeDragProperty.displayLabel} (${activeDragProperty.propertyType})`, titleTooltip: `${activeDragProperty.actualECClassName}`, subText: activeDragProperty.categoryLabel, actionGroup: react_1.default.createElement(itwinui_react_1.IconButton, { styleType: "borderless" },
|
|
261
|
+
react_1.default.createElement(itwinui_icons_react_1.SvgRemove, null)), dragHandle: react_1.default.createElement("div", { className: "gmw-drag-icon" },
|
|
262
|
+
react_1.default.createElement(itwinui_icons_react_1.SvgDragHandleVertical, null)) }) : null)));
|
|
416
263
|
};
|
|
417
264
|
exports.default = GroupPropertyAction;
|
|
418
265
|
//# sourceMappingURL=GroupPropertyAction.js.map
|