@itwin/grouping-mapping-widget 0.2.2 → 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 (61) hide show
  1. package/lib/cjs/widget/components/ActionPanel.js +5 -3
  2. package/lib/cjs/widget/components/ActionPanel.js.map +1 -1
  3. package/lib/cjs/widget/components/DeleteModal.js +4 -2
  4. package/lib/cjs/widget/components/DeleteModal.js.map +1 -1
  5. package/lib/cjs/widget/components/DeleteModal.scss +6 -0
  6. package/lib/cjs/widget/components/GroupAction.js +85 -12
  7. package/lib/cjs/widget/components/GroupAction.js.map +1 -1
  8. package/lib/cjs/widget/components/GroupAction.scss +23 -0
  9. package/lib/cjs/widget/components/GroupPropertyAction.js +51 -20
  10. package/lib/cjs/widget/components/GroupPropertyAction.js.map +1 -1
  11. package/lib/cjs/widget/components/GroupQueryBuilderContext.d.ts +2 -0
  12. package/lib/cjs/widget/components/GroupQueryBuilderContext.js +2 -0
  13. package/lib/cjs/widget/components/GroupQueryBuilderContext.js.map +1 -1
  14. package/lib/cjs/widget/components/QueryBuilder.d.ts +1 -1
  15. package/lib/cjs/widget/components/QueryBuilder.js +10 -4
  16. package/lib/cjs/widget/components/QueryBuilder.js.map +1 -1
  17. package/lib/cjs/widget/components/property-grid/PrimitivePropertyRenderer.js +7 -3
  18. package/lib/cjs/widget/components/property-grid/PrimitivePropertyRenderer.js.map +1 -1
  19. package/lib/cjs/widget/components/property-grid/PropertyGrid.scss +3 -3
  20. package/lib/cjs/widget/components/property-grid/PropertyRender.d.ts +1 -1
  21. package/lib/cjs/widget/components/property-grid/PropertyRender.js +5 -8
  22. package/lib/cjs/widget/components/property-grid/PropertyRender.js.map +1 -1
  23. package/lib/cjs/widget/components/property-grid/PropertyView.d.ts +2 -0
  24. package/lib/cjs/widget/components/property-grid/PropertyView.js +14 -11
  25. package/lib/cjs/widget/components/property-grid/PropertyView.js.map +1 -1
  26. package/lib/cjs/widget/components/property-grid/PropertyView.scss +19 -4
  27. package/lib/cjs/widget/components/utils.d.ts +1 -0
  28. package/lib/cjs/widget/components/utils.js +6 -1
  29. package/lib/cjs/widget/components/utils.js.map +1 -1
  30. package/lib/cjs/widget/components/utils.scss +5 -0
  31. package/lib/esm/widget/components/ActionPanel.js +6 -4
  32. package/lib/esm/widget/components/ActionPanel.js.map +1 -1
  33. package/lib/esm/widget/components/DeleteModal.js +6 -4
  34. package/lib/esm/widget/components/DeleteModal.js.map +1 -1
  35. package/lib/esm/widget/components/DeleteModal.scss +6 -0
  36. package/lib/esm/widget/components/GroupAction.js +87 -14
  37. package/lib/esm/widget/components/GroupAction.js.map +1 -1
  38. package/lib/esm/widget/components/GroupAction.scss +23 -0
  39. package/lib/esm/widget/components/GroupPropertyAction.js +51 -20
  40. package/lib/esm/widget/components/GroupPropertyAction.js.map +1 -1
  41. package/lib/esm/widget/components/GroupQueryBuilderContext.d.ts +2 -0
  42. package/lib/esm/widget/components/GroupQueryBuilderContext.js +2 -0
  43. package/lib/esm/widget/components/GroupQueryBuilderContext.js.map +1 -1
  44. package/lib/esm/widget/components/QueryBuilder.d.ts +1 -1
  45. package/lib/esm/widget/components/QueryBuilder.js +10 -4
  46. package/lib/esm/widget/components/QueryBuilder.js.map +1 -1
  47. package/lib/esm/widget/components/property-grid/PrimitivePropertyRenderer.js +7 -3
  48. package/lib/esm/widget/components/property-grid/PrimitivePropertyRenderer.js.map +1 -1
  49. package/lib/esm/widget/components/property-grid/PropertyGrid.scss +3 -3
  50. package/lib/esm/widget/components/property-grid/PropertyRender.d.ts +1 -1
  51. package/lib/esm/widget/components/property-grid/PropertyRender.js +5 -8
  52. package/lib/esm/widget/components/property-grid/PropertyRender.js.map +1 -1
  53. package/lib/esm/widget/components/property-grid/PropertyView.d.ts +2 -0
  54. package/lib/esm/widget/components/property-grid/PropertyView.js +14 -11
  55. package/lib/esm/widget/components/property-grid/PropertyView.js.map +1 -1
  56. package/lib/esm/widget/components/property-grid/PropertyView.scss +19 -4
  57. package/lib/esm/widget/components/utils.d.ts +1 -0
  58. package/lib/esm/widget/components/utils.js +5 -1
  59. package/lib/esm/widget/components/utils.js.map +1 -1
  60. package/lib/esm/widget/components/utils.scss +5 -0
  61. package/package.json +3 -3
@@ -26,12 +26,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  const itwinui_react_1 = require("@itwin/itwinui-react");
27
27
  const React = __importStar(require("react"));
28
28
  require("./ActionPanel.scss");
29
+ const utils_1 = require("./utils");
29
30
  const ActionPanel = ({ onSave, onCancel, disabled = false, isLoading = false, }) => {
30
31
  return (React.createElement("div", { id: 'action', className: 'action-panel-container' },
31
32
  React.createElement("div", { className: 'action-panel' },
32
- isLoading ? (React.createElement(itwinui_react_1.IconButton, { styleType: 'high-visibility' },
33
- React.createElement(itwinui_react_1.ProgressRadial, { size: "small", indeterminate: true }))) : (React.createElement(itwinui_react_1.Button, { disabled: disabled, styleType: 'high-visibility', id: 'save-app', onClick: onSave }, "Save")),
34
- React.createElement(itwinui_react_1.Button, { styleType: 'default', type: 'button', id: 'cancel', onClick: onCancel, disabled: isLoading }, "Cancel"))));
33
+ isLoading &&
34
+ React.createElement(utils_1.LoadingSpinner, null),
35
+ React.createElement(itwinui_react_1.Button, { disabled: disabled || isLoading, styleType: 'high-visibility', id: 'save-app', onClick: onSave }, "Save"),
36
+ React.createElement(itwinui_react_1.Button, { styleType: 'default', type: 'button', id: 'cancel', onClick: onCancel, disabled: disabled || isLoading }, "Cancel"))));
35
37
  };
