@mantine-vue/table 3.0.0 → 3.1.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/cjs/index.cjs +1608 -33
- package/cjs/index.cjs.map +1 -1
- package/esm/index.mjs +1585 -36
- package/esm/index.mjs.map +1 -1
- package/lib/components/MVT_TableSlots.d.ts +28 -0
- package/lib/components/buttons/MVT_EditActionButtons.d.ts +1 -1
- package/lib/components/menus/MVT_ColumnActionMenu.d.ts +1 -1
- package/lib/index.d.mts +7 -0
- package/lib/index.d.ts +7 -0
- package/lib/server-grouping/MVT_ServerGroupingBody.d.ts +24 -0
- package/lib/server-grouping/MVT_ServerGroupingGroupBy.d.ts +45 -0
- package/lib/server-grouping/createServerGroupingProvider.d.ts +39 -0
- package/lib/server-grouping/serverGrouping.types.d.ts +494 -0
- package/lib/server-grouping/serverGrouping.utils.d.ts +31 -0
- package/lib/server-grouping/serverGroupingSelection.d.ts +65 -0
- package/lib/server-grouping/useMVT_ServerGrouping.d.ts +50 -0
- package/lib/types.d.ts +36 -2
- package/lib/utils/style.utils.d.ts +12 -0
- package/locales/en.cjs +11 -0
- package/locales/en.mjs +11 -0
- package/package.json +4 -4
- package/styles.css +60 -0
- package/styles.layer.css +60 -0
package/cjs/index.cjs
CHANGED
|
@@ -149,6 +149,896 @@ var getDefaultColumnOrderIds = (tableOptions, reset = false) => {
|
|
|
149
149
|
];
|
|
150
150
|
};
|
|
151
151
|
//#endregion
|
|
152
|
+
//#region src/server-grouping/serverGrouping.types.ts
|
|
153
|
+
var MVT_SERVER_GROUPING_ROOT_PATH_ID = "__root__";
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/utils/utils.ts
|
|
156
|
+
var parseFromValuesOrFunc = (fn, arg) => fn instanceof Function ? fn(arg) : fn;
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/server-grouping/serverGroupingSelection.ts
|
|
159
|
+
/** The server-grouping engine of a table, when server grouping is active. */
|
|
160
|
+
var getServerGroupingManager = (table) => table._serverGrouping;
|
|
161
|
+
/**
|
|
162
|
+
* Record rows that the user may currently select: loaded records inside
|
|
163
|
+
* expanded groups only (never group rows, never collapsed or unloaded
|
|
164
|
+
* groups), filtered by `enableRowSelection`.
|
|
165
|
+
*/
|
|
166
|
+
var getServerGroupingSelectableRows = (table) => {
|
|
167
|
+
const manager = getServerGroupingManager(table);
|
|
168
|
+
if (!manager) return [];
|
|
169
|
+
const { enableRowSelection } = table.options;
|
|
170
|
+
return manager.getVisibleRecordRows().filter((row) => parseFromValuesOrFunc(enableRowSelection, row) !== false);
|
|
171
|
+
};
|
|
172
|
+
/** Whether one record row is selected, honoring exclude mode. */
|
|
173
|
+
var isServerGroupingRecordSelected = (table, row) => {
|
|
174
|
+
const selectAll = getServerGroupingManager(table)?.getSelectAll();
|
|
175
|
+
if (selectAll?.active) return !selectAll.excludedRowIds.includes(row.id);
|
|
176
|
+
return !!table.getState().rowSelection?.[row.id];
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Header-checkbox state for a server-grouped table.
|
|
180
|
+
*
|
|
181
|
+
* In *include* mode `isAll` means "every selectable loaded record is
|
|
182
|
+
* selected". In *exclude* mode ("all matching records") the selection is a
|
|
183
|
+
* query, so the checkbox is checked, and turns indeterminate as soon as the
|
|
184
|
+
* user unchecks individual rows.
|
|
185
|
+
*/
|
|
186
|
+
var getServerGroupingSelectionSummary = (table) => {
|
|
187
|
+
const rows = getServerGroupingSelectableRows(table);
|
|
188
|
+
const selectAll = getServerGroupingManager(table)?.getSelectAll() ?? {
|
|
189
|
+
active: false,
|
|
190
|
+
excludedRowIds: []
|
|
191
|
+
};
|
|
192
|
+
if (selectAll.active) {
|
|
193
|
+
const excludedVisible = rows.filter((row) => selectAll.excludedRowIds.includes(row.id)).length;
|
|
194
|
+
return {
|
|
195
|
+
excludedRowIds: selectAll.excludedRowIds,
|
|
196
|
+
isAll: selectAll.excludedRowIds.length === 0,
|
|
197
|
+
isSelectAllMatching: true,
|
|
198
|
+
isSome: selectAll.excludedRowIds.length > 0,
|
|
199
|
+
mode: "exclude",
|
|
200
|
+
selectableCount: rows.length,
|
|
201
|
+
selectedCount: rows.length - excludedVisible,
|
|
202
|
+
selectedRowIds: []
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const rowSelection = table.getState().rowSelection ?? {};
|
|
206
|
+
const selectedCount = rows.filter((row) => rowSelection[row.id]).length;
|
|
207
|
+
const selectedRowIds = Object.keys(rowSelection).filter((rowId) => rowSelection[rowId]);
|
|
208
|
+
const isAll = rows.length > 0 && selectedCount === rows.length;
|
|
209
|
+
return {
|
|
210
|
+
excludedRowIds: [],
|
|
211
|
+
isAll,
|
|
212
|
+
isSelectAllMatching: false,
|
|
213
|
+
isSome: !isAll && selectedRowIds.length > 0,
|
|
214
|
+
mode: "include",
|
|
215
|
+
selectableCount: rows.length,
|
|
216
|
+
selectedCount,
|
|
217
|
+
selectedRowIds
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Everything a bulk action needs to send to the server.
|
|
222
|
+
*
|
|
223
|
+
* In exclude mode this is the query plus the user's deselections — no row ids
|
|
224
|
+
* are transferred, so it scales to millions of matching records.
|
|
225
|
+
*/
|
|
226
|
+
var getServerGroupingSelectionPayload = (table) => {
|
|
227
|
+
const manager = getServerGroupingManager(table);
|
|
228
|
+
const summary = getServerGroupingSelectionSummary(table);
|
|
229
|
+
const tableState = table.getState();
|
|
230
|
+
return {
|
|
231
|
+
columnFilters: tableState.columnFilters ?? [],
|
|
232
|
+
excludedRowIds: summary.excludedRowIds,
|
|
233
|
+
globalFilter: tableState.globalFilter,
|
|
234
|
+
grouping: manager?.getGroupingFields() ?? [],
|
|
235
|
+
mode: summary.mode,
|
|
236
|
+
rowIds: summary.selectedRowIds,
|
|
237
|
+
sorting: tableState.sorting ?? []
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* Header-checkbox toggle.
|
|
242
|
+
*
|
|
243
|
+
* - **Checking** selects every loaded record inside expanded groups. Records in
|
|
244
|
+
* collapsed or unloaded groups are never implicitly selected.
|
|
245
|
+
* - **Unchecking** clears the *entire* selection — including records whose
|
|
246
|
+
* group was collapsed since, and everything added by "select all matching
|
|
247
|
+
* records". Removing only the on-screen ids would leave invisible records
|
|
248
|
+
* selected while the header checkbox reads unchecked.
|
|
249
|
+
*/
|
|
250
|
+
var toggleAllServerGroupingRecordsSelected = (table, value) => {
|
|
251
|
+
const manager = getServerGroupingManager(table);
|
|
252
|
+
const summary = getServerGroupingSelectionSummary(table);
|
|
253
|
+
if (!(value ?? !(summary.isAll || summary.isSelectAllMatching))) {
|
|
254
|
+
manager?.setSelectAll({
|
|
255
|
+
active: false,
|
|
256
|
+
excludedRowIds: []
|
|
257
|
+
});
|
|
258
|
+
table.setRowSelection({});
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (summary.isSelectAllMatching) {
|
|
262
|
+
manager?.setSelectAll({
|
|
263
|
+
active: true,
|
|
264
|
+
excludedRowIds: []
|
|
265
|
+
});
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const rows = getServerGroupingSelectableRows(table);
|
|
269
|
+
table.setRowSelection((prev) => {
|
|
270
|
+
const selection = { ...prev };
|
|
271
|
+
rows.forEach((row) => {
|
|
272
|
+
selection[row.id] = true;
|
|
273
|
+
});
|
|
274
|
+
return selection;
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
/** Deselect the given record ids (used by `selection.clearOnCollapse`). */
|
|
278
|
+
var deselectServerGroupingRecords = (table, rowIds) => {
|
|
279
|
+
if (!rowIds.length) return;
|
|
280
|
+
table.setRowSelection((prev) => {
|
|
281
|
+
const selection = { ...prev };
|
|
282
|
+
rowIds.forEach((rowId) => delete selection[rowId]);
|
|
283
|
+
return selection;
|
|
284
|
+
});
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Toggle a single server-grouping record.
|
|
288
|
+
*
|
|
289
|
+
* Provider rows live outside the table's row model (`data` is empty), so
|
|
290
|
+
* `row.toggleSelected()` — which resolves the row through `table.getRow()` —
|
|
291
|
+
* would throw. Selection state is mutated directly instead.
|
|
292
|
+
*
|
|
293
|
+
* Supports shift-click range selection across the loaded records currently on
|
|
294
|
+
* screen, matching the behavior of a regular MVT table.
|
|
295
|
+
*/
|
|
296
|
+
var toggleServerGroupingRecordSelected = (table, row, value, options) => {
|
|
297
|
+
const manager = getServerGroupingManager(table);
|
|
298
|
+
const rows = getServerGroupingSelectableRows(table);
|
|
299
|
+
const targetIds = new Set([row.id]);
|
|
300
|
+
if (options?.batch && options.lastSelectedRowId) {
|
|
301
|
+
const lastIndex = rows.findIndex((candidate) => candidate.id === options.lastSelectedRowId);
|
|
302
|
+
const currentIndex = rows.findIndex((candidate) => candidate.id === row.id);
|
|
303
|
+
if (lastIndex !== -1 && currentIndex !== -1) {
|
|
304
|
+
const [start, end] = lastIndex < currentIndex ? [lastIndex, currentIndex] : [currentIndex, lastIndex];
|
|
305
|
+
for (let index = start; index <= end; index++) targetIds.add(rows[index].id);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const selectAll = manager?.getSelectAll();
|
|
309
|
+
if (selectAll?.active) {
|
|
310
|
+
const excluded = new Set(selectAll.excludedRowIds);
|
|
311
|
+
targetIds.forEach((rowId) => {
|
|
312
|
+
if (value) excluded.delete(rowId);
|
|
313
|
+
else excluded.add(rowId);
|
|
314
|
+
});
|
|
315
|
+
manager.setSelectAll({
|
|
316
|
+
active: true,
|
|
317
|
+
excludedRowIds: [...excluded]
|
|
318
|
+
});
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
table.setRowSelection((prev) => {
|
|
322
|
+
const selection = { ...prev };
|
|
323
|
+
targetIds.forEach((rowId) => {
|
|
324
|
+
if (value) selection[rowId] = true;
|
|
325
|
+
else delete selection[rowId];
|
|
326
|
+
});
|
|
327
|
+
return selection;
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* Opt-in "select all matching records" action: asks the consumer-provided
|
|
332
|
+
* `serverGrouping.selection.loadAllMatchingRowIds` for every row id matching
|
|
333
|
+
* the current filters (across all groups and pages) and selects them.
|
|
334
|
+
*/
|
|
335
|
+
var selectAllMatchingServerGroupingRecords = async (table) => {
|
|
336
|
+
const manager = getServerGroupingManager(table);
|
|
337
|
+
if (!manager) return;
|
|
338
|
+
const selectionOptions = manager.options.selection;
|
|
339
|
+
if ((selectionOptions?.selectAllMode ?? "query") === "query") {
|
|
340
|
+
table.setRowSelection({});
|
|
341
|
+
manager.setSelectAll({
|
|
342
|
+
active: true,
|
|
343
|
+
excludedRowIds: []
|
|
344
|
+
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
const loadAllMatchingRowIds = selectionOptions?.loadAllMatchingRowIds;
|
|
348
|
+
if (!loadAllMatchingRowIds) return;
|
|
349
|
+
const tableState = table.getState();
|
|
350
|
+
const rowIds = await loadAllMatchingRowIds({
|
|
351
|
+
columnFilters: tableState.columnFilters ?? [],
|
|
352
|
+
globalFilter: tableState.globalFilter,
|
|
353
|
+
grouping: manager.getGroupingFields(),
|
|
354
|
+
sorting: tableState.sorting ?? [],
|
|
355
|
+
table
|
|
356
|
+
});
|
|
357
|
+
table.setRowSelection((prev) => {
|
|
358
|
+
const selection = { ...prev };
|
|
359
|
+
rowIds.forEach((rowId) => {
|
|
360
|
+
selection[rowId] = true;
|
|
361
|
+
});
|
|
362
|
+
return selection;
|
|
363
|
+
});
|
|
364
|
+
};
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region src/server-grouping/serverGrouping.utils.ts
|
|
367
|
+
/**
|
|
368
|
+
* Escape a path segment part so group ids may safely contain the reserved
|
|
369
|
+
* characters `/` and `:` (and `%`, used for escaping).
|
|
370
|
+
*/
|
|
371
|
+
var escapeServerGroupPathPart = (part) => part.replace(/%/g, "%25").replace(/:/g, "%3A").replace(/\//g, "%2F");
|
|
372
|
+
var unescapeServerGroupPathPart = (part) => part.replace(/%2F/g, "/").replace(/%3A/g, ":").replace(/%25/g, "%");
|
|
373
|
+
/**
|
|
374
|
+
* Build the stable path id of a group's content, e.g.
|
|
375
|
+
* `createServerGroupPathId('__root__', 'country', 'BH')` → `'country:BH'` and
|
|
376
|
+
* `createServerGroupPathId('country:BH', 'salesperson', '42')` →
|
|
377
|
+
* `'country:BH/salesperson:42'`. Never derived from row indexes.
|
|
378
|
+
*/
|
|
379
|
+
var createServerGroupPathId = (parentPathId, field, groupId) => {
|
|
380
|
+
const segment = `${escapeServerGroupPathPart(field)}:${escapeServerGroupPathPart(groupId)}`;
|
|
381
|
+
return parentPathId === "__root__" ? segment : `${parentPathId}/${segment}`;
|
|
382
|
+
};
|
|
383
|
+
/** Parse a path id back into its `{ field, groupId }` segments. Root → `[]`. */
|
|
384
|
+
var parseServerGroupPathId = (pathId) => {
|
|
385
|
+
if (pathId === "__root__") return [];
|
|
386
|
+
return pathId.split("/").map((segment) => {
|
|
387
|
+
const separatorIndex = segment.indexOf(":");
|
|
388
|
+
return {
|
|
389
|
+
field: unescapeServerGroupPathPart(segment.slice(0, separatorIndex)),
|
|
390
|
+
groupId: unescapeServerGroupPathPart(segment.slice(separatorIndex + 1))
|
|
391
|
+
};
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
/** Depth of the content addressed by a path id (root → 0). */
|
|
395
|
+
var getServerGroupPathDepth = (pathId) => pathId === "__root__" ? 0 : pathId.split("/").length;
|
|
396
|
+
/** Whether `pathId` equals `ancestorPathId` or is nested anywhere below it. */
|
|
397
|
+
var isServerGroupPathOrDescendant = (pathId, ancestorPathId) => ancestorPathId === "__root__" || pathId === ancestorPathId || pathId.startsWith(`${ancestorPathId}/`);
|
|
398
|
+
/** JSON replacer producing deterministic output for plain objects. */
|
|
399
|
+
var stableReplacer = (_key, value) => {
|
|
400
|
+
if (value && typeof value === "object" && !Array.isArray(value)) return Object.keys(value).sort().reduce((acc, key) => {
|
|
401
|
+
acc[key] = value[key];
|
|
402
|
+
return acc;
|
|
403
|
+
}, {});
|
|
404
|
+
return value;
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Serialize cache key parts deterministically (object key order does not
|
|
408
|
+
* affect the result).
|
|
409
|
+
*/
|
|
410
|
+
var serializeServerGroupingCacheKey = (parts) => JSON.stringify(parts, stableReplacer);
|
|
411
|
+
/** Whether an error was caused by request cancellation (never shown as an error). */
|
|
412
|
+
var isAbortError = (error) => error instanceof DOMException ? error.name === "AbortError" : error?.name === "AbortError";
|
|
413
|
+
//#endregion
|
|
414
|
+
//#region src/server-grouping/useMVT_ServerGrouping.ts
|
|
415
|
+
var createMVT_ServerGroupingManager = (table, controlledExpandedReader, controlledSelectAllReader) => {
|
|
416
|
+
const serverGroupingOptions = table.options.serverGrouping;
|
|
417
|
+
if (!serverGroupingOptions?.provider || serverGroupingOptions.enabled === false) return;
|
|
418
|
+
const options = serverGroupingOptions;
|
|
419
|
+
const provider = options.provider;
|
|
420
|
+
const sortingMode = options.sortingMode ?? "independent";
|
|
421
|
+
const filteringMode = options.filteringMode ?? "shared";
|
|
422
|
+
const cacheOptions = {
|
|
423
|
+
enabled: options.cache?.enabled ?? false,
|
|
424
|
+
gcTime: options.cache?.gcTime ?? 3e5,
|
|
425
|
+
keepCollapsedGroups: options.cache?.keepCollapsedGroups ?? true,
|
|
426
|
+
staleTime: options.cache?.staleTime ?? 0
|
|
427
|
+
};
|
|
428
|
+
const configuredPageSize = options.pagination?.defaultPageSize ?? options.initialPageSize ?? 10;
|
|
429
|
+
let defaultPageSize = configuredPageSize;
|
|
430
|
+
if (!Number.isInteger(configuredPageSize) || configuredPageSize <= 0) {
|
|
431
|
+
console.warn(`[mantine-vue-table] serverGrouping page size ${JSON.stringify(configuredPageSize)} is invalid — expected a positive integer. Falling back to 10.`);
|
|
432
|
+
defaultPageSize = 10;
|
|
433
|
+
}
|
|
434
|
+
const pathStates = (0, vue.ref)({});
|
|
435
|
+
const internalExpanded = (0, vue.ref)(table.options.initialState?.serverGroupingExpanded ?? {});
|
|
436
|
+
const internalSelectAll = (0, vue.ref)(table.options.initialState?.serverGroupingSelectAll ?? {
|
|
437
|
+
active: false,
|
|
438
|
+
excludedRowIds: []
|
|
439
|
+
});
|
|
440
|
+
const nodeRegistry = /* @__PURE__ */ new Map();
|
|
441
|
+
const controllers = /* @__PURE__ */ new Map();
|
|
442
|
+
const versions = /* @__PURE__ */ new Map();
|
|
443
|
+
const cache = /* @__PURE__ */ new Map();
|
|
444
|
+
const rowCache = /* @__PURE__ */ new Map();
|
|
445
|
+
const readControlledExpanded = controlledExpandedReader ?? (() => table.options.state?.serverGroupingExpanded);
|
|
446
|
+
const isExpandedControlled = readControlledExpanded() !== void 0;
|
|
447
|
+
const getExpanded = () => readControlledExpanded() ?? internalExpanded.value;
|
|
448
|
+
const setExpanded = (updater) => {
|
|
449
|
+
const next = updater instanceof Function ? updater(getExpanded()) : updater;
|
|
450
|
+
const onChange = table.options.onServerGroupingExpandedChange;
|
|
451
|
+
if (onChange) onChange(next);
|
|
452
|
+
if (!isExpandedControlled) internalExpanded.value = next;
|
|
453
|
+
};
|
|
454
|
+
const isExpanded = (pathId) => getExpanded()[pathId] === true;
|
|
455
|
+
const readControlledSelectAll = controlledSelectAllReader ?? (() => table.options.state?.serverGroupingSelectAll);
|
|
456
|
+
const isSelectAllControlled = readControlledSelectAll() !== void 0;
|
|
457
|
+
const getSelectAll = () => readControlledSelectAll() ?? internalSelectAll.value;
|
|
458
|
+
const setSelectAll = (updater) => {
|
|
459
|
+
const next = updater instanceof Function ? updater(getSelectAll()) : updater;
|
|
460
|
+
table.options.onServerGroupingSelectAllChange?.(next);
|
|
461
|
+
if (!isSelectAllControlled) internalSelectAll.value = next;
|
|
462
|
+
};
|
|
463
|
+
/** The "all matching" selection is tied to the query it was made under. */
|
|
464
|
+
const resetSelectAll = () => {
|
|
465
|
+
if (getSelectAll().active || getSelectAll().excludedRowIds.length) setSelectAll({
|
|
466
|
+
active: false,
|
|
467
|
+
excludedRowIds: []
|
|
468
|
+
});
|
|
469
|
+
};
|
|
470
|
+
const getGroupingFields = () => options.grouping ?? table.getState().grouping ?? [];
|
|
471
|
+
const setPathState = (pathId, state) => {
|
|
472
|
+
pathStates.value = {
|
|
473
|
+
...pathStates.value,
|
|
474
|
+
[pathId]: state
|
|
475
|
+
};
|
|
476
|
+
};
|
|
477
|
+
const getPathState = (pathId) => pathStates.value[pathId];
|
|
478
|
+
/**
|
|
479
|
+
* Table rows for one loaded record page. Rows are created (and cached) here
|
|
480
|
+
* rather than in the renderer so row ids — and therefore selection state —
|
|
481
|
+
* have a single source of truth shared by the body, the header checkbox, and
|
|
482
|
+
* the public selection APIs.
|
|
483
|
+
*/
|
|
484
|
+
const getRecordRows = (pathId) => {
|
|
485
|
+
const state = getPathState(pathId);
|
|
486
|
+
if (!state || state.kind !== "records" || !state.rows) return [];
|
|
487
|
+
const cached = rowCache.get(pathId);
|
|
488
|
+
if (cached && cached.source === state.rows) return cached.rows;
|
|
489
|
+
const depth = getServerGroupPathDepth(pathId);
|
|
490
|
+
const rows = state.rows.map((original, index) => {
|
|
491
|
+
return (0, _tanstack_vue_table.createRow)(table, provider.getRowId?.(original) ?? table.options.getRowId?.(original, index, void 0) ?? `${pathId}::${index}`, original, index, depth);
|
|
492
|
+
});
|
|
493
|
+
rowCache.set(pathId, {
|
|
494
|
+
rows,
|
|
495
|
+
source: state.rows
|
|
496
|
+
});
|
|
497
|
+
return rows;
|
|
498
|
+
};
|
|
499
|
+
/**
|
|
500
|
+
* Every loaded record row that is currently visible — i.e. inside expanded
|
|
501
|
+
* groups on the current pages. Records in collapsed or never-loaded groups
|
|
502
|
+
* are deliberately excluded, so selection can never reach them.
|
|
503
|
+
*/
|
|
504
|
+
const getVisibleRecordRows = () => Object.keys(pathStates.value).filter((pathId) => pathStates.value[pathId]?.kind === "records" && isPathVisible(pathId)).flatMap((pathId) => getRecordRows(pathId));
|
|
505
|
+
const getNode = (pathId) => {
|
|
506
|
+
const item = nodeRegistry.get(pathId);
|
|
507
|
+
if (!item) return void 0;
|
|
508
|
+
return {
|
|
509
|
+
count: void 0,
|
|
510
|
+
id: item.id,
|
|
511
|
+
label: item.label,
|
|
512
|
+
meta: item.meta,
|
|
513
|
+
original: item.original,
|
|
514
|
+
value: item.value,
|
|
515
|
+
...item.__node
|
|
516
|
+
};
|
|
517
|
+
};
|
|
518
|
+
const getParentItems = (pathId) => {
|
|
519
|
+
if (pathId === "__root__") return [];
|
|
520
|
+
const segments = pathId.split("/");
|
|
521
|
+
const items = [];
|
|
522
|
+
for (let index = 0; index < segments.length; index++) {
|
|
523
|
+
const ancestorPathId = segments.slice(0, index + 1).join("/");
|
|
524
|
+
const item = nodeRegistry.get(ancestorPathId);
|
|
525
|
+
if (item) items.push(item);
|
|
526
|
+
}
|
|
527
|
+
return items;
|
|
528
|
+
};
|
|
529
|
+
const getEffectiveSorting = (pathId, kind) => {
|
|
530
|
+
const override = getPathState(pathId)?.sorting;
|
|
531
|
+
if (override) return override;
|
|
532
|
+
const tableSorting = table.getState().sorting ?? [];
|
|
533
|
+
if (sortingMode === "shared") return tableSorting;
|
|
534
|
+
if (sortingMode === "records-only") return kind === "records" ? tableSorting : [];
|
|
535
|
+
return pathId === "__root__" ? tableSorting : [];
|
|
536
|
+
};
|
|
537
|
+
const getEffectiveFilters = (pathId, kind) => {
|
|
538
|
+
const state = getPathState(pathId);
|
|
539
|
+
if (state?.columnFilters || state?.globalFilter !== void 0) return {
|
|
540
|
+
columnFilters: state.columnFilters ?? [],
|
|
541
|
+
globalFilter: state.globalFilter
|
|
542
|
+
};
|
|
543
|
+
if (filteringMode === "independent") return {
|
|
544
|
+
columnFilters: [],
|
|
545
|
+
globalFilter: void 0
|
|
546
|
+
};
|
|
547
|
+
if (filteringMode === "records-only" && kind !== "records") return {
|
|
548
|
+
columnFilters: [],
|
|
549
|
+
globalFilter: void 0
|
|
550
|
+
};
|
|
551
|
+
const tableState = table.getState();
|
|
552
|
+
return {
|
|
553
|
+
columnFilters: tableState.columnFilters ?? [],
|
|
554
|
+
globalFilter: tableState.globalFilter
|
|
555
|
+
};
|
|
556
|
+
};
|
|
557
|
+
const isRootPath = (pathId) => pathId === MVT_SERVER_GROUPING_ROOT_PATH_ID;
|
|
558
|
+
const getDefaultPagination = () => ({
|
|
559
|
+
pageIndex: 0,
|
|
560
|
+
pageSize: defaultPageSize
|
|
561
|
+
});
|
|
562
|
+
/**
|
|
563
|
+
* Effective pagination of a path. The root level is driven by the table's
|
|
564
|
+
* own `pagination` state, so the standard bottom toolbar (page navigation +
|
|
565
|
+
* rows-per-page) controls it exactly like an ungrouped server-side table.
|
|
566
|
+
* Nested levels keep their own independent, fixed-page-size state.
|
|
567
|
+
*/
|
|
568
|
+
const getEffectivePagination = (pathId) => {
|
|
569
|
+
if (isRootPath(pathId)) {
|
|
570
|
+
const { pageIndex, pageSize } = table.getState().pagination;
|
|
571
|
+
return {
|
|
572
|
+
...getPathState(pathId)?.pagination,
|
|
573
|
+
pageIndex,
|
|
574
|
+
pageSize
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
return getPathState(pathId)?.pagination ?? getDefaultPagination();
|
|
578
|
+
};
|
|
579
|
+
/** Reset a path to page 0. Returns `true` when it triggered a root reload. */
|
|
580
|
+
const resetPageIndex = (pathId) => {
|
|
581
|
+
if (isRootPath(pathId)) {
|
|
582
|
+
const { pageIndex } = table.getState().pagination;
|
|
583
|
+
if (pageIndex === 0) return false;
|
|
584
|
+
table.setPageIndex(0);
|
|
585
|
+
return true;
|
|
586
|
+
}
|
|
587
|
+
const state = getPathState(pathId);
|
|
588
|
+
if (state) setPathState(pathId, {
|
|
589
|
+
...state,
|
|
590
|
+
pagination: {
|
|
591
|
+
...state.pagination,
|
|
592
|
+
cursor: void 0,
|
|
593
|
+
pageIndex: 0
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
return false;
|
|
597
|
+
};
|
|
598
|
+
const buildRequest = (pathId, kind, signal) => {
|
|
599
|
+
const grouping = getGroupingFields();
|
|
600
|
+
const depth = getServerGroupPathDepth(pathId);
|
|
601
|
+
const parentGroups = getParentItems(pathId);
|
|
602
|
+
const { columnFilters, globalFilter } = getEffectiveFilters(pathId, kind);
|
|
603
|
+
const base = {
|
|
604
|
+
columnFilters,
|
|
605
|
+
depth,
|
|
606
|
+
globalFilter,
|
|
607
|
+
grouping,
|
|
608
|
+
pagination: getEffectivePagination(pathId),
|
|
609
|
+
parentGroup: parentGroups.at(-1),
|
|
610
|
+
parentGroups,
|
|
611
|
+
pathId,
|
|
612
|
+
signal,
|
|
613
|
+
sorting: getEffectiveSorting(pathId, kind),
|
|
614
|
+
table
|
|
615
|
+
};
|
|
616
|
+
return kind === "groups" ? {
|
|
617
|
+
...base,
|
|
618
|
+
groupingField: grouping[depth]
|
|
619
|
+
} : base;
|
|
620
|
+
};
|
|
621
|
+
const getCacheKey = (request) => serializeServerGroupingCacheKey([
|
|
622
|
+
request.pathId,
|
|
623
|
+
request.grouping,
|
|
624
|
+
request.depth,
|
|
625
|
+
request.pagination,
|
|
626
|
+
request.sorting,
|
|
627
|
+
request.columnFilters,
|
|
628
|
+
request.globalFilter ?? null,
|
|
629
|
+
...provider.getCacheKey?.(request) ?? []
|
|
630
|
+
]);
|
|
631
|
+
const gcCache = () => {
|
|
632
|
+
const now = Date.now();
|
|
633
|
+
cache.forEach((entry, key) => {
|
|
634
|
+
if (now - entry.updatedAt > cacheOptions.gcTime) cache.delete(key);
|
|
635
|
+
});
|
|
636
|
+
};
|
|
637
|
+
const load = (pathId) => {
|
|
638
|
+
const grouping = getGroupingFields();
|
|
639
|
+
const depth = getServerGroupPathDepth(pathId);
|
|
640
|
+
const kind = depth >= grouping.length ? "records" : "groups";
|
|
641
|
+
const previous = getPathState(pathId);
|
|
642
|
+
const hasData = previous?.groups !== void 0 || previous?.rows !== void 0;
|
|
643
|
+
controllers.get(pathId)?.abort();
|
|
644
|
+
const controller = new AbortController();
|
|
645
|
+
controllers.set(pathId, controller);
|
|
646
|
+
const version = (versions.get(pathId) ?? 0) + 1;
|
|
647
|
+
versions.set(pathId, version);
|
|
648
|
+
const request = buildRequest(pathId, kind, controller.signal);
|
|
649
|
+
const isCurrent = () => versions.get(pathId) === version && !controller.signal.aborted;
|
|
650
|
+
let servedFromCache = false;
|
|
651
|
+
let cacheKey;
|
|
652
|
+
if (cacheOptions.enabled) {
|
|
653
|
+
cacheKey = getCacheKey(request);
|
|
654
|
+
const entry = cache.get(cacheKey);
|
|
655
|
+
if (entry) {
|
|
656
|
+
servedFromCache = true;
|
|
657
|
+
const fresh = Date.now() - entry.updatedAt <= cacheOptions.staleTime;
|
|
658
|
+
setPathState(pathId, {
|
|
659
|
+
...entry.payload,
|
|
660
|
+
columnFilters: previous?.columnFilters,
|
|
661
|
+
depth,
|
|
662
|
+
error: null,
|
|
663
|
+
globalFilter: previous?.globalFilter,
|
|
664
|
+
isFetching: !fresh,
|
|
665
|
+
isLoading: false,
|
|
666
|
+
pagination: request.pagination,
|
|
667
|
+
pathId,
|
|
668
|
+
sorting: previous?.sorting,
|
|
669
|
+
updatedAt: entry.updatedAt
|
|
670
|
+
});
|
|
671
|
+
if (entry.payload.kind === "groups") registerGroups(pathId, entry.payload.groups ?? [], grouping[depth], depth);
|
|
672
|
+
if (fresh) return;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
if (!servedFromCache) setPathState(pathId, {
|
|
676
|
+
...previous,
|
|
677
|
+
columnFilters: previous?.columnFilters,
|
|
678
|
+
depth,
|
|
679
|
+
error: null,
|
|
680
|
+
groups: kind === "groups" ? previous?.groups : void 0,
|
|
681
|
+
isFetching: true,
|
|
682
|
+
isLoading: !hasData,
|
|
683
|
+
kind,
|
|
684
|
+
pagination: request.pagination,
|
|
685
|
+
pathId,
|
|
686
|
+
rowCount: previous?.rowCount ?? 0,
|
|
687
|
+
rows: kind === "records" ? previous?.rows : void 0,
|
|
688
|
+
sorting: previous?.sorting
|
|
689
|
+
});
|
|
690
|
+
const eventPayload = {
|
|
691
|
+
path: request.parentGroups,
|
|
692
|
+
pathId
|
|
693
|
+
};
|
|
694
|
+
options.onGroupLoadStart?.({
|
|
695
|
+
...eventPayload,
|
|
696
|
+
request
|
|
697
|
+
});
|
|
698
|
+
const promise = kind === "groups" ? provider.loadGroups(request) : provider.loadRecords(request);
|
|
699
|
+
Promise.resolve(promise).then((response) => {
|
|
700
|
+
if (!isCurrent()) return;
|
|
701
|
+
const updatedAt = Date.now();
|
|
702
|
+
let payload;
|
|
703
|
+
if (kind === "groups") {
|
|
704
|
+
const context = {
|
|
705
|
+
depth,
|
|
706
|
+
field: grouping[depth],
|
|
707
|
+
request
|
|
708
|
+
};
|
|
709
|
+
const groups = (provider.getGroups(response) ?? []).map((group) => ({
|
|
710
|
+
count: provider.getGroupCount?.(group, context),
|
|
711
|
+
hasChildren: provider.hasGroupChildren?.(group, context) ?? true,
|
|
712
|
+
id: provider.getGroupId(group, context),
|
|
713
|
+
label: provider.getGroupLabel(group, context),
|
|
714
|
+
meta: provider.getGroupMeta?.(group, context) ?? {},
|
|
715
|
+
original: group,
|
|
716
|
+
value: provider.getGroupValue ? provider.getGroupValue(group, context) : group
|
|
717
|
+
}));
|
|
718
|
+
registerGroups(pathId, groups, grouping[depth], depth);
|
|
719
|
+
payload = {
|
|
720
|
+
groups,
|
|
721
|
+
kind,
|
|
722
|
+
rowCount: provider.getGroupRowCount(response)
|
|
723
|
+
};
|
|
724
|
+
options.onGroupLoadSuccess?.({
|
|
725
|
+
...eventPayload,
|
|
726
|
+
groups,
|
|
727
|
+
request,
|
|
728
|
+
response
|
|
729
|
+
});
|
|
730
|
+
} else {
|
|
731
|
+
const rows = provider.getRecords(response) ?? [];
|
|
732
|
+
payload = {
|
|
733
|
+
kind,
|
|
734
|
+
rowCount: provider.getRecordRowCount(response),
|
|
735
|
+
rows
|
|
736
|
+
};
|
|
737
|
+
options.onRecordLoadSuccess?.({
|
|
738
|
+
...eventPayload,
|
|
739
|
+
request,
|
|
740
|
+
response,
|
|
741
|
+
rows
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
setPathState(pathId, {
|
|
745
|
+
...getPathState(pathId),
|
|
746
|
+
...payload,
|
|
747
|
+
error: null,
|
|
748
|
+
isFetching: false,
|
|
749
|
+
isLoading: false,
|
|
750
|
+
updatedAt
|
|
751
|
+
});
|
|
752
|
+
if (cacheOptions.enabled && cacheKey) {
|
|
753
|
+
cache.set(cacheKey, {
|
|
754
|
+
pathId,
|
|
755
|
+
payload,
|
|
756
|
+
updatedAt
|
|
757
|
+
});
|
|
758
|
+
gcCache();
|
|
759
|
+
}
|
|
760
|
+
}).catch((error) => {
|
|
761
|
+
if (!isCurrent() || isAbortError(error)) return;
|
|
762
|
+
setPathState(pathId, {
|
|
763
|
+
...getPathState(pathId),
|
|
764
|
+
error,
|
|
765
|
+
isFetching: false,
|
|
766
|
+
isLoading: false
|
|
767
|
+
});
|
|
768
|
+
options.onError?.({
|
|
769
|
+
...eventPayload,
|
|
770
|
+
error,
|
|
771
|
+
request
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
};
|
|
775
|
+
const registerGroups = (parentPathId, groups, field, depth) => {
|
|
776
|
+
groups.forEach((node) => {
|
|
777
|
+
const childPathId = createServerGroupPathId(parentPathId, field, node.id);
|
|
778
|
+
const item = {
|
|
779
|
+
depth,
|
|
780
|
+
field,
|
|
781
|
+
id: node.id,
|
|
782
|
+
label: node.label,
|
|
783
|
+
meta: node.meta,
|
|
784
|
+
original: node.original,
|
|
785
|
+
value: node.value
|
|
786
|
+
};
|
|
787
|
+
item.__node = node;
|
|
788
|
+
nodeRegistry.set(childPathId, item);
|
|
789
|
+
});
|
|
790
|
+
};
|
|
791
|
+
const ensureLoaded = (pathId) => {
|
|
792
|
+
const state = getPathState(pathId);
|
|
793
|
+
if (!state || state.groups === void 0 && state.rows === void 0 && !state.isFetching) load(pathId);
|
|
794
|
+
};
|
|
795
|
+
const isPathVisible = (pathId) => {
|
|
796
|
+
if (pathId === "__root__") return true;
|
|
797
|
+
const segments = pathId.split("/");
|
|
798
|
+
for (let index = 0; index < segments.length; index++) if (!isExpanded(segments.slice(0, index + 1).join("/"))) return false;
|
|
799
|
+
return true;
|
|
800
|
+
};
|
|
801
|
+
const getLoadedVisiblePaths = () => Object.keys(pathStates.value).filter(isPathVisible);
|
|
802
|
+
const abortPathAndDescendants = (pathId) => {
|
|
803
|
+
controllers.forEach((controller, key) => {
|
|
804
|
+
if (!isServerGroupPathOrDescendant(key, pathId)) return;
|
|
805
|
+
controller.abort();
|
|
806
|
+
const state = getPathState(key);
|
|
807
|
+
if (state?.isFetching || state?.isLoading) setPathState(key, {
|
|
808
|
+
...state,
|
|
809
|
+
isFetching: false,
|
|
810
|
+
isLoading: false
|
|
811
|
+
});
|
|
812
|
+
});
|
|
813
|
+
};
|
|
814
|
+
const dropPathAndDescendants = (pathId) => {
|
|
815
|
+
const next = { ...pathStates.value };
|
|
816
|
+
Object.keys(next).forEach((key) => {
|
|
817
|
+
if (isServerGroupPathOrDescendant(key, pathId)) delete next[key];
|
|
818
|
+
});
|
|
819
|
+
pathStates.value = next;
|
|
820
|
+
cache.forEach((entry, key) => {
|
|
821
|
+
if (isServerGroupPathOrDescendant(entry.pathId, pathId)) cache.delete(key);
|
|
822
|
+
});
|
|
823
|
+
rowCache.forEach((_entry, key) => {
|
|
824
|
+
if (isServerGroupPathOrDescendant(key, pathId)) rowCache.delete(key);
|
|
825
|
+
});
|
|
826
|
+
};
|
|
827
|
+
const expand = (pathId) => {
|
|
828
|
+
if (isExpanded(pathId)) return;
|
|
829
|
+
setExpanded((prev) => ({
|
|
830
|
+
...prev,
|
|
831
|
+
[pathId]: true
|
|
832
|
+
}));
|
|
833
|
+
};
|
|
834
|
+
const collapse = (pathId) => {
|
|
835
|
+
if (!isExpanded(pathId)) return;
|
|
836
|
+
setExpanded((prev) => ({
|
|
837
|
+
...prev,
|
|
838
|
+
[pathId]: false
|
|
839
|
+
}));
|
|
840
|
+
};
|
|
841
|
+
const toggle = (pathId) => {
|
|
842
|
+
if (isExpanded(pathId)) collapse(pathId);
|
|
843
|
+
else expand(pathId);
|
|
844
|
+
};
|
|
845
|
+
const invalidate = (pathId) => {
|
|
846
|
+
if (pathId === void 0) cache.clear();
|
|
847
|
+
else cache.forEach((entry, key) => {
|
|
848
|
+
if (isServerGroupPathOrDescendant(entry.pathId, pathId)) cache.delete(key);
|
|
849
|
+
});
|
|
850
|
+
};
|
|
851
|
+
const reload = (pathId) => {
|
|
852
|
+
if (pathId !== void 0) {
|
|
853
|
+
invalidate(pathId);
|
|
854
|
+
if (getPathState(pathId)) load(pathId);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
invalidate();
|
|
858
|
+
getLoadedVisiblePaths().forEach((visiblePathId) => load(visiblePathId));
|
|
859
|
+
};
|
|
860
|
+
const retry = (pathId) => {
|
|
861
|
+
load(pathId);
|
|
862
|
+
};
|
|
863
|
+
const reset = () => {
|
|
864
|
+
controllers.forEach((controller) => controller.abort());
|
|
865
|
+
controllers.clear();
|
|
866
|
+
versions.clear();
|
|
867
|
+
nodeRegistry.clear();
|
|
868
|
+
cache.clear();
|
|
869
|
+
rowCache.clear();
|
|
870
|
+
pathStates.value = {};
|
|
871
|
+
if (options.resetExpansionOnGroupingChange !== false) setExpanded({});
|
|
872
|
+
load(MVT_SERVER_GROUPING_ROOT_PATH_ID);
|
|
873
|
+
};
|
|
874
|
+
const setPagination = (pathId, updater) => {
|
|
875
|
+
const previous = getEffectivePagination(pathId);
|
|
876
|
+
const next = updater instanceof Function ? updater(previous) : {
|
|
877
|
+
...previous,
|
|
878
|
+
...updater
|
|
879
|
+
};
|
|
880
|
+
if (isRootPath(pathId)) {
|
|
881
|
+
const state = getPathState(pathId);
|
|
882
|
+
if (state) setPathState(pathId, {
|
|
883
|
+
...state,
|
|
884
|
+
pagination: next
|
|
885
|
+
});
|
|
886
|
+
const current = table.getState().pagination;
|
|
887
|
+
if (current.pageIndex === next.pageIndex && current.pageSize === next.pageSize) load(pathId);
|
|
888
|
+
else table.setPagination({
|
|
889
|
+
pageIndex: next.pageIndex,
|
|
890
|
+
pageSize: next.pageSize
|
|
891
|
+
});
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const state = getPathState(pathId);
|
|
895
|
+
if (state) setPathState(pathId, {
|
|
896
|
+
...state,
|
|
897
|
+
pagination: next
|
|
898
|
+
});
|
|
899
|
+
else setPathState(pathId, {
|
|
900
|
+
depth: getServerGroupPathDepth(pathId),
|
|
901
|
+
error: null,
|
|
902
|
+
isFetching: false,
|
|
903
|
+
isLoading: false,
|
|
904
|
+
kind: getServerGroupPathDepth(pathId) >= getGroupingFields().length ? "records" : "groups",
|
|
905
|
+
pagination: next,
|
|
906
|
+
pathId,
|
|
907
|
+
rowCount: 0
|
|
908
|
+
});
|
|
909
|
+
load(pathId);
|
|
910
|
+
};
|
|
911
|
+
const setSorting = (pathId, updater) => {
|
|
912
|
+
const state = getPathState(pathId);
|
|
913
|
+
const previous = state?.sorting ?? [];
|
|
914
|
+
const next = updater instanceof Function ? updater(previous) : updater;
|
|
915
|
+
if (!state) return;
|
|
916
|
+
setPathState(pathId, {
|
|
917
|
+
...state,
|
|
918
|
+
sorting: next
|
|
919
|
+
});
|
|
920
|
+
if (!resetPageIndex(pathId)) load(pathId);
|
|
921
|
+
};
|
|
922
|
+
const setColumnFilters = (pathId, updater) => {
|
|
923
|
+
const state = getPathState(pathId);
|
|
924
|
+
if (!state) return;
|
|
925
|
+
const previous = state.columnFilters ?? [];
|
|
926
|
+
const next = updater instanceof Function ? updater(previous) : updater;
|
|
927
|
+
setPathState(pathId, {
|
|
928
|
+
...state,
|
|
929
|
+
columnFilters: next
|
|
930
|
+
});
|
|
931
|
+
if (!resetPageIndex(pathId)) load(pathId);
|
|
932
|
+
};
|
|
933
|
+
const setGlobalFilter = (pathId, value) => {
|
|
934
|
+
const state = getPathState(pathId);
|
|
935
|
+
if (!state) return;
|
|
936
|
+
setPathState(pathId, {
|
|
937
|
+
...state,
|
|
938
|
+
globalFilter: value
|
|
939
|
+
});
|
|
940
|
+
if (!resetPageIndex(pathId)) load(pathId);
|
|
941
|
+
};
|
|
942
|
+
const getState = () => ({
|
|
943
|
+
enabled: true,
|
|
944
|
+
expanded: getExpanded(),
|
|
945
|
+
grouping: getGroupingFields(),
|
|
946
|
+
paths: pathStates.value
|
|
947
|
+
});
|
|
948
|
+
(0, vue.watch)(() => ({ ...getExpanded() }), (next, prev) => {
|
|
949
|
+
Object.keys(next).forEach((pathId) => {
|
|
950
|
+
if (next[pathId] && !prev?.[pathId]) {
|
|
951
|
+
options.onGroupExpand?.({
|
|
952
|
+
group: getNode(pathId),
|
|
953
|
+
path: getParentItems(pathId),
|
|
954
|
+
pathId
|
|
955
|
+
});
|
|
956
|
+
ensureLoaded(pathId);
|
|
957
|
+
}
|
|
958
|
+
});
|
|
959
|
+
Object.keys(prev ?? {}).forEach((pathId) => {
|
|
960
|
+
if (prev?.[pathId] && !next[pathId]) {
|
|
961
|
+
options.onGroupCollapse?.({
|
|
962
|
+
group: getNode(pathId),
|
|
963
|
+
path: getParentItems(pathId),
|
|
964
|
+
pathId
|
|
965
|
+
});
|
|
966
|
+
abortPathAndDescendants(pathId);
|
|
967
|
+
if (options.selection?.clearOnCollapse) deselectServerGroupingRecords(table, Object.keys(pathStates.value).filter((key) => pathStates.value[key]?.kind === "records" && isServerGroupPathOrDescendant(key, pathId)).flatMap((key) => getRecordRows(key).map((row) => row.id)));
|
|
968
|
+
if (!cacheOptions.keepCollapsedGroups) dropPathAndDescendants(pathId);
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
(0, vue.watch)(() => JSON.stringify(getGroupingFields()), (next, prev) => {
|
|
973
|
+
if (next !== prev) {
|
|
974
|
+
resetSelectAll();
|
|
975
|
+
reset();
|
|
976
|
+
}
|
|
977
|
+
});
|
|
978
|
+
(0, vue.watch)(() => JSON.stringify([table.getState().columnFilters ?? [], table.getState().globalFilter ?? null]), (next, prev) => {
|
|
979
|
+
if (next === prev || filteringMode === "independent") return;
|
|
980
|
+
resetSelectAll();
|
|
981
|
+
invalidate();
|
|
982
|
+
getLoadedVisiblePaths().filter((pathId) => filteringMode === "shared" || getPathState(pathId)?.kind === "records").forEach((pathId) => {
|
|
983
|
+
setPathState(pathId, {
|
|
984
|
+
...getPathState(pathId),
|
|
985
|
+
groups: void 0,
|
|
986
|
+
rows: void 0
|
|
987
|
+
});
|
|
988
|
+
if (!resetPageIndex(pathId)) load(pathId);
|
|
989
|
+
});
|
|
990
|
+
});
|
|
991
|
+
(0, vue.watch)(() => JSON.stringify(table.getState().sorting ?? []), (next, prev) => {
|
|
992
|
+
if (next === prev) return;
|
|
993
|
+
getLoadedVisiblePaths().filter((pathId) => {
|
|
994
|
+
if (getPathState(pathId)?.sorting) return false;
|
|
995
|
+
if (sortingMode === "shared") return true;
|
|
996
|
+
if (sortingMode === "records-only") return getPathState(pathId)?.kind === "records";
|
|
997
|
+
return pathId === MVT_SERVER_GROUPING_ROOT_PATH_ID;
|
|
998
|
+
}).forEach((pathId) => {
|
|
999
|
+
if (!resetPageIndex(pathId)) load(pathId);
|
|
1000
|
+
});
|
|
1001
|
+
});
|
|
1002
|
+
(0, vue.watch)(() => {
|
|
1003
|
+
const { pageIndex, pageSize } = table.getState().pagination;
|
|
1004
|
+
return `${pageIndex}:${pageSize}`;
|
|
1005
|
+
}, (next, prev) => {
|
|
1006
|
+
if (next !== prev) load(MVT_SERVER_GROUPING_ROOT_PATH_ID);
|
|
1007
|
+
});
|
|
1008
|
+
load(MVT_SERVER_GROUPING_ROOT_PATH_ID);
|
|
1009
|
+
if ((0, vue.getCurrentScope)()) (0, vue.onScopeDispose)(() => {
|
|
1010
|
+
controllers.forEach((controller) => controller.abort());
|
|
1011
|
+
controllers.clear();
|
|
1012
|
+
});
|
|
1013
|
+
return {
|
|
1014
|
+
collapse,
|
|
1015
|
+
ensureLoaded,
|
|
1016
|
+
expand,
|
|
1017
|
+
getExpanded,
|
|
1018
|
+
getGroupingFields,
|
|
1019
|
+
getNode,
|
|
1020
|
+
getParentItems,
|
|
1021
|
+
getPathState,
|
|
1022
|
+
getRecordRows,
|
|
1023
|
+
getSelectAll,
|
|
1024
|
+
getState,
|
|
1025
|
+
getVisibleRecordRows,
|
|
1026
|
+
invalidate,
|
|
1027
|
+
isExpanded,
|
|
1028
|
+
options,
|
|
1029
|
+
reload,
|
|
1030
|
+
reset,
|
|
1031
|
+
retry,
|
|
1032
|
+
setColumnFilters,
|
|
1033
|
+
setExpanded,
|
|
1034
|
+
setGlobalFilter,
|
|
1035
|
+
setSelectAll,
|
|
1036
|
+
setPagination,
|
|
1037
|
+
setSorting,
|
|
1038
|
+
toggle
|
|
1039
|
+
};
|
|
1040
|
+
};
|
|
1041
|
+
//#endregion
|
|
152
1042
|
//#region src/utils/tanstack.helpers.ts
|
|
153
1043
|
/**
|
|
154
1044
|
* Vue equivalent of `@tanstack/react-table`'s `flexRender`.
|
|
@@ -178,9 +1068,6 @@ function createMVTColumnHelper() {
|
|
|
178
1068
|
}
|
|
179
1069
|
var createRow = (table, originalRow, rowIndex = -1, depth = 0, subRows, parentId) => (0, _tanstack_vue_table.createRow)(table, "mvt-row-create", originalRow ?? Object.assign({}, ...getAllLeafColumnDefs(table.options.columns).map((col) => ({ [getColumnId(col)]: "" }))), rowIndex, depth, subRows, parentId);
|
|
180
1070
|
//#endregion
|
|
181
|
-
//#region src/utils/utils.ts
|
|
182
|
-
var parseFromValuesOrFunc = (fn, arg) => fn instanceof Function ? fn(arg) : fn;
|
|
183
|
-
//#endregion
|
|
184
1071
|
//#region src/components/MVT_TableSlots.ts
|
|
185
1072
|
var MVT_SLOTS_KEY = Symbol("MVT_Slots");
|
|
186
1073
|
/**
|
|
@@ -1002,6 +1889,7 @@ var getIsRankingRows = (table) => {
|
|
|
1002
1889
|
};
|
|
1003
1890
|
var getIsRowSelected = ({ row, table }) => {
|
|
1004
1891
|
const { options: { enableRowSelection } } = table;
|
|
1892
|
+
if (getServerGroupingManager(table)) return isServerGroupingRecordSelected(table, row);
|
|
1005
1893
|
return row.getIsSelected() || parseFromValuesOrFunc(enableRowSelection, row) && row.getCanSelectSubRows() && row.getIsAllSubRowsSelected();
|
|
1006
1894
|
};
|
|
1007
1895
|
var getMVT_RowSelectionHandler = ({ renderedRowIndex = 0, row, table }) => (event, value) => {
|
|
@@ -1012,6 +1900,14 @@ var getMVT_RowSelectionHandler = ({ renderedRowIndex = 0, row, table }) => (even
|
|
|
1012
1900
|
row,
|
|
1013
1901
|
table
|
|
1014
1902
|
});
|
|
1903
|
+
if (getServerGroupingManager(table)) {
|
|
1904
|
+
toggleServerGroupingRecordSelected(table, row, value ?? !wasCurrentRowChecked, {
|
|
1905
|
+
batch: !!enableBatchRowSelection && enableMultiRowSelection !== false && event.shiftKey,
|
|
1906
|
+
lastSelectedRowId: lastSelectedRowId.value
|
|
1907
|
+
});
|
|
1908
|
+
lastSelectedRowId.value = row.id;
|
|
1909
|
+
return;
|
|
1910
|
+
}
|
|
1015
1911
|
row.toggleSelected(value ?? !wasCurrentRowChecked);
|
|
1016
1912
|
const changedRowIds = new Set([row.id]);
|
|
1017
1913
|
if (enableBatchRowSelection && enableMultiRowSelection && event.shiftKey && lastSelectedRowId.value !== null) {
|
|
@@ -1072,7 +1968,10 @@ var MVT_SelectCheckbox = (0, vue.defineComponent)({
|
|
|
1072
1968
|
const o = table.options;
|
|
1073
1969
|
const state = table.getState();
|
|
1074
1970
|
const selectAll = !row;
|
|
1075
|
-
const
|
|
1971
|
+
const anyTable = table;
|
|
1972
|
+
const serverGroupingSummary = selectAll && getServerGroupingManager(anyTable) ? getServerGroupingSelectionSummary(anyTable) : void 0;
|
|
1973
|
+
const isServerGrouping = !!getServerGroupingManager(anyTable);
|
|
1974
|
+
const checked = serverGroupingSummary ? serverGroupingSummary.isAll : selectAll ? o.selectAllMode === "page" ? table.getIsAllPageRowsSelected() : table.getIsAllRowsSelected() : isServerGrouping && row ? isServerGroupingRecordSelected(anyTable, row) : getIsRowSelected({
|
|
1076
1975
|
row,
|
|
1077
1976
|
table
|
|
1078
1977
|
});
|
|
@@ -1088,11 +1987,11 @@ var MVT_SelectCheckbox = (0, vue.defineComponent)({
|
|
|
1088
1987
|
renderedRowIndex: props.renderedRowIndex,
|
|
1089
1988
|
row,
|
|
1090
1989
|
table
|
|
1091
|
-
}) : getMVT_SelectAllHandler({ table });
|
|
1990
|
+
}) : serverGroupingSummary ? (event) => toggleAllServerGroupingRecordsSelected(anyTable, event.target?.checked ?? !serverGroupingSummary.isAll) : getMVT_SelectAllHandler({ table });
|
|
1092
1991
|
const common = {
|
|
1093
1992
|
"aria-label": label,
|
|
1094
1993
|
checked,
|
|
1095
|
-
disabled: state.isLoading || row && !row.getCanSelect() || row?.id === "mvt-row-create",
|
|
1994
|
+
disabled: state.isLoading || row && !row.getCanSelect() || row?.id === "mvt-row-create" || serverGroupingSummary?.selectableCount === 0 && serverGroupingSummary.selectedRowIds.length === 0,
|
|
1096
1995
|
size: state.density === "xs" ? "sm" : "md",
|
|
1097
1996
|
...checkboxProps,
|
|
1098
1997
|
title: void 0,
|
|
@@ -1108,7 +2007,7 @@ var MVT_SelectCheckbox = (0, vue.defineComponent)({
|
|
|
1108
2007
|
}
|
|
1109
2008
|
};
|
|
1110
2009
|
const control = o.selectDisplayMode === "switch" ? (0, vue.h)(_mantine_vue_core.Switch, common) : o.selectDisplayMode === "radio" || o.enableMultiRowSelection === false ? (0, vue.h)(_mantine_vue_core.Radio, common) : (0, vue.h)(_mantine_vue_core.Checkbox, {
|
|
1111
|
-
indeterminate: !checked && selectAll ? table.getIsSomeRowsSelected() : row?.getIsSomeSelected() && row.getCanSelectSubRows(),
|
|
2010
|
+
indeterminate: serverGroupingSummary ? serverGroupingSummary.isSome : !checked && selectAll ? table.getIsSomeRowsSelected() : row?.getIsSomeSelected() && row.getCanSelectSubRows(),
|
|
1112
2011
|
...common
|
|
1113
2012
|
});
|
|
1114
2013
|
return (0, vue.h)(_mantine_vue_core.Tooltip, {
|
|
@@ -1238,12 +2137,14 @@ var MVT_Default_Icons = {
|
|
|
1238
2137
|
//#region src/locales/en.ts
|
|
1239
2138
|
var MVT_Localization_EN = {
|
|
1240
2139
|
actions: "Actions",
|
|
2140
|
+
allMatchingRecordsSelected: "All records matching the current filters are selected",
|
|
1241
2141
|
and: "and",
|
|
1242
2142
|
cancel: "Cancel",
|
|
1243
2143
|
changeFilterMode: "Change filter mode",
|
|
1244
2144
|
changeSearchMode: "Change search mode",
|
|
1245
2145
|
clearFilter: "Clear filter",
|
|
1246
2146
|
clearSearch: "Clear search",
|
|
2147
|
+
clearGrouping: "Clear grouping",
|
|
1247
2148
|
clearSelection: "Clear selection",
|
|
1248
2149
|
clearSort: "Clear sort",
|
|
1249
2150
|
clickToCopy: "Click to copy",
|
|
@@ -1254,6 +2155,7 @@ var MVT_Localization_EN = {
|
|
|
1254
2155
|
copiedToClipboard: "Copied to clipboard",
|
|
1255
2156
|
dropToGroupBy: "Drop to group by {column}",
|
|
1256
2157
|
edit: "Edit",
|
|
2158
|
+
errorLoadingData: "Error loading data",
|
|
1257
2159
|
expand: "Expand",
|
|
1258
2160
|
expandAll: "Expand all",
|
|
1259
2161
|
filterArrIncludes: "Includes",
|
|
@@ -1286,13 +2188,18 @@ var MVT_Localization_EN = {
|
|
|
1286
2188
|
goToNextPage: "Go to next page",
|
|
1287
2189
|
goToPreviousPage: "Go to previous page",
|
|
1288
2190
|
grab: "Grab",
|
|
2191
|
+
groupBy: "Group by",
|
|
1289
2192
|
groupByColumn: "Group by {column}",
|
|
1290
2193
|
groupedBy: "Grouped by ",
|
|
1291
2194
|
hideAll: "Hide all",
|
|
1292
2195
|
hideColumn: "Hide {column} column",
|
|
2196
|
+
loading: "Loading…",
|
|
1293
2197
|
max: "Max",
|
|
1294
2198
|
min: "Min",
|
|
1295
2199
|
move: "Move",
|
|
2200
|
+
moveDown: "Move down",
|
|
2201
|
+
moveUp: "Move up",
|
|
2202
|
+
noGroupableColumns: "No groupable columns",
|
|
1296
2203
|
noRecordsToDisplay: "No records to display",
|
|
1297
2204
|
noResultsFound: "No results found",
|
|
1298
2205
|
of: "of",
|
|
@@ -1302,6 +2209,7 @@ var MVT_Localization_EN = {
|
|
|
1302
2209
|
pinToRight: "Pin to right",
|
|
1303
2210
|
resetColumnSize: "Reset column size",
|
|
1304
2211
|
resetOrder: "Reset order",
|
|
2212
|
+
retry: "Retry",
|
|
1305
2213
|
rowActions: "Row Actions",
|
|
1306
2214
|
rowNumber: "#",
|
|
1307
2215
|
rowNumbers: "Row Numbers",
|
|
@@ -1309,7 +2217,9 @@ var MVT_Localization_EN = {
|
|
|
1309
2217
|
save: "Save",
|
|
1310
2218
|
search: "Search",
|
|
1311
2219
|
selectedCountOfRowCountRowsSelected: "{selectedCount} of {rowCount} row(s) selected",
|
|
2220
|
+
selectedCountRowsSelected: "{selectedCount} row(s) selected",
|
|
1312
2221
|
select: "Select",
|
|
2222
|
+
selectAllMatching: "Select all matching records",
|
|
1313
2223
|
showAll: "Show all",
|
|
1314
2224
|
showAllColumns: "Show all columns",
|
|
1315
2225
|
showHideColumns: "Show/Hide columns",
|
|
@@ -1396,6 +2306,33 @@ var useMVT_TableOptions = (rawOptions) => {
|
|
|
1396
2306
|
manualPagination = true;
|
|
1397
2307
|
manualSorting = true;
|
|
1398
2308
|
}
|
|
2309
|
+
if (rest.serverGrouping?.provider && rest.serverGrouping.enabled !== false) {
|
|
2310
|
+
if (enableGrouping || rawOptions.manualGrouping) console.warn("[mantine-vue-table] `serverGrouping` cannot be combined with client-side `enableGrouping` or `manualGrouping`. Disable one of them — `serverGrouping` will take precedence for rendering.");
|
|
2311
|
+
manualFiltering = true;
|
|
2312
|
+
manualPagination = true;
|
|
2313
|
+
manualSorting = true;
|
|
2314
|
+
if (rawOptions.groupedColumnMode === void 0) rest.groupedColumnMode = false;
|
|
2315
|
+
const configuredPageSize = rest.serverGrouping.pagination?.defaultPageSize ?? rest.serverGrouping.initialPageSize;
|
|
2316
|
+
const seededPageSize = Number.isInteger(configuredPageSize) && configuredPageSize > 0 ? configuredPageSize : void 0;
|
|
2317
|
+
if (seededPageSize && rawOptions.state?.pagination === void 0) rest.initialState = {
|
|
2318
|
+
...rest.initialState,
|
|
2319
|
+
pagination: {
|
|
2320
|
+
pageIndex: rest.initialState?.pagination?.pageIndex ?? 0,
|
|
2321
|
+
pageSize: rest.initialState?.pagination?.pageSize ?? seededPageSize
|
|
2322
|
+
}
|
|
2323
|
+
};
|
|
2324
|
+
const { defaultGrouping } = rest.serverGrouping;
|
|
2325
|
+
if (defaultGrouping?.length && !rest.serverGrouping.grouping && rawOptions.state?.grouping === void 0 && rest.initialState?.grouping === void 0) rest.initialState = {
|
|
2326
|
+
...rest.initialState,
|
|
2327
|
+
grouping: [...defaultGrouping]
|
|
2328
|
+
};
|
|
2329
|
+
const configuredFields = [...rest.serverGrouping.grouping ?? [], ...defaultGrouping ?? []];
|
|
2330
|
+
if (configuredFields.length) {
|
|
2331
|
+
const knownFields = new Set([...getAllLeafColumnDefs(rawOptions.columns).map((col) => getColumnId(col)), ...rest.serverGrouping.groupBy?.columns ?? []]);
|
|
2332
|
+
const unknownFields = [...new Set(configuredFields)].filter((field) => !knownFields.has(field));
|
|
2333
|
+
if (unknownFields.length) console.warn(`[mantine-vue-table] serverGrouping field(s) ${unknownFields.map((field) => `"${field}"`).join(", ")} do not match any column id. Custom backend descriptors are supported — declare them in \`serverGrouping.groupBy.columns\` to silence this warning and make them selectable in the group-by toolbar.`);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
1399
2336
|
const definedOptions = {
|
|
1400
2337
|
aggregationFns,
|
|
1401
2338
|
autoResetExpanded,
|
|
@@ -1644,6 +2581,12 @@ var useMVT_TableInstance = (definedTableOptions) => {
|
|
|
1644
2581
|
get: getter
|
|
1645
2582
|
});
|
|
1646
2583
|
};
|
|
2584
|
+
let serverGroupingManager;
|
|
2585
|
+
defineState("serverGroupingExpanded", () => serverGroupingManager?.getExpanded() ?? {});
|
|
2586
|
+
defineState("serverGroupingSelectAll", () => serverGroupingManager?.getSelectAll() ?? {
|
|
2587
|
+
active: false,
|
|
2588
|
+
excludedRowIds: []
|
|
2589
|
+
});
|
|
1647
2590
|
defineState("columnFilterFns", () => columnFilterFns.value);
|
|
1648
2591
|
defineState("columnOrder", () => columnOrder.value);
|
|
1649
2592
|
defineState("columnSizingInfo", () => columnSizingInfo.value);
|
|
@@ -1746,6 +2689,58 @@ var useMVT_TableInstance = (definedTableOptions) => {
|
|
|
1746
2689
|
table.setShowColumnFilters = statefulTableOptions.onShowColumnFiltersChange ?? ((updater) => applyUpdater(showColumnFilters, updater));
|
|
1747
2690
|
table.setShowGlobalFilter = statefulTableOptions.onShowGlobalFilterChange ?? ((updater) => applyUpdater(showGlobalFilter, updater));
|
|
1748
2691
|
table.setShowToolbarDropZone = statefulTableOptions.onShowToolbarDropZoneChange ?? ((updater) => applyUpdater(showToolbarDropZone, updater));
|
|
2692
|
+
serverGroupingManager = createMVT_ServerGroupingManager(table, () => userStateKeys.has("serverGroupingExpanded") ? readUserState().serverGroupingExpanded : void 0, () => userStateKeys.has("serverGroupingSelectAll") ? readUserState().serverGroupingSelectAll : void 0);
|
|
2693
|
+
table._serverGrouping = serverGroupingManager;
|
|
2694
|
+
if (serverGroupingManager) {
|
|
2695
|
+
const readUserRowCount = Object.getOwnPropertyDescriptor(definedTableOptions, "rowCount")?.get;
|
|
2696
|
+
Object.defineProperty(definedTableOptions, "rowCount", {
|
|
2697
|
+
configurable: true,
|
|
2698
|
+
enumerable: true,
|
|
2699
|
+
get: () => readUserRowCount?.call(definedTableOptions) ?? serverGroupingManager?.getPathState("__root__")?.rowCount
|
|
2700
|
+
});
|
|
2701
|
+
}
|
|
2702
|
+
table.getServerGroupingState = () => serverGroupingManager?.getState() ?? {
|
|
2703
|
+
enabled: false,
|
|
2704
|
+
expanded: {},
|
|
2705
|
+
grouping: [],
|
|
2706
|
+
paths: {}
|
|
2707
|
+
};
|
|
2708
|
+
table.getServerGroupingPathState = (pathId) => serverGroupingManager?.getPathState(pathId);
|
|
2709
|
+
table.expandServerGroup = (pathId) => serverGroupingManager?.expand(pathId);
|
|
2710
|
+
table.collapseServerGroup = (pathId) => serverGroupingManager?.collapse(pathId);
|
|
2711
|
+
table.toggleServerGroup = (pathId) => serverGroupingManager?.toggle(pathId);
|
|
2712
|
+
table.reloadServerGrouping = () => serverGroupingManager?.reload();
|
|
2713
|
+
table.reloadServerGroupingPath = (pathId) => serverGroupingManager?.reload(pathId);
|
|
2714
|
+
table.invalidateServerGrouping = () => serverGroupingManager?.invalidate();
|
|
2715
|
+
table.invalidateServerGroupingPath = (pathId) => serverGroupingManager?.invalidate(pathId);
|
|
2716
|
+
table.resetServerGroupingState = () => serverGroupingManager?.reset();
|
|
2717
|
+
table.setServerGroupingExpanded = (updater) => serverGroupingManager?.setExpanded(updater);
|
|
2718
|
+
table.setServerGroupingPagination = (pathId, pagination) => serverGroupingManager?.setPagination(pathId, pagination);
|
|
2719
|
+
table.setServerGroupingSorting = (pathId, sorting) => serverGroupingManager?.setSorting(pathId, sorting);
|
|
2720
|
+
table.setServerGroupingColumnFilters = (pathId, columnFilters) => serverGroupingManager?.setColumnFilters(pathId, columnFilters);
|
|
2721
|
+
table.setServerGroupingGlobalFilter = (pathId, globalFilter) => serverGroupingManager?.setGlobalFilter(pathId, globalFilter);
|
|
2722
|
+
table.getServerGroupingSelectionSummary = () => serverGroupingManager ? getServerGroupingSelectionSummary(table) : {
|
|
2723
|
+
excludedRowIds: [],
|
|
2724
|
+
isAll: false,
|
|
2725
|
+
isSelectAllMatching: false,
|
|
2726
|
+
isSome: false,
|
|
2727
|
+
mode: "include",
|
|
2728
|
+
selectableCount: 0,
|
|
2729
|
+
selectedCount: 0,
|
|
2730
|
+
selectedRowIds: []
|
|
2731
|
+
};
|
|
2732
|
+
table.toggleAllServerGroupingRecordsSelected = (value) => {
|
|
2733
|
+
if (serverGroupingManager) toggleAllServerGroupingRecordsSelected(table, value);
|
|
2734
|
+
};
|
|
2735
|
+
table.selectAllMatchingServerGroupingRecords = async () => {
|
|
2736
|
+
if (serverGroupingManager) await selectAllMatchingServerGroupingRecords(table);
|
|
2737
|
+
};
|
|
2738
|
+
table.getServerGroupingSelectAllState = () => serverGroupingManager?.getSelectAll() ?? {
|
|
2739
|
+
active: false,
|
|
2740
|
+
excludedRowIds: []
|
|
2741
|
+
};
|
|
2742
|
+
table.setServerGroupingSelectAllState = (updater) => serverGroupingManager?.setSelectAll(updater);
|
|
2743
|
+
table.getServerGroupingSelectionPayload = () => getServerGroupingSelectionPayload(table);
|
|
1749
2744
|
table._mvtSlots = mvtSlots;
|
|
1750
2745
|
table.setMVTSlots = (slots) => {
|
|
1751
2746
|
mvtSlots.value = slots;
|
|
@@ -1848,10 +2843,10 @@ var MVT_TablePagination = (0, vue.defineComponent)({
|
|
|
1848
2843
|
const { rowsPerPageOptions = defaultRowsPerPage, showRowsPerPage = true, withEdges = showEdges, ...rest } = paginationProps;
|
|
1849
2844
|
const controls = o.paginationDisplayMode === "pages" ? (0, vue.h)(_mantine_vue_core.Pagination, {
|
|
1850
2845
|
total: numberOfPages,
|
|
1851
|
-
|
|
2846
|
+
modelValue: pageIndex + 1,
|
|
1852
2847
|
withEdges,
|
|
1853
2848
|
...rest,
|
|
1854
|
-
|
|
2849
|
+
"onUpdate:modelValue": (page) => table.setPageIndex(page - 1)
|
|
1855
2850
|
}) : o.paginationDisplayMode === "default" ? [(0, vue.h)(_mantine_vue_core.Text, null, () => `${lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString()}-${lastRowIndex.toLocaleString()} ${o.localization.of} ${totalRowCount.toLocaleString()}`), (0, vue.h)(_mantine_vue_core.Group, { gap: 6 }, () => [
|
|
1856
2851
|
withEdges && (0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
1857
2852
|
"aria-label": o.localization.goToFirstPage,
|
|
@@ -1887,8 +2882,8 @@ var MVT_TablePagination = (0, vue.defineComponent)({
|
|
|
1887
2882
|
"aria-labelledby": "rpp-label",
|
|
1888
2883
|
class: MVT_TablePagination_module_default.pagesize,
|
|
1889
2884
|
data: rowsPerPageOptions,
|
|
1890
|
-
|
|
1891
|
-
|
|
2885
|
+
modelValue: pageSize.toString(),
|
|
2886
|
+
"onUpdate:modelValue": (value) => value && table.setPageSize(+value)
|
|
1892
2887
|
})]), controls]);
|
|
1893
2888
|
};
|
|
1894
2889
|
}
|
|
@@ -1928,26 +2923,50 @@ var MVT_ToolbarAlertBanner = (0, vue.defineComponent)({
|
|
|
1928
2923
|
const badgeProps = parseFromValuesOrFunc(o.mantineToolbarAlertBannerBadgeProps, { table });
|
|
1929
2924
|
const total = o.rowCount ?? table.getPrePaginationRowModel().flatRows.length;
|
|
1930
2925
|
const selectedCount = o.manualPagination ? Object.values(state.rowSelection).filter(Boolean).length : table.getFilteredSelectedRowModel().rows.length;
|
|
1931
|
-
const
|
|
2926
|
+
const serverGroupingSelection = o.serverGrouping?.selection;
|
|
2927
|
+
const serverGroupingSummary = table._serverGrouping ? table.getServerGroupingSelectionSummary() : void 0;
|
|
2928
|
+
const showSelectAllMatching = !!serverGroupingSelection?.enableSelectAllMatching && ((serverGroupingSelection.selectAllMode ?? "query") === "query" || !!serverGroupingSelection.loadAllMatchingRowIds) && !!serverGroupingSummary?.isAll && !serverGroupingSummary.isSelectAllMatching;
|
|
2929
|
+
const serverGroupingListsRecords = !serverGroupingSummary || table.getServerGroupingPathState("__root__")?.kind === "records";
|
|
2930
|
+
const selectedText = serverGroupingSummary?.isSelectAllMatching ? (o.localization.allMatchingRecordsSelected ?? "All records matching the current filters are selected") + (serverGroupingSummary.excludedRowIds.length ? ` (${serverGroupingSummary.excludedRowIds.length} excluded)` : "") : serverGroupingListsRecords ? o.localization.selectedCountOfRowCountRowsSelected.replace("{selectedCount}", String(selectedCount)).replace("{rowCount}", String(total)) : (o.localization.selectedCountRowsSelected ?? "{selectedCount} row(s) selected").replace("{selectedCount}", String(selectedCount));
|
|
2931
|
+
const selectedAlert = selectedCount || serverGroupingSummary?.isSelectAllMatching ? (0, vue.h)(_mantine_vue_core.Flex, {
|
|
1932
2932
|
align: "center",
|
|
1933
2933
|
gap: "sm"
|
|
1934
|
-
}, () => [
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
...badgeProps,
|
|
1944
|
-
rightSection: (0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
1945
|
-
color: "white",
|
|
1946
|
-
size: "xs",
|
|
2934
|
+
}, () => [
|
|
2935
|
+
selectedText,
|
|
2936
|
+
showSelectAllMatching && (0, vue.h)(_mantine_vue_core.Button, {
|
|
2937
|
+
size: "compact-xs",
|
|
2938
|
+
variant: "subtle",
|
|
2939
|
+
onClick: () => void table.selectAllMatchingServerGroupingRecords()
|
|
2940
|
+
}, () => o.localization.selectAllMatching ?? "Select all matching records"),
|
|
2941
|
+
(0, vue.h)(_mantine_vue_core.Button, {
|
|
2942
|
+
size: "compact-xs",
|
|
1947
2943
|
variant: "subtle",
|
|
1948
|
-
onClick: () =>
|
|
1949
|
-
|
|
1950
|
-
|
|
2944
|
+
onClick: (event) => {
|
|
2945
|
+
if (serverGroupingSummary) {
|
|
2946
|
+
table.toggleAllServerGroupingRecordsSelected(false);
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
getMVT_SelectAllHandler({ table })(event, false, true);
|
|
2950
|
+
}
|
|
2951
|
+
}, () => o.localization.clearSelection)
|
|
2952
|
+
]) : null;
|
|
2953
|
+
const groupedAlert = state.grouping.length ? (0, vue.h)(_mantine_vue_core.Flex, null, () => [`${o.localization.groupedBy} `, ...state.grouping.flatMap((columnId, index) => {
|
|
2954
|
+
const column = table.getAllLeafColumns().find((col) => col.id === columnId);
|
|
2955
|
+
const header = column?.columnDef.header;
|
|
2956
|
+
const label = typeof header === "string" && header.length ? header : columnId;
|
|
2957
|
+
return [index > 0 ? o.localization.thenBy : null, (0, vue.h)(_mantine_vue_core.Badge, {
|
|
2958
|
+
key: columnId,
|
|
2959
|
+
class: MVT_ToolbarAlertBanner_module_default["alert-badge"],
|
|
2960
|
+
variant: "filled",
|
|
2961
|
+
...badgeProps,
|
|
2962
|
+
rightSection: (0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
2963
|
+
color: "white",
|
|
2964
|
+
size: "xs",
|
|
2965
|
+
variant: "subtle",
|
|
2966
|
+
onClick: () => column ? column.toggleGrouping() : table.setGrouping((prev) => prev.filter((field) => field !== columnId))
|
|
2967
|
+
}, () => (0, vue.h)(o.icons.IconX, { style: { transform: "scale(0.8)" } }))
|
|
2968
|
+
}, () => `${label} `)];
|
|
2969
|
+
})]) : null;
|
|
1951
2970
|
const custom = slots.default?.({
|
|
1952
2971
|
groupedAlert,
|
|
1953
2972
|
selectedAlert,
|
|
@@ -2069,6 +3088,207 @@ var MVT_BottomToolbar = (0, vue.defineComponent)({
|
|
|
2069
3088
|
};
|
|
2070
3089
|
}
|
|
2071
3090
|
});
|
|
3091
|
+
var MVT_ServerGrouping_module_default = {
|
|
3092
|
+
"group-row": "_group-row_u9zpp_1",
|
|
3093
|
+
"row-grid": "_row-grid_u9zpp_7",
|
|
3094
|
+
"group-cell": "_group-cell_u9zpp_11",
|
|
3095
|
+
"aggregate-cell": "_aggregate-cell_u9zpp_15",
|
|
3096
|
+
"expand-spacer": "_expand-spacer_u9zpp_19",
|
|
3097
|
+
"aux-row": "_aux-row_u9zpp_24",
|
|
3098
|
+
"aux-cell": "_aux-cell_u9zpp_28",
|
|
3099
|
+
pagination: "_pagination_u9zpp_32",
|
|
3100
|
+
pagesize: "_pagesize_u9zpp_36",
|
|
3101
|
+
"groupby-control": "_groupby-control_u9zpp_40",
|
|
3102
|
+
"groupby-active-row": "_groupby-active-row_u9zpp_45",
|
|
3103
|
+
"groupby-active-label": "_groupby-active-label_u9zpp_52"
|
|
3104
|
+
};
|
|
3105
|
+
//#endregion
|
|
3106
|
+
//#region src/server-grouping/MVT_ServerGroupingGroupBy.ts
|
|
3107
|
+
/**
|
|
3108
|
+
* Resolve the columns/fields offered by the group-by toolbar control.
|
|
3109
|
+
*
|
|
3110
|
+
* With `serverGrouping.groupBy.columns` set, exactly that whitelist is used
|
|
3111
|
+
* (entries may be custom descriptors like `'createdAt:month'`). Otherwise
|
|
3112
|
+
* every leaf `data` column whose `enableGrouping` is not `false` is offered —
|
|
3113
|
+
* display columns and columns with `enableGrouping: false` never appear.
|
|
3114
|
+
*/
|
|
3115
|
+
var getServerGroupableColumns = (table) => {
|
|
3116
|
+
const groupByOptions = table.options.serverGrouping?.groupBy;
|
|
3117
|
+
const getFieldLabel = groupByOptions?.getFieldLabel;
|
|
3118
|
+
const labelFor = (field) => {
|
|
3119
|
+
if (getFieldLabel) return getFieldLabel(field, table);
|
|
3120
|
+
const header = table.getAllLeafColumns().find((leafColumn) => leafColumn.id === field)?.columnDef.header;
|
|
3121
|
+
return typeof header === "string" && header.length ? header : field;
|
|
3122
|
+
};
|
|
3123
|
+
if (groupByOptions?.columns) return groupByOptions.columns.map((field) => ({
|
|
3124
|
+
id: field,
|
|
3125
|
+
label: labelFor(field)
|
|
3126
|
+
}));
|
|
3127
|
+
return table.getAllLeafColumns().filter((column) => column.columnDef.columnDefType === "data" && column.columnDef.enableGrouping !== false).map((column) => ({
|
|
3128
|
+
id: column.id,
|
|
3129
|
+
label: labelFor(column.id)
|
|
3130
|
+
}));
|
|
3131
|
+
};
|
|
3132
|
+
/** Build the scoped context handed to the group-by slot / render callback. */
|
|
3133
|
+
var getServerGroupingGroupByContext = (table, manager) => {
|
|
3134
|
+
const grouping = manager.getGroupingFields();
|
|
3135
|
+
const setGrouping = (next) => table.setGrouping(next);
|
|
3136
|
+
return {
|
|
3137
|
+
addGroup: (field) => {
|
|
3138
|
+
if (!grouping.includes(field)) setGrouping([...grouping, field]);
|
|
3139
|
+
},
|
|
3140
|
+
clearGrouping: () => setGrouping([]),
|
|
3141
|
+
groupableColumns: getServerGroupableColumns(table),
|
|
3142
|
+
grouping,
|
|
3143
|
+
moveGroup: (field, direction) => {
|
|
3144
|
+
const index = grouping.indexOf(field);
|
|
3145
|
+
const target = index + direction;
|
|
3146
|
+
if (index === -1 || target < 0 || target >= grouping.length) return;
|
|
3147
|
+
const next = [...grouping];
|
|
3148
|
+
[next[index], next[target]] = [next[target], next[index]];
|
|
3149
|
+
setGrouping(next);
|
|
3150
|
+
},
|
|
3151
|
+
removeGroup: (field) => setGrouping(grouping.filter((activeField) => activeField !== field)),
|
|
3152
|
+
table
|
|
3153
|
+
};
|
|
3154
|
+
};
|
|
3155
|
+
/**
|
|
3156
|
+
* Grouping actions for one column's action menu, or `undefined` when the
|
|
3157
|
+
* column cannot be grouped by.
|
|
3158
|
+
*
|
|
3159
|
+
* Uses exactly the same rules as the toolbar "Group by" control: server
|
|
3160
|
+
* grouping must be active and driven by the table's `grouping` state, the
|
|
3161
|
+
* control must not be disabled, and the column must be offered by
|
|
3162
|
+
* {@link getServerGroupableColumns}.
|
|
3163
|
+
*/
|
|
3164
|
+
var getServerGroupingColumnActions = (table, columnId) => {
|
|
3165
|
+
const manager = table._serverGrouping;
|
|
3166
|
+
if (!manager) return void 0;
|
|
3167
|
+
const groupByOptions = manager.options.groupBy ?? {};
|
|
3168
|
+
if (groupByOptions.enabled === false || groupByOptions.showInColumnActions === false) return;
|
|
3169
|
+
if (manager.options.grouping && groupByOptions.enabled !== true) return void 0;
|
|
3170
|
+
const context = getServerGroupingGroupByContext(table, manager);
|
|
3171
|
+
return context.groupableColumns.some((column) => column.id === columnId) ? context : void 0;
|
|
3172
|
+
};
|
|
3173
|
+
/**
|
|
3174
|
+
* Built-in group-by toolbar control for server-side grouping. Renders a
|
|
3175
|
+
* "Group by" menu (add / reorder / remove / clear levels) plus the active
|
|
3176
|
+
* levels as removable pills. Hidden when server grouping is inactive, when
|
|
3177
|
+
* `groupBy.enabled` is `false`, or when grouping is a static
|
|
3178
|
+
* `serverGrouping.grouping` array (which the control could not change).
|
|
3179
|
+
*/
|
|
3180
|
+
var MVT_ServerGroupingGroupBy = (0, vue.defineComponent)({
|
|
3181
|
+
name: "MVTServerGroupingGroupBy",
|
|
3182
|
+
inheritAttrs: false,
|
|
3183
|
+
props: { table: {
|
|
3184
|
+
type: Object,
|
|
3185
|
+
required: true
|
|
3186
|
+
} },
|
|
3187
|
+
setup(props) {
|
|
3188
|
+
const mvtSlots = useMVT_Slots();
|
|
3189
|
+
return () => {
|
|
3190
|
+
const table = props.table;
|
|
3191
|
+
const manager = table._serverGrouping;
|
|
3192
|
+
if (!manager) return null;
|
|
3193
|
+
const sgOptions = manager.options;
|
|
3194
|
+
const groupByOptions = sgOptions.groupBy ?? {};
|
|
3195
|
+
if (groupByOptions.enabled === false) return null;
|
|
3196
|
+
if (sgOptions.grouping && groupByOptions.enabled !== true) return null;
|
|
3197
|
+
const localization = table.options.localization;
|
|
3198
|
+
const icons = table.options.icons;
|
|
3199
|
+
const allowReorder = groupByOptions.allowReorder ?? true;
|
|
3200
|
+
const allowClearAll = groupByOptions.allowClearAll ?? true;
|
|
3201
|
+
const context = getServerGroupingGroupByContext(table, manager);
|
|
3202
|
+
const { addGroup, clearGrouping, groupableColumns, grouping, moveGroup, removeGroup } = context;
|
|
3203
|
+
const custom = mvtSlots.serverGroupByControl?.(context) ?? parseFromValuesOrFunc(groupByOptions.renderControl, context);
|
|
3204
|
+
if (custom !== void 0 && custom !== null) return custom;
|
|
3205
|
+
const labelFor = (field) => groupableColumns.find((column) => column.id === field)?.label ?? field;
|
|
3206
|
+
const activeRows = grouping.map((field, index) => (0, vue.h)(_mantine_vue_core.Box, {
|
|
3207
|
+
class: MVT_ServerGrouping_module_default["groupby-active-row"],
|
|
3208
|
+
key: field
|
|
3209
|
+
}, () => [
|
|
3210
|
+
allowReorder && (0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
3211
|
+
"aria-label": `${localization.moveUp ?? "Move up"} ${labelFor(field)}`,
|
|
3212
|
+
color: "gray",
|
|
3213
|
+
disabled: index === 0,
|
|
3214
|
+
onClick: () => moveGroup(field, -1),
|
|
3215
|
+
size: "xs",
|
|
3216
|
+
variant: "subtle"
|
|
3217
|
+
}, () => (0, vue.h)(icons.IconChevronDown, { style: { transform: "rotate(180deg)" } })),
|
|
3218
|
+
allowReorder && (0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
3219
|
+
"aria-label": `${localization.moveDown ?? "Move down"} ${labelFor(field)}`,
|
|
3220
|
+
color: "gray",
|
|
3221
|
+
disabled: index === grouping.length - 1,
|
|
3222
|
+
onClick: () => moveGroup(field, 1),
|
|
3223
|
+
size: "xs",
|
|
3224
|
+
variant: "subtle"
|
|
3225
|
+
}, () => (0, vue.h)(icons.IconChevronDown)),
|
|
3226
|
+
(0, vue.h)(_mantine_vue_core.Text, {
|
|
3227
|
+
class: MVT_ServerGrouping_module_default["groupby-active-label"],
|
|
3228
|
+
size: "sm"
|
|
3229
|
+
}, () => `${index + 1}. ${labelFor(field)}`),
|
|
3230
|
+
(0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
3231
|
+
"aria-label": (localization.ungroupByColumn ?? "Ungroup by {column}").replace("{column}", labelFor(field)),
|
|
3232
|
+
color: "gray",
|
|
3233
|
+
onClick: () => removeGroup(field),
|
|
3234
|
+
size: "xs",
|
|
3235
|
+
variant: "subtle"
|
|
3236
|
+
}, () => (0, vue.h)(icons.IconX))
|
|
3237
|
+
]));
|
|
3238
|
+
const menu = (0, vue.h)(_mantine_vue_core.Menu, {
|
|
3239
|
+
closeOnItemClick: false,
|
|
3240
|
+
position: "bottom-start",
|
|
3241
|
+
shadow: "md",
|
|
3242
|
+
width: 260,
|
|
3243
|
+
...groupByOptions.mantineMenuProps
|
|
3244
|
+
}, () => [(0, vue.h)(_mantine_vue_core.Menu.Target, null, () => (0, vue.h)(_mantine_vue_core.Button, {
|
|
3245
|
+
size: "xs",
|
|
3246
|
+
variant: "default",
|
|
3247
|
+
...groupByOptions.mantineButtonProps,
|
|
3248
|
+
leftSection: groupByOptions.mantineButtonProps?.leftSection ?? (0, vue.h)(icons.IconColumns)
|
|
3249
|
+
}, () => localization.groupBy ?? "Group by")), (0, vue.h)(_mantine_vue_core.Menu.Dropdown, null, () => [
|
|
3250
|
+
groupableColumns.length ? groupableColumns.map((column) => (0, vue.h)(_mantine_vue_core.Menu.Item, {
|
|
3251
|
+
disabled: grouping.includes(column.id),
|
|
3252
|
+
key: column.id,
|
|
3253
|
+
onClick: () => addGroup(column.id)
|
|
3254
|
+
}, () => column.label)) : (0, vue.h)(_mantine_vue_core.Menu.Label, null, () => localization.noGroupableColumns ?? "No groupable columns"),
|
|
3255
|
+
grouping.length > 0 && [
|
|
3256
|
+
(0, vue.h)(_mantine_vue_core.Menu.Divider),
|
|
3257
|
+
(0, vue.h)(_mantine_vue_core.Menu.Label, null, () => (localization.groupedBy ?? "Grouped by ").trim()),
|
|
3258
|
+
...activeRows
|
|
3259
|
+
],
|
|
3260
|
+
allowClearAll && grouping.length > 0 && [(0, vue.h)(_mantine_vue_core.Menu.Divider), (0, vue.h)(_mantine_vue_core.Menu.Item, {
|
|
3261
|
+
color: "red",
|
|
3262
|
+
onClick: () => clearGrouping()
|
|
3263
|
+
}, () => localization.clearGrouping ?? "Clear grouping")]
|
|
3264
|
+
])]);
|
|
3265
|
+
const pills = grouping.length > 0 && (0, vue.h)(_mantine_vue_core.PillGroup, { gap: 4 }, () => grouping.map((field, index) => {
|
|
3266
|
+
const pillProps = parseFromValuesOrFunc(groupByOptions.mantinePillProps, {
|
|
3267
|
+
field,
|
|
3268
|
+
index
|
|
3269
|
+
}) ?? {};
|
|
3270
|
+
return (0, vue.h)(_mantine_vue_core.Pill, {
|
|
3271
|
+
size: "sm",
|
|
3272
|
+
withRemoveButton: true,
|
|
3273
|
+
...pillProps,
|
|
3274
|
+
key: field,
|
|
3275
|
+
onRemove: () => removeGroup(field),
|
|
3276
|
+
removeButtonProps: {
|
|
3277
|
+
"aria-label": (localization.ungroupByColumn ?? "Ungroup by {column}").replace("{column}", labelFor(field)),
|
|
3278
|
+
...pillProps?.removeButtonProps
|
|
3279
|
+
}
|
|
3280
|
+
}, () => `${index + 1}. ${labelFor(field)}`);
|
|
3281
|
+
}));
|
|
3282
|
+
return (0, vue.h)(_mantine_vue_core.Box, {
|
|
3283
|
+
class: (0, clsx.default)("mvt-server-groupby-control", MVT_ServerGrouping_module_default["groupby-control"]),
|
|
3284
|
+
style: {
|
|
3285
|
+
display: "flex",
|
|
3286
|
+
gap: "8px"
|
|
3287
|
+
}
|
|
3288
|
+
}, () => [menu, pills]);
|
|
3289
|
+
};
|
|
3290
|
+
}
|
|
3291
|
+
});
|
|
2072
3292
|
var MVT_FilterOptionMenu_module_default = { symbol: "_symbol_1b3vj_1" };
|
|
2073
3293
|
//#endregion
|
|
2074
3294
|
//#region src/components/menus/MVT_FilterOptionMenu.ts
|
|
@@ -2457,7 +3677,7 @@ var MVT_ShowHideColumnsMenuItems = (0, vue.defineComponent)({
|
|
|
2457
3677
|
openDelay: 1e3,
|
|
2458
3678
|
withinPortal: true
|
|
2459
3679
|
}, () => (0, vue.h)(_mantine_vue_core.Switch, {
|
|
2460
|
-
checked,
|
|
3680
|
+
modelValue: checked,
|
|
2461
3681
|
class: MVT_ShowHideColumnsMenuItems_module_default.switch,
|
|
2462
3682
|
disabled: !column.getCanHide(),
|
|
2463
3683
|
label: def.header,
|
|
@@ -2776,6 +3996,7 @@ var MVT_TopToolbar = (0, vue.defineComponent)({
|
|
|
2776
3996
|
["both", "top"].includes(positionToolbarDropZone ?? "") && (0, vue.h)(MVT_ToolbarDropZone, { table }),
|
|
2777
3997
|
(0, vue.h)(_mantine_vue_core.Flex, { class: [MVT_TopToolbar_module_default["actions-container"], stackAlertBanner ? MVT_TopToolbar_module_default["actions-container-stack-alert"] : void 0] }, () => [
|
|
2778
3998
|
enableGlobalFilter && positionGlobalFilter === "left" && (0, vue.h)(MVT_GlobalFilterTextInput, globalFilterProps),
|
|
3999
|
+
table._serverGrouping && (0, vue.h)(MVT_ServerGroupingGroupBy, { table }),
|
|
2779
4000
|
parseFromValuesOrFunc(renderTopToolbarCustomActions, { table }) ?? (0, vue.h)("span"),
|
|
2780
4001
|
enableToolbarInternalActions ? (0, vue.h)(_mantine_vue_core.Flex, {
|
|
2781
4002
|
justify: "end",
|
|
@@ -2952,6 +4173,21 @@ var useMVT_ColumnVirtualizer = (table) => {
|
|
|
2952
4173
|
//#endregion
|
|
2953
4174
|
//#region src/utils/style.utils.ts
|
|
2954
4175
|
var parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, "_");
|
|
4176
|
+
/**
|
|
4177
|
+
* Width/flex styles that bind a cell to its column's live size variables, so
|
|
4178
|
+
* custom cells (server-grouping group rows, …) stay aligned with the root
|
|
4179
|
+
* table while columns are resized or reordered.
|
|
4180
|
+
*/
|
|
4181
|
+
var getMVT_ColumnWidthStyles = ({ columnId, grow, layoutMode, minSize }) => {
|
|
4182
|
+
const cssVar = `--col-${parseCSSVarId(columnId)}-size`;
|
|
4183
|
+
const styles = {
|
|
4184
|
+
minWidth: `max(calc(var(${cssVar}) * 1px), ${minSize ?? 30}px)`,
|
|
4185
|
+
width: `calc(var(${cssVar}) * 1px)`
|
|
4186
|
+
};
|
|
4187
|
+
if (layoutMode === "grid") styles.flex = `${[0, false].includes(grow) ? 0 : `var(${cssVar})`} 0 auto`;
|
|
4188
|
+
else if (layoutMode === "grid-no-grow") styles.flex = `${+(grow || 0)} 0 auto`;
|
|
4189
|
+
return styles;
|
|
4190
|
+
};
|
|
2955
4191
|
var getPrimaryShade = (theme) => typeof theme.primaryShade === "number" ? theme.primaryShade : theme.primaryShade?.dark ?? 7;
|
|
2956
4192
|
var getPrimaryColor = (theme, shade) => theme.colors[theme.primaryColor][shade ?? getPrimaryShade(theme)];
|
|
2957
4193
|
function dataVariable(name, value) {
|
|
@@ -3279,8 +4515,9 @@ var MVT_TableBodyCell = (0, vue.defineComponent)({
|
|
|
3279
4515
|
if (!columnDef.enableCellHoverReveal) return;
|
|
3280
4516
|
isCellContentOverflowing.value = false;
|
|
3281
4517
|
};
|
|
4518
|
+
const isServerGrouping = !!table._serverGrouping;
|
|
3282
4519
|
const renderCellContent = () => {
|
|
3283
|
-
if (cell.getIsPlaceholder()) return columnDef.PlaceholderCell?.({
|
|
4520
|
+
if (!isServerGrouping && cell.getIsPlaceholder()) return columnDef.PlaceholderCell?.({
|
|
3284
4521
|
cell,
|
|
3285
4522
|
column,
|
|
3286
4523
|
row,
|
|
@@ -3606,6 +4843,271 @@ var MVT_TableBodyRow = (0, vue.defineComponent)({
|
|
|
3606
4843
|
}
|
|
3607
4844
|
});
|
|
3608
4845
|
var Memo_MVT_TableBodyRow = MVT_TableBodyRow;
|
|
4846
|
+
//#endregion
|
|
4847
|
+
//#region src/server-grouping/MVT_ServerGroupingBody.ts
|
|
4848
|
+
var INDENT_PX = 24;
|
|
4849
|
+
/** Renders the server-grouping hierarchy as rows of the root table body. */
|
|
4850
|
+
var MVT_ServerGroupingBody = (0, vue.defineComponent)({
|
|
4851
|
+
name: "MVTServerGroupingBody",
|
|
4852
|
+
inheritAttrs: false,
|
|
4853
|
+
props: {
|
|
4854
|
+
table: {
|
|
4855
|
+
type: Object,
|
|
4856
|
+
required: true
|
|
4857
|
+
},
|
|
4858
|
+
tableProps: {
|
|
4859
|
+
type: Object,
|
|
4860
|
+
required: true
|
|
4861
|
+
}
|
|
4862
|
+
},
|
|
4863
|
+
setup(props) {
|
|
4864
|
+
const mvtSlots = useMVT_Slots();
|
|
4865
|
+
return () => {
|
|
4866
|
+
const { tableProps } = props;
|
|
4867
|
+
const table = props.table;
|
|
4868
|
+
const manager = table._serverGrouping;
|
|
4869
|
+
if (!manager) return null;
|
|
4870
|
+
const { options: sgOptions } = manager;
|
|
4871
|
+
const tableOptions = table.options;
|
|
4872
|
+
const localization = tableOptions.localization;
|
|
4873
|
+
const icons = tableOptions.icons;
|
|
4874
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
4875
|
+
const colSpan = visibleColumns.length || 1;
|
|
4876
|
+
const layoutMode = tableOptions.layoutMode;
|
|
4877
|
+
const paginationOptions = {
|
|
4878
|
+
enabled: sgOptions.pagination?.enabled ?? true,
|
|
4879
|
+
mantineActionIconProps: sgOptions.pagination?.mantineActionIconProps ?? {},
|
|
4880
|
+
showAtRoot: sgOptions.pagination?.showAtRoot ?? (tableOptions.enablePagination === false || tableOptions.positionPagination === "none"),
|
|
4881
|
+
showForGroups: sgOptions.pagination?.showForGroups ?? true,
|
|
4882
|
+
showForRecords: sgOptions.pagination?.showForRecords ?? true
|
|
4883
|
+
};
|
|
4884
|
+
const indentStyle = (depth) => ({ paddingInlineStart: `${8 + depth * INDENT_PX}px` });
|
|
4885
|
+
const columnStyle = (column, extra) => ({
|
|
4886
|
+
...getMVT_ColumnWidthStyles({
|
|
4887
|
+
columnId: column.id,
|
|
4888
|
+
grow: column.columnDef.grow,
|
|
4889
|
+
layoutMode,
|
|
4890
|
+
minSize: column.columnDef.minSize
|
|
4891
|
+
}),
|
|
4892
|
+
...extra
|
|
4893
|
+
});
|
|
4894
|
+
const auxRow = (key, depth, children) => (0, vue.h)(_mantine_vue_core.TableTr, {
|
|
4895
|
+
class: (0, clsx.default)(MVT_ServerGrouping_module_default["aux-row"], layoutMode?.startsWith("grid") && MVT_ServerGrouping_module_default["row-grid"]),
|
|
4896
|
+
key
|
|
4897
|
+
}, () => (0, vue.h)(_mantine_vue_core.TableTd, {
|
|
4898
|
+
class: MVT_ServerGrouping_module_default["aux-cell"],
|
|
4899
|
+
colspan: colSpan,
|
|
4900
|
+
style: {
|
|
4901
|
+
...indentStyle(depth),
|
|
4902
|
+
...layoutMode?.startsWith("grid") ? {
|
|
4903
|
+
flex: "1 0 auto",
|
|
4904
|
+
width: "100%"
|
|
4905
|
+
} : {}
|
|
4906
|
+
}
|
|
4907
|
+
}, () => children));
|
|
4908
|
+
const loadingContent = (pathId, depth) => mvtSlots.serverGroupLoading?.({
|
|
4909
|
+
depth,
|
|
4910
|
+
pathId,
|
|
4911
|
+
table
|
|
4912
|
+
}) ?? parseFromValuesOrFunc(sgOptions.renderGroupLoading, {
|
|
4913
|
+
depth,
|
|
4914
|
+
pathId,
|
|
4915
|
+
table
|
|
4916
|
+
}) ?? (0, vue.h)(_mantine_vue_core.Group, { gap: "xs" }, () => [(0, vue.h)(_mantine_vue_core.Loader, { size: "xs" }), (0, vue.h)(_mantine_vue_core.Text, {
|
|
4917
|
+
c: "dimmed",
|
|
4918
|
+
size: "sm"
|
|
4919
|
+
}, () => localization.loading ?? "Loading…")]);
|
|
4920
|
+
const errorContent = (pathId, error, retry) => mvtSlots.serverGroupError?.({
|
|
4921
|
+
error,
|
|
4922
|
+
pathId,
|
|
4923
|
+
retry,
|
|
4924
|
+
table
|
|
4925
|
+
}) ?? parseFromValuesOrFunc(sgOptions.renderGroupError, {
|
|
4926
|
+
error,
|
|
4927
|
+
pathId,
|
|
4928
|
+
retry,
|
|
4929
|
+
table
|
|
4930
|
+
}) ?? (0, vue.h)(_mantine_vue_core.Alert, {
|
|
4931
|
+
color: "red",
|
|
4932
|
+
role: "alert",
|
|
4933
|
+
variant: "light"
|
|
4934
|
+
}, () => (0, vue.h)(_mantine_vue_core.Group, { gap: "sm" }, () => [(0, vue.h)(_mantine_vue_core.Text, { size: "sm" }, () => localization.errorLoadingData ?? (error instanceof Error && error.message) ?? "Error loading data"), (0, vue.h)(_mantine_vue_core.Button, {
|
|
4935
|
+
color: "red",
|
|
4936
|
+
onClick: retry,
|
|
4937
|
+
size: "compact-xs",
|
|
4938
|
+
variant: "outline"
|
|
4939
|
+
}, () => localization.retry ?? "Retry")]));
|
|
4940
|
+
const emptyContent = (pathId, field) => {
|
|
4941
|
+
const parentGroup = manager.getParentItems(pathId).at(-1);
|
|
4942
|
+
return mvtSlots.serverGroupEmpty?.({
|
|
4943
|
+
field,
|
|
4944
|
+
parentGroup,
|
|
4945
|
+
pathId,
|
|
4946
|
+
table
|
|
4947
|
+
}) ?? parseFromValuesOrFunc(sgOptions.renderGroupEmpty, {
|
|
4948
|
+
field,
|
|
4949
|
+
parentGroup,
|
|
4950
|
+
pathId,
|
|
4951
|
+
table
|
|
4952
|
+
}) ?? (0, vue.h)(_mantine_vue_core.Text, {
|
|
4953
|
+
c: "dimmed",
|
|
4954
|
+
size: "sm"
|
|
4955
|
+
}, () => localization.noRecordsToDisplay ?? "No records to display");
|
|
4956
|
+
};
|
|
4957
|
+
const paginationRow = (pathId, depth, state) => {
|
|
4958
|
+
const isRoot = pathId === MVT_SERVER_GROUPING_ROOT_PATH_ID;
|
|
4959
|
+
const { pageIndex, pageSize } = state.pagination;
|
|
4960
|
+
const totalRowCount = state.rowCount;
|
|
4961
|
+
if (!(paginationOptions.enabled && (state.kind === "groups" ? paginationOptions.showForGroups : paginationOptions.showForRecords) && (!isRoot || paginationOptions.showAtRoot) && (totalRowCount > pageSize || pageIndex > 0))) return null;
|
|
4962
|
+
const firstRowIndex = pageIndex * pageSize;
|
|
4963
|
+
const lastRowIndex = Math.min(firstRowIndex + pageSize, totalRowCount);
|
|
4964
|
+
const setPageIndex = (nextPageIndex) => manager.setPagination(pathId, { pageIndex: nextPageIndex });
|
|
4965
|
+
return auxRow(`${pathId}:pagination`, depth, (0, vue.h)(_mantine_vue_core.Group, {
|
|
4966
|
+
class: MVT_ServerGrouping_module_default.pagination,
|
|
4967
|
+
gap: "xs",
|
|
4968
|
+
wrap: "nowrap"
|
|
4969
|
+
}, () => [
|
|
4970
|
+
(0, vue.h)(_mantine_vue_core.Text, {
|
|
4971
|
+
c: "dimmed",
|
|
4972
|
+
size: "sm"
|
|
4973
|
+
}, () => `${totalRowCount === 0 ? 0 : (firstRowIndex + 1).toLocaleString()}-${lastRowIndex.toLocaleString()} ${localization.of} ${totalRowCount.toLocaleString()}`),
|
|
4974
|
+
(0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
4975
|
+
color: "gray",
|
|
4976
|
+
size: "sm",
|
|
4977
|
+
variant: "subtle",
|
|
4978
|
+
...paginationOptions.mantineActionIconProps,
|
|
4979
|
+
"aria-label": localization.goToPreviousPage,
|
|
4980
|
+
disabled: pageIndex <= 0 || state.isFetching,
|
|
4981
|
+
onClick: () => setPageIndex(pageIndex - 1)
|
|
4982
|
+
}, () => (0, vue.h)(icons.IconChevronLeft)),
|
|
4983
|
+
(0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
4984
|
+
color: "gray",
|
|
4985
|
+
size: "sm",
|
|
4986
|
+
variant: "subtle",
|
|
4987
|
+
...paginationOptions.mantineActionIconProps,
|
|
4988
|
+
"aria-label": localization.goToNextPage,
|
|
4989
|
+
disabled: lastRowIndex >= totalRowCount || state.isFetching,
|
|
4990
|
+
onClick: () => setPageIndex(pageIndex + 1)
|
|
4991
|
+
}, () => (0, vue.h)(icons.IconChevronRight))
|
|
4992
|
+
]));
|
|
4993
|
+
};
|
|
4994
|
+
const groupRow = (node, parentPathId, field, depth) => {
|
|
4995
|
+
const pathId = createServerGroupPathId(parentPathId, field, node.id);
|
|
4996
|
+
const expanded = manager.isExpanded(pathId);
|
|
4997
|
+
const childState = manager.getPathState(pathId);
|
|
4998
|
+
const context = {
|
|
4999
|
+
depth,
|
|
5000
|
+
field,
|
|
5001
|
+
group: node,
|
|
5002
|
+
isExpanded: expanded,
|
|
5003
|
+
parentGroups: manager.getParentItems(pathId).slice(0, -1),
|
|
5004
|
+
pathId,
|
|
5005
|
+
table
|
|
5006
|
+
};
|
|
5007
|
+
const hasChildren = node.hasChildren !== false;
|
|
5008
|
+
const rowProps = parseFromValuesOrFunc(sgOptions.mantineGroupRowProps, context) ?? {};
|
|
5009
|
+
const label = mvtSlots.serverGroupLabel?.(context) ?? parseFromValuesOrFunc(sgOptions.renderGroupLabel, context) ?? node.label;
|
|
5010
|
+
const count = mvtSlots.serverGroupCount?.(context) ?? parseFromValuesOrFunc(sgOptions.renderGroupCount, context) ?? (node.count !== void 0 ? `(${node.count.toLocaleString()})` : null);
|
|
5011
|
+
const labelColumn = visibleColumns.find((column) => column.columnDef.columnDefType !== "display");
|
|
5012
|
+
const labelCell = (column) => (0, vue.h)(_mantine_vue_core.TableTd, {
|
|
5013
|
+
class: MVT_ServerGrouping_module_default["group-cell"],
|
|
5014
|
+
key: column?.id ?? "mvt-server-group-label",
|
|
5015
|
+
style: column ? columnStyle(column, indentStyle(depth)) : indentStyle(depth)
|
|
5016
|
+
}, () => (0, vue.h)(_mantine_vue_core.Group, {
|
|
5017
|
+
gap: "xs",
|
|
5018
|
+
wrap: "nowrap"
|
|
5019
|
+
}, () => [
|
|
5020
|
+
hasChildren ? (0, vue.h)(_mantine_vue_core.ActionIcon, {
|
|
5021
|
+
"aria-expanded": String(expanded),
|
|
5022
|
+
"aria-label": `${expanded ? localization.collapse : localization.expand} ${node.label}`,
|
|
5023
|
+
color: "gray",
|
|
5024
|
+
onClick: () => manager.toggle(pathId),
|
|
5025
|
+
size: "sm",
|
|
5026
|
+
variant: "subtle"
|
|
5027
|
+
}, () => (0, vue.h)(expanded ? icons.IconChevronDown : icons.IconChevronRight)) : (0, vue.h)("span", { class: MVT_ServerGrouping_module_default["expand-spacer"] }),
|
|
5028
|
+
(0, vue.h)(_mantine_vue_core.Text, {
|
|
5029
|
+
fw: 600,
|
|
5030
|
+
size: "sm"
|
|
5031
|
+
}, () => [label]),
|
|
5032
|
+
count !== null && (0, vue.h)(_mantine_vue_core.Text, {
|
|
5033
|
+
c: "dimmed",
|
|
5034
|
+
size: "sm"
|
|
5035
|
+
}, () => [count]),
|
|
5036
|
+
expanded && childState?.isFetching && !childState.isLoading && (0, vue.h)(_mantine_vue_core.Loader, { size: "xs" })
|
|
5037
|
+
]));
|
|
5038
|
+
const aggregateCell = (column) => {
|
|
5039
|
+
const columnServerGrouping = column.columnDef.serverGrouping;
|
|
5040
|
+
let content = null;
|
|
5041
|
+
if (columnServerGrouping?.visible !== false && columnServerGrouping?.getValue) {
|
|
5042
|
+
const value = columnServerGrouping.getValue({
|
|
5043
|
+
...context,
|
|
5044
|
+
column
|
|
5045
|
+
});
|
|
5046
|
+
const cellContext = {
|
|
5047
|
+
...context,
|
|
5048
|
+
column,
|
|
5049
|
+
value
|
|
5050
|
+
};
|
|
5051
|
+
content = mvtSlots.serverGroupCell?.(cellContext) ?? (columnServerGrouping.Cell ? flexRender(columnServerGrouping.Cell, cellContext) : value ?? null);
|
|
5052
|
+
} else if (mvtSlots.serverGroupCell) content = mvtSlots.serverGroupCell({
|
|
5053
|
+
...context,
|
|
5054
|
+
column,
|
|
5055
|
+
value: void 0
|
|
5056
|
+
});
|
|
5057
|
+
return (0, vue.h)(_mantine_vue_core.TableTd, {
|
|
5058
|
+
class: MVT_ServerGrouping_module_default["aggregate-cell"],
|
|
5059
|
+
key: column.id,
|
|
5060
|
+
style: columnStyle(column)
|
|
5061
|
+
}, () => [content]);
|
|
5062
|
+
};
|
|
5063
|
+
const spacerCell = (column) => (0, vue.h)(_mantine_vue_core.TableTd, {
|
|
5064
|
+
key: column.id,
|
|
5065
|
+
style: columnStyle(column)
|
|
5066
|
+
}, () => null);
|
|
5067
|
+
const cells = visibleColumns.length ? visibleColumns.map((column) => column.id === labelColumn?.id ? labelCell(column) : column.columnDef.columnDefType === "display" ? spacerCell(column) : aggregateCell(column)) : [labelCell()];
|
|
5068
|
+
const rows = [(0, vue.h)(_mantine_vue_core.TableTr, {
|
|
5069
|
+
"aria-expanded": hasChildren ? String(expanded) : void 0,
|
|
5070
|
+
"aria-level": depth + 1,
|
|
5071
|
+
"data-depth": depth,
|
|
5072
|
+
"data-expanded": expanded || void 0,
|
|
5073
|
+
key: pathId,
|
|
5074
|
+
...rowProps,
|
|
5075
|
+
class: (0, clsx.default)(MVT_ServerGrouping_module_default["group-row"], layoutMode?.startsWith("grid") && MVT_ServerGrouping_module_default["row-grid"], rowProps?.class)
|
|
5076
|
+
}, () => cells)];
|
|
5077
|
+
if (expanded) rows.push(...levelRows(pathId, depth + 1));
|
|
5078
|
+
return rows;
|
|
5079
|
+
};
|
|
5080
|
+
const recordRows = (pathId) => {
|
|
5081
|
+
const rows = manager.getRecordRows(pathId);
|
|
5082
|
+
return rows.map((row, index) => (0, vue.h)(MVT_TableBodyRow, {
|
|
5083
|
+
key: row.id,
|
|
5084
|
+
numRows: rows.length,
|
|
5085
|
+
renderedRowIndex: index,
|
|
5086
|
+
row,
|
|
5087
|
+
table,
|
|
5088
|
+
tableProps
|
|
5089
|
+
}));
|
|
5090
|
+
};
|
|
5091
|
+
const levelRows = (pathId, depth) => {
|
|
5092
|
+
const state = manager.getPathState(pathId);
|
|
5093
|
+
const field = manager.getGroupingFields()[getServerGroupPathDepth(pathId)];
|
|
5094
|
+
if (!state || state.isLoading) return [auxRow(`${pathId}:loading`, depth, loadingContent(pathId, depth))];
|
|
5095
|
+
if (state.error != null) return [auxRow(`${pathId}:error`, depth, errorContent(pathId, state.error, () => manager.retry(pathId)))];
|
|
5096
|
+
const out = [];
|
|
5097
|
+
if (state.kind === "groups") {
|
|
5098
|
+
const groups = state.groups ?? [];
|
|
5099
|
+
if (!groups.length) out.push(auxRow(`${pathId}:empty`, depth, emptyContent(pathId, field)));
|
|
5100
|
+
else groups.forEach((node) => out.push(...groupRow(node, pathId, field, depth)));
|
|
5101
|
+
} else if (!(state.rows ?? []).length) out.push(auxRow(`${pathId}:empty`, depth, emptyContent(pathId, field)));
|
|
5102
|
+
else out.push(...recordRows(pathId));
|
|
5103
|
+
const pagination = paginationRow(pathId, depth, state);
|
|
5104
|
+
if (pagination) out.push(pagination);
|
|
5105
|
+
return out;
|
|
5106
|
+
};
|
|
5107
|
+
return (0, vue.h)(vue.Fragment, null, levelRows(MVT_SERVER_GROUPING_ROOT_PATH_ID, 0));
|
|
5108
|
+
};
|
|
5109
|
+
}
|
|
5110
|
+
});
|
|
3609
5111
|
var MVT_TableBody_module_default = {
|
|
3610
5112
|
root: "_root_17rwk_1",
|
|
3611
5113
|
"root-grid": "_root-grid_17rwk_6",
|
|
@@ -3735,7 +5237,10 @@ var MVT_TableBody = (0, vue.defineComponent)({
|
|
|
3735
5237
|
...tableBodyProps?.style
|
|
3736
5238
|
},
|
|
3737
5239
|
class: (0, clsx.default)(MVT_TableBody_module_default.root, layoutMode?.startsWith("grid") && MVT_TableBody_module_default["root-grid"], !currentRows.length && MVT_TableBody_module_default["root-no-rows"], rowVirtualizer && MVT_TableBody_module_default["root-virtualized"], tableBodyProps?.class)
|
|
3738
|
-
}, () => tableBodyProps?.children ?? (
|
|
5240
|
+
}, () => tableBodyProps?.children ?? (table._serverGrouping ? (0, vue.h)(MVT_ServerGroupingBody, {
|
|
5241
|
+
table,
|
|
5242
|
+
tableProps
|
|
5243
|
+
}) : null) ?? (!currentRows.length ? (0, vue.h)(MVT_TableBodyEmptyRow, commonRowProps) : (virtualRows ?? currentRows).map((rowOrVirtualRow, renderedRowIndex) => {
|
|
3739
5244
|
let index = renderedRowIndex;
|
|
3740
5245
|
if (rowVirtualizer) if (renderDetailPanel) {
|
|
3741
5246
|
if (rowOrVirtualRow.index % 2 === 1) return null;
|
|
@@ -4003,6 +5508,7 @@ var MVT_ColumnActionMenu = (0, vue.defineComponent)({
|
|
|
4003
5508
|
leftSection: (0, vue.h)(icon, { class: iconClass }),
|
|
4004
5509
|
onClick
|
|
4005
5510
|
}, () => label);
|
|
5511
|
+
const serverGroupBy = getServerGroupingColumnActions(table, column.id);
|
|
4006
5512
|
const internal = [];
|
|
4007
5513
|
if (o.enableSorting && column.getCanSort()) {
|
|
4008
5514
|
if (o.enableSortingRemoval !== false) internal.push(item(l.clearSort, icons.IconClearAll, () => column.clearSorting(), !column.getIsSorted()));
|
|
@@ -4024,6 +5530,11 @@ var MVT_ColumnActionMenu = (0, vue.defineComponent)({
|
|
|
4024
5530
|
table.setColumnOrder((old) => ["mvt-row-expand", ...old]);
|
|
4025
5531
|
}));
|
|
4026
5532
|
if (o.enableColumnPinning) internal.push((0, vue.h)(_mantine_vue_core.Menu.Divider));
|
|
5533
|
+
} else if (serverGroupBy) {
|
|
5534
|
+
const { addGroup, grouping, removeGroup } = serverGroupBy;
|
|
5535
|
+
const isGrouped = grouping.includes(column.id);
|
|
5536
|
+
internal.push(isGrouped ? item(l.clearGrouping ?? "Clear grouping", icons.IconClearAll, () => removeGroup(column.id)) : item(l.groupByColumn.replace("{column}", String(def.header)), icons.IconBoxMultiple, () => addGroup(column.id)));
|
|
5537
|
+
if (o.enableColumnPinning) internal.push((0, vue.h)(_mantine_vue_core.Menu.Divider));
|
|
4027
5538
|
}
|
|
4028
5539
|
if (o.enableColumnPinning && column.getCanPin()) {
|
|
4029
5540
|
internal.push(item(l.pinToLeft, icons.IconPinned, () => column.pin("left"), column.getIsPinned() === "left", MVT_ColumnActionMenu_module_default.left));
|
|
@@ -4054,7 +5565,7 @@ var MVT_ColumnActionMenu = (0, vue.defineComponent)({
|
|
|
4054
5565
|
withinPortal: true,
|
|
4055
5566
|
...attrs,
|
|
4056
5567
|
opened: props.opened,
|
|
4057
|
-
|
|
5568
|
+
"onUpdate:opened": props.onChange
|
|
4058
5569
|
}, () => [(0, vue.h)(_mantine_vue_core.Tooltip, {
|
|
4059
5570
|
label: actionProps.title ?? l.columnActions,
|
|
4060
5571
|
openDelay: 1e3,
|
|
@@ -4426,7 +5937,7 @@ var MVT_FilterRangeSlider = (0, vue.defineComponent)({
|
|
|
4426
5937
|
class: (0, clsx.default)("mvt-filter-range-slider", MVT_FilterRangeSlider_module_default.root, rangeProps.class),
|
|
4427
5938
|
min,
|
|
4428
5939
|
max,
|
|
4429
|
-
|
|
5940
|
+
modelValue: values.value,
|
|
4430
5941
|
...rangeProps,
|
|
4431
5942
|
onChange: (value) => {
|
|
4432
5943
|
values.value = value;
|
|
@@ -5248,6 +6759,44 @@ var MantineVueTable = (0, vue.defineComponent)({
|
|
|
5248
6759
|
}
|
|
5249
6760
|
});
|
|
5250
6761
|
//#endregion
|
|
6762
|
+
//#region src/server-grouping/createServerGroupingProvider.ts
|
|
6763
|
+
var asString = (value) => value === null || value === void 0 ? "" : String(value);
|
|
6764
|
+
/**
|
|
6765
|
+
* Build a {@link MVT_ServerGroupingProvider} with sensible defaults for common
|
|
6766
|
+
* response formats:
|
|
6767
|
+
*
|
|
6768
|
+
* - `groups`/`records` default to the response itself when it is an array.
|
|
6769
|
+
* - `groupRowCount`/`recordRowCount` default to the mapped array length.
|
|
6770
|
+
* - `groupId`/`groupLabel` default to stringifying `groupValue` (or the group
|
|
6771
|
+
* itself when it is a primitive).
|
|
6772
|
+
* - `groupValue` defaults to the group object itself.
|
|
6773
|
+
* - `groupMeta` defaults to `{}`; `groupCount` and aggregates stay optional.
|
|
6774
|
+
* - `hasChildren` defaults to `true` (every level up to and including the last
|
|
6775
|
+
* grouping level is expandable).
|
|
6776
|
+
* - `rowId` falls back to the table's existing `getRowId` logic.
|
|
6777
|
+
*/
|
|
6778
|
+
var createServerGroupingProvider = (options) => {
|
|
6779
|
+
const getGroups = options.getGroups ?? options.groups ?? ((response) => Array.isArray(response) ? response : []);
|
|
6780
|
+
const getRecords = options.getRecords ?? options.records ?? ((response) => Array.isArray(response) ? response : []);
|
|
6781
|
+
const getGroupValue = options.getGroupValue ?? options.groupValue ?? ((group) => group);
|
|
6782
|
+
return {
|
|
6783
|
+
getGroupId: options.getGroupId ?? options.groupId ?? ((group, context) => asString(getGroupValue(group, context))),
|
|
6784
|
+
getGroupLabel: options.getGroupLabel ?? options.groupLabel ?? ((group, context) => asString(getGroupValue(group, context))),
|
|
6785
|
+
getGroupValue,
|
|
6786
|
+
getGroupCount: options.getGroupCount ?? options.groupCount,
|
|
6787
|
+
getGroupMeta: options.getGroupMeta ?? options.groupMeta ?? (() => ({})),
|
|
6788
|
+
hasGroupChildren: options.hasGroupChildren ?? options.hasChildren,
|
|
6789
|
+
loadGroups: options.loadGroups,
|
|
6790
|
+
getGroups,
|
|
6791
|
+
getGroupRowCount: options.getGroupRowCount ?? options.groupRowCount ?? ((response) => getGroups(response).length),
|
|
6792
|
+
loadRecords: options.loadRecords,
|
|
6793
|
+
getRecords,
|
|
6794
|
+
getRecordRowCount: options.getRecordRowCount ?? options.recordRowCount ?? ((response) => getRecords(response).length),
|
|
6795
|
+
getRowId: options.getRowId ?? options.rowId,
|
|
6796
|
+
getCacheKey: options.getCacheKey ?? options.cacheKey
|
|
6797
|
+
};
|
|
6798
|
+
};
|
|
6799
|
+
//#endregion
|
|
5251
6800
|
exports.MVT_AggregationFns = MVT_AggregationFns;
|
|
5252
6801
|
exports.MVT_BottomToolbar = MVT_BottomToolbar;
|
|
5253
6802
|
exports.MVT_ColumnActionMenu = MVT_ColumnActionMenu;
|
|
@@ -5272,7 +6821,10 @@ exports.MVT_GrabHandleButton = MVT_GrabHandleButton;
|
|
|
5272
6821
|
exports.MVT_ProgressBar = MVT_ProgressBar;
|
|
5273
6822
|
exports.MVT_RowActionMenu = MVT_RowActionMenu;
|
|
5274
6823
|
exports.MVT_RowPinButton = MVT_RowPinButton;
|
|
6824
|
+
exports.MVT_SERVER_GROUPING_ROOT_PATH_ID = MVT_SERVER_GROUPING_ROOT_PATH_ID;
|
|
5275
6825
|
exports.MVT_SelectCheckbox = MVT_SelectCheckbox;
|
|
6826
|
+
exports.MVT_ServerGroupingBody = MVT_ServerGroupingBody;
|
|
6827
|
+
exports.MVT_ServerGroupingGroupBy = MVT_ServerGroupingGroupBy;
|
|
5276
6828
|
exports.MVT_ShowHideColumnsButton = MVT_ShowHideColumnsButton;
|
|
5277
6829
|
exports.MVT_ShowHideColumnsMenu = MVT_ShowHideColumnsMenu;
|
|
5278
6830
|
exports.MVT_ShowHideColumnsMenuItems = MVT_ShowHideColumnsMenuItems;
|
|
@@ -5314,9 +6866,14 @@ exports.Memo_MVT_TableBody = Memo_MVT_TableBody;
|
|
|
5314
6866
|
exports.Memo_MVT_TableBodyCell = Memo_MVT_TableBodyCell;
|
|
5315
6867
|
exports.Memo_MVT_TableBodyRow = Memo_MVT_TableBodyRow;
|
|
5316
6868
|
exports.createMVTColumnHelper = createMVTColumnHelper;
|
|
6869
|
+
exports.createMVT_ServerGroupingManager = createMVT_ServerGroupingManager;
|
|
5317
6870
|
exports.createRow = createRow;
|
|
6871
|
+
exports.createServerGroupPathId = createServerGroupPathId;
|
|
6872
|
+
exports.createServerGroupingProvider = createServerGroupingProvider;
|
|
5318
6873
|
exports.dataVariable = dataVariable;
|
|
5319
6874
|
exports.defaultDisplayColumnProps = defaultDisplayColumnProps;
|
|
6875
|
+
exports.deselectServerGroupingRecords = deselectServerGroupingRecords;
|
|
6876
|
+
exports.escapeServerGroupPathPart = escapeServerGroupPathPart;
|
|
5320
6877
|
exports.flexRender = flexRender;
|
|
5321
6878
|
exports.getAllLeafColumnDefs = getAllLeafColumnDefs;
|
|
5322
6879
|
exports.getCanRankRows = getCanRankRows;
|
|
@@ -5326,21 +6883,36 @@ exports.getDefaultColumnOrderIds = getDefaultColumnOrderIds;
|
|
|
5326
6883
|
exports.getIsRankingRows = getIsRankingRows;
|
|
5327
6884
|
exports.getIsRowSelected = getIsRowSelected;
|
|
5328
6885
|
exports.getLeadingDisplayColumnIds = getLeadingDisplayColumnIds;
|
|
6886
|
+
exports.getMVT_ColumnWidthStyles = getMVT_ColumnWidthStyles;
|
|
5329
6887
|
exports.getMVT_RowSelectionHandler = getMVT_RowSelectionHandler;
|
|
5330
6888
|
exports.getMVT_Rows = getMVT_Rows;
|
|
5331
6889
|
exports.getMVT_SelectAllHandler = getMVT_SelectAllHandler;
|
|
5332
6890
|
exports.getPrimaryColor = getPrimaryColor;
|
|
5333
6891
|
exports.getPrimaryShade = getPrimaryShade;
|
|
6892
|
+
exports.getServerGroupPathDepth = getServerGroupPathDepth;
|
|
6893
|
+
exports.getServerGroupableColumns = getServerGroupableColumns;
|
|
6894
|
+
exports.getServerGroupingColumnActions = getServerGroupingColumnActions;
|
|
6895
|
+
exports.getServerGroupingGroupByContext = getServerGroupingGroupByContext;
|
|
6896
|
+
exports.getServerGroupingManager = getServerGroupingManager;
|
|
6897
|
+
exports.getServerGroupingSelectableRows = getServerGroupingSelectableRows;
|
|
6898
|
+
exports.getServerGroupingSelectionPayload = getServerGroupingSelectionPayload;
|
|
6899
|
+
exports.getServerGroupingSelectionSummary = getServerGroupingSelectionSummary;
|
|
5334
6900
|
exports.getTrailingDisplayColumnIds = getTrailingDisplayColumnIds;
|
|
6901
|
+
exports.isAbortError = isAbortError;
|
|
6902
|
+
exports.isServerGroupPathOrDescendant = isServerGroupPathOrDescendant;
|
|
6903
|
+
exports.isServerGroupingRecordSelected = isServerGroupingRecordSelected;
|
|
5335
6904
|
exports.localizedFilterOption = localizedFilterOption;
|
|
5336
6905
|
exports.mrtFilterOptions = mrtFilterOptions;
|
|
5337
6906
|
exports.parseCSSVarId = parseCSSVarId;
|
|
5338
6907
|
exports.parseFromValuesOrFunc = parseFromValuesOrFunc;
|
|
6908
|
+
exports.parseServerGroupPathId = parseServerGroupPathId;
|
|
5339
6909
|
exports.prepareColumns = prepareColumns;
|
|
5340
6910
|
exports.provideMVT_Slots = provideMVT_Slots;
|
|
5341
6911
|
exports.rankGlobalFuzzy = rankGlobalFuzzy;
|
|
5342
6912
|
exports.renderMVT_Renderable = renderMVT_Renderable;
|
|
5343
6913
|
exports.reorderColumn = reorderColumn;
|
|
6914
|
+
exports.selectAllMatchingServerGroupingRecords = selectAllMatchingServerGroupingRecords;
|
|
6915
|
+
exports.serializeServerGroupingCacheKey = serializeServerGroupingCacheKey;
|
|
5344
6916
|
exports.showRowActionsColumn = showRowActionsColumn;
|
|
5345
6917
|
exports.showRowDragColumn = showRowDragColumn;
|
|
5346
6918
|
exports.showRowExpandColumn = showRowExpandColumn;
|
|
@@ -5348,6 +6920,9 @@ exports.showRowNumbersColumn = showRowNumbersColumn;
|
|
|
5348
6920
|
exports.showRowPinningColumn = showRowPinningColumn;
|
|
5349
6921
|
exports.showRowSelectionColumn = showRowSelectionColumn;
|
|
5350
6922
|
exports.showRowSpacerColumn = showRowSpacerColumn;
|
|
6923
|
+
exports.toggleAllServerGroupingRecordsSelected = toggleAllServerGroupingRecordsSelected;
|
|
6924
|
+
exports.toggleServerGroupingRecordSelected = toggleServerGroupingRecordSelected;
|
|
6925
|
+
exports.unescapeServerGroupPathPart = unescapeServerGroupPathPart;
|
|
5351
6926
|
exports.useMVT_ColumnVirtualizer = useMVT_ColumnVirtualizer;
|
|
5352
6927
|
exports.useMVT_Effects = useMVT_Effects;
|
|
5353
6928
|
exports.useMVT_RowVirtualizer = useMVT_RowVirtualizer;
|