@itwin/presentation-components
Version:
React components based on iTwin.js Presentation library
115 lines • 6.62 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
/*---------------------------------------------------------------------------------------------
* 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
*/
import { useCallback, useEffect, useMemo } from "react";
import { PropertyFilterBuilderRuleValue, usePropertyFilterBuilder } from "@itwin/components-react";
import { assert } from "@itwin/core-bentley";
import { NavigationPropertyEditorContextProvider } from "../properties/editors/NavigationPropertyEditorContext.js";
import { UniquePropertyValuesSelector } from "../properties/inputs/UniquePropertyValuesSelector.js";
import { InstanceFilterBuilder, usePresentationInstanceFilteringProps } from "./InstanceFilterBuilder.js";
import { createFilterClassExpression, createInstanceFilterDefinitionBase } from "./InstanceFilterConverter.js";
import { PresentationInstanceFilter } from "./PresentationInstanceFilter.js";
import { PresentationInstanceFilterProperty } from "./PresentationInstanceFilterProperty.js";
import { createInstanceFilterPropertyInfos, useFilterBuilderNavigationPropertyEditorContextProviderProps } from "./Utils.js";
/**
* Function that checks if supplied [[PresentationInstanceFilter]] is [[PresentationInstanceFilterConditionGroup]].
* @beta
* @deprecated in 5.0. Use `PresentationInstanceFilter.isConditionGroup` instead.
*/
/* c8 ignore next 3 */
export function isPresentationInstanceFilterConditionGroup(filter) {
return PresentationInstanceFilter.isConditionGroup(filter);
}
/**
* Converts [[PresentationInstanceFilter]] into [InstanceFilterDefinition]($presentation-common) that can be passed
* to [PresentationManager]($presentation-frontend) through request options in order to filter results.
* @beta
* @deprecated in 5.0. Use `createInstanceFilterDefinition` instead.
*/
/* c8 ignore next 3 */
export async function convertToInstanceFilterDefinition(filter, imodel) {
return createInstanceFilterDefinitionBase(filter, imodel);
}
/**
* Custom hook that collects properties from descriptor for filter building.
* @public
*/
export function useInstanceFilterPropertyInfos({ descriptor }) {
const propertyInfos = useMemo(() => createInstanceFilterPropertyInfos(descriptor), [descriptor]);
const propertyRenderer = useCallback((name) => {
const instanceFilterPropertyInfo = propertyInfos.find((info) => info.propertyDescription.name === name);
assert(instanceFilterPropertyInfo !== undefined);
return (_jsx(PresentationInstanceFilterProperty, { propertyDescription: instanceFilterPropertyInfo.propertyDescription, fullClassName: instanceFilterPropertyInfo.className, categoryLabel: instanceFilterPropertyInfo.categoryLabel }));
}, [propertyInfos]);
return {
propertyInfos,
propertyRenderer,
};
}
/**
* Custom renderer of the filter rule value input. It extends default value input functionality:
* - For `IsEqual` and `IsNotEqual` operators it renders a selector with unique property values. Unique values are collected from
* the instances described by the descriptor ([[PresentationFilterBuilderValueRendererProps.descriptor]] and [[PresentationFilterBuilderValueRendererProps.descriptorInputKeys]]).
* - For kind of quantity properties it renders input with units support.
*
* @public
*/
export function PresentationFilterBuilderValueRenderer({ imodel, descriptor, descriptorInputKeys, selectedClasses, ...props }) {
const navigationPropertyContextProviderProps = useFilterBuilderNavigationPropertyEditorContextProviderProps(imodel, descriptor);
if (props.operator === "is-equal" || props.operator === "is-not-equal") {
return (_jsx(UniquePropertyValuesSelector, { ...props, imodel: imodel, descriptor: descriptor, descriptorInputKeys: descriptorInputKeys, selectedClasses: selectedClasses }));
}
return (_jsx(NavigationPropertyEditorContextProvider, { ...navigationPropertyContextProviderProps, children: _jsx(PropertyFilterBuilderRuleValue, { ...props }) }));
}
/**
* Component for building complex instance filters for filtering content and nodes produced
* by [PresentationManager]($presentation-frontend).
*
* @public
*/
export function PresentationInstanceFilterBuilder(props) {
const { imodel, descriptor, onInstanceFilterChanged, initialFilter } = props;
const { rootGroup, actions, buildFilter } = usePropertyFilterBuilder({
initialFilter: initialFilter?.filter ? PresentationInstanceFilter.toComponentsPropertyFilter(descriptor, initialFilter.filter) : undefined,
});
const filteringProps = usePresentationInstanceFilteringProps(descriptor, imodel, initialFilter?.usedClasses);
useEffect(() => {
const filter = buildFilter({ ignoreErrors: true });
onInstanceFilterChanged(filter ? { filter: PresentationInstanceFilter.fromComponentsPropertyFilter(descriptor, filter), usedClasses: filteringProps.selectedClasses } : undefined);
}, [descriptor, buildFilter, onInstanceFilterChanged, filteringProps.selectedClasses]);
const onSelectedClassesChanged = (classIds) => {
filteringProps.onSelectedClassesChanged(classIds);
actions.removeAllItems();
};
return (_jsx(InstanceFilterBuilder, { ...filteringProps, onSelectedClassesChanged: onSelectedClassesChanged, rootGroup: rootGroup, actions: actions, imodel: imodel, descriptor: descriptor }));
}
/**
* Creates [InstanceFilterDefinition]($presentation-common) from [[PresentationInstanceFilterInfo]]. Created definition
* can be passed to [PresentationManager]($presentation-frontend) through request options in order to filter results.
* @public
*/
export async function createInstanceFilterDefinition(info, imodel) {
if (!info.filter) {
return { expression: createFilterClassExpression(info.usedClasses), selectClassName: "" };
}
const instanceFilter = await createInstanceFilterDefinitionBase(info.filter, imodel);
if (info.usedClasses.length === 0) {
return instanceFilter;
}
return {
...instanceFilter,
expression: `${wrap(instanceFilter.expression)} AND ${createFilterClassExpression(info.usedClasses)}`,
};
}
function wrap(expression) {
if (expression.startsWith("(") && expression.endsWith(")")) {
return expression;
}
return `(${expression})`;
}
//# sourceMappingURL=PresentationFilterBuilder.js.map