@flanksource/clicky-ui 0.2.9 → 0.2.11
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/Combobox.cjs +4 -1
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts +6 -0
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +4 -1
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +24 -5
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +24 -5
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/json-schema-form-array.cjs +117 -37
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +118 -38
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-fields.cjs +121 -51
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts +9 -6
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +121 -51
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +15 -8
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts +5 -2
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +15 -8
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +41 -6
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +41 -6
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-size.cjs +61 -0
- package/dist/components/json-schema-form-size.cjs.map +1 -0
- package/dist/components/json-schema-form-size.d.ts +11 -0
- package/dist/components/json-schema-form-size.d.ts.map +1 -0
- package/dist/components/json-schema-form-size.js +61 -0
- package/dist/components/json-schema-form-size.js.map +1 -0
- package/dist/components/json-schema-form-types.d.ts +36 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components.cjs +2 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +2 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +412 -90
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts +4 -2
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +413 -91
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +534 -293
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +12 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +534 -293
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data.d.ts +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/rpc/CommandOutput.cjs +101 -20
- package/dist/rpc/CommandOutput.cjs.map +1 -1
- package/dist/rpc/CommandOutput.d.ts +12 -4
- package/dist/rpc/CommandOutput.d.ts.map +1 -1
- package/dist/rpc/CommandOutput.js +102 -21
- package/dist/rpc/CommandOutput.js.map +1 -1
- package/dist/rpc/ExecutionResult.cjs +4 -76
- package/dist/rpc/ExecutionResult.cjs.map +1 -1
- package/dist/rpc/ExecutionResult.d.ts +3 -22
- package/dist/rpc/ExecutionResult.d.ts.map +1 -1
- package/dist/rpc/ExecutionResult.js +4 -76
- package/dist/rpc/ExecutionResult.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +22 -13
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +24 -15
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +10 -20
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +11 -21
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/apiClient.cjs +18 -0
- package/dist/rpc/apiClient.cjs.map +1 -1
- package/dist/rpc/apiClient.d.ts.map +1 -1
- package/dist/rpc/apiClient.js +18 -0
- package/dist/rpc/apiClient.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +31 -0
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts +3 -1
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +31 -0
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +7 -0
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/data/DataTable.js
CHANGED
|
@@ -14,6 +14,8 @@ import { StatusDot } from "./cells/StatusDot.js";
|
|
|
14
14
|
import { normalizeStatus } from "./cells/status-mapping.js";
|
|
15
15
|
import { UiEllipsis } from "../icons/components/UiEllipsis.js";
|
|
16
16
|
import { UiFilterFilled, UiFilter } from "../icons/components/UiFilter.js";
|
|
17
|
+
import { UiArrowLeft } from "../icons/components/UiArrowLeft.js";
|
|
18
|
+
import { UiArrowRight } from "../icons/components/UiArrowRight.js";
|
|
17
19
|
import { UiEyeClosed } from "../icons/components/UiEyeClosed.js";
|
|
18
20
|
import { UiClose } from "../icons/components/UiClose.js";
|
|
19
21
|
import { UiFullscreen } from "../icons/components/UiFullscreen.js";
|
|
@@ -90,7 +92,8 @@ function DataTableInner({
|
|
|
90
92
|
themeMenuValue,
|
|
91
93
|
onThemeChange,
|
|
92
94
|
showThemeControl = false,
|
|
93
|
-
showHeaderFilters = true
|
|
95
|
+
showHeaderFilters = true,
|
|
96
|
+
menuActions
|
|
94
97
|
}) {
|
|
95
98
|
const columns = useMemo(
|
|
96
99
|
() => columnsInput.map(
|
|
@@ -145,7 +148,11 @@ function DataTableInner({
|
|
|
145
148
|
const next = pruneColumnWidths({ ...stored, ...current }, columns);
|
|
146
149
|
return sameColumnWidths(current, next) ? current : next;
|
|
147
150
|
});
|
|
148
|
-
}, [
|
|
151
|
+
}, [
|
|
152
|
+
columnKeysSignature,
|
|
153
|
+
persistColumnWidths,
|
|
154
|
+
resolvedColumnResizeStorageKey
|
|
155
|
+
]);
|
|
149
156
|
useEffect(() => {
|
|
150
157
|
if (!persistColumnWidths) return;
|
|
151
158
|
writeStoredColumnWidths(resolvedColumnResizeStorageKey, columnWidths);
|
|
@@ -156,21 +163,39 @@ function DataTableInner({
|
|
|
156
163
|
const next = pruneHiddenColumns({ ...stored, ...current }, columns);
|
|
157
164
|
return sameHiddenColumns(current, next) ? current : next;
|
|
158
165
|
});
|
|
159
|
-
}, [
|
|
166
|
+
}, [
|
|
167
|
+
columnKeysSignature,
|
|
168
|
+
persistColumnVisibility,
|
|
169
|
+
resolvedColumnVisibilityStorageKey
|
|
170
|
+
]);
|
|
160
171
|
useEffect(() => {
|
|
161
172
|
if (!persistColumnVisibility) return;
|
|
162
173
|
writeStoredHiddenColumns(resolvedColumnVisibilityStorageKey, hiddenColumns);
|
|
163
|
-
}, [
|
|
174
|
+
}, [
|
|
175
|
+
hiddenColumns,
|
|
176
|
+
persistColumnVisibility,
|
|
177
|
+
resolvedColumnVisibilityStorageKey
|
|
178
|
+
]);
|
|
164
179
|
useEffect(() => {
|
|
165
180
|
if (densityControlled) return;
|
|
166
181
|
setLocalDensityOverride(
|
|
167
182
|
persistDensity ? readStoredDensityOverride(resolvedDensityStorageKey) ?? defaultDensity : defaultDensity
|
|
168
183
|
);
|
|
169
|
-
}, [
|
|
184
|
+
}, [
|
|
185
|
+
defaultDensity,
|
|
186
|
+
densityControlled,
|
|
187
|
+
persistDensity,
|
|
188
|
+
resolvedDensityStorageKey
|
|
189
|
+
]);
|
|
170
190
|
useEffect(() => {
|
|
171
191
|
if (densityControlled || !persistDensity) return;
|
|
172
192
|
writeStoredDensityOverride(resolvedDensityStorageKey, localDensityOverride);
|
|
173
|
-
}, [
|
|
193
|
+
}, [
|
|
194
|
+
densityControlled,
|
|
195
|
+
localDensityOverride,
|
|
196
|
+
persistDensity,
|
|
197
|
+
resolvedDensityStorageKey
|
|
198
|
+
]);
|
|
174
199
|
useEffect(() => {
|
|
175
200
|
if (!columnMenu && !headerFilterMenu) return;
|
|
176
201
|
const close = () => {
|
|
@@ -206,17 +231,24 @@ function DataTableInner({
|
|
|
206
231
|
if (parsed) dates.push(parsed);
|
|
207
232
|
}
|
|
208
233
|
const dataFormat = chooseTimestampFormat(dates);
|
|
209
|
-
out[column.key] = modeToFormat(
|
|
234
|
+
out[column.key] = modeToFormat(
|
|
235
|
+
((_a = column.timestamp) == null ? void 0 : _a.mode) ?? "auto",
|
|
236
|
+
dataFormat
|
|
237
|
+
);
|
|
210
238
|
}
|
|
211
239
|
return out;
|
|
212
240
|
}, [columns, data]);
|
|
213
241
|
const effectiveColumns = useMemo(
|
|
214
|
-
() => columns.map(
|
|
242
|
+
() => columns.map(
|
|
243
|
+
(column) => applyKindDefaults(column, timestampFormats[column.key])
|
|
244
|
+
),
|
|
215
245
|
[columns, timestampFormats]
|
|
216
246
|
);
|
|
217
247
|
const visibleColumns = useMemo(() => {
|
|
218
248
|
if (!hideableColumns) return effectiveColumns;
|
|
219
|
-
const next = effectiveColumns.filter(
|
|
249
|
+
const next = effectiveColumns.filter(
|
|
250
|
+
(column) => !hiddenColumns[column.key]
|
|
251
|
+
);
|
|
220
252
|
return next.length > 0 ? next : effectiveColumns;
|
|
221
253
|
}, [effectiveColumns, hiddenColumns, hideableColumns]);
|
|
222
254
|
const hideableColumnCount = useMemo(
|
|
@@ -229,7 +261,8 @@ function DataTableInner({
|
|
|
229
261
|
);
|
|
230
262
|
const showColumnVisibilityControl = hideableColumns && hideableColumnCount > 1;
|
|
231
263
|
const resolvedShowDensityControl = showDensityControl ?? showColumnVisibilityControl;
|
|
232
|
-
const
|
|
264
|
+
const hasMenuActions = Boolean(menuActions && menuActions.length > 0);
|
|
265
|
+
const showTablePreferencesControl = showColumnVisibilityControl || resolvedShowDensityControl || showThemeControl || hasMenuActions;
|
|
233
266
|
const densityOverride = densityControlled ? density : localDensityOverride;
|
|
234
267
|
const timeRangeColumn = useMemo(() => {
|
|
235
268
|
if (filterBarProps == null ? void 0 : filterBarProps.timeRange) return null;
|
|
@@ -267,7 +300,9 @@ function DataTableInner({
|
|
|
267
300
|
if (token) values.add(token);
|
|
268
301
|
}
|
|
269
302
|
}
|
|
270
|
-
const options = Array.from(values).sort(
|
|
303
|
+
const options = Array.from(values).sort(
|
|
304
|
+
(left, right) => left.localeCompare(right, void 0, { numeric: true })
|
|
305
|
+
).map((value) => ({ value, label: value }));
|
|
271
306
|
const multiCap = column.kind === "tags" ? 50 : 20;
|
|
272
307
|
const fitsMulti = options.length >= 2 && options.length <= multiCap;
|
|
273
308
|
if (column.kind === "tags" && fitsMulti) {
|
|
@@ -301,9 +336,15 @@ function DataTableInner({
|
|
|
301
336
|
return out;
|
|
302
337
|
}, [generatedFilters, multiFilters]);
|
|
303
338
|
useEffect(() => {
|
|
304
|
-
setTextFilters(
|
|
305
|
-
|
|
306
|
-
|
|
339
|
+
setTextFilters(
|
|
340
|
+
(current) => pruneTextFilterState(current, generatedFilters)
|
|
341
|
+
);
|
|
342
|
+
setMultiFilters(
|
|
343
|
+
(current) => pruneMultiFilterState(current, generatedFilters)
|
|
344
|
+
);
|
|
345
|
+
setNumberFilters(
|
|
346
|
+
(current) => pruneNumberFilterState(current, generatedFilters)
|
|
347
|
+
);
|
|
307
348
|
}, [generatedFilters]);
|
|
308
349
|
const globalFilterControlled = globalFilter !== void 0;
|
|
309
350
|
const effectiveGlobalFilter = globalFilterControlled ? globalFilter : localGlobalFilter;
|
|
@@ -319,7 +360,9 @@ function DataTableInner({
|
|
|
319
360
|
kind: "multi",
|
|
320
361
|
label: labelText(filter.column),
|
|
321
362
|
value: multiFilters[columnKey] ?? {},
|
|
322
|
-
onChange: (next) => setMultiFilters(
|
|
363
|
+
onChange: (next) => setMultiFilters(
|
|
364
|
+
(current) => updateFilterRecord(current, columnKey, next)
|
|
365
|
+
),
|
|
323
366
|
options: filter.options
|
|
324
367
|
};
|
|
325
368
|
}
|
|
@@ -329,7 +372,9 @@ function DataTableInner({
|
|
|
329
372
|
kind: "nested-multi",
|
|
330
373
|
label: labelText(filter.column),
|
|
331
374
|
value: multiFilters[columnKey] ?? {},
|
|
332
|
-
onChange: (next) => setMultiFilters(
|
|
375
|
+
onChange: (next) => setMultiFilters(
|
|
376
|
+
(current) => updateFilterRecord(current, columnKey, next)
|
|
377
|
+
),
|
|
333
378
|
groups: filter.groups ?? []
|
|
334
379
|
};
|
|
335
380
|
}
|
|
@@ -339,7 +384,9 @@ function DataTableInner({
|
|
|
339
384
|
kind: "number",
|
|
340
385
|
label: labelText(filter.column),
|
|
341
386
|
value: numberFilters[columnKey] ?? {},
|
|
342
|
-
onChange: (next) => setNumberFilters(
|
|
387
|
+
onChange: (next) => setNumberFilters(
|
|
388
|
+
(current) => updateNumberFilterValue(current, columnKey, next)
|
|
389
|
+
)
|
|
343
390
|
};
|
|
344
391
|
if (((_a = filter.numberBounds) == null ? void 0 : _a.min) !== void 0) {
|
|
345
392
|
numberFilter.domainMin = filter.numberBounds.min;
|
|
@@ -357,7 +404,9 @@ function DataTableInner({
|
|
|
357
404
|
kind: "text",
|
|
358
405
|
label: labelText(filter.column),
|
|
359
406
|
value: textFilters[columnKey] ?? "",
|
|
360
|
-
onChange: (next) => setTextFilters(
|
|
407
|
+
onChange: (next) => setTextFilters(
|
|
408
|
+
(current) => updateFilterValue(current, columnKey, next)
|
|
409
|
+
)
|
|
361
410
|
};
|
|
362
411
|
}),
|
|
363
412
|
[generatedFilters, multiFilters, numberFilters, textFilters]
|
|
@@ -399,7 +448,12 @@ function DataTableInner({
|
|
|
399
448
|
};
|
|
400
449
|
const filterBarTrailing = showTablePreferencesControl ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
401
450
|
filterBarProps == null ? void 0 : filterBarProps.trailing,
|
|
402
|
-
/* @__PURE__ */ jsx(
|
|
451
|
+
/* @__PURE__ */ jsx(
|
|
452
|
+
ColumnVisibilityTrigger,
|
|
453
|
+
{
|
|
454
|
+
onOpen: (event) => setColumnMenu(menuStateFromTrigger(event))
|
|
455
|
+
}
|
|
456
|
+
)
|
|
403
457
|
] }) : filterBarProps == null ? void 0 : filterBarProps.trailing;
|
|
404
458
|
const showHeaderFilterControls = autoFilter && showHeaderFilters;
|
|
405
459
|
const filteredRows = useMemo(() => {
|
|
@@ -413,7 +467,8 @@ function DataTableInner({
|
|
|
413
467
|
const raw = resolvePath(row, rangeColumnKey);
|
|
414
468
|
const ts = parseTimestamp(raw);
|
|
415
469
|
if (!ts) return false;
|
|
416
|
-
if (rangeFromDate && ts.getTime() < rangeFromDate.getTime())
|
|
470
|
+
if (rangeFromDate && ts.getTime() < rangeFromDate.getTime())
|
|
471
|
+
return false;
|
|
417
472
|
if (rangeToDate && ts.getTime() > rangeToDate.getTime()) return false;
|
|
418
473
|
}
|
|
419
474
|
if (globalNeedle) {
|
|
@@ -492,7 +547,10 @@ function DataTableInner({
|
|
|
492
547
|
const measuredWidth = (header == null ? void 0 : header.getBoundingClientRect().width) ?? 0;
|
|
493
548
|
const startWidth = measuredWidth || columnWidths[column.key] || defaultColumnWidth(column);
|
|
494
549
|
const onMove = (moveEvent) => {
|
|
495
|
-
const nextWidth = clampColumnWidth(
|
|
550
|
+
const nextWidth = clampColumnWidth(
|
|
551
|
+
column,
|
|
552
|
+
startWidth + moveEvent.clientX - startX
|
|
553
|
+
);
|
|
496
554
|
setColumnWidths((current) => ({
|
|
497
555
|
...current,
|
|
498
556
|
[column.key]: nextWidth
|
|
@@ -516,7 +574,9 @@ function DataTableInner({
|
|
|
516
574
|
const header = event.currentTarget.closest("th");
|
|
517
575
|
const table = event.currentTarget.closest("table");
|
|
518
576
|
if (!header || !table) return;
|
|
519
|
-
const columnIndex = Array.from(
|
|
577
|
+
const columnIndex = Array.from(
|
|
578
|
+
((_a = header.parentElement) == null ? void 0 : _a.children) ?? []
|
|
579
|
+
).indexOf(header);
|
|
520
580
|
if (columnIndex < 0) return;
|
|
521
581
|
const width = measureColumnContentWidth(table, columnIndex, column);
|
|
522
582
|
setColumnWidths((current) => ({
|
|
@@ -549,274 +609,325 @@ function DataTableInner({
|
|
|
549
609
|
event.stopPropagation();
|
|
550
610
|
setHeaderFilterMenu(menuStateFromTrigger(event, columnKey));
|
|
551
611
|
};
|
|
552
|
-
return /* @__PURE__ */ jsx(DensityValueProvider, { density: densityOverride ?? "comfortable", children: /* @__PURE__ */ jsxs(
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
612
|
+
return /* @__PURE__ */ jsx(DensityValueProvider, { density: densityOverride ?? "comfortable", children: /* @__PURE__ */ jsxs(
|
|
613
|
+
"div",
|
|
614
|
+
{
|
|
615
|
+
className: cn("flex min-h-0 flex-col gap-3", className),
|
|
616
|
+
"data-density": densityOverride,
|
|
617
|
+
children: [
|
|
618
|
+
showFilterBar && /* @__PURE__ */ jsx(
|
|
619
|
+
FilterBar,
|
|
620
|
+
{
|
|
621
|
+
...filterBarProps,
|
|
622
|
+
...externalSearch ? { search: externalSearch } : autoFilter && showGlobalFilter ? {
|
|
623
|
+
search: {
|
|
624
|
+
value: effectiveGlobalFilter,
|
|
625
|
+
onChange: setEffectiveGlobalFilter,
|
|
626
|
+
placeholder: globalFilterPlaceholder
|
|
627
|
+
}
|
|
628
|
+
} : {},
|
|
629
|
+
...externalTimeRange ? { timeRange: externalTimeRange } : autoTimeRange ? { timeRange: autoTimeRange } : {},
|
|
630
|
+
trailing: filterBarTrailing,
|
|
631
|
+
filters: externalFilters && externalFilters.length > 0 ? [...externalFilters, ...nativeFilters] : nativeFilters
|
|
562
632
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
},
|
|
581
|
-
column.key
|
|
582
|
-
)) }),
|
|
583
|
-
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-10 bg-muted shadow-[0_1px_0_0_var(--tw-shadow-color)] shadow-border", children: /* @__PURE__ */ jsx("tr", { className: "border-b border-border text-xs text-muted-foreground", children: visibleColumns.map((column) => /* @__PURE__ */ jsxs(
|
|
584
|
-
"th",
|
|
585
|
-
{
|
|
586
|
-
className: cn(
|
|
587
|
-
"group/header relative whitespace-nowrap font-medium",
|
|
588
|
-
DATA_TABLE_HEADER_DENSITY_CLASS,
|
|
589
|
-
alignmentClass(column.align),
|
|
590
|
-
resizableColumns && column.resizable !== false && "select-none",
|
|
591
|
-
column.headerClassName
|
|
592
|
-
),
|
|
593
|
-
onContextMenu: (event) => openHeaderColumnMenu(event, column),
|
|
594
|
-
children: [
|
|
595
|
-
/* @__PURE__ */ jsxs(
|
|
596
|
-
"div",
|
|
597
|
-
{
|
|
598
|
-
className: cn(
|
|
599
|
-
"flex min-w-0 items-center gap-1",
|
|
600
|
-
headerAlignmentClass(column.align),
|
|
601
|
-
resizableColumns && column.resizable !== false && "pr-2"
|
|
602
|
-
),
|
|
603
|
-
children: [
|
|
604
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0", children: column.sortable === false ? /* @__PURE__ */ jsx("span", { children: column.label }) : /* @__PURE__ */ jsx(
|
|
605
|
-
SortableHeader,
|
|
606
|
-
{
|
|
607
|
-
active: (sort == null ? void 0 : sort.key) === column.key,
|
|
608
|
-
...(sort == null ? void 0 : sort.key) === column.key ? { dir: sort.dir } : {},
|
|
609
|
-
...column.align ? { align: column.align } : {},
|
|
610
|
-
onClick: () => toggle(column.key),
|
|
611
|
-
children: column.label
|
|
612
|
-
}
|
|
613
|
-
) }),
|
|
614
|
-
showHeaderFilterControls && (nativeFilterByColumn.has(column.key) || autoTimeRange && (timeRangeColumn == null ? void 0 : timeRangeColumn.key) === column.key) && /* @__PURE__ */ jsx(
|
|
615
|
-
HeaderFilterButton,
|
|
616
|
-
{
|
|
617
|
-
column,
|
|
618
|
-
active: nativeFilterByColumn.has(column.key) ? isFilterBarFilterActive(nativeFilterByColumn.get(column.key)) : Boolean(timeRangeFilter.from || timeRangeFilter.to),
|
|
619
|
-
onOpen: (event) => openHeaderFilterMenu(event, column.key)
|
|
620
|
-
}
|
|
621
|
-
)
|
|
622
|
-
]
|
|
623
|
-
}
|
|
624
|
-
),
|
|
625
|
-
resizableColumns && column.resizable !== false && /* @__PURE__ */ jsx(
|
|
626
|
-
"span",
|
|
627
|
-
{
|
|
628
|
-
role: "separator",
|
|
629
|
-
"aria-label": `Resize ${labelText(column)} column`,
|
|
630
|
-
"aria-orientation": "vertical",
|
|
631
|
-
className: "absolute right-0 top-0 flex h-full w-3 cursor-col-resize touch-none items-center justify-center border-r border-border/70 bg-gradient-to-l from-border/30 to-transparent transition-colors hover:border-primary hover:from-primary/20",
|
|
632
|
-
onClick: (event) => {
|
|
633
|
-
event.preventDefault();
|
|
634
|
-
event.stopPropagation();
|
|
635
|
-
},
|
|
636
|
-
onDoubleClick: (event) => autoFitColumn(event, column),
|
|
637
|
-
onMouseDown: (event) => startColumnResize(event, column),
|
|
638
|
-
children: /* @__PURE__ */ jsx(
|
|
639
|
-
"span",
|
|
640
|
-
{
|
|
641
|
-
"aria-hidden": true,
|
|
642
|
-
className: "h-4 w-0.5 rounded-full bg-border transition-colors group-hover/header:bg-primary/70"
|
|
643
|
-
}
|
|
644
|
-
)
|
|
645
|
-
}
|
|
646
|
-
)
|
|
647
|
-
]
|
|
648
|
-
},
|
|
649
|
-
column.key
|
|
650
|
-
)) }) }),
|
|
651
|
-
/* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx(
|
|
652
|
-
DataTableLoadingRows,
|
|
653
|
-
{
|
|
654
|
-
columns: visibleColumns,
|
|
655
|
-
rowCount: loadingRowCount,
|
|
656
|
-
message: loadingMessage
|
|
657
|
-
}
|
|
658
|
-
) : sorted.map((record) => {
|
|
659
|
-
const href = getRowHref == null ? void 0 : getRowHref(record.row);
|
|
660
|
-
const expanded = expandedRows[record.id] ?? false;
|
|
661
|
-
const expandedContent = (renderExpandedRow == null ? void 0 : renderExpandedRow(record.row, {
|
|
662
|
-
columns: effectiveColumns,
|
|
663
|
-
visibleColumns,
|
|
664
|
-
filterActionsByColumn
|
|
665
|
-
})) ?? null;
|
|
666
|
-
const expandable = expandedContent !== null;
|
|
667
|
-
const expandsInline = expandable && detailStyle === "row";
|
|
668
|
-
const opensDialog = expandable && detailStyle === "dialog";
|
|
669
|
-
const rowClickEnabled = (isRowClickable == null ? void 0 : isRowClickable(record.row)) ?? !!onRowClick;
|
|
670
|
-
const clickable = !!href || rowClickEnabled || expandable;
|
|
671
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
672
|
-
/* @__PURE__ */ jsx(
|
|
673
|
-
"tr",
|
|
633
|
+
),
|
|
634
|
+
/* @__PURE__ */ jsx(
|
|
635
|
+
"div",
|
|
636
|
+
{
|
|
637
|
+
className: "min-h-0 flex-1 overflow-auto rounded-md border border-border",
|
|
638
|
+
"aria-busy": loading || void 0,
|
|
639
|
+
children: /* @__PURE__ */ jsxs("table", { className: "w-max table-auto text-left text-sm", children: [
|
|
640
|
+
/* @__PURE__ */ jsx("colgroup", { children: visibleColumns.map((column) => /* @__PURE__ */ jsx(
|
|
641
|
+
"col",
|
|
642
|
+
{
|
|
643
|
+
style: columnStyle(column, columnWidths),
|
|
644
|
+
className: column.shrink && !column.grow ? "w-px" : void 0
|
|
645
|
+
},
|
|
646
|
+
column.key
|
|
647
|
+
)) }),
|
|
648
|
+
/* @__PURE__ */ jsx("thead", { className: "sticky top-0 z-10 bg-muted shadow-[0_1px_0_0_var(--tw-shadow-color)] shadow-border", children: /* @__PURE__ */ jsx("tr", { className: "border-b border-border text-xs text-muted-foreground", children: visibleColumns.map((column) => /* @__PURE__ */ jsxs(
|
|
649
|
+
"th",
|
|
674
650
|
{
|
|
675
651
|
className: cn(
|
|
676
|
-
"
|
|
677
|
-
|
|
652
|
+
"group/header relative whitespace-nowrap font-medium",
|
|
653
|
+
DATA_TABLE_HEADER_DENSITY_CLASS,
|
|
654
|
+
alignmentClass(column.align),
|
|
655
|
+
resizableColumns && column.resizable !== false && "select-none",
|
|
656
|
+
column.headerClassName
|
|
678
657
|
),
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
[record.id]: !current[record.id]
|
|
684
|
-
}));
|
|
685
|
-
}
|
|
686
|
-
if (opensDialog) {
|
|
687
|
-
setDetailRow(record);
|
|
688
|
-
}
|
|
689
|
-
if (rowClickEnabled) {
|
|
690
|
-
onRowClick == null ? void 0 : onRowClick(record.row);
|
|
691
|
-
}
|
|
692
|
-
},
|
|
693
|
-
children: visibleColumns.map((column, index) => {
|
|
694
|
-
const rawValue = resolvePath(record.row, column.key);
|
|
695
|
-
let content = column.render ? column.render(rawValue, record.row) : formatCell(rawValue);
|
|
696
|
-
if (column.kind === "tags" && filterActionsByColumn[column.key]) {
|
|
697
|
-
content = /* @__PURE__ */ jsx(TagActionsProvider, { value: filterActionsByColumn[column.key], children: content });
|
|
698
|
-
}
|
|
699
|
-
return /* @__PURE__ */ jsx(
|
|
700
|
-
"td",
|
|
658
|
+
onContextMenu: (event) => openHeaderColumnMenu(event, column),
|
|
659
|
+
children: [
|
|
660
|
+
/* @__PURE__ */ jsxs(
|
|
661
|
+
"div",
|
|
701
662
|
{
|
|
702
663
|
className: cn(
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
column.
|
|
664
|
+
"flex min-w-0 items-center gap-1",
|
|
665
|
+
headerAlignmentClass(column.align),
|
|
666
|
+
resizableColumns && column.resizable !== false && "pr-2"
|
|
706
667
|
),
|
|
668
|
+
children: [
|
|
669
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0", children: column.sortable === false ? /* @__PURE__ */ jsx("span", { children: column.label }) : /* @__PURE__ */ jsx(
|
|
670
|
+
SortableHeader,
|
|
671
|
+
{
|
|
672
|
+
active: (sort == null ? void 0 : sort.key) === column.key,
|
|
673
|
+
...(sort == null ? void 0 : sort.key) === column.key ? { dir: sort.dir } : {},
|
|
674
|
+
...column.align ? { align: column.align } : {},
|
|
675
|
+
onClick: () => toggle(column.key),
|
|
676
|
+
children: column.label
|
|
677
|
+
}
|
|
678
|
+
) }),
|
|
679
|
+
showHeaderFilterControls && (nativeFilterByColumn.has(column.key) || autoTimeRange && (timeRangeColumn == null ? void 0 : timeRangeColumn.key) === column.key) && /* @__PURE__ */ jsx(
|
|
680
|
+
HeaderFilterButton,
|
|
681
|
+
{
|
|
682
|
+
column,
|
|
683
|
+
active: nativeFilterByColumn.has(column.key) ? isFilterBarFilterActive(
|
|
684
|
+
nativeFilterByColumn.get(column.key)
|
|
685
|
+
) : Boolean(
|
|
686
|
+
timeRangeFilter.from || timeRangeFilter.to
|
|
687
|
+
),
|
|
688
|
+
onOpen: (event) => openHeaderFilterMenu(event, column.key)
|
|
689
|
+
}
|
|
690
|
+
)
|
|
691
|
+
]
|
|
692
|
+
}
|
|
693
|
+
),
|
|
694
|
+
resizableColumns && column.resizable !== false && /* @__PURE__ */ jsx(
|
|
695
|
+
"span",
|
|
696
|
+
{
|
|
697
|
+
role: "separator",
|
|
698
|
+
"aria-label": `Resize ${labelText(column)} column`,
|
|
699
|
+
"aria-orientation": "vertical",
|
|
700
|
+
className: "absolute right-0 top-0 flex h-full w-3 cursor-col-resize touch-none items-center justify-center border-r border-border/70 bg-gradient-to-l from-border/30 to-transparent transition-colors hover:border-primary hover:from-primary/20",
|
|
701
|
+
onClick: (event) => {
|
|
702
|
+
event.preventDefault();
|
|
703
|
+
event.stopPropagation();
|
|
704
|
+
},
|
|
705
|
+
onDoubleClick: (event) => autoFitColumn(event, column),
|
|
706
|
+
onMouseDown: (event) => startColumnResize(event, column),
|
|
707
707
|
children: /* @__PURE__ */ jsx(
|
|
708
|
-
|
|
708
|
+
"span",
|
|
709
709
|
{
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
children: href && index === 0 ? /* @__PURE__ */ jsx("a", { href, className: "hover:underline", children: content }) : content
|
|
710
|
+
"aria-hidden": true,
|
|
711
|
+
className: "h-4 w-0.5 rounded-full bg-border transition-colors group-hover/header:bg-primary/70"
|
|
713
712
|
}
|
|
714
713
|
)
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
714
|
+
}
|
|
715
|
+
)
|
|
716
|
+
]
|
|
717
|
+
},
|
|
718
|
+
column.key
|
|
719
|
+
)) }) }),
|
|
720
|
+
/* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx(
|
|
721
|
+
DataTableLoadingRows,
|
|
722
|
+
{
|
|
723
|
+
columns: visibleColumns,
|
|
724
|
+
rowCount: loadingRowCount,
|
|
725
|
+
message: loadingMessage
|
|
719
726
|
}
|
|
720
|
-
)
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
727
|
+
) : sorted.map((record) => {
|
|
728
|
+
const href = getRowHref == null ? void 0 : getRowHref(record.row);
|
|
729
|
+
const expanded = expandedRows[record.id] ?? false;
|
|
730
|
+
const expandedContent = (renderExpandedRow == null ? void 0 : renderExpandedRow(record.row, {
|
|
731
|
+
columns: effectiveColumns,
|
|
732
|
+
visibleColumns,
|
|
733
|
+
filterActionsByColumn
|
|
734
|
+
})) ?? null;
|
|
735
|
+
const expandable = expandedContent !== null;
|
|
736
|
+
const expandsInline = expandable && detailStyle === "row";
|
|
737
|
+
const opensDialog = expandable && detailStyle === "dialog";
|
|
738
|
+
const rowClickEnabled = (isRowClickable == null ? void 0 : isRowClickable(record.row)) ?? !!onRowClick;
|
|
739
|
+
const clickable = !!href || rowClickEnabled || expandable;
|
|
740
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
741
|
+
/* @__PURE__ */ jsx(
|
|
742
|
+
"tr",
|
|
743
|
+
{
|
|
744
|
+
className: cn(
|
|
745
|
+
"border-b border-border/60 align-top",
|
|
746
|
+
clickable && "cursor-pointer hover:bg-accent/40"
|
|
747
|
+
),
|
|
748
|
+
onClick: () => {
|
|
749
|
+
if (expandsInline) {
|
|
750
|
+
setExpandedRows((current) => ({
|
|
751
|
+
...current,
|
|
752
|
+
[record.id]: !current[record.id]
|
|
753
|
+
}));
|
|
754
|
+
}
|
|
755
|
+
if (opensDialog) {
|
|
756
|
+
setDetailRow(record);
|
|
757
|
+
}
|
|
758
|
+
if (rowClickEnabled) {
|
|
759
|
+
onRowClick == null ? void 0 : onRowClick(record.row);
|
|
760
|
+
}
|
|
761
|
+
},
|
|
762
|
+
children: visibleColumns.map((column, index) => {
|
|
763
|
+
const rawValue = resolvePath(record.row, column.key);
|
|
764
|
+
let content = column.render ? column.render(rawValue, record.row) : formatCell(rawValue);
|
|
765
|
+
if (column.kind === "tags" && filterActionsByColumn[column.key]) {
|
|
766
|
+
content = /* @__PURE__ */ jsx(
|
|
767
|
+
TagActionsProvider,
|
|
768
|
+
{
|
|
769
|
+
value: filterActionsByColumn[column.key],
|
|
770
|
+
children: content
|
|
771
|
+
}
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
return /* @__PURE__ */ jsx(
|
|
775
|
+
"td",
|
|
776
|
+
{
|
|
777
|
+
className: cn(
|
|
778
|
+
DATA_TABLE_CELL_DENSITY_CLASS,
|
|
779
|
+
alignmentClass(column.align),
|
|
780
|
+
column.cellClassName
|
|
781
|
+
),
|
|
782
|
+
children: /* @__PURE__ */ jsx(
|
|
783
|
+
CellContent,
|
|
784
|
+
{
|
|
785
|
+
column,
|
|
786
|
+
...columnWidths[column.key] !== void 0 ? { width: columnWidths[column.key] } : {},
|
|
787
|
+
children: href && index === 0 ? /* @__PURE__ */ jsx("a", { href, className: "hover:underline", children: content }) : content
|
|
788
|
+
}
|
|
789
|
+
)
|
|
790
|
+
},
|
|
791
|
+
column.key
|
|
792
|
+
);
|
|
793
|
+
})
|
|
794
|
+
}
|
|
795
|
+
),
|
|
796
|
+
expandsInline && expanded && expandedContent && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
797
|
+
"td",
|
|
798
|
+
{
|
|
799
|
+
colSpan: visibleColumns.length,
|
|
800
|
+
className: "bg-muted/40 p-density-3",
|
|
801
|
+
children: /* @__PURE__ */ jsx("div", { className: "rounded-md border border-border bg-background p-density-3", children: expandedContent })
|
|
802
|
+
}
|
|
803
|
+
) })
|
|
804
|
+
] }, record.id);
|
|
805
|
+
}) })
|
|
806
|
+
] })
|
|
807
|
+
}
|
|
808
|
+
),
|
|
809
|
+
pagination ? /* @__PURE__ */ jsx(
|
|
810
|
+
DataTablePaginationFooter,
|
|
811
|
+
{
|
|
812
|
+
pagination,
|
|
813
|
+
visibleRowCount: sorted.length,
|
|
814
|
+
loading,
|
|
815
|
+
loadingMessage
|
|
816
|
+
}
|
|
817
|
+
) : /* @__PURE__ */ jsx("div", { className: "px-1 text-xs text-muted-foreground", children: loading ? loadingMessage : `${sorted.length} of ${data.length} row${data.length === 1 ? "" : "s"}` }),
|
|
818
|
+
detailStyle === "dialog" && renderExpandedRow && /* @__PURE__ */ jsx(
|
|
819
|
+
Modal,
|
|
820
|
+
{
|
|
821
|
+
open: detailRow !== null,
|
|
822
|
+
onClose: () => setDetailRow(null),
|
|
823
|
+
size: detailDialogSize,
|
|
824
|
+
...detailRow ? {
|
|
825
|
+
title: typeof detailDialogTitle === "function" ? detailDialogTitle(detailRow.row) : detailDialogTitle
|
|
826
|
+
} : {},
|
|
827
|
+
children: detailRow ? renderExpandedRow(detailRow.row, {
|
|
828
|
+
columns: effectiveColumns,
|
|
829
|
+
visibleColumns,
|
|
830
|
+
filterActionsByColumn
|
|
831
|
+
}) : null
|
|
832
|
+
}
|
|
833
|
+
),
|
|
834
|
+
columnMenu && showTablePreferencesControl && /* @__PURE__ */ jsx(
|
|
835
|
+
ColumnVisibilityMenu,
|
|
836
|
+
{
|
|
837
|
+
columns: effectiveColumns,
|
|
838
|
+
hiddenColumns,
|
|
839
|
+
anchor: columnMenu,
|
|
840
|
+
actions: menuActions ?? [],
|
|
841
|
+
showColumnVisibilityControl,
|
|
842
|
+
showDensityControl: resolvedShowDensityControl,
|
|
843
|
+
showThemeControl,
|
|
844
|
+
themeMenuValue,
|
|
845
|
+
densityOverride,
|
|
846
|
+
visibleHideableColumnCount,
|
|
847
|
+
onToggle: toggleColumnVisibility,
|
|
848
|
+
onShowAll: showAllColumns,
|
|
849
|
+
onDensityChange: setDensityOverride,
|
|
850
|
+
...onThemeChange ? { onThemeChange } : {},
|
|
851
|
+
onClose: () => setColumnMenu(null)
|
|
852
|
+
}
|
|
853
|
+
),
|
|
854
|
+
headerFilterMenu && /* @__PURE__ */ jsx(
|
|
855
|
+
HeaderFilterMenu,
|
|
856
|
+
{
|
|
857
|
+
filter: nativeFilterByColumn.get(headerFilterMenu.columnKey ?? ""),
|
|
858
|
+
...autoTimeRange && (timeRangeColumn == null ? void 0 : timeRangeColumn.key) === headerFilterMenu.columnKey ? { timeRange: autoTimeRange } : {},
|
|
859
|
+
anchor: headerFilterMenu,
|
|
860
|
+
onClose: () => setHeaderFilterMenu(null)
|
|
861
|
+
}
|
|
862
|
+
)
|
|
863
|
+
]
|
|
864
|
+
}
|
|
865
|
+
) });
|
|
774
866
|
}
|
|
775
|
-
const DEFAULT_PAGE_SIZE_OPTIONS = [25, 50, 100, 200];
|
|
776
|
-
function DataTablePaginationFooter({
|
|
867
|
+
const DEFAULT_PAGE_SIZE_OPTIONS = [5, 10, 25, 50, 100, 200];
|
|
868
|
+
function DataTablePaginationFooter({
|
|
869
|
+
pagination,
|
|
870
|
+
visibleRowCount,
|
|
871
|
+
loading,
|
|
872
|
+
loadingMessage
|
|
873
|
+
}) {
|
|
777
874
|
const { page, pageSize, total, onPageChange, onPageSizeChange } = pagination;
|
|
778
|
-
const options =
|
|
875
|
+
const options = Array.from(
|
|
876
|
+
/* @__PURE__ */ new Set([
|
|
877
|
+
...pagination.pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS,
|
|
878
|
+
pageSize
|
|
879
|
+
])
|
|
880
|
+
).sort((a, b) => a - b);
|
|
779
881
|
const safePage = Math.max(0, page);
|
|
780
882
|
const totalPages = total != null && pageSize > 0 ? Math.max(1, Math.ceil(total / pageSize)) : void 0;
|
|
781
883
|
const atFirst = safePage === 0;
|
|
782
|
-
const atLast = totalPages != null ? safePage >= totalPages - 1 :
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
884
|
+
const atLast = totalPages != null ? safePage >= totalPages - 1 : visibleRowCount < pageSize;
|
|
885
|
+
const hasVisibleRows = visibleRowCount > 0;
|
|
886
|
+
const rangeStart = total === 0 || !hasVisibleRows ? 0 : safePage * pageSize + 1;
|
|
887
|
+
const rangeEnd = total != null && hasVisibleRows ? Math.min(total, rangeStart + Math.max(visibleRowCount - 1, 0)) : visibleRowCount;
|
|
888
|
+
const rangeLabel = total != null ? `${rangeStart}-${rangeEnd} of ${total}` : `${visibleRowCount} row${visibleRowCount === 1 ? "" : "s"}`;
|
|
889
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-9 flex-wrap items-center justify-between gap-3 border-t border-border/70 px-1 pt-2 text-xs text-muted-foreground", children: [
|
|
890
|
+
/* @__PURE__ */ jsx("div", { "aria-live": "polite", children: loading ? loadingMessage : rangeLabel }),
|
|
891
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
892
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5", children: [
|
|
893
|
+
/* @__PURE__ */ jsx("span", { children: "Rows per page" }),
|
|
894
|
+
/* @__PURE__ */ jsx(
|
|
895
|
+
"select",
|
|
896
|
+
{
|
|
897
|
+
className: "h-7 rounded-md border border-border bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
898
|
+
value: pageSize,
|
|
899
|
+
onChange: (event) => onPageSizeChange(Number(event.target.value)),
|
|
900
|
+
children: options.map((option) => /* @__PURE__ */ jsx("option", { value: option, children: option }, option))
|
|
901
|
+
}
|
|
902
|
+
)
|
|
903
|
+
] }),
|
|
904
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-20 text-center", children: [
|
|
905
|
+
"Page ",
|
|
906
|
+
safePage + 1,
|
|
907
|
+
totalPages != null ? ` of ${totalPages}` : ""
|
|
908
|
+
] }),
|
|
797
909
|
/* @__PURE__ */ jsx(
|
|
798
910
|
"button",
|
|
799
911
|
{
|
|
800
912
|
type: "button",
|
|
801
|
-
className: "rounded border border-border
|
|
913
|
+
className: "inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-background text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50",
|
|
914
|
+
"aria-label": "Previous page",
|
|
915
|
+
title: "Previous page",
|
|
802
916
|
disabled: atFirst,
|
|
803
917
|
onClick: () => onPageChange(Math.max(0, safePage - 1)),
|
|
804
|
-
children:
|
|
918
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiArrowLeft })
|
|
805
919
|
}
|
|
806
920
|
),
|
|
807
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
808
|
-
"Page ",
|
|
809
|
-
safePage + 1,
|
|
810
|
-
totalPages != null ? ` of ${totalPages}` : ""
|
|
811
|
-
] }),
|
|
812
921
|
/* @__PURE__ */ jsx(
|
|
813
922
|
"button",
|
|
814
923
|
{
|
|
815
924
|
type: "button",
|
|
816
|
-
className: "rounded border border-border
|
|
925
|
+
className: "inline-flex h-7 w-7 items-center justify-center rounded-md border border-border bg-background text-foreground hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50",
|
|
926
|
+
"aria-label": "Next page",
|
|
927
|
+
title: "Next page",
|
|
817
928
|
disabled: atLast,
|
|
818
929
|
onClick: () => onPageChange(safePage + 1),
|
|
819
|
-
children:
|
|
930
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiArrowRight })
|
|
820
931
|
}
|
|
821
932
|
)
|
|
822
933
|
] })
|
|
@@ -830,19 +941,26 @@ function DataTableLoadingRows({
|
|
|
830
941
|
const safeRowCount = Math.max(1, rowCount);
|
|
831
942
|
const safeColumnCount = Math.max(1, columns.length);
|
|
832
943
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
833
|
-
/* @__PURE__ */ jsx("tr", { className: "border-b border-border/60 bg-muted/20", children: /* @__PURE__ */ jsxs(
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
944
|
+
/* @__PURE__ */ jsx("tr", { className: "border-b border-border/60 bg-muted/20", children: /* @__PURE__ */ jsxs(
|
|
945
|
+
"td",
|
|
946
|
+
{
|
|
947
|
+
colSpan: safeColumnCount,
|
|
948
|
+
className: cn(DATA_TABLE_CELL_DENSITY_CLASS, "p-0"),
|
|
949
|
+
children: [
|
|
950
|
+
/* @__PURE__ */ jsx("div", { className: "h-0.5 w-full overflow-hidden bg-muted", children: /* @__PURE__ */ jsx("div", { className: "h-full w-1/2 animate-pulse rounded-full bg-primary/70" }) }),
|
|
951
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-xs text-muted-foreground", children: [
|
|
952
|
+
/* @__PURE__ */ jsx(
|
|
953
|
+
"span",
|
|
954
|
+
{
|
|
955
|
+
"aria-hidden": true,
|
|
956
|
+
className: "h-3 w-3 animate-spin rounded-full border-2 border-primary/30 border-t-primary"
|
|
957
|
+
}
|
|
958
|
+
),
|
|
959
|
+
/* @__PURE__ */ jsx("span", { children: message })
|
|
960
|
+
] })
|
|
961
|
+
]
|
|
962
|
+
}
|
|
963
|
+
) }),
|
|
846
964
|
Array.from({ length: safeRowCount }).map((_, rowIndex) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border/60", children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx(
|
|
847
965
|
"td",
|
|
848
966
|
{
|
|
@@ -883,7 +1001,14 @@ function HeaderFilterButton({
|
|
|
883
1001
|
active && "bg-accent text-foreground"
|
|
884
1002
|
),
|
|
885
1003
|
onClick: onOpen,
|
|
886
|
-
children: /* @__PURE__ */ jsx(
|
|
1004
|
+
children: /* @__PURE__ */ jsx(
|
|
1005
|
+
"span",
|
|
1006
|
+
{
|
|
1007
|
+
"data-filter-icon-state": active ? "filled" : "outline",
|
|
1008
|
+
className: "inline-flex",
|
|
1009
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: active ? UiFilterFilled : UiFilter, className: "text-xs" })
|
|
1010
|
+
}
|
|
1011
|
+
)
|
|
887
1012
|
}
|
|
888
1013
|
);
|
|
889
1014
|
}
|
|
@@ -972,6 +1097,7 @@ function ColumnVisibilityMenu({
|
|
|
972
1097
|
columns,
|
|
973
1098
|
hiddenColumns,
|
|
974
1099
|
anchor,
|
|
1100
|
+
actions,
|
|
975
1101
|
showColumnVisibilityControl,
|
|
976
1102
|
showDensityControl,
|
|
977
1103
|
showThemeControl,
|
|
@@ -986,6 +1112,7 @@ function ColumnVisibilityMenu({
|
|
|
986
1112
|
}) {
|
|
987
1113
|
const activeColumn = anchor.columnKey ? columns.find((column) => column.key === anchor.columnKey) : void 0;
|
|
988
1114
|
const canHideActiveColumn = activeColumn && isColumnHideable(activeColumn) && visibleHideableColumnCount > 1;
|
|
1115
|
+
const hasActions = actions.length > 0;
|
|
989
1116
|
return /* @__PURE__ */ jsxs(
|
|
990
1117
|
"div",
|
|
991
1118
|
{
|
|
@@ -1026,7 +1153,13 @@ function ColumnVisibilityMenu({
|
|
|
1026
1153
|
onClose();
|
|
1027
1154
|
},
|
|
1028
1155
|
children: [
|
|
1029
|
-
/* @__PURE__ */ jsx(
|
|
1156
|
+
/* @__PURE__ */ jsx(
|
|
1157
|
+
Icon,
|
|
1158
|
+
{
|
|
1159
|
+
icon: UiEyeClosed,
|
|
1160
|
+
className: "text-sm text-muted-foreground"
|
|
1161
|
+
}
|
|
1162
|
+
),
|
|
1030
1163
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
1031
1164
|
"Hide ",
|
|
1032
1165
|
labelText(activeColumn)
|
|
@@ -1073,11 +1206,19 @@ function ColumnVisibilityMenu({
|
|
|
1073
1206
|
onDensityChange
|
|
1074
1207
|
}
|
|
1075
1208
|
),
|
|
1209
|
+
hasActions && /* @__PURE__ */ jsx(
|
|
1210
|
+
MenuActionSection,
|
|
1211
|
+
{
|
|
1212
|
+
actions,
|
|
1213
|
+
separated: showColumnVisibilityControl || showDensityControl,
|
|
1214
|
+
onClose
|
|
1215
|
+
}
|
|
1216
|
+
),
|
|
1076
1217
|
showThemeControl && onThemeChange && /* @__PURE__ */ jsx(
|
|
1077
1218
|
ThemeMenuSection,
|
|
1078
1219
|
{
|
|
1079
1220
|
value: themeMenuValue ?? "system",
|
|
1080
|
-
separated: showColumnVisibilityControl || showDensityControl,
|
|
1221
|
+
separated: showColumnVisibilityControl || showDensityControl || hasActions,
|
|
1081
1222
|
onChange: onThemeChange
|
|
1082
1223
|
}
|
|
1083
1224
|
)
|
|
@@ -1085,6 +1226,54 @@ function ColumnVisibilityMenu({
|
|
|
1085
1226
|
}
|
|
1086
1227
|
);
|
|
1087
1228
|
}
|
|
1229
|
+
function MenuActionSection({
|
|
1230
|
+
actions,
|
|
1231
|
+
separated,
|
|
1232
|
+
onClose
|
|
1233
|
+
}) {
|
|
1234
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(separated && "mt-1 border-t border-border pt-1"), children: [
|
|
1235
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground", children: "Download" }),
|
|
1236
|
+
actions.map((action) => {
|
|
1237
|
+
const hasDescription = Boolean(action.description);
|
|
1238
|
+
return /* @__PURE__ */ jsxs(
|
|
1239
|
+
"button",
|
|
1240
|
+
{
|
|
1241
|
+
type: "button",
|
|
1242
|
+
role: "menuitem",
|
|
1243
|
+
disabled: action.disabled,
|
|
1244
|
+
className: cn(
|
|
1245
|
+
"flex w-full gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none",
|
|
1246
|
+
hasDescription ? "items-start" : "items-center",
|
|
1247
|
+
action.disabled && "cursor-not-allowed opacity-50"
|
|
1248
|
+
),
|
|
1249
|
+
onClick: () => {
|
|
1250
|
+
if (action.disabled) return;
|
|
1251
|
+
action.onSelect();
|
|
1252
|
+
onClose();
|
|
1253
|
+
},
|
|
1254
|
+
children: [
|
|
1255
|
+
action.icon && /* @__PURE__ */ jsx(
|
|
1256
|
+
Icon,
|
|
1257
|
+
{
|
|
1258
|
+
icon: action.icon,
|
|
1259
|
+
className: cn(
|
|
1260
|
+
"shrink-0 text-sm",
|
|
1261
|
+
hasDescription && "mt-0.5",
|
|
1262
|
+
action.iconClassName ?? "text-muted-foreground"
|
|
1263
|
+
)
|
|
1264
|
+
}
|
|
1265
|
+
),
|
|
1266
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
1267
|
+
/* @__PURE__ */ jsx("span", { className: cn(hasDescription && "font-medium"), children: action.label }),
|
|
1268
|
+
action.description && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: action.description })
|
|
1269
|
+
] })
|
|
1270
|
+
]
|
|
1271
|
+
},
|
|
1272
|
+
action.id
|
|
1273
|
+
);
|
|
1274
|
+
})
|
|
1275
|
+
] });
|
|
1276
|
+
}
|
|
1088
1277
|
function DensityMenuSection({
|
|
1089
1278
|
densityOverride,
|
|
1090
1279
|
separated,
|
|
@@ -1102,7 +1291,13 @@ function DensityMenuSection({
|
|
|
1102
1291
|
className: densityMenuItemClassName(current === "inherit"),
|
|
1103
1292
|
onClick: () => onDensityChange(void 0),
|
|
1104
1293
|
children: [
|
|
1105
|
-
/* @__PURE__ */ jsx(
|
|
1294
|
+
/* @__PURE__ */ jsx(
|
|
1295
|
+
Icon,
|
|
1296
|
+
{
|
|
1297
|
+
icon: UiResizeVertical,
|
|
1298
|
+
className: "text-sm text-muted-foreground"
|
|
1299
|
+
}
|
|
1300
|
+
),
|
|
1106
1301
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: "Use page density" }),
|
|
1107
1302
|
current === "inherit" ? /* @__PURE__ */ jsx(Icon, { icon: UiCheck, className: "text-sm text-foreground" }) : /* @__PURE__ */ jsx("span", { className: "inline-block h-4 w-4", "aria-hidden": true })
|
|
1108
1303
|
]
|
|
@@ -1119,7 +1314,13 @@ function DensityMenuSection({
|
|
|
1119
1314
|
className: densityMenuItemClassName(active),
|
|
1120
1315
|
onClick: () => onDensityChange(option.value),
|
|
1121
1316
|
children: [
|
|
1122
|
-
/* @__PURE__ */ jsx(
|
|
1317
|
+
/* @__PURE__ */ jsx(
|
|
1318
|
+
Icon,
|
|
1319
|
+
{
|
|
1320
|
+
icon: option.icon,
|
|
1321
|
+
className: "text-sm text-muted-foreground"
|
|
1322
|
+
}
|
|
1323
|
+
),
|
|
1123
1324
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
|
|
1124
1325
|
active ? /* @__PURE__ */ jsx(Icon, { icon: UiCheck, className: "text-sm text-foreground" }) : /* @__PURE__ */ jsx("span", { className: "inline-block h-4 w-4", "aria-hidden": true })
|
|
1125
1326
|
]
|
|
@@ -1158,7 +1359,13 @@ function ThemeMenuSection({
|
|
|
1158
1359
|
className: densityMenuItemClassName(active),
|
|
1159
1360
|
onClick: () => onChange(option.value),
|
|
1160
1361
|
children: [
|
|
1161
|
-
/* @__PURE__ */ jsx(
|
|
1362
|
+
/* @__PURE__ */ jsx(
|
|
1363
|
+
Icon,
|
|
1364
|
+
{
|
|
1365
|
+
icon: option.icon,
|
|
1366
|
+
className: "text-sm text-muted-foreground"
|
|
1367
|
+
}
|
|
1368
|
+
),
|
|
1162
1369
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
|
|
1163
1370
|
active ? /* @__PURE__ */ jsx(Icon, { icon: UiCheck, className: "text-sm text-foreground" }) : /* @__PURE__ */ jsx("span", { className: "inline-block h-4 w-4", "aria-hidden": true })
|
|
1164
1371
|
]
|
|
@@ -1176,7 +1383,10 @@ function CellContent({
|
|
|
1176
1383
|
return /* @__PURE__ */ jsx(
|
|
1177
1384
|
"div",
|
|
1178
1385
|
{
|
|
1179
|
-
className: cn(
|
|
1386
|
+
className: cn(
|
|
1387
|
+
cellContentClassName(column, width),
|
|
1388
|
+
alignmentClass(column.align)
|
|
1389
|
+
),
|
|
1180
1390
|
style: cellContentStyle(width),
|
|
1181
1391
|
children
|
|
1182
1392
|
}
|
|
@@ -1242,11 +1452,18 @@ function updateNumberFilterValue(state, key, nextValue) {
|
|
|
1242
1452
|
return next;
|
|
1243
1453
|
}
|
|
1244
1454
|
function pruneTextFilterState(state, filters) {
|
|
1245
|
-
return pruneFilterState(
|
|
1455
|
+
return pruneFilterState(
|
|
1456
|
+
state,
|
|
1457
|
+
filters,
|
|
1458
|
+
"text",
|
|
1459
|
+
(value) => !String(value ?? "").trim()
|
|
1460
|
+
);
|
|
1246
1461
|
}
|
|
1247
1462
|
function pruneMultiFilterState(state, filters) {
|
|
1248
1463
|
const allowed = new Set(
|
|
1249
|
-
filters.filter(
|
|
1464
|
+
filters.filter(
|
|
1465
|
+
(filter) => filter.kind === "multi" || filter.kind === "nested-multi"
|
|
1466
|
+
).map((filter) => filter.column.key)
|
|
1250
1467
|
);
|
|
1251
1468
|
return Object.fromEntries(
|
|
1252
1469
|
Object.entries(state).filter(
|
|
@@ -1267,7 +1484,9 @@ function pruneFilterState(state, filters, kind, isEmpty) {
|
|
|
1267
1484
|
filters.filter((filter) => filter.kind === kind).map((filter) => filter.column.key)
|
|
1268
1485
|
);
|
|
1269
1486
|
return Object.fromEntries(
|
|
1270
|
-
Object.entries(state).filter(
|
|
1487
|
+
Object.entries(state).filter(
|
|
1488
|
+
([key, value]) => allowed.has(key) && !isEmpty(value)
|
|
1489
|
+
)
|
|
1271
1490
|
);
|
|
1272
1491
|
}
|
|
1273
1492
|
function resolvePath(obj, path) {
|
|
@@ -1393,8 +1612,14 @@ function menuStateFromPointer(event, columnKey) {
|
|
|
1393
1612
|
const viewportWidth = typeof window === "undefined" ? event.clientX + width : window.innerWidth;
|
|
1394
1613
|
const viewportHeight = typeof window === "undefined" ? event.clientY + height : window.innerHeight;
|
|
1395
1614
|
const position = {
|
|
1396
|
-
x: Math.max(
|
|
1397
|
-
|
|
1615
|
+
x: Math.max(
|
|
1616
|
+
padding,
|
|
1617
|
+
Math.min(event.clientX, viewportWidth - width - padding)
|
|
1618
|
+
),
|
|
1619
|
+
y: Math.max(
|
|
1620
|
+
padding,
|
|
1621
|
+
Math.min(event.clientY, viewportHeight - height - padding)
|
|
1622
|
+
)
|
|
1398
1623
|
};
|
|
1399
1624
|
return columnKey ? { ...position, columnKey } : position;
|
|
1400
1625
|
}
|
|
@@ -1406,8 +1631,14 @@ function menuStateFromTrigger(event, columnKey) {
|
|
|
1406
1631
|
const viewportWidth = typeof window === "undefined" ? rect.right + width : window.innerWidth;
|
|
1407
1632
|
const viewportHeight = typeof window === "undefined" ? rect.bottom + height : window.innerHeight;
|
|
1408
1633
|
const position = {
|
|
1409
|
-
x: Math.max(
|
|
1410
|
-
|
|
1634
|
+
x: Math.max(
|
|
1635
|
+
padding,
|
|
1636
|
+
Math.min(rect.right - width, viewportWidth - width - padding)
|
|
1637
|
+
),
|
|
1638
|
+
y: Math.max(
|
|
1639
|
+
padding,
|
|
1640
|
+
Math.min(rect.bottom + 6, viewportHeight - height - padding)
|
|
1641
|
+
)
|
|
1411
1642
|
};
|
|
1412
1643
|
return columnKey ? { ...position, columnKey } : position;
|
|
1413
1644
|
}
|
|
@@ -1443,7 +1674,8 @@ function readStoredColumnWidths(storageKey, columns) {
|
|
|
1443
1674
|
const raw = window.localStorage.getItem(storageKey);
|
|
1444
1675
|
if (!raw) return {};
|
|
1445
1676
|
const parsed = JSON.parse(raw);
|
|
1446
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
1677
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
1678
|
+
return {};
|
|
1447
1679
|
return pruneColumnWidths(parsed, columns);
|
|
1448
1680
|
} catch {
|
|
1449
1681
|
return {};
|
|
@@ -1466,7 +1698,8 @@ function readStoredHiddenColumns(storageKey, columns) {
|
|
|
1466
1698
|
const raw = window.localStorage.getItem(storageKey);
|
|
1467
1699
|
if (!raw) return {};
|
|
1468
1700
|
const parsed = JSON.parse(raw);
|
|
1469
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
1701
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
1702
|
+
return {};
|
|
1470
1703
|
return pruneHiddenColumns(parsed, columns);
|
|
1471
1704
|
} catch {
|
|
1472
1705
|
return {};
|
|
@@ -1511,7 +1744,8 @@ function pruneColumnWidths(widths, columns) {
|
|
|
1511
1744
|
const next = {};
|
|
1512
1745
|
for (const [key, width] of Object.entries(widths)) {
|
|
1513
1746
|
const column = byKey.get(key);
|
|
1514
|
-
if (!column || typeof width !== "number" || !Number.isFinite(width))
|
|
1747
|
+
if (!column || typeof width !== "number" || !Number.isFinite(width))
|
|
1748
|
+
continue;
|
|
1515
1749
|
next[key] = clampColumnWidth(column, width);
|
|
1516
1750
|
}
|
|
1517
1751
|
return next;
|
|
@@ -1525,7 +1759,9 @@ function pruneHiddenColumns(hiddenColumns, columns) {
|
|
|
1525
1759
|
next[key] = true;
|
|
1526
1760
|
}
|
|
1527
1761
|
const hideable = columns.filter(isColumnHideable);
|
|
1528
|
-
const visibleHideableCount = hideable.filter(
|
|
1762
|
+
const visibleHideableCount = hideable.filter(
|
|
1763
|
+
(column) => next[column.key] !== true
|
|
1764
|
+
).length;
|
|
1529
1765
|
if (hideable.length > 0 && visibleHideableCount === 0) {
|
|
1530
1766
|
delete next[hideable[0].key];
|
|
1531
1767
|
}
|
|
@@ -1622,8 +1858,10 @@ function cellContentStyle(width) {
|
|
|
1622
1858
|
function cellContentClassName(column, width) {
|
|
1623
1859
|
const resized = width !== void 0;
|
|
1624
1860
|
const base = "w-full truncate";
|
|
1625
|
-
if (column.grow)
|
|
1626
|
-
|
|
1861
|
+
if (column.grow)
|
|
1862
|
+
return cn(base, resized ? "min-w-0" : "min-w-56 max-w-[36rem]");
|
|
1863
|
+
if (column.shrink)
|
|
1864
|
+
return cn(base, "min-w-0 whitespace-nowrap", !resized && "max-w-[16rem]");
|
|
1627
1865
|
return cn(base, "min-w-0", !resized && "max-w-[18rem]");
|
|
1628
1866
|
}
|
|
1629
1867
|
function inferColumns(data) {
|
|
@@ -1715,7 +1953,10 @@ function DataTable({
|
|
|
1715
1953
|
}
|
|
1716
1954
|
);
|
|
1717
1955
|
}
|
|
1718
|
-
function FullscreenButton({
|
|
1956
|
+
function FullscreenButton({
|
|
1957
|
+
label,
|
|
1958
|
+
onClick
|
|
1959
|
+
}) {
|
|
1719
1960
|
return /* @__PURE__ */ jsx(
|
|
1720
1961
|
"button",
|
|
1721
1962
|
{
|