@itwin/grouping-mapping-widget 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/cjs/components/Groups/QueryBuilder/QueryBuilder.d.ts +7 -3
  2. package/lib/cjs/components/Groups/QueryBuilder/QueryBuilder.js +41 -12
  3. package/lib/cjs/components/Groups/QueryBuilder/QueryBuilder.js.map +1 -1
  4. package/lib/cjs/components/Properties/PropertyAction.js +7 -2
  5. package/lib/cjs/components/Properties/PropertyAction.js.map +1 -1
  6. package/lib/cjs/components/context/GroupHilitedElementsContext.d.ts +12 -0
  7. package/lib/cjs/components/context/GroupHilitedElementsContext.js +8 -0
  8. package/lib/cjs/components/context/GroupHilitedElementsContext.js.map +1 -1
  9. package/lib/cjs/components/customUI/GroupQueryBuilderCustomUI.js +1 -1
  10. package/lib/cjs/components/customUI/GroupQueryBuilderCustomUI.js.map +1 -1
  11. package/lib/cjs/grouping-mapping-widget.d.ts +1 -0
  12. package/lib/cjs/grouping-mapping-widget.js +4 -1
  13. package/lib/cjs/grouping-mapping-widget.js.map +1 -1
  14. package/lib/cjs/test/QueryBuilder.test.js +17 -6
  15. package/lib/cjs/test/QueryBuilder.test.js.map +1 -1
  16. package/lib/cjs/test/QueryBuilder.testdata.js +46 -0
  17. package/lib/cjs/test/QueryBuilder.testdata.js.map +1 -1
  18. package/lib/cjs/test/QueryBuilderTestData.d.ts +2 -2
  19. package/lib/cjs/test/QueryBuilderTestData.js.map +1 -1
  20. package/lib/esm/components/Groups/QueryBuilder/QueryBuilder.d.ts +7 -3
  21. package/lib/esm/components/Groups/QueryBuilder/QueryBuilder.js +41 -12
  22. package/lib/esm/components/Groups/QueryBuilder/QueryBuilder.js.map +1 -1
  23. package/lib/esm/components/Properties/PropertyAction.js +7 -2
  24. package/lib/esm/components/Properties/PropertyAction.js.map +1 -1
  25. package/lib/esm/components/context/GroupHilitedElementsContext.d.ts +12 -0
  26. package/lib/esm/components/context/GroupHilitedElementsContext.js +8 -0
  27. package/lib/esm/components/context/GroupHilitedElementsContext.js.map +1 -1
  28. package/lib/esm/components/customUI/GroupQueryBuilderCustomUI.js +1 -1
  29. package/lib/esm/components/customUI/GroupQueryBuilderCustomUI.js.map +1 -1
  30. package/lib/esm/grouping-mapping-widget.d.ts +1 -0
  31. package/lib/esm/grouping-mapping-widget.js +1 -0
  32. package/lib/esm/grouping-mapping-widget.js.map +1 -1
  33. package/lib/esm/test/QueryBuilder.test.js +17 -6
  34. package/lib/esm/test/QueryBuilder.test.js.map +1 -1
  35. package/lib/esm/test/QueryBuilder.testdata.js +46 -0
  36. package/lib/esm/test/QueryBuilder.testdata.js.map +1 -1
  37. package/lib/esm/test/QueryBuilderTestData.d.ts +2 -2
  38. package/lib/esm/test/QueryBuilderTestData.js.map +1 -1
  39. package/package.json +1 -1
@@ -1,16 +1,19 @@
1
1
  import { PropertyValueFormat } from "@itwin/appui-abstract";
2
2
  import { toaster } from "@itwin/itwinui-react";
3
+ import { QueryBinder } from "@itwin/core-common";
3
4
  /* This class is to build adaptive and dynamic query for find similar property selections */
