UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

155 lines 7.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UniquePropertyValuesSelector = UniquePropertyValuesSelector; const jsx_runtime_1 = require("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. *--------------------------------------------------------------------------------------------*/ const react_1 = require("react"); const appui_abstract_1 = require("@itwin/appui-abstract"); const itwinui_react_1 = require("@itwin/itwinui-react"); const Utils_js_1 = require("../../common/Utils.js"); const Utils_js_2 = require("../../instance-filter-builder/Utils.js"); const ItemsLoader_js_1 = require("./ItemsLoader.js"); const UseUniquePropertyValuesLoader_js_1 = require("./UseUniquePropertyValuesLoader.js"); /** @internal */ function UniquePropertyValuesSelector(props) { const { imodel, descriptor, property, onChange, value, descriptorInputKeys, selectedClasses } = props; const [field, setField] = (0, react_1.useState)(() => (0, Utils_js_1.findField)(descriptor, (0, Utils_js_2.getInstanceFilterFieldName)(property))); const [searchInput, setSearchInput] = (0, react_1.useState)(""); const selectedValues = (0, react_1.useMemo)(() => getUniqueValueFromProperty(value)?.map((val) => val.displayValue), [value]); const ruleset = useUniquePropertyValuesRuleset(descriptor.ruleset, field, descriptorInputKeys, selectedClasses); const { selectOptions, loadedOptions, isLoading } = (0, UseUniquePropertyValuesLoader_js_1.useUniquePropertyValuesLoader)({ imodel, ruleset, field, descriptorInputKeys, typeName: property.typename, selectedValues, filterText: searchInput, }); const onValueChange = (0, react_1.useCallback)((newValues) => { const newSelectedValues = loadedOptions.filter((opt) => newValues.includes(opt.displayValue)); if (newSelectedValues.length === 0) { onChange({ valueFormat: appui_abstract_1.PropertyValueFormat.Primitive, displayValue: undefined, value: undefined, }); } else { const { displayValues, groupedRawValues } = (0, Utils_js_1.serializeUniqueValues)(newSelectedValues); onChange({ valueFormat: appui_abstract_1.PropertyValueFormat.Primitive, displayValue: displayValues, value: groupedRawValues, }); } }, [loadedOptions, onChange]); const emptyContent = (0, react_1.useMemo)(() => { return isLoading ? (0, Utils_js_1.translate)("unique-values-property-editor.loading-values") : (0, Utils_js_1.translate)("unique-values-property-editor.no-values"); }, [isLoading]); (0, react_1.useEffect)(() => { setField((0, Utils_js_1.findField)(descriptor, (0, Utils_js_2.getInstanceFilterFieldName)(property))); setSearchInput(""); }, [descriptor, property]); return ((0, jsx_runtime_1.jsx)(itwinui_react_1.ComboBox, { multiple: true, enableVirtualization: true, options: selectOptions, onChange: onValueChange, filterFunction: (options, inputValue) => { const filteredOptions = options .filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()) && option.value !== ItemsLoader_js_1.FILTER_WARNING_OPTION.value) .slice(0, ItemsLoader_js_1.VALUE_BATCH_SIZE); if (filteredOptions.length >= ItemsLoader_js_1.VALUE_BATCH_SIZE) { filteredOptions.push(ItemsLoader_js_1.FILTER_WARNING_OPTION); } return filteredOptions; }, emptyStateMessage: emptyContent, value: selectedValues, clearFilterOnOptionToggle: false, inputProps: { placeholder: (0, Utils_js_1.translate)("unique-values-property-editor.select-values"), size: "small", value: searchInput, onChange: (e) => setSearchInput(e.target.value), }, onHide: () => setSearchInput("") })); } function getUniqueValueFromProperty(propertyValue) { if (propertyValue?.valueFormat === appui_abstract_1.PropertyValueFormat.Primitive && typeof propertyValue.value === "string" && propertyValue.displayValue) { return (0, Utils_js_1.deserializeUniqueValues)(propertyValue.displayValue, propertyValue.value); } return []; } function useUniquePropertyValuesRuleset(descriptorRuleset, field, descriptorInputKeys, selectedClasses) { const [ruleset, setRuleset] = (0, react_1.useState)(); (0, react_1.useEffect)(() => { if (descriptorRuleset) { setRuleset(descriptorRuleset); return; } if (descriptorInputKeys && hasKeys(descriptorInputKeys)) { setRuleset({ id: "unique-instances-property-values", rules: [ { ruleType: "Content", specifications: [ { specType: "SelectedNodeInstances", acceptableClassNames: selectedClasses ? selectedClasses.map(({ name }) => name.split(/[\.:]/)[1]) : undefined, acceptablePolymorphically: true, }, ], }, ], }); return; } const classInfos = selectedClasses ?? getFieldClassInfos(field); if (classInfos.length === 0) { setRuleset(undefined); return; } setRuleset({ id: "unique-class-property-values", rules: [ { ruleType: "Content", specifications: [ { specType: "ContentInstancesOfSpecificClasses", classes: createSchemaClasses(classInfos), }, ], }, ], }); }, [field, descriptorRuleset, descriptorInputKeys, selectedClasses]); return ruleset; } function createSchemaClasses(infos) { const schemaClassMap = new Map(); infos.forEach((info) => { const [schemaName, className] = info.name.split(/[\.:]/); let classNames = schemaClassMap.get(schemaName); if (!classNames) { classNames = []; schemaClassMap.set(schemaName, classNames); } if (!classNames.includes(className)) { classNames.push(className); } }); const schemaClasses = [...schemaClassMap.entries()].map(([schemaName, classNames]) => ({ schemaName, classNames, arePolymorphic: true })); return schemaClasses.length === 1 ? schemaClasses[0] : schemaClasses; } function getFieldClassInfos(field) { if (field?.parent === undefined && field?.isPropertiesField()) { return field.properties.map((p) => p.property.classInfo); } let rootParentField = field?.parent; while (rootParentField?.parent !== undefined) { rootParentField = rootParentField.parent; } const lastStepToPrimaryClass = rootParentField?.pathToPrimaryClass.slice(-1).pop(); return lastStepToPrimaryClass ? [lastStepToPrimaryClass.targetClassInfo] : []; } function hasKeys(descriptorInputKeys) { return Array.isArray(descriptorInputKeys) ? descriptorInputKeys.length > 0 : !descriptorInputKeys.isEmpty; } //# sourceMappingURL=UniquePropertyValuesSelector.js.map