@itwin/presentation-frontend 4.5.0-dev.8 → 4.5.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 (128) hide show
  1. package/CHANGELOG.md +72 -1
  2. package/LICENSE.md +1 -1
  3. package/README.md +1 -1
  4. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
  5. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js +10 -6
  6. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  7. package/lib/cjs/presentation-frontend/Diagnostics.d.ts.map +1 -1
  8. package/lib/cjs/presentation-frontend/Diagnostics.js +18 -13
  9. package/lib/cjs/presentation-frontend/Diagnostics.js.map +1 -1
  10. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js +3 -3
  11. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
  12. package/lib/cjs/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
  13. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js +3 -3
  14. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  15. package/lib/cjs/presentation-frontend/LocalizationHelper.js +3 -3
  16. package/lib/cjs/presentation-frontend/LocalizationHelper.js.map +1 -1
  17. package/lib/cjs/presentation-frontend/Presentation.d.ts +1 -1
  18. package/lib/cjs/presentation-frontend/Presentation.d.ts.map +1 -1
  19. package/lib/cjs/presentation-frontend/Presentation.js +36 -21
  20. package/lib/cjs/presentation-frontend/Presentation.js.map +1 -1
  21. package/lib/cjs/presentation-frontend/PresentationManager.d.ts +84 -21
  22. package/lib/cjs/presentation-frontend/PresentationManager.d.ts.map +1 -1
  23. package/lib/cjs/presentation-frontend/PresentationManager.js +245 -154
  24. package/lib/cjs/presentation-frontend/PresentationManager.js.map +1 -1
  25. package/lib/cjs/presentation-frontend/RulesetManager.d.ts.map +1 -1
  26. package/lib/cjs/presentation-frontend/RulesetManager.js +11 -7
  27. package/lib/cjs/presentation-frontend/RulesetManager.js.map +1 -1
  28. package/lib/cjs/presentation-frontend/RulesetVariablesManager.d.ts.map +1 -1
  29. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js +53 -31
  30. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  31. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.d.ts +30 -0
  32. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.d.ts.map +1 -0
  33. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.js +117 -0
  34. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.js.map +1 -0
  35. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +33 -4
  36. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  37. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +179 -74
  38. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  39. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
  40. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +54 -25
  41. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  42. package/lib/cjs/presentation-frontend/selection/HiliteRules.json +172 -172
  43. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.d.ts.map +1 -1
  44. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js +23 -13
  45. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
  46. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js +3 -3
  47. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
  48. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.d.ts.map +1 -1
  49. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js +3 -3
  50. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
  51. package/lib/cjs/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
  52. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js +15 -9
  53. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js.map +1 -1
  54. package/lib/cjs/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
  55. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js +7 -5
  56. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  57. package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts +22 -3
  58. package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
  59. package/lib/cjs/presentation-frontend/selection/SelectionManager.js +295 -75
  60. package/lib/cjs/presentation-frontend/selection/SelectionManager.js.map +1 -1
  61. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
  62. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js +25 -14
  63. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  64. package/lib/cjs/presentation-frontend.js +3 -3
  65. package/lib/cjs/presentation-frontend.js.map +1 -1
  66. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
  67. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js +10 -6
  68. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  69. package/lib/esm/presentation-frontend/Diagnostics.d.ts.map +1 -1
  70. package/lib/esm/presentation-frontend/Diagnostics.js +18 -13
  71. package/lib/esm/presentation-frontend/Diagnostics.js.map +1 -1
  72. package/lib/esm/presentation-frontend/FrontendLoggerCategory.js +3 -3
  73. package/lib/esm/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
  74. package/lib/esm/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
  75. package/lib/esm/presentation-frontend/IpcRequestsHandler.js +3 -3
  76. package/lib/esm/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  77. package/lib/esm/presentation-frontend/LocalizationHelper.js +3 -3
  78. package/lib/esm/presentation-frontend/LocalizationHelper.js.map +1 -1
  79. package/lib/esm/presentation-frontend/Presentation.d.ts +1 -1
  80. package/lib/esm/presentation-frontend/Presentation.d.ts.map +1 -1
  81. package/lib/esm/presentation-frontend/Presentation.js +36 -21
  82. package/lib/esm/presentation-frontend/Presentation.js.map +1 -1
  83. package/lib/esm/presentation-frontend/PresentationManager.d.ts +84 -21
  84. package/lib/esm/presentation-frontend/PresentationManager.d.ts.map +1 -1
  85. package/lib/esm/presentation-frontend/PresentationManager.js +244 -152
  86. package/lib/esm/presentation-frontend/PresentationManager.js.map +1 -1
  87. package/lib/esm/presentation-frontend/RulesetManager.d.ts.map +1 -1
  88. package/lib/esm/presentation-frontend/RulesetManager.js +11 -7
  89. package/lib/esm/presentation-frontend/RulesetManager.js.map +1 -1
  90. package/lib/esm/presentation-frontend/RulesetVariablesManager.d.ts.map +1 -1
  91. package/lib/esm/presentation-frontend/RulesetVariablesManager.js +53 -31
  92. package/lib/esm/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  93. package/lib/esm/presentation-frontend/StreamedResponseGenerator.d.ts +30 -0
  94. package/lib/esm/presentation-frontend/StreamedResponseGenerator.d.ts.map +1 -0
  95. package/lib/esm/presentation-frontend/StreamedResponseGenerator.js +113 -0
  96. package/lib/esm/presentation-frontend/StreamedResponseGenerator.js.map +1 -0
  97. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +33 -4
  98. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  99. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +179 -74
  100. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  101. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
  102. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +54 -25
  103. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  104. package/lib/esm/presentation-frontend/selection/HiliteRules.json +172 -172
  105. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.d.ts.map +1 -1
  106. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js +24 -14
  107. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
  108. package/lib/esm/presentation-frontend/selection/ISelectionProvider.js +3 -3
  109. package/lib/esm/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
  110. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.d.ts.map +1 -1
  111. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js +3 -3
  112. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
  113. package/lib/esm/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
  114. package/lib/esm/presentation-frontend/selection/SelectionHandler.js +15 -9
  115. package/lib/esm/presentation-frontend/selection/SelectionHandler.js.map +1 -1
  116. package/lib/esm/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
  117. package/lib/esm/presentation-frontend/selection/SelectionHelper.js +7 -5
  118. package/lib/esm/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  119. package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts +22 -3
  120. package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
  121. package/lib/esm/presentation-frontend/selection/SelectionManager.js +295 -75
  122. package/lib/esm/presentation-frontend/selection/SelectionManager.js.map +1 -1
  123. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
  124. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js +25 -14
  125. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  126. package/lib/esm/presentation-frontend.js +3 -3
  127. package/lib/esm/presentation-frontend.js.map +1 -1
  128. package/package.json +20 -16
