@itwin/presentation-frontend
Version:
Frontend of iModel.js Presentation library
164 lines • 6.71 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/* eslint-disable @typescript-eslint/no-deprecated */
/* eslint-disable @typescript-eslint/ban-ts-comment */
/** @packageDocumentation
* @module UnifiedSelection
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HiliteSetProvider = void 0;
const rxjs_1 = require("rxjs");
const rxjs_for_await_1 = require("rxjs-for-await");
const presentation_common_1 = require("@itwin/presentation-common");
const Presentation_js_1 = require("../Presentation.js");
// @ts-ignore TS complains about `with` in CJS builds, but not ESM
const HiliteRules_json_1 = __importDefault(require("./HiliteRules.json"));
const unified_selection_1 = require("@itwin/unified-selection");
const HILITE_RULESET = HiliteRules_json_1.default;
/**
* Presentation-based provider which uses presentation ruleset to determine
* what `HiliteSet` should be hilited in the graphics viewport based on the
* supplied `KeySet`.
*
* @public
* @deprecated in 5.0 - will not be removed until after 2026-06-13. Use `HiliteSetProvider` from [@itwin/unified-selection](https://github.com/iTwin/presentation/blob/master/packages/unified-selection/README.md#hilite-sets) package instead.
*/
class HiliteSetProvider {
_imodel;
_cache;
constructor(props) {
this._imodel = props.imodel;
}
/**
* Create a hilite set provider for the specified iModel.
*/
static create(props) {
return new HiliteSetProvider(props);
}
/**
* Get hilite set for instances and/or nodes whose keys are specified in the
* given KeySet.
*
* Note: The provider caches result of the last request, so subsequent requests
* for the same input doesn't cost.
*/
async getHiliteSet(selection) {
const modelIds = new Array();
const subCategoryIds = new Array();
const elementIds = new Array();
const iterator = this.getHiliteSetIterator(selection);
for await (const set of iterator) {
modelIds.push(...(set.models ?? []));
subCategoryIds.push(...(set.subCategories ?? []));
elementIds.push(...(set.elements ?? []));
}
return {
models: modelIds.length ? modelIds : undefined,
subCategories: subCategoryIds.length ? subCategoryIds : undefined,
elements: elementIds.length ? elementIds : undefined,
};
}
/**
* Get hilite set iterator for provided keys. It loads content in batches and
* yields hilite set created from each batch after it is loaded.
*/
getHiliteSetIterator(selection) {
if (!this._cache || this._cache.keysGuid !== selection.guid) {
this._cache = {
keysGuid: selection.guid,
observable: (0, rxjs_1.from)(this.createHiliteSetIterator(selection)).pipe((0, rxjs_1.shareReplay)({ refCount: true })),
};
}
return (0, rxjs_for_await_1.eachValueFrom)(this._cache.observable);
}
async *createHiliteSetIterator(selection) {
const { keys, transientIds } = this.handleTransientKeys(selection);
const { options, keyBatches } = this.getContentOptions(keys);
if (transientIds.length !== 0) {
yield { elements: transientIds };
}
for (const batch of keyBatches) {
let loadedItems = 0;
while (true) {
const content = await Presentation_js_1.Presentation.presentation.getContentIterator({
...options,
paging: { start: loadedItems, size: CONTENT_SET_PAGE_SIZE },
keys: batch,
});
if (!content) {
break;
}
const items = new Array();
for await (const item of content.items) {
items.push(item);
}
const result = this.createHiliteSet(items);
yield result;
loadedItems += items.length;
if (loadedItems >= content.total) {
break;
}
}
}
}
createHiliteSet(records) {
const modelIds = new Array();
const subCategoryIds = new Array();
const elementIds = new Array();
records.forEach((rec) => {
const ids = isModelRecord(rec) ? modelIds : isSubCategoryRecord(rec) ? subCategoryIds : elementIds;
rec.primaryKeys.forEach((pk) => ids.push(pk.id));
});
return {
models: modelIds.length ? modelIds : undefined,
subCategories: subCategoryIds.length ? subCategoryIds : undefined,
elements: elementIds.length ? elementIds : undefined,
};
}
getContentOptions(keys) {
const descriptor = {
displayType: presentation_common_1.DefaultContentDisplayTypes.Viewport,
contentFlags: presentation_common_1.ContentFlags.KeysOnly,
};
const options = {
imodel: this._imodel,
rulesetOrId: HILITE_RULESET,
descriptor,
};
const keyBatches = new Array();
keys.forEachBatch(presentation_common_1.DEFAULT_KEYS_BATCH_SIZE, (batch) => {
keyBatches.push(batch);
});
return {
options,
keyBatches,
};
}
handleTransientKeys(selection) {
// need to create a new set without transients
const transientIds = new Array();
const keys = new presentation_common_1.KeySet();
keys.add(selection, (key) => {
if (presentation_common_1.Key.isInstanceKey(key) && key.className === unified_selection_1.TRANSIENT_ELEMENT_CLASSNAME) {
transientIds.push(key.id);
return false;
}
return true;
});
return {
transientIds,
keys,
};
}
}
exports.HiliteSetProvider = HiliteSetProvider;
const CONTENT_SET_PAGE_SIZE = 1000;
const isModelRecord = (rec) => rec.extendedData && rec.extendedData.isModel;
const isSubCategoryRecord = (rec) => rec.extendedData && rec.extendedData.isSubCategory;
//# sourceMappingURL=HiliteSetProvider.js.map