UNPKG

@mui/x-data-grid

Version:

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

221 lines (219 loc) 10.1 kB
"use strict"; 'use client'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useGridDataSourceBase = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var React = _interopRequireWildcard(require("react")); var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef")); var _debounce = _interopRequireDefault(require("@mui/utils/debounce")); var _warning = require("@mui/x-internals/warning"); var _isDeepEqual = require("@mui/x-internals/isDeepEqual"); var _gridRowsUtils = require("../rows/gridRowsUtils"); var _utils = require("../../../utils/utils"); var _strategyProcessing = require("../../core/strategyProcessing"); var _useGridSelector = require("../../utils/useGridSelector"); var _gridPaginationSelector = require("../pagination/gridPaginationSelector"); var _gridDataSourceSelector = require("./gridDataSourceSelector"); var _utils2 = require("./utils"); var _cache = require("./cache"); var _gridDataSourceError = require("./gridDataSourceError"); const _excluded = ["skipCache"]; const noopCache = { clear: () => {}, get: () => undefined, set: () => {} }; function getCache(cacheProp, options = {}) { if (cacheProp === null) { return noopCache; } return cacheProp ?? new _cache.GridDataSourceCacheDefault(options); } const useGridDataSourceBase = (apiRef, props, options = {}) => { const setStrategyAvailability = React.useCallback(() => { apiRef.current.setStrategyAvailability(_strategyProcessing.GridStrategyGroup.DataSource, _utils2.DataSourceRowsUpdateStrategy.Default, props.dataSource ? () => true : () => false); }, [apiRef, props.dataSource]); const [defaultRowsUpdateStrategyActive, setDefaultRowsUpdateStrategyActive] = React.useState(false); const paginationModel = (0, _useGridSelector.useGridSelector)(apiRef, _gridPaginationSelector.gridPaginationModelSelector); const lastRequestId = React.useRef(0); const onDataSourceErrorProp = props.onDataSourceError; const cacheChunkManager = (0, _useLazyRef.default)(() => { if (!props.pagination) { return new _utils2.CacheChunkManager(paginationModel.pageSize); } const sortedPageSizeOptions = props.pageSizeOptions.map(option => typeof option === 'number' ? option : option.value).sort((a, b) => a - b); const cacheChunkSize = Math.min(paginationModel.pageSize, sortedPageSizeOptions[0]); return new _utils2.CacheChunkManager(cacheChunkSize); }).current; const [cache, setCache] = React.useState(() => getCache(props.dataSourceCache, options.cacheOptions)); const fetchRows = React.useCallback(async (parentId, params) => { const getRows = props.dataSource?.getRows; if (!getRows) { return; } if (parentId && parentId !== _gridRowsUtils.GRID_ROOT_GROUP_ID && props.signature !== 'DataGrid') { options.fetchRowChildren?.([parentId]); return; } options.clearDataSourceState?.(); const _ref = params || {}, { skipCache } = _ref, getRowsParams = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded); const fetchParams = (0, _extends2.default)({}, (0, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef), apiRef.current.unstable_applyPipeProcessors('getRowsParams', {}), getRowsParams); const cacheKeys = cacheChunkManager.getCacheKeys(fetchParams); const responses = cacheKeys.map(cacheKey => cache.get(cacheKey)); if (!skipCache && responses.every(response => response !== undefined)) { apiRef.current.applyStrategyProcessor('dataSourceRowsUpdate', { response: _utils2.CacheChunkManager.mergeResponses(responses), fetchParams }); return; } // Manage loading state only for the default strategy if (defaultRowsUpdateStrategyActive || apiRef.current.getRowsCount() === 0) { apiRef.current.setLoading(true); } const requestId = lastRequestId.current + 1; lastRequestId.current = requestId; try { const getRowsResponse = await getRows(fetchParams); const cacheResponses = cacheChunkManager.splitResponse(fetchParams, getRowsResponse); cacheResponses.forEach((response, key) => cache.set(key, response)); if (lastRequestId.current === requestId) { apiRef.current.applyStrategyProcessor('dataSourceRowsUpdate', { response: getRowsResponse, fetchParams }); } } catch (originalError) { if (lastRequestId.current === requestId) { apiRef.current.applyStrategyProcessor('dataSourceRowsUpdate', { error: originalError, fetchParams }); if (typeof onDataSourceErrorProp === 'function') { onDataSourceErrorProp(new _gridDataSourceError.GridGetRowsError({ message: originalError?.message, params: fetchParams, cause: originalError })); } 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 { if (defaultRowsUpdateStrategyActive && lastRequestId.current === requestId) { apiRef.current.setLoading(false); } } }, [cacheChunkManager, cache, apiRef, defaultRowsUpdateStrategyActive, props.dataSource?.getRows, onDataSourceErrorProp, options, props.signature]); const handleStrategyActivityChange = React.useCallback(() => { setDefaultRowsUpdateStrategyActive(apiRef.current.getActiveStrategy(_strategyProcessing.GridStrategyGroup.DataSource) === _utils2.DataSourceRowsUpdateStrategy.Default); }, [apiRef]); const handleDataUpdate = React.useCallback(params => { if ('error' in params) { apiRef.current.setRows([]); return; } const { response } = params; if (response.rowCount !== undefined) { apiRef.current.setRowCount(response.rowCount); } apiRef.current.setRows(response.rows); apiRef.current.unstable_applyPipeProcessors('processDataSourceRows', { params: params.fetchParams, response }, true); }, [apiRef]); const dataSourceUpdateRow = props.dataSource?.updateRow; const handleEditRowOption = options.handleEditRow; const editRow = React.useCallback(async params => { if (!dataSourceUpdateRow) { return undefined; } try { const finalRowUpdate = await dataSourceUpdateRow(params); if (typeof handleEditRowOption === 'function') { handleEditRowOption(params, finalRowUpdate); return finalRowUpdate; } apiRef.current.updateNestedRows([finalRowUpdate], []); if (finalRowUpdate && !(0, _isDeepEqual.isDeepEqual)(finalRowUpdate, params.previousRow)) { // Reset the outdated cache, only if the row is _actually_ updated apiRef.current.dataSource.cache.clear(); } return finalRowUpdate; } catch (errorThrown) { if (typeof onDataSourceErrorProp === 'function') { onDataSourceErrorProp(new _gridDataSourceError.GridUpdateRowError({ message: errorThrown?.message, params, cause: errorThrown })); } else if (process.env.NODE_ENV !== 'production') { (0, _warning.warnOnce)(['MUI X: A call to `dataSource.updateRow()` 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'); } throw errorThrown; // Let the caller handle the error further } }, [apiRef, dataSourceUpdateRow, onDataSourceErrorProp, handleEditRowOption]); const dataSourceApi = { dataSource: { fetchRows, cache, editRow } }; const debouncedFetchRows = React.useMemo(() => (0, _debounce.default)(fetchRows, 0), [fetchRows]); const isFirstRender = React.useRef(true); React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } if (props.dataSourceCache === undefined) { return; } const newCache = getCache(props.dataSourceCache, options.cacheOptions); setCache(prevCache => prevCache !== newCache ? newCache : prevCache); }, [props.dataSourceCache, options.cacheOptions]); React.useEffect(() => { if (props.dataSource) { apiRef.current.dataSource.cache.clear(); apiRef.current.dataSource.fetchRows(); } return () => { // ignore the current request on unmount lastRequestId.current += 1; }; }, [apiRef, props.dataSource]); return { api: { public: dataSourceApi }, debouncedFetchRows, strategyProcessor: { strategyName: _utils2.DataSourceRowsUpdateStrategy.Default, group: 'dataSourceRowsUpdate', processor: handleDataUpdate }, setStrategyAvailability, cacheChunkManager, cache, events: { strategyAvailabilityChange: handleStrategyActivityChange, sortModelChange: (0, _utils.runIf)(defaultRowsUpdateStrategyActive, () => debouncedFetchRows()), filterModelChange: (0, _utils.runIf)(defaultRowsUpdateStrategyActive, () => debouncedFetchRows()), paginationModelChange: (0, _utils.runIf)(defaultRowsUpdateStrategyActive, () => debouncedFetchRows()) } }; }; exports.useGridDataSourceBase = useGridDataSourceBase;