@@ -1,7 +1,7 @@
1
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
- *--------------------------------------------------------------------------------------------*/
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
5
  /** @packageDocumentation
6
6
  * @module Core
7
7
  */
@@ -29,21 +29,23 @@ class FavoritePropertiesManager {
29
29
  this.onFavoritesChanged = new BeEvent();
30
30
  /**
31
31
  * Initialize favorite properties for the provided IModelConnection.
32
+ * @deprecated in 4.5. Initialization is performed automatically by all async methods and only needed for deprecated [[FavoritePropertiesManager.has]] and [[FavoritePropertiesManager.sortFields]].
32
33
  */
33
34
  this.initializeConnection = async (imodel) => {
34
35
  const imodelId = imodel.iModelId;
35
36
  const iTwinId = imodel.iTwinId;
36
- if (this._globalProperties === undefined)
37
- this._globalProperties = await this._storage.loadProperties() || new Set();
37
+ if (this._globalProperties === undefined) {
38
+ this._globalProperties = (await this._storage.loadProperties()) || new Set();
39
+ }
38
40
  if (!this._iTwinProperties.has(iTwinId)) {
39
- const iTwinProperties = await this._storage.loadProperties(iTwinId) || new Set();
41
+ const iTwinProperties = (await this._storage.loadProperties(iTwinId)) || new Set();
40
42
  this._iTwinProperties.set(iTwinId, iTwinProperties);
41
43
  }
42
44
  if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId))) {
43
- const imodelProperties = await this._storage.loadProperties(iTwinId, imodelId) || new Set();
45
+ const imodelProperties = (await this._storage.loadProperties(iTwinId, imodelId)) || new Set();
44
46
  this._imodelProperties.set(getiModelInfo(iTwinId, imodelId), imodelProperties);
45
47
  }
