@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.
Files changed (136) hide show
  1. package/README.md +7 -2
  2. package/lib/cjs/widget/GroupingMappingWidget.d.ts +2 -2
  3. package/lib/cjs/widget/GroupingMappingWidget.js +4 -3
  4. package/lib/cjs/widget/GroupingMappingWidget.js.map +1 -1
  5. package/lib/cjs/widget/components/ActionPanel.js +5 -3
  6. package/lib/cjs/widget/components/ActionPanel.js.map +1 -1
  7. package/lib/cjs/widget/components/CalculatedPropertyAction.js +8 -2
  8. package/lib/cjs/widget/components/CalculatedPropertyAction.js.map +1 -1
  9. package/lib/cjs/widget/components/CalculatedPropertyTable.js +3 -2
  10. package/lib/cjs/widget/components/CalculatedPropertyTable.js.map +1 -1
  11. package/lib/cjs/widget/components/ConfirmMappingsImport.js +30 -12
  12. package/lib/cjs/widget/components/ConfirmMappingsImport.js.map +1 -1
  13. package/lib/cjs/widget/components/ConfirmMappingsImport.scss +0 -7
  14. package/lib/cjs/widget/components/CustomCalculationAction.js +3 -1
  15. package/lib/cjs/widget/components/CustomCalculationAction.js.map +1 -1
  16. package/lib/cjs/widget/components/CustomCalculationTable.js +4 -3
  17. package/lib/cjs/widget/components/CustomCalculationTable.js.map +1 -1
  18. package/lib/cjs/widget/components/DeleteModal.js +7 -6
  19. package/lib/cjs/widget/components/DeleteModal.js.map +1 -1
  20. package/lib/cjs/widget/components/DeleteModal.scss +6 -0
  21. package/lib/cjs/widget/components/GroupAction.js +98 -28
  22. package/lib/cjs/widget/components/GroupAction.js.map +1 -1
  23. package/lib/cjs/widget/components/GroupAction.scss +23 -0
  24. package/lib/cjs/widget/components/GroupPropertyAction.js +68 -34
  25. package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
  26. package/lib/cjs/widget/components/GroupPropertyTable.js +3 -2
  27. package/lib/cjs/widget/components/GroupPropertyTable.js.map +1 -1
  28. package/lib/cjs/widget/components/GroupQueryBuilderContext.d.ts +2 -0
  29. package/lib/cjs/widget/components/GroupQueryBuilderContext.js +2 -0
  30. package/lib/cjs/widget/components/GroupQueryBuilderContext.js.map +1 -1
  31. package/lib/cjs/widget/components/Grouping.js +69 -12
  32. package/lib/cjs/widget/components/Grouping.js.map +1 -1
  33. package/lib/cjs/widget/components/Mapping.js +2 -1
  34. package/lib/cjs/widget/components/Mapping.js.map +1 -1
  35. package/lib/cjs/widget/components/MappingAction.js +2 -1
  36. package/lib/cjs/widget/components/MappingAction.js.map +1 -1
  37. package/lib/cjs/widget/components/MappingImportWizardModal.js +1 -1
  38. package/lib/cjs/widget/components/MappingImportWizardModal.js.map +1 -1
  39. package/lib/cjs/widget/components/MappingImportWizardModal.scss +1 -1
  40. package/lib/cjs/widget/components/PropertyMenu.js +22 -12
  41. package/lib/cjs/widget/components/PropertyMenu.js.map +1 -1
  42. package/lib/cjs/widget/components/PropertyMenu.scss +3 -0
  43. package/lib/cjs/widget/components/QueryBuilder.d.ts +1 -1
  44. package/lib/cjs/widget/components/QueryBuilder.js +11 -5
  45. package/lib/cjs/widget/components/QueryBuilder.js.map +1 -1
  46. package/lib/cjs/widget/components/SelectMappings.js +3 -1
  47. package/lib/cjs/widget/components/SelectMappings.js.map +1 -1
  48. package/lib/cjs/widget/components/SelectProject.scss +1 -1
  49. package/lib/cjs/widget/components/property-grid/PrimitivePropertyRenderer.js +7 -3
  50. package/lib/cjs/widget/components/property-grid/PrimitivePropertyRenderer.js.map +1 -1
  51. package/lib/cjs/widget/components/property-grid/PropertyGrid.scss +3 -3
  52. package/lib/cjs/widget/components/property-grid/PropertyRender.d.ts +1 -1
  53. package/lib/cjs/widget/components/property-grid/PropertyRender.js +5 -8
  54. package/lib/cjs/widget/components/property-grid/PropertyRender.js.map +1 -1
  55. package/lib/cjs/widget/components/property-grid/PropertyView.d.ts +2 -0
  56. package/lib/cjs/widget/components/property-grid/PropertyView.js +14 -11
  57. package/lib/cjs/widget/components/property-grid/PropertyView.js.map +1 -1
  58. package/lib/cjs/widget/components/property-grid/PropertyView.scss +19 -4
  59. package/lib/cjs/widget/components/utils.d.ts +2 -0
  60. package/lib/cjs/widget/components/utils.js +45 -4
  61. package/lib/cjs/widget/components/utils.js.map +1 -1
  62. package/lib/cjs/widget/components/utils.scss +5 -0
  63. package/lib/cjs/widget/components/viewerUtils.js +1 -1
  64. package/lib/cjs/widget/components/viewerUtils.js.map +1 -1
  65. package/lib/esm/widget/GroupingMappingWidget.d.ts +2 -2
  66. package/lib/esm/widget/GroupingMappingWidget.js +5 -4
  67. package/lib/esm/widget/GroupingMappingWidget.js.map +1 -1
  68. package/lib/esm/widget/components/ActionPanel.js +6 -4
  69. package/lib/esm/widget/components/ActionPanel.js.map +1 -1
  70. package/lib/esm/widget/components/CalculatedPropertyAction.js +9 -3
  71. package/lib/esm/widget/components/CalculatedPropertyAction.js.map +1 -1
  72. package/lib/esm/widget/components/CalculatedPropertyTable.js +3 -2
  73. package/lib/esm/widget/components/CalculatedPropertyTable.js.map +1 -1
  74. package/lib/esm/widget/components/ConfirmMappingsImport.js +30 -12
  75. package/lib/esm/widget/components/ConfirmMappingsImport.js.map +1 -1
  76. package/lib/esm/widget/components/ConfirmMappingsImport.scss +0 -7
  77. package/lib/esm/widget/components/CustomCalculationAction.js +4 -2
  78. package/lib/esm/widget/components/CustomCalculationAction.js.map +1 -1
  79. package/lib/esm/widget/components/CustomCalculationTable.js +4 -3
  80. package/lib/esm/widget/components/CustomCalculationTable.js.map +1 -1
  81. package/lib/esm/widget/components/DeleteModal.js +8 -7
  82. package/lib/esm/widget/components/DeleteModal.js.map +1 -1
  83. package/lib/esm/widget/components/DeleteModal.scss +6 -0
  84. package/lib/esm/widget/components/GroupAction.js +100 -30
  85. package/lib/esm/widget/components/GroupAction.js.map +1 -1
  86. package/lib/esm/widget/components/GroupAction.scss +23 -0
  87. package/lib/esm/widget/components/GroupPropertyAction.js +69 -35
  88. package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
  89. package/lib/esm/widget/components/GroupPropertyTable.js +3 -2
  90. package/lib/esm/widget/components/GroupPropertyTable.js.map +1 -1
  91. package/lib/esm/widget/components/GroupQueryBuilderContext.d.ts +2 -0
  92. package/lib/esm/widget/components/GroupQueryBuilderContext.js +2 -0
  93. package/lib/esm/widget/components/GroupQueryBuilderContext.js.map +1 -1
  94. package/lib/esm/widget/components/Grouping.js +71 -14
  95. package/lib/esm/widget/components/Grouping.js.map +1 -1
  96. package/lib/esm/widget/components/Mapping.js +3 -2
  97. package/lib/esm/widget/components/Mapping.js.map +1 -1
  98. package/lib/esm/widget/components/MappingAction.js +3 -2
  99. package/lib/esm/widget/components/MappingAction.js.map +1 -1
  100. package/lib/esm/widget/components/MappingImportWizardModal.js +1 -1
  101. package/lib/esm/widget/components/MappingImportWizardModal.js.map +1 -1
  102. package/lib/esm/widget/components/MappingImportWizardModal.scss +1 -1
  103. package/lib/esm/widget/components/PropertyMenu.js +23 -13
  104. package/lib/esm/widget/components/PropertyMenu.js.map +1 -1
  105. package/lib/esm/widget/components/PropertyMenu.scss +3 -0
  106. package/lib/esm/widget/components/QueryBuilder.d.ts +1 -1
  107. package/lib/esm/widget/components/QueryBuilder.js +11 -5
  108. package/lib/esm/widget/components/QueryBuilder.js.map +1 -1
  109. package/lib/esm/widget/components/SelectMappings.js +3 -1
  110. package/lib/esm/widget/components/SelectMappings.js.map +1 -1
  111. package/lib/esm/widget/components/SelectProject.scss +1 -1
  112. package/lib/esm/widget/components/property-grid/PrimitivePropertyRenderer.js +7 -3
  113. package/lib/esm/widget/components/property-grid/PrimitivePropertyRenderer.js.map +1 -1
  114. package/lib/esm/widget/components/property-grid/PropertyGrid.scss +3 -3
  115. package/lib/esm/widget/components/property-grid/PropertyRender.d.ts +1 -1
  116. package/lib/esm/widget/components/property-grid/PropertyRender.js +5 -8
  117. package/lib/esm/widget/components/property-grid/PropertyRender.js.map +1 -1
  118. package/lib/esm/widget/components/property-grid/PropertyView.d.ts +2 -0
  119. package/lib/esm/widget/components/property-grid/PropertyView.js +14 -11
  120. package/lib/esm/widget/components/property-grid/PropertyView.js.map +1 -1
  121. package/lib/esm/widget/components/property-grid/PropertyView.scss +19 -4
  122. package/lib/esm/widget/components/utils.d.ts +2 -0
  123. package/lib/esm/widget/components/utils.js +43 -4
  124. package/lib/esm/widget/components/utils.js.map +1 -1
  125. package/lib/esm/widget/components/utils.scss +5 -0
  126. package/lib/esm/widget/components/viewerUtils.js +1 -1
  127. package/lib/esm/widget/components/viewerUtils.js.map +1 -1
  128. package/package.json +4 -4
  129. package/lib/cjs/widget/icons/DatabaseInfo.d.ts +0 -5
  130. package/lib/cjs/widget/icons/DatabaseInfo.js +0 -19
  131. package/lib/cjs/widget/icons/DatabaseInfo.js.map +0 -1
  132. package/lib/cjs/widget/icons/DatabaseInfo.scss +0 -12
  133. package/lib/esm/widget/icons/DatabaseInfo.d.ts +0 -5
  134. package/lib/esm/widget/icons/DatabaseInfo.js +0 -14
  135. package/lib/esm/widget/icons/DatabaseInfo.js.map +0 -1
  136. 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
- clearEmphasizedElements();
49
- if (!query || query === "") {
50
- return;
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: 'find-similar' },
125
- React.createElement(GroupQueryBuilderContext.Provider, { value: {
126
- currentPropertyList,
127
- setCurrentPropertyList,
128
- query,
129
- setQuery,
130
- queryBuilder,
131
- setQueryBuilder,
132
- } },
133
- React.createElement(GroupQueryBuilderContainer, null)))),
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
- (_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
42
- name: propertyName,
43
- label,
44
- type: propertiesField.properties[0].property.type,
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
- // Some elements don't have a path to primary class..
83
- // Most likely a simple struct property
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 = (_c = (_b = response.property) === null || _b === void 0 ? void 0 : _b.ecProperties) !== null && _c !== void 0 ? _c : [];
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((_e = (_d = response.property) === null || _d === void 0 ? void 0 : _d.propertyName) !== null && _e !== void 0 ? _e : "");
194
- setDataType((_g = (_f = response.property) === null || _f === void 0 ? void 0 : _f.dataType) !== null && _g !== void 0 ? _g : "");
195
- setQuantityType((_j = (_h = response.property) === null || _h === void 0 ? void 0 : _h.quantityType) !== null && _j !== void 0 ? _j : "");
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
  };