UNPKG

@itwin/presentation-common

Version:

Common pieces for iModel.js presentation packages

263 lines • 12.4 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Content */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Descriptor = exports.SortDirection = exports.ContentFlags = exports.SelectClassInfo = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const EC_js_1 = require("../EC.js"); const Utils_js_1 = require("../Utils.js"); const Category_js_1 = require("./Category.js"); const Fields_js_1 = require("./Fields.js"); /** @public */ var SelectClassInfo; (function (SelectClassInfo) { /** Deserialize [[SelectClassInfo]] from compressed JSON */ function fromCompressedJSON(json, classesMap) { (0, core_bentley_1.assert)(classesMap.hasOwnProperty(json.selectClassInfo)); return { selectClassInfo: { id: json.selectClassInfo, ...classesMap[json.selectClassInfo] }, isSelectPolymorphic: json.isSelectPolymorphic, ...(json.navigationPropertyClasses ? { navigationPropertyClasses: json.navigationPropertyClasses.map((item) => EC_js_1.RelatedClassInfo.fromCompressedJSON(item, classesMap)) } : undefined), ...(json.relatedInstancePaths ? { relatedInstancePaths: json.relatedInstancePaths.map((rip) => rip.map((item) => EC_js_1.RelatedClassInfo.fromCompressedJSON(item, classesMap))) } : undefined), ...(json.pathFromInputToSelectClass ? { pathFromInputToSelectClass: json.pathFromInputToSelectClass.map((item) => EC_js_1.RelatedClassInfoWithOptionalRelationship.fromCompressedJSON(item, classesMap)), } : undefined), ...(json.relatedPropertyPaths ? { relatedPropertyPaths: json.relatedPropertyPaths.map((path) => path.map((item) => EC_js_1.RelatedClassInfo.fromCompressedJSON(item, classesMap))) } : undefined), }; } SelectClassInfo.fromCompressedJSON = fromCompressedJSON; /** Serialize [[SelectClassInfo]] to compressed JSON */ function toCompressedJSON(selectClass, classesMap) { const { id, ...leftOverClassInfo } = selectClass.selectClassInfo; classesMap[id] = leftOverClassInfo; return { selectClassInfo: id, isSelectPolymorphic: selectClass.isSelectPolymorphic, ...(selectClass.relatedInstancePaths ? { relatedInstancePaths: selectClass.relatedInstancePaths.map((rip) => rip.map((item) => EC_js_1.RelatedClassInfo.toCompressedJSON(item, classesMap))) } : undefined), ...(selectClass.navigationPropertyClasses ? { navigationPropertyClasses: selectClass.navigationPropertyClasses.map((propertyClass) => EC_js_1.RelatedClassInfo.toCompressedJSON(propertyClass, classesMap)), } : undefined), ...(selectClass.pathFromInputToSelectClass ? { pathFromInputToSelectClass: selectClass.pathFromInputToSelectClass.map((item) => EC_js_1.RelatedClassInfoWithOptionalRelationship.toCompressedJSON(item, classesMap)), } : undefined), ...(selectClass.relatedPropertyPaths ? { relatedPropertyPaths: selectClass.relatedPropertyPaths.map((path) => path.map((relatedClass) => EC_js_1.RelatedClassInfo.toCompressedJSON(relatedClass, classesMap))), } : undefined), }; } SelectClassInfo.toCompressedJSON = toCompressedJSON; })(SelectClassInfo || (exports.SelectClassInfo = SelectClassInfo = {})); /** * Flags that control content format. * @public */ var ContentFlags; (function (ContentFlags) { /** Each content record only has [[InstanceKey]] and no data */ ContentFlags[ContentFlags["KeysOnly"] = 1] = "KeysOnly"; /** Each content record additionally has a display label */ ContentFlags[ContentFlags["ShowLabels"] = 4] = "ShowLabels"; /** All content records are merged into a single record (see [Merging values]($docs/presentation/content/terminology#value-merging)) */ ContentFlags[ContentFlags["MergeResults"] = 8] = "MergeResults"; /** Content has only distinct values */ ContentFlags[ContentFlags["DistinctValues"] = 16] = "DistinctValues"; /** Doesn't create property or calculated fields. Can be used in conjunction with [[ShowLabels]]. */ ContentFlags[ContentFlags["NoFields"] = 32] = "NoFields"; /** * Set related input keys on [[Item]] objects when creating content. This helps identify which [[Item]] is associated to which * given input key at the cost of performance creating those items. */ ContentFlags[ContentFlags["IncludeInputKeys"] = 256] = "IncludeInputKeys"; })(ContentFlags || (exports.ContentFlags = ContentFlags = {})); /** * Data sorting direction * @public */ var SortDirection; (function (SortDirection) { SortDirection[SortDirection["Ascending"] = 0] = "Ascending"; SortDirection[SortDirection["Descending"] = 1] = "Descending"; })(SortDirection || (exports.SortDirection = SortDirection = {})); /** * Data structure that describes content: fields, sorting, filtering, format, etc. * Descriptor may be changed to control how content is created. * * @public */ class Descriptor { /** Id of the connection used to create the descriptor */ connectionId; /** Hash of the input keys used to create the descriptor */ inputKeysHash; /** Selection info used to create the descriptor */ selectionInfo; /** Display type used to create the descriptor */ displayType; /** A list of classes that will be selected when creating content with this descriptor */ selectClasses; /** A list of content field categories used in this descriptor */ categories; /** A list of fields contained in the descriptor */ fields; /** [[ContentFlags]] used to create the descriptor */ contentFlags; /** * A ruleset used to create this descriptor. * Only set if descriptor is created using a ruleset different from the input ruleset, e.g. when creating a hierarchy level descriptor. */ ruleset; /** Field used to sort the content */ sortingField; /** Sorting direction */ sortDirection; /** * [ECExpression]($docs/presentation/advanced/ECExpressions.md) for filtering content by * select fields. * * This is different from [[instanceFilter]] as filtering is applied on the union of all selects, * which removes access to content instance property values. Instead of referencing properties * through `this.PropertyName` alias, the expression should reference them by field names. In cases * when properties field merges multiple properties, this allows applying the filter on all of them * at once. This is useful for filtering table rows by column value, when content is displayed in * table format. */ fieldsFilterExpression; /** * Instances filter that allows filtering content by class, properties of specific class * or properties of instances related to the content instance. * * This is different from [[fieldsFilterExpression]] as filter is applied at a lower level - on * specific select class rather than a union of multiple select classes. This means the filter has * access to properties of that class and they can be referenced using symbols like `this.Property`. * This is useful for filtering instances of specific class. */ instanceFilter; /** Construct a new Descriptor using a [[DescriptorSource]] */ constructor(source) { this.connectionId = source.connectionId; this.inputKeysHash = source.inputKeysHash; this.selectionInfo = source.selectionInfo; this.displayType = source.displayType; this.contentFlags = source.contentFlags; this.selectClasses = [...source.selectClasses]; this.categories = [...source.categories]; this.fields = [...source.fields]; this.sortingField = source.sortingField; this.sortDirection = source.sortDirection; this.fieldsFilterExpression = source.fieldsFilterExpression; this.instanceFilter = source.instanceFilter; this.ruleset = source.ruleset; } /** Serialize [[Descriptor]] to JSON */ toJSON() { const classesMap = {}; const selectClasses = this.selectClasses.map((selectClass) => SelectClassInfo.toCompressedJSON(selectClass, classesMap)); const fields = this.fields.map((field) => field.toCompressedJSON(classesMap)); return (0, Utils_js_1.omitUndefined)({ displayType: this.displayType, contentFlags: this.contentFlags, categories: this.categories.map(Category_js_1.CategoryDescription.toJSON), fields, selectClasses, classesMap, connectionId: this.connectionId ?? "", inputKeysHash: this.inputKeysHash ?? "", sortingFieldName: this.sortingField?.name, sortDirection: this.sortDirection, fieldsFilterExpression: this.fieldsFilterExpression, instanceFilter: this.instanceFilter, selectionInfo: this.selectionInfo, ruleset: this.ruleset, }); } /** Deserialize [[Descriptor]] from JSON */ static fromJSON(json) { if (!json) { return undefined; } const { categories: jsonCategories, selectClasses: jsonSelectClasses, fields: jsonFields, connectionId, inputKeysHash, classesMap, sortingFieldName, ...leftOverJson } = json; const categories = Category_js_1.CategoryDescription.listFromJSON(jsonCategories); const selectClasses = jsonSelectClasses.map((jsc) => SelectClassInfo.fromCompressedJSON(jsc, classesMap)); const fields = this.getFieldsFromJSON(jsonFields, (fieldJson) => Fields_js_1.Field.fromCompressedJSON(fieldJson, classesMap, categories)); return new Descriptor({ ...leftOverJson, ...(connectionId ? /* c8 ignore next */ { connectionId } : undefined), ...(inputKeysHash ? /* c8 ignore next */ { inputKeysHash } : undefined), selectClasses, categories, fields, sortingField: (0, Fields_js_1.getFieldByName)(fields, sortingFieldName, true), }); } static getFieldsFromJSON(json, factory) { return json .map((fieldJson) => { const field = factory(fieldJson); if (field) { field.rebuildParentship(); } return field; }) .filter((field) => !!field); } /** * Get field by its name * @param name Name of the field to find * @param recurse Recurse into nested fields */ getFieldByName(name, recurse) { return (0, Fields_js_1.getFieldByName)(this.fields, name, recurse); } /** * Get field by its descriptor. */ getFieldByDescriptor(fieldDescriptor, recurse) { return (0, Fields_js_1.getFieldByDescriptor)(this.fields, fieldDescriptor, recurse); } /** * Create descriptor overrides object from this descriptor. * @public */ createDescriptorOverrides() { const overrides = {}; if (this.displayType) { overrides.displayType = this.displayType; } if (this.contentFlags !== 0) { overrides.contentFlags = this.contentFlags; } if (this.fieldsFilterExpression) { overrides.fieldsFilterExpression = this.fieldsFilterExpression; } if (this.instanceFilter) { overrides.instanceFilter = this.instanceFilter; } if (this.sortingField) { overrides.sorting = { field: this.sortingField.getFieldDescriptor(), direction: this.sortDirection ?? SortDirection.Ascending }; } return overrides; } } exports.Descriptor = Descriptor; //# sourceMappingURL=Descriptor.js.map