@universe-platform/ui 0.1.0-beta.4 → 0.1.0-beta.5
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/globals.css +114 -0
- package/dist/index.js +391 -87
- package/dist/index.mjs +391 -87
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ function cn(...inputs) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
80
|
-
var
|
|
80
|
+
var import_react6 = require("react");
|
|
81
81
|
|
|
82
82
|
// src/hooks/useToast.ts
|
|
83
83
|
var import_react2 = require("react");
|
|
@@ -277,7 +277,7 @@ function useToast() {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
280
|
-
var
|
|
280
|
+
var import_react5 = __toESM(require("react"));
|
|
281
281
|
|
|
282
282
|
// src/components/TableBlock/fields/DrivePickerCell.tsx
|
|
283
283
|
var import_react3 = require("react");
|
|
@@ -399,8 +399,311 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
|
|
|
399
399
|
) });
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
// src/components/TableBlock/fields/
|
|
402
|
+
// src/components/TableBlock/fields/DatePickerCell.tsx
|
|
403
|
+
var import_react4 = require("react");
|
|
404
|
+
var import_lucide_react3 = require("lucide-react");
|
|
403
405
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
406
|
+
function parseDateParts(val) {
|
|
407
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
408
|
+
if (typeof val === "string") {
|
|
409
|
+
const trimmed = val.trim();
|
|
410
|
+
if (!trimmed) return null;
|
|
411
|
+
const ymdMatch = trimmed.match(/^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})/);
|
|
412
|
+
if (ymdMatch) {
|
|
413
|
+
const year = parseInt(ymdMatch[1], 10);
|
|
414
|
+
const month = parseInt(ymdMatch[2], 10);
|
|
415
|
+
const day = parseInt(ymdMatch[3], 10);
|
|
416
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
417
|
+
return { year, month, day };
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
const dmyMatch = trimmed.match(/^(\d{1,2})[-/.](\d{1,2})[-/.](\d{4})/);
|
|
421
|
+
if (dmyMatch) {
|
|
422
|
+
const day = parseInt(dmyMatch[1], 10);
|
|
423
|
+
const month = parseInt(dmyMatch[2], 10);
|
|
424
|
+
const year = parseInt(dmyMatch[3], 10);
|
|
425
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
426
|
+
return { year, month, day };
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const parsed = new Date(trimmed);
|
|
430
|
+
if (!isNaN(parsed.getTime())) {
|
|
431
|
+
return {
|
|
432
|
+
year: parsed.getFullYear(),
|
|
433
|
+
month: parsed.getMonth() + 1,
|
|
434
|
+
day: parsed.getDate()
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
} else if (val instanceof Date && !isNaN(val.getTime())) {
|
|
438
|
+
return {
|
|
439
|
+
year: val.getFullYear(),
|
|
440
|
+
month: val.getMonth() + 1,
|
|
441
|
+
day: val.getDate()
|
|
442
|
+
};
|
|
443
|
+
} else if (typeof val === "number" && !isNaN(val)) {
|
|
444
|
+
const parsed = new Date(val);
|
|
445
|
+
if (!isNaN(parsed.getTime())) {
|
|
446
|
+
return {
|
|
447
|
+
year: parsed.getFullYear(),
|
|
448
|
+
month: parsed.getMonth() + 1,
|
|
449
|
+
day: parsed.getDate()
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
function formatDateIso(year, month, day) {
|
|
456
|
+
const mm = String(month).padStart(2, "0");
|
|
457
|
+
const dd = String(day).padStart(2, "0");
|
|
458
|
+
return `${year}-${mm}-${dd}`;
|
|
459
|
+
}
|
|
460
|
+
function formatDateDisplay(parts) {
|
|
461
|
+
if (!parts) return "";
|
|
462
|
+
const mm = String(parts.month).padStart(2, "0");
|
|
463
|
+
const dd = String(parts.day).padStart(2, "0");
|
|
464
|
+
return `${dd}/${mm}/${parts.year}`;
|
|
465
|
+
}
|
|
466
|
+
var HEBREW_MONTHS = [
|
|
467
|
+
"\u05D9\u05E0\u05D5\u05D0\u05E8",
|
|
468
|
+
"\u05E4\u05D1\u05E8\u05D5\u05D0\u05E8",
|
|
469
|
+
"\u05DE\u05E8\u05E5",
|
|
470
|
+
"\u05D0\u05E4\u05E8\u05D9\u05DC",
|
|
471
|
+
"\u05DE\u05D0\u05D9",
|
|
472
|
+
"\u05D9\u05D5\u05E0\u05D9",
|
|
473
|
+
"\u05D9\u05D5\u05DC\u05D9",
|
|
474
|
+
"\u05D0\u05D5\u05D2\u05D5\u05E1\u05D8",
|
|
475
|
+
"\u05E1\u05E4\u05D8\u05DE\u05D1\u05E8",
|
|
476
|
+
"\u05D0\u05D5\u05E7\u05D8\u05D5\u05D1\u05E8",
|
|
477
|
+
"\u05E0\u05D5\u05D1\u05DE\u05D1\u05E8",
|
|
478
|
+
"\u05D3\u05E6\u05DE\u05D1\u05E8"
|
|
479
|
+
];
|
|
480
|
+
var WEEKDAY_LABELS = ["\u05D0'", "\u05D1'", "\u05D2'", "\u05D3'", "\u05D4'", "\u05D5'", "\u05E9'"];
|
|
481
|
+
function DatePickerCell({ value, onChange, readOnly = false }) {
|
|
482
|
+
const [isOpen, setIsOpen] = (0, import_react4.useState)(false);
|
|
483
|
+
const containerRef = (0, import_react4.useRef)(null);
|
|
484
|
+
const [popoverPos, setPopoverPos] = (0, import_react4.useState)({ top: 0, right: 0 });
|
|
485
|
+
const parsedParts = (0, import_react4.useMemo)(() => parseDateParts(value), [value]);
|
|
486
|
+
const displayString = (0, import_react4.useMemo)(() => formatDateDisplay(parsedParts), [parsedParts]);
|
|
487
|
+
const [rawInput, setRawInput] = (0, import_react4.useState)(displayString);
|
|
488
|
+
(0, import_react4.useEffect)(() => {
|
|
489
|
+
setRawInput(displayString);
|
|
490
|
+
}, [displayString]);
|
|
491
|
+
const now = /* @__PURE__ */ new Date();
|
|
492
|
+
const [viewYear, setViewYear] = (0, import_react4.useState)((parsedParts == null ? void 0 : parsedParts.year) || now.getFullYear());
|
|
493
|
+
const [viewMonth, setViewMonth] = (0, import_react4.useState)((parsedParts == null ? void 0 : parsedParts.month) || now.getMonth() + 1);
|
|
494
|
+
(0, import_react4.useEffect)(() => {
|
|
495
|
+
if (parsedParts) {
|
|
496
|
+
setViewYear(parsedParts.year);
|
|
497
|
+
setViewMonth(parsedParts.month);
|
|
498
|
+
}
|
|
499
|
+
}, [parsedParts, isOpen]);
|
|
500
|
+
const updatePopoverPosition = (0, import_react4.useCallback)(() => {
|
|
501
|
+
if (containerRef.current) {
|
|
502
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
503
|
+
const right = window.innerWidth - rect.right;
|
|
504
|
+
const popoverHeight = 320;
|
|
505
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
506
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
507
|
+
setPopoverPos({
|
|
508
|
+
top: Math.max(10, rect.top - popoverHeight - 4),
|
|
509
|
+
right: Math.max(10, right)
|
|
510
|
+
});
|
|
511
|
+
} else {
|
|
512
|
+
setPopoverPos({
|
|
513
|
+
top: Math.min(window.innerHeight - popoverHeight - 10, rect.bottom + 4),
|
|
514
|
+
right: Math.max(10, right)
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}, []);
|
|
519
|
+
(0, import_react4.useEffect)(() => {
|
|
520
|
+
if (!isOpen) return;
|
|
521
|
+
updatePopoverPosition();
|
|
522
|
+
function handleScrollOrResize() {
|
|
523
|
+
updatePopoverPosition();
|
|
524
|
+
}
|
|
525
|
+
function handleClickOutside(event) {
|
|
526
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
527
|
+
const popoverEl = document.getElementById("date-picker-popover");
|
|
528
|
+
if (popoverEl && popoverEl.contains(event.target)) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
setIsOpen(false);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
535
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
536
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
537
|
+
return () => {
|
|
538
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
539
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
540
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
541
|
+
};
|
|
542
|
+
}, [isOpen, updatePopoverPosition]);
|
|
543
|
+
const handleInputChange = (e) => {
|
|
544
|
+
const text = e.target.value;
|
|
545
|
+
setRawInput(text);
|
|
546
|
+
if (!text.trim()) {
|
|
547
|
+
onChange(null);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
const parts = parseDateParts(text);
|
|
551
|
+
if (parts) {
|
|
552
|
+
const iso = formatDateIso(parts.year, parts.month, parts.day);
|
|
553
|
+
onChange(iso);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
const handleInputBlur = () => {
|
|
557
|
+
const parts = parseDateParts(rawInput);
|
|
558
|
+
if (parts) {
|
|
559
|
+
setRawInput(formatDateDisplay(parts));
|
|
560
|
+
} else if (!rawInput.trim()) {
|
|
561
|
+
setRawInput("");
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
const handleSelectDay = (day) => {
|
|
565
|
+
const iso = formatDateIso(viewYear, viewMonth, day);
|
|
566
|
+
onChange(iso);
|
|
567
|
+
setRawInput(formatDateDisplay({ year: viewYear, month: viewMonth, day }));
|
|
568
|
+
setIsOpen(false);
|
|
569
|
+
};
|
|
570
|
+
const handlePrevMonth = () => {
|
|
571
|
+
if (viewMonth === 1) {
|
|
572
|
+
setViewMonth(12);
|
|
573
|
+
setViewYear((prev) => prev - 1);
|
|
574
|
+
} else {
|
|
575
|
+
setViewMonth((prev) => prev - 1);
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
const handleNextMonth = () => {
|
|
579
|
+
if (viewMonth === 12) {
|
|
580
|
+
setViewMonth(1);
|
|
581
|
+
setViewYear((prev) => prev + 1);
|
|
582
|
+
} else {
|
|
583
|
+
setViewMonth((prev) => prev + 1);
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
const calendarDays = (0, import_react4.useMemo)(() => {
|
|
587
|
+
const firstDayIndex = new Date(viewYear, viewMonth - 1, 1).getDay();
|
|
588
|
+
const totalDays = new Date(viewYear, viewMonth, 0).getDate();
|
|
589
|
+
const days = [];
|
|
590
|
+
const prevMonthTotalDays = new Date(viewYear, viewMonth - 1, 0).getDate();
|
|
591
|
+
for (let i = firstDayIndex - 1; i >= 0; i--) {
|
|
592
|
+
days.push({ day: prevMonthTotalDays - i, isCurrentMonth: false });
|
|
593
|
+
}
|
|
594
|
+
for (let d = 1; d <= totalDays; d++) {
|
|
595
|
+
days.push({ day: d, isCurrentMonth: true });
|
|
596
|
+
}
|
|
597
|
+
const remaining = 7 - days.length % 7;
|
|
598
|
+
if (remaining < 7) {
|
|
599
|
+
for (let d = 1; d <= remaining; d++) {
|
|
600
|
+
days.push({ day: d, isCurrentMonth: false });
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return days;
|
|
604
|
+
}, [viewYear, viewMonth]);
|
|
605
|
+
if (readOnly) {
|
|
606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "px-2 py-1 flex items-center justify-end w-full h-full text-sm font-normal text-slate-800 text-right", dir: "ltr", children: displayString });
|
|
607
|
+
}
|
|
608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { ref: containerRef, className: "relative w-full h-full flex items-center", children: [
|
|
609
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
610
|
+
"input",
|
|
611
|
+
{
|
|
612
|
+
type: "text",
|
|
613
|
+
dir: "ltr",
|
|
614
|
+
placeholder: "DD/MM/YYYY",
|
|
615
|
+
className: "w-full h-8 pl-8 pr-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm text-right font-normal text-slate-800",
|
|
616
|
+
value: rawInput,
|
|
617
|
+
onChange: handleInputChange,
|
|
618
|
+
onBlur: handleInputBlur
|
|
619
|
+
}
|
|
620
|
+
),
|
|
621
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
622
|
+
"button",
|
|
623
|
+
{
|
|
624
|
+
type: "button",
|
|
625
|
+
onClick: () => {
|
|
626
|
+
setIsOpen((prev) => {
|
|
627
|
+
const next = !prev;
|
|
628
|
+
if (next) updatePopoverPosition();
|
|
629
|
+
return next;
|
|
630
|
+
});
|
|
631
|
+
},
|
|
632
|
+
className: "absolute left-1.5 p-1 text-slate-400 hover:text-blue-600 rounded transition-colors",
|
|
633
|
+
title: "\u05D1\u05D7\u05E8 \u05EA\u05D0\u05E8\u05D9\u05DA",
|
|
634
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Calendar, { className: "w-4 h-4" })
|
|
635
|
+
}
|
|
636
|
+
),
|
|
637
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
638
|
+
"div",
|
|
639
|
+
{
|
|
640
|
+
id: "date-picker-popover",
|
|
641
|
+
dir: "rtl",
|
|
642
|
+
style: { top: `${popoverPos.top}px`, right: `${popoverPos.right}px` },
|
|
643
|
+
className: "fixed z-[99999] w-72 bg-white rounded-xl shadow-2xl border border-slate-200 p-3.5 animate-in fade-in zoom-in-95 duration-150",
|
|
644
|
+
children: [
|
|
645
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center justify-between border-b border-slate-100 pb-2.5 mb-2.5", children: [
|
|
646
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "text-xs font-semibold text-slate-500", children: parsedParts ? `${parsedParts.day} \u05D1${HEBREW_MONTHS[parsedParts.month - 1]} ${parsedParts.year}` : "\u05D1\u05D7\u05D9\u05E8\u05EA \u05EA\u05D0\u05E8\u05D9\u05DA" }),
|
|
647
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
648
|
+
"button",
|
|
649
|
+
{
|
|
650
|
+
onClick: () => setIsOpen(false),
|
|
651
|
+
className: "text-slate-400 hover:text-slate-600 p-0.5 rounded-full hover:bg-slate-100",
|
|
652
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.X, { className: "w-4 h-4" })
|
|
653
|
+
}
|
|
654
|
+
)
|
|
655
|
+
] }),
|
|
656
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center justify-between mb-3 px-1", children: [
|
|
657
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
658
|
+
"button",
|
|
659
|
+
{
|
|
660
|
+
type: "button",
|
|
661
|
+
onClick: handleNextMonth,
|
|
662
|
+
className: "p-1 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors",
|
|
663
|
+
title: "\u05D7\u05D5\u05D3\u05E9 \u05D4\u05D1\u05D0",
|
|
664
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.ChevronRight, { className: "w-4 h-4" })
|
|
665
|
+
}
|
|
666
|
+
),
|
|
667
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "font-bold text-sm text-slate-800", children: [
|
|
668
|
+
HEBREW_MONTHS[viewMonth - 1],
|
|
669
|
+
" ",
|
|
670
|
+
viewYear
|
|
671
|
+
] }),
|
|
672
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
673
|
+
"button",
|
|
674
|
+
{
|
|
675
|
+
type: "button",
|
|
676
|
+
onClick: handlePrevMonth,
|
|
677
|
+
className: "p-1 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors",
|
|
678
|
+
title: "\u05D7\u05D5\u05D3\u05E9 \u05E7\u05D5\u05D3\u05DD",
|
|
679
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.ChevronLeft, { className: "w-4 h-4" })
|
|
680
|
+
}
|
|
681
|
+
)
|
|
682
|
+
] }),
|
|
683
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "grid grid-cols-7 gap-1 text-center mb-1.5", children: WEEKDAY_LABELS.map((label, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[11px] font-bold text-slate-400 select-none py-0.5", children: label }, idx)) }),
|
|
684
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "grid grid-cols-7 gap-1 text-center", children: calendarDays.map((item, idx) => {
|
|
685
|
+
const isSelected = item.isCurrentMonth && (parsedParts == null ? void 0 : parsedParts.year) === viewYear && (parsedParts == null ? void 0 : parsedParts.month) === viewMonth && (parsedParts == null ? void 0 : parsedParts.day) === item.day;
|
|
686
|
+
const isToday = item.isCurrentMonth && now.getFullYear() === viewYear && now.getMonth() + 1 === viewMonth && now.getDate() === item.day;
|
|
687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
688
|
+
"button",
|
|
689
|
+
{
|
|
690
|
+
type: "button",
|
|
691
|
+
disabled: !item.isCurrentMonth,
|
|
692
|
+
onClick: () => item.isCurrentMonth && handleSelectDay(item.day),
|
|
693
|
+
className: `h-8 w-8 mx-auto flex items-center justify-center rounded-lg text-xs transition-all ${!item.isCurrentMonth ? "text-slate-300 cursor-not-allowed" : isSelected ? "bg-blue-600 text-white font-bold shadow-md scale-105" : isToday ? "bg-blue-50 text-blue-700 font-bold border border-blue-300 hover:bg-blue-100" : "text-slate-700 hover:bg-slate-100 font-medium"}`,
|
|
694
|
+
children: item.day
|
|
695
|
+
},
|
|
696
|
+
idx
|
|
697
|
+
);
|
|
698
|
+
}) })
|
|
699
|
+
]
|
|
700
|
+
}
|
|
701
|
+
)
|
|
702
|
+
] });
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
706
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
404
707
|
var CURRENCY_SYMBOLS = {
|
|
405
708
|
USD: "$",
|
|
406
709
|
EUR: "\u20AC",
|
|
@@ -436,11 +739,12 @@ function getRelationDisplayLabel(opt, column) {
|
|
|
436
739
|
return "\u05E2\u05E8\u05DA \u05E8\u05D9\u05E7";
|
|
437
740
|
}
|
|
438
741
|
var FORM_INPUTS = {
|
|
742
|
+
DATE: ({ value, onChange, column }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DatePickerCell, { value, onChange, column }),
|
|
439
743
|
CURRENCY: ({ value, column, onChange }) => {
|
|
440
744
|
const symbol = getCurrencySymbol(column.currencySymbol);
|
|
441
|
-
return /* @__PURE__ */ (0,
|
|
442
|
-
symbol && /* @__PURE__ */ (0,
|
|
443
|
-
/* @__PURE__ */ (0,
|
|
745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative w-full h-full", children: [
|
|
746
|
+
symbol && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none text-sm", children: symbol }),
|
|
747
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
444
748
|
"input",
|
|
445
749
|
{
|
|
446
750
|
type: "number",
|
|
@@ -455,7 +759,7 @@ var FORM_INPUTS = {
|
|
|
455
759
|
)
|
|
456
760
|
] });
|
|
457
761
|
},
|
|
458
|
-
TIME: ({ value, onChange }) => /* @__PURE__ */ (0,
|
|
762
|
+
TIME: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
459
763
|
"input",
|
|
460
764
|
{
|
|
461
765
|
type: "time",
|
|
@@ -465,13 +769,13 @@ var FORM_INPUTS = {
|
|
|
465
769
|
}
|
|
466
770
|
),
|
|
467
771
|
LINK: ({ value, onChange }) => {
|
|
468
|
-
const [isEditing, setIsEditing] =
|
|
772
|
+
const [isEditing, setIsEditing] = import_react5.default.useState(false);
|
|
469
773
|
const label = (value == null ? void 0 : value.label) || "";
|
|
470
774
|
const url = (value == null ? void 0 : value.url) || "";
|
|
471
775
|
if (!isEditing) {
|
|
472
|
-
return /* @__PURE__ */ (0,
|
|
473
|
-
url ? /* @__PURE__ */ (0,
|
|
474
|
-
/* @__PURE__ */ (0,
|
|
776
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 px-2 py-1 h-full w-full", children: [
|
|
777
|
+
url ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:underline flex-1 truncate", children: label || url }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-slate-400 italic flex-1 text-sm", children: "\u05E8\u05D9\u05E7" }),
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
475
779
|
"button",
|
|
476
780
|
{
|
|
477
781
|
onClick: () => setIsEditing(true),
|
|
@@ -482,8 +786,8 @@ var FORM_INPUTS = {
|
|
|
482
786
|
)
|
|
483
787
|
] });
|
|
484
788
|
}
|
|
485
|
-
return /* @__PURE__ */ (0,
|
|
486
|
-
/* @__PURE__ */ (0,
|
|
789
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex gap-2 p-1 w-full min-w-[250px] items-center bg-white border border-blue-200 rounded shadow-sm z-10", children: [
|
|
790
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
487
791
|
"input",
|
|
488
792
|
{
|
|
489
793
|
type: "text",
|
|
@@ -493,7 +797,7 @@ var FORM_INPUTS = {
|
|
|
493
797
|
onChange: (e) => onChange({ label: e.target.value, url })
|
|
494
798
|
}
|
|
495
799
|
),
|
|
496
|
-
/* @__PURE__ */ (0,
|
|
800
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
497
801
|
"input",
|
|
498
802
|
{
|
|
499
803
|
type: "url",
|
|
@@ -503,7 +807,7 @@ var FORM_INPUTS = {
|
|
|
503
807
|
onChange: (e) => onChange({ label, url: e.target.value })
|
|
504
808
|
}
|
|
505
809
|
),
|
|
506
|
-
/* @__PURE__ */ (0,
|
|
810
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
507
811
|
"button",
|
|
508
812
|
{
|
|
509
813
|
onClick: () => setIsEditing(false),
|
|
@@ -514,7 +818,7 @@ var FORM_INPUTS = {
|
|
|
514
818
|
)
|
|
515
819
|
] });
|
|
516
820
|
},
|
|
517
|
-
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */ (0,
|
|
821
|
+
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center justify-center w-full h-full p-2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
518
822
|
"input",
|
|
519
823
|
{
|
|
520
824
|
type: "checkbox",
|
|
@@ -523,7 +827,7 @@ var FORM_INPUTS = {
|
|
|
523
827
|
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
524
828
|
}
|
|
525
829
|
) }),
|
|
526
|
-
GOOGLE_DRIVE_FILE: ({ value, onChange, context }) => /* @__PURE__ */ (0,
|
|
830
|
+
GOOGLE_DRIVE_FILE: ({ value, onChange, context }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
527
831
|
DrivePickerCell,
|
|
528
832
|
{
|
|
529
833
|
value: value || null,
|
|
@@ -536,7 +840,7 @@ var FORM_INPUTS = {
|
|
|
536
840
|
RELATION: ({ value, onChange, column, context }) => {
|
|
537
841
|
var _a;
|
|
538
842
|
const options = ((_a = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a[column.name]) || [];
|
|
539
|
-
|
|
843
|
+
import_react5.default.useEffect(() => {
|
|
540
844
|
if (typeof value === "string" && value !== "" && options.length > 0) {
|
|
541
845
|
const isValidId = options.some((o) => String(o.id) === String(value));
|
|
542
846
|
if (!isValidId) {
|
|
@@ -555,7 +859,7 @@ var FORM_INPUTS = {
|
|
|
555
859
|
_displayLabel: getRelationDisplayLabel(opt, column)
|
|
556
860
|
}));
|
|
557
861
|
const validOptions = processedOptions.filter((o) => o._displayLabel !== "\u05D4\u05E2\u05E8\u05DA \u05E9\u05D1\u05E8\u05E9\u05D5\u05DE\u05D4 \u05D4\u05DE\u05E7\u05D5\u05E9\u05E8\u05EA \u05E0\u05E9\u05D0\u05E8 \u05E8\u05D9\u05E7");
|
|
558
|
-
return /* @__PURE__ */ (0,
|
|
862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
559
863
|
"select",
|
|
560
864
|
{
|
|
561
865
|
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
@@ -567,13 +871,13 @@ var FORM_INPUTS = {
|
|
|
567
871
|
}
|
|
568
872
|
},
|
|
569
873
|
children: [
|
|
570
|
-
/* @__PURE__ */ (0,
|
|
571
|
-
validOptions.length > 0 ? validOptions.map((opt) => /* @__PURE__ */ (0,
|
|
874
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "\u05D1\u05D7\u05E8..." }),
|
|
875
|
+
validOptions.length > 0 ? validOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: opt.id, children: opt._displayLabel }, opt.id)) : options.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "empty_all", disabled: true, children: "\u05DB\u05DC \u05D4\u05E2\u05E8\u05DB\u05D9\u05DD \u05D1\u05D8\u05D1\u05DC\u05D4 \u05D4\u05DE\u05E7\u05D5\u05E9\u05E8\u05EA \u05E8\u05D9\u05E7\u05D9\u05DD" }) : null
|
|
572
876
|
]
|
|
573
877
|
}
|
|
574
878
|
);
|
|
575
879
|
},
|
|
576
|
-
NUMBER: ({ value, onChange }) => /* @__PURE__ */ (0,
|
|
880
|
+
NUMBER: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
577
881
|
"input",
|
|
578
882
|
{
|
|
579
883
|
type: "number",
|
|
@@ -585,7 +889,7 @@ var FORM_INPUTS = {
|
|
|
585
889
|
}
|
|
586
890
|
}
|
|
587
891
|
),
|
|
588
|
-
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ (0,
|
|
892
|
+
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
589
893
|
"input",
|
|
590
894
|
{
|
|
591
895
|
type: "text",
|
|
@@ -597,7 +901,7 @@ var FORM_INPUTS = {
|
|
|
597
901
|
};
|
|
598
902
|
|
|
599
903
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
600
|
-
var
|
|
904
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
601
905
|
function TableBlockClient({
|
|
602
906
|
data: initialRecords,
|
|
603
907
|
settings: schema,
|
|
@@ -639,18 +943,18 @@ function TableBlockClient({
|
|
|
639
943
|
return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
|
|
640
944
|
});
|
|
641
945
|
};
|
|
642
|
-
const [localColumns, setLocalColumns] = (0,
|
|
643
|
-
(0,
|
|
946
|
+
const [localColumns, setLocalColumns] = (0, import_react6.useState)(() => (schema == null ? void 0 : schema.columns) || []);
|
|
947
|
+
(0, import_react6.useEffect)(() => {
|
|
644
948
|
if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
|
|
645
949
|
setLocalColumns(schema.columns);
|
|
646
950
|
}
|
|
647
951
|
}, [schema == null ? void 0 : schema.columns]);
|
|
648
|
-
const [dirty, setDirty] = (0,
|
|
649
|
-
const dirtyRef = (0,
|
|
650
|
-
(0,
|
|
952
|
+
const [dirty, setDirty] = (0, import_react6.useState)({ added: [], modified: {}, deleted: [] });
|
|
953
|
+
const dirtyRef = (0, import_react6.useRef)(dirty);
|
|
954
|
+
(0, import_react6.useEffect)(() => {
|
|
651
955
|
dirtyRef.current = dirty;
|
|
652
956
|
}, [dirty]);
|
|
653
|
-
const mergeWithDirty = (0,
|
|
957
|
+
const mergeWithDirty = (0, import_react6.useCallback)((baseRecords) => {
|
|
654
958
|
const { added, modified, deleted } = dirtyRef.current;
|
|
655
959
|
const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
|
|
656
960
|
const modifiedRecords = nonDeleted.map((r) => {
|
|
@@ -663,8 +967,8 @@ function TableBlockClient({
|
|
|
663
967
|
const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
|
|
664
968
|
return [...uniqueAdded, ...modifiedRecords];
|
|
665
969
|
}, []);
|
|
666
|
-
const [data, setData] = (0,
|
|
667
|
-
(0,
|
|
970
|
+
const [data, setData] = (0, import_react6.useState)(() => normalizeRecords(initialRecords));
|
|
971
|
+
(0, import_react6.useEffect)(() => {
|
|
668
972
|
if (initialRecords) {
|
|
669
973
|
setData(mergeWithDirty(normalizeRecords(initialRecords)));
|
|
670
974
|
}
|
|
@@ -679,19 +983,19 @@ function TableBlockClient({
|
|
|
679
983
|
}
|
|
680
984
|
return false;
|
|
681
985
|
};
|
|
682
|
-
const [baseRecordsMap, setBaseRecordsMap] = (0,
|
|
986
|
+
const [baseRecordsMap, setBaseRecordsMap] = (0, import_react6.useState)(() => {
|
|
683
987
|
const map = /* @__PURE__ */ new Map();
|
|
684
988
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
685
989
|
return map;
|
|
686
990
|
});
|
|
687
|
-
(0,
|
|
991
|
+
(0, import_react6.useEffect)(() => {
|
|
688
992
|
if (initialRecords && initialRecords.length > 0) {
|
|
689
993
|
const map = /* @__PURE__ */ new Map();
|
|
690
994
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
691
995
|
setBaseRecordsMap(map);
|
|
692
996
|
}
|
|
693
997
|
}, [initialRecords]);
|
|
694
|
-
(0,
|
|
998
|
+
(0, import_react6.useEffect)(() => {
|
|
695
999
|
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
696
1000
|
if (!tableId || !executeAction) return;
|
|
697
1001
|
if (!(schema == null ? void 0 : schema.columns) || schema.columns.length === 0 || (!initialRecords || initialRecords.length === 0)) {
|
|
@@ -714,19 +1018,19 @@ function TableBlockClient({
|
|
|
714
1018
|
});
|
|
715
1019
|
}
|
|
716
1020
|
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, schema == null ? void 0 : schema.columns, initialRecords, executeAction, mergeWithDirty]);
|
|
717
|
-
(0,
|
|
1021
|
+
(0, import_react6.useEffect)(() => {
|
|
718
1022
|
if (error) {
|
|
719
1023
|
showError(error, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E8\u05DB\u05D9\u05D1");
|
|
720
1024
|
}
|
|
721
1025
|
}, [error, showError]);
|
|
722
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
723
|
-
const [selectedIds, setSelectedIds] = (0,
|
|
724
|
-
const [pendingDeletions, setPendingDeletions] = (0,
|
|
725
|
-
const [isSaving, setIsSaving] = (0,
|
|
726
|
-
const [isSaveSuccess, setIsSaveSuccess] = (0,
|
|
727
|
-
const [relationOptions, setRelationOptions] = (0,
|
|
728
|
-
const schemaColsString = (0,
|
|
729
|
-
const refetchRelation = (0,
|
|
1026
|
+
const [searchQuery, setSearchQuery] = (0, import_react6.useState)("");
|
|
1027
|
+
const [selectedIds, setSelectedIds] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
1028
|
+
const [pendingDeletions, setPendingDeletions] = (0, import_react6.useState)([]);
|
|
1029
|
+
const [isSaving, setIsSaving] = (0, import_react6.useState)(false);
|
|
1030
|
+
const [isSaveSuccess, setIsSaveSuccess] = (0, import_react6.useState)(false);
|
|
1031
|
+
const [relationOptions, setRelationOptions] = (0, import_react6.useState)({});
|
|
1032
|
+
const schemaColsString = (0, import_react6.useMemo)(() => JSON.stringify(localColumns || []), [localColumns]);
|
|
1033
|
+
const refetchRelation = (0, import_react6.useCallback)(async (colName) => {
|
|
730
1034
|
var _a;
|
|
731
1035
|
let parsedCols = [];
|
|
732
1036
|
try {
|
|
@@ -746,7 +1050,7 @@ function TableBlockClient({
|
|
|
746
1050
|
console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
|
|
747
1051
|
}
|
|
748
1052
|
}, [schemaColsString, executeAction]);
|
|
749
|
-
(0,
|
|
1053
|
+
(0, import_react6.useEffect)(() => {
|
|
750
1054
|
let parsedCols = [];
|
|
751
1055
|
try {
|
|
752
1056
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -760,7 +1064,7 @@ function TableBlockClient({
|
|
|
760
1064
|
refetchRelation(col.name);
|
|
761
1065
|
});
|
|
762
1066
|
}, [schemaColsString, refetchRelation]);
|
|
763
|
-
const filteredColumns = (0,
|
|
1067
|
+
const filteredColumns = (0, import_react6.useMemo)(() => {
|
|
764
1068
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
765
1069
|
return (localColumns || []).filter((col) => !systemFields.includes(col.name));
|
|
766
1070
|
}, [localColumns]);
|
|
@@ -1025,7 +1329,7 @@ function TableBlockClient({
|
|
|
1025
1329
|
setIsSaving(false);
|
|
1026
1330
|
}
|
|
1027
1331
|
};
|
|
1028
|
-
const filteredData = (0,
|
|
1332
|
+
const filteredData = (0, import_react6.useMemo)(() => {
|
|
1029
1333
|
if (!searchQuery) return data;
|
|
1030
1334
|
const lowerQuery = searchQuery.toLowerCase();
|
|
1031
1335
|
return data.filter(
|
|
@@ -1036,7 +1340,7 @@ function TableBlockClient({
|
|
|
1036
1340
|
}, [data, searchQuery]);
|
|
1037
1341
|
const isUpdatingActive = Boolean(isUpdating || isSaving);
|
|
1038
1342
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
1039
|
-
return /* @__PURE__ */ (0,
|
|
1343
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1040
1344
|
"div",
|
|
1041
1345
|
{
|
|
1042
1346
|
id: componentId,
|
|
@@ -1044,24 +1348,24 @@ function TableBlockClient({
|
|
|
1044
1348
|
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs overflow-hidden ${className}`,
|
|
1045
1349
|
dir: "rtl",
|
|
1046
1350
|
children: [
|
|
1047
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
1048
|
-
/* @__PURE__ */ (0,
|
|
1049
|
-
/* @__PURE__ */ (0,
|
|
1351
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1352
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
1353
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: errorMessage })
|
|
1050
1354
|
] }) }),
|
|
1051
|
-
/* @__PURE__ */ (0,
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0,
|
|
1054
|
-
/* @__PURE__ */ (0,
|
|
1355
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 p-3.5 sm:p-4 bg-slate-50 border-b border-slate-200", children: [
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
1357
|
+
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: schema.title || schema.name }) }),
|
|
1358
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1055
1359
|
"button",
|
|
1056
1360
|
{
|
|
1057
1361
|
onClick: handleAddRow,
|
|
1058
1362
|
disabled: isLoading || isUpdatingActive,
|
|
1059
1363
|
className: "w-9 h-9 bg-emerald-600 hover:bg-emerald-700 active:bg-emerald-800 text-white rounded-lg shadow-xs flex items-center justify-center transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
1060
1364
|
title: "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
1061
|
-
children: /* @__PURE__ */ (0,
|
|
1365
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
1062
1366
|
}
|
|
1063
1367
|
),
|
|
1064
|
-
/* @__PURE__ */ (0,
|
|
1368
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1065
1369
|
"button",
|
|
1066
1370
|
{
|
|
1067
1371
|
onClick: handleDeleteSelected,
|
|
@@ -1069,14 +1373,14 @@ function TableBlockClient({
|
|
|
1069
1373
|
className: "w-9 h-9 bg-rose-50 hover:bg-rose-100 border border-rose-200 text-rose-700 rounded-lg shadow-2xs flex items-center justify-center relative transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
1070
1374
|
title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
|
|
1071
1375
|
children: [
|
|
1072
|
-
/* @__PURE__ */ (0,
|
|
1073
|
-
selectedIds.size > 0 && /* @__PURE__ */ (0,
|
|
1376
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
|
|
1377
|
+
selectedIds.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "absolute -top-1.5 -right-1.5 bg-rose-600 text-white min-w-[18px] h-[18px] px-1 rounded-full text-[10px] font-bold flex items-center justify-center shadow-xs", children: selectedIds.size })
|
|
1074
1378
|
]
|
|
1075
1379
|
}
|
|
1076
1380
|
),
|
|
1077
|
-
/* @__PURE__ */ (0,
|
|
1078
|
-
/* @__PURE__ */ (0,
|
|
1079
|
-
/* @__PURE__ */ (0,
|
|
1381
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
|
|
1382
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
|
|
1383
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1080
1384
|
"input",
|
|
1081
1385
|
{
|
|
1082
1386
|
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
@@ -1086,36 +1390,36 @@ function TableBlockClient({
|
|
|
1086
1390
|
className: "w-full h-9 px-3 pr-9 text-xs border border-slate-300 rounded-lg bg-white shadow-2xs focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 text-slate-800 disabled:opacity-50"
|
|
1087
1391
|
}
|
|
1088
1392
|
),
|
|
1089
|
-
/* @__PURE__ */ (0,
|
|
1393
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-4 h-4 text-slate-400 absolute right-2.5 top-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
|
|
1090
1394
|
] })
|
|
1091
1395
|
] }),
|
|
1092
|
-
/* @__PURE__ */ (0,
|
|
1093
|
-
isUpdatingActive ? /* @__PURE__ */ (0,
|
|
1094
|
-
/* @__PURE__ */ (0,
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
1397
|
+
isUpdatingActive ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-xs text-blue-600 font-semibold flex items-center gap-1.5 bg-blue-50 border border-blue-200 px-3 py-1.5 rounded-lg animate-pulse", children: [
|
|
1398
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
|
|
1095
1399
|
"\u05DE\u05E2\u05D3\u05DB\u05DF..."
|
|
1096
|
-
] }) : isSaveSuccess ? /* @__PURE__ */ (0,
|
|
1097
|
-
/* @__PURE__ */ (0,
|
|
1400
|
+
] }) : isSaveSuccess ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "text-xs text-emerald-700 font-semibold flex items-center gap-1.5 bg-emerald-50 border border-emerald-200 px-3 py-1.5 rounded-lg animate-in fade-in duration-200", children: [
|
|
1401
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
1098
1402
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
1099
|
-
] }) : hasChanges ? /* @__PURE__ */ (0,
|
|
1100
|
-
/* @__PURE__ */ (0,
|
|
1403
|
+
] }) : hasChanges ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-xs font-semibold text-amber-700 animate-in fade-in", children: "\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5" }) : null,
|
|
1404
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1101
1405
|
"button",
|
|
1102
1406
|
{
|
|
1103
1407
|
onClick: handleSave,
|
|
1104
1408
|
disabled: isUpdatingActive || isLoading || !hasChanges,
|
|
1105
1409
|
className: `h-9 px-4 text-xs font-bold rounded-lg shadow-2xs transition-all flex items-center justify-center cursor-pointer ${hasChanges && !isUpdatingActive && !isLoading ? "bg-brand hover:bg-brand-hover active:bg-[#00897b] text-white shadow-teal-500/20" : "opacity-50 grayscale bg-slate-200 text-slate-400 cursor-not-allowed"}`,
|
|
1106
|
-
children: /* @__PURE__ */ (0,
|
|
1410
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
|
|
1107
1411
|
}
|
|
1108
1412
|
)
|
|
1109
1413
|
] })
|
|
1110
1414
|
] }),
|
|
1111
|
-
/* @__PURE__ */ (0,
|
|
1112
|
-
isLoading && /* @__PURE__ */ (0,
|
|
1113
|
-
/* @__PURE__ */ (0,
|
|
1114
|
-
/* @__PURE__ */ (0,
|
|
1415
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "overflow-x-auto relative", children: [
|
|
1416
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
|
|
1417
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
|
|
1115
1419
|
] }),
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1117
|
-
/* @__PURE__ */ (0,
|
|
1118
|
-
/* @__PURE__ */ (0,
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("table", { className: "w-full text-sm text-right border-collapse", children: [
|
|
1421
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { children: [
|
|
1422
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { className: "border-b border-l border-slate-200 p-2.5 w-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1119
1423
|
"input",
|
|
1120
1424
|
{
|
|
1121
1425
|
type: "checkbox",
|
|
@@ -1125,13 +1429,13 @@ function TableBlockClient({
|
|
|
1125
1429
|
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
1126
1430
|
}
|
|
1127
1431
|
) }),
|
|
1128
|
-
filteredColumns.map((col) => /* @__PURE__ */ (0,
|
|
1432
|
+
filteredColumns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { className: "border-b border-l border-slate-200 px-4 py-2.5 font-semibold text-slate-700 whitespace-nowrap min-w-[140px]", children: col.name }, col.name))
|
|
1129
1433
|
] }) }),
|
|
1130
|
-
/* @__PURE__ */ (0,
|
|
1131
|
-
/* @__PURE__ */ (0,
|
|
1132
|
-
/* @__PURE__ */ (0,
|
|
1133
|
-
] }) }) }) : filteredData.map((row) => /* @__PURE__ */ (0,
|
|
1134
|
-
/* @__PURE__ */ (0,
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { colSpan: filteredColumns.length + 1, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" }) }),
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
|
|
1437
|
+
] }) }) }) : filteredData.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1135
1439
|
"input",
|
|
1136
1440
|
{
|
|
1137
1441
|
type: "checkbox",
|
|
@@ -1153,7 +1457,7 @@ function TableBlockClient({
|
|
|
1153
1457
|
}
|
|
1154
1458
|
}
|
|
1155
1459
|
if (value === void 0) value = null;
|
|
1156
|
-
return /* @__PURE__ */ (0,
|
|
1460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border-b border-l border-slate-200 p-0 relative", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1157
1461
|
InputComponent,
|
|
1158
1462
|
{
|
|
1159
1463
|
value,
|
|
@@ -1183,9 +1487,9 @@ function TableBlockClient({
|
|
|
1183
1487
|
}
|
|
1184
1488
|
|
|
1185
1489
|
// src/components/TableBlock/TableBlock.tsx
|
|
1186
|
-
var
|
|
1490
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1187
1491
|
function TableBlock(props) {
|
|
1188
|
-
return /* @__PURE__ */ (0,
|
|
1492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TableBlockClient, __spreadValues({}, props));
|
|
1189
1493
|
}
|
|
1190
1494
|
|
|
1191
1495
|
// src/registry.ts
|