Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
public async computeSelection(imodel: IModelConnection, ids: Id64Arg, scope: SelectionScope | string): Promise {
const scopeId = getScopeId(scope);
// convert ids input to array
if (typeof ids === "string")
ids = [ids];
else if (ids instanceof Set)
ids = [...ids];
// compute selection in batches to avoid HTTP 413
const keys = new KeySet();
const batchSize = DEFAULT_KEYS_BATCH_SIZE;
const batchesCount = Math.ceil(ids.length / batchSize);
const batchKeyPromises = [];
for (let batchIndex = 0; batchIndex < batchesCount; ++batchIndex) {
const batchStart = batchSize * batchIndex;
const batchEnd = (batchStart + batchSize > ids.length) ? ids.length : (batchStart + batchSize);
const batchIds = (0 === batchIndex && ids.length <= batchEnd) ? ids : ids.slice(batchStart, batchEnd);
batchKeyPromises.push(this._rpcRequestsHandler.computeSelection({ imodel: imodel.iModelToken }, batchIds, scopeId));
}
const batchKeys = (await Promise.all(batchKeyPromises)).map(KeySet.fromJSON);
batchKeys.forEach((bk) => keys.add(bk));
return keys;
}
}
const createNestedContentRecord = (field: NestedContentField, item: Item, props: NestedContentCreationProps & PropertyDescriptionCreationProps): PropertyRecord => {
const isMerged = item.isFieldMerged(field.name);
let value: PropertyValue;
if (isMerged) {
const displayValue = item.displayValues[field.name];
if (!DisplayValue.isPrimitive(displayValue))
throw new PresentationError(PresentationStatus.Error, "displayValue should be primitive");
// if the value is merged, just take the display value
value = {
valueFormat: UiPropertyValueFormat.Primitive,
value: undefined,
displayValue: (undefined !== displayValue) ? displayValue.toString() : "",
};
} else {
const dictionaryValue = item.values[field.name];
if (!Value.isNestedContent(dictionaryValue))
throw new PresentationError(PresentationStatus.Error, "value should be nested content");
// nested content value is in NestedContent[] format
const nestedContentArray: NestedContentValue[] = dictionaryValue;
value = {
valueFormat: UiPropertyValueFormat.Array,
items: nestedContentArray.map((r) => createNestedStructRecord(field, r, props)),
itemsTypeName: field.type.typeName,
exclusiveIncludePath: pathToFieldFromRoot,
hiddenFieldPaths: filterMatchingFieldPaths(hiddenFieldPaths, rootField),
});
}
let item = this._contentItem;
// need to remove the last element because the Field information is in `field`
const pathUpToField = pathToRootField.slice(undefined, -1);
let namePrefix: string | undefined;
for (const parentField of pathUpToField) {
if (item.isFieldMerged(parentField.name))
return this.createRecord(field, true, hiddenFieldPaths);
const nestedContentValues = item.values[parentField.name];
if (!Value.isNestedContent(nestedContentValues))
throw new PresentationError(PresentationStatus.Error, "value should be nested content");
if (nestedContentValues.length === 0)
return undefined;
namePrefix = applyOptionalPrefix(parentField.name, namePrefix);
if (nestedContentValues.length > 1) {
const mergedItem = new Item(nestedContentValues.reduce((keys, ncv) => {
keys.push(...ncv.primaryKeys);
return keys;
}, new Array()), "", "", undefined, { [field.name]: undefined }, { [field.name]: undefined }, [field.name]);
return ContentBuilder.createPropertyRecord(field, mergedItem, { namePrefix });
}
const nestedContentValue = nestedContentValues[0];
item = new Item(nestedContentValue.primaryKeys, "", "", undefined, nestedContentValue.values,
let value: PropertyValue;
if (isMerged) {
const displayValue = item.displayValues[field.name];
if (!DisplayValue.isPrimitive(displayValue))
throw new PresentationError(PresentationStatus.Error, "displayValue should be primitive");
// if the value is merged, just take the display value
value = {
valueFormat: UiPropertyValueFormat.Primitive,
value: undefined,
displayValue: (undefined !== displayValue) ? displayValue.toString() : "",
};
} else {
const dictionaryValue = item.values[field.name];
if (!Value.isNestedContent(dictionaryValue))
throw new PresentationError(PresentationStatus.Error, "value should be nested content");
// nested content value is in NestedContent[] format
const nestedContentArray: NestedContentValue[] = dictionaryValue;
value = {
valueFormat: UiPropertyValueFormat.Array,
items: nestedContentArray.map((r) => createNestedStructRecord(field, r, props)),
itemsTypeName: field.type.typeName,
};
// if array contains just one value, replace it with the value
if (1 === value.items.length)
value = value.items[0].value!;
}
const record = new PropertyRecord(value, ContentBuilder.createPropertyDescription(field, props));
if (isMerged)
record.isMerged = true;
if (field.isReadonly || isMerged)
if (!this._selectionHandler)
return false;
const selection = this._selectionHandler.getSelection();
// consider node selected if it's key is in selection
const nodeKey = this.props.dataProvider.getNodeKey(node);
if (selection.has(nodeKey))
return true;
// ... or if it's an ECInstances node and any of instance keys is in selection
if (NodeKey.isInstancesNodeKey(nodeKey) && nodeKey.instanceKeys.some((instanceKey) => selection.has(instanceKey)))
return true;
// ... or if it's an ECInstance node and instance key is in selection
if (NodeKey.isInstanceNodeKey(nodeKey) && selection.has(nodeKey.instanceKey))
return true;
return false;
}
protected shouldSelectNode(node: TreeNodeItem, selection: Readonly) {
const nodeKey = this.getNodeKey(node);
if (nodeKey === undefined)
return false;
// consider node selected if it's key is in selection
if (selection.has(nodeKey))
return true;
// ... or if it's an ECInstances node and any of instance keys is in selection
if (NodeKey.isInstancesNodeKey(nodeKey) && nodeKey.instanceKeys.some((instanceKey) => selection.has(instanceKey)))
return true;
// ... or if it's an ECInstance node and instance key is in selection
if (NodeKey.isInstanceNodeKey(nodeKey) && selection.has(nodeKey.instanceKey))
return true;
return false;
}
const createNestedContentRecord = (field: NestedContentField, item: Item, props: NestedContentCreationProps & PropertyDescriptionCreationProps): PropertyRecord => {
const isMerged = item.isFieldMerged(field.name);
let value: PropertyValue;
if (isMerged) {
const displayValue = item.displayValues[field.name];
if (!DisplayValue.isPrimitive(displayValue))
throw new PresentationError(PresentationStatus.Error, "displayValue should be primitive");
// if the value is merged, just take the display value
value = {
valueFormat: UiPropertyValueFormat.Primitive,
value: undefined,
displayValue: (undefined !== displayValue) ? displayValue.toString() : "",
};
} else {
const dictionaryValue = item.values[field.name];
if (!Value.isNestedContent(dictionaryValue))
throw new PresentationError(PresentationStatus.Error, "value should be nested content");
// nested content value is in NestedContent[] format
const nestedContentArray: NestedContentValue[] = dictionaryValue;
value = {
valueFormat: UiPropertyValueFormat.Array,
items: nestedContentArray.map((r) => createNestedStructRecord(field, r, props)),
const createNestedStructRecord = (field: NestedContentField, nestedContent: NestedContentValue, props: NestedContentCreationProps & PropertyDescriptionCreationProps): PropertyRecord => {
const exclusiveIncludePath = props.exclusiveIncludePath ? [...props.exclusiveIncludePath] : undefined;
let exclusiveIncludePathField: Field | undefined;
if (exclusiveIncludePath && 0 !== exclusiveIncludePath.length) {
exclusiveIncludePathField = exclusiveIncludePath.shift();
}
const item = new Item(nestedContent.primaryKeys, "", "",
field.contentClassInfo, nestedContent.values, nestedContent.displayValues, nestedContent.mergedFieldNames);
const namePrefix = applyOptionalPrefix(field.name, props.namePrefix);
const members: { [name: string]: PropertyRecord } = {};
for (const nestedField of field.nestedFields) {
if (exclusiveIncludePathField && exclusiveIncludePathField !== nestedField) {
// we know specific field that we want - skip if the current field doesn't match
continue;
}
let hiddenFieldPaths = props.hiddenFieldPaths;
if (hiddenFieldPaths) {
if (hiddenFieldPaths.some((path) => path.length === 1 && path[0] === nestedField)) {
// we know paths of fields that we want hidden - skip if the current field matches any of those paths
continue;
}
// pick all paths that start with current field
protected shouldSelectNode(node: TreeNodeItem, selection: Readonly) {
const nodeKey = this.getNodeKey(node);
if (nodeKey === undefined)
return false;
// consider node selected if it's key is in selection
if (selection.has(nodeKey))
return true;
// ... or if it's an ECInstances node and any of instance keys is in selection
if (NodeKey.isInstancesNodeKey(nodeKey) && nodeKey.instanceKeys.some((instanceKey) => selection.has(instanceKey)))
return true;
// ... or if it's an ECInstance node and instance key is in selection
if (NodeKey.isInstanceNodeKey(nodeKey) && selection.has(nodeKey.instanceKey))
return true;
return false;
}
private isNodeSelected(node: TreeNodeItem): boolean {
if (!this._selectionHandler)
return false;
const selection = this._selectionHandler.getSelection();
// consider node selected if it's key is in selection
const nodeKey = this.props.dataProvider.getNodeKey(node);
if (selection.has(nodeKey))
return true;
// ... or if it's an ECInstances node and any of instance keys is in selection
if (NodeKey.isInstancesNodeKey(nodeKey) && nodeKey.instanceKeys.some((instanceKey) => selection.has(instanceKey)))
return true;
// ... or if it's an ECInstance node and instance key is in selection
if (NodeKey.isInstanceNodeKey(nodeKey) && selection.has(nodeKey.instanceKey))
return true;
return false;
}