@juv/codego-react-ui 3.4.11 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +982 -141
- package/dist/index.d.cts +143 -22
- package/dist/index.d.ts +143 -22
- package/dist/index.global.js +1041 -187
- package/dist/index.js +1013 -172
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5783,13 +5783,79 @@ function FileUpload({
|
|
|
5783
5783
|
}
|
|
5784
5784
|
|
|
5785
5785
|
// src/components/ui/repeater.tsx
|
|
5786
|
-
import { Plus as Plus3, Trash2, GripVertical as GripVertical3 } from "lucide-react";
|
|
5786
|
+
import { Plus as Plus3, Trash2, GripVertical as GripVertical3, Paperclip } from "lucide-react";
|
|
5787
5787
|
import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5788
|
+
function RepeaterFieldRenderer({
|
|
5789
|
+
field,
|
|
5790
|
+
value,
|
|
5791
|
+
onChange
|
|
5792
|
+
}) {
|
|
5793
|
+
if (field.type === "image") {
|
|
5794
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1.5", children: [
|
|
5795
|
+
field.label && /* @__PURE__ */ jsx29("span", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
|
|
5796
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-3", children: [
|
|
5797
|
+
value && /* @__PURE__ */ jsx29("img", { src: value, alt: field.key, className: "h-10 w-10 rounded-lg object-cover ring-1 ring-border shrink-0" }),
|
|
5798
|
+
/* @__PURE__ */ jsx29(
|
|
5799
|
+
Input,
|
|
5800
|
+
{
|
|
5801
|
+
inputMode: "text",
|
|
5802
|
+
value: value ?? "",
|
|
5803
|
+
onChange: (e) => onChange(e.target.value),
|
|
5804
|
+
placeholder: field.placeholder ?? "Image URL"
|
|
5805
|
+
}
|
|
5806
|
+
)
|
|
5807
|
+
] })
|
|
5808
|
+
] });
|
|
5809
|
+
}
|
|
5810
|
+
if (field.type === "attachment") {
|
|
5811
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1.5", children: [
|
|
5812
|
+
field.label && /* @__PURE__ */ jsx29("span", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
|
|
5813
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2", children: [
|
|
5814
|
+
value && /* @__PURE__ */ jsxs27(
|
|
5815
|
+
"a",
|
|
5816
|
+
{
|
|
5817
|
+
href: value,
|
|
5818
|
+
target: "_blank",
|
|
5819
|
+
rel: "noopener noreferrer",
|
|
5820
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted transition-colors shrink-0",
|
|
5821
|
+
children: [
|
|
5822
|
+
/* @__PURE__ */ jsx29(Paperclip, { className: "h-3 w-3" }),
|
|
5823
|
+
String(value).split("/").pop()
|
|
5824
|
+
]
|
|
5825
|
+
}
|
|
5826
|
+
),
|
|
5827
|
+
/* @__PURE__ */ jsx29(
|
|
5828
|
+
Input,
|
|
5829
|
+
{
|
|
5830
|
+
inputMode: "text",
|
|
5831
|
+
value: value ?? "",
|
|
5832
|
+
onChange: (e) => onChange(e.target.value),
|
|
5833
|
+
placeholder: field.placeholder ?? "Attachment URL"
|
|
5834
|
+
}
|
|
5835
|
+
)
|
|
5836
|
+
] })
|
|
5837
|
+
] });
|
|
5838
|
+
}
|
|
5839
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1.5", children: [
|
|
5840
|
+
field.label && /* @__PURE__ */ jsx29("span", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
|
|
5841
|
+
/* @__PURE__ */ jsx29(
|
|
5842
|
+
Input,
|
|
5843
|
+
{
|
|
5844
|
+
inputMode: "text",
|
|
5845
|
+
value: value ?? "",
|
|
5846
|
+
onChange: (e) => onChange(e.target.value),
|
|
5847
|
+
placeholder: field.placeholder ?? field.key
|
|
5848
|
+
}
|
|
5849
|
+
)
|
|
5850
|
+
] });
|
|
5851
|
+
}
|
|
5788
5852
|
function Repeater({
|
|
5789
5853
|
items,
|
|
5790
5854
|
onAdd,
|
|
5791
5855
|
onRemove,
|
|
5792
5856
|
renderItem,
|
|
5857
|
+
fields,
|
|
5858
|
+
onFieldChange,
|
|
5793
5859
|
addButtonText = "Add Item",
|
|
5794
5860
|
className
|
|
5795
5861
|
}) {
|
|
@@ -5802,7 +5868,15 @@ function Repeater({
|
|
|
5802
5868
|
children: [
|
|
5803
5869
|
/* @__PURE__ */ jsx29("div", { className: "mt-1 cursor-grab text-muted-foreground/30 group-hover:text-muted-foreground/60 transition-colors shrink-0", children: /* @__PURE__ */ jsx29(GripVertical3, { className: "h-4 w-4" }) }),
|
|
5804
5870
|
/* @__PURE__ */ jsx29("div", { className: "mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary", children: index + 1 }),
|
|
5805
|
-
/* @__PURE__ */ jsx29("div", { className: "flex-1 min-w-0", children:
|
|
5871
|
+
/* @__PURE__ */ jsx29("div", { className: "flex-1 min-w-0", children: fields ? /* @__PURE__ */ jsx29("div", { className: "grid gap-3", style: { gridTemplateColumns: fields.length > 1 ? `repeat(${Math.min(fields.length, 3)}, minmax(0, 1fr))` : "1fr" }, children: fields.map((f) => /* @__PURE__ */ jsx29(
|
|
5872
|
+
RepeaterFieldRenderer,
|
|
5873
|
+
{
|
|
5874
|
+
field: f,
|
|
5875
|
+
value: item[f.key],
|
|
5876
|
+
onChange: (v) => onFieldChange?.(index, f.key, v)
|
|
5877
|
+
},
|
|
5878
|
+
f.key
|
|
5879
|
+
)) }) : renderItem ? renderItem(item, index) : null }),
|
|
5806
5880
|
/* @__PURE__ */ jsxs27(
|
|
5807
5881
|
Button,
|
|
5808
5882
|
{
|
|
@@ -6284,18 +6358,8 @@ import * as React28 from "react";
|
|
|
6284
6358
|
import { createPortal as createPortal3 } from "react-dom";
|
|
6285
6359
|
import axios3 from "axios";
|
|
6286
6360
|
import { ChevronLeft as ChevronLeft6, ChevronRight as ChevronRight8, Search as Search5, Trash2 as Trash22, ChevronsUpDown, ChevronUp, ChevronDown as ChevronDown4, X as X9, Eye as Eye2, Pencil as Pencil2, Trash as Trash3, Loader2 as Loader22 } from "lucide-react";
|
|
6287
|
-
import { Fragment as
|
|
6288
|
-
|
|
6289
|
-
csrfAxios.interceptors.request.use((config) => {
|
|
6290
|
-
const method = (config.method ?? "").toUpperCase();
|
|
6291
|
-
if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
6292
|
-
const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
6293
|
-
if (!token) throw new Error('[Table] CSRF token not found. Add <meta name="csrf-token" content="..."> to your HTML <head>.');
|
|
6294
|
-
config.headers.set("X-CSRF-Token", token);
|
|
6295
|
-
}
|
|
6296
|
-
return config;
|
|
6297
|
-
});
|
|
6298
|
-
function useServerTable({ url, params, encrypt, key, decryptPayloadLog, columnOverrides, debounce = 300, transform, manual = false, refresh: refreshEnabled = false, refreshInterval = 0, hardReload, onSuccess, onError }) {
|
|
6361
|
+
import { Fragment as Fragment12, jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6362
|
+
function useServerTable({ url, params, encrypt, key, decryptPayloadLog, columnOverrides, debounce = 300, transform, manual = false, refresh: refreshEnabled = false, refreshInterval = 0, hardReload, onSuccess, onError, filter: filterFields, sort: sortKeys }) {
|
|
6299
6363
|
const [data, setData] = React28.useState([]);
|
|
6300
6364
|
const [columns, setColumns] = React28.useState([]);
|
|
6301
6365
|
const [currentPage, setCurrentPage] = React28.useState(1);
|
|
@@ -6305,6 +6369,15 @@ function useServerTable({ url, params, encrypt, key, decryptPayloadLog, columnOv
|
|
|
6305
6369
|
const [tick, setTick] = React28.useState(0);
|
|
6306
6370
|
const [searchValue, setSearchValue] = React28.useState("");
|
|
6307
6371
|
const debounceTimer = React28.useRef(void 0);
|
|
6372
|
+
const [filterValues, setFilterValues] = React28.useState(() => {
|
|
6373
|
+
const init = {};
|
|
6374
|
+
filterFields?.forEach((f) => {
|
|
6375
|
+
init[f.key] = f.type === "checkbox" || f.type === "toggle" ? false : "";
|
|
6376
|
+
});
|
|
6377
|
+
return init;
|
|
6378
|
+
});
|
|
6379
|
+
const [sortKey, setSortKey] = React28.useState("");
|
|
6380
|
+
const [sortDir, setSortDir] = React28.useState("asc");
|
|
6308
6381
|
React28.useEffect(() => {
|
|
6309
6382
|
if (hardReload) hardReload.current = () => setTick((t) => t + 1);
|
|
6310
6383
|
}, [hardReload]);
|
|
@@ -6313,13 +6386,32 @@ function useServerTable({ url, params, encrypt, key, decryptPayloadLog, columnOv
|
|
|
6313
6386
|
const id = setInterval(() => setTick((t) => t + 1), refreshInterval);
|
|
6314
6387
|
return () => clearInterval(id);
|
|
6315
6388
|
}, [refreshInterval]);
|
|
6389
|
+
const activeFilterParams = React28.useMemo(() => {
|
|
6390
|
+
const out = {};
|
|
6391
|
+
filterFields?.forEach((f) => {
|
|
6392
|
+
const v = filterValues[f.key];
|
|
6393
|
+
if (f.type === "checkbox" || f.type === "toggle") {
|
|
6394
|
+
if (v) out[f.key] = 1;
|
|
6395
|
+
} else if (f.type === "date-range") {
|
|
6396
|
+
if (v?.from) out[`${f.key}_from`] = v.from;
|
|
6397
|
+
if (v?.to) out[`${f.key}_to`] = v.to;
|
|
6398
|
+
} else if (v !== "" && v !== null && v !== void 0) {
|
|
6399
|
+
out[f.key] = v;
|
|
6400
|
+
}
|
|
6401
|
+
});
|
|
6402
|
+
if (sortKey) {
|
|
6403
|
+
out.sort = sortKey;
|
|
6404
|
+
out.direction = sortDir;
|
|
6405
|
+
}
|
|
6406
|
+
return out;
|
|
6407
|
+
}, [filterValues, sortKey, sortDir, filterFields]);
|
|
6316
6408
|
React28.useEffect(() => {
|
|
6317
6409
|
if (manual && tick === 0) return;
|
|
6318
6410
|
let cancelled = false;
|
|
6319
6411
|
setLoading(true);
|
|
6320
6412
|
setError(null);
|
|
6321
6413
|
axios3.get(url, {
|
|
6322
|
-
params: { ...params, page: currentPage, search: searchValue }
|
|
6414
|
+
params: { ...params, ...activeFilterParams, page: currentPage, search: searchValue }
|
|
6323
6415
|
}).then(({ data: res }) => {
|
|
6324
6416
|
if (cancelled) return;
|
|
6325
6417
|
const payload = encrypt ? decryptLaravelPayload(res, key) : res;
|
|
@@ -6365,15 +6457,184 @@ function useServerTable({ url, params, encrypt, key, decryptPayloadLog, columnOv
|
|
|
6365
6457
|
return () => {
|
|
6366
6458
|
cancelled = true;
|
|
6367
6459
|
};
|
|
6368
|
-
}, [url, currentPage, tick, JSON.stringify(params), encrypt, decryptPayloadLog, JSON.stringify(columnOverrides), searchValue]);
|
|
6460
|
+
}, [url, currentPage, tick, JSON.stringify(params), JSON.stringify(activeFilterParams), encrypt, decryptPayloadLog, JSON.stringify(columnOverrides), searchValue]);
|
|
6369
6461
|
const handleSearchChange = (value) => {
|
|
6370
6462
|
setSearchValue(value);
|
|
6371
6463
|
setCurrentPage(1);
|
|
6372
6464
|
if (debounceTimer.current) clearTimeout(debounceTimer.current);
|
|
6373
|
-
debounceTimer.current = setTimeout(() =>
|
|
6374
|
-
|
|
6375
|
-
|
|
6465
|
+
debounceTimer.current = setTimeout(() => setTick((t) => t + 1), debounce);
|
|
6466
|
+
};
|
|
6467
|
+
const handleFilterChange = (key2, value) => {
|
|
6468
|
+
setFilterValues((prev) => ({ ...prev, [key2]: value }));
|
|
6469
|
+
setCurrentPage(1);
|
|
6470
|
+
setTick((t) => t + 1);
|
|
6471
|
+
};
|
|
6472
|
+
const handleClearFilters = () => {
|
|
6473
|
+
const reset = {};
|
|
6474
|
+
filterFields?.forEach((f) => {
|
|
6475
|
+
reset[f.key] = f.type === "checkbox" || f.type === "toggle" ? false : "";
|
|
6476
|
+
});
|
|
6477
|
+
setFilterValues(reset);
|
|
6478
|
+
setSortKey("");
|
|
6479
|
+
setSortDir("asc");
|
|
6480
|
+
setCurrentPage(1);
|
|
6481
|
+
setTick((t) => t + 1);
|
|
6376
6482
|
};
|
|
6483
|
+
const hasActiveFilters = filterFields?.some((f) => {
|
|
6484
|
+
const v = filterValues[f.key];
|
|
6485
|
+
return f.type === "checkbox" || f.type === "toggle" ? !!v : v !== "" && v !== null && v !== void 0;
|
|
6486
|
+
}) || !!sortKey;
|
|
6487
|
+
const filterBar = filterFields?.length || sortKeys?.length ? /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-end gap-3 rounded-xl border border-border bg-muted/30 px-4 py-3", children: [
|
|
6488
|
+
filterFields?.map((f) => {
|
|
6489
|
+
const label = f.label ?? f.key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
6490
|
+
const value = filterValues[f.key];
|
|
6491
|
+
const opts = (f.options ?? []).map(
|
|
6492
|
+
(o) => typeof o === "string" ? { label: o, value: o } : o
|
|
6493
|
+
);
|
|
6494
|
+
if (f.type === "checkbox") return /* @__PURE__ */ jsxs30("label", { className: "flex items-center gap-2 cursor-pointer select-none", children: [
|
|
6495
|
+
/* @__PURE__ */ jsx32(
|
|
6496
|
+
"input",
|
|
6497
|
+
{
|
|
6498
|
+
type: "checkbox",
|
|
6499
|
+
checked: !!value,
|
|
6500
|
+
onChange: (e) => handleFilterChange(f.key, e.target.checked),
|
|
6501
|
+
className: "h-4 w-4 rounded accent-primary"
|
|
6502
|
+
}
|
|
6503
|
+
),
|
|
6504
|
+
/* @__PURE__ */ jsx32("span", { className: "text-xs font-medium text-foreground", children: label })
|
|
6505
|
+
] }, f.key);
|
|
6506
|
+
if (f.type === "toggle") return /* @__PURE__ */ jsxs30("label", { className: "flex items-center gap-2 cursor-pointer select-none", children: [
|
|
6507
|
+
/* @__PURE__ */ jsx32(
|
|
6508
|
+
"button",
|
|
6509
|
+
{
|
|
6510
|
+
type: "button",
|
|
6511
|
+
role: "switch",
|
|
6512
|
+
"aria-checked": !!value,
|
|
6513
|
+
onClick: () => handleFilterChange(f.key, !value),
|
|
6514
|
+
className: cn(
|
|
6515
|
+
"relative inline-flex h-5 w-9 shrink-0 rounded-full border-2 border-transparent transition-colors",
|
|
6516
|
+
value ? "bg-primary" : "bg-muted"
|
|
6517
|
+
),
|
|
6518
|
+
children: /* @__PURE__ */ jsx32("span", { className: cn(
|
|
6519
|
+
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
6520
|
+
value ? "translate-x-4" : "translate-x-0"
|
|
6521
|
+
) })
|
|
6522
|
+
}
|
|
6523
|
+
),
|
|
6524
|
+
/* @__PURE__ */ jsx32("span", { className: "text-xs font-medium text-foreground", children: label })
|
|
6525
|
+
] }, f.key);
|
|
6526
|
+
if (f.type === "select") return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6527
|
+
/* @__PURE__ */ jsx32("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
6528
|
+
/* @__PURE__ */ jsxs30(
|
|
6529
|
+
"select",
|
|
6530
|
+
{
|
|
6531
|
+
value: value ?? "",
|
|
6532
|
+
onChange: (e) => handleFilterChange(f.key, e.target.value),
|
|
6533
|
+
className: "h-8 min-w-[120px] rounded-lg border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors",
|
|
6534
|
+
children: [
|
|
6535
|
+
/* @__PURE__ */ jsx32("option", { value: "", children: f.placeholder ?? `All ${label}` }),
|
|
6536
|
+
opts.map((o) => /* @__PURE__ */ jsx32("option", { value: o.value, children: o.label }, o.value))
|
|
6537
|
+
]
|
|
6538
|
+
}
|
|
6539
|
+
)
|
|
6540
|
+
] }, f.key);
|
|
6541
|
+
if (f.type === "date" || f.type === "date-time") return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6542
|
+
/* @__PURE__ */ jsx32("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
6543
|
+
/* @__PURE__ */ jsx32(
|
|
6544
|
+
"input",
|
|
6545
|
+
{
|
|
6546
|
+
type: f.type === "date-time" ? "datetime-local" : "date",
|
|
6547
|
+
value: value ?? "",
|
|
6548
|
+
onChange: (e) => handleFilterChange(f.key, e.target.value),
|
|
6549
|
+
className: "h-8 rounded-lg border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors"
|
|
6550
|
+
}
|
|
6551
|
+
)
|
|
6552
|
+
] }, f.key);
|
|
6553
|
+
if (f.type === "date-range") return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6554
|
+
/* @__PURE__ */ jsx32("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
6555
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-1.5", children: [
|
|
6556
|
+
/* @__PURE__ */ jsx32(
|
|
6557
|
+
"input",
|
|
6558
|
+
{
|
|
6559
|
+
type: "date",
|
|
6560
|
+
value: value?.from ?? "",
|
|
6561
|
+
onChange: (e) => handleFilterChange(f.key, { ...value, from: e.target.value }),
|
|
6562
|
+
className: "h-8 rounded-lg border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors"
|
|
6563
|
+
}
|
|
6564
|
+
),
|
|
6565
|
+
/* @__PURE__ */ jsx32("span", { className: "text-xs text-muted-foreground", children: "\u2013" }),
|
|
6566
|
+
/* @__PURE__ */ jsx32(
|
|
6567
|
+
"input",
|
|
6568
|
+
{
|
|
6569
|
+
type: "date",
|
|
6570
|
+
value: value?.to ?? "",
|
|
6571
|
+
onChange: (e) => handleFilterChange(f.key, { ...value, to: e.target.value }),
|
|
6572
|
+
className: "h-8 rounded-lg border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors"
|
|
6573
|
+
}
|
|
6574
|
+
)
|
|
6575
|
+
] })
|
|
6576
|
+
] }, f.key);
|
|
6577
|
+
return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6578
|
+
/* @__PURE__ */ jsx32("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
6579
|
+
/* @__PURE__ */ jsx32(
|
|
6580
|
+
"input",
|
|
6581
|
+
{
|
|
6582
|
+
type: "text",
|
|
6583
|
+
value: value ?? "",
|
|
6584
|
+
placeholder: f.placeholder ?? `Filter ${label}\u2026`,
|
|
6585
|
+
onChange: (e) => handleFilterChange(f.key, e.target.value),
|
|
6586
|
+
className: "h-8 min-w-[140px] rounded-lg border border-border bg-background px-3 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors"
|
|
6587
|
+
}
|
|
6588
|
+
)
|
|
6589
|
+
] }, f.key);
|
|
6590
|
+
}),
|
|
6591
|
+
sortKeys?.length ? /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6592
|
+
/* @__PURE__ */ jsx32("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: "Sort by" }),
|
|
6593
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-1.5", children: [
|
|
6594
|
+
/* @__PURE__ */ jsxs30(
|
|
6595
|
+
"select",
|
|
6596
|
+
{
|
|
6597
|
+
value: sortKey,
|
|
6598
|
+
onChange: (e) => {
|
|
6599
|
+
setSortKey(e.target.value);
|
|
6600
|
+
setCurrentPage(1);
|
|
6601
|
+
setTick((t) => t + 1);
|
|
6602
|
+
},
|
|
6603
|
+
className: "h-8 min-w-[120px] rounded-lg border border-border bg-background px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors",
|
|
6604
|
+
children: [
|
|
6605
|
+
/* @__PURE__ */ jsx32("option", { value: "", children: "Default" }),
|
|
6606
|
+
sortKeys.map((k) => /* @__PURE__ */ jsx32("option", { value: k, children: k.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()) }, k))
|
|
6607
|
+
]
|
|
6608
|
+
}
|
|
6609
|
+
),
|
|
6610
|
+
sortKey && /* @__PURE__ */ jsx32(
|
|
6611
|
+
"button",
|
|
6612
|
+
{
|
|
6613
|
+
type: "button",
|
|
6614
|
+
onClick: () => {
|
|
6615
|
+
setSortDir((d) => d === "asc" ? "desc" : "asc");
|
|
6616
|
+
setTick((t) => t + 1);
|
|
6617
|
+
},
|
|
6618
|
+
className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border bg-background text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
|
|
6619
|
+
title: sortDir === "asc" ? "Ascending" : "Descending",
|
|
6620
|
+
children: sortDir === "asc" ? /* @__PURE__ */ jsx32(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx32(ChevronDown4, { className: "h-3.5 w-3.5" })
|
|
6621
|
+
}
|
|
6622
|
+
)
|
|
6623
|
+
] })
|
|
6624
|
+
] }) : null,
|
|
6625
|
+
hasActiveFilters && /* @__PURE__ */ jsxs30(
|
|
6626
|
+
"button",
|
|
6627
|
+
{
|
|
6628
|
+
type: "button",
|
|
6629
|
+
onClick: handleClearFilters,
|
|
6630
|
+
className: "flex h-8 items-center gap-1.5 self-end rounded-lg border border-border bg-background px-3 text-xs font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors",
|
|
6631
|
+
children: [
|
|
6632
|
+
/* @__PURE__ */ jsx32(X9, { className: "h-3 w-3" }),
|
|
6633
|
+
" Clear"
|
|
6634
|
+
]
|
|
6635
|
+
}
|
|
6636
|
+
)
|
|
6637
|
+
] }) : null;
|
|
6377
6638
|
return {
|
|
6378
6639
|
data,
|
|
6379
6640
|
columns,
|
|
@@ -6382,11 +6643,18 @@ function useServerTable({ url, params, encrypt, key, decryptPayloadLog, columnOv
|
|
|
6382
6643
|
serverPagination: pagination ? { pagination, currentPage, goToPage: (page) => setCurrentPage(page) } : null,
|
|
6383
6644
|
loading,
|
|
6384
6645
|
error,
|
|
6646
|
+
filterBar,
|
|
6385
6647
|
goToPage: (page) => setCurrentPage(page),
|
|
6386
6648
|
reload: () => setTick((t) => t + 1),
|
|
6387
6649
|
refresh: () => setTick((t) => t + 1),
|
|
6650
|
+
// Passthrough props
|
|
6388
6651
|
searchValue,
|
|
6389
|
-
onSearchChange: handleSearchChange
|
|
6652
|
+
onSearchChange: handleSearchChange,
|
|
6653
|
+
page: currentPage,
|
|
6654
|
+
onPageChange: (page) => setCurrentPage(page),
|
|
6655
|
+
sort: [],
|
|
6656
|
+
onSortChange: () => {
|
|
6657
|
+
}
|
|
6390
6658
|
};
|
|
6391
6659
|
}
|
|
6392
6660
|
var MODAL_WIDTH = {
|
|
@@ -6444,7 +6712,8 @@ function validateField(field, value) {
|
|
|
6444
6712
|
return null;
|
|
6445
6713
|
}
|
|
6446
6714
|
function FieldRenderer({ field, value, onChange }) {
|
|
6447
|
-
if (field.
|
|
6715
|
+
if (field.component) return /* @__PURE__ */ jsx32(Fragment12, { children: field.component });
|
|
6716
|
+
if (field.render) return /* @__PURE__ */ jsx32(Fragment12, { children: field.render(value, onChange) });
|
|
6448
6717
|
const toLabelValue = (o) => {
|
|
6449
6718
|
if (typeof o === "string") return { label: o, value: o };
|
|
6450
6719
|
if (Array.isArray(o)) return { label: o[0], value: o[1] };
|
|
@@ -6536,9 +6805,33 @@ function FieldRenderer({ field, value, onChange }) {
|
|
|
6536
6805
|
case "rich-text":
|
|
6537
6806
|
return /* @__PURE__ */ jsx32(RichTextEditor, { value: value ?? "", onChange: (v) => onChange(v) });
|
|
6538
6807
|
case "file-upload":
|
|
6539
|
-
return /* @__PURE__ */ jsx32(FileUpload, {
|
|
6808
|
+
return /* @__PURE__ */ jsx32(FileUpload, { onFileSelect: (file) => onChange(file), onFilesChange: (files) => {
|
|
6809
|
+
if (files.length > 1) onChange(files);
|
|
6810
|
+
} });
|
|
6540
6811
|
case "repeater": {
|
|
6541
6812
|
const items = Array.isArray(value) ? value : [];
|
|
6813
|
+
if (field.repeaterFields) {
|
|
6814
|
+
const rows = Array.isArray(value) ? value : [];
|
|
6815
|
+
return /* @__PURE__ */ jsx32(
|
|
6816
|
+
Repeater,
|
|
6817
|
+
{
|
|
6818
|
+
items: rows,
|
|
6819
|
+
fields: field.repeaterFields,
|
|
6820
|
+
onAdd: () => {
|
|
6821
|
+
const blank = {};
|
|
6822
|
+
field.repeaterFields.forEach((f) => {
|
|
6823
|
+
blank[f.key] = "";
|
|
6824
|
+
});
|
|
6825
|
+
onChange([...rows, blank]);
|
|
6826
|
+
},
|
|
6827
|
+
onRemove: (i) => onChange(rows.filter((_, idx) => idx !== i)),
|
|
6828
|
+
onFieldChange: (i, key, val) => {
|
|
6829
|
+
const next = rows.map((r, idx) => idx === i ? { ...r, [key]: val } : r);
|
|
6830
|
+
onChange(next);
|
|
6831
|
+
}
|
|
6832
|
+
}
|
|
6833
|
+
);
|
|
6834
|
+
}
|
|
6542
6835
|
return /* @__PURE__ */ jsx32(
|
|
6543
6836
|
Repeater,
|
|
6544
6837
|
{
|
|
@@ -6579,8 +6872,172 @@ function ViewModal({
|
|
|
6579
6872
|
item,
|
|
6580
6873
|
fields,
|
|
6581
6874
|
onClose,
|
|
6582
|
-
width
|
|
6875
|
+
width,
|
|
6876
|
+
grid
|
|
6583
6877
|
}) {
|
|
6878
|
+
const renderViewValue = (f, value) => {
|
|
6879
|
+
const sizeStyle = {
|
|
6880
|
+
...f.width ? { width: typeof f.width === "number" ? `${f.width}px` : f.width } : {},
|
|
6881
|
+
...f.height ? { height: typeof f.height === "number" ? `${f.height}px` : f.height } : {}
|
|
6882
|
+
};
|
|
6883
|
+
const vt = f.viewType ?? f.type;
|
|
6884
|
+
const empty = value === null || value === void 0 || value === "";
|
|
6885
|
+
const dash = /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground italic text-sm", children: "\u2014" });
|
|
6886
|
+
if (f.component) return /* @__PURE__ */ jsx32(Fragment12, { children: f.component });
|
|
6887
|
+
if (f.render) return /* @__PURE__ */ jsx32(Fragment12, { children: f.render(value, () => {
|
|
6888
|
+
}) });
|
|
6889
|
+
switch (vt) {
|
|
6890
|
+
case "image":
|
|
6891
|
+
return empty ? dash : /* @__PURE__ */ jsx32(
|
|
6892
|
+
"img",
|
|
6893
|
+
{
|
|
6894
|
+
src: value,
|
|
6895
|
+
alt: f.label,
|
|
6896
|
+
className: "rounded-xl object-cover ring-1 ring-border",
|
|
6897
|
+
style: { width: sizeStyle.width ?? 128, height: sizeStyle.height ?? 128 }
|
|
6898
|
+
}
|
|
6899
|
+
);
|
|
6900
|
+
case "image-url":
|
|
6901
|
+
return empty ? dash : /* @__PURE__ */ jsx32(
|
|
6902
|
+
"a",
|
|
6903
|
+
{
|
|
6904
|
+
href: value,
|
|
6905
|
+
onClick: (e) => e.preventDefault(),
|
|
6906
|
+
className: "inline-block rounded-xl overflow-hidden ring-1 ring-border hover:ring-primary transition-all",
|
|
6907
|
+
style: { width: sizeStyle.width ?? 128, height: sizeStyle.height ?? 128 },
|
|
6908
|
+
children: /* @__PURE__ */ jsx32("img", { src: value, alt: f.label, className: "w-full h-full object-cover" })
|
|
6909
|
+
}
|
|
6910
|
+
);
|
|
6911
|
+
case "image-url-open-other-tabs":
|
|
6912
|
+
return empty ? dash : /* @__PURE__ */ jsx32(
|
|
6913
|
+
"a",
|
|
6914
|
+
{
|
|
6915
|
+
href: value,
|
|
6916
|
+
target: "_blank",
|
|
6917
|
+
rel: "noopener noreferrer",
|
|
6918
|
+
className: "inline-block rounded-xl overflow-hidden ring-1 ring-border hover:ring-primary transition-all",
|
|
6919
|
+
style: { width: sizeStyle.width ?? 128, height: sizeStyle.height ?? 128 },
|
|
6920
|
+
children: /* @__PURE__ */ jsx32("img", { src: value, alt: f.label, className: "w-full h-full object-cover" })
|
|
6921
|
+
}
|
|
6922
|
+
);
|
|
6923
|
+
case "text-url":
|
|
6924
|
+
return empty ? dash : /* @__PURE__ */ jsx32(
|
|
6925
|
+
"a",
|
|
6926
|
+
{
|
|
6927
|
+
href: value,
|
|
6928
|
+
onClick: (e) => e.preventDefault(),
|
|
6929
|
+
className: "text-sm text-primary underline underline-offset-2 hover:text-primary/80 break-all",
|
|
6930
|
+
style: sizeStyle,
|
|
6931
|
+
children: value
|
|
6932
|
+
}
|
|
6933
|
+
);
|
|
6934
|
+
case "text-url-open-other-tabs":
|
|
6935
|
+
return empty ? dash : /* @__PURE__ */ jsx32(
|
|
6936
|
+
"a",
|
|
6937
|
+
{
|
|
6938
|
+
href: value,
|
|
6939
|
+
target: "_blank",
|
|
6940
|
+
rel: "noopener noreferrer",
|
|
6941
|
+
className: "text-sm text-primary underline underline-offset-2 hover:text-primary/80 break-all",
|
|
6942
|
+
style: sizeStyle,
|
|
6943
|
+
children: value
|
|
6944
|
+
}
|
|
6945
|
+
);
|
|
6946
|
+
case "attachment":
|
|
6947
|
+
return empty ? dash : /* @__PURE__ */ jsxs30(
|
|
6948
|
+
"a",
|
|
6949
|
+
{
|
|
6950
|
+
href: value,
|
|
6951
|
+
target: "_blank",
|
|
6952
|
+
rel: "noopener noreferrer",
|
|
6953
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-3 py-1.5 text-xs font-medium text-foreground hover:bg-muted transition-colors",
|
|
6954
|
+
style: sizeStyle,
|
|
6955
|
+
children: [
|
|
6956
|
+
/* @__PURE__ */ jsx32("svg", { className: "h-3.5 w-3.5 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx32("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" }) }),
|
|
6957
|
+
String(value).split("/").pop() ?? "Download"
|
|
6958
|
+
]
|
|
6959
|
+
}
|
|
6960
|
+
);
|
|
6961
|
+
case "repeater": {
|
|
6962
|
+
const rows = Array.isArray(value) ? value : [];
|
|
6963
|
+
if (!rows.length) return dash;
|
|
6964
|
+
const rFields = f.repeaterFields;
|
|
6965
|
+
return /* @__PURE__ */ jsx32("div", { className: "space-y-2", children: rows.map((row, ri) => /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap gap-3 rounded-xl border border-border bg-muted/30 px-3 py-2", children: [
|
|
6966
|
+
/* @__PURE__ */ jsx32("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary", children: ri + 1 }),
|
|
6967
|
+
rFields ? rFields.map((rf) => {
|
|
6968
|
+
const v = row[rf.key];
|
|
6969
|
+
if (rf.type === "image") return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6970
|
+
rf.label && /* @__PURE__ */ jsx32("span", { className: "text-[10px] text-muted-foreground", children: rf.label }),
|
|
6971
|
+
v ? /* @__PURE__ */ jsx32("img", { src: v, alt: rf.key, className: "h-10 w-10 rounded-lg object-cover ring-1 ring-border" }) : dash
|
|
6972
|
+
] }, rf.key);
|
|
6973
|
+
if (rf.type === "attachment") return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6974
|
+
rf.label && /* @__PURE__ */ jsx32("span", { className: "text-[10px] text-muted-foreground", children: rf.label }),
|
|
6975
|
+
v ? /* @__PURE__ */ jsxs30(
|
|
6976
|
+
"a",
|
|
6977
|
+
{
|
|
6978
|
+
href: v,
|
|
6979
|
+
target: "_blank",
|
|
6980
|
+
rel: "noopener noreferrer",
|
|
6981
|
+
className: "inline-flex items-center gap-1 rounded-lg border border-border bg-muted/50 px-2 py-1 text-xs font-medium hover:bg-muted transition-colors",
|
|
6982
|
+
children: [
|
|
6983
|
+
/* @__PURE__ */ jsx32("svg", { className: "h-3 w-3 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx32("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" }) }),
|
|
6984
|
+
String(v).split("/").pop()
|
|
6985
|
+
]
|
|
6986
|
+
}
|
|
6987
|
+
) : dash
|
|
6988
|
+
] }, rf.key);
|
|
6989
|
+
return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6990
|
+
rf.label && /* @__PURE__ */ jsx32("span", { className: "text-[10px] text-muted-foreground", children: rf.label }),
|
|
6991
|
+
/* @__PURE__ */ jsx32("span", { className: "text-sm", children: v ?? "\u2014" })
|
|
6992
|
+
] }, rf.key);
|
|
6993
|
+
}) : (
|
|
6994
|
+
// payload mode: row has { type, key, value }
|
|
6995
|
+
Object.entries(row).map(([k, v]) => /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
|
|
6996
|
+
/* @__PURE__ */ jsx32("span", { className: "text-[10px] text-muted-foreground", children: k }),
|
|
6997
|
+
/* @__PURE__ */ jsx32("span", { className: "text-sm", children: String(v) })
|
|
6998
|
+
] }, k))
|
|
6999
|
+
)
|
|
7000
|
+
] }, ri)) });
|
|
7001
|
+
}
|
|
7002
|
+
case "checkbox":
|
|
7003
|
+
return /* @__PURE__ */ jsx32(
|
|
7004
|
+
"input",
|
|
7005
|
+
{
|
|
7006
|
+
type: "checkbox",
|
|
7007
|
+
checked: !!value,
|
|
7008
|
+
readOnly: true,
|
|
7009
|
+
className: "h-4 w-4 rounded border-border accent-primary cursor-default",
|
|
7010
|
+
style: sizeStyle
|
|
7011
|
+
}
|
|
7012
|
+
);
|
|
7013
|
+
case "toggle":
|
|
7014
|
+
return /* @__PURE__ */ jsx32(
|
|
7015
|
+
"div",
|
|
7016
|
+
{
|
|
7017
|
+
className: cn(
|
|
7018
|
+
"relative inline-flex shrink-0 rounded-full border-2 border-transparent transition-colors",
|
|
7019
|
+
value ? "bg-primary" : "bg-muted"
|
|
7020
|
+
),
|
|
7021
|
+
style: { width: sizeStyle.width ?? 36, height: sizeStyle.height ?? 20 },
|
|
7022
|
+
children: /* @__PURE__ */ jsx32(
|
|
7023
|
+
"span",
|
|
7024
|
+
{
|
|
7025
|
+
className: cn(
|
|
7026
|
+
"pointer-events-none inline-block rounded-full bg-white shadow-sm transition-transform"
|
|
7027
|
+
),
|
|
7028
|
+
style: {
|
|
7029
|
+
width: typeof (sizeStyle.height ?? 20) === "number" ? sizeStyle.height - 4 : 16,
|
|
7030
|
+
height: typeof (sizeStyle.height ?? 20) === "number" ? sizeStyle.height - 4 : 16,
|
|
7031
|
+
transform: value ? `translateX(${typeof (sizeStyle.width ?? 36) === "number" ? sizeStyle.width - (sizeStyle.height ?? 20) : 16}px)` : "translateX(0)"
|
|
7032
|
+
}
|
|
7033
|
+
}
|
|
7034
|
+
)
|
|
7035
|
+
}
|
|
7036
|
+
);
|
|
7037
|
+
default:
|
|
7038
|
+
return empty ? dash : /* @__PURE__ */ jsx32("p", { className: "text-sm text-foreground break-words", style: sizeStyle, children: String(value) });
|
|
7039
|
+
}
|
|
7040
|
+
};
|
|
6584
7041
|
return /* @__PURE__ */ jsx32(
|
|
6585
7042
|
ModalShell,
|
|
6586
7043
|
{
|
|
@@ -6588,11 +7045,27 @@ function ViewModal({
|
|
|
6588
7045
|
onClose,
|
|
6589
7046
|
width,
|
|
6590
7047
|
footer: /* @__PURE__ */ jsx32(Button, { variant: "outline", size: "sm", onClick: onClose, children: "Close" }),
|
|
6591
|
-
children: /* @__PURE__ */ jsx32(
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
7048
|
+
children: /* @__PURE__ */ jsx32(
|
|
7049
|
+
"div",
|
|
7050
|
+
{
|
|
7051
|
+
className: grid ? "grid gap-4" : "space-y-3",
|
|
7052
|
+
style: grid ? { gridTemplateColumns: `repeat(${grid}, minmax(0, 1fr))` } : void 0,
|
|
7053
|
+
children: fields.map((f) => /* @__PURE__ */ jsxs30(
|
|
7054
|
+
"div",
|
|
7055
|
+
{
|
|
7056
|
+
style: {
|
|
7057
|
+
...f.colSpan ? { gridColumn: `span ${f.colSpan}` } : {},
|
|
7058
|
+
...f.rowSpan ? { gridRow: `span ${f.rowSpan}` } : {}
|
|
7059
|
+
},
|
|
7060
|
+
children: [
|
|
7061
|
+
/* @__PURE__ */ jsx32("p", { className: "text-xs font-semibold text-muted-foreground mb-1", children: f.label }),
|
|
7062
|
+
renderViewValue(f, item[f.key])
|
|
7063
|
+
]
|
|
7064
|
+
},
|
|
7065
|
+
f.key
|
|
7066
|
+
))
|
|
7067
|
+
}
|
|
7068
|
+
)
|
|
6596
7069
|
}
|
|
6597
7070
|
);
|
|
6598
7071
|
}
|
|
@@ -6610,7 +7083,7 @@ function EditModal({
|
|
|
6610
7083
|
const [form, setForm] = React28.useState(() => {
|
|
6611
7084
|
const init = {};
|
|
6612
7085
|
fields.forEach((f) => {
|
|
6613
|
-
init[f.key] = item[f.key] ?? "";
|
|
7086
|
+
init[f.key] = f.type === "file-upload" ? null : item[f.key] ?? "";
|
|
6614
7087
|
});
|
|
6615
7088
|
return init;
|
|
6616
7089
|
});
|
|
@@ -6622,6 +7095,7 @@ function EditModal({
|
|
|
6622
7095
|
e.preventDefault();
|
|
6623
7096
|
const errs = {};
|
|
6624
7097
|
fields.forEach((f) => {
|
|
7098
|
+
if (f.type === "file-upload" && !form[f.key] && item[f.key]) return;
|
|
6625
7099
|
const msg = validateField(f, form[f.key]);
|
|
6626
7100
|
if (msg) errs[f.key] = msg;
|
|
6627
7101
|
});
|
|
@@ -6633,7 +7107,30 @@ function EditModal({
|
|
|
6633
7107
|
setLoading(true);
|
|
6634
7108
|
setError(null);
|
|
6635
7109
|
try {
|
|
6636
|
-
|
|
7110
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
7111
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
7112
|
+
const isFile = (v) => v instanceof File;
|
|
7113
|
+
const isFileArray = (v) => Array.isArray(v) && v.length > 0 && v[0] instanceof File;
|
|
7114
|
+
const hasFiles = Object.values(form).some((v) => isFile(v) || isFileArray(v));
|
|
7115
|
+
let body;
|
|
7116
|
+
if (hasFiles) {
|
|
7117
|
+
const fd = new FormData();
|
|
7118
|
+
fd.append("_method", "PUT");
|
|
7119
|
+
Object.entries(form).forEach(([k, v]) => {
|
|
7120
|
+
if (isFileArray(v)) {
|
|
7121
|
+
v.forEach((f) => fd.append(k, f));
|
|
7122
|
+
} else if (isFile(v)) {
|
|
7123
|
+
fd.append(k, v);
|
|
7124
|
+
} else if (v === null || v === void 0) {
|
|
7125
|
+
} else if (!Array.isArray(v)) {
|
|
7126
|
+
fd.append(k, String(v));
|
|
7127
|
+
}
|
|
7128
|
+
});
|
|
7129
|
+
body = fd;
|
|
7130
|
+
} else {
|
|
7131
|
+
body = form;
|
|
7132
|
+
}
|
|
7133
|
+
await axios3.put(`${baseUrl}/${itemId}/update`, body, { headers: { "X-CSRF-Token": csrfToken } });
|
|
6637
7134
|
const updated = { ...item, ...form };
|
|
6638
7135
|
if (notif && (notif.type ?? "toast") === "notification") {
|
|
6639
7136
|
setBanner(true);
|
|
@@ -6654,7 +7151,7 @@ function EditModal({
|
|
|
6654
7151
|
title: "Edit Record",
|
|
6655
7152
|
onClose,
|
|
6656
7153
|
width,
|
|
6657
|
-
footer: /* @__PURE__ */ jsxs30(
|
|
7154
|
+
footer: /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
6658
7155
|
/* @__PURE__ */ jsx32(Button, { variant: "outline", size: "sm", onClick: onClose, disabled: loading, children: "Cancel" }),
|
|
6659
7156
|
/* @__PURE__ */ jsxs30(Button, { size: "sm", onClick: handleSubmit, disabled: loading, children: [
|
|
6660
7157
|
loading && /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 mr-1.5 animate-spin" }),
|
|
@@ -6674,14 +7171,14 @@ function EditModal({
|
|
|
6674
7171
|
),
|
|
6675
7172
|
notif.action && /* @__PURE__ */ jsx32("div", { children: notif.action })
|
|
6676
7173
|
] }),
|
|
6677
|
-
fields.map((f) => /* @__PURE__ */
|
|
7174
|
+
fields.map((f) => /* @__PURE__ */ jsx32(
|
|
6678
7175
|
"div",
|
|
6679
7176
|
{
|
|
6680
7177
|
style: {
|
|
6681
7178
|
...f.colSpan ? { gridColumn: `span ${f.colSpan}` } : {},
|
|
6682
7179
|
...f.rowSpan ? { gridRow: `span ${f.rowSpan}` } : {}
|
|
6683
7180
|
},
|
|
6684
|
-
children: [
|
|
7181
|
+
children: f.component ? /* @__PURE__ */ jsx32(Fragment12, { children: f.component }) : /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
6685
7182
|
f.type !== "checkbox" && /* @__PURE__ */ jsxs30("label", { className: "block text-xs font-semibold text-muted-foreground mb-1", children: [
|
|
6686
7183
|
f.label,
|
|
6687
7184
|
f.required && /* @__PURE__ */ jsx32("span", { className: "text-danger ml-0.5", children: "*" })
|
|
@@ -6701,7 +7198,7 @@ function EditModal({
|
|
|
6701
7198
|
}
|
|
6702
7199
|
),
|
|
6703
7200
|
fieldErrors[f.key] && /* @__PURE__ */ jsx32("p", { className: "text-xs text-danger mt-1", children: fieldErrors[f.key] })
|
|
6704
|
-
]
|
|
7201
|
+
] })
|
|
6705
7202
|
},
|
|
6706
7203
|
f.key
|
|
6707
7204
|
)),
|
|
@@ -6724,7 +7221,9 @@ function DeleteModal({
|
|
|
6724
7221
|
setLoading(true);
|
|
6725
7222
|
setError(null);
|
|
6726
7223
|
try {
|
|
6727
|
-
|
|
7224
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
7225
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
7226
|
+
await axios3.delete(`${baseUrl}/${itemId}/delete?csrfToken=${encodeURIComponent(csrfToken)}`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
6728
7227
|
onSuccess?.(item);
|
|
6729
7228
|
onClose();
|
|
6730
7229
|
} catch (err) {
|
|
@@ -6739,7 +7238,7 @@ function DeleteModal({
|
|
|
6739
7238
|
title: "Confirm Delete",
|
|
6740
7239
|
onClose,
|
|
6741
7240
|
width: "lg",
|
|
6742
|
-
footer: /* @__PURE__ */ jsxs30(
|
|
7241
|
+
footer: /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
6743
7242
|
/* @__PURE__ */ jsx32(Button, { variant: "outline", size: "sm", onClick: onClose, disabled: loading, children: "Cancel" }),
|
|
6744
7243
|
/* @__PURE__ */ jsxs30(Button, { variant: "danger", size: "sm", onClick: handleDelete, disabled: loading, children: [
|
|
6745
7244
|
loading && /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 mr-1.5 animate-spin" }),
|
|
@@ -6799,26 +7298,89 @@ var BADGE_COLORS = {
|
|
|
6799
7298
|
function badgeClass(value) {
|
|
6800
7299
|
return BADGE_COLORS[value.toLowerCase()] ?? "bg-primary/10 text-primary border-primary/20";
|
|
6801
7300
|
}
|
|
7301
|
+
function deriveField(key, sample) {
|
|
7302
|
+
const label = key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7303
|
+
const base = { key, label };
|
|
7304
|
+
if (typeof sample === "boolean") return { ...base, type: "toggle", viewType: "toggle" };
|
|
7305
|
+
if (typeof sample === "number") return { ...base, inputType: "number" };
|
|
7306
|
+
if (Array.isArray(sample)) {
|
|
7307
|
+
if (sample.length === 0 || typeof sample[0] === "string")
|
|
7308
|
+
return { ...base, type: "tag-input" };
|
|
7309
|
+
return base;
|
|
7310
|
+
}
|
|
7311
|
+
if (typeof sample === "string") {
|
|
7312
|
+
if (/\.(png|jpe?g|gif|webp|svg|avif)(\?.*)?$/i.test(sample))
|
|
7313
|
+
return { ...base, type: "input", viewType: "image" };
|
|
7314
|
+
if (/\.(pdf|docx?|xlsx?|csv|zip|pptx?)(\?.*)?$/i.test(sample))
|
|
7315
|
+
return { ...base, type: "input", viewType: "attachment" };
|
|
7316
|
+
if (/^https?:\/\//.test(sample))
|
|
7317
|
+
return { ...base, type: "input", viewType: "text-url-open-other-tabs" };
|
|
7318
|
+
if (sample.length > 120 || /\n/.test(sample))
|
|
7319
|
+
return { ...base, type: "textarea" };
|
|
7320
|
+
if (/password|secret|token/i.test(key))
|
|
7321
|
+
return { ...base, type: "password" };
|
|
7322
|
+
if (/email/i.test(key))
|
|
7323
|
+
return { ...base, inputType: "email" };
|
|
7324
|
+
if (/color|colour/i.test(key) && /^#[0-9a-f]{3,8}$/i.test(sample))
|
|
7325
|
+
return { ...base, type: "color-picker", viewType: "text" };
|
|
7326
|
+
}
|
|
7327
|
+
return base;
|
|
7328
|
+
}
|
|
6802
7329
|
function Table({
|
|
6803
7330
|
data,
|
|
6804
7331
|
columns,
|
|
7332
|
+
loading,
|
|
7333
|
+
emptyState,
|
|
7334
|
+
error: errorProp,
|
|
6805
7335
|
searchable = false,
|
|
6806
7336
|
searchPlaceholder = "Search...",
|
|
6807
|
-
|
|
7337
|
+
searchValue: controlledSearch,
|
|
7338
|
+
onSearchChange,
|
|
7339
|
+
clientPagination = false,
|
|
6808
7340
|
itemsPerPage = 10,
|
|
6809
7341
|
selectable = false,
|
|
6810
7342
|
onBulkDelete,
|
|
6811
7343
|
idKey = "id",
|
|
7344
|
+
bulkDeleteBaseUrl,
|
|
6812
7345
|
defaultActions,
|
|
6813
7346
|
serverPagination,
|
|
6814
|
-
|
|
7347
|
+
variant = "default",
|
|
7348
|
+
className,
|
|
7349
|
+
onRowClick,
|
|
7350
|
+
onRowDoubleClick,
|
|
7351
|
+
rowClassName,
|
|
7352
|
+
expandable = false,
|
|
7353
|
+
renderExpanded,
|
|
7354
|
+
columnVisibility,
|
|
7355
|
+
onColumnVisibilityChange,
|
|
7356
|
+
columnVisibilityIcon,
|
|
7357
|
+
filterBar,
|
|
7358
|
+
filterableIcon,
|
|
7359
|
+
exportable = false,
|
|
7360
|
+
onExport,
|
|
7361
|
+
virtualized = false,
|
|
7362
|
+
draggable = false,
|
|
7363
|
+
onRowReorder,
|
|
7364
|
+
keyboardNavigation = false
|
|
6815
7365
|
}) {
|
|
6816
7366
|
const { toast } = useToast();
|
|
6817
|
-
const
|
|
7367
|
+
const isControlledSearch = controlledSearch !== void 0;
|
|
7368
|
+
const [internalSearch, setInternalSearch] = React28.useState("");
|
|
7369
|
+
const search = isControlledSearch ? controlledSearch : internalSearch;
|
|
7370
|
+
const setSearch = (v) => {
|
|
7371
|
+
if (!isControlledSearch) setInternalSearch(v);
|
|
7372
|
+
onSearchChange?.(v);
|
|
7373
|
+
};
|
|
6818
7374
|
const [currentPage, setCurrentPage] = React28.useState(1);
|
|
6819
7375
|
const [selectedIds, setSelectedIds] = React28.useState([]);
|
|
6820
7376
|
const [sortKey, setSortKey] = React28.useState(null);
|
|
6821
7377
|
const [sortDir, setSortDir] = React28.useState(null);
|
|
7378
|
+
const [bulkLoading, setBulkLoading] = React28.useState(false);
|
|
7379
|
+
const [bulkConfirm, setBulkConfirm] = React28.useState(null);
|
|
7380
|
+
const [filterBarOpen, setFilterBarOpen] = React28.useState(false);
|
|
7381
|
+
const [expandedIds, setExpandedIds] = React28.useState(/* @__PURE__ */ new Set());
|
|
7382
|
+
const [dragOverId, setDragOverId] = React28.useState(null);
|
|
7383
|
+
const [focusedRowIdx, setFocusedRowIdx] = React28.useState(-1);
|
|
6822
7384
|
const [viewItem, setViewItem] = React28.useState(null);
|
|
6823
7385
|
const [editItem, setEditItem] = React28.useState(null);
|
|
6824
7386
|
const [deleteItem, setDeleteItem] = React28.useState(null);
|
|
@@ -6830,15 +7392,17 @@ function Table({
|
|
|
6830
7392
|
const safeBaseUrl = defaultActions?.baseUrl.replace(/\/+$/, "") ?? "";
|
|
6831
7393
|
const autoFields = React28.useMemo(() => {
|
|
6832
7394
|
if (!tableData.length) return [];
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
label: k.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
|
|
6836
|
-
}));
|
|
7395
|
+
const row = tableData[0];
|
|
7396
|
+
return Object.keys(row).map((k) => deriveField(k, row[k]));
|
|
6837
7397
|
}, [tableData]);
|
|
6838
7398
|
const editFields = defaultActions?.editForm ?? autoFields;
|
|
6839
7399
|
const viewFields = defaultActions?.viewForm ?? autoFields;
|
|
7400
|
+
const visibleColumns = React28.useMemo(() => {
|
|
7401
|
+
if (!columnVisibility) return columns;
|
|
7402
|
+
return columns.filter((col) => columnVisibility[String(col.key)] !== false);
|
|
7403
|
+
}, [columns, columnVisibility]);
|
|
6840
7404
|
const allColumns = React28.useMemo(() => {
|
|
6841
|
-
if (!defaultActions) return
|
|
7405
|
+
if (!defaultActions) return visibleColumns;
|
|
6842
7406
|
const actionsCol = {
|
|
6843
7407
|
key: "__actions__",
|
|
6844
7408
|
title: "Actions",
|
|
@@ -6887,8 +7451,8 @@ function Table({
|
|
|
6887
7451
|
))
|
|
6888
7452
|
] })
|
|
6889
7453
|
};
|
|
6890
|
-
return defaultActions.position === "first" ? [actionsCol, ...
|
|
6891
|
-
}, [
|
|
7454
|
+
return defaultActions.position === "first" ? [actionsCol, ...visibleColumns] : [...visibleColumns, actionsCol];
|
|
7455
|
+
}, [visibleColumns, defaultActions]);
|
|
6892
7456
|
const handleSort = (key) => {
|
|
6893
7457
|
if (sortKey !== key) {
|
|
6894
7458
|
setSortKey(key);
|
|
@@ -6921,16 +7485,74 @@ function Table({
|
|
|
6921
7485
|
const totalPages = Math.max(1, Math.ceil(filteredData.length / itemsPerPage));
|
|
6922
7486
|
const safePage = Math.min(currentPage, totalPages);
|
|
6923
7487
|
const paginatedData = React28.useMemo(() => {
|
|
6924
|
-
if (!
|
|
7488
|
+
if (!clientPagination) return filteredData;
|
|
6925
7489
|
const start = (safePage - 1) * itemsPerPage;
|
|
6926
7490
|
return filteredData.slice(start, start + itemsPerPage);
|
|
6927
|
-
}, [filteredData,
|
|
7491
|
+
}, [filteredData, clientPagination, safePage, itemsPerPage]);
|
|
6928
7492
|
React28.useEffect(() => {
|
|
6929
7493
|
setCurrentPage(1);
|
|
6930
7494
|
}, [search]);
|
|
7495
|
+
React28.useEffect(() => {
|
|
7496
|
+
if (!keyboardNavigation) return;
|
|
7497
|
+
const handler = (e) => {
|
|
7498
|
+
if (e.key === "ArrowDown") {
|
|
7499
|
+
e.preventDefault();
|
|
7500
|
+
setFocusedRowIdx((i) => Math.min(i + 1, paginatedData.length - 1));
|
|
7501
|
+
}
|
|
7502
|
+
if (e.key === "ArrowUp") {
|
|
7503
|
+
e.preventDefault();
|
|
7504
|
+
setFocusedRowIdx((i) => Math.max(i - 1, 0));
|
|
7505
|
+
}
|
|
7506
|
+
};
|
|
7507
|
+
window.addEventListener("keydown", handler);
|
|
7508
|
+
return () => window.removeEventListener("keydown", handler);
|
|
7509
|
+
}, [keyboardNavigation, paginatedData.length]);
|
|
6931
7510
|
const handleSelectAll = (checked) => setSelectedIds(checked ? paginatedData.map((item) => String(item[idKey])) : []);
|
|
6932
7511
|
const handleSelect = (id, checked) => setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((i) => i !== id));
|
|
6933
7512
|
const allSelected = paginatedData.length > 0 && selectedIds.length === paginatedData.length;
|
|
7513
|
+
const totalRows = serverPagination ? serverPagination.pagination.total : filteredData.length;
|
|
7514
|
+
const unselectedCount = totalRows - selectedIds.length;
|
|
7515
|
+
const handleSelectAllRecords = () => setSelectedIds(filteredData.map((item) => String(item[idKey])));
|
|
7516
|
+
const handleUnselectAll = () => setSelectedIds([]);
|
|
7517
|
+
const execBulkDeleteSelected = async () => {
|
|
7518
|
+
if (!bulkDeleteBaseUrl || selectedIds.length === 0) {
|
|
7519
|
+
onBulkDelete?.(selectedIds);
|
|
7520
|
+
setSelectedIds([]);
|
|
7521
|
+
return;
|
|
7522
|
+
}
|
|
7523
|
+
setBulkLoading(true);
|
|
7524
|
+
try {
|
|
7525
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
7526
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
7527
|
+
const safeUrl = bulkDeleteBaseUrl.replace(/\/+$/, "");
|
|
7528
|
+
await axios3.delete(`${safeUrl}/delete/${selectedIds.join(",")}/selected`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
7529
|
+
setTableData((prev) => prev.filter((r) => !selectedIds.includes(String(r[idKey]))));
|
|
7530
|
+
onBulkDelete?.(selectedIds);
|
|
7531
|
+
setSelectedIds([]);
|
|
7532
|
+
defaultActions?.onReload?.();
|
|
7533
|
+
} catch (err) {
|
|
7534
|
+
console.error("[Table] Bulk delete selected failed:", err?.response?.data?.message ?? err.message);
|
|
7535
|
+
} finally {
|
|
7536
|
+
setBulkLoading(false);
|
|
7537
|
+
}
|
|
7538
|
+
};
|
|
7539
|
+
const execDeleteAll = async () => {
|
|
7540
|
+
if (!bulkDeleteBaseUrl) return;
|
|
7541
|
+
setBulkLoading(true);
|
|
7542
|
+
try {
|
|
7543
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
7544
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
7545
|
+
const safeUrl = bulkDeleteBaseUrl.replace(/\/+$/, "");
|
|
7546
|
+
await axios3.delete(`${safeUrl}/delete/all`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
7547
|
+
setTableData([]);
|
|
7548
|
+
setSelectedIds([]);
|
|
7549
|
+
defaultActions?.onReload?.();
|
|
7550
|
+
} catch (err) {
|
|
7551
|
+
console.error("[Table] Delete all failed:", err?.response?.data?.message ?? err.message);
|
|
7552
|
+
} finally {
|
|
7553
|
+
setBulkLoading(false);
|
|
7554
|
+
}
|
|
7555
|
+
};
|
|
6934
7556
|
const pagePills = React28.useMemo(() => {
|
|
6935
7557
|
if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
6936
7558
|
if (safePage <= 3) return [1, 2, 3, 4, 5];
|
|
@@ -6942,8 +7564,9 @@ function Table({
|
|
|
6942
7564
|
if (sortKey !== String(col.key)) return /* @__PURE__ */ jsx32(ChevronsUpDown, { className: "ml-1.5 h-3.5 w-3.5 opacity-40" });
|
|
6943
7565
|
return sortDir === "asc" ? /* @__PURE__ */ jsx32(ChevronUp, { className: "ml-1.5 h-3.5 w-3.5 text-primary" }) : /* @__PURE__ */ jsx32(ChevronDown4, { className: "ml-1.5 h-3.5 w-3.5 text-primary" });
|
|
6944
7566
|
};
|
|
6945
|
-
return /* @__PURE__ */ jsxs30(
|
|
7567
|
+
return /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
6946
7568
|
/* @__PURE__ */ jsxs30("div", { className: cn("w-full space-y-3", className), children: [
|
|
7569
|
+
errorProp && /* @__PURE__ */ jsx32("div", { className: "rounded-xl border border-danger/30 bg-danger/5 px-4 py-3 text-sm text-danger", children: errorProp }),
|
|
6947
7570
|
/* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-3 flex-wrap", children: [
|
|
6948
7571
|
searchable && /* @__PURE__ */ jsxs30("div", { className: "relative w-72", children: [
|
|
6949
7572
|
/* @__PURE__ */ jsx32(Search5, { className: "absolute text-primary left-3 top-1/2 -translate-y-1/2 h-4 w-4 z-10" }),
|
|
@@ -6965,33 +7588,127 @@ function Table({
|
|
|
6965
7588
|
}
|
|
6966
7589
|
)
|
|
6967
7590
|
] }),
|
|
6968
|
-
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 ml-auto", children: [
|
|
6969
|
-
selectable &&
|
|
7591
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 ml-auto flex-wrap", children: [
|
|
7592
|
+
selectable && selectedIds.length > 0 && /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
7593
|
+
/* @__PURE__ */ jsxs30(
|
|
7594
|
+
"button",
|
|
7595
|
+
{
|
|
7596
|
+
onClick: handleUnselectAll,
|
|
7597
|
+
disabled: bulkLoading,
|
|
7598
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors disabled:opacity-40",
|
|
7599
|
+
children: [
|
|
7600
|
+
/* @__PURE__ */ jsx32(X9, { className: "h-3.5 w-3.5" }),
|
|
7601
|
+
"Unselect all ",
|
|
7602
|
+
selectedIds.length
|
|
7603
|
+
]
|
|
7604
|
+
}
|
|
7605
|
+
),
|
|
7606
|
+
unselectedCount > 0 && /* @__PURE__ */ jsxs30(
|
|
7607
|
+
"button",
|
|
7608
|
+
{
|
|
7609
|
+
onClick: handleSelectAllRecords,
|
|
7610
|
+
disabled: bulkLoading,
|
|
7611
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors disabled:opacity-40",
|
|
7612
|
+
children: [
|
|
7613
|
+
"Select all ",
|
|
7614
|
+
unselectedCount
|
|
7615
|
+
]
|
|
7616
|
+
}
|
|
7617
|
+
),
|
|
7618
|
+
/* @__PURE__ */ jsxs30(
|
|
7619
|
+
"button",
|
|
7620
|
+
{
|
|
7621
|
+
onClick: () => setBulkConfirm("selected"),
|
|
7622
|
+
disabled: bulkLoading,
|
|
7623
|
+
className: "inline-flex items-center gap-1.5 rounded-lg bg-danger/10 border border-danger/20 px-3 py-1.5 text-xs font-medium text-danger hover:bg-danger/20 transition-colors disabled:opacity-40",
|
|
7624
|
+
children: [
|
|
7625
|
+
bulkLoading ? /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx32(Trash22, { className: "h-3.5 w-3.5" }),
|
|
7626
|
+
"Delete ",
|
|
7627
|
+
selectedIds.length,
|
|
7628
|
+
" selected"
|
|
7629
|
+
]
|
|
7630
|
+
}
|
|
7631
|
+
),
|
|
7632
|
+
bulkDeleteBaseUrl && /* @__PURE__ */ jsxs30(
|
|
7633
|
+
"button",
|
|
7634
|
+
{
|
|
7635
|
+
onClick: () => setBulkConfirm("all"),
|
|
7636
|
+
disabled: bulkLoading,
|
|
7637
|
+
className: "inline-flex items-center gap-1.5 rounded-lg bg-danger/10 border border-danger/20 px-3 py-1.5 text-xs font-medium text-danger hover:bg-danger/20 transition-colors disabled:opacity-40",
|
|
7638
|
+
children: [
|
|
7639
|
+
bulkLoading ? /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx32(Trash22, { className: "h-3.5 w-3.5" }),
|
|
7640
|
+
"Delete all"
|
|
7641
|
+
]
|
|
7642
|
+
}
|
|
7643
|
+
)
|
|
7644
|
+
] }),
|
|
7645
|
+
filterBar && /* @__PURE__ */ jsx32(
|
|
6970
7646
|
"button",
|
|
6971
7647
|
{
|
|
6972
|
-
onClick: () =>
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
children:
|
|
6978
|
-
/* @__PURE__ */ jsx32(Trash22, { className: "h-3.5 w-3.5" }),
|
|
6979
|
-
"Delete ",
|
|
6980
|
-
selectedIds.length,
|
|
6981
|
-
" selected"
|
|
6982
|
-
]
|
|
7648
|
+
onClick: () => setFilterBarOpen((o) => !o),
|
|
7649
|
+
className: cn(
|
|
7650
|
+
"inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-xs font-medium transition-colors",
|
|
7651
|
+
filterBarOpen ? "border-primary bg-primary/10 text-primary hover:bg-primary/20" : "border-border bg-muted/50 text-muted-foreground hover:bg-muted"
|
|
7652
|
+
),
|
|
7653
|
+
children: filterableIcon ?? "Filter"
|
|
6983
7654
|
}
|
|
6984
7655
|
),
|
|
7656
|
+
exportable && /* @__PURE__ */ jsxs30("div", { className: "relative group", children: [
|
|
7657
|
+
/* @__PURE__ */ jsx32("button", { className: "inline-flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors", children: "Export" }),
|
|
7658
|
+
/* @__PURE__ */ jsx32("div", { className: "absolute right-0 top-full mt-1 z-20 hidden group-hover:flex flex-col min-w-[110px] rounded-xl border border-border bg-card shadow-lg overflow-hidden", children: ["csv", "excel", "pdf"].map((type) => /* @__PURE__ */ jsx32(
|
|
7659
|
+
"button",
|
|
7660
|
+
{
|
|
7661
|
+
onClick: () => onExport?.(type),
|
|
7662
|
+
className: "px-4 py-2 text-xs text-left hover:bg-muted transition-colors capitalize",
|
|
7663
|
+
children: type.toUpperCase()
|
|
7664
|
+
},
|
|
7665
|
+
type
|
|
7666
|
+
)) })
|
|
7667
|
+
] }),
|
|
7668
|
+
columnVisibility && onColumnVisibilityChange && /* @__PURE__ */ jsxs30("div", { className: "relative group", children: [
|
|
7669
|
+
/* @__PURE__ */ jsx32("button", { className: "inline-flex items-center gap-1.5 rounded-lg border border-border bg-muted/50 px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-muted transition-colors", children: columnVisibilityIcon ?? "Columns" }),
|
|
7670
|
+
/* @__PURE__ */ jsx32("div", { className: "absolute right-0 top-full mt-1 z-20 hidden group-hover:flex flex-col min-w-[150px] rounded-xl border border-border bg-card shadow-lg overflow-hidden p-2 gap-1", children: columns.map((col) => /* @__PURE__ */ jsxs30("label", { className: "flex items-center gap-2 px-2 py-1 rounded-lg hover:bg-muted cursor-pointer text-xs", children: [
|
|
7671
|
+
/* @__PURE__ */ jsx32(
|
|
7672
|
+
"input",
|
|
7673
|
+
{
|
|
7674
|
+
type: "checkbox",
|
|
7675
|
+
checked: columnVisibility[String(col.key)] !== false,
|
|
7676
|
+
onChange: (e) => onColumnVisibilityChange({ ...columnVisibility, [String(col.key)]: e.target.checked }),
|
|
7677
|
+
className: "accent-primary"
|
|
7678
|
+
}
|
|
7679
|
+
),
|
|
7680
|
+
col.title
|
|
7681
|
+
] }, String(col.key))) })
|
|
7682
|
+
] }),
|
|
6985
7683
|
/* @__PURE__ */ jsxs30("span", { className: "text-xs text-muted-foreground", children: [
|
|
6986
|
-
|
|
7684
|
+
totalRows,
|
|
6987
7685
|
" ",
|
|
6988
|
-
|
|
7686
|
+
totalRows === 1 ? "row" : "rows",
|
|
6989
7687
|
search && ` \xB7 filtered from ${tableData.length}`
|
|
6990
7688
|
] })
|
|
6991
7689
|
] })
|
|
6992
7690
|
] }),
|
|
6993
|
-
|
|
6994
|
-
|
|
7691
|
+
filterBar && filterBarOpen && /* @__PURE__ */ jsx32("div", { children: filterBar }),
|
|
7692
|
+
loading && /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-center py-12 text-muted-foreground gap-2", children: [
|
|
7693
|
+
/* @__PURE__ */ jsx32(Loader22, { className: "h-5 w-5 animate-spin" }),
|
|
7694
|
+
/* @__PURE__ */ jsx32("span", { className: "text-sm", children: "Loading\u2026" })
|
|
7695
|
+
] }),
|
|
7696
|
+
!loading && /* @__PURE__ */ jsx32("div", { className: cn(
|
|
7697
|
+
variant === "default" && "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm",
|
|
7698
|
+
variant === "zebra" && "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm",
|
|
7699
|
+
variant === "card" && "space-y-2",
|
|
7700
|
+
variant === "glass" && "rounded-2xl overflow-hidden border border-white/10 bg-background/30 backdrop-blur-xl shadow-xl",
|
|
7701
|
+
variant === "soft" && "rounded-2xl overflow-hidden bg-card",
|
|
7702
|
+
variant === "soft" && "[box-shadow:6px_6px_12px_hsl(var(--foreground)/0.07),-6px_-6px_12px_hsl(var(--background)/0.8)]",
|
|
7703
|
+
virtualized && "max-h-[520px] overflow-y-auto"
|
|
7704
|
+
), children: /* @__PURE__ */ jsx32("div", { className: cn("w-full overflow-auto", variant === "card" && "space-y-2"), children: /* @__PURE__ */ jsxs30("table", { className: cn("w-full caption-bottom text-sm", variant === "card" && "border-separate border-spacing-y-2"), children: [
|
|
7705
|
+
/* @__PURE__ */ jsx32("thead", { children: /* @__PURE__ */ jsxs30("tr", { className: cn(
|
|
7706
|
+
variant === "default" && "border-b border-border bg-muted/40",
|
|
7707
|
+
variant === "zebra" && "border-b border-border bg-muted/40",
|
|
7708
|
+
variant === "card" && "[&>th]:bg-transparent",
|
|
7709
|
+
variant === "glass" && "border-b border-white/10 bg-white/5",
|
|
7710
|
+
variant === "soft" && "border-b-0 bg-muted/30"
|
|
7711
|
+
), children: [
|
|
6995
7712
|
selectable && /* @__PURE__ */ jsx32("th", { className: "h-11 w-[46px] px-4 text-left align-middle", children: /* @__PURE__ */ jsx32(
|
|
6996
7713
|
Checkbox,
|
|
6997
7714
|
{
|
|
@@ -6999,13 +7716,16 @@ function Table({
|
|
|
6999
7716
|
onChange: (e) => handleSelectAll(e.target.checked)
|
|
7000
7717
|
}
|
|
7001
7718
|
) }),
|
|
7719
|
+
expandable && /* @__PURE__ */ jsx32("th", { className: "h-11 w-8" }),
|
|
7002
7720
|
allColumns.map((col, ci) => /* @__PURE__ */ jsx32(
|
|
7003
7721
|
"th",
|
|
7004
7722
|
{
|
|
7005
7723
|
onClick: () => col.sortable && handleSort(String(col.key)),
|
|
7006
7724
|
className: cn(
|
|
7007
7725
|
"h-11 px-4 text-left align-middle text-xs font-semibold uppercase tracking-wider text-muted-foreground select-none whitespace-nowrap",
|
|
7008
|
-
col.sortable && "cursor-pointer hover:text-foreground transition-colors"
|
|
7726
|
+
col.sortable && "cursor-pointer hover:text-foreground transition-colors",
|
|
7727
|
+
variant === "glass" && "text-foreground/70",
|
|
7728
|
+
variant === "soft" && "text-muted-foreground/80"
|
|
7009
7729
|
),
|
|
7010
7730
|
children: /* @__PURE__ */ jsxs30("span", { className: "inline-flex items-center", children: [
|
|
7011
7731
|
col.title,
|
|
@@ -7018,9 +7738,9 @@ function Table({
|
|
|
7018
7738
|
/* @__PURE__ */ jsx32("tbody", { children: paginatedData.length === 0 ? /* @__PURE__ */ jsx32("tr", { children: /* @__PURE__ */ jsx32(
|
|
7019
7739
|
"td",
|
|
7020
7740
|
{
|
|
7021
|
-
colSpan: allColumns.length + (selectable ? 1 : 0),
|
|
7741
|
+
colSpan: allColumns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0),
|
|
7022
7742
|
className: "h-32 text-center align-middle",
|
|
7023
|
-
children: /* @__PURE__ */ jsxs30("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
7743
|
+
children: emptyState ?? /* @__PURE__ */ jsxs30("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
7024
7744
|
/* @__PURE__ */ jsx32(Search5, { className: "h-8 w-8 opacity-20" }),
|
|
7025
7745
|
/* @__PURE__ */ jsx32("span", { className: "text-sm", children: "No results found" }),
|
|
7026
7746
|
search && /* @__PURE__ */ jsx32("button", { onClick: () => setSearch(""), className: "text-xs text-primary hover:underline", children: "Clear search" })
|
|
@@ -7029,85 +7749,168 @@ function Table({
|
|
|
7029
7749
|
) }) : paginatedData.map((item, i) => {
|
|
7030
7750
|
const id = String(item[idKey] || i);
|
|
7031
7751
|
const isSelected = selectedIds.includes(id);
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7752
|
+
const isExpanded = expandedIds.has(id);
|
|
7753
|
+
const isFocused = keyboardNavigation && focusedRowIdx === i;
|
|
7754
|
+
return /* @__PURE__ */ jsxs30(React28.Fragment, { children: [
|
|
7755
|
+
/* @__PURE__ */ jsxs30(
|
|
7756
|
+
"tr",
|
|
7757
|
+
{
|
|
7758
|
+
draggable,
|
|
7759
|
+
tabIndex: keyboardNavigation ? 0 : void 0,
|
|
7760
|
+
onDragStart: draggable ? (e) => {
|
|
7761
|
+
e.dataTransfer.setData("text/plain", id);
|
|
7762
|
+
} : void 0,
|
|
7763
|
+
onDragOver: draggable ? (e) => {
|
|
7764
|
+
e.preventDefault();
|
|
7765
|
+
setDragOverId(id);
|
|
7766
|
+
} : void 0,
|
|
7767
|
+
onDragLeave: draggable ? () => setDragOverId(null) : void 0,
|
|
7768
|
+
onDrop: draggable ? (e) => {
|
|
7769
|
+
e.preventDefault();
|
|
7770
|
+
setDragOverId(null);
|
|
7771
|
+
const fromId = e.dataTransfer.getData("text/plain");
|
|
7772
|
+
if (fromId === id) return;
|
|
7773
|
+
setTableData((prev) => {
|
|
7774
|
+
const fromIdx = prev.findIndex((r) => String(r[idKey] || "") === fromId);
|
|
7775
|
+
const toIdx = prev.findIndex((r) => String(r[idKey] || "") === id);
|
|
7776
|
+
if (fromIdx < 0 || toIdx < 0) return prev;
|
|
7777
|
+
const next = [...prev];
|
|
7778
|
+
const [moved] = next.splice(fromIdx, 1);
|
|
7779
|
+
next.splice(toIdx, 0, moved);
|
|
7780
|
+
onRowReorder?.(next);
|
|
7781
|
+
return next;
|
|
7782
|
+
});
|
|
7783
|
+
} : void 0,
|
|
7784
|
+
onClick: () => {
|
|
7785
|
+
if (expandable) setExpandedIds((prev) => {
|
|
7786
|
+
const s = new Set(prev);
|
|
7787
|
+
s.has(id) ? s.delete(id) : s.add(id);
|
|
7788
|
+
return s;
|
|
7789
|
+
});
|
|
7790
|
+
onRowClick?.(item);
|
|
7791
|
+
if (keyboardNavigation) setFocusedRowIdx(i);
|
|
7792
|
+
},
|
|
7793
|
+
onDoubleClick: () => onRowDoubleClick?.(item),
|
|
7794
|
+
className: cn(
|
|
7795
|
+
// default
|
|
7796
|
+
variant === "default" && "border-b border-border/60 transition-colors last:border-0",
|
|
7797
|
+
variant === "default" && (isSelected ? "bg-primary/5 hover:bg-primary/8" : "hover:bg-muted/30"),
|
|
7798
|
+
// zebra
|
|
7799
|
+
variant === "zebra" && "border-b border-border/40 transition-colors last:border-0",
|
|
7800
|
+
variant === "zebra" && (isSelected ? "bg-primary/8" : i % 2 === 0 ? "bg-card" : "bg-muted/40"),
|
|
7801
|
+
variant === "zebra" && !isSelected && "hover:bg-primary/5",
|
|
7802
|
+
// card
|
|
7803
|
+
variant === "card" && "rounded-xl border border-border bg-card shadow-sm transition-all hover:shadow-md hover:-translate-y-px",
|
|
7804
|
+
variant === "card" && (isSelected ? "border-primary/50 bg-primary/5" : ""),
|
|
7805
|
+
variant === "card" && "[&>td:first-child]:rounded-l-xl [&>td:last-child]:rounded-r-xl",
|
|
7806
|
+
// glass
|
|
7807
|
+
variant === "glass" && "border-b border-white/8 transition-colors last:border-0",
|
|
7808
|
+
variant === "glass" && (isSelected ? "bg-primary/15 hover:bg-primary/20" : "hover:bg-white/5"),
|
|
7809
|
+
// soft
|
|
7810
|
+
variant === "soft" && "transition-all",
|
|
7811
|
+
variant === "soft" && (isSelected ? "bg-primary/8 [box-shadow:inset_2px_2px_5px_hsl(var(--foreground)/0.06),inset_-2px_-2px_5px_hsl(var(--background)/0.7)]" : "hover:bg-muted/20"),
|
|
7812
|
+
variant === "soft" && "border-b border-border/30 last:border-0",
|
|
7813
|
+
(onRowClick || onRowDoubleClick || expandable) && "cursor-pointer",
|
|
7814
|
+
draggable && dragOverId === id && "ring-2 ring-inset ring-primary/40",
|
|
7815
|
+
isFocused && "ring-2 ring-inset ring-ring",
|
|
7816
|
+
rowClassName?.(item)
|
|
7817
|
+
),
|
|
7818
|
+
children: [
|
|
7819
|
+
selectable && /* @__PURE__ */ jsx32("td", { className: "px-4 py-3 align-middle", children: /* @__PURE__ */ jsx32(
|
|
7820
|
+
Checkbox,
|
|
7821
|
+
{
|
|
7822
|
+
checked: isSelected,
|
|
7823
|
+
onChange: (e) => handleSelect(id, e.target.checked)
|
|
7824
|
+
}
|
|
7061
7825
|
) }),
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
children: /* @__PURE__ */ jsx32("span", { className: cn(
|
|
7082
|
-
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
7083
|
-
item[col.key] ? "translate-x-4" : "translate-x-0"
|
|
7084
|
-
) })
|
|
7085
|
-
}
|
|
7086
|
-
) : col.type === "color" ? /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
7087
|
-
/* @__PURE__ */ jsx32(
|
|
7088
|
-
"input",
|
|
7826
|
+
expandable && /* @__PURE__ */ jsx32("td", { className: "w-8 px-2 py-3 align-middle", children: /* @__PURE__ */ jsx32(ChevronRight8, { className: cn("h-3.5 w-3.5 text-muted-foreground transition-transform", isExpanded && "rotate-90") }) }),
|
|
7827
|
+
allColumns.map((col, ci) => /* @__PURE__ */ jsx32("td", { className: "px-4 py-3 align-middle", children: col.render ? col.render(item) : col.type === "image" ? /* @__PURE__ */ jsx32(
|
|
7828
|
+
"img",
|
|
7829
|
+
{
|
|
7830
|
+
src: item[col.key],
|
|
7831
|
+
alt: item[col.key],
|
|
7832
|
+
className: "h-9 w-9 rounded-lg object-cover ring-1 ring-border"
|
|
7833
|
+
}
|
|
7834
|
+
) : col.type === "badge" ? /* @__PURE__ */ jsxs30("span", { className: cn(
|
|
7835
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium",
|
|
7836
|
+
badgeClass(String(item[col.key]))
|
|
7837
|
+
), children: [
|
|
7838
|
+
/* @__PURE__ */ jsx32("span", { className: cn(
|
|
7839
|
+
"mr-1.5 h-1.5 w-1.5 rounded-full",
|
|
7840
|
+
badgeClass(String(item[col.key])).includes("success") ? "bg-success" : badgeClass(String(item[col.key])).includes("warning") ? "bg-warning" : badgeClass(String(item[col.key])).includes("danger") ? "bg-danger" : badgeClass(String(item[col.key])).includes("info") ? "bg-info" : "bg-primary"
|
|
7841
|
+
) }),
|
|
7842
|
+
item[col.key]
|
|
7843
|
+
] }) : col.type === "stack" ? /* @__PURE__ */ jsx32(AvatarStack, { images: Array.isArray(item[col.key]) ? item[col.key] : [], ...col.stackProps ?? {} }) : col.type === "icon" ? /* @__PURE__ */ jsx32("span", { className: "flex items-center", children: item[col.key] }) : col.type === "select" ? /* @__PURE__ */ jsx32(
|
|
7844
|
+
"select",
|
|
7089
7845
|
{
|
|
7090
|
-
|
|
7091
|
-
value: item[col.key] || "#000000",
|
|
7846
|
+
value: item[col.key],
|
|
7092
7847
|
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
7093
|
-
className: "h-
|
|
7848
|
+
className: "h-8 rounded-lg border border-border bg-background/50 px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors",
|
|
7849
|
+
children: (col.selectOptions ?? []).map((opt) => /* @__PURE__ */ jsx32("option", { value: opt, children: opt }, opt))
|
|
7094
7850
|
}
|
|
7095
|
-
)
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7851
|
+
) : col.type === "toggle" ? /* @__PURE__ */ jsx32(
|
|
7852
|
+
"button",
|
|
7853
|
+
{
|
|
7854
|
+
role: "switch",
|
|
7855
|
+
"aria-checked": !!item[col.key],
|
|
7856
|
+
onClick: () => col.onChange?.(item, !item[col.key]),
|
|
7857
|
+
className: cn(
|
|
7858
|
+
"relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
7859
|
+
item[col.key] ? "bg-primary" : "bg-muted"
|
|
7860
|
+
),
|
|
7861
|
+
children: /* @__PURE__ */ jsx32("span", { className: cn(
|
|
7862
|
+
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
7863
|
+
item[col.key] ? "translate-x-4" : "translate-x-0"
|
|
7864
|
+
) })
|
|
7865
|
+
}
|
|
7866
|
+
) : col.type === "color" ? /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
7867
|
+
/* @__PURE__ */ jsx32(
|
|
7868
|
+
"input",
|
|
7869
|
+
{
|
|
7870
|
+
type: "color",
|
|
7871
|
+
value: item[col.key] || "#000000",
|
|
7872
|
+
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
7873
|
+
className: "h-7 w-7 cursor-pointer rounded border border-border bg-transparent p-0.5"
|
|
7874
|
+
}
|
|
7875
|
+
),
|
|
7876
|
+
/* @__PURE__ */ jsx32("span", { className: "text-xs text-muted-foreground font-mono", children: item[col.key] })
|
|
7877
|
+
] }) : col.type === "checkbox" ? /* @__PURE__ */ jsx32(
|
|
7878
|
+
Checkbox,
|
|
7879
|
+
{
|
|
7880
|
+
checked: !!item[col.key],
|
|
7881
|
+
onChange: (e) => col.onChange?.(item, e.target.checked)
|
|
7882
|
+
}
|
|
7883
|
+
) : col.type === "text-url" ? (() => {
|
|
7884
|
+
const href = col.redirect ? typeof col.redirect === "function" ? col.redirect(item) : col.redirect : String(item[col.key] ?? "");
|
|
7885
|
+
const colorMap = {
|
|
7886
|
+
primary: "var(--primary)",
|
|
7887
|
+
info: "var(--info)",
|
|
7888
|
+
success: "var(--success)",
|
|
7889
|
+
warning: "var(--warning)",
|
|
7890
|
+
danger: "var(--danger)"
|
|
7891
|
+
};
|
|
7892
|
+
const underline = col.underlineColor ? colorMap[col.underlineColor] ?? col.underlineColor : "var(--primary)";
|
|
7893
|
+
return /* @__PURE__ */ jsx32(
|
|
7894
|
+
"a",
|
|
7895
|
+
{
|
|
7896
|
+
href,
|
|
7897
|
+
target: col.openNewTab ? "_blank" : void 0,
|
|
7898
|
+
rel: col.openNewTab ? "noopener noreferrer" : void 0,
|
|
7899
|
+
style: { textDecorationColor: underline },
|
|
7900
|
+
className: "text-sm underline underline-offset-2 hover:opacity-75 transition-opacity break-all",
|
|
7901
|
+
onClick: col.openNewTab ? void 0 : (e) => e.preventDefault(),
|
|
7902
|
+
children: item[col.key]
|
|
7903
|
+
}
|
|
7904
|
+
);
|
|
7905
|
+
})() : /* @__PURE__ */ jsx32("span", { className: "text-foreground/90", children: item[col.key] }) }, `${String(col.key)}-${ci}`))
|
|
7906
|
+
]
|
|
7907
|
+
}
|
|
7908
|
+
),
|
|
7909
|
+
expandable && isExpanded && renderExpanded && /* @__PURE__ */ jsx32("tr", { className: "bg-muted/20 border-b border-border/60", children: /* @__PURE__ */ jsx32("td", { colSpan: allColumns.length + (selectable ? 1 : 0) + 1, className: "px-6 py-3", children: renderExpanded(item) }) })
|
|
7910
|
+
] }, id);
|
|
7108
7911
|
}) })
|
|
7109
7912
|
] }) }) }),
|
|
7110
|
-
|
|
7913
|
+
clientPagination && !serverPagination && totalPages > 1 && /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
7111
7914
|
/* @__PURE__ */ jsxs30("span", { className: "text-xs text-muted-foreground", children: [
|
|
7112
7915
|
"Showing ",
|
|
7113
7916
|
(safePage - 1) * itemsPerPage + 1,
|
|
@@ -7126,7 +7929,7 @@ function Table({
|
|
|
7126
7929
|
children: /* @__PURE__ */ jsx32(ChevronLeft6, { className: "h-4 w-4" })
|
|
7127
7930
|
}
|
|
7128
7931
|
),
|
|
7129
|
-
pagePills[0] > 1 && /* @__PURE__ */ jsxs30(
|
|
7932
|
+
pagePills[0] > 1 && /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
7130
7933
|
/* @__PURE__ */ jsx32("button", { onClick: () => setCurrentPage(1), className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-xs text-muted-foreground hover:bg-muted transition-colors", children: "1" }),
|
|
7131
7934
|
pagePills[0] > 2 && /* @__PURE__ */ jsx32("span", { className: "px-1 text-muted-foreground text-xs", children: "\u2026" })
|
|
7132
7935
|
] }),
|
|
@@ -7142,7 +7945,7 @@ function Table({
|
|
|
7142
7945
|
},
|
|
7143
7946
|
p
|
|
7144
7947
|
)),
|
|
7145
|
-
pagePills[pagePills.length - 1] < totalPages && /* @__PURE__ */ jsxs30(
|
|
7948
|
+
pagePills[pagePills.length - 1] < totalPages && /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
7146
7949
|
pagePills[pagePills.length - 1] < totalPages - 1 && /* @__PURE__ */ jsx32("span", { className: "px-1 text-muted-foreground text-xs", children: "\u2026" }),
|
|
7147
7950
|
/* @__PURE__ */ jsx32("button", { onClick: () => setCurrentPage(totalPages), className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-xs text-muted-foreground hover:bg-muted transition-colors", children: totalPages })
|
|
7148
7951
|
] }),
|
|
@@ -7158,8 +7961,8 @@ function Table({
|
|
|
7158
7961
|
] })
|
|
7159
7962
|
] }),
|
|
7160
7963
|
serverPagination && (() => {
|
|
7161
|
-
const { pagination
|
|
7162
|
-
const totalServerPages =
|
|
7964
|
+
const { pagination, currentPage: cp, goToPage } = serverPagination;
|
|
7965
|
+
const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
|
|
7163
7966
|
const pills = [];
|
|
7164
7967
|
if (totalServerPages <= 7) {
|
|
7165
7968
|
for (let i = 1; i <= totalServerPages; i++) pills.push(i);
|
|
@@ -7172,7 +7975,7 @@ function Table({
|
|
|
7172
7975
|
}
|
|
7173
7976
|
return /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
7174
7977
|
/* @__PURE__ */ jsxs30("span", { className: "text-xs text-muted-foreground", children: [
|
|
7175
|
-
|
|
7978
|
+
pagination.total,
|
|
7176
7979
|
" total rows \xB7 page ",
|
|
7177
7980
|
cp,
|
|
7178
7981
|
" of ",
|
|
@@ -7183,7 +7986,7 @@ function Table({
|
|
|
7183
7986
|
"button",
|
|
7184
7987
|
{
|
|
7185
7988
|
onClick: () => goToPage(cp - 1),
|
|
7186
|
-
disabled: !
|
|
7989
|
+
disabled: !pagination.prev_page_url,
|
|
7187
7990
|
className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:pointer-events-none",
|
|
7188
7991
|
children: /* @__PURE__ */ jsx32(ChevronLeft6, { className: "h-4 w-4" })
|
|
7189
7992
|
}
|
|
@@ -7206,7 +8009,7 @@ function Table({
|
|
|
7206
8009
|
"button",
|
|
7207
8010
|
{
|
|
7208
8011
|
onClick: () => goToPage(cp + 1),
|
|
7209
|
-
disabled: !
|
|
8012
|
+
disabled: !pagination.next_page_url,
|
|
7210
8013
|
className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:pointer-events-none",
|
|
7211
8014
|
children: /* @__PURE__ */ jsx32(ChevronRight8, { className: "h-4 w-4" })
|
|
7212
8015
|
}
|
|
@@ -7221,6 +8024,7 @@ function Table({
|
|
|
7221
8024
|
item: viewItem,
|
|
7222
8025
|
fields: viewFields,
|
|
7223
8026
|
width: defaultActions.modalWidth,
|
|
8027
|
+
grid: defaultActions.viewFormGrid,
|
|
7224
8028
|
onClose: () => setViewItem(null)
|
|
7225
8029
|
}
|
|
7226
8030
|
),
|
|
@@ -7278,12 +8082,43 @@ function Table({
|
|
|
7278
8082
|
}
|
|
7279
8083
|
}
|
|
7280
8084
|
}
|
|
8085
|
+
),
|
|
8086
|
+
bulkConfirm && createPortal3(
|
|
8087
|
+
/* @__PURE__ */ jsx32(
|
|
8088
|
+
"div",
|
|
8089
|
+
{
|
|
8090
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
|
|
8091
|
+
style: { background: "rgba(0,0,0,0.5)" },
|
|
8092
|
+
onMouseDown: (e) => {
|
|
8093
|
+
if (e.target === e.currentTarget) setBulkConfirm(null);
|
|
8094
|
+
},
|
|
8095
|
+
children: /* @__PURE__ */ jsxs30("div", { className: "relative w-full max-w-md rounded-2xl border border-border bg-card shadow-2xl flex flex-col", children: [
|
|
8096
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border", children: [
|
|
8097
|
+
/* @__PURE__ */ jsx32("h2", { className: "text-base font-semibold", children: "Confirm Delete" }),
|
|
8098
|
+
/* @__PURE__ */ jsx32("button", { onClick: () => setBulkConfirm(null), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx32(X9, { className: "h-4 w-4" }) })
|
|
8099
|
+
] }),
|
|
8100
|
+
/* @__PURE__ */ jsx32("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx32("p", { className: "text-sm text-muted-foreground", children: bulkConfirm === "selected" ? `Are you sure you want to delete ${selectedIds.length} selected record${selectedIds.length !== 1 ? "s" : ""}? This action cannot be undone.` : "Are you sure you want to delete all records? This action cannot be undone." }) }),
|
|
8101
|
+
/* @__PURE__ */ jsxs30("div", { className: "px-6 py-4 border-t border-border flex justify-end gap-2", children: [
|
|
8102
|
+
/* @__PURE__ */ jsx32(Button, { variant: "outline", size: "sm", onClick: () => setBulkConfirm(null), disabled: bulkLoading, children: "Cancel" }),
|
|
8103
|
+
/* @__PURE__ */ jsxs30(Button, { variant: "danger", size: "sm", disabled: bulkLoading, onClick: async () => {
|
|
8104
|
+
if (bulkConfirm === "selected") await execBulkDeleteSelected();
|
|
8105
|
+
else await execDeleteAll();
|
|
8106
|
+
setBulkConfirm(null);
|
|
8107
|
+
}, children: [
|
|
8108
|
+
bulkLoading && /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 mr-1.5 animate-spin" }),
|
|
8109
|
+
bulkLoading ? "Deleting\u2026" : "Delete"
|
|
8110
|
+
] })
|
|
8111
|
+
] })
|
|
8112
|
+
] })
|
|
8113
|
+
}
|
|
8114
|
+
),
|
|
8115
|
+
document.body
|
|
7281
8116
|
)
|
|
7282
8117
|
] });
|
|
7283
8118
|
}
|
|
7284
8119
|
|
|
7285
8120
|
// src/components/ui/data-grid.tsx
|
|
7286
|
-
import { Fragment as
|
|
8121
|
+
import { Fragment as Fragment13, jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
7287
8122
|
function useServerDataGrid({ url, params, encrypt, key, decryptPayloadLog, columnOverrides }) {
|
|
7288
8123
|
const [data, setData] = React29.useState([]);
|
|
7289
8124
|
const [columns, setColumns] = React29.useState([]);
|
|
@@ -7411,7 +8246,7 @@ function DGModalShell({ title, onClose, children, footer, width = "lg" }) {
|
|
|
7411
8246
|
);
|
|
7412
8247
|
}
|
|
7413
8248
|
function DGFieldRenderer({ field, value, onChange }) {
|
|
7414
|
-
if (field.render) return /* @__PURE__ */ jsx33(
|
|
8249
|
+
if (field.render) return /* @__PURE__ */ jsx33(Fragment13, { children: field.render(value, onChange) });
|
|
7415
8250
|
const toLabelValue = (o) => {
|
|
7416
8251
|
if (typeof o === "string") return { label: o, value: o };
|
|
7417
8252
|
if (Array.isArray(o)) return { label: o[0], value: o[1] };
|
|
@@ -7491,7 +8326,7 @@ function DGViewModal({ item, fields, onClose, width }) {
|
|
|
7491
8326
|
footer: /* @__PURE__ */ jsx33("button", { onClick: onClose, className: "px-4 py-1.5 text-sm rounded-xl border border-border hover:bg-accent transition-colors", children: "Close" }),
|
|
7492
8327
|
children: /* @__PURE__ */ jsx33("div", { className: "space-y-3", children: fields.map((f) => /* @__PURE__ */ jsxs31("div", { children: [
|
|
7493
8328
|
/* @__PURE__ */ jsx33("p", { className: "text-xs font-semibold text-muted-foreground mb-1", children: f.label }),
|
|
7494
|
-
f.render ? /* @__PURE__ */ jsx33(
|
|
8329
|
+
f.render ? /* @__PURE__ */ jsx33(Fragment13, { children: f.render(item[f.key], () => {
|
|
7495
8330
|
}) }) : /* @__PURE__ */ jsx33("p", { className: "text-sm text-foreground break-words", children: item[f.key] == null || item[f.key] === "" ? /* @__PURE__ */ jsx33("span", { className: "text-muted-foreground italic", children: "\u2014" }) : String(item[f.key]) })
|
|
7496
8331
|
] }, f.key)) })
|
|
7497
8332
|
}
|
|
@@ -7555,7 +8390,7 @@ function DGEditModal({
|
|
|
7555
8390
|
title: "Edit Record",
|
|
7556
8391
|
onClose,
|
|
7557
8392
|
width,
|
|
7558
|
-
footer: /* @__PURE__ */ jsxs31(
|
|
8393
|
+
footer: /* @__PURE__ */ jsxs31(Fragment13, { children: [
|
|
7559
8394
|
/* @__PURE__ */ jsx33("button", { onClick: onClose, disabled: loading, className: "px-4 py-1.5 text-sm rounded-xl border border-border hover:bg-accent transition-colors", children: "Cancel" }),
|
|
7560
8395
|
/* @__PURE__ */ jsxs31("button", { onClick: handleSubmit, disabled: loading, className: "px-4 py-1.5 text-sm rounded-xl bg-primary text-primary-foreground hover:bg-primary-hover transition-colors flex items-center gap-1.5", children: [
|
|
7561
8396
|
loading && /* @__PURE__ */ jsx33(Loader23, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
@@ -7615,7 +8450,7 @@ function DGDeleteModal({
|
|
|
7615
8450
|
title: "Confirm Delete",
|
|
7616
8451
|
onClose,
|
|
7617
8452
|
width: "lg",
|
|
7618
|
-
footer: /* @__PURE__ */ jsxs31(
|
|
8453
|
+
footer: /* @__PURE__ */ jsxs31(Fragment13, { children: [
|
|
7619
8454
|
/* @__PURE__ */ jsx33("button", { onClick: onClose, disabled: loading, className: "px-4 py-1.5 text-sm rounded-xl border border-border hover:bg-accent transition-colors", children: "Cancel" }),
|
|
7620
8455
|
/* @__PURE__ */ jsxs31("button", { onClick: handleDelete, disabled: loading, className: "px-4 py-1.5 text-sm rounded-xl bg-danger text-danger-foreground hover:bg-danger-hover transition-colors flex items-center gap-1.5", children: [
|
|
7621
8456
|
loading && /* @__PURE__ */ jsx33(Loader23, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
@@ -8547,7 +9382,7 @@ function KanbanBoard({ columns: controlled, onChange, onAddCard, className }) {
|
|
|
8547
9382
|
import * as React33 from "react";
|
|
8548
9383
|
import { MapContainer, TileLayer, Marker, Popup, Polyline, useMap, CircleMarker } from "react-leaflet";
|
|
8549
9384
|
import L from "leaflet";
|
|
8550
|
-
import { Fragment as
|
|
9385
|
+
import { Fragment as Fragment15, jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
8551
9386
|
L.Icon.Default.mergeOptions({
|
|
8552
9387
|
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
|
|
8553
9388
|
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
|
|
@@ -8653,7 +9488,7 @@ function RouteLayer({ routes }) {
|
|
|
8653
9488
|
});
|
|
8654
9489
|
}, [routes]);
|
|
8655
9490
|
if (loading) return null;
|
|
8656
|
-
return /* @__PURE__ */ jsx39(
|
|
9491
|
+
return /* @__PURE__ */ jsx39(Fragment15, { children: resolved.map((r, i) => {
|
|
8657
9492
|
const color = r.route.color ?? (r.route.routeType === "walk" ? "#22c55e" : "#6366f1");
|
|
8658
9493
|
const isDrive = (r.route.routeType ?? "drive") === "drive";
|
|
8659
9494
|
const midIdx = Math.floor(r.coords.length / 2);
|
|
@@ -8693,7 +9528,7 @@ function RouteLayer({ routes }) {
|
|
|
8693
9528
|
zIndexOffset: 100,
|
|
8694
9529
|
children: /* @__PURE__ */ jsx39(Popup, { children: /* @__PURE__ */ jsxs35("div", { className: "text-xs space-y-0.5 min-w-[120px]", children: [
|
|
8695
9530
|
/* @__PURE__ */ jsx39("p", { className: "font-semibold", children: r.route.label ? `${r.route.label} \u2014 Start` : "Start" }),
|
|
8696
|
-
r.distance > 0 && /* @__PURE__ */ jsxs35(
|
|
9531
|
+
r.distance > 0 && /* @__PURE__ */ jsxs35(Fragment15, { children: [
|
|
8697
9532
|
/* @__PURE__ */ jsx39("p", { className: "text-muted-foreground", children: fmtDistance(r.distance) }),
|
|
8698
9533
|
/* @__PURE__ */ jsxs35("p", { className: "text-muted-foreground", children: [
|
|
8699
9534
|
fmtDuration(r.duration),
|
|
@@ -8712,7 +9547,7 @@ function RouteLayer({ routes }) {
|
|
|
8712
9547
|
zIndexOffset: 100,
|
|
8713
9548
|
children: /* @__PURE__ */ jsx39(Popup, { children: /* @__PURE__ */ jsxs35("div", { className: "text-xs space-y-0.5 min-w-[120px]", children: [
|
|
8714
9549
|
/* @__PURE__ */ jsx39("p", { className: "font-semibold", children: r.route.label ? `${r.route.label} \u2014 End` : "End" }),
|
|
8715
|
-
r.distance > 0 && /* @__PURE__ */ jsxs35(
|
|
9550
|
+
r.distance > 0 && /* @__PURE__ */ jsxs35(Fragment15, { children: [
|
|
8716
9551
|
/* @__PURE__ */ jsx39("p", { className: "text-muted-foreground", children: fmtDistance(r.distance) }),
|
|
8717
9552
|
/* @__PURE__ */ jsxs35("p", { className: "text-muted-foreground", children: [
|
|
8718
9553
|
fmtDuration(r.duration),
|
|
@@ -8827,7 +9662,7 @@ function ClusterLayer({ markers, variant, onMarkerClick }) {
|
|
|
8827
9662
|
});
|
|
8828
9663
|
return groups;
|
|
8829
9664
|
}, [markers, zoom, map]);
|
|
8830
|
-
return /* @__PURE__ */ jsx39(
|
|
9665
|
+
return /* @__PURE__ */ jsx39(Fragment15, { children: clusters.map((g, gi) => {
|
|
8831
9666
|
if (g.items.length === 1) {
|
|
8832
9667
|
const m = g.items[0];
|
|
8833
9668
|
const color2 = resolveColor(m.color);
|
|
@@ -9696,7 +10531,7 @@ function Modal({
|
|
|
9696
10531
|
// src/components/ui/modal-variants.tsx
|
|
9697
10532
|
import * as React36 from "react";
|
|
9698
10533
|
import { AlertTriangle as AlertTriangle3, CheckCircle as CheckCircle2, Trash2 as Trash23, X as X13 } from "lucide-react";
|
|
9699
|
-
import { Fragment as
|
|
10534
|
+
import { Fragment as Fragment16, jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
9700
10535
|
function ModalBase({
|
|
9701
10536
|
isOpen,
|
|
9702
10537
|
onClose,
|
|
@@ -9847,7 +10682,7 @@ function ModalWithForms({
|
|
|
9847
10682
|
onSubmit(values);
|
|
9848
10683
|
}
|
|
9849
10684
|
function renderField(field) {
|
|
9850
|
-
if (field.render) return /* @__PURE__ */ jsx42(
|
|
10685
|
+
if (field.render) return /* @__PURE__ */ jsx42(Fragment16, { children: field.render(values[field.name], (v) => handleChange(field.name, v)) });
|
|
9851
10686
|
const strOptions = (field.options ?? []).map(
|
|
9852
10687
|
(o) => typeof o === "string" ? { label: o, value: o } : o
|
|
9853
10688
|
);
|
|
@@ -10195,7 +11030,7 @@ import { PanelLeftClose, PanelLeftOpen, Sun as Sun3, Moon as Moon2, Loader2 as L
|
|
|
10195
11030
|
// src/components/ui/tooltip.tsx
|
|
10196
11031
|
import * as React38 from "react";
|
|
10197
11032
|
import * as ReactDOM2 from "react-dom";
|
|
10198
|
-
import { Fragment as
|
|
11033
|
+
import { Fragment as Fragment17, jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
10199
11034
|
function Tooltip({
|
|
10200
11035
|
content,
|
|
10201
11036
|
children,
|
|
@@ -10206,7 +11041,7 @@ function Tooltip({
|
|
|
10206
11041
|
const [visible, setVisible] = React38.useState(false);
|
|
10207
11042
|
const [coords, setCoords] = React38.useState({ top: 0, left: 0 });
|
|
10208
11043
|
const ref = React38.useRef(null);
|
|
10209
|
-
if (!enabled) return /* @__PURE__ */ jsx44(
|
|
11044
|
+
if (!enabled) return /* @__PURE__ */ jsx44(Fragment17, { children });
|
|
10210
11045
|
function calcCoords() {
|
|
10211
11046
|
const r = ref.current?.getBoundingClientRect();
|
|
10212
11047
|
if (!r) return;
|
|
@@ -10803,7 +11638,7 @@ var useTheme = () => {
|
|
|
10803
11638
|
};
|
|
10804
11639
|
|
|
10805
11640
|
// src/components/ui/panel.tsx
|
|
10806
|
-
import { Fragment as
|
|
11641
|
+
import { Fragment as Fragment18, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
10807
11642
|
var PanelCollapsedContext = React40.createContext(false);
|
|
10808
11643
|
var PanelGroupsContext = React40.createContext({ expandedGroups: /* @__PURE__ */ new Set(), onGroupToggle: () => {
|
|
10809
11644
|
} });
|
|
@@ -10965,7 +11800,7 @@ function Panel({
|
|
|
10965
11800
|
"shrink-0 border-b border-border",
|
|
10966
11801
|
effectiveCollapsed ? "flex items-center justify-center py-3" : "flex items-center gap-2 px-4 py-3"
|
|
10967
11802
|
),
|
|
10968
|
-
children: sidebarBrand ? effectiveCollapsed ? sidebarBrand.image ? /* @__PURE__ */ jsx46("img", { src: sidebarBrand.image, alt: "logo", className: "h-7 w-7 rounded-md object-cover shrink-0" }) : /* @__PURE__ */ jsx46("span", { className: "shrink-0", children: sidebarBrand.icon }) : /* @__PURE__ */ jsxs41(
|
|
11803
|
+
children: sidebarBrand ? effectiveCollapsed ? sidebarBrand.image ? /* @__PURE__ */ jsx46("img", { src: sidebarBrand.image, alt: "logo", className: "h-7 w-7 rounded-md object-cover shrink-0" }) : /* @__PURE__ */ jsx46("span", { className: "shrink-0", children: sidebarBrand.icon }) : /* @__PURE__ */ jsxs41(Fragment18, { children: [
|
|
10969
11804
|
sidebarBrand.image ? /* @__PURE__ */ jsx46("img", { src: sidebarBrand.image, alt: "logo", className: "h-7 w-7 rounded-md object-cover shrink-0" }) : sidebarBrand.icon && /* @__PURE__ */ jsx46("span", { className: "shrink-0", children: sidebarBrand.icon }),
|
|
10970
11805
|
sidebarBrand.title && /* @__PURE__ */ jsx46("span", { className: "flex-1 truncate text-sm font-semibold", children: sidebarBrand.title }),
|
|
10971
11806
|
sidebarBrand.trailing && /* @__PURE__ */ jsx46("span", { className: "shrink-0", children: sidebarBrand.trailing })
|
|
@@ -12044,13 +12879,13 @@ function Timeline({ items, align = "left", className }) {
|
|
|
12044
12879
|
|
|
12045
12880
|
// src/components/ui/tree-view.tsx
|
|
12046
12881
|
import * as React48 from "react";
|
|
12047
|
-
import { ChevronRight as ChevronRight11, Folder, FolderOpen, File } from "lucide-react";
|
|
12882
|
+
import { ChevronRight as ChevronRight11, Folder, FolderOpen, File as File2 } from "lucide-react";
|
|
12048
12883
|
import { jsx as jsx60, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
12049
12884
|
function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelect, multiple }) {
|
|
12050
12885
|
const hasChildren = !!node.children?.length;
|
|
12051
12886
|
const isExpanded = expanded.includes(node.id);
|
|
12052
12887
|
const isSelected = selected.includes(node.id);
|
|
12053
|
-
const defaultIcon = hasChildren ? isExpanded ? /* @__PURE__ */ jsx60(FolderOpen, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ jsx60(Folder, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ jsx60(
|
|
12888
|
+
const defaultIcon = hasChildren ? isExpanded ? /* @__PURE__ */ jsx60(FolderOpen, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ jsx60(Folder, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ jsx60(File2, { className: "h-4 w-4 text-muted-foreground" });
|
|
12054
12889
|
return /* @__PURE__ */ jsxs53("div", { children: [
|
|
12055
12890
|
/* @__PURE__ */ jsxs53(
|
|
12056
12891
|
"div",
|
|
@@ -12274,7 +13109,7 @@ function Widget({
|
|
|
12274
13109
|
// src/components/ui/wizard.tsx
|
|
12275
13110
|
import * as React50 from "react";
|
|
12276
13111
|
import { Check as Check7, X as X15, ChevronLeft as ChevronLeft8, ChevronRight as ChevronRight12, AlertCircle as AlertCircle2 } from "lucide-react";
|
|
12277
|
-
import { Fragment as
|
|
13112
|
+
import { Fragment as Fragment21, jsx as jsx62, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
12278
13113
|
var SIZE_MAP = {
|
|
12279
13114
|
sm: "max-w-sm",
|
|
12280
13115
|
md: "max-w-lg",
|
|
@@ -12484,10 +13319,10 @@ function DefaultActions({
|
|
|
12484
13319
|
/* @__PURE__ */ jsx62("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v8z" })
|
|
12485
13320
|
] }),
|
|
12486
13321
|
"Processing..."
|
|
12487
|
-
] }) : isLast ? /* @__PURE__ */ jsxs55(
|
|
13322
|
+
] }) : isLast ? /* @__PURE__ */ jsxs55(Fragment21, { children: [
|
|
12488
13323
|
/* @__PURE__ */ jsx62(Check7, { className: "h-4 w-4" }),
|
|
12489
13324
|
finishLabel ?? "Finish"
|
|
12490
|
-
] }) : /* @__PURE__ */ jsxs55(
|
|
13325
|
+
] }) : /* @__PURE__ */ jsxs55(Fragment21, { children: [
|
|
12491
13326
|
nextLabel ?? "Next",
|
|
12492
13327
|
/* @__PURE__ */ jsx62(ChevronRight12, { className: "h-4 w-4" })
|
|
12493
13328
|
] })
|
|
@@ -12732,6 +13567,12 @@ var axiosInstance = axios5.create({
|
|
|
12732
13567
|
Accept: "application/json"
|
|
12733
13568
|
}
|
|
12734
13569
|
});
|
|
13570
|
+
axiosInstance.interceptors.request.use((config) => {
|
|
13571
|
+
if (config.data instanceof FormData) {
|
|
13572
|
+
delete config.headers["Content-Type"];
|
|
13573
|
+
}
|
|
13574
|
+
return config;
|
|
13575
|
+
});
|
|
12735
13576
|
|
|
12736
13577
|
// src/lib/codego/request.ts
|
|
12737
13578
|
var request = async (config) => {
|
|
@@ -12790,13 +13631,13 @@ var setupInterceptors = () => {
|
|
|
12790
13631
|
|
|
12791
13632
|
// src/lib/codego/provider.tsx
|
|
12792
13633
|
import * as React51 from "react";
|
|
12793
|
-
import { Fragment as
|
|
13634
|
+
import { Fragment as Fragment22, jsx as jsx63 } from "react/jsx-runtime";
|
|
12794
13635
|
function CodegoApiProvider({ children }) {
|
|
12795
13636
|
const { toast } = useToast();
|
|
12796
13637
|
React51.useEffect(() => {
|
|
12797
13638
|
setToastFunction(toast);
|
|
12798
13639
|
}, [toast]);
|
|
12799
|
-
return /* @__PURE__ */ jsx63(
|
|
13640
|
+
return /* @__PURE__ */ jsx63(Fragment22, { children });
|
|
12800
13641
|
}
|
|
12801
13642
|
|
|
12802
13643
|
// src/lib/codego/index.ts
|