@universe-platform/ui 0.1.0-beta.3 → 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 +451 -97
- package/dist/index.mjs +451 -97
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -39,7 +39,7 @@ function cn(...inputs) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
42
|
-
import { useState as
|
|
42
|
+
import { useState as useState4, useMemo as useMemo2, useEffect as useEffect2, useCallback as useCallback3, useRef as useRef3 } from "react";
|
|
43
43
|
|
|
44
44
|
// src/hooks/useToast.ts
|
|
45
45
|
import { useContext as useContext2 } from "react";
|
|
@@ -239,7 +239,7 @@ function useToast() {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
242
|
-
import
|
|
242
|
+
import React4 from "react";
|
|
243
243
|
|
|
244
244
|
// src/components/TableBlock/fields/DrivePickerCell.tsx
|
|
245
245
|
import { useState as useState2 } from "react";
|
|
@@ -361,8 +361,311 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
|
|
|
361
361
|
) });
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
-
// src/components/TableBlock/fields/
|
|
364
|
+
// src/components/TableBlock/fields/DatePickerCell.tsx
|
|
365
|
+
import { useState as useState3, useRef as useRef2, useEffect, useMemo, useCallback as useCallback2 } from "react";
|
|
366
|
+
import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, X as X3 } from "lucide-react";
|
|
365
367
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
368
|
+
function parseDateParts(val) {
|
|
369
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
370
|
+
if (typeof val === "string") {
|
|
371
|
+
const trimmed = val.trim();
|
|
372
|
+
if (!trimmed) return null;
|
|
373
|
+
const ymdMatch = trimmed.match(/^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})/);
|
|
374
|
+
if (ymdMatch) {
|
|
375
|
+
const year = parseInt(ymdMatch[1], 10);
|
|
376
|
+
const month = parseInt(ymdMatch[2], 10);
|
|
377
|
+
const day = parseInt(ymdMatch[3], 10);
|
|
378
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
379
|
+
return { year, month, day };
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const dmyMatch = trimmed.match(/^(\d{1,2})[-/.](\d{1,2})[-/.](\d{4})/);
|
|
383
|
+
if (dmyMatch) {
|
|
384
|
+
const day = parseInt(dmyMatch[1], 10);
|
|
385
|
+
const month = parseInt(dmyMatch[2], 10);
|
|
386
|
+
const year = parseInt(dmyMatch[3], 10);
|
|
387
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
388
|
+
return { year, month, day };
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const parsed = new Date(trimmed);
|
|
392
|
+
if (!isNaN(parsed.getTime())) {
|
|
393
|
+
return {
|
|
394
|
+
year: parsed.getFullYear(),
|
|
395
|
+
month: parsed.getMonth() + 1,
|
|
396
|
+
day: parsed.getDate()
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
} else if (val instanceof Date && !isNaN(val.getTime())) {
|
|
400
|
+
return {
|
|
401
|
+
year: val.getFullYear(),
|
|
402
|
+
month: val.getMonth() + 1,
|
|
403
|
+
day: val.getDate()
|
|
404
|
+
};
|
|
405
|
+
} else if (typeof val === "number" && !isNaN(val)) {
|
|
406
|
+
const parsed = new Date(val);
|
|
407
|
+
if (!isNaN(parsed.getTime())) {
|
|
408
|
+
return {
|
|
409
|
+
year: parsed.getFullYear(),
|
|
410
|
+
month: parsed.getMonth() + 1,
|
|
411
|
+
day: parsed.getDate()
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
function formatDateIso(year, month, day) {
|
|
418
|
+
const mm = String(month).padStart(2, "0");
|
|
419
|
+
const dd = String(day).padStart(2, "0");
|
|
420
|
+
return `${year}-${mm}-${dd}`;
|
|
421
|
+
}
|
|
422
|
+
function formatDateDisplay(parts) {
|
|
423
|
+
if (!parts) return "";
|
|
424
|
+
const mm = String(parts.month).padStart(2, "0");
|
|
425
|
+
const dd = String(parts.day).padStart(2, "0");
|
|
426
|
+
return `${dd}/${mm}/${parts.year}`;
|
|
427
|
+
}
|
|
428
|
+
var HEBREW_MONTHS = [
|
|
429
|
+
"\u05D9\u05E0\u05D5\u05D0\u05E8",
|
|
430
|
+
"\u05E4\u05D1\u05E8\u05D5\u05D0\u05E8",
|
|
431
|
+
"\u05DE\u05E8\u05E5",
|
|
432
|
+
"\u05D0\u05E4\u05E8\u05D9\u05DC",
|
|
433
|
+
"\u05DE\u05D0\u05D9",
|
|
434
|
+
"\u05D9\u05D5\u05E0\u05D9",
|
|
435
|
+
"\u05D9\u05D5\u05DC\u05D9",
|
|
436
|
+
"\u05D0\u05D5\u05D2\u05D5\u05E1\u05D8",
|
|
437
|
+
"\u05E1\u05E4\u05D8\u05DE\u05D1\u05E8",
|
|
438
|
+
"\u05D0\u05D5\u05E7\u05D8\u05D5\u05D1\u05E8",
|
|
439
|
+
"\u05E0\u05D5\u05D1\u05DE\u05D1\u05E8",
|
|
440
|
+
"\u05D3\u05E6\u05DE\u05D1\u05E8"
|
|
441
|
+
];
|
|
442
|
+
var WEEKDAY_LABELS = ["\u05D0'", "\u05D1'", "\u05D2'", "\u05D3'", "\u05D4'", "\u05D5'", "\u05E9'"];
|
|
443
|
+
function DatePickerCell({ value, onChange, readOnly = false }) {
|
|
444
|
+
const [isOpen, setIsOpen] = useState3(false);
|
|
445
|
+
const containerRef = useRef2(null);
|
|
446
|
+
const [popoverPos, setPopoverPos] = useState3({ top: 0, right: 0 });
|
|
447
|
+
const parsedParts = useMemo(() => parseDateParts(value), [value]);
|
|
448
|
+
const displayString = useMemo(() => formatDateDisplay(parsedParts), [parsedParts]);
|
|
449
|
+
const [rawInput, setRawInput] = useState3(displayString);
|
|
450
|
+
useEffect(() => {
|
|
451
|
+
setRawInput(displayString);
|
|
452
|
+
}, [displayString]);
|
|
453
|
+
const now = /* @__PURE__ */ new Date();
|
|
454
|
+
const [viewYear, setViewYear] = useState3((parsedParts == null ? void 0 : parsedParts.year) || now.getFullYear());
|
|
455
|
+
const [viewMonth, setViewMonth] = useState3((parsedParts == null ? void 0 : parsedParts.month) || now.getMonth() + 1);
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
if (parsedParts) {
|
|
458
|
+
setViewYear(parsedParts.year);
|
|
459
|
+
setViewMonth(parsedParts.month);
|
|
460
|
+
}
|
|
461
|
+
}, [parsedParts, isOpen]);
|
|
462
|
+
const updatePopoverPosition = useCallback2(() => {
|
|
463
|
+
if (containerRef.current) {
|
|
464
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
465
|
+
const right = window.innerWidth - rect.right;
|
|
466
|
+
const popoverHeight = 320;
|
|
467
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
468
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
469
|
+
setPopoverPos({
|
|
470
|
+
top: Math.max(10, rect.top - popoverHeight - 4),
|
|
471
|
+
right: Math.max(10, right)
|
|
472
|
+
});
|
|
473
|
+
} else {
|
|
474
|
+
setPopoverPos({
|
|
475
|
+
top: Math.min(window.innerHeight - popoverHeight - 10, rect.bottom + 4),
|
|
476
|
+
right: Math.max(10, right)
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}, []);
|
|
481
|
+
useEffect(() => {
|
|
482
|
+
if (!isOpen) return;
|
|
483
|
+
updatePopoverPosition();
|
|
484
|
+
function handleScrollOrResize() {
|
|
485
|
+
updatePopoverPosition();
|
|
486
|
+
}
|
|
487
|
+
function handleClickOutside(event) {
|
|
488
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
489
|
+
const popoverEl = document.getElementById("date-picker-popover");
|
|
490
|
+
if (popoverEl && popoverEl.contains(event.target)) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
setIsOpen(false);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
497
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
498
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
499
|
+
return () => {
|
|
500
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
501
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
502
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
503
|
+
};
|
|
504
|
+
}, [isOpen, updatePopoverPosition]);
|
|
505
|
+
const handleInputChange = (e) => {
|
|
506
|
+
const text = e.target.value;
|
|
507
|
+
setRawInput(text);
|
|
508
|
+
if (!text.trim()) {
|
|
509
|
+
onChange(null);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const parts = parseDateParts(text);
|
|
513
|
+
if (parts) {
|
|
514
|
+
const iso = formatDateIso(parts.year, parts.month, parts.day);
|
|
515
|
+
onChange(iso);
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
const handleInputBlur = () => {
|
|
519
|
+
const parts = parseDateParts(rawInput);
|
|
520
|
+
if (parts) {
|
|
521
|
+
setRawInput(formatDateDisplay(parts));
|
|
522
|
+
} else if (!rawInput.trim()) {
|
|
523
|
+
setRawInput("");
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
const handleSelectDay = (day) => {
|
|
527
|
+
const iso = formatDateIso(viewYear, viewMonth, day);
|
|
528
|
+
onChange(iso);
|
|
529
|
+
setRawInput(formatDateDisplay({ year: viewYear, month: viewMonth, day }));
|
|
530
|
+
setIsOpen(false);
|
|
531
|
+
};
|
|
532
|
+
const handlePrevMonth = () => {
|
|
533
|
+
if (viewMonth === 1) {
|
|
534
|
+
setViewMonth(12);
|
|
535
|
+
setViewYear((prev) => prev - 1);
|
|
536
|
+
} else {
|
|
537
|
+
setViewMonth((prev) => prev - 1);
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
const handleNextMonth = () => {
|
|
541
|
+
if (viewMonth === 12) {
|
|
542
|
+
setViewMonth(1);
|
|
543
|
+
setViewYear((prev) => prev + 1);
|
|
544
|
+
} else {
|
|
545
|
+
setViewMonth((prev) => prev + 1);
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
const calendarDays = useMemo(() => {
|
|
549
|
+
const firstDayIndex = new Date(viewYear, viewMonth - 1, 1).getDay();
|
|
550
|
+
const totalDays = new Date(viewYear, viewMonth, 0).getDate();
|
|
551
|
+
const days = [];
|
|
552
|
+
const prevMonthTotalDays = new Date(viewYear, viewMonth - 1, 0).getDate();
|
|
553
|
+
for (let i = firstDayIndex - 1; i >= 0; i--) {
|
|
554
|
+
days.push({ day: prevMonthTotalDays - i, isCurrentMonth: false });
|
|
555
|
+
}
|
|
556
|
+
for (let d = 1; d <= totalDays; d++) {
|
|
557
|
+
days.push({ day: d, isCurrentMonth: true });
|
|
558
|
+
}
|
|
559
|
+
const remaining = 7 - days.length % 7;
|
|
560
|
+
if (remaining < 7) {
|
|
561
|
+
for (let d = 1; d <= remaining; d++) {
|
|
562
|
+
days.push({ day: d, isCurrentMonth: false });
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return days;
|
|
566
|
+
}, [viewYear, viewMonth]);
|
|
567
|
+
if (readOnly) {
|
|
568
|
+
return /* @__PURE__ */ jsx3("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 });
|
|
569
|
+
}
|
|
570
|
+
return /* @__PURE__ */ jsxs3("div", { ref: containerRef, className: "relative w-full h-full flex items-center", children: [
|
|
571
|
+
/* @__PURE__ */ jsx3(
|
|
572
|
+
"input",
|
|
573
|
+
{
|
|
574
|
+
type: "text",
|
|
575
|
+
dir: "ltr",
|
|
576
|
+
placeholder: "DD/MM/YYYY",
|
|
577
|
+
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",
|
|
578
|
+
value: rawInput,
|
|
579
|
+
onChange: handleInputChange,
|
|
580
|
+
onBlur: handleInputBlur
|
|
581
|
+
}
|
|
582
|
+
),
|
|
583
|
+
/* @__PURE__ */ jsx3(
|
|
584
|
+
"button",
|
|
585
|
+
{
|
|
586
|
+
type: "button",
|
|
587
|
+
onClick: () => {
|
|
588
|
+
setIsOpen((prev) => {
|
|
589
|
+
const next = !prev;
|
|
590
|
+
if (next) updatePopoverPosition();
|
|
591
|
+
return next;
|
|
592
|
+
});
|
|
593
|
+
},
|
|
594
|
+
className: "absolute left-1.5 p-1 text-slate-400 hover:text-blue-600 rounded transition-colors",
|
|
595
|
+
title: "\u05D1\u05D7\u05E8 \u05EA\u05D0\u05E8\u05D9\u05DA",
|
|
596
|
+
children: /* @__PURE__ */ jsx3(CalendarIcon, { className: "w-4 h-4" })
|
|
597
|
+
}
|
|
598
|
+
),
|
|
599
|
+
isOpen && /* @__PURE__ */ jsxs3(
|
|
600
|
+
"div",
|
|
601
|
+
{
|
|
602
|
+
id: "date-picker-popover",
|
|
603
|
+
dir: "rtl",
|
|
604
|
+
style: { top: `${popoverPos.top}px`, right: `${popoverPos.right}px` },
|
|
605
|
+
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",
|
|
606
|
+
children: [
|
|
607
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between border-b border-slate-100 pb-2.5 mb-2.5", children: [
|
|
608
|
+
/* @__PURE__ */ jsx3("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" }),
|
|
609
|
+
/* @__PURE__ */ jsx3(
|
|
610
|
+
"button",
|
|
611
|
+
{
|
|
612
|
+
onClick: () => setIsOpen(false),
|
|
613
|
+
className: "text-slate-400 hover:text-slate-600 p-0.5 rounded-full hover:bg-slate-100",
|
|
614
|
+
children: /* @__PURE__ */ jsx3(X3, { className: "w-4 h-4" })
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
] }),
|
|
618
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between mb-3 px-1", children: [
|
|
619
|
+
/* @__PURE__ */ jsx3(
|
|
620
|
+
"button",
|
|
621
|
+
{
|
|
622
|
+
type: "button",
|
|
623
|
+
onClick: handleNextMonth,
|
|
624
|
+
className: "p-1 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors",
|
|
625
|
+
title: "\u05D7\u05D5\u05D3\u05E9 \u05D4\u05D1\u05D0",
|
|
626
|
+
children: /* @__PURE__ */ jsx3(ChevronRight, { className: "w-4 h-4" })
|
|
627
|
+
}
|
|
628
|
+
),
|
|
629
|
+
/* @__PURE__ */ jsxs3("span", { className: "font-bold text-sm text-slate-800", children: [
|
|
630
|
+
HEBREW_MONTHS[viewMonth - 1],
|
|
631
|
+
" ",
|
|
632
|
+
viewYear
|
|
633
|
+
] }),
|
|
634
|
+
/* @__PURE__ */ jsx3(
|
|
635
|
+
"button",
|
|
636
|
+
{
|
|
637
|
+
type: "button",
|
|
638
|
+
onClick: handlePrevMonth,
|
|
639
|
+
className: "p-1 text-slate-600 hover:bg-slate-100 rounded-lg transition-colors",
|
|
640
|
+
title: "\u05D7\u05D5\u05D3\u05E9 \u05E7\u05D5\u05D3\u05DD",
|
|
641
|
+
children: /* @__PURE__ */ jsx3(ChevronLeft, { className: "w-4 h-4" })
|
|
642
|
+
}
|
|
643
|
+
)
|
|
644
|
+
] }),
|
|
645
|
+
/* @__PURE__ */ jsx3("div", { className: "grid grid-cols-7 gap-1 text-center mb-1.5", children: WEEKDAY_LABELS.map((label, idx) => /* @__PURE__ */ jsx3("span", { className: "text-[11px] font-bold text-slate-400 select-none py-0.5", children: label }, idx)) }),
|
|
646
|
+
/* @__PURE__ */ jsx3("div", { className: "grid grid-cols-7 gap-1 text-center", children: calendarDays.map((item, idx) => {
|
|
647
|
+
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;
|
|
648
|
+
const isToday = item.isCurrentMonth && now.getFullYear() === viewYear && now.getMonth() + 1 === viewMonth && now.getDate() === item.day;
|
|
649
|
+
return /* @__PURE__ */ jsx3(
|
|
650
|
+
"button",
|
|
651
|
+
{
|
|
652
|
+
type: "button",
|
|
653
|
+
disabled: !item.isCurrentMonth,
|
|
654
|
+
onClick: () => item.isCurrentMonth && handleSelectDay(item.day),
|
|
655
|
+
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"}`,
|
|
656
|
+
children: item.day
|
|
657
|
+
},
|
|
658
|
+
idx
|
|
659
|
+
);
|
|
660
|
+
}) })
|
|
661
|
+
]
|
|
662
|
+
}
|
|
663
|
+
)
|
|
664
|
+
] });
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
668
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
366
669
|
var CURRENCY_SYMBOLS = {
|
|
367
670
|
USD: "$",
|
|
368
671
|
EUR: "\u20AC",
|
|
@@ -379,24 +682,31 @@ function getRelationDisplayLabel(opt, column) {
|
|
|
379
682
|
if (val !== void 0 && val !== null && val !== "") {
|
|
380
683
|
return String(val);
|
|
381
684
|
}
|
|
685
|
+
if (opt.label && opt.label !== opt.id) {
|
|
686
|
+
return String(opt.label);
|
|
687
|
+
}
|
|
382
688
|
if (opt.data) {
|
|
383
689
|
const fallbackField = Object.keys(opt.data).find((k) => {
|
|
384
690
|
if (k === "_id" || k === "id") return false;
|
|
385
691
|
const v = opt.data[k];
|
|
386
692
|
if (typeof v === "string" && v.trim() !== "") return true;
|
|
387
|
-
if (typeof v === "number") return true;
|
|
693
|
+
if (typeof v === "number" && !isNaN(v)) return true;
|
|
388
694
|
return false;
|
|
389
695
|
});
|
|
390
696
|
if (fallbackField) return String(opt.data[fallbackField]);
|
|
391
697
|
}
|
|
698
|
+
if (opt.label) {
|
|
699
|
+
return String(opt.label);
|
|
700
|
+
}
|
|
392
701
|
return "\u05E2\u05E8\u05DA \u05E8\u05D9\u05E7";
|
|
393
702
|
}
|
|
394
703
|
var FORM_INPUTS = {
|
|
704
|
+
DATE: ({ value, onChange, column }) => /* @__PURE__ */ jsx4(DatePickerCell, { value, onChange, column }),
|
|
395
705
|
CURRENCY: ({ value, column, onChange }) => {
|
|
396
706
|
const symbol = getCurrencySymbol(column.currencySymbol);
|
|
397
|
-
return /* @__PURE__ */
|
|
398
|
-
symbol && /* @__PURE__ */
|
|
399
|
-
/* @__PURE__ */
|
|
707
|
+
return /* @__PURE__ */ jsxs4("div", { className: "relative w-full h-full", children: [
|
|
708
|
+
symbol && /* @__PURE__ */ jsx4("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none text-sm", children: symbol }),
|
|
709
|
+
/* @__PURE__ */ jsx4(
|
|
400
710
|
"input",
|
|
401
711
|
{
|
|
402
712
|
type: "number",
|
|
@@ -411,7 +721,7 @@ var FORM_INPUTS = {
|
|
|
411
721
|
)
|
|
412
722
|
] });
|
|
413
723
|
},
|
|
414
|
-
TIME: ({ value, onChange }) => /* @__PURE__ */
|
|
724
|
+
TIME: ({ value, onChange }) => /* @__PURE__ */ jsx4(
|
|
415
725
|
"input",
|
|
416
726
|
{
|
|
417
727
|
type: "time",
|
|
@@ -421,13 +731,13 @@ var FORM_INPUTS = {
|
|
|
421
731
|
}
|
|
422
732
|
),
|
|
423
733
|
LINK: ({ value, onChange }) => {
|
|
424
|
-
const [isEditing, setIsEditing] =
|
|
734
|
+
const [isEditing, setIsEditing] = React4.useState(false);
|
|
425
735
|
const label = (value == null ? void 0 : value.label) || "";
|
|
426
736
|
const url = (value == null ? void 0 : value.url) || "";
|
|
427
737
|
if (!isEditing) {
|
|
428
|
-
return /* @__PURE__ */
|
|
429
|
-
url ? /* @__PURE__ */
|
|
430
|
-
/* @__PURE__ */
|
|
738
|
+
return /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 px-2 py-1 h-full w-full", children: [
|
|
739
|
+
url ? /* @__PURE__ */ jsx4("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:underline flex-1 truncate", children: label || url }) : /* @__PURE__ */ jsx4("span", { className: "text-slate-400 italic flex-1 text-sm", children: "\u05E8\u05D9\u05E7" }),
|
|
740
|
+
/* @__PURE__ */ jsx4(
|
|
431
741
|
"button",
|
|
432
742
|
{
|
|
433
743
|
onClick: () => setIsEditing(true),
|
|
@@ -438,8 +748,8 @@ var FORM_INPUTS = {
|
|
|
438
748
|
)
|
|
439
749
|
] });
|
|
440
750
|
}
|
|
441
|
-
return /* @__PURE__ */
|
|
442
|
-
/* @__PURE__ */
|
|
751
|
+
return /* @__PURE__ */ jsxs4("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: [
|
|
752
|
+
/* @__PURE__ */ jsx4(
|
|
443
753
|
"input",
|
|
444
754
|
{
|
|
445
755
|
type: "text",
|
|
@@ -449,7 +759,7 @@ var FORM_INPUTS = {
|
|
|
449
759
|
onChange: (e) => onChange({ label: e.target.value, url })
|
|
450
760
|
}
|
|
451
761
|
),
|
|
452
|
-
/* @__PURE__ */
|
|
762
|
+
/* @__PURE__ */ jsx4(
|
|
453
763
|
"input",
|
|
454
764
|
{
|
|
455
765
|
type: "url",
|
|
@@ -459,7 +769,7 @@ var FORM_INPUTS = {
|
|
|
459
769
|
onChange: (e) => onChange({ label, url: e.target.value })
|
|
460
770
|
}
|
|
461
771
|
),
|
|
462
|
-
/* @__PURE__ */
|
|
772
|
+
/* @__PURE__ */ jsx4(
|
|
463
773
|
"button",
|
|
464
774
|
{
|
|
465
775
|
onClick: () => setIsEditing(false),
|
|
@@ -470,7 +780,7 @@ var FORM_INPUTS = {
|
|
|
470
780
|
)
|
|
471
781
|
] });
|
|
472
782
|
},
|
|
473
|
-
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */
|
|
783
|
+
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */ jsx4("div", { className: "flex items-center justify-center w-full h-full p-2", children: /* @__PURE__ */ jsx4(
|
|
474
784
|
"input",
|
|
475
785
|
{
|
|
476
786
|
type: "checkbox",
|
|
@@ -479,7 +789,7 @@ var FORM_INPUTS = {
|
|
|
479
789
|
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
480
790
|
}
|
|
481
791
|
) }),
|
|
482
|
-
GOOGLE_DRIVE_FILE: ({ value, onChange, context }) => /* @__PURE__ */
|
|
792
|
+
GOOGLE_DRIVE_FILE: ({ value, onChange, context }) => /* @__PURE__ */ jsx4(
|
|
483
793
|
DrivePickerCell,
|
|
484
794
|
{
|
|
485
795
|
value: value || null,
|
|
@@ -492,7 +802,7 @@ var FORM_INPUTS = {
|
|
|
492
802
|
RELATION: ({ value, onChange, column, context }) => {
|
|
493
803
|
var _a;
|
|
494
804
|
const options = ((_a = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a[column.name]) || [];
|
|
495
|
-
|
|
805
|
+
React4.useEffect(() => {
|
|
496
806
|
if (typeof value === "string" && value !== "" && options.length > 0) {
|
|
497
807
|
const isValidId = options.some((o) => String(o.id) === String(value));
|
|
498
808
|
if (!isValidId) {
|
|
@@ -511,7 +821,7 @@ var FORM_INPUTS = {
|
|
|
511
821
|
_displayLabel: getRelationDisplayLabel(opt, column)
|
|
512
822
|
}));
|
|
513
823
|
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");
|
|
514
|
-
return /* @__PURE__ */
|
|
824
|
+
return /* @__PURE__ */ jsxs4(
|
|
515
825
|
"select",
|
|
516
826
|
{
|
|
517
827
|
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
@@ -523,13 +833,13 @@ var FORM_INPUTS = {
|
|
|
523
833
|
}
|
|
524
834
|
},
|
|
525
835
|
children: [
|
|
526
|
-
/* @__PURE__ */
|
|
527
|
-
validOptions.length > 0 ? validOptions.map((opt) => /* @__PURE__ */
|
|
836
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: "\u05D1\u05D7\u05E8..." }),
|
|
837
|
+
validOptions.length > 0 ? validOptions.map((opt) => /* @__PURE__ */ jsx4("option", { value: opt.id, children: opt._displayLabel }, opt.id)) : options.length > 0 ? /* @__PURE__ */ jsx4("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
|
|
528
838
|
]
|
|
529
839
|
}
|
|
530
840
|
);
|
|
531
841
|
},
|
|
532
|
-
NUMBER: ({ value, onChange }) => /* @__PURE__ */
|
|
842
|
+
NUMBER: ({ value, onChange }) => /* @__PURE__ */ jsx4(
|
|
533
843
|
"input",
|
|
534
844
|
{
|
|
535
845
|
type: "number",
|
|
@@ -541,7 +851,7 @@ var FORM_INPUTS = {
|
|
|
541
851
|
}
|
|
542
852
|
}
|
|
543
853
|
),
|
|
544
|
-
DEFAULT: ({ value, onChange }) => /* @__PURE__ */
|
|
854
|
+
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ jsx4(
|
|
545
855
|
"input",
|
|
546
856
|
{
|
|
547
857
|
type: "text",
|
|
@@ -553,7 +863,7 @@ var FORM_INPUTS = {
|
|
|
553
863
|
};
|
|
554
864
|
|
|
555
865
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
556
|
-
import { jsx as
|
|
866
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
557
867
|
function TableBlockClient({
|
|
558
868
|
data: initialRecords,
|
|
559
869
|
settings: schema,
|
|
@@ -595,18 +905,18 @@ function TableBlockClient({
|
|
|
595
905
|
return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
|
|
596
906
|
});
|
|
597
907
|
};
|
|
598
|
-
const [localColumns, setLocalColumns] =
|
|
599
|
-
|
|
908
|
+
const [localColumns, setLocalColumns] = useState4(() => (schema == null ? void 0 : schema.columns) || []);
|
|
909
|
+
useEffect2(() => {
|
|
600
910
|
if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
|
|
601
911
|
setLocalColumns(schema.columns);
|
|
602
912
|
}
|
|
603
913
|
}, [schema == null ? void 0 : schema.columns]);
|
|
604
|
-
const [dirty, setDirty] =
|
|
605
|
-
const dirtyRef =
|
|
606
|
-
|
|
914
|
+
const [dirty, setDirty] = useState4({ added: [], modified: {}, deleted: [] });
|
|
915
|
+
const dirtyRef = useRef3(dirty);
|
|
916
|
+
useEffect2(() => {
|
|
607
917
|
dirtyRef.current = dirty;
|
|
608
918
|
}, [dirty]);
|
|
609
|
-
const mergeWithDirty =
|
|
919
|
+
const mergeWithDirty = useCallback3((baseRecords) => {
|
|
610
920
|
const { added, modified, deleted } = dirtyRef.current;
|
|
611
921
|
const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
|
|
612
922
|
const modifiedRecords = nonDeleted.map((r) => {
|
|
@@ -619,8 +929,8 @@ function TableBlockClient({
|
|
|
619
929
|
const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
|
|
620
930
|
return [...uniqueAdded, ...modifiedRecords];
|
|
621
931
|
}, []);
|
|
622
|
-
const [data, setData] =
|
|
623
|
-
|
|
932
|
+
const [data, setData] = useState4(() => normalizeRecords(initialRecords));
|
|
933
|
+
useEffect2(() => {
|
|
624
934
|
if (initialRecords) {
|
|
625
935
|
setData(mergeWithDirty(normalizeRecords(initialRecords)));
|
|
626
936
|
}
|
|
@@ -635,20 +945,20 @@ function TableBlockClient({
|
|
|
635
945
|
}
|
|
636
946
|
return false;
|
|
637
947
|
};
|
|
638
|
-
const [baseRecordsMap, setBaseRecordsMap] =
|
|
948
|
+
const [baseRecordsMap, setBaseRecordsMap] = useState4(() => {
|
|
639
949
|
const map = /* @__PURE__ */ new Map();
|
|
640
950
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
641
951
|
return map;
|
|
642
952
|
});
|
|
643
|
-
|
|
953
|
+
useEffect2(() => {
|
|
644
954
|
if (initialRecords && initialRecords.length > 0) {
|
|
645
955
|
const map = /* @__PURE__ */ new Map();
|
|
646
956
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
647
957
|
setBaseRecordsMap(map);
|
|
648
958
|
}
|
|
649
959
|
}, [initialRecords]);
|
|
650
|
-
|
|
651
|
-
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.
|
|
960
|
+
useEffect2(() => {
|
|
961
|
+
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
652
962
|
if (!tableId || !executeAction) return;
|
|
653
963
|
if (!(schema == null ? void 0 : schema.columns) || schema.columns.length === 0 || (!initialRecords || initialRecords.length === 0)) {
|
|
654
964
|
executeAction("FETCH_TABLE_DATA", { tableId }).then((res) => {
|
|
@@ -669,20 +979,20 @@ function TableBlockClient({
|
|
|
669
979
|
console.error("[TableBlock] Failed to auto-fetch table data:", err);
|
|
670
980
|
});
|
|
671
981
|
}
|
|
672
|
-
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.
|
|
673
|
-
|
|
982
|
+
}, [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]);
|
|
983
|
+
useEffect2(() => {
|
|
674
984
|
if (error) {
|
|
675
985
|
showError(error, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E8\u05DB\u05D9\u05D1");
|
|
676
986
|
}
|
|
677
987
|
}, [error, showError]);
|
|
678
|
-
const [searchQuery, setSearchQuery] =
|
|
679
|
-
const [selectedIds, setSelectedIds] =
|
|
680
|
-
const [pendingDeletions, setPendingDeletions] =
|
|
681
|
-
const [isSaving, setIsSaving] =
|
|
682
|
-
const [isSaveSuccess, setIsSaveSuccess] =
|
|
683
|
-
const [relationOptions, setRelationOptions] =
|
|
684
|
-
const schemaColsString =
|
|
685
|
-
const refetchRelation =
|
|
988
|
+
const [searchQuery, setSearchQuery] = useState4("");
|
|
989
|
+
const [selectedIds, setSelectedIds] = useState4(/* @__PURE__ */ new Set());
|
|
990
|
+
const [pendingDeletions, setPendingDeletions] = useState4([]);
|
|
991
|
+
const [isSaving, setIsSaving] = useState4(false);
|
|
992
|
+
const [isSaveSuccess, setIsSaveSuccess] = useState4(false);
|
|
993
|
+
const [relationOptions, setRelationOptions] = useState4({});
|
|
994
|
+
const schemaColsString = useMemo2(() => JSON.stringify(localColumns || []), [localColumns]);
|
|
995
|
+
const refetchRelation = useCallback3(async (colName) => {
|
|
686
996
|
var _a;
|
|
687
997
|
let parsedCols = [];
|
|
688
998
|
try {
|
|
@@ -693,7 +1003,7 @@ function TableBlockClient({
|
|
|
693
1003
|
if (!col || ((_a = col.type) == null ? void 0 : _a.toUpperCase()) !== "RELATION" || !col.referencedTableId) return;
|
|
694
1004
|
try {
|
|
695
1005
|
if (executeAction) {
|
|
696
|
-
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId });
|
|
1006
|
+
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
|
|
697
1007
|
if (options && Array.isArray(options)) {
|
|
698
1008
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [colName]: options }));
|
|
699
1009
|
}
|
|
@@ -702,7 +1012,7 @@ function TableBlockClient({
|
|
|
702
1012
|
console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
|
|
703
1013
|
}
|
|
704
1014
|
}, [schemaColsString, executeAction]);
|
|
705
|
-
|
|
1015
|
+
useEffect2(() => {
|
|
706
1016
|
let parsedCols = [];
|
|
707
1017
|
try {
|
|
708
1018
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -716,7 +1026,7 @@ function TableBlockClient({
|
|
|
716
1026
|
refetchRelation(col.name);
|
|
717
1027
|
});
|
|
718
1028
|
}, [schemaColsString, refetchRelation]);
|
|
719
|
-
const filteredColumns =
|
|
1029
|
+
const filteredColumns = useMemo2(() => {
|
|
720
1030
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
721
1031
|
return (localColumns || []).filter((col) => !systemFields.includes(col.name));
|
|
722
1032
|
}, [localColumns]);
|
|
@@ -888,19 +1198,58 @@ function TableBlockClient({
|
|
|
888
1198
|
showError("\u05E8\u05DB\u05D9\u05D1 \u05D4\u05EA\u05E7\u05E9\u05D5\u05E8\u05EA \u05DC\u05D0 \u05D0\u05D5\u05EA\u05D7\u05DC", "\u05E9\u05D2\u05D9\u05D0\u05EA \u05EA\u05E7\u05E9\u05D5\u05E8\u05EA");
|
|
889
1199
|
return;
|
|
890
1200
|
}
|
|
891
|
-
const targetTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.
|
|
1201
|
+
const targetTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
892
1202
|
if (!targetTableId) {
|
|
893
1203
|
showError("\u05DC\u05D0 \u05E0\u05D9\u05EA\u05DF \u05DC\u05E9\u05DE\u05D5\u05E8: \u05DE\u05D6\u05D4\u05D4 \u05D4\u05D8\u05D1\u05DC\u05D4 \u05D7\u05E1\u05E8 (tableId)", "\u05E9\u05D2\u05D9\u05D0\u05EA \u05E9\u05DE\u05D9\u05E8\u05D4");
|
|
894
1204
|
return;
|
|
895
1205
|
}
|
|
1206
|
+
const tempToRealMap = {};
|
|
1207
|
+
const realRecordDataMap = {};
|
|
896
1208
|
if (dirty.added.length > 0) {
|
|
897
1209
|
const payload = dirty.added.map((row) => formatPayload(row.data));
|
|
898
|
-
await executeAction("CREATE_RECORD", { tableId: targetTableId, tableMetaId: targetTableId, records: payload });
|
|
1210
|
+
const res = await executeAction("CREATE_RECORD", { tableId: targetTableId, tableMetaId: targetTableId, records: payload });
|
|
1211
|
+
const createdList = Array.isArray(res) ? res : (res == null ? void 0 : res.data) && Array.isArray(res.data) ? res.data : res ? [res] : [];
|
|
1212
|
+
if (createdList && createdList.length > 0) {
|
|
1213
|
+
dirty.added.forEach((addedRow, idx) => {
|
|
1214
|
+
const created = createdList[idx];
|
|
1215
|
+
if (created) {
|
|
1216
|
+
const realId = String(created.id || created._id || "");
|
|
1217
|
+
if (realId) {
|
|
1218
|
+
tempToRealMap[addedRow.id] = realId;
|
|
1219
|
+
const createdData = created.data && typeof created.data === "object" ? created.data : addedRow.data;
|
|
1220
|
+
realRecordDataMap[realId] = __spreadValues(__spreadValues({}, addedRow.data), createdData);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
});
|
|
1224
|
+
setData((prev) => prev.map((row) => {
|
|
1225
|
+
if (tempToRealMap[row.id]) {
|
|
1226
|
+
const realId = tempToRealMap[row.id];
|
|
1227
|
+
return __spreadProps(__spreadValues({}, row), {
|
|
1228
|
+
id: realId,
|
|
1229
|
+
data: realRecordDataMap[realId] || row.data
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
return row;
|
|
1233
|
+
}));
|
|
1234
|
+
setSelectedIds((prev) => {
|
|
1235
|
+
let changed = false;
|
|
1236
|
+
const next = new Set(prev);
|
|
1237
|
+
Object.entries(tempToRealMap).forEach(([tempId, realId]) => {
|
|
1238
|
+
if (next.has(tempId)) {
|
|
1239
|
+
next.delete(tempId);
|
|
1240
|
+
next.add(realId);
|
|
1241
|
+
changed = true;
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
return changed ? next : prev;
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
899
1247
|
}
|
|
900
1248
|
if (Object.keys(dirty.modified).length > 0) {
|
|
901
1249
|
const payload = {};
|
|
902
1250
|
for (const [id, modData] of Object.entries(dirty.modified)) {
|
|
903
|
-
|
|
1251
|
+
const targetId = tempToRealMap[id] || id;
|
|
1252
|
+
payload[targetId] = formatPayload(modData);
|
|
904
1253
|
}
|
|
905
1254
|
await executeAction("UPDATE_RECORD", { tableId: targetTableId, tableMetaId: targetTableId, modifications: payload });
|
|
906
1255
|
}
|
|
@@ -916,10 +1265,15 @@ function TableBlockClient({
|
|
|
916
1265
|
}
|
|
917
1266
|
setBaseRecordsMap((prev) => {
|
|
918
1267
|
const next = new Map(prev);
|
|
919
|
-
dirty.added.forEach((r) =>
|
|
1268
|
+
dirty.added.forEach((r) => {
|
|
1269
|
+
const realId = tempToRealMap[r.id] || r.id;
|
|
1270
|
+
const dataToStore = realRecordDataMap[realId] || __spreadValues({}, r.data);
|
|
1271
|
+
next.set(realId, dataToStore);
|
|
1272
|
+
});
|
|
920
1273
|
Object.entries(dirty.modified).forEach(([id, mods]) => {
|
|
921
|
-
const
|
|
922
|
-
next.
|
|
1274
|
+
const realId = tempToRealMap[id] || id;
|
|
1275
|
+
const existing = next.get(realId) || {};
|
|
1276
|
+
next.set(realId, __spreadValues(__spreadValues({}, existing), mods));
|
|
923
1277
|
});
|
|
924
1278
|
dirty.deleted.forEach((id) => next.delete(id));
|
|
925
1279
|
return next;
|
|
@@ -937,7 +1291,7 @@ function TableBlockClient({
|
|
|
937
1291
|
setIsSaving(false);
|
|
938
1292
|
}
|
|
939
1293
|
};
|
|
940
|
-
const filteredData =
|
|
1294
|
+
const filteredData = useMemo2(() => {
|
|
941
1295
|
if (!searchQuery) return data;
|
|
942
1296
|
const lowerQuery = searchQuery.toLowerCase();
|
|
943
1297
|
return data.filter(
|
|
@@ -948,7 +1302,7 @@ function TableBlockClient({
|
|
|
948
1302
|
}, [data, searchQuery]);
|
|
949
1303
|
const isUpdatingActive = Boolean(isUpdating || isSaving);
|
|
950
1304
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
951
|
-
return /* @__PURE__ */
|
|
1305
|
+
return /* @__PURE__ */ jsxs5(
|
|
952
1306
|
"div",
|
|
953
1307
|
{
|
|
954
1308
|
id: componentId,
|
|
@@ -956,24 +1310,24 @@ function TableBlockClient({
|
|
|
956
1310
|
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs overflow-hidden ${className}`,
|
|
957
1311
|
dir: "rtl",
|
|
958
1312
|
children: [
|
|
959
|
-
errorMessage && /* @__PURE__ */
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
/* @__PURE__ */
|
|
1313
|
+
errorMessage && /* @__PURE__ */ jsx5("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
|
|
1314
|
+
/* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
1315
|
+
/* @__PURE__ */ jsx5("span", { children: errorMessage })
|
|
962
1316
|
] }) }),
|
|
963
|
-
/* @__PURE__ */
|
|
964
|
-
/* @__PURE__ */
|
|
965
|
-
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */
|
|
966
|
-
/* @__PURE__ */
|
|
1317
|
+
/* @__PURE__ */ jsxs5("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: [
|
|
1318
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
1319
|
+
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ jsx5("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ jsx5("span", { children: schema.title || schema.name }) }),
|
|
1320
|
+
/* @__PURE__ */ jsx5(
|
|
967
1321
|
"button",
|
|
968
1322
|
{
|
|
969
1323
|
onClick: handleAddRow,
|
|
970
1324
|
disabled: isLoading || isUpdatingActive,
|
|
971
1325
|
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",
|
|
972
1326
|
title: "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
973
|
-
children: /* @__PURE__ */
|
|
1327
|
+
children: /* @__PURE__ */ jsx5("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
974
1328
|
}
|
|
975
1329
|
),
|
|
976
|
-
/* @__PURE__ */
|
|
1330
|
+
/* @__PURE__ */ jsxs5(
|
|
977
1331
|
"button",
|
|
978
1332
|
{
|
|
979
1333
|
onClick: handleDeleteSelected,
|
|
@@ -981,14 +1335,14 @@ function TableBlockClient({
|
|
|
981
1335
|
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",
|
|
982
1336
|
title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
|
|
983
1337
|
children: [
|
|
984
|
-
/* @__PURE__ */
|
|
985
|
-
selectedIds.size > 0 && /* @__PURE__ */
|
|
1338
|
+
/* @__PURE__ */ jsx5("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("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" }) }),
|
|
1339
|
+
selectedIds.size > 0 && /* @__PURE__ */ jsx5("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 })
|
|
986
1340
|
]
|
|
987
1341
|
}
|
|
988
1342
|
),
|
|
989
|
-
/* @__PURE__ */
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
/* @__PURE__ */
|
|
1343
|
+
/* @__PURE__ */ jsx5("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
|
|
1344
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
|
|
1345
|
+
/* @__PURE__ */ jsx5(
|
|
992
1346
|
"input",
|
|
993
1347
|
{
|
|
994
1348
|
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
@@ -998,36 +1352,36 @@ function TableBlockClient({
|
|
|
998
1352
|
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"
|
|
999
1353
|
}
|
|
1000
1354
|
),
|
|
1001
|
-
/* @__PURE__ */
|
|
1355
|
+
/* @__PURE__ */ jsx5("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__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
|
|
1002
1356
|
] })
|
|
1003
1357
|
] }),
|
|
1004
|
-
/* @__PURE__ */
|
|
1005
|
-
isUpdatingActive ? /* @__PURE__ */
|
|
1006
|
-
/* @__PURE__ */
|
|
1358
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
|
|
1359
|
+
isUpdatingActive ? /* @__PURE__ */ jsxs5("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: [
|
|
1360
|
+
/* @__PURE__ */ jsx5("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
|
|
1007
1361
|
"\u05DE\u05E2\u05D3\u05DB\u05DF..."
|
|
1008
|
-
] }) : isSaveSuccess ? /* @__PURE__ */
|
|
1009
|
-
/* @__PURE__ */
|
|
1362
|
+
] }) : isSaveSuccess ? /* @__PURE__ */ jsxs5("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: [
|
|
1363
|
+
/* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
1010
1364
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
1011
|
-
] }) : hasChanges ? /* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1365
|
+
] }) : hasChanges ? /* @__PURE__ */ jsx5("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,
|
|
1366
|
+
/* @__PURE__ */ jsx5(
|
|
1013
1367
|
"button",
|
|
1014
1368
|
{
|
|
1015
1369
|
onClick: handleSave,
|
|
1016
1370
|
disabled: isUpdatingActive || isLoading || !hasChanges,
|
|
1017
1371
|
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"}`,
|
|
1018
|
-
children: /* @__PURE__ */
|
|
1372
|
+
children: /* @__PURE__ */ jsx5("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
|
|
1019
1373
|
}
|
|
1020
1374
|
)
|
|
1021
1375
|
] })
|
|
1022
1376
|
] }),
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
isLoading && /* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
/* @__PURE__ */
|
|
1377
|
+
/* @__PURE__ */ jsxs5("div", { className: "overflow-x-auto relative", children: [
|
|
1378
|
+
isLoading && /* @__PURE__ */ jsxs5("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
|
|
1379
|
+
/* @__PURE__ */ jsx5("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
|
|
1380
|
+
/* @__PURE__ */ jsx5("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
|
|
1027
1381
|
] }),
|
|
1028
|
-
/* @__PURE__ */
|
|
1029
|
-
/* @__PURE__ */
|
|
1030
|
-
/* @__PURE__ */
|
|
1382
|
+
/* @__PURE__ */ jsxs5("table", { className: "w-full text-sm text-right border-collapse", children: [
|
|
1383
|
+
/* @__PURE__ */ jsx5("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ jsxs5("tr", { children: [
|
|
1384
|
+
/* @__PURE__ */ jsx5("th", { className: "border-b border-l border-slate-200 p-2.5 w-10 text-center", children: /* @__PURE__ */ jsx5(
|
|
1031
1385
|
"input",
|
|
1032
1386
|
{
|
|
1033
1387
|
type: "checkbox",
|
|
@@ -1037,13 +1391,13 @@ function TableBlockClient({
|
|
|
1037
1391
|
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
1038
1392
|
}
|
|
1039
1393
|
) }),
|
|
1040
|
-
filteredColumns.map((col) => /* @__PURE__ */
|
|
1394
|
+
filteredColumns.map((col) => /* @__PURE__ */ jsx5("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))
|
|
1041
1395
|
] }) }),
|
|
1042
|
-
/* @__PURE__ */
|
|
1043
|
-
/* @__PURE__ */
|
|
1044
|
-
/* @__PURE__ */
|
|
1045
|
-
] }) }) }) : filteredData.map((row) => /* @__PURE__ */
|
|
1046
|
-
/* @__PURE__ */
|
|
1396
|
+
/* @__PURE__ */ jsx5("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: filteredColumns.length + 1, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
1397
|
+
/* @__PURE__ */ jsx5("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("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" }) }),
|
|
1398
|
+
/* @__PURE__ */ jsx5("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
|
|
1399
|
+
] }) }) }) : filteredData.map((row) => /* @__PURE__ */ jsxs5("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
|
|
1400
|
+
/* @__PURE__ */ jsx5("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", children: /* @__PURE__ */ jsx5(
|
|
1047
1401
|
"input",
|
|
1048
1402
|
{
|
|
1049
1403
|
type: "checkbox",
|
|
@@ -1065,7 +1419,7 @@ function TableBlockClient({
|
|
|
1065
1419
|
}
|
|
1066
1420
|
}
|
|
1067
1421
|
if (value === void 0) value = null;
|
|
1068
|
-
return /* @__PURE__ */
|
|
1422
|
+
return /* @__PURE__ */ jsx5("td", { className: "border-b border-l border-slate-200 p-0 relative", children: /* @__PURE__ */ jsx5(
|
|
1069
1423
|
InputComponent,
|
|
1070
1424
|
{
|
|
1071
1425
|
value,
|
|
@@ -1095,9 +1449,9 @@ function TableBlockClient({
|
|
|
1095
1449
|
}
|
|
1096
1450
|
|
|
1097
1451
|
// src/components/TableBlock/TableBlock.tsx
|
|
1098
|
-
import { jsx as
|
|
1452
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1099
1453
|
function TableBlock(props) {
|
|
1100
|
-
return /* @__PURE__ */
|
|
1454
|
+
return /* @__PURE__ */ jsx6(TableBlockClient, __spreadValues({}, props));
|
|
1101
1455
|
}
|
|
1102
1456
|
|
|
1103
1457
|
// src/registry.ts
|