@hexclave/dashboard-ui-components 1.0.29 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/button.d.ts +2 -2
- package/dist/components/chart-legend.d.ts +1 -1
- package/dist/components/data-grid/data-grid-export-dialog.d.ts +23 -0
- package/dist/components/data-grid/data-grid-export-dialog.d.ts.map +1 -0
- package/dist/components/data-grid/data-grid-export-dialog.js +406 -0
- package/dist/components/data-grid/data-grid-export-dialog.js.map +1 -0
- package/dist/components/data-grid/data-grid.d.ts.map +1 -1
- package/dist/components/data-grid/data-grid.js +14 -14
- package/dist/components/data-grid/data-grid.js.map +1 -1
- package/dist/components/data-grid/index.d.ts +2 -2
- package/dist/components/data-grid/types.d.ts +31 -2
- package/dist/components/data-grid/types.d.ts.map +1 -1
- package/dist/dashboard-ui-components.global.js +904 -535
- package/dist/dashboard-ui-components.global.js.map +4 -4
- package/dist/esm/components/button.d.ts +2 -2
- package/dist/esm/components/chart-legend.d.ts +1 -1
- package/dist/esm/components/data-grid/data-grid-export-dialog.d.ts +23 -0
- package/dist/esm/components/data-grid/data-grid-export-dialog.d.ts.map +1 -0
- package/dist/esm/components/data-grid/data-grid-export-dialog.js +403 -0
- package/dist/esm/components/data-grid/data-grid-export-dialog.js.map +1 -0
- package/dist/esm/components/data-grid/data-grid.d.ts.map +1 -1
- package/dist/esm/components/data-grid/data-grid.js +16 -16
- package/dist/esm/components/data-grid/data-grid.js.map +1 -1
- package/dist/esm/components/data-grid/index.d.ts +2 -2
- package/dist/esm/components/data-grid/types.d.ts +31 -2
- package/dist/esm/components/data-grid/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/package.json +3 -3
- package/src/components/data-grid/data-grid-export-dialog.tsx +479 -0
- package/src/components/data-grid/data-grid.tsx +192 -193
- package/src/components/data-grid/index.ts +5 -0
- package/src/components/data-grid/types.ts +35 -0
|
@@ -163,7 +163,7 @@ var DashboardUI = (() => {
|
|
|
163
163
|
var snakeCase2 = (str) => join2(str, "_");
|
|
164
164
|
var kebabCase = (str) => join2(str, "-");
|
|
165
165
|
var sentenceCase = (str) => upperFirst(join2(str, " "));
|
|
166
|
-
var
|
|
166
|
+
var titleCase2 = (str) => words(str).map(upperFirst).join(" ");
|
|
167
167
|
module.exports = {
|
|
168
168
|
words,
|
|
169
169
|
upperFirst,
|
|
@@ -172,7 +172,7 @@ var DashboardUI = (() => {
|
|
|
172
172
|
snakeCase: snakeCase2,
|
|
173
173
|
kebabCase,
|
|
174
174
|
sentenceCase,
|
|
175
|
-
titleCase
|
|
175
|
+
titleCase: titleCase2
|
|
176
176
|
};
|
|
177
177
|
}
|
|
178
178
|
});
|
|
@@ -22120,7 +22120,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
22120
22120
|
}
|
|
22121
22121
|
|
|
22122
22122
|
// src/components/data-grid/data-grid.tsx
|
|
22123
|
-
var
|
|
22123
|
+
var import_react35 = __toESM(require_react());
|
|
22124
22124
|
|
|
22125
22125
|
// src/components/data-grid/data-grid-sizing.ts
|
|
22126
22126
|
var MIN_COL_WIDTH = 20;
|
|
@@ -22162,12 +22162,520 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
22162
22162
|
return Math.max(getEffectiveMinWidth(col), Math.min(getEffectiveMaxWidth(col), width));
|
|
22163
22163
|
}
|
|
22164
22164
|
|
|
22165
|
-
// src/components/data-grid/data-grid-
|
|
22165
|
+
// src/components/data-grid/data-grid-export-dialog.tsx
|
|
22166
22166
|
var import_react31 = __toESM(require_react());
|
|
22167
|
+
|
|
22168
|
+
// src/components/data-grid/state.ts
|
|
22169
|
+
function createDefaultDataGridState(columns) {
|
|
22170
|
+
const columnWidths = {};
|
|
22171
|
+
const columnOrder = [];
|
|
22172
|
+
for (const col of columns) {
|
|
22173
|
+
columnWidths[col.id] = clampColumnWidth(col, col.width ?? DEFAULT_COL_WIDTH);
|
|
22174
|
+
columnOrder.push(col.id);
|
|
22175
|
+
}
|
|
22176
|
+
return {
|
|
22177
|
+
sorting: [],
|
|
22178
|
+
columnVisibility: {},
|
|
22179
|
+
columnWidths,
|
|
22180
|
+
columnPinning: { left: [], right: [] },
|
|
22181
|
+
columnOrder,
|
|
22182
|
+
pagination: { pageIndex: 0, pageSize: 50 },
|
|
22183
|
+
selection: { selectedIds: /* @__PURE__ */ new Set(), anchorId: null },
|
|
22184
|
+
dateDisplay: "relative",
|
|
22185
|
+
quickSearch: ""
|
|
22186
|
+
};
|
|
22187
|
+
}
|
|
22188
|
+
function resolveColumnValue(col, row) {
|
|
22189
|
+
if (typeof col.accessor === "function") return col.accessor(row);
|
|
22190
|
+
const key = col.accessor ?? col.id;
|
|
22191
|
+
return row[key];
|
|
22192
|
+
}
|
|
22193
|
+
function defaultComparator(a26, b) {
|
|
22194
|
+
if (a26 == null && b == null) return 0;
|
|
22195
|
+
if (a26 == null) return -1;
|
|
22196
|
+
if (b == null) return 1;
|
|
22197
|
+
if (typeof a26 === "number" && typeof b === "number") return a26 - b;
|
|
22198
|
+
if (a26 instanceof Date && b instanceof Date) return a26.getTime() - b.getTime();
|
|
22199
|
+
return stringCompare(String(a26), String(b));
|
|
22200
|
+
}
|
|
22201
|
+
function buildRowComparator(sortModel, columns) {
|
|
22202
|
+
if (sortModel.length === 0) return null;
|
|
22203
|
+
const colMap = new Map(columns.map((c4) => [c4.id, c4]));
|
|
22204
|
+
return (a26, b) => {
|
|
22205
|
+
for (const { columnId, direction } of sortModel) {
|
|
22206
|
+
const col = colMap.get(columnId);
|
|
22207
|
+
if (!col) continue;
|
|
22208
|
+
const va = resolveColumnValue(col, a26);
|
|
22209
|
+
const vb = resolveColumnValue(col, b);
|
|
22210
|
+
const cmp = col.sortComparator ? col.sortComparator(va, vb) : defaultComparator(va, vb);
|
|
22211
|
+
if (cmp !== 0) return direction === "asc" ? cmp : -cmp;
|
|
22212
|
+
}
|
|
22213
|
+
return 0;
|
|
22214
|
+
};
|
|
22215
|
+
}
|
|
22216
|
+
function paginateRows(rows, pagination) {
|
|
22217
|
+
const start = pagination.pageIndex * pagination.pageSize;
|
|
22218
|
+
return rows.slice(start, start + pagination.pageSize);
|
|
22219
|
+
}
|
|
22220
|
+
function defaultMatchRow(row, query, columns) {
|
|
22221
|
+
for (const col of columns) {
|
|
22222
|
+
const v = resolveColumnValue(col, row);
|
|
22223
|
+
if (v == null) continue;
|
|
22224
|
+
if (String(v).toLowerCase().includes(query)) return true;
|
|
22225
|
+
}
|
|
22226
|
+
return false;
|
|
22227
|
+
}
|
|
22228
|
+
function applyQuickSearch(rows, query, columns, matchRow = defaultMatchRow) {
|
|
22229
|
+
const trimmed = query.trim().toLowerCase();
|
|
22230
|
+
if (!trimmed) return rows;
|
|
22231
|
+
return rows.filter((r7) => matchRow(r7, trimmed, columns));
|
|
22232
|
+
}
|
|
22233
|
+
function defaultParseDate(value) {
|
|
22234
|
+
if (value == null) return null;
|
|
22235
|
+
if (value instanceof Date) return isNaN(value.getTime()) ? null : value;
|
|
22236
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
22237
|
+
const d = new Date(value);
|
|
22238
|
+
return isNaN(d.getTime()) ? null : d;
|
|
22239
|
+
}
|
|
22240
|
+
return null;
|
|
22241
|
+
}
|
|
22242
|
+
var DIVISIONS = [
|
|
22243
|
+
{ amount: 60, unit: "second" },
|
|
22244
|
+
{ amount: 60, unit: "minute" },
|
|
22245
|
+
{ amount: 24, unit: "hour" },
|
|
22246
|
+
{ amount: 7, unit: "day" },
|
|
22247
|
+
{ amount: 4.34524, unit: "week" },
|
|
22248
|
+
{ amount: 12, unit: "month" },
|
|
22249
|
+
{ amount: Number.POSITIVE_INFINITY, unit: "year" }
|
|
22250
|
+
];
|
|
22251
|
+
var relativeTimeFormatterCache = /* @__PURE__ */ new Map();
|
|
22252
|
+
function getRelativeTimeFormatter(locale2) {
|
|
22253
|
+
const key = locale2 ?? "__default__";
|
|
22254
|
+
let cached = relativeTimeFormatterCache.get(key);
|
|
22255
|
+
if (cached == null) {
|
|
22256
|
+
cached = new Intl.RelativeTimeFormat(locale2, { numeric: "auto" });
|
|
22257
|
+
relativeTimeFormatterCache.set(key, cached);
|
|
22258
|
+
}
|
|
22259
|
+
return cached;
|
|
22260
|
+
}
|
|
22261
|
+
function defaultFormatRelative(date2) {
|
|
22262
|
+
const rtf = getRelativeTimeFormatter();
|
|
22263
|
+
let duration = (date2.getTime() - Date.now()) / 1e3;
|
|
22264
|
+
for (const div of DIVISIONS) {
|
|
22265
|
+
if (Math.abs(duration) < div.amount) return rtf.format(Math.round(duration), div.unit);
|
|
22266
|
+
duration /= div.amount;
|
|
22267
|
+
}
|
|
22268
|
+
return rtf.format(Math.round(duration), "year");
|
|
22269
|
+
}
|
|
22270
|
+
function defaultFormatAbsolute(date2) {
|
|
22271
|
+
return date2.toLocaleString();
|
|
22272
|
+
}
|
|
22273
|
+
function formatGridDate(value, mode, opts) {
|
|
22274
|
+
const parse2 = opts?.parseValue ?? defaultParseDate;
|
|
22275
|
+
const date2 = parse2(value);
|
|
22276
|
+
if (!date2) return { display: null, tooltip: null };
|
|
22277
|
+
const relative = opts?.dateFormat?.relative ?? defaultFormatRelative;
|
|
22278
|
+
const absolute = opts?.dateFormat?.absolute ?? defaultFormatAbsolute;
|
|
22279
|
+
const tooltip = absolute(date2);
|
|
22280
|
+
const display = mode === "relative" ? relative(date2) : tooltip;
|
|
22281
|
+
return { display, tooltip };
|
|
22282
|
+
}
|
|
22283
|
+
function exportToCsv(rows, columns, filename) {
|
|
22284
|
+
const header = columns.map(
|
|
22285
|
+
(col) => typeof col.header === "string" ? col.header : col.id
|
|
22286
|
+
);
|
|
22287
|
+
const csvRows = rows.map(
|
|
22288
|
+
(row) => columns.map((col) => {
|
|
22289
|
+
const val = resolveColumnValue(col, row);
|
|
22290
|
+
const formatted = col.formatValue ? String(col.formatValue(val, row) ?? "") : String(val ?? "");
|
|
22291
|
+
if (formatted.includes(",") || formatted.includes('"') || formatted.includes("\n")) {
|
|
22292
|
+
return `"${formatted.replace(/"/g, '""')}"`;
|
|
22293
|
+
}
|
|
22294
|
+
return formatted;
|
|
22295
|
+
})
|
|
22296
|
+
);
|
|
22297
|
+
const csvContent = "\uFEFF" + [
|
|
22298
|
+
header.join(","),
|
|
22299
|
+
...csvRows.map((row) => row.join(","))
|
|
22300
|
+
].join("\n");
|
|
22301
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
22302
|
+
const url = URL.createObjectURL(blob);
|
|
22303
|
+
const link = document.createElement("a");
|
|
22304
|
+
link.href = url;
|
|
22305
|
+
link.download = `${filename}.csv`;
|
|
22306
|
+
document.body.appendChild(link);
|
|
22307
|
+
try {
|
|
22308
|
+
link.click();
|
|
22309
|
+
} finally {
|
|
22310
|
+
link.remove();
|
|
22311
|
+
URL.revokeObjectURL(url);
|
|
22312
|
+
}
|
|
22313
|
+
}
|
|
22314
|
+
|
|
22315
|
+
// src/components/data-grid/data-grid-export-dialog.tsx
|
|
22316
|
+
var idleExportProgress = {
|
|
22317
|
+
phase: "idle",
|
|
22318
|
+
fetched: 0
|
|
22319
|
+
};
|
|
22320
|
+
var exportCompletionDisplayMs = 800;
|
|
22321
|
+
function DataGridExportDialog({
|
|
22322
|
+
open,
|
|
22323
|
+
onOpenChange,
|
|
22324
|
+
rows,
|
|
22325
|
+
columns,
|
|
22326
|
+
exportFilename,
|
|
22327
|
+
exportOptions
|
|
22328
|
+
}) {
|
|
22329
|
+
const hasServerExport = exportOptions?.fetchRows != null;
|
|
22330
|
+
const resolvedFields = (0, import_react31.useMemo)(
|
|
22331
|
+
() => exportOptions?.fields ?? buildColumnExportFields(columns),
|
|
22332
|
+
[exportOptions?.fields, columns]
|
|
22333
|
+
);
|
|
22334
|
+
const [format, setFormat] = (0, import_react31.useState)("csv");
|
|
22335
|
+
const [scope, setScope] = (0, import_react31.useState)("all");
|
|
22336
|
+
const [fields, setFields] = (0, import_react31.useState)(resolvedFields);
|
|
22337
|
+
const [isExporting, setIsExporting] = (0, import_react31.useState)(false);
|
|
22338
|
+
const [progress, setProgress] = (0, import_react31.useState)(idleExportProgress);
|
|
22339
|
+
const [errorMessage, setErrorMessage] = (0, import_react31.useState)(null);
|
|
22340
|
+
(0, import_react31.useEffect)(() => {
|
|
22341
|
+
if (!isExporting) {
|
|
22342
|
+
setFields(resolvedFields);
|
|
22343
|
+
}
|
|
22344
|
+
}, [isExporting, resolvedFields]);
|
|
22345
|
+
const entityName = exportOptions?.entityName ?? "row";
|
|
22346
|
+
const entityNamePlural = exportOptions?.entityNamePlural ?? "rows";
|
|
22347
|
+
const filenamePrefix = exportOptions?.filenamePrefix ?? exportFilename;
|
|
22348
|
+
const title = exportOptions?.title ?? "Export data";
|
|
22349
|
+
const description = exportOptions?.description ?? (hasServerExport ? "Configure and download data from this table" : "Configure and download the rows currently loaded in this table");
|
|
22350
|
+
const allScopeLabel = exportOptions?.allScopeLabel ?? `Export all ${entityNamePlural} in the project`;
|
|
22351
|
+
const filteredScopeLabel = exportOptions?.filteredScopeLabel ?? `Export only filtered/searched ${entityNamePlural}`;
|
|
22352
|
+
const progressSubjectLabel = exportOptions?.progressSubjectLabel ?? entityNamePlural;
|
|
22353
|
+
const progressTitle = progress.phase === "complete" ? "Export complete" : `Exporting ${progressSubjectLabel}`;
|
|
22354
|
+
const fetchExportRows = exportOptions?.fetchRows;
|
|
22355
|
+
const closeDialog = (0, import_react31.useCallback)(() => {
|
|
22356
|
+
onOpenChange(false);
|
|
22357
|
+
setErrorMessage(null);
|
|
22358
|
+
}, [onOpenChange]);
|
|
22359
|
+
const handleOpenChange = (0, import_react31.useCallback)((nextOpen) => {
|
|
22360
|
+
if (isExporting && !nextOpen) {
|
|
22361
|
+
return;
|
|
22362
|
+
}
|
|
22363
|
+
if (nextOpen) {
|
|
22364
|
+
onOpenChange(true);
|
|
22365
|
+
} else {
|
|
22366
|
+
closeDialog();
|
|
22367
|
+
}
|
|
22368
|
+
}, [closeDialog, isExporting, onOpenChange]);
|
|
22369
|
+
const toggleField = (0, import_react31.useCallback)((key) => {
|
|
22370
|
+
setFields(
|
|
22371
|
+
(prev) => prev.map(
|
|
22372
|
+
(field) => field.key === key ? { ...field, enabled: !field.enabled } : field
|
|
22373
|
+
)
|
|
22374
|
+
);
|
|
22375
|
+
}, []);
|
|
22376
|
+
const selectAllFields = (0, import_react31.useCallback)(() => {
|
|
22377
|
+
setFields((prev) => prev.map((field) => ({ ...field, enabled: true })));
|
|
22378
|
+
}, []);
|
|
22379
|
+
const deselectAllFields = (0, import_react31.useCallback)(() => {
|
|
22380
|
+
setFields((prev) => prev.map((field) => ({ ...field, enabled: false })));
|
|
22381
|
+
}, []);
|
|
22382
|
+
const fetchRows = (0, import_react31.useCallback)(async () => {
|
|
22383
|
+
if (fetchExportRows != null) {
|
|
22384
|
+
return await fetchExportRows({
|
|
22385
|
+
scope,
|
|
22386
|
+
onProgress: (fetched) => setProgress({ phase: "fetching", fetched })
|
|
22387
|
+
});
|
|
22388
|
+
}
|
|
22389
|
+
setProgress({ phase: "fetching", fetched: rows.length });
|
|
22390
|
+
return rows;
|
|
22391
|
+
}, [fetchExportRows, rows, scope]);
|
|
22392
|
+
const handleExport = async () => {
|
|
22393
|
+
const enabledFields = fields.filter((field) => field.enabled);
|
|
22394
|
+
if (enabledFields.length === 0) {
|
|
22395
|
+
setErrorMessage("Select at least one field to export.");
|
|
22396
|
+
return;
|
|
22397
|
+
}
|
|
22398
|
+
setErrorMessage(null);
|
|
22399
|
+
setIsExporting(true);
|
|
22400
|
+
setProgress({ phase: "fetching", fetched: 0 });
|
|
22401
|
+
try {
|
|
22402
|
+
const exportRows = await fetchRows();
|
|
22403
|
+
if (exportRows.length === 0) {
|
|
22404
|
+
setErrorMessage(
|
|
22405
|
+
exportOptions?.emptyExportDescription ?? `There are no ${entityNamePlural} to export.`
|
|
22406
|
+
);
|
|
22407
|
+
setIsExporting(false);
|
|
22408
|
+
setProgress(idleExportProgress);
|
|
22409
|
+
return;
|
|
22410
|
+
}
|
|
22411
|
+
setProgress({ phase: "generating", fetched: exportRows.length });
|
|
22412
|
+
const transformedData = buildExportTable(exportRows, enabledFields);
|
|
22413
|
+
if (format === "csv") {
|
|
22414
|
+
exportToCsv2(transformedData, filenamePrefix);
|
|
22415
|
+
} else {
|
|
22416
|
+
exportToJson(transformedData, filenamePrefix);
|
|
22417
|
+
}
|
|
22418
|
+
setProgress({ phase: "complete", fetched: exportRows.length });
|
|
22419
|
+
await new Promise((resolve) => setTimeout(resolve, exportCompletionDisplayMs));
|
|
22420
|
+
closeDialog();
|
|
22421
|
+
} catch {
|
|
22422
|
+
setErrorMessage("Something went wrong while exporting. Please try again.");
|
|
22423
|
+
} finally {
|
|
22424
|
+
setIsExporting(false);
|
|
22425
|
+
setProgress(idleExportProgress);
|
|
22426
|
+
}
|
|
22427
|
+
};
|
|
22428
|
+
return /* @__PURE__ */ jsx(
|
|
22429
|
+
DesignDialog,
|
|
22430
|
+
{
|
|
22431
|
+
open,
|
|
22432
|
+
onOpenChange: handleOpenChange,
|
|
22433
|
+
title: isExporting ? progressTitle : title,
|
|
22434
|
+
description: isExporting ? `Preparing export for ${progressSubjectLabel}.` : description,
|
|
22435
|
+
size: "2xl",
|
|
22436
|
+
variant: "plain",
|
|
22437
|
+
headerClassName: isExporting ? "sr-only" : void 0,
|
|
22438
|
+
hideTopCloseButton: isExporting,
|
|
22439
|
+
children: isExporting ? /* @__PURE__ */ jsx(
|
|
22440
|
+
ExportProgressContent,
|
|
22441
|
+
{
|
|
22442
|
+
progress,
|
|
22443
|
+
format,
|
|
22444
|
+
subjectLabel: progressSubjectLabel
|
|
22445
|
+
}
|
|
22446
|
+
) : /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
22447
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
22448
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", htmlFor: `${filenamePrefix}-export-format`, children: "Export Format" }),
|
|
22449
|
+
/* @__PURE__ */ jsxs(
|
|
22450
|
+
"select",
|
|
22451
|
+
{
|
|
22452
|
+
id: `${filenamePrefix}-export-format`,
|
|
22453
|
+
value: format,
|
|
22454
|
+
onChange: (event) => setFormat(event.currentTarget.value === "json" ? "json" : "csv"),
|
|
22455
|
+
className: "h-9 w-full rounded-md border border-input bg-white px-3 text-sm dark:bg-background",
|
|
22456
|
+
children: [
|
|
22457
|
+
/* @__PURE__ */ jsx("option", { value: "csv", children: "CSV (Comma-separated values)" }),
|
|
22458
|
+
/* @__PURE__ */ jsx("option", { value: "json", children: "JSON (JavaScript Object Notation)" })
|
|
22459
|
+
]
|
|
22460
|
+
}
|
|
22461
|
+
)
|
|
22462
|
+
] }),
|
|
22463
|
+
hasServerExport ? /* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", children: [
|
|
22464
|
+
/* @__PURE__ */ jsx("legend", { className: "text-sm font-medium", children: "Export Scope" }),
|
|
22465
|
+
/* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm", children: [
|
|
22466
|
+
/* @__PURE__ */ jsx(
|
|
22467
|
+
"input",
|
|
22468
|
+
{
|
|
22469
|
+
type: "radio",
|
|
22470
|
+
name: `${filenamePrefix}-export-scope`,
|
|
22471
|
+
value: "all",
|
|
22472
|
+
checked: scope === "all",
|
|
22473
|
+
onChange: () => setScope("all")
|
|
22474
|
+
}
|
|
22475
|
+
),
|
|
22476
|
+
/* @__PURE__ */ jsx("span", { children: allScopeLabel })
|
|
22477
|
+
] }),
|
|
22478
|
+
/* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm", children: [
|
|
22479
|
+
/* @__PURE__ */ jsx(
|
|
22480
|
+
"input",
|
|
22481
|
+
{
|
|
22482
|
+
type: "radio",
|
|
22483
|
+
name: `${filenamePrefix}-export-scope`,
|
|
22484
|
+
value: "filtered",
|
|
22485
|
+
checked: scope === "filtered",
|
|
22486
|
+
onChange: () => setScope("filtered")
|
|
22487
|
+
}
|
|
22488
|
+
),
|
|
22489
|
+
/* @__PURE__ */ jsx("span", { children: filteredScopeLabel })
|
|
22490
|
+
] })
|
|
22491
|
+
] }) : null,
|
|
22492
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
22493
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
22494
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Fields to Export" }),
|
|
22495
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
22496
|
+
/* @__PURE__ */ jsx(DesignButton, { type: "button", variant: "ghost", size: "sm", onClick: selectAllFields, className: "h-7 text-xs", children: "Select All" }),
|
|
22497
|
+
/* @__PURE__ */ jsx(DesignButton, { type: "button", variant: "ghost", size: "sm", onClick: deselectAllFields, className: "h-7 text-xs", children: "Deselect All" })
|
|
22498
|
+
] })
|
|
22499
|
+
] }),
|
|
22500
|
+
/* @__PURE__ */ jsx("div", { className: "grid max-h-[300px] grid-cols-1 gap-3 overflow-y-auto rounded-lg border border-border p-4 sm:grid-cols-2", children: fields.map((field) => /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm font-normal", children: [
|
|
22501
|
+
/* @__PURE__ */ jsx(
|
|
22502
|
+
"input",
|
|
22503
|
+
{
|
|
22504
|
+
type: "checkbox",
|
|
22505
|
+
checked: field.enabled,
|
|
22506
|
+
onChange: () => toggleField(field.key)
|
|
22507
|
+
}
|
|
22508
|
+
),
|
|
22509
|
+
/* @__PURE__ */ jsx("span", { children: field.label })
|
|
22510
|
+
] }, field.key)) })
|
|
22511
|
+
] }),
|
|
22512
|
+
errorMessage != null ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: [
|
|
22513
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: exportOptions?.emptyExportTitle ?? "Export unavailable" }),
|
|
22514
|
+
/* @__PURE__ */ jsx("div", { children: errorMessage })
|
|
22515
|
+
] }) : null,
|
|
22516
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 pt-2", children: [
|
|
22517
|
+
/* @__PURE__ */ jsx(DesignButton, { variant: "outline", onClick: closeDialog, children: "Cancel" }),
|
|
22518
|
+
/* @__PURE__ */ jsxs(DesignButton, { onClick: handleExport, children: [
|
|
22519
|
+
/* @__PURE__ */ jsx(e29, { className: "mr-2 h-4 w-4" }),
|
|
22520
|
+
"Export ",
|
|
22521
|
+
titleCase(entityNamePlural)
|
|
22522
|
+
] })
|
|
22523
|
+
] })
|
|
22524
|
+
] })
|
|
22525
|
+
}
|
|
22526
|
+
);
|
|
22527
|
+
}
|
|
22528
|
+
function ExportProgressContent(props) {
|
|
22529
|
+
const { progress, format, subjectLabel } = props;
|
|
22530
|
+
const fileLabel = format.toUpperCase();
|
|
22531
|
+
const isComplete = progress.phase === "complete";
|
|
22532
|
+
const title = isComplete ? "Export complete" : `Exporting ${subjectLabel}`;
|
|
22533
|
+
const description = isComplete ? `Your ${fileLabel} is ready and the download should begin automatically.` : `Your ${fileLabel} is being prepared from matching ${subjectLabel}.`;
|
|
22534
|
+
const statusLabel = progress.phase === "complete" ? "Download ready" : progress.phase === "generating" ? `Preparing ${fileLabel}` : `Fetching ${subjectLabel}`;
|
|
22535
|
+
const countLabel = `${progress.fetched.toLocaleString()} ${isComplete ? "exported" : "fetched"}`;
|
|
22536
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
22537
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
22538
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold leading-snug", children: title }),
|
|
22539
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
|
|
22540
|
+
] }),
|
|
22541
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border bg-muted/35 p-4", children: [
|
|
22542
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between gap-4 text-sm", children: [
|
|
22543
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: statusLabel }),
|
|
22544
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 tabular-nums text-muted-foreground", children: countLabel })
|
|
22545
|
+
] }),
|
|
22546
|
+
/* @__PURE__ */ jsx("div", { className: "relative h-2 overflow-hidden rounded-full bg-foreground/10", children: isComplete ? /* @__PURE__ */ jsx("div", { className: "h-full w-full rounded-full bg-emerald-500/80" }) : /* @__PURE__ */ jsx("div", { className: "data-grid-export-progress-shimmer absolute inset-y-0 left-0 w-2/5 rounded-full bg-gradient-to-r from-transparent via-foreground/65 to-transparent" }) })
|
|
22547
|
+
] }),
|
|
22548
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-200", children: "Do not reload this page until the export finishes. The download will start automatically." }),
|
|
22549
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-end gap-3 pt-2", children: /* @__PURE__ */ jsx(DesignButton, { variant: "outline", disabled: true, children: "Cancel" }) })
|
|
22550
|
+
] });
|
|
22551
|
+
}
|
|
22552
|
+
function buildColumnExportFields(columns) {
|
|
22553
|
+
const fields = [];
|
|
22554
|
+
for (const column of columns) {
|
|
22555
|
+
const label = typeof column.header === "string" ? column.header.trim() : column.id;
|
|
22556
|
+
if (label.length === 0) {
|
|
22557
|
+
continue;
|
|
22558
|
+
}
|
|
22559
|
+
fields.push({
|
|
22560
|
+
key: column.id,
|
|
22561
|
+
label,
|
|
22562
|
+
enabled: true,
|
|
22563
|
+
getValue: (row) => formatColumnExportValue(column, row)
|
|
22564
|
+
});
|
|
22565
|
+
}
|
|
22566
|
+
return fields;
|
|
22567
|
+
}
|
|
22568
|
+
function formatColumnExportValue(column, row) {
|
|
22569
|
+
const value = resolveColumnValue(column, row);
|
|
22570
|
+
if (column.formatValue != null) {
|
|
22571
|
+
return column.formatValue(value, row);
|
|
22572
|
+
}
|
|
22573
|
+
if (column.type === "date" || column.type === "dateTime") {
|
|
22574
|
+
return formatGridDate(value, "absolute", {
|
|
22575
|
+
parseValue: column.parseValue,
|
|
22576
|
+
dateFormat: column.dateFormat
|
|
22577
|
+
}).display ?? "";
|
|
22578
|
+
}
|
|
22579
|
+
return value;
|
|
22580
|
+
}
|
|
22581
|
+
function buildExportTable(rows, enabledFields) {
|
|
22582
|
+
return {
|
|
22583
|
+
csvHeaders: enabledFields.map((field) => field.label),
|
|
22584
|
+
jsonKeys: buildJsonKeys(enabledFields),
|
|
22585
|
+
rows: rows.map((row) => enabledFields.map((field) => toExportCellValue(field.getValue(row))))
|
|
22586
|
+
};
|
|
22587
|
+
}
|
|
22588
|
+
function buildJsonKeys(fields) {
|
|
22589
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
22590
|
+
for (const field of fields) {
|
|
22591
|
+
labelCounts.set(field.label, (labelCounts.get(field.label) ?? 0) + 1);
|
|
22592
|
+
}
|
|
22593
|
+
const usedKeys = /* @__PURE__ */ new Map();
|
|
22594
|
+
const keys = [];
|
|
22595
|
+
for (const field of fields) {
|
|
22596
|
+
const baseKey = labelCounts.get(field.label) === 1 ? field.label : `${field.label} (${field.key})`;
|
|
22597
|
+
let key = baseKey;
|
|
22598
|
+
let suffix = 2;
|
|
22599
|
+
while (usedKeys.has(key)) {
|
|
22600
|
+
key = `${baseKey} ${suffix}`;
|
|
22601
|
+
suffix++;
|
|
22602
|
+
}
|
|
22603
|
+
usedKeys.set(key, true);
|
|
22604
|
+
keys.push(key);
|
|
22605
|
+
}
|
|
22606
|
+
return keys;
|
|
22607
|
+
}
|
|
22608
|
+
function toExportCellValue(value) {
|
|
22609
|
+
if (value == null) {
|
|
22610
|
+
return "";
|
|
22611
|
+
}
|
|
22612
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
22613
|
+
return value;
|
|
22614
|
+
}
|
|
22615
|
+
if (typeof value === "bigint") {
|
|
22616
|
+
return value.toString();
|
|
22617
|
+
}
|
|
22618
|
+
if (value instanceof Date) {
|
|
22619
|
+
return value.toISOString();
|
|
22620
|
+
}
|
|
22621
|
+
if (typeof value === "object") {
|
|
22622
|
+
return JSON.stringify(value);
|
|
22623
|
+
}
|
|
22624
|
+
return String(value);
|
|
22625
|
+
}
|
|
22626
|
+
function exportToCsv2(data, filenamePrefix) {
|
|
22627
|
+
const csvContent = "\uFEFF" + [
|
|
22628
|
+
data.csvHeaders.map(escapeCsvCell).join(","),
|
|
22629
|
+
...data.rows.map((row) => row.map(escapeCsvCell).join(","))
|
|
22630
|
+
].join("\n");
|
|
22631
|
+
downloadFile(csvContent, `${buildExportFilename(filenamePrefix)}.csv`, "text/csv;charset=utf-8;");
|
|
22632
|
+
}
|
|
22633
|
+
function escapeCsvCell(value) {
|
|
22634
|
+
const rawText = String(value ?? "");
|
|
22635
|
+
const text2 = typeof value === "string" && /^[=+\-@\t\r]/.test(rawText.trimStart()) ? `'${rawText}` : rawText;
|
|
22636
|
+
if (text2.includes(",") || text2.includes('"') || text2.includes("\n") || text2.includes("\r")) {
|
|
22637
|
+
return `"${text2.replace(/"/g, '""')}"`;
|
|
22638
|
+
}
|
|
22639
|
+
return text2;
|
|
22640
|
+
}
|
|
22641
|
+
function exportToJson(data, filenamePrefix) {
|
|
22642
|
+
const rows = data.rows.map((row) => {
|
|
22643
|
+
const jsonRow = {};
|
|
22644
|
+
for (let i = 0; i < data.jsonKeys.length; i++) {
|
|
22645
|
+
jsonRow[data.jsonKeys[i]] = row[i] ?? "";
|
|
22646
|
+
}
|
|
22647
|
+
return jsonRow;
|
|
22648
|
+
});
|
|
22649
|
+
const jsonString = JSON.stringify(rows, null, 2);
|
|
22650
|
+
downloadFile(jsonString, `${buildExportFilename(filenamePrefix)}.json`, "application/json");
|
|
22651
|
+
}
|
|
22652
|
+
function downloadFile(content, filename, type) {
|
|
22653
|
+
const blob = new Blob([content], { type });
|
|
22654
|
+
const url = URL.createObjectURL(blob);
|
|
22655
|
+
const link = document.createElement("a");
|
|
22656
|
+
link.href = url;
|
|
22657
|
+
link.download = filename;
|
|
22658
|
+
document.body.appendChild(link);
|
|
22659
|
+
try {
|
|
22660
|
+
link.click();
|
|
22661
|
+
} finally {
|
|
22662
|
+
link.remove();
|
|
22663
|
+
URL.revokeObjectURL(url);
|
|
22664
|
+
}
|
|
22665
|
+
}
|
|
22666
|
+
function buildExportFilename(prefix) {
|
|
22667
|
+
return `${prefix}-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`;
|
|
22668
|
+
}
|
|
22669
|
+
function titleCase(value) {
|
|
22670
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
22671
|
+
}
|
|
22672
|
+
|
|
22673
|
+
// src/components/data-grid/data-grid-toolbar.tsx
|
|
22674
|
+
var import_react33 = __toESM(require_react());
|
|
22167
22675
|
function usePopover() {
|
|
22168
|
-
const [open, setOpen] = (0,
|
|
22169
|
-
const ref = (0,
|
|
22170
|
-
|
|
22676
|
+
const [open, setOpen] = (0, import_react33.useState)(false);
|
|
22677
|
+
const ref = (0, import_react33.useRef)(null);
|
|
22678
|
+
import_react33.default.useEffect(() => {
|
|
22171
22679
|
if (!open) return;
|
|
22172
22680
|
const handler = (e40) => {
|
|
22173
22681
|
if (ref.current && !ref.current.contains(e40.target)) {
|
|
@@ -22177,7 +22685,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
22177
22685
|
document.addEventListener("mousedown", handler);
|
|
22178
22686
|
return () => document.removeEventListener("mousedown", handler);
|
|
22179
22687
|
}, [open]);
|
|
22180
|
-
|
|
22688
|
+
import_react33.default.useEffect(() => {
|
|
22181
22689
|
if (!open) return;
|
|
22182
22690
|
const handler = (e40) => {
|
|
22183
22691
|
if (e40.key === "Escape") setOpen(false);
|
|
@@ -22274,7 +22782,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
22274
22782
|
onDateDisplayChange,
|
|
22275
22783
|
hasDateColumns
|
|
22276
22784
|
}) {
|
|
22277
|
-
const hideableColumns = (0,
|
|
22785
|
+
const hideableColumns = (0, import_react33.useMemo)(
|
|
22278
22786
|
() => columns.filter((c4) => c4.hideable !== false),
|
|
22279
22787
|
[columns]
|
|
22280
22788
|
);
|
|
@@ -22322,255 +22830,108 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
22322
22830
|
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: strings.dateFormat }),
|
|
22323
22831
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-0.5 rounded-lg bg-zinc-100/90 p-0.5 ring-1 ring-black/[0.06] dark:bg-foreground/[0.04] dark:ring-white/[0.06]", children: [
|
|
22324
22832
|
/* @__PURE__ */ jsx(
|
|
22325
|
-
"button",
|
|
22326
|
-
{
|
|
22327
|
-
className: cn(
|
|
22328
|
-
"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none",
|
|
22329
|
-
dateDisplay === "relative" ? "bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]" : "text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]"
|
|
22330
|
-
),
|
|
22331
|
-
onClick: () => onDateDisplayChange("relative"),
|
|
22332
|
-
children: strings.dateFormatRelative
|
|
22333
|
-
}
|
|
22334
|
-
),
|
|
22335
|
-
/* @__PURE__ */ jsx(
|
|
22336
|
-
"button",
|
|
22337
|
-
{
|
|
22338
|
-
className: cn(
|
|
22339
|
-
"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none",
|
|
22340
|
-
dateDisplay === "absolute" ? "bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]" : "text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]"
|
|
22341
|
-
),
|
|
22342
|
-
onClick: () => onDateDisplayChange("absolute"),
|
|
22343
|
-
children: strings.dateFormatAbsolute
|
|
22344
|
-
}
|
|
22345
|
-
)
|
|
22346
|
-
] })
|
|
22347
|
-
] }) })
|
|
22348
|
-
] });
|
|
22349
|
-
}
|
|
22350
|
-
function DataGridToolbar({
|
|
22351
|
-
ctx,
|
|
22352
|
-
extra,
|
|
22353
|
-
extraLeading,
|
|
22354
|
-
hideQuickSearch
|
|
22355
|
-
}) {
|
|
22356
|
-
const { state, onChange, columns, strings, exportCsv } = ctx;
|
|
22357
|
-
const columnPopover = usePopover();
|
|
22358
|
-
const updateVisibility = (0, import_react31.useCallback)(
|
|
22359
|
-
(visibility) => {
|
|
22360
|
-
onChange((s8) => ({ ...s8, columnVisibility: visibility }));
|
|
22361
|
-
},
|
|
22362
|
-
[onChange]
|
|
22363
|
-
);
|
|
22364
|
-
const updateDateDisplay = (0, import_react31.useCallback)(
|
|
22365
|
-
(mode) => {
|
|
22366
|
-
onChange((s8) => ({ ...s8, dateDisplay: mode }));
|
|
22367
|
-
},
|
|
22368
|
-
[onChange]
|
|
22369
|
-
);
|
|
22370
|
-
const updateQuickSearch = (0, import_react31.useCallback)(
|
|
22371
|
-
(value) => {
|
|
22372
|
-
onChange((s8) => ({
|
|
22373
|
-
...s8,
|
|
22374
|
-
quickSearch: value,
|
|
22375
|
-
// Reset to first page whenever the search text changes,
|
|
22376
|
-
// otherwise you can end up on a page index that no longer
|
|
22377
|
-
// exists in the filtered / refetched result set.
|
|
22378
|
-
pagination: { ...s8.pagination, pageIndex: 0 }
|
|
22379
|
-
}));
|
|
22380
|
-
},
|
|
22381
|
-
[onChange]
|
|
22382
|
-
);
|
|
22383
|
-
const hasDateColumns = (0, import_react31.useMemo)(
|
|
22384
|
-
() => columns.some((c4) => c4.type === "date" || c4.type === "dateTime"),
|
|
22385
|
-
[columns]
|
|
22386
|
-
);
|
|
22387
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0 flex-col gap-2 px-2.5 py-2.5 border-b border-foreground/[0.06] sm:flex-row sm:items-center sm:gap-2", children: [
|
|
22388
|
-
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-2", children: [
|
|
22389
|
-
!hideQuickSearch && /* @__PURE__ */ jsx(
|
|
22390
|
-
QuickSearch,
|
|
22391
|
-
{
|
|
22392
|
-
value: state.quickSearch,
|
|
22393
|
-
onChange: updateQuickSearch,
|
|
22394
|
-
placeholder: strings.searchPlaceholder
|
|
22395
|
-
}
|
|
22396
|
-
),
|
|
22397
|
-
extraLeading,
|
|
22398
|
-
extra
|
|
22399
|
-
] }),
|
|
22400
|
-
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-end gap-2", children: [
|
|
22401
|
-
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", ref: columnPopover.ref, children: [
|
|
22402
|
-
/* @__PURE__ */ jsx(
|
|
22403
|
-
ToolbarButton,
|
|
22404
|
-
{
|
|
22405
|
-
onClick: () => columnPopover.setOpen(!columnPopover.open),
|
|
22406
|
-
active: columnPopover.open,
|
|
22407
|
-
title: strings.columns,
|
|
22408
|
-
children: /* @__PURE__ */ jsx(n3, { className: "h-3.5 w-3.5" })
|
|
22409
|
-
}
|
|
22410
|
-
),
|
|
22411
|
-
columnPopover.open && /* @__PURE__ */ jsx(PopoverPanel, { popoverRef: columnPopover.ref, className: "right-0 left-auto", children: /* @__PURE__ */ jsx(
|
|
22412
|
-
ColumnManager,
|
|
22413
|
-
{
|
|
22414
|
-
columns,
|
|
22415
|
-
visibility: state.columnVisibility,
|
|
22416
|
-
onChange: updateVisibility,
|
|
22417
|
-
strings,
|
|
22418
|
-
dateDisplay: state.dateDisplay,
|
|
22419
|
-
onDateDisplayChange: updateDateDisplay,
|
|
22420
|
-
hasDateColumns
|
|
22421
|
-
}
|
|
22422
|
-
) })
|
|
22423
|
-
] }),
|
|
22424
|
-
/* @__PURE__ */ jsx(ToolbarButton, { onClick: exportCsv, title: strings.export, children: /* @__PURE__ */ jsx(l2, { className: "h-3.5 w-3.5" }) })
|
|
22425
|
-
] })
|
|
22426
|
-
] });
|
|
22427
|
-
}
|
|
22428
|
-
|
|
22429
|
-
// src/components/data-grid/state.ts
|
|
22430
|
-
function createDefaultDataGridState(columns) {
|
|
22431
|
-
const columnWidths = {};
|
|
22432
|
-
const columnOrder = [];
|
|
22433
|
-
for (const col of columns) {
|
|
22434
|
-
columnWidths[col.id] = clampColumnWidth(col, col.width ?? DEFAULT_COL_WIDTH);
|
|
22435
|
-
columnOrder.push(col.id);
|
|
22436
|
-
}
|
|
22437
|
-
return {
|
|
22438
|
-
sorting: [],
|
|
22439
|
-
columnVisibility: {},
|
|
22440
|
-
columnWidths,
|
|
22441
|
-
columnPinning: { left: [], right: [] },
|
|
22442
|
-
columnOrder,
|
|
22443
|
-
pagination: { pageIndex: 0, pageSize: 50 },
|
|
22444
|
-
selection: { selectedIds: /* @__PURE__ */ new Set(), anchorId: null },
|
|
22445
|
-
dateDisplay: "relative",
|
|
22446
|
-
quickSearch: ""
|
|
22447
|
-
};
|
|
22448
|
-
}
|
|
22449
|
-
function resolveColumnValue(col, row) {
|
|
22450
|
-
if (typeof col.accessor === "function") return col.accessor(row);
|
|
22451
|
-
const key = col.accessor ?? col.id;
|
|
22452
|
-
return row[key];
|
|
22453
|
-
}
|
|
22454
|
-
function defaultComparator(a26, b) {
|
|
22455
|
-
if (a26 == null && b == null) return 0;
|
|
22456
|
-
if (a26 == null) return -1;
|
|
22457
|
-
if (b == null) return 1;
|
|
22458
|
-
if (typeof a26 === "number" && typeof b === "number") return a26 - b;
|
|
22459
|
-
if (a26 instanceof Date && b instanceof Date) return a26.getTime() - b.getTime();
|
|
22460
|
-
return stringCompare(String(a26), String(b));
|
|
22461
|
-
}
|
|
22462
|
-
function buildRowComparator(sortModel, columns) {
|
|
22463
|
-
if (sortModel.length === 0) return null;
|
|
22464
|
-
const colMap = new Map(columns.map((c4) => [c4.id, c4]));
|
|
22465
|
-
return (a26, b) => {
|
|
22466
|
-
for (const { columnId, direction } of sortModel) {
|
|
22467
|
-
const col = colMap.get(columnId);
|
|
22468
|
-
if (!col) continue;
|
|
22469
|
-
const va = resolveColumnValue(col, a26);
|
|
22470
|
-
const vb = resolveColumnValue(col, b);
|
|
22471
|
-
const cmp = col.sortComparator ? col.sortComparator(va, vb) : defaultComparator(va, vb);
|
|
22472
|
-
if (cmp !== 0) return direction === "asc" ? cmp : -cmp;
|
|
22473
|
-
}
|
|
22474
|
-
return 0;
|
|
22475
|
-
};
|
|
22476
|
-
}
|
|
22477
|
-
function paginateRows(rows, pagination) {
|
|
22478
|
-
const start = pagination.pageIndex * pagination.pageSize;
|
|
22479
|
-
return rows.slice(start, start + pagination.pageSize);
|
|
22480
|
-
}
|
|
22481
|
-
function defaultMatchRow(row, query, columns) {
|
|
22482
|
-
for (const col of columns) {
|
|
22483
|
-
const v = resolveColumnValue(col, row);
|
|
22484
|
-
if (v == null) continue;
|
|
22485
|
-
if (String(v).toLowerCase().includes(query)) return true;
|
|
22486
|
-
}
|
|
22487
|
-
return false;
|
|
22488
|
-
}
|
|
22489
|
-
function applyQuickSearch(rows, query, columns, matchRow = defaultMatchRow) {
|
|
22490
|
-
const trimmed = query.trim().toLowerCase();
|
|
22491
|
-
if (!trimmed) return rows;
|
|
22492
|
-
return rows.filter((r7) => matchRow(r7, trimmed, columns));
|
|
22493
|
-
}
|
|
22494
|
-
function defaultParseDate(value) {
|
|
22495
|
-
if (value == null) return null;
|
|
22496
|
-
if (value instanceof Date) return isNaN(value.getTime()) ? null : value;
|
|
22497
|
-
if (typeof value === "number" || typeof value === "string") {
|
|
22498
|
-
const d = new Date(value);
|
|
22499
|
-
return isNaN(d.getTime()) ? null : d;
|
|
22500
|
-
}
|
|
22501
|
-
return null;
|
|
22502
|
-
}
|
|
22503
|
-
var DIVISIONS = [
|
|
22504
|
-
{ amount: 60, unit: "second" },
|
|
22505
|
-
{ amount: 60, unit: "minute" },
|
|
22506
|
-
{ amount: 24, unit: "hour" },
|
|
22507
|
-
{ amount: 7, unit: "day" },
|
|
22508
|
-
{ amount: 4.34524, unit: "week" },
|
|
22509
|
-
{ amount: 12, unit: "month" },
|
|
22510
|
-
{ amount: Number.POSITIVE_INFINITY, unit: "year" }
|
|
22511
|
-
];
|
|
22512
|
-
var relativeTimeFormatterCache = /* @__PURE__ */ new Map();
|
|
22513
|
-
function getRelativeTimeFormatter(locale2) {
|
|
22514
|
-
const key = locale2 ?? "__default__";
|
|
22515
|
-
let cached = relativeTimeFormatterCache.get(key);
|
|
22516
|
-
if (cached == null) {
|
|
22517
|
-
cached = new Intl.RelativeTimeFormat(locale2, { numeric: "auto" });
|
|
22518
|
-
relativeTimeFormatterCache.set(key, cached);
|
|
22519
|
-
}
|
|
22520
|
-
return cached;
|
|
22521
|
-
}
|
|
22522
|
-
function defaultFormatRelative(date2) {
|
|
22523
|
-
const rtf = getRelativeTimeFormatter();
|
|
22524
|
-
let duration = (date2.getTime() - Date.now()) / 1e3;
|
|
22525
|
-
for (const div of DIVISIONS) {
|
|
22526
|
-
if (Math.abs(duration) < div.amount) return rtf.format(Math.round(duration), div.unit);
|
|
22527
|
-
duration /= div.amount;
|
|
22528
|
-
}
|
|
22529
|
-
return rtf.format(Math.round(duration), "year");
|
|
22530
|
-
}
|
|
22531
|
-
function defaultFormatAbsolute(date2) {
|
|
22532
|
-
return date2.toLocaleString();
|
|
22533
|
-
}
|
|
22534
|
-
function formatGridDate(value, mode, opts) {
|
|
22535
|
-
const parse2 = opts?.parseValue ?? defaultParseDate;
|
|
22536
|
-
const date2 = parse2(value);
|
|
22537
|
-
if (!date2) return { display: null, tooltip: null };
|
|
22538
|
-
const relative = opts?.dateFormat?.relative ?? defaultFormatRelative;
|
|
22539
|
-
const absolute = opts?.dateFormat?.absolute ?? defaultFormatAbsolute;
|
|
22540
|
-
const tooltip = absolute(date2);
|
|
22541
|
-
const display = mode === "relative" ? relative(date2) : tooltip;
|
|
22542
|
-
return { display, tooltip };
|
|
22833
|
+
"button",
|
|
22834
|
+
{
|
|
22835
|
+
className: cn(
|
|
22836
|
+
"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none",
|
|
22837
|
+
dateDisplay === "relative" ? "bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]" : "text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]"
|
|
22838
|
+
),
|
|
22839
|
+
onClick: () => onDateDisplayChange("relative"),
|
|
22840
|
+
children: strings.dateFormatRelative
|
|
22841
|
+
}
|
|
22842
|
+
),
|
|
22843
|
+
/* @__PURE__ */ jsx(
|
|
22844
|
+
"button",
|
|
22845
|
+
{
|
|
22846
|
+
className: cn(
|
|
22847
|
+
"px-2 py-0.5 rounded-md text-[11px] font-medium transition-colors duration-150 hover:transition-none",
|
|
22848
|
+
dateDisplay === "absolute" ? "bg-white text-foreground shadow-sm ring-1 ring-black/[0.12] dark:bg-background dark:ring-white/[0.06]" : "text-muted-foreground hover:text-foreground hover:bg-white/50 dark:hover:bg-white/[0.06]"
|
|
22849
|
+
),
|
|
22850
|
+
onClick: () => onDateDisplayChange("absolute"),
|
|
22851
|
+
children: strings.dateFormatAbsolute
|
|
22852
|
+
}
|
|
22853
|
+
)
|
|
22854
|
+
] })
|
|
22855
|
+
] }) })
|
|
22856
|
+
] });
|
|
22543
22857
|
}
|
|
22544
|
-
function
|
|
22545
|
-
|
|
22546
|
-
|
|
22858
|
+
function DataGridToolbar({
|
|
22859
|
+
ctx,
|
|
22860
|
+
extra,
|
|
22861
|
+
extraLeading,
|
|
22862
|
+
hideQuickSearch
|
|
22863
|
+
}) {
|
|
22864
|
+
const { state, onChange, columns, strings, exportCsv } = ctx;
|
|
22865
|
+
const columnPopover = usePopover();
|
|
22866
|
+
const updateVisibility = (0, import_react33.useCallback)(
|
|
22867
|
+
(visibility) => {
|
|
22868
|
+
onChange((s8) => ({ ...s8, columnVisibility: visibility }));
|
|
22869
|
+
},
|
|
22870
|
+
[onChange]
|
|
22547
22871
|
);
|
|
22548
|
-
const
|
|
22549
|
-
(
|
|
22550
|
-
|
|
22551
|
-
|
|
22552
|
-
|
|
22553
|
-
return `"${formatted.replace(/"/g, '""')}"`;
|
|
22554
|
-
}
|
|
22555
|
-
return formatted;
|
|
22556
|
-
})
|
|
22872
|
+
const updateDateDisplay = (0, import_react33.useCallback)(
|
|
22873
|
+
(mode) => {
|
|
22874
|
+
onChange((s8) => ({ ...s8, dateDisplay: mode }));
|
|
22875
|
+
},
|
|
22876
|
+
[onChange]
|
|
22557
22877
|
);
|
|
22558
|
-
const
|
|
22559
|
-
|
|
22560
|
-
|
|
22561
|
-
|
|
22562
|
-
|
|
22563
|
-
|
|
22564
|
-
|
|
22565
|
-
|
|
22566
|
-
|
|
22567
|
-
|
|
22568
|
-
|
|
22569
|
-
|
|
22570
|
-
|
|
22571
|
-
|
|
22572
|
-
|
|
22573
|
-
|
|
22878
|
+
const updateQuickSearch = (0, import_react33.useCallback)(
|
|
22879
|
+
(value) => {
|
|
22880
|
+
onChange((s8) => ({
|
|
22881
|
+
...s8,
|
|
22882
|
+
quickSearch: value,
|
|
22883
|
+
// Reset to first page whenever the search text changes,
|
|
22884
|
+
// otherwise you can end up on a page index that no longer
|
|
22885
|
+
// exists in the filtered / refetched result set.
|
|
22886
|
+
pagination: { ...s8.pagination, pageIndex: 0 }
|
|
22887
|
+
}));
|
|
22888
|
+
},
|
|
22889
|
+
[onChange]
|
|
22890
|
+
);
|
|
22891
|
+
const hasDateColumns = (0, import_react33.useMemo)(
|
|
22892
|
+
() => columns.some((c4) => c4.type === "date" || c4.type === "dateTime"),
|
|
22893
|
+
[columns]
|
|
22894
|
+
);
|
|
22895
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0 flex-col gap-2 px-2.5 py-2.5 border-b border-foreground/[0.06] sm:flex-row sm:items-center sm:gap-2", children: [
|
|
22896
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-2", children: [
|
|
22897
|
+
!hideQuickSearch && /* @__PURE__ */ jsx(
|
|
22898
|
+
QuickSearch,
|
|
22899
|
+
{
|
|
22900
|
+
value: state.quickSearch,
|
|
22901
|
+
onChange: updateQuickSearch,
|
|
22902
|
+
placeholder: strings.searchPlaceholder
|
|
22903
|
+
}
|
|
22904
|
+
),
|
|
22905
|
+
extraLeading,
|
|
22906
|
+
extra
|
|
22907
|
+
] }),
|
|
22908
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-end gap-2", children: [
|
|
22909
|
+
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", ref: columnPopover.ref, children: [
|
|
22910
|
+
/* @__PURE__ */ jsx(
|
|
22911
|
+
ToolbarButton,
|
|
22912
|
+
{
|
|
22913
|
+
onClick: () => columnPopover.setOpen(!columnPopover.open),
|
|
22914
|
+
active: columnPopover.open,
|
|
22915
|
+
title: strings.columns,
|
|
22916
|
+
children: /* @__PURE__ */ jsx(n3, { className: "h-3.5 w-3.5" })
|
|
22917
|
+
}
|
|
22918
|
+
),
|
|
22919
|
+
columnPopover.open && /* @__PURE__ */ jsx(PopoverPanel, { popoverRef: columnPopover.ref, className: "right-0 left-auto", children: /* @__PURE__ */ jsx(
|
|
22920
|
+
ColumnManager,
|
|
22921
|
+
{
|
|
22922
|
+
columns,
|
|
22923
|
+
visibility: state.columnVisibility,
|
|
22924
|
+
onChange: updateVisibility,
|
|
22925
|
+
strings,
|
|
22926
|
+
dateDisplay: state.dateDisplay,
|
|
22927
|
+
onDateDisplayChange: updateDateDisplay,
|
|
22928
|
+
hasDateColumns
|
|
22929
|
+
}
|
|
22930
|
+
) })
|
|
22931
|
+
] }),
|
|
22932
|
+
/* @__PURE__ */ jsx(ToolbarButton, { onClick: exportCsv, title: strings.export, children: /* @__PURE__ */ jsx(l2, { className: "h-3.5 w-3.5" }) })
|
|
22933
|
+
] })
|
|
22934
|
+
] });
|
|
22574
22935
|
}
|
|
22575
22936
|
|
|
22576
22937
|
// src/components/data-grid/strings.ts
|
|
@@ -22896,8 +23257,8 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
22896
23257
|
rootRef,
|
|
22897
23258
|
strings
|
|
22898
23259
|
}) {
|
|
22899
|
-
const ref = (0,
|
|
22900
|
-
(0,
|
|
23260
|
+
const ref = (0, import_react35.useRef)(null);
|
|
23261
|
+
(0, import_react35.useEffect)(() => {
|
|
22901
23262
|
const el = ref.current;
|
|
22902
23263
|
if (!el) return;
|
|
22903
23264
|
const observer = new IntersectionObserver(
|
|
@@ -23015,6 +23376,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23015
23376
|
footer,
|
|
23016
23377
|
footerExtra,
|
|
23017
23378
|
exportFilename = "export",
|
|
23379
|
+
exportOptions,
|
|
23018
23380
|
strings: stringsOverride,
|
|
23019
23381
|
className,
|
|
23020
23382
|
onRowClick,
|
|
@@ -23027,8 +23389,8 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23027
23389
|
const isDynamicRowHeight = rowHeightProp === "auto";
|
|
23028
23390
|
const fixedRowHeight = isDynamicRowHeight ? void 0 : rowHeightProp;
|
|
23029
23391
|
const estimatedRowHeight = estimatedRowHeightProp ?? (fixedRowHeight ?? 44);
|
|
23030
|
-
const strings = (0,
|
|
23031
|
-
const tableColumns = (0,
|
|
23392
|
+
const strings = (0, import_react35.useMemo)(() => resolveDataGridStrings(stringsOverride), [stringsOverride]);
|
|
23393
|
+
const tableColumns = (0, import_react35.useMemo)(
|
|
23032
23394
|
() => allColumns.map((col) => ({
|
|
23033
23395
|
id: col.id,
|
|
23034
23396
|
accessorFn: (row) => resolveColumnValue(col, row),
|
|
@@ -23043,22 +23405,22 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23043
23405
|
})),
|
|
23044
23406
|
[allColumns]
|
|
23045
23407
|
);
|
|
23046
|
-
const tanstackSorting = (0,
|
|
23047
|
-
const tanstackRowSelection = (0,
|
|
23408
|
+
const tanstackSorting = (0, import_react35.useMemo)(() => toTanstackSorting(state.sorting), [state.sorting]);
|
|
23409
|
+
const tanstackRowSelection = (0, import_react35.useMemo)(
|
|
23048
23410
|
() => toTanstackRowSelection(state.selection.selectedIds),
|
|
23049
23411
|
[state.selection.selectedIds]
|
|
23050
23412
|
);
|
|
23051
|
-
const tanstackColumnPinning = (0,
|
|
23413
|
+
const tanstackColumnPinning = (0, import_react35.useMemo)(
|
|
23052
23414
|
() => ({ left: [...state.columnPinning.left], right: [...state.columnPinning.right] }),
|
|
23053
23415
|
[state.columnPinning]
|
|
23054
23416
|
);
|
|
23055
|
-
const tanstackColumnOrder = (0,
|
|
23417
|
+
const tanstackColumnOrder = (0, import_react35.useMemo)(
|
|
23056
23418
|
() => [...state.columnOrder],
|
|
23057
23419
|
[state.columnOrder]
|
|
23058
23420
|
);
|
|
23059
|
-
const allColumnsRef = (0,
|
|
23421
|
+
const allColumnsRef = (0, import_react35.useRef)(allColumns);
|
|
23060
23422
|
allColumnsRef.current = allColumns;
|
|
23061
|
-
const handleSortingChange = (0,
|
|
23423
|
+
const handleSortingChange = (0, import_react35.useCallback)(
|
|
23062
23424
|
(updater) => {
|
|
23063
23425
|
const next = resolveUpdater(updater, toTanstackSorting(state.sorting));
|
|
23064
23426
|
const ours = fromTanstackSorting(next).map((s8) => ({ ...s8 }));
|
|
@@ -23071,7 +23433,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23071
23433
|
},
|
|
23072
23434
|
[onChange, onSortChange, state.sorting]
|
|
23073
23435
|
);
|
|
23074
|
-
const handleColumnSizingChange = (0,
|
|
23436
|
+
const handleColumnSizingChange = (0, import_react35.useCallback)(
|
|
23075
23437
|
(updater) => {
|
|
23076
23438
|
const next = resolveUpdater(updater, state.columnWidths);
|
|
23077
23439
|
const clamped = {};
|
|
@@ -23088,7 +23450,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23088
23450
|
},
|
|
23089
23451
|
[onChange, onColumnResize, state.columnWidths]
|
|
23090
23452
|
);
|
|
23091
|
-
const handleVisibilityChange = (0,
|
|
23453
|
+
const handleVisibilityChange = (0, import_react35.useCallback)(
|
|
23092
23454
|
(updater) => {
|
|
23093
23455
|
const next = resolveUpdater(updater, state.columnVisibility);
|
|
23094
23456
|
onChange((s8) => ({ ...s8, columnVisibility: next }));
|
|
@@ -23096,14 +23458,14 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23096
23458
|
},
|
|
23097
23459
|
[onChange, onColumnVisibilityChange, state.columnVisibility]
|
|
23098
23460
|
);
|
|
23099
|
-
const handleColumnOrderChange = (0,
|
|
23461
|
+
const handleColumnOrderChange = (0, import_react35.useCallback)(
|
|
23100
23462
|
(updater) => {
|
|
23101
23463
|
const next = resolveUpdater(updater, [...state.columnOrder]);
|
|
23102
23464
|
onChange((s8) => ({ ...s8, columnOrder: next }));
|
|
23103
23465
|
},
|
|
23104
23466
|
[onChange, state.columnOrder]
|
|
23105
23467
|
);
|
|
23106
|
-
const handleColumnPinningChange = (0,
|
|
23468
|
+
const handleColumnPinningChange = (0, import_react35.useCallback)(
|
|
23107
23469
|
(updater) => {
|
|
23108
23470
|
const current = {
|
|
23109
23471
|
left: [...state.columnPinning.left],
|
|
@@ -23143,13 +23505,13 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23143
23505
|
manualPagination: true,
|
|
23144
23506
|
manualFiltering: true
|
|
23145
23507
|
});
|
|
23146
|
-
const visibleColumns = (0,
|
|
23508
|
+
const visibleColumns = (0, import_react35.useMemo)(() => {
|
|
23147
23509
|
const colMap = new Map(allColumns.map((c4) => [c4.id, c4]));
|
|
23148
23510
|
return table.getVisibleLeafColumns().map((c4) => colMap.get(c4.id)).filter(Boolean);
|
|
23149
23511
|
}, [allColumns, table, state.columnOrder, state.columnVisibility]);
|
|
23150
|
-
const rowIds = (0,
|
|
23151
|
-
const [containerWidth, setContainerWidth] = (0,
|
|
23152
|
-
(0,
|
|
23512
|
+
const rowIds = (0, import_react35.useMemo)(() => rows.map(getRowId), [rows, getRowId]);
|
|
23513
|
+
const [containerWidth, setContainerWidth] = (0, import_react35.useState)(0);
|
|
23514
|
+
(0, import_react35.useLayoutEffect)(() => {
|
|
23153
23515
|
const grid = gridRef.current;
|
|
23154
23516
|
const scroller = scrollContainerRef.current;
|
|
23155
23517
|
if (!grid) return;
|
|
@@ -23174,7 +23536,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23174
23536
|
return () => observer.disconnect();
|
|
23175
23537
|
}, []);
|
|
23176
23538
|
const columnSizingInfo = table.getState().columnSizingInfo;
|
|
23177
|
-
const columnSizes = (0,
|
|
23539
|
+
const columnSizes = (0, import_react35.useMemo)(() => {
|
|
23178
23540
|
const sizes = {};
|
|
23179
23541
|
let baseTotal = selectionMode !== "none" ? 44 : 0;
|
|
23180
23542
|
const resizingId = columnSizingInfo.isResizingColumn || null;
|
|
@@ -23189,19 +23551,19 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23189
23551
|
distributeFlexWidths(sizes, visibleColumns, containerWidth - baseTotal);
|
|
23190
23552
|
return sizes;
|
|
23191
23553
|
}, [visibleColumns, table, columnSizingInfo, state.columnWidths, containerWidth, selectionMode]);
|
|
23192
|
-
const totalContentWidth = (0,
|
|
23554
|
+
const totalContentWidth = (0, import_react35.useMemo)(() => {
|
|
23193
23555
|
let total = selectionMode !== "none" ? 44 : 0;
|
|
23194
23556
|
for (const col of visibleColumns) total += columnSizes[col.id] ?? 0;
|
|
23195
23557
|
return total;
|
|
23196
23558
|
}, [visibleColumns, columnSizes, selectionMode]);
|
|
23197
|
-
const cssVars = (0,
|
|
23559
|
+
const cssVars = (0, import_react35.useMemo)(() => {
|
|
23198
23560
|
const vars = { "--grid-total-w": `${totalContentWidth}px` };
|
|
23199
23561
|
for (const col of visibleColumns) {
|
|
23200
23562
|
vars[`--col-${col.id}-size`] = columnSizes[col.id];
|
|
23201
23563
|
}
|
|
23202
23564
|
return vars;
|
|
23203
23565
|
}, [visibleColumns, columnSizes, totalContentWidth]);
|
|
23204
|
-
const fireSelection = (0,
|
|
23566
|
+
const fireSelection = (0, import_react35.useCallback)(
|
|
23205
23567
|
(next) => {
|
|
23206
23568
|
onChange((s8) => ({ ...s8, selection: next }));
|
|
23207
23569
|
if (onSelectionChange) {
|
|
@@ -23212,7 +23574,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23212
23574
|
},
|
|
23213
23575
|
[onChange, onSelectionChange, rows, getRowId]
|
|
23214
23576
|
);
|
|
23215
|
-
const handleRowClick = (0,
|
|
23577
|
+
const handleRowClick = (0, import_react35.useCallback)(
|
|
23216
23578
|
(row, rowId, event) => {
|
|
23217
23579
|
if (selectionMode !== "none") {
|
|
23218
23580
|
const next = nextSelection({
|
|
@@ -23228,28 +23590,22 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23228
23590
|
},
|
|
23229
23591
|
[selectionMode, state.selection, rowIds, fireSelection, onRowClick]
|
|
23230
23592
|
);
|
|
23231
|
-
const handleSelectAll = (0,
|
|
23593
|
+
const handleSelectAll = (0, import_react35.useCallback)(() => {
|
|
23232
23594
|
const allSelectedNow = rowIds.length > 0 && rowIds.every((id) => state.selection.selectedIds.has(id));
|
|
23233
23595
|
fireSelection(
|
|
23234
23596
|
allSelectedNow ? { selectedIds: /* @__PURE__ */ new Set(), anchorId: null } : { selectedIds: new Set(rowIds), anchorId: null }
|
|
23235
23597
|
);
|
|
23236
23598
|
}, [rowIds, state.selection.selectedIds, fireSelection]);
|
|
23237
|
-
const
|
|
23238
|
-
|
|
23239
|
-
|
|
23240
|
-
|
|
23241
|
-
|
|
23242
|
-
|
|
23243
|
-
|
|
23244
|
-
|
|
23245
|
-
|
|
23246
|
-
|
|
23247
|
-
const scrollContainerRef = (0, import_react33.useRef)(null);
|
|
23248
|
-
const headerScrollRef = (0, import_react33.useRef)(null);
|
|
23249
|
-
const stickyChromeRef = (0, import_react33.useRef)(null);
|
|
23250
|
-
const rowsClipRef = (0, import_react33.useRef)(null);
|
|
23251
|
-
const gridRef = (0, import_react33.useRef)(null);
|
|
23252
|
-
const measureElementFn = (0, import_react33.useCallback)((el) => el.getBoundingClientRect().height, []);
|
|
23599
|
+
const [exportDialogOpen, setExportDialogOpen] = (0, import_react35.useState)(false);
|
|
23600
|
+
const handleExportCsv = (0, import_react35.useCallback)(() => {
|
|
23601
|
+
setExportDialogOpen(true);
|
|
23602
|
+
}, []);
|
|
23603
|
+
const scrollContainerRef = (0, import_react35.useRef)(null);
|
|
23604
|
+
const headerScrollRef = (0, import_react35.useRef)(null);
|
|
23605
|
+
const stickyChromeRef = (0, import_react35.useRef)(null);
|
|
23606
|
+
const rowsClipRef = (0, import_react35.useRef)(null);
|
|
23607
|
+
const gridRef = (0, import_react35.useRef)(null);
|
|
23608
|
+
const measureElementFn = (0, import_react35.useCallback)((el) => el.getBoundingClientRect().height, []);
|
|
23253
23609
|
const rowVirtualizer = useVirtualizer({
|
|
23254
23610
|
count: rows.length,
|
|
23255
23611
|
getScrollElement: () => scrollContainerRef.current,
|
|
@@ -23261,7 +23617,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23261
23617
|
},
|
|
23262
23618
|
...isDynamicRowHeight ? { measureElement: measureElementFn } : {}
|
|
23263
23619
|
});
|
|
23264
|
-
(0,
|
|
23620
|
+
(0, import_react35.useLayoutEffect)(() => {
|
|
23265
23621
|
const gridEl = gridRef.current;
|
|
23266
23622
|
const stickyEl = stickyChromeRef.current;
|
|
23267
23623
|
const bodyEl = scrollContainerRef.current;
|
|
@@ -23288,12 +23644,12 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23288
23644
|
observer.disconnect();
|
|
23289
23645
|
};
|
|
23290
23646
|
}, []);
|
|
23291
|
-
const handleBodyScroll = (0,
|
|
23647
|
+
const handleBodyScroll = (0, import_react35.useCallback)(() => {
|
|
23292
23648
|
const body = scrollContainerRef.current;
|
|
23293
23649
|
const header = headerScrollRef.current;
|
|
23294
23650
|
if (body && header) header.scrollLeft = body.scrollLeft;
|
|
23295
23651
|
}, []);
|
|
23296
|
-
const toolbarCtx = (0,
|
|
23652
|
+
const toolbarCtx = (0, import_react35.useMemo)(
|
|
23297
23653
|
() => ({
|
|
23298
23654
|
state,
|
|
23299
23655
|
onChange,
|
|
@@ -23306,7 +23662,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23306
23662
|
}),
|
|
23307
23663
|
[state, onChange, allColumns, visibleColumns, totalRowCount, strings, handleExportCsv]
|
|
23308
23664
|
);
|
|
23309
|
-
const footerCtx = (0,
|
|
23665
|
+
const footerCtx = (0, import_react35.useMemo)(
|
|
23310
23666
|
() => ({
|
|
23311
23667
|
state,
|
|
23312
23668
|
totalRowCount,
|
|
@@ -23320,238 +23676,251 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23320
23676
|
const allSelected = rowIds.length > 0 && rowIds.every((id) => state.selection.selectedIds.has(id));
|
|
23321
23677
|
const someSelected = !allSelected && rowIds.some((id) => state.selection.selectedIds.has(id));
|
|
23322
23678
|
const infiniteScrollRootRef = paginationMode === "infinite" && (fillHeight || maxHeight != null) ? scrollContainerRef : void 0;
|
|
23323
|
-
const headers = (0,
|
|
23679
|
+
const headers = (0, import_react35.useMemo)(
|
|
23324
23680
|
() => table.getHeaderGroups()[0]?.headers.filter((h) => visibleColumns.some((c4) => c4.id === h.column.id)) ?? [],
|
|
23325
23681
|
[table, visibleColumns]
|
|
23326
23682
|
);
|
|
23327
|
-
const headerByColId = (0,
|
|
23683
|
+
const headerByColId = (0, import_react35.useMemo)(() => {
|
|
23328
23684
|
const m5 = /* @__PURE__ */ new Map();
|
|
23329
23685
|
for (const h of headers) m5.set(h.column.id, h);
|
|
23330
23686
|
return m5;
|
|
23331
23687
|
}, [headers]);
|
|
23332
23688
|
const isBounded = fillHeight || maxHeight != null;
|
|
23333
|
-
return /* @__PURE__ */ jsxs(
|
|
23334
|
-
|
|
23335
|
-
|
|
23336
|
-
|
|
23337
|
-
|
|
23338
|
-
|
|
23339
|
-
|
|
23340
|
-
|
|
23341
|
-
|
|
23342
|
-
|
|
23343
|
-
|
|
23344
|
-
|
|
23345
|
-
|
|
23346
|
-
"
|
|
23347
|
-
|
|
23348
|
-
|
|
23349
|
-
|
|
23350
|
-
|
|
23351
|
-
|
|
23352
|
-
|
|
23353
|
-
|
|
23354
|
-
|
|
23355
|
-
|
|
23356
|
-
|
|
23357
|
-
|
|
23358
|
-
|
|
23359
|
-
|
|
23360
|
-
|
|
23361
|
-
|
|
23362
|
-
|
|
23363
|
-
|
|
23364
|
-
|
|
23365
|
-
|
|
23689
|
+
return /* @__PURE__ */ jsxs(Fragment24, { children: [
|
|
23690
|
+
/* @__PURE__ */ jsx(
|
|
23691
|
+
DataGridExportDialog,
|
|
23692
|
+
{
|
|
23693
|
+
open: exportDialogOpen,
|
|
23694
|
+
onOpenChange: setExportDialogOpen,
|
|
23695
|
+
rows,
|
|
23696
|
+
columns: visibleColumns,
|
|
23697
|
+
exportFilename,
|
|
23698
|
+
exportOptions
|
|
23699
|
+
}
|
|
23700
|
+
),
|
|
23701
|
+
/* @__PURE__ */ jsxs(
|
|
23702
|
+
"div",
|
|
23703
|
+
{
|
|
23704
|
+
ref: gridRef,
|
|
23705
|
+
className: cn(
|
|
23706
|
+
"isolate flex w-full min-w-0 max-w-full flex-col bg-transparent rounded-[calc(var(--radius)*2)]",
|
|
23707
|
+
fillHeight ? "min-h-0 h-full" : "min-h-0 h-auto",
|
|
23708
|
+
isBounded && "overflow-hidden",
|
|
23709
|
+
className
|
|
23710
|
+
),
|
|
23711
|
+
style: maxHeight != null ? { ...cssVars, maxHeight } : cssVars,
|
|
23712
|
+
role: "grid",
|
|
23713
|
+
"aria-rowcount": totalRowCount ?? rows.length,
|
|
23714
|
+
"aria-colcount": visibleColumns.length,
|
|
23715
|
+
children: [
|
|
23716
|
+
/* @__PURE__ */ jsxs(
|
|
23717
|
+
"div",
|
|
23718
|
+
{
|
|
23719
|
+
ref: stickyChromeRef,
|
|
23720
|
+
className: "sticky z-30 w-full min-w-0 shrink-0 overflow-visible rounded-t-[calc(var(--radius)*2)] bg-white/90 dark:bg-background/60 backdrop-blur-xl",
|
|
23721
|
+
style: { top: stickyTop ?? (maxHeight != null ? 0 : "var(--data-grid-sticky-top, 0px)") },
|
|
23722
|
+
children: [
|
|
23723
|
+
toolbar !== false && /* @__PURE__ */ jsx("div", { className: "relative bg-transparent", children: toolbar ? toolbar(toolbarCtx) : /* @__PURE__ */ jsx(
|
|
23724
|
+
DataGridToolbar,
|
|
23366
23725
|
{
|
|
23367
|
-
|
|
23368
|
-
|
|
23369
|
-
children: /* @__PURE__ */ jsxs(
|
|
23370
|
-
"div",
|
|
23371
|
-
{
|
|
23372
|
-
className: "flex",
|
|
23373
|
-
style: { height: headerHeight, minWidth: totalContentWidth },
|
|
23374
|
-
role: "row",
|
|
23375
|
-
children: [
|
|
23376
|
-
selectionMode !== "none" && /* @__PURE__ */ jsx(
|
|
23377
|
-
"div",
|
|
23378
|
-
{
|
|
23379
|
-
className: "flex items-center justify-center border-r border-foreground/[0.04]",
|
|
23380
|
-
style: { width: 44 },
|
|
23381
|
-
children: selectionMode === "multiple" && /* @__PURE__ */ jsx(
|
|
23382
|
-
SelectionCheckbox,
|
|
23383
|
-
{
|
|
23384
|
-
checked: allSelected,
|
|
23385
|
-
indeterminate: someSelected,
|
|
23386
|
-
onChange: handleSelectAll,
|
|
23387
|
-
ariaLabel: "Select all rows on this page",
|
|
23388
|
-
title: "Select all rows on this page"
|
|
23389
|
-
}
|
|
23390
|
-
)
|
|
23391
|
-
}
|
|
23392
|
-
),
|
|
23393
|
-
visibleColumns.map((col) => {
|
|
23394
|
-
const header = headerByColId.get(col.id);
|
|
23395
|
-
if (!header) return null;
|
|
23396
|
-
return /* @__PURE__ */ jsx(HeaderCell, { header, col, resizable }, col.id);
|
|
23397
|
-
})
|
|
23398
|
-
]
|
|
23399
|
-
}
|
|
23400
|
-
)
|
|
23726
|
+
ctx: toolbarCtx,
|
|
23727
|
+
extra: typeof toolbarExtra === "function" ? toolbarExtra(toolbarCtx) : toolbarExtra
|
|
23401
23728
|
}
|
|
23402
|
-
)
|
|
23403
|
-
|
|
23404
|
-
|
|
23405
|
-
|
|
23406
|
-
),
|
|
23407
|
-
/* @__PURE__ */ jsx(
|
|
23408
|
-
"div",
|
|
23409
|
-
{
|
|
23410
|
-
ref: scrollContainerRef,
|
|
23411
|
-
className: cn(
|
|
23412
|
-
"relative z-0 w-full min-w-0 overflow-auto bg-transparent",
|
|
23413
|
-
isBounded ? "min-h-0 flex-1" : "flex-none",
|
|
23414
|
-
"[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5",
|
|
23415
|
-
"[&::-webkit-scrollbar-track]:bg-transparent",
|
|
23416
|
-
"[&::-webkit-scrollbar-thumb]:bg-foreground/[0.08] [&::-webkit-scrollbar-thumb]:rounded-full",
|
|
23417
|
-
"[&::-webkit-scrollbar-thumb]:hover:bg-foreground/[0.15]"
|
|
23418
|
-
),
|
|
23419
|
-
onScroll: handleBodyScroll,
|
|
23420
|
-
children: /* @__PURE__ */ jsxs(
|
|
23421
|
-
"div",
|
|
23422
|
-
{
|
|
23423
|
-
ref: rowsClipRef,
|
|
23424
|
-
"data-data-grid-rows-clip": "",
|
|
23425
|
-
className: "relative z-0",
|
|
23426
|
-
style: {
|
|
23427
|
-
minWidth: totalContentWidth,
|
|
23428
|
-
clipPath: "inset(var(--data-grid-sticky-overlap, 0px) 0 0 0)"
|
|
23429
|
-
},
|
|
23430
|
-
children: [
|
|
23431
|
-
isLoading && /* @__PURE__ */ jsx("div", { style: { minWidth: totalContentWidth }, children: loadingState ?? Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
23432
|
-
SkeletonRow,
|
|
23433
|
-
{
|
|
23434
|
-
columns: visibleColumns,
|
|
23435
|
-
height: estimatedRowHeight,
|
|
23436
|
-
showCheckbox: selectionMode !== "none"
|
|
23437
|
-
},
|
|
23438
|
-
i
|
|
23439
|
-
)) }),
|
|
23440
|
-
!isLoading && rows.length === 0 && /* @__PURE__ */ jsx(
|
|
23441
|
-
"div",
|
|
23442
|
-
{
|
|
23443
|
-
className: "flex items-center justify-center py-16 text-sm text-muted-foreground",
|
|
23444
|
-
style: { minWidth: totalContentWidth },
|
|
23445
|
-
children: emptyState ?? strings.noData
|
|
23446
|
-
}
|
|
23447
|
-
),
|
|
23448
|
-
!isLoading && rows.length > 0 && /* @__PURE__ */ jsx(
|
|
23729
|
+
) }),
|
|
23730
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
23731
|
+
isRefetching && /* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 right-0 h-0.5 z-30 bg-foreground/[0.04] overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "h-full w-1/3 bg-blue-500/60 rounded-full animate-pulse" }) }),
|
|
23732
|
+
/* @__PURE__ */ jsx(
|
|
23449
23733
|
"div",
|
|
23450
23734
|
{
|
|
23451
|
-
|
|
23452
|
-
|
|
23453
|
-
|
|
23454
|
-
|
|
23455
|
-
|
|
23456
|
-
|
|
23457
|
-
|
|
23458
|
-
|
|
23459
|
-
|
|
23460
|
-
|
|
23461
|
-
|
|
23462
|
-
|
|
23463
|
-
|
|
23464
|
-
|
|
23465
|
-
|
|
23466
|
-
|
|
23467
|
-
|
|
23468
|
-
|
|
23469
|
-
|
|
23470
|
-
|
|
23471
|
-
|
|
23472
|
-
|
|
23473
|
-
|
|
23474
|
-
|
|
23735
|
+
ref: headerScrollRef,
|
|
23736
|
+
className: "w-full min-w-0 shrink-0 overflow-hidden border-b border-foreground/[0.06]",
|
|
23737
|
+
children: /* @__PURE__ */ jsxs(
|
|
23738
|
+
"div",
|
|
23739
|
+
{
|
|
23740
|
+
className: "flex",
|
|
23741
|
+
style: { height: headerHeight, minWidth: totalContentWidth },
|
|
23742
|
+
role: "row",
|
|
23743
|
+
children: [
|
|
23744
|
+
selectionMode !== "none" && /* @__PURE__ */ jsx(
|
|
23745
|
+
"div",
|
|
23746
|
+
{
|
|
23747
|
+
className: "flex items-center justify-center border-r border-foreground/[0.04]",
|
|
23748
|
+
style: { width: 44 },
|
|
23749
|
+
children: selectionMode === "multiple" && /* @__PURE__ */ jsx(
|
|
23750
|
+
SelectionCheckbox,
|
|
23751
|
+
{
|
|
23752
|
+
checked: allSelected,
|
|
23753
|
+
indeterminate: someSelected,
|
|
23754
|
+
onChange: handleSelectAll,
|
|
23755
|
+
ariaLabel: "Select all rows on this page",
|
|
23756
|
+
title: "Select all rows on this page"
|
|
23757
|
+
}
|
|
23758
|
+
)
|
|
23759
|
+
}
|
|
23475
23760
|
),
|
|
23476
|
-
|
|
23477
|
-
|
|
23478
|
-
|
|
23479
|
-
|
|
23480
|
-
|
|
23481
|
-
|
|
23482
|
-
|
|
23483
|
-
|
|
23484
|
-
if (!shouldIgnoreRowClick(e40)) onRowDoubleClick?.(row, rowId, e40);
|
|
23485
|
-
},
|
|
23486
|
-
role: "row",
|
|
23487
|
-
"aria-rowindex": virtualRow.index + 2,
|
|
23488
|
-
"aria-selected": isSelected,
|
|
23489
|
-
"data-row-id": rowId,
|
|
23490
|
-
"data-state": isSelected ? "selected" : void 0,
|
|
23491
|
-
children: [
|
|
23492
|
-
selectionMode !== "none" && /* @__PURE__ */ jsx(
|
|
23493
|
-
"div",
|
|
23494
|
-
{
|
|
23495
|
-
className: "flex items-center justify-center border-r border-black/[0.04] dark:border-white/[0.04]",
|
|
23496
|
-
style: { width: 44 },
|
|
23497
|
-
children: /* @__PURE__ */ jsx(
|
|
23498
|
-
SelectionCheckbox,
|
|
23499
|
-
{
|
|
23500
|
-
checked: isSelected,
|
|
23501
|
-
onChange: (event) => handleRowClick(row, rowId, event),
|
|
23502
|
-
ariaLabel: `Select row ${rowId}`
|
|
23503
|
-
}
|
|
23504
|
-
)
|
|
23505
|
-
}
|
|
23506
|
-
),
|
|
23507
|
-
visibleColumns.map((col) => /* @__PURE__ */ jsx(
|
|
23508
|
-
DataCell,
|
|
23509
|
-
{
|
|
23510
|
-
col,
|
|
23511
|
-
row,
|
|
23512
|
-
rowId,
|
|
23513
|
-
rowIndex: virtualRow.index,
|
|
23514
|
-
isSelected,
|
|
23515
|
-
dateDisplay: state.dateDisplay
|
|
23516
|
-
},
|
|
23517
|
-
col.id
|
|
23518
|
-
))
|
|
23519
|
-
]
|
|
23520
|
-
},
|
|
23521
|
-
rowId
|
|
23522
|
-
);
|
|
23523
|
-
})
|
|
23524
|
-
}
|
|
23525
|
-
),
|
|
23526
|
-
paginationMode === "infinite" && hasMore && !isLoading && /* @__PURE__ */ jsx(
|
|
23527
|
-
InfiniteScrollSentinel,
|
|
23528
|
-
{
|
|
23529
|
-
onIntersect: onLoadMore ?? NOOP,
|
|
23530
|
-
isLoading: isLoadingMore,
|
|
23531
|
-
rootRef: infiniteScrollRootRef,
|
|
23532
|
-
strings
|
|
23761
|
+
visibleColumns.map((col) => {
|
|
23762
|
+
const header = headerByColId.get(col.id);
|
|
23763
|
+
if (!header) return null;
|
|
23764
|
+
return /* @__PURE__ */ jsx(HeaderCell, { header, col, resizable }, col.id);
|
|
23765
|
+
})
|
|
23766
|
+
]
|
|
23767
|
+
}
|
|
23768
|
+
)
|
|
23533
23769
|
}
|
|
23534
23770
|
)
|
|
23535
|
-
]
|
|
23536
|
-
|
|
23537
|
-
|
|
23538
|
-
|
|
23539
|
-
|
|
23540
|
-
|
|
23541
|
-
|
|
23542
|
-
|
|
23543
|
-
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
|
|
23771
|
+
] })
|
|
23772
|
+
]
|
|
23773
|
+
}
|
|
23774
|
+
),
|
|
23775
|
+
/* @__PURE__ */ jsx(
|
|
23776
|
+
"div",
|
|
23777
|
+
{
|
|
23778
|
+
ref: scrollContainerRef,
|
|
23779
|
+
className: cn(
|
|
23780
|
+
"relative z-0 w-full min-w-0 overflow-auto bg-transparent",
|
|
23781
|
+
isBounded ? "min-h-0 flex-1" : "flex-none",
|
|
23782
|
+
"[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5",
|
|
23783
|
+
"[&::-webkit-scrollbar-track]:bg-transparent",
|
|
23784
|
+
"[&::-webkit-scrollbar-thumb]:bg-foreground/[0.08] [&::-webkit-scrollbar-thumb]:rounded-full",
|
|
23785
|
+
"[&::-webkit-scrollbar-thumb]:hover:bg-foreground/[0.15]"
|
|
23786
|
+
),
|
|
23787
|
+
onScroll: handleBodyScroll,
|
|
23788
|
+
children: /* @__PURE__ */ jsxs(
|
|
23789
|
+
"div",
|
|
23790
|
+
{
|
|
23791
|
+
ref: rowsClipRef,
|
|
23792
|
+
"data-data-grid-rows-clip": "",
|
|
23793
|
+
className: "relative z-0",
|
|
23794
|
+
style: {
|
|
23795
|
+
minWidth: totalContentWidth,
|
|
23796
|
+
clipPath: "inset(var(--data-grid-sticky-overlap, 0px) 0 0 0)"
|
|
23797
|
+
},
|
|
23798
|
+
children: [
|
|
23799
|
+
isLoading && /* @__PURE__ */ jsx("div", { style: { minWidth: totalContentWidth }, children: loadingState ?? Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
23800
|
+
SkeletonRow,
|
|
23801
|
+
{
|
|
23802
|
+
columns: visibleColumns,
|
|
23803
|
+
height: estimatedRowHeight,
|
|
23804
|
+
showCheckbox: selectionMode !== "none"
|
|
23805
|
+
},
|
|
23806
|
+
i
|
|
23807
|
+
)) }),
|
|
23808
|
+
!isLoading && rows.length === 0 && /* @__PURE__ */ jsx(
|
|
23809
|
+
"div",
|
|
23810
|
+
{
|
|
23811
|
+
className: "flex items-center justify-center py-16 text-sm text-muted-foreground",
|
|
23812
|
+
style: { minWidth: totalContentWidth },
|
|
23813
|
+
children: emptyState ?? strings.noData
|
|
23814
|
+
}
|
|
23815
|
+
),
|
|
23816
|
+
!isLoading && rows.length > 0 && /* @__PURE__ */ jsx(
|
|
23817
|
+
"div",
|
|
23818
|
+
{
|
|
23819
|
+
style: {
|
|
23820
|
+
height: rowVirtualizer.getTotalSize(),
|
|
23821
|
+
width: "100%",
|
|
23822
|
+
minWidth: totalContentWidth,
|
|
23823
|
+
position: "relative"
|
|
23824
|
+
},
|
|
23825
|
+
children: rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
|
23826
|
+
const row = rows[virtualRow.index] ?? throwErr(
|
|
23827
|
+
`DataGrid: virtualized row index ${virtualRow.index} out of range (rows.length=${rows.length})`
|
|
23828
|
+
);
|
|
23829
|
+
const rowId = getRowId(row);
|
|
23830
|
+
const isSelected = state.selection.selectedIds.has(rowId);
|
|
23831
|
+
const isOddRow = virtualRow.index % 2 === 1;
|
|
23832
|
+
return /* @__PURE__ */ jsxs(
|
|
23833
|
+
"div",
|
|
23834
|
+
{
|
|
23835
|
+
ref: isDynamicRowHeight ? rowVirtualizer.measureElement : void 0,
|
|
23836
|
+
"data-index": virtualRow.index,
|
|
23837
|
+
className: cn(
|
|
23838
|
+
"absolute left-0 w-full flex",
|
|
23839
|
+
"border-b border-black/[0.03] dark:border-white/[0.03]",
|
|
23840
|
+
"transition-colors duration-75",
|
|
23841
|
+
isSelected ? "bg-blue-500/[0.06] dark:bg-blue-400/[0.08] hover:bg-blue-500/[0.08] dark:hover:bg-blue-400/[0.1]" : isOddRow ? "bg-foreground/[0.02] dark:bg-foreground/[0.03] hover:bg-foreground/[0.04] dark:hover:bg-foreground/[0.06]" : "hover:bg-foreground/[0.025] dark:hover:bg-foreground/[0.04]",
|
|
23842
|
+
(selectionMode !== "none" || onRowClick) && "cursor-pointer"
|
|
23843
|
+
),
|
|
23844
|
+
style: {
|
|
23845
|
+
...isDynamicRowHeight ? { minHeight: estimatedRowHeight } : { height: fixedRowHeight },
|
|
23846
|
+
transform: `translateY(${virtualRow.start}px)`
|
|
23847
|
+
},
|
|
23848
|
+
onClick: (e40) => {
|
|
23849
|
+
if (!shouldIgnoreRowClick(e40)) handleRowClick(row, rowId, e40);
|
|
23850
|
+
},
|
|
23851
|
+
onDoubleClick: (e40) => {
|
|
23852
|
+
if (!shouldIgnoreRowClick(e40)) onRowDoubleClick?.(row, rowId, e40);
|
|
23853
|
+
},
|
|
23854
|
+
role: "row",
|
|
23855
|
+
"aria-rowindex": virtualRow.index + 2,
|
|
23856
|
+
"aria-selected": isSelected,
|
|
23857
|
+
"data-row-id": rowId,
|
|
23858
|
+
"data-state": isSelected ? "selected" : void 0,
|
|
23859
|
+
children: [
|
|
23860
|
+
selectionMode !== "none" && /* @__PURE__ */ jsx(
|
|
23861
|
+
"div",
|
|
23862
|
+
{
|
|
23863
|
+
className: "flex items-center justify-center border-r border-black/[0.04] dark:border-white/[0.04]",
|
|
23864
|
+
style: { width: 44 },
|
|
23865
|
+
children: /* @__PURE__ */ jsx(
|
|
23866
|
+
SelectionCheckbox,
|
|
23867
|
+
{
|
|
23868
|
+
checked: isSelected,
|
|
23869
|
+
onChange: (event) => handleRowClick(row, rowId, event),
|
|
23870
|
+
ariaLabel: `Select row ${rowId}`
|
|
23871
|
+
}
|
|
23872
|
+
)
|
|
23873
|
+
}
|
|
23874
|
+
),
|
|
23875
|
+
visibleColumns.map((col) => /* @__PURE__ */ jsx(
|
|
23876
|
+
DataCell,
|
|
23877
|
+
{
|
|
23878
|
+
col,
|
|
23879
|
+
row,
|
|
23880
|
+
rowId,
|
|
23881
|
+
rowIndex: virtualRow.index,
|
|
23882
|
+
isSelected,
|
|
23883
|
+
dateDisplay: state.dateDisplay
|
|
23884
|
+
},
|
|
23885
|
+
col.id
|
|
23886
|
+
))
|
|
23887
|
+
]
|
|
23888
|
+
},
|
|
23889
|
+
rowId
|
|
23890
|
+
);
|
|
23891
|
+
})
|
|
23892
|
+
}
|
|
23893
|
+
),
|
|
23894
|
+
paginationMode === "infinite" && hasMore && !isLoading && /* @__PURE__ */ jsx(
|
|
23895
|
+
InfiniteScrollSentinel,
|
|
23896
|
+
{
|
|
23897
|
+
onIntersect: onLoadMore ?? NOOP,
|
|
23898
|
+
isLoading: isLoadingMore,
|
|
23899
|
+
rootRef: infiniteScrollRootRef,
|
|
23900
|
+
strings
|
|
23901
|
+
}
|
|
23902
|
+
)
|
|
23903
|
+
]
|
|
23904
|
+
}
|
|
23905
|
+
)
|
|
23906
|
+
}
|
|
23907
|
+
),
|
|
23908
|
+
footer !== false && /* @__PURE__ */ jsxs("div", { className: "sticky bottom-0 z-30 shrink-0 overflow-hidden rounded-b-[calc(var(--radius)*2)] bg-white/90 dark:bg-background/60 backdrop-blur-xl", children: [
|
|
23909
|
+
footer ? footer(footerCtx) : /* @__PURE__ */ jsx(DefaultFooter, { ctx: footerCtx, pagination: paginationMode, onChange }),
|
|
23910
|
+
footerExtra && (typeof footerExtra === "function" ? footerExtra(footerCtx) : footerExtra)
|
|
23911
|
+
] })
|
|
23912
|
+
]
|
|
23913
|
+
}
|
|
23914
|
+
)
|
|
23915
|
+
] });
|
|
23547
23916
|
}
|
|
23548
23917
|
|
|
23549
23918
|
// src/components/data-grid/use-data-source.ts
|
|
23550
|
-
var
|
|
23919
|
+
var import_react36 = __toESM(require_react());
|
|
23551
23920
|
function useClientDataSource(opts) {
|
|
23552
23921
|
const { data, columns, sorting, quickSearch, matchRow, pagination, paginationMode } = opts;
|
|
23553
23922
|
const sortingKey = JSON.stringify(sorting);
|
|
23554
|
-
const processed = (0,
|
|
23923
|
+
const processed = (0, import_react36.useMemo)(() => {
|
|
23555
23924
|
const searched = applyQuickSearch(data, quickSearch, columns, matchRow);
|
|
23556
23925
|
const comparator = buildRowComparator(sorting, columns);
|
|
23557
23926
|
const sorted = comparator ? [...searched].sort(comparator) : searched;
|
|
@@ -23559,7 +23928,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23559
23928
|
const paged = paginationMode === "client" ? paginateRows(sorted, pagination) : sorted;
|
|
23560
23929
|
return { rows: paged, totalRowCount };
|
|
23561
23930
|
}, [data, sortingKey, quickSearch, matchRow, pagination.pageIndex, pagination.pageSize, paginationMode, columns]);
|
|
23562
|
-
return (0,
|
|
23931
|
+
return (0, import_react36.useMemo)(() => ({
|
|
23563
23932
|
rows: processed.rows,
|
|
23564
23933
|
totalRowCount: processed.totalRowCount,
|
|
23565
23934
|
isLoading: false,
|
|
@@ -23582,19 +23951,19 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23582
23951
|
pagination,
|
|
23583
23952
|
paginationMode
|
|
23584
23953
|
} = opts;
|
|
23585
|
-
const [rows, setRows] = (0,
|
|
23586
|
-
const [totalRowCount, setTotalRowCount] = (0,
|
|
23587
|
-
const [isLoading, setIsLoading] = (0,
|
|
23588
|
-
const [isRefetching, setIsRefetching] = (0,
|
|
23589
|
-
const [isLoadingMore, setIsLoadingMore] = (0,
|
|
23590
|
-
const [hasMore, setHasMore] = (0,
|
|
23591
|
-
const [error, setError] = (0,
|
|
23592
|
-
const cursorRef = (0,
|
|
23593
|
-
const abortRef = (0,
|
|
23594
|
-
const pageIndexRef = (0,
|
|
23595
|
-
const hasDataRef = (0,
|
|
23596
|
-
const hasMountedServerPaginationRef = (0,
|
|
23597
|
-
const latestArgsRef = (0,
|
|
23954
|
+
const [rows, setRows] = (0, import_react36.useState)([]);
|
|
23955
|
+
const [totalRowCount, setTotalRowCount] = (0, import_react36.useState)(void 0);
|
|
23956
|
+
const [isLoading, setIsLoading] = (0, import_react36.useState)(true);
|
|
23957
|
+
const [isRefetching, setIsRefetching] = (0, import_react36.useState)(false);
|
|
23958
|
+
const [isLoadingMore, setIsLoadingMore] = (0, import_react36.useState)(false);
|
|
23959
|
+
const [hasMore, setHasMore] = (0, import_react36.useState)(true);
|
|
23960
|
+
const [error, setError] = (0, import_react36.useState)(null);
|
|
23961
|
+
const cursorRef = (0, import_react36.useRef)(void 0);
|
|
23962
|
+
const abortRef = (0, import_react36.useRef)(null);
|
|
23963
|
+
const pageIndexRef = (0, import_react36.useRef)(0);
|
|
23964
|
+
const hasDataRef = (0, import_react36.useRef)(false);
|
|
23965
|
+
const hasMountedServerPaginationRef = (0, import_react36.useRef)(false);
|
|
23966
|
+
const latestArgsRef = (0, import_react36.useRef)({
|
|
23598
23967
|
dataSource,
|
|
23599
23968
|
getRowId,
|
|
23600
23969
|
sorting,
|
|
@@ -23604,7 +23973,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23604
23973
|
latestArgsRef.current = { dataSource, getRowId, sorting, quickSearch, pagination };
|
|
23605
23974
|
const sortingKey = JSON.stringify(sorting);
|
|
23606
23975
|
const quickSearchKey = quickSearch;
|
|
23607
|
-
const fetchPage = (0,
|
|
23976
|
+
const fetchPage = (0, import_react36.useCallback)(
|
|
23608
23977
|
async (append) => {
|
|
23609
23978
|
const {
|
|
23610
23979
|
dataSource: currentDataSource,
|
|
@@ -23673,12 +24042,12 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23673
24042
|
},
|
|
23674
24043
|
[]
|
|
23675
24044
|
);
|
|
23676
|
-
(0,
|
|
24045
|
+
(0, import_react36.useEffect)(() => {
|
|
23677
24046
|
fetchPage(false).catch(() => {
|
|
23678
24047
|
});
|
|
23679
24048
|
return () => abortRef.current?.abort();
|
|
23680
24049
|
}, [fetchPage, dataSource, sortingKey, quickSearchKey, pagination.pageSize]);
|
|
23681
|
-
(0,
|
|
24050
|
+
(0, import_react36.useEffect)(() => {
|
|
23682
24051
|
if (paginationMode !== "server") {
|
|
23683
24052
|
hasMountedServerPaginationRef.current = false;
|
|
23684
24053
|
return;
|
|
@@ -23690,13 +24059,13 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23690
24059
|
fetchPage(false).catch(() => {
|
|
23691
24060
|
});
|
|
23692
24061
|
}, [fetchPage, paginationMode, pagination.pageIndex]);
|
|
23693
|
-
const loadMore = (0,
|
|
24062
|
+
const loadMore = (0, import_react36.useCallback)(() => {
|
|
23694
24063
|
if (!isLoadingMore && hasMore && paginationMode === "infinite") {
|
|
23695
24064
|
fetchPage(true).catch(() => {
|
|
23696
24065
|
});
|
|
23697
24066
|
}
|
|
23698
24067
|
}, [isLoadingMore, hasMore, paginationMode, fetchPage]);
|
|
23699
|
-
const reload = (0,
|
|
24068
|
+
const reload = (0, import_react36.useCallback)(() => {
|
|
23700
24069
|
fetchPage(false).catch(() => {
|
|
23701
24070
|
});
|
|
23702
24071
|
}, [fetchPage]);
|
|
@@ -23759,7 +24128,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23759
24128
|
}
|
|
23760
24129
|
|
|
23761
24130
|
// src/components/data-grid/use-url-state.ts
|
|
23762
|
-
var
|
|
24131
|
+
var import_react37 = __toESM(require_react());
|
|
23763
24132
|
function serializeWidths(widths, columns) {
|
|
23764
24133
|
const parts = [];
|
|
23765
24134
|
for (const col of columns) {
|
|
@@ -23855,10 +24224,10 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23855
24224
|
const hiddenKey = `${prefix}_h`;
|
|
23856
24225
|
const sortKey = `${prefix}_s`;
|
|
23857
24226
|
const searchKey = `${prefix}_q`;
|
|
23858
|
-
const columnsRef = (0,
|
|
24227
|
+
const columnsRef = (0, import_react37.useRef)(columns);
|
|
23859
24228
|
columnsRef.current = columns;
|
|
23860
|
-
const initialRef = (0,
|
|
23861
|
-
const [state, setState] = (0,
|
|
24229
|
+
const initialRef = (0, import_react37.useRef)(opts?.initial);
|
|
24230
|
+
const [state, setState] = (0, import_react37.useState)(() => {
|
|
23862
24231
|
const base = createDefaultDataGridState(columns);
|
|
23863
24232
|
const initial = initialRef.current ?? {};
|
|
23864
24233
|
const baseWithInitial = {
|
|
@@ -23877,7 +24246,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23877
24246
|
quickSearch: parseQuickSearch(params.get(searchKey), baseWithInitial.quickSearch)
|
|
23878
24247
|
};
|
|
23879
24248
|
});
|
|
23880
|
-
(0,
|
|
24249
|
+
(0, import_react37.useEffect)(() => {
|
|
23881
24250
|
if (typeof window === "undefined") return;
|
|
23882
24251
|
const timer = setTimeout(() => {
|
|
23883
24252
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -23914,7 +24283,7 @@ ${colorConfig.map(([key, itemConfig]) => {
|
|
|
23914
24283
|
sortKey,
|
|
23915
24284
|
searchKey
|
|
23916
24285
|
]);
|
|
23917
|
-
(0,
|
|
24286
|
+
(0, import_react37.useEffect)(() => {
|
|
23918
24287
|
if (typeof window === "undefined") return;
|
|
23919
24288
|
const onPop = () => {
|
|
23920
24289
|
const params = new URLSearchParams(window.location.search);
|