@itwin/presentation-components
Version:
React components based on iTwin.js Presentation library
155 lines • 7.71 kB
JavaScript
;
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