36
38
  exports.default = ActionPanel;
37
39
  //# sourceMappingURL=ActionPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActionPanel.js","sourceRoot":"","sources":["../../../../src/widget/components/ActionPanel.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;+FAG+F;AAC/F,wDAA0E;AAC1E,6CAA+B;AAC/B,8BAA4B;AAS5B,MAAM,WAAW,GAAG,CAAC,EACnB,MAAM,EACN,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,KAAK,GACA,EAAe,EAAE;IAClC,OAAO,CACL,6BAAK,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAC,wBAAwB;QACjD,6BAAK,SAAS,EAAC,cAAc;YAC1B,SAAS,CAAC,CAAC,CAAC,CACX,oBAAC,0BAAU,IAAC,SAAS,EAAC,iBAAiB;gBACrC,oBAAC,8BAAc,IAAC,IAAI,EAAC,OAAO,EAAC,aAAa,SAAG,CAClC,CACd,CAAC,CAAC,CAAC,CACF,oBAAC,sBAAM,IACL,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,iBAAiB,EAC3B,EAAE,EAAC,UAAU,EACb,OAAO,EAAE,MAAM,WAGR,CACV;YACD,oBAAC,sBAAM,IACL,SAAS,EAAC,SAAS,EACnB,IAAI,EAAC,QAAQ,EACb,EAAE,EAAC,QAAQ,EACX,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,SAAS,aAGZ,CACL,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { Button, IconButton, ProgressRadial } from \"@itwin/itwinui-react\";\nimport * as React from \"react\";\nimport \"./ActionPanel.scss\";\n\nexport interface ActionPanelProps {\n onSave: () => void;\n onCancel: () => void;\n disabled?: boolean;\n isLoading?: boolean;\n}\n\nconst ActionPanel = ({\n onSave,\n onCancel,\n disabled = false,\n isLoading = false,\n}: ActionPanelProps): JSX.Element => {\n return (\n <div id='action' className='action-panel-container'>\n <div className='action-panel'>\n {isLoading ? (\n <IconButton styleType='high-visibility'>\n <ProgressRadial size=\"small\" indeterminate />\n </IconButton>\n ) : (\n <Button\n disabled={disabled}\n styleType='high-visibility'\n id='save-app'\n onClick={onSave}\n >\n Save\n </Button>\n )}\n <Button\n styleType='default'\n type='button'\n id='cancel'\n onClick={onCancel}\n disabled={isLoading}\n >\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n\nexport default ActionPanel;\n"]}
1
+ {"version":3,"file":"ActionPanel.js","sourceRoot":"","sources":["../../../../src/widget/components/ActionPanel.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;+FAG+F;AAC/F,wDAA8C;AAC9C,6CAA+B;AAC/B,8BAA4B;AAC5B,mCAAyC;AASzC,MAAM,WAAW,GAAG,CAAC,EACnB,MAAM,EACN,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,KAAK,GACA,EAAe,EAAE;IAClC,OAAO,CACL,6BAAK,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAC,wBAAwB;QACjD,6BAAK,SAAS,EAAC,cAAc;YAC1B,SAAS;gBACR,oBAAC,sBAAc,OAAG;YAEpB,oBAAC,sBAAM,IACL,QAAQ,EAAE,QAAQ,IAAI,SAAS,EAC/B,SAAS,EAAC,iBAAiB,EAC3B,EAAE,EAAC,UAAU,EACb,OAAO,EAAE,MAAM,WAGR;YACT,oBAAC,sBAAM,IACL,SAAS,EAAC,SAAS,EACnB,IAAI,EAAC,QAAQ,EACb,EAAE,EAAC,QAAQ,EACX,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,QAAQ,IAAI,SAAS,aAGxB,CACL,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { Button } from \"@itwin/itwinui-react\";\nimport * as React from \"react\";\nimport \"./ActionPanel.scss\";\nimport { LoadingSpinner } from \"./utils\";\n\nexport interface ActionPanelProps {\n onSave: () => void;\n onCancel: () => void;\n disabled?: boolean;\n isLoading?: boolean;\n}\n\nconst ActionPanel = ({\n onSave,\n onCancel,\n disabled = false,\n isLoading = false,\n}: ActionPanelProps): JSX.Element => {\n return (\n <div id='action' className='action-panel-container'>\n <div className='action-panel'>\n {isLoading &&\n <LoadingSpinner />\n }\n <Button\n disabled={disabled || isLoading}\n styleType='high-visibility'\n id='save-app'\n onClick={onSave}\n >\n Save\n </Button>\n <Button\n styleType='default'\n type='button'\n id='cancel'\n onClick={onCancel}\n disabled={disabled || isLoading}\n >\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n\nexport default ActionPanel;\n"]}
@@ -52,8 +52,10 @@ const DeleteModal = ({ entityName, show, setShow, onDelete, refresh, }) => {
52
52
  react_1.default.createElement(itwinui_react_1.Leading, null, "Are you sure you want to delete"),
53
53
  react_1.default.createElement("strong", null, react_1.default.createElement(itwinui_react_1.MiddleTextTruncation, { text: `${entityName}?` }))),
54
54
  react_1.default.createElement(itwinui_react_1.ModalButtonBar, null,
55
- isLoading ? (react_1.default.createElement(itwinui_react_1.IconButton, { styleType: 'high-visibility' },
56
- react_1.default.createElement(itwinui_react_1.ProgressRadial, { size: "small", indeterminate: true }))) : (react_1.default.createElement(itwinui_react_1.Button, { styleType: 'high-visibility', onClick: deleteCallback }, "Delete")),
55
+ isLoading &&
56
+ react_1.default.createElement("div", { className: "loading-delete" },
57
+ react_1.default.createElement(utils_1.LoadingSpinner, null)),
58
+ react_1.default.createElement(itwinui_react_1.Button, { styleType: 'high-visibility', onClick: deleteCallback, disabled: isLoading }, "Delete"),
57
59
  react_1.default.createElement(itwinui_react_1.Button, { styleType: 'default', onClick: () => {
58
60
  setShow(false);
59
61
  }, disabled: isLoading }, "Cancel")))));
