UNPKG

@itwin/presentation-components

Version:

React components based on iTwin.js Presentation library

208 lines 8.3 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Internal */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ROWS_RELOAD_PAGE_SIZE = void 0; exports.useRows = useRows; const react_1 = require("react"); const rxjs_1 = require("rxjs"); const core_bentley_1 = require("@itwin/core-bentley"); const core_frontend_1 = require("@itwin/core-frontend"); 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 ContentBuilder_js_1 = require("../common/ContentBuilder.js"); const Utils_js_1 = require("../common/Utils.js"); /** @internal */ function useRows(props) { const { imodel, ruleset, keys, pageSize, options } = props; const setErrorState = (0, Utils_js_1.useErrorState)(); const [state, setState] = (0, react_1.useState)({ isLoading: false, rows: [], total: 0, }); const loaderRef = (0, react_1.useRef)(noopRowsLoader); (0, react_1.useEffect)(() => { setState((prev) => ({ ...prev, rows: [], total: 0 })); const { observable, ...loader } = createRowsLoader({ imodel, ruleset, keys, pageSize, options, onPageLoadStart: () => setState((prev) => ({ ...prev, isLoading: true })), }); loaderRef.current = loader; const subscription = observable.subscribe({ next: ({ total, rowDefinitions, offset }) => { setState((prev) => { const newRows = [...prev.rows]; newRows.splice(offset, rowDefinitions.length, ...rowDefinitions); return { ...prev, isLoading: false, rows: newRows, total, }; }); }, error: (err) => { setErrorState(err); }, }); loaderRef.current.loadPage(0); return () => { subscription.unsubscribe(); loaderRef.current = noopRowsLoader; }; }, [imodel, ruleset, keys, pageSize, options, setErrorState]); (0, react_1.useEffect)(() => { return core_frontend_1.IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(() => { loaderRef.current.reload(state.rows.length); }); }, [state.rows]); return { rows: state.rows, isLoading: state.isLoading, loadMoreRows: () => { if (state.rows.length === state.total) { return; } loaderRef.current.loadPage(state.rows.length); }, }; } function createRowsLoader({ imodel, ruleset, keys, pageSize, options, onPageLoadStart, }) { const loaderSubject = new rxjs_1.Subject(); const loaderObservable = loaderSubject.pipe((0, rxjs_1.mergeMap)((loaderOptions) => { if (keys.isEmpty) { return rxjs_1.EMPTY; } switch (loaderOptions.action) { case "load-page": { onPageLoadStart(); return (0, rxjs_1.from)(loadRows(imodel, ruleset, keys, { start: loaderOptions.pageStart, size: pageSize }, options)); } case "reload": { return loaderOptions.loadedRowsCount === 0 ? rxjs_1.EMPTY : createReloadObs(imodel, ruleset, keys, options, loaderOptions.loadedRowsCount); } } })); return { observable: loaderObservable, loadPage: (pageStart) => { loaderSubject.next({ action: "load-page", pageStart }); }, reload: (rowsCount) => { loaderSubject.next({ action: "reload", loadedRowsCount: rowsCount }); }, }; } /** @internal */ exports.ROWS_RELOAD_PAGE_SIZE = 1000; function createReloadObs(imodel, ruleset, keys, options, loadedItemsCount) { const lastPageIndex = Math.floor(loadedItemsCount / exports.ROWS_RELOAD_PAGE_SIZE); const lastPageSize = loadedItemsCount % exports.ROWS_RELOAD_PAGE_SIZE; const pages = []; for (let i = 0; i <= lastPageIndex; i++) { pages.push({ start: i * exports.ROWS_RELOAD_PAGE_SIZE, size: i === lastPageIndex ? lastPageSize : exports.ROWS_RELOAD_PAGE_SIZE, }); } return (0, rxjs_1.from)(pages).pipe((0, rxjs_1.mergeMap)((pageOptions) => (0, rxjs_1.from)(loadRows(imodel, ruleset, keys, pageOptions, options)))); } async function loadRows(imodel, ruleset, keys, paging, options) { const requestProps = { imodel, keys: new presentation_common_1.KeySet(keys), descriptor: { displayType: presentation_common_1.DefaultContentDisplayTypes.Grid, sorting: options.sorting, fieldsFilterExpression: options.fieldsFilterExpression, }, rulesetOrId: ruleset, paging, }; return new Promise((resolve, reject) => { (presentation_frontend_1.Presentation.presentation.getContentIterator ? (0, rxjs_1.from)(presentation_frontend_1.Presentation.presentation.getContentIterator(requestProps)).pipe((0, rxjs_1.mergeMap)((result) => { if (!result) { return (0, rxjs_1.of)(undefined); } return (0, rxjs_1.from)(result.items).pipe((0, rxjs_1.toArray)(), (0, rxjs_1.map)((items) => ({ total: result.total, content: new presentation_common_1.Content(result.descriptor, items) }))); })) : // eslint-disable-next-line @typescript-eslint/no-deprecated (0, rxjs_1.from)(presentation_frontend_1.Presentation.presentation.getContentAndSize(requestProps)).pipe((0, rxjs_1.map)((result) => result ? { total: result.size, content: result.content, } : undefined))) .pipe((0, rxjs_1.map)((result) => result ? { rowDefinitions: createRows(result.content, imodel), total: result.total, offset: paging.start, } : { rowDefinitions: [], total: 0, offset: 0, })) .subscribe({ next: resolve, error: reject, }); }); } function createRows(content, imodel) { const rowsBuilder = new RowsBuilder({ imodel }); (0, presentation_common_1.traverseContent)(rowsBuilder, content); return rowsBuilder.rows; } class RowsBuilder extends ContentBuilder_js_1.InternalPropertyRecordsBuilder { rows = []; _currentRow = undefined; constructor({ imodel }) { super((item) => ({ item, append: (record) => { if (record.fieldHierarchy.field.isNestedContentField()) { return; } (0, core_bentley_1.assert)(this._currentRow !== undefined); this._currentRow.cells.push({ key: record.fieldHierarchy.field.name, record: record.record, }); }, }), (record) => { record.imodelKey = (0, presentation_core_interop_1.createIModelKey)(imodel); }); } startItem(props) { const key = JSON.stringify(props.item.primaryKeys[0]); this._currentRow = { key, cells: [] }; return super.startItem(props); } finishItem() { (0, core_bentley_1.assert)(this._currentRow !== undefined); this.rows.push(this._currentRow); this._currentRow = undefined; super.finishItem(); } } /* c8 ignore start */ const noopRowsLoader = { loadPage: () => { }, reload: () => { }, }; /* c8 ignore end */ //# sourceMappingURL=UseRows.js.map