@mui/x-data-grid 7.17.0 → 7.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +208 -5
- package/DataGrid/DataGrid.js +16 -1
- package/DataGrid/useDataGridComponent.js +3 -0
- package/DataGrid/useDataGridProps.js +2 -1
- package/components/GridRow.js +1 -0
- package/components/cell/GridCell.js +33 -9
- package/components/columnHeaders/GridBaseColumnHeaders.js +1 -1
- package/components/columnSelection/GridCellCheckboxRenderer.js +12 -4
- package/components/columnSelection/GridHeaderCheckbox.d.ts +1 -1
- package/components/containers/GridRoot.js +1 -1
- package/components/containers/GridRootStyles.js +32 -23
- package/components/containers/GridToolbarContainer.js +1 -1
- package/components/menu/GridMenu.js +1 -1
- package/components/panel/GridPanel.d.ts +1 -1
- package/components/panel/GridPanel.js +1 -1
- package/components/panel/GridPanelContent.js +1 -1
- package/components/panel/GridPanelFooter.js +1 -1
- package/components/panel/GridPanelHeader.js +1 -1
- package/components/panel/GridPanelWrapper.js +1 -1
- package/components/panel/filterPanel/filterPanelUtils.d.ts +1 -1
- package/components/toolbar/GridToolbarQuickFilter.js +1 -1
- package/components/virtualization/GridBottomContainer.d.ts +1 -1
- package/components/virtualization/GridBottomContainer.js +18 -1
- package/components/virtualization/GridMainContainer.js +3 -1
- package/components/virtualization/GridTopContainer.d.ts +1 -1
- package/components/virtualization/GridTopContainer.js +1 -1
- package/components/virtualization/GridVirtualScrollbar.js +1 -7
- package/components/virtualization/GridVirtualScroller.js +1 -0
- package/components/virtualization/GridVirtualScrollerFiller.js +3 -4
- package/hooks/features/columnGrouping/gridColumnGroupsSelector.d.ts +4 -4
- package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +1 -2
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
- package/hooks/features/columnResize/columnResizeSelector.d.ts +1 -1
- package/hooks/features/columnResize/useGridColumnResize.js +6 -6
- package/hooks/features/columns/gridColumnsSelector.d.ts +12 -12
- package/hooks/features/columns/gridColumnsUtils.js +3 -2
- package/hooks/features/density/densitySelector.d.ts +1 -1
- package/hooks/features/dimensions/gridDimensionsApi.d.ts +4 -0
- package/hooks/features/dimensions/useGridDimensions.d.ts +1 -1
- package/hooks/features/dimensions/useGridDimensions.js +4 -1
- package/hooks/features/editing/useGridCellEditing.js +3 -19
- package/hooks/features/editing/useGridRowEditing.js +7 -2
- package/hooks/features/editing/utils.d.ts +2 -0
- package/hooks/features/editing/utils.js +15 -0
- package/hooks/features/export/useGridPrintExport.js +2 -1
- package/hooks/features/filter/gridFilterSelector.d.ts +17 -17
- package/hooks/features/focus/gridFocusStateSelector.d.ts +8 -8
- package/hooks/features/focus/useGridFocus.js +2 -1
- package/hooks/features/headerFiltering/gridHeaderFilteringSelectors.d.ts +3 -3
- package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +10 -46
- package/hooks/features/keyboardNavigation/utils.d.ts +17 -0
- package/hooks/features/keyboardNavigation/utils.js +58 -0
- package/hooks/features/pagination/gridPaginationSelector.d.ts +9 -9
- package/hooks/features/rowSelection/gridRowSelectionSelector.d.ts +3 -3
- package/hooks/features/rowSelection/useGridRowSelection.d.ts +1 -1
- package/hooks/features/rowSelection/useGridRowSelection.js +105 -29
- package/hooks/features/rowSelection/utils.d.ts +10 -0
- package/hooks/features/rowSelection/utils.js +156 -1
- package/hooks/features/rows/gridRowSpanningSelectors.d.ts +4 -0
- package/hooks/features/rows/gridRowSpanningSelectors.js +5 -0
- package/hooks/features/rows/gridRowSpanningUtils.d.ts +10 -0
- package/hooks/features/rows/gridRowSpanningUtils.js +42 -0
- package/hooks/features/rows/gridRowsSelector.d.ts +14 -14
- package/hooks/features/rows/useGridRowSpanning.d.ts +27 -0
- package/hooks/features/rows/useGridRowSpanning.js +257 -0
- package/hooks/features/rows/useGridRows.d.ts +1 -1
- package/hooks/features/rows/useGridRows.js +7 -1
- package/hooks/features/scroll/useGridScroll.js +19 -19
- package/hooks/features/sorting/gridSortingSelector.d.ts +4 -4
- package/hooks/features/virtualization/gridVirtualizationSelectors.d.ts +5 -5
- package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -1
- package/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/hooks/utils/useGridApiEventHandler.js +0 -1
- package/hooks/utils/useGridVisibleRows.d.ts +2 -2
- package/index.js +1 -1
- package/internals/index.d.ts +2 -0
- package/internals/index.js +2 -0
- package/locales/bgBG.js +8 -9
- package/locales/deDE.js +4 -4
- package/locales/frFR.js +4 -4
- package/locales/hrHR.d.ts +1 -1
- package/locales/hrHR.js +69 -46
- package/locales/jaJP.js +1 -2
- package/locales/ptPT.d.ts +1 -1
- package/locales/ptPT.js +4 -4
- package/locales/viVN.js +20 -20
- package/locales/zhHK.d.ts +1 -1
- package/models/colDef/gridColDef.d.ts +4 -0
- package/models/gridRowSelectionModel.d.ts +4 -0
- package/models/gridStateCommunity.d.ts +2 -0
- package/models/props/DataGridProps.d.ts +30 -1
- package/modern/DataGrid/DataGrid.js +16 -1
- package/modern/DataGrid/useDataGridComponent.js +3 -0
- package/modern/DataGrid/useDataGridProps.js +2 -1
- package/modern/components/GridRow.js +1 -0
- package/modern/components/cell/GridCell.js +33 -9
- package/modern/components/columnHeaders/GridBaseColumnHeaders.js +1 -1
- package/modern/components/columnSelection/GridCellCheckboxRenderer.js +12 -4
- package/modern/components/containers/GridRoot.js +1 -1
- package/modern/components/containers/GridRootStyles.js +32 -23
- package/modern/components/containers/GridToolbarContainer.js +1 -1
- package/modern/components/menu/GridMenu.js +1 -1
- package/modern/components/panel/GridPanel.js +1 -1
- package/modern/components/panel/GridPanelContent.js +1 -1
- package/modern/components/panel/GridPanelFooter.js +1 -1
- package/modern/components/panel/GridPanelHeader.js +1 -1
- package/modern/components/panel/GridPanelWrapper.js +1 -1
- package/modern/components/toolbar/GridToolbarQuickFilter.js +1 -1
- package/modern/components/virtualization/GridBottomContainer.js +18 -1
- package/modern/components/virtualization/GridMainContainer.js +3 -1
- package/modern/components/virtualization/GridTopContainer.js +1 -1
- package/modern/components/virtualization/GridVirtualScrollbar.js +1 -7
- package/modern/components/virtualization/GridVirtualScroller.js +1 -0
- package/modern/components/virtualization/GridVirtualScrollerFiller.js +3 -4
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
- package/modern/hooks/features/columnResize/useGridColumnResize.js +6 -6
- package/modern/hooks/features/columns/gridColumnsUtils.js +3 -2
- package/modern/hooks/features/dimensions/useGridDimensions.js +4 -1
- package/modern/hooks/features/editing/useGridCellEditing.js +3 -19
- package/modern/hooks/features/editing/useGridRowEditing.js +7 -2
- package/modern/hooks/features/editing/utils.js +15 -0
- package/modern/hooks/features/export/useGridPrintExport.js +2 -1
- package/modern/hooks/features/focus/useGridFocus.js +2 -1
- package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +10 -46
- package/modern/hooks/features/keyboardNavigation/utils.js +58 -0
- package/modern/hooks/features/rowSelection/useGridRowSelection.js +105 -29
- package/modern/hooks/features/rowSelection/utils.js +156 -1
- package/modern/hooks/features/rows/gridRowSpanningSelectors.js +5 -0
- package/modern/hooks/features/rows/gridRowSpanningUtils.js +42 -0
- package/modern/hooks/features/rows/useGridRowSpanning.js +257 -0
- package/modern/hooks/features/rows/useGridRows.js +7 -1
- package/modern/hooks/features/scroll/useGridScroll.js +19 -19
- package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/modern/hooks/utils/useGridApiEventHandler.js +0 -1
- package/modern/index.js +1 -1
- package/modern/internals/index.js +2 -0
- package/modern/locales/bgBG.js +8 -9
- package/modern/locales/deDE.js +4 -4
- package/modern/locales/frFR.js +4 -4
- package/modern/locales/hrHR.js +69 -46
- package/modern/locales/jaJP.js +1 -2
- package/modern/locales/ptPT.js +4 -4
- package/modern/locales/viVN.js +20 -20
- package/modern/utils/createSelector.js +6 -0
- package/modern/utils/domUtils.js +12 -12
- package/node/DataGrid/DataGrid.js +16 -1
- package/node/DataGrid/useDataGridComponent.js +3 -0
- package/node/DataGrid/useDataGridProps.js +2 -1
- package/node/components/GridRow.js +1 -0
- package/node/components/cell/GridCell.js +33 -9
- package/node/components/columnHeaders/GridBaseColumnHeaders.js +1 -1
- package/node/components/columnSelection/GridCellCheckboxRenderer.js +12 -4
- package/node/components/containers/GridRoot.js +1 -1
- package/node/components/containers/GridRootStyles.js +32 -23
- package/node/components/containers/GridToolbarContainer.js +1 -1
- package/node/components/menu/GridMenu.js +1 -1
- package/node/components/panel/GridPanel.js +1 -1
- package/node/components/panel/GridPanelContent.js +1 -1
- package/node/components/panel/GridPanelFooter.js +1 -1
- package/node/components/panel/GridPanelHeader.js +1 -1
- package/node/components/panel/GridPanelWrapper.js +1 -1
- package/node/components/toolbar/GridToolbarQuickFilter.js +1 -1
- package/node/components/virtualization/GridBottomContainer.js +18 -1
- package/node/components/virtualization/GridMainContainer.js +3 -1
- package/node/components/virtualization/GridTopContainer.js +1 -1
- package/node/components/virtualization/GridVirtualScrollbar.js +1 -7
- package/node/components/virtualization/GridVirtualScroller.js +1 -0
- package/node/components/virtualization/GridVirtualScrollerFiller.js +3 -4
- package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
- package/node/hooks/features/columnResize/useGridColumnResize.js +6 -6
- package/node/hooks/features/columns/gridColumnsUtils.js +3 -2
- package/node/hooks/features/dimensions/useGridDimensions.js +4 -1
- package/node/hooks/features/editing/useGridCellEditing.js +3 -19
- package/node/hooks/features/editing/useGridRowEditing.js +7 -2
- package/node/hooks/features/editing/utils.js +22 -0
- package/node/hooks/features/export/useGridPrintExport.js +2 -1
- package/node/hooks/features/focus/useGridFocus.js +2 -1
- package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +16 -53
- package/node/hooks/features/keyboardNavigation/utils.js +68 -0
- package/node/hooks/features/rowSelection/useGridRowSelection.js +102 -26
- package/node/hooks/features/rowSelection/utils.js +160 -1
- package/node/hooks/features/rows/gridRowSpanningSelectors.js +11 -0
- package/node/hooks/features/rows/gridRowSpanningUtils.js +52 -0
- package/node/hooks/features/rows/useGridRowSpanning.js +267 -0
- package/node/hooks/features/rows/useGridRows.js +7 -1
- package/node/hooks/features/scroll/useGridScroll.js +19 -19
- package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/node/hooks/utils/useGridApiEventHandler.js +0 -1
- package/node/index.js +1 -1
- package/node/internals/index.js +38 -15
- package/node/locales/bgBG.js +8 -9
- package/node/locales/deDE.js +4 -4
- package/node/locales/frFR.js +4 -4
- package/node/locales/hrHR.js +69 -46
- package/node/locales/jaJP.js +1 -2
- package/node/locales/ptPT.js +4 -4
- package/node/locales/viVN.js +20 -20
- package/node/utils/createSelector.js +6 -0
- package/node/utils/domUtils.js +12 -12
- package/package.json +3 -3
- package/utils/createSelector.js +6 -0
- package/utils/domUtils.d.ts +4 -4
- package/utils/domUtils.js +12 -12
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import useLazyRef from '@mui/utils/useLazyRef';
|
|
4
|
+
import { gridVisibleColumnDefinitionsSelector } from "../columns/gridColumnsSelector.js";
|
|
5
|
+
import { useGridVisibleRows } from "../../utils/useGridVisibleRows.js";
|
|
6
|
+
import { gridRenderContextSelector } from "../virtualization/gridVirtualizationSelectors.js";
|
|
7
|
+
import { useGridSelector } from "../../utils/useGridSelector.js";
|
|
8
|
+
import { getUnprocessedRange, isRowRangeUpdated, isRowContextInitialized, getCellValue } from "./gridRowSpanningUtils.js";
|
|
9
|
+
const EMPTY_STATE = {
|
|
10
|
+
spannedCells: {},
|
|
11
|
+
hiddenCells: {},
|
|
12
|
+
hiddenCellOriginMap: {}
|
|
13
|
+
};
|
|
14
|
+
const EMPTY_RANGE = {
|
|
15
|
+
firstRowIndex: 0,
|
|
16
|
+
lastRowIndex: 0
|
|
17
|
+
};
|
|
18
|
+
const skippedFields = new Set(['__check__', '__reorder__', '__detail_panel_toggle__']);
|
|
19
|
+
/**
|
|
20
|
+
* Default number of rows to process during state initialization to avoid flickering.
|
|
21
|
+
* Number `20` is arbitrarily chosen to be large enough to cover most of the cases without
|
|
22
|
+
* compromising performance.
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_ROWS_TO_PROCESS = 20;
|
|
25
|
+
const computeRowSpanningState = (apiRef, colDefs, visibleRows, range, rangeToProcess, resetState, processedRange) => {
|
|
26
|
+
const spannedCells = resetState ? {} : _extends({}, apiRef.current.state.rowSpanning.spannedCells);
|
|
27
|
+
const hiddenCells = resetState ? {} : _extends({}, apiRef.current.state.rowSpanning.hiddenCells);
|
|
28
|
+
const hiddenCellOriginMap = resetState ? {} : _extends({}, apiRef.current.state.rowSpanning.hiddenCellOriginMap);
|
|
29
|
+
if (resetState) {
|
|
30
|
+
processedRange = EMPTY_RANGE;
|
|
31
|
+
}
|
|
32
|
+
colDefs.forEach(colDef => {
|
|
33
|
+
if (skippedFields.has(colDef.field)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
for (let index = rangeToProcess.firstRowIndex; index <= rangeToProcess.lastRowIndex; index += 1) {
|
|
37
|
+
const row = visibleRows[index];
|
|
38
|
+
if (hiddenCells[row.id]?.[colDef.field]) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const cellValue = getCellValue(row.model, colDef, apiRef);
|
|
42
|
+
if (cellValue == null) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
let spannedRowId = row.id;
|
|
46
|
+
let spannedRowIndex = index;
|
|
47
|
+
let rowSpan = 0;
|
|
48
|
+
|
|
49
|
+
// For first index, also scan in the previous rows to handle the reset state case e.g by sorting
|
|
50
|
+
const backwardsHiddenCells = [];
|
|
51
|
+
if (index === rangeToProcess.firstRowIndex) {
|
|
52
|
+
let prevIndex = index - 1;
|
|
53
|
+
const prevRowEntry = visibleRows[prevIndex];
|
|
54
|
+
while (prevIndex >= range.firstRowIndex && getCellValue(prevRowEntry.model, colDef, apiRef) === cellValue) {
|
|
55
|
+
const currentRow = visibleRows[prevIndex + 1];
|
|
56
|
+
if (hiddenCells[currentRow.id]) {
|
|
57
|
+
hiddenCells[currentRow.id][colDef.field] = true;
|
|
58
|
+
} else {
|
|
59
|
+
hiddenCells[currentRow.id] = {
|
|
60
|
+
[colDef.field]: true
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
backwardsHiddenCells.push(index);
|
|
64
|
+
rowSpan += 1;
|
|
65
|
+
spannedRowId = prevRowEntry.id;
|
|
66
|
+
spannedRowIndex = prevIndex;
|
|
67
|
+
prevIndex -= 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
backwardsHiddenCells.forEach(hiddenCellIndex => {
|
|
71
|
+
if (hiddenCellOriginMap[hiddenCellIndex]) {
|
|
72
|
+
hiddenCellOriginMap[hiddenCellIndex][colDef.field] = spannedRowIndex;
|
|
73
|
+
} else {
|
|
74
|
+
hiddenCellOriginMap[hiddenCellIndex] = {
|
|
75
|
+
[colDef.field]: spannedRowIndex
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Scan the next rows
|
|
81
|
+
let relativeIndex = index + 1;
|
|
82
|
+
while (relativeIndex <= range.lastRowIndex && visibleRows[relativeIndex] && getCellValue(visibleRows[relativeIndex].model, colDef, apiRef) === cellValue) {
|
|
83
|
+
const currentRow = visibleRows[relativeIndex];
|
|
84
|
+
if (hiddenCells[currentRow.id]) {
|
|
85
|
+
hiddenCells[currentRow.id][colDef.field] = true;
|
|
86
|
+
} else {
|
|
87
|
+
hiddenCells[currentRow.id] = {
|
|
88
|
+
[colDef.field]: true
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (hiddenCellOriginMap[relativeIndex]) {
|
|
92
|
+
hiddenCellOriginMap[relativeIndex][colDef.field] = spannedRowIndex;
|
|
93
|
+
} else {
|
|
94
|
+
hiddenCellOriginMap[relativeIndex] = {
|
|
95
|
+
[colDef.field]: spannedRowIndex
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
relativeIndex += 1;
|
|
99
|
+
rowSpan += 1;
|
|
100
|
+
}
|
|
101
|
+
if (rowSpan > 0) {
|
|
102
|
+
if (spannedCells[spannedRowId]) {
|
|
103
|
+
spannedCells[spannedRowId][colDef.field] = rowSpan + 1;
|
|
104
|
+
} else {
|
|
105
|
+
spannedCells[spannedRowId] = {
|
|
106
|
+
[colDef.field]: rowSpan + 1
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
processedRange = {
|
|
112
|
+
firstRowIndex: Math.min(processedRange.firstRowIndex, rangeToProcess.firstRowIndex),
|
|
113
|
+
lastRowIndex: Math.max(processedRange.lastRowIndex, rangeToProcess.lastRowIndex)
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
spannedCells,
|
|
118
|
+
hiddenCells,
|
|
119
|
+
hiddenCellOriginMap,
|
|
120
|
+
processedRange
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @requires columnsStateInitializer (method) - should be initialized before
|
|
126
|
+
* @requires rowsStateInitializer (method) - should be initialized before
|
|
127
|
+
* @requires filterStateInitializer (method) - should be initialized before
|
|
128
|
+
*/
|
|
129
|
+
export const rowSpanningStateInitializer = (state, props, apiRef) => {
|
|
130
|
+
if (props.unstable_rowSpanning) {
|
|
131
|
+
const rowIds = state.rows.dataRowIds || [];
|
|
132
|
+
const orderedFields = state.columns.orderedFields || [];
|
|
133
|
+
const dataRowIdToModelLookup = state.rows.dataRowIdToModelLookup;
|
|
134
|
+
const columnsLookup = state.columns.lookup;
|
|
135
|
+
const isFilteringPending = Boolean(state.filter.filterModel.items.length) || Boolean(state.filter.filterModel.quickFilterValues?.length);
|
|
136
|
+
if (!rowIds.length || !orderedFields.length || !dataRowIdToModelLookup || !columnsLookup || isFilteringPending) {
|
|
137
|
+
return _extends({}, state, {
|
|
138
|
+
rowSpanning: EMPTY_STATE
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const rangeToProcess = {
|
|
142
|
+
firstRowIndex: 0,
|
|
143
|
+
lastRowIndex: Math.min(DEFAULT_ROWS_TO_PROCESS - 1, Math.max(rowIds.length - 1, 0))
|
|
144
|
+
};
|
|
145
|
+
const rows = rowIds.map(id => ({
|
|
146
|
+
id,
|
|
147
|
+
model: dataRowIdToModelLookup[id]
|
|
148
|
+
}));
|
|
149
|
+
const colDefs = orderedFields.map(field => columnsLookup[field]);
|
|
150
|
+
const {
|
|
151
|
+
spannedCells,
|
|
152
|
+
hiddenCells,
|
|
153
|
+
hiddenCellOriginMap
|
|
154
|
+
} = computeRowSpanningState(apiRef, colDefs, rows, rangeToProcess, rangeToProcess, true, EMPTY_RANGE);
|
|
155
|
+
return _extends({}, state, {
|
|
156
|
+
rowSpanning: {
|
|
157
|
+
spannedCells,
|
|
158
|
+
hiddenCells,
|
|
159
|
+
hiddenCellOriginMap
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return _extends({}, state, {
|
|
164
|
+
rowSpanning: EMPTY_STATE
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
export const useGridRowSpanning = (apiRef, props) => {
|
|
168
|
+
const {
|
|
169
|
+
range,
|
|
170
|
+
rows: visibleRows
|
|
171
|
+
} = useGridVisibleRows(apiRef, props);
|
|
172
|
+
const renderContext = useGridSelector(apiRef, gridRenderContextSelector);
|
|
173
|
+
const colDefs = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
|
|
174
|
+
const processedRange = useLazyRef(() => {
|
|
175
|
+
return Object.keys(apiRef.current.state.rowSpanning.spannedCells).length > 0 ? {
|
|
176
|
+
firstRowIndex: 0,
|
|
177
|
+
lastRowIndex: Math.min(DEFAULT_ROWS_TO_PROCESS - 1, Math.max(apiRef.current.state.rows.dataRowIds.length - 1, 0))
|
|
178
|
+
} : EMPTY_RANGE;
|
|
179
|
+
});
|
|
180
|
+
const lastRange = React.useRef(EMPTY_RANGE);
|
|
181
|
+
const updateRowSpanningState = React.useCallback(
|
|
182
|
+
// A reset needs to occur when:
|
|
183
|
+
// - The `unstable_rowSpanning` prop is updated (feature flag)
|
|
184
|
+
// - The filtering is applied
|
|
185
|
+
// - The sorting is applied
|
|
186
|
+
// - The `paginationModel` is updated
|
|
187
|
+
// - The rows are updated
|
|
188
|
+
(resetState = true) => {
|
|
189
|
+
if (!props.unstable_rowSpanning) {
|
|
190
|
+
if (apiRef.current.state.rowSpanning !== EMPTY_STATE) {
|
|
191
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
192
|
+
rowSpanning: EMPTY_STATE
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (range === null || !isRowContextInitialized(renderContext)) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (resetState) {
|
|
201
|
+
processedRange.current = EMPTY_RANGE;
|
|
202
|
+
}
|
|
203
|
+
const rangeToProcess = getUnprocessedRange({
|
|
204
|
+
firstRowIndex: renderContext.firstRowIndex,
|
|
205
|
+
lastRowIndex: renderContext.lastRowIndex - 1
|
|
206
|
+
}, processedRange.current);
|
|
207
|
+
if (rangeToProcess === null) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const {
|
|
211
|
+
spannedCells,
|
|
212
|
+
hiddenCells,
|
|
213
|
+
hiddenCellOriginMap,
|
|
214
|
+
processedRange: newProcessedRange
|
|
215
|
+
} = computeRowSpanningState(apiRef, colDefs, visibleRows, range, rangeToProcess, resetState, processedRange.current);
|
|
216
|
+
processedRange.current = newProcessedRange;
|
|
217
|
+
const newSpannedCellsCount = Object.keys(spannedCells).length;
|
|
218
|
+
const newHiddenCellsCount = Object.keys(hiddenCells).length;
|
|
219
|
+
const currentSpannedCellsCount = Object.keys(apiRef.current.state.rowSpanning.spannedCells).length;
|
|
220
|
+
const currentHiddenCellsCount = Object.keys(apiRef.current.state.rowSpanning.hiddenCells).length;
|
|
221
|
+
const shouldUpdateState = resetState || newSpannedCellsCount !== currentSpannedCellsCount || newHiddenCellsCount !== currentHiddenCellsCount;
|
|
222
|
+
if (!shouldUpdateState) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
apiRef.current.setState(state => {
|
|
226
|
+
return _extends({}, state, {
|
|
227
|
+
rowSpanning: {
|
|
228
|
+
spannedCells,
|
|
229
|
+
hiddenCells,
|
|
230
|
+
hiddenCellOriginMap
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}, [apiRef, props.unstable_rowSpanning, range, renderContext, visibleRows, colDefs, processedRange]);
|
|
235
|
+
const prevRenderContext = React.useRef(renderContext);
|
|
236
|
+
const isFirstRender = React.useRef(true);
|
|
237
|
+
const shouldResetState = React.useRef(false);
|
|
238
|
+
React.useEffect(() => {
|
|
239
|
+
const firstRender = isFirstRender.current;
|
|
240
|
+
if (isFirstRender.current) {
|
|
241
|
+
isFirstRender.current = false;
|
|
242
|
+
}
|
|
243
|
+
if (range && lastRange.current && isRowRangeUpdated(range, lastRange.current)) {
|
|
244
|
+
lastRange.current = range;
|
|
245
|
+
shouldResetState.current = true;
|
|
246
|
+
}
|
|
247
|
+
if (!firstRender && prevRenderContext.current !== renderContext) {
|
|
248
|
+
if (isRowRangeUpdated(prevRenderContext.current, renderContext)) {
|
|
249
|
+
updateRowSpanningState(shouldResetState.current);
|
|
250
|
+
shouldResetState.current = false;
|
|
251
|
+
}
|
|
252
|
+
prevRenderContext.current = renderContext;
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
updateRowSpanningState();
|
|
256
|
+
}, [updateRowSpanningState, renderContext, range, lastRange]);
|
|
257
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import useLazyRef from '@mui/utils/useLazyRef';
|
|
3
4
|
import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
|
|
4
5
|
import { useGridLogger } from "../../utils/useGridLogger.js";
|
|
5
6
|
import { gridRowCountSelector, gridRowsLookupSelector, gridRowTreeSelector, gridRowGroupingNameSelector, gridRowTreeDepthsSelector, gridDataRowIdsSelector, gridRowsDataRowIdToIdLookupSelector, gridRowMaximumTreeDepthSelector, gridRowGroupsToFetchSelector } from "./gridRowsSelector.js";
|
|
@@ -367,11 +368,16 @@ export const useGridRows = (apiRef, props) => {
|
|
|
367
368
|
throttle: false
|
|
368
369
|
});
|
|
369
370
|
}, [logger, apiRef, props.rows, props.getRowId, props.loading, props.rowCount, throttledRowsChange]);
|
|
371
|
+
const previousDataSource = useLazyRef(() => props.unstable_dataSource);
|
|
370
372
|
const handleStrategyProcessorChange = React.useCallback(methodName => {
|
|
373
|
+
if (props.unstable_dataSource && props.unstable_dataSource !== previousDataSource.current) {
|
|
374
|
+
previousDataSource.current = props.unstable_dataSource;
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
371
377
|
if (methodName === 'rowTreeCreation') {
|
|
372
378
|
groupRows();
|
|
373
379
|
}
|
|
374
|
-
}, [groupRows]);
|
|
380
|
+
}, [groupRows, previousDataSource, props.unstable_dataSource]);
|
|
375
381
|
const handleStrategyActivityChange = React.useCallback(() => {
|
|
376
382
|
// `rowTreeCreation` is the only processor ran when `strategyAvailabilityChange` is fired.
|
|
377
383
|
// All the other processors listen to `rowsSet` which will be published by the `groupRows` method below.
|
|
@@ -14,22 +14,22 @@ import { gridDimensionsSelector } from "../dimensions/index.js";
|
|
|
14
14
|
// Similar to https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
|
15
15
|
function scrollIntoView(dimensions) {
|
|
16
16
|
const {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
containerSize,
|
|
18
|
+
scrollPosition,
|
|
19
|
+
elementSize,
|
|
20
|
+
elementOffset
|
|
21
21
|
} = dimensions;
|
|
22
|
-
const
|
|
22
|
+
const elementEnd = elementOffset + elementSize;
|
|
23
23
|
// Always scroll to top when cell is higher than viewport to avoid scroll jump
|
|
24
24
|
// See https://github.com/mui/mui-x/issues/4513 and https://github.com/mui/mui-x/issues/4514
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
25
|
+
if (elementSize > containerSize) {
|
|
26
|
+
return elementOffset;
|
|
27
27
|
}
|
|
28
|
-
if (
|
|
29
|
-
return
|
|
28
|
+
if (elementEnd - containerSize > scrollPosition) {
|
|
29
|
+
return elementEnd - containerSize;
|
|
30
30
|
}
|
|
31
|
-
if (
|
|
32
|
-
return
|
|
31
|
+
if (elementOffset < scrollPosition) {
|
|
32
|
+
return elementOffset;
|
|
33
33
|
}
|
|
34
34
|
return undefined;
|
|
35
35
|
}
|
|
@@ -73,10 +73,10 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
73
73
|
}
|
|
74
74
|
// When using RTL, `scrollLeft` becomes negative, so we must ensure that we only compare values.
|
|
75
75
|
scrollCoordinates.left = scrollIntoView({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
containerSize: dimensions.viewportOuterSize.width,
|
|
77
|
+
scrollPosition: Math.abs(virtualScrollerRef.current.scrollLeft),
|
|
78
|
+
elementSize: cellWidth,
|
|
79
|
+
elementOffset: columnPositions[params.colIndex]
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
if (params.rowIndex !== undefined) {
|
|
@@ -86,10 +86,10 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
86
86
|
const elementIndex = !props.pagination ? params.rowIndex : params.rowIndex - page * pageSize;
|
|
87
87
|
const targetOffsetHeight = rowsMeta.positions[elementIndex + 1] ? rowsMeta.positions[elementIndex + 1] - rowsMeta.positions[elementIndex] : rowsMeta.currentPageTotalHeight - rowsMeta.positions[elementIndex];
|
|
88
88
|
scrollCoordinates.top = scrollIntoView({
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
containerSize: dimensions.viewportInnerSize.height,
|
|
90
|
+
scrollPosition: virtualScrollerRef.current.scrollTop,
|
|
91
|
+
elementSize: targetOffsetHeight,
|
|
92
|
+
elementOffset: rowsMeta.positions[elementIndex]
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
scrollCoordinates = apiRef.current.unstable_applyPipeProcessors('scrollToIndexes', scrollCoordinates, params);
|
|
@@ -24,6 +24,7 @@ import { getFirstNonSpannedColumnToRender } from "../columns/gridColumnsUtils.js
|
|
|
24
24
|
import { getMinimalContentHeight } from "../rows/gridRowsUtils.js";
|
|
25
25
|
import { gridRenderContextSelector, gridVirtualizationRowEnabledSelector, gridVirtualizationColumnEnabledSelector } from "./gridVirtualizationSelectors.js";
|
|
26
26
|
import { EMPTY_RENDER_CONTEXT } from "./useGridVirtualization.js";
|
|
27
|
+
import { gridRowSpanningHiddenCellsOriginMapSelector } from "../rows/gridRowSpanningSelectors.js";
|
|
27
28
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
28
29
|
const MINIMUM_COLUMN_WIDTH = 50;
|
|
29
30
|
var ScrollDirection = /*#__PURE__*/function (ScrollDirection) {
|
|
@@ -325,7 +326,7 @@ export const useGridVirtualScroller = () => {
|
|
|
325
326
|
if (!isPinnedSection && frozenContext.current && rowIndexInPage >= frozenContext.current.firstRowIndex && rowIndexInPage < frozenContext.current.lastRowIndex) {
|
|
326
327
|
currentRenderContext = frozenContext.current;
|
|
327
328
|
}
|
|
328
|
-
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext,
|
|
329
|
+
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, pinnedColumns.left.length);
|
|
329
330
|
const showBottomBorder = isLastVisibleInSection && params.position === 'top';
|
|
330
331
|
rows.push(/*#__PURE__*/_jsx(rootProps.slots.row, _extends({
|
|
331
332
|
row: model,
|
|
@@ -353,7 +354,7 @@ export const useGridVirtualScroller = () => {
|
|
|
353
354
|
if (panel) {
|
|
354
355
|
rows.push(panel);
|
|
355
356
|
}
|
|
356
|
-
if (
|
|
357
|
+
if (params.position === undefined && isLastVisibleInSection) {
|
|
357
358
|
rows.push(apiRef.current.getInfiniteLoadingTriggerElement?.({
|
|
358
359
|
lastRowId: id
|
|
359
360
|
}));
|
|
@@ -447,6 +448,7 @@ function inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns) {
|
|
|
447
448
|
const dimensions = gridDimensionsSelector(apiRef.current.state);
|
|
448
449
|
const currentPage = getVisibleRows(apiRef, rootProps);
|
|
449
450
|
const visibleColumns = gridVisibleColumnDefinitionsSelector(apiRef);
|
|
451
|
+
const hiddenCellsOriginMap = gridRowSpanningHiddenCellsOriginMapSelector(apiRef);
|
|
450
452
|
const lastRowId = apiRef.current.state.rows.dataRowIds.at(-1);
|
|
451
453
|
const lastColumn = visibleColumns.at(-1);
|
|
452
454
|
return {
|
|
@@ -467,7 +469,8 @@ function inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns) {
|
|
|
467
469
|
rows: currentPage.rows,
|
|
468
470
|
range: currentPage.range,
|
|
469
471
|
pinnedColumns: gridVisiblePinnedColumnDefinitionsSelector(apiRef),
|
|
470
|
-
visibleColumns
|
|
472
|
+
visibleColumns,
|
|
473
|
+
hiddenCellsOriginMap
|
|
471
474
|
};
|
|
472
475
|
}
|
|
473
476
|
function computeRenderContext(inputs, scrollPosition, scrollCache) {
|
|
@@ -485,10 +488,18 @@ function computeRenderContext(inputs, scrollPosition, scrollCache) {
|
|
|
485
488
|
if (inputs.enabledForRows) {
|
|
486
489
|
// Clamp the value because the search may return an index out of bounds.
|
|
487
490
|
// In the last index, this is not needed because Array.slice doesn't include it.
|
|
488
|
-
|
|
491
|
+
let firstRowIndex = Math.min(getNearestIndexToRender(inputs, top, {
|
|
489
492
|
atStart: true,
|
|
490
493
|
lastPosition: inputs.rowsMeta.positions[inputs.rowsMeta.positions.length - 1] + inputs.lastRowHeight
|
|
491
494
|
}), inputs.rowsMeta.positions.length - 1);
|
|
495
|
+
|
|
496
|
+
// If any of the cells in the `firstRowIndex` is hidden due to an extended row span,
|
|
497
|
+
// Make sure the row from where the rowSpan is originated is visible.
|
|
498
|
+
const rowSpanHiddenCellOrigin = inputs.hiddenCellsOriginMap[firstRowIndex];
|
|
499
|
+
if (rowSpanHiddenCellOrigin) {
|
|
500
|
+
const minSpannedRowIndex = Math.min(...Object.values(rowSpanHiddenCellOrigin));
|
|
501
|
+
firstRowIndex = Math.min(firstRowIndex, minSpannedRowIndex);
|
|
502
|
+
}
|
|
492
503
|
const lastRowIndex = inputs.autoHeight ? firstRowIndex + inputs.rows.length : getNearestIndexToRender(inputs, top + inputs.viewportInnerHeight);
|
|
493
504
|
renderContext.firstRowIndex = firstRowIndex;
|
|
494
505
|
renderContext.lastRowIndex = lastRowIndex;
|
|
@@ -642,9 +653,8 @@ export function areRenderContextsEqual(context1, context2) {
|
|
|
642
653
|
}
|
|
643
654
|
return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
|
|
644
655
|
}
|
|
645
|
-
export function computeOffsetLeft(columnPositions, renderContext,
|
|
646
|
-
const
|
|
647
|
-
const left = factor * (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0);
|
|
656
|
+
export function computeOffsetLeft(columnPositions, renderContext, pinnedLeftLength) {
|
|
657
|
+
const left = (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0);
|
|
648
658
|
return Math.abs(left);
|
|
649
659
|
}
|
|
650
660
|
function directionForDelta(dx, dy) {
|
|
@@ -90,7 +90,6 @@ const optionsSubscriberOptions = {
|
|
|
90
90
|
isFirst: true
|
|
91
91
|
};
|
|
92
92
|
export function useGridApiOptionHandler(apiRef, eventName, handler) {
|
|
93
|
-
// Validate that only one per event name?
|
|
94
93
|
useGridApiEventHandler(apiRef, eventName, handler, optionsSubscriberOptions);
|
|
95
94
|
}
|
|
96
95
|
export { GridSignature };
|
package/modern/index.js
CHANGED
|
@@ -32,6 +32,7 @@ export { useGridPreferencesPanel, preferencePanelStateInitializer } from "../hoo
|
|
|
32
32
|
export { useGridEditing, editingStateInitializer } from "../hooks/features/editing/useGridEditing.js";
|
|
33
33
|
export { gridEditRowsStateSelector } from "../hooks/features/editing/gridEditingSelectors.js";
|
|
34
34
|
export { useGridRows, rowsStateInitializer } from "../hooks/features/rows/useGridRows.js";
|
|
35
|
+
export { useGridRowSpanning, rowSpanningStateInitializer } from "../hooks/features/rows/useGridRowSpanning.js";
|
|
35
36
|
export { useGridAriaAttributes } from "../hooks/utils/useGridAriaAttributes.js";
|
|
36
37
|
export { useGridRowAriaAttributes } from "../hooks/features/rows/useGridRowAriaAttributes.js";
|
|
37
38
|
export { useGridRowsPreProcessors } from "../hooks/features/rows/useGridRowsPreProcessors.js";
|
|
@@ -52,6 +53,7 @@ export { useGridStatePersistence } from "../hooks/features/statePersistence/useG
|
|
|
52
53
|
export { useGridVirtualScroller, EMPTY_DETAIL_PANELS } from "../hooks/features/virtualization/useGridVirtualScroller.js";
|
|
53
54
|
export * from "../hooks/features/virtualization/index.js";
|
|
54
55
|
export { useGridColumnResize, columnResizeStateInitializer } from "../hooks/features/columnResize/useGridColumnResize.js";
|
|
56
|
+
export { ROW_SELECTION_PROPAGATION_DEFAULT } from "../hooks/features/rowSelection/utils.js";
|
|
55
57
|
export { useTimeout } from "../hooks/utils/useTimeout.js";
|
|
56
58
|
export { useGridVisibleRows, getVisibleRows } from "../hooks/utils/useGridVisibleRows.js";
|
|
57
59
|
export { useGridInitializeState } from "../hooks/utils/useGridInitializeState.js";
|
package/modern/locales/bgBG.js
CHANGED
|
@@ -30,11 +30,10 @@ const bgBGGrid = {
|
|
|
30
30
|
toolbarExportPrint: 'Принтиране',
|
|
31
31
|
toolbarExportExcel: 'Изтегли като Excel',
|
|
32
32
|
// Columns management text
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
columnsManagementSearchTitle: 'Търсене',
|
|
34
|
+
columnsManagementNoColumns: 'Няма колони',
|
|
35
|
+
columnsManagementShowHideAllText: 'Покажи/Скрий Всичко',
|
|
36
|
+
columnsManagementReset: 'Нулирай',
|
|
38
37
|
// Filter panel text
|
|
39
38
|
filterPanelAddFilter: 'Добави Филтър',
|
|
40
39
|
filterPanelRemoveAll: 'Премахни всички',
|
|
@@ -48,9 +47,9 @@ const bgBGGrid = {
|
|
|
48
47
|
filterPanelInputPlaceholder: 'Стойност на филтъра',
|
|
49
48
|
// Filter operators text
|
|
50
49
|
filterOperatorContains: 'съдържа',
|
|
51
|
-
|
|
50
|
+
filterOperatorDoesNotContain: 'не съдържа',
|
|
52
51
|
filterOperatorEquals: 'равно',
|
|
53
|
-
|
|
52
|
+
filterOperatorDoesNotEqual: 'не е равно',
|
|
54
53
|
filterOperatorStartsWith: 'започва с',
|
|
55
54
|
filterOperatorEndsWith: 'завършва с',
|
|
56
55
|
filterOperatorIs: 'е',
|
|
@@ -70,9 +69,9 @@ const bgBGGrid = {
|
|
|
70
69
|
'filterOperator<=': '<=',
|
|
71
70
|
// Header filter operators text
|
|
72
71
|
headerFilterOperatorContains: 'Съдържа',
|
|
73
|
-
|
|
72
|
+
headerFilterOperatorDoesNotContain: 'Не съдържа',
|
|
74
73
|
headerFilterOperatorEquals: 'Равнo',
|
|
75
|
-
|
|
74
|
+
headerFilterOperatorDoesNotEqual: 'Не е равно',
|
|
76
75
|
headerFilterOperatorStartsWith: 'Започва с',
|
|
77
76
|
headerFilterOperatorEndsWith: 'Завършва с',
|
|
78
77
|
headerFilterOperatorIs: 'Равно е на',
|
package/modern/locales/deDE.js
CHANGED
|
@@ -47,9 +47,9 @@ const deDEGrid = {
|
|
|
47
47
|
filterPanelInputPlaceholder: 'Wert filtern',
|
|
48
48
|
// Filter operators text
|
|
49
49
|
filterOperatorContains: 'enthält',
|
|
50
|
-
|
|
50
|
+
filterOperatorDoesNotContain: 'enthält nicht',
|
|
51
51
|
filterOperatorEquals: 'ist gleich',
|
|
52
|
-
|
|
52
|
+
filterOperatorDoesNotEqual: 'ist ungleich',
|
|
53
53
|
filterOperatorStartsWith: 'beginnt mit',
|
|
54
54
|
filterOperatorEndsWith: 'endet mit',
|
|
55
55
|
filterOperatorIs: 'ist',
|
|
@@ -69,9 +69,9 @@ const deDEGrid = {
|
|
|
69
69
|
'filterOperator<=': '<=',
|
|
70
70
|
// Header filter operators text
|
|
71
71
|
headerFilterOperatorContains: 'Enthält',
|
|
72
|
-
|
|
72
|
+
headerFilterOperatorDoesNotContain: 'Enthält nicht',
|
|
73
73
|
headerFilterOperatorEquals: 'Gleich',
|
|
74
|
-
|
|
74
|
+
headerFilterOperatorDoesNotEqual: 'Ungleich',
|
|
75
75
|
headerFilterOperatorStartsWith: 'Beginnt mit',
|
|
76
76
|
headerFilterOperatorEndsWith: 'Endet mit',
|
|
77
77
|
headerFilterOperatorIs: 'Ist',
|
package/modern/locales/frFR.js
CHANGED
|
@@ -47,9 +47,9 @@ const frFRGrid = {
|
|
|
47
47
|
filterPanelInputPlaceholder: 'Filtrer la valeur',
|
|
48
48
|
// Filter operators text
|
|
49
49
|
filterOperatorContains: 'contient',
|
|
50
|
-
|
|
50
|
+
filterOperatorDoesNotContain: 'ne contient pas',
|
|
51
51
|
filterOperatorEquals: 'est égal à',
|
|
52
|
-
|
|
52
|
+
filterOperatorDoesNotEqual: "n'est pas égal à",
|
|
53
53
|
filterOperatorStartsWith: 'commence par',
|
|
54
54
|
filterOperatorEndsWith: 'se termine par',
|
|
55
55
|
filterOperatorIs: 'est',
|
|
@@ -69,9 +69,9 @@ const frFRGrid = {
|
|
|
69
69
|
'filterOperator<=': '<=',
|
|
70
70
|
// Header filter operators text
|
|
71
71
|
headerFilterOperatorContains: 'Contient',
|
|
72
|
-
|
|
72
|
+
headerFilterOperatorDoesNotContain: 'Ne contient pas',
|
|
73
73
|
headerFilterOperatorEquals: 'Est égal à',
|
|
74
|
-
|
|
74
|
+
headerFilterOperatorDoesNotEqual: "N'est pas égal à",
|
|
75
75
|
headerFilterOperatorStartsWith: 'Commence par',
|
|
76
76
|
headerFilterOperatorEndsWith: 'Se termine par',
|
|
77
77
|
headerFilterOperatorIs: 'Est',
|