@itwin/presentation-components
Version:
React components based on iTwin.js Presentation library
78 lines • 4.57 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment } 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.
*--------------------------------------------------------------------------------------------*/
import "./NavigationPropertyTargetSelector.scss";
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import { PropertyValueFormat } from "@itwin/appui-abstract";
import { PropertyValueRendererManager } from "@itwin/components-react";
import { ComboBox } from "@itwin/itwinui-react";
import { LabelDefinition } from "@itwin/presentation-common";
import { translate } from "../../common/Utils.js";
import { FILTER_WARNING_OPTION, VALUE_BATCH_SIZE } from "./ItemsLoader.js";
import { useNavigationPropertyTargetsLoader, useNavigationPropertyTargetsRuleset } from "./UseNavigationPropertyTargetsLoader.js";
/** @internal */
export const NavigationPropertyTargetSelector = forwardRef((props, ref) => {
const { imodel, getNavigationPropertyInfo, propertyRecord, onCommit } = props;
const [selectedTarget, setSelectedTarget] = useState(() => getNavigationTargetFromPropertyRecord(propertyRecord));
const [searchInput, setSearchInput] = useState();
const targetsRuleset = useNavigationPropertyTargetsRuleset(getNavigationPropertyInfo, propertyRecord.property);
const { selectOptions, loadedOptions, isLoading } = useNavigationPropertyTargetsLoader({
imodel,
ruleset: targetsRuleset,
filterText: searchInput,
initialSelectedTarget: selectedTarget?.label.displayValue,
});
const divRef = useRef(null);
const emptyContent = useMemo(() => {
return isLoading ? translate("navigation-property-editor.loading-target-instances") : translate("navigation-property-editor.no-target-instances");
}, [isLoading]);
const onChange = useCallback((newValue) => {
const newSelectedTarget = loadedOptions.find((loadedOption) => loadedOption.label.displayValue === newValue);
setSelectedTarget(newSelectedTarget);
newSelectedTarget && onCommit && onCommit({ propertyRecord, newValue: getPropertyValue(newSelectedTarget) });
}, [loadedOptions, onCommit, propertyRecord]);
useImperativeHandle(ref, () => ({
getValue: () => getPropertyValue(selectedTarget),
htmlElement: divRef.current,
}), [selectedTarget]);
useEffect(() => {
setSelectedTarget(getNavigationTargetFromPropertyRecord(propertyRecord));
}, [propertyRecord]);
if (!targetsRuleset) {
return _jsx(ReadonlyNavigationPropertyTarget, { record: props.propertyRecord });
}
return (_jsx(ComboBox, { multiple: false, enableVirtualization: true, options: selectOptions, onChange: onChange, filterFunction: (options, inputValue) => {
const filteredOptions = options
.filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()) && option.value !== FILTER_WARNING_OPTION.value)
.slice(0, VALUE_BATCH_SIZE);
if (filteredOptions.length >= VALUE_BATCH_SIZE) {
filteredOptions.push(FILTER_WARNING_OPTION);
}
return filteredOptions;
}, emptyStateMessage: emptyContent, value: selectedTarget?.label.displayValue, inputProps: {
placeholder: translate("navigation-property-editor.select-target-instance"),
size: "small",
onChange: (e) => {
setSearchInput(e.target.value);
},
} }));
});
NavigationPropertyTargetSelector.displayName = "NavigationPropertyTargetSelector";
/** @internal */
export function ReadonlyNavigationPropertyTarget(props) {
const { record } = props;
return _jsx(_Fragment, { children: PropertyValueRendererManager.defaultManager.render(record) });
}
function getPropertyValue(target) {
return { valueFormat: PropertyValueFormat.Primitive, value: target?.key, displayValue: target?.label.displayValue };
}
function getNavigationTargetFromPropertyRecord(record) {
const value = record.value;
if (value.valueFormat !== PropertyValueFormat.Primitive || !value.value || !value.displayValue) {
return undefined;
}
return { key: value.value, label: LabelDefinition.fromLabelString(value.displayValue) };
}
//# sourceMappingURL=NavigationPropertyTargetSelector.js.map