UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

156 lines 6.84 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 InstancesFilter */ Object.defineProperty(exports, "__esModule", { value: true }); exports.findBaseExpressionClassName = findBaseExpressionClassName; exports.createInstanceFilterDefinitionBase = createInstanceFilterDefinitionBase; exports.createFilterExpression = createFilterExpression; exports.createFilterClassExpression = createFilterClassExpression; const appui_abstract_1 = require("@itwin/appui-abstract"); const components_react_1 = require("@itwin/components-react"); const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const ECMetadataProvider_js_1 = require("./ECMetadataProvider.js"); const PresentationInstanceFilter_js_1 = require("./PresentationInstanceFilter.js"); /** @internal */ async function findBaseExpressionClassName(imodel, propertyClassNames) { if (propertyClassNames.length === 1) { return propertyClassNames[0]; } const metadataProvider = (0, ECMetadataProvider_js_1.getIModelMetadataProvider)(imodel); const [firstClassName, ...restClassNames] = propertyClassNames; let currentBaseClassInfo = await metadataProvider.getECClassInfo(firstClassName); /* c8 ignore next 3 */ if (!currentBaseClassInfo) { return firstClassName; } for (const propClassName of restClassNames) { const propClassInfo = await metadataProvider.getECClassInfo(propClassName); if (propClassInfo && propClassInfo.isDerivedFrom(currentBaseClassInfo.id)) { currentBaseClassInfo = propClassInfo; } } return currentBaseClassInfo.name; } /** @internal */ async function createInstanceFilterDefinitionBase(filter, imodel) { const { rules, propertyClassNames, relatedInstances } = PresentationInstanceFilter_js_1.PresentationInstanceFilter.toGenericInstanceFilter(filter); const filterExpression = createFilterExpression(rules); const baseClassName = await findBaseExpressionClassName(imodel, propertyClassNames); return { expression: filterExpression, selectClassName: baseClassName, relatedInstances: relatedInstances.map((related) => ({ pathFromSelectToPropertyClass: related.path.map((step) => ({ sourceClassName: step.sourceClassName, targetClassName: step.targetClassName, relationshipName: step.relationshipClassName, isForwardRelationship: step.isForwardRelationship, })), alias: related.alias, })), }; } /** @internal */ function createFilterExpression(filter) { return createComparisonExpression(filter); } function createComparisonExpression(filter) { if (core_common_1.GenericInstanceFilter.isFilterRuleGroup(filter)) { return createExpressionFromGroup(filter); } const { propertyName, propertyTypeName, sourceAlias, operator, value } = filter; return createComparison(propertyName, propertyTypeName, sourceAlias, operator, value); } function createExpressionFromGroup(group) { const convertedConditions = group.rules.map((rule) => createComparisonExpression(rule)); return `(${convertedConditions.join(` ${getGroupOperatorString(group.operator)} `)})`; } /** @internal */ function createFilterClassExpression(usedClasses) { if (usedClasses.length === 0) { return ""; } return `(${usedClasses.map((classInfo) => `this.IsOfClass(${classInfo.id})`).join(" OR ")})`; } function createComparison(propertyName, type, alias, operator, propValue) { const propertyAccessor = `${alias}.${propertyName}`; const operatorExpression = getRuleOperatorString(operator); if (propValue === undefined || (0, components_react_1.isUnaryPropertyFilterOperator)(operator)) { return `${propertyAccessor} ${operatorExpression}`; } const value = propValue.rawValue; if (operator === "like" && typeof value === "string") { return `${propertyAccessor} ${operatorExpression} "%${escapeString(value)}%"`; } let valueExpression = ""; switch (typeof value) { case "string": valueExpression = `"${escapeString(value)}"`; break; case "number": valueExpression = value.toString(); break; } if (type === appui_abstract_1.StandardTypeNames.Point2d || type === appui_abstract_1.StandardTypeNames.Point3d) { (0, core_bentley_1.assert)(core_common_1.GenericInstanceFilterRuleValue.isPoint2d(value)); return createPointComparison(value, operatorExpression, propertyAccessor); } if (type === "navigation") { return `${propertyAccessor}.Id ${operatorExpression} ${value.id}`; } if (type === "double") { return `CompareDoubles(${propertyAccessor}, ${valueExpression}) ${operatorExpression} 0`; } if (type === "dateTime") { return `CompareDateTimes(${propertyAccessor}, ${valueExpression}) ${operatorExpression} 0`; } return `${propertyAccessor} ${operatorExpression} ${valueExpression}`; } function getGroupOperatorString(operator) { switch (operator) { case "and": return "AND"; case "or": return "OR"; } } function getRuleOperatorString(operator) { switch (operator) { case "is-true": return "= TRUE"; case "is-false": return "= FALSE"; case "is-equal": return "="; case "is-not-equal": return "<>"; case "greater": return ">"; case "greater-or-equal": return ">="; case "less": return "<"; case "less-or-equal": return "<="; case "like": return "~"; case "is-null": return "= NULL"; case "is-not-null": return "<> NULL"; } } function escapeString(str) { return str.replace(/"/g, `""`); } function createPointComparison(point, operatorExpression, propertyAccessor) { const logicalOperator = operatorExpression === "=" ? "AND" : "OR"; return `(CompareDoubles(${propertyAccessor}.x, ${point.x}) ${operatorExpression} 0) ${logicalOperator} (CompareDoubles(${propertyAccessor}.y, ${point.y}) ${operatorExpression} 0)${core_common_1.GenericInstanceFilterRuleValue.isPoint3d(point) ? ` ${logicalOperator} (CompareDoubles(${propertyAccessor}.z, ${point.z}) ${operatorExpression} 0)` : ""}`; } //# sourceMappingURL=InstanceFilterConverter.js.map