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