46
- const propertiesOrder = await this._storage.loadPropertiesOrder(iTwinId, imodelId) || [];
48
+ const propertiesOrder = (await this._storage.loadPropertiesOrder(iTwinId, imodelId)) || [];
47
49
  this._propertiesOrder.set(getiModelInfo(iTwinId, imodelId), propertiesOrder);
48
50
  await this._adjustPropertyOrderInfos(iTwinId, imodelId);
49
51
  };
@@ -59,10 +61,12 @@ class FavoritePropertiesManager {
59
61
  // favorite property infos that need to be added to the propertiesOrder array
60
62
  const infosToAdd = new Set([...globalProperties, ...iTwinProperties, ...imodelProperties]);
61
63
  for (let i = propertiesOrder.length - 1; i >= 0; i--) {
62
- if (infosToAdd.has(propertiesOrder[i].name))
64
+ if (infosToAdd.has(propertiesOrder[i].name)) {
63
65
  infosToAdd.delete(propertiesOrder[i].name);
64
- else
66
+ }
67
+ else {
65
68
  propertiesOrder.splice(i, 1);
69
+ }
66
70
  }
67
71
  infosToAdd.forEach((info) => propertiesOrder.push({
68
72
  name: info,
@@ -71,7 +75,7 @@ class FavoritePropertiesManager {
71
75
  priority: 0,
72
76
  }));
73
77
  let priority = propertiesOrder.length;
74
- propertiesOrder.forEach((oi) => oi.priority = priority--);
78
+ propertiesOrder.forEach((oi) => (oi.priority = priority--));
75
79
  };
76
80
  /**
77
81
  * Sorts an array of fields with respect to favorite property order.
@@ -79,6 +83,7 @@ class FavoritePropertiesManager {
79
83
  * @param imodel IModelConnection.
80
84
  * @param fields Array of Field's that needs to be sorted.
81
85
  * @note `initializeConnection` must be called with the `imodel` before calling this function.
86
+ * @deprecated in 4.5. Use [[FavoritePropertiesManager.sortFieldsAsync]] instead. This method is not async, therefore it requires early initialization by calling [[FavoritePropertiesManager.initializeConnection]].
82
87
  */
83
88
  this.sortFields = (imodel, fields) => {
84
89
  this.validateInitialization(imodel);
@@ -89,11 +94,15 @@ class FavoritePropertiesManager {
89
94
  const sortFunction = (left, right) => {
90
95
  const lp = fieldPriority.get(left);
91
96
  const rp = fieldPriority.get(right);
92
- return lp < rp ? 1 :
93
- lp > rp ? -1 :
94
- left.priority < right.priority ? 1 : // if favorite fields have equal priorities, sort by field priority
95
- left.priority > right.priority ? -1 :
96
- left.name.localeCompare(right.name);
97
+ return lp < rp
98
+ ? 1
99
+ : lp > rp
100
+ ? -1
101
+ : left.priority < right.priority
102
+ ? 1 // if favorite fields have equal priorities, sort by field priority
103
+ : left.priority > right.priority
104
+ ? -1
105
+ : left.name.localeCompare(right.name);
97
106
  };
98
107
  return fields.sort(sortFunction);
99
108
  };
@@ -102,30 +111,35 @@ class FavoritePropertiesManager {
102
111
  const imodelId = imodel.iModelId;
103
112
  const imodelInfo = getiModelInfo(iTwinId, imodelId);
104
113
  let baseClasses;
105
- if (this._imodelBaseClassesByClass.has(imodelInfo))
114
+ if (this._imodelBaseClassesByClass.has(imodelInfo)) {
106
115
  baseClasses = this._imodelBaseClassesByClass.get(imodelInfo);
107
- else
108
- this._imodelBaseClassesByClass.set(imodelInfo, baseClasses = {});
116
+ }
117
+ else {
118
+ this._imodelBaseClassesByClass.set(imodelInfo, (baseClasses = {}));
119
+ }
109
120
  const missingClasses = new Set();
110
121
  neededClasses.forEach((className) => {
111
- if (!baseClasses.hasOwnProperty(className))
122
+ if (!baseClasses.hasOwnProperty(className)) {
112
123
  missingClasses.add(className);
124
+ }
113
125
  });
114
- if (missingClasses.size === 0)
126
+ if (missingClasses.size === 0) {
115
127
  return baseClasses;
116
- const query = `
117
- SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS "ClassFullName", (baseSchema.Name || ':' || baseClass.Name) AS "BaseClassFullName"
118
- FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels
119
- INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId
120
- INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id
121
- INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId
122
- INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id
128
+ }
129
+ const query = `
130
+ SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS "ClassFullName", (baseSchema.Name || ':' || baseClass.Name) AS "BaseClassFullName"
131
+ FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels
132
+ INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId
133
+ INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id
134
+ INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId
135
+ INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id
123
136
  WHERE (derivedSchema.Name || ':' || derivedClass.Name) IN (${[...missingClasses].map((className) => `'${className}'`).join(",")})`;
124
137
  const reader = imodel.createQueryReader(query, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames });
125
138
  while (await reader.step()) {
126
139
  const row = reader.current.toRow();
127
- if (!(row.classFullName in baseClasses))
140
+ if (!(row.classFullName in baseClasses)) {
128
141
  baseClasses[row.classFullName] = [];
142
+ }
129
143
  baseClasses[row.classFullName].push(row.baseClassFullName);
130
144
  }
131
145
  return baseClasses;
@@ -135,27 +149,67 @@ class FavoritePropertiesManager {
135
149
  this._imodelProperties = new Map();
136
150
  this._propertiesOrder = new Map();
137
151
  this._imodelBaseClassesByClass = new Map();
152
+ this._imodelInitializationPromises = new Map();
138
153
  }
139
154
  dispose() {
140
155
  // istanbul ignore else
141
- if (isIDisposable(this._storage))
156
+ if (isIDisposable(this._storage)) {
142
157
  this._storage.dispose();
158
+ }
143
159
  }
160
+ isInitialized(imodel) {
161
+ const iTwinId = imodel.iTwinId;
162
+ const imodelId = imodel.iModelId;
163
+ return this._imodelProperties.has(getiModelInfo(iTwinId, imodelId));
164
+ }
165
+ /**
166
+ * Checks if [[FavoritePropertiesManager.initializeConnection]] has been called for a given imodel.
167
+ * Can be removed when [[FavoritePropertiesManager.has]] and [[FavoritePropertiesManager.sortFields]] are removed.
168
+ */
144
169
  validateInitialization(imodel) {
145
170
  const iTwinId = imodel.iTwinId;
146
171
  const imodelId = imodel.iModelId;
147
- if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId)))
172
+ if (!this.isInitialized(imodel)) {
148
173
  throw Error(`Favorite properties are not initialized for iModel: '${imodelId}', in iTwin: '${iTwinId}'. Call initializeConnection() with an IModelConnection to initialize.`);
174
+ }
175
+ }
176
+ /**
177
+ * Calls [[FavoritePropertiesManager.initializeConnection]] and caches the promise which should be awaited by calling [[FavoritePropertiesManager.ensureInitialized]].
178
+ * @internal
179
+ */
180
+ startConnectionInitialization(imodel) {
181
+ if (!this.isInitialized(imodel) && !this._imodelInitializationPromises.has(imodel)) {
182
+ // eslint-disable-next-line deprecation/deprecation
183
+ this._imodelInitializationPromises.set(imodel, this.initializeConnection(imodel));
184
+ }
185
+ }
186
+ /**
187
+ * Performs the initialization process or finishes the one that was started by [[FavoritePropertiesManager.startConnectionInitialization]].
188
+ * @internal
189
+ */
190
+ async ensureInitialized(imodel) {
191
+ if (this.isInitialized(imodel)) {
192
+ return;
193
+ }
194
+ let promise = this._imodelInitializationPromises.get(imodel);
195
+ if (!promise) {
196
+ // eslint-disable-next-line deprecation/deprecation
197
+ promise = this.initializeConnection(imodel);
198
+ // Put the promise in the map to avoid possible multiple initializations from different promises.
199
+ this._imodelInitializationPromises.set(imodel, promise);
200
+ }
201
+ await promise;
202
+ // Remove this promise from the map, because the next time this method is called, `this.isInitialized` should return true.
203
+ this._imodelInitializationPromises.delete(imodel);
149
204
  }
150
205
  /**
151
206
  * Adds favorite properties into a certain scope.
152
207
  * @param field Field that contains properties. If field contains multiple properties, all of them will be favorited.
153
208
  * @param imodel IModelConnection.
154
209
  * @param scope FavoritePropertiesScope to put the favorite properties into.
155
- * @note `initializeConnection` must be called with the `imodel` before calling this function.
156
210
  */
157
211
  async add(field, imodel, scope) {
158
- this.validateInitialization(imodel);
212
+ await this.ensureInitialized(imodel);
159
213
  const iTwinId = imodel.iTwinId;
160
214
  const imodelId = imodel.iModelId;
161
215
  let favoriteProperties;
@@ -191,10 +245,9 @@ class FavoritePropertiesManager {
191
245
  * @param field Field that contains properties. If field contains multiple properties, all of them will be un-favorited.
192
246
  * @param imodel IModelConnection.
193
247
  * @param scope FavoritePropertiesScope to remove the favorite properties from. It also removes from more general scopes.
194
- * @note `initializeConnection` must be called with the `imodel` before calling this function.
195
248
  */
196
249
  async remove(field, imodel, scope) {
197
- this.validateInitialization(imodel);
250
+ await this.ensureInitialized(imodel);
198
251
  const iTwinId = imodel.iTwinId;
199
252
  const imodelId = imodel.iModelId;
200
253
  const fieldInfos = getFieldInfos(field);
@@ -225,8 +278,9 @@ class FavoritePropertiesManager {
225
278
  favoritesChanged = true;
226
279
  }
227
280
  }
228
- if (!favoritesChanged)
281
+ if (!favoritesChanged) {
229
282
  return;
283
+ }
230
284
  const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId));
231
285
  removeOrderInfos(propertiesOrder, createFieldOrderInfos(field));
232
286
  saves.push(this._storage.savePropertiesOrder(propertiesOrder, iTwinId, imodelId));
@@ -237,10 +291,9 @@ class FavoritePropertiesManager {
237
291
  * Removes all favorite properties from a certain scope.
238
292
  * @param imodel IModelConnection.
239
293
  * @param scope FavoritePropertiesScope to remove the favorite properties from.
240
- * @note `initializeConnection` must be called with the `imodel` before calling this function.
241
294
  */
242
295
  async clear(imodel, scope) {
243
- this.validateInitialization(imodel);
296
+ await this.ensureInitialized(imodel);
244
297
  const iTwinId = imodel.iTwinId;
245
298
  const imodelId = imodel.iModelId;
246
299
  let favoriteProperties;
@@ -258,8 +311,9 @@ class FavoritePropertiesManager {
258
311
  favoriteProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId));
259
312
  saveProperties = async () => this._storage.saveProperties(new Set(), iTwinId, imodelId);
260
313
  }
261
- if (favoriteProperties.size === 0)
314
+ if (favoriteProperties.size === 0) {
262
315
  return;
316
+ }
263
317
  favoriteProperties.clear();
264
318
  const saves = [];
265
319
  saves.push(saveProperties());
@@ -273,21 +327,45 @@ class FavoritePropertiesManager {
273
327
  * @param imodel IModelConnection.
274
328
  * @param scope FavoritePropertiesScope to check for favorite properties. It also checks the more general scopes.
275
329
  * @note `initializeConnection` must be called with the `imodel` before calling this function.
330
+ * @deprecated in 4.5. Use [[FavoritePropertiesManager.hasAsync]] instead. This method is not async, therefore it requires early initialization by calling [[FavoritePropertiesManager.initializeConnection]].
276
331
  */
277
332
  has(field, imodel, scope) {
278
333
  this.validateInitialization(imodel);
279
334
  const iTwinId = imodel.iTwinId;
280
335
  const imodelId = imodel.iModelId;
281
336
  const fieldInfos = getFieldInfos(field);
282
- return setHasAny(this._globalProperties, fieldInfos) ||
337
+ return (setHasAny(this._globalProperties, fieldInfos) ||
283
338
  (scope !== FavoritePropertiesScope.Global && setHasAny(this._iTwinProperties.get(iTwinId), fieldInfos)) ||
284
- (scope === FavoritePropertiesScope.IModel && setHasAny(this._imodelProperties.get(getiModelInfo(iTwinId, imodelId)), fieldInfos));
339
+ (scope === FavoritePropertiesScope.IModel && setHasAny(this._imodelProperties.get(getiModelInfo(iTwinId, imodelId)), fieldInfos)));
340
+ }
341
+ /**
342
+ * Check if field contains at least one favorite property.
343
+ * @param field Field that contains properties.
344
+ * @param imodel IModelConnection.
345
+ * @param scope FavoritePropertiesScope to check for favorite properties. It also checks the more general scopes.
346
+ */
347
+ async hasAsync(field, imodel, scope) {
348
+ await this.ensureInitialized(imodel);
349
+ // eslint-disable-next-line deprecation/deprecation
350
+ return this.has(field, imodel, scope);
351
+ }
352
+ /**
353
+ * Sorts an array of fields with respect to favorite property order.
354
+ * Non-favorited fields get sorted by their default priority and always have lower priority than favorited fields.
355
+ * @param imodel IModelConnection.
356
+ * @param fields Array of Field's that needs to be sorted.
357
+ */
358
+ async sortFieldsAsync(imodel, fields) {
359
+ await this.ensureInitialized(imodel);
360
+ // eslint-disable-next-line deprecation/deprecation
361
+ return this.sortFields(imodel, fields);
285
362
  }
286
363
  getFieldPriority(field, iTwinId, imodelId) {
287
364
  const orderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId));
288
365
  const fieldOrderInfos = getFieldOrderInfos(field, orderInfos);
289
- if (fieldOrderInfos.length === 0)
366
+ if (fieldOrderInfos.length === 0) {
290
367
  return -1;
368
+ }
291
369
  const mostRecent = getMostRecentOrderInfo(fieldOrderInfos);
292
370
  return mostRecent.priority;
293
371
  }
@@ -296,7 +374,6 @@ class FavoritePropertiesManager {
296
374
  * @param field Field that priority is being changed.
297
375
  * @param afterField Field that goes before the moved field. If undefined the moving field is changed to the highest priority (to the top).
298
376
  * @param visibleFields Array of fields to move the field in.
299
- * @note `initializeConnection` must be called with the `imodel` before calling this function.
300
377
  */
301
378
  async changeFieldPriority(imodel, field, afterField, visibleFields) {
302
379
  /**
@@ -311,23 +388,26 @@ class FavoritePropertiesManager {
311
388
  * 4. Irrelevant orderInfos's get moved after `orderInfo` (depends on the direction)
312
389
  * 5. All `field` orderInfo's get moved after `afterOrderInfo`
313
390
  */
314
- this.validateInitialization(imodel);
391
+ await this.ensureInitialized(imodel);
315
392
  const iTwinId = imodel.iTwinId;
316
393
  const imodelId = imodel.iModelId;
317
- if (field === afterField)
394
+ if (field === afterField) {
318
395
  throw Error("`field` can not be the same as `afterField`.");
396
+ }
319
397
  const allOrderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId));
320
398
  const findFieldOrderInfoData = (f) => {
321
- if (!visibleFields.includes(f))
399
+ if (!visibleFields.includes(f)) {
322
400
  throw Error("Field is not contained in visible fields.");
401
+ }
323
402
  const infos = getFieldOrderInfos(f, allOrderInfos);
324
- if (infos.length === 0)
403
+ if (infos.length === 0) {
325
404
  throw Error("Field has no property order information.");
405
+ }
326
406
  const info = getMostRecentOrderInfo(infos);
327
407
  const index = allOrderInfos.indexOf(info);
328
408
  return { infos, mostRecent: { info, index } };
329
409
  };
330
- const { infos: movingOrderInfos, mostRecent: { index: orderInfoIndex } } = findFieldOrderInfoData(field);
410
+ const { infos: movingOrderInfos, mostRecent: { index: orderInfoIndex }, } = findFieldOrderInfoData(field);
331
411
  let afterOrderInfo;
332
412
  let afterOrderInfoIndex;
333
413
  if (afterField === undefined) {
@@ -335,7 +415,9 @@ class FavoritePropertiesManager {
335
415
  afterOrderInfoIndex = -1;
336
416
  }
337
417
  else {
338
- ({ mostRecent: { info: afterOrderInfo, index: afterOrderInfoIndex } } = findFieldOrderInfoData(afterField));
418
+ ({
419
+ mostRecent: { info: afterOrderInfo, index: afterOrderInfoIndex },
420
+ } = findFieldOrderInfoData(afterField));
339
421
  }
340
422
  let direction; // where to go from `afterOrderInfo` to `orderInfo`
341
423
  let startIndex;
@@ -348,8 +430,9 @@ class FavoritePropertiesManager {
348
430
  startIndex = afterOrderInfoIndex + 1;
349
431
  }
350
432
  const neededClassNames = allOrderInfos.reduce((classNames, oi) => {
351
- if (oi.parentClassName)
433
+ if (oi.parentClassName) {
352
434
  classNames.add(oi.parentClassName);
435
+ }
353
436
  return classNames;
354
437
  }, new Set());
355
438
  const baseClassesByClass = await this._getBaseClassesByClass(imodel, neededClassNames);
@@ -359,20 +442,24 @@ class FavoritePropertiesManager {
359
442
  for (let i = startIndex; i !== orderInfoIndex; i += direction) {
360
443
  const currOrderInfo = allOrderInfos[i];
361
444
  // primitive properties are always relevant, because we can't determine their relevance based on the class hierarchy
362
- if (currOrderInfo.parentClassName === undefined)
445
+ if (currOrderInfo.parentClassName === undefined) {
363
446
  continue;
447
+ }
364
448
  const visible = visibleOrderInfos.includes(currOrderInfo);
365
449
  if (visible) {
366
450
  relevantClasses.add(currOrderInfo.parentClassName);
367
451
  continue;
368
452
  }
369
453
  const hasBaseClasses = baseClassesByClass[currOrderInfo.parentClassName].some((classId) => relevantClasses.has(classId));
370
- if (hasBaseClasses)
454
+ if (hasBaseClasses) {
371
455
  continue;
372
- if (direction === Direction.Down)
456
+ }
457
+ if (direction === Direction.Down) {
373
458
  irrelevantOrderInfos.push(currOrderInfo);
374
- else
459
+ }
460
+ else {
375
461
  irrelevantOrderInfos.unshift(currOrderInfo);
462
+ }
376
463
  }
377
464
  // remove irrelevantOrderInfo's to add them after the `orderInfo`
378
465
  irrelevantOrderInfos.forEach((foi) => {
@@ -384,13 +471,13 @@ class FavoritePropertiesManager {
384
471
  const index = allOrderInfos.findIndex((oi) => oi.parentClassName === foi.parentClassName && oi.name === foi.name);
385
472
  allOrderInfos.splice(index, 1);
386
473
  });
387
- movingOrderInfos.forEach((oi) => oi.orderedTimestamp = new Date());
474
+ movingOrderInfos.forEach((oi) => (oi.orderedTimestamp = new Date()));
388
475
  afterOrderInfoIndex = afterOrderInfo === undefined ? -1 : allOrderInfos.indexOf(afterOrderInfo);
389
476
  allOrderInfos.splice(afterOrderInfoIndex + 1, 0, ...movingOrderInfos);
390
477
  allOrderInfos.splice(afterOrderInfoIndex + 1 + (direction === Direction.Up ? movingOrderInfos.length : 0), 0, ...irrelevantOrderInfos);
391
478
  // reassign priority numbers
392
479
  let priority = allOrderInfos.length;
393
- allOrderInfos.forEach((oi) => oi.priority = priority--);
480
+ allOrderInfos.forEach((oi) => (oi.priority = priority--));
394
481
  await this._storage.savePropertiesOrder(allOrderInfos, iTwinId, imodelId);
395
482
  this.onFavoritesChanged.raiseEvent();
396
483
  }
@@ -426,36 +513,45 @@ const getNestingPrefix = (field) => {
426
513
  });
427
514
  curr = curr.parent;
428
515
  }
429
- if (path.length === 0)
516
+ if (path.length === 0) {
430
517
  return "";
518
+ }
431
519
  path.reverse();
432
520
  return `${path.join("-")}-`;
433
521
  };
434
522
  const getPropertyClassName = (propertyName) => {
435
523
  const propertyNameStart = propertyName.split("-")[0];
436
524
  const parts = propertyNameStart.split(":").length;
437
- if (parts === 1) // primitive
525
+ if (parts === 1) {
526
+ // primitive
438
527
  return undefined;
439
- if (parts === 2) // nested property OR nested property parent class OR regular property parent class
528
+ }
529
+ if (parts === 2) {
530
+ // nested property OR nested property parent class OR regular property parent class
440
531
  return propertyNameStart;
532
+ }
441
533
  // regular property without parent class
442
534
  return propertyNameStart.substring(0, propertyName.lastIndexOf(":"));
443
535
  };
444
536
  /** @internal */
445
537
  export const getFieldInfos = (field) => {
446
538
  const fieldInfos = new Set();
447
- if (field.isPropertiesField())
539
+ if (field.isPropertiesField()) {
448
540
  getPropertiesFieldPropertyNames(field).forEach((info) => fieldInfos.add(info));
449
- else if (field.isNestedContentField())
541
+ }
542
+ else if (field.isNestedContentField()) {
450
543
  fieldInfos.add(getNestedContentFieldPropertyName(field));
451
- else
544
+ }
545
+ else {
452
546
  fieldInfos.add(`${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${field.name}`);
547
+ }
453
548
  return fieldInfos;
454
549
  };
455
550
  const setHasAny = (set, lookup) => {
456
551
  for (const key of lookup) {
457
- if (set.has(key))
552
+ if (set.has(key)) {
458
553
  return true;
554
+ }
459
555
  }
460
556
  return false;
461
557
  };
@@ -468,26 +564,29 @@ const addOrderInfos = (dest, source) => {
468
564
  }
469
565
  });
470
566
  let priority = dest.length;
471
- dest.forEach((info) => info.priority = priority--);
567
+ dest.forEach((info) => (info.priority = priority--));
472
568
  };
473
569
  const removeOrderInfos = (container, toRemove) => {
474
570
  toRemove.forEach((roi) => {
475
571
  const index = container.findIndex((oi) => oi.name === roi.name);
476
572
  /* istanbul ignore else */
477
- if (index >= 0)
573
+ if (index >= 0) {
478
574
  container.splice(index, 1);
575
+ }
479
576
  });
480
577
  };
481
578
  /** @internal */
482
579
  export const createFieldOrderInfos = (field) => {
483
580
  if (field.isNestedContentField()) {
484
581
  const propertyName = getNestedContentFieldPropertyName(field);
485
- return [{
582
+ return [
583
+ {
486
584
  parentClassName: getPropertyClassName(propertyName),
487
585
  name: propertyName,
488
586
  priority: 0,
489
587
  orderedTimestamp: new Date(),
490
- }];
588
+ },
589
+ ];
491
590
  }
492
591
  if (field.isPropertiesField()) {
493
592
  return getPropertiesFieldPropertyNames(field).map((propertyName) => ({
@@ -497,27 +596,33 @@ export const createFieldOrderInfos = (field) => {
497
596
  orderedTimestamp: new Date(),
498
597
  }));
499
598
  }
500
- return [{
599
+ return [
600
+ {
501
601
  parentClassName: undefined,
502
602
  name: field.name,
503
603
  priority: 0,
504
604
  orderedTimestamp: new Date(),
505
- }];
605
+ },
606
+ ];
506
607
  };
507
608
  const getFieldOrderInfos = (field, orderInfos) => {
508
609
  const fieldOrderInfos = [];
509
610
  const tryAddOrderInfo = (name) => {
510
611
  const fieldOrderInfo = orderInfos.find((oi) => oi.name === name);
511
- if (fieldOrderInfo !== undefined)
612
+ if (fieldOrderInfo !== undefined) {
512
613
  fieldOrderInfos.push(fieldOrderInfo);
614
+ }
513
615
  };
514
- if (field.isPropertiesField())
616
+ if (field.isPropertiesField()) {
515
617
  getPropertiesFieldPropertyNames(field).forEach(tryAddOrderInfo);
516
- else if (field.isNestedContentField())
618
+ }
619
+ else if (field.isNestedContentField()) {
517
620
  tryAddOrderInfo(getNestedContentFieldPropertyName(field));
518
- else
621
+ }
622
+ else {
519
623
  tryAddOrderInfo(field.name);
624
+ }
520
625
  return fieldOrderInfos;
521
626
  };
522
- const getMostRecentOrderInfo = (orderInfos) => orderInfos.reduce((recent, curr) => (recent && recent.orderedTimestamp >= curr.orderedTimestamp) ? recent : curr);
627
+ const getMostRecentOrderInfo = (orderInfos) => orderInfos.reduce((recent, curr) => (recent && recent.orderedTimestamp >= curr.orderedTimestamp ? recent : curr));
523
628
  //# sourceMappingURL=FavoritePropertiesManager.js.map