@monolith-forensics/monolith-ui 1.5.2-dev.0 → 1.6.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/dist/Table/StateStorage.d.ts +0 -4
- package/dist/Table/StateStorage.js +0 -13
- package/dist/Table/Table.js +12 -160
- package/dist/Table/TableComponents.d.ts +0 -10
- package/dist/Table/TableComponents.js +0 -49
- package/dist/Table/TableDefaults.d.ts +0 -7
- package/dist/Table/TableDefaults.js +0 -7
- package/dist/Table/TableHeader.js +8 -7
- package/dist/Table/TableProvider.js +93 -276
- package/dist/Table/TableRow.js +10 -15
- package/dist/Table/Utils/columnStateUpdate.d.ts +7 -0
- package/dist/Table/Utils/columnStateUpdate.js +9 -0
- package/dist/Table/types.d.ts +3 -66
- package/package.json +1 -1
|
@@ -11,8 +11,6 @@ type GetSearchStateFn = (key: string) => string;
|
|
|
11
11
|
type SetSearchStateFn = (key: string, value: string) => void;
|
|
12
12
|
type GetFilterStateFn = (key: string) => Query | undefined;
|
|
13
13
|
type SetFilterStateFn = (key: string, value?: Query | null) => void;
|
|
14
|
-
type GetExpandedKeysFn = (key: string) => string[] | undefined;
|
|
15
|
-
type SetExpandedKeysFn = (key: string, value: string[]) => void;
|
|
16
14
|
declare const StateStorage: {
|
|
17
15
|
getTableState: GetTableStateFn;
|
|
18
16
|
getColumnState: GetColumnStateFn;
|
|
@@ -25,7 +23,5 @@ declare const StateStorage: {
|
|
|
25
23
|
setSearchState: SetSearchStateFn;
|
|
26
24
|
getFilterState: GetFilterStateFn;
|
|
27
25
|
setFilterState: SetFilterStateFn;
|
|
28
|
-
getExpandedKeys: GetExpandedKeysFn;
|
|
29
|
-
setExpandedKeys: SetExpandedKeysFn;
|
|
30
26
|
};
|
|
31
27
|
export default StateStorage;
|
|
@@ -82,17 +82,6 @@ const setFilterState = (key, value) => {
|
|
|
82
82
|
const newState = Object.assign(Object.assign({}, previousState), { filterState: value });
|
|
83
83
|
set(key, newState);
|
|
84
84
|
};
|
|
85
|
-
const getExpandedKeys = (key) => {
|
|
86
|
-
const data = getTableState(key);
|
|
87
|
-
return data.expandedKeys;
|
|
88
|
-
};
|
|
89
|
-
const setExpandedKeys = (key, value) => {
|
|
90
|
-
// get previous state
|
|
91
|
-
const previousState = getTableState(key);
|
|
92
|
-
// merge previous state with new state
|
|
93
|
-
const newState = Object.assign(Object.assign({}, previousState), { expandedKeys: value });
|
|
94
|
-
set(key, newState);
|
|
95
|
-
};
|
|
96
85
|
const StateStorage = {
|
|
97
86
|
getTableState,
|
|
98
87
|
getColumnState,
|
|
@@ -105,7 +94,5 @@ const StateStorage = {
|
|
|
105
94
|
setSearchState,
|
|
106
95
|
getFilterState,
|
|
107
96
|
setFilterState,
|
|
108
|
-
getExpandedKeys,
|
|
109
|
-
setExpandedKeys,
|
|
110
97
|
};
|
|
111
98
|
export default StateStorage;
|
package/dist/Table/Table.js
CHANGED
|
@@ -22,7 +22,6 @@ import TableMenu from "./TableMenu";
|
|
|
22
22
|
import useTable from "./useTable";
|
|
23
23
|
import LoadingIndicator from "./LoadingIndicator";
|
|
24
24
|
import styled from "styled-components";
|
|
25
|
-
import TableDefaults from "./TableDefaults";
|
|
26
25
|
const StyledTableContainer = styled.div `
|
|
27
26
|
display: flex;
|
|
28
27
|
flex-direction: column;
|
|
@@ -41,20 +40,8 @@ const TableContent = ({ children, }) => {
|
|
|
41
40
|
}, ref: tableElement, "data-compact": compactState, children: [_jsx(LoadingIndicator, { visible: loading }), _jsx(TableHeader, { headerRowElm: headerRowElm }), visibleColumnCount === 0 && _jsx("div", { children: "No columns visible" }), virtualized === true ? (_jsx(VirtualizedRows, { tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm, rowHeight: rowHeight, headerRowHeight: headerRowHeight })) : (_jsx(StaticRows, { targetElm: targetElm, listElm: listElm }))] })] }));
|
|
42
41
|
};
|
|
43
42
|
export const Table = (_a) => {
|
|
44
|
-
var { data, columnProps, children
|
|
43
|
+
var { data, columnProps, children } = _a, props = __rest(_a, ["data", "columnProps", "children"]) // pass through props straight to table context
|
|
45
44
|
;
|
|
46
|
-
const resolvedTreeOptions = useMemo(() => {
|
|
47
|
-
var _a, _b, _c, _d, _e, _f;
|
|
48
|
-
return ({
|
|
49
|
-
enabled: (_a = treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.enabled) !== null && _a !== void 0 ? _a : false,
|
|
50
|
-
mode: (_b = treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.mode) !== null && _b !== void 0 ? _b : TableDefaults.tree.defaultMode,
|
|
51
|
-
childrenField: (_c = treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.childrenField) !== null && _c !== void 0 ? _c : TableDefaults.tree.defaultChildrenField,
|
|
52
|
-
parentIdField: (_d = treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.parentIdField) !== null && _d !== void 0 ? _d : TableDefaults.tree.defaultParentIdField,
|
|
53
|
-
idField: treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.idField,
|
|
54
|
-
indentPx: (_e = treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.indentPx) !== null && _e !== void 0 ? _e : TableDefaults.tree.indentPx,
|
|
55
|
-
autoExpandOnMatch: (_f = treeOptions === null || treeOptions === void 0 ? void 0 : treeOptions.autoExpandOnMatch) !== null && _f !== void 0 ? _f : true,
|
|
56
|
-
});
|
|
57
|
-
}, [treeOptions]);
|
|
58
45
|
const tableElement = useRef(null);
|
|
59
46
|
const targetElm = useRef(null);
|
|
60
47
|
const listElm = useRef(null);
|
|
@@ -126,153 +113,18 @@ export const Table = (_a) => {
|
|
|
126
113
|
// Uses a WeakMap so entries are automatically garbage collected
|
|
127
114
|
// when their corresponding row objects are no longer referenced.
|
|
128
115
|
const uuidCache = useRef(new WeakMap());
|
|
129
|
-
|
|
130
|
-
|
|
116
|
+
// Augment each row with a stable __key (UUID) and __index.
|
|
117
|
+
// The WeakMap ensures that the same row object always receives
|
|
118
|
+
// the same UUID across re-renders, preventing unnecessary DOM
|
|
119
|
+
// reconciliation. useMemo preserves referential stability of
|
|
120
|
+
// the output array when the data reference hasn't changed.
|
|
121
|
+
const __data = useMemo(() => data === null || data === void 0 ? void 0 : data.map((d, i) => {
|
|
122
|
+
let key = uuidCache.current.get(d);
|
|
131
123
|
if (!key) {
|
|
132
124
|
key = shortUUID.uuid();
|
|
133
|
-
uuidCache.current.set(
|
|
134
|
-
}
|
|
135
|
-
return key;
|
|
136
|
-
};
|
|
137
|
-
// Augment each row with stable metadata. When tree mode is disabled,
|
|
138
|
-
// produces a flat 1:1 mapping with __key and __index. When enabled,
|
|
139
|
-
// walks the input (nested or flat) into a flat depth-first array
|
|
140
|
-
// and adds tree metadata (__level, __parentKey, __hasChildren, __childKeys).
|
|
141
|
-
const { rows: __data, treeMeta } = useMemo(() => {
|
|
142
|
-
const parentKeyMap = new Map();
|
|
143
|
-
const childrenKeyMap = new Map();
|
|
144
|
-
const expandableKeys = [];
|
|
145
|
-
if (!data) {
|
|
146
|
-
return {
|
|
147
|
-
rows: [],
|
|
148
|
-
treeMeta: { parentKeyMap, childrenKeyMap, expandableKeys },
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (!resolvedTreeOptions.enabled) {
|
|
152
|
-
const rows = data.map((d, i) => (Object.assign(Object.assign({}, d), { __key: getOrAssignKey(d), __index: i })));
|
|
153
|
-
return {
|
|
154
|
-
rows,
|
|
155
|
-
treeMeta: { parentKeyMap, childrenKeyMap, expandableKeys },
|
|
156
|
-
};
|
|
125
|
+
uuidCache.current.set(d, key);
|
|
157
126
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const childrenField = resolvedTreeOptions.childrenField;
|
|
162
|
-
const walk = (node, level, parentKey) => {
|
|
163
|
-
const key = getOrAssignKey(node);
|
|
164
|
-
const rawChildren = node === null || node === void 0 ? void 0 : node[childrenField];
|
|
165
|
-
const children = Array.isArray(rawChildren) ? rawChildren : [];
|
|
166
|
-
const childKeys = children.map((c) => getOrAssignKey(c));
|
|
167
|
-
// Strip the nested children field from the augmented copy to avoid
|
|
168
|
-
// memory bloat and prevent accidental iteration of the raw tree.
|
|
169
|
-
const _a = node, _b = childrenField, _stripped = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
170
|
-
const augmented = Object.assign(Object.assign({}, rest), { __key: key, __index: counter++, __level: level, __parentKey: parentKey, __hasChildren: children.length > 0, __childKeys: childKeys });
|
|
171
|
-
rows.push(augmented);
|
|
172
|
-
parentKeyMap.set(key, parentKey);
|
|
173
|
-
if (children.length > 0) {
|
|
174
|
-
childrenKeyMap.set(key, childKeys);
|
|
175
|
-
expandableKeys.push(key);
|
|
176
|
-
}
|
|
177
|
-
for (const child of children) {
|
|
178
|
-
walk(child, level + 1, key);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
const rootKeys = [];
|
|
182
|
-
for (const root of data) {
|
|
183
|
-
rootKeys.push(getOrAssignKey(root));
|
|
184
|
-
walk(root, 0, undefined);
|
|
185
|
-
}
|
|
186
|
-
childrenKeyMap.set(undefined, rootKeys);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
// flat mode
|
|
190
|
-
const idField = resolvedTreeOptions.idField || props.keyField;
|
|
191
|
-
if (!idField) {
|
|
192
|
-
throw new Error('Table treeOptions.mode="flat" requires either treeOptions.idField or keyField to be set so the table can resolve parent-child relationships against a stable id.');
|
|
193
|
-
}
|
|
194
|
-
const parentIdField = resolvedTreeOptions.parentIdField;
|
|
195
|
-
// Pass 1: assign __key, build idToKey
|
|
196
|
-
const idToKey = new Map();
|
|
197
|
-
const idToRow = new Map();
|
|
198
|
-
for (const d of data) {
|
|
199
|
-
const id = d === null || d === void 0 ? void 0 : d[idField];
|
|
200
|
-
if (id === undefined || id === null)
|
|
201
|
-
continue;
|
|
202
|
-
idToKey.set(id, getOrAssignKey(d));
|
|
203
|
-
idToRow.set(id, d);
|
|
204
|
-
}
|
|
205
|
-
// Pass 2: build parent->children id map. Roots = parentId null/undefined
|
|
206
|
-
// OR parentId points at a non-existent row.
|
|
207
|
-
const parentToChildIds = new Map();
|
|
208
|
-
const rootIds = [];
|
|
209
|
-
let warnedOrphan = false;
|
|
210
|
-
for (const d of data) {
|
|
211
|
-
const id = d === null || d === void 0 ? void 0 : d[idField];
|
|
212
|
-
if (id === undefined || id === null)
|
|
213
|
-
continue;
|
|
214
|
-
const parentId = d === null || d === void 0 ? void 0 : d[parentIdField];
|
|
215
|
-
if (parentId === undefined || parentId === null) {
|
|
216
|
-
rootIds.push(id);
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
if (!idToRow.has(parentId)) {
|
|
220
|
-
if (!warnedOrphan) {
|
|
221
|
-
// eslint-disable-next-line no-console
|
|
222
|
-
console.warn(`Table tree (flat mode): row id "${id}" references missing parentId "${parentId}"; treating as root.`);
|
|
223
|
-
warnedOrphan = true;
|
|
224
|
-
}
|
|
225
|
-
rootIds.push(id);
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
if (!parentToChildIds.has(parentId))
|
|
229
|
-
parentToChildIds.set(parentId, []);
|
|
230
|
-
parentToChildIds.get(parentId).push(id);
|
|
231
|
-
}
|
|
232
|
-
// Pass 3: DFS from roots with cycle detection
|
|
233
|
-
const visiting = new Set();
|
|
234
|
-
let warnedCycle = false;
|
|
235
|
-
const walkFlat = (id, level, parentKey) => {
|
|
236
|
-
if (visiting.has(id)) {
|
|
237
|
-
if (!warnedCycle) {
|
|
238
|
-
// eslint-disable-next-line no-console
|
|
239
|
-
console.warn(`Table tree (flat mode): cycle detected at row id "${id}"; truncating subtree.`);
|
|
240
|
-
warnedCycle = true;
|
|
241
|
-
}
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
visiting.add(id);
|
|
245
|
-
const node = idToRow.get(id);
|
|
246
|
-
const key = idToKey.get(id);
|
|
247
|
-
const childIds = parentToChildIds.get(id) || [];
|
|
248
|
-
const childKeys = childIds
|
|
249
|
-
.map((cid) => idToKey.get(cid))
|
|
250
|
-
.filter((k) => !!k);
|
|
251
|
-
const augmented = Object.assign(Object.assign({}, node), { __key: key, __index: counter++, __level: level, __parentKey: parentKey, __hasChildren: childIds.length > 0, __childKeys: childKeys });
|
|
252
|
-
rows.push(augmented);
|
|
253
|
-
parentKeyMap.set(key, parentKey);
|
|
254
|
-
if (childIds.length > 0) {
|
|
255
|
-
childrenKeyMap.set(key, childKeys);
|
|
256
|
-
expandableKeys.push(key);
|
|
257
|
-
}
|
|
258
|
-
for (const cid of childIds) {
|
|
259
|
-
walkFlat(cid, level + 1, key);
|
|
260
|
-
}
|
|
261
|
-
visiting.delete(id);
|
|
262
|
-
};
|
|
263
|
-
const rootKeys = [];
|
|
264
|
-
for (const id of rootIds) {
|
|
265
|
-
const k = idToKey.get(id);
|
|
266
|
-
if (k)
|
|
267
|
-
rootKeys.push(k);
|
|
268
|
-
walkFlat(id, 0, undefined);
|
|
269
|
-
}
|
|
270
|
-
childrenKeyMap.set(undefined, rootKeys);
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
rows,
|
|
274
|
-
treeMeta: { parentKeyMap, childrenKeyMap, expandableKeys },
|
|
275
|
-
};
|
|
276
|
-
}, [data, resolvedTreeOptions, props.keyField]);
|
|
277
|
-
return (_jsx(TableProvider, Object.assign({ columns: columnProps, data: __data, tableElement: tableElement, headerRowElm: headerRowElm, tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm, treeOptions: resolvedTreeOptions, treeMeta: treeMeta }, props, { children: _jsx(TableContent, { children: children }) })));
|
|
127
|
+
return Object.assign(Object.assign({}, d), { __key: key, __index: i });
|
|
128
|
+
}), [data]);
|
|
129
|
+
return (_jsx(TableProvider, Object.assign({ columns: columnProps, data: __data, tableElement: tableElement, headerRowElm: headerRowElm, tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm }, props, { children: _jsx(TableContent, { children: children }) })));
|
|
278
130
|
};
|
|
@@ -6,16 +6,6 @@ export declare const THR: import("styled-components/dist/types").IStyledComponen
|
|
|
6
6
|
export declare const TD: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, TDProps>> & string;
|
|
7
7
|
export declare const TH: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof TDProps> & TDProps, never>> & string;
|
|
8
8
|
export declare const InnerCellContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
9
|
-
export declare const TreeCellWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
10
|
-
export declare const TreeIndentSpacer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
11
|
-
$level: number;
|
|
12
|
-
$indentPx: number;
|
|
13
|
-
}>> & string;
|
|
14
|
-
export declare const TreeChevronButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
|
|
15
|
-
$expanded: boolean;
|
|
16
|
-
}>> & string;
|
|
17
|
-
export declare const TreeChevronPlaceholder: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
18
|
-
export declare const TreeCellContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
19
9
|
export declare const TableViewPort: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
20
10
|
export declare const TableListElement: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
21
11
|
export declare const TableWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -115,55 +115,6 @@ 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
|
-
gap: 4px;
|
|
125
|
-
`;
|
|
126
|
-
export const TreeIndentSpacer = styled.div `
|
|
127
|
-
flex: 0 0 auto;
|
|
128
|
-
width: ${({ $level, $indentPx }) => $level * $indentPx}px;
|
|
129
|
-
`;
|
|
130
|
-
export const TreeChevronButton = styled.button `
|
|
131
|
-
flex: 0 0 auto;
|
|
132
|
-
width: 16px;
|
|
133
|
-
height: 16px;
|
|
134
|
-
padding: 0;
|
|
135
|
-
margin: 0;
|
|
136
|
-
display: inline-flex;
|
|
137
|
-
align-items: center;
|
|
138
|
-
justify-content: center;
|
|
139
|
-
background: transparent;
|
|
140
|
-
border: none;
|
|
141
|
-
cursor: pointer;
|
|
142
|
-
color: ${({ theme }) => theme.palette.text.secondary};
|
|
143
|
-
transition: transform 120ms ease;
|
|
144
|
-
transform: rotate(${({ $expanded }) => ($expanded ? "90deg" : "0deg")});
|
|
145
|
-
|
|
146
|
-
&:hover {
|
|
147
|
-
color: ${({ theme }) => theme.palette.text.primary};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
&:focus-visible {
|
|
151
|
-
outline: 1px solid ${({ theme }) => theme.palette.primary.main};
|
|
152
|
-
outline-offset: 1px;
|
|
153
|
-
}
|
|
154
|
-
`;
|
|
155
|
-
export const TreeChevronPlaceholder = styled.div `
|
|
156
|
-
flex: 0 0 auto;
|
|
157
|
-
width: 16px;
|
|
158
|
-
height: 16px;
|
|
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
|
-
`;
|
|
167
118
|
export const TableViewPort = styled.div `
|
|
168
119
|
display: flex;
|
|
169
120
|
flex-direction: column;
|
|
@@ -21,12 +21,5 @@ 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
|
-
};
|
|
31
24
|
};
|
|
32
25
|
export default TableDefaults;
|
|
@@ -21,12 +21,5 @@ 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
|
-
},
|
|
31
24
|
};
|
|
32
25
|
export default TableDefaults;
|
|
@@ -16,23 +16,24 @@ const StyledCaption = styled.span `
|
|
|
16
16
|
`;
|
|
17
17
|
const TableHeader = ({ headerRowElm }) => {
|
|
18
18
|
var _a;
|
|
19
|
-
const { columnState, sortState, setColumnState, onColumnResize, handleColumnReorder, enableColumnReorder, handleColumnHeaderClick, enableColumnResize, headerRowHeight, enableActionButton, enableSelection, selectionState, disableSelectAll, selectAllRows, clearSelections, compactState, } = useTable();
|
|
19
|
+
const { columnState, sortState, setColumnState: updateColumnState, onColumnResize, handleColumnReorder, enableColumnReorder, handleColumnHeaderClick, enableColumnResize, headerRowHeight, enableActionButton, enableSelection, selectionState, disableSelectAll, selectAllRows, clearSelections, compactState, } = useTable();
|
|
20
20
|
const [dragColumn, setDragColumn] = useState(null);
|
|
21
21
|
const [dropColumn, setDropColumn] = useState(null);
|
|
22
22
|
const handleResize = (e) => {
|
|
23
23
|
const columnId = e.column.columnId;
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const newWidth = Number(e.newWidth);
|
|
25
|
+
updateColumnState((prevColumnState) => {
|
|
26
|
+
const nextColumnState = prevColumnState.map((col) => {
|
|
26
27
|
if (col.columnId === columnId) {
|
|
27
|
-
return Object.assign(Object.assign({}, col), { width:
|
|
28
|
+
return Object.assign(Object.assign({}, col), { width: newWidth });
|
|
28
29
|
}
|
|
29
30
|
return col;
|
|
30
31
|
});
|
|
31
32
|
onColumnResize === null || onColumnResize === void 0 ? void 0 : onColumnResize({
|
|
32
|
-
column: Object.assign(Object.assign({}, e.column), { width:
|
|
33
|
-
columnState:
|
|
33
|
+
column: Object.assign(Object.assign({}, e.column), { width: newWidth }),
|
|
34
|
+
columnState: nextColumnState,
|
|
34
35
|
});
|
|
35
|
-
return
|
|
36
|
+
return nextColumnState;
|
|
36
37
|
});
|
|
37
38
|
};
|
|
38
39
|
const handleChangeSelection = (e) => {
|
|
@@ -19,36 +19,16 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
19
19
|
return t;
|
|
20
20
|
};
|
|
21
21
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
22
|
-
import { createContext, useMemo, useState } from "react";
|
|
22
|
+
import { createContext, useEffect, useMemo, useRef, useState } from "react";
|
|
23
23
|
import StateStorage from "./StateStorage";
|
|
24
24
|
import { resolveColumnResize, syncColumnState } from "./Utils";
|
|
25
|
+
import { notifyAndPersistColumnState, resolveColumnStateUpdate, } from "./Utils/columnStateUpdate";
|
|
25
26
|
import TableDefaults from "./TableDefaults";
|
|
26
27
|
import shortUUID from "short-uuid";
|
|
27
28
|
import { SelectionStatus } from "./enums";
|
|
28
29
|
import moment from "moment";
|
|
29
30
|
import { useControlled } from "../Utilities";
|
|
30
31
|
import { exportTableToExcel } from "./Utils";
|
|
31
|
-
const RESERVED_FIELDS = [
|
|
32
|
-
"__key",
|
|
33
|
-
"__index",
|
|
34
|
-
"__level",
|
|
35
|
-
"__parentKey",
|
|
36
|
-
"__hasChildren",
|
|
37
|
-
"__childKeys",
|
|
38
|
-
];
|
|
39
|
-
const EMPTY_TREE_META = {
|
|
40
|
-
parentKeyMap: new Map(),
|
|
41
|
-
childrenKeyMap: new Map(),
|
|
42
|
-
expandableKeys: [],
|
|
43
|
-
};
|
|
44
|
-
const DEFAULT_TREE_OPTIONS = {
|
|
45
|
-
enabled: false,
|
|
46
|
-
mode: "nested",
|
|
47
|
-
childrenField: "children",
|
|
48
|
-
parentIdField: "parentId",
|
|
49
|
-
indentPx: 16,
|
|
50
|
-
autoExpandOnMatch: true,
|
|
51
|
-
};
|
|
52
32
|
const calculateSelectionTotal = (selectionState, totalRecords, dataLength = 0) => {
|
|
53
33
|
if (!selectionState) {
|
|
54
34
|
return 0;
|
|
@@ -68,21 +48,11 @@ const calculateSelectionTotal = (selectionState, totalRecords, dataLength = 0) =
|
|
|
68
48
|
};
|
|
69
49
|
export const TableContext = createContext(null);
|
|
70
50
|
const TableProvider = (_a) => {
|
|
71
|
-
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
|
|
72
|
-
const _treeOptions = treeOptions || DEFAULT_TREE_OPTIONS;
|
|
73
|
-
const _treeMeta = treeMeta || EMPTY_TREE_META;
|
|
74
|
-
if (_treeOptions.enabled) {
|
|
75
|
-
if (RESERVED_FIELDS.includes(_treeOptions.childrenField)) {
|
|
76
|
-
throw new Error(`treeOptions.childrenField cannot be a reserved internal field: "${_treeOptions.childrenField}".`);
|
|
77
|
-
}
|
|
78
|
-
if (RESERVED_FIELDS.includes(_treeOptions.parentIdField)) {
|
|
79
|
-
throw new Error(`treeOptions.parentIdField cannot be a reserved internal field: "${_treeOptions.parentIdField}".`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
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"]);
|
|
82
52
|
const _columns = useMemo(() => columns
|
|
83
53
|
.map((child, index) => {
|
|
84
|
-
if (
|
|
85
|
-
throw new Error(
|
|
54
|
+
if (child.dataField === "__key") {
|
|
55
|
+
throw new Error("dataField cannot be __key");
|
|
86
56
|
}
|
|
87
57
|
// check for duplicate dataFields
|
|
88
58
|
const dataFieldCount = columns.filter((col) => col.dataField === child.dataField).length;
|
|
@@ -101,9 +71,13 @@ const TableProvider = (_a) => {
|
|
|
101
71
|
? StateStorage.getTableState(stateStorage.key)
|
|
102
72
|
: undefined;
|
|
103
73
|
}, [stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.key]);
|
|
104
|
-
const { columnState: savedColumnState, selectionState: savedSelectionState, sortState: savedSortState, searchState: savedSearchState, filterState: savedFilterState,
|
|
74
|
+
const { columnState: savedColumnState, selectionState: savedSelectionState, sortState: savedSortState, searchState: savedSearchState, filterState: savedFilterState, } = savedTableState || {};
|
|
105
75
|
const [compactState, setCompactState] = useState(compact || false);
|
|
106
|
-
const [columnState,
|
|
76
|
+
const [columnState, _setColumnState] = useState(syncColumnState(_columns, savedColumnState));
|
|
77
|
+
const columnStateRef = useRef(columnState);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
columnStateRef.current = columnState;
|
|
80
|
+
}, [columnState]);
|
|
107
81
|
const [search, setSearch] = useState(savedSearchState || "");
|
|
108
82
|
const [_filterState, _setFilterState] = useControlled(filterState, defaultFilterState ||
|
|
109
83
|
savedFilterState || {
|
|
@@ -111,8 +85,6 @@ const TableProvider = (_a) => {
|
|
|
111
85
|
rules: [],
|
|
112
86
|
});
|
|
113
87
|
const [sortState, setSortState] = useState(savedSortState);
|
|
114
|
-
const [_expandedKeys, _setExpandedKeys] = useControlled(expandedKeys, defaultExpandedKeys || savedExpandedKeys || []);
|
|
115
|
-
const expandedKeysSet = useMemo(() => new Set(_expandedKeys), [_expandedKeys]);
|
|
116
88
|
const [_selectionState, _setSelectionState] = useControlled(selectionState, defaultSelectionState || {
|
|
117
89
|
selectedRowKeys: (savedSelectionState === null || savedSelectionState === void 0 ? void 0 : savedSelectionState.selectedRowKeys) || [],
|
|
118
90
|
excludedRowKeys: (savedSelectionState === null || savedSelectionState === void 0 ? void 0 : savedSelectionState.excludedRowKeys) || [],
|
|
@@ -148,14 +120,20 @@ const TableProvider = (_a) => {
|
|
|
148
120
|
const getColumnState = (dataField) => {
|
|
149
121
|
return columnState.find((col) => col.dataField === dataField);
|
|
150
122
|
};
|
|
151
|
-
const updateColumnState = (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
123
|
+
const updateColumnState = (columnStateUpdate) => {
|
|
124
|
+
const previousColumnState = columnStateRef.current;
|
|
125
|
+
const nextColumnState = resolveColumnStateUpdate(columnStateUpdate, previousColumnState);
|
|
126
|
+
columnStateRef.current = nextColumnState;
|
|
127
|
+
_setColumnState(nextColumnState);
|
|
128
|
+
notifyAndPersistColumnState({
|
|
129
|
+
nextColumnState,
|
|
130
|
+
onColumnStateChange,
|
|
131
|
+
persistColumnState: (stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.enabled) && (stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.type) === "localStorage"
|
|
132
|
+
? (columnState) => {
|
|
133
|
+
StateStorage.setColumnState(stateStorage.key, columnState);
|
|
134
|
+
}
|
|
135
|
+
: undefined,
|
|
136
|
+
});
|
|
159
137
|
};
|
|
160
138
|
const handleColumnReorder = (dragColumn, dropColumn) => {
|
|
161
139
|
var _a, _b;
|
|
@@ -260,99 +238,58 @@ const TableProvider = (_a) => {
|
|
|
260
238
|
}
|
|
261
239
|
}
|
|
262
240
|
};
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
241
|
+
const sortData = (sortState) => {
|
|
242
|
+
// sort data
|
|
243
|
+
return data.sort((a, b) => {
|
|
244
|
+
if (sortState) {
|
|
245
|
+
const aValue = a[sortState.dataField];
|
|
246
|
+
const bValue = b[sortState.dataField];
|
|
247
|
+
const aIsEmpty = aValue === null || aValue === undefined;
|
|
248
|
+
const bIsEmpty = bValue === null || bValue === undefined;
|
|
249
|
+
// Treat empty values as the smallest values.
|
|
250
|
+
if (aIsEmpty && bIsEmpty) {
|
|
251
|
+
return 0;
|
|
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
261
|
if (sortState.dir === "asc") {
|
|
275
|
-
|
|
262
|
+
if (aValue < bValue) {
|
|
263
|
+
return -1;
|
|
264
|
+
}
|
|
265
|
+
if (aValue > bValue) {
|
|
266
|
+
return 1;
|
|
267
|
+
}
|
|
268
|
+
return 0;
|
|
276
269
|
}
|
|
277
|
-
if (sortState.dir === "desc") {
|
|
278
|
-
|
|
270
|
+
else if (sortState.dir === "desc") {
|
|
271
|
+
if (aValue > bValue) {
|
|
272
|
+
return -1;
|
|
273
|
+
}
|
|
274
|
+
if (aValue < bValue) {
|
|
275
|
+
return 1;
|
|
276
|
+
}
|
|
277
|
+
return 0;
|
|
279
278
|
}
|
|
280
279
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (aValue > bValue)
|
|
285
|
-
return 1;
|
|
286
|
-
return 0;
|
|
287
|
-
}
|
|
288
|
-
else if (sortState.dir === "desc") {
|
|
289
|
-
if (aValue > bValue)
|
|
290
|
-
return -1;
|
|
291
|
-
if (aValue < bValue)
|
|
292
|
-
return 1;
|
|
293
|
-
return 0;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// sort by __index
|
|
297
|
-
if (a.__index < b.__index)
|
|
298
|
-
return -1;
|
|
299
|
-
if (a.__index > b.__index)
|
|
300
|
-
return 1;
|
|
301
|
-
return 0;
|
|
302
|
-
};
|
|
303
|
-
const sortData = (sortState) => {
|
|
304
|
-
if (!_treeOptions.enabled) {
|
|
305
|
-
// Flat data — sort in-place (preserves existing behavior).
|
|
306
|
-
return data.sort((a, b) => compareRows(a, b, sortState));
|
|
307
|
-
}
|
|
308
|
-
// Tree-aware sort: sort siblings only, then re-DFS to rebuild the
|
|
309
|
-
// flat order. Cross-parent sorting is never allowed in tree mode.
|
|
310
|
-
const byKey = new Map();
|
|
311
|
-
const childrenByParent = new Map();
|
|
312
|
-
for (const row of data) {
|
|
313
|
-
byKey.set(row.__key, row);
|
|
314
|
-
const pk = row.__parentKey;
|
|
315
|
-
if (!childrenByParent.has(pk))
|
|
316
|
-
childrenByParent.set(pk, []);
|
|
317
|
-
childrenByParent.get(pk).push(row);
|
|
318
|
-
}
|
|
319
|
-
for (const [, siblings] of childrenByParent) {
|
|
320
|
-
siblings.sort((a, b) => compareRows(a, b, sortState));
|
|
321
|
-
}
|
|
322
|
-
const result = [];
|
|
323
|
-
const walk = (parentKey) => {
|
|
324
|
-
const siblings = childrenByParent.get(parentKey);
|
|
325
|
-
if (!siblings)
|
|
326
|
-
return;
|
|
327
|
-
for (const row of siblings) {
|
|
328
|
-
result.push(row);
|
|
329
|
-
if (row.__hasChildren)
|
|
330
|
-
walk(row.__key);
|
|
280
|
+
// sort by __index
|
|
281
|
+
if (a.__index < b.__index) {
|
|
282
|
+
return -1;
|
|
331
283
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return result;
|
|
335
|
-
};
|
|
336
|
-
const collectAncestors = (rows) => {
|
|
337
|
-
const ancestorSet = new Set();
|
|
338
|
-
const byKey = new Map();
|
|
339
|
-
for (const r of data)
|
|
340
|
-
byKey.set(r.__key, r);
|
|
341
|
-
for (const row of rows) {
|
|
342
|
-
let parentKey = row.__parentKey;
|
|
343
|
-
while (parentKey) {
|
|
344
|
-
if (ancestorSet.has(parentKey))
|
|
345
|
-
break;
|
|
346
|
-
ancestorSet.add(parentKey);
|
|
347
|
-
const parent = byKey.get(parentKey);
|
|
348
|
-
parentKey = parent === null || parent === void 0 ? void 0 : parent.__parentKey;
|
|
284
|
+
if (a.__index > b.__index) {
|
|
285
|
+
return 1;
|
|
349
286
|
}
|
|
350
|
-
|
|
351
|
-
|
|
287
|
+
return 0;
|
|
288
|
+
});
|
|
352
289
|
};
|
|
353
|
-
const searchData = (
|
|
290
|
+
const searchData = (searchText) => {
|
|
354
291
|
const columnKeys = columnState.map((col) => col.dataField);
|
|
355
|
-
|
|
292
|
+
return data.filter((row) => {
|
|
356
293
|
return columnKeys.some((key) => {
|
|
357
294
|
if (typeof row[key] === "string") {
|
|
358
295
|
return row[key].toLowerCase().includes(searchText.toLowerCase());
|
|
@@ -360,16 +297,6 @@ const TableProvider = (_a) => {
|
|
|
360
297
|
return false;
|
|
361
298
|
});
|
|
362
299
|
});
|
|
363
|
-
if (!_treeOptions.enabled) {
|
|
364
|
-
return { rows: matched, ancestorKeys: new Set() };
|
|
365
|
-
}
|
|
366
|
-
const ancestorKeys = collectAncestors(matched);
|
|
367
|
-
const visibleSet = new Set(matched.map((r) => r.__key));
|
|
368
|
-
ancestorKeys.forEach((k) => visibleSet.add(k));
|
|
369
|
-
return {
|
|
370
|
-
rows: rows.filter((r) => visibleSet.has(r.__key)),
|
|
371
|
-
ancestorKeys,
|
|
372
|
-
};
|
|
373
300
|
};
|
|
374
301
|
const rowMatchesRule = (row, rule) => {
|
|
375
302
|
var _a, _b, _c, _d;
|
|
@@ -469,26 +396,16 @@ const TableProvider = (_a) => {
|
|
|
469
396
|
return true;
|
|
470
397
|
}
|
|
471
398
|
};
|
|
472
|
-
const filterData = (
|
|
473
|
-
if (!
|
|
474
|
-
return
|
|
399
|
+
const filterData = (filter) => {
|
|
400
|
+
if (!data)
|
|
401
|
+
return [];
|
|
475
402
|
const { combinator, rules } = filter;
|
|
476
|
-
if (!combinator || !rules
|
|
477
|
-
return
|
|
403
|
+
if (!combinator || !rules)
|
|
404
|
+
return data;
|
|
405
|
+
if (combinator === "or") {
|
|
406
|
+
return data.filter((row) => rules.some((rule) => rowMatchesRule(row, rule)));
|
|
478
407
|
}
|
|
479
|
-
|
|
480
|
-
? rows.filter((row) => rules.some((rule) => rowMatchesRule(row, rule)))
|
|
481
|
-
: rows.filter((row) => rules.every((rule) => rowMatchesRule(row, rule)));
|
|
482
|
-
if (!_treeOptions.enabled) {
|
|
483
|
-
return { rows: matched, ancestorKeys: new Set() };
|
|
484
|
-
}
|
|
485
|
-
const ancestorKeys = collectAncestors(matched);
|
|
486
|
-
const visibleSet = new Set(matched.map((r) => r.__key));
|
|
487
|
-
ancestorKeys.forEach((k) => visibleSet.add(k));
|
|
488
|
-
return {
|
|
489
|
-
rows: rows.filter((r) => visibleSet.has(r.__key)),
|
|
490
|
-
ancestorKeys,
|
|
491
|
-
};
|
|
408
|
+
return data.filter((row) => rules.every((rule) => rowMatchesRule(row, rule)));
|
|
492
409
|
};
|
|
493
410
|
const toggleColumnVisibility = (dataField) => {
|
|
494
411
|
const newColumnState = columnState.map((col) => {
|
|
@@ -517,47 +434,6 @@ const TableProvider = (_a) => {
|
|
|
517
434
|
const key = !!keyField ? row[keyField] : row.__key;
|
|
518
435
|
return String(key);
|
|
519
436
|
};
|
|
520
|
-
const firstVisibleDataField = useMemo(() => { var _a; return (_a = columnState.find((c) => c.visible !== false)) === null || _a === void 0 ? void 0 : _a.dataField; }, [columnState]);
|
|
521
|
-
const persistExpandedKeys = (next) => {
|
|
522
|
-
if ((stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.enabled) && (stateStorage === null || stateStorage === void 0 ? void 0 : stateStorage.type) === "localStorage") {
|
|
523
|
-
StateStorage.setExpandedKeys(stateStorage.key, next);
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
const updateExpandedKeys = (next) => {
|
|
527
|
-
_setExpandedKeys(next);
|
|
528
|
-
onExpandedChange === null || onExpandedChange === void 0 ? void 0 : onExpandedChange(next);
|
|
529
|
-
persistExpandedKeys(next);
|
|
530
|
-
};
|
|
531
|
-
const expandRow = (row) => {
|
|
532
|
-
var _a;
|
|
533
|
-
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
534
|
-
if (expandedKeysSet.has(key))
|
|
535
|
-
return;
|
|
536
|
-
updateExpandedKeys([..._expandedKeys, key]);
|
|
537
|
-
};
|
|
538
|
-
const collapseRow = (row) => {
|
|
539
|
-
var _a;
|
|
540
|
-
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
541
|
-
if (!expandedKeysSet.has(key))
|
|
542
|
-
return;
|
|
543
|
-
updateExpandedKeys(_expandedKeys.filter((k) => k !== key));
|
|
544
|
-
};
|
|
545
|
-
const toggleRowExpanded = (row) => {
|
|
546
|
-
var _a;
|
|
547
|
-
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
548
|
-
if (expandedKeysSet.has(key)) {
|
|
549
|
-
updateExpandedKeys(_expandedKeys.filter((k) => k !== key));
|
|
550
|
-
}
|
|
551
|
-
else {
|
|
552
|
-
updateExpandedKeys([..._expandedKeys, key]);
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
const expandAllRows = () => {
|
|
556
|
-
updateExpandedKeys([..._treeMeta.expandableKeys]);
|
|
557
|
-
};
|
|
558
|
-
const collapseAllRows = () => {
|
|
559
|
-
updateExpandedKeys([]);
|
|
560
|
-
};
|
|
561
437
|
const selectRow = (row) => {
|
|
562
438
|
const key = getRowKey(row);
|
|
563
439
|
const newSelectionState = {
|
|
@@ -695,61 +571,6 @@ const TableProvider = (_a) => {
|
|
|
695
571
|
const key = getRowKey(row);
|
|
696
572
|
return focusedRowId === key;
|
|
697
573
|
};
|
|
698
|
-
const { _data, effectiveExpandedKeys } = useMemo(() => {
|
|
699
|
-
let processedData = data || [];
|
|
700
|
-
if (manualSorting !== true) {
|
|
701
|
-
processedData = sortData(sortState);
|
|
702
|
-
}
|
|
703
|
-
const autoExpandedSet = new Set();
|
|
704
|
-
if (manualFiltering !== true && _filterState) {
|
|
705
|
-
const result = filterData(processedData, _filterState);
|
|
706
|
-
processedData = result.rows;
|
|
707
|
-
if (_treeOptions.enabled && _treeOptions.autoExpandOnMatch) {
|
|
708
|
-
result.ancestorKeys.forEach((k) => autoExpandedSet.add(k));
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
if (manualSearch !== true && search) {
|
|
712
|
-
const result = searchData(processedData, search);
|
|
713
|
-
processedData = result.rows;
|
|
714
|
-
if (_treeOptions.enabled && _treeOptions.autoExpandOnMatch) {
|
|
715
|
-
result.ancestorKeys.forEach((k) => autoExpandedSet.add(k));
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
// Compute the effective expanded set: user expansion ∪ auto-expanded ancestors.
|
|
719
|
-
// Never mutates user's _expandedKeys.
|
|
720
|
-
const effective = new Set(expandedKeysSet);
|
|
721
|
-
autoExpandedSet.forEach((k) => effective.add(k));
|
|
722
|
-
// Final pass: drop rows whose ancestors are not in the effective set.
|
|
723
|
-
if (_treeOptions.enabled) {
|
|
724
|
-
const byKey = new Map();
|
|
725
|
-
for (const r of processedData)
|
|
726
|
-
byKey.set(r.__key, r);
|
|
727
|
-
processedData = processedData.filter((row) => {
|
|
728
|
-
let pk = row.__parentKey;
|
|
729
|
-
while (pk) {
|
|
730
|
-
if (!effective.has(pk))
|
|
731
|
-
return false;
|
|
732
|
-
const parent = byKey.get(pk);
|
|
733
|
-
pk = parent === null || parent === void 0 ? void 0 : parent.__parentKey;
|
|
734
|
-
}
|
|
735
|
-
return true;
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
return { _data: processedData, effectiveExpandedKeys: effective };
|
|
739
|
-
}, [
|
|
740
|
-
data,
|
|
741
|
-
columnState,
|
|
742
|
-
search,
|
|
743
|
-
sortState,
|
|
744
|
-
_filterState,
|
|
745
|
-
expandedKeysSet,
|
|
746
|
-
_treeOptions,
|
|
747
|
-
]);
|
|
748
|
-
const isRowExpanded = (row) => {
|
|
749
|
-
var _a;
|
|
750
|
-
const key = (_a = row === null || row === void 0 ? void 0 : row.__key) !== null && _a !== void 0 ? _a : getRowKey(row);
|
|
751
|
-
return effectiveExpandedKeys.has(key);
|
|
752
|
-
};
|
|
753
574
|
if (tableInstanceRef) {
|
|
754
575
|
tableInstanceRef.current = {
|
|
755
576
|
columnState,
|
|
@@ -766,13 +587,6 @@ const TableProvider = (_a) => {
|
|
|
766
587
|
clearSelections,
|
|
767
588
|
runSearch,
|
|
768
589
|
clearSearch,
|
|
769
|
-
expandRow,
|
|
770
|
-
collapseRow,
|
|
771
|
-
toggleRowExpanded,
|
|
772
|
-
isRowExpanded,
|
|
773
|
-
expandAllRows,
|
|
774
|
-
collapseAllRows,
|
|
775
|
-
getExpandedRowKeys: () => [..._expandedKeys],
|
|
776
590
|
getTableState: () => {
|
|
777
591
|
return {
|
|
778
592
|
columnState,
|
|
@@ -784,15 +598,25 @@ const TableProvider = (_a) => {
|
|
|
784
598
|
},
|
|
785
599
|
sortState,
|
|
786
600
|
searchState: search,
|
|
787
|
-
|
|
788
|
-
expandedKeys: [..._expandedKeys],
|
|
601
|
+
_filterState,
|
|
789
602
|
};
|
|
790
603
|
},
|
|
791
604
|
};
|
|
792
605
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
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
|
+
return (_jsx(TableContext.Provider, { value: Object.assign({ columnState, setColumnState: updateColumnState, sortState, searchState: search, totalRecords,
|
|
796
620
|
keyField,
|
|
797
621
|
handleColumnReorder,
|
|
798
622
|
handleColumnHeaderClick, selectionState: _selectionState, selectRow,
|
|
@@ -816,13 +640,6 @@ const TableProvider = (_a) => {
|
|
|
816
640
|
stateStorage, tableHeight: height, tableMaxHeight: maxHeight, tableMinHeight: minHeight, compact, tableElement: tableElement, headerRowElm: headerRowElm, tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm, enableColumnResize,
|
|
817
641
|
onSelectionChange,
|
|
818
642
|
onColumnStateChange,
|
|
819
|
-
onColumnReorder, onRowUpdated: onRowUpdated || (() => { }), tableMenuOptions, data: _data
|
|
820
|
-
isRowExpanded,
|
|
821
|
-
toggleRowExpanded,
|
|
822
|
-
expandRow,
|
|
823
|
-
collapseRow,
|
|
824
|
-
expandAllRows,
|
|
825
|
-
collapseAllRows,
|
|
826
|
-
onExpandedChange }, props), children: children }));
|
|
643
|
+
onColumnReorder, onRowUpdated: onRowUpdated || (() => { }), tableMenuOptions, data: _data }, props), children: children }));
|
|
827
644
|
};
|
|
828
645
|
export default TableProvider;
|
package/dist/Table/TableRow.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Maximize2Icon } from "lucide-react";
|
|
3
3
|
import ColumnResizer from "./ColumnResizer";
|
|
4
|
-
import { InnerCellContent, TD, TR
|
|
4
|
+
import { InnerCellContent, TD, TR } 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,
|
|
11
|
+
const { columnState, enableActionButton, onActionButtonClick, actionButtonIcon: Icon, enableSelection, selectRow, deselectRow, isRowSelected, isRowFocused, onRowUpdated, } = 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
|
-
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", 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;
|
|
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) => {
|
|
19
18
|
if (column.visible === false)
|
|
20
19
|
return null;
|
|
21
20
|
if (loading) {
|
|
@@ -25,20 +24,16 @@ const TableRow = ({ rowData, loading, rowStyle }) => {
|
|
|
25
24
|
flex: column.width ? "0 0 auto" : "1",
|
|
26
25
|
}, children: _jsx(LoadingCellIndicator, {}) }, index));
|
|
27
26
|
}
|
|
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
27
|
return (_jsxs(TD, { className: `mfui-td column-${column.columnId}`, "data-field": column.dataField, style: {
|
|
35
28
|
width: column.width,
|
|
36
29
|
minWidth: column.minWidth,
|
|
37
30
|
flex: column.width ? "0 0 auto" : "1",
|
|
38
|
-
}, children: [(column === null || column === void 0 ? void 0 : column.enableResize) === true && _jsx(ColumnResizer, { column: column }), _jsx(InnerCellContent, { className: "mfui inner-cell-content", children:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
}, children: [(column === null || column === void 0 ? void 0 : column.enableResize) === true && _jsx(ColumnResizer, { column: column }), _jsx(InnerCellContent, { className: "mfui inner-cell-content", children: column.render
|
|
32
|
+
? column.render({
|
|
33
|
+
rowData,
|
|
34
|
+
onRowUpdated,
|
|
35
|
+
})
|
|
36
|
+
: rowData[column.dataField] })] }, index));
|
|
42
37
|
})] }));
|
|
43
38
|
};
|
|
44
39
|
export default TableRow;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ColumnState, ColumnStateUpdate } from "../types";
|
|
2
|
+
export declare const resolveColumnStateUpdate: (columnStateUpdate: ColumnStateUpdate, previousColumnState: ColumnState[]) => ColumnState[];
|
|
3
|
+
export declare const notifyAndPersistColumnState: ({ nextColumnState, onColumnStateChange, persistColumnState, }: {
|
|
4
|
+
nextColumnState: ColumnState[];
|
|
5
|
+
onColumnStateChange?: (columnState: ColumnState[]) => void;
|
|
6
|
+
persistColumnState?: (columnState: ColumnState[]) => void;
|
|
7
|
+
}) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const resolveColumnStateUpdate = (columnStateUpdate, previousColumnState) => {
|
|
2
|
+
return typeof columnStateUpdate === "function"
|
|
3
|
+
? columnStateUpdate(previousColumnState)
|
|
4
|
+
: columnStateUpdate;
|
|
5
|
+
};
|
|
6
|
+
export const notifyAndPersistColumnState = ({ nextColumnState, onColumnStateChange, persistColumnState, }) => {
|
|
7
|
+
onColumnStateChange === null || onColumnStateChange === void 0 ? void 0 : onColumnStateChange(nextColumnState);
|
|
8
|
+
persistColumnState === null || persistColumnState === void 0 ? void 0 : persistColumnState(nextColumnState);
|
|
9
|
+
};
|
package/dist/Table/types.d.ts
CHANGED
|
@@ -10,42 +10,6 @@ export type StateStorage = {
|
|
|
10
10
|
type: "localStorage";
|
|
11
11
|
key: string;
|
|
12
12
|
};
|
|
13
|
-
export type TreeMode = "nested" | "flat";
|
|
14
|
-
export type TreeOptions = {
|
|
15
|
-
/** Enable tree-row behavior. Default: false */
|
|
16
|
-
enabled?: boolean;
|
|
17
|
-
/** Input shape. Default: "nested" */
|
|
18
|
-
mode?: TreeMode;
|
|
19
|
-
/** For mode="nested": field name that holds child array. Default: "children" */
|
|
20
|
-
childrenField?: string;
|
|
21
|
-
/** For mode="flat": field name that holds parent id. Default: "parentId" */
|
|
22
|
-
parentIdField?: string;
|
|
23
|
-
/** For mode="flat": field name that holds the row's stable id. Falls back to keyField. */
|
|
24
|
-
idField?: string;
|
|
25
|
-
/** Pixel width of one indentation level. Default: 16 */
|
|
26
|
-
indentPx?: number;
|
|
27
|
-
/** If a descendant matches search/filter, auto-expand its ancestors for the effective view. Default: true */
|
|
28
|
-
autoExpandOnMatch?: boolean;
|
|
29
|
-
};
|
|
30
|
-
export type ResolvedTreeOptions = {
|
|
31
|
-
enabled: boolean;
|
|
32
|
-
mode: TreeMode;
|
|
33
|
-
childrenField: string;
|
|
34
|
-
parentIdField: string;
|
|
35
|
-
idField?: string;
|
|
36
|
-
indentPx: number;
|
|
37
|
-
autoExpandOnMatch: boolean;
|
|
38
|
-
};
|
|
39
|
-
export type ExpandedKeysState = string[];
|
|
40
|
-
export type OnExpandedChangeFn = (keys: string[]) => void;
|
|
41
|
-
export type TreeMeta = {
|
|
42
|
-
/** Map of row key -> parent row key (undefined for roots) */
|
|
43
|
-
parentKeyMap: Map<string, string | undefined>;
|
|
44
|
-
/** Map of parent key -> ordered list of direct child keys */
|
|
45
|
-
childrenKeyMap: Map<string | undefined, string[]>;
|
|
46
|
-
/** All row keys that have children (eligible for expansion) */
|
|
47
|
-
expandableKeys: string[];
|
|
48
|
-
};
|
|
49
13
|
export type RenderOptions = {
|
|
50
14
|
rowData: any;
|
|
51
15
|
onRowUpdated?: (context: {
|
|
@@ -91,7 +55,6 @@ export type TableState = {
|
|
|
91
55
|
sortState?: SortState;
|
|
92
56
|
filterState?: Query;
|
|
93
57
|
searchState?: string;
|
|
94
|
-
expandedKeys?: ExpandedKeysState;
|
|
95
58
|
};
|
|
96
59
|
export interface onResizeFinishedProps {
|
|
97
60
|
column: ColumnState;
|
|
@@ -105,6 +68,7 @@ export interface onResizeProps {
|
|
|
105
68
|
width: number;
|
|
106
69
|
}[];
|
|
107
70
|
}
|
|
71
|
+
export type ColumnStateUpdate = ColumnState[] | ((prevColumnState: ColumnState[]) => ColumnState[]);
|
|
108
72
|
export interface ResizeHandlerProps {
|
|
109
73
|
event: React.MouseEvent<HTMLDivElement>;
|
|
110
74
|
columnId?: string;
|
|
@@ -132,24 +96,13 @@ export type TableDimensions = {
|
|
|
132
96
|
};
|
|
133
97
|
export type TableContextType = {
|
|
134
98
|
columnState: ColumnState[];
|
|
135
|
-
setColumnState:
|
|
99
|
+
setColumnState: (columnStateUpdate: ColumnStateUpdate) => void;
|
|
136
100
|
sortState?: SortState | null;
|
|
137
101
|
filterState?: Query | null;
|
|
138
102
|
searchState?: string | null;
|
|
139
103
|
data: any[];
|
|
140
104
|
totalRecords?: number;
|
|
141
105
|
keyField?: string;
|
|
142
|
-
treeOptions: ResolvedTreeOptions;
|
|
143
|
-
firstVisibleDataField?: string;
|
|
144
|
-
expandedKeys: string[];
|
|
145
|
-
effectiveExpandedKeys: Set<string>;
|
|
146
|
-
isRowExpanded: (row: any) => boolean;
|
|
147
|
-
toggleRowExpanded: (row: any) => void;
|
|
148
|
-
expandRow: (row: any) => void;
|
|
149
|
-
collapseRow: (row: any) => void;
|
|
150
|
-
expandAllRows: () => void;
|
|
151
|
-
collapseAllRows: () => void;
|
|
152
|
-
onExpandedChange?: OnExpandedChangeFn;
|
|
153
106
|
tableHeight?: number;
|
|
154
107
|
tableMaxHeight?: number;
|
|
155
108
|
tableMinHeight?: number;
|
|
@@ -261,11 +214,6 @@ export interface TableProviderProps {
|
|
|
261
214
|
defaultFilterState?: Query;
|
|
262
215
|
filterState?: Query;
|
|
263
216
|
onFilterChange?: (e: Query) => void;
|
|
264
|
-
treeOptions?: ResolvedTreeOptions;
|
|
265
|
-
defaultExpandedKeys?: ExpandedKeysState;
|
|
266
|
-
expandedKeys?: ExpandedKeysState;
|
|
267
|
-
onExpandedChange?: OnExpandedChangeFn;
|
|
268
|
-
treeMeta?: TreeMeta;
|
|
269
217
|
}
|
|
270
218
|
export interface TableRowProps {
|
|
271
219
|
rowData: {
|
|
@@ -387,14 +335,10 @@ export interface TableProps {
|
|
|
387
335
|
defaultFilterState?: Query;
|
|
388
336
|
filterState?: Query;
|
|
389
337
|
onFilterChange?: (e: Query) => void;
|
|
390
|
-
treeOptions?: TreeOptions;
|
|
391
|
-
defaultExpandedKeys?: ExpandedKeysState;
|
|
392
|
-
expandedKeys?: ExpandedKeysState;
|
|
393
|
-
onExpandedChange?: OnExpandedChangeFn;
|
|
394
338
|
}
|
|
395
339
|
export type TableInstance = {
|
|
396
340
|
columnState: ColumnState[];
|
|
397
|
-
setColumnState: (
|
|
341
|
+
setColumnState: (columnStateUpdate: ColumnStateUpdate) => void;
|
|
398
342
|
getColumnState: (dataField: string) => ColumnState | undefined;
|
|
399
343
|
onColumnResize?: (e: OnColumnChangeProps) => void;
|
|
400
344
|
onColumnReorder?: (e: OnColumnChangeProps) => void;
|
|
@@ -411,11 +355,4 @@ export type TableInstance = {
|
|
|
411
355
|
clearSearch: () => void;
|
|
412
356
|
clearSelections: () => void;
|
|
413
357
|
getTableState: () => TableState;
|
|
414
|
-
expandRow: (row: any) => void;
|
|
415
|
-
collapseRow: (row: any) => void;
|
|
416
|
-
toggleRowExpanded: (row: any) => void;
|
|
417
|
-
isRowExpanded: (row: any) => boolean;
|
|
418
|
-
expandAllRows: () => void;
|
|
419
|
-
collapseAllRows: () => void;
|
|
420
|
-
getExpandedRowKeys: () => string[];
|
|
421
358
|
};
|