UNPKG

@mui/x-data-grid-pro

Version:

The Pro plan edition of the MUI X Data Grid components.

216 lines (215 loc) 9.32 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useGridDataSourceBasePro = exports.INITIAL_STATE = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _isDeepEqual = require("@mui/x-internals/isDeepEqual"); var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef")); var _xDataGrid = require("@mui/x-data-grid"); var _internals = require("@mui/x-data-grid/internals"); var _warning = require("@mui/x-internals/warning"); var _utils = require("./utils"); var _gridDataSourceSelector = require("./gridDataSourceSelector"); const INITIAL_STATE = exports.INITIAL_STATE = { loading: {}, errors: {} }; const useGridDataSourceBasePro = (apiRef, props, options = {}) => { const groupsToAutoFetch = (0, _xDataGrid.useGridSelector)(apiRef, _internals.gridRowGroupsToFetchSelector); const nestedDataManager = (0, _useLazyRef.default)(() => new _utils.NestedDataManager(apiRef)).current; const scheduledGroups = React.useRef(0); const clearDataSourceState = React.useCallback(() => { nestedDataManager.clear(); scheduledGroups.current = 0; const dataSourceState = apiRef.current.state.dataSource; if (dataSourceState !== INITIAL_STATE) { apiRef.current.resetDataSourceState(); } return null; }, [apiRef, nestedDataManager]); const handleEditRow = React.useCallback((params, updatedRow) => { const groupKeys = (0, _utils.getGroupKeys)((0, _xDataGrid.gridRowTreeSelector)(apiRef), params.rowId); apiRef.current.updateNestedRows([updatedRow], groupKeys); if (updatedRow && !(0, _isDeepEqual.isDeepEqual)(updatedRow, params.previousRow)) { // Reset the outdated cache, only if the row is _actually_ updated apiRef.current.dataSource.cache.clear(); } }, [apiRef]); const { api, debouncedFetchRows, strategyProcessor, events, cacheChunkManager, cache } = (0, _internals.useGridDataSourceBase)(apiRef, props, (0, _extends2.default)({ fetchRowChildren: nestedDataManager.queue, clearDataSourceState, handleEditRow }, options)); const setStrategyAvailability = React.useCallback(() => { apiRef.current.setStrategyAvailability(_internals.GridStrategyGroup.DataSource, _internals.DataSourceRowsUpdateStrategy.Default, props.dataSource && !props.lazyLoading ? () => true : () => false); }, [apiRef, props.dataSource, props.lazyLoading]); const onDataSourceErrorProp = props.onDataSourceError; const fetchRowChildren = React.useCallback(async id => { const pipedParams = apiRef.current.unstable_applyPipeProcessors('getRowsParams', {}); if (!props.treeData && (pipedParams.groupFields?.length ?? 0) === 0) { nestedDataManager.clearPendingRequest(id); return; } const getRows = props.dataSource?.getRows; if (!getRows) { nestedDataManager.clearPendingRequest(id); return; } const rowNode = apiRef.current.getRowNode(id); if (!rowNode) { nestedDataManager.clearPendingRequest(id); return; } const fetchParams = (0, _extends2.default)({}, (0, _internals.gridGetRowsParamsSelector)(apiRef), pipedParams, { groupKeys: rowNode.path }); const cacheKeys = cacheChunkManager.getCacheKeys(fetchParams); const responses = cacheKeys.map(cacheKey => cache.get(cacheKey)); const cachedData = responses.some(response => response === undefined) ? undefined : _internals.CacheChunkManager.mergeResponses(responses); if (cachedData !== undefined) { const rows = cachedData.rows; nestedDataManager.setRequestSettled(id); apiRef.current.updateNestedRows(rows, rowNode.path); apiRef.current.setRowCount(cachedData.rowCount === undefined ? -1 : cachedData.rowCount); apiRef.current.setRowChildrenExpansion(id, true); apiRef.current.dataSource.setChildrenLoading(id, false); return; } const existingError = (0, _gridDataSourceSelector.gridDataSourceErrorsSelector)(apiRef)[id] ?? null; if (existingError) { apiRef.current.dataSource.setChildrenFetchError(id, null); } try { const getRowsResponse = await getRows(fetchParams); if (!apiRef.current.getRowNode(id)) { // The row has been removed from the grid nestedDataManager.clearPendingRequest(id); return; } if (nestedDataManager.getRequestStatus(id) === _utils.RequestStatus.UNKNOWN) { apiRef.current.dataSource.setChildrenLoading(id, false); return; } nestedDataManager.setRequestSettled(id); const cacheResponses = cacheChunkManager.splitResponse(fetchParams, getRowsResponse); cacheResponses.forEach((response, key) => { cache.set(key, response); }); apiRef.current.setRowCount(getRowsResponse.rowCount === undefined ? -1 : getRowsResponse.rowCount); // Remove existing outdated rows before setting the new ones const rowsToDelete = []; getRowsResponse.rows.forEach(row => { const rowId = (0, _xDataGrid.gridRowIdSelector)(apiRef, row); const treeNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, rowId); if (treeNode) { rowsToDelete.push({ id: rowId, _action: 'delete' }); } }); if (rowsToDelete.length > 0) { // TODO: Make this happen in a single pass by modifying the pre-processing of the rows apiRef.current.updateNestedRows(rowsToDelete, rowNode.path); } apiRef.current.updateNestedRows(getRowsResponse.rows, rowNode.path); apiRef.current.setRowChildrenExpansion(id, true); } catch (error) { const childrenFetchError = error; apiRef.current.dataSource.setChildrenFetchError(id, childrenFetchError); if (typeof onDataSourceErrorProp === 'function') { onDataSourceErrorProp(new _xDataGrid.GridGetRowsError({ message: childrenFetchError.message, params: fetchParams, cause: childrenFetchError })); } else if (process.env.NODE_ENV !== 'production') { (0, _warning.warnOnce)(['MUI X: A call to `dataSource.getRows()` threw an error which was not handled because `onDataSourceError()` is missing.', 'To handle the error pass a callback to the `onDataSourceError` prop, for example `<DataGrid onDataSourceError={(error) => ...} />`.', 'For more detail, see https://mui.com/x/react-data-grid/server-side-data/#error-handling.'], 'error'); } } finally { apiRef.current.dataSource.setChildrenLoading(id, false); nestedDataManager.setRequestSettled(id); } }, [nestedDataManager, cacheChunkManager, cache, onDataSourceErrorProp, apiRef, props.treeData, props.dataSource?.getRows]); const setChildrenLoading = React.useCallback((parentId, isLoading) => { apiRef.current.setState(state => { if (!state.dataSource.loading[parentId] && isLoading === false) { return state; } const newLoadingState = (0, _extends2.default)({}, state.dataSource.loading); if (isLoading === false) { delete newLoadingState[parentId]; } else { newLoadingState[parentId] = isLoading; } return (0, _extends2.default)({}, state, { dataSource: (0, _extends2.default)({}, state.dataSource, { loading: newLoadingState }) }); }); }, [apiRef]); const setChildrenFetchError = React.useCallback((parentId, error) => { apiRef.current.setState(state => { const newErrorsState = (0, _extends2.default)({}, state.dataSource.errors); if (error === null && newErrorsState[parentId] !== undefined) { delete newErrorsState[parentId]; } else { newErrorsState[parentId] = error; } return (0, _extends2.default)({}, state, { dataSource: (0, _extends2.default)({}, state.dataSource, { errors: newErrorsState }) }); }); }, [apiRef]); const resetDataSourceState = React.useCallback(() => { apiRef.current.setState(state => { return (0, _extends2.default)({}, state, { dataSource: INITIAL_STATE }); }); }, [apiRef]); const dataSourceApi = { dataSource: (0, _extends2.default)({}, api.public.dataSource, { setChildrenLoading, setChildrenFetchError }) }; const dataSourcePrivateApi = { fetchRowChildren, resetDataSourceState }; React.useEffect(() => { if (groupsToAutoFetch && groupsToAutoFetch.length && scheduledGroups.current < groupsToAutoFetch.length) { const groupsToSchedule = groupsToAutoFetch.slice(scheduledGroups.current); nestedDataManager.queue(groupsToSchedule); scheduledGroups.current = groupsToAutoFetch.length; } }, [apiRef, nestedDataManager, groupsToAutoFetch]); return { api: { public: dataSourceApi, private: dataSourcePrivateApi }, debouncedFetchRows, strategyProcessor, events, setStrategyAvailability, cacheChunkManager, cache }; }; exports.useGridDataSourceBasePro = useGridDataSourceBasePro;