@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.global.js
CHANGED
|
@@ -63192,7 +63192,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63192
63192
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
63193
63193
|
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
|
|
63194
63194
|
];
|
|
63195
|
-
var
|
|
63195
|
+
var File2 = createLucideIcon("file", __iconNode30);
|
|
63196
63196
|
|
|
63197
63197
|
// node_modules/lucide-react/dist/esm/icons/flip-horizontal.js
|
|
63198
63198
|
var __iconNode31 = [
|
|
@@ -63373,8 +63373,20 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63373
63373
|
];
|
|
63374
63374
|
var PanelLeftOpen = createLucideIcon("panel-left-open", __iconNode49);
|
|
63375
63375
|
|
|
63376
|
-
// node_modules/lucide-react/dist/esm/icons/
|
|
63376
|
+
// node_modules/lucide-react/dist/esm/icons/paperclip.js
|
|
63377
63377
|
var __iconNode50 = [
|
|
63378
|
+
[
|
|
63379
|
+
"path",
|
|
63380
|
+
{
|
|
63381
|
+
d: "m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551",
|
|
63382
|
+
key: "1miecu"
|
|
63383
|
+
}
|
|
63384
|
+
]
|
|
63385
|
+
];
|
|
63386
|
+
var Paperclip = createLucideIcon("paperclip", __iconNode50);
|
|
63387
|
+
|
|
63388
|
+
// node_modules/lucide-react/dist/esm/icons/pencil.js
|
|
63389
|
+
var __iconNode51 = [
|
|
63378
63390
|
[
|
|
63379
63391
|
"path",
|
|
63380
63392
|
{
|
|
@@ -63384,10 +63396,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63384
63396
|
],
|
|
63385
63397
|
["path", { d: "m15 5 4 4", key: "1mk7zo" }]
|
|
63386
63398
|
];
|
|
63387
|
-
var Pencil = createLucideIcon("pencil",
|
|
63399
|
+
var Pencil = createLucideIcon("pencil", __iconNode51);
|
|
63388
63400
|
|
|
63389
63401
|
// node_modules/lucide-react/dist/esm/icons/pin.js
|
|
63390
|
-
var
|
|
63402
|
+
var __iconNode52 = [
|
|
63391
63403
|
["path", { d: "M12 17v5", key: "bb1du9" }],
|
|
63392
63404
|
[
|
|
63393
63405
|
"path",
|
|
@@ -63397,17 +63409,17 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63397
63409
|
}
|
|
63398
63410
|
]
|
|
63399
63411
|
];
|
|
63400
|
-
var Pin = createLucideIcon("pin",
|
|
63412
|
+
var Pin = createLucideIcon("pin", __iconNode52);
|
|
63401
63413
|
|
|
63402
63414
|
// node_modules/lucide-react/dist/esm/icons/plus.js
|
|
63403
|
-
var
|
|
63415
|
+
var __iconNode53 = [
|
|
63404
63416
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
63405
63417
|
["path", { d: "M12 5v14", key: "s699le" }]
|
|
63406
63418
|
];
|
|
63407
|
-
var Plus = createLucideIcon("plus",
|
|
63419
|
+
var Plus = createLucideIcon("plus", __iconNode53);
|
|
63408
63420
|
|
|
63409
63421
|
// node_modules/lucide-react/dist/esm/icons/quote.js
|
|
63410
|
-
var
|
|
63422
|
+
var __iconNode54 = [
|
|
63411
63423
|
[
|
|
63412
63424
|
"path",
|
|
63413
63425
|
{
|
|
@@ -63423,31 +63435,31 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63423
63435
|
}
|
|
63424
63436
|
]
|
|
63425
63437
|
];
|
|
63426
|
-
var Quote = createLucideIcon("quote",
|
|
63438
|
+
var Quote = createLucideIcon("quote", __iconNode54);
|
|
63427
63439
|
|
|
63428
63440
|
// node_modules/lucide-react/dist/esm/icons/redo.js
|
|
63429
|
-
var
|
|
63441
|
+
var __iconNode55 = [
|
|
63430
63442
|
["path", { d: "M21 7v6h-6", key: "3ptur4" }],
|
|
63431
63443
|
["path", { d: "M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7", key: "1kgawr" }]
|
|
63432
63444
|
];
|
|
63433
|
-
var Redo = createLucideIcon("redo",
|
|
63445
|
+
var Redo = createLucideIcon("redo", __iconNode55);
|
|
63434
63446
|
|
|
63435
63447
|
// node_modules/lucide-react/dist/esm/icons/rotate-ccw.js
|
|
63436
|
-
var
|
|
63448
|
+
var __iconNode56 = [
|
|
63437
63449
|
["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
|
|
63438
63450
|
["path", { d: "M3 3v5h5", key: "1xhq8a" }]
|
|
63439
63451
|
];
|
|
63440
|
-
var RotateCcw = createLucideIcon("rotate-ccw",
|
|
63452
|
+
var RotateCcw = createLucideIcon("rotate-ccw", __iconNode56);
|
|
63441
63453
|
|
|
63442
63454
|
// node_modules/lucide-react/dist/esm/icons/rotate-cw.js
|
|
63443
|
-
var
|
|
63455
|
+
var __iconNode57 = [
|
|
63444
63456
|
["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
|
|
63445
63457
|
["path", { d: "M21 3v5h-5", key: "1q7to0" }]
|
|
63446
63458
|
];
|
|
63447
|
-
var RotateCw = createLucideIcon("rotate-cw",
|
|
63459
|
+
var RotateCw = createLucideIcon("rotate-cw", __iconNode57);
|
|
63448
63460
|
|
|
63449
63461
|
// node_modules/lucide-react/dist/esm/icons/satellite.js
|
|
63450
|
-
var
|
|
63462
|
+
var __iconNode58 = [
|
|
63451
63463
|
[
|
|
63452
63464
|
"path",
|
|
63453
63465
|
{
|
|
@@ -63472,10 +63484,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63472
63484
|
}
|
|
63473
63485
|
]
|
|
63474
63486
|
];
|
|
63475
|
-
var Satellite = createLucideIcon("satellite",
|
|
63487
|
+
var Satellite = createLucideIcon("satellite", __iconNode58);
|
|
63476
63488
|
|
|
63477
63489
|
// node_modules/lucide-react/dist/esm/icons/save.js
|
|
63478
|
-
var
|
|
63490
|
+
var __iconNode59 = [
|
|
63479
63491
|
[
|
|
63480
63492
|
"path",
|
|
63481
63493
|
{
|
|
@@ -63486,26 +63498,26 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63486
63498
|
["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
|
|
63487
63499
|
["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
|
|
63488
63500
|
];
|
|
63489
|
-
var Save = createLucideIcon("save",
|
|
63501
|
+
var Save = createLucideIcon("save", __iconNode59);
|
|
63490
63502
|
|
|
63491
63503
|
// node_modules/lucide-react/dist/esm/icons/search.js
|
|
63492
|
-
var
|
|
63504
|
+
var __iconNode60 = [
|
|
63493
63505
|
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
63494
63506
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
63495
63507
|
];
|
|
63496
|
-
var Search = createLucideIcon("search",
|
|
63508
|
+
var Search = createLucideIcon("search", __iconNode60);
|
|
63497
63509
|
|
|
63498
63510
|
// node_modules/lucide-react/dist/esm/icons/settings-2.js
|
|
63499
|
-
var
|
|
63511
|
+
var __iconNode61 = [
|
|
63500
63512
|
["path", { d: "M14 17H5", key: "gfn3mx" }],
|
|
63501
63513
|
["path", { d: "M19 7h-9", key: "6i9tg" }],
|
|
63502
63514
|
["circle", { cx: "17", cy: "17", r: "3", key: "18b49y" }],
|
|
63503
63515
|
["circle", { cx: "7", cy: "7", r: "3", key: "dfmy0x" }]
|
|
63504
63516
|
];
|
|
63505
|
-
var Settings2 = createLucideIcon("settings-2",
|
|
63517
|
+
var Settings2 = createLucideIcon("settings-2", __iconNode61);
|
|
63506
63518
|
|
|
63507
63519
|
// node_modules/lucide-react/dist/esm/icons/sliders-vertical.js
|
|
63508
|
-
var
|
|
63520
|
+
var __iconNode62 = [
|
|
63509
63521
|
["path", { d: "M10 8h4", key: "1sr2af" }],
|
|
63510
63522
|
["path", { d: "M12 21v-9", key: "17s77i" }],
|
|
63511
63523
|
["path", { d: "M12 8V3", key: "13r4qs" }],
|
|
@@ -63516,10 +63528,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63516
63528
|
["path", { d: "M5 10V3", key: "cb8scm" }],
|
|
63517
63529
|
["path", { d: "M5 21v-7", key: "1w1uti" }]
|
|
63518
63530
|
];
|
|
63519
|
-
var SlidersVertical = createLucideIcon("sliders-vertical",
|
|
63531
|
+
var SlidersVertical = createLucideIcon("sliders-vertical", __iconNode62);
|
|
63520
63532
|
|
|
63521
63533
|
// node_modules/lucide-react/dist/esm/icons/sun.js
|
|
63522
|
-
var
|
|
63534
|
+
var __iconNode63 = [
|
|
63523
63535
|
["circle", { cx: "12", cy: "12", r: "4", key: "4exip2" }],
|
|
63524
63536
|
["path", { d: "M12 2v2", key: "tus03m" }],
|
|
63525
63537
|
["path", { d: "M12 20v2", key: "1lh1kg" }],
|
|
@@ -63530,10 +63542,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63530
63542
|
["path", { d: "m6.34 17.66-1.41 1.41", key: "1m8zz5" }],
|
|
63531
63543
|
["path", { d: "m19.07 4.93-1.41 1.41", key: "1shlcs" }]
|
|
63532
63544
|
];
|
|
63533
|
-
var Sun = createLucideIcon("sun",
|
|
63545
|
+
var Sun = createLucideIcon("sun", __iconNode63);
|
|
63534
63546
|
|
|
63535
63547
|
// node_modules/lucide-react/dist/esm/icons/tag.js
|
|
63536
|
-
var
|
|
63548
|
+
var __iconNode64 = [
|
|
63537
63549
|
[
|
|
63538
63550
|
"path",
|
|
63539
63551
|
{
|
|
@@ -63543,42 +63555,42 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63543
63555
|
],
|
|
63544
63556
|
["circle", { cx: "7.5", cy: "7.5", r: ".5", fill: "currentColor", key: "kqv944" }]
|
|
63545
63557
|
];
|
|
63546
|
-
var Tag = createLucideIcon("tag",
|
|
63558
|
+
var Tag = createLucideIcon("tag", __iconNode64);
|
|
63547
63559
|
|
|
63548
63560
|
// node_modules/lucide-react/dist/esm/icons/trash-2.js
|
|
63549
|
-
var
|
|
63561
|
+
var __iconNode65 = [
|
|
63550
63562
|
["path", { d: "M10 11v6", key: "nco0om" }],
|
|
63551
63563
|
["path", { d: "M14 11v6", key: "outv1u" }],
|
|
63552
63564
|
["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
|
|
63553
63565
|
["path", { d: "M3 6h18", key: "d0wm0j" }],
|
|
63554
63566
|
["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
|
|
63555
63567
|
];
|
|
63556
|
-
var Trash2 = createLucideIcon("trash-2",
|
|
63568
|
+
var Trash2 = createLucideIcon("trash-2", __iconNode65);
|
|
63557
63569
|
|
|
63558
63570
|
// node_modules/lucide-react/dist/esm/icons/trash.js
|
|
63559
|
-
var
|
|
63571
|
+
var __iconNode66 = [
|
|
63560
63572
|
["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
|
|
63561
63573
|
["path", { d: "M3 6h18", key: "d0wm0j" }],
|
|
63562
63574
|
["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
|
|
63563
63575
|
];
|
|
63564
|
-
var Trash = createLucideIcon("trash",
|
|
63576
|
+
var Trash = createLucideIcon("trash", __iconNode66);
|
|
63565
63577
|
|
|
63566
63578
|
// node_modules/lucide-react/dist/esm/icons/trending-down.js
|
|
63567
|
-
var
|
|
63579
|
+
var __iconNode67 = [
|
|
63568
63580
|
["path", { d: "M16 17h6v-6", key: "t6n2it" }],
|
|
63569
63581
|
["path", { d: "m22 17-8.5-8.5-5 5L2 7", key: "x473p" }]
|
|
63570
63582
|
];
|
|
63571
|
-
var TrendingDown = createLucideIcon("trending-down",
|
|
63583
|
+
var TrendingDown = createLucideIcon("trending-down", __iconNode67);
|
|
63572
63584
|
|
|
63573
63585
|
// node_modules/lucide-react/dist/esm/icons/trending-up.js
|
|
63574
|
-
var
|
|
63586
|
+
var __iconNode68 = [
|
|
63575
63587
|
["path", { d: "M16 7h6v6", key: "box55l" }],
|
|
63576
63588
|
["path", { d: "m22 7-8.5 8.5-5-5L2 17", key: "1t1m79" }]
|
|
63577
63589
|
];
|
|
63578
|
-
var TrendingUp = createLucideIcon("trending-up",
|
|
63590
|
+
var TrendingUp = createLucideIcon("trending-up", __iconNode68);
|
|
63579
63591
|
|
|
63580
63592
|
// node_modules/lucide-react/dist/esm/icons/triangle-alert.js
|
|
63581
|
-
var
|
|
63593
|
+
var __iconNode69 = [
|
|
63582
63594
|
[
|
|
63583
63595
|
"path",
|
|
63584
63596
|
{
|
|
@@ -63589,28 +63601,28 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
63589
63601
|
["path", { d: "M12 9v4", key: "juzpu7" }],
|
|
63590
63602
|
["path", { d: "M12 17h.01", key: "p32p05" }]
|
|
63591
63603
|
];
|
|
63592
|
-
var TriangleAlert = createLucideIcon("triangle-alert",
|
|
63604
|
+
var TriangleAlert = createLucideIcon("triangle-alert", __iconNode69);
|
|
63593
63605
|
|
|
63594
63606
|
// node_modules/lucide-react/dist/esm/icons/underline.js
|
|
63595
|
-
var
|
|
63607
|
+
var __iconNode70 = [
|
|
63596
63608
|
["path", { d: "M6 4v6a6 6 0 0 0 12 0V4", key: "9kb039" }],
|
|
63597
63609
|
["line", { x1: "4", x2: "20", y1: "20", y2: "20", key: "nun2al" }]
|
|
63598
63610
|
];
|
|
63599
|
-
var Underline = createLucideIcon("underline",
|
|
63611
|
+
var Underline = createLucideIcon("underline", __iconNode70);
|
|
63600
63612
|
|
|
63601
63613
|
// node_modules/lucide-react/dist/esm/icons/undo.js
|
|
63602
|
-
var
|
|
63614
|
+
var __iconNode71 = [
|
|
63603
63615
|
["path", { d: "M3 7v6h6", key: "1v2h90" }],
|
|
63604
63616
|
["path", { d: "M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13", key: "1r6uu6" }]
|
|
63605
63617
|
];
|
|
63606
|
-
var Undo = createLucideIcon("undo",
|
|
63618
|
+
var Undo = createLucideIcon("undo", __iconNode71);
|
|
63607
63619
|
|
|
63608
63620
|
// node_modules/lucide-react/dist/esm/icons/x.js
|
|
63609
|
-
var
|
|
63621
|
+
var __iconNode72 = [
|
|
63610
63622
|
["path", { d: "M18 6 6 18", key: "1bl5f8" }],
|
|
63611
63623
|
["path", { d: "m6 6 12 12", key: "d8bk6v" }]
|
|
63612
63624
|
];
|
|
63613
|
-
var X = createLucideIcon("x",
|
|
63625
|
+
var X = createLucideIcon("x", __iconNode72);
|
|
63614
63626
|
|
|
63615
63627
|
// src/components/ui/date-picker.tsx
|
|
63616
63628
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -65399,13 +65411,13 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
65399
65411
|
const categories = React8.useMemo(() => {
|
|
65400
65412
|
if (categoriesProp) return categoriesProp;
|
|
65401
65413
|
const set = /* @__PURE__ */ new Set();
|
|
65402
|
-
items.forEach((i) => {
|
|
65414
|
+
(items ?? []).forEach((i) => {
|
|
65403
65415
|
if (i.category) set.add(i.category);
|
|
65404
65416
|
});
|
|
65405
65417
|
return Array.from(set);
|
|
65406
65418
|
}, [items, categoriesProp]);
|
|
65407
65419
|
const filtered = React8.useMemo(() => {
|
|
65408
|
-
let list = items;
|
|
65420
|
+
let list = items ?? [];
|
|
65409
65421
|
if (search.trim()) {
|
|
65410
65422
|
const q = search.toLowerCase();
|
|
65411
65423
|
list = list.filter(
|
|
@@ -65414,7 +65426,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
65414
65426
|
}
|
|
65415
65427
|
if (category) list = list.filter((i) => i.category === category);
|
|
65416
65428
|
return [...list].sort((a, b) => (b.pinned ? 1 : 0) - (a.pinned ? 1 : 0));
|
|
65417
|
-
}, [items, search, category]);
|
|
65429
|
+
}, [items ?? [], search, category]);
|
|
65418
65430
|
const showToolbar = searchable || filterable && categories.length > 0;
|
|
65419
65431
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
65420
65432
|
showHeader && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
@@ -69055,11 +69067,77 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69055
69067
|
|
|
69056
69068
|
// src/components/ui/repeater.tsx
|
|
69057
69069
|
var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
|
|
69070
|
+
function RepeaterFieldRenderer({
|
|
69071
|
+
field,
|
|
69072
|
+
value,
|
|
69073
|
+
onChange
|
|
69074
|
+
}) {
|
|
69075
|
+
if (field.type === "image") {
|
|
69076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
69077
|
+
field.label && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
|
|
69078
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
69079
|
+
value && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("img", { src: value, alt: field.key, className: "h-10 w-10 rounded-lg object-cover ring-1 ring-border shrink-0" }),
|
|
69080
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
69081
|
+
Input,
|
|
69082
|
+
{
|
|
69083
|
+
inputMode: "text",
|
|
69084
|
+
value: value ?? "",
|
|
69085
|
+
onChange: (e) => onChange(e.target.value),
|
|
69086
|
+
placeholder: field.placeholder ?? "Image URL"
|
|
69087
|
+
}
|
|
69088
|
+
)
|
|
69089
|
+
] })
|
|
69090
|
+
] });
|
|
69091
|
+
}
|
|
69092
|
+
if (field.type === "attachment") {
|
|
69093
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
69094
|
+
field.label && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
|
|
69095
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
69096
|
+
value && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
69097
|
+
"a",
|
|
69098
|
+
{
|
|
69099
|
+
href: value,
|
|
69100
|
+
target: "_blank",
|
|
69101
|
+
rel: "noopener noreferrer",
|
|
69102
|
+
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",
|
|
69103
|
+
children: [
|
|
69104
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Paperclip, { className: "h-3 w-3" }),
|
|
69105
|
+
String(value).split("/").pop()
|
|
69106
|
+
]
|
|
69107
|
+
}
|
|
69108
|
+
),
|
|
69109
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
69110
|
+
Input,
|
|
69111
|
+
{
|
|
69112
|
+
inputMode: "text",
|
|
69113
|
+
value: value ?? "",
|
|
69114
|
+
onChange: (e) => onChange(e.target.value),
|
|
69115
|
+
placeholder: field.placeholder ?? "Attachment URL"
|
|
69116
|
+
}
|
|
69117
|
+
)
|
|
69118
|
+
] })
|
|
69119
|
+
] });
|
|
69120
|
+
}
|
|
69121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
|
69122
|
+
field.label && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: field.label }),
|
|
69123
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
69124
|
+
Input,
|
|
69125
|
+
{
|
|
69126
|
+
inputMode: "text",
|
|
69127
|
+
value: value ?? "",
|
|
69128
|
+
onChange: (e) => onChange(e.target.value),
|
|
69129
|
+
placeholder: field.placeholder ?? field.key
|
|
69130
|
+
}
|
|
69131
|
+
)
|
|
69132
|
+
] });
|
|
69133
|
+
}
|
|
69058
69134
|
function Repeater({
|
|
69059
69135
|
items,
|
|
69060
69136
|
onAdd,
|
|
69061
69137
|
onRemove,
|
|
69062
69138
|
renderItem,
|
|
69139
|
+
fields,
|
|
69140
|
+
onFieldChange,
|
|
69063
69141
|
addButtonText = "Add Item",
|
|
69064
69142
|
className
|
|
69065
69143
|
}) {
|
|
@@ -69072,7 +69150,15 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69072
69150
|
children: [
|
|
69073
69151
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-1 cursor-grab text-muted-foreground/30 group-hover:text-muted-foreground/60 transition-colors shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(GripVertical, { className: "h-4 w-4" }) }),
|
|
69074
69152
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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 }),
|
|
69075
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex-1 min-w-0", children:
|
|
69153
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex-1 min-w-0", children: fields ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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__ */ (0, import_jsx_runtime29.jsx)(
|
|
69154
|
+
RepeaterFieldRenderer,
|
|
69155
|
+
{
|
|
69156
|
+
field: f,
|
|
69157
|
+
value: item[f.key],
|
|
69158
|
+
onChange: (v) => onFieldChange?.(index, f.key, v)
|
|
69159
|
+
},
|
|
69160
|
+
f.key
|
|
69161
|
+
)) }) : renderItem ? renderItem(item, index) : null }),
|
|
69076
69162
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
69077
69163
|
Button,
|
|
69078
69164
|
{
|
|
@@ -69552,17 +69638,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69552
69638
|
var React28 = __toESM(require_react(), 1);
|
|
69553
69639
|
var import_react_dom2 = __toESM(require_react_dom(), 1);
|
|
69554
69640
|
var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
|
|
69555
|
-
|
|
69556
|
-
csrfAxios.interceptors.request.use((config) => {
|
|
69557
|
-
const method = (config.method ?? "").toUpperCase();
|
|
69558
|
-
if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) {
|
|
69559
|
-
const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
69560
|
-
if (!token) throw new Error('[Table] CSRF token not found. Add <meta name="csrf-token" content="..."> to your HTML <head>.');
|
|
69561
|
-
config.headers.set("X-CSRF-Token", token);
|
|
69562
|
-
}
|
|
69563
|
-
return config;
|
|
69564
|
-
});
|
|
69565
|
-
function useServerTable({ url: url2, params, encrypt, key, decryptPayloadLog, columnOverrides, debounce = 300, transform, manual = false, refresh: refreshEnabled = false, refreshInterval = 0, hardReload, onSuccess, onError }) {
|
|
69641
|
+
function useServerTable({ url: url2, params, encrypt, key, decryptPayloadLog, columnOverrides, debounce = 300, transform, manual = false, refresh: refreshEnabled = false, refreshInterval = 0, hardReload, onSuccess, onError, filter: filterFields, sort: sortKeys }) {
|
|
69566
69642
|
const [data, setData] = React28.useState([]);
|
|
69567
69643
|
const [columns, setColumns] = React28.useState([]);
|
|
69568
69644
|
const [currentPage, setCurrentPage] = React28.useState(1);
|
|
@@ -69572,6 +69648,15 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69572
69648
|
const [tick, setTick] = React28.useState(0);
|
|
69573
69649
|
const [searchValue, setSearchValue] = React28.useState("");
|
|
69574
69650
|
const debounceTimer = React28.useRef(void 0);
|
|
69651
|
+
const [filterValues, setFilterValues] = React28.useState(() => {
|
|
69652
|
+
const init = {};
|
|
69653
|
+
filterFields?.forEach((f) => {
|
|
69654
|
+
init[f.key] = f.type === "checkbox" || f.type === "toggle" ? false : "";
|
|
69655
|
+
});
|
|
69656
|
+
return init;
|
|
69657
|
+
});
|
|
69658
|
+
const [sortKey, setSortKey] = React28.useState("");
|
|
69659
|
+
const [sortDir, setSortDir] = React28.useState("asc");
|
|
69575
69660
|
React28.useEffect(() => {
|
|
69576
69661
|
if (hardReload) hardReload.current = () => setTick((t) => t + 1);
|
|
69577
69662
|
}, [hardReload]);
|
|
@@ -69580,13 +69665,32 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69580
69665
|
const id = setInterval(() => setTick((t) => t + 1), refreshInterval);
|
|
69581
69666
|
return () => clearInterval(id);
|
|
69582
69667
|
}, [refreshInterval]);
|
|
69668
|
+
const activeFilterParams = React28.useMemo(() => {
|
|
69669
|
+
const out = {};
|
|
69670
|
+
filterFields?.forEach((f) => {
|
|
69671
|
+
const v = filterValues[f.key];
|
|
69672
|
+
if (f.type === "checkbox" || f.type === "toggle") {
|
|
69673
|
+
if (v) out[f.key] = 1;
|
|
69674
|
+
} else if (f.type === "date-range") {
|
|
69675
|
+
if (v?.from) out[`${f.key}_from`] = v.from;
|
|
69676
|
+
if (v?.to) out[`${f.key}_to`] = v.to;
|
|
69677
|
+
} else if (v !== "" && v !== null && v !== void 0) {
|
|
69678
|
+
out[f.key] = v;
|
|
69679
|
+
}
|
|
69680
|
+
});
|
|
69681
|
+
if (sortKey) {
|
|
69682
|
+
out.sort = sortKey;
|
|
69683
|
+
out.direction = sortDir;
|
|
69684
|
+
}
|
|
69685
|
+
return out;
|
|
69686
|
+
}, [filterValues, sortKey, sortDir, filterFields]);
|
|
69583
69687
|
React28.useEffect(() => {
|
|
69584
69688
|
if (manual && tick === 0) return;
|
|
69585
69689
|
let cancelled = false;
|
|
69586
69690
|
setLoading(true);
|
|
69587
69691
|
setError(null);
|
|
69588
69692
|
axios_default.get(url2, {
|
|
69589
|
-
params: { ...params, page: currentPage, search: searchValue }
|
|
69693
|
+
params: { ...params, ...activeFilterParams, page: currentPage, search: searchValue }
|
|
69590
69694
|
}).then(({ data: res }) => {
|
|
69591
69695
|
if (cancelled) return;
|
|
69592
69696
|
const payload = encrypt ? decryptLaravelPayload(res, key) : res;
|
|
@@ -69632,15 +69736,184 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69632
69736
|
return () => {
|
|
69633
69737
|
cancelled = true;
|
|
69634
69738
|
};
|
|
69635
|
-
}, [url2, currentPage, tick, JSON.stringify(params), encrypt, decryptPayloadLog, JSON.stringify(columnOverrides), searchValue]);
|
|
69739
|
+
}, [url2, currentPage, tick, JSON.stringify(params), JSON.stringify(activeFilterParams), encrypt, decryptPayloadLog, JSON.stringify(columnOverrides), searchValue]);
|
|
69636
69740
|
const handleSearchChange = (value) => {
|
|
69637
69741
|
setSearchValue(value);
|
|
69638
69742
|
setCurrentPage(1);
|
|
69639
69743
|
if (debounceTimer.current) clearTimeout(debounceTimer.current);
|
|
69640
|
-
debounceTimer.current = setTimeout(() =>
|
|
69641
|
-
|
|
69642
|
-
|
|
69744
|
+
debounceTimer.current = setTimeout(() => setTick((t) => t + 1), debounce);
|
|
69745
|
+
};
|
|
69746
|
+
const handleFilterChange = (key2, value) => {
|
|
69747
|
+
setFilterValues((prev) => ({ ...prev, [key2]: value }));
|
|
69748
|
+
setCurrentPage(1);
|
|
69749
|
+
setTick((t) => t + 1);
|
|
69750
|
+
};
|
|
69751
|
+
const handleClearFilters = () => {
|
|
69752
|
+
const reset = {};
|
|
69753
|
+
filterFields?.forEach((f) => {
|
|
69754
|
+
reset[f.key] = f.type === "checkbox" || f.type === "toggle" ? false : "";
|
|
69755
|
+
});
|
|
69756
|
+
setFilterValues(reset);
|
|
69757
|
+
setSortKey("");
|
|
69758
|
+
setSortDir("asc");
|
|
69759
|
+
setCurrentPage(1);
|
|
69760
|
+
setTick((t) => t + 1);
|
|
69643
69761
|
};
|
|
69762
|
+
const hasActiveFilters = filterFields?.some((f) => {
|
|
69763
|
+
const v = filterValues[f.key];
|
|
69764
|
+
return f.type === "checkbox" || f.type === "toggle" ? !!v : v !== "" && v !== null && v !== void 0;
|
|
69765
|
+
}) || !!sortKey;
|
|
69766
|
+
const filterBar = filterFields?.length || sortKeys?.length ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-wrap items-end gap-3 rounded-xl border border-border bg-muted/30 px-4 py-3", children: [
|
|
69767
|
+
filterFields?.map((f) => {
|
|
69768
|
+
const label = f.label ?? f.key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
69769
|
+
const value = filterValues[f.key];
|
|
69770
|
+
const opts = (f.options ?? []).map(
|
|
69771
|
+
(o) => typeof o === "string" ? { label: o, value: o } : o
|
|
69772
|
+
);
|
|
69773
|
+
if (f.type === "checkbox") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer select-none", children: [
|
|
69774
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69775
|
+
"input",
|
|
69776
|
+
{
|
|
69777
|
+
type: "checkbox",
|
|
69778
|
+
checked: !!value,
|
|
69779
|
+
onChange: (e) => handleFilterChange(f.key, e.target.checked),
|
|
69780
|
+
className: "h-4 w-4 rounded accent-primary"
|
|
69781
|
+
}
|
|
69782
|
+
),
|
|
69783
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs font-medium text-foreground", children: label })
|
|
69784
|
+
] }, f.key);
|
|
69785
|
+
if (f.type === "toggle") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer select-none", children: [
|
|
69786
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69787
|
+
"button",
|
|
69788
|
+
{
|
|
69789
|
+
type: "button",
|
|
69790
|
+
role: "switch",
|
|
69791
|
+
"aria-checked": !!value,
|
|
69792
|
+
onClick: () => handleFilterChange(f.key, !value),
|
|
69793
|
+
className: cn(
|
|
69794
|
+
"relative inline-flex h-5 w-9 shrink-0 rounded-full border-2 border-transparent transition-colors",
|
|
69795
|
+
value ? "bg-primary" : "bg-muted"
|
|
69796
|
+
),
|
|
69797
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn(
|
|
69798
|
+
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
69799
|
+
value ? "translate-x-4" : "translate-x-0"
|
|
69800
|
+
) })
|
|
69801
|
+
}
|
|
69802
|
+
),
|
|
69803
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs font-medium text-foreground", children: label })
|
|
69804
|
+
] }, f.key);
|
|
69805
|
+
if (f.type === "select") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
69806
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
69807
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
69808
|
+
"select",
|
|
69809
|
+
{
|
|
69810
|
+
value: value ?? "",
|
|
69811
|
+
onChange: (e) => handleFilterChange(f.key, e.target.value),
|
|
69812
|
+
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",
|
|
69813
|
+
children: [
|
|
69814
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: "", children: f.placeholder ?? `All ${label}` }),
|
|
69815
|
+
opts.map((o) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: o.value, children: o.label }, o.value))
|
|
69816
|
+
]
|
|
69817
|
+
}
|
|
69818
|
+
)
|
|
69819
|
+
] }, f.key);
|
|
69820
|
+
if (f.type === "date" || f.type === "date-time") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
69821
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
69822
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69823
|
+
"input",
|
|
69824
|
+
{
|
|
69825
|
+
type: f.type === "date-time" ? "datetime-local" : "date",
|
|
69826
|
+
value: value ?? "",
|
|
69827
|
+
onChange: (e) => handleFilterChange(f.key, e.target.value),
|
|
69828
|
+
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"
|
|
69829
|
+
}
|
|
69830
|
+
)
|
|
69831
|
+
] }, f.key);
|
|
69832
|
+
if (f.type === "date-range") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
69833
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
69834
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
69835
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69836
|
+
"input",
|
|
69837
|
+
{
|
|
69838
|
+
type: "date",
|
|
69839
|
+
value: value?.from ?? "",
|
|
69840
|
+
onChange: (e) => handleFilterChange(f.key, { ...value, from: e.target.value }),
|
|
69841
|
+
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"
|
|
69842
|
+
}
|
|
69843
|
+
),
|
|
69844
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs text-muted-foreground", children: "\u2013" }),
|
|
69845
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69846
|
+
"input",
|
|
69847
|
+
{
|
|
69848
|
+
type: "date",
|
|
69849
|
+
value: value?.to ?? "",
|
|
69850
|
+
onChange: (e) => handleFilterChange(f.key, { ...value, to: e.target.value }),
|
|
69851
|
+
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"
|
|
69852
|
+
}
|
|
69853
|
+
)
|
|
69854
|
+
] })
|
|
69855
|
+
] }, f.key);
|
|
69856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
69857
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }),
|
|
69858
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69859
|
+
"input",
|
|
69860
|
+
{
|
|
69861
|
+
type: "text",
|
|
69862
|
+
value: value ?? "",
|
|
69863
|
+
placeholder: f.placeholder ?? `Filter ${label}\u2026`,
|
|
69864
|
+
onChange: (e) => handleFilterChange(f.key, e.target.value),
|
|
69865
|
+
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"
|
|
69866
|
+
}
|
|
69867
|
+
)
|
|
69868
|
+
] }, f.key);
|
|
69869
|
+
}),
|
|
69870
|
+
sortKeys?.length ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
69871
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: "Sort by" }),
|
|
69872
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
69873
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
69874
|
+
"select",
|
|
69875
|
+
{
|
|
69876
|
+
value: sortKey,
|
|
69877
|
+
onChange: (e) => {
|
|
69878
|
+
setSortKey(e.target.value);
|
|
69879
|
+
setCurrentPage(1);
|
|
69880
|
+
setTick((t) => t + 1);
|
|
69881
|
+
},
|
|
69882
|
+
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",
|
|
69883
|
+
children: [
|
|
69884
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: "", children: "Default" }),
|
|
69885
|
+
sortKeys.map((k) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: k, children: k.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()) }, k))
|
|
69886
|
+
]
|
|
69887
|
+
}
|
|
69888
|
+
),
|
|
69889
|
+
sortKey && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69890
|
+
"button",
|
|
69891
|
+
{
|
|
69892
|
+
type: "button",
|
|
69893
|
+
onClick: () => {
|
|
69894
|
+
setSortDir((d) => d === "asc" ? "desc" : "asc");
|
|
69895
|
+
setTick((t) => t + 1);
|
|
69896
|
+
},
|
|
69897
|
+
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",
|
|
69898
|
+
title: sortDir === "asc" ? "Ascending" : "Descending",
|
|
69899
|
+
children: sortDir === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronDown, { className: "h-3.5 w-3.5" })
|
|
69900
|
+
}
|
|
69901
|
+
)
|
|
69902
|
+
] })
|
|
69903
|
+
] }) : null,
|
|
69904
|
+
hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
69905
|
+
"button",
|
|
69906
|
+
{
|
|
69907
|
+
type: "button",
|
|
69908
|
+
onClick: handleClearFilters,
|
|
69909
|
+
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",
|
|
69910
|
+
children: [
|
|
69911
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(X, { className: "h-3 w-3" }),
|
|
69912
|
+
" Clear"
|
|
69913
|
+
]
|
|
69914
|
+
}
|
|
69915
|
+
)
|
|
69916
|
+
] }) : null;
|
|
69644
69917
|
return {
|
|
69645
69918
|
data,
|
|
69646
69919
|
columns,
|
|
@@ -69649,11 +69922,18 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69649
69922
|
serverPagination: pagination ? { pagination, currentPage, goToPage: (page) => setCurrentPage(page) } : null,
|
|
69650
69923
|
loading,
|
|
69651
69924
|
error,
|
|
69925
|
+
filterBar,
|
|
69652
69926
|
goToPage: (page) => setCurrentPage(page),
|
|
69653
69927
|
reload: () => setTick((t) => t + 1),
|
|
69654
69928
|
refresh: () => setTick((t) => t + 1),
|
|
69929
|
+
// Passthrough props
|
|
69655
69930
|
searchValue,
|
|
69656
|
-
onSearchChange: handleSearchChange
|
|
69931
|
+
onSearchChange: handleSearchChange,
|
|
69932
|
+
page: currentPage,
|
|
69933
|
+
onPageChange: (page) => setCurrentPage(page),
|
|
69934
|
+
sort: [],
|
|
69935
|
+
onSortChange: () => {
|
|
69936
|
+
}
|
|
69657
69937
|
};
|
|
69658
69938
|
}
|
|
69659
69939
|
var MODAL_WIDTH = {
|
|
@@ -69711,6 +69991,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69711
69991
|
return null;
|
|
69712
69992
|
}
|
|
69713
69993
|
function FieldRenderer({ field, value, onChange }) {
|
|
69994
|
+
if (field.component) return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: field.component });
|
|
69714
69995
|
if (field.render) return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: field.render(value, onChange) });
|
|
69715
69996
|
const toLabelValue = (o) => {
|
|
69716
69997
|
if (typeof o === "string") return { label: o, value: o };
|
|
@@ -69803,9 +70084,33 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69803
70084
|
case "rich-text":
|
|
69804
70085
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(RichTextEditor, { value: value ?? "", onChange: (v) => onChange(v) });
|
|
69805
70086
|
case "file-upload":
|
|
69806
|
-
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FileUpload, {
|
|
70087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FileUpload, { onFileSelect: (file) => onChange(file), onFilesChange: (files) => {
|
|
70088
|
+
if (files.length > 1) onChange(files);
|
|
70089
|
+
} });
|
|
69807
70090
|
case "repeater": {
|
|
69808
70091
|
const items = Array.isArray(value) ? value : [];
|
|
70092
|
+
if (field.repeaterFields) {
|
|
70093
|
+
const rows = Array.isArray(value) ? value : [];
|
|
70094
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70095
|
+
Repeater,
|
|
70096
|
+
{
|
|
70097
|
+
items: rows,
|
|
70098
|
+
fields: field.repeaterFields,
|
|
70099
|
+
onAdd: () => {
|
|
70100
|
+
const blank = {};
|
|
70101
|
+
field.repeaterFields.forEach((f) => {
|
|
70102
|
+
blank[f.key] = "";
|
|
70103
|
+
});
|
|
70104
|
+
onChange([...rows, blank]);
|
|
70105
|
+
},
|
|
70106
|
+
onRemove: (i) => onChange(rows.filter((_, idx) => idx !== i)),
|
|
70107
|
+
onFieldChange: (i, key, val) => {
|
|
70108
|
+
const next = rows.map((r2, idx) => idx === i ? { ...r2, [key]: val } : r2);
|
|
70109
|
+
onChange(next);
|
|
70110
|
+
}
|
|
70111
|
+
}
|
|
70112
|
+
);
|
|
70113
|
+
}
|
|
69809
70114
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69810
70115
|
Repeater,
|
|
69811
70116
|
{
|
|
@@ -69846,8 +70151,172 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69846
70151
|
item,
|
|
69847
70152
|
fields,
|
|
69848
70153
|
onClose,
|
|
69849
|
-
width
|
|
70154
|
+
width,
|
|
70155
|
+
grid
|
|
69850
70156
|
}) {
|
|
70157
|
+
const renderViewValue = (f, value) => {
|
|
70158
|
+
const sizeStyle = {
|
|
70159
|
+
...f.width ? { width: typeof f.width === "number" ? `${f.width}px` : f.width } : {},
|
|
70160
|
+
...f.height ? { height: typeof f.height === "number" ? `${f.height}px` : f.height } : {}
|
|
70161
|
+
};
|
|
70162
|
+
const vt = f.viewType ?? f.type;
|
|
70163
|
+
const empty = value === null || value === void 0 || value === "";
|
|
70164
|
+
const dash = /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground italic text-sm", children: "\u2014" });
|
|
70165
|
+
if (f.component) return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: f.component });
|
|
70166
|
+
if (f.render) return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: f.render(value, () => {
|
|
70167
|
+
}) });
|
|
70168
|
+
switch (vt) {
|
|
70169
|
+
case "image":
|
|
70170
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70171
|
+
"img",
|
|
70172
|
+
{
|
|
70173
|
+
src: value,
|
|
70174
|
+
alt: f.label,
|
|
70175
|
+
className: "rounded-xl object-cover ring-1 ring-border",
|
|
70176
|
+
style: { width: sizeStyle.width ?? 128, height: sizeStyle.height ?? 128 }
|
|
70177
|
+
}
|
|
70178
|
+
);
|
|
70179
|
+
case "image-url":
|
|
70180
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70181
|
+
"a",
|
|
70182
|
+
{
|
|
70183
|
+
href: value,
|
|
70184
|
+
onClick: (e) => e.preventDefault(),
|
|
70185
|
+
className: "inline-block rounded-xl overflow-hidden ring-1 ring-border hover:ring-primary transition-all",
|
|
70186
|
+
style: { width: sizeStyle.width ?? 128, height: sizeStyle.height ?? 128 },
|
|
70187
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { src: value, alt: f.label, className: "w-full h-full object-cover" })
|
|
70188
|
+
}
|
|
70189
|
+
);
|
|
70190
|
+
case "image-url-open-other-tabs":
|
|
70191
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70192
|
+
"a",
|
|
70193
|
+
{
|
|
70194
|
+
href: value,
|
|
70195
|
+
target: "_blank",
|
|
70196
|
+
rel: "noopener noreferrer",
|
|
70197
|
+
className: "inline-block rounded-xl overflow-hidden ring-1 ring-border hover:ring-primary transition-all",
|
|
70198
|
+
style: { width: sizeStyle.width ?? 128, height: sizeStyle.height ?? 128 },
|
|
70199
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { src: value, alt: f.label, className: "w-full h-full object-cover" })
|
|
70200
|
+
}
|
|
70201
|
+
);
|
|
70202
|
+
case "text-url":
|
|
70203
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70204
|
+
"a",
|
|
70205
|
+
{
|
|
70206
|
+
href: value,
|
|
70207
|
+
onClick: (e) => e.preventDefault(),
|
|
70208
|
+
className: "text-sm text-primary underline underline-offset-2 hover:text-primary/80 break-all",
|
|
70209
|
+
style: sizeStyle,
|
|
70210
|
+
children: value
|
|
70211
|
+
}
|
|
70212
|
+
);
|
|
70213
|
+
case "text-url-open-other-tabs":
|
|
70214
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70215
|
+
"a",
|
|
70216
|
+
{
|
|
70217
|
+
href: value,
|
|
70218
|
+
target: "_blank",
|
|
70219
|
+
rel: "noopener noreferrer",
|
|
70220
|
+
className: "text-sm text-primary underline underline-offset-2 hover:text-primary/80 break-all",
|
|
70221
|
+
style: sizeStyle,
|
|
70222
|
+
children: value
|
|
70223
|
+
}
|
|
70224
|
+
);
|
|
70225
|
+
case "attachment":
|
|
70226
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70227
|
+
"a",
|
|
70228
|
+
{
|
|
70229
|
+
href: value,
|
|
70230
|
+
target: "_blank",
|
|
70231
|
+
rel: "noopener noreferrer",
|
|
70232
|
+
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",
|
|
70233
|
+
style: sizeStyle,
|
|
70234
|
+
children: [
|
|
70235
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("svg", { className: "h-3.5 w-3.5 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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" }) }),
|
|
70236
|
+
String(value).split("/").pop() ?? "Download"
|
|
70237
|
+
]
|
|
70238
|
+
}
|
|
70239
|
+
);
|
|
70240
|
+
case "repeater": {
|
|
70241
|
+
const rows = Array.isArray(value) ? value : [];
|
|
70242
|
+
if (!rows.length) return dash;
|
|
70243
|
+
const rFields = f.repeaterFields;
|
|
70244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "space-y-2", children: rows.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-wrap gap-3 rounded-xl border border-border bg-muted/30 px-3 py-2", children: [
|
|
70245
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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 }),
|
|
70246
|
+
rFields ? rFields.map((rf) => {
|
|
70247
|
+
const v = row[rf.key];
|
|
70248
|
+
if (rf.type === "image") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
70249
|
+
rf.label && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] text-muted-foreground", children: rf.label }),
|
|
70250
|
+
v ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("img", { src: v, alt: rf.key, className: "h-10 w-10 rounded-lg object-cover ring-1 ring-border" }) : dash
|
|
70251
|
+
] }, rf.key);
|
|
70252
|
+
if (rf.type === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
70253
|
+
rf.label && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] text-muted-foreground", children: rf.label }),
|
|
70254
|
+
v ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70255
|
+
"a",
|
|
70256
|
+
{
|
|
70257
|
+
href: v,
|
|
70258
|
+
target: "_blank",
|
|
70259
|
+
rel: "noopener noreferrer",
|
|
70260
|
+
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",
|
|
70261
|
+
children: [
|
|
70262
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("svg", { className: "h-3 w-3 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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" }) }),
|
|
70263
|
+
String(v).split("/").pop()
|
|
70264
|
+
]
|
|
70265
|
+
}
|
|
70266
|
+
) : dash
|
|
70267
|
+
] }, rf.key);
|
|
70268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
70269
|
+
rf.label && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] text-muted-foreground", children: rf.label }),
|
|
70270
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-sm", children: v ?? "\u2014" })
|
|
70271
|
+
] }, rf.key);
|
|
70272
|
+
}) : (
|
|
70273
|
+
// payload mode: row has { type, key, value }
|
|
70274
|
+
Object.entries(row).map(([k, v]) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
70275
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-[10px] text-muted-foreground", children: k }),
|
|
70276
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-sm", children: String(v) })
|
|
70277
|
+
] }, k))
|
|
70278
|
+
)
|
|
70279
|
+
] }, ri)) });
|
|
70280
|
+
}
|
|
70281
|
+
case "checkbox":
|
|
70282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70283
|
+
"input",
|
|
70284
|
+
{
|
|
70285
|
+
type: "checkbox",
|
|
70286
|
+
checked: !!value,
|
|
70287
|
+
readOnly: true,
|
|
70288
|
+
className: "h-4 w-4 rounded border-border accent-primary cursor-default",
|
|
70289
|
+
style: sizeStyle
|
|
70290
|
+
}
|
|
70291
|
+
);
|
|
70292
|
+
case "toggle":
|
|
70293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70294
|
+
"div",
|
|
70295
|
+
{
|
|
70296
|
+
className: cn(
|
|
70297
|
+
"relative inline-flex shrink-0 rounded-full border-2 border-transparent transition-colors",
|
|
70298
|
+
value ? "bg-primary" : "bg-muted"
|
|
70299
|
+
),
|
|
70300
|
+
style: { width: sizeStyle.width ?? 36, height: sizeStyle.height ?? 20 },
|
|
70301
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70302
|
+
"span",
|
|
70303
|
+
{
|
|
70304
|
+
className: cn(
|
|
70305
|
+
"pointer-events-none inline-block rounded-full bg-white shadow-sm transition-transform"
|
|
70306
|
+
),
|
|
70307
|
+
style: {
|
|
70308
|
+
width: typeof (sizeStyle.height ?? 20) === "number" ? sizeStyle.height - 4 : 16,
|
|
70309
|
+
height: typeof (sizeStyle.height ?? 20) === "number" ? sizeStyle.height - 4 : 16,
|
|
70310
|
+
transform: value ? `translateX(${typeof (sizeStyle.width ?? 36) === "number" ? sizeStyle.width - (sizeStyle.height ?? 20) : 16}px)` : "translateX(0)"
|
|
70311
|
+
}
|
|
70312
|
+
}
|
|
70313
|
+
)
|
|
70314
|
+
}
|
|
70315
|
+
);
|
|
70316
|
+
default:
|
|
70317
|
+
return empty ? dash : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-sm text-foreground break-words", style: sizeStyle, children: String(value) });
|
|
70318
|
+
}
|
|
70319
|
+
};
|
|
69851
70320
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69852
70321
|
ModalShell,
|
|
69853
70322
|
{
|
|
@@ -69855,11 +70324,27 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69855
70324
|
onClose,
|
|
69856
70325
|
width,
|
|
69857
70326
|
footer: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Button, { variant: "outline", size: "sm", onClick: onClose, children: "Close" }),
|
|
69858
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69859
|
-
|
|
69860
|
-
|
|
69861
|
-
|
|
69862
|
-
|
|
70327
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70328
|
+
"div",
|
|
70329
|
+
{
|
|
70330
|
+
className: grid ? "grid gap-4" : "space-y-3",
|
|
70331
|
+
style: grid ? { gridTemplateColumns: `repeat(${grid}, minmax(0, 1fr))` } : void 0,
|
|
70332
|
+
children: fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70333
|
+
"div",
|
|
70334
|
+
{
|
|
70335
|
+
style: {
|
|
70336
|
+
...f.colSpan ? { gridColumn: `span ${f.colSpan}` } : {},
|
|
70337
|
+
...f.rowSpan ? { gridRow: `span ${f.rowSpan}` } : {}
|
|
70338
|
+
},
|
|
70339
|
+
children: [
|
|
70340
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-xs font-semibold text-muted-foreground mb-1", children: f.label }),
|
|
70341
|
+
renderViewValue(f, item[f.key])
|
|
70342
|
+
]
|
|
70343
|
+
},
|
|
70344
|
+
f.key
|
|
70345
|
+
))
|
|
70346
|
+
}
|
|
70347
|
+
)
|
|
69863
70348
|
}
|
|
69864
70349
|
);
|
|
69865
70350
|
}
|
|
@@ -69877,7 +70362,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69877
70362
|
const [form, setForm] = React28.useState(() => {
|
|
69878
70363
|
const init = {};
|
|
69879
70364
|
fields.forEach((f) => {
|
|
69880
|
-
init[f.key] = item[f.key] ?? "";
|
|
70365
|
+
init[f.key] = f.type === "file-upload" ? null : item[f.key] ?? "";
|
|
69881
70366
|
});
|
|
69882
70367
|
return init;
|
|
69883
70368
|
});
|
|
@@ -69889,6 +70374,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69889
70374
|
e.preventDefault();
|
|
69890
70375
|
const errs = {};
|
|
69891
70376
|
fields.forEach((f) => {
|
|
70377
|
+
if (f.type === "file-upload" && !form[f.key] && item[f.key]) return;
|
|
69892
70378
|
const msg = validateField(f, form[f.key]);
|
|
69893
70379
|
if (msg) errs[f.key] = msg;
|
|
69894
70380
|
});
|
|
@@ -69900,7 +70386,30 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69900
70386
|
setLoading(true);
|
|
69901
70387
|
setError(null);
|
|
69902
70388
|
try {
|
|
69903
|
-
|
|
70389
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
70390
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
70391
|
+
const isFile2 = (v) => v instanceof File;
|
|
70392
|
+
const isFileArray = (v) => Array.isArray(v) && v.length > 0 && v[0] instanceof File;
|
|
70393
|
+
const hasFiles = Object.values(form).some((v) => isFile2(v) || isFileArray(v));
|
|
70394
|
+
let body;
|
|
70395
|
+
if (hasFiles) {
|
|
70396
|
+
const fd = new FormData();
|
|
70397
|
+
fd.append("_method", "PUT");
|
|
70398
|
+
Object.entries(form).forEach(([k, v]) => {
|
|
70399
|
+
if (isFileArray(v)) {
|
|
70400
|
+
v.forEach((f) => fd.append(k, f));
|
|
70401
|
+
} else if (isFile2(v)) {
|
|
70402
|
+
fd.append(k, v);
|
|
70403
|
+
} else if (v === null || v === void 0) {
|
|
70404
|
+
} else if (!Array.isArray(v)) {
|
|
70405
|
+
fd.append(k, String(v));
|
|
70406
|
+
}
|
|
70407
|
+
});
|
|
70408
|
+
body = fd;
|
|
70409
|
+
} else {
|
|
70410
|
+
body = form;
|
|
70411
|
+
}
|
|
70412
|
+
await axios_default.put(`${baseUrl}/${itemId}/update`, body, { headers: { "X-CSRF-Token": csrfToken } });
|
|
69904
70413
|
const updated = { ...item, ...form };
|
|
69905
70414
|
if (notif && (notif.type ?? "toast") === "notification") {
|
|
69906
70415
|
setBanner(true);
|
|
@@ -69941,14 +70450,14 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69941
70450
|
),
|
|
69942
70451
|
notif.action && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { children: notif.action })
|
|
69943
70452
|
] }),
|
|
69944
|
-
fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime32.
|
|
70453
|
+
fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
69945
70454
|
"div",
|
|
69946
70455
|
{
|
|
69947
70456
|
style: {
|
|
69948
70457
|
...f.colSpan ? { gridColumn: `span ${f.colSpan}` } : {},
|
|
69949
70458
|
...f.rowSpan ? { gridRow: `span ${f.rowSpan}` } : {}
|
|
69950
70459
|
},
|
|
69951
|
-
children: [
|
|
70460
|
+
children: f.component ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_jsx_runtime32.Fragment, { children: f.component }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
69952
70461
|
f.type !== "checkbox" && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "block text-xs font-semibold text-muted-foreground mb-1", children: [
|
|
69953
70462
|
f.label,
|
|
69954
70463
|
f.required && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-danger ml-0.5", children: "*" })
|
|
@@ -69968,7 +70477,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69968
70477
|
}
|
|
69969
70478
|
),
|
|
69970
70479
|
fieldErrors[f.key] && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-xs text-danger mt-1", children: fieldErrors[f.key] })
|
|
69971
|
-
]
|
|
70480
|
+
] })
|
|
69972
70481
|
},
|
|
69973
70482
|
f.key
|
|
69974
70483
|
)),
|
|
@@ -69991,7 +70500,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
69991
70500
|
setLoading(true);
|
|
69992
70501
|
setError(null);
|
|
69993
70502
|
try {
|
|
69994
|
-
|
|
70503
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
70504
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
70505
|
+
await axios_default.delete(`${baseUrl}/${itemId}/delete?csrfToken=${encodeURIComponent(csrfToken)}`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
69995
70506
|
onSuccess?.(item);
|
|
69996
70507
|
onClose();
|
|
69997
70508
|
} catch (err) {
|
|
@@ -70066,26 +70577,89 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70066
70577
|
function badgeClass(value) {
|
|
70067
70578
|
return BADGE_COLORS[value.toLowerCase()] ?? "bg-primary/10 text-primary border-primary/20";
|
|
70068
70579
|
}
|
|
70580
|
+
function deriveField(key, sample) {
|
|
70581
|
+
const label = key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
70582
|
+
const base = { key, label };
|
|
70583
|
+
if (typeof sample === "boolean") return { ...base, type: "toggle", viewType: "toggle" };
|
|
70584
|
+
if (typeof sample === "number") return { ...base, inputType: "number" };
|
|
70585
|
+
if (Array.isArray(sample)) {
|
|
70586
|
+
if (sample.length === 0 || typeof sample[0] === "string")
|
|
70587
|
+
return { ...base, type: "tag-input" };
|
|
70588
|
+
return base;
|
|
70589
|
+
}
|
|
70590
|
+
if (typeof sample === "string") {
|
|
70591
|
+
if (/\.(png|jpe?g|gif|webp|svg|avif)(\?.*)?$/i.test(sample))
|
|
70592
|
+
return { ...base, type: "input", viewType: "image" };
|
|
70593
|
+
if (/\.(pdf|docx?|xlsx?|csv|zip|pptx?)(\?.*)?$/i.test(sample))
|
|
70594
|
+
return { ...base, type: "input", viewType: "attachment" };
|
|
70595
|
+
if (/^https?:\/\//.test(sample))
|
|
70596
|
+
return { ...base, type: "input", viewType: "text-url-open-other-tabs" };
|
|
70597
|
+
if (sample.length > 120 || /\n/.test(sample))
|
|
70598
|
+
return { ...base, type: "textarea" };
|
|
70599
|
+
if (/password|secret|token/i.test(key))
|
|
70600
|
+
return { ...base, type: "password" };
|
|
70601
|
+
if (/email/i.test(key))
|
|
70602
|
+
return { ...base, inputType: "email" };
|
|
70603
|
+
if (/color|colour/i.test(key) && /^#[0-9a-f]{3,8}$/i.test(sample))
|
|
70604
|
+
return { ...base, type: "color-picker", viewType: "text" };
|
|
70605
|
+
}
|
|
70606
|
+
return base;
|
|
70607
|
+
}
|
|
70069
70608
|
function Table({
|
|
70070
70609
|
data,
|
|
70071
70610
|
columns,
|
|
70611
|
+
loading,
|
|
70612
|
+
emptyState,
|
|
70613
|
+
error: errorProp,
|
|
70072
70614
|
searchable = false,
|
|
70073
70615
|
searchPlaceholder = "Search...",
|
|
70074
|
-
|
|
70616
|
+
searchValue: controlledSearch,
|
|
70617
|
+
onSearchChange,
|
|
70618
|
+
clientPagination = false,
|
|
70075
70619
|
itemsPerPage = 10,
|
|
70076
70620
|
selectable = false,
|
|
70077
70621
|
onBulkDelete,
|
|
70078
70622
|
idKey = "id",
|
|
70623
|
+
bulkDeleteBaseUrl,
|
|
70079
70624
|
defaultActions,
|
|
70080
70625
|
serverPagination,
|
|
70081
|
-
|
|
70626
|
+
variant = "default",
|
|
70627
|
+
className,
|
|
70628
|
+
onRowClick,
|
|
70629
|
+
onRowDoubleClick,
|
|
70630
|
+
rowClassName,
|
|
70631
|
+
expandable = false,
|
|
70632
|
+
renderExpanded,
|
|
70633
|
+
columnVisibility,
|
|
70634
|
+
onColumnVisibilityChange,
|
|
70635
|
+
columnVisibilityIcon,
|
|
70636
|
+
filterBar,
|
|
70637
|
+
filterableIcon,
|
|
70638
|
+
exportable = false,
|
|
70639
|
+
onExport,
|
|
70640
|
+
virtualized = false,
|
|
70641
|
+
draggable = false,
|
|
70642
|
+
onRowReorder,
|
|
70643
|
+
keyboardNavigation = false
|
|
70082
70644
|
}) {
|
|
70083
70645
|
const { toast } = useToast();
|
|
70084
|
-
const
|
|
70646
|
+
const isControlledSearch = controlledSearch !== void 0;
|
|
70647
|
+
const [internalSearch, setInternalSearch] = React28.useState("");
|
|
70648
|
+
const search = isControlledSearch ? controlledSearch : internalSearch;
|
|
70649
|
+
const setSearch = (v) => {
|
|
70650
|
+
if (!isControlledSearch) setInternalSearch(v);
|
|
70651
|
+
onSearchChange?.(v);
|
|
70652
|
+
};
|
|
70085
70653
|
const [currentPage, setCurrentPage] = React28.useState(1);
|
|
70086
70654
|
const [selectedIds, setSelectedIds] = React28.useState([]);
|
|
70087
70655
|
const [sortKey, setSortKey] = React28.useState(null);
|
|
70088
70656
|
const [sortDir, setSortDir] = React28.useState(null);
|
|
70657
|
+
const [bulkLoading, setBulkLoading] = React28.useState(false);
|
|
70658
|
+
const [bulkConfirm, setBulkConfirm] = React28.useState(null);
|
|
70659
|
+
const [filterBarOpen, setFilterBarOpen] = React28.useState(false);
|
|
70660
|
+
const [expandedIds, setExpandedIds] = React28.useState(/* @__PURE__ */ new Set());
|
|
70661
|
+
const [dragOverId, setDragOverId] = React28.useState(null);
|
|
70662
|
+
const [focusedRowIdx, setFocusedRowIdx] = React28.useState(-1);
|
|
70089
70663
|
const [viewItem, setViewItem] = React28.useState(null);
|
|
70090
70664
|
const [editItem, setEditItem] = React28.useState(null);
|
|
70091
70665
|
const [deleteItem, setDeleteItem] = React28.useState(null);
|
|
@@ -70097,15 +70671,17 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70097
70671
|
const safeBaseUrl = defaultActions?.baseUrl.replace(/\/+$/, "") ?? "";
|
|
70098
70672
|
const autoFields = React28.useMemo(() => {
|
|
70099
70673
|
if (!tableData.length) return [];
|
|
70100
|
-
|
|
70101
|
-
|
|
70102
|
-
label: k.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
|
|
70103
|
-
}));
|
|
70674
|
+
const row = tableData[0];
|
|
70675
|
+
return Object.keys(row).map((k) => deriveField(k, row[k]));
|
|
70104
70676
|
}, [tableData]);
|
|
70105
70677
|
const editFields = defaultActions?.editForm ?? autoFields;
|
|
70106
70678
|
const viewFields = defaultActions?.viewForm ?? autoFields;
|
|
70679
|
+
const visibleColumns = React28.useMemo(() => {
|
|
70680
|
+
if (!columnVisibility) return columns;
|
|
70681
|
+
return columns.filter((col) => columnVisibility[String(col.key)] !== false);
|
|
70682
|
+
}, [columns, columnVisibility]);
|
|
70107
70683
|
const allColumns = React28.useMemo(() => {
|
|
70108
|
-
if (!defaultActions) return
|
|
70684
|
+
if (!defaultActions) return visibleColumns;
|
|
70109
70685
|
const actionsCol = {
|
|
70110
70686
|
key: "__actions__",
|
|
70111
70687
|
title: "Actions",
|
|
@@ -70154,8 +70730,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70154
70730
|
))
|
|
70155
70731
|
] })
|
|
70156
70732
|
};
|
|
70157
|
-
return defaultActions.position === "first" ? [actionsCol, ...
|
|
70158
|
-
}, [
|
|
70733
|
+
return defaultActions.position === "first" ? [actionsCol, ...visibleColumns] : [...visibleColumns, actionsCol];
|
|
70734
|
+
}, [visibleColumns, defaultActions]);
|
|
70159
70735
|
const handleSort = (key) => {
|
|
70160
70736
|
if (sortKey !== key) {
|
|
70161
70737
|
setSortKey(key);
|
|
@@ -70188,16 +70764,78 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70188
70764
|
const totalPages = Math.max(1, Math.ceil(filteredData.length / itemsPerPage));
|
|
70189
70765
|
const safePage = Math.min(currentPage, totalPages);
|
|
70190
70766
|
const paginatedData = React28.useMemo(() => {
|
|
70191
|
-
if (!
|
|
70767
|
+
if (!clientPagination) return filteredData;
|
|
70192
70768
|
const start = (safePage - 1) * itemsPerPage;
|
|
70193
70769
|
return filteredData.slice(start, start + itemsPerPage);
|
|
70194
|
-
}, [filteredData,
|
|
70770
|
+
}, [filteredData, clientPagination, safePage, itemsPerPage]);
|
|
70195
70771
|
React28.useEffect(() => {
|
|
70196
70772
|
setCurrentPage(1);
|
|
70197
70773
|
}, [search]);
|
|
70774
|
+
React28.useEffect(() => {
|
|
70775
|
+
if (!keyboardNavigation) return;
|
|
70776
|
+
const handler = (e) => {
|
|
70777
|
+
if (e.key === "ArrowDown") {
|
|
70778
|
+
e.preventDefault();
|
|
70779
|
+
setFocusedRowIdx((i) => Math.min(i + 1, paginatedData.length - 1));
|
|
70780
|
+
}
|
|
70781
|
+
if (e.key === "ArrowUp") {
|
|
70782
|
+
e.preventDefault();
|
|
70783
|
+
setFocusedRowIdx((i) => Math.max(i - 1, 0));
|
|
70784
|
+
}
|
|
70785
|
+
};
|
|
70786
|
+
window.addEventListener("keydown", handler);
|
|
70787
|
+
return () => window.removeEventListener("keydown", handler);
|
|
70788
|
+
}, [keyboardNavigation, paginatedData.length]);
|
|
70198
70789
|
const handleSelectAll = (checked) => setSelectedIds(checked ? paginatedData.map((item) => String(item[idKey])) : []);
|
|
70199
70790
|
const handleSelect = (id, checked) => setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((i) => i !== id));
|
|
70200
70791
|
const allSelected = paginatedData.length > 0 && selectedIds.length === paginatedData.length;
|
|
70792
|
+
const totalRows = serverPagination ? serverPagination.pagination.total : filteredData.length;
|
|
70793
|
+
const unselectedCount = totalRows - selectedIds.length;
|
|
70794
|
+
const handleSelectAllRecords = () => setSelectedIds(filteredData.map((item) => String(item[idKey])));
|
|
70795
|
+
const handleUnselectAll = () => setSelectedIds([]);
|
|
70796
|
+
const execBulkDeleteSelected = async () => {
|
|
70797
|
+
if (!bulkDeleteBaseUrl || selectedIds.length === 0) {
|
|
70798
|
+
onBulkDelete?.(selectedIds);
|
|
70799
|
+
setSelectedIds([]);
|
|
70800
|
+
return;
|
|
70801
|
+
}
|
|
70802
|
+
setBulkLoading(true);
|
|
70803
|
+
try {
|
|
70804
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
70805
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
70806
|
+
const safeUrl = bulkDeleteBaseUrl.replace(/\/+$/, "");
|
|
70807
|
+
await axios_default.delete(`${safeUrl}/delete/${selectedIds.join(",")}/selected`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
70808
|
+
setTableData((prev) => prev.filter((r2) => !selectedIds.includes(String(r2[idKey]))));
|
|
70809
|
+
onBulkDelete?.(selectedIds);
|
|
70810
|
+
setSelectedIds([]);
|
|
70811
|
+
defaultActions?.onReload?.();
|
|
70812
|
+
toast({ variant: "success", title: "Deleted", description: `${selectedIds.length} record${selectedIds.length !== 1 ? "s" : ""} deleted successfully.` });
|
|
70813
|
+
} catch (err) {
|
|
70814
|
+
const msg = err?.response?.data?.message ?? err.message ?? "Bulk delete failed";
|
|
70815
|
+
toast({ variant: "error", title: "Delete failed", description: msg });
|
|
70816
|
+
} finally {
|
|
70817
|
+
setBulkLoading(false);
|
|
70818
|
+
}
|
|
70819
|
+
};
|
|
70820
|
+
const execDeleteAll = async () => {
|
|
70821
|
+
if (!bulkDeleteBaseUrl) return;
|
|
70822
|
+
setBulkLoading(true);
|
|
70823
|
+
try {
|
|
70824
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
|
|
70825
|
+
if (!csrfToken) throw new Error("[Table] CSRF token not found.");
|
|
70826
|
+
const safeUrl = bulkDeleteBaseUrl.replace(/\/+$/, "");
|
|
70827
|
+
await axios_default.delete(`${safeUrl}/delete/all`, { headers: { "X-CSRF-Token": csrfToken } });
|
|
70828
|
+
setTableData([]);
|
|
70829
|
+
setSelectedIds([]);
|
|
70830
|
+
defaultActions?.onReload?.();
|
|
70831
|
+
toast({ variant: "success", title: "Deleted", description: "All records deleted successfully." });
|
|
70832
|
+
} catch (err) {
|
|
70833
|
+
const msg = err?.response?.data?.message ?? err.message ?? "Delete all failed";
|
|
70834
|
+
toast({ variant: "error", title: "Delete failed", description: msg });
|
|
70835
|
+
} finally {
|
|
70836
|
+
setBulkLoading(false);
|
|
70837
|
+
}
|
|
70838
|
+
};
|
|
70201
70839
|
const pagePills = React28.useMemo(() => {
|
|
70202
70840
|
if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
70203
70841
|
if (safePage <= 3) return [1, 2, 3, 4, 5];
|
|
@@ -70211,6 +70849,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70211
70849
|
};
|
|
70212
70850
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
70213
70851
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cn("w-full space-y-3", className), children: [
|
|
70852
|
+
errorProp && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "rounded-xl border border-danger/30 bg-danger/5 px-4 py-3 text-sm text-danger", children: errorProp }),
|
|
70214
70853
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between gap-3 flex-wrap", children: [
|
|
70215
70854
|
searchable && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative w-72", children: [
|
|
70216
70855
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Search, { className: "absolute text-primary left-3 top-1/2 -translate-y-1/2 h-4 w-4 z-10" }),
|
|
@@ -70232,33 +70871,127 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70232
70871
|
}
|
|
70233
70872
|
)
|
|
70234
70873
|
] }),
|
|
70235
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2 ml-auto", children: [
|
|
70236
|
-
selectable &&
|
|
70874
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2 ml-auto flex-wrap", children: [
|
|
70875
|
+
selectable && selectedIds.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
70876
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70877
|
+
"button",
|
|
70878
|
+
{
|
|
70879
|
+
onClick: handleUnselectAll,
|
|
70880
|
+
disabled: bulkLoading,
|
|
70881
|
+
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",
|
|
70882
|
+
children: [
|
|
70883
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(X, { className: "h-3.5 w-3.5" }),
|
|
70884
|
+
"Unselect all ",
|
|
70885
|
+
selectedIds.length
|
|
70886
|
+
]
|
|
70887
|
+
}
|
|
70888
|
+
),
|
|
70889
|
+
unselectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70890
|
+
"button",
|
|
70891
|
+
{
|
|
70892
|
+
onClick: handleSelectAllRecords,
|
|
70893
|
+
disabled: bulkLoading,
|
|
70894
|
+
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",
|
|
70895
|
+
children: [
|
|
70896
|
+
"Select all ",
|
|
70897
|
+
unselectedCount
|
|
70898
|
+
]
|
|
70899
|
+
}
|
|
70900
|
+
),
|
|
70901
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70902
|
+
"button",
|
|
70903
|
+
{
|
|
70904
|
+
onClick: () => setBulkConfirm("selected"),
|
|
70905
|
+
disabled: bulkLoading,
|
|
70906
|
+
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",
|
|
70907
|
+
children: [
|
|
70908
|
+
bulkLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Trash2, { className: "h-3.5 w-3.5" }),
|
|
70909
|
+
"Delete ",
|
|
70910
|
+
selectedIds.length,
|
|
70911
|
+
" selected"
|
|
70912
|
+
]
|
|
70913
|
+
}
|
|
70914
|
+
),
|
|
70915
|
+
bulkDeleteBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
70916
|
+
"button",
|
|
70917
|
+
{
|
|
70918
|
+
onClick: () => setBulkConfirm("all"),
|
|
70919
|
+
disabled: bulkLoading,
|
|
70920
|
+
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",
|
|
70921
|
+
children: [
|
|
70922
|
+
bulkLoading ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Trash2, { className: "h-3.5 w-3.5" }),
|
|
70923
|
+
"Delete all"
|
|
70924
|
+
]
|
|
70925
|
+
}
|
|
70926
|
+
)
|
|
70927
|
+
] }),
|
|
70928
|
+
filterBar && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70237
70929
|
"button",
|
|
70238
70930
|
{
|
|
70239
|
-
onClick: () =>
|
|
70240
|
-
|
|
70241
|
-
|
|
70242
|
-
|
|
70243
|
-
|
|
70244
|
-
children:
|
|
70245
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Trash2, { className: "h-3.5 w-3.5" }),
|
|
70246
|
-
"Delete ",
|
|
70247
|
-
selectedIds.length,
|
|
70248
|
-
" selected"
|
|
70249
|
-
]
|
|
70931
|
+
onClick: () => setFilterBarOpen((o) => !o),
|
|
70932
|
+
className: cn(
|
|
70933
|
+
"inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-xs font-medium transition-colors",
|
|
70934
|
+
filterBarOpen ? "border-primary bg-primary/10 text-primary hover:bg-primary/20" : "border-border bg-muted/50 text-muted-foreground hover:bg-muted"
|
|
70935
|
+
),
|
|
70936
|
+
children: filterableIcon ?? "Filter"
|
|
70250
70937
|
}
|
|
70251
70938
|
),
|
|
70939
|
+
exportable && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative group", children: [
|
|
70940
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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" }),
|
|
70941
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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__ */ (0, import_jsx_runtime32.jsx)(
|
|
70942
|
+
"button",
|
|
70943
|
+
{
|
|
70944
|
+
onClick: () => onExport?.(type),
|
|
70945
|
+
className: "px-4 py-2 text-xs text-left hover:bg-muted transition-colors capitalize",
|
|
70946
|
+
children: type.toUpperCase()
|
|
70947
|
+
},
|
|
70948
|
+
type
|
|
70949
|
+
)) })
|
|
70950
|
+
] }),
|
|
70951
|
+
columnVisibility && onColumnVisibilityChange && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative group", children: [
|
|
70952
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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" }),
|
|
70953
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "flex items-center gap-2 px-2 py-1 rounded-lg hover:bg-muted cursor-pointer text-xs", children: [
|
|
70954
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70955
|
+
"input",
|
|
70956
|
+
{
|
|
70957
|
+
type: "checkbox",
|
|
70958
|
+
checked: columnVisibility[String(col.key)] !== false,
|
|
70959
|
+
onChange: (e) => onColumnVisibilityChange({ ...columnVisibility, [String(col.key)]: e.target.checked }),
|
|
70960
|
+
className: "accent-primary"
|
|
70961
|
+
}
|
|
70962
|
+
),
|
|
70963
|
+
col.title
|
|
70964
|
+
] }, String(col.key))) })
|
|
70965
|
+
] }),
|
|
70252
70966
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
70253
|
-
|
|
70967
|
+
totalRows,
|
|
70254
70968
|
" ",
|
|
70255
|
-
|
|
70969
|
+
totalRows === 1 ? "row" : "rows",
|
|
70256
70970
|
search && ` \xB7 filtered from ${tableData.length}`
|
|
70257
70971
|
] })
|
|
70258
70972
|
] })
|
|
70259
70973
|
] }),
|
|
70260
|
-
|
|
70261
|
-
|
|
70974
|
+
filterBar && filterBarOpen && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { children: filterBar }),
|
|
70975
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-center py-12 text-muted-foreground gap-2", children: [
|
|
70976
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LoaderCircle, { className: "h-5 w-5 animate-spin" }),
|
|
70977
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-sm", children: "Loading\u2026" })
|
|
70978
|
+
] }),
|
|
70979
|
+
!loading && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn(
|
|
70980
|
+
variant === "default" && "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm",
|
|
70981
|
+
variant === "zebra" && "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm",
|
|
70982
|
+
variant === "card" && "space-y-2",
|
|
70983
|
+
variant === "glass" && "rounded-2xl overflow-hidden border border-white/10 bg-background/30 backdrop-blur-xl shadow-xl",
|
|
70984
|
+
variant === "soft" && "rounded-2xl overflow-hidden bg-card",
|
|
70985
|
+
variant === "soft" && "[box-shadow:6px_6px_12px_hsl(var(--foreground)/0.07),-6px_-6px_12px_hsl(var(--background)/0.8)]",
|
|
70986
|
+
virtualized && "max-h-[520px] overflow-y-auto"
|
|
70987
|
+
), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn("w-full overflow-auto", variant === "card" && "space-y-2"), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("table", { className: cn("w-full caption-bottom text-sm", variant === "card" && "border-separate border-spacing-y-2"), children: [
|
|
70988
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { className: cn(
|
|
70989
|
+
variant === "default" && "border-b border-border bg-muted/40",
|
|
70990
|
+
variant === "zebra" && "border-b border-border bg-muted/40",
|
|
70991
|
+
variant === "card" && "[&>th]:bg-transparent",
|
|
70992
|
+
variant === "glass" && "border-b border-white/10 bg-white/5",
|
|
70993
|
+
variant === "soft" && "border-b-0 bg-muted/30"
|
|
70994
|
+
), children: [
|
|
70262
70995
|
selectable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { className: "h-11 w-[46px] px-4 text-left align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70263
70996
|
Checkbox,
|
|
70264
70997
|
{
|
|
@@ -70266,13 +70999,16 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70266
70999
|
onChange: (e) => handleSelectAll(e.target.checked)
|
|
70267
71000
|
}
|
|
70268
71001
|
) }),
|
|
71002
|
+
expandable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { className: "h-11 w-8" }),
|
|
70269
71003
|
allColumns.map((col, ci) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70270
71004
|
"th",
|
|
70271
71005
|
{
|
|
70272
71006
|
onClick: () => col.sortable && handleSort(String(col.key)),
|
|
70273
71007
|
className: cn(
|
|
70274
71008
|
"h-11 px-4 text-left align-middle text-xs font-semibold uppercase tracking-wider text-muted-foreground select-none whitespace-nowrap",
|
|
70275
|
-
col.sortable && "cursor-pointer hover:text-foreground transition-colors"
|
|
71009
|
+
col.sortable && "cursor-pointer hover:text-foreground transition-colors",
|
|
71010
|
+
variant === "glass" && "text-foreground/70",
|
|
71011
|
+
variant === "soft" && "text-muted-foreground/80"
|
|
70276
71012
|
),
|
|
70277
71013
|
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "inline-flex items-center", children: [
|
|
70278
71014
|
col.title,
|
|
@@ -70285,9 +71021,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70285
71021
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tbody", { children: paginatedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70286
71022
|
"td",
|
|
70287
71023
|
{
|
|
70288
|
-
colSpan: allColumns.length + (selectable ? 1 : 0),
|
|
71024
|
+
colSpan: allColumns.length + (selectable ? 1 : 0) + (expandable ? 1 : 0),
|
|
70289
71025
|
className: "h-32 text-center align-middle",
|
|
70290
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
71026
|
+
children: emptyState ?? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
70291
71027
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Search, { className: "h-8 w-8 opacity-20" }),
|
|
70292
71028
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-sm", children: "No results found" }),
|
|
70293
71029
|
search && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { onClick: () => setSearch(""), className: "text-xs text-primary hover:underline", children: "Clear search" })
|
|
@@ -70296,85 +71032,168 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70296
71032
|
) }) : paginatedData.map((item, i) => {
|
|
70297
71033
|
const id = String(item[idKey] || i);
|
|
70298
71034
|
const isSelected = selectedIds.includes(id);
|
|
70299
|
-
|
|
70300
|
-
|
|
70301
|
-
|
|
70302
|
-
|
|
70303
|
-
|
|
70304
|
-
|
|
70305
|
-
|
|
70306
|
-
|
|
70307
|
-
|
|
70308
|
-
|
|
70309
|
-
|
|
70310
|
-
|
|
70311
|
-
|
|
70312
|
-
|
|
70313
|
-
|
|
70314
|
-
|
|
70315
|
-
|
|
70316
|
-
|
|
70317
|
-
|
|
70318
|
-
|
|
70319
|
-
|
|
70320
|
-
|
|
70321
|
-
|
|
70322
|
-
|
|
70323
|
-
|
|
70324
|
-
|
|
70325
|
-
|
|
70326
|
-
|
|
70327
|
-
|
|
71035
|
+
const isExpanded = expandedIds.has(id);
|
|
71036
|
+
const isFocused = keyboardNavigation && focusedRowIdx === i;
|
|
71037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(React28.Fragment, { children: [
|
|
71038
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
71039
|
+
"tr",
|
|
71040
|
+
{
|
|
71041
|
+
draggable,
|
|
71042
|
+
tabIndex: keyboardNavigation ? 0 : void 0,
|
|
71043
|
+
onDragStart: draggable ? (e) => {
|
|
71044
|
+
e.dataTransfer.setData("text/plain", id);
|
|
71045
|
+
} : void 0,
|
|
71046
|
+
onDragOver: draggable ? (e) => {
|
|
71047
|
+
e.preventDefault();
|
|
71048
|
+
setDragOverId(id);
|
|
71049
|
+
} : void 0,
|
|
71050
|
+
onDragLeave: draggable ? () => setDragOverId(null) : void 0,
|
|
71051
|
+
onDrop: draggable ? (e) => {
|
|
71052
|
+
e.preventDefault();
|
|
71053
|
+
setDragOverId(null);
|
|
71054
|
+
const fromId = e.dataTransfer.getData("text/plain");
|
|
71055
|
+
if (fromId === id) return;
|
|
71056
|
+
setTableData((prev) => {
|
|
71057
|
+
const fromIdx = prev.findIndex((r2) => String(r2[idKey] || "") === fromId);
|
|
71058
|
+
const toIdx = prev.findIndex((r2) => String(r2[idKey] || "") === id);
|
|
71059
|
+
if (fromIdx < 0 || toIdx < 0) return prev;
|
|
71060
|
+
const next = [...prev];
|
|
71061
|
+
const [moved] = next.splice(fromIdx, 1);
|
|
71062
|
+
next.splice(toIdx, 0, moved);
|
|
71063
|
+
onRowReorder?.(next);
|
|
71064
|
+
return next;
|
|
71065
|
+
});
|
|
71066
|
+
} : void 0,
|
|
71067
|
+
onClick: () => {
|
|
71068
|
+
if (expandable) setExpandedIds((prev) => {
|
|
71069
|
+
const s = new Set(prev);
|
|
71070
|
+
s.has(id) ? s.delete(id) : s.add(id);
|
|
71071
|
+
return s;
|
|
71072
|
+
});
|
|
71073
|
+
onRowClick?.(item);
|
|
71074
|
+
if (keyboardNavigation) setFocusedRowIdx(i);
|
|
71075
|
+
},
|
|
71076
|
+
onDoubleClick: () => onRowDoubleClick?.(item),
|
|
71077
|
+
className: cn(
|
|
71078
|
+
// default
|
|
71079
|
+
variant === "default" && "border-b border-border/60 transition-colors last:border-0",
|
|
71080
|
+
variant === "default" && (isSelected ? "bg-primary/5 hover:bg-primary/8" : "hover:bg-muted/30"),
|
|
71081
|
+
// zebra
|
|
71082
|
+
variant === "zebra" && "border-b border-border/40 transition-colors last:border-0",
|
|
71083
|
+
variant === "zebra" && (isSelected ? "bg-primary/8" : i % 2 === 0 ? "bg-card" : "bg-muted/40"),
|
|
71084
|
+
variant === "zebra" && !isSelected && "hover:bg-primary/5",
|
|
71085
|
+
// card
|
|
71086
|
+
variant === "card" && "rounded-xl border border-border bg-card shadow-sm transition-all hover:shadow-md hover:-translate-y-px",
|
|
71087
|
+
variant === "card" && (isSelected ? "border-primary/50 bg-primary/5" : ""),
|
|
71088
|
+
variant === "card" && "[&>td:first-child]:rounded-l-xl [&>td:last-child]:rounded-r-xl",
|
|
71089
|
+
// glass
|
|
71090
|
+
variant === "glass" && "border-b border-white/8 transition-colors last:border-0",
|
|
71091
|
+
variant === "glass" && (isSelected ? "bg-primary/15 hover:bg-primary/20" : "hover:bg-white/5"),
|
|
71092
|
+
// soft
|
|
71093
|
+
variant === "soft" && "transition-all",
|
|
71094
|
+
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"),
|
|
71095
|
+
variant === "soft" && "border-b border-border/30 last:border-0",
|
|
71096
|
+
(onRowClick || onRowDoubleClick || expandable) && "cursor-pointer",
|
|
71097
|
+
draggable && dragOverId === id && "ring-2 ring-inset ring-primary/40",
|
|
71098
|
+
isFocused && "ring-2 ring-inset ring-ring",
|
|
71099
|
+
rowClassName?.(item)
|
|
71100
|
+
),
|
|
71101
|
+
children: [
|
|
71102
|
+
selectable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { className: "px-4 py-3 align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71103
|
+
Checkbox,
|
|
71104
|
+
{
|
|
71105
|
+
checked: isSelected,
|
|
71106
|
+
onChange: (e) => handleSelect(id, e.target.checked)
|
|
71107
|
+
}
|
|
70328
71108
|
) }),
|
|
70329
|
-
|
|
70330
|
-
|
|
70331
|
-
|
|
70332
|
-
|
|
70333
|
-
|
|
70334
|
-
|
|
70335
|
-
|
|
70336
|
-
|
|
70337
|
-
|
|
70338
|
-
|
|
70339
|
-
|
|
70340
|
-
|
|
70341
|
-
|
|
70342
|
-
|
|
70343
|
-
|
|
70344
|
-
|
|
70345
|
-
|
|
70346
|
-
|
|
70347
|
-
|
|
70348
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn(
|
|
70349
|
-
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
70350
|
-
item[col.key] ? "translate-x-4" : "translate-x-0"
|
|
70351
|
-
) })
|
|
70352
|
-
}
|
|
70353
|
-
) : col.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
70354
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
70355
|
-
"input",
|
|
71109
|
+
expandable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { className: "w-8 px-2 py-3 align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronRight, { className: cn("h-3.5 w-3.5 text-muted-foreground transition-transform", isExpanded && "rotate-90") }) }),
|
|
71110
|
+
allColumns.map((col, ci) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { className: "px-4 py-3 align-middle", children: col.render ? col.render(item) : col.type === "image" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71111
|
+
"img",
|
|
71112
|
+
{
|
|
71113
|
+
src: item[col.key],
|
|
71114
|
+
alt: item[col.key],
|
|
71115
|
+
className: "h-9 w-9 rounded-lg object-cover ring-1 ring-border"
|
|
71116
|
+
}
|
|
71117
|
+
) : col.type === "badge" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: cn(
|
|
71118
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium",
|
|
71119
|
+
badgeClass(String(item[col.key]))
|
|
71120
|
+
), children: [
|
|
71121
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn(
|
|
71122
|
+
"mr-1.5 h-1.5 w-1.5 rounded-full",
|
|
71123
|
+
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"
|
|
71124
|
+
) }),
|
|
71125
|
+
item[col.key]
|
|
71126
|
+
] }) : col.type === "stack" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(AvatarStack, { images: Array.isArray(item[col.key]) ? item[col.key] : [], ...col.stackProps ?? {} }) : col.type === "icon" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "flex items-center", children: item[col.key] }) : col.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71127
|
+
"select",
|
|
70356
71128
|
{
|
|
70357
|
-
|
|
70358
|
-
value: item[col.key] || "#000000",
|
|
71129
|
+
value: item[col.key],
|
|
70359
71130
|
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
70360
|
-
className: "h-
|
|
71131
|
+
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",
|
|
71132
|
+
children: (col.selectOptions ?? []).map((opt) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: opt, children: opt }, opt))
|
|
70361
71133
|
}
|
|
70362
|
-
),
|
|
70363
|
-
|
|
70364
|
-
|
|
70365
|
-
|
|
70366
|
-
|
|
70367
|
-
|
|
70368
|
-
|
|
70369
|
-
|
|
70370
|
-
|
|
70371
|
-
|
|
70372
|
-
|
|
70373
|
-
|
|
70374
|
-
|
|
71134
|
+
) : col.type === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71135
|
+
"button",
|
|
71136
|
+
{
|
|
71137
|
+
role: "switch",
|
|
71138
|
+
"aria-checked": !!item[col.key],
|
|
71139
|
+
onClick: () => col.onChange?.(item, !item[col.key]),
|
|
71140
|
+
className: cn(
|
|
71141
|
+
"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",
|
|
71142
|
+
item[col.key] ? "bg-primary" : "bg-muted"
|
|
71143
|
+
),
|
|
71144
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: cn(
|
|
71145
|
+
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
71146
|
+
item[col.key] ? "translate-x-4" : "translate-x-0"
|
|
71147
|
+
) })
|
|
71148
|
+
}
|
|
71149
|
+
) : col.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
71150
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71151
|
+
"input",
|
|
71152
|
+
{
|
|
71153
|
+
type: "color",
|
|
71154
|
+
value: item[col.key] || "#000000",
|
|
71155
|
+
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
71156
|
+
className: "h-7 w-7 cursor-pointer rounded border border-border bg-transparent p-0.5"
|
|
71157
|
+
}
|
|
71158
|
+
),
|
|
71159
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-xs text-muted-foreground font-mono", children: item[col.key] })
|
|
71160
|
+
] }) : col.type === "checkbox" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71161
|
+
Checkbox,
|
|
71162
|
+
{
|
|
71163
|
+
checked: !!item[col.key],
|
|
71164
|
+
onChange: (e) => col.onChange?.(item, e.target.checked)
|
|
71165
|
+
}
|
|
71166
|
+
) : col.type === "text-url" ? (() => {
|
|
71167
|
+
const href = col.redirect ? typeof col.redirect === "function" ? col.redirect(item) : col.redirect : String(item[col.key] ?? "");
|
|
71168
|
+
const colorMap = {
|
|
71169
|
+
primary: "var(--primary)",
|
|
71170
|
+
info: "var(--info)",
|
|
71171
|
+
success: "var(--success)",
|
|
71172
|
+
warning: "var(--warning)",
|
|
71173
|
+
danger: "var(--danger)"
|
|
71174
|
+
};
|
|
71175
|
+
const underline = col.underlineColor ? colorMap[col.underlineColor] ?? col.underlineColor : "var(--primary)";
|
|
71176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71177
|
+
"a",
|
|
71178
|
+
{
|
|
71179
|
+
href,
|
|
71180
|
+
target: col.openNewTab ? "_blank" : void 0,
|
|
71181
|
+
rel: col.openNewTab ? "noopener noreferrer" : void 0,
|
|
71182
|
+
style: { textDecorationColor: underline },
|
|
71183
|
+
className: "text-sm underline underline-offset-2 hover:opacity-75 transition-opacity break-all",
|
|
71184
|
+
onClick: col.openNewTab ? void 0 : (e) => e.preventDefault(),
|
|
71185
|
+
children: item[col.key]
|
|
71186
|
+
}
|
|
71187
|
+
);
|
|
71188
|
+
})() : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-foreground/90", children: item[col.key] }) }, `${String(col.key)}-${ci}`))
|
|
71189
|
+
]
|
|
71190
|
+
}
|
|
71191
|
+
),
|
|
71192
|
+
expandable && isExpanded && renderExpanded && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tr", { className: "bg-muted/20 border-b border-border/60", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { colSpan: allColumns.length + (selectable ? 1 : 0) + 1, className: "px-6 py-3", children: renderExpanded(item) }) })
|
|
71193
|
+
] }, id);
|
|
70375
71194
|
}) })
|
|
70376
71195
|
] }) }) }),
|
|
70377
|
-
|
|
71196
|
+
clientPagination && !serverPagination && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
70378
71197
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
70379
71198
|
"Showing ",
|
|
70380
71199
|
(safePage - 1) * itemsPerPage + 1,
|
|
@@ -70425,8 +71244,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70425
71244
|
] })
|
|
70426
71245
|
] }),
|
|
70427
71246
|
serverPagination && (() => {
|
|
70428
|
-
const { pagination
|
|
70429
|
-
const totalServerPages =
|
|
71247
|
+
const { pagination, currentPage: cp, goToPage } = serverPagination;
|
|
71248
|
+
const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
|
|
70430
71249
|
const pills = [];
|
|
70431
71250
|
if (totalServerPages <= 7) {
|
|
70432
71251
|
for (let i = 1; i <= totalServerPages; i++) pills.push(i);
|
|
@@ -70439,7 +71258,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70439
71258
|
}
|
|
70440
71259
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
70441
71260
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
70442
|
-
|
|
71261
|
+
pagination.total,
|
|
70443
71262
|
" total rows \xB7 page ",
|
|
70444
71263
|
cp,
|
|
70445
71264
|
" of ",
|
|
@@ -70450,7 +71269,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70450
71269
|
"button",
|
|
70451
71270
|
{
|
|
70452
71271
|
onClick: () => goToPage(cp - 1),
|
|
70453
|
-
disabled: !
|
|
71272
|
+
disabled: !pagination.prev_page_url,
|
|
70454
71273
|
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",
|
|
70455
71274
|
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronLeft, { className: "h-4 w-4" })
|
|
70456
71275
|
}
|
|
@@ -70473,7 +71292,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70473
71292
|
"button",
|
|
70474
71293
|
{
|
|
70475
71294
|
onClick: () => goToPage(cp + 1),
|
|
70476
|
-
disabled: !
|
|
71295
|
+
disabled: !pagination.next_page_url,
|
|
70477
71296
|
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",
|
|
70478
71297
|
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ChevronRight, { className: "h-4 w-4" })
|
|
70479
71298
|
}
|
|
@@ -70488,6 +71307,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70488
71307
|
item: viewItem,
|
|
70489
71308
|
fields: viewFields,
|
|
70490
71309
|
width: defaultActions.modalWidth,
|
|
71310
|
+
grid: defaultActions.viewFormGrid,
|
|
70491
71311
|
onClose: () => setViewItem(null)
|
|
70492
71312
|
}
|
|
70493
71313
|
),
|
|
@@ -70545,6 +71365,37 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
70545
71365
|
}
|
|
70546
71366
|
}
|
|
70547
71367
|
}
|
|
71368
|
+
),
|
|
71369
|
+
bulkConfirm && (0, import_react_dom2.createPortal)(
|
|
71370
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
71371
|
+
"div",
|
|
71372
|
+
{
|
|
71373
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4",
|
|
71374
|
+
style: { background: "rgba(0,0,0,0.5)" },
|
|
71375
|
+
onMouseDown: (e) => {
|
|
71376
|
+
if (e.target === e.currentTarget) setBulkConfirm(null);
|
|
71377
|
+
},
|
|
71378
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative w-full max-w-md rounded-2xl border border-border bg-card shadow-2xl flex flex-col", children: [
|
|
71379
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border", children: [
|
|
71380
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h2", { className: "text-base font-semibold", children: "Confirm Delete" }),
|
|
71381
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { onClick: () => setBulkConfirm(null), className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(X, { className: "h-4 w-4" }) })
|
|
71382
|
+
] }),
|
|
71383
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "px-6 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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." }) }),
|
|
71384
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "px-6 py-4 border-t border-border flex justify-end gap-2", children: [
|
|
71385
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Button, { variant: "outline", size: "sm", onClick: () => setBulkConfirm(null), disabled: bulkLoading, children: "Cancel" }),
|
|
71386
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Button, { variant: "danger", size: "sm", disabled: bulkLoading, onClick: async () => {
|
|
71387
|
+
if (bulkConfirm === "selected") await execBulkDeleteSelected();
|
|
71388
|
+
else await execDeleteAll();
|
|
71389
|
+
setBulkConfirm(null);
|
|
71390
|
+
}, children: [
|
|
71391
|
+
bulkLoading && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LoaderCircle, { className: "h-3.5 w-3.5 mr-1.5 animate-spin" }),
|
|
71392
|
+
bulkLoading ? "Deleting\u2026" : "Delete"
|
|
71393
|
+
] })
|
|
71394
|
+
] })
|
|
71395
|
+
] })
|
|
71396
|
+
}
|
|
71397
|
+
),
|
|
71398
|
+
document.body
|
|
70548
71399
|
)
|
|
70549
71400
|
] });
|
|
70550
71401
|
}
|
|
@@ -75729,7 +76580,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
75729
76580
|
const hasChildren = !!node.children?.length;
|
|
75730
76581
|
const isExpanded = expanded.includes(node.id);
|
|
75731
76582
|
const isSelected = selected.includes(node.id);
|
|
75732
|
-
const defaultIcon = hasChildren ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FolderOpen, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Folder, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
76583
|
+
const defaultIcon = hasChildren ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FolderOpen, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Folder, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(File2, { className: "h-4 w-4 text-muted-foreground" });
|
|
75733
76584
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
75734
76585
|
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
75735
76586
|
"div",
|
|
@@ -76409,6 +77260,12 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
|
|
|
76409
77260
|
Accept: "application/json"
|
|
76410
77261
|
}
|
|
76411
77262
|
});
|
|
77263
|
+
axiosInstance.interceptors.request.use((config) => {
|
|
77264
|
+
if (config.data instanceof FormData) {
|
|
77265
|
+
delete config.headers["Content-Type"];
|
|
77266
|
+
}
|
|
77267
|
+
return config;
|
|
77268
|
+
});
|
|
76412
77269
|
|
|
76413
77270
|
// src/lib/codego/request.ts
|
|
76414
77271
|
var request = async (config) => {
|
|
@@ -76930,6 +77787,7 @@ lucide-react/dist/esm/icons/minus.js:
|
|
|
76930
77787
|
lucide-react/dist/esm/icons/moon.js:
|
|
76931
77788
|
lucide-react/dist/esm/icons/panel-left-close.js:
|
|
76932
77789
|
lucide-react/dist/esm/icons/panel-left-open.js:
|
|
77790
|
+
lucide-react/dist/esm/icons/paperclip.js:
|
|
76933
77791
|
lucide-react/dist/esm/icons/pencil.js:
|
|
76934
77792
|
lucide-react/dist/esm/icons/pin.js:
|
|
76935
77793
|
lucide-react/dist/esm/icons/plus.js:
|