@itwin/grouping-mapping-widget 0.7.0 → 0.8.0

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.
Files changed (33) hide show
  1. package/lib/cjs/widget/components/GroupPropertyAction.d.ts +1 -1
  2. package/lib/cjs/widget/components/GroupPropertyAction.js +149 -302
  3. package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
  4. package/lib/cjs/widget/components/GroupPropertyAction.scss +82 -8
  5. package/lib/cjs/widget/components/GroupPropertyUtils.d.ts +21 -0
  6. package/lib/cjs/widget/components/GroupPropertyUtils.js +287 -0
  7. package/lib/cjs/widget/components/GroupPropertyUtils.js.map +1 -0
  8. package/lib/cjs/widget/components/HorizontalTile.d.ts +5 -3
  9. package/lib/cjs/widget/components/HorizontalTile.js +9 -6
  10. package/lib/cjs/widget/components/HorizontalTile.js.map +1 -1
  11. package/lib/cjs/widget/components/HorizontalTile.scss +46 -22
  12. package/lib/cjs/widget/components/SelectProject.js +2 -0
  13. package/lib/cjs/widget/components/SelectProject.js.map +1 -1
  14. package/lib/cjs/widget/components/SortableHorizontalTile.d.ts +8 -0
  15. package/lib/cjs/widget/components/SortableHorizontalTile.js +51 -0
  16. package/lib/cjs/widget/components/SortableHorizontalTile.js.map +1 -0
  17. package/lib/esm/widget/components/GroupPropertyAction.d.ts +1 -1
  18. package/lib/esm/widget/components/GroupPropertyAction.js +151 -304
  19. package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
  20. package/lib/esm/widget/components/GroupPropertyAction.scss +82 -8
  21. package/lib/esm/widget/components/GroupPropertyUtils.d.ts +21 -0
  22. package/lib/esm/widget/components/GroupPropertyUtils.js +280 -0
  23. package/lib/esm/widget/components/GroupPropertyUtils.js.map +1 -0
  24. package/lib/esm/widget/components/HorizontalTile.d.ts +5 -3
  25. package/lib/esm/widget/components/HorizontalTile.js +9 -6
  26. package/lib/esm/widget/components/HorizontalTile.js.map +1 -1
  27. package/lib/esm/widget/components/HorizontalTile.scss +46 -22
  28. package/lib/esm/widget/components/SelectProject.js +2 -0
  29. package/lib/esm/widget/components/SelectProject.js.map +1 -1
  30. package/lib/esm/widget/components/SortableHorizontalTile.d.ts +8 -0
  31. package/lib/esm/widget/components/SortableHorizontalTile.js +30 -0
  32. package/lib/esm/widget/components/SortableHorizontalTile.js.map +1 -0
  33. package/package.json +8 -3
