UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

127 lines 6.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SelectionHandlerContextProvider = SelectionHandlerContextProvider; exports.useSelectionHandlerContext = useSelectionHandlerContext; exports.usePropertyDataProviderWithUnifiedSelection = usePropertyDataProviderWithUnifiedSelection; 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. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module PropertyGrid */ const react_1 = require("react"); const rxjs_1 = require("rxjs"); const presentation_common_1 = require("@itwin/presentation-common"); const presentation_core_interop_1 = require("@itwin/presentation-core-interop"); const presentation_frontend_1 = require("@itwin/presentation-frontend"); const Utils_js_1 = require("../common/Utils.js"); const DEFAULT_REQUESTED_CONTENT_INSTANCES_LIMIT = 100; // eslint-disable-next-line @typescript-eslint/no-deprecated const SelectionHandlerContext = (0, react_1.createContext)(undefined); /** @internal */ // eslint-disable-next-line @typescript-eslint/no-deprecated function SelectionHandlerContextProvider({ selectionHandler, children }) { return (0, jsx_runtime_1.jsx)(SelectionHandlerContext.Provider, { value: selectionHandler, children: children }); } /** @internal */ function useSelectionHandlerContext() { return (0, react_1.useContext)(SelectionHandlerContext); } /** * A React hook that adds unified selection functionality to the provided data provider. * @public */ function usePropertyDataProviderWithUnifiedSelection(props) { const { dataProvider, selectionStorage } = props; const { imodel, rulesetId } = dataProvider; const requestedContentInstancesLimit = props.requestedContentInstancesLimit ?? DEFAULT_REQUESTED_CONTENT_INSTANCES_LIMIT; const [numSelectedElements, setNumSelectedElements] = (0, react_1.useState)(0); const suppliedSelectionHandler = useSelectionHandlerContext(); (0, react_1.useEffect)(() => { function onSelectionChanged(newSelection) { setNumSelectedElements(newSelection.size); dataProvider.keys = isOverLimit(newSelection.size, requestedContentInstancesLimit) ? new presentation_common_1.KeySet() : newSelection; } if (selectionStorage) { return initUnifiedSelectionFromStorage({ imodel, selectionStorage, onSelectionChanged }); } return initUnifiedSelectionFromPresentationFrontend({ imodel, rulesetId, suppliedSelectionHandler, onSelectionChanged, }); }, [dataProvider, imodel, rulesetId, requestedContentInstancesLimit, suppliedSelectionHandler, selectionStorage]); return { isOverLimit: isOverLimit(numSelectedElements, requestedContentInstancesLimit), numSelectedElements }; } function initUnifiedSelectionFromStorage({ imodel, selectionStorage, onSelectionChanged, }) { const imodelKey = (0, presentation_core_interop_1.createIModelKey)(imodel); const update = new rxjs_1.Subject(); const subscription = update .pipe((0, rxjs_1.map)((level) => selectionStorage.getSelection({ imodelKey, level })), (0, rxjs_1.switchMap)(async (selectables) => (0, Utils_js_1.createKeySetFromSelectables)(selectables))) .subscribe({ next: onSelectionChanged, }); const removeSelectionChangesListener = selectionStorage.selectionChangeEvent.addListener((args) => { const isMyIModel = args.imodelKey === imodelKey; isMyIModel && update.next(args.level); }); (0, rxjs_1.from)(selectionStorage.getSelectionLevels({ imodelKey })) .pipe((0, rxjs_1.takeLast)(1)) .subscribe({ next: (level) => update.next(level), }); return () => { removeSelectionChangesListener(); subscription.unsubscribe(); }; } function initUnifiedSelectionFromPresentationFrontend({ suppliedSelectionHandler, imodel, rulesetId, onSelectionChanged, }) { // eslint-disable-next-line @typescript-eslint/no-deprecated const updateProviderSelection = (selectionHandler, selectionLevel) => { const selection = getSelectedKeys(selectionHandler, selectionLevel); selection && onSelectionChanged(selection); }; /* c8 ignore start */ const handler = suppliedSelectionHandler ?? // eslint-disable-next-line @typescript-eslint/no-deprecated new presentation_frontend_1.SelectionHandler({ // eslint-disable-next-line @typescript-eslint/no-deprecated manager: presentation_frontend_1.Presentation.selection, name: "PropertyGrid", imodel, rulesetId, }); /* c8 ignore end */ // eslint-disable-next-line @typescript-eslint/no-deprecated handler.onSelect = (evt) => { updateProviderSelection(handler, evt.level); }; updateProviderSelection(handler); return () => { (0, Utils_js_1.safeDispose)(handler); }; } // eslint-disable-next-line @typescript-eslint/no-deprecated function getSelectedKeys(selectionHandler, selectionLevel) { if (undefined === selectionLevel) { const availableLevels = selectionHandler.getSelectionLevels(); if (0 === availableLevels.length) { return undefined; } selectionLevel = availableLevels[availableLevels.length - 1]; } for (let i = selectionLevel; i >= 0; i--) { const selection = selectionHandler.getSelection(i); if (!selection.isEmpty) { return new presentation_common_1.KeySet(selection); } } return new presentation_common_1.KeySet(); } function isOverLimit(numSelectedElements, limit) { return numSelectedElements > limit; } //# sourceMappingURL=UseUnifiedSelection.js.map