UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

125 lines 5.12 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import "../../common/DisposePolyfill.js"; import { useEffect, useMemo, useState } from "react"; import { from, map, mergeMap, toArray } from "rxjs"; import { DisplayValue, KeySet } from "@itwin/presentation-common"; import { Presentation } from "@itwin/presentation-frontend"; import { translate } from "../../common/Utils.js"; import { FILTER_WARNING_OPTION, ItemsLoader, VALUE_BATCH_SIZE } from "./ItemsLoader.js"; /** @internal */ export function useUniquePropertyValuesLoader({ imodel, ruleset, field, descriptorInputKeys, typeName, filterText, selectedValues, }) { const [itemsLoader, setItemsLoader] = useState(); const [initialSelectedValues] = useState(selectedValues); const [state, setLoadedOptions] = useState({ options: [], isLoading: false, }); // Get initial loader and values useEffect(() => { setLoadedOptions({ options: [], isLoading: false }); if (!ruleset || !field) { return; } const loader = new ItemsLoader(() => { setLoadedOptions((prev) => ({ ...prev, isLoading: true })); }, (newItems) => { setLoadedOptions((prev) => ({ options: [...prev.options, ...newItems], isLoading: false, })); }, async (offset) => getItems({ imodel, offset, field: field.getFieldDescriptor(), ruleset, keys: new KeySet(descriptorInputKeys) }), (option) => option.displayValue); void loader.loadMatchingItems(initialSelectedValues); setItemsLoader(loader); return () => { loader[Symbol.dispose](); }; }, [imodel, ruleset, field, descriptorInputKeys, initialSelectedValues]); // On filter text change, check if more items need to be loaded useEffect(() => { if (!filterText || !itemsLoader) { return; } const timeout = setTimeout(() => { void itemsLoader.loadItems(filterText); }, 250); return () => { clearTimeout(timeout); }; }, [itemsLoader, filterText]); return { selectOptions: useMemo(() => { const options = state.options.map((option) => { return { label: formatOptionLabel(option.displayValue, typeName), value: option.displayValue, }; }); if (options.length >= VALUE_BATCH_SIZE) { options.push(FILTER_WARNING_OPTION); } return options; }, [state.options, typeName]), loadedOptions: state.options, isLoading: state.isLoading, }; } function formatOptionLabel(displayValue, type) { if (displayValue === "") { return translate("unique-values-property-editor.empty-value"); } switch (type) { case "dateTime": return new Date(displayValue).toLocaleString(undefined, { year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", fractionalSecondDigits: 3, }); case "shortDate": return new Date(displayValue).toLocaleDateString(); default: return displayValue; } } async function getItems({ imodel, field, offset, ruleset, keys, }) { const requestProps = { imodel, descriptor: {}, fieldDescriptor: field, rulesetOrId: ruleset, paging: { start: offset, size: VALUE_BATCH_SIZE }, keys, }; const items = await new Promise((resolve) => { (Presentation.presentation.getDistinctValuesIterator ? from(Presentation.presentation.getDistinctValuesIterator(requestProps)).pipe(mergeMap((result) => result.items), toArray()) : // eslint-disable-next-line @typescript-eslint/no-deprecated from(Presentation.presentation.getPagedDistinctValues(requestProps)).pipe(map((result) => result.items))).subscribe({ next: resolve, error: () => resolve([]), }); }); const hasMore = items.length === VALUE_BATCH_SIZE; const options = []; for (const option of items) { if (option.displayValue === undefined || !DisplayValue.isPrimitive(option.displayValue)) { continue; } const groupedValues = option.groupedRawValues.filter((value) => value !== undefined); if (groupedValues.length !== 0) { options.push({ displayValue: option.displayValue, groupedRawValues: groupedValues }); } } return { options, length: items.length, hasMore, }; } //# sourceMappingURL=UseUniquePropertyValuesLoader.js.map