@itwin/unified-selection
Version:
Package for managing unified selection in iTwin.js applications.
237 lines • 8.94 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Selectables = exports.TRANSIENT_ELEMENT_CLASSNAME = exports.Selectable = void 0;
const rxjs_1 = require("rxjs");
const rxjs_for_await_1 = require("rxjs-for-await");
const presentation_shared_1 = require("@itwin/presentation-shared");
/** @public */
// eslint-disable-next-line @typescript-eslint/no-redeclare
var Selectable;
(function (Selectable) {
/** Check if the supplied selectable is a `SelectableInstanceKey` */
function isInstanceKey(selectable) {
const instanceKey = selectable;
return !!instanceKey.className && !!instanceKey.id;
}
Selectable.isInstanceKey = isInstanceKey;
/** Check if the supplied selectable is a `CustomSelectable` */
function isCustom(selectable) {
return !!selectable.identifier;
}
Selectable.isCustom = isCustom;
})(Selectable || (exports.Selectable = Selectable = {}));
/**
* Class name used to create `SelectableInstanceKey` for transient elements.
* @public
*/
exports.TRANSIENT_ELEMENT_CLASSNAME = "/TRANSIENT";
/** @public */
var Selectables;
(function (Selectables) {
/**
* Creates `Selectables` from array of selectable
* @param source Source to create selectables from
* @public
*/
function create(source) {
const newSelectables = {
instanceKeys: new Map(),
custom: new Map(),
};
Selectables.add(newSelectables, source);
return newSelectables;
}
Selectables.create = create;
/**
* Get the number of selectables stored in a `Selectables` object.
* @param selectables `Selectables` object to get size for
* @public
*/
function size(selectables) {
let instanceCount = 0;
selectables.instanceKeys.forEach((set) => (instanceCount += set.size));
return instanceCount + selectables.custom.size;
}
Selectables.size = size;
/**
* Is a `Selectables` object currently empty.
* @param selectables `Selectables` object to check
* @public
*/
function isEmpty(selectables) {
return Selectables.size(selectables) === 0;
}
Selectables.isEmpty = isEmpty;
/**
* Check if a `Selectables` object contains the specified selectable.
* @param selectables `Selectables` object to check
* @param value The selectable to check for.
* @public
*/
function has(selectables, value) {
if (Selectable.isInstanceKey(value)) {
const normalizedClassName = normalizeClassName(value.className);
const set = selectables.instanceKeys.get(normalizedClassName);
return !!(set && set.has(value.id));
}
return selectables.custom.has(value.identifier);
}
Selectables.has = has;
/**
* Check if a `Selectables` object contains all the specified selectables.
* @param selectables `Selectables` object to check
* @param values The selectables to check for.
* @public
*/
function hasAll(selectables, values) {
if (Selectables.size(selectables) < values.length) {
return false;
}
for (const selectable of values) {
if (!Selectables.has(selectables, selectable)) {
return false;
}
}
return true;
}
Selectables.hasAll = hasAll;
/**
* Check if a `Selectables` object contains any of the specified selectables.
* @param selectables `Selectables` object to check
* @param values The selectables to check for.
* @public
*/
function hasAny(selectables, values) {
for (const selectable of values) {
if (Selectables.has(selectables, selectable)) {
return true;
}
}
return false;
}
Selectables.hasAny = hasAny;
/**
* Add a one or more selectables to a `Selectables`
* @param selectables `Selectables` object to add selectables for
* @param values Selectables to add.
* @public
*/
function add(selectables, values) {
let hasChanged = false;
for (const selectable of values) {
if (Selectable.isInstanceKey(selectable)) {
const normalizedClassName = normalizeClassName(selectable.className);
let set = selectables.instanceKeys.get(normalizedClassName);
if (!set) {
set = new Set();
}
if (!set.has(selectable.id)) {
set.add(selectable.id);
selectables.instanceKeys.set(normalizedClassName, set);
hasChanged = true;
}
}
else if (!selectables.custom.has(selectable.identifier)) {
selectables.custom.set(selectable.identifier, selectable);
hasChanged = true;
}
}
return hasChanged;
}
Selectables.add = add;
/**
* Removes one or more selectables from a `Selectables` object.
* @param selectables `Selectables` object to remove selectables for
* @param values Selectables to remove.
* @public
*/
function remove(selectables, values) {
let hasChanged = false;
for (const selectable of values) {
if (Selectable.isInstanceKey(selectable)) {
const normalizedClassName = normalizeClassName(selectable.className);
const set = selectables.instanceKeys.get(normalizedClassName);
if (set && set.has(selectable.id)) {
set.delete(selectable.id);
hasChanged = true;
if (set.size === 0) {
selectables.instanceKeys.delete(normalizedClassName);
}
}
}
else if (selectables.custom.has(selectable.identifier)) {
selectables.custom.delete(selectable.identifier);
hasChanged = true;
}
}
return hasChanged;
}
Selectables.remove = remove;
/**
* Clear a `Selectables` object.
* @param selectables `Selectables` object to clear selectables for
* @public
*/
function clear(selectables) {
if (Selectables.size(selectables) === 0) {
return false;
}
selectables.instanceKeys = new Map();
selectables.custom = new Map();
return true;
}
Selectables.clear = clear;
/**
* Check whether at least one selectable passes a condition in a `Selectables` object.
* @param selectables `Selectables` object to check
* @public
*/
function some(selectables, callback) {
for (const entry of selectables.instanceKeys) {
for (const item of entry[1]) {
if (callback({ className: entry[0], id: item })) {
return true;
}
}
}
for (const entry of selectables.custom) {
if (callback(entry[1])) {
return true;
}
}
return false;
}
Selectables.some = some;
/**
* Iterate over all keys in a `Selectables` object.
* @param selectables `Selectables` object to iterate over
* @public
*/
function forEach(selectables, callback) {
let index = 0;
selectables.instanceKeys.forEach((ids, className) => {
ids.forEach((id) => callback({ className, id }, index++));
});
selectables.custom.forEach((data) => {
callback(data, index++);
});
}
Selectables.forEach = forEach;
/**
* Load all instance keys from the given `Selectables` object.
* @param selectables `Selectables` object to load instance keys from
* @public
*/
function load(selectables) {
return (0, rxjs_for_await_1.eachValueFrom)((0, rxjs_1.merge)((0, rxjs_1.from)(selectables.instanceKeys).pipe((0, rxjs_1.mergeMap)(([className, ids]) => (0, rxjs_1.from)(ids).pipe((0, rxjs_1.map)((id) => ({ className, id }))))), (0, rxjs_1.from)(selectables.custom).pipe((0, rxjs_1.mergeMap)(([_, selectable]) => (0, rxjs_1.from)(selectable.loadInstanceKeys())))));
}
Selectables.load = load;
})(Selectables || (exports.Selectables = Selectables = {}));
function normalizeClassName(fullClassName) {
return fullClassName === exports.TRANSIENT_ELEMENT_CLASSNAME ? fullClassName : (0, presentation_shared_1.normalizeFullClassName)(fullClassName);
}
//# sourceMappingURL=Selectable.js.map