@@ -1 +1 @@
1
- {"version":3,"file":"DeleteModal.js","sourceRoot":"","sources":["../../../../src/widget/components/DeleteModal.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;;;+FAG+F;AAC/F,wDAQ8B;AAC9B,+CAAwC;AACxC,8BAA4B;AAC5B,mCAAsC;AAU/B,MAAM,WAAW,GAAG,CAAC,EAC1B,UAAU,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,OAAO,GACU,EAAE,EAAE;IACrB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,gBAAQ,CAAU,KAAK,CAAC,CAAC;IAE3D,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;QAChC,IAAI;YACF,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,QAAQ,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,MAAM,OAAO,EAAE,CAAC;SACjB;QAAC,OAAO,KAAU,EAAE;YACnB,mBAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SAC3B;gBAAS;YACR,YAAY,CAAC,KAAK,CAAC,CAAC;SACrB;IACH,CAAC,CAAC;IAEF,OAAO,CACL;QACE,8BAAC,qBAAK,IACJ,KAAK,EAAC,SAAS,EACf,WAAW,EAAC,yBAAyB,EACrC,MAAM,EAAE,IAAI,EACZ,aAAa,EAAE,CAAC,SAAS,EACzB,OAAO,EAAE,GAAG,EAAE;gBACZ,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;YAED,uCAAK,SAAS,EAAC,wBAAwB;gBACrC,8BAAC,uBAAO,0CAEE;gBACV,8CACG,8BAAC,oCAAoB,IAAC,IAAI,EAAE,GAAG,UAAU,GAAG,GAAI,CAC1C,CACL;YACN,8BAAC,8BAAc;gBACZ,SAAS,CAAC,CAAC,CAAC,CACX,8BAAC,0BAAU,IAAC,SAAS,EAAC,iBAAiB;oBACrC,8BAAC,8BAAc,IAAC,IAAI,EAAC,OAAO,EAAC,aAAa,SAAG,CAClC,CACd,CAAC,CAAC,CAAC,CACF,8BAAC,sBAAM,IAAC,SAAS,EAAC,iBAAiB,EAAC,OAAO,EAAE,cAAc,aAElD,CACV;gBACD,8BAAC,sBAAM,IACL,SAAS,EAAC,SAAS,EACnB,OAAO,EAAE,GAAG,EAAE;wBACZ,OAAO,CAAC,KAAK,CAAC,CAAC;oBACjB,CAAC,EACD,QAAQ,EAAE,SAAS,aAGZ,CACM,CACX,CACP,CACJ,CAAC;AACJ,CAAC,CAAC;AAhEW,QAAA,WAAW,eAgEtB;AAEF,kBAAe,mBAAW,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport {\n Button,\n IconButton,\n Leading,\n MiddleTextTruncation,\n Modal,\n ModalButtonBar,\n ProgressRadial,\n} from \"@itwin/itwinui-react\";\nimport React, { useState } from \"react\";\nimport \"./DeleteModal.scss\";\nimport { handleError } from \"./utils\";\n\nexport interface DeleteModalProps {\n entityName: string;\n show: boolean;\n setShow: React.Dispatch<React.SetStateAction<boolean>>;\n onDelete: () => Promise<void>;\n refresh: () => Promise<void>;\n}\n\nexport const DeleteModal = ({\n entityName,\n show,\n setShow,\n onDelete,\n refresh,\n}: DeleteModalProps) => {\n const [isLoading, setIsLoading] = useState<boolean>(false);\n\n const deleteCallback = async () => {\n try {\n setIsLoading(true);\n await onDelete();\n setShow(false);\n await refresh();\n } catch (error: any) {\n handleError(error.status);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <>\n <Modal\n title='Confirm'\n modalRootId='grouping-mapping-widget'\n isOpen={show}\n isDismissible={!isLoading}\n onClose={() => {\n setShow(false);\n }}\n >\n <div className=\"delete-modal-body-text\">\n <Leading>\n Are you sure you want to delete\n </Leading>\n <strong>\n {<MiddleTextTruncation text={`${entityName}?`} />}\n </strong>\n </div>\n <ModalButtonBar>\n {isLoading ? (\n <IconButton styleType='high-visibility'>\n <ProgressRadial size=\"small\" indeterminate />\n </IconButton>\n ) : (\n <Button styleType='high-visibility' onClick={deleteCallback}>\n Delete\n </Button>\n )}\n <Button\n styleType='default'\n onClick={() => {\n setShow(false);\n }}\n disabled={isLoading}\n >\n Cancel\n </Button>\n </ModalButtonBar>\n </Modal>\n </>\n );\n};\n\nexport default DeleteModal;\n"]}
1
+ {"version":3,"file":"DeleteModal.js","sourceRoot":"","sources":["../../../../src/widget/components/DeleteModal.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;;;+FAG+F;AAC/F,wDAM8B;AAC9B,+CAAwC;AACxC,8BAA4B;AAC5B,mCAAsD;AAU/C,MAAM,WAAW,GAAG,CAAC,EAC1B,UAAU,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,OAAO,GACU,EAAE,EAAE;IACrB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,gBAAQ,CAAU,KAAK,CAAC,CAAC;IAE3D,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;QAChC,IAAI;YACF,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,QAAQ,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,MAAM,OAAO,EAAE,CAAC;SACjB;QAAC,OAAO,KAAU,EAAE;YACnB,mBAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SAC3B;gBAAS;YACR,YAAY,CAAC,KAAK,CAAC,CAAC;SACrB;IACH,CAAC,CAAC;IAEF,OAAO,CACL;QACE,8BAAC,qBAAK,IACJ,KAAK,EAAC,SAAS,EACf,WAAW,EAAC,yBAAyB,EACrC,MAAM,EAAE,IAAI,EACZ,aAAa,EAAE,CAAC,SAAS,EACzB,OAAO,EAAE,GAAG,EAAE;gBACZ,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;YAED,uCAAK,SAAS,EAAC,wBAAwB;gBACrC,8BAAC,uBAAO,0CAEE;gBACV,8CACG,8BAAC,oCAAoB,IAAC,IAAI,EAAE,GAAG,UAAU,GAAG,GAAI,CAC1C,CACL;YACN,8BAAC,8BAAc;gBACZ,SAAS;oBACR,uCAAK,SAAS,EAAC,gBAAgB;wBAC7B,8BAAC,sBAAc,OAAG,CACd;gBACR,8BAAC,sBAAM,IAAC,SAAS,EAAC,iBAAiB,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,aAEvE;gBACT,8BAAC,sBAAM,IACL,SAAS,EAAC,SAAS,EACnB,OAAO,EAAE,GAAG,EAAE;wBACZ,OAAO,CAAC,KAAK,CAAC,CAAC;oBACjB,CAAC,EACD,QAAQ,EAAE,SAAS,aAGZ,CACM,CACX,CACP,CACJ,CAAC;AACJ,CAAC,CAAC;AA9DW,QAAA,WAAW,eA8DtB;AAEF,kBAAe,mBAAW,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport {\n Button,\n Leading,\n MiddleTextTruncation,\n Modal,\n ModalButtonBar,\n} from \"@itwin/itwinui-react\";\nimport React, { useState } from \"react\";\nimport \"./DeleteModal.scss\";\nimport { handleError, LoadingSpinner } from \"./utils\";\n\nexport interface DeleteModalProps {\n entityName: string;\n show: boolean;\n setShow: React.Dispatch<React.SetStateAction<boolean>>;\n onDelete: () => Promise<void>;\n refresh: () => Promise<void>;\n}\n\nexport const DeleteModal = ({\n entityName,\n show,\n setShow,\n onDelete,\n refresh,\n}: DeleteModalProps) => {\n const [isLoading, setIsLoading] = useState<boolean>(false);\n\n const deleteCallback = async () => {\n try {\n setIsLoading(true);\n await onDelete();\n setShow(false);\n await refresh();\n } catch (error: any) {\n handleError(error.status);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <>\n <Modal\n title='Confirm'\n modalRootId='grouping-mapping-widget'\n isOpen={show}\n isDismissible={!isLoading}\n onClose={() => {\n setShow(false);\n }}\n >\n <div className=\"delete-modal-body-text\">\n <Leading>\n Are you sure you want to delete\n </Leading>\n <strong>\n {<MiddleTextTruncation text={`${entityName}?`} />}\n </strong>\n </div>\n <ModalButtonBar>\n {isLoading &&\n <div className=\"loading-delete\">\n <LoadingSpinner />\n </div>}\n <Button styleType='high-visibility' onClick={deleteCallback} disabled={isLoading}>\n Delete\n </Button>\n <Button\n styleType='default'\n onClick={() => {\n setShow(false);\n }}\n disabled={isLoading}\n >\n Cancel\n </Button>\n </ModalButtonBar>\n </Modal>\n </>\n );\n};\n\nexport default DeleteModal;\n"]}
@@ -2,6 +2,8 @@
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 '~@itwin/itwinui-css/scss/variables';
6
+
5
7
  .delete-modal-body-text {
6
8
  display: flex;
7
9
  gap: 4px;
@@ -10,3 +12,7 @@
10
12
  min-width: 0px;
11
13
  }