@@ -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 [classToPropertiesMapping, setClassToPropertiesMapping] = react_1.useState();
181
- const [ecProperties, setEcProperties] = react_1.useState([]);
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 getContent = async () => {
187
- var _a, _b, _c, _d, _e;
99
+ const generateProperties = async () => {
100
+ var _a;
188
101
  setIsLoading(true);
189
- const ruleSet = {
190
- id: "element-properties",
191
- rules: [
192
- {
193
- ruleType: presentation_common_1.RuleTypes.Content,
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
- // Map properties to their classes
213
- const classToPropertiesMapping = new Map();
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 getContent();
130
+ void generateProperties();
283
131
  }, [getAccessToken, mappingClient, groupId, groupPropertyId, iModelConnection, iModelId, keySet, mappingId]);
284
132
  const onSave = async () => {
285
- const filteredEcProperties = ecProperties.filter((ecProperty) => ecProperty.ecPropertyName && ecProperty.ecPropertyType);
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: filteredEcProperties,
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 onChange = react_1.useCallback((value, index) => {
313
- setPropertyAlert(false);
314
- const property = JSON.parse(value);
315
- setEcProperties((ecProperties) => {
316
- const updatedEcProperties = [...ecProperties];
317
- updatedEcProperties[index].ecPropertyName = property.name;
318
- // Unique types
319
- let type = insights_client_1.DataType.Undefined;
320
- switch (property.type) {
321
- case "long":
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
- const propertyOptions = react_1.useMemo(() => {
332
- return ecProperties.map((ecProperty) => {
333
- var _a, _b;
334
- return (_b = (_a = classToPropertiesMapping === null || classToPropertiesMapping === void 0 ? void 0 : classToPropertiesMapping.get(`${ecProperty.ecSchemaName}:${ecProperty.ecClassName}`)) === null || _a === void 0 ? void 0 : _a.map((property) => ({
335
- value: JSON.stringify({
336
- name: property.name,
337
- type: property.type,
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, disabled: isLoading, onChange: (event) => {
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', disabled: isLoading, options: [
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', disabled: isLoading, options: exports.quantityTypesSelectionOptions, value: quantityType, onChange: setQuantityType, onShow: () => { }, onHide: () => { } })),
378
- react_1.default.createElement(itwinui_react_1.Fieldset, { className: 'gmw-property-selection-container', legend: 'Properties' },
379
- propertyAlert && (react_1.default.createElement(itwinui_react_1.Alert, { type: "negative" }, "Please select at least one property.")),
380
- isLoading &&
381
- Array(3)
382
- .fill(null)
383
- .map((_, index) => (react_1.default.createElement(itwinui_react_1.Text, { key: index, variant: 'headline', isSkeleton: true }, "LOADING SKELETON"))),
384
- ecProperties.map((ecProperty, index) => {
385
- return (react_1.default.createElement("div", { className: 'gmw-property-select-item', key: `${ecProperty.ecSchemaName}${ecProperty.ecClassName}` },
386
- react_1.default.createElement(itwinui_react_1.Text, { variant: 'leading' }, ecProperty.ecClassName),
387
- react_1.default.createElement(itwinui_react_1.Text, { isMuted: true, variant: 'small' }, ecProperty.ecSchemaName),
388
- react_1.default.createElement("div", { className: 'gmw-selection-and-reorder' },
389
- react_1.default.createElement(itwinui_react_1.Select, { options: propertyOptions[index], value: getValue(ecProperty, index), onChange: (value) => { value && onChange(value, index); }, placeholder: "<No Property Mapped>", style: { width: "100%" }, onShow: () => { }, onHide: () => { } }),
390
- react_1.default.createElement(itwinui_react_1.IconButton, { onClick: () => {
391
- const updatedEcPropertyList = [...ecProperties];
392
- updatedEcPropertyList[index] = {
393
- ...updatedEcPropertyList[index],
394
- ecPropertyName: "",
395
- ecPropertyType: insights_client_1.DataType.Undefined,
396
- };
397
- setEcProperties(updatedEcPropertyList);
398
- }, disabled: !ecProperty.ecPropertyName && !ecProperty.ecPropertyType },
399
- react_1.default.createElement(itwinui_icons_react_1.SvgRemove, null)),
400
- react_1.default.createElement(itwinui_react_1.IconButton, { onClick: () => {
401
- const tab = [...ecProperties];
402
- const item = tab.splice(index, 1);
403
- tab.splice(index - 1, 0, item[0]);
404
- setEcProperties(tab);
405
- }, disabled: index === 0 },
406
- react_1.default.createElement(itwinui_icons_react_1.SvgChevronUp, null)),
407
- react_1.default.createElement(itwinui_react_1.IconButton, { onClick: () => {
408
- const tab = [...ecProperties];
409
- const item = tab.splice(index, 1);
410
- tab.splice(index + 1, 0, item[0]);
411
- setEcProperties(tab);
412
- }, disabled: index === ecProperties.length - 1 },
413
- react_1.default.createElement(itwinui_icons_react_1.SvgChevronDown, null)))));
414
- }))),
415
- react_1.default.createElement(ActionPanel_1.default, { onSave: onSave, onCancel: async () => returnFn(false), isLoading: isLoading })));
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