UNPKG

@mui/x-data-grid-premium

Version:

The Premium plan edition of the MUI X Data Grid Components.

442 lines (439 loc) 17.4 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.useGridPivotingExportState = exports.useGridPivoting = exports.pivotingStateInitializer = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _xDataGridPro = require("@mui/x-data-grid-pro"); var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect")); var _useOnMount = _interopRequireDefault(require("@mui/utils/useOnMount")); var _internals = require("@mui/x-data-grid-pro/internals"); var _pivotPanel = require("../../../components/pivotPanel"); var _gridPivotingSelectors = require("./gridPivotingSelectors"); var _utils = require("./utils"); var _gridAggregationUtils = require("../aggregation/gridAggregationUtils"); var _sidebar = require("../sidebar"); var _jsxRuntime = require("react/jsx-runtime"); const emptyPivotModel = { rows: [], columns: [], values: [] }; const pivotingStateInitializer = (state, props, apiRef) => { apiRef.current.caches.pivoting = { exportedStateRef: { current: null }, nonPivotDataRef: { current: undefined } }; if (props.disablePivoting) { return (0, _extends2.default)({}, state, { pivoting: { active: false, model: emptyPivotModel } }); } const initialColumns = (0, _utils.getInitialColumns)(props.columns ?? [], props.getPivotDerivedColumns, apiRef.current.getLocaleText); const open = props.pivotPanelOpen ?? props.initialState?.pivoting?.panelOpen ?? false; const sidebarStateUpdate = open ? { open, value: _sidebar.GridSidebarValue.Pivot } : {}; return (0, _extends2.default)({}, state, { pivoting: { active: props.pivotActive ?? props.initialState?.pivoting?.enabled ?? false, model: props.pivotModel ?? props.initialState?.pivoting?.model ?? emptyPivotModel, initialColumns }, sidebar: (0, _extends2.default)({}, state.sidebar, sidebarStateUpdate) }); }; exports.pivotingStateInitializer = pivotingStateInitializer; const useGridPivoting = (apiRef, props, originalColumnsProp, originalRowsProp) => { const isPivotActive = (0, _internals.useGridSelector)(apiRef, _gridPivotingSelectors.gridPivotActiveSelector); const isLoading = props.loading ?? (0, _xDataGridPro.gridRowsLoadingSelector)(apiRef); const { exportedStateRef, nonPivotDataRef } = apiRef.current.caches.pivoting; const isPivotingAvailable = !props.disablePivoting; apiRef.current.registerControlState({ stateId: 'pivotModel', propModel: props.pivotModel, propOnChange: props.onPivotModelChange, stateSelector: _gridPivotingSelectors.gridPivotModelSelector, changeEvent: 'pivotModelChange' }); apiRef.current.registerControlState({ stateId: 'pivotMode', propModel: props.pivotActive, propOnChange: props.onPivotActiveChange, stateSelector: _gridPivotingSelectors.gridPivotActiveSelector, changeEvent: 'pivotModeChange' }); apiRef.current.registerControlState({ stateId: 'pivotPanelOpen', propModel: props.pivotPanelOpen, propOnChange: props.onPivotPanelOpenChange, stateSelector: _gridPivotingSelectors.gridPivotPanelOpenSelector, changeEvent: 'pivotPanelOpenChange' }); const getInitialData = React.useCallback(() => { if (!exportedStateRef.current) { exportedStateRef.current = apiRef.current.exportState(); } let rows = []; if (!props.dataSource) { const rowIds = (0, _xDataGridPro.gridDataRowIdsSelector)(apiRef); const rowsLookup = (0, _xDataGridPro.gridRowsLookupSelector)(apiRef); rows = rowIds.map(id => rowsLookup[id]); } const initialColumns = (0, _utils.getInitialColumns)(originalColumnsProp, props.getPivotDerivedColumns, apiRef.current.getLocaleText); return { rows, columns: initialColumns, originalRowsProp }; }, [apiRef, props.getPivotDerivedColumns, originalColumnsProp, originalRowsProp, exportedStateRef, props.dataSource]); const computePivotingState = React.useCallback(({ active, model: pivotModel }) => { if (active && pivotModel) { const { rows, columns } = nonPivotDataRef.current || { rows: [], columns: new Map() }; let propsOverrides = (0, _utils.getPivotForcedProps)(pivotModel, columns, props.groupingColDef); // without data source, add more props overrides based on the data if (!isLoading && !props.dataSource) { propsOverrides = (0, _extends2.default)({}, propsOverrides, (0, _utils.createPivotPropsFromRows)({ rows, columns, pivotModel, pivotingColDef: props.pivotingColDef, apiRef })); } return { initialColumns: columns, propsOverrides }; } return {}; }, [apiRef, isLoading, props.dataSource, props.pivotingColDef, props.groupingColDef, nonPivotDataRef]); (0, _useOnMount.default)(() => { if (!isPivotingAvailable || !isPivotActive) { return undefined; } nonPivotDataRef.current = getInitialData(); apiRef.current.setState(state => { const { initialColumns, propsOverrides } = computePivotingState(state.pivoting); const pivotingState = (0, _extends2.default)({}, state.pivoting, { initialColumns: initialColumns || state.pivoting.initialColumns, propsOverrides: (0, _extends2.default)({}, state.pivoting.propsOverrides, propsOverrides) }); return (0, _extends2.default)({}, state, { pivoting: pivotingState }); }); return undefined; }); (0, _useEnhancedEffect.default)(() => { if (!isPivotingAvailable || !isPivotActive) { if (nonPivotDataRef.current) { // Prevent rows from being resynced from the original rows prop apiRef.current.caches.rows.rowsBeforePartialUpdates = nonPivotDataRef.current.originalRowsProp; apiRef.current.setRows(nonPivotDataRef.current.rows); nonPivotDataRef.current = undefined; } if (exportedStateRef.current) { apiRef.current.restoreState(exportedStateRef.current); exportedStateRef.current = null; } } }, [isPivotActive, apiRef, isPivotingAvailable, nonPivotDataRef, exportedStateRef]); const setPivotModel = React.useCallback(callback => { if (!isPivotingAvailable) { return; } apiRef.current.setState(state => { const newPivotModel = typeof callback === 'function' ? callback(state.pivoting?.model) : callback; if (state.pivoting?.model === newPivotModel) { return state; } const { initialColumns, propsOverrides } = computePivotingState((0, _extends2.default)({}, state.pivoting, { model: newPivotModel })); const newPivotingState = (0, _extends2.default)({}, state.pivoting, { initialColumns: initialColumns || state.pivoting.initialColumns, propsOverrides: (0, _extends2.default)({}, state.pivoting.propsOverrides, propsOverrides), model: newPivotModel }); return (0, _extends2.default)({}, state, { pivoting: newPivotingState }); }); }, [apiRef, computePivotingState, isPivotingAvailable]); const updatePivotModel = React.useCallback(({ field, targetSection, originSection, targetField, targetFieldPosition }) => { if (field === targetField) { return; } apiRef.current.setPivotModel(prev => { const newModel = (0, _extends2.default)({}, prev); const isSameSection = targetSection === originSection; const hidden = originSection === null ? false : prev[originSection].find(item => item.field === field)?.hidden ?? false; if (targetSection) { const newSectionArray = [...prev[targetSection]]; let toIndex = newSectionArray.length; if (targetField) { const fromIndex = newSectionArray.findIndex(item => item.field === field); if (fromIndex > -1) { newSectionArray.splice(fromIndex, 1); } toIndex = newSectionArray.findIndex(item => item.field === targetField); if (targetFieldPosition === 'bottom') { toIndex += 1; } } if (targetSection === 'values') { const initialColumns = (0, _internals.gridPivotInitialColumnsSelector)(apiRef); const aggFunc = isSameSection ? prev.values.find(item => item.field === field)?.aggFunc : (0, _gridAggregationUtils.getAvailableAggregationFunctions)({ aggregationFunctions: props.aggregationFunctions, colDef: initialColumns.get(field), isDataSource: !!props.dataSource })[0]; newSectionArray.splice(toIndex, 0, { field, aggFunc, hidden }); newModel.values = newSectionArray; } else if (targetSection === 'columns') { const sort = isSameSection ? prev.columns.find(item => item.field === field)?.sort : undefined; newSectionArray.splice(toIndex, 0, { field, sort, hidden }); newModel.columns = newSectionArray; } else if (targetSection === 'rows') { newSectionArray.splice(toIndex, 0, { field, hidden }); newModel.rows = newSectionArray; } } if (!isSameSection && originSection) { newModel[originSection] = prev[originSection].filter(f => f.field !== field); } return newModel; }); }, [apiRef, props.aggregationFunctions, props.dataSource]); const setPivotActive = React.useCallback(callback => { if (!isPivotingAvailable) { return; } apiRef.current.setState(state => { const newPivotMode = typeof callback === 'function' ? callback(state.pivoting?.active) : callback; if (state.pivoting?.active === newPivotMode) { return state; } if (newPivotMode) { nonPivotDataRef.current = getInitialData(); } const { initialColumns, propsOverrides } = computePivotingState((0, _extends2.default)({}, state.pivoting, { active: newPivotMode })); const newPivotingState = (0, _extends2.default)({}, state.pivoting, { initialColumns: initialColumns || state.pivoting.initialColumns, propsOverrides: (0, _extends2.default)({}, state.pivoting.propsOverrides, propsOverrides), active: newPivotMode }); const newState = (0, _extends2.default)({}, state, { pivoting: newPivotingState }); return newState; }); apiRef.current.selectRows([], false, true); }, [apiRef, computePivotingState, getInitialData, isPivotingAvailable, nonPivotDataRef]); const setPivotPanelOpen = React.useCallback(callback => { if (!isPivotingAvailable) { return; } const panelOpen = (0, _gridPivotingSelectors.gridPivotPanelOpenSelector)(apiRef); const newPanelOpen = typeof callback === 'function' ? callback(panelOpen) : callback; if (panelOpen === newPanelOpen) { return; } if (newPanelOpen) { apiRef.current.showSidebar(_sidebar.GridSidebarValue.Pivot); } else { apiRef.current.hideSidebar(); } }, [apiRef, isPivotingAvailable]); const addColumnMenuButton = React.useCallback(menuItems => { if (isPivotingAvailable) { return [...menuItems, 'columnMenuManagePanelItem']; } return menuItems; }, [isPivotingAvailable]); (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'columnMenu', addColumnMenuButton); const updateNonPivotColumns = React.useCallback((columns, keepPreviousColumns = true) => { if (!nonPivotDataRef.current || !isPivotingAvailable) { return; } if (keepPreviousColumns) { (0, _utils.getInitialColumns)(columns, props.getPivotDerivedColumns, apiRef.current.getLocaleText).forEach(col => { nonPivotDataRef.current.columns.set(col.field, col); }); } else { nonPivotDataRef.current.columns = (0, _utils.getInitialColumns)(columns, props.getPivotDerivedColumns, apiRef.current.getLocaleText); } apiRef.current.setState(state => { const { propsOverrides } = computePivotingState(state.pivoting); return (0, _extends2.default)({}, state, { pivoting: (0, _extends2.default)({}, state.pivoting, { initialColumns: nonPivotDataRef.current?.columns, propsOverrides: (0, _extends2.default)({}, state.pivoting.propsOverrides, propsOverrides) }) }); }); }, [isPivotingAvailable, apiRef, props.getPivotDerivedColumns, computePivotingState, nonPivotDataRef]); const updateNonPivotRows = React.useCallback((rows, keepPreviousRows = true) => { if (!nonPivotDataRef.current || props.dataSource || !isPivotingAvailable || !rows || rows.length === 0) { return; } if (keepPreviousRows) { const rowsMap = new Map(); nonPivotDataRef.current.rows.forEach(row => { rowsMap.set((0, _xDataGridPro.gridRowIdSelector)(apiRef, row), row); }); rows.forEach(row => { const rowId = (0, _xDataGridPro.gridRowIdSelector)(apiRef, row); // eslint-disable-next-line no-underscore-dangle if (row._action === 'delete') { rowsMap.delete(rowId); } else { rowsMap.set(rowId, row); } }); nonPivotDataRef.current.rows = Array.from(rowsMap.values()); } else { nonPivotDataRef.current.rows = rows; } apiRef.current.setState(state => { const { initialColumns, propsOverrides } = computePivotingState(state.pivoting); return (0, _extends2.default)({}, state, { pivoting: (0, _extends2.default)({}, state.pivoting, { initialColumns: initialColumns || state.pivoting.initialColumns, propsOverrides: (0, _extends2.default)({}, state.pivoting.propsOverrides, propsOverrides) }) }); }); }, [apiRef, computePivotingState, isPivotingAvailable, nonPivotDataRef, props.dataSource]); const addPivotingPanel = React.useCallback((initialValue, value) => { if (isPivotingAvailable && value === _sidebar.GridSidebarValue.Pivot) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_pivotPanel.GridPivotPanel, {}); } return initialValue; }, [isPivotingAvailable]); const addGetRowsParams = React.useCallback(params => { if (!isPivotingAvailable || !isPivotActive) { return params; } const pivotModel = (0, _gridPivotingSelectors.gridPivotModelSelector)(apiRef); const visibleColumns = pivotModel.columns.filter(column => !column.hidden); const visibleRows = pivotModel.rows.filter(row => !row.hidden); const visibleValues = pivotModel.values.filter(value => !value.hidden); return (0, _extends2.default)({}, params, { pivotModel: { columns: visibleColumns, rows: visibleRows, values: visibleValues } }); }, [apiRef, isPivotingAvailable, isPivotActive]); (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'sidebar', addPivotingPanel); (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'getRowsParams', addGetRowsParams); (0, _internals.useGridApiMethod)(apiRef, { setPivotModel, setPivotActive, setPivotPanelOpen }, 'public'); (0, _internals.useGridApiMethod)(apiRef, { updatePivotModel, updateNonPivotColumns, updateNonPivotRows }, 'private'); (0, _useEnhancedEffect.default)(() => { apiRef.current.updateNonPivotColumns(originalColumnsProp, false); }, [originalColumnsProp, apiRef]); (0, _useEnhancedEffect.default)(() => { apiRef.current.updateNonPivotRows(originalRowsProp, false); if (nonPivotDataRef.current) { nonPivotDataRef.current.originalRowsProp = originalRowsProp; } }, [originalRowsProp, apiRef, nonPivotDataRef]); (0, _useEnhancedEffect.default)(() => { if (props.pivotModel !== undefined) { apiRef.current.setPivotModel(props.pivotModel); } }, [apiRef, props.pivotModel]); (0, _useEnhancedEffect.default)(() => { if (props.pivotActive !== undefined) { apiRef.current.setPivotActive(props.pivotActive); } }, [apiRef, props.pivotActive]); (0, _useEnhancedEffect.default)(() => { if (props.pivotPanelOpen !== undefined) { apiRef.current.setPivotPanelOpen(props.pivotPanelOpen); } }, [apiRef, props.pivotPanelOpen]); }; exports.useGridPivoting = useGridPivoting; const useGridPivotingExportState = apiRef => { const stateExportPreProcessing = React.useCallback(state => { const isPivotActive = (0, _gridPivotingSelectors.gridPivotActiveSelector)(apiRef); if (!isPivotActive) { return state; } // To-do: implement context.exportOnlyDirtyModels const newState = (0, _extends2.default)({}, state, apiRef.current.caches.pivoting.exportedStateRef.current, { sorting: state.sorting }); return newState; }, [apiRef]); (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing); }; exports.useGridPivotingExportState = useGridPivotingExportState;