12
14
  }
15
+
16
+ .loading-delete {
17
+ margin-right: $iui-s;
18
+ }
@@ -35,6 +35,7 @@ const GroupQueryBuilderContainer_1 = require("./GroupQueryBuilderContainer");
35
35
  const GroupQueryBuilderContext_1 = require("./GroupQueryBuilderContext");
36
36
  const QueryBuilder_1 = require("./QueryBuilder");
37
37
  const viewerUtils_1 = require("./viewerUtils");
38
+ const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
38
39
  const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
39
40
  var _a, _b, _c;
40
41
  const iModelConnection = appui_react_1.useActiveIModelConnection();
@@ -46,12 +47,21 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
46
47
  const [simpleQuery, setSimpleQuery] = react_1.useState("");
47
48
  const [validator, showValidationMessage] = useValidator_1.default();
48
49
  const [isLoading, setIsLoading] = react_1.useState(false);
50
+ const [isRendering, setIsRendering] = react_1.useState(false);
49
51
  const [currentPropertyList, setCurrentPropertyList] = react_1.default.useState([]);
50
52
  const [queryBuilder, setQueryBuilder] = react_1.default.useState(new QueryBuilder_1.QueryBuilder(undefined));
53
+ const [groupByType, setGroupByType] = react_1.default.useState("Selection");
54
+ const [searchInput, setSearchInput] = react_1.default.useState("");
55
+ const changeGroupByType = (event) => {
56
+ const { target: { value }, } = event;
57
+ setGroupByType(value);
58
+ presentation_frontend_1.Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
59
+ setQuery("");
60
+ };
51
61
  react_1.useEffect(() => {
52
62
  const removeListener = presentation_frontend_1.Presentation.selection.selectionChange.addListener(async (evt, selectionProvider) => {
53
63
  const selection = selectionProvider.getSelection(evt.imodel, evt.level);
54
- const query = `SELECT ECInstanceId FROM ${selection.instanceKeys.keys().next().value}`;
64
+ const query = selection.instanceKeys.size > 0 ? `SELECT ECInstanceId FROM ${selection.instanceKeys.keys().next().value}` : "";
55
65
  setSimpleQuery(query);
56
66
  });
57
67
  return () => {
@@ -65,6 +75,7 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
65
75
  if (!query || query === "") {
66
76
  return;
67
77
  }
78
+ setIsRendering(true);
68
79
  const ids = await utils_1.fetchIdsFromQuery(query !== null && query !== void 0 ? query : "", iModelConnection);
69
80
  const resolvedHiliteIds = await viewerUtils_1.visualizeElementsById(ids, "red", iModelConnection);
70
81
  await viewerUtils_1.zoomToElements(resolvedHiliteIds);
@@ -72,12 +83,57 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
72
83
  catch {
73
84
  itwinui_react_1.toaster.negative("Sorry, we have failed to generate a valid query. 😔");
74
85
  }
86
+ finally {
87
+ setIsRendering(false);
88
+ }
75
89
  };
76
90
  void reemphasize();
77
91
  }, [iModelConnection, query]);
