@juv/codego-react-ui 3.4.11 → 3.5.1
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 +989 -144
- package/dist/index.d.cts +143 -22
- package/dist/index.d.ts +143 -22
- package/dist/index.global.js +1048 -190
- package/dist/index.js +1020 -175
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2116,13 +2116,13 @@ function BulletinBoard({
|
|
|
2116
2116
|
const categories = React8.useMemo(() => {
|
|
2117
2117
|
if (categoriesProp) return categoriesProp;
|
|
2118
2118
|
const set = /* @__PURE__ */ new Set();
|
|
2119
|
-
items.forEach((i) => {
|
|
2119
|
+
(items ?? []).forEach((i) => {
|
|
2120
2120
|
if (i.category) set.add(i.category);
|
|
2121
2121
|
});
|
|
2122
2122
|
return Array.from(set);
|
|
2123
2123
|
}, [items, categoriesProp]);
|
|
2124
2124
|
const filtered = React8.useMemo(() => {
|
|
2125
|
-
let list = items;
|
|
2125
|
+
let list = items ?? [];
|
|
2126
2126
|
if (search.trim()) {
|
|
2127
2127
|
const q = search.toLowerCase();
|
|
2128
2128
|
list = list.filter(
|
|
@@ -2131,7 +2131,7 @@ function BulletinBoard({
|
|
|
2131
2131
|
}
|
|
2132
2132
|
if (category) list = list.filter((i) => i.category === category);
|
|
2133
2133
|
return [...list].sort((a, b) => (b.pinned ? 1 : 0) - (a.pinned ? 1 : 0));
|
|
2134
|
-
}, [items, search, category]);
|
|
2134
|
+
}, [items ?? [], search, category]);
|
|
2135
2135
|
const showToolbar = searchable || filterable && categories.length > 0;
|
|
2136
2136
|
return /* @__PURE__ */ jsxs9("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
2137
2137
|
showHeader && /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-2", children: [
|
|
@@ -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,78 @@ 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
|
+
toast({ variant: "success", title: "Deleted", description: `${selectedIds.length} record${selectedIds.length !== 1 ? "s" : ""} deleted successfully.` });
|
|
7534
|
+
} catch (err) {
|
|
7535
|
+
const msg = err?.response?.data?.message ?? err.message ?? "Bulk delete failed";
|
|
7536
|
+
toast({ variant: "error", title: "Delete failed", description: msg });
|
|
7537
|
+
} finally {
|
|
7538
|
+
setBulkLoading(false);
|
|
7539
|
+
}
|
|
7540
|
+
};
|
|
7541
|
+
const execDeleteAll = async () => {
|
|
7542
|
+
if (!bulkDeleteBaseUrl) return;
|
|
7543
|
+
setBulkLoading(true);
|
|
7544
|
+
try {
|
|
7545
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
7546
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
7547
|
+
const safeUrl = bulkDeleteBaseUrl.replace(/\/+$/, "");
|
|
7548
|
+
await axios3.delete(`${safeUrl}/delete/all`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
7549
|
+
setTableData([]);
|
|
7550
|
+
setSelectedIds([]);
|
|
7551
|
+
defaultActions?.onReload?.();
|
|
7552
|
+
toast({ variant: "success", title: "Deleted", description: "All records deleted successfully." });
|
|
7553
|
+
} catch (err) {
|
|
7554
|
+
const msg = err?.response?.data?.message ?? err.message ?? "Delete all failed";
|
|
7555
|
+
toast({ variant: "error", title: "Delete failed", description: msg });
|
|
7556
|
+
} finally {
|
|
7557
|
+
setBulkLoading(false);
|
|
7558
|
+
}
|
|
7559
|
+
};
|
|
6934
7560
|
const pagePills = React28.useMemo(() => {
|
|
6935
7561
|
if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
6936
7562
|
if (safePage <= 3) return [1, 2, 3, 4, 5];
|
|
@@ -6942,8 +7568,9 @@ function Table({
|
|
|
6942
7568
|
if (sortKey !== String(col.key)) return /* @__PURE__ */ jsx32(ChevronsUpDown, { className: "ml-1.5 h-3.5 w-3.5 opacity-40" });
|
|
6943
7569
|
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
7570
|
};
|
|
6945
|
-
return /* @__PURE__ */ jsxs30(
|
|
7571
|
+
return /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
6946
7572
|
/* @__PURE__ */ jsxs30("div", { className: cn("w-full space-y-3", className), children: [
|
|
7573
|
+
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
7574
|
/* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-3 flex-wrap", children: [
|
|
6948
7575
|
searchable && /* @__PURE__ */ jsxs30("div", { className: "relative w-72", children: [
|
|
6949
7576
|
/* @__PURE__ */ jsx32(Search5, { className: "absolute text-primary left-3 top-1/2 -translate-y-1/2 h-4 w-4 z-10" }),
|
|
@@ -6965,33 +7592,127 @@ function Table({
|
|
|
6965
7592
|
}
|
|
6966
7593
|
)
|
|
6967
7594
|
] }),
|
|
6968
|
-
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 ml-auto", children: [
|
|
6969
|
-
selectable &&
|
|
7595
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 ml-auto flex-wrap", children: [
|
|
7596
|
+
selectable && selectedIds.length > 0 && /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
7597
|
+
/* @__PURE__ */ jsxs30(
|
|
7598
|
+
"button",
|
|
7599
|
+
{
|
|
7600
|
+
onClick: handleUnselectAll,
|
|
7601
|
+
disabled: bulkLoading,
|
|
7602
|
+
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",
|
|
7603
|
+
children: [
|
|
7604
|
+
/* @__PURE__ */ jsx32(X9, { className: "h-3.5 w-3.5" }),
|
|
7605
|
+
"Unselect all ",
|
|
7606
|
+
selectedIds.length
|
|
7607
|
+
]
|
|
7608
|
+
}
|
|
7609
|
+
),
|
|
7610
|
+
unselectedCount > 0 && /* @__PURE__ */ jsxs30(
|
|
7611
|
+
"button",
|
|
7612
|
+
{
|
|
7613
|
+
onClick: handleSelectAllRecords,
|
|
7614
|
+
disabled: bulkLoading,
|
|
7615
|
+
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",
|
|
7616
|
+
children: [
|
|
7617
|
+
"Select all ",
|
|
7618
|
+
unselectedCount
|
|
7619
|
+
]
|
|
7620
|
+
}
|
|
7621
|
+
),
|
|
7622
|
+
/* @__PURE__ */ jsxs30(
|
|
7623
|
+
"button",
|
|
7624
|
+
{
|
|
7625
|
+
onClick: () => setBulkConfirm("selected"),
|
|
7626
|
+
disabled: bulkLoading,
|
|
7627
|
+
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",
|
|
7628
|
+
children: [
|
|
7629
|
+
bulkLoading ? /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx32(Trash22, { className: "h-3.5 w-3.5" }),
|
|
7630
|
+
"Delete ",
|
|
7631
|
+
selectedIds.length,
|
|
7632
|
+
" selected"
|
|
7633
|
+
]
|
|
7634
|
+
}
|
|
7635
|
+
),
|
|
7636
|
+
bulkDeleteBaseUrl && /* @__PURE__ */ jsxs30(
|
|
7637
|
+
"button",
|
|
7638
|
+
{
|
|
7639
|
+
onClick: () => setBulkConfirm("all"),
|
|
7640
|
+
disabled: bulkLoading,
|
|
7641
|
+
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",
|
|
7642
|
+
children: [
|
|
7643
|
+
bulkLoading ? /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx32(Trash22, { className: "h-3.5 w-3.5" }),
|
|
7644
|
+
"Delete all"
|
|
7645
|
+
]
|
|
7646
|
+
}
|
|
7647
|
+
)
|
|
7648
|
+
] }),
|
|
7649
|
+
filterBar && /* @__PURE__ */ jsx32(
|
|
6970
7650
|
"button",
|
|
6971
7651
|
{
|
|
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
|
-
]
|
|
7652
|
+
onClick: () => setFilterBarOpen((o) => !o),
|
|
7653
|
+
className: cn(
|
|
7654
|
+
"inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-xs font-medium transition-colors",
|
|
7655
|
+
filterBarOpen ? "border-primary bg-primary/10 text-primary hover:bg-primary/20" : "border-border bg-muted/50 text-muted-foreground hover:bg-muted"
|
|
7656
|
+
),
|
|
7657
|
+
children: filterableIcon ?? "Filter"
|
|
6983
7658
|
}
|
|
6984
7659
|
),
|
|
7660
|
+
exportable && /* @__PURE__ */ jsxs30("div", { className: "relative group", children: [
|
|
7661
|
+
/* @__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" }),
|
|
7662
|
+
/* @__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(
|
|
7663
|
+
"button",
|
|
7664
|
+
{
|
|
7665
|
+
onClick: () => onExport?.(type),
|
|
7666
|
+
className: "px-4 py-2 text-xs text-left hover:bg-muted transition-colors capitalize",
|
|
7667
|
+
children: type.toUpperCase()
|
|
7668
|
+
},
|
|
7669
|
+
type
|
|
7670
|
+
)) })
|
|
7671
|
+
] }),
|
|
7672
|
+
columnVisibility && onColumnVisibilityChange && /* @__PURE__ */ jsxs30("div", { className: "relative group", children: [
|
|
7673
|
+
/* @__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" }),
|
|
7674
|
+
/* @__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: [
|
|
7675
|
+
/* @__PURE__ */ jsx32(
|
|
7676
|
+
"input",
|
|
7677
|
+
{
|
|
7678
|
+
type: "checkbox",
|
|
7679
|
+
checked: columnVisibility[String(col.key)] !== false,
|
|
7680
|
+
onChange: (e) => onColumnVisibilityChange({ ...columnVisibility, [String(col.key)]: e.target.checked }),
|
|
7681
|
+
className: "accent-primary"
|
|
7682
|
+
}
|
|
7683
|
+
),
|
|
7684
|
+
col.title
|
|
7685
|
+
] }, String(col.key))) })
|
|
7686
|
+
] }),
|
|
6985
7687
|
/* @__PURE__ */ jsxs30("span", { className: "text-xs text-muted-foreground", children: [
|
|
6986
|
-
|
|
7688
|
+
totalRows,
|
|
6987
7689
|
" ",
|
|
6988
|
-
|
|
7690
|
+
totalRows === 1 ? "row" : "rows",
|
|
6989
7691
|
search && ` \xB7 filtered from ${tableData.length}`
|
|
6990
7692
|
] })
|
|
6991
7693
|
] })
|
|
6992
7694
|
] }),
|
|
6993
|
-
|
|
6994
|
-
|
|
7695
|
+
filterBar && filterBarOpen && /* @__PURE__ */ jsx32("div", { children: filterBar }),
|
|
7696
|
+
loading && /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-center py-12 text-muted-foreground gap-2", children: [
|
|
7697
|
+
/* @__PURE__ */ jsx32(Loader22, { className: "h-5 w-5 animate-spin" }),
|
|
7698
|
+
/* @__PURE__ */ jsx32("span", { className: "text-sm", children: "Loading\u2026" })
|
|
7699
|
+
] }),
|
|
7700
|
+
!loading && /* @__PURE__ */ jsx32("div", { className: cn(
|
|
7701
|
+
variant === "default" && "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm",
|
|
7702
|
+
variant === "zebra" && "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm",
|
|
7703
|
+
variant === "card" && "space-y-2",
|
|
7704
|
+
variant === "glass" && "rounded-2xl overflow-hidden border border-white/10 bg-background/30 backdrop-blur-xl shadow-xl",
|
|
7705
|
+
variant === "soft" && "rounded-2xl overflow-hidden bg-card",
|
|
7706
|
+
variant === "soft" && "[box-shadow:6px_6px_12px_hsl(var(--foreground)/0.07),-6px_-6px_12px_hsl(var(--background)/0.8)]",
|
|
7707
|
+
virtualized && "max-h-[520px] overflow-y-auto"
|
|
7708
|
+
), 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: [
|
|
7709
|
+
/* @__PURE__ */ jsx32("thead", { children: /* @__PURE__ */ jsxs30("tr", { className: cn(
|
|
7710
|
+
variant === "default" && "border-b border-border bg-muted/40",
|
|
7711
|
+
variant === "zebra" && "border-b border-border bg-muted/40",
|
|
7712
|
+
variant === "card" && "[&>th]:bg-transparent",
|
|
7713
|
+
variant === "glass" && "border-b border-white/10 bg-white/5",
|
|
7714
|
+
variant === "soft" && "border-b-0 bg-muted/30"
|
|
7715
|
+
), children: [
|
|
6995
7716
|
selectable && /* @__PURE__ */ jsx32("th", { className: "h-11 w-[46px] px-4 text-left align-middle", children: /* @__PURE__ */ jsx32(
|
|
6996
7717
|
Checkbox,
|
|
6997
7718
|
{
|
|
@@ -6999,13 +7720,16 @@ function Table({
|
|
|
6999
7720
|
onChange: (e) => handleSelectAll(e.target.checked)
|
|
7000
7721
|
}
|
|
7001
7722
|
) }),
|
|
7723
|
+
expandable && /* @__PURE__ */ jsx32("th", { className: "h-11 w-8" }),
|
|
7002
7724
|
allColumns.map((col, ci) => /* @__PURE__ */ jsx32(
|
|
7003
7725
|
"th",
|
|
7004
7726
|
{
|
|
7005
7727
|
onClick: () => col.sortable && handleSort(String(col.key)),
|
|
7006
7728
|
className: cn(
|
|
7007
7729
|
"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"
|
|
7730
|
+
col.sortable && "cursor-pointer hover:text-foreground transition-colors",
|
|
7731
|
+
variant === "glass" && "text-foreground/70",
|
|
7732
|
+
variant === "soft" && "text-muted-foreground/80"
|
|
7009
7733
|
),
|
|
7010
7734
|
children: /* @__PURE__ */ jsxs30("span", { className: "inline-flex items-center", children: [
|
|
7011
7735
|
col.title,
|
|
@@ -7018,9 +7742,9 @@ function Table({
|
|
|
7018
7742
|
/* @__PURE__ */ jsx32("tbody", { children: paginatedData.length === 0 ? /* @__PURE__ */ jsx32("tr", { children: /* @__PURE__ */ jsx32(
|
|
7019
7743
|
"td",
|
|
7020
7744
|
{
|
|
7021
|
-
colSpan: allColumns.length + (selectable ? 1 : 0),
|
|
7745
|
+
colSpan: allColumns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0),
|
|
7022
7746
|
className: "h-32 text-center align-middle",
|
|
7023
|
-
children: /* @__PURE__ */ jsxs30("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
7747
|
+
children: emptyState ?? /* @__PURE__ */ jsxs30("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
7024
7748
|
/* @__PURE__ */ jsx32(Search5, { className: "h-8 w-8 opacity-20" }),
|
|
7025
7749
|
/* @__PURE__ */ jsx32("span", { className: "text-sm", children: "No results found" }),
|
|
7026
7750
|
search && /* @__PURE__ */ jsx32("button", { onClick: () => setSearch(""), className: "text-xs text-primary hover:underline", children: "Clear search" })
|
|
@@ -7029,85 +7753,168 @@ function Table({
|
|
|
7029
7753
|
) }) : paginatedData.map((item, i) => {
|
|
7030
7754
|
const id = String(item[idKey] || i);
|
|
7031
7755
|
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
|
-
|
|
7756
|
+
const isExpanded = expandedIds.has(id);
|
|
7757
|
+
const isFocused = keyboardNavigation && focusedRowIdx === i;
|
|
7758
|
+
return /* @__PURE__ */ jsxs30(React28.Fragment, { children: [
|
|
7759
|
+
/* @__PURE__ */ jsxs30(
|
|
7760
|
+
"tr",
|
|
7761
|
+
{
|
|
7762
|
+
draggable,
|
|
7763
|
+
tabIndex: keyboardNavigation ? 0 : void 0,
|
|
7764
|
+
onDragStart: draggable ? (e) => {
|
|
7765
|
+
e.dataTransfer.setData("text/plain", id);
|
|
7766
|
+
} : void 0,
|
|
7767
|
+
onDragOver: draggable ? (e) => {
|
|
7768
|
+
e.preventDefault();
|
|
7769
|
+
setDragOverId(id);
|
|
7770
|
+
} : void 0,
|
|
7771
|
+
onDragLeave: draggable ? () => setDragOverId(null) : void 0,
|
|
7772
|
+
onDrop: draggable ? (e) => {
|
|
7773
|
+
e.preventDefault();
|
|
7774
|
+
setDragOverId(null);
|
|
7775
|
+
const fromId = e.dataTransfer.getData("text/plain");
|
|
7776
|
+
if (fromId === id) return;
|
|
7777
|
+
setTableData((prev) => {
|
|
7778
|
+
const fromIdx = prev.findIndex((r) => String(r[idKey] || "") === fromId);
|
|
7779
|
+
const toIdx = prev.findIndex((r) => String(r[idKey] || "") === id);
|
|
7780
|
+
if (fromIdx < 0 || toIdx < 0) return prev;
|
|
7781
|
+
const next = [...prev];
|
|
7782
|
+
const [moved] = next.splice(fromIdx, 1);
|
|
7783
|
+
next.splice(toIdx, 0, moved);
|
|
7784
|
+
onRowReorder?.(next);
|
|
7785
|
+
return next;
|
|
7786
|
+
});
|
|
7787
|
+
} : void 0,
|
|
7788
|
+
onClick: () => {
|
|
7789
|
+
if (expandable) setExpandedIds((prev) => {
|
|
7790
|
+
const s = new Set(prev);
|
|
7791
|
+
s.has(id) ? s.delete(id) : s.add(id);
|
|
7792
|
+
return s;
|
|
7793
|
+
});
|
|
7794
|
+
onRowClick?.(item);
|
|
7795
|
+
if (keyboardNavigation) setFocusedRowIdx(i);
|
|
7796
|
+
},
|
|
7797
|
+
onDoubleClick: () => onRowDoubleClick?.(item),
|
|
7798
|
+
className: cn(
|
|
7799
|
+
// default
|
|
7800
|
+
variant === "default" && "border-b border-border/60 transition-colors last:border-0",
|
|
7801
|
+
variant === "default" && (isSelected ? "bg-primary/5 hover:bg-primary/8" : "hover:bg-muted/30"),
|
|
7802
|
+
// zebra
|
|
7803
|
+
variant === "zebra" && "border-b border-border/40 transition-colors last:border-0",
|
|
7804
|
+
variant === "zebra" && (isSelected ? "bg-primary/8" : i % 2 === 0 ? "bg-card" : "bg-muted/40"),
|
|
7805
|
+
variant === "zebra" && !isSelected && "hover:bg-primary/5",
|
|
7806
|
+
// card
|
|
7807
|
+
variant === "card" && "rounded-xl border border-border bg-card shadow-sm transition-all hover:shadow-md hover:-translate-y-px",
|
|
7808
|
+
variant === "card" && (isSelected ? "border-primary/50 bg-primary/5" : ""),
|
|
7809
|
+
variant === "card" && "[&>td:first-child]:rounded-l-xl [&>td:last-child]:rounded-r-xl",
|
|
7810
|
+
// glass
|
|
7811
|
+
variant === "glass" && "border-b border-white/8 transition-colors last:border-0",
|
|
7812
|
+
variant === "glass" && (isSelected ? "bg-primary/15 hover:bg-primary/20" : "hover:bg-white/5"),
|
|
7813
|
+
// soft
|
|
7814
|
+
variant === "soft" && "transition-all",
|
|
7815
|
+
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"),
|
|
7816
|
+
variant === "soft" && "border-b border-border/30 last:border-0",
|
|
7817
|
+
(onRowClick || onRowDoubleClick || expandable) && "cursor-pointer",
|
|
7818
|
+
draggable && dragOverId === id && "ring-2 ring-inset ring-primary/40",
|
|
7819
|
+
isFocused && "ring-2 ring-inset ring-ring",
|
|
7820
|
+
rowClassName?.(item)
|
|
7821
|
+
),
|
|
7822
|
+
children: [
|
|
7823
|
+
selectable && /* @__PURE__ */ jsx32("td", { className: "px-4 py-3 align-middle", children: /* @__PURE__ */ jsx32(
|
|
7824
|
+
Checkbox,
|
|
7825
|
+
{
|
|
7826
|
+
checked: isSelected,
|
|
7827
|
+
onChange: (e) => handleSelect(id, e.target.checked)
|
|
7828
|
+
}
|
|
7061
7829
|
) }),
|
|
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",
|
|
7830
|
+
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") }) }),
|
|
7831
|
+
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(
|
|
7832
|
+
"img",
|
|
7833
|
+
{
|
|
7834
|
+
src: item[col.key],
|
|
7835
|
+
alt: item[col.key],
|
|
7836
|
+
className: "h-9 w-9 rounded-lg object-cover ring-1 ring-border"
|
|
7837
|
+
}
|
|
7838
|
+
) : col.type === "badge" ? /* @__PURE__ */ jsxs30("span", { className: cn(
|
|
7839
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium",
|
|
7840
|
+
badgeClass(String(item[col.key]))
|
|
7841
|
+
), children: [
|
|
7842
|
+
/* @__PURE__ */ jsx32("span", { className: cn(
|
|
7843
|
+
"mr-1.5 h-1.5 w-1.5 rounded-full",
|
|
7844
|
+
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"
|
|
7845
|
+
) }),
|
|
7846
|
+
item[col.key]
|
|
7847
|
+
] }) : 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(
|
|
7848
|
+
"select",
|
|
7089
7849
|
{
|
|
7090
|
-
|
|
7091
|
-
value: item[col.key] || "#000000",
|
|
7850
|
+
value: item[col.key],
|
|
7092
7851
|
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
7093
|
-
className: "h-
|
|
7852
|
+
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",
|
|
7853
|
+
children: (col.selectOptions ?? []).map((opt) => /* @__PURE__ */ jsx32("option", { value: opt, children: opt }, opt))
|
|
7094
7854
|
}
|
|
7095
|
-
)
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7855
|
+
) : col.type === "toggle" ? /* @__PURE__ */ jsx32(
|
|
7856
|
+
"button",
|
|
7857
|
+
{
|
|
7858
|
+
role: "switch",
|
|
7859
|
+
"aria-checked": !!item[col.key],
|
|
7860
|
+
onClick: () => col.onChange?.(item, !item[col.key]),
|
|
7861
|
+
className: cn(
|
|
7862
|
+
"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",
|
|
7863
|
+
item[col.key] ? "bg-primary" : "bg-muted"
|
|
7864
|
+
),
|
|
7865
|
+
children: /* @__PURE__ */ jsx32("span", { className: cn(
|
|
7866
|
+
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
7867
|
+
item[col.key] ? "translate-x-4" : "translate-x-0"
|
|
7868
|
+
) })
|
|
7869
|
+
}
|
|
7870
|
+
) : col.type === "color" ? /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
|
|
7871
|
+
/* @__PURE__ */ jsx32(
|
|
7872
|
+
"input",
|
|
7873
|
+
{
|
|
7874
|
+
type: "color",
|
|
7875
|
+
value: item[col.key] || "#000000",
|
|
7876
|
+
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
7877
|
+
className: "h-7 w-7 cursor-pointer rounded border border-border bg-transparent p-0.5"
|
|
7878
|
+
}
|
|
7879
|
+
),
|
|
7880
|
+
/* @__PURE__ */ jsx32("span", { className: "text-xs text-muted-foreground font-mono", children: item[col.key] })
|
|
7881
|
+
] }) : col.type === "checkbox" ? /* @__PURE__ */ jsx32(
|
|
7882
|
+
Checkbox,
|
|
7883
|
+
{
|
|
7884
|
+
checked: !!item[col.key],
|
|
7885
|
+
onChange: (e) => col.onChange?.(item, e.target.checked)
|
|
7886
|
+
}
|
|
7887
|
+
) : col.type === "text-url" ? (() => {
|
|
7888
|
+
const href = col.redirect ? typeof col.redirect === "function" ? col.redirect(item) : col.redirect : String(item[col.key] ?? "");
|
|
7889
|
+
const colorMap = {
|
|
7890
|
+
primary: "var(--primary)",
|
|
7891
|
+
info: "var(--info)",
|
|
7892
|
+
success: "var(--success)",
|
|
7893
|
+
warning: "var(--warning)",
|
|
7894
|
+
danger: "var(--danger)"
|
|
7895
|
+
};
|
|
7896
|
+
const underline = col.underlineColor ? colorMap[col.underlineColor] ?? col.underlineColor : "var(--primary)";
|
|
7897
|
+
return /* @__PURE__ */ jsx32(
|
|
7898
|
+
"a",
|
|
7899
|
+
{
|
|
7900
|
+
href,
|
|
7901
|
+
target: col.openNewTab ? "_blank" : void 0,
|
|
7902
|
+
rel: col.openNewTab ? "noopener noreferrer" : void 0,
|
|
7903
|
+
style: { textDecorationColor: underline },
|
|
7904
|
+
className: "text-sm underline underline-offset-2 hover:opacity-75 transition-opacity break-all",
|
|
7905
|
+
onClick: col.openNewTab ? void 0 : (e) => e.preventDefault(),
|
|
7906
|
+
children: item[col.key]
|
|
7907
|
+
}
|
|
7908
|
+
);
|
|
7909
|
+
})() : /* @__PURE__ */ jsx32("span", { className: "text-foreground/90", children: item[col.key] }) }, `${String(col.key)}-${ci}`))
|
|
7910
|
+
]
|
|
7911
|
+
}
|
|
7912
|
+
),
|
|
7913
|
+
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) }) })
|
|
7914
|
+
] }, id);
|
|
7108
7915
|
}) })
|
|
7109
7916
|
] }) }) }),
|
|
7110
|
-
|
|
7917
|
+
clientPagination && !serverPagination && totalPages > 1 && /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
7111
7918
|
/* @__PURE__ */ jsxs30("span", { className: "text-xs text-muted-foreground", children: [
|
|
7112
7919
|
"Showing ",
|
|
7113
7920
|
(safePage - 1) * itemsPerPage + 1,
|
|
@@ -7126,7 +7933,7 @@ function Table({
|
|
|
7126
7933
|
children: /* @__PURE__ */ jsx32(ChevronLeft6, { className: "h-4 w-4" })
|
|
7127
7934
|
}
|
|
7128
7935
|
),
|
|
7129
|
-
pagePills[0] > 1 && /* @__PURE__ */ jsxs30(
|
|
7936
|
+
pagePills[0] > 1 && /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
7130
7937
|
/* @__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
7938
|
pagePills[0] > 2 && /* @__PURE__ */ jsx32("span", { className: "px-1 text-muted-foreground text-xs", children: "\u2026" })
|
|
7132
7939
|
] }),
|
|
@@ -7142,7 +7949,7 @@ function Table({
|
|
|
7142
7949
|
},
|
|
7143
7950
|
p
|
|
7144
7951
|
)),
|
|
7145
|
-
pagePills[pagePills.length - 1] < totalPages && /* @__PURE__ */ jsxs30(
|
|
7952
|
+
pagePills[pagePills.length - 1] < totalPages && /* @__PURE__ */ jsxs30(Fragment12, { children: [
|
|
7146
7953
|
pagePills[pagePills.length - 1] < totalPages - 1 && /* @__PURE__ */ jsx32("span", { className: "px-1 text-muted-foreground text-xs", children: "\u2026" }),
|
|
7147
7954
|
/* @__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
7955
|
] }),
|
|
@@ -7158,8 +7965,8 @@ function Table({
|
|
|
7158
7965
|
] })
|
|
7159
7966
|
] }),
|
|
7160
7967
|
serverPagination && (() => {
|
|
7161
|
-
const { pagination
|
|
7162
|
-
const totalServerPages =
|
|
7968
|
+
const { pagination, currentPage: cp, goToPage } = serverPagination;
|
|
7969
|
+
const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
|
|
7163
7970
|
const pills = [];
|
|
7164
7971
|
if (totalServerPages <= 7) {
|
|
7165
7972
|
for (let i = 1; i <= totalServerPages; i++) pills.push(i);
|
|
@@ -7172,7 +7979,7 @@ function Table({
|
|
|
7172
7979
|
}
|
|
7173
7980
|
return /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
7174
7981
|
/* @__PURE__ */ jsxs30("span", { className: "text-xs text-muted-foreground", children: [
|
|
7175
|
-
|
|
7982
|
+
pagination.total,
|
|
7176
7983
|
" total rows \xB7 page ",
|
|
7177
7984
|
cp,
|
|
7178
7985
|
" of ",
|
|
@@ -7183,7 +7990,7 @@ function Table({
|
|
|
7183
7990
|
"button",
|
|
7184
7991
|
{
|
|
7185
7992
|
onClick: () => goToPage(cp - 1),
|
|
7186
|
-
disabled: !
|
|
7993
|
+
disabled: !pagination.prev_page_url,
|
|
7187
7994
|
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
7995
|
children: /* @__PURE__ */ jsx32(ChevronLeft6, { className: "h-4 w-4" })
|
|
7189
7996
|
}
|
|
@@ -7206,7 +8013,7 @@ function Table({
|
|
|
7206
8013
|
"button",
|
|
7207
8014
|
{
|
|
7208
8015
|
onClick: () => goToPage(cp + 1),
|
|
7209
|
-
disabled: !
|
|
8016
|
+
disabled: !pagination.next_page_url,
|
|
7210
8017
|
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
8018
|
children: /* @__PURE__ */ jsx32(ChevronRight8, { className: "h-4 w-4" })
|
|
7212
8019
|
}
|
|
@@ -7221,6 +8028,7 @@ function Table({
|
|
|
7221
8028
|
item: viewItem,
|
|
7222
8029
|
fields: viewFields,
|
|
7223
8030
|
width: defaultActions.modalWidth,
|
|
8031
|
+
grid: defaultActions.viewFormGrid,
|
|
7224
8032
|
onClose: () => setViewItem(null)
|
|
7225
8033
|
}
|
|
7226
8034
|
),
|
|
@@ -7278,12 +8086,43 @@ function Table({
|
|
|
7278
8086
|
}
|
|
7279
8087
|
}
|
|
7280
8088
|
}
|
|
8089
|
+
),
|
|
8090
|
+
bulkConfirm && createPortal3(
|
|
8091
|
+
/* @__PURE__ */ jsx32(
|
|
8092
|
+
"div",
|
|
8093
|
+
{
|
|
8094
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
|
|
8095
|
+
style: { background: "rgba(0,0,0,0.5)" },
|
|
8096
|
+
onMouseDown: (e) => {
|
|
8097
|
+
if (e.target === e.currentTarget) setBulkConfirm(null);
|
|
8098
|
+
},
|
|
8099
|
+
children: /* @__PURE__ */ jsxs30("div", { className: "relative w-full max-w-md rounded-2xl border border-border bg-card shadow-2xl flex flex-col", children: [
|
|
8100
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border", children: [
|
|
8101
|
+
/* @__PURE__ */ jsx32("h2", { className: "text-base font-semibold", children: "Confirm Delete" }),
|
|
8102
|
+
/* @__PURE__ */ jsx32("button", { onClick: () => setBulkConfirm(null), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx32(X9, { className: "h-4 w-4" }) })
|
|
8103
|
+
] }),
|
|
8104
|
+
/* @__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." }) }),
|
|
8105
|
+
/* @__PURE__ */ jsxs30("div", { className: "px-6 py-4 border-t border-border flex justify-end gap-2", children: [
|
|
8106
|
+
/* @__PURE__ */ jsx32(Button, { variant: "outline", size: "sm", onClick: () => setBulkConfirm(null), disabled: bulkLoading, children: "Cancel" }),
|
|
8107
|
+
/* @__PURE__ */ jsxs30(Button, { variant: "danger", size: "sm", disabled: bulkLoading, onClick: async () => {
|
|
8108
|
+
if (bulkConfirm === "selected") await execBulkDeleteSelected();
|
|
8109
|
+
else await execDeleteAll();
|
|
8110
|
+
setBulkConfirm(null);
|
|
8111
|
+
}, children: [
|
|
8112
|
+
bulkLoading && /* @__PURE__ */ jsx32(Loader22, { className: "h-3.5 w-3.5 mr-1.5 animate-spin" }),
|
|
8113
|
+
bulkLoading ? "Deleting\u2026" : "Delete"
|
|
8114
|
+
] })
|
|
8115
|
+
] })
|
|
8116
|
+
] })
|
|
8117
|
+
}
|
|
8118
|
+
),
|
|
8119
|
+
document.body
|
|
7281
8120
|
)
|
|
7282
8121
|
] });
|
|
7283
8122
|
}
|
|
7284
8123
|
|
|
7285
8124
|
// src/components/ui/data-grid.tsx
|
|
7286
|
-
import { Fragment as
|
|
8125
|
+
import { Fragment as Fragment13, jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
7287
8126
|
function useServerDataGrid({ url, params, encrypt, key, decryptPayloadLog, columnOverrides }) {
|
|
7288
8127
|
const [data, setData] = React29.useState([]);
|
|
7289
8128
|
const [columns, setColumns] = React29.useState([]);
|
|
@@ -7411,7 +8250,7 @@ function DGModalShell({ title, onClose, children, footer, width = "lg" }) {
|
|
|
7411
8250
|
);
|
|
7412
8251
|
}
|
|
7413
8252
|
function DGFieldRenderer({ field, value, onChange }) {
|
|
7414
|
-
if (field.render) return /* @__PURE__ */ jsx33(
|
|
8253
|
+
if (field.render) return /* @__PURE__ */ jsx33(Fragment13, { children: field.render(value, onChange) });
|
|
7415
8254
|
const toLabelValue = (o) => {
|
|
7416
8255
|
if (typeof o === "string") return { label: o, value: o };
|
|
7417
8256
|
if (Array.isArray(o)) return { label: o[0], value: o[1] };
|
|
@@ -7491,7 +8330,7 @@ function DGViewModal({ item, fields, onClose, width }) {
|
|
|
7491
8330
|
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
8331
|
children: /* @__PURE__ */ jsx33("div", { className: "space-y-3", children: fields.map((f) => /* @__PURE__ */ jsxs31("div", { children: [
|
|
7493
8332
|
/* @__PURE__ */ jsx33("p", { className: "text-xs font-semibold text-muted-foreground mb-1", children: f.label }),
|
|
7494
|
-
f.render ? /* @__PURE__ */ jsx33(
|
|
8333
|
+
f.render ? /* @__PURE__ */ jsx33(Fragment13, { children: f.render(item[f.key], () => {
|
|
7495
8334
|
}) }) : /* @__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
8335
|
] }, f.key)) })
|
|
7497
8336
|
}
|
|
@@ -7555,7 +8394,7 @@ function DGEditModal({
|
|
|
7555
8394
|
title: "Edit Record",
|
|
7556
8395
|
onClose,
|
|
7557
8396
|
width,
|
|
7558
|
-
footer: /* @__PURE__ */ jsxs31(
|
|
8397
|
+
footer: /* @__PURE__ */ jsxs31(Fragment13, { children: [
|
|
7559
8398
|
/* @__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
8399
|
/* @__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
8400
|
loading && /* @__PURE__ */ jsx33(Loader23, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
@@ -7615,7 +8454,7 @@ function DGDeleteModal({
|
|
|
7615
8454
|
title: "Confirm Delete",
|
|
7616
8455
|
onClose,
|
|
7617
8456
|
width: "lg",
|
|
7618
|
-
footer: /* @__PURE__ */ jsxs31(
|
|
8457
|
+
footer: /* @__PURE__ */ jsxs31(Fragment13, { children: [
|
|
7619
8458
|
/* @__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
8459
|
/* @__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
8460
|
loading && /* @__PURE__ */ jsx33(Loader23, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
@@ -8547,7 +9386,7 @@ function KanbanBoard({ columns: controlled, onChange, onAddCard, className }) {
|
|
|
8547
9386
|
import * as React33 from "react";
|
|
8548
9387
|
import { MapContainer, TileLayer, Marker, Popup, Polyline, useMap, CircleMarker } from "react-leaflet";
|
|
8549
9388
|
import L from "leaflet";
|
|
8550
|
-
import { Fragment as
|
|
9389
|
+
import { Fragment as Fragment15, jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
8551
9390
|
L.Icon.Default.mergeOptions({
|
|
8552
9391
|
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
|
|
8553
9392
|
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
|
|
@@ -8653,7 +9492,7 @@ function RouteLayer({ routes }) {
|
|
|
8653
9492
|
});
|
|
8654
9493
|
}, [routes]);
|
|
8655
9494
|
if (loading) return null;
|
|
8656
|
-
return /* @__PURE__ */ jsx39(
|
|
9495
|
+
return /* @__PURE__ */ jsx39(Fragment15, { children: resolved.map((r, i) => {
|
|
8657
9496
|
const color = r.route.color ?? (r.route.routeType === "walk" ? "#22c55e" : "#6366f1");
|
|
8658
9497
|
const isDrive = (r.route.routeType ?? "drive") === "drive";
|
|
8659
9498
|
const midIdx = Math.floor(r.coords.length / 2);
|
|
@@ -8693,7 +9532,7 @@ function RouteLayer({ routes }) {
|
|
|
8693
9532
|
zIndexOffset: 100,
|
|
8694
9533
|
children: /* @__PURE__ */ jsx39(Popup, { children: /* @__PURE__ */ jsxs35("div", { className: "text-xs space-y-0.5 min-w-[120px]", children: [
|
|
8695
9534
|
/* @__PURE__ */ jsx39("p", { className: "font-semibold", children: r.route.label ? `${r.route.label} \u2014 Start` : "Start" }),
|
|
8696
|
-
r.distance > 0 && /* @__PURE__ */ jsxs35(
|
|
9535
|
+
r.distance > 0 && /* @__PURE__ */ jsxs35(Fragment15, { children: [
|
|
8697
9536
|
/* @__PURE__ */ jsx39("p", { className: "text-muted-foreground", children: fmtDistance(r.distance) }),
|
|
8698
9537
|
/* @__PURE__ */ jsxs35("p", { className: "text-muted-foreground", children: [
|
|
8699
9538
|
fmtDuration(r.duration),
|
|
@@ -8712,7 +9551,7 @@ function RouteLayer({ routes }) {
|
|
|
8712
9551
|
zIndexOffset: 100,
|
|
8713
9552
|
children: /* @__PURE__ */ jsx39(Popup, { children: /* @__PURE__ */ jsxs35("div", { className: "text-xs space-y-0.5 min-w-[120px]", children: [
|
|
8714
9553
|
/* @__PURE__ */ jsx39("p", { className: "font-semibold", children: r.route.label ? `${r.route.label} \u2014 End` : "End" }),
|
|
8715
|
-
r.distance > 0 && /* @__PURE__ */ jsxs35(
|
|
9554
|
+
r.distance > 0 && /* @__PURE__ */ jsxs35(Fragment15, { children: [
|
|
8716
9555
|
/* @__PURE__ */ jsx39("p", { className: "text-muted-foreground", children: fmtDistance(r.distance) }),
|
|
8717
9556
|
/* @__PURE__ */ jsxs35("p", { className: "text-muted-foreground", children: [
|
|
8718
9557
|
fmtDuration(r.duration),
|
|
@@ -8827,7 +9666,7 @@ function ClusterLayer({ markers, variant, onMarkerClick }) {
|
|
|
8827
9666
|
});
|
|
8828
9667
|
return groups;
|
|
8829
9668
|
}, [markers, zoom, map]);
|
|
8830
|
-
return /* @__PURE__ */ jsx39(
|
|
9669
|
+
return /* @__PURE__ */ jsx39(Fragment15, { children: clusters.map((g, gi) => {
|
|
8831
9670
|
if (g.items.length === 1) {
|
|
8832
9671
|
const m = g.items[0];
|
|
8833
9672
|
const color2 = resolveColor(m.color);
|
|
@@ -9696,7 +10535,7 @@ function Modal({
|
|
|
9696
10535
|
// src/components/ui/modal-variants.tsx
|
|
9697
10536
|
import * as React36 from "react";
|
|
9698
10537
|
import { AlertTriangle as AlertTriangle3, CheckCircle as CheckCircle2, Trash2 as Trash23, X as X13 } from "lucide-react";
|
|
9699
|
-
import { Fragment as
|
|
10538
|
+
import { Fragment as Fragment16, jsx as jsx42, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
9700
10539
|
function ModalBase({
|
|
9701
10540
|
isOpen,
|
|
9702
10541
|
onClose,
|
|
@@ -9847,7 +10686,7 @@ function ModalWithForms({
|
|
|
9847
10686
|
onSubmit(values);
|
|
9848
10687
|
}
|
|
9849
10688
|
function renderField(field) {
|
|
9850
|
-
if (field.render) return /* @__PURE__ */ jsx42(
|
|
10689
|
+
if (field.render) return /* @__PURE__ */ jsx42(Fragment16, { children: field.render(values[field.name], (v) => handleChange(field.name, v)) });
|
|
9851
10690
|
const strOptions = (field.options ?? []).map(
|
|
9852
10691
|
(o) => typeof o === "string" ? { label: o, value: o } : o
|
|
9853
10692
|
);
|
|
@@ -10195,7 +11034,7 @@ import { PanelLeftClose, PanelLeftOpen, Sun as Sun3, Moon as Moon2, Loader2 as L
|
|
|
10195
11034
|
// src/components/ui/tooltip.tsx
|
|
10196
11035
|
import * as React38 from "react";
|
|
10197
11036
|
import * as ReactDOM2 from "react-dom";
|
|
10198
|
-
import { Fragment as
|
|
11037
|
+
import { Fragment as Fragment17, jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
10199
11038
|
function Tooltip({
|
|
10200
11039
|
content,
|
|
10201
11040
|
children,
|
|
@@ -10206,7 +11045,7 @@ function Tooltip({
|
|
|
10206
11045
|
const [visible, setVisible] = React38.useState(false);
|
|
10207
11046
|
const [coords, setCoords] = React38.useState({ top: 0, left: 0 });
|
|
10208
11047
|
const ref = React38.useRef(null);
|
|
10209
|
-
if (!enabled) return /* @__PURE__ */ jsx44(
|
|
11048
|
+
if (!enabled) return /* @__PURE__ */ jsx44(Fragment17, { children });
|
|
10210
11049
|
function calcCoords() {
|
|
10211
11050
|
const r = ref.current?.getBoundingClientRect();
|
|
10212
11051
|
if (!r) return;
|
|
@@ -10803,7 +11642,7 @@ var useTheme = () => {
|
|
|
10803
11642
|
};
|
|
10804
11643
|
|
|
10805
11644
|
// src/components/ui/panel.tsx
|
|
10806
|
-
import { Fragment as
|
|
11645
|
+
import { Fragment as Fragment18, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
10807
11646
|
var PanelCollapsedContext = React40.createContext(false);
|
|
10808
11647
|
var PanelGroupsContext = React40.createContext({ expandedGroups: /* @__PURE__ */ new Set(), onGroupToggle: () => {
|
|
10809
11648
|
} });
|
|
@@ -10965,7 +11804,7 @@ function Panel({
|
|
|
10965
11804
|
"shrink-0 border-b border-border",
|
|
10966
11805
|
effectiveCollapsed ? "flex items-center justify-center py-3" : "flex items-center gap-2 px-4 py-3"
|
|
10967
11806
|
),
|
|
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(
|
|
11807
|
+
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
11808
|
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
11809
|
sidebarBrand.title && /* @__PURE__ */ jsx46("span", { className: "flex-1 truncate text-sm font-semibold", children: sidebarBrand.title }),
|
|
10971
11810
|
sidebarBrand.trailing && /* @__PURE__ */ jsx46("span", { className: "shrink-0", children: sidebarBrand.trailing })
|
|
@@ -12044,13 +12883,13 @@ function Timeline({ items, align = "left", className }) {
|
|
|
12044
12883
|
|
|
12045
12884
|
// src/components/ui/tree-view.tsx
|
|
12046
12885
|
import * as React48 from "react";
|
|
12047
|
-
import { ChevronRight as ChevronRight11, Folder, FolderOpen, File } from "lucide-react";
|
|
12886
|
+
import { ChevronRight as ChevronRight11, Folder, FolderOpen, File as File2 } from "lucide-react";
|
|
12048
12887
|
import { jsx as jsx60, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
12049
12888
|
function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelect, multiple }) {
|
|
12050
12889
|
const hasChildren = !!node.children?.length;
|
|
12051
12890
|
const isExpanded = expanded.includes(node.id);
|
|
12052
12891
|
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(
|
|
12892
|
+
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
12893
|
return /* @__PURE__ */ jsxs53("div", { children: [
|
|
12055
12894
|
/* @__PURE__ */ jsxs53(
|
|
12056
12895
|
"div",
|
|
@@ -12274,7 +13113,7 @@ function Widget({
|
|
|
12274
13113
|
// src/components/ui/wizard.tsx
|
|
12275
13114
|
import * as React50 from "react";
|
|
12276
13115
|
import { Check as Check7, X as X15, ChevronLeft as ChevronLeft8, ChevronRight as ChevronRight12, AlertCircle as AlertCircle2 } from "lucide-react";
|
|
12277
|
-
import { Fragment as
|
|
13116
|
+
import { Fragment as Fragment21, jsx as jsx62, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
12278
13117
|
var SIZE_MAP = {
|
|
12279
13118
|
sm: "max-w-sm",
|
|
12280
13119
|
md: "max-w-lg",
|
|
@@ -12484,10 +13323,10 @@ function DefaultActions({
|
|
|
12484
13323
|
/* @__PURE__ */ jsx62("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v8z" })
|
|
12485
13324
|
] }),
|
|
12486
13325
|
"Processing..."
|
|
12487
|
-
] }) : isLast ? /* @__PURE__ */ jsxs55(
|
|
13326
|
+
] }) : isLast ? /* @__PURE__ */ jsxs55(Fragment21, { children: [
|
|
12488
13327
|
/* @__PURE__ */ jsx62(Check7, { className: "h-4 w-4" }),
|
|
12489
13328
|
finishLabel ?? "Finish"
|
|
12490
|
-
] }) : /* @__PURE__ */ jsxs55(
|
|
13329
|
+
] }) : /* @__PURE__ */ jsxs55(Fragment21, { children: [
|
|
12491
13330
|
nextLabel ?? "Next",
|
|
12492
13331
|
/* @__PURE__ */ jsx62(ChevronRight12, { className: "h-4 w-4" })
|
|
12493
13332
|
] })
|
|
@@ -12732,6 +13571,12 @@ var axiosInstance = axios5.create({
|
|
|
12732
13571
|
Accept: "application/json"
|
|
12733
13572
|
}
|
|
12734
13573
|
});
|
|
13574
|
+
axiosInstance.interceptors.request.use((config) => {
|
|
13575
|
+
if (config.data instanceof FormData) {
|
|
13576
|
+
delete config.headers["Content-Type"];
|
|
13577
|
+
}
|
|
13578
|
+
return config;
|
|
13579
|
+
});
|
|
12735
13580
|
|
|
12736
13581
|
// src/lib/codego/request.ts
|
|
12737
13582
|
var request = async (config) => {
|
|
@@ -12790,13 +13635,13 @@ var setupInterceptors = () => {
|
|
|
12790
13635
|
|
|
12791
13636
|
// src/lib/codego/provider.tsx
|
|
12792
13637
|
import * as React51 from "react";
|
|
12793
|
-
import { Fragment as
|
|
13638
|
+
import { Fragment as Fragment22, jsx as jsx63 } from "react/jsx-runtime";
|
|
12794
13639
|
function CodegoApiProvider({ children }) {
|
|
12795
13640
|
const { toast } = useToast();
|
|
12796
13641
|
React51.useEffect(() => {
|
|
12797
13642
|
setToastFunction(toast);
|
|
12798
13643
|
}, [toast]);
|
|
12799
|
-
return /* @__PURE__ */ jsx63(
|
|
13644
|
+
return /* @__PURE__ */ jsx63(Fragment22, { children });
|
|
12800
13645
|
}
|
|
12801
13646
|
|
|
12802
13647
|
// src/lib/codego/index.ts
|