UNPKG

@mui/x-data-grid-pro

Version:

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

231 lines (230 loc) 9.46 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.useGridDataSource = exports.dataSourceStateInitializer = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef")); var _xDataGrid = require("@mui/x-data-grid"); var _internals = require("@mui/x-data-grid/internals"); var _utils = require("@mui/utils"); var _gridDataSourceSelector = require("./gridDataSourceSelector"); var _utils2 = require("./utils"); var _cache = require("./cache"); const INITIAL_STATE = { loading: {}, errors: {} }; const noopCache = { clear: () => {}, get: () => undefined, set: () => {} }; function getCache(cacheProp) { if (cacheProp === null) { return noopCache; } return cacheProp ?? new _cache.GridDataSourceCacheDefault({}); } const dataSourceStateInitializer = state => { return (0, _extends2.default)({}, state, { dataSource: INITIAL_STATE }); }; exports.dataSourceStateInitializer = dataSourceStateInitializer; const useGridDataSource = (apiRef, props) => { const nestedDataManager = (0, _useLazyRef.default)(() => new _utils2.NestedDataManager(apiRef)).current; const groupsToAutoFetch = (0, _xDataGrid.useGridSelector)(apiRef, _internals.gridRowGroupsToFetchSelector); const scheduledGroups = React.useRef(0); const onError = props.unstable_onDataSourceError; const [cache, setCache] = React.useState(() => getCache(props.unstable_dataSourceCache)); const fetchRows = React.useCallback(async parentId => { const getRows = props.unstable_dataSource?.getRows; if (!getRows) { return; } if (parentId) { nestedDataManager.queue([parentId]); return; } nestedDataManager.clear(); scheduledGroups.current = 0; const dataSourceState = apiRef.current.state.dataSource; if (dataSourceState !== INITIAL_STATE) { apiRef.current.resetDataSourceState(); } const fetchParams = (0, _extends2.default)({}, (0, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef), apiRef.current.unstable_applyPipeProcessors('getRowsParams', {})); const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams); if (cachedData !== undefined) { const rows = cachedData.rows; apiRef.current.setRows(rows); if (cachedData.rowCount !== undefined) { apiRef.current.setRowCount(cachedData.rowCount); } return; } const isLoading = (0, _xDataGrid.gridRowsLoadingSelector)(apiRef); if (!isLoading) { apiRef.current.setLoading(true); } try { const getRowsResponse = await getRows(fetchParams); apiRef.current.unstable_dataSource.cache.set(fetchParams, getRowsResponse); if (getRowsResponse.rowCount !== undefined) { apiRef.current.setRowCount(getRowsResponse.rowCount); } apiRef.current.setRows(getRowsResponse.rows); apiRef.current.setLoading(false); } catch (error) { apiRef.current.setRows([]); apiRef.current.setLoading(false); onError?.(error, fetchParams); } }, [nestedDataManager, apiRef, props.unstable_dataSource?.getRows, onError]); 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.unstable_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, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef), pipedParams, { groupKeys: rowNode.path }); const cachedData = apiRef.current.unstable_dataSource.cache.get(fetchParams); if (cachedData !== undefined) { const rows = cachedData.rows; nestedDataManager.setRequestSettled(id); apiRef.current.updateServerRows(rows, rowNode.path); if (cachedData.rowCount) { apiRef.current.setRowCount(cachedData.rowCount); } apiRef.current.setRowChildrenExpansion(id, true); apiRef.current.unstable_dataSource.setChildrenLoading(id, false); return; } const existingError = (0, _gridDataSourceSelector.gridDataSourceErrorsSelector)(apiRef)[id] ?? null; if (existingError) { apiRef.current.unstable_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) === _utils2.RequestStatus.UNKNOWN) { apiRef.current.unstable_dataSource.setChildrenLoading(id, false); return; } nestedDataManager.setRequestSettled(id); apiRef.current.unstable_dataSource.cache.set(fetchParams, getRowsResponse); if (getRowsResponse.rowCount) { apiRef.current.setRowCount(getRowsResponse.rowCount); } apiRef.current.updateServerRows(getRowsResponse.rows, rowNode.path); apiRef.current.setRowChildrenExpansion(id, true); } catch (error) { const childrenFetchError = error; apiRef.current.unstable_dataSource.setChildrenFetchError(id, childrenFetchError); onError?.(childrenFetchError, fetchParams); } finally { apiRef.current.unstable_dataSource.setChildrenLoading(id, false); nestedDataManager.setRequestSettled(id); } }, [nestedDataManager, onError, apiRef, props.treeData, props.unstable_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 debouncedFetchRows = React.useMemo(() => (0, _utils.unstable_debounce)(fetchRows, 0), [fetchRows]); const dataSourceApi = { unstable_dataSource: { setChildrenLoading, setChildrenFetchError, fetchRows, cache } }; const dataSourcePrivateApi = { fetchRowChildren, resetDataSourceState }; (0, _xDataGrid.useGridApiMethod)(apiRef, dataSourceApi, 'public'); (0, _xDataGrid.useGridApiMethod)(apiRef, dataSourcePrivateApi, 'private'); (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'sortModelChange', (0, _utils2.runIfServerMode)(props.sortingMode, debouncedFetchRows)); (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'filterModelChange', (0, _utils2.runIfServerMode)(props.filterMode, debouncedFetchRows)); (0, _xDataGrid.useGridApiEventHandler)(apiRef, 'paginationModelChange', (0, _utils2.runIfServerMode)(props.paginationMode, debouncedFetchRows)); const isFirstRender = React.useRef(true); React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } const newCache = getCache(props.unstable_dataSourceCache); setCache(prevCache => prevCache !== newCache ? newCache : prevCache); }, [props.unstable_dataSourceCache]); React.useEffect(() => { if (props.unstable_dataSource) { apiRef.current.unstable_dataSource.cache.clear(); apiRef.current.unstable_dataSource.fetchRows(); } }, [apiRef, props.unstable_dataSource]); 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]); }; exports.useGridDataSource = useGridDataSource;