78
92
  react_1.useEffect(() => {
79
93
  presentation_frontend_1.Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
80
94
  }, [iModelConnection]);
95
+ const isWrappedInQuotes = (text) => {
96
+ return text.startsWith(`"`) && text.endsWith(`"`);
97
+ };
98
+ // Temporary until ECViews become available for use.
99
+ const generateSearchQuery = (searchQuery) => {
100
+ const generatedSearchQuery = searchQuery.length > 0 ? `SELECT
101
+ be.ecinstanceid
102
+ FROM
103
+ generic.physicalobject be
104
+ JOIN
105
+ biscore.geometricelement3disincategory ce
106
+ ON be.ecinstanceid = ce.sourceecinstanceid
107
+ JOIN
108
+ bis.ELEMENT de
109
+ ON ce.targetecinstanceid = de.ecinstanceid
110
+ WHERE
111
+ (${searchQuery.map((token, index) => `${index === 0 ? "" : isWrappedInQuotes(token) ? "AND" : "OR"}
112
+ de.codevalue LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`).join(" ")}
113
+ )
114
+ UNION
115
+ SELECT
116
+ de.ecinstanceid
117
+ FROM
118
+ biscore.geometricelement3d AS de
119
+ JOIN
120
+ ecdbmeta.ecclassdef AS be
121
+ ON de.ecclassid = be.ecinstanceid
122
+ WHERE
123
+ (${searchQuery.map((token, index) => `${index === 0 ? "" : isWrappedInQuotes(token) ? "AND" : "OR"}
124
+ be.name LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`).join(" ")}
125
+ )
126
+ UNION
127
+ SELECT
128
+ be.ecinstanceid
129
+ FROM
130
+ generic.physicalobject be
131
+ WHERE
132
+ (${searchQuery.map((token, index) => `${index === 0 ? "" : isWrappedInQuotes(token) ? "AND" : "OR"}
133
+ be.userlabel LIKE '%${isWrappedInQuotes(token) ? token.slice(1, -1) : token}%'`).join(" ")}
134
+ )` : "";
135
+ setQuery(generatedSearchQuery.trim());
136
+ };
81
137
  const save = react_1.useCallback(async () => {
82
138
  var _a;
83
139
  if (!validator.allValid()) {
@@ -142,22 +198,39 @@ const GroupAction = ({ iModelId, mappingId, group, goBack, }) => {
142
198
  utils_1.handleInputChange(event, details, setDetails);
143
199
  validator.showMessageFor("description");
144
200
  } })),
145
- react_1.default.createElement(itwinui_react_1.Fieldset, { legend: 'Group By', className: 'find-similar' },
146
- react_1.default.createElement(GroupQueryBuilderContext_1.GroupQueryBuilderContext.Provider, { value: {
147
- currentPropertyList,
148
- setCurrentPropertyList,
149
- query,
150
- setQuery,
151
- queryBuilder,
152
- setQueryBuilder,
153
- } },
154
- react_1.default.createElement(GroupQueryBuilderContainer_1.GroupQueryBuilderContainer, null)))),
201
+ react_1.default.createElement(itwinui_react_1.Fieldset, { legend: 'Group By', className: 'query-builder-container' },
202
+ react_1.default.createElement(itwinui_react_1.RadioTileGroup, { className: "radio-group-tile", required: true },
203
+ react_1.default.createElement(itwinui_react_1.RadioTile, { name: "groupby", icon: react_1.default.createElement(itwinui_icons_react_1.SvgCursor, null), onChange: changeGroupByType, defaultChecked: true, value: "Selection", label: "Selection", disabled: isLoading || isRendering }),
204
+ react_1.default.createElement(itwinui_react_1.RadioTile, { icon: react_1.default.createElement(itwinui_icons_react_1.SvgSearch, null), name: "groupby", onChange: changeGroupByType, value: "Query Keywords", label: "Query Keywords", disabled: isLoading || isRendering })),
205
+ groupByType === "Selection" ?
206
+ react_1.default.createElement(GroupQueryBuilderContext_1.GroupQueryBuilderContext.Provider, { value: {
207
+ currentPropertyList,
208
+ setCurrentPropertyList,
209
+ query,
210
+ setQuery,
211
+ queryBuilder,
212
+ setQueryBuilder,
213
+ isLoading,
214
+ isRendering,
215
+ } },
216
+ react_1.default.createElement(GroupQueryBuilderContainer_1.GroupQueryBuilderContainer, null)) :
217
+ react_1.default.createElement("div", { className: "search-form" },
218
+ react_1.default.createElement(itwinui_react_1.Text, null, "Generate a query by keywords. Keywords wrapped in double quotes will be considered a required criteria."),
219
+ react_1.default.createElement(itwinui_react_1.LabeledTextarea, { label: "Query Keywords", required: true, value: searchInput, onChange: (event) => setSearchInput(event.target.value), disabled: isLoading || isRendering, placeholder: `ex: wall curtain "panel" facade` }),
220
+ react_1.default.createElement("div", { className: "search-actions" },
221
+ isRendering &&
222
+ react_1.default.createElement(utils_1.LoadingSpinner, null),
223
+ react_1.default.createElement(itwinui_react_1.Button, { disabled: isLoading || isRendering, onClick: () => generateSearchQuery(searchInput ? searchInput.split(" ") : []) }, "Apply"),
224
+ react_1.default.createElement(itwinui_react_1.Button, { disabled: isLoading || isRendering, onClick: () => {
225
+ setQuery("");
226
+ setSearchInput("");
227
+ } }, "Clear"))))),
155
228
  react_1.default.createElement(ActionPanel_1.default, { onSave: async () => {
156
229
  await save();
157
230
  }, onCancel: async () => {
158
231
  presentation_frontend_1.Presentation.selection.clearSelection("GroupingMappingWidget", iModelConnection);
159
232
  await goBack();
160
- }, disabled: !(details.groupName && details.description && (query || simpleQuery)), isLoading: isLoading })));
233
+ }, disabled: !(details.groupName && details.description && (query || simpleQuery) && !isRendering && !isLoading), isLoading: isLoading })));
161
234
  };
162
235
  exports.default = GroupAction;
