@itwin/presentation-components
Version:
React components based on iTwin.js Presentation library
157 lines • 8.41 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/* eslint-disable @typescript-eslint/no-deprecated */
/** @packageDocumentation
* @module Tree
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.usePresentationTreeNodeLoader = usePresentationTreeNodeLoader;
exports.useControlledPresentationTreeFiltering = useControlledPresentationTreeFiltering;
require("../../common/DisposePolyfill.js");
const react_1 = require("react");
const components_react_1 = require("@itwin/components-react");
const core_frontend_1 = require("@itwin/core-frontend");
const presentation_frontend_1 = require("@itwin/presentation-frontend");
const DataProvider_js_1 = require("../DataProvider.js");
const TreeReloader_js_1 = require("./TreeReloader.js");
const UseControlledTreeFiltering_js_1 = require("./UseControlledTreeFiltering.js");
/**
* Custom hooks which creates PagedTreeNodeLoader with PresentationTreeDataProvider using
* supplied imodel and ruleset.
* @public
* @deprecated in 4.x. This hook is not compatible with React 18 `StrictMode`. Use [[usePresentationTreeState]] instead.
*/
function usePresentationTreeNodeLoader(props) {
const { seedTreeModel, ...rest } = props;
const firstRenderRef = (0, react_1.useRef)(true);
const treeNodeLoaderStateProps = (0, react_1.useMemo)(() => ({ ...rest, seedTreeModel: firstRenderRef.current ? seedTreeModel : undefined }), Object.values(rest));
const [{ modelSource, dataProvider }, setState] = (0, react_1.useState)(() => ({
modelSource: new components_react_1.TreeModelSource(new components_react_1.MutableTreeModel(treeNodeLoaderStateProps.seedTreeModel)),
dataProvider: new DataProvider_js_1.PresentationTreeDataProvider({ ...treeNodeLoaderStateProps }),
}));
(0, react_1.useEffect)(() => {
const provider = new DataProvider_js_1.PresentationTreeDataProvider({ ...treeNodeLoaderStateProps });
setState({
modelSource: new components_react_1.TreeModelSource(new components_react_1.MutableTreeModel(treeNodeLoaderStateProps.seedTreeModel)),
dataProvider: provider,
});
return () => {
provider[Symbol.dispose]();
};
}, [treeNodeLoaderStateProps]);
const nodeLoader = (0, components_react_1.usePagedTreeNodeLoader)(dataProvider, rest.pagingSize, modelSource);
const renderedItems = (0, react_1.useRef)(undefined);
/* c8 ignore next 3 */
const onItemsRendered = (0, react_1.useCallback)((items) => {
renderedItems.current = items;
}, []);
const params = {
pageSize: rest.pagingSize,
modelSource,
dataProviderProps: treeNodeLoaderStateProps,
rulesetId: dataProvider.rulesetId,
setTreeNodeLoaderState: setState,
renderedItems,
};
useModelSourceUpdateOnIModelHierarchyUpdate(params);
useModelSourceUpdateOnRulesetModification(params);
useModelSourceUpdateOnRulesetVariablesChange(params);
useModelSourceUpdateOnUnitSystemChange(params);
firstRenderRef.current = false;
return { nodeLoader, onItemsRendered };
}
/**
* A custom hook that creates filtered model source and node loader for supplied filter.
* If filter string is not provided or filtering is still in progress it returns supplied
* model source and node loader.
*
* @public
* @deprecated in 5.7. All tree-related APIs have been deprecated in favor of the new generation hierarchy
* building APIs (see https://github.com/iTwin/presentation/blob/33e79ee8d77f30580a9bab81a72884bda008db25/README.md#the-packages).
*/
function useControlledPresentationTreeFiltering(props) {
const { filteredNodeLoader, filteredProvider, isFiltering, matchesCount } = (0, UseControlledTreeFiltering_js_1.useFilteredNodeLoader)({
dataProvider: props.nodeLoader.dataProvider,
filter: props.filter,
});
const nodeHighlightingProps = (0, UseControlledTreeFiltering_js_1.useNodeHighlightingProps)(props.filter, filteredProvider, props.activeMatchIndex);
return {
nodeHighlightingProps,
filteredNodeLoader: filteredNodeLoader || props.nodeLoader,
filteredModelSource: filteredNodeLoader?.modelSource || props.nodeLoader.modelSource,
isFiltering,
matchesCount,
};
}
function useModelSourceUpdateOnIModelHierarchyUpdate(params) {
const { dataProviderProps, rulesetId, pageSize, modelSource, setTreeNodeLoaderState, renderedItems } = params;
(0, react_1.useEffect)(() => {
let subscription;
const removeListener = presentation_frontend_1.Presentation.presentation.onIModelHierarchyChanged.addListener((args) => {
if (args.rulesetId !== rulesetId || args.imodelKey !== dataProviderProps.imodel.key) {
return;
}
subscription = startTreeReload({ dataProviderProps, rulesetId, pageSize, modelSource, renderedItems, setTreeNodeLoaderState });
});
return () => {
removeListener();
subscription?.unsubscribe();
};
}, [modelSource, pageSize, dataProviderProps, rulesetId, setTreeNodeLoaderState, renderedItems]);
}
function useModelSourceUpdateOnRulesetModification(params) {
const { dataProviderProps, rulesetId, pageSize, modelSource, setTreeNodeLoaderState, renderedItems } = params;
(0, react_1.useEffect)(() => {
let subscription;
const removeListener = presentation_frontend_1.Presentation.presentation.rulesets().onRulesetModified.addListener((ruleset) => {
if (ruleset.id !== rulesetId) {
return;
}
subscription = startTreeReload({ dataProviderProps, rulesetId, pageSize, modelSource, renderedItems, setTreeNodeLoaderState });
});
return () => {
removeListener();
subscription?.unsubscribe();
};
}, [dataProviderProps, rulesetId, modelSource, pageSize, setTreeNodeLoaderState, renderedItems]);
}
function useModelSourceUpdateOnRulesetVariablesChange(params) {
const { dataProviderProps, pageSize, rulesetId, modelSource, setTreeNodeLoaderState, renderedItems } = params;
(0, react_1.useEffect)(() => {
let subscription;
const removeListener = presentation_frontend_1.Presentation.presentation.vars(rulesetId).onVariableChanged.addListener(() => {
// note: we should probably debounce these events while accumulating changed variables in case multiple vars are changed
subscription = startTreeReload({ dataProviderProps, rulesetId, pageSize, modelSource, renderedItems, setTreeNodeLoaderState });
});
return () => {
removeListener();
subscription?.unsubscribe();
};
}, [dataProviderProps, modelSource, pageSize, rulesetId, setTreeNodeLoaderState, renderedItems]);
}
function useModelSourceUpdateOnUnitSystemChange(params) {
const { dataProviderProps, pageSize, rulesetId, modelSource, setTreeNodeLoaderState, renderedItems } = params;
(0, react_1.useEffect)(() => {
let subscription;
const removeListener = core_frontend_1.IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(() => {
subscription = startTreeReload({ dataProviderProps, rulesetId, pageSize, modelSource, renderedItems, setTreeNodeLoaderState });
});
return () => {
removeListener();
subscription?.unsubscribe();
};
}, [dataProviderProps, modelSource, pageSize, rulesetId, setTreeNodeLoaderState, renderedItems]);
}
function startTreeReload({ dataProviderProps, rulesetId, modelSource, pageSize, renderedItems, setTreeNodeLoaderState }) {
const dataProvider = new DataProvider_js_1.PresentationTreeDataProvider({ ...dataProviderProps, ruleset: rulesetId });
return (0, TreeReloader_js_1.reloadTree)(modelSource.getModel(), dataProvider, pageSize, renderedItems.current).subscribe({
next: (newModelSource) => setTreeNodeLoaderState({
modelSource: newModelSource,
dataProvider,
}),
});
}
//# sourceMappingURL=TreeHooks.js.map