@monolith-forensics/monolith-ui 1.8.0 → 1.8.1-dev.1
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/dist/Button/Button.js +9 -58
- package/dist/Calendar/Calendar.d.ts +3 -1
- package/dist/Calendar/Calendar.js +134 -33
- package/dist/Calendar/CalendarStyles.d.ts +3 -0
- package/dist/Calendar/CalendarStyles.js +92 -14
- package/dist/Calendar/calendarHelpers.d.ts +5 -1
- package/dist/Calendar/calendarHelpers.js +13 -5
- package/dist/Charts/BarChart/BarChart.d.ts +5 -0
- package/dist/Charts/BarChart/BarChart.js +549 -0
- package/dist/Charts/BarChart/BarChart.lib.d.ts +31 -0
- package/dist/Charts/BarChart/BarChart.lib.js +136 -0
- package/dist/Charts/BarChart/BarChart.styled.d.ts +51 -0
- package/dist/Charts/BarChart/BarChart.styled.js +115 -0
- package/dist/Charts/BarChart/BarChart.types.d.ts +171 -0
- package/dist/Charts/BarChart/BarChart.types.js +1 -0
- package/dist/Charts/BarChart/index.d.ts +3 -0
- package/dist/Charts/BarChart/index.js +2 -0
- package/dist/Charts/ChartPrimitives/ChartExportControl.d.ts +11 -0
- package/dist/Charts/ChartPrimitives/ChartExportControl.js +29 -0
- package/dist/Charts/ChartPrimitives/chartActions.styled.d.ts +1 -0
- package/dist/Charts/ChartPrimitives/chartActions.styled.js +8 -0
- package/dist/Charts/ChartPrimitives/chartLegend.styled.d.ts +12 -0
- package/dist/Charts/ChartPrimitives/chartLegend.styled.js +52 -0
- package/dist/Charts/ChartPrimitives/chartTooltip.styled.d.ts +19 -0
- package/dist/Charts/ChartPrimitives/chartTooltip.styled.js +61 -0
- package/dist/Charts/ChartPrimitives/index.d.ts +4 -0
- package/dist/Charts/ChartPrimitives/index.js +4 -0
- package/dist/Charts/ChartUtils/chartColors.d.ts +8 -0
- package/dist/Charts/ChartUtils/chartColors.js +65 -0
- package/dist/Charts/ChartUtils/chartExport.d.ts +47 -0
- package/dist/Charts/ChartUtils/chartExport.js +311 -0
- package/dist/Charts/ChartUtils/chartMath.d.ts +3 -0
- package/dist/Charts/ChartUtils/chartMath.js +3 -0
- package/dist/Charts/ChartUtils/index.d.ts +3 -0
- package/dist/Charts/ChartUtils/index.js +3 -0
- package/dist/Charts/HeatMap/HeatMap.d.ts +5 -0
- package/dist/Charts/HeatMap/HeatMap.js +212 -0
- package/dist/Charts/HeatMap/HeatMap.lib.d.ts +30 -0
- package/dist/Charts/HeatMap/HeatMap.lib.js +115 -0
- package/dist/Charts/HeatMap/HeatMap.styled.d.ts +37 -0
- package/dist/Charts/HeatMap/HeatMap.styled.js +91 -0
- package/dist/Charts/HeatMap/HeatMap.types.d.ts +80 -0
- package/dist/Charts/HeatMap/HeatMap.types.js +1 -0
- package/dist/Charts/HeatMap/index.d.ts +3 -0
- package/dist/Charts/HeatMap/index.js +2 -0
- package/dist/Charts/LineChart/LineChart.d.ts +5 -0
- package/dist/Charts/LineChart/LineChart.js +529 -0
- package/dist/Charts/LineChart/LineChart.lib.d.ts +24 -0
- package/dist/Charts/LineChart/LineChart.lib.js +132 -0
- package/dist/Charts/LineChart/LineChart.styled.d.ts +59 -0
- package/dist/Charts/LineChart/LineChart.styled.js +147 -0
- package/dist/Charts/LineChart/LineChart.types.d.ts +193 -0
- package/dist/Charts/LineChart/LineChart.types.js +1 -0
- package/dist/Charts/LineChart/index.d.ts +3 -0
- package/dist/Charts/LineChart/index.js +2 -0
- package/dist/Charts/PieChart/PieChart.d.ts +4 -0
- package/dist/Charts/PieChart/PieChart.js +199 -0
- package/dist/Charts/PieChart/PieChart.lib.d.ts +5 -0
- package/dist/Charts/PieChart/PieChart.lib.js +19 -0
- package/dist/Charts/PieChart/PieChart.styled.d.ts +51 -0
- package/dist/Charts/PieChart/PieChart.styled.js +163 -0
- package/dist/Charts/PieChart/PieChart.types.d.ts +100 -0
- package/dist/Charts/PieChart/PieChart.types.js +1 -0
- package/dist/Charts/PieChart/index.d.ts +2 -0
- package/dist/Charts/PieChart/index.js +1 -0
- package/dist/Charts/index.d.ts +5 -0
- package/dist/Charts/index.js +4 -0
- package/dist/CheckBox/CheckBox.js +2 -16
- package/dist/DateInput/DateInput.js +198 -143
- package/dist/DropDownMenu/components/MenuComponent.js +2 -1
- package/dist/DropDownMenu/components/MenuItem.js +5 -14
- package/dist/DropDownMenu/components/MenuItemList.js +7 -24
- package/dist/DropDownMenu/components/StyledFloatContainer.js +1 -1
- package/dist/FieldLabel/FieldLabel.js +4 -12
- package/dist/FileInputField/FileInputField.js +4 -23
- package/dist/FormSection/FormSection.js +5 -25
- package/dist/IconButton/IconButton.js +2 -16
- package/dist/Input/Input.js +7 -56
- package/dist/Pill/Pill.js +8 -79
- package/dist/Popover/Popover.context.d.ts +2 -1
- package/dist/Popover/Popover.js +5 -2
- package/dist/Popover/Popover.styles.d.ts +1 -6
- package/dist/Popover/Popover.styles.js +11 -28
- package/dist/Popover/Popover.transitions.d.ts +4 -2
- package/dist/Popover/Popover.transitions.js +23 -49
- package/dist/Popover/PopoverDropdown.js +6 -8
- package/dist/Popover/PopoverTarget.js +6 -3
- package/dist/SegmentedControl/SegmentedControl.utils.d.ts +2 -2
- package/dist/SegmentedControl/SegmentedControl.utils.js +3 -30
- package/dist/SelectBox/SelectBox.js +5 -5
- package/dist/SelectBox/select-box.styled-components.d.ts +4 -1
- package/dist/SelectBox/select-box.styled-components.js +11 -48
- package/dist/SelectBox/types.d.ts +1 -0
- package/dist/Switch/Switch.d.ts +2 -2
- package/dist/Switch/Switch.js +18 -83
- package/dist/Table/StateStorage.d.ts +4 -0
- package/dist/Table/StateStorage.js +13 -0
- package/dist/Table/Table.js +160 -12
- package/dist/Table/TableComponents.d.ts +10 -0
- package/dist/Table/TableComponents.js +57 -0
- package/dist/Table/TableDefaults.d.ts +7 -0
- package/dist/Table/TableDefaults.js +7 -0
- package/dist/Table/TableProvider.js +263 -71
- package/dist/Table/TableRow.js +15 -10
- package/dist/Table/types.d.ts +64 -0
- package/dist/TagBox/TagBox.js +18 -76
- package/dist/TextArea/TextArea.js +4 -23
- package/dist/TextInput/TextInput.js +12 -6
- package/dist/Utilities/parseTimestamp.js +11 -6
- package/dist/core/ArrowButton.d.ts +2 -0
- package/dist/core/ArrowButton.js +7 -3
- package/dist/core/ClearButton.d.ts +2 -0
- package/dist/core/ClearButton.js +7 -3
- package/dist/core/controlSizes.d.ts +34 -0
- package/dist/core/controlSizes.js +190 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +5 -1
|
@@ -115,6 +115,55 @@ export const InnerCellContent = styled.div `
|
|
|
115
115
|
overflow: hidden;
|
|
116
116
|
text-overflow: ellipsis;
|
|
117
117
|
`;
|
|
118
|
+
export const TreeCellWrapper = styled.div `
|
|
119
|
+
display: flex;
|
|
120
|
+
flex-direction: row;
|
|
121
|
+
align-items: center;
|
|
122
|
+
flex: 1 1 auto;
|
|
123
|
+
min-width: 0;
|
|
124
|
+
`;
|
|
125
|
+
export const TreeIndentSpacer = styled.div `
|
|
126
|
+
flex: 0 0 auto;
|
|
127
|
+
width: ${({ $level, $indentPx }) => $level * $indentPx}px;
|
|
128
|
+
`;
|
|
129
|
+
export const TreeChevronButton = styled.button `
|
|
130
|
+
flex: 0 0 auto;
|
|
131
|
+
width: 14px;
|
|
132
|
+
height: 16px;
|
|
133
|
+
padding: 0;
|
|
134
|
+
margin: 0 8px 0 0;
|
|
135
|
+
display: inline-flex;
|
|
136
|
+
align-items: center;
|
|
137
|
+
justify-content: flex-start;
|
|
138
|
+
background: transparent;
|
|
139
|
+
border: none;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
color: ${({ theme }) => theme.palette.text.secondary};
|
|
142
|
+
transition: transform 120ms ease;
|
|
143
|
+
transform: rotate(${({ $expanded }) => ($expanded ? "90deg" : "0deg")});
|
|
144
|
+
|
|
145
|
+
&:hover {
|
|
146
|
+
color: ${({ theme }) => theme.palette.text.primary};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
&:focus-visible {
|
|
150
|
+
outline: 1px solid ${({ theme }) => theme.palette.primary.main};
|
|
151
|
+
outline-offset: 1px;
|
|
152
|
+
}
|
|
153
|
+
`;
|
|
154
|
+
export const TreeChevronPlaceholder = styled.div `
|
|
155
|
+
flex: 0 0 auto;
|
|
156
|
+
width: 12px;
|
|
157
|
+
height: 16px;
|
|
158
|
+
margin: 0 10px 0 0;
|
|
159
|
+
`;
|
|
160
|
+
export const TreeCellContent = styled.div `
|
|
161
|
+
flex: 1 1 auto;
|
|
162
|
+
min-width: 0;
|
|
163
|
+
overflow: hidden;
|
|
164
|
+
text-overflow: ellipsis;
|
|
165
|
+
white-space: nowrap;
|
|
166
|
+
`;
|
|
118
167
|
export const TableViewPort = styled.div `
|
|
119
168
|
display: flex;
|
|
120
169
|
flex-direction: column;
|
|
@@ -148,6 +197,14 @@ export const StyledTable = styled.div `
|
|
|
148
197
|
font-size: ${TableDefaults.td.fontSize.compact}px !important;
|
|
149
198
|
}
|
|
150
199
|
|
|
200
|
+
.mfui-td[data-tree-cell="true"] {
|
|
201
|
+
padding-left: ${TableDefaults.td.padding.normal - 3}px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
&[data-compact="true"] .mfui-td[data-tree-cell="true"] {
|
|
205
|
+
padding-left: ${TableDefaults.td.padding.compact - 3}px !important;
|
|
206
|
+
}
|
|
207
|
+
|
|
151
208
|
.os-scrollbar {
|
|
152
209
|
pointer-events: auto;
|
|
153
210
|
visibility: visible;
|
|
@@ -21,5 +21,12 @@ declare const TableDefaults: {
|
|
|
21
21
|
minWidth: number;
|
|
22
22
|
maxWidth: number;
|
|
23
23
|
};
|
|
24
|
+
tree: {
|
|
25
|
+
indentPx: number;
|
|
26
|
+
chevronWidth: number;
|
|
27
|
+
defaultMode: "nested";
|
|
28
|
+
defaultChildrenField: string;
|
|
29
|
+
defaultParentIdField: string;
|
|
30
|
+
};
|
|
24
31
|
};
|
|
25
32
|
export default TableDefaults;
|
|
@@ -21,5 +21,12 @@ const TableDefaults = {
|
|
|
21
21
|
minWidth: 35,
|
|
22
22
|
maxWidth: 35,
|
|
23
23
|
},
|
|
24
|
+
tree: {
|
|
25
|
+
indentPx: 16,
|
|
26
|
+
chevronWidth: 16,
|
|
27
|
+
defaultMode: "nested",
|
|
28
|
+
defaultChildrenField: "children",
|
|
29
|
+
defaultParentIdField: "parentId",
|
|
30
|
+
},
|
|
24
31
|
};
|
|
25
32
|
export default TableDefaults;
|
|
@@ -29,6 +29,27 @@ import { SelectionStatus } from "./enums";
|
|
|
29
29
|
import moment from "moment";
|
|
30
30
|
import { useControlled } from "../Utilities";
|
|
31
31
|
import { exportTableToExcel } from "./Utils";
|
|
32
|
+
const RESERVED_FIELDS = [
|
|
33
|
+
"__key",
|
|
34
|
+
"__index",
|
|
35
|
+
"__level",
|
|
36
|
+
"__parentKey",
|
|
37
|
+
"__hasChildren",
|
|
38
|
+
"__childKeys",
|
|
39
|
+
];
|
|
40
|
+
const EMPTY_TREE_META = {
|
|
41
|
+
parentKeyMap: new Map(),
|
|
42
|
+
childrenKeyMap: new Map(),
|
|
43
|
+
expandableKeys: [],
|
|
44
|
+
};
|
|
45
|
+
const DEFAULT_TREE_OPTIONS = {
|
|
46
|
+
enabled: false,
|
|
47
|
+
mode: "nested",
|
|
48
|
+
childrenField: "children",
|
|
49
|
+
parentIdField: "parentId",
|
|
50
|
+
indentPx: 16,
|
|
51
|
+
autoExpandOnMatch: true,
|
|
52
|
+
};
|
|
32
53
|
const calculateSelectionTotal = (selectionState, totalRecords, dataLength = 0) => {
|
|
33
54
|
if (!selectionState) {
|
|
34
55
|
return 0;
|
|
@@ -48,11 +69,21 @@ const calculateSelectionTotal = (selectionState, totalRecords, dataLength = 0) =
|
|
|
48
69
|
};
|
|
49
70
|
export const TableContext = createContext(null);
|
|
50
71
|
const TableProvider = (_a) => {
|
|
51
|
-
var { children, columns, data, keyField, tableInstanceRef, stateStorage, tableMenuOptions, manualSorting, manualFiltering, manualSearch, manualExport, height, maxHeight, minHeight, focusedRowId, enableColumnResize, enableSorting, compact, totalRecords, onColumnStateChange, onColumnReorder, onColumnHeaderClick, onSort, onRowUpdated, tableElement, headerRowElm, tableDimensions, targetElm, listElm, defaultSelectionState, selectionState, onSelectionChange, defaultFilterState, filterState, onFilterChange } = _a, props = __rest(_a, ["children", "columns", "data", "keyField", "tableInstanceRef", "stateStorage", "tableMenuOptions", "manualSorting", "manualFiltering", "manualSearch", "manualExport", "height", "maxHeight", "minHeight", "focusedRowId", "enableColumnResize", "enableSorting", "compact", "totalRecords", "onColumnStateChange", "onColumnReorder", "onColumnHeaderClick", "onSort", "onRowUpdated", "tableElement", "headerRowElm", "tableDimensions", "targetElm", "listElm", "defaultSelectionState", "selectionState", "onSelectionChange", "defaultFilterState", "filterState", "onFilterChange"]);
|
|
72
|
+
var { children, columns, data, keyField, tableInstanceRef, stateStorage, tableMenuOptions, manualSorting, manualFiltering, manualSearch, manualExport, height, maxHeight, minHeight, focusedRowId, enableColumnResize, enableSorting, compact, totalRecords, onColumnStateChange, onColumnReorder, onColumnHeaderClick, onSort, onRowUpdated, tableElement, headerRowElm, tableDimensions, targetElm, listElm, defaultSelectionState, selectionState, onSelectionChange, defaultFilterState, filterState, onFilterChange, treeOptions, treeMeta, defaultExpandedKeys, expandedKeys, onExpandedChange } = _a, props = __rest(_a, ["children", "columns", "data", "keyField", "tableInstanceRef", "stateStorage", "tableMenuOptions", "manualSorting", "manualFiltering", "manualSearch", "manualExport", "height", "maxHeight", "minHeight", "focusedRowId", "enableColumnResize", "enableSorting", "compact", "totalRecords", "onColumnStateChange", "onColumnReorder", "onColumnHeaderClick", "onSort", "onRowUpdated", "tableElement", "headerRowElm", "tableDimensions", "targetElm", "listElm", "defaultSelectionState", "selectionState", "onSelectionChange", "defaultFilterState", "filterState", "onFilterChange", "treeOptions", "treeMeta", "defaultExpandedKeys", "expandedKeys", "onExpandedChange"]);
|
|
73
|
+
const _treeOptions = treeOptions || DEFAULT_TREE_OPTIONS;
|
|
74
|
+
const _treeMeta = treeMeta || EMPTY_TREE_META;
|
|
75
|
+
if (_treeOptions.enabled) {
|
|
76
|
+
if (RESERVED_FIELDS.includes(_treeOptions.childrenField)) {
|
|
77
|
+
throw new Error(`treeOptions.childrenField cannot be a reserved internal field: "${_treeOptions.childrenField}".`);
|
|
78
|
+
}
|
|
79
|
+
if (RESERVED_FIELDS.includes(_treeOptions.parentIdField)) {
|
|
80
|
+
throw new Error(`treeOptions.parentIdField cannot be a reserved internal field: "${_treeOptions.parentIdField}".`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
52
83
|
const _columns = useMemo(() => columns
|
|
53
84
|
.map((child, index) => {
|
|
54
|
-
if (child.dataField
|
|
55
|
-
throw new Error(
|
|
85
|
+
if (RESERVED_FIELDS.includes(child.dataField)) {
|
|
86
|
+
throw new Error(`dataField cannot be a reserved internal field: "${child.dataField}". Reserved: ${RESERVED_FIELDS.join(", ")}`);
|
|
56
87
|
}
|
|
57
88
|
// check for duplicate dataFields
|
|
58
89
|
const dataFieldCount = columns.filter((col) => col.dataField === child.dataField).length;
|
|
@@ -71,7 +102,7 @@ const TableProvider = (_a) => {
|
|
|
71
102
|
? StateStorage.getTableState(stateStorage.key)
|
|
72
103
|
: undefined;
|
|
73
104
|
}, [stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.key]);
|
|
74
|
-
const { columnState: savedColumnState, selectionState: savedSelectionState, sortState: savedSortState, searchState: savedSearchState, filterState: savedFilterState, } = savedTableState || {};
|
|
105
|
+
const { columnState: savedColumnState, selectionState: savedSelectionState, sortState: savedSortState, searchState: savedSearchState, filterState: savedFilterState, expandedKeys: savedExpandedKeys, } = savedTableState || {};
|
|
75
106
|
const [compactState, setCompactState] = useState(compact || false);
|
|
76
107
|
const [columnState, _setColumnState] = useState(syncColumnState(_columns, savedColumnState));
|
|
77
108
|
const columnStateRef = useRef(columnState);
|
|
@@ -85,6 +116,8 @@ const TableProvider = (_a) => {
|
|
|
85
116
|
rules: [],
|
|
86
117
|
});
|
|
87
118
|
const [sortState, setSortState] = useState(savedSortState);
|
|
119
|
+
const [_expandedKeys, _setExpandedKeys] = useControlled(expandedKeys, defaultExpandedKeys || savedExpandedKeys || []);
|
|
120
|
+
const expandedKeysSet = useMemo(() => new Set(_expandedKeys), [_expandedKeys]);
|
|
88
121
|
const [_selectionState, _setSelectionState] = useControlled(selectionState, defaultSelectionState || {
|
|
89
122
|
selectedRowKeys: (savedSelectionState === null || savedSelectionState === void 0 ? void 0 : savedSelectionState.selectedRowKeys) || [],
|
|
90
123
|
excludedRowKeys: (savedSelectionState === null || savedSelectionState === void 0 ? void 0 : savedSelectionState.excludedRowKeys) || [],
|
|
@@ -238,58 +271,99 @@ const TableProvider = (_a) => {
|
|
|
238
271
|
}
|
|
239
272
|
}
|
|
240
273
|
};
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
if (aIsEmpty || bIsEmpty) {
|
|
254
|
-
if (sortState.dir === "asc") {
|
|
255
|
-
return aIsEmpty ? -1 : 1;
|
|
256
|
-
}
|
|
257
|
-
if (sortState.dir === "desc") {
|
|
258
|
-
return aIsEmpty ? 1 : -1;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
274
|
+
const compareRows = (a, b, sortState) => {
|
|
275
|
+
if (sortState) {
|
|
276
|
+
const aValue = a[sortState.dataField];
|
|
277
|
+
const bValue = b[sortState.dataField];
|
|
278
|
+
const aIsEmpty = aValue === null || aValue === undefined;
|
|
279
|
+
const bIsEmpty = bValue === null || bValue === undefined;
|
|
280
|
+
// Treat empty values as the smallest values.
|
|
281
|
+
if (aIsEmpty && bIsEmpty) {
|
|
282
|
+
return 0;
|
|
283
|
+
}
|
|
284
|
+
if (aIsEmpty || bIsEmpty) {
|
|
261
285
|
if (sortState.dir === "asc") {
|
|
262
|
-
|
|
263
|
-
return -1;
|
|
264
|
-
}
|
|
265
|
-
if (aValue > bValue) {
|
|
266
|
-
return 1;
|
|
267
|
-
}
|
|
268
|
-
return 0;
|
|
286
|
+
return aIsEmpty ? -1 : 1;
|
|
269
287
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
return -1;
|
|
273
|
-
}
|
|
274
|
-
if (aValue < bValue) {
|
|
275
|
-
return 1;
|
|
276
|
-
}
|
|
277
|
-
return 0;
|
|
288
|
+
if (sortState.dir === "desc") {
|
|
289
|
+
return aIsEmpty ? 1 : -1;
|
|
278
290
|
}
|
|
279
291
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
292
|
+
if (sortState.dir === "asc") {
|
|
293
|
+
if (aValue < bValue)
|
|
294
|
+
return -1;
|
|
295
|
+
if (aValue > bValue)
|
|
296
|
+
return 1;
|
|
297
|
+
return 0;
|
|
283
298
|
}
|
|
284
|
-
if (
|
|
285
|
-
|
|
299
|
+
else if (sortState.dir === "desc") {
|
|
300
|
+
if (aValue > bValue)
|
|
301
|
+
return -1;
|
|
302
|
+
if (aValue < bValue)
|
|
303
|
+
return 1;
|
|
304
|
+
return 0;
|
|
286
305
|
}
|
|
287
|
-
|
|
288
|
-
|
|
306
|
+
}
|
|
307
|
+
// sort by __index
|
|
308
|
+
if (a.__index < b.__index)
|
|
309
|
+
return -1;
|
|
310
|
+
if (a.__index > b.__index)
|
|
311
|
+
return 1;
|
|
312
|
+
return 0;
|
|
313
|
+
};
|
|
314
|
+
const sortData = (sortState) => {
|
|
315
|
+
if (!_treeOptions.enabled) {
|
|
316
|
+
// Flat data — sort in-place (preserves existing behavior).
|
|
317
|
+
return data.sort((a, b) => compareRows(a, b, sortState));
|
|
318
|
+
}
|
|
319
|
+
// Tree-aware sort: sort siblings only, then re-DFS to rebuild the
|
|
320
|
+
// flat order. Cross-parent sorting is never allowed in tree mode.
|
|
321
|
+
const byKey = new Map();
|
|
322
|
+
const childrenByParent = new Map();
|
|
323
|
+
for (const row of data) {
|
|
324
|
+
byKey.set(row.__key, row);
|
|
325
|
+
const pk = row.__parentKey;
|
|
326
|
+
if (!childrenByParent.has(pk))
|
|
327
|
+
childrenByParent.set(pk, []);
|
|
328
|
+
childrenByParent.get(pk).push(row);
|
|
329
|
+
}
|
|
330
|
+
for (const [, siblings] of childrenByParent) {
|
|
331
|
+
siblings.sort((a, b) => compareRows(a, b, sortState));
|
|
332
|
+
}
|
|
333
|
+
const result = [];
|
|
334
|
+
const walk = (parentKey) => {
|
|
335
|
+
const siblings = childrenByParent.get(parentKey);
|
|
336
|
+
if (!siblings)
|
|
337
|
+
return;
|
|
338
|
+
for (const row of siblings) {
|
|
339
|
+
result.push(row);
|
|
340
|
+
if (row.__hasChildren)
|
|
341
|
+
walk(row.__key);
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
walk(undefined);
|
|
345
|
+
return result;
|
|
346
|
+
};
|
|
347
|
+
const collectAncestors = (rows) => {
|
|
348
|
+
const ancestorSet = new Set();
|
|
349
|
+
const byKey = new Map();
|
|
350
|
+
for (const r of data)
|
|
351
|
+
byKey.set(r.__key, r);
|
|
352
|
+
for (const row of rows) {
|
|
353
|
+
let parentKey = row.__parentKey;
|
|
354
|
+
while (parentKey) {
|
|
355
|
+
if (ancestorSet.has(parentKey))
|
|
356
|
+
break;
|
|
357
|
+
ancestorSet.add(parentKey);
|
|
358
|
+
const parent = byKey.get(parentKey);
|
|
359
|
+
parentKey = parent === null || parent === void 0 ? void 0 : parent.__parentKey;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return ancestorSet;
|
|
289
363
|
};
|
|
290
|
-
const searchData = (searchText) => {
|
|
364
|
+
const searchData = (rows, searchText) => {
|
|
291
365
|
const columnKeys = columnState.map((col) => col.dataField);
|
|
292
|
-
|
|
366
|
+
const matched = rows.filter((row) => {
|
|
293
367
|
return columnKeys.some((key) => {
|
|
294
368
|
if (typeof row[key] === "string") {
|
|
295
369
|
return row[key].toLowerCase().includes(searchText.toLowerCase());
|
|
@@ -297,6 +371,16 @@ const TableProvider = (_a) => {
|
|
|
297
371
|
return false;
|
|
298
372
|
});
|
|
299
373
|
});
|
|
374
|
+
if (!_treeOptions.enabled) {
|
|
375
|
+
return { rows: matched, ancestorKeys: new Set() };
|
|
376
|
+
}
|
|
377
|
+
const ancestorKeys = collectAncestors(matched);
|
|
378
|
+
const visibleSet = new Set(matched.map((r) => r.__key));
|
|
379
|
+
ancestorKeys.forEach((k) => visibleSet.add(k));
|
|
380
|
+
return {
|
|
381
|
+
rows: rows.filter((r) => visibleSet.has(r.__key)),
|
|
382
|
+
ancestorKeys,
|
|
383
|
+
};
|
|
300
384
|
};
|
|
301
385
|
const rowMatchesRule = (row, rule) => {
|
|
302
386
|
var _a, _b, _c, _d;
|
|
@@ -396,16 +480,26 @@ const TableProvider = (_a) => {
|
|
|
396
480
|
return true;
|
|
397
481
|
}
|
|
398
482
|
};
|
|
399
|
-
const filterData = (filter) => {
|
|
400
|
-
if (!
|
|
401
|
-
return [];
|
|
483
|
+
const filterData = (rows, filter) => {
|
|
484
|
+
if (!rows)
|
|
485
|
+
return { rows: [], ancestorKeys: new Set() };
|
|
402
486
|
const { combinator, rules } = filter;
|
|
403
|
-
if (!combinator || !rules)
|
|
404
|
-
return
|
|
405
|
-
if (combinator === "or") {
|
|
406
|
-
return data.filter((row) => rules.some((rule) => rowMatchesRule(row, rule)));
|
|
487
|
+
if (!combinator || !rules || rules.length === 0) {
|
|
488
|
+
return { rows, ancestorKeys: new Set() };
|
|
407
489
|
}
|
|
408
|
-
|
|
490
|
+
const matched = combinator === "or"
|
|
491
|
+
? rows.filter((row) => rules.some((rule) => rowMatchesRule(row, rule)))
|
|
492
|
+
: rows.filter((row) => rules.every((rule) => rowMatchesRule(row, rule)));
|
|
493
|
+
if (!_treeOptions.enabled) {
|
|
494
|
+
return { rows: matched, ancestorKeys: new Set() };
|
|
495
|
+
}
|
|
496
|
+
const ancestorKeys = collectAncestors(matched);
|
|
497
|
+
const visibleSet = new Set(matched.map((r) => r.__key));
|
|
498
|
+
ancestorKeys.forEach((k) => visibleSet.add(k));
|
|
499
|
+
return {
|
|
500
|
+
rows: rows.filter((r) => visibleSet.has(r.__key)),
|
|
501
|
+
ancestorKeys,
|
|
502
|
+
};
|
|
409
503
|
};
|
|
410
504
|
const toggleColumnVisibility = (dataField) => {
|
|
411
505
|
const newColumnState = columnState.map((col) => {
|
|
@@ -434,6 +528,47 @@ const TableProvider = (_a) => {
|
|
|
434
528
|
const key = !!keyField ? row[keyField] : row.__key;
|
|
435
529
|
return String(key);
|
|
436
530
|
};
|
|
531
|
+
const firstVisibleDataField = useMemo(() => { var _a; return (_a = columnState.find((c) => c.visible !== false)) === null || _a === void 0 ? void 0 : _a.dataField; }, [columnState]);
|
|
532
|
+
const persistExpandedKeys = (next) => {
|
|
533
|
+
if ((stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.enabled) && (stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.type) === "localStorage") {
|
|
534
|
+
StateStorage.setExpandedKeys(stateStorage.key, next);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
const updateExpandedKeys = (next) => {
|
|
538
|
+
_setExpandedKeys(next);
|
|
539
|
+
onExpandedChange === null || onExpandedChange === void 0 ? void 0 : onExpandedChange(next);
|
|
540
|
+
persistExpandedKeys(next);
|
|
541
|
+
};
|
|
542
|
+
const expandRow = (row) => {
|
|
543
|
+
var _a;
|
|
544
|
+
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
545
|
+
if (expandedKeysSet.has(key))
|
|
546
|
+
return;
|
|
547
|
+
updateExpandedKeys([..._expandedKeys, key]);
|
|
548
|
+
};
|
|
549
|
+
const collapseRow = (row) => {
|
|
550
|
+
var _a;
|
|
551
|
+
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
552
|
+
if (!expandedKeysSet.has(key))
|
|
553
|
+
return;
|
|
554
|
+
updateExpandedKeys(_expandedKeys.filter((k) => k !== key));
|
|
555
|
+
};
|
|
556
|
+
const toggleRowExpanded = (row) => {
|
|
557
|
+
var _a;
|
|
558
|
+
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
559
|
+
if (expandedKeysSet.has(key)) {
|
|
560
|
+
updateExpandedKeys(_expandedKeys.filter((k) => k !== key));
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
updateExpandedKeys([..._expandedKeys, key]);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
const expandAllRows = () => {
|
|
567
|
+
updateExpandedKeys([..._treeMeta.expandableKeys]);
|
|
568
|
+
};
|
|
569
|
+
const collapseAllRows = () => {
|
|
570
|
+
updateExpandedKeys([]);
|
|
571
|
+
};
|
|
437
572
|
const selectRow = (row) => {
|
|
438
573
|
const key = getRowKey(row);
|
|
439
574
|
const newSelectionState = {
|
|
@@ -571,6 +706,61 @@ const TableProvider = (_a) => {
|
|
|
571
706
|
const key = getRowKey(row);
|
|
572
707
|
return focusedRowId === key;
|
|
573
708
|
};
|
|
709
|
+
const { _data, effectiveExpandedKeys } = useMemo(() => {
|
|
710
|
+
let processedData = data || [];
|
|
711
|
+
if (manualSorting !== true) {
|
|
712
|
+
processedData = sortData(sortState);
|
|
713
|
+
}
|
|
714
|
+
const autoExpandedSet = new Set();
|
|
715
|
+
if (manualFiltering !== true && _filterState) {
|
|
716
|
+
const result = filterData(processedData, _filterState);
|
|
717
|
+
processedData = result.rows;
|
|
718
|
+
if (_treeOptions.enabled && _treeOptions.autoExpandOnMatch) {
|
|
719
|
+
result.ancestorKeys.forEach((k) => autoExpandedSet.add(k));
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
if (manualSearch !== true && search) {
|
|
723
|
+
const result = searchData(processedData, search);
|
|
724
|
+
processedData = result.rows;
|
|
725
|
+
if (_treeOptions.enabled && _treeOptions.autoExpandOnMatch) {
|
|
726
|
+
result.ancestorKeys.forEach((k) => autoExpandedSet.add(k));
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
// Compute the effective expanded set: user expansion ∪ auto-expanded ancestors.
|
|
730
|
+
// Never mutates user's _expandedKeys.
|
|
731
|
+
const effective = new Set(expandedKeysSet);
|
|
732
|
+
autoExpandedSet.forEach((k) => effective.add(k));
|
|
733
|
+
// Final pass: drop rows whose ancestors are not in the effective set.
|
|
734
|
+
if (_treeOptions.enabled) {
|
|
735
|
+
const byKey = new Map();
|
|
736
|
+
for (const r of processedData)
|
|
737
|
+
byKey.set(r.__key, r);
|
|
738
|
+
processedData = processedData.filter((row) => {
|
|
739
|
+
let pk = row.__parentKey;
|
|
740
|
+
while (pk) {
|
|
741
|
+
if (!effective.has(pk))
|
|
742
|
+
return false;
|
|
743
|
+
const parent = byKey.get(pk);
|
|
744
|
+
pk = parent === null || parent === void 0 ? void 0 : parent.__parentKey;
|
|
745
|
+
}
|
|
746
|
+
return true;
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
return { _data: processedData, effectiveExpandedKeys: effective };
|
|
750
|
+
}, [
|
|
751
|
+
data,
|
|
752
|
+
columnState,
|
|
753
|
+
search,
|
|
754
|
+
sortState,
|
|
755
|
+
_filterState,
|
|
756
|
+
expandedKeysSet,
|
|
757
|
+
_treeOptions,
|
|
758
|
+
]);
|
|
759
|
+
const isRowExpanded = (row) => {
|
|
760
|
+
var _a;
|
|
761
|
+
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
762
|
+
return effectiveExpandedKeys.has(key);
|
|
763
|
+
};
|
|
574
764
|
if (tableInstanceRef) {
|
|
575
765
|
tableInstanceRef.current = {
|
|
576
766
|
columnState,
|
|
@@ -587,6 +777,13 @@ const TableProvider = (_a) => {
|
|
|
587
777
|
clearSelections,
|
|
588
778
|
runSearch,
|
|
589
779
|
clearSearch,
|
|
780
|
+
expandRow,
|
|
781
|
+
collapseRow,
|
|
782
|
+
toggleRowExpanded,
|
|
783
|
+
isRowExpanded,
|
|
784
|
+
expandAllRows,
|
|
785
|
+
collapseAllRows,
|
|
786
|
+
getExpandedRowKeys: () => [..._expandedKeys],
|
|
590
787
|
getTableState: () => {
|
|
591
788
|
return {
|
|
592
789
|
columnState,
|
|
@@ -598,24 +795,12 @@ const TableProvider = (_a) => {
|
|
|
598
795
|
},
|
|
599
796
|
sortState,
|
|
600
797
|
searchState: search,
|
|
601
|
-
_filterState,
|
|
798
|
+
filterState: _filterState,
|
|
799
|
+
expandedKeys: [..._expandedKeys],
|
|
602
800
|
};
|
|
603
801
|
},
|
|
604
802
|
};
|
|
605
803
|
}
|
|
606
|
-
const _data = useMemo(() => {
|
|
607
|
-
let processedData = data; // create a new array to avoid mutating the original data
|
|
608
|
-
if (manualSorting !== true) {
|
|
609
|
-
processedData = sortData(sortState);
|
|
610
|
-
}
|
|
611
|
-
if (manualFiltering !== true && _filterState) {
|
|
612
|
-
processedData = filterData(_filterState);
|
|
613
|
-
}
|
|
614
|
-
if (manualSearch !== true && search) {
|
|
615
|
-
processedData = searchData(search);
|
|
616
|
-
}
|
|
617
|
-
return processedData;
|
|
618
|
-
}, [data, columnState, search, sortState, _filterState]);
|
|
619
804
|
return (_jsx(TableContext.Provider, { value: Object.assign({ columnState, setColumnState: updateColumnState, sortState, searchState: search, totalRecords,
|
|
620
805
|
keyField,
|
|
621
806
|
handleColumnReorder,
|
|
@@ -640,6 +825,13 @@ const TableProvider = (_a) => {
|
|
|
640
825
|
stateStorage, tableHeight: height, tableMaxHeight: maxHeight, tableMinHeight: minHeight, compact, tableElement: tableElement, headerRowElm: headerRowElm, tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm, enableColumnResize,
|
|
641
826
|
onSelectionChange,
|
|
642
827
|
onColumnStateChange,
|
|
643
|
-
onColumnReorder, onRowUpdated: onRowUpdated || (() => { }), tableMenuOptions, data: _data
|
|
828
|
+
onColumnReorder, onRowUpdated: onRowUpdated || (() => { }), tableMenuOptions, data: _data, treeOptions: _treeOptions, firstVisibleDataField, expandedKeys: _expandedKeys, effectiveExpandedKeys,
|
|
829
|
+
isRowExpanded,
|
|
830
|
+
toggleRowExpanded,
|
|
831
|
+
expandRow,
|
|
832
|
+
collapseRow,
|
|
833
|
+
expandAllRows,
|
|
834
|
+
collapseAllRows,
|
|
835
|
+
onExpandedChange }, props), children: children }));
|
|
644
836
|
};
|
|
645
837
|
export default TableProvider;
|
package/dist/Table/TableRow.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Maximize2Icon } from "lucide-react";
|
|
2
|
+
import { ChevronRightIcon, Maximize2Icon } from "lucide-react";
|
|
3
3
|
import ColumnResizer from "./ColumnResizer";
|
|
4
|
-
import { InnerCellContent, TD, TR } from "./TableComponents";
|
|
4
|
+
import { InnerCellContent, TD, TR, TreeCellContent, TreeCellWrapper, TreeChevronButton, TreeChevronPlaceholder, TreeIndentSpacer, } from "./TableComponents";
|
|
5
5
|
import useTable from "./useTable";
|
|
6
6
|
import ActionCell from "./ActionCell";
|
|
7
7
|
import ActionButton from "./ActionButton";
|
|
8
8
|
import CheckBox from "../CheckBox";
|
|
9
9
|
import { LoadingCellIndicator } from "./LoadingCellIndicator";
|
|
10
10
|
const TableRow = ({ rowData, loading, rowStyle }) => {
|
|
11
|
-
const { columnState, enableActionButton, onActionButtonClick, actionButtonIcon: Icon, enableSelection, selectRow, deselectRow, isRowSelected, isRowFocused, onRowUpdated, } = useTable();
|
|
11
|
+
const { columnState, enableActionButton, onActionButtonClick, actionButtonIcon: Icon, enableSelection, selectRow, deselectRow, isRowSelected, isRowFocused, onRowUpdated, treeOptions, firstVisibleDataField, isRowExpanded, toggleRowExpanded, } = useTable();
|
|
12
12
|
const selected = isRowSelected(rowData);
|
|
13
13
|
const focused = isRowFocused(rowData);
|
|
14
14
|
const handleSelectionChange = (e) => {
|
|
15
15
|
e === true ? selectRow(rowData) : deselectRow(rowData);
|
|
16
16
|
};
|
|
17
17
|
return (_jsxs(TR, { className: "mfui-tr", style: rowStyle, "data-key": rowData.__key, "data-selected": selected, "data-focused": focused, children: [enableSelection && (_jsx(ActionCell, { className: `mfui-td column-select`, children: _jsx(InnerCellContent, { className: "mfui inner-cell-content row-action row-selection-action", children: _jsx(CheckBox, { className: `mfui-checkbox`, value: selected, onChange: (e) => handleSelectionChange(e) }) }) })), enableActionButton && (_jsx(ActionCell, { className: `mfui-td column-action`, children: _jsx(InnerCellContent, { className: "mfui inner-cell-content row-action", children: _jsx(ActionButton, { variant: "subtle", onClick: () => onActionButtonClick === null || onActionButtonClick === void 0 ? void 0 : onActionButtonClick(rowData), children: Icon ? _jsx(Icon, { size: 14 }) : _jsx(Maximize2Icon, { size: 14 }) }) }) })), columnState.map((column, index) => {
|
|
18
|
+
var _a;
|
|
18
19
|
if (column.visible === false)
|
|
19
20
|
return null;
|
|
20
21
|
if (loading) {
|
|
@@ -24,16 +25,20 @@ const TableRow = ({ rowData, loading, rowStyle }) => {
|
|
|
24
25
|
flex: column.width ? "0 0 auto" : "1",
|
|
25
26
|
}, children: _jsx(LoadingCellIndicator, {}) }, index));
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
+
const cellBody = column.render
|
|
29
|
+
? column.render({ rowData, onRowUpdated })
|
|
30
|
+
: rowData[column.dataField];
|
|
31
|
+
const isTreeColumn = (treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.enabled) === true &&
|
|
32
|
+
column.dataField === firstVisibleDataField;
|
|
33
|
+
const expanded = isTreeColumn ? isRowExpanded(rowData) : false;
|
|
34
|
+
return (_jsxs(TD, { className: `mfui-td column-${column.columnId}`, "data-field": column.dataField, "data-tree-cell": isTreeColumn ? "true" : undefined, style: {
|
|
28
35
|
width: column.width,
|
|
29
36
|
minWidth: column.minWidth,
|
|
30
37
|
flex: column.width ? "0 0 auto" : "1",
|
|
31
|
-
}, children: [(column === null || column === void 0 ? void 0 : column.enableResize) === true && _jsx(ColumnResizer, { column: column }), _jsx(InnerCellContent, { className: "mfui inner-cell-content", children:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
: rowData[column.dataField] })] }, index));
|
|
38
|
+
}, children: [(column === null || column === void 0 ? void 0 : column.enableResize) === true && _jsx(ColumnResizer, { column: column }), _jsx(InnerCellContent, { className: "mfui inner-cell-content", children: isTreeColumn ? (_jsxs(TreeCellWrapper, { children: [_jsx(TreeIndentSpacer, { "$level": (_a = rowData.__level) !== null && _a !== void 0 ? _a : 0, "$indentPx": treeOptions.indentPx }), rowData.__hasChildren ? (_jsx(TreeChevronButton, { type: "button", "$expanded": expanded, onClick: (e) => {
|
|
39
|
+
e.stopPropagation();
|
|
40
|
+
toggleRowExpanded(rowData);
|
|
41
|
+
}, "aria-label": expanded ? "Collapse row" : "Expand row", "aria-expanded": expanded, children: _jsx(ChevronRightIcon, { size: 14 }) })) : (_jsx(TreeChevronPlaceholder, {})), _jsx(TreeCellContent, { children: cellBody })] })) : (cellBody) })] }, index));
|
|
37
42
|
})] }));
|
|
38
43
|
};
|
|
39
44
|
export default TableRow;
|