163
236
  //# 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,\n} from \"@itwin/presentation-frontend\";\nimport {\n Presentation,\n} from \"@itwin/presentation-frontend\";\nimport { useActiveIModelConnection } from \"@itwin/appui-react\";\nimport { Fieldset, LabeledInput, Small, toaster } from \"@itwin/itwinui-react\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { reportingClientApi } from \"../../api/reportingClient\";\nimport { fetchIdsFromQuery, handleError, 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 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 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 }\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 (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\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":";;;;;;;;;;;;;;;;;;;;;;;;AASA,wEAEsC;AACtC,oDAA+D;AAC/D,wDAAwI;AACxI,+CAAgE;AAChE,+DAA+D;AAC/D,mCAA0G;AAE1G,8BAA4B;AAC5B,gEAAwC;AACxC,sEAAwE;AAExE,6EAA0E;AAC1E,yEAAsE;AACtE,iDAA8C;AAC9C,+CAIuB;AACvB,oEAAkE;AASlE,MAAM,WAAW,GAAG,CAAC,EACnB,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,GACW,EAAE,EAAE;;IACrB,MAAM,gBAAgB,GAAG,uCAAyB,EAAsB,CAAC;IACzE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,gBAAQ,CAAC;QACrC,SAAS,EAAE,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,mCAAI,EAAE;QACjC,WAAW,EAAE,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,mCAAI,EAAE;KACtC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,gBAAQ,CAAS,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,gBAAQ,CAAS,EAAE,CAAC,CAAC;IAC3D,MAAM,CAAC,SAAS,EAAE,qBAAqB,CAAC,GAAG,sBAAY,EAAE,CAAC;IAC1D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,gBAAQ,CAAU,KAAK,CAAC,CAAC;IAC3D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,gBAAQ,CAAU,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,eAAK,CAAC,QAAQ,CAElE,EAAE,CAAC,CAAC;IACN,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,eAAK,CAAC,QAAQ,CACpD,IAAI,2BAAY,CAAC,SAAS,CAAC,CAC5B,CAAC;IACF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAClE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEzD,MAAM,iBAAiB,GAAG,CAAC,KAA0C,EAAE,EAAE;QACvE,MAAM,EACJ,MAAM,EAAE,EAAE,KAAK,EAAE,GAClB,GAAG,KAAK,CAAC;QACV,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,oCAAY,CAAC,SAAS,CAAC,cAAc,CACnC,uBAAuB,EACvB,gBAAgB,CACjB,CAAC;QACF,QAAQ,CAAC,EAAE,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,iBAAS,CAAC,GAAG,EAAE;QACb,MAAM,cAAc,GAAG,oCAAY,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,CACvE,KAAK,EACH,GAA6B,EAC7B,iBAAqC,EACrC,EAAE;YACF,MAAM,SAAS,GAAG,iBAAiB,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YACxE,MAAM,KAAK,GAAG,SAAS,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,4BAA4B,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KACjH,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACR,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC,CACF,CAAC;QACF,OAAO,GAAG,EAAE;YACV,cAAc,EAAE,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,iBAAS,CAAC,GAAG,EAAE;QACb,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;YAC7B,IAAI;gBACF,qCAAuB,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE,EAAE;oBAC1B,OAAO;iBACR;gBAED,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM,GAAG,GAAG,MAAM,yBAAiB,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,EAAE,gBAAgB,CAAC,CAAC;gBACnE,MAAM,iBAAiB,GAAG,MAAM,mCAAqB,CACnD,GAAG,EACH,KAAK,EACL,gBAAgB,CACjB,CAAC;gBACF,MAAM,4BAAc,CAAC,iBAAiB,CAAC,CAAC;aACzC;YAAC,MAAM;gBACN,uBAAO,CAAC,QAAQ,CAAC,qDAAqD,CAAC,CAAC;aACzE;oBAAS;gBACR,cAAc,CAAC,KAAK,CAAC,CAAC;aACvB;QACH,CAAC,CAAC;QAEF,KAAK,WAAW,EAAE,CAAC;IACrB,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;IAE9B,iBAAS,CAAC,GAAG,EAAE;QACb,oCAAY,CAAC,SAAS,CAAC,cAAc,CACnC,uBAAuB,EACvB,gBAAgB,CACjB,CAAC;IACJ,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE;QACzC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC,CAAC;IACF,oDAAoD;IACpD,MAAM,mBAAmB,GAAG,CAAC,WAAqB,EAAE,EAAE;QACpD,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;SAWjD,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACtC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;4BACrC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAClF,CAAC,IAAI,CAAC,GAAG,CAAC;;;;;;;;;;;SAWJ,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACtC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;uBAC1C,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAC7E,CAAC,IAAI,CAAC,GAAG,CAAC;;;;;;;;SAQJ,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACtC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;4BACrC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAClF,CAAC,IAAI,CAAC,GAAG,CAAC;QACL,CAAC,CAAC,CAAC,EAAE,CAAC;QACV,QAAQ,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC;IAExC,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,mBAAW,CAAC,KAAK,IAAI,EAAE;;QAClC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE;YACzB,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO;SACR;QACD,IAAI;YACF,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,YAAY,GAAG,KAAK,IAAI,WAAW,CAAC;YAE1C,KAAK;gBACH,CAAC,CAAC,MAAM,oCAAkB,CAAC,WAAW,CACpC,QAAQ,EACR,SAAS,EACT,MAAA,KAAK,CAAC,EAAE,mCAAI,EAAE,EACd,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CACpC;gBACD,CAAC,CAAC,MAAM,oCAAkB,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE;oBAC1D,GAAG,OAAO;oBACV,KAAK,EAAE,YAAY;iBACpB,CAAC,CAAC;YACL,oCAAY,CAAC,SAAS,CAAC,cAAc,CACnC,uBAAuB,EACvB,gBAAgB,CACjB,CAAC;YACF,MAAM,MAAM,EAAE,CAAC;SAChB;QAAC,OAAO,KAAU,EAAE;YACnB,mBAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC1B,YAAY,CAAC,KAAK,CAAC,CAAC;SACrB;IACH,CAAC,EAAE;QACD,OAAO;QACP,MAAM;QACN,KAAK;QACL,gBAAgB;QAChB,QAAQ;QACR,SAAS;QACT,KAAK;QACL,qBAAqB;QACrB,WAAW;QACX,SAAS;KACV,CAAC,CAAC;IAEH,OAAO,CACL;QACE,8BAAC,oBAAY,IACX,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,MAAA,KAAK,CAAC,SAAS,mCAAI,EAAE,CAAC,CAAC,CAAC,WAAW,EAClD,QAAQ,EAAE,KAAK,IAAI,EAAE;gBACnB,oCAAY,CAAC,SAAS,CAAC,cAAc,CACnC,uBAAuB,EACvB,gBAAgB,CACjB,CAAC;gBACF,MAAM,MAAM,EAAE,CAAC;YACjB,CAAC,GACD;QACF,uCAAK,SAAS,EAAC,4BAA4B;YACzC,8BAAC,wBAAQ,IAAC,MAAM,EAAC,eAAe,EAAC,SAAS,EAAC,eAAe;gBACxD,8BAAC,qBAAK,IAAC,SAAS,EAAC,cAAc,6CAEvB;gBACR,8BAAC,4BAAY,IACX,EAAE,EAAC,WAAW,EACd,IAAI,EAAC,WAAW,EAChB,KAAK,EAAC,MAAM,EACZ,KAAK,EAAE,OAAO,CAAC,SAAS,EACxB,QAAQ,QACR,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;wBAClB,yBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;wBAC9C,SAAS,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;oBACxC,CAAC,EACD,OAAO,EAAE,SAAS,CAAC,OAAO,CACxB,WAAW,EACX,OAAO,CAAC,SAAS,EACjB,gCAAiB,CAClB,EACD,MAAM,EACJ,SAAS,CAAC,OAAO,CACf,WAAW,EACX,OAAO,CAAC,SAAS,EACjB,gCAAiB,CAClB;wBACC,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,SAAS,EAEf,MAAM,EAAE,GAAG,EAAE;wBACX,SAAS,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;oBACxC,CAAC,EACD,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,yBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;wBAC9C,SAAS,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;oBACxC,CAAC,GACD;gBACF,8BAAC,4BAAY,IACX,EAAE,EAAC,aAAa,EAChB,QAAQ,QACR,IAAI,EAAC,aAAa,EAClB,KAAK,EAAC,aAAa,EACnB,KAAK,EAAE,OAAO,CAAC,WAAW,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;wBAClB,yBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;wBAC9C,SAAS,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;oBAC1C,CAAC,EACD,OAAO,EAAE,SAAS,CAAC,OAAO,CACxB,aAAa,EACb,OAAO,CAAC,WAAW,EACnB,UAAU,CACX,EACD,MAAM,EACJ,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC;wBAC/D,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,SAAS,EAEf,MAAM,EAAE,GAAG,EAAE;wBACX,SAAS,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;oBAC1C,CAAC,EACD,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,yBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;wBAC9C,SAAS,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;oBAC1C,CAAC,GACD,CACO;YACX,8BAAC,wBAAQ,IAAC,MAAM,EAAC,UAAU,EAAC,SAAS,EAAC,yBAAyB;gBAC7D,8BAAC,8BAAc,IACb,SAAS,EAAC,kBAAkB,EAC5B,QAAQ;oBACR,8BAAC,yBAAS,IACR,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,8BAAC,+BAAS,OAAG,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,cAAc,QACd,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,SAAS,IAAI,WAAW,GAClC;oBACF,8BAAC,yBAAS,IACR,IAAI,EAAE,8BAAC,+BAAS,OAAG,EACnB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,SAAS,IAAI,WAAW,GAClC,CACa;gBAChB,WAAW,KAAK,WAAW,CAAC,CAAC;oBAC5B,8BAAC,mDAAwB,CAAC,QAAQ,IAChC,KAAK,EAAE;4BACL,mBAAmB;4BACnB,sBAAsB;4BACtB,KAAK;4BACL,QAAQ;4BACR,YAAY;4BACZ,eAAe;4BACf,SAAS;4BACT,WAAW;yBACZ;wBAED,8BAAC,uDAA0B,OAAG,CACI,CAAC,CAAC;oBACtC,uCAAK,SAAS,EAAC,aAAa;wBAC1B,8BAAC,oBAAI,kHAA+G;wBACpH,8BAAC,+BAAe,IACd,KAAK,EAAC,gBAAgB,EACtB,QAAQ,QACR,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EACvD,QAAQ,EAAE,SAAS,IAAI,WAAW,EAClC,WAAW,EAAE,iCAAiC,GAAI;wBACpD,uCAAK,SAAS,EAAC,gBAAgB;4BAC5B,WAAW;gCACV,8BAAC,sBAAc,OAAG;4BAEpB,8BAAC,sBAAM,IAAC,QAAQ,EAAE,SAAS,IAAI,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAgB;4BACzI,8BAAC,sBAAM,IAAC,QAAQ,EAAE,SAAS,IAAI,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE;oCACxD,QAAQ,CAAC,EAAE,CAAC,CAAC;oCACb,cAAc,CAAC,EAAE,CAAC,CAAC;gCACrB,CAAC,YAAgB,CACb,CACF,CAEC,CACP;QACN,8BAAC,qBAAW,IACV,MAAM,EAAE,KAAK,IAAI,EAAE;gBACjB,MAAM,IAAI,EAAE,CAAC;YACf,CAAC,EACD,QAAQ,EAAE,KAAK,IAAI,EAAE;gBACnB,oCAAY,CAAC,SAAS,CAAC,cAAc,CACnC,uBAAuB,EACvB,gBAAgB,CACjB,CAAC;gBACF,MAAM,MAAM,EAAE,CAAC;YACjB,CAAC,EACD,QAAQ,EACN,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,EAErG,SAAS,EAAE,SAAS,GACpB,CACD,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport 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
  }
