@itwin/presentation-frontend 4.5.0-dev.0 → 4.5.0-dev.10
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.
- package/CHANGELOG.md +10 -1
- package/README.md +1 -1
- package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js +10 -6
- package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
- package/lib/cjs/presentation-frontend/Diagnostics.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/Diagnostics.js +18 -13
- package/lib/cjs/presentation-frontend/Diagnostics.js.map +1 -1
- package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js +3 -3
- package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
- package/lib/cjs/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/IpcRequestsHandler.js +3 -3
- package/lib/cjs/presentation-frontend/IpcRequestsHandler.js.map +1 -1
- package/lib/cjs/presentation-frontend/LocalizationHelper.js +3 -3
- package/lib/cjs/presentation-frontend/LocalizationHelper.js.map +1 -1
- package/lib/cjs/presentation-frontend/Presentation.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/Presentation.js +24 -14
- package/lib/cjs/presentation-frontend/Presentation.js.map +1 -1
- package/lib/cjs/presentation-frontend/PresentationManager.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/PresentationManager.js +57 -30
- package/lib/cjs/presentation-frontend/PresentationManager.js.map +1 -1
- package/lib/cjs/presentation-frontend/RulesetManager.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/RulesetManager.js +11 -7
- package/lib/cjs/presentation-frontend/RulesetManager.js.map +1 -1
- package/lib/cjs/presentation-frontend/RulesetVariablesManager.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/RulesetVariablesManager.js +53 -31
- package/lib/cjs/presentation-frontend/RulesetVariablesManager.js.map +1 -1
- package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +111 -66
- package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
- package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +54 -25
- package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/HiliteRules.json +172 -172
- package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js +16 -10
- package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js +3 -3
- package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js +3 -3
- package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionHandler.js +15 -9
- package/lib/cjs/presentation-frontend/selection/SelectionHandler.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionHelper.js +7 -5
- package/lib/cjs/presentation-frontend/selection/SelectionHelper.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionManager.js +31 -16
- package/lib/cjs/presentation-frontend/selection/SelectionManager.js.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
- package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js +25 -14
- package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
- package/lib/cjs/presentation-frontend.js +3 -3
- package/lib/cjs/presentation-frontend.js.map +1 -1
- package/lib/esm/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js +10 -6
- package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
- package/lib/esm/presentation-frontend/Diagnostics.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/Diagnostics.js +18 -13
- package/lib/esm/presentation-frontend/Diagnostics.js.map +1 -1
- package/lib/esm/presentation-frontend/FrontendLoggerCategory.js +3 -3
- package/lib/esm/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
- package/lib/esm/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/IpcRequestsHandler.js +3 -3
- package/lib/esm/presentation-frontend/IpcRequestsHandler.js.map +1 -1
- package/lib/esm/presentation-frontend/LocalizationHelper.js +3 -3
- package/lib/esm/presentation-frontend/LocalizationHelper.js.map +1 -1
- package/lib/esm/presentation-frontend/Presentation.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/Presentation.js +24 -14
- package/lib/esm/presentation-frontend/Presentation.js.map +1 -1
- package/lib/esm/presentation-frontend/PresentationManager.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/PresentationManager.js +57 -30
- package/lib/esm/presentation-frontend/PresentationManager.js.map +1 -1
- package/lib/esm/presentation-frontend/RulesetManager.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/RulesetManager.js +11 -7
- package/lib/esm/presentation-frontend/RulesetManager.js.map +1 -1
- package/lib/esm/presentation-frontend/RulesetVariablesManager.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/RulesetVariablesManager.js +53 -31
- package/lib/esm/presentation-frontend/RulesetVariablesManager.js.map +1 -1
- package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +111 -66
- package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
- package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +54 -25
- package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/HiliteRules.json +172 -172
- package/lib/esm/presentation-frontend/selection/HiliteSetProvider.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js +17 -11
- package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/ISelectionProvider.js +3 -3
- package/lib/esm/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js +3 -3
- package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionHandler.js +15 -9
- package/lib/esm/presentation-frontend/selection/SelectionHandler.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionHelper.js +7 -5
- package/lib/esm/presentation-frontend/selection/SelectionHelper.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionManager.js +31 -16
- package/lib/esm/presentation-frontend/selection/SelectionManager.js.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
- package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js +25 -14
- package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
- package/lib/esm/presentation-frontend.js +3 -3
- package/lib/esm/presentation-frontend.js.map +1 -1
- package/package.json +19 -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
|
*/
|
|
@@ -33,17 +33,18 @@ class FavoritePropertiesManager {
|
|
|
33
33
|
this.initializeConnection = async (imodel) => {
|
|
34
34
|
const imodelId = imodel.iModelId;
|
|
35
35
|
const iTwinId = imodel.iTwinId;
|
|
36
|
-
if (this._globalProperties === undefined)
|
|
37
|
-
this._globalProperties = await this._storage.loadProperties() || new Set();
|
|
36
|
+
if (this._globalProperties === undefined) {
|
|
37
|
+
this._globalProperties = (await this._storage.loadProperties()) || new Set();
|
|
38
|
+
}
|
|
38
39
|
if (!this._iTwinProperties.has(iTwinId)) {
|
|
39
|
-
const iTwinProperties = await this._storage.loadProperties(iTwinId) || new Set();
|
|
40
|
+
const iTwinProperties = (await this._storage.loadProperties(iTwinId)) || new Set();
|
|
40
41
|
this._iTwinProperties.set(iTwinId, iTwinProperties);
|
|
41
42
|
}
|
|
42
43
|
if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId))) {
|
|
43
|
-
const imodelProperties = await this._storage.loadProperties(iTwinId, imodelId) || new Set();
|
|
44
|
+
const imodelProperties = (await this._storage.loadProperties(iTwinId, imodelId)) || new Set();
|
|
44
45
|
this._imodelProperties.set(getiModelInfo(iTwinId, imodelId), imodelProperties);
|
|
45
46
|
}
|
|
46
|
-
const propertiesOrder = await this._storage.loadPropertiesOrder(iTwinId, imodelId) || [];
|
|
47
|
+
const propertiesOrder = (await this._storage.loadPropertiesOrder(iTwinId, imodelId)) || [];
|
|
47
48
|
this._propertiesOrder.set(getiModelInfo(iTwinId, imodelId), propertiesOrder);
|
|
48
49
|
await this._adjustPropertyOrderInfos(iTwinId, imodelId);
|
|
49
50
|
};
|
|
@@ -59,10 +60,12 @@ class FavoritePropertiesManager {
|
|
|
59
60
|
// favorite property infos that need to be added to the propertiesOrder array
|
|
60
61
|
const infosToAdd = new Set([...globalProperties, ...iTwinProperties, ...imodelProperties]);
|
|
61
62
|
for (let i = propertiesOrder.length - 1; i >= 0; i--) {
|
|
62
|
-
if (infosToAdd.has(propertiesOrder[i].name))
|
|
63
|
+
if (infosToAdd.has(propertiesOrder[i].name)) {
|
|
63
64
|
infosToAdd.delete(propertiesOrder[i].name);
|
|
64
|
-
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
65
67
|
propertiesOrder.splice(i, 1);
|
|
68
|
+
}
|
|
66
69
|
}
|
|
67
70
|
infosToAdd.forEach((info) => propertiesOrder.push({
|
|
68
71
|
name: info,
|
|
@@ -71,7 +74,7 @@ class FavoritePropertiesManager {
|
|
|
71
74
|
priority: 0,
|
|
72
75
|
}));
|
|
73
76
|
let priority = propertiesOrder.length;
|
|
74
|
-
propertiesOrder.forEach((oi) => oi.priority = priority--);
|
|
77
|
+
propertiesOrder.forEach((oi) => (oi.priority = priority--));
|
|
75
78
|
};
|
|
76
79
|
/**
|
|
77
80
|
* Sorts an array of fields with respect to favorite property order.
|
|
@@ -89,11 +92,15 @@ class FavoritePropertiesManager {
|
|
|
89
92
|
const sortFunction = (left, right) => {
|
|
90
93
|
const lp = fieldPriority.get(left);
|
|
91
94
|
const rp = fieldPriority.get(right);
|
|
92
|
-
return lp < rp
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
return lp < rp
|
|
96
|
+
? 1
|
|
97
|
+
: lp > rp
|
|
98
|
+
? -1
|
|
99
|
+
: left.priority < right.priority
|
|
100
|
+
? 1 // if favorite fields have equal priorities, sort by field priority
|
|
101
|
+
: left.priority > right.priority
|
|
102
|
+
? -1
|
|
103
|
+
: left.name.localeCompare(right.name);
|
|
97
104
|
};
|
|
98
105
|
return fields.sort(sortFunction);
|
|
99
106
|
};
|
|
@@ -102,30 +109,35 @@ class FavoritePropertiesManager {
|
|
|
102
109
|
const imodelId = imodel.iModelId;
|
|
103
110
|
const imodelInfo = getiModelInfo(iTwinId, imodelId);
|
|
104
111
|
let baseClasses;
|
|
105
|
-
if (this._imodelBaseClassesByClass.has(imodelInfo))
|
|
112
|
+
if (this._imodelBaseClassesByClass.has(imodelInfo)) {
|
|
106
113
|
baseClasses = this._imodelBaseClassesByClass.get(imodelInfo);
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
this._imodelBaseClassesByClass.set(imodelInfo, (baseClasses = {}));
|
|
117
|
+
}
|
|
109
118
|
const missingClasses = new Set();
|
|
110
119
|
neededClasses.forEach((className) => {
|
|
111
|
-
if (!baseClasses.hasOwnProperty(className))
|
|
120
|
+
if (!baseClasses.hasOwnProperty(className)) {
|
|
112
121
|
missingClasses.add(className);
|
|
122
|
+
}
|
|
113
123
|
});
|
|
114
|
-
if (missingClasses.size === 0)
|
|
124
|
+
if (missingClasses.size === 0) {
|
|
115
125
|
return baseClasses;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
INNER JOIN ECDbMeta.
|
|
121
|
-
INNER JOIN ECDbMeta.
|
|
122
|
-
INNER JOIN ECDbMeta.
|
|
126
|
+
}
|
|
127
|
+
const query = `
|
|
128
|
+
SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS "ClassFullName", (baseSchema.Name || ':' || baseClass.Name) AS "BaseClassFullName"
|
|
129
|
+
FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels
|
|
130
|
+
INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId
|
|
131
|
+
INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id
|
|
132
|
+
INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId
|
|
133
|
+
INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id
|
|
123
134
|
WHERE (derivedSchema.Name || ':' || derivedClass.Name) IN (${[...missingClasses].map((className) => `'${className}'`).join(",")})`;
|
|
124
135
|
const reader = imodel.createQueryReader(query, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames });
|
|
125
136
|
while (await reader.step()) {
|
|
126
137
|
const row = reader.current.toRow();
|
|
127
|
-
if (!(row.classFullName in baseClasses))
|
|
138
|
+
if (!(row.classFullName in baseClasses)) {
|
|
128
139
|
baseClasses[row.classFullName] = [];
|
|
140
|
+
}
|
|
129
141
|
baseClasses[row.classFullName].push(row.baseClassFullName);
|
|
130
142
|
}
|
|
131
143
|
return baseClasses;
|
|
@@ -138,14 +150,16 @@ class FavoritePropertiesManager {
|
|
|
138
150
|
}
|
|
139
151
|
dispose() {
|
|
140
152
|
// istanbul ignore else
|
|
141
|
-
if (isIDisposable(this._storage))
|
|
153
|
+
if (isIDisposable(this._storage)) {
|
|
142
154
|
this._storage.dispose();
|
|
155
|
+
}
|
|
143
156
|
}
|
|
144
157
|
validateInitialization(imodel) {
|
|
145
158
|
const iTwinId = imodel.iTwinId;
|
|
146
159
|
const imodelId = imodel.iModelId;
|
|
147
|
-
if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId)))
|
|
160
|
+
if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId))) {
|
|
148
161
|
throw Error(`Favorite properties are not initialized for iModel: '${imodelId}', in iTwin: '${iTwinId}'. Call initializeConnection() with an IModelConnection to initialize.`);
|
|
162
|
+
}
|
|
149
163
|
}
|
|
150
164
|
/**
|
|
151
165
|
* Adds favorite properties into a certain scope.
|
|
@@ -225,8 +239,9 @@ class FavoritePropertiesManager {
|
|
|
225
239
|
favoritesChanged = true;
|
|
226
240
|
}
|
|
227
241
|
}
|
|
228
|
-
if (!favoritesChanged)
|
|
242
|
+
if (!favoritesChanged) {
|
|
229
243
|
return;
|
|
244
|
+
}
|
|
230
245
|
const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId));
|
|
231
246
|
removeOrderInfos(propertiesOrder, createFieldOrderInfos(field));
|
|
232
247
|
saves.push(this._storage.savePropertiesOrder(propertiesOrder, iTwinId, imodelId));
|
|
@@ -258,8 +273,9 @@ class FavoritePropertiesManager {
|
|
|
258
273
|
favoriteProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId));
|
|
259
274
|
saveProperties = async () => this._storage.saveProperties(new Set(), iTwinId, imodelId);
|
|
260
275
|
}
|
|
261
|
-
if (favoriteProperties.size === 0)
|
|
276
|
+
if (favoriteProperties.size === 0) {
|
|
262
277
|
return;
|
|
278
|
+
}
|
|
263
279
|
favoriteProperties.clear();
|
|
264
280
|
const saves = [];
|
|
265
281
|
saves.push(saveProperties());
|
|
@@ -279,15 +295,16 @@ class FavoritePropertiesManager {
|
|
|
279
295
|
const iTwinId = imodel.iTwinId;
|
|
280
296
|
const imodelId = imodel.iModelId;
|
|
281
297
|
const fieldInfos = getFieldInfos(field);
|
|
282
|
-
return setHasAny(this._globalProperties, fieldInfos) ||
|
|
298
|
+
return (setHasAny(this._globalProperties, fieldInfos) ||
|
|
283
299
|
(scope !== FavoritePropertiesScope.Global && setHasAny(this._iTwinProperties.get(iTwinId), fieldInfos)) ||
|
|
284
|
-
(scope === FavoritePropertiesScope.IModel && setHasAny(this._imodelProperties.get(getiModelInfo(iTwinId, imodelId)), fieldInfos));
|
|
300
|
+
(scope === FavoritePropertiesScope.IModel && setHasAny(this._imodelProperties.get(getiModelInfo(iTwinId, imodelId)), fieldInfos)));
|
|
285
301
|
}
|
|
286
302
|
getFieldPriority(field, iTwinId, imodelId) {
|
|
287
303
|
const orderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId));
|
|
288
304
|
const fieldOrderInfos = getFieldOrderInfos(field, orderInfos);
|
|
289
|
-
if (fieldOrderInfos.length === 0)
|
|
305
|
+
if (fieldOrderInfos.length === 0) {
|
|
290
306
|
return -1;
|
|
307
|
+
}
|
|
291
308
|
const mostRecent = getMostRecentOrderInfo(fieldOrderInfos);
|
|
292
309
|
return mostRecent.priority;
|
|
293
310
|
}
|
|
@@ -314,20 +331,23 @@ class FavoritePropertiesManager {
|
|
|
314
331
|
this.validateInitialization(imodel);
|
|
315
332
|
const iTwinId = imodel.iTwinId;
|
|
316
333
|
const imodelId = imodel.iModelId;
|
|
317
|
-
if (field === afterField)
|
|
334
|
+
if (field === afterField) {
|
|
318
335
|
throw Error("`field` can not be the same as `afterField`.");
|
|
336
|
+
}
|
|
319
337
|
const allOrderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId));
|
|
320
338
|
const findFieldOrderInfoData = (f) => {
|
|
321
|
-
if (!visibleFields.includes(f))
|
|
339
|
+
if (!visibleFields.includes(f)) {
|
|
322
340
|
throw Error("Field is not contained in visible fields.");
|
|
341
|
+
}
|
|
323
342
|
const infos = getFieldOrderInfos(f, allOrderInfos);
|
|
324
|
-
if (infos.length === 0)
|
|
343
|
+
if (infos.length === 0) {
|
|
325
344
|
throw Error("Field has no property order information.");
|
|
345
|
+
}
|
|
326
346
|
const info = getMostRecentOrderInfo(infos);
|
|
327
347
|
const index = allOrderInfos.indexOf(info);
|
|
328
348
|
return { infos, mostRecent: { info, index } };
|
|
329
349
|
};
|
|
330
|
-
const { infos: movingOrderInfos, mostRecent: { index: orderInfoIndex } } = findFieldOrderInfoData(field);
|
|
350
|
+
const { infos: movingOrderInfos, mostRecent: { index: orderInfoIndex }, } = findFieldOrderInfoData(field);
|
|
331
351
|
let afterOrderInfo;
|
|
332
352
|
let afterOrderInfoIndex;
|
|
333
353
|
if (afterField === undefined) {
|
|
@@ -335,7 +355,9 @@ class FavoritePropertiesManager {
|
|
|
335
355
|
afterOrderInfoIndex = -1;
|
|
336
356
|
}
|
|
337
357
|
else {
|
|
338
|
-
({
|
|
358
|
+
({
|
|
359
|
+
mostRecent: { info: afterOrderInfo, index: afterOrderInfoIndex },
|
|
360
|
+
} = findFieldOrderInfoData(afterField));
|
|
339
361
|
}
|
|
340
362
|
let direction; // where to go from `afterOrderInfo` to `orderInfo`
|
|
341
363
|
let startIndex;
|
|
@@ -348,8 +370,9 @@ class FavoritePropertiesManager {
|
|
|
348
370
|
startIndex = afterOrderInfoIndex + 1;
|
|
349
371
|
}
|
|
350
372
|
const neededClassNames = allOrderInfos.reduce((classNames, oi) => {
|
|
351
|
-
if (oi.parentClassName)
|
|
373
|
+
if (oi.parentClassName) {
|
|
352
374
|
classNames.add(oi.parentClassName);
|
|
375
|
+
}
|
|
353
376
|
return classNames;
|
|
354
377
|
}, new Set());
|
|
355
378
|
const baseClassesByClass = await this._getBaseClassesByClass(imodel, neededClassNames);
|
|
@@ -359,20 +382,24 @@ class FavoritePropertiesManager {
|
|
|
359
382
|
for (let i = startIndex; i !== orderInfoIndex; i += direction) {
|
|
360
383
|
const currOrderInfo = allOrderInfos[i];
|
|
361
384
|
// primitive properties are always relevant, because we can't determine their relevance based on the class hierarchy
|
|
362
|
-
if (currOrderInfo.parentClassName === undefined)
|
|
385
|
+
if (currOrderInfo.parentClassName === undefined) {
|
|
363
386
|
continue;
|
|
387
|
+
}
|
|
364
388
|
const visible = visibleOrderInfos.includes(currOrderInfo);
|
|
365
389
|
if (visible) {
|
|
366
390
|
relevantClasses.add(currOrderInfo.parentClassName);
|
|
367
391
|
continue;
|
|
368
392
|
}
|
|
369
393
|
const hasBaseClasses = baseClassesByClass[currOrderInfo.parentClassName].some((classId) => relevantClasses.has(classId));
|
|
370
|
-
if (hasBaseClasses)
|
|
394
|
+
if (hasBaseClasses) {
|
|
371
395
|
continue;
|
|
372
|
-
|
|
396
|
+
}
|
|
397
|
+
if (direction === Direction.Down) {
|
|
373
398
|
irrelevantOrderInfos.push(currOrderInfo);
|
|
374
|
-
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
375
401
|
irrelevantOrderInfos.unshift(currOrderInfo);
|
|
402
|
+
}
|
|
376
403
|
}
|
|
377
404
|
// remove irrelevantOrderInfo's to add them after the `orderInfo`
|
|
378
405
|
irrelevantOrderInfos.forEach((foi) => {
|
|
@@ -384,13 +411,13 @@ class FavoritePropertiesManager {
|
|
|
384
411
|
const index = allOrderInfos.findIndex((oi) => oi.parentClassName === foi.parentClassName && oi.name === foi.name);
|
|
385
412
|
allOrderInfos.splice(index, 1);
|
|
386
413
|
});
|
|
387
|
-
movingOrderInfos.forEach((oi) => oi.orderedTimestamp = new Date());
|
|
414
|
+
movingOrderInfos.forEach((oi) => (oi.orderedTimestamp = new Date()));
|
|
388
415
|
afterOrderInfoIndex = afterOrderInfo === undefined ? -1 : allOrderInfos.indexOf(afterOrderInfo);
|
|
389
416
|
allOrderInfos.splice(afterOrderInfoIndex + 1, 0, ...movingOrderInfos);
|
|
390
417
|
allOrderInfos.splice(afterOrderInfoIndex + 1 + (direction === Direction.Up ? movingOrderInfos.length : 0), 0, ...irrelevantOrderInfos);
|
|
391
418
|
// reassign priority numbers
|
|
392
419
|
let priority = allOrderInfos.length;
|
|
393
|
-
allOrderInfos.forEach((oi) => oi.priority = priority--);
|
|
420
|
+
allOrderInfos.forEach((oi) => (oi.priority = priority--));
|
|
394
421
|
await this._storage.savePropertiesOrder(allOrderInfos, iTwinId, imodelId);
|
|
395
422
|
this.onFavoritesChanged.raiseEvent();
|
|
396
423
|
}
|
|
@@ -426,36 +453,45 @@ const getNestingPrefix = (field) => {
|
|
|
426
453
|
});
|
|
427
454
|
curr = curr.parent;
|
|
428
455
|
}
|
|
429
|
-
if (path.length === 0)
|
|
456
|
+
if (path.length === 0) {
|
|
430
457
|
return "";
|
|
458
|
+
}
|
|
431
459
|
path.reverse();
|
|
432
460
|
return `${path.join("-")}-`;
|
|
433
461
|
};
|
|
434
462
|
const getPropertyClassName = (propertyName) => {
|
|
435
463
|
const propertyNameStart = propertyName.split("-")[0];
|
|
436
464
|
const parts = propertyNameStart.split(":").length;
|
|
437
|
-
if (parts === 1)
|
|
465
|
+
if (parts === 1) {
|
|
466
|
+
// primitive
|
|
438
467
|
return undefined;
|
|
439
|
-
|
|
468
|
+
}
|
|
469
|
+
if (parts === 2) {
|
|
470
|
+
// nested property OR nested property parent class OR regular property parent class
|
|
440
471
|
return propertyNameStart;
|
|
472
|
+
}
|
|
441
473
|
// regular property without parent class
|
|
442
474
|
return propertyNameStart.substring(0, propertyName.lastIndexOf(":"));
|
|
443
475
|
};
|
|
444
476
|
/** @internal */
|
|
445
477
|
export const getFieldInfos = (field) => {
|
|
446
478
|
const fieldInfos = new Set();
|
|
447
|
-
if (field.isPropertiesField())
|
|
479
|
+
if (field.isPropertiesField()) {
|
|
448
480
|
getPropertiesFieldPropertyNames(field).forEach((info) => fieldInfos.add(info));
|
|
449
|
-
|
|
481
|
+
}
|
|
482
|
+
else if (field.isNestedContentField()) {
|
|
450
483
|
fieldInfos.add(getNestedContentFieldPropertyName(field));
|
|
451
|
-
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
452
486
|
fieldInfos.add(`${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${field.name}`);
|
|
487
|
+
}
|
|
453
488
|
return fieldInfos;
|
|
454
489
|
};
|
|
455
490
|
const setHasAny = (set, lookup) => {
|
|
456
491
|
for (const key of lookup) {
|
|
457
|
-
if (set.has(key))
|
|
492
|
+
if (set.has(key)) {
|
|
458
493
|
return true;
|
|
494
|
+
}
|
|
459
495
|
}
|
|
460
496
|
return false;
|
|
461
497
|
};
|
|
@@ -468,26 +504,29 @@ const addOrderInfos = (dest, source) => {
|
|
|
468
504
|
}
|
|
469
505
|
});
|
|
470
506
|
let priority = dest.length;
|
|
471
|
-
dest.forEach((info) => info.priority = priority--);
|
|
507
|
+
dest.forEach((info) => (info.priority = priority--));
|
|
472
508
|
};
|
|
473
509
|
const removeOrderInfos = (container, toRemove) => {
|
|
474
510
|
toRemove.forEach((roi) => {
|
|
475
511
|
const index = container.findIndex((oi) => oi.name === roi.name);
|
|
476
512
|
/* istanbul ignore else */
|
|
477
|
-
if (index >= 0)
|
|
513
|
+
if (index >= 0) {
|
|
478
514
|
container.splice(index, 1);
|
|
515
|
+
}
|
|
479
516
|
});
|
|
480
517
|
};
|
|
481
518
|
/** @internal */
|
|
482
519
|
export const createFieldOrderInfos = (field) => {
|
|
483
520
|
if (field.isNestedContentField()) {
|
|
484
521
|
const propertyName = getNestedContentFieldPropertyName(field);
|
|
485
|
-
return [
|
|
522
|
+
return [
|
|
523
|
+
{
|
|
486
524
|
parentClassName: getPropertyClassName(propertyName),
|
|
487
525
|
name: propertyName,
|
|
488
526
|
priority: 0,
|
|
489
527
|
orderedTimestamp: new Date(),
|
|
490
|
-
}
|
|
528
|
+
},
|
|
529
|
+
];
|
|
491
530
|
}
|
|
492
531
|
if (field.isPropertiesField()) {
|
|
493
532
|
return getPropertiesFieldPropertyNames(field).map((propertyName) => ({
|
|
@@ -497,27 +536,33 @@ export const createFieldOrderInfos = (field) => {
|
|
|
497
536
|
orderedTimestamp: new Date(),
|
|
498
537
|
}));
|
|
499
538
|
}
|
|
500
|
-
return [
|
|
539
|
+
return [
|
|
540
|
+
{
|
|
501
541
|
parentClassName: undefined,
|
|
502
542
|
name: field.name,
|
|
503
543
|
priority: 0,
|
|
504
544
|
orderedTimestamp: new Date(),
|
|
505
|
-
}
|
|
545
|
+
},
|
|
546
|
+
];
|
|
506
547
|
};
|
|
507
548
|
const getFieldOrderInfos = (field, orderInfos) => {
|
|
508
549
|
const fieldOrderInfos = [];
|
|
509
550
|
const tryAddOrderInfo = (name) => {
|
|
510
551
|
const fieldOrderInfo = orderInfos.find((oi) => oi.name === name);
|
|
511
|
-
if (fieldOrderInfo !== undefined)
|
|
552
|
+
if (fieldOrderInfo !== undefined) {
|
|
512
553
|
fieldOrderInfos.push(fieldOrderInfo);
|
|
554
|
+
}
|
|
513
555
|
};
|
|
514
|
-
if (field.isPropertiesField())
|
|
556
|
+
if (field.isPropertiesField()) {
|
|
515
557
|
getPropertiesFieldPropertyNames(field).forEach(tryAddOrderInfo);
|
|
516
|
-
|
|
558
|
+
}
|
|
559
|
+
else if (field.isNestedContentField()) {
|
|
517
560
|
tryAddOrderInfo(getNestedContentFieldPropertyName(field));
|
|
518
|
-
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
519
563
|
tryAddOrderInfo(field.name);
|
|
564
|
+
}
|
|
520
565
|
return fieldOrderInfos;
|
|
521
566
|
};
|
|
522
|
-
const getMostRecentOrderInfo = (orderInfos) => orderInfos.reduce((recent, curr) => (recent && recent.orderedTimestamp >= curr.orderedTimestamp
|
|
567
|
+
const getMostRecentOrderInfo = (orderInfos) => orderInfos.reduce((recent, curr) => (recent && recent.orderedTimestamp >= curr.orderedTimestamp ? recent : curr));
|
|
523
568
|
//# sourceMappingURL=FavoritePropertiesManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FavoritePropertiesManager.js","sourceRoot":"","sources":["../../../../src/presentation-frontend/favorite-properties/FavoritePropertiesManager.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*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Core\n */\n\nimport { BeEvent, IDisposable, isIDisposable } from \"@itwin/core-bentley\";\nimport { QueryRowFormat } from \"@itwin/core-common\";\nimport { IModelConnection } from \"@itwin/core-frontend\";\nimport { ClassId, Field, NestedContentField, PropertiesField } from \"@itwin/presentation-common\";\nimport { IFavoritePropertiesStorage } from \"./FavoritePropertiesStorage\";\n\n/**\n * Scopes that favorite properties can be stored in.\n * @public\n */\nexport enum FavoritePropertiesScope {\n Global,\n ITwin,\n IModel,\n}\n\n/**\n * Format:\n * Regular property - [{path from parent class}-]{schema name}:{class name}:{property name}.\n * Nested property - [{path from parent class}-]{content class schema name}:{content class name}.\n * Primitive property - {field name}.\n * @public\n */\nexport type PropertyFullName = string;\n\n/**\n * Holds the information of favorite properties ordering.\n * @public\n */\nexport interface FavoritePropertiesOrderInfo {\n parentClassName: string | undefined;\n name: PropertyFullName;\n priority: number;\n orderedTimestamp: Date;\n}\n\n/**\n * Properties for initializing [[FavoritePropertiesManager]]\n * @public\n */\nexport interface FavoritePropertiesManagerProps {\n /**\n * Implementation of a persistence layer for storing favorite properties and their order.\n * @public\n */\n storage: IFavoritePropertiesStorage;\n}\n\n/**\n * The favorite property manager which lets to store favorite properties\n * and check if field contains favorite properties.\n *\n * @public\n */\nexport class FavoritePropertiesManager implements IDisposable {\n /**\n * Used in tests to avoid collisions between multiple runs using the same storage\n * @internal\n */\n public static FAVORITES_IDENTIFIER_PREFIX = \"\";\n\n /** Event raised after favorite properties have changed. */\n public onFavoritesChanged = new BeEvent<() => void>();\n\n private _storage: IFavoritePropertiesStorage;\n private _globalProperties: Set<PropertyFullName> | undefined;\n private _iTwinProperties: Map<string, Set<PropertyFullName>>;\n private _imodelProperties: Map<string, Set<PropertyFullName>>;\n private _imodelBaseClassesByClass: Map<string, { [className: string]: string[] }>;\n\n /** Property order is saved only in iModel scope */\n private _propertiesOrder: Map<string, FavoritePropertiesOrderInfo[]>;\n\n public constructor(props: FavoritePropertiesManagerProps) {\n this._storage = props.storage;\n this._iTwinProperties = new Map<string, Set<PropertyFullName>>();\n this._imodelProperties = new Map<string, Set<PropertyFullName>>();\n this._propertiesOrder = new Map<string, FavoritePropertiesOrderInfo[]>();\n this._imodelBaseClassesByClass = new Map<string, { [className: string]: string[] }>();\n }\n\n public dispose() {\n // istanbul ignore else\n if (isIDisposable(this._storage))\n this._storage.dispose();\n }\n\n /**\n * Initialize favorite properties for the provided IModelConnection.\n */\n public initializeConnection = async (imodel: IModelConnection) => {\n const imodelId = imodel.iModelId!;\n const iTwinId = imodel.iTwinId!;\n\n if (this._globalProperties === undefined)\n this._globalProperties = await this._storage.loadProperties() || new Set<PropertyFullName>();\n\n if (!this._iTwinProperties.has(iTwinId)) {\n const iTwinProperties = await this._storage.loadProperties(iTwinId) || new Set<PropertyFullName>();\n this._iTwinProperties.set(iTwinId, iTwinProperties);\n }\n\n if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId))) {\n const imodelProperties = await this._storage.loadProperties(iTwinId, imodelId) || new Set<PropertyFullName>();\n this._imodelProperties.set(getiModelInfo(iTwinId, imodelId), imodelProperties);\n }\n const propertiesOrder = await this._storage.loadPropertiesOrder(iTwinId, imodelId) || [];\n this._propertiesOrder.set(getiModelInfo(iTwinId, imodelId), propertiesOrder);\n await this._adjustPropertyOrderInfos(iTwinId, imodelId);\n };\n\n /**\n * Function that removes order information of properties that are no longer\n * favorited and adds missing order information for favorited properties.\n */\n private _adjustPropertyOrderInfos = async (iTwinId: string, imodelId: string) => {\n const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\n\n const globalProperties = this._globalProperties!;\n const iTwinProperties = this._iTwinProperties.get(iTwinId)!;\n const imodelProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!;\n // favorite property infos that need to be added to the propertiesOrder array\n const infosToAdd = new Set<string>([...globalProperties, ...iTwinProperties, ...imodelProperties]);\n\n for (let i = propertiesOrder.length - 1; i >= 0; i--) {\n if (infosToAdd.has(propertiesOrder[i].name))\n infosToAdd.delete(propertiesOrder[i].name);\n else\n propertiesOrder.splice(i, 1);\n }\n\n infosToAdd.forEach((info) => propertiesOrder.push({\n name: info,\n parentClassName: getPropertyClassName(info),\n orderedTimestamp: new Date(),\n priority: 0,\n }));\n\n let priority = propertiesOrder.length;\n propertiesOrder.forEach((oi) => oi.priority = priority--);\n };\n\n private validateInitialization(imodel: IModelConnection) {\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId)))\n throw Error(`Favorite properties are not initialized for iModel: '${imodelId}', in iTwin: '${iTwinId}'. Call initializeConnection() with an IModelConnection to initialize.`);\n }\n\n /**\n * Adds favorite properties into a certain scope.\n * @param field Field that contains properties. If field contains multiple properties, all of them will be favorited.\n * @param imodel IModelConnection.\n * @param scope FavoritePropertiesScope to put the favorite properties into.\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\n */\n public async add(field: Field, imodel: IModelConnection, scope: FavoritePropertiesScope): Promise<void> {\n this.validateInitialization(imodel);\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n let favoriteProperties: Set<PropertyFullName>;\n let saveProperties: (properties: Set<PropertyFullName>) => Promise<void>;\n switch (scope) {\n case FavoritePropertiesScope.Global:\n favoriteProperties = this._globalProperties!;\n saveProperties = async (properties) => this._storage.saveProperties(properties);\n break;\n case FavoritePropertiesScope.ITwin:\n favoriteProperties = this._iTwinProperties.get(iTwinId)!;\n saveProperties = async (properties) => this._storage.saveProperties(properties, iTwinId);\n break;\n default:\n favoriteProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!;\n saveProperties = async (properties) => this._storage.saveProperties(properties, iTwinId, imodelId);\n }\n\n const countBefore = favoriteProperties.size;\n const fieldInfos = getFieldInfos(field);\n fieldInfos.forEach((info) => favoriteProperties.add(info));\n if (favoriteProperties.size !== countBefore) {\n const saves: Array<Promise<void>> = [];\n saves.push(saveProperties(favoriteProperties));\n\n const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\n addOrderInfos(propertiesOrder, createFieldOrderInfos(field));\n saves.push(this._storage.savePropertiesOrder(propertiesOrder, iTwinId, imodelId));\n\n await Promise.all(saves);\n this.onFavoritesChanged.raiseEvent();\n }\n }\n\n /**\n * Removes favorite properties from a scope specified and all the more general scopes.\n * @param field Field that contains properties. If field contains multiple properties, all of them will be un-favorited.\n * @param imodel IModelConnection.\n * @param scope FavoritePropertiesScope to remove the favorite properties from. It also removes from more general scopes.\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\n */\n public async remove(field: Field, imodel: IModelConnection, scope: FavoritePropertiesScope): Promise<void> {\n this.validateInitialization(imodel);\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n const fieldInfos = getFieldInfos(field);\n const workingScopes: Array<{ properties: Set<PropertyFullName>, save: (properties: Set<PropertyFullName>) => Promise<void> }> = [];\n workingScopes.push({\n properties: this._globalProperties!,\n save: async (properties) => this._storage.saveProperties(properties),\n });\n if (scope === FavoritePropertiesScope.ITwin || scope === FavoritePropertiesScope.IModel) {\n workingScopes.push({\n properties: this._iTwinProperties.get(iTwinId)!,\n save: async (properties) => this._storage.saveProperties(properties, iTwinId),\n });\n }\n if (scope === FavoritePropertiesScope.IModel) {\n workingScopes.push({\n properties: this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!,\n save: async (properties) => this._storage.saveProperties(properties, iTwinId, imodelId),\n });\n }\n\n const saves: Array<Promise<void>> = [];\n let favoritesChanged = false;\n for (const { properties, save } of workingScopes) {\n const countBefore = properties.size;\n fieldInfos.forEach((info) => properties.delete(info));\n if (properties.size !== countBefore) {\n saves.push(save(properties));\n favoritesChanged = true;\n }\n }\n if (!favoritesChanged)\n return;\n\n const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\n removeOrderInfos(propertiesOrder, createFieldOrderInfos(field));\n saves.push(this._storage.savePropertiesOrder(propertiesOrder, iTwinId, imodelId));\n\n await Promise.all(saves);\n this.onFavoritesChanged.raiseEvent();\n }\n\n /**\n * Removes all favorite properties from a certain scope.\n * @param imodel IModelConnection.\n * @param scope FavoritePropertiesScope to remove the favorite properties from.\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\n */\n public async clear(imodel: IModelConnection, scope: FavoritePropertiesScope): Promise<void> {\n this.validateInitialization(imodel);\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n let favoriteProperties: Set<PropertyFullName>;\n let saveProperties: () => Promise<void>;\n switch (scope) {\n case FavoritePropertiesScope.Global:\n favoriteProperties = this._globalProperties!;\n saveProperties = async () => this._storage.saveProperties(new Set<PropertyFullName>());\n break;\n case FavoritePropertiesScope.ITwin:\n favoriteProperties = this._iTwinProperties.get(iTwinId)!;\n saveProperties = async () => this._storage.saveProperties(new Set<PropertyFullName>(), iTwinId);\n break;\n default:\n favoriteProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!;\n saveProperties = async () => this._storage.saveProperties(new Set<PropertyFullName>(), iTwinId, imodelId);\n }\n\n if (favoriteProperties.size === 0)\n return;\n\n favoriteProperties.clear();\n const saves: Array<Promise<void>> = [];\n saves.push(saveProperties());\n saves.push(this._adjustPropertyOrderInfos(iTwinId, imodelId));\n await Promise.all(saves);\n this.onFavoritesChanged.raiseEvent();\n }\n\n /**\n * Check if field contains at least one favorite property.\n * @param field Field that contains properties.\n * @param imodel IModelConnection.\n * @param scope FavoritePropertiesScope to check for favorite properties. It also checks the more general scopes.\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\n */\n public has(field: Field, imodel: IModelConnection, scope: FavoritePropertiesScope): boolean {\n this.validateInitialization(imodel);\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n const fieldInfos = getFieldInfos(field);\n return setHasAny(this._globalProperties!, fieldInfos) ||\n (scope !== FavoritePropertiesScope.Global && setHasAny(this._iTwinProperties.get(iTwinId)!, fieldInfos)) ||\n (scope === FavoritePropertiesScope.IModel && setHasAny(this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!, fieldInfos));\n }\n\n /**\n * Sorts an array of fields with respect to favorite property order.\n * Non-favorited fields get sorted by their default priority and always have lower priority than favorited fields.\n * @param imodel IModelConnection.\n * @param fields Array of Field's that needs to be sorted.\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\n */\n public sortFields = (imodel: IModelConnection, fields: Field[]): Field[] => {\n this.validateInitialization(imodel);\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n const fieldPriority = new Map<Field, number>();\n fields.forEach((field) => fieldPriority.set(field, this.getFieldPriority(field, iTwinId, imodelId)));\n\n const sortFunction = (left: Field, right: Field): number => {\n const lp = fieldPriority.get(left)!;\n const rp = fieldPriority.get(right)!;\n return lp < rp ? 1 :\n lp > rp ? -1 :\n left.priority < right.priority ? 1 : // if favorite fields have equal priorities, sort by field priority\n left.priority > right.priority ? -1 :\n left.name.localeCompare(right.name);\n };\n\n return fields.sort(sortFunction);\n };\n\n private getFieldPriority(field: Field, iTwinId: string, imodelId: string): number {\n const orderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\n const fieldOrderInfos = getFieldOrderInfos(field, orderInfos);\n if (fieldOrderInfos.length === 0)\n return -1;\n const mostRecent = getMostRecentOrderInfo(fieldOrderInfos);\n return mostRecent.priority;\n }\n\n private _getBaseClassesByClass = async (imodel: IModelConnection, neededClasses: Set<string>): Promise<{ [className: string]: string[] }> => {\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n const imodelInfo = getiModelInfo(iTwinId, imodelId);\n let baseClasses: { [className: string]: string[] };\n if (this._imodelBaseClassesByClass.has(imodelInfo))\n baseClasses = this._imodelBaseClassesByClass.get(imodelInfo)!;\n else\n this._imodelBaseClassesByClass.set(imodelInfo, baseClasses = {});\n\n const missingClasses = new Set<string>();\n neededClasses.forEach((className) => {\n if (!baseClasses.hasOwnProperty(className))\n missingClasses.add(className);\n });\n if (missingClasses.size === 0)\n return baseClasses;\n\n const query = `\n SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS \"ClassFullName\", (baseSchema.Name || ':' || baseClass.Name) AS \"BaseClassFullName\"\n FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels\n INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId\n INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id\n INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId\n INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id\n WHERE (derivedSchema.Name || ':' || derivedClass.Name) IN (${[...missingClasses].map((className) => `'${className}'`).join(\",\")})`;\n const reader = imodel.createQueryReader(query, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames });\n while (await reader.step()) {\n const row = reader.current.toRow();\n if (!(row.classFullName in baseClasses))\n baseClasses[row.classFullName] = [];\n baseClasses[row.classFullName].push(row.baseClassFullName);\n }\n return baseClasses;\n };\n\n /** Changes field properties priorities to lower than another fields priority\n * @param imodel IModelConnection.\n * @param field Field that priority is being changed.\n * @param afterField Field that goes before the moved field. If undefined the moving field is changed to the highest priority (to the top).\n * @param visibleFields Array of fields to move the field in.\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\n */\n public async changeFieldPriority(imodel: IModelConnection, field: Field, afterField: Field | undefined, visibleFields: Field[]) {\n /**\n * How it works:\n * 1. Gets the orderInfo's for `field` (`orderInfo`) and `afterField` (`afterOrderInfo`) by selecting the most recent order informations for each field\n * 2. Iterates all orderInfo's that are in between `afterOrderInfo` and `orderInfo` when sorted by priority\n * 3. For each iterated orderInfo it checks if it is relevant:\n * 3.1. If orderInfo belongs to a primitive property, orderInfo is relevant\n * 3.2. If orderInfo's field is visible, orderInfo is relevant\n * 3.3. If orderInfo's class has a base class or itself in previously labeled relevant orderInfo's, orderInfo is relevant\n * 3.4. If 3.1 - 3.3 don't pass, orderInfo is irrelevant\n * 4. Irrelevant orderInfos's get moved after `orderInfo` (depends on the direction)\n * 5. All `field` orderInfo's get moved after `afterOrderInfo`\n */\n this.validateInitialization(imodel);\n const iTwinId = imodel.iTwinId!;\n const imodelId = imodel.iModelId!;\n\n if (field === afterField)\n throw Error(\"`field` can not be the same as `afterField`.\");\n\n const allOrderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\n\n const findFieldOrderInfoData = (f: Field) => {\n if (!visibleFields.includes(f))\n throw Error(\"Field is not contained in visible fields.\");\n const infos = getFieldOrderInfos(f, allOrderInfos);\n\n if (infos.length === 0)\n throw Error(\"Field has no property order information.\");\n const info = getMostRecentOrderInfo(infos);\n const index = allOrderInfos.indexOf(info);\n return { infos, mostRecent: { info, index } };\n };\n\n const { infos: movingOrderInfos, mostRecent: { index: orderInfoIndex } } = findFieldOrderInfoData(field);\n\n let afterOrderInfo: FavoritePropertiesOrderInfo | undefined;\n let afterOrderInfoIndex;\n if (afterField === undefined) {\n afterOrderInfo = undefined;\n afterOrderInfoIndex = -1;\n } else {\n ({ mostRecent: { info: afterOrderInfo, index: afterOrderInfoIndex } } = findFieldOrderInfoData(afterField));\n }\n\n let direction: Direction; // where to go from `afterOrderInfo` to `orderInfo`\n let startIndex: number;\n if (orderInfoIndex < afterOrderInfoIndex) {\n direction = Direction.Up;\n startIndex = afterOrderInfoIndex;\n } else {\n direction = Direction.Down;\n startIndex = afterOrderInfoIndex + 1;\n }\n\n const neededClassNames: Set<string> = allOrderInfos.reduce((classNames: Set<string>, oi) => {\n if (oi.parentClassName)\n classNames.add(oi.parentClassName);\n return classNames;\n }, new Set<string>());\n const baseClassesByClass = await this._getBaseClassesByClass(imodel, neededClassNames);\n\n const visibleOrderInfos = visibleFields.reduce((union: FavoritePropertiesOrderInfo[], currField) => union.concat(getFieldOrderInfos(currField, allOrderInfos)), []);\n const irrelevantOrderInfos: FavoritePropertiesOrderInfo[] = []; // orderInfos's that won't change their logical order in respect to other properties\n const relevantClasses: Set<ClassId> = new Set<ClassId>(); // currently relevant classes\n\n for (let i = startIndex; i !== orderInfoIndex; i += direction) {\n const currOrderInfo = allOrderInfos[i];\n\n // primitive properties are always relevant, because we can't determine their relevance based on the class hierarchy\n if (currOrderInfo.parentClassName === undefined)\n continue;\n\n const visible = visibleOrderInfos.includes(currOrderInfo);\n if (visible) {\n relevantClasses.add(currOrderInfo.parentClassName);\n continue;\n }\n\n const hasBaseClasses = baseClassesByClass[currOrderInfo.parentClassName].some((classId) => relevantClasses.has(classId));\n if (hasBaseClasses)\n continue;\n\n if (direction === Direction.Down)\n irrelevantOrderInfos.push(currOrderInfo);\n else\n irrelevantOrderInfos.unshift(currOrderInfo);\n }\n\n // remove irrelevantOrderInfo's to add them after the `orderInfo`\n irrelevantOrderInfos.forEach((foi) => {\n const index = allOrderInfos.findIndex((oi) => oi.parentClassName === foi.parentClassName && oi.name === foi.name);\n allOrderInfos.splice(index, 1);\n });\n\n // remove movingOrderInfos's to add them after the `afterOrderInfo`\n movingOrderInfos.forEach((foi) => {\n const index = allOrderInfos.findIndex((oi) => oi.parentClassName === foi.parentClassName && oi.name === foi.name);\n allOrderInfos.splice(index, 1);\n });\n movingOrderInfos.forEach((oi) => oi.orderedTimestamp = new Date());\n\n afterOrderInfoIndex = afterOrderInfo === undefined ? -1 : allOrderInfos.indexOf(afterOrderInfo);\n allOrderInfos.splice(afterOrderInfoIndex + 1, 0, ...movingOrderInfos);\n allOrderInfos.splice(afterOrderInfoIndex + 1 + (direction === Direction.Up ? movingOrderInfos.length : 0), 0, ...irrelevantOrderInfos);\n\n // reassign priority numbers\n let priority = allOrderInfos.length;\n allOrderInfos.forEach((oi) => oi.priority = priority--);\n\n await this._storage.savePropertiesOrder(allOrderInfos, iTwinId, imodelId);\n this.onFavoritesChanged.raiseEvent();\n }\n}\n\nenum Direction {\n Up = -1,\n Down = 1,\n}\n\nconst getiModelInfo = (iTwinId: string, imodelId: string) => `${iTwinId}/${imodelId}`;\n\nconst getPropertiesFieldPropertyNames = (field: PropertiesField) => {\n const nestingPrefix = getNestingPrefix(field.parent);\n return field.properties.map((property) => `${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${nestingPrefix}${property.property.classInfo.name}:${property.property.name}`);\n};\n\nconst getNestedContentFieldPropertyName = (field: NestedContentField) => {\n const nestingPrefix = getNestingPrefix(field);\n return `${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${nestingPrefix}${field.contentClassInfo.name}`;\n};\n\nconst getNestingPrefix = (field: NestedContentField | undefined) => {\n const path: string[] = [];\n let curr = field;\n while (curr !== undefined) {\n curr.pathToPrimaryClass.forEach((rel) => {\n // Relationship directions are reversed, because we are generating a relationship list starting from the parent\n path.push(`${rel.isForwardRelationship ? \"B\" : \"F\"}:${rel.relationshipInfo.name}`);\n path.push(rel.targetClassInfo.name);\n });\n curr = curr.parent;\n }\n if (path.length === 0)\n return \"\";\n\n path.reverse();\n return `${path.join(\"-\")}-`;\n};\n\nconst getPropertyClassName = (propertyName: PropertyFullName): string | undefined => {\n const propertyNameStart = propertyName.split(\"-\")[0];\n const parts = propertyNameStart.split(\":\").length;\n if (parts === 1) // primitive\n return undefined;\n if (parts === 2) // nested property OR nested property parent class OR regular property parent class\n return propertyNameStart;\n // regular property without parent class\n return propertyNameStart.substring(0, propertyName.lastIndexOf(\":\"));\n};\n\n/** @internal */\nexport const getFieldInfos = (field: Field): Set<PropertyFullName> => {\n const fieldInfos: Set<PropertyFullName> = new Set<PropertyFullName>();\n if (field.isPropertiesField())\n getPropertiesFieldPropertyNames(field).forEach((info) => fieldInfos.add(info));\n else if (field.isNestedContentField())\n fieldInfos.add(getNestedContentFieldPropertyName(field));\n else\n fieldInfos.add(`${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${field.name}`);\n return fieldInfos;\n};\n\nconst setHasAny = (set: Set<string>, lookup: Set<string>) => {\n for (const key of lookup) {\n if (set.has(key))\n return true;\n }\n return false;\n};\n\nconst addOrderInfos = (dest: FavoritePropertiesOrderInfo[], source: FavoritePropertiesOrderInfo[]) => {\n source.forEach((si) => {\n const index = dest.findIndex((di) => di.name === si.name);\n if (index === -1) {\n si.orderedTimestamp = new Date();\n dest.push(si);\n }\n });\n let priority = dest.length;\n dest.forEach((info) => info.priority = priority--);\n};\n\nconst removeOrderInfos = (container: FavoritePropertiesOrderInfo[], toRemove: FavoritePropertiesOrderInfo[]) => {\n toRemove.forEach((roi) => {\n const index = container.findIndex((oi) => oi.name === roi.name);\n /* istanbul ignore else */\n if (index >= 0)\n container.splice(index, 1);\n });\n};\n\n/** @internal */\nexport const createFieldOrderInfos = (field: Field): FavoritePropertiesOrderInfo[] => {\n if (field.isNestedContentField()) {\n const propertyName = getNestedContentFieldPropertyName(field);\n return [{\n parentClassName: getPropertyClassName(propertyName),\n name: propertyName,\n priority: 0,\n orderedTimestamp: new Date(),\n }];\n }\n if (field.isPropertiesField()) {\n return getPropertiesFieldPropertyNames(field).map((propertyName) => ({\n parentClassName: getPropertyClassName(propertyName),\n name: propertyName,\n priority: 0,\n orderedTimestamp: new Date(),\n }));\n }\n return [{\n parentClassName: undefined,\n name: field.name,\n priority: 0,\n orderedTimestamp: new Date(),\n }];\n};\n\nconst getFieldOrderInfos = (field: Field, orderInfos: FavoritePropertiesOrderInfo[]): FavoritePropertiesOrderInfo[] => {\n const fieldOrderInfos: FavoritePropertiesOrderInfo[] = [];\n const tryAddOrderInfo = (name: string) => {\n const fieldOrderInfo = orderInfos.find((oi) => oi.name === name);\n if (fieldOrderInfo !== undefined)\n fieldOrderInfos.push(fieldOrderInfo);\n };\n\n if (field.isPropertiesField())\n getPropertiesFieldPropertyNames(field).forEach(tryAddOrderInfo);\n else if (field.isNestedContentField())\n tryAddOrderInfo(getNestedContentFieldPropertyName(field));\n else\n tryAddOrderInfo(field.name);\n\n return fieldOrderInfos;\n};\n\nconst getMostRecentOrderInfo = (orderInfos: FavoritePropertiesOrderInfo[]) =>\n orderInfos.reduce((recent, curr) => (recent && recent.orderedTimestamp >= curr.orderedTimestamp) ? recent : curr);\n"]}
|
|
1
|
+
{"version":3,"file":"FavoritePropertiesManager.js","sourceRoot":"","sources":["../../../../src/presentation-frontend/favorite-properties/FavoritePropertiesManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n * See LICENSE.md in the project root for license terms and full copyright notice.\r\n *--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Core\r\n */\r\n\r\nimport { BeEvent, IDisposable, isIDisposable } from \"@itwin/core-bentley\";\r\nimport { QueryRowFormat } from \"@itwin/core-common\";\r\nimport { IModelConnection } from \"@itwin/core-frontend\";\r\nimport { ClassId, Field, NestedContentField, PropertiesField } from \"@itwin/presentation-common\";\r\nimport { IFavoritePropertiesStorage } from \"./FavoritePropertiesStorage\";\r\n\r\n/**\r\n * Scopes that favorite properties can be stored in.\r\n * @public\r\n */\r\nexport enum FavoritePropertiesScope {\r\n Global,\r\n ITwin,\r\n IModel,\r\n}\r\n\r\n/**\r\n * Format:\r\n * Regular property - [{path from parent class}-]{schema name}:{class name}:{property name}.\r\n * Nested property - [{path from parent class}-]{content class schema name}:{content class name}.\r\n * Primitive property - {field name}.\r\n * @public\r\n */\r\nexport type PropertyFullName = string;\r\n\r\n/**\r\n * Holds the information of favorite properties ordering.\r\n * @public\r\n */\r\nexport interface FavoritePropertiesOrderInfo {\r\n parentClassName: string | undefined;\r\n name: PropertyFullName;\r\n priority: number;\r\n orderedTimestamp: Date;\r\n}\r\n\r\n/**\r\n * Properties for initializing [[FavoritePropertiesManager]]\r\n * @public\r\n */\r\nexport interface FavoritePropertiesManagerProps {\r\n /**\r\n * Implementation of a persistence layer for storing favorite properties and their order.\r\n * @public\r\n */\r\n storage: IFavoritePropertiesStorage;\r\n}\r\n\r\n/**\r\n * The favorite property manager which lets to store favorite properties\r\n * and check if field contains favorite properties.\r\n *\r\n * @public\r\n */\r\nexport class FavoritePropertiesManager implements IDisposable {\r\n /**\r\n * Used in tests to avoid collisions between multiple runs using the same storage\r\n * @internal\r\n */\r\n public static FAVORITES_IDENTIFIER_PREFIX = \"\";\r\n\r\n /** Event raised after favorite properties have changed. */\r\n public onFavoritesChanged = new BeEvent<() => void>();\r\n\r\n private _storage: IFavoritePropertiesStorage;\r\n private _globalProperties: Set<PropertyFullName> | undefined;\r\n private _iTwinProperties: Map<string, Set<PropertyFullName>>;\r\n private _imodelProperties: Map<string, Set<PropertyFullName>>;\r\n private _imodelBaseClassesByClass: Map<string, { [className: string]: string[] }>;\r\n\r\n /** Property order is saved only in iModel scope */\r\n private _propertiesOrder: Map<string, FavoritePropertiesOrderInfo[]>;\r\n\r\n public constructor(props: FavoritePropertiesManagerProps) {\r\n this._storage = props.storage;\r\n this._iTwinProperties = new Map<string, Set<PropertyFullName>>();\r\n this._imodelProperties = new Map<string, Set<PropertyFullName>>();\r\n this._propertiesOrder = new Map<string, FavoritePropertiesOrderInfo[]>();\r\n this._imodelBaseClassesByClass = new Map<string, { [className: string]: string[] }>();\r\n }\r\n\r\n public dispose() {\r\n // istanbul ignore else\r\n if (isIDisposable(this._storage)) {\r\n this._storage.dispose();\r\n }\r\n }\r\n\r\n /**\r\n * Initialize favorite properties for the provided IModelConnection.\r\n */\r\n public initializeConnection = async (imodel: IModelConnection) => {\r\n const imodelId = imodel.iModelId!;\r\n const iTwinId = imodel.iTwinId!;\r\n\r\n if (this._globalProperties === undefined) {\r\n this._globalProperties = (await this._storage.loadProperties()) || new Set<PropertyFullName>();\r\n }\r\n\r\n if (!this._iTwinProperties.has(iTwinId)) {\r\n const iTwinProperties = (await this._storage.loadProperties(iTwinId)) || new Set<PropertyFullName>();\r\n this._iTwinProperties.set(iTwinId, iTwinProperties);\r\n }\r\n\r\n if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId))) {\r\n const imodelProperties = (await this._storage.loadProperties(iTwinId, imodelId)) || new Set<PropertyFullName>();\r\n this._imodelProperties.set(getiModelInfo(iTwinId, imodelId), imodelProperties);\r\n }\r\n const propertiesOrder = (await this._storage.loadPropertiesOrder(iTwinId, imodelId)) || [];\r\n this._propertiesOrder.set(getiModelInfo(iTwinId, imodelId), propertiesOrder);\r\n await this._adjustPropertyOrderInfos(iTwinId, imodelId);\r\n };\r\n\r\n /**\r\n * Function that removes order information of properties that are no longer\r\n * favorited and adds missing order information for favorited properties.\r\n */\r\n private _adjustPropertyOrderInfos = async (iTwinId: string, imodelId: string) => {\r\n const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\r\n\r\n const globalProperties = this._globalProperties!;\r\n const iTwinProperties = this._iTwinProperties.get(iTwinId)!;\r\n const imodelProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!;\r\n // favorite property infos that need to be added to the propertiesOrder array\r\n const infosToAdd = new Set<string>([...globalProperties, ...iTwinProperties, ...imodelProperties]);\r\n\r\n for (let i = propertiesOrder.length - 1; i >= 0; i--) {\r\n if (infosToAdd.has(propertiesOrder[i].name)) {\r\n infosToAdd.delete(propertiesOrder[i].name);\r\n } else {\r\n propertiesOrder.splice(i, 1);\r\n }\r\n }\r\n\r\n infosToAdd.forEach((info) =>\r\n propertiesOrder.push({\r\n name: info,\r\n parentClassName: getPropertyClassName(info),\r\n orderedTimestamp: new Date(),\r\n priority: 0,\r\n }),\r\n );\r\n\r\n let priority = propertiesOrder.length;\r\n propertiesOrder.forEach((oi) => (oi.priority = priority--));\r\n };\r\n\r\n private validateInitialization(imodel: IModelConnection) {\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n if (!this._imodelProperties.has(getiModelInfo(iTwinId, imodelId))) {\r\n throw Error(\r\n `Favorite properties are not initialized for iModel: '${imodelId}', in iTwin: '${iTwinId}'. Call initializeConnection() with an IModelConnection to initialize.`,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Adds favorite properties into a certain scope.\r\n * @param field Field that contains properties. If field contains multiple properties, all of them will be favorited.\r\n * @param imodel IModelConnection.\r\n * @param scope FavoritePropertiesScope to put the favorite properties into.\r\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\r\n */\r\n public async add(field: Field, imodel: IModelConnection, scope: FavoritePropertiesScope): Promise<void> {\r\n this.validateInitialization(imodel);\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n let favoriteProperties: Set<PropertyFullName>;\r\n let saveProperties: (properties: Set<PropertyFullName>) => Promise<void>;\r\n switch (scope) {\r\n case FavoritePropertiesScope.Global:\r\n favoriteProperties = this._globalProperties!;\r\n saveProperties = async (properties) => this._storage.saveProperties(properties);\r\n break;\r\n case FavoritePropertiesScope.ITwin:\r\n favoriteProperties = this._iTwinProperties.get(iTwinId)!;\r\n saveProperties = async (properties) => this._storage.saveProperties(properties, iTwinId);\r\n break;\r\n default:\r\n favoriteProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!;\r\n saveProperties = async (properties) => this._storage.saveProperties(properties, iTwinId, imodelId);\r\n }\r\n\r\n const countBefore = favoriteProperties.size;\r\n const fieldInfos = getFieldInfos(field);\r\n fieldInfos.forEach((info) => favoriteProperties.add(info));\r\n if (favoriteProperties.size !== countBefore) {\r\n const saves: Array<Promise<void>> = [];\r\n saves.push(saveProperties(favoriteProperties));\r\n\r\n const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\r\n addOrderInfos(propertiesOrder, createFieldOrderInfos(field));\r\n saves.push(this._storage.savePropertiesOrder(propertiesOrder, iTwinId, imodelId));\r\n\r\n await Promise.all(saves);\r\n this.onFavoritesChanged.raiseEvent();\r\n }\r\n }\r\n\r\n /**\r\n * Removes favorite properties from a scope specified and all the more general scopes.\r\n * @param field Field that contains properties. If field contains multiple properties, all of them will be un-favorited.\r\n * @param imodel IModelConnection.\r\n * @param scope FavoritePropertiesScope to remove the favorite properties from. It also removes from more general scopes.\r\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\r\n */\r\n public async remove(field: Field, imodel: IModelConnection, scope: FavoritePropertiesScope): Promise<void> {\r\n this.validateInitialization(imodel);\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n const fieldInfos = getFieldInfos(field);\r\n const workingScopes: Array<{ properties: Set<PropertyFullName>; save: (properties: Set<PropertyFullName>) => Promise<void> }> = [];\r\n workingScopes.push({\r\n properties: this._globalProperties!,\r\n save: async (properties) => this._storage.saveProperties(properties),\r\n });\r\n if (scope === FavoritePropertiesScope.ITwin || scope === FavoritePropertiesScope.IModel) {\r\n workingScopes.push({\r\n properties: this._iTwinProperties.get(iTwinId)!,\r\n save: async (properties) => this._storage.saveProperties(properties, iTwinId),\r\n });\r\n }\r\n if (scope === FavoritePropertiesScope.IModel) {\r\n workingScopes.push({\r\n properties: this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!,\r\n save: async (properties) => this._storage.saveProperties(properties, iTwinId, imodelId),\r\n });\r\n }\r\n\r\n const saves: Array<Promise<void>> = [];\r\n let favoritesChanged = false;\r\n for (const { properties, save } of workingScopes) {\r\n const countBefore = properties.size;\r\n fieldInfos.forEach((info) => properties.delete(info));\r\n if (properties.size !== countBefore) {\r\n saves.push(save(properties));\r\n favoritesChanged = true;\r\n }\r\n }\r\n if (!favoritesChanged) {\r\n return;\r\n }\r\n\r\n const propertiesOrder = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\r\n removeOrderInfos(propertiesOrder, createFieldOrderInfos(field));\r\n saves.push(this._storage.savePropertiesOrder(propertiesOrder, iTwinId, imodelId));\r\n\r\n await Promise.all(saves);\r\n this.onFavoritesChanged.raiseEvent();\r\n }\r\n\r\n /**\r\n * Removes all favorite properties from a certain scope.\r\n * @param imodel IModelConnection.\r\n * @param scope FavoritePropertiesScope to remove the favorite properties from.\r\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\r\n */\r\n public async clear(imodel: IModelConnection, scope: FavoritePropertiesScope): Promise<void> {\r\n this.validateInitialization(imodel);\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n let favoriteProperties: Set<PropertyFullName>;\r\n let saveProperties: () => Promise<void>;\r\n switch (scope) {\r\n case FavoritePropertiesScope.Global:\r\n favoriteProperties = this._globalProperties!;\r\n saveProperties = async () => this._storage.saveProperties(new Set<PropertyFullName>());\r\n break;\r\n case FavoritePropertiesScope.ITwin:\r\n favoriteProperties = this._iTwinProperties.get(iTwinId)!;\r\n saveProperties = async () => this._storage.saveProperties(new Set<PropertyFullName>(), iTwinId);\r\n break;\r\n default:\r\n favoriteProperties = this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!;\r\n saveProperties = async () => this._storage.saveProperties(new Set<PropertyFullName>(), iTwinId, imodelId);\r\n }\r\n\r\n if (favoriteProperties.size === 0) {\r\n return;\r\n }\r\n\r\n favoriteProperties.clear();\r\n const saves: Array<Promise<void>> = [];\r\n saves.push(saveProperties());\r\n saves.push(this._adjustPropertyOrderInfos(iTwinId, imodelId));\r\n await Promise.all(saves);\r\n this.onFavoritesChanged.raiseEvent();\r\n }\r\n\r\n /**\r\n * Check if field contains at least one favorite property.\r\n * @param field Field that contains properties.\r\n * @param imodel IModelConnection.\r\n * @param scope FavoritePropertiesScope to check for favorite properties. It also checks the more general scopes.\r\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\r\n */\r\n public has(field: Field, imodel: IModelConnection, scope: FavoritePropertiesScope): boolean {\r\n this.validateInitialization(imodel);\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n const fieldInfos = getFieldInfos(field);\r\n return (\r\n setHasAny(this._globalProperties!, fieldInfos) ||\r\n (scope !== FavoritePropertiesScope.Global && setHasAny(this._iTwinProperties.get(iTwinId)!, fieldInfos)) ||\r\n (scope === FavoritePropertiesScope.IModel && setHasAny(this._imodelProperties.get(getiModelInfo(iTwinId, imodelId))!, fieldInfos))\r\n );\r\n }\r\n\r\n /**\r\n * Sorts an array of fields with respect to favorite property order.\r\n * Non-favorited fields get sorted by their default priority and always have lower priority than favorited fields.\r\n * @param imodel IModelConnection.\r\n * @param fields Array of Field's that needs to be sorted.\r\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\r\n */\r\n public sortFields = (imodel: IModelConnection, fields: Field[]): Field[] => {\r\n this.validateInitialization(imodel);\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n const fieldPriority = new Map<Field, number>();\r\n fields.forEach((field) => fieldPriority.set(field, this.getFieldPriority(field, iTwinId, imodelId)));\r\n\r\n const sortFunction = (left: Field, right: Field): number => {\r\n const lp = fieldPriority.get(left)!;\r\n const rp = fieldPriority.get(right)!;\r\n return lp < rp\r\n ? 1\r\n : lp > rp\r\n ? -1\r\n : left.priority < right.priority\r\n ? 1 // if favorite fields have equal priorities, sort by field priority\r\n : left.priority > right.priority\r\n ? -1\r\n : left.name.localeCompare(right.name);\r\n };\r\n\r\n return fields.sort(sortFunction);\r\n };\r\n\r\n private getFieldPriority(field: Field, iTwinId: string, imodelId: string): number {\r\n const orderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\r\n const fieldOrderInfos = getFieldOrderInfos(field, orderInfos);\r\n if (fieldOrderInfos.length === 0) {\r\n return -1;\r\n }\r\n const mostRecent = getMostRecentOrderInfo(fieldOrderInfos);\r\n return mostRecent.priority;\r\n }\r\n\r\n private _getBaseClassesByClass = async (imodel: IModelConnection, neededClasses: Set<string>): Promise<{ [className: string]: string[] }> => {\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n const imodelInfo = getiModelInfo(iTwinId, imodelId);\r\n let baseClasses: { [className: string]: string[] };\r\n if (this._imodelBaseClassesByClass.has(imodelInfo)) {\r\n baseClasses = this._imodelBaseClassesByClass.get(imodelInfo)!;\r\n } else {\r\n this._imodelBaseClassesByClass.set(imodelInfo, (baseClasses = {}));\r\n }\r\n\r\n const missingClasses = new Set<string>();\r\n neededClasses.forEach((className) => {\r\n if (!baseClasses.hasOwnProperty(className)) {\r\n missingClasses.add(className);\r\n }\r\n });\r\n if (missingClasses.size === 0) {\r\n return baseClasses;\r\n }\r\n\r\n const query = `\r\n SELECT (derivedSchema.Name || ':' || derivedClass.Name) AS \"ClassFullName\", (baseSchema.Name || ':' || baseClass.Name) AS \"BaseClassFullName\"\r\n FROM ECDbMeta.ClassHasAllBaseClasses baseClassRels\r\n INNER JOIN ECDbMeta.ECClassDef derivedClass ON derivedClass.ECInstanceId = baseClassRels.SourceECInstanceId\r\n INNER JOIN ECDbMeta.ECSchemaDef derivedSchema ON derivedSchema.ECInstanceId = derivedClass.Schema.Id\r\n INNER JOIN ECDbMeta.ECClassDef baseClass ON baseClass.ECInstanceId = baseClassRels.TargetECInstanceId\r\n INNER JOIN ECDbMeta.ECSchemaDef baseSchema ON baseSchema.ECInstanceId = baseClass.Schema.Id\r\n WHERE (derivedSchema.Name || ':' || derivedClass.Name) IN (${[...missingClasses].map((className) => `'${className}'`).join(\",\")})`;\r\n const reader = imodel.createQueryReader(query, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames });\r\n while (await reader.step()) {\r\n const row = reader.current.toRow();\r\n if (!(row.classFullName in baseClasses)) {\r\n baseClasses[row.classFullName] = [];\r\n }\r\n baseClasses[row.classFullName].push(row.baseClassFullName);\r\n }\r\n return baseClasses;\r\n };\r\n\r\n /** Changes field properties priorities to lower than another fields priority\r\n * @param imodel IModelConnection.\r\n * @param field Field that priority is being changed.\r\n * @param afterField Field that goes before the moved field. If undefined the moving field is changed to the highest priority (to the top).\r\n * @param visibleFields Array of fields to move the field in.\r\n * @note `initializeConnection` must be called with the `imodel` before calling this function.\r\n */\r\n public async changeFieldPriority(imodel: IModelConnection, field: Field, afterField: Field | undefined, visibleFields: Field[]) {\r\n /**\r\n * How it works:\r\n * 1. Gets the orderInfo's for `field` (`orderInfo`) and `afterField` (`afterOrderInfo`) by selecting the most recent order informations for each field\r\n * 2. Iterates all orderInfo's that are in between `afterOrderInfo` and `orderInfo` when sorted by priority\r\n * 3. For each iterated orderInfo it checks if it is relevant:\r\n * 3.1. If orderInfo belongs to a primitive property, orderInfo is relevant\r\n * 3.2. If orderInfo's field is visible, orderInfo is relevant\r\n * 3.3. If orderInfo's class has a base class or itself in previously labeled relevant orderInfo's, orderInfo is relevant\r\n * 3.4. If 3.1 - 3.3 don't pass, orderInfo is irrelevant\r\n * 4. Irrelevant orderInfos's get moved after `orderInfo` (depends on the direction)\r\n * 5. All `field` orderInfo's get moved after `afterOrderInfo`\r\n */\r\n this.validateInitialization(imodel);\r\n const iTwinId = imodel.iTwinId!;\r\n const imodelId = imodel.iModelId!;\r\n\r\n if (field === afterField) {\r\n throw Error(\"`field` can not be the same as `afterField`.\");\r\n }\r\n\r\n const allOrderInfos = this._propertiesOrder.get(getiModelInfo(iTwinId, imodelId))!;\r\n\r\n const findFieldOrderInfoData = (f: Field) => {\r\n if (!visibleFields.includes(f)) {\r\n throw Error(\"Field is not contained in visible fields.\");\r\n }\r\n const infos = getFieldOrderInfos(f, allOrderInfos);\r\n\r\n if (infos.length === 0) {\r\n throw Error(\"Field has no property order information.\");\r\n }\r\n const info = getMostRecentOrderInfo(infos);\r\n const index = allOrderInfos.indexOf(info);\r\n return { infos, mostRecent: { info, index } };\r\n };\r\n\r\n const {\r\n infos: movingOrderInfos,\r\n mostRecent: { index: orderInfoIndex },\r\n } = findFieldOrderInfoData(field);\r\n\r\n let afterOrderInfo: FavoritePropertiesOrderInfo | undefined;\r\n let afterOrderInfoIndex;\r\n if (afterField === undefined) {\r\n afterOrderInfo = undefined;\r\n afterOrderInfoIndex = -1;\r\n } else {\r\n ({\r\n mostRecent: { info: afterOrderInfo, index: afterOrderInfoIndex },\r\n } = findFieldOrderInfoData(afterField));\r\n }\r\n\r\n let direction: Direction; // where to go from `afterOrderInfo` to `orderInfo`\r\n let startIndex: number;\r\n if (orderInfoIndex < afterOrderInfoIndex) {\r\n direction = Direction.Up;\r\n startIndex = afterOrderInfoIndex;\r\n } else {\r\n direction = Direction.Down;\r\n startIndex = afterOrderInfoIndex + 1;\r\n }\r\n\r\n const neededClassNames: Set<string> = allOrderInfos.reduce((classNames: Set<string>, oi) => {\r\n if (oi.parentClassName) {\r\n classNames.add(oi.parentClassName);\r\n }\r\n return classNames;\r\n }, new Set<string>());\r\n const baseClassesByClass = await this._getBaseClassesByClass(imodel, neededClassNames);\r\n\r\n const visibleOrderInfos = visibleFields.reduce(\r\n (union: FavoritePropertiesOrderInfo[], currField) => union.concat(getFieldOrderInfos(currField, allOrderInfos)),\r\n [],\r\n );\r\n const irrelevantOrderInfos: FavoritePropertiesOrderInfo[] = []; // orderInfos's that won't change their logical order in respect to other properties\r\n const relevantClasses: Set<ClassId> = new Set<ClassId>(); // currently relevant classes\r\n\r\n for (let i = startIndex; i !== orderInfoIndex; i += direction) {\r\n const currOrderInfo = allOrderInfos[i];\r\n\r\n // primitive properties are always relevant, because we can't determine their relevance based on the class hierarchy\r\n if (currOrderInfo.parentClassName === undefined) {\r\n continue;\r\n }\r\n\r\n const visible = visibleOrderInfos.includes(currOrderInfo);\r\n if (visible) {\r\n relevantClasses.add(currOrderInfo.parentClassName);\r\n continue;\r\n }\r\n\r\n const hasBaseClasses = baseClassesByClass[currOrderInfo.parentClassName].some((classId) => relevantClasses.has(classId));\r\n if (hasBaseClasses) {\r\n continue;\r\n }\r\n\r\n if (direction === Direction.Down) {\r\n irrelevantOrderInfos.push(currOrderInfo);\r\n } else {\r\n irrelevantOrderInfos.unshift(currOrderInfo);\r\n }\r\n }\r\n\r\n // remove irrelevantOrderInfo's to add them after the `orderInfo`\r\n irrelevantOrderInfos.forEach((foi) => {\r\n const index = allOrderInfos.findIndex((oi) => oi.parentClassName === foi.parentClassName && oi.name === foi.name);\r\n allOrderInfos.splice(index, 1);\r\n });\r\n\r\n // remove movingOrderInfos's to add them after the `afterOrderInfo`\r\n movingOrderInfos.forEach((foi) => {\r\n const index = allOrderInfos.findIndex((oi) => oi.parentClassName === foi.parentClassName && oi.name === foi.name);\r\n allOrderInfos.splice(index, 1);\r\n });\r\n movingOrderInfos.forEach((oi) => (oi.orderedTimestamp = new Date()));\r\n\r\n afterOrderInfoIndex = afterOrderInfo === undefined ? -1 : allOrderInfos.indexOf(afterOrderInfo);\r\n allOrderInfos.splice(afterOrderInfoIndex + 1, 0, ...movingOrderInfos);\r\n allOrderInfos.splice(afterOrderInfoIndex + 1 + (direction === Direction.Up ? movingOrderInfos.length : 0), 0, ...irrelevantOrderInfos);\r\n\r\n // reassign priority numbers\r\n let priority = allOrderInfos.length;\r\n allOrderInfos.forEach((oi) => (oi.priority = priority--));\r\n\r\n await this._storage.savePropertiesOrder(allOrderInfos, iTwinId, imodelId);\r\n this.onFavoritesChanged.raiseEvent();\r\n }\r\n}\r\n\r\nenum Direction {\r\n Up = -1,\r\n Down = 1,\r\n}\r\n\r\nconst getiModelInfo = (iTwinId: string, imodelId: string) => `${iTwinId}/${imodelId}`;\r\n\r\nconst getPropertiesFieldPropertyNames = (field: PropertiesField) => {\r\n const nestingPrefix = getNestingPrefix(field.parent);\r\n return field.properties.map(\r\n (property) => `${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${nestingPrefix}${property.property.classInfo.name}:${property.property.name}`,\r\n );\r\n};\r\n\r\nconst getNestedContentFieldPropertyName = (field: NestedContentField) => {\r\n const nestingPrefix = getNestingPrefix(field);\r\n return `${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${nestingPrefix}${field.contentClassInfo.name}`;\r\n};\r\n\r\nconst getNestingPrefix = (field: NestedContentField | undefined) => {\r\n const path: string[] = [];\r\n let curr = field;\r\n while (curr !== undefined) {\r\n curr.pathToPrimaryClass.forEach((rel) => {\r\n // Relationship directions are reversed, because we are generating a relationship list starting from the parent\r\n path.push(`${rel.isForwardRelationship ? \"B\" : \"F\"}:${rel.relationshipInfo.name}`);\r\n path.push(rel.targetClassInfo.name);\r\n });\r\n curr = curr.parent;\r\n }\r\n if (path.length === 0) {\r\n return \"\";\r\n }\r\n\r\n path.reverse();\r\n return `${path.join(\"-\")}-`;\r\n};\r\n\r\nconst getPropertyClassName = (propertyName: PropertyFullName): string | undefined => {\r\n const propertyNameStart = propertyName.split(\"-\")[0];\r\n const parts = propertyNameStart.split(\":\").length;\r\n if (parts === 1) {\r\n // primitive\r\n return undefined;\r\n }\r\n if (parts === 2) {\r\n // nested property OR nested property parent class OR regular property parent class\r\n return propertyNameStart;\r\n }\r\n // regular property without parent class\r\n return propertyNameStart.substring(0, propertyName.lastIndexOf(\":\"));\r\n};\r\n\r\n/** @internal */\r\nexport const getFieldInfos = (field: Field): Set<PropertyFullName> => {\r\n const fieldInfos: Set<PropertyFullName> = new Set<PropertyFullName>();\r\n if (field.isPropertiesField()) {\r\n getPropertiesFieldPropertyNames(field).forEach((info) => fieldInfos.add(info));\r\n } else if (field.isNestedContentField()) {\r\n fieldInfos.add(getNestedContentFieldPropertyName(field));\r\n } else {\r\n fieldInfos.add(`${FavoritePropertiesManager.FAVORITES_IDENTIFIER_PREFIX}${field.name}`);\r\n }\r\n return fieldInfos;\r\n};\r\n\r\nconst setHasAny = (set: Set<string>, lookup: Set<string>) => {\r\n for (const key of lookup) {\r\n if (set.has(key)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n};\r\n\r\nconst addOrderInfos = (dest: FavoritePropertiesOrderInfo[], source: FavoritePropertiesOrderInfo[]) => {\r\n source.forEach((si) => {\r\n const index = dest.findIndex((di) => di.name === si.name);\r\n if (index === -1) {\r\n si.orderedTimestamp = new Date();\r\n dest.push(si);\r\n }\r\n });\r\n let priority = dest.length;\r\n dest.forEach((info) => (info.priority = priority--));\r\n};\r\n\r\nconst removeOrderInfos = (container: FavoritePropertiesOrderInfo[], toRemove: FavoritePropertiesOrderInfo[]) => {\r\n toRemove.forEach((roi) => {\r\n const index = container.findIndex((oi) => oi.name === roi.name);\r\n /* istanbul ignore else */\r\n if (index >= 0) {\r\n container.splice(index, 1);\r\n }\r\n });\r\n};\r\n\r\n/** @internal */\r\nexport const createFieldOrderInfos = (field: Field): FavoritePropertiesOrderInfo[] => {\r\n if (field.isNestedContentField()) {\r\n const propertyName = getNestedContentFieldPropertyName(field);\r\n return [\r\n {\r\n parentClassName: getPropertyClassName(propertyName),\r\n name: propertyName,\r\n priority: 0,\r\n orderedTimestamp: new Date(),\r\n },\r\n ];\r\n }\r\n if (field.isPropertiesField()) {\r\n return getPropertiesFieldPropertyNames(field).map((propertyName) => ({\r\n parentClassName: getPropertyClassName(propertyName),\r\n name: propertyName,\r\n priority: 0,\r\n orderedTimestamp: new Date(),\r\n }));\r\n }\r\n return [\r\n {\r\n parentClassName: undefined,\r\n name: field.name,\r\n priority: 0,\r\n orderedTimestamp: new Date(),\r\n },\r\n ];\r\n};\r\n\r\nconst getFieldOrderInfos = (field: Field, orderInfos: FavoritePropertiesOrderInfo[]): FavoritePropertiesOrderInfo[] => {\r\n const fieldOrderInfos: FavoritePropertiesOrderInfo[] = [];\r\n const tryAddOrderInfo = (name: string) => {\r\n const fieldOrderInfo = orderInfos.find((oi) => oi.name === name);\r\n if (fieldOrderInfo !== undefined) {\r\n fieldOrderInfos.push(fieldOrderInfo);\r\n }\r\n };\r\n\r\n if (field.isPropertiesField()) {\r\n getPropertiesFieldPropertyNames(field).forEach(tryAddOrderInfo);\r\n } else if (field.isNestedContentField()) {\r\n tryAddOrderInfo(getNestedContentFieldPropertyName(field));\r\n } else {\r\n tryAddOrderInfo(field.name);\r\n }\r\n\r\n return fieldOrderInfos;\r\n};\r\n\r\nconst getMostRecentOrderInfo = (orderInfos: FavoritePropertiesOrderInfo[]) =>\r\n orderInfos.reduce((recent, curr) => (recent && recent.orderedTimestamp >= curr.orderedTimestamp ? recent : curr));\r\n"]}
|