UNPKG

@itwin/presentation-hierarchies-react

Version:

React components based on `@itwin/presentation-hierarchies`

94 lines 4.29 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ import { catchError, expand, from, map, mergeMap, of, toArray } from "rxjs"; import { isTreeModelHierarchyNode } from "./TreeModel.js"; import { createNodeId } from "./Utils.js"; /** @internal */ export class TreeLoader { _hierarchyProvider; _onHierarchyLimitExceeded; _onHierarchyLoadError; _treeNodeIdFactory; constructor(_hierarchyProvider, _onHierarchyLimitExceeded, _onHierarchyLoadError, treeNodeIdFactory) { this._hierarchyProvider = _hierarchyProvider; this._onHierarchyLimitExceeded = _onHierarchyLimitExceeded; this._onHierarchyLoadError = _onHierarchyLoadError; this._treeNodeIdFactory = treeNodeIdFactory ?? /* c8 ignore next */ createNodeId; } loadChildren({ parent, getHierarchyLevelOptions, buildNode, ignoreCache }) { const { instanceFilter, hierarchyLevelSizeLimit } = getHierarchyLevelOptions(parent); const infoNodeIdBase = `${parent.id ?? "<root>"}`; const treeModelNodesFactory = createTreeModelNodesFactory({ buildNode, treeNodeIdFactory: this._treeNodeIdFactory }); return from(this._hierarchyProvider.getNodes({ parentNode: parent.nodeData, hierarchyLevelSizeLimit, instanceFilter, ignoreCache, })).pipe(toArray(), catchError((err) => { const nodeProps = { id: `${infoNodeIdBase}-Unknown`, parentId: parent.id, }; let hierarchyLoadErrorType = "unknown"; if (err instanceof Error) { nodeProps.id = `${infoNodeIdBase}-${err.message}`; if (isRowsLimitError(err)) { this._onHierarchyLimitExceeded({ parentId: parent.id, filter: instanceFilter, limit: err.limit }); return of([{ ...nodeProps, type: "ResultSetTooLarge", resultSetSizeLimit: err.limit }]); } if (isTimeoutError(err)) { hierarchyLoadErrorType = "timeout"; } } this._onHierarchyLoadError({ parentId: parent.id, type: hierarchyLoadErrorType, error: err }); return of([ { ...nodeProps, type: "Unknown", message: "Failed to create hierarchy level", }, ]); }), map((childNodes) => ({ parentId: parent.id, loadedNodes: instanceFilter && childNodes.length === 0 ? [ { id: `${infoNodeIdBase}-no-filter-matches`, parentId: parent.id, type: "NoFilterMatches", }, ] : childNodes.map(treeModelNodesFactory), }))); } loadNodes({ shouldLoadChildren, ...options }) { return this.loadChildren(options).pipe(expand((loadedPart) => from(loadedPart.loadedNodes.filter((node) => isTreeModelHierarchyNode(node) && shouldLoadChildren(node))).pipe(mergeMap((node) => this.loadChildren({ ...options, parent: node }))))); } } function createTreeModelNodesFactory({ buildNode, treeNodeIdFactory, }) { return (node) => { if (!isHierarchyNode(node)) { return node; } const modelNode = { id: treeNodeIdFactory(node), children: node.children, label: node.label, nodeData: node, }; return buildNode ? buildNode(modelNode) : modelNode; }; } function isHierarchyNode(node) { return "key" in node && node.key !== undefined; } function isRowsLimitError(error) { const asRowsError = error; return asRowsError.limit !== undefined && asRowsError.message.includes("Query rows limit of"); } function isTimeoutError(error) { return error.message.includes("query too long to execute or server is too busy"); } //# sourceMappingURL=TreeLoader.js.map