@@ -63,11 +63,17 @@ const extractPrimitive = (propertiesField, classToPropertiesMapping, navigation)
63
63
  const label = navigation
64
64
  ? `${propertiesField.label} (${navigation === null || navigation === void 0 ? void 0 : navigation.navigationName})`
65
65
  : propertiesField.label;
66
- (_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
67
- name: propertyName,
68
- label,
69
- type: propertiesField.properties[0].property.type,
70
- });
66
+ // Ignore hardcoded BisCore navigation properties
67
+ if (propertiesField.type.typeName === "navigation") {
68
+ return;
69
+ }
70
+ else {
71
+ (_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
72
+ name: propertyName,
73
+ label,
74
+ type: propertiesField.properties[0].property.type,
75
+ });
76
+ }
71
77
  };
72
78
  const extractStructProperties = (name, className, classToPropertiesMapping, members) => {
73
79
  var _a;
@@ -88,6 +94,7 @@ const extractStructProperties = (name, className, classToPropertiesMapping, memb
88
94
  }
89
95
  };
90
96
  const extractProperties = (properties, classToPropertiesMapping, navigation) => {
97
+ var _a, _b;
91
98
  for (const property of properties) {
92
99
  switch (property.type.valueFormat) {
93
100
  case presentation_common_1.PropertyValueFormat.Primitive: {
@@ -129,6 +136,17 @@ const extractProperties = (properties, classToPropertiesMapping, navigation) =>
129
136
  navigationName: "TypeDefinition",
130
137
  rootClassName: className,
131
138
  });
139
+ // Hardcoded BisCore navigation properties for the type definition.
140
+ (_a = classToPropertiesMapping.get(className)) === null || _a === void 0 ? void 0 : _a.push({
141
+ name: "TypeDefinition.Model.ModeledElement.UserLabel",
142
+ label: "Model UserLabel (TypeDefinition)",
143
+ type: "string",
144
+ });
145
+ (_b = classToPropertiesMapping.get(className)) === null || _b === void 0 ? void 0 : _b.push({
146
+ name: "TypeDefinition.Model.ModeledElement.CodeValue",
147
+ label: "Model CodeValue (TypeDefinition)",
148
+ type: "string",
149
+ });
132
150
  }
133
151
  break;
134
152
  }