4
5
  export class QueryBuilder {
5
- constructor(provider) {
6
+ constructor(dataProvider, iModelConnection) {
7
+ this.dataProvider = dataProvider;
8
+ this.iModelConnection = iModelConnection;
6
9
  this._propertyMap = new Map();
7
10
  this.resetQueryBuilder = () => {
8
11
  this._propertyMap = new Map();
9
12
  };
10
- this.regenerateQuery = () => {
13
+ this.regenerateQuery = async () => {
11
14
  this.query = undefined;
12
15
  for (const property of this._propertyMap.values()) {
13
- this.buildProperty(property.propertyRecord, property.propertiesField);
16
+ await this.buildProperty(property.propertyRecord, property.propertiesField);
14
17
  }
15
18
  };
16
19
  this.relationalJoinSegments = (classes, querySegments) => {
@@ -33,12 +36,27 @@ export class QueryBuilder {
33
36
  const propertyValue = needsQuote ? `'${property.value}'` : property.value;
34
37
  return `${className}.${property.name} = ${propertyValue}`;
35
38
  };
36
- this.dataProvider = provider;
37
39
  }
38
40
  isCategory(propertyField) {
39
41
  const classInfo = propertyField.properties[0].property.navigationPropertyInfo?.classInfo;
40
42
  return classInfo?.name === "BisCore:GeometricElement3dIsInCategory";
41
43
  }
44
+ async getPotentialModeledElement(propertyField, propertyRecord) {
45
+ const classInfo = propertyField.properties[0].property.navigationPropertyInfo?.classInfo;
46
+ if (propertyRecord.value?.valueFormat !== PropertyValueFormat.Primitive)
47
+ return;
48
+ const navigationPropertyValue = propertyRecord.value.value;
49
+ if (classInfo?.name === "BisCore:ModelContainsElements") {
50
+ // https://www.itwinjs.org/bis/guide/fundamentals/model-fundamentals/#model-identity
51
+ // Lookup the modeled element as they share the same ECInstanceId
52
+ const modeledElementQuery = `SELECT ec_classname(ecclassid) FROM biscore.element WHERE ecinstanceid = ? LIMIT 1`;
53
+ const queryBinder = new QueryBinder();
54
+ queryBinder.bindString(1, navigationPropertyValue.id);
55
+ const modeledElement = (await this.iModelConnection.createQueryReader(modeledElementQuery, queryBinder).next()).value[0];
56
+ return modeledElement.replace(":", ".");
57
+ }
58
+ return;
59
+ }
42
60
  async addProperty(prop) {
43
61
  // TODO: only handle primitive properties now
44
62
  if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {
@@ -60,7 +78,7 @@ export class QueryBuilder {
60
78
  const propertyField = (await this.dataProvider.getFieldByPropertyRecord(prop));
61
79
  this._propertyMap.delete(JSON.stringify(propertyField.getFieldDescriptor()));
62
80
  }
63
- buildProperty(prop, propertiesField) {
81
+ async buildProperty(prop, propertiesField) {
64
82
  if (prop.value?.valueFormat !== PropertyValueFormat.Primitive || prop.value.value === undefined) {
65
83
  toaster.negative("Error. An unexpected error has occured while building a query.");
66
84
  return;
@@ -76,17 +94,22 @@ export class QueryBuilder {
76
94
  // get the special cases
77
95
  const isNavigation = prop.property.typename.toLowerCase() === "navigation";
78
96
  const isCategory = isNavigation && this.isCategory(propertiesField);
97
+ const modeledElement = await this.getPotentialModeledElement(propertiesField, prop);
79
98
  const isAspect = pathToPrimaryClass?.find((a) => a.relationshipInfo?.name === QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS || a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS) !== undefined;
80
99
  for (let i = 0; i < propertiesField.properties.length; i++) {
81
100
  const property = propertiesField.properties[i].property;
82
101
  const className = property.classInfo.name.replace(":", ".");
83
- const propertyName = isNavigation ? (isCategory ? `${property.name}.CodeValue` : `${property.name}.id`) : property.name;
84
- const propertyValue = isNavigation ? (isCategory ? prop.value.displayValue ?? "" : prop.value.value.id) : prop.value.value;
102
+ const propertyName = isNavigation ? (isCategory || modeledElement ? `${property.name}.CodeValue` : `${property.name}.id`) : property.name;
103
+ const propertyValue = isNavigation
104
+ ? isCategory || modeledElement
105
+ ? prop.value.displayValue ?? ""
106
+ : prop.value.value.id
107
+ : prop.value.value;
85
108
  if (!isAspect && pathToPrimaryClass && pathToPrimaryClass.length > 0) {
86
109
  this.addRelatedToQuery(i, propertiesField, propertyName, propertyValue);
87
110
  }
88
111
  else {
89
- this.addPropertyToQuery(i, className, propertyName, propertyValue, this.needsQuote(propertiesField), isCategory, isAspect);
112
+ this.addPropertyToQuery(i, className, propertyName, propertyValue, this.needsQuote(propertiesField), isCategory, modeledElement, isAspect);
90
113
  }
91
114
  }
92
115
  return true;
@@ -107,7 +130,7 @@ export class QueryBuilder {
107
130
  this.addClassToQuery(unionIndex, targetClassName, `ECInstanceId`, relClassName, relPropertyValue);
108
131
  this.addClassToQuery(unionIndex, relClassName, relClassProperty, sourceClassName, `ECInstanceId`);
109
132
  if (path.sourceClassInfo?.name === propertyField.parent?.contentClassInfo.name) {
110
- this.addPropertyToQuery(unionIndex, sourceClassName, propertyName, propertyValue, this.needsQuote(propertyField), false, false);
133
+ this.addPropertyToQuery(unionIndex, sourceClassName, propertyName, propertyValue, this.needsQuote(propertyField), false, "", false);
111
134
  }
112
135
  });
113
136
  }
@@ -140,7 +163,7 @@ export class QueryBuilder {
140
163
  }
141
164
  this.query.unions[unionIndex].classes.push(queryClass);
142
165
  }
143
- addPropertyToQuery(unionIndex, className, propertyName, propertyValue, needsQuote, isCategory, isAspect) {
166
+ addPropertyToQuery(unionIndex, className, propertyName, propertyValue, needsQuote, isCategory, modeledElementClass, isAspect) {
144
167
  if (this.query === undefined) {
145
168
  this.query = { unions: [] };
146
169
  }
@@ -152,6 +175,7 @@ export class QueryBuilder {
152
175
  const queryProperty = {
153
176
  className,
154
177
  isCategory,
178
+ modeledElementClass,
155
179
  isAspect,
156
180
  classProperties: [queryJoin],
157
181
  };
@@ -174,8 +198,8 @@ export class QueryBuilder {
174
198
  }
175
199
  this.query.unions[unionIndex].properties.push(queryProperty);
176
200
  }
177
- buildQueryString() {
178
- this.regenerateQuery();
201
+ async buildQueryString() {
202
+ await this.regenerateQuery();
179
203
  if (this.query === undefined || this.query.unions.find((u) => u.classes.length === 0 && u.properties.length === 0)) {
180
204
  return "";
181
205
  }
@@ -197,6 +221,11 @@ export class QueryBuilder {
197
221
  whereSegments.push(this.categoryWhereQuery(property.classProperties[0].value.toString()));
198
222
  continue;
199
223
  }
224
+ else if (property.modeledElementClass) {
225
+ querySegments.set(property.modeledElementClass, [`${property.modeledElementClass}.ECInstanceId = BisCore.Element.Model.id`]);
226
+ whereSegments.push(`${property.modeledElementClass}.UserLabel = '${property.classProperties[0].value.toString()}' OR ${property.modeledElementClass}.CodeValue = '${property.classProperties[0].value.toString()}'`);
227
+ continue;
228
+ }
200
229
  const joinIdName = property.isAspect ? `${property.className}.Element.id` : `${property.className}.ECInstanceId`;
201
230
  if (!querySegments.has(property.className) && property.className !== baseClassName)
202
231
  querySegments.set(property.className, [`${joinIdName} = ${baseIdName}`]);
@@ -1 +1 @@
1
- {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../../../../src/components/Groups/QueryBuilder/QueryBuilder.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAyC/C,4FAA4F;AAC5F,MAAM,OAAO,YAAY;IAQvB,YAAY,QAA0C;QAS9C,iBAAY,GAA+B,IAAI,GAAG,EAAE,CAAC;QAEtD,sBAAiB,GAAG,GAAG,EAAE;YAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAChC,CAAC,CAAC;QAEM,oBAAe,GAAG,GAAG,EAAE;YAC7B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YAEvB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE;gBACjD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;aACvE;QACH,CAAC,CAAC;QA8PM,2BAAsB,GAAG,CAAC,OAAqB,EAAE,aAAoC,EAAyB,EAAE;YACtH,KAAK,MAAM,UAAU,IAAI,OAAO,EAAE;gBAChC,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE;oBAC7C,MAAM,YAAY,GAAG;wBACnB,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;wBACrD,GAAG,UAAU,CAAC,SAAS,IAAI,SAAS,CAAC,aAAa,MAAM,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,iBAAiB,EAAE;qBACjH,CAAC;oBACF,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;iBAC1D;aACF;YAED,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC;QAEM,yBAAoB,GAAG,CAAC,SAAiB,EAAE,QAAuB,EAAE,UAAmB,EAAU,EAAE;YACzG,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAC9B,OAAO,CACL,SAAS,SAAS,IAAI,QAAQ,CAAC,IAAI,IAAI;oBACvC,GAAG,YAAY,CAAC,wBAAwB,MAAM;oBAC9C,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC,EAAE,CAC3E,CAAC;YAEJ,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC1E,OAAO,GAAG,SAAS,IAAI,QAAQ,CAAC,IAAI,MAAM,aAAa,EAAE,CAAC;QAC5D,CAAC,CAAC;QA1SA,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;IAC/B,CAAC;IAEO,UAAU,CAAC,aAA8B;QAC/C,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,EAAE,SAAS,CAAC;QACzF,OAAO,SAAS,EAAE,IAAI,KAAK,wCAAwC,CAAC;IACtE,CAAC;IAgBM,KAAK,CAAC,WAAW,CAAC,IAAoB;QAC3C,6CAA6C;QAC7C,IAAI,IAAI,CAAC,KAAK,EAAE,WAAW,KAAK,mBAAmB,CAAC,SAAS,EAAE;YAC7D,OAAO,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;YAC/D,OAAO,KAAK,CAAC;SACd;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE;YAClC,OAAO,KAAK,CAAC;SACd;QAED,MAAM,aAAa,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAoB,CAAC;QAElG,IAAI,CAAC,aAAa,EAAE;YAClB,OAAO,CAAC,QAAQ,CAAC,wDAAwD,CAAC,CAAC;YAC3E,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,kBAAkB,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,CAAC;QACpI,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,IAAoB;QAC9C,MAAM,aAAa,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAoB,CAAC;QAElG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAEO,aAAa,CAAC,IAAoB,EAAE,eAAgC;QAC1E,IAAI,IAAI,CAAC,KAAK,EAAE,WAAW,KAAK,mBAAmB,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE;YAC/F,OAAO,CAAC,QAAQ,CAAC,gEAAgE,CAAC,CAAC;YACnF,OAAO;SACR;QAED,SAAS,UAAU,CAAC,GAAW,EAAE,KAAa,EAAE,WAAmB;YACjE,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;QACD,6CAA6C;QAC7C,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,YAAY,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC9H,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;SACvE;QAED,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,EAAE,kBAAkB,CAAC;QAEtE,wBAAwB;QACxB,MAAM,YAAY,GAAY,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC;QACpF,MAAM,UAAU,GAAY,YAAY,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QAE7E,MAAM,QAAQ,GACZ,kBAAkB,EAAE,IAAI,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,EAAE,IAAI,KAAK,YAAY,CAAC,2BAA2B,IAAI,CAAC,CAAC,gBAAgB,EAAE,IAAI,KAAK,YAAY,CAAC,0BAA0B,CACrJ,KAAK,SAAS,CAAC;QAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YAC1D,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAExD,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YACxH,MAAM,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,KAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAE5I,IAAI,CAAC,QAAQ,IAAI,kBAAkB,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;gBACpE,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;aACzE;iBAAM;gBACL,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;aAC5H;SACF;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,UAAU,CAAC,aAA8B;QAC/C,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3D,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC;IACrD,CAAC;IAEO,iBAAiB,CAAC,UAAkB,EAAE,aAA8B,EAAE,YAAoB,EAAE,aAA+B;QACjI,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;QACpE,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/B,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACrE,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAEnE,MAAM,gBAAgB,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;YAElG,MAAM,gBAAgB,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;YAElG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;YAElG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;YAElG,IAAI,IAAI,CAAC,eAAe,EAAE,IAAI,KAAK,aAAa,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,EAAE;gBAC9E,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;aACjI;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,UAAkB,EAAE,SAAiB,EAAE,aAAqB,EAAE,aAAqB,EAAE,iBAAyB;QACpI,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;YAC5B,IAAI,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;SAC7B;QAED,MAAM,SAAS,GAAc;YAC3B,aAAa;YACb,aAAa;YACb,iBAAiB;SAClB,CAAC;QAEF,MAAM,UAAU,GAAe;YAC7B,SAAS;YACT,UAAU,EAAE,CAAC,SAAS,CAAC;SACxB,CAAC;QAEF,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,UAAU,EAAE;YAC1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;gBACrB,OAAO,EAAE,CAAC,UAAU,CAAC;gBACrB,UAAU,EAAE,EAAE;aACf,CAAC,CAAC;YACH,OAAO;SACR;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAEhG,IAAI,UAAU,EAAE;YACd,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAC1C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,KAAK,aAAa,IAAI,IAAI,CAAC,aAAa,KAAK,aAAa,IAAI,IAAI,CAAC,iBAAiB,KAAK,iBAAiB,CACvI,CAAC;YAEF,IAAI,CAAC,SAAS;gBAAE,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtD,OAAO;SACR;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IAEO,kBAAkB,CACxB,UAAkB,EAClB,SAAiB,EACjB,YAAoB,EACpB,aAA+B,EAC/B,UAAmB,EACnB,UAAmB,EACnB,QAAiB;QAEjB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;YAC5B,IAAI,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;SAC7B;QAED,MAAM,SAAS,GAAkB;YAC/B,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,aAAa;YACpB,UAAU;SACX,CAAC;QAEF,MAAM,aAAa,GAAkB;YACnC,SAAS;YACT,UAAU;YACV,QAAQ;YACR,eAAe,EAAE,CAAC,SAAS,CAAC;SAC7B,CAAC;QAEF,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,UAAU,EAAE;YAC1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;gBACrB,OAAO,EAAE,EAAE;gBACX,UAAU,EAAE,CAAC,aAAa,CAAC;aAC5B,CAAC,CAAC;YACH,OAAO;SACR;QAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAE3G,IAAI,kBAAkB,EAAE;YACtB,MAAM,SAAS,GAAG,kBAAkB,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YAEjG,IAAI,SAAS,EAAE;gBACb,SAAS,CAAC,KAAK,GAAG,aAAa,CAAC;gBAChC,OAAO;aACR;YAED,kBAAkB,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACnD,OAAO;SACR;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/D,CAAC;IAEM,gBAAgB;QACrB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE;YAClH,OAAO,EAAE,CAAC;SACX;QAED,MAAM,aAAa,GAAa,EAAE,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACrC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC;YAChF,MAAM,UAAU,GAAG,GAAG,aAAa,eAAe,CAAC;YAEnD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAEhE,IAAI,aAAa,GAA0B,IAAI,GAAG,EAAE,CAAC;YACrD,aAAa,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAE1E,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,UAAU,EAAE;gBACvC,IAAI,QAAQ,CAAC,UAAU,EAAE;oBACvB,IAAI,QAAQ,CAAC,SAAS,KAAK,aAAa;wBACtC,aAAa,CAAC,GAAG,CAAC,4BAA4B,EAAE,CAAC,6CAA6C,UAAU,EAAE,CAAC,CAAC,CAAC;oBAE/G,aAAa,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,wEAAwE,CAAC,CAAC,CAAC;oBAClH,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;oBAC1F,SAAS;iBACV;gBAED,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,eAAe,CAAC;gBAEjH,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,SAAS,KAAK,aAAa;oBAChF,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,UAAU,MAAM,UAAU,EAAE,CAAC,CAAC,CAAC;gBAE3E,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,eAAe,EAAE;oBAC3C,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;iBAC1F;aACF;YAED,MAAM,WAAW,GAAa,EAAE,CAAC;YACjC,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,EAAE;gBACtC,WAAW,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;aAC7E;YAED,MAAM,WAAW,GAAG,SAAS,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAE3D,aAAa,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,GAAG,WAAW,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;SAC3E;QAED,OAAO,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAEO,YAAY,CAAC,YAAuC,EAAE,SAAiC;QAC7F,IAAI,SAAS,EAAE;YACb,OAAO,UAAU,SAAS,CAAC,SAAS,kBAAkB,SAAS,CAAC,SAAS,mBAAmB,SAAS,CAAC,SAAS,EAAE,CAAC;SACnH;QAED,IAAI,YAAY,EAAE;YAChB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ;gBACtC,CAAC,CAAC,GAAG,YAAY,CAAC,SAAS,0BAA0B;gBACrD,CAAC,CAAC,GAAG,YAAY,CAAC,SAAS,kBAAkB,YAAY,CAAC,SAAS,YAAY,CAAC;YAElF,OAAO,UAAU,UAAU,SAAS,YAAY,CAAC,SAAS,EAAE,CAAC;SAC9D;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IA4BO,kBAAkB,CAAC,SAAiB;QAC1C,OAAO,mCAAmC,SAAS,wCAAwC,SAAS,KAAK,CAAC;IAC5G,CAAC;IAEO,OAAO,CAAC,CAAU;QACxB,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;;AA1TuB,uCAA0B,GAAG,iCAAiC,CAAC;AAC/D,wCAA2B,GAAG,iCAAiC,CAAC;AAChE,qCAAwB,GAAG,CAAC,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 { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type { InstanceKey, PropertiesField } from \"@itwin/presentation-common\";\nimport type { Primitives, PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { toaster } from \"@itwin/itwinui-react\";\n\nexport interface Query {\n unions: QueryUnion[];\n}\n\nexport interface QueryUnion {\n classes: QueryClass[];\n properties: QueryProperty[];\n}\n\nexport interface QueryClass {\n // schemaName.className\n className: string;\n classJoins: ClassJoin[];\n}\n\nexport interface ClassJoin {\n classProperty: string;\n joinClassName: string;\n joinClassProperty: string;\n}\n\nexport interface QueryProperty {\n className: string;\n classProperties: ClassProperty[];\n isCategory: boolean;\n isAspect: boolean;\n}\n\nexport interface ClassProperty {\n name: string;\n value: Primitives.Value;\n needsQuote: boolean;\n}\n\nexport interface AddedProperty {\n propertyRecord: PropertyRecord;\n propertiesField: PropertiesField;\n}\n\n/* This class is to build adaptive and dynamic query for find similar property selections */\nexport class QueryBuilder {\n private static readonly MULTI_ASPECT_PRIMARY_CLASS = \"BisCore:ElementOwnsMultiAspects\";\n private static readonly UNIQUE_ASPECT_PRIMARY_CLASS = \"BisCore:ElementOwnsUniqueAspect\";\n private static readonly DEFAULT_DOUBLE_PRECISION = 4;\n\n private dataProvider: PresentationPropertyDataProvider;\n private query: Query | undefined;\n\n constructor(provider: PresentationPropertyDataProvider) {\n this.dataProvider = provider;\n }\n\n private isCategory(propertyField: PropertiesField): boolean {\n const classInfo = propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n return classInfo?.name === \"BisCore:GeometricElement3dIsInCategory\";\n }\n\n private _propertyMap: Map<string, AddedProperty> = new Map();\n\n public resetQueryBuilder = () => {\n this._propertyMap = new Map();\n };\n\n private regenerateQuery = () => {\n this.query = undefined;\n\n for (const property of this._propertyMap.values()) {\n this.buildProperty(property.propertyRecord, property.propertiesField);\n }\n };\n\n public async addProperty(prop: PropertyRecord): Promise<boolean> {\n // TODO: only handle primitive properties now\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {\n toaster.warning(\"Only primitive types are supported for now.\");\n return false;\n }\n if (prop.value.value === undefined) {\n return false;\n }\n\n const propertyField = (await this.dataProvider.getFieldByPropertyRecord(prop)) as PropertiesField;\n\n if (!propertyField) {\n toaster.negative(\"Error. Failed to fetch field for this property record.\");\n return false;\n }\n\n this._propertyMap.set(JSON.stringify(propertyField.getFieldDescriptor()), { propertyRecord: prop, propertiesField: propertyField });\n return true;\n }\n\n public async removeProperty(prop: PropertyRecord) {\n const propertyField = (await this.dataProvider.getFieldByPropertyRecord(prop)) as PropertiesField;\n\n this._propertyMap.delete(JSON.stringify(propertyField.getFieldDescriptor()));\n }\n\n private buildProperty(prop: PropertyRecord, propertiesField: PropertiesField) {\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive || prop.value.value === undefined) {\n toaster.negative(\"Error. An unexpected error has occured while building a query.\");\n return;\n }\n\n function replaceAll(str: string, match: string, replacement: string) {\n return str.split(match).join(replacement);\n }\n // if property value has single quote, escape\n if ((typeof prop.value.value === \"string\" || prop.value.value instanceof String) && String(prop.value.value).indexOf(\"'\") >= 0) {\n prop.value.value = replaceAll(prop.value.value.toString(), \"'\", \"''\");\n }\n\n const pathToPrimaryClass = propertiesField.parent?.pathToPrimaryClass;\n\n // get the special cases\n const isNavigation: boolean = prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertiesField);\n\n const isAspect: boolean =\n pathToPrimaryClass?.find(\n (a) => a.relationshipInfo?.name === QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS || a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n\n for (let i = 0; i < propertiesField.properties.length; i++) {\n const property = propertiesField.properties[i].property;\n\n const className = property.classInfo.name.replace(\":\", \".\");\n const propertyName = isNavigation ? (isCategory ? `${property.name}.CodeValue` : `${property.name}.id`) : property.name;\n const propertyValue = isNavigation ? (isCategory ? prop.value.displayValue ?? \"\" : (prop.value.value as InstanceKey).id) : prop.value.value;\n\n if (!isAspect && pathToPrimaryClass && pathToPrimaryClass.length > 0) {\n this.addRelatedToQuery(i, propertiesField, propertyName, propertyValue);\n } else {\n this.addPropertyToQuery(i, className, propertyName, propertyValue, this.needsQuote(propertiesField), isCategory, isAspect);\n }\n }\n return true;\n }\n\n private needsQuote(propertyField: PropertiesField): boolean {\n // list of property types that need quote around property value\n const typeName = propertyField.type.typeName.toLowerCase();\n return \"string\" === typeName || \"uri\" === typeName;\n }\n\n private addRelatedToQuery(unionIndex: number, propertyField: PropertiesField, propertyName: string, propertyValue: Primitives.Value) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n\n const relClassProperty = path.isForwardRelationship ? `SourceECInstanceId` : `TargetECInstanceId`;\n\n const relPropertyValue = path.isForwardRelationship ? `TargetECInstanceId` : `SourceECInstanceId`;\n\n this.addClassToQuery(unionIndex, targetClassName, `ECInstanceId`, relClassName, relPropertyValue);\n\n this.addClassToQuery(unionIndex, relClassName, relClassProperty, sourceClassName, `ECInstanceId`);\n\n if (path.sourceClassInfo?.name === propertyField.parent?.contentClassInfo.name) {\n this.addPropertyToQuery(unionIndex, sourceClassName, propertyName, propertyValue, this.needsQuote(propertyField), false, false);\n }\n });\n }\n\n private addClassToQuery(unionIndex: number, className: string, classProperty: string, joinClassName: string, joinClassProperty: string) {\n if (this.query === undefined) {\n this.query = { unions: [] };\n }\n\n const classJoin: ClassJoin = {\n classProperty,\n joinClassName,\n joinClassProperty,\n };\n\n const queryClass: QueryClass = {\n className,\n classJoins: [classJoin],\n };\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [queryClass],\n properties: [],\n });\n return;\n }\n\n const foundClass = this.query.unions[unionIndex].classes.find((c) => c.className === className);\n\n if (foundClass) {\n const foundJoin = foundClass.classJoins.find(\n (join) => join.classProperty === classProperty && join.joinClassName === joinClassName && join.joinClassProperty === joinClassProperty,\n );\n\n if (!foundJoin) foundClass.classJoins.push(classJoin);\n return;\n }\n\n this.query.unions[unionIndex].classes.push(queryClass);\n }\n\n private addPropertyToQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n propertyValue: Primitives.Value,\n needsQuote: boolean,\n isCategory: boolean,\n isAspect: boolean,\n ) {\n if (this.query === undefined) {\n this.query = { unions: [] };\n }\n\n const queryJoin: ClassProperty = {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n };\n\n const queryProperty: QueryProperty = {\n className,\n isCategory,\n isAspect,\n classProperties: [queryJoin],\n };\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [],\n properties: [queryProperty],\n });\n return;\n }\n\n const foundPropertyClass = this.query.unions[unionIndex].properties.find((p) => p.className === className);\n\n if (foundPropertyClass) {\n const foundJoin = foundPropertyClass?.classProperties.find((join) => join.name === propertyName);\n\n if (foundJoin) {\n foundJoin.value = propertyValue;\n return;\n }\n\n foundPropertyClass.classProperties.push(queryJoin);\n return;\n }\n\n this.query.unions[unionIndex].properties.push(queryProperty);\n }\n\n public buildQueryString() {\n this.regenerateQuery();\n if (this.query === undefined || this.query.unions.find((u) => u.classes.length === 0 && u.properties.length === 0)) {\n return \"\";\n }\n\n const unionSegments: string[] = [];\n for (const union of this.query.unions) {\n const baseClass = union.classes[0];\n const baseProperty = union.properties[0];\n const baseClassName = baseClass ? baseClass.className : baseProperty?.className;\n const baseIdName = `${baseClassName}.ECInstanceId`;\n\n const selectClause = this.selectClause(baseProperty, baseClass);\n\n let querySegments: Map<string, string[]> = new Map();\n querySegments = this.relationalJoinSegments(union.classes, querySegments);\n\n const whereSegments: string[] = [];\n for (const property of union.properties) {\n if (property.isCategory) {\n if (property.className !== baseClassName)\n querySegments.set(\"BisCore.GeometricElement3d\", [`BisCore.GeometricElement3d.ECInstanceId = ${baseIdName}`]);\n\n querySegments.set(\"BisCore.Category\", [`BisCore.Category.ECInstanceId = BisCore.GeometricElement3d.category.id`]);\n whereSegments.push(this.categoryWhereQuery(property.classProperties[0].value.toString()));\n continue;\n }\n\n const joinIdName = property.isAspect ? `${property.className}.Element.id` : `${property.className}.ECInstanceId`;\n\n if (!querySegments.has(property.className) && property.className !== baseClassName)\n querySegments.set(property.className, [`${joinIdName} = ${baseIdName}`]);\n\n for (const prop of property.classProperties) {\n whereSegments.push(this.propertyQuerySegment(property.className, prop, prop.needsQuote));\n }\n }\n\n const joinClauses: string[] = [];\n for (const key of querySegments.keys()) {\n joinClauses.push(`JOIN ${key} ON ${querySegments.get(key)?.join(\" AND \")}`);\n }\n\n const whereClause = `WHERE ${whereSegments.join(\" AND \")}`;\n\n unionSegments.push([selectClause, ...joinClauses, whereClause].join(\" \"));\n }\n\n return unionSegments.join(\" UNION \");\n }\n\n private selectClause(baseProperty: QueryProperty | undefined, baseClass: QueryClass | undefined) {\n if (baseClass) {\n return `SELECT ${baseClass.className}.ECInstanceId, ${baseClass.className}.ECClassId FROM ${baseClass.className}`;\n }\n\n if (baseProperty) {\n const baseIdName = baseProperty.isAspect\n ? `${baseProperty.className}.Element.id ECInstanceId`\n : `${baseProperty.className}.ECInstanceId, ${baseProperty.className}.ECClassId`;\n\n return `SELECT ${baseIdName} FROM ${baseProperty.className}`;\n }\n\n return \"\";\n }\n\n private relationalJoinSegments = (classes: QueryClass[], querySegments: Map<string, string[]>): Map<string, string[]> => {\n for (const queryClass of classes) {\n for (const classJoin of queryClass.classJoins) {\n const querySegment = [\n ...(querySegments.get(classJoin.joinClassName) ?? []),\n `${queryClass.className}.${classJoin.classProperty} = ${classJoin.joinClassName}.${classJoin.joinClassProperty}`,\n ];\n querySegments.set(classJoin.joinClassName, querySegment);\n }\n }\n\n return querySegments;\n };\n\n private propertyQuerySegment = (className: string, property: ClassProperty, needsQuote: boolean): string => {\n if (this.isFloat(property.value))\n return (\n `ROUND(${className}.${property.name}, ` +\n `${QueryBuilder.DEFAULT_DOUBLE_PRECISION}) = ` +\n `${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`\n );\n\n const propertyValue = needsQuote ? `'${property.value}'` : property.value;\n return `${className}.${property.name} = ${propertyValue}`;\n };\n\n private categoryWhereQuery(codeValue: string): string {\n return `((BisCore.Category.CodeValue = '${codeValue}') OR (BisCore.Category.UserLabel = '${codeValue}'))`;\n }\n\n private isFloat(n: unknown): boolean {\n return Number(n) === n && n % 1 !== 0;\n }\n}\n"]}
1
+ {"version":3,"file":"QueryBuilder.js","sourceRoot":"","sources":["../../../../../src/components/Groups/QueryBuilder/QueryBuilder.ts"],"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 { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type { InstanceKey, NavigationPropertyValue, PropertiesField } from \"@itwin/presentation-common\";\nimport type { Primitives, PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { toaster } from \"@itwin/itwinui-react\";\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport { QueryBinder } from \"@itwin/core-common\";\n\nexport interface Query {\n unions: QueryUnion[];\n}\n\nexport interface QueryUnion {\n classes: QueryClass[];\n properties: QueryProperty[];\n}\n\nexport interface QueryClass {\n // schemaName.className\n className: string;\n classJoins: ClassJoin[];\n}\n\nexport interface ClassJoin {\n classProperty: string;\n joinClassName: string;\n joinClassProperty: string;\n}\n\nexport interface QueryProperty {\n className: string;\n classProperties: ClassProperty[];\n isCategory: boolean;\n modeledElementClass?: string;\n isAspect: boolean;\n}\n\nexport interface ClassProperty {\n name: string;\n value: Primitives.Value;\n needsQuote: boolean;\n}\n\nexport interface AddedProperty {\n propertyRecord: PropertyRecord;\n propertiesField: PropertiesField;\n}\n\n/* This class is to build adaptive and dynamic query for find similar property selections */\nexport class QueryBuilder {\n private static readonly MULTI_ASPECT_PRIMARY_CLASS = \"BisCore:ElementOwnsMultiAspects\";\n private static readonly UNIQUE_ASPECT_PRIMARY_CLASS = \"BisCore:ElementOwnsUniqueAspect\";\n private static readonly DEFAULT_DOUBLE_PRECISION = 4;\n private query: Query | undefined;\n\n constructor(\n private readonly dataProvider: PresentationPropertyDataProvider,\n private readonly iModelConnection: IModelConnection,\n ) {}\n\n private isCategory(propertyField: PropertiesField): boolean {\n const classInfo = propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n return classInfo?.name === \"BisCore:GeometricElement3dIsInCategory\";\n }\n\n private async getPotentialModeledElement(propertyField: PropertiesField, propertyRecord: PropertyRecord): Promise<string | undefined> {\n const classInfo = propertyField.properties[0].property.navigationPropertyInfo?.classInfo;\n if (propertyRecord.value?.valueFormat !== PropertyValueFormat.Primitive) return;\n const navigationPropertyValue = propertyRecord.value.value as NavigationPropertyValue;\n if (classInfo?.name === \"BisCore:ModelContainsElements\") {\n // https://www.itwinjs.org/bis/guide/fundamentals/model-fundamentals/#model-identity\n // Lookup the modeled element as they share the same ECInstanceId\n const modeledElementQuery = `SELECT ec_classname(ecclassid) FROM biscore.element WHERE ecinstanceid = ? LIMIT 1`;\n const queryBinder = new QueryBinder();\n queryBinder.bindString(1, navigationPropertyValue.id);\n const modeledElement = (await this.iModelConnection.createQueryReader(modeledElementQuery, queryBinder).next()).value[0];\n return modeledElement.replace(\":\", \".\");\n }\n return;\n }\n\n private _propertyMap: Map<string, AddedProperty> = new Map();\n\n public resetQueryBuilder = () => {\n this._propertyMap = new Map();\n };\n\n private regenerateQuery = async () => {\n this.query = undefined;\n\n for (const property of this._propertyMap.values()) {\n await this.buildProperty(property.propertyRecord, property.propertiesField);\n }\n };\n\n public async addProperty(prop: PropertyRecord): Promise<boolean> {\n // TODO: only handle primitive properties now\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive) {\n toaster.warning(\"Only primitive types are supported for now.\");\n return false;\n }\n if (prop.value.value === undefined) {\n return false;\n }\n\n const propertyField = (await this.dataProvider.getFieldByPropertyRecord(prop)) as PropertiesField;\n\n if (!propertyField) {\n toaster.negative(\"Error. Failed to fetch field for this property record.\");\n return false;\n }\n\n this._propertyMap.set(JSON.stringify(propertyField.getFieldDescriptor()), { propertyRecord: prop, propertiesField: propertyField });\n return true;\n }\n\n public async removeProperty(prop: PropertyRecord) {\n const propertyField = (await this.dataProvider.getFieldByPropertyRecord(prop)) as PropertiesField;\n\n this._propertyMap.delete(JSON.stringify(propertyField.getFieldDescriptor()));\n }\n\n private async buildProperty(prop: PropertyRecord, propertiesField: PropertiesField) {\n if (prop.value?.valueFormat !== PropertyValueFormat.Primitive || prop.value.value === undefined) {\n toaster.negative(\"Error. An unexpected error has occured while building a query.\");\n return;\n }\n\n function replaceAll(str: string, match: string, replacement: string) {\n return str.split(match).join(replacement);\n }\n // if property value has single quote, escape\n if ((typeof prop.value.value === \"string\" || prop.value.value instanceof String) && String(prop.value.value).indexOf(\"'\") >= 0) {\n prop.value.value = replaceAll(prop.value.value.toString(), \"'\", \"''\");\n }\n\n const pathToPrimaryClass = propertiesField.parent?.pathToPrimaryClass;\n\n // get the special cases\n const isNavigation: boolean = prop.property.typename.toLowerCase() === \"navigation\";\n const isCategory: boolean = isNavigation && this.isCategory(propertiesField);\n const modeledElement = await this.getPotentialModeledElement(propertiesField, prop);\n\n const isAspect: boolean =\n pathToPrimaryClass?.find(\n (a) => a.relationshipInfo?.name === QueryBuilder.UNIQUE_ASPECT_PRIMARY_CLASS || a.relationshipInfo?.name === QueryBuilder.MULTI_ASPECT_PRIMARY_CLASS,\n ) !== undefined;\n\n for (let i = 0; i < propertiesField.properties.length; i++) {\n const property = propertiesField.properties[i].property;\n\n const className = property.classInfo.name.replace(\":\", \".\");\n const propertyName = isNavigation ? (isCategory || modeledElement ? `${property.name}.CodeValue` : `${property.name}.id`) : property.name;\n const propertyValue = isNavigation\n ? isCategory || modeledElement\n ? prop.value.displayValue ?? \"\"\n : (prop.value.value as InstanceKey).id\n : prop.value.value;\n\n if (!isAspect && pathToPrimaryClass && pathToPrimaryClass.length > 0) {\n this.addRelatedToQuery(i, propertiesField, propertyName, propertyValue);\n } else {\n this.addPropertyToQuery(i, className, propertyName, propertyValue, this.needsQuote(propertiesField), isCategory, modeledElement, isAspect);\n }\n }\n return true;\n }\n\n private needsQuote(propertyField: PropertiesField): boolean {\n // list of property types that need quote around property value\n const typeName = propertyField.type.typeName.toLowerCase();\n return \"string\" === typeName || \"uri\" === typeName;\n }\n\n private addRelatedToQuery(unionIndex: number, propertyField: PropertiesField, propertyName: string, propertyValue: Primitives.Value) {\n const paths = [...(propertyField.parent?.pathToPrimaryClass ?? [])];\n paths.reverse().forEach((path) => {\n const sourceClassName = path.sourceClassInfo?.name.replace(\":\", \".\");\n const targetClassName = path.targetClassInfo?.name.replace(\":\", \".\");\n const relClassName = path.relationshipInfo?.name.replace(\":\", \".\");\n\n const relClassProperty = path.isForwardRelationship ? `SourceECInstanceId` : `TargetECInstanceId`;\n\n const relPropertyValue = path.isForwardRelationship ? `TargetECInstanceId` : `SourceECInstanceId`;\n\n this.addClassToQuery(unionIndex, targetClassName, `ECInstanceId`, relClassName, relPropertyValue);\n\n this.addClassToQuery(unionIndex, relClassName, relClassProperty, sourceClassName, `ECInstanceId`);\n\n if (path.sourceClassInfo?.name === propertyField.parent?.contentClassInfo.name) {\n this.addPropertyToQuery(unionIndex, sourceClassName, propertyName, propertyValue, this.needsQuote(propertyField), false, \"\", false);\n }\n });\n }\n\n private addClassToQuery(unionIndex: number, className: string, classProperty: string, joinClassName: string, joinClassProperty: string) {\n if (this.query === undefined) {\n this.query = { unions: [] };\n }\n\n const classJoin: ClassJoin = {\n classProperty,\n joinClassName,\n joinClassProperty,\n };\n\n const queryClass: QueryClass = {\n className,\n classJoins: [classJoin],\n };\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [queryClass],\n properties: [],\n });\n return;\n }\n\n const foundClass = this.query.unions[unionIndex].classes.find((c) => c.className === className);\n\n if (foundClass) {\n const foundJoin = foundClass.classJoins.find(\n (join) => join.classProperty === classProperty && join.joinClassName === joinClassName && join.joinClassProperty === joinClassProperty,\n );\n\n if (!foundJoin) foundClass.classJoins.push(classJoin);\n return;\n }\n\n this.query.unions[unionIndex].classes.push(queryClass);\n }\n\n private addPropertyToQuery(\n unionIndex: number,\n className: string,\n propertyName: string,\n propertyValue: Primitives.Value,\n needsQuote: boolean,\n isCategory: boolean,\n modeledElementClass: string | undefined,\n isAspect: boolean,\n ) {\n if (this.query === undefined) {\n this.query = { unions: [] };\n }\n\n const queryJoin: ClassProperty = {\n name: propertyName,\n value: propertyValue,\n needsQuote,\n };\n\n const queryProperty: QueryProperty = {\n className,\n isCategory,\n modeledElementClass,\n isAspect,\n classProperties: [queryJoin],\n };\n\n if (this.query.unions.length <= unionIndex) {\n this.query.unions.push({\n classes: [],\n properties: [queryProperty],\n });\n return;\n }\n\n const foundPropertyClass = this.query.unions[unionIndex].properties.find((p) => p.className === className);\n\n if (foundPropertyClass) {\n const foundJoin = foundPropertyClass?.classProperties.find((join) => join.name === propertyName);\n\n if (foundJoin) {\n foundJoin.value = propertyValue;\n return;\n }\n\n foundPropertyClass.classProperties.push(queryJoin);\n return;\n }\n\n this.query.unions[unionIndex].properties.push(queryProperty);\n }\n\n public async buildQueryString() {\n await this.regenerateQuery();\n if (this.query === undefined || this.query.unions.find((u) => u.classes.length === 0 && u.properties.length === 0)) {\n return \"\";\n }\n\n const unionSegments: string[] = [];\n for (const union of this.query.unions) {\n const baseClass = union.classes[0];\n const baseProperty = union.properties[0];\n const baseClassName = baseClass ? baseClass.className : baseProperty?.className;\n const baseIdName = `${baseClassName}.ECInstanceId`;\n\n const selectClause = this.selectClause(baseProperty, baseClass);\n\n let querySegments: Map<string, string[]> = new Map();\n querySegments = this.relationalJoinSegments(union.classes, querySegments);\n\n const whereSegments: string[] = [];\n for (const property of union.properties) {\n if (property.isCategory) {\n if (property.className !== baseClassName)\n querySegments.set(\"BisCore.GeometricElement3d\", [`BisCore.GeometricElement3d.ECInstanceId = ${baseIdName}`]);\n\n querySegments.set(\"BisCore.Category\", [`BisCore.Category.ECInstanceId = BisCore.GeometricElement3d.category.id`]);\n whereSegments.push(this.categoryWhereQuery(property.classProperties[0].value.toString()));\n continue;\n } else if (property.modeledElementClass) {\n querySegments.set(property.modeledElementClass, [`${property.modeledElementClass}.ECInstanceId = BisCore.Element.Model.id`]);\n whereSegments.push(\n `${property.modeledElementClass}.UserLabel = '${property.classProperties[0].value.toString()}' OR ${property.modeledElementClass}.CodeValue = '${property.classProperties[0].value.toString()}'`,\n );\n continue;\n }\n\n const joinIdName = property.isAspect ? `${property.className}.Element.id` : `${property.className}.ECInstanceId`;\n\n if (!querySegments.has(property.className) && property.className !== baseClassName)\n querySegments.set(property.className, [`${joinIdName} = ${baseIdName}`]);\n\n for (const prop of property.classProperties) {\n whereSegments.push(this.propertyQuerySegment(property.className, prop, prop.needsQuote));\n }\n }\n\n const joinClauses: string[] = [];\n for (const key of querySegments.keys()) {\n joinClauses.push(`JOIN ${key} ON ${querySegments.get(key)?.join(\" AND \")}`);\n }\n\n const whereClause = `WHERE ${whereSegments.join(\" AND \")}`;\n\n unionSegments.push([selectClause, ...joinClauses, whereClause].join(\" \"));\n }\n\n return unionSegments.join(\" UNION \");\n }\n\n private selectClause(baseProperty: QueryProperty | undefined, baseClass: QueryClass | undefined) {\n if (baseClass) {\n return `SELECT ${baseClass.className}.ECInstanceId, ${baseClass.className}.ECClassId FROM ${baseClass.className}`;\n }\n\n if (baseProperty) {\n const baseIdName = baseProperty.isAspect\n ? `${baseProperty.className}.Element.id ECInstanceId`\n : `${baseProperty.className}.ECInstanceId, ${baseProperty.className}.ECClassId`;\n\n return `SELECT ${baseIdName} FROM ${baseProperty.className}`;\n }\n\n return \"\";\n }\n\n private relationalJoinSegments = (classes: QueryClass[], querySegments: Map<string, string[]>): Map<string, string[]> => {\n for (const queryClass of classes) {\n for (const classJoin of queryClass.classJoins) {\n const querySegment = [\n ...(querySegments.get(classJoin.joinClassName) ?? []),\n `${queryClass.className}.${classJoin.classProperty} = ${classJoin.joinClassName}.${classJoin.joinClassProperty}`,\n ];\n querySegments.set(classJoin.joinClassName, querySegment);\n }\n }\n\n return querySegments;\n };\n\n private propertyQuerySegment = (className: string, property: ClassProperty, needsQuote: boolean): string => {\n if (this.isFloat(property.value))\n return (\n `ROUND(${className}.${property.name}, ` +\n `${QueryBuilder.DEFAULT_DOUBLE_PRECISION}) = ` +\n `${Number(property.value).toFixed(QueryBuilder.DEFAULT_DOUBLE_PRECISION)}`\n );\n\n const propertyValue = needsQuote ? `'${property.value}'` : property.value;\n return `${className}.${property.name} = ${propertyValue}`;\n };\n\n private categoryWhereQuery(codeValue: string): string {\n return `((BisCore.Category.CodeValue = '${codeValue}') OR (BisCore.Category.UserLabel = '${codeValue}'))`;\n }\n\n private isFloat(n: unknown): boolean {\n return Number(n) === n && n % 1 !== 0;\n }\n}\n"]}
@@ -7,8 +7,13 @@ import { PropertyValueFormat } from "@itwin/appui-abstract";
7
7
  import { usePropertyGridWrapper } from "../context/PropertyGridWrapperContext";
8
8
  import { Checkbox } from "@itwin/itwinui-react";
9
9
  import "./PropertyAction.scss";
10
+ import { useGroupingMappingApiConfig } from "../context/GroupingApiConfigContext";
10
11
  const usePropertySelection = (property, currentPropertyList, queryBuilder) => {
11
12
  const [isCheckboxLoading, setIsCheckboxLoading] = useState(false);
13
+ const { iModelConnection } = useGroupingMappingApiConfig();
14
+ if (!iModelConnection) {
15
+ throw new Error("This hook requires an active iModelConnection.");
16
+ }
12
17
  const checkIfPropertyIsSelected = useCallback((property) => {
13
18
  if (property.value.valueFormat === PropertyValueFormat.Primitive) {
14
19
  return currentPropertyList.includes(property);
@@ -50,12 +55,12 @@ export const PropertyAction = ({ property }) => {
50
55
  if (isPropertySelected) {
51
56
  await removeProperty(property);
52
57
  setCurrentPropertyList((prevList) => prevList.filter((x) => x !== property));
53
- setQuery(queryBuilder?.buildQueryString() ?? "");
58
+ setQuery(await queryBuilder?.buildQueryString() ?? "");
54
59
  }
55
60
  else {
56
61
  if (await addProperty(property)) {
57
62
  setCurrentPropertyList((prevList) => prevList.concat(property));
58
- setQuery(queryBuilder?.buildQueryString() ?? "");
63
+ setQuery(await queryBuilder?.buildQueryString() ?? "");
59
64
  }
60
65
  }
61
66
  }, [addProperty, isPropertySelected, property, removeProperty, queryBuilder, setCurrentPropertyList, setQuery]);
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyAction.js","sourceRoot":"","sources":["../../../../src/components/Properties/PropertyAction.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 React, { useCallback, useEffect, useState } from \"react\";\nimport type { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { usePropertyGridWrapper } from \"../context/PropertyGridWrapperContext\";\nimport { Checkbox } from \"@itwin/itwinui-react\";\nimport \"./PropertyAction.scss\";\nimport type { QueryBuilder } from \"../Groups/QueryBuilder/QueryBuilder\";\n\nexport interface PropertyActionProps {\n property: PropertyRecord;\n}\n\nconst usePropertySelection = (property: PropertyRecord, currentPropertyList: PropertyRecord[], queryBuilder: QueryBuilder | undefined) => {\n const [isCheckboxLoading, setIsCheckboxLoading] = useState(false);\n\n const checkIfPropertyIsSelected = useCallback(\n (property: PropertyRecord): boolean => {\n if (property.value.valueFormat === PropertyValueFormat.Primitive) {\n return currentPropertyList.includes(property);\n }\n\n if (property.value.valueFormat === PropertyValueFormat.Array) {\n return property.value.items.length === 0 && currentPropertyList.includes(property);\n }\n return Object.values(property.value.members).every((subProp: PropertyRecord) => checkIfPropertyIsSelected(subProp));\n },\n [currentPropertyList],\n );\n\n const isPropertySelected = checkIfPropertyIsSelected(property);\n\n const addProperty = useCallback(\n async (prop: PropertyRecord) => {\n if (prop.value.valueFormat === PropertyValueFormat.Primitive && !currentPropertyList.includes(prop) && (await queryBuilder?.addProperty(prop))) {\n setIsCheckboxLoading(false);\n return true;\n }\n return false;\n },\n [currentPropertyList, queryBuilder],\n );\n\n const removeProperty = useCallback(\n async (prop: PropertyRecord) => {\n if (currentPropertyList.includes(prop)) {\n await queryBuilder?.removeProperty(prop);\n setIsCheckboxLoading(false);\n }\n },\n [currentPropertyList, queryBuilder],\n );\n\n return {\n isPropertySelected,\n addProperty,\n removeProperty,\n isCheckboxLoading,\n setIsCheckboxLoading,\n };\n};\n\nexport const PropertyAction = ({ property }: PropertyActionProps) => {\n const { currentPropertyList, queryBuilder, setCurrentPropertyList, setQuery, isUpdating } = usePropertyGridWrapper();\n\n const { isPropertySelected, addProperty, removeProperty, isCheckboxLoading, setIsCheckboxLoading } = usePropertySelection(\n property,\n currentPropertyList,\n queryBuilder,\n );\n\n useEffect(() => {\n setIsCheckboxLoading(isPropertySelected && isUpdating);\n }, [isPropertySelected, isUpdating, setIsCheckboxLoading]);\n\n const onPropertySelectionChanged = useCallback(async () => {\n if (isPropertySelected) {\n await removeProperty(property);\n setCurrentPropertyList((prevList) => prevList.filter((x) => x !== property));\n setQuery(queryBuilder?.buildQueryString() ?? \"\");\n } else {\n if (await addProperty(property)) {\n setCurrentPropertyList((prevList) => prevList.concat(property));\n setQuery(queryBuilder?.buildQueryString() ?? \"\");\n }\n }\n }, [addProperty, isPropertySelected, property, removeProperty, queryBuilder, setCurrentPropertyList, setQuery]);\n\n return (\n <div className=\"gmw-property-selection-checkbox\">\n {property.value.valueFormat === PropertyValueFormat.Primitive && property.value.value !== undefined && (\n <Checkbox checked={isPropertySelected} onChange={onPropertySelectionChanged} disabled={isUpdating} isLoading={isCheckboxLoading} />\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"PropertyAction.js","sourceRoot":"","sources":["../../../../src/components/Properties/PropertyAction.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 React, { useCallback, useEffect, useState } from \"react\";\nimport type { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\nimport { usePropertyGridWrapper } from \"../context/PropertyGridWrapperContext\";\nimport { Checkbox } from \"@itwin/itwinui-react\";\nimport \"./PropertyAction.scss\";\nimport type { QueryBuilder } from \"../Groups/QueryBuilder/QueryBuilder\";\nimport { useGroupingMappingApiConfig } from \"../context/GroupingApiConfigContext\";\n\nexport interface PropertyActionProps {\n property: PropertyRecord;\n}\n\nconst usePropertySelection = (property: PropertyRecord, currentPropertyList: PropertyRecord[], queryBuilder: QueryBuilder | undefined) => {\n const [isCheckboxLoading, setIsCheckboxLoading] = useState(false);\n const { iModelConnection } = useGroupingMappingApiConfig();\n if (!iModelConnection) {\n throw new Error(\"This hook requires an active iModelConnection.\");\n }\n\n const checkIfPropertyIsSelected = useCallback(\n (property: PropertyRecord): boolean => {\n if (property.value.valueFormat === PropertyValueFormat.Primitive) {\n return currentPropertyList.includes(property);\n }\n\n if (property.value.valueFormat === PropertyValueFormat.Array) {\n return property.value.items.length === 0 && currentPropertyList.includes(property);\n }\n return Object.values(property.value.members).every((subProp: PropertyRecord) => checkIfPropertyIsSelected(subProp));\n },\n [currentPropertyList],\n );\n\n const isPropertySelected = checkIfPropertyIsSelected(property);\n\n const addProperty = useCallback(\n async (prop: PropertyRecord) => {\n if (prop.value.valueFormat === PropertyValueFormat.Primitive && !currentPropertyList.includes(prop) && (await queryBuilder?.addProperty(prop))) {\n setIsCheckboxLoading(false);\n return true;\n }\n return false;\n },\n [currentPropertyList, queryBuilder],\n );\n\n const removeProperty = useCallback(\n async (prop: PropertyRecord) => {\n if (currentPropertyList.includes(prop)) {\n await queryBuilder?.removeProperty(prop);\n setIsCheckboxLoading(false);\n }\n },\n [currentPropertyList, queryBuilder],\n );\n\n return {\n isPropertySelected,\n addProperty,\n removeProperty,\n isCheckboxLoading,\n setIsCheckboxLoading,\n };\n};\n\nexport const PropertyAction = ({ property }: PropertyActionProps) => {\n const { currentPropertyList, queryBuilder, setCurrentPropertyList, setQuery, isUpdating } = usePropertyGridWrapper();\n\n const { isPropertySelected, addProperty, removeProperty, isCheckboxLoading, setIsCheckboxLoading } = usePropertySelection(\n property,\n currentPropertyList,\n queryBuilder,\n );\n\n useEffect(() => {\n setIsCheckboxLoading(isPropertySelected && isUpdating);\n }, [isPropertySelected, isUpdating, setIsCheckboxLoading]);\n\n const onPropertySelectionChanged = useCallback(async () => {\n if (isPropertySelected) {\n await removeProperty(property);\n setCurrentPropertyList((prevList) => prevList.filter((x) => x !== property));\n setQuery(await queryBuilder?.buildQueryString() ?? \"\");\n } else {\n if (await addProperty(property)) {\n setCurrentPropertyList((prevList) => prevList.concat(property));\n setQuery(await queryBuilder?.buildQueryString() ?? \"\");\n }\n }\n }, [addProperty, isPropertySelected, property, removeProperty, queryBuilder, setCurrentPropertyList, setQuery]);\n\n return (\n <div className=\"gmw-property-selection-checkbox\">\n {property.value.valueFormat === PropertyValueFormat.Primitive && property.value.value !== undefined && (\n <Checkbox checked={isPropertySelected} onChange={onPropertySelectionChanged} disabled={isUpdating} isLoading={isCheckboxLoading} />\n )}\n </div>\n );\n};\n"]}
@@ -12,6 +12,10 @@ export interface OverlappedElementsMetadata {
12
12
  groupElementsInfo: Map<string, number>;
13
13
  overlappedElementGroupPairs: OverlappedElementGroupPairs[];
14
14
  }
15
+ /**
16
+ * The type for the {@link GroupHilitedElementsContext} context.
17
+ * @public
18
+ */
15
19
  export interface GroupHilitedElements {
16
20
  hiddenGroupsIds: Set<string>;
17
21
  showGroupColor: boolean;
@@ -28,6 +32,14 @@ export interface GroupHilitedElements {
28
32
  groupColors: Map<string, string>;
29
33
  setGroupColors: (colors: Map<string, string>) => void;
30
34
  }
35
+ /**
36
+ * The context which provides metadata for group highlighting.
37
+ * @public
38
+ */
31
39
  export declare const GroupHilitedElementsContext: React.Context<GroupHilitedElements>;
40
+ /**
41
+ * The hook which provides context for group highlighting.
42
+ * @public
43
+ */
32
44
  export declare const useGroupHilitedElementsContext: () => GroupHilitedElements;
33
45
  //# sourceMappingURL=GroupHilitedElementsContext.d.ts.map
@@ -3,6 +3,10 @@
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from "react";
6
+ /**
7
+ * The context which provides metadata for group highlighting.
8
+ * @public
9
+ */
6
10
  export const GroupHilitedElementsContext = React.createContext({
7
11
  hiddenGroupsIds: new Set(),
8
12
  showGroupColor: false,
@@ -23,6 +27,10 @@ export const GroupHilitedElementsContext = React.createContext({
23
27
  setGroupColors: () => { },
24
28
  groupColors: new Map(),
25
29
  });
30
+ /**
31
+ * The hook which provides context for group highlighting.
32
+ * @public
33
+ */
26
34
  export const useGroupHilitedElementsContext = () => {
27
35
  const context = React.useContext(GroupHilitedElementsContext);
28
36
  if (!context) {
@@ -1 +1 @@
1
- {"version":3,"file":"GroupHilitedElementsContext.js","sourceRoot":"","sources":["../../../../src/components/context/GroupHilitedElementsContext.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAkC/B,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC,aAAa,CAAuB;IACnF,eAAe,EAAE,IAAI,GAAG,EAAE;IAC1B,cAAc,EAAE,KAAK;IACrB,oBAAoB,EAAE,CAAC;IACvB,0BAA0B,EAAE;QAC1B,sBAAsB,EAAE,IAAI,GAAG,EAAE;QACjC,iBAAiB,EAAE,IAAI,GAAG,EAAE;QAC5B,2BAA2B,EAAE,EAAE;KAChC;IACD,uBAAuB,EAAE,KAAK;IAC9B,mBAAmB,EAAE,KAAK;IAC1B,kBAAkB,EAAE,GAAG,EAAE,GAAE,CAAC;IAC5B,iBAAiB,EAAE,GAAG,EAAE,GAAE,CAAC;IAC3B,2BAA2B,EAAE,GAAG,EAAE,GAAE,CAAC;IACrC,6BAA6B,EAAE,GAAG,EAAE,GAAE,CAAC;IACvC,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;IAChC,0BAA0B,EAAE,GAAG,EAAE,GAAE,CAAC;IACpC,cAAc,EAAE,GAAG,EAAE,GAAE,CAAC;IACxB,WAAW,EAAE,IAAI,GAAG,EAAE;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAyB,EAAE;IACvE,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;KAChH;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,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 * as React from \"react\";\nexport interface OverlappedInfo {\n groupIds: string[];\n elements: string[];\n}\n\nexport interface OverlappedElementGroupPairs {\n elementIds: Set<string>;\n groupIds: Set<string>;\n}\n\nexport interface OverlappedElementsMetadata {\n overlappedElementsInfo: Map<string, OverlappedInfo[]>;\n groupElementsInfo: Map<string, number>;\n overlappedElementGroupPairs: OverlappedElementGroupPairs[];\n}\n\nexport interface GroupHilitedElements {\n hiddenGroupsIds: Set<string>;\n showGroupColor: boolean;\n currentHilitedGroups: number;\n overlappedElementsMetadata: OverlappedElementsMetadata;\n isVisualizationsEnabled: boolean;\n isOverlappedColored: boolean;\n setHiddenGroupsIds: (hiddenGroupIds: Set<string>) => void;\n setShowGroupColor: (showGroupColor: boolean | ((showGroupColor: boolean) => boolean)) => void;\n setNumberOfVisualizedGroups: (numberOfVisualizedGroups: number | ((numberOfVisualizedGroups: number) => number)) => void;\n setOverlappedElementsMetadata: (overlappedElementsMetaData: OverlappedElementsMetadata) => void;\n setIsOverlappedColored: (isOverlappedColored: boolean | ((isOverlappedColored: boolean) => boolean)) => void;\n setIsVisualizationsEnabled: (isVisualizationsEnabled: boolean | ((isVisualizationsEnabled: boolean) => boolean)) => void;\n groupColors: Map<string, string>;\n setGroupColors: (colors: Map<string, string>) => void;\n}\n\nexport const GroupHilitedElementsContext = React.createContext<GroupHilitedElements>({\n hiddenGroupsIds: new Set(),\n showGroupColor: false,\n currentHilitedGroups: 0,\n overlappedElementsMetadata: {\n overlappedElementsInfo: new Map(),\n groupElementsInfo: new Map(),\n overlappedElementGroupPairs: [],\n },\n isVisualizationsEnabled: false,\n isOverlappedColored: false,\n setHiddenGroupsIds: () => {},\n setShowGroupColor: () => {},\n setNumberOfVisualizedGroups: () => {},\n setOverlappedElementsMetadata: () => {},\n setIsOverlappedColored: () => {},\n setIsVisualizationsEnabled: () => {},\n setGroupColors: () => {},\n groupColors: new Map(),\n});\n\nexport const useGroupHilitedElementsContext = (): GroupHilitedElements => {\n const context = React.useContext(GroupHilitedElementsContext);\n if (!context) {\n throw new Error(\"useGroupHilitedElementsContext should be used within a GroupHilitedElementsContext provider\");\n }\n return context;\n};\n"]}
1
+ {"version":3,"file":"GroupHilitedElementsContext.js","sourceRoot":"","sources":["../../../../src/components/context/GroupHilitedElementsContext.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsC/B;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC,aAAa,CAAuB;IACnF,eAAe,EAAE,IAAI,GAAG,EAAE;IAC1B,cAAc,EAAE,KAAK;IACrB,oBAAoB,EAAE,CAAC;IACvB,0BAA0B,EAAE;QAC1B,sBAAsB,EAAE,IAAI,GAAG,EAAE;QACjC,iBAAiB,EAAE,IAAI,GAAG,EAAE;QAC5B,2BAA2B,EAAE,EAAE;KAChC;IACD,uBAAuB,EAAE,KAAK;IAC9B,mBAAmB,EAAE,KAAK;IAC1B,kBAAkB,EAAE,GAAG,EAAE,GAAE,CAAC;IAC5B,iBAAiB,EAAE,GAAG,EAAE,GAAE,CAAC;IAC3B,2BAA2B,EAAE,GAAG,EAAE,GAAE,CAAC;IACrC,6BAA6B,EAAE,GAAG,EAAE,GAAE,CAAC;IACvC,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;IAChC,0BAA0B,EAAE,GAAG,EAAE,GAAE,CAAC;IACpC,cAAc,EAAE,GAAG,EAAE,GAAE,CAAC;IACxB,WAAW,EAAE,IAAI,GAAG,EAAE;CACvB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAyB,EAAE;IACvE,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;KAChH;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,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 * as React from \"react\";\nexport interface OverlappedInfo {\n groupIds: string[];\n elements: string[];\n}\n\nexport interface OverlappedElementGroupPairs {\n elementIds: Set<string>;\n groupIds: Set<string>;\n}\n\nexport interface OverlappedElementsMetadata {\n overlappedElementsInfo: Map<string, OverlappedInfo[]>;\n groupElementsInfo: Map<string, number>;\n overlappedElementGroupPairs: OverlappedElementGroupPairs[];\n}\n\n/**\n * The type for the {@link GroupHilitedElementsContext} context.\n * @public\n */\nexport interface GroupHilitedElements {\n hiddenGroupsIds: Set<string>;\n showGroupColor: boolean;\n currentHilitedGroups: number;\n overlappedElementsMetadata: OverlappedElementsMetadata;\n isVisualizationsEnabled: boolean;\n isOverlappedColored: boolean;\n setHiddenGroupsIds: (hiddenGroupIds: Set<string>) => void;\n setShowGroupColor: (showGroupColor: boolean | ((showGroupColor: boolean) => boolean)) => void;\n setNumberOfVisualizedGroups: (numberOfVisualizedGroups: number | ((numberOfVisualizedGroups: number) => number)) => void;\n setOverlappedElementsMetadata: (overlappedElementsMetaData: OverlappedElementsMetadata) => void;\n setIsOverlappedColored: (isOverlappedColored: boolean | ((isOverlappedColored: boolean) => boolean)) => void;\n setIsVisualizationsEnabled: (isVisualizationsEnabled: boolean | ((isVisualizationsEnabled: boolean) => boolean)) => void;\n groupColors: Map<string, string>;\n setGroupColors: (colors: Map<string, string>) => void;\n}\n\n/**\n * The context which provides metadata for group highlighting.\n * @public\n */\nexport const GroupHilitedElementsContext = React.createContext<GroupHilitedElements>({\n hiddenGroupsIds: new Set(),\n showGroupColor: false,\n currentHilitedGroups: 0,\n overlappedElementsMetadata: {\n overlappedElementsInfo: new Map(),\n groupElementsInfo: new Map(),\n overlappedElementGroupPairs: [],\n },\n isVisualizationsEnabled: false,\n isOverlappedColored: false,\n setHiddenGroupsIds: () => {},\n setShowGroupColor: () => {},\n setNumberOfVisualizedGroups: () => {},\n setOverlappedElementsMetadata: () => {},\n setIsOverlappedColored: () => {},\n setIsVisualizationsEnabled: () => {},\n setGroupColors: () => {},\n groupColors: new Map(),\n});\n\n/**\n * The hook which provides context for group highlighting.\n * @public\n */\nexport const useGroupHilitedElementsContext = (): GroupHilitedElements => {\n const context = React.useContext(GroupHilitedElementsContext);\n if (!context) {\n throw new Error(\"useGroupHilitedElementsContext should be used within a GroupHilitedElementsContext provider\");\n }\n return context;\n};\n"]}
@@ -50,7 +50,7 @@ export const GroupQueryBuilderCustomUI = ({ updateQuery, isUpdating, resetView }
50
50
  setSelectionKeyset(keys);
51
51
  const dataProvider = await createPropertyDataProvider(keys, iModelConnection);
52
52
  setDataProvider(dataProvider);
53
- setQueryBuilder(new QueryBuilder(dataProvider));
53
+ setQueryBuilder(new QueryBuilder(dataProvider, iModelConnection));
54
54
  };
55
55
  return iModelConnection ? Presentation.selection.selectionChange.addListener(onSelectionChanged) : () => { };
56
56
  }, [iModelConnection]);
@@ -1 +1 @@
1
- {"version":3,"file":"GroupQueryBuilderCustomUI.js","sourceRoot":"","sources":["../../../../src/components/customUI/GroupQueryBuilderCustomUI.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 React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Presentation } from \"@itwin/presentation-frontend\";\nimport type { ISelectionProvider, SelectionChangeEventArgs } from \"@itwin/presentation-frontend\";\nimport { KeySet } from \"@itwin/presentation-common\";\nimport \"./GroupQueryBuilderCustomUI.scss\";\nimport { QueryBuilder } from \"../Groups/QueryBuilder/QueryBuilder\";\nimport type { GroupingCustomUIProps } from \"./GroupingMappingCustomUI\";\nimport { DEFAULT_PROPERTY_GRID_RULESET, PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { ActionButtonRendererProps } from \"@itwin/components-react\";\nimport { VirtualizedPropertyGridWithDataProvider } from \"@itwin/components-react\";\nimport { ResizableContainerObserver } from \"@itwin/core-react\";\nimport type { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyGridWrapperContext } from \"../context/PropertyGridWrapperContext\";\nimport { PropertyAction } from \"../Properties/PropertyAction\";\nimport { Alert, Button } from \"@itwin/itwinui-react\";\nimport { useGroupingMappingApiConfig } from \"../context/GroupingApiConfigContext\";\nimport { IModelApp } from \"@itwin/core-frontend\";\n\nconst createPropertyDataProvider = async (keys: KeySet, iModelConnection: IModelConnection): Promise<PresentationPropertyDataProvider> => {\n const dataProvider = new PresentationPropertyDataProvider({\n imodel: iModelConnection,\n ruleset: DEFAULT_PROPERTY_GRID_RULESET,\n });\n dataProvider.keys = keys;\n dataProvider.isNestedPropertyCategoryGroupingEnabled = true;\n const data = await dataProvider.getData();\n const selectedCategory = data.categories.find(\n (category) => category.label === IModelApp.localization.getLocalizedString(\"Presentation:selectedItems.categoryLabel\"),\n );\n if (selectedCategory) {\n selectedCategory.expand = true;\n }\n return dataProvider;\n};\n\ninterface ContainerDimensions {\n width: number;\n height: number;\n}\n\n/**\n * A default group query builder for the Grouping Mapping Widget that uses the property grid to generate queries.\n * @public\n */\nexport const GroupQueryBuilderCustomUI = ({ updateQuery, isUpdating, resetView }: GroupingCustomUIProps) => {\n const { iModelConnection } = useGroupingMappingApiConfig();\n if (!iModelConnection) {\n throw new Error(\"This component requires an active iModelConnection.\");\n }\n const [size, setSize] = useState<ContainerDimensions>({ width: 0, height: 0 });\n const [dataProvider, setDataProvider] = useState<PresentationPropertyDataProvider | undefined>(undefined);\n const [currentPropertyList, setCurrentPropertyList] = useState<PropertyRecord[]>([]);\n const [selectionKeySet, setSelectionKeyset] = useState<KeySet>(new KeySet());\n const [queryBuilder, setQueryBuilder] = useState<QueryBuilder | undefined>();\n\n useEffect(() => {\n const onSelectionChanged = async (evt: SelectionChangeEventArgs, selectionProvider: ISelectionProvider) => {\n const selection = selectionProvider.getSelection(evt.imodel, evt.level);\n const keys = new KeySet(selection);\n setSelectionKeyset(keys);\n const dataProvider = await createPropertyDataProvider(keys, iModelConnection);\n setDataProvider(dataProvider);\n setQueryBuilder(new QueryBuilder(dataProvider));\n };\n\n return iModelConnection ? Presentation.selection.selectionChange.addListener(onSelectionChanged) : () => {};\n }, [iModelConnection]);\n\n const onClickResetButton = async () => {\n queryBuilder?.resetQueryBuilder();\n updateQuery(\"\");\n setCurrentPropertyList([]);\n if (resetView)\n await resetView().catch((e) =>\n /* eslint-disable no-console */\n console.error(e),\n );\n };\n\n const resize = useCallback((width, height) => setSize({ width, height }), []);\n\n const propertyContextValues = useMemo(\n () => ({\n currentPropertyList,\n setCurrentPropertyList,\n queryBuilder,\n setQuery: updateQuery,\n isUpdating: isUpdating ?? false,\n }),\n [currentPropertyList, isUpdating, queryBuilder, updateQuery],\n );\n\n const actionButtonRenderers = useMemo(() => [({ property }: ActionButtonRendererProps) => <PropertyAction property={property} />], []);\n\n return (\n <div className=\"gmw-select-query-generator-container\">\n {!dataProvider || selectionKeySet.size === 0 ? (\n <Alert type=\"informational\">Please select on an element within the viewer first, then select properties to generate a group query.</Alert>\n ) : (\n <>\n <div className=\"gmw-select-property-grid-container\">\n <ResizableContainerObserver onResize={resize} />\n <PropertyGridWrapperContext.Provider value={propertyContextValues}>\n <VirtualizedPropertyGridWithDataProvider\n dataProvider={dataProvider}\n width={size.width}\n height={size.height}\n actionButtonRenderers={actionButtonRenderers}\n />\n </PropertyGridWrapperContext.Provider>\n </div>\n <div className=\"gmw-select-reset-button\">\n <Button styleType=\"default\" size=\"small\" onClick={onClickResetButton}>\n Reset\n </Button>\n </div>\n </>\n )}\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"GroupQueryBuilderCustomUI.js","sourceRoot":"","sources":["../../../../src/components/customUI/GroupQueryBuilderCustomUI.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 React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Presentation } from \"@itwin/presentation-frontend\";\nimport type { ISelectionProvider, SelectionChangeEventArgs } from \"@itwin/presentation-frontend\";\nimport { KeySet } from \"@itwin/presentation-common\";\nimport \"./GroupQueryBuilderCustomUI.scss\";\nimport { QueryBuilder } from \"../Groups/QueryBuilder/QueryBuilder\";\nimport type { GroupingCustomUIProps } from \"./GroupingMappingCustomUI\";\nimport { DEFAULT_PROPERTY_GRID_RULESET, PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { ActionButtonRendererProps } from \"@itwin/components-react\";\nimport { VirtualizedPropertyGridWithDataProvider } from \"@itwin/components-react\";\nimport { ResizableContainerObserver } from \"@itwin/core-react\";\nimport type { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { PropertyGridWrapperContext } from \"../context/PropertyGridWrapperContext\";\nimport { PropertyAction } from \"../Properties/PropertyAction\";\nimport { Alert, Button } from \"@itwin/itwinui-react\";\nimport { useGroupingMappingApiConfig } from \"../context/GroupingApiConfigContext\";\nimport { IModelApp } from \"@itwin/core-frontend\";\n\nconst createPropertyDataProvider = async (keys: KeySet, iModelConnection: IModelConnection): Promise<PresentationPropertyDataProvider> => {\n const dataProvider = new PresentationPropertyDataProvider({\n imodel: iModelConnection,\n ruleset: DEFAULT_PROPERTY_GRID_RULESET,\n });\n dataProvider.keys = keys;\n dataProvider.isNestedPropertyCategoryGroupingEnabled = true;\n const data = await dataProvider.getData();\n const selectedCategory = data.categories.find(\n (category) => category.label === IModelApp.localization.getLocalizedString(\"Presentation:selectedItems.categoryLabel\"),\n );\n if (selectedCategory) {\n selectedCategory.expand = true;\n }\n return dataProvider;\n};\n\ninterface ContainerDimensions {\n width: number;\n height: number;\n}\n\n/**\n * A default group query builder for the Grouping Mapping Widget that uses the property grid to generate queries.\n * @public\n */\nexport const GroupQueryBuilderCustomUI = ({ updateQuery, isUpdating, resetView }: GroupingCustomUIProps) => {\n const { iModelConnection } = useGroupingMappingApiConfig();\n if (!iModelConnection) {\n throw new Error(\"This component requires an active iModelConnection.\");\n }\n const [size, setSize] = useState<ContainerDimensions>({ width: 0, height: 0 });\n const [dataProvider, setDataProvider] = useState<PresentationPropertyDataProvider | undefined>(undefined);\n const [currentPropertyList, setCurrentPropertyList] = useState<PropertyRecord[]>([]);\n const [selectionKeySet, setSelectionKeyset] = useState<KeySet>(new KeySet());\n const [queryBuilder, setQueryBuilder] = useState<QueryBuilder | undefined>();\n\n useEffect(() => {\n const onSelectionChanged = async (evt: SelectionChangeEventArgs, selectionProvider: ISelectionProvider) => {\n const selection = selectionProvider.getSelection(evt.imodel, evt.level);\n const keys = new KeySet(selection);\n setSelectionKeyset(keys);\n const dataProvider = await createPropertyDataProvider(keys, iModelConnection);\n setDataProvider(dataProvider);\n setQueryBuilder(new QueryBuilder(dataProvider, iModelConnection));\n };\n\n return iModelConnection ? Presentation.selection.selectionChange.addListener(onSelectionChanged) : () => {};\n }, [iModelConnection]);\n\n const onClickResetButton = async () => {\n queryBuilder?.resetQueryBuilder();\n updateQuery(\"\");\n setCurrentPropertyList([]);\n if (resetView)\n await resetView().catch((e) =>\n /* eslint-disable no-console */\n console.error(e),\n );\n };\n\n const resize = useCallback((width, height) => setSize({ width, height }), []);\n\n const propertyContextValues = useMemo(\n () => ({\n currentPropertyList,\n setCurrentPropertyList,\n queryBuilder,\n setQuery: updateQuery,\n isUpdating: isUpdating ?? false,\n }),\n [currentPropertyList, isUpdating, queryBuilder, updateQuery],\n );\n\n const actionButtonRenderers = useMemo(() => [({ property }: ActionButtonRendererProps) => <PropertyAction property={property} />], []);\n\n return (\n <div className=\"gmw-select-query-generator-container\">\n {!dataProvider || selectionKeySet.size === 0 ? (\n <Alert type=\"informational\">Please select on an element within the viewer first, then select properties to generate a group query.</Alert>\n ) : (\n <>\n <div className=\"gmw-select-property-grid-container\">\n <ResizableContainerObserver onResize={resize} />\n <PropertyGridWrapperContext.Provider value={propertyContextValues}>\n <VirtualizedPropertyGridWithDataProvider\n dataProvider={dataProvider}\n width={size.width}\n height={size.height}\n actionButtonRenderers={actionButtonRenderers}\n />\n </PropertyGridWrapperContext.Provider>\n </div>\n <div className=\"gmw-select-reset-button\">\n <Button styleType=\"default\" size=\"small\" onClick={onClickResetButton}>\n Reset\n </Button>\n </div>\n </>\n )}\n </div>\n );\n};\n"]}
@@ -14,6 +14,7 @@ export { MappingsView, MappingsViewProps } from "./components/Mappings/MappingsV
14
14
  export { useGroupsOperations, GroupsOperationsProps } from "./components/Groups/hooks/useGroupsOperations";
15
15
  export { GroupsView, GroupsViewProps } from "./components/Groups/GroupsView";
16
16
  export { GroupingMappingContext, GroupingMappingContextProps } from "./components/GroupingMappingContext";
17
+ export { useGroupHilitedElementsContext, GroupHilitedElements, GroupHilitedElementsContext } from "./components/context/GroupHilitedElementsContext";
17
18
  export { Groups, GroupsProps } from "./components/Groups/Groups";
18
19
  export { GroupsVisualization, GroupsVisualizationProps } from "./components/Groups/GroupsVisualization";
19
20
  export { GroupAction, GroupActionProps } from "./components/Groups/Editing/GroupAction";
@@ -18,6 +18,7 @@ export { MappingsView } from "./components/Mappings/MappingsView";
18
18
  export { useGroupsOperations } from "./components/Groups/hooks/useGroupsOperations";
19
19
  export { GroupsView } from "./components/Groups/GroupsView";
20
20
  export { GroupingMappingContext } from "./components/GroupingMappingContext";
21
+ export { useGroupHilitedElementsContext, GroupHilitedElementsContext } from "./components/context/GroupHilitedElementsContext";
21
22
  export { Groups } from "./components/Groups/Groups";
22
23
  export { GroupsVisualization } from "./components/Groups/GroupsVisualization";
23
24
  export { GroupAction } from "./components/Groups/Editing/GroupAction";
@@ -1 +1 @@
1
- {"version":3,"file":"grouping-mapping-widget.js","sourceRoot":"","sources":["../../src/grouping-mapping-widget.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,gDAAgD;AAChD,cAAc,qCAAqC,CAAC;AAEpD,0EAA0E;AAC1E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACpJ,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC/I,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAIL,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,+CAA+C,CAAC;AACvD,cAAc,wBAAwB,CAAC;AAEvC,yCAAyC;AACzC,OAAO,EAAE,QAAQ,EAAiB,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAA2B,MAAM,mDAAmD,CAAC;AACnH,OAAO,EAAE,aAAa,EAAsB,MAAM,6CAA6C,CAAC;AAChG,OAAO,EAAE,YAAY,EAAqB,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAyB,MAAM,+CAA+C,CAAC;AAC3G,OAAO,EAAE,UAAU,EAAmB,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAA+B,MAAM,qCAAqC,CAAC;AAC1G,OAAO,EAAE,MAAM,EAAe,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,yCAAyC,CAAC;AACxG,OAAO,EAAE,WAAW,EAAoB,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,YAAY,EAAqB,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAsC,MAAM,uDAAuD,CAAC;AAC1I,OAAO,EAAE,mBAAmB,EAA4B,MAAM,6DAA6D,CAAC;AAC5H,OAAO,EAAE,wBAAwB,EAAiC,MAAM,uEAAuE,CAAC;AAChJ,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAEL,2BAA2B,GAK5B,MAAM,+CAA+C,CAAC;AAEvD,gCAAgC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,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 *--------------------------------------------------------------------------------------------*/\n/** UI Provider for iTwin Viewer Applications */\nexport * from \"./WidgetShell/GroupingMappingWidget\";\n\n/** Interfaces for providing custom MappingClient and API configuration */\nexport { createDefaultMappingClient, createMappingClient, MappingClientContext, useMappingClient } from \"./components/context/MappingClientContext\";\nexport { createDefaultGroupsClient, createGroupsClient, GroupsClientContext, useGroupsClient } from \"./components/context/GroupsClientContext\";\nexport {\n createDefaultPropertiesClient,\n createPropertiesClient,\n PropertiesClientContext,\n usePropertiesClient,\n} from \"./components/context/PropertiesClientContext\";\nexport {\n ClientPrefix,\n GetAccessTokenFn,\n GroupingMappingApiConfig,\n GroupingMappingApiConfigContext,\n useGroupingMappingApiConfig,\n} from \"./components/context/GroupingApiConfigContext\";\nexport * from \"@itwin/insights-client\";\n\n/** Internal components for custom UIs */\nexport { Mappings, MappingsProps } from \"./components/Mappings/Mappings\";\nexport { useMappingsOperations, MappingsOperationsProps } from \"./components/Mappings/hooks/useMappingsOperations\";\nexport { MappingAction, MappingActionProps } from \"./components/Mappings/Editing/MappingAction\";\nexport { MappingsView, MappingsViewProps } from \"./components/Mappings/MappingsView\";\nexport { useGroupsOperations, GroupsOperationsProps } from \"./components/Groups/hooks/useGroupsOperations\";\nexport { GroupsView, GroupsViewProps } from \"./components/Groups/GroupsView\";\nexport { GroupingMappingContext, GroupingMappingContextProps } from \"./components/GroupingMappingContext\";\nexport { Groups, GroupsProps } from \"./components/Groups/Groups\";\nexport { GroupsVisualization, GroupsVisualizationProps } from \"./components/Groups/GroupsVisualization\";\nexport { GroupAction, GroupActionProps } from \"./components/Groups/Editing/GroupAction\";\nexport { PropertyMenu, PropertyMenuProps } from \"./components/Properties/PropertyMenu\";\nexport { PropertyMenuWithVisualization, PropertyMenuWithVisualizationProps } from \"./components/Properties/PropertyMenuWithVisualization\";\nexport { GroupPropertyAction, GroupPropertyActionProps } from \"./components/Properties/GroupProperties/GroupPropertyAction\";\nexport { CalculatedPropertyAction, CalculatedPropertyActionProps } from \"./components/Properties/CalculatedProperties/CalculatedPropertyAction\";\nexport { SearchGroupingCustomUI } from \"./components/customUI/SearchGroupingCustomUI\";\nexport { ManualGroupingCustomUI } from \"./components/customUI/ManualGroupingCustomUI\";\nexport { GroupQueryBuilderCustomUI } from \"./components/customUI/GroupQueryBuilderCustomUI\";\nexport {\n GroupingMappingCustomUI,\n GroupingMappingCustomUIType,\n ContextCustomUI,\n GroupingCustomUI,\n GroupingCustomUIProps,\n ContextCustomUIProps,\n} from \"./components/customUI/GroupingMappingCustomUI\";\n\n/** Formula DataType resolver */\nexport { resolveFormulaDataType } from \"./formula/FormulaDataTypeResolver\";\nexport { DataType, PropertyMap } from \"./formula/Types\";\nexport { IResult } from \"./formula/IResult\";\n"]}
1
+ {"version":3,"file":"grouping-mapping-widget.js","sourceRoot":"","sources":["../../src/grouping-mapping-widget.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,gDAAgD;AAChD,cAAc,qCAAqC,CAAC;AAEpD,0EAA0E;AAC1E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACpJ,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC/I,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAIL,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,+CAA+C,CAAC;AACvD,cAAc,wBAAwB,CAAC;AAEvC,yCAAyC;AACzC,OAAO,EAAE,QAAQ,EAAiB,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAA2B,MAAM,mDAAmD,CAAC;AACnH,OAAO,EAAE,aAAa,EAAsB,MAAM,6CAA6C,CAAC;AAChG,OAAO,EAAE,YAAY,EAAqB,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAyB,MAAM,+CAA+C,CAAC;AAC3G,OAAO,EAAE,UAAU,EAAmB,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAA+B,MAAM,qCAAqC,CAAC;AAC1G,OAAO,EAAE,8BAA8B,EAAwB,2BAA2B,EAAE,MAAM,kDAAkD,CAAC;AACrJ,OAAO,EAAE,MAAM,EAAe,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,yCAAyC,CAAC;AACxG,OAAO,EAAE,WAAW,EAAoB,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,YAAY,EAAqB,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAsC,MAAM,uDAAuD,CAAC;AAC1I,OAAO,EAAE,mBAAmB,EAA4B,MAAM,6DAA6D,CAAC;AAC5H,OAAO,EAAE,wBAAwB,EAAiC,MAAM,uEAAuE,CAAC;AAChJ,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAEL,2BAA2B,GAK5B,MAAM,+CAA+C,CAAC;AAEvD,gCAAgC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,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 *--------------------------------------------------------------------------------------------*/\n/** UI Provider for iTwin Viewer Applications */\nexport * from \"./WidgetShell/GroupingMappingWidget\";\n\n/** Interfaces for providing custom MappingClient and API configuration */\nexport { createDefaultMappingClient, createMappingClient, MappingClientContext, useMappingClient } from \"./components/context/MappingClientContext\";\nexport { createDefaultGroupsClient, createGroupsClient, GroupsClientContext, useGroupsClient } from \"./components/context/GroupsClientContext\";\nexport {\n createDefaultPropertiesClient,\n createPropertiesClient,\n PropertiesClientContext,\n usePropertiesClient,\n} from \"./components/context/PropertiesClientContext\";\nexport {\n ClientPrefix,\n GetAccessTokenFn,\n GroupingMappingApiConfig,\n GroupingMappingApiConfigContext,\n useGroupingMappingApiConfig,\n} from \"./components/context/GroupingApiConfigContext\";\nexport * from \"@itwin/insights-client\";\n\n/** Internal components for custom UIs */\nexport { Mappings, MappingsProps } from \"./components/Mappings/Mappings\";\nexport { useMappingsOperations, MappingsOperationsProps } from \"./components/Mappings/hooks/useMappingsOperations\";\nexport { MappingAction, MappingActionProps } from \"./components/Mappings/Editing/MappingAction\";\nexport { MappingsView, MappingsViewProps } from \"./components/Mappings/MappingsView\";\nexport { useGroupsOperations, GroupsOperationsProps } from \"./components/Groups/hooks/useGroupsOperations\";\nexport { GroupsView, GroupsViewProps } from \"./components/Groups/GroupsView\";\nexport { GroupingMappingContext, GroupingMappingContextProps } from \"./components/GroupingMappingContext\";\nexport { useGroupHilitedElementsContext, GroupHilitedElements, GroupHilitedElementsContext } from \"./components/context/GroupHilitedElementsContext\";\nexport { Groups, GroupsProps } from \"./components/Groups/Groups\";\nexport { GroupsVisualization, GroupsVisualizationProps } from \"./components/Groups/GroupsVisualization\";\nexport { GroupAction, GroupActionProps } from \"./components/Groups/Editing/GroupAction\";\nexport { PropertyMenu, PropertyMenuProps } from \"./components/Properties/PropertyMenu\";\nexport { PropertyMenuWithVisualization, PropertyMenuWithVisualizationProps } from \"./components/Properties/PropertyMenuWithVisualization\";\nexport { GroupPropertyAction, GroupPropertyActionProps } from \"./components/Properties/GroupProperties/GroupPropertyAction\";\nexport { CalculatedPropertyAction, CalculatedPropertyActionProps } from \"./components/Properties/CalculatedProperties/CalculatedPropertyAction\";\nexport { SearchGroupingCustomUI } from \"./components/customUI/SearchGroupingCustomUI\";\nexport { ManualGroupingCustomUI } from \"./components/customUI/ManualGroupingCustomUI\";\nexport { GroupQueryBuilderCustomUI } from \"./components/customUI/GroupQueryBuilderCustomUI\";\nexport {\n GroupingMappingCustomUI,\n GroupingMappingCustomUIType,\n ContextCustomUI,\n GroupingCustomUI,\n GroupingCustomUIProps,\n ContextCustomUIProps,\n} from \"./components/customUI/GroupingMappingCustomUI\";\n\n/** Formula DataType resolver */\nexport { resolveFormulaDataType } from \"./formula/FormulaDataTypeResolver\";\nexport { DataType, PropertyMap } from \"./formula/Types\";\nexport { IResult } from \"./formula/IResult\";\n"]}
@@ -1,7 +1,3 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
1
  import { PropertyRecord } from "@itwin/appui-abstract";
6
2
  import { FieldDescriptorType, PropertiesField } from "@itwin/presentation-common";
7
3
  import { PresentationPropertyDataProvider } from "@itwin/presentation-components";
@@ -15,7 +11,22 @@ describe("QueryBuilder", () => {
15
11
  beforeEach(() => {
16
12
  dataProvider = MockFactory.create(PresentationPropertyDataProvider);
17
13
  MockFactory.stubProperty(dataProvider, "getContentDescriptor", () => () => true);
18
- sut = new QueryBuilder(dataProvider);
14
+ const imodel = {
15
+ createQueryReader: (query) => {
16
+ if (query.includes("SELECT ec_classname(ecclassid) FROM biscore.element WHERE ecinstanceid = ?")) {
17
+ return {
18
+ next: async () => {
19
+ return {
20
+ value: ["mockModeledElement"],
21
+ done: true,
22
+ };
23
+ },
24
+ };
25
+ }
26
+ return '';
27
+ }
28
+ };
29
+ sut = new QueryBuilder(dataProvider, imodel);
19
30
  });
20
31
  afterEach(() => {
21
32
  dataProvider.getFieldByPropertyRecord.restore();
@@ -71,7 +82,7 @@ describe("QueryBuilder", () => {
71
82
  await queryBuilder.removeProperty(prop);
72
83
  }
73
84
  }
74
- const result = queryBuilder.buildQueryString();
85
+ const result = await queryBuilder.buildQueryString();
75
86
  assert.strictEqual(result, expectedResult);
76
87
  };
77
88
  });
@@ -1 +1 @@
1
- {"version":3,"file":"QueryBuilder.test.js","sourceRoot":"","sources":["../../../src/test/QueryBuilder.test.ts"],"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 { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { FieldDescriptorType, PropertiesField } from \"@itwin/presentation-common\";\nimport type { FieldDescriptor, RelationshipPath, StrippedRelatedClassInfo } from \"@itwin/presentation-common\";\nimport { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport { assert } from \"chai\";\nimport { QueryBuilder } from \"../components/Groups/QueryBuilder/QueryBuilder\";\nimport { MockFactory } from \"./MockFactory\";\nimport type { StubbedType } from \"./MockFactory\";\nimport type { OperationTestData, PropertiesTestData, PropertyRecordTestData, QueryBuilderTestData } from \"./QueryBuilderTestData\";\nimport { testCases } from \"./QueryBuilder.testdata\";\n\ndescribe(\"QueryBuilder\", () => {\n let sut: QueryBuilder;\n let dataProvider: StubbedType<PresentationPropertyDataProvider>;\n\n beforeEach(() => {\n dataProvider = MockFactory.create(PresentationPropertyDataProvider);\n MockFactory.stubProperty(dataProvider, \"getContentDescriptor\", () => () => true);\n\n sut = new QueryBuilder(dataProvider);\n });\n\n afterEach(() => {\n dataProvider.getFieldByPropertyRecord.restore();\n });\n\n const testData: QueryBuilderTestData = testCases;\n testData.testCases.forEach((testCase) => {\n it(testCase.name, async () => executeTest(sut, testCase.expectedResult, testCase.operations));\n });\n\n const createFieldDescriptor = (\n pathToClass: RelationshipPath | undefined,\n fieldProperties: PropertiesTestData[],\n type: FieldDescriptorType,\n fieldName: string | undefined,\n ): FieldDescriptor => {\n switch (type) {\n case FieldDescriptorType.Properties:\n const pathFromSelectToPropertyClass: StrippedRelatedClassInfo[] = (pathToClass ?? []).map((x) => ({\n sourceClassName: x.sourceClassInfo.name,\n targetClassName: x.targetClassInfo.name,\n relationshipName: x.relationshipInfo.name,\n isForwardRelationship: x.isForwardRelationship,\n }));\n\n const properties = fieldProperties.map((x) => ({\n class: x.property.classInfo.name,\n name: x.property.name,\n }));\n\n return {\n pathFromSelectToPropertyClass,\n properties,\n type,\n };\n case FieldDescriptorType.Name:\n return {\n type,\n fieldName: fieldName ?? \"\",\n };\n }\n };\n\n const createPropertyRecord = (propertyRecord: PropertyRecordTestData, propertiesField: PropertiesField, fieldDescriptor: FieldDescriptor) => {\n const propertiesFieldMock: StubbedType<PropertiesField> = MockFactory.create(PropertiesField);\n\n MockFactory.stubProperty(propertiesFieldMock, \"parent\", () => propertiesField.parent);\n MockFactory.stubProperty(propertiesFieldMock, \"properties\", () => propertiesField.properties);\n MockFactory.stubProperty(propertiesFieldMock, \"type\", () => propertiesField.type);\n MockFactory.stubProperty(propertiesFieldMock, \"getFieldDescriptor\", () => () => fieldDescriptor);\n\n const prop: PropertyRecord = new PropertyRecord(propertyRecord.value, propertyRecord.property);\n dataProvider.getFieldByPropertyRecord.withArgs(prop).resolves(propertiesFieldMock);\n return prop;\n };\n\n const executeTest = async (queryBuilder: QueryBuilder, expectedResult: string, operations: OperationTestData[]) => {\n for (const op of operations) {\n const fieldDescriptor = createFieldDescriptor(\n op.propertiesField.parent?.pathToPrimaryClass,\n op.propertiesField.properties,\n op.fieldDescriptorType,\n op.fieldDescriptorName,\n );\n\n const prop = createPropertyRecord(op.propertyRecord, op.propertiesField as PropertiesField, fieldDescriptor);\n\n if (op.operationType === \"addProperty\") {\n const result = await queryBuilder.addProperty(prop);\n assert.strictEqual(result, op.expectedResult);\n }\n if (op.operationType === \"removeProperty\") {\n await queryBuilder.removeProperty(prop);\n }\n }\n\n const result = queryBuilder.buildQueryString();\n assert.strictEqual(result, expectedResult);\n };\n});\n"]}
1
+ {"version":3,"file":"QueryBuilder.test.js","sourceRoot":"","sources":["../../../src/test/QueryBuilder.test.ts"],"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 { PropertyValue } from \"@itwin/appui-abstract\";\nimport { PropertyRecord } from \"@itwin/appui-abstract\";\nimport { FieldDescriptorType, PropertiesField } from \"@itwin/presentation-common\";\nimport type { FieldDescriptor, RelationshipPath, StrippedRelatedClassInfo } from \"@itwin/presentation-common\";\nimport { PresentationPropertyDataProvider } from \"@itwin/presentation-components\";\nimport { assert } from \"chai\";\nimport { QueryBuilder } from \"../components/Groups/QueryBuilder/QueryBuilder\";\nimport { MockFactory } from \"./MockFactory\";\nimport type { StubbedType } from \"./MockFactory\";\nimport type { OperationTestData, PropertiesTestData, PropertyRecordTestData, QueryBuilderTestData } from \"./QueryBuilderTestData\";\nimport { testCases } from \"./QueryBuilder.testdata\";\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { ECSqlReader } from \"@itwin/core-common\";\n\ndescribe(\"QueryBuilder\", () => {\n let sut: QueryBuilder;\n let dataProvider: StubbedType<PresentationPropertyDataProvider>;\n\n beforeEach(() => {\n dataProvider = MockFactory.create(PresentationPropertyDataProvider);\n MockFactory.stubProperty(dataProvider, \"getContentDescriptor\", () => () => true);\n const imodel = {\n createQueryReader: (query) => {\n if (query.includes(\"SELECT ec_classname(ecclassid) FROM biscore.element WHERE ecinstanceid = ?\")) {\n return {\n next: async () => {\n return {\n value: [\"mockModeledElement\"],\n done: true,\n };\n },\n } as ECSqlReader;\n }\n return '';\n }\n } as IModelConnection;\n\n sut = new QueryBuilder(dataProvider, imodel);\n });\n\n afterEach(() => {\n dataProvider.getFieldByPropertyRecord.restore();\n });\n\n const testData: QueryBuilderTestData = testCases;\n testData.testCases.forEach((testCase) => {\n it(testCase.name, async () => executeTest(sut, testCase.expectedResult, testCase.operations));\n });\n\n const createFieldDescriptor = (\n pathToClass: RelationshipPath | undefined,\n fieldProperties: PropertiesTestData[],\n type: FieldDescriptorType,\n fieldName: string | undefined,\n ): FieldDescriptor => {\n switch (type) {\n case FieldDescriptorType.Properties:\n const pathFromSelectToPropertyClass: StrippedRelatedClassInfo[] = (pathToClass ?? []).map((x) => ({\n sourceClassName: x.sourceClassInfo.name,\n targetClassName: x.targetClassInfo.name,\n relationshipName: x.relationshipInfo.name,\n isForwardRelationship: x.isForwardRelationship,\n }));\n\n const properties = fieldProperties.map((x) => ({\n class: x.property.classInfo.name,\n name: x.property.name,\n }));\n\n return {\n pathFromSelectToPropertyClass,\n properties,\n type,\n };\n case FieldDescriptorType.Name:\n return {\n type,\n fieldName: fieldName ?? \"\",\n };\n }\n };\n\n const createPropertyRecord = (propertyRecord: PropertyRecordTestData, propertiesField: PropertiesField, fieldDescriptor: FieldDescriptor) => {\n const propertiesFieldMock: StubbedType<PropertiesField> = MockFactory.create(PropertiesField);\n\n MockFactory.stubProperty(propertiesFieldMock, \"parent\", () => propertiesField.parent);\n MockFactory.stubProperty(propertiesFieldMock, \"properties\", () => propertiesField.properties);\n MockFactory.stubProperty(propertiesFieldMock, \"type\", () => propertiesField.type);\n MockFactory.stubProperty(propertiesFieldMock, \"getFieldDescriptor\", () => () => fieldDescriptor);\n\n const prop: PropertyRecord = new PropertyRecord(propertyRecord.value as PropertyValue, propertyRecord.property);\n dataProvider.getFieldByPropertyRecord.withArgs(prop).resolves(propertiesFieldMock);\n return prop;\n };\n\n const executeTest = async (queryBuilder: QueryBuilder, expectedResult: string, operations: OperationTestData[]) => {\n for (const op of operations) {\n const fieldDescriptor = createFieldDescriptor(\n op.propertiesField.parent?.pathToPrimaryClass,\n op.propertiesField.properties,\n op.fieldDescriptorType,\n op.fieldDescriptorName,\n );\n\n const prop = createPropertyRecord(op.propertyRecord, op.propertiesField as PropertiesField, fieldDescriptor);\n\n if (op.operationType === \"addProperty\") {\n const result = await queryBuilder.addProperty(prop);\n assert.strictEqual(result, op.expectedResult);\n }\n if (op.operationType === \"removeProperty\") {\n await queryBuilder.removeProperty(prop);\n }\n }\n\n const result = await queryBuilder.buildQueryString();\n assert.strictEqual(result, expectedResult);\n };\n});\n"]}