@@ -162,7 +180,7 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
162
180
  const [isLoading, setIsLoading] = react_1.useState(false);
163
181
  react_1.useEffect(() => {
164
182
  const getContent = async () => {
165
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
183
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
166
184
  setIsLoading(true);
167
185
  const ruleSet = {
168
186
  id: "element-properties",
@@ -172,18 +190,9 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
172
190
  specifications: [
173
191
  {
174
192
  specType: presentation_common_1.ContentSpecificationTypes.SelectedNodeInstances,
175
- // relationshipPaths: [
176
- // {
177
- // relationship: {
178
- // schemaName: "BisCore",
179
- // className: "ElementMultiAspect",
180
- // },
181
- // direction: RelationshipDirection.Forward,
182
- // },
183
- // ],
184
193
  },
185
194
  ],
186
- },
195
+ }
187
196
  ],
188
197
  };
189
198
  const requestOptions = {
@@ -199,13 +208,35 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
199
208
  // Map properties to their classes
200
209
  const classToPropertiesMapping = new Map();
201
210
  extractProperties(properties, classToPropertiesMapping);
211
+ const rootClassName = keySet.instanceKeys.keys().next().value;
212
+ // Hardcoded BisCore navigation properties.
213
+ (_b = classToPropertiesMapping.get(rootClassName)) === null || _b === void 0 ? void 0 : _b.push({
214
+ name: "Model.ModeledElement.UserLabel",
215
+ label: "Model UserLabel",
216
+ type: "string",
217
+ });
218
+ (_c = classToPropertiesMapping.get(rootClassName)) === null || _c === void 0 ? void 0 : _c.push({
219
+ name: "Model.ModeledElement.CodeValue",
220
+ label: "Model CodeValue",
221
+ type: "string",
222
+ });
223
+ (_d = classToPropertiesMapping.get(rootClassName)) === null || _d === void 0 ? void 0 : _d.push({
224
+ name: "Category.CodeValue",
225
+ label: "Category CodeValue",
226
+ type: "string",
227
+ });
228
+ (_e = classToPropertiesMapping.get(rootClassName)) === null || _e === void 0 ? void 0 : _e.push({
229
+ name: "Category.UserLabel",
230
+ label: "Category UserLabel",
231
+ type: "string",
232
+ });
202
233
  setClassToPropertiesMapping(classToPropertiesMapping);
203
234
  let newEcProperties;
204
235
  // Fetch already existing ec properties then add all classes from presentation
205
236
  if (groupPropertyId) {
206
237
  // TODO Error handling
207
238
  const response = await reportingClient_1.reportingClientApi.getGroupProperty(iModelId, mappingId, groupId, groupPropertyId);
208
- newEcProperties = (_c = (_b = response.property) === null || _b === void 0 ? void 0 : _b.ecProperties) !== null && _c !== void 0 ? _c : [];
239
+ newEcProperties = (_g = (_f = response.property) === null || _f === void 0 ? void 0 : _f.ecProperties) !== null && _g !== void 0 ? _g : [];
209
240
  let keys = Array.from(classToPropertiesMapping.keys()).reverse();
210
241
  for (const ecProperty of newEcProperties) {
211
242
  keys = keys.filter((key) => `${ecProperty.ecSchemaName}:${ecProperty.ecClassName}` !== key);
@@ -217,9 +248,9 @@ const GroupPropertyAction = ({ iModelId, mappingId, groupId, groupPropertyId, gr
217
248
  ecPropertyName: "",
218
249
  ecPropertyType: "",
219
250
  })));
220
- setPropertyName((_e = (_d = response.property) === null || _d === void 0 ? void 0 : _d.propertyName) !== null && _e !== void 0 ? _e : "");
221
- setDataType((_g = (_f = response.property) === null || _f === void 0 ? void 0 : _f.dataType) !== null && _g !== void 0 ? _g : "");
222
- setQuantityType((_j = (_h = response.property) === null || _h === void 0 ? void 0 : _h.quantityType) !== null && _j !== void 0 ? _j : "");
251
+ setPropertyName((_j = (_h = response.property) === null || _h === void 0 ? void 0 : _h.propertyName) !== null && _j !== void 0 ? _j : "");
252
+ setDataType((_l = (_k = response.property) === null || _k === void 0 ? void 0 : _k.dataType) !== null && _l !== void 0 ? _l : "");
253
+ setQuantityType((_o = (_m = response.property) === null || _m === void 0 ? void 0 : _m.quantityType) !== null && _o !== void 0 ? _o : "");
223
254
  }
224
255
  else {
225
256
  newEcProperties = Array.from(classToPropertiesMapping)