@universe-platform/ui 0.1.0-beta.7 → 0.1.0-beta.9
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 +524 -18
- package/dist/index.d.mts +167 -45
- package/dist/index.d.ts +167 -45
- package/dist/index.js +2988 -715
- package/dist/index.mjs +3005 -706
- package/dist/phone.d.mts +38 -0
- package/dist/phone.d.ts +38 -0
- package/dist/phone.js +90 -0
- package/dist/phone.mjs +59 -0
- package/package.json +7 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
7
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -30,6 +32,51 @@ var __objRest = (source, exclude) => {
|
|
|
30
32
|
}
|
|
31
33
|
return target;
|
|
32
34
|
};
|
|
35
|
+
var __export = (target, all) => {
|
|
36
|
+
for (var name in all)
|
|
37
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
38
|
+
};
|
|
39
|
+
var __copyProps = (to, from, except, desc) => {
|
|
40
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
41
|
+
for (let key of __getOwnPropNames(from))
|
|
42
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
43
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
44
|
+
}
|
|
45
|
+
return to;
|
|
46
|
+
};
|
|
47
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
48
|
+
|
|
49
|
+
// src/index.ts
|
|
50
|
+
var src_exports = {};
|
|
51
|
+
__export(src_exports, {
|
|
52
|
+
ColumnHeaderTitle: () => ColumnHeaderTitle,
|
|
53
|
+
DatePickerCell: () => DatePickerCell,
|
|
54
|
+
LinkPickerCell: () => LinkPickerCell,
|
|
55
|
+
PASTEL_PALETTES: () => PASTEL_PALETTES,
|
|
56
|
+
RelationPickerCell: () => RelationPickerCell,
|
|
57
|
+
TableBlock: () => TableBlock,
|
|
58
|
+
TimePickerCell: () => TimePickerCell,
|
|
59
|
+
ToastContext: () => ToastContext,
|
|
60
|
+
ToastProvider: () => ToastProvider,
|
|
61
|
+
UNIVERSE_COMPONENTS: () => UNIVERSE_COMPONENTS,
|
|
62
|
+
calculateMinColumnWidth: () => calculateMinColumnWidth,
|
|
63
|
+
cn: () => cn,
|
|
64
|
+
formatConflictCellValue: () => formatConflictCellValue,
|
|
65
|
+
formatPhoneDisplay: () => formatPhoneDisplay,
|
|
66
|
+
formatTimeInput: () => formatTimeInput,
|
|
67
|
+
formatTimeIso: () => formatTimeIso,
|
|
68
|
+
getDeterministicPastelBadge: () => getDeterministicPastelBadge,
|
|
69
|
+
measureTextWidth: () => measureTextWidth,
|
|
70
|
+
normalizeRelationValue: () => normalizeRelationValue,
|
|
71
|
+
openWhatsAppChat: () => openWhatsAppChat,
|
|
72
|
+
parseLinkValue: () => parseLinkValue,
|
|
73
|
+
parseTimeParts: () => parseTimeParts,
|
|
74
|
+
resolveProtocol: () => resolveProtocol,
|
|
75
|
+
splitHeaderTitle: () => splitHeaderTitle,
|
|
76
|
+
useColumnReorder: () => useColumnReorder,
|
|
77
|
+
useColumnResize: () => useColumnResize,
|
|
78
|
+
useToast: () => useToast
|
|
79
|
+
});
|
|
33
80
|
|
|
34
81
|
// src/utils/cn.ts
|
|
35
82
|
import { clsx } from "clsx";
|
|
@@ -38,8 +85,77 @@ function cn(...inputs) {
|
|
|
38
85
|
return twMerge(clsx(inputs));
|
|
39
86
|
}
|
|
40
87
|
|
|
88
|
+
// src/utils/whatsapp.ts
|
|
89
|
+
function openWhatsAppChat(phone, defaultCountryCode = "972") {
|
|
90
|
+
if (!phone || typeof window === "undefined") return;
|
|
91
|
+
let cleaned = phone.replace(/\D/g, "");
|
|
92
|
+
if (cleaned.startsWith("0")) {
|
|
93
|
+
cleaned = defaultCountryCode + cleaned.substring(1);
|
|
94
|
+
}
|
|
95
|
+
const appUrl = `whatsapp://send?phone=${cleaned}`;
|
|
96
|
+
const webUrl = `https://web.whatsapp.com/send?phone=${cleaned}`;
|
|
97
|
+
const start = Date.now();
|
|
98
|
+
window.location.href = appUrl;
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
if (typeof document !== "undefined" && document.hasFocus() && Date.now() - start < 2e3) {
|
|
101
|
+
window.open(webUrl, "_blank", "noopener,noreferrer");
|
|
102
|
+
}
|
|
103
|
+
}, 1200);
|
|
104
|
+
}
|
|
105
|
+
function formatPhoneDisplay(phone) {
|
|
106
|
+
if (!phone) return "";
|
|
107
|
+
const digits = phone.replace(/\D/g, "");
|
|
108
|
+
if (digits.length === 10 && digits.startsWith("05")) {
|
|
109
|
+
return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
110
|
+
}
|
|
111
|
+
if (digits.length === 12 && digits.startsWith("9725")) {
|
|
112
|
+
const local = "0" + digits.slice(3);
|
|
113
|
+
return `${local.slice(0, 3)}-${local.slice(3, 6)}-${local.slice(6)}`;
|
|
114
|
+
}
|
|
115
|
+
return phone;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/utils/colors.ts
|
|
119
|
+
var PASTEL_PALETTES = [
|
|
120
|
+
{ bg: "bg-blue-50", text: "text-blue-700", border: "border-blue-200" },
|
|
121
|
+
{ bg: "bg-emerald-50", text: "text-emerald-700", border: "border-emerald-200" },
|
|
122
|
+
{ bg: "bg-violet-50", text: "text-violet-700", border: "border-violet-200" },
|
|
123
|
+
{ bg: "bg-amber-50", text: "text-amber-700", border: "border-amber-200" },
|
|
124
|
+
{ bg: "bg-rose-50", text: "text-rose-700", border: "border-rose-200" },
|
|
125
|
+
{ bg: "bg-cyan-50", text: "text-cyan-700", border: "border-cyan-200" },
|
|
126
|
+
{ bg: "bg-indigo-50", text: "text-indigo-700", border: "border-indigo-200" },
|
|
127
|
+
{ bg: "bg-teal-50", text: "text-teal-700", border: "border-teal-200" },
|
|
128
|
+
{ bg: "bg-sky-50", text: "text-sky-700", border: "border-sky-200" },
|
|
129
|
+
{ bg: "bg-fuchsia-50", text: "text-fuchsia-700", border: "border-fuchsia-200" },
|
|
130
|
+
{ bg: "bg-pink-50", text: "text-pink-700", border: "border-pink-200" },
|
|
131
|
+
{ bg: "bg-purple-50", text: "text-purple-700", border: "border-purple-200" },
|
|
132
|
+
{ bg: "bg-orange-50", text: "text-orange-700", border: "border-orange-200" },
|
|
133
|
+
{ bg: "bg-red-50", text: "text-red-700", border: "border-red-200" },
|
|
134
|
+
{ bg: "bg-lime-50", text: "text-lime-700", border: "border-lime-200" },
|
|
135
|
+
{ bg: "bg-green-50", text: "text-green-700", border: "border-green-200" },
|
|
136
|
+
{ bg: "bg-yellow-50", text: "text-yellow-700", border: "border-yellow-200" }
|
|
137
|
+
];
|
|
138
|
+
function getDeterministicPastelBadge(key) {
|
|
139
|
+
if (!key) return PASTEL_PALETTES[0];
|
|
140
|
+
let hash = 2166136261;
|
|
141
|
+
for (let i = 0; i < key.length; i++) {
|
|
142
|
+
hash ^= key.charCodeAt(i);
|
|
143
|
+
hash = Math.imul(hash, 16777619);
|
|
144
|
+
}
|
|
145
|
+
const index = Math.abs(hash) % PASTEL_PALETTES.length;
|
|
146
|
+
return PASTEL_PALETTES[index];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/types/data.types.ts
|
|
150
|
+
var data_types_exports = {};
|
|
151
|
+
__reExport(data_types_exports, shared_star);
|
|
152
|
+
import * as shared_star from "@universe-platform/shared";
|
|
153
|
+
|
|
154
|
+
// src/index.ts
|
|
155
|
+
__reExport(src_exports, data_types_exports);
|
|
156
|
+
|
|
41
157
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
42
|
-
import
|
|
158
|
+
import React9, { useState as useState10, useMemo as useMemo5, useEffect as useEffect8, useCallback as useCallback9, useRef as useRef7 } from "react";
|
|
43
159
|
|
|
44
160
|
// src/hooks/useToast.ts
|
|
45
161
|
import { useContext as useContext2 } from "react";
|
|
@@ -239,7 +355,7 @@ function useToast() {
|
|
|
239
355
|
}
|
|
240
356
|
|
|
241
357
|
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
242
|
-
import
|
|
358
|
+
import React7 from "react";
|
|
243
359
|
|
|
244
360
|
// src/components/TableBlock/fields/DrivePickerCell.tsx
|
|
245
361
|
import React2, { useState as useState2, useEffect } from "react";
|
|
@@ -696,219 +812,1091 @@ function DatePickerCell({ value, onChange, readOnly = false }) {
|
|
|
696
812
|
] });
|
|
697
813
|
}
|
|
698
814
|
|
|
699
|
-
// src/components/TableBlock/fields/
|
|
815
|
+
// src/components/TableBlock/fields/TimePickerCell.tsx
|
|
816
|
+
import { useState as useState4, useRef as useRef3, useEffect as useEffect3, useMemo as useMemo2, useCallback as useCallback3 } from "react";
|
|
817
|
+
import { Clock, X as X4 } from "lucide-react";
|
|
700
818
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
819
|
+
function parseTimeParts(val) {
|
|
820
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
821
|
+
if (typeof val === "string") {
|
|
822
|
+
const trimmed = val.trim();
|
|
823
|
+
if (!trimmed) return null;
|
|
824
|
+
const match = trimmed.match(/^(\d{1,2})[:.](\d{1,2})(?:[:.]\d{1,2})?$/);
|
|
825
|
+
if (match) {
|
|
826
|
+
const hour = parseInt(match[1], 10);
|
|
827
|
+
const minute = parseInt(match[2], 10);
|
|
828
|
+
if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59) {
|
|
829
|
+
return { hour, minute };
|
|
830
|
+
}
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
if (trimmed.includes("T")) {
|
|
834
|
+
const d = new Date(trimmed);
|
|
835
|
+
if (!isNaN(d.getTime())) {
|
|
836
|
+
return { hour: d.getHours(), minute: d.getMinutes() };
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
} else if (val instanceof Date && !isNaN(val.getTime())) {
|
|
840
|
+
return { hour: val.getHours(), minute: val.getMinutes() };
|
|
716
841
|
}
|
|
717
|
-
|
|
718
|
-
|
|
842
|
+
return null;
|
|
843
|
+
}
|
|
844
|
+
function formatTimeIso(hour, minute) {
|
|
845
|
+
const hh = String(hour).padStart(2, "0");
|
|
846
|
+
const mm = String(minute).padStart(2, "0");
|
|
847
|
+
return `${hh}:${mm}`;
|
|
848
|
+
}
|
|
849
|
+
function formatTimeInput(input) {
|
|
850
|
+
if (!input) return "";
|
|
851
|
+
const digits = String(input).replace(/\D/g, "");
|
|
852
|
+
if (!digits) return "";
|
|
853
|
+
if (digits.length === 1) {
|
|
854
|
+
const d = parseInt(digits, 10);
|
|
855
|
+
if (d > 2) {
|
|
856
|
+
return `0${d}:`;
|
|
857
|
+
}
|
|
858
|
+
return `${digits}:`;
|
|
719
859
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
if (typeof v === "string" && v.trim() !== "") return true;
|
|
725
|
-
if (typeof v === "number" && !isNaN(v)) return true;
|
|
726
|
-
return false;
|
|
727
|
-
});
|
|
728
|
-
if (fallbackField) return String(opt.data[fallbackField]);
|
|
860
|
+
const h = parseInt(digits.slice(0, 2), 10);
|
|
861
|
+
const hh = h > 23 ? "23" : digits.slice(0, 2);
|
|
862
|
+
if (digits.length === 2) {
|
|
863
|
+
return `${hh}:`;
|
|
729
864
|
}
|
|
730
|
-
if (
|
|
731
|
-
return
|
|
865
|
+
if (digits.length === 3) {
|
|
866
|
+
return `${hh}:${digits[2]}`;
|
|
732
867
|
}
|
|
733
|
-
|
|
868
|
+
const m = parseInt(digits.slice(2, 4), 10);
|
|
869
|
+
const mm = m > 59 ? "59" : digits.slice(2, 4);
|
|
870
|
+
return `${hh}:${mm}`;
|
|
734
871
|
}
|
|
735
|
-
var
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
872
|
+
var ALL_MINUTES = Array.from({ length: 60 }, (_, i) => i);
|
|
873
|
+
function TimePickerCell({ value, onChange, readOnly = false }) {
|
|
874
|
+
var _a, _b;
|
|
875
|
+
const [isOpen, setIsOpen] = useState4(false);
|
|
876
|
+
const containerRef = useRef3(null);
|
|
877
|
+
const hoursListRef = useRef3(null);
|
|
878
|
+
const minutesListRef = useRef3(null);
|
|
879
|
+
const [popoverPos, setPopoverPos] = useState4({ top: 0, right: 0 });
|
|
880
|
+
const parsedParts = useMemo2(() => parseTimeParts(value), [value]);
|
|
881
|
+
const displayString = useMemo2(() => {
|
|
882
|
+
return parsedParts ? formatTimeIso(parsedParts.hour, parsedParts.minute) : "";
|
|
883
|
+
}, [parsedParts]);
|
|
884
|
+
const [rawInput, setRawInput] = useState4(displayString);
|
|
885
|
+
useEffect3(() => {
|
|
886
|
+
setRawInput(displayString);
|
|
887
|
+
}, [displayString]);
|
|
888
|
+
const selectedHour = (_a = parsedParts == null ? void 0 : parsedParts.hour) != null ? _a : null;
|
|
889
|
+
const selectedMinute = (_b = parsedParts == null ? void 0 : parsedParts.minute) != null ? _b : null;
|
|
890
|
+
const updatePopoverPosition = useCallback3(() => {
|
|
891
|
+
if (containerRef.current) {
|
|
892
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
893
|
+
const right = window.innerWidth - rect.right;
|
|
894
|
+
const popoverHeight = 260;
|
|
895
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
896
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
897
|
+
setPopoverPos({
|
|
898
|
+
top: Math.max(10, rect.top - popoverHeight - 4),
|
|
899
|
+
right: Math.max(10, right)
|
|
900
|
+
});
|
|
901
|
+
} else {
|
|
902
|
+
setPopoverPos({
|
|
903
|
+
top: Math.min(window.innerHeight - popoverHeight - 10, rect.bottom + 4),
|
|
904
|
+
right: Math.max(10, right)
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}, []);
|
|
909
|
+
useEffect3(() => {
|
|
910
|
+
if (!isOpen) return;
|
|
911
|
+
updatePopoverPosition();
|
|
912
|
+
function handleScrollOrResize() {
|
|
913
|
+
updatePopoverPosition();
|
|
914
|
+
}
|
|
915
|
+
function handleClickOutside(event) {
|
|
916
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
917
|
+
const popoverEl = document.getElementById("time-picker-popover");
|
|
918
|
+
if (popoverEl && popoverEl.contains(event.target)) {
|
|
919
|
+
return;
|
|
756
920
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
},
|
|
760
|
-
TIME: ({ value, onChange }) => /* @__PURE__ */ jsx4(
|
|
761
|
-
"input",
|
|
762
|
-
{
|
|
763
|
-
type: "time",
|
|
764
|
-
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
765
|
-
value: value || "",
|
|
766
|
-
onChange: (e) => onChange(e.target.value)
|
|
921
|
+
setIsOpen(false);
|
|
922
|
+
}
|
|
767
923
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
924
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
925
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
926
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
927
|
+
return () => {
|
|
928
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
929
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
930
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
931
|
+
};
|
|
932
|
+
}, [isOpen, updatePopoverPosition]);
|
|
933
|
+
useEffect3(() => {
|
|
934
|
+
if (isOpen) {
|
|
935
|
+
if (selectedHour !== null && hoursListRef.current) {
|
|
936
|
+
const activeHourBtn = hoursListRef.current.querySelector('[data-selected="true"]');
|
|
937
|
+
if (activeHourBtn) {
|
|
938
|
+
activeHourBtn.scrollIntoView({ block: "center" });
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
if (selectedMinute !== null && minutesListRef.current) {
|
|
942
|
+
const activeMinBtn = minutesListRef.current.querySelector('[data-selected="true"]');
|
|
943
|
+
if (activeMinBtn) {
|
|
944
|
+
activeMinBtn.scrollIntoView({ block: "center" });
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}, [isOpen, selectedHour, selectedMinute]);
|
|
949
|
+
const handleInputChange = (e) => {
|
|
950
|
+
let val = e.target.value;
|
|
951
|
+
if (val.length === 2 && !val.includes(":") && rawInput.length === 1) {
|
|
952
|
+
val += ":";
|
|
953
|
+
}
|
|
954
|
+
if (val.length > 5) return;
|
|
955
|
+
setRawInput(val);
|
|
956
|
+
if (val.length === 5 && /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/.test(val)) {
|
|
957
|
+
onChange(val);
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
const handleKeyDown = (e) => {
|
|
961
|
+
if (e.key === "Enter") {
|
|
962
|
+
handleInputBlur();
|
|
963
|
+
setIsOpen(false);
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
if (e.key === "Backspace" || e.key === "Delete" || e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "Tab" || e.key === "Escape" || (e.ctrlKey || e.metaKey)) {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
if (e.key === ":") return;
|
|
970
|
+
if (!/^\d$/.test(e.key)) {
|
|
971
|
+
e.preventDefault();
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
const handleInputBlur = () => {
|
|
975
|
+
let text = rawInput.trim();
|
|
976
|
+
if (!text) {
|
|
977
|
+
onChange(null);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
if (!text.includes(":")) {
|
|
981
|
+
if (text.length === 1 || text.length === 2) {
|
|
982
|
+
text = `${text}:00`;
|
|
983
|
+
} else if (text.length === 3) {
|
|
984
|
+
text = `0${text[0]}:${text.slice(1)}`;
|
|
985
|
+
} else if (text.length === 4) {
|
|
986
|
+
text = `${text.slice(0, 2)}:${text.slice(2)}`;
|
|
987
|
+
}
|
|
988
|
+
} else if (text.endsWith(":")) {
|
|
989
|
+
text = `${text}00`;
|
|
990
|
+
}
|
|
991
|
+
const parts = parseTimeParts(text);
|
|
992
|
+
if (parts) {
|
|
993
|
+
const iso = formatTimeIso(parts.hour, parts.minute);
|
|
994
|
+
setRawInput(iso);
|
|
995
|
+
onChange(iso);
|
|
996
|
+
} else {
|
|
997
|
+
setRawInput(displayString);
|
|
786
998
|
}
|
|
787
|
-
|
|
999
|
+
};
|
|
1000
|
+
const handleSelectHour = (h) => {
|
|
1001
|
+
const m = selectedMinute != null ? selectedMinute : 0;
|
|
1002
|
+
const iso = formatTimeIso(h, m);
|
|
1003
|
+
onChange(iso);
|
|
1004
|
+
setRawInput(iso);
|
|
1005
|
+
};
|
|
1006
|
+
const handleSelectMinute = (m) => {
|
|
1007
|
+
const h = selectedHour != null ? selectedHour : (/* @__PURE__ */ new Date()).getHours();
|
|
1008
|
+
const iso = formatTimeIso(h, m);
|
|
1009
|
+
onChange(iso);
|
|
1010
|
+
setRawInput(iso);
|
|
1011
|
+
};
|
|
1012
|
+
const handleSetNow = () => {
|
|
1013
|
+
const now = /* @__PURE__ */ new Date();
|
|
1014
|
+
const iso = formatTimeIso(now.getHours(), now.getMinutes());
|
|
1015
|
+
onChange(iso);
|
|
1016
|
+
setRawInput(iso);
|
|
1017
|
+
};
|
|
1018
|
+
const handleClear = () => {
|
|
1019
|
+
onChange(null);
|
|
1020
|
+
setRawInput("");
|
|
1021
|
+
setIsOpen(false);
|
|
1022
|
+
};
|
|
1023
|
+
if (readOnly) {
|
|
1024
|
+
return /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5 px-2 h-full", children: [
|
|
1025
|
+
/* @__PURE__ */ jsx4(Clock, { className: "w-3.5 h-3.5 text-slate-400 shrink-0" }),
|
|
1026
|
+
/* @__PURE__ */ jsx4("span", { className: "text-sm font-normal text-slate-800 tracking-wider", dir: "ltr", children: displayString || "-" })
|
|
1027
|
+
] });
|
|
1028
|
+
}
|
|
1029
|
+
return /* @__PURE__ */ jsxs4("div", { ref: containerRef, className: "relative w-full h-full flex items-center px-2", children: [
|
|
1030
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5", children: [
|
|
788
1031
|
/* @__PURE__ */ jsx4(
|
|
789
|
-
"
|
|
1032
|
+
"button",
|
|
790
1033
|
{
|
|
791
|
-
type: "
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1034
|
+
type: "button",
|
|
1035
|
+
onClick: () => {
|
|
1036
|
+
setIsOpen((prev) => {
|
|
1037
|
+
const next = !prev;
|
|
1038
|
+
if (next) updatePopoverPosition();
|
|
1039
|
+
return next;
|
|
1040
|
+
});
|
|
1041
|
+
},
|
|
1042
|
+
className: "p-1 text-slate-400 hover:text-blue-600 rounded transition-colors cursor-pointer shrink-0",
|
|
1043
|
+
title: "\u05D1\u05D7\u05E8 \u05E9\u05E2\u05D4",
|
|
1044
|
+
children: /* @__PURE__ */ jsx4(Clock, { className: "w-4 h-4" })
|
|
796
1045
|
}
|
|
797
1046
|
),
|
|
798
1047
|
/* @__PURE__ */ jsx4(
|
|
799
1048
|
"input",
|
|
800
1049
|
{
|
|
801
|
-
type: "
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
"button",
|
|
810
|
-
{
|
|
811
|
-
onClick: () => setIsEditing(false),
|
|
812
|
-
className: "text-xs font-medium text-green-600 hover:text-green-700 p-1 mx-1 rounded transition-colors",
|
|
813
|
-
title: "\u05E9\u05DE\u05D5\u05E8",
|
|
814
|
-
children: "\u05E9\u05DE\u05D5\u05E8"
|
|
1050
|
+
type: "text",
|
|
1051
|
+
dir: "ltr",
|
|
1052
|
+
placeholder: "--:--",
|
|
1053
|
+
className: "w-14 h-7 px-1 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm font-normal text-slate-800 tracking-wider rounded text-center",
|
|
1054
|
+
value: rawInput,
|
|
1055
|
+
onChange: handleInputChange,
|
|
1056
|
+
onKeyDown: handleKeyDown,
|
|
1057
|
+
onBlur: handleInputBlur
|
|
815
1058
|
}
|
|
816
1059
|
)
|
|
817
|
-
] })
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
"input",
|
|
821
|
-
{
|
|
822
|
-
type: "checkbox",
|
|
823
|
-
checked: !!value,
|
|
824
|
-
onChange: (e) => onChange(e.target.checked),
|
|
825
|
-
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
826
|
-
}
|
|
827
|
-
) }),
|
|
828
|
-
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ jsx4(
|
|
829
|
-
DrivePickerCell,
|
|
830
|
-
{
|
|
831
|
-
value: value || [],
|
|
832
|
-
onChange,
|
|
833
|
-
column,
|
|
834
|
-
rowId,
|
|
835
|
-
tableName: context == null ? void 0 : context.tableName,
|
|
836
|
-
onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
|
|
837
|
-
context
|
|
838
|
-
}
|
|
839
|
-
),
|
|
840
|
-
RELATION: ({ value, onChange, column, context }) => {
|
|
841
|
-
var _a;
|
|
842
|
-
const options = ((_a = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a[column.name]) || [];
|
|
843
|
-
React4.useEffect(() => {
|
|
844
|
-
if (typeof value === "string" && value !== "" && options.length > 0) {
|
|
845
|
-
const isValidId = options.some((o) => String(o.id) === String(value));
|
|
846
|
-
if (!isValidId) {
|
|
847
|
-
const match = options.find(
|
|
848
|
-
(o) => String(getRelationDisplayLabel(o, column)).trim() === String(value).trim()
|
|
849
|
-
);
|
|
850
|
-
if (match) {
|
|
851
|
-
onChange(match.id);
|
|
852
|
-
} else {
|
|
853
|
-
onChange("");
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
}, [value, options, column, onChange]);
|
|
858
|
-
const processedOptions = options.map((opt) => __spreadProps(__spreadValues({}, opt), {
|
|
859
|
-
_displayLabel: getRelationDisplayLabel(opt, column)
|
|
860
|
-
}));
|
|
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");
|
|
862
|
-
return /* @__PURE__ */ jsxs4(
|
|
863
|
-
"select",
|
|
1060
|
+
] }),
|
|
1061
|
+
isOpen && /* @__PURE__ */ jsxs4(
|
|
1062
|
+
"div",
|
|
864
1063
|
{
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
if (context == null ? void 0 : context.refetchRelation) {
|
|
870
|
-
context.refetchRelation(column.name);
|
|
871
|
-
}
|
|
872
|
-
},
|
|
1064
|
+
id: "time-picker-popover",
|
|
1065
|
+
dir: "rtl",
|
|
1066
|
+
style: { top: `${popoverPos.top}px`, right: `${popoverPos.right}px` },
|
|
1067
|
+
className: "fixed z-[99999] w-64 bg-white rounded-xl shadow-2xl border border-slate-200 p-3.5 animate-in fade-in zoom-in-95 duration-150",
|
|
873
1068
|
children: [
|
|
874
|
-
/* @__PURE__ */
|
|
875
|
-
|
|
1069
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between pb-2 mb-2 border-b border-slate-100", children: [
|
|
1070
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5 text-xs font-semibold text-slate-700", children: [
|
|
1071
|
+
/* @__PURE__ */ jsx4(Clock, { className: "w-3.5 h-3.5 text-blue-600" }),
|
|
1072
|
+
/* @__PURE__ */ jsx4("span", { children: "\u05D1\u05D7\u05D9\u05E8\u05EA \u05E9\u05E2\u05D4" })
|
|
1073
|
+
] }),
|
|
1074
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1", children: [
|
|
1075
|
+
/* @__PURE__ */ jsx4(
|
|
1076
|
+
"button",
|
|
1077
|
+
{
|
|
1078
|
+
type: "button",
|
|
1079
|
+
onClick: handleSetNow,
|
|
1080
|
+
className: "text-[11px] px-1.5 py-0.5 font-medium text-blue-600 hover:bg-blue-50 rounded transition-colors cursor-pointer",
|
|
1081
|
+
children: "\u05E2\u05DB\u05E9\u05D9\u05D5"
|
|
1082
|
+
}
|
|
1083
|
+
),
|
|
1084
|
+
displayString && /* @__PURE__ */ jsx4(
|
|
1085
|
+
"button",
|
|
1086
|
+
{
|
|
1087
|
+
type: "button",
|
|
1088
|
+
onClick: handleClear,
|
|
1089
|
+
className: "text-[11px] px-1.5 py-0.5 font-medium text-slate-500 hover:text-rose-600 hover:bg-rose-50 rounded transition-colors cursor-pointer",
|
|
1090
|
+
children: "\u05E0\u05E7\u05D4"
|
|
1091
|
+
}
|
|
1092
|
+
),
|
|
1093
|
+
/* @__PURE__ */ jsx4(
|
|
1094
|
+
"button",
|
|
1095
|
+
{
|
|
1096
|
+
type: "button",
|
|
1097
|
+
onClick: () => setIsOpen(false),
|
|
1098
|
+
className: "p-0.5 text-slate-400 hover:text-slate-600 rounded transition-colors cursor-pointer mr-0.5",
|
|
1099
|
+
title: "\u05E1\u05D2\u05D5\u05E8",
|
|
1100
|
+
children: /* @__PURE__ */ jsx4(X4, { className: "w-3.5 h-3.5" })
|
|
1101
|
+
}
|
|
1102
|
+
)
|
|
1103
|
+
] })
|
|
1104
|
+
] }),
|
|
1105
|
+
/* @__PURE__ */ jsx4("div", { className: "flex items-center justify-center py-1 mb-2 bg-slate-50 border border-slate-100 rounded-lg", children: /* @__PURE__ */ jsx4("span", { className: "text-base font-semibold text-slate-800 tracking-wider", dir: "ltr", children: displayString || "--:--" }) }),
|
|
1106
|
+
/* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
1107
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1108
|
+
/* @__PURE__ */ jsx4("div", { className: "text-[11px] font-medium text-slate-400 text-center mb-1", children: "\u05D3\u05E7\u05D5\u05EA" }),
|
|
1109
|
+
/* @__PURE__ */ jsx4(
|
|
1110
|
+
"div",
|
|
1111
|
+
{
|
|
1112
|
+
ref: minutesListRef,
|
|
1113
|
+
className: "h-44 overflow-y-auto border border-slate-100 rounded-lg p-1 space-y-0.5 bg-slate-50/50",
|
|
1114
|
+
children: ALL_MINUTES.map((m) => {
|
|
1115
|
+
const isSelected = selectedMinute === m;
|
|
1116
|
+
return /* @__PURE__ */ jsx4(
|
|
1117
|
+
"button",
|
|
1118
|
+
{
|
|
1119
|
+
type: "button",
|
|
1120
|
+
"data-selected": isSelected,
|
|
1121
|
+
onClick: () => handleSelectMinute(m),
|
|
1122
|
+
className: `w-full py-1 text-xs text-center rounded transition-colors cursor-pointer ${isSelected ? "bg-blue-600 text-white font-medium shadow-xs" : "text-slate-700 hover:bg-slate-200/70"}`,
|
|
1123
|
+
children: String(m).padStart(2, "0")
|
|
1124
|
+
},
|
|
1125
|
+
m
|
|
1126
|
+
);
|
|
1127
|
+
})
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] }),
|
|
1131
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1132
|
+
/* @__PURE__ */ jsx4("div", { className: "text-[11px] font-medium text-slate-400 text-center mb-1", children: "\u05E9\u05E2\u05D5\u05EA" }),
|
|
1133
|
+
/* @__PURE__ */ jsx4(
|
|
1134
|
+
"div",
|
|
1135
|
+
{
|
|
1136
|
+
ref: hoursListRef,
|
|
1137
|
+
className: "h-44 overflow-y-auto border border-slate-100 rounded-lg p-1 space-y-0.5 bg-slate-50/50",
|
|
1138
|
+
children: Array.from({ length: 24 }, (_, i) => {
|
|
1139
|
+
const isSelected = selectedHour === i;
|
|
1140
|
+
return /* @__PURE__ */ jsx4(
|
|
1141
|
+
"button",
|
|
1142
|
+
{
|
|
1143
|
+
type: "button",
|
|
1144
|
+
"data-selected": isSelected,
|
|
1145
|
+
onClick: () => handleSelectHour(i),
|
|
1146
|
+
className: `w-full py-1 text-xs text-center rounded transition-colors cursor-pointer ${isSelected ? "bg-blue-600 text-white font-medium shadow-xs" : "text-slate-700 hover:bg-slate-200/70"}`,
|
|
1147
|
+
children: String(i).padStart(2, "0")
|
|
1148
|
+
},
|
|
1149
|
+
i
|
|
1150
|
+
);
|
|
1151
|
+
})
|
|
1152
|
+
}
|
|
1153
|
+
)
|
|
1154
|
+
] })
|
|
1155
|
+
] })
|
|
876
1156
|
]
|
|
877
1157
|
}
|
|
878
|
-
)
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
)
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
)
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1158
|
+
)
|
|
1159
|
+
] });
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// src/components/TableBlock/fields/LinkPickerCell.tsx
|
|
1163
|
+
import { useState as useState5, useRef as useRef4, useEffect as useEffect4, useCallback as useCallback4 } from "react";
|
|
1164
|
+
import { Link2, ExternalLink, X as X5, Check as Check2, Trash2 } from "lucide-react";
|
|
1165
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1166
|
+
function parseLinkValue(val) {
|
|
1167
|
+
if (!val) return { url: "", label: "" };
|
|
1168
|
+
if (typeof val === "string") {
|
|
1169
|
+
return { url: val.trim(), label: "" };
|
|
1170
|
+
}
|
|
1171
|
+
if (typeof val === "object") {
|
|
1172
|
+
return {
|
|
1173
|
+
url: typeof val.url === "string" ? val.url.trim() : "",
|
|
1174
|
+
label: typeof val.label === "string" ? val.label.trim() : ""
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
return { url: "", label: "" };
|
|
1178
|
+
}
|
|
1179
|
+
function resolveProtocol(url) {
|
|
1180
|
+
const trimmed = url.trim();
|
|
1181
|
+
if (!trimmed) return "";
|
|
1182
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
1183
|
+
return trimmed;
|
|
1184
|
+
}
|
|
1185
|
+
return `https://${trimmed}`;
|
|
1186
|
+
}
|
|
1187
|
+
function LinkPickerCell({ value, onChange, readOnly = false }) {
|
|
1188
|
+
const [isOpen, setIsOpen] = useState5(false);
|
|
1189
|
+
const containerRef = useRef4(null);
|
|
1190
|
+
const urlInputRef = useRef4(null);
|
|
1191
|
+
const [popoverPos, setPopoverPos] = useState5({ top: 0, right: 0 });
|
|
1192
|
+
const currentLink = parseLinkValue(value);
|
|
1193
|
+
const [draftUrl, setDraftUrl] = useState5(currentLink.url);
|
|
1194
|
+
const [draftLabel, setDraftLabel] = useState5(currentLink.label);
|
|
1195
|
+
const draftUrlRef = useRef4(draftUrl);
|
|
1196
|
+
const draftLabelRef = useRef4(draftLabel);
|
|
1197
|
+
useEffect4(() => {
|
|
1198
|
+
draftUrlRef.current = draftUrl;
|
|
1199
|
+
}, [draftUrl]);
|
|
1200
|
+
useEffect4(() => {
|
|
1201
|
+
draftLabelRef.current = draftLabel;
|
|
1202
|
+
}, [draftLabel]);
|
|
1203
|
+
useEffect4(() => {
|
|
1204
|
+
if (!isOpen) {
|
|
1205
|
+
setDraftUrl(currentLink.url);
|
|
1206
|
+
setDraftLabel(currentLink.label);
|
|
1207
|
+
}
|
|
1208
|
+
}, [value, isOpen]);
|
|
1209
|
+
const updatePopoverPosition = useCallback4(() => {
|
|
1210
|
+
if (containerRef.current) {
|
|
1211
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
1212
|
+
const right = window.innerWidth - rect.right;
|
|
1213
|
+
const popoverHeight = 220;
|
|
1214
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1215
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
1216
|
+
setPopoverPos({
|
|
1217
|
+
top: Math.max(10, rect.top - popoverHeight - 4),
|
|
1218
|
+
right: Math.max(10, right)
|
|
1219
|
+
});
|
|
1220
|
+
} else {
|
|
1221
|
+
setPopoverPos({
|
|
1222
|
+
top: Math.min(window.innerHeight - popoverHeight - 10, rect.bottom + 4),
|
|
1223
|
+
right: Math.max(10, right)
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}, []);
|
|
1228
|
+
const handleSaveAndClose = useCallback4(() => {
|
|
1229
|
+
const rawUrl = draftUrlRef.current.trim();
|
|
1230
|
+
const rawLabel = draftLabelRef.current.trim();
|
|
1231
|
+
if (!rawUrl) {
|
|
1232
|
+
onChange(null);
|
|
1233
|
+
} else {
|
|
1234
|
+
const resolved = resolveProtocol(rawUrl);
|
|
1235
|
+
onChange({
|
|
1236
|
+
url: resolved,
|
|
1237
|
+
label: rawLabel
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
setIsOpen(false);
|
|
1241
|
+
}, [onChange]);
|
|
1242
|
+
const handleOpen = () => {
|
|
1243
|
+
setDraftUrl(currentLink.url);
|
|
1244
|
+
setDraftLabel(currentLink.label);
|
|
1245
|
+
updatePopoverPosition();
|
|
1246
|
+
setIsOpen(true);
|
|
1247
|
+
setTimeout(() => {
|
|
1248
|
+
var _a;
|
|
1249
|
+
(_a = urlInputRef.current) == null ? void 0 : _a.focus();
|
|
1250
|
+
}, 50);
|
|
1251
|
+
};
|
|
1252
|
+
useEffect4(() => {
|
|
1253
|
+
if (!isOpen) return;
|
|
1254
|
+
updatePopoverPosition();
|
|
1255
|
+
function handleScrollOrResize() {
|
|
1256
|
+
updatePopoverPosition();
|
|
1257
|
+
}
|
|
1258
|
+
function handleClickOutside(event) {
|
|
1259
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1260
|
+
const popoverEl = document.getElementById("link-picker-popover");
|
|
1261
|
+
if (popoverEl && popoverEl.contains(event.target)) {
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
handleSaveAndClose();
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
1268
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
1269
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1270
|
+
return () => {
|
|
1271
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
1272
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
1273
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1274
|
+
};
|
|
1275
|
+
}, [isOpen, updatePopoverPosition, handleSaveAndClose]);
|
|
1276
|
+
const handleClear = () => {
|
|
1277
|
+
onChange(null);
|
|
1278
|
+
setDraftUrl("");
|
|
1279
|
+
setDraftLabel("");
|
|
1280
|
+
setIsOpen(false);
|
|
1281
|
+
};
|
|
1282
|
+
if (readOnly) {
|
|
1283
|
+
if (!currentLink.url) {
|
|
1284
|
+
return /* @__PURE__ */ jsx5("span", { className: "px-2 py-1 flex items-center h-full text-slate-400 text-xs italic", children: "-" });
|
|
1285
|
+
}
|
|
1286
|
+
return /* @__PURE__ */ jsx5("div", { className: "px-2 py-1 flex items-center h-full w-full", children: /* @__PURE__ */ jsxs5(
|
|
1287
|
+
"a",
|
|
1288
|
+
{
|
|
1289
|
+
href: currentLink.url,
|
|
1290
|
+
target: "_blank",
|
|
1291
|
+
rel: "noopener noreferrer",
|
|
1292
|
+
className: "text-blue-600 hover:underline truncate text-sm flex items-center gap-1.5",
|
|
1293
|
+
onClick: (e) => e.stopPropagation(),
|
|
1294
|
+
children: [
|
|
1295
|
+
/* @__PURE__ */ jsx5(ExternalLink, { className: "w-3.5 h-3.5 shrink-0 text-blue-500" }),
|
|
1296
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: currentLink.label || currentLink.url })
|
|
1297
|
+
]
|
|
1298
|
+
}
|
|
1299
|
+
) });
|
|
1300
|
+
}
|
|
1301
|
+
return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "relative w-full h-full flex items-center justify-between px-2 py-1 group", children: [
|
|
1302
|
+
currentLink.url ? /* @__PURE__ */ jsxs5(
|
|
1303
|
+
"a",
|
|
1304
|
+
{
|
|
1305
|
+
href: currentLink.url,
|
|
1306
|
+
target: "_blank",
|
|
1307
|
+
rel: "noopener noreferrer",
|
|
1308
|
+
className: "text-blue-600 hover:underline truncate text-sm flex items-center gap-1.5 flex-1 min-w-0",
|
|
1309
|
+
onClick: (e) => e.stopPropagation(),
|
|
1310
|
+
title: currentLink.url,
|
|
1311
|
+
children: [
|
|
1312
|
+
/* @__PURE__ */ jsx5(ExternalLink, { className: "w-3.5 h-3.5 shrink-0 text-blue-500" }),
|
|
1313
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: currentLink.label || currentLink.url })
|
|
1314
|
+
]
|
|
1315
|
+
}
|
|
1316
|
+
) : /* @__PURE__ */ jsx5(
|
|
1317
|
+
"span",
|
|
1318
|
+
{
|
|
1319
|
+
className: "text-slate-400 italic text-sm flex-1 cursor-pointer select-none",
|
|
1320
|
+
onClick: handleOpen,
|
|
1321
|
+
children: "\u05E8\u05D9\u05E7"
|
|
1322
|
+
}
|
|
1323
|
+
),
|
|
1324
|
+
/* @__PURE__ */ jsx5(
|
|
1325
|
+
"button",
|
|
1326
|
+
{
|
|
1327
|
+
type: "button",
|
|
1328
|
+
onClick: (e) => {
|
|
1329
|
+
e.stopPropagation();
|
|
1330
|
+
if (isOpen) {
|
|
1331
|
+
handleSaveAndClose();
|
|
1332
|
+
} else {
|
|
1333
|
+
handleOpen();
|
|
1334
|
+
}
|
|
1335
|
+
},
|
|
1336
|
+
className: "p-1 text-slate-400 hover:text-blue-600 hover:bg-slate-100 rounded transition-colors cursor-pointer shrink-0 ml-1",
|
|
1337
|
+
title: "\u05E2\u05E8\u05D9\u05DB\u05EA \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1338
|
+
children: /* @__PURE__ */ jsx5(Link2, { className: "w-3.5 h-3.5" })
|
|
1339
|
+
}
|
|
1340
|
+
),
|
|
1341
|
+
isOpen && /* @__PURE__ */ jsxs5(
|
|
1342
|
+
"div",
|
|
1343
|
+
{
|
|
1344
|
+
id: "link-picker-popover",
|
|
1345
|
+
dir: "rtl",
|
|
1346
|
+
style: { top: `${popoverPos.top}px`, right: `${popoverPos.right}px` },
|
|
1347
|
+
className: "fixed z-[99999] w-[280px] bg-white rounded-xl shadow-2xl border border-slate-200 p-3.5 animate-in fade-in zoom-in-95 duration-150",
|
|
1348
|
+
onClick: (e) => e.stopPropagation(),
|
|
1349
|
+
children: [
|
|
1350
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between pb-2 mb-3 border-b border-slate-100", children: [
|
|
1351
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1.5 text-xs font-semibold text-slate-700", children: [
|
|
1352
|
+
/* @__PURE__ */ jsx5(Link2, { className: "w-3.5 h-3.5 text-blue-600" }),
|
|
1353
|
+
/* @__PURE__ */ jsx5("span", { children: "\u05E2\u05E8\u05D9\u05DB\u05EA \u05E7\u05D9\u05E9\u05D5\u05E8" })
|
|
1354
|
+
] }),
|
|
1355
|
+
/* @__PURE__ */ jsx5(
|
|
1356
|
+
"button",
|
|
1357
|
+
{
|
|
1358
|
+
type: "button",
|
|
1359
|
+
onClick: handleSaveAndClose,
|
|
1360
|
+
className: "p-0.5 text-slate-400 hover:text-slate-600 rounded transition-colors cursor-pointer",
|
|
1361
|
+
title: "\u05E1\u05D2\u05D5\u05E8 \u05D5\u05E9\u05DE\u05D5\u05E8",
|
|
1362
|
+
children: /* @__PURE__ */ jsx5(X5, { className: "w-3.5 h-3.5" })
|
|
1363
|
+
}
|
|
1364
|
+
)
|
|
1365
|
+
] }),
|
|
1366
|
+
/* @__PURE__ */ jsxs5("div", { className: "space-y-2.5 mb-3.5", children: [
|
|
1367
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1368
|
+
/* @__PURE__ */ jsxs5("label", { className: "block text-xs font-medium text-slate-700 mb-1", children: [
|
|
1369
|
+
"\u05DB\u05EA\u05D5\u05D1\u05EA URL ",
|
|
1370
|
+
/* @__PURE__ */ jsx5("span", { className: "text-rose-500", children: "*" })
|
|
1371
|
+
] }),
|
|
1372
|
+
/* @__PURE__ */ jsx5(
|
|
1373
|
+
"input",
|
|
1374
|
+
{
|
|
1375
|
+
ref: urlInputRef,
|
|
1376
|
+
type: "text",
|
|
1377
|
+
dir: "ltr",
|
|
1378
|
+
placeholder: "https://...",
|
|
1379
|
+
className: "w-full h-8 px-2.5 bg-slate-50 border border-slate-200 rounded-lg text-sm text-slate-800 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 transition-colors",
|
|
1380
|
+
value: draftUrl,
|
|
1381
|
+
onChange: (e) => setDraftUrl(e.target.value),
|
|
1382
|
+
onKeyDown: (e) => {
|
|
1383
|
+
if (e.key === "Enter") {
|
|
1384
|
+
e.preventDefault();
|
|
1385
|
+
handleSaveAndClose();
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
)
|
|
1390
|
+
] }),
|
|
1391
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1392
|
+
/* @__PURE__ */ jsxs5("label", { className: "block text-xs font-medium text-slate-700 mb-1", children: [
|
|
1393
|
+
"\u05D8\u05E7\u05E1\u05D8 \u05DC\u05EA\u05E6\u05D5\u05D2\u05D4 ",
|
|
1394
|
+
/* @__PURE__ */ jsx5("span", { className: "text-slate-400 font-normal", children: "(\u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9)" })
|
|
1395
|
+
] }),
|
|
1396
|
+
/* @__PURE__ */ jsx5(
|
|
1397
|
+
"input",
|
|
1398
|
+
{
|
|
1399
|
+
type: "text",
|
|
1400
|
+
placeholder: "\u05E9\u05DD \u05D4\u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1401
|
+
className: "w-full h-8 px-2.5 bg-slate-50 border border-slate-200 rounded-lg text-sm text-slate-800 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 transition-colors",
|
|
1402
|
+
value: draftLabel,
|
|
1403
|
+
onChange: (e) => setDraftLabel(e.target.value),
|
|
1404
|
+
onKeyDown: (e) => {
|
|
1405
|
+
if (e.key === "Enter") {
|
|
1406
|
+
e.preventDefault();
|
|
1407
|
+
handleSaveAndClose();
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
)
|
|
1412
|
+
] })
|
|
1413
|
+
] }),
|
|
1414
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between pt-2 border-t border-slate-100", children: [
|
|
1415
|
+
currentLink.url ? /* @__PURE__ */ jsxs5(
|
|
1416
|
+
"button",
|
|
1417
|
+
{
|
|
1418
|
+
type: "button",
|
|
1419
|
+
onClick: handleClear,
|
|
1420
|
+
className: "inline-flex items-center gap-1 text-xs text-rose-600 hover:text-rose-700 hover:bg-rose-50 px-2 py-1 rounded transition-colors cursor-pointer",
|
|
1421
|
+
title: "\u05DE\u05D7\u05E7 \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1422
|
+
children: [
|
|
1423
|
+
/* @__PURE__ */ jsx5(Trash2, { className: "w-3 h-3" }),
|
|
1424
|
+
/* @__PURE__ */ jsx5("span", { children: "\u05E0\u05E7\u05D4" })
|
|
1425
|
+
]
|
|
1426
|
+
}
|
|
1427
|
+
) : /* @__PURE__ */ jsx5("span", {}),
|
|
1428
|
+
/* @__PURE__ */ jsxs5(
|
|
1429
|
+
"button",
|
|
1430
|
+
{
|
|
1431
|
+
type: "button",
|
|
1432
|
+
onClick: handleSaveAndClose,
|
|
1433
|
+
className: "inline-flex items-center gap-1 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 px-3 py-1.5 rounded-lg shadow-xs transition-colors cursor-pointer",
|
|
1434
|
+
children: [
|
|
1435
|
+
/* @__PURE__ */ jsx5(Check2, { className: "w-3.5 h-3.5" }),
|
|
1436
|
+
/* @__PURE__ */ jsx5("span", { children: "\u05E9\u05DE\u05D5\u05E8" })
|
|
1437
|
+
]
|
|
1438
|
+
}
|
|
1439
|
+
)
|
|
1440
|
+
] })
|
|
1441
|
+
]
|
|
1442
|
+
}
|
|
1443
|
+
)
|
|
1444
|
+
] });
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
// src/components/TableBlock/fields/RelationPickerCell.tsx
|
|
1448
|
+
import { useState as useState6, useRef as useRef5, useEffect as useEffect5, useCallback as useCallback5, useMemo as useMemo3 } from "react";
|
|
1449
|
+
import { X as X6, Search, Check as Check3, ChevronDown } from "lucide-react";
|
|
1450
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1451
|
+
function isRawObjectId(str) {
|
|
1452
|
+
if (typeof str !== "string") return false;
|
|
1453
|
+
const trimmed = str.trim();
|
|
1454
|
+
return /^[0-9a-fA-F]{24}$/.test(trimmed) || trimmed.startsWith("temp_");
|
|
1455
|
+
}
|
|
1456
|
+
function normalizeRelationValue(val) {
|
|
1457
|
+
if (val === null || val === void 0 || val === "") return [];
|
|
1458
|
+
if (Array.isArray(val)) {
|
|
1459
|
+
return val.map((item) => {
|
|
1460
|
+
if (typeof item === "string") return item.trim();
|
|
1461
|
+
if (typeof item === "object" && item !== null) {
|
|
1462
|
+
return String(item.id || item._id || item.value || "").trim();
|
|
1463
|
+
}
|
|
1464
|
+
return String(item).trim();
|
|
1465
|
+
}).filter((id) => Boolean(id) && id !== "");
|
|
1466
|
+
}
|
|
1467
|
+
if (typeof val === "string") {
|
|
1468
|
+
const trimmed = val.trim();
|
|
1469
|
+
return trimmed ? [trimmed] : [];
|
|
1470
|
+
}
|
|
1471
|
+
if (typeof val === "object" && val !== null) {
|
|
1472
|
+
const id = String(val.id || val._id || val.value || "").trim();
|
|
1473
|
+
return id ? [id] : [];
|
|
1474
|
+
}
|
|
1475
|
+
return [];
|
|
1476
|
+
}
|
|
1477
|
+
function resolveRelationLabel(opt, column) {
|
|
1478
|
+
var _a;
|
|
1479
|
+
if (!opt) return "";
|
|
1480
|
+
const displayField = (_a = column.config) == null ? void 0 : _a.displayField;
|
|
1481
|
+
if (displayField && opt.data) {
|
|
1482
|
+
const val = opt.data[displayField];
|
|
1483
|
+
if (val !== void 0 && val !== null) {
|
|
1484
|
+
const s = String(val).trim();
|
|
1485
|
+
if (s !== "" && !isRawObjectId(s)) {
|
|
1486
|
+
return s;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
if (opt.label && typeof opt.label === "string") {
|
|
1491
|
+
const s = opt.label.trim();
|
|
1492
|
+
if (s !== "" && !isRawObjectId(s) && s !== opt.id) {
|
|
1493
|
+
return s;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
if (opt.data) {
|
|
1497
|
+
const defaultLabel = opt.data.name || opt.data.title || opt.data.fullName;
|
|
1498
|
+
if (defaultLabel !== void 0 && defaultLabel !== null) {
|
|
1499
|
+
const s = String(defaultLabel).trim();
|
|
1500
|
+
if (s !== "" && !isRawObjectId(s)) {
|
|
1501
|
+
return s;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
return "";
|
|
1506
|
+
}
|
|
1507
|
+
function RelationPickerCell({
|
|
1508
|
+
value,
|
|
1509
|
+
onChange,
|
|
1510
|
+
column,
|
|
1511
|
+
context,
|
|
1512
|
+
rowId,
|
|
1513
|
+
readOnly = false
|
|
1514
|
+
}) {
|
|
1515
|
+
var _a;
|
|
1516
|
+
const [isOpen, setIsOpen] = useState6(false);
|
|
1517
|
+
const [searchQuery, setSearchQuery] = useState6("");
|
|
1518
|
+
const containerRef = useRef5(null);
|
|
1519
|
+
const searchInputRef = useRef5(null);
|
|
1520
|
+
const allowMultiple = Boolean((_a = column.config) == null ? void 0 : _a.allowMultiple);
|
|
1521
|
+
const selectedIds = useMemo3(() => normalizeRelationValue(value), [value]);
|
|
1522
|
+
const isStandalone = !context || context.relationOptions === void 0;
|
|
1523
|
+
const optionsLoaded = isStandalone || context.relationOptions[column.name] !== void 0;
|
|
1524
|
+
const rawOptions = useMemo3(() => {
|
|
1525
|
+
var _a2;
|
|
1526
|
+
return ((_a2 = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a2[column.name]) || [];
|
|
1527
|
+
}, [context == null ? void 0 : context.relationOptions, column.name]);
|
|
1528
|
+
const processedOptions = useMemo3(() => {
|
|
1529
|
+
return rawOptions.map((opt) => {
|
|
1530
|
+
const label = resolveRelationLabel(opt, column);
|
|
1531
|
+
return {
|
|
1532
|
+
id: String(opt.id),
|
|
1533
|
+
_displayLabel: label
|
|
1534
|
+
};
|
|
1535
|
+
}).filter((opt) => opt._displayLabel && opt._displayLabel.trim() !== "" && !isRawObjectId(opt._displayLabel));
|
|
1536
|
+
}, [rawOptions, column]);
|
|
1537
|
+
const getDisplayForId = useCallback5((id) => {
|
|
1538
|
+
const found = processedOptions.find((o) => String(o.id) === String(id));
|
|
1539
|
+
if (found && found._displayLabel && !isRawObjectId(found._displayLabel)) {
|
|
1540
|
+
return found._displayLabel;
|
|
1541
|
+
}
|
|
1542
|
+
return "-";
|
|
1543
|
+
}, [processedOptions]);
|
|
1544
|
+
const handleOpen = (e) => {
|
|
1545
|
+
if (readOnly) return;
|
|
1546
|
+
e == null ? void 0 : e.stopPropagation();
|
|
1547
|
+
setIsOpen((prev) => !prev);
|
|
1548
|
+
setSearchQuery("");
|
|
1549
|
+
if (context == null ? void 0 : context.refetchRelation) {
|
|
1550
|
+
context.refetchRelation(column.name);
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1553
|
+
useEffect5(() => {
|
|
1554
|
+
if (isOpen) {
|
|
1555
|
+
setTimeout(() => {
|
|
1556
|
+
var _a2;
|
|
1557
|
+
(_a2 = searchInputRef.current) == null ? void 0 : _a2.focus();
|
|
1558
|
+
}, 50);
|
|
1559
|
+
}
|
|
1560
|
+
}, [isOpen]);
|
|
1561
|
+
const handleSelectOption = (optId) => {
|
|
1562
|
+
if (!allowMultiple) {
|
|
1563
|
+
onChange([optId]);
|
|
1564
|
+
setIsOpen(false);
|
|
1565
|
+
} else {
|
|
1566
|
+
if (selectedIds.includes(optId)) {
|
|
1567
|
+
onChange(selectedIds.filter((id) => id !== optId));
|
|
1568
|
+
} else {
|
|
1569
|
+
onChange([...selectedIds, optId]);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
const handleRemove = (idToRemove) => {
|
|
1574
|
+
onChange(selectedIds.filter((id) => id !== idToRemove));
|
|
1575
|
+
};
|
|
1576
|
+
const handleClearSingle = (e) => {
|
|
1577
|
+
e.stopPropagation();
|
|
1578
|
+
onChange([]);
|
|
1579
|
+
};
|
|
1580
|
+
useEffect5(() => {
|
|
1581
|
+
if (!isOpen) return;
|
|
1582
|
+
function handleClickOutside(event) {
|
|
1583
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1584
|
+
setIsOpen(false);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
function handleKeyDown(event) {
|
|
1588
|
+
if (event.key === "Escape") {
|
|
1589
|
+
setIsOpen(false);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1593
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1594
|
+
return () => {
|
|
1595
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1596
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1597
|
+
};
|
|
1598
|
+
}, [isOpen]);
|
|
1599
|
+
const filteredOptions = useMemo3(() => {
|
|
1600
|
+
const query = searchQuery.trim().toLowerCase();
|
|
1601
|
+
if (!query) return processedOptions;
|
|
1602
|
+
return processedOptions.filter((opt) => {
|
|
1603
|
+
return (opt._displayLabel || "").toLowerCase().includes(query);
|
|
1604
|
+
});
|
|
1605
|
+
}, [processedOptions, searchQuery]);
|
|
1606
|
+
if (!optionsLoaded && selectedIds.length > 0) {
|
|
1607
|
+
return /* @__PURE__ */ jsx6("div", { className: "px-2 py-1 flex items-center h-full w-full", children: /* @__PURE__ */ jsx6("span", { className: "inline-block w-16 h-4 bg-slate-100 animate-pulse rounded" }) });
|
|
1608
|
+
}
|
|
1609
|
+
if (readOnly) {
|
|
1610
|
+
if (selectedIds.length === 0) {
|
|
1611
|
+
return /* @__PURE__ */ jsx6("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "-" });
|
|
1612
|
+
}
|
|
1613
|
+
return /* @__PURE__ */ jsx6("div", { className: "px-1.5 py-1 flex flex-wrap items-center gap-1 h-full max-w-full overflow-hidden", dir: "rtl", children: selectedIds.map((id) => {
|
|
1614
|
+
const displayText = getDisplayForId(id);
|
|
1615
|
+
if (displayText === "-") {
|
|
1616
|
+
return /* @__PURE__ */ jsx6("span", { className: "text-slate-400 text-xs", children: "-" }, id);
|
|
1617
|
+
}
|
|
1618
|
+
const palette = getDeterministicPastelBadge(displayText);
|
|
1619
|
+
return /* @__PURE__ */ jsx6(
|
|
1620
|
+
"span",
|
|
1621
|
+
{
|
|
1622
|
+
className: `inline-flex items-center px-2 py-0.5 rounded text-xs font-medium border shadow-xs max-w-full truncate ${palette.bg} ${palette.text} ${palette.border}`,
|
|
1623
|
+
title: displayText,
|
|
1624
|
+
children: displayText
|
|
1625
|
+
},
|
|
1626
|
+
id
|
|
1627
|
+
);
|
|
1628
|
+
}) });
|
|
1629
|
+
}
|
|
1630
|
+
return /* @__PURE__ */ jsxs6(
|
|
1631
|
+
"div",
|
|
1632
|
+
{
|
|
1633
|
+
ref: containerRef,
|
|
1634
|
+
className: `relative w-full h-full flex items-center justify-between px-1.5 py-1 ${isOpen ? "z-50" : ""}`,
|
|
1635
|
+
dir: "rtl",
|
|
1636
|
+
children: [
|
|
1637
|
+
/* @__PURE__ */ jsx6(
|
|
1638
|
+
"div",
|
|
1639
|
+
{
|
|
1640
|
+
className: "flex items-center justify-between w-full h-full overflow-hidden cursor-pointer gap-1",
|
|
1641
|
+
onClick: handleOpen,
|
|
1642
|
+
children: !allowMultiple ? (
|
|
1643
|
+
// Single Select Mode
|
|
1644
|
+
(() => {
|
|
1645
|
+
const singleId = selectedIds[0];
|
|
1646
|
+
const displayText = singleId ? getDisplayForId(singleId) : "";
|
|
1647
|
+
const hasValidSelection = singleId && displayText !== "-" && displayText !== "";
|
|
1648
|
+
if (hasValidSelection) {
|
|
1649
|
+
const palette = getDeterministicPastelBadge(displayText);
|
|
1650
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between w-full overflow-hidden", children: [
|
|
1651
|
+
/* @__PURE__ */ jsxs6(
|
|
1652
|
+
"span",
|
|
1653
|
+
{
|
|
1654
|
+
className: `inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium border shadow-xs max-w-full truncate group/tag ${palette.bg} ${palette.text} ${palette.border}`,
|
|
1655
|
+
title: displayText,
|
|
1656
|
+
children: [
|
|
1657
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children: displayText }),
|
|
1658
|
+
/* @__PURE__ */ jsx6(
|
|
1659
|
+
"button",
|
|
1660
|
+
{
|
|
1661
|
+
type: "button",
|
|
1662
|
+
onClick: handleClearSingle,
|
|
1663
|
+
className: "opacity-0 group-hover/tag:opacity-100 hover:opacity-100 focus:opacity-100 focus:outline-none p-0.5 rounded-full hover:bg-black/10 transition-opacity cursor-pointer shrink-0",
|
|
1664
|
+
title: "\u05E0\u05E7\u05D4",
|
|
1665
|
+
children: /* @__PURE__ */ jsx6(X6, { className: "w-3 h-3" })
|
|
1666
|
+
}
|
|
1667
|
+
)
|
|
1668
|
+
]
|
|
1669
|
+
}
|
|
1670
|
+
),
|
|
1671
|
+
/* @__PURE__ */ jsx6(ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-0 hover:opacity-60 transition-opacity shrink-0 ml-1" })
|
|
1672
|
+
] });
|
|
1673
|
+
}
|
|
1674
|
+
if (singleId && displayText === "-") {
|
|
1675
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between w-full text-slate-400 text-xs", children: [
|
|
1676
|
+
/* @__PURE__ */ jsx6("span", { children: "-" }),
|
|
1677
|
+
/* @__PURE__ */ jsx6(ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-0 hover:opacity-60 transition-opacity shrink-0 ml-1" })
|
|
1678
|
+
] });
|
|
1679
|
+
}
|
|
1680
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between w-full text-slate-400 italic text-xs select-none", children: [
|
|
1681
|
+
/* @__PURE__ */ jsx6("span", { children: "\u05D1\u05D7\u05E8..." }),
|
|
1682
|
+
/* @__PURE__ */ jsx6(ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-60 shrink-0 ml-1" })
|
|
1683
|
+
] });
|
|
1684
|
+
})()
|
|
1685
|
+
) : (
|
|
1686
|
+
// Multi Select Mode
|
|
1687
|
+
selectedIds.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between w-full text-slate-400 italic text-xs select-none", children: [
|
|
1688
|
+
/* @__PURE__ */ jsx6("span", { children: "\u05D1\u05D7\u05E8..." }),
|
|
1689
|
+
/* @__PURE__ */ jsx6(ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-60 shrink-0 ml-1" })
|
|
1690
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between w-full overflow-hidden", children: [
|
|
1691
|
+
/* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-1 overflow-hidden max-h-full flex-1 py-0.5", children: selectedIds.map((id) => {
|
|
1692
|
+
const displayText = getDisplayForId(id);
|
|
1693
|
+
if (displayText === "-") {
|
|
1694
|
+
return /* @__PURE__ */ jsx6("span", { className: "text-slate-400 text-xs px-1", children: "-" }, id);
|
|
1695
|
+
}
|
|
1696
|
+
const palette = getDeterministicPastelBadge(displayText);
|
|
1697
|
+
return /* @__PURE__ */ jsxs6(
|
|
1698
|
+
"span",
|
|
1699
|
+
{
|
|
1700
|
+
className: `inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium border shadow-xs max-w-[160px] truncate group/tag ${palette.bg} ${palette.text} ${palette.border}`,
|
|
1701
|
+
title: displayText,
|
|
1702
|
+
children: [
|
|
1703
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate", children: displayText }),
|
|
1704
|
+
/* @__PURE__ */ jsx6(
|
|
1705
|
+
"button",
|
|
1706
|
+
{
|
|
1707
|
+
type: "button",
|
|
1708
|
+
onClick: (e) => {
|
|
1709
|
+
e.stopPropagation();
|
|
1710
|
+
handleRemove(id);
|
|
1711
|
+
},
|
|
1712
|
+
className: "opacity-0 group-hover/tag:opacity-100 hover:opacity-100 focus:opacity-100 focus:outline-none p-0.5 rounded-full hover:bg-black/10 transition-opacity cursor-pointer shrink-0",
|
|
1713
|
+
title: "\u05D4\u05E1\u05E8",
|
|
1714
|
+
children: /* @__PURE__ */ jsx6(X6, { className: "w-3 h-3" })
|
|
1715
|
+
}
|
|
1716
|
+
)
|
|
1717
|
+
]
|
|
1718
|
+
},
|
|
1719
|
+
id
|
|
1720
|
+
);
|
|
1721
|
+
}) }),
|
|
1722
|
+
/* @__PURE__ */ jsx6(ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-0 hover:opacity-60 transition-opacity shrink-0 ml-1" })
|
|
1723
|
+
] })
|
|
1724
|
+
)
|
|
1725
|
+
}
|
|
1726
|
+
),
|
|
1727
|
+
isOpen && /* @__PURE__ */ jsxs6(
|
|
1728
|
+
"div",
|
|
1729
|
+
{
|
|
1730
|
+
id: `relation-dropdown-${column.name}-${rowId || "cell"}`,
|
|
1731
|
+
dir: "rtl",
|
|
1732
|
+
className: "absolute top-full right-0 mt-1 z-[100] bg-white rounded-md shadow-lg border border-slate-200 p-1 min-w-[200px] w-full max-w-[300px] animate-in fade-in duration-100 flex flex-col",
|
|
1733
|
+
onClick: (e) => e.stopPropagation(),
|
|
1734
|
+
children: [
|
|
1735
|
+
/* @__PURE__ */ jsxs6("div", { className: "relative mb-1", children: [
|
|
1736
|
+
/* @__PURE__ */ jsx6(Search, { className: "w-3.5 h-3.5 text-slate-400 absolute right-2 top-2 pointer-events-none" }),
|
|
1737
|
+
/* @__PURE__ */ jsx6(
|
|
1738
|
+
"input",
|
|
1739
|
+
{
|
|
1740
|
+
ref: searchInputRef,
|
|
1741
|
+
type: "text",
|
|
1742
|
+
placeholder: "\u05D7\u05E4\u05E9...",
|
|
1743
|
+
value: searchQuery,
|
|
1744
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
1745
|
+
onKeyDown: (e) => {
|
|
1746
|
+
if (e.key === "Escape") {
|
|
1747
|
+
e.stopPropagation();
|
|
1748
|
+
setIsOpen(false);
|
|
1749
|
+
}
|
|
1750
|
+
},
|
|
1751
|
+
className: "w-full h-7 pr-7 pl-2 bg-slate-50 border border-slate-200 rounded text-xs text-slate-800 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 transition-colors"
|
|
1752
|
+
}
|
|
1753
|
+
)
|
|
1754
|
+
] }),
|
|
1755
|
+
/* @__PURE__ */ jsx6("div", { className: "overflow-y-auto max-h-[180px] space-y-0.5", children: filteredOptions.length > 0 ? filteredOptions.map((opt) => {
|
|
1756
|
+
const isSelected = selectedIds.includes(opt.id);
|
|
1757
|
+
return /* @__PURE__ */ jsxs6(
|
|
1758
|
+
"div",
|
|
1759
|
+
{
|
|
1760
|
+
onClick: () => handleSelectOption(opt.id),
|
|
1761
|
+
className: `flex items-center justify-between px-2.5 py-1.5 rounded cursor-pointer text-xs transition-colors ${isSelected ? "bg-blue-50 text-blue-900 font-medium" : "hover:bg-slate-50 text-slate-700"}`,
|
|
1762
|
+
children: [
|
|
1763
|
+
/* @__PURE__ */ jsx6("span", { className: "truncate flex-1", children: opt._displayLabel }),
|
|
1764
|
+
isSelected && /* @__PURE__ */ jsx6(Check3, { className: "w-3.5 h-3.5 text-blue-600 shrink-0 mr-1" })
|
|
1765
|
+
]
|
|
1766
|
+
},
|
|
1767
|
+
opt.id
|
|
1768
|
+
);
|
|
1769
|
+
}) : /* @__PURE__ */ jsx6("div", { className: "py-2.5 px-2 text-center text-xs text-slate-400 select-none", children: processedOptions.length === 0 ? "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D6\u05DE\u05D9\u05E0\u05D5\u05EA" : "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA" }) })
|
|
1770
|
+
]
|
|
1771
|
+
}
|
|
1772
|
+
)
|
|
1773
|
+
]
|
|
1774
|
+
}
|
|
1775
|
+
);
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
1779
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1780
|
+
var CURRENCY_SYMBOLS = {
|
|
1781
|
+
USD: "$",
|
|
1782
|
+
EUR: "\u20AC",
|
|
1783
|
+
ILS: "\u20AA",
|
|
1784
|
+
GBP: "\xA3"
|
|
1785
|
+
};
|
|
1786
|
+
function getCurrencySymbol(code) {
|
|
1787
|
+
if (!code) return "";
|
|
1788
|
+
return CURRENCY_SYMBOLS[code.toUpperCase()] || code;
|
|
1789
|
+
}
|
|
1790
|
+
var FORM_INPUTS = {
|
|
1791
|
+
DATE: ({ value, onChange, column }) => /* @__PURE__ */ jsx7(DatePickerCell, { value, onChange, column }),
|
|
1792
|
+
CURRENCY: ({ value, column, onChange }) => {
|
|
1793
|
+
var _a;
|
|
1794
|
+
const symbol = getCurrencySymbol((_a = column.config) == null ? void 0 : _a.currencySymbol);
|
|
1795
|
+
const [isFocused, setIsFocused] = React7.useState(false);
|
|
1796
|
+
const displayValue = !isFocused && value !== void 0 && value !== null && !isNaN(Number(value)) ? new Intl.NumberFormat("en-US").format(Number(value)) : value !== void 0 && value !== null ? value : "";
|
|
1797
|
+
return /* @__PURE__ */ jsxs7("div", { className: "relative w-full h-full", children: [
|
|
1798
|
+
symbol && /* @__PURE__ */ jsx7("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none text-sm", children: symbol }),
|
|
1799
|
+
/* @__PURE__ */ jsx7(
|
|
1800
|
+
"input",
|
|
1801
|
+
{
|
|
1802
|
+
type: isFocused ? "number" : "text",
|
|
1803
|
+
step: "any",
|
|
1804
|
+
className: `w-full h-8 ${symbol ? "pl-6 pr-2" : "px-2"} bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm`,
|
|
1805
|
+
value: displayValue,
|
|
1806
|
+
onFocus: () => setIsFocused(true),
|
|
1807
|
+
onBlur: () => setIsFocused(false),
|
|
1808
|
+
onChange: (e) => {
|
|
1809
|
+
const val = e.target.value;
|
|
1810
|
+
onChange(val === "" ? null : Number(val));
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
)
|
|
1814
|
+
] });
|
|
1815
|
+
},
|
|
1816
|
+
TIME: ({ value, onChange, column }) => /* @__PURE__ */ jsx7(TimePickerCell, { value, onChange, column }),
|
|
1817
|
+
LINK: ({ value, onChange, column }) => /* @__PURE__ */ jsx7(LinkPickerCell, { value, onChange, column }),
|
|
1818
|
+
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center w-full h-full p-2", children: /* @__PURE__ */ jsx7(
|
|
1819
|
+
"input",
|
|
1820
|
+
{
|
|
1821
|
+
type: "checkbox",
|
|
1822
|
+
checked: !!value,
|
|
1823
|
+
onChange: (e) => onChange(e.target.checked),
|
|
1824
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
1825
|
+
}
|
|
1826
|
+
) }),
|
|
1827
|
+
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ jsx7(
|
|
1828
|
+
DrivePickerCell,
|
|
1829
|
+
{
|
|
1830
|
+
value: value || [],
|
|
1831
|
+
onChange,
|
|
1832
|
+
column,
|
|
1833
|
+
rowId,
|
|
1834
|
+
tableName: context == null ? void 0 : context.tableName,
|
|
1835
|
+
onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
|
|
1836
|
+
context
|
|
1837
|
+
}
|
|
1838
|
+
),
|
|
1839
|
+
RELATION: ({ value, onChange, column, context, rowId }) => /* @__PURE__ */ jsx7(
|
|
1840
|
+
RelationPickerCell,
|
|
1841
|
+
{
|
|
1842
|
+
value,
|
|
1843
|
+
onChange,
|
|
1844
|
+
column,
|
|
1845
|
+
context,
|
|
1846
|
+
rowId
|
|
1847
|
+
}
|
|
1848
|
+
),
|
|
1849
|
+
NUMBER: ({ value, onChange }) => /* @__PURE__ */ jsx7(
|
|
1850
|
+
"input",
|
|
1851
|
+
{
|
|
1852
|
+
type: "number",
|
|
1853
|
+
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
1854
|
+
value: value !== void 0 && value !== null ? value : "",
|
|
1855
|
+
onChange: (e) => {
|
|
1856
|
+
const val = e.target.value;
|
|
1857
|
+
onChange(val === "" ? null : Number(val));
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
),
|
|
1861
|
+
PHONE: ({ value, onChange, column }) => {
|
|
1862
|
+
var _a;
|
|
1863
|
+
const enableWhatsApp = (_a = column == null ? void 0 : column.config) == null ? void 0 : _a.enableWhatsApp;
|
|
1864
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center w-full h-full px-2 gap-1.5 overflow-hidden", children: [
|
|
1865
|
+
/* @__PURE__ */ jsx7(
|
|
1866
|
+
"input",
|
|
1867
|
+
{
|
|
1868
|
+
type: "tel",
|
|
1869
|
+
className: "w-full h-8 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm flex-1 min-w-0",
|
|
1870
|
+
value: value !== void 0 && value !== null ? String(value) : "",
|
|
1871
|
+
onChange: (e) => onChange(e.target.value || null),
|
|
1872
|
+
dir: "ltr"
|
|
1873
|
+
}
|
|
1874
|
+
),
|
|
1875
|
+
enableWhatsApp && value && /* @__PURE__ */ jsx7(
|
|
1876
|
+
"button",
|
|
1877
|
+
{
|
|
1878
|
+
type: "button",
|
|
1879
|
+
className: "text-emerald-500 cursor-pointer hover:opacity-80 transition-opacity shrink-0 p-1 rounded hover:bg-emerald-50",
|
|
1880
|
+
title: "\u05E4\u05EA\u05D9\u05D7\u05EA \u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4",
|
|
1881
|
+
onClick: (e) => {
|
|
1882
|
+
e.stopPropagation();
|
|
1883
|
+
openWhatsAppChat(String(value));
|
|
1884
|
+
},
|
|
1885
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a5.816 5.816 0 00-.571-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" }) })
|
|
1886
|
+
}
|
|
1887
|
+
)
|
|
1888
|
+
] });
|
|
1889
|
+
},
|
|
1890
|
+
GOOGLE_CONTACT: ({ value, column, rowId, onChange, context }) => {
|
|
1891
|
+
const [isSyncing, setIsSyncing] = React7.useState(false);
|
|
1892
|
+
const { addToast } = useToast();
|
|
1893
|
+
const googleClientIdRef = React7.useRef(null);
|
|
1894
|
+
const ensureGisScript = React7.useCallback(() => {
|
|
1895
|
+
return new Promise((resolve, reject) => {
|
|
1896
|
+
var _a, _b, _c;
|
|
1897
|
+
if ((_c = (_b = (_a = window.google) == null ? void 0 : _a.accounts) == null ? void 0 : _b.oauth2) == null ? void 0 : _c.initTokenClient) {
|
|
1898
|
+
resolve();
|
|
1899
|
+
return;
|
|
912
1900
|
}
|
|
913
1901
|
if (document.querySelector('script[src*="accounts.google.com/gsi/client"]')) {
|
|
914
1902
|
const waitForLoad = setInterval(() => {
|
|
@@ -932,7 +1920,7 @@ var FORM_INPUTS = {
|
|
|
932
1920
|
document.head.appendChild(script);
|
|
933
1921
|
});
|
|
934
1922
|
}, []);
|
|
935
|
-
const requestGisToken =
|
|
1923
|
+
const requestGisToken = React7.useCallback(async (hint) => {
|
|
936
1924
|
await ensureGisScript();
|
|
937
1925
|
if (!googleClientIdRef.current && (context == null ? void 0 : context.executeAction)) {
|
|
938
1926
|
try {
|
|
@@ -979,19 +1967,27 @@ var FORM_INPUTS = {
|
|
|
979
1967
|
return { accessToken, email };
|
|
980
1968
|
}, [ensureGisScript, context]);
|
|
981
1969
|
const handleSync = async () => {
|
|
982
|
-
var _a, _b, _c;
|
|
1970
|
+
var _a, _b, _c, _d, _e, _f;
|
|
983
1971
|
if (!(context == null ? void 0 : context.executeAction)) return;
|
|
984
1972
|
setIsSyncing(true);
|
|
985
1973
|
try {
|
|
986
|
-
const mapping = column.contactMapping || {};
|
|
1974
|
+
const mapping = ((_a = column.config) == null ? void 0 : _a.contactMapping) || {};
|
|
987
1975
|
const rowData = context.rowData || {};
|
|
1976
|
+
const targetTableMetaId = (context == null ? void 0 : context.tableMetaId) || (context == null ? void 0 : context.tableId);
|
|
1977
|
+
const targetOrgId = context == null ? void 0 : context.orgId;
|
|
988
1978
|
let hasPhone = false;
|
|
989
1979
|
if (mapping.phoneCol && rowData[mapping.phoneCol]) hasPhone = true;
|
|
1980
|
+
const activeParentTableId = ((_b = context.parentRecord) == null ? void 0 : _b.tableId) || (context == null ? void 0 : context.parentTableId);
|
|
990
1981
|
let hasName = false;
|
|
991
1982
|
if (mapping.nameParts && Array.isArray(mapping.nameParts)) {
|
|
992
1983
|
for (const part of mapping.nameParts) {
|
|
993
1984
|
if (part.type === "LOCAL" && rowData[part.columnId]) hasName = true;
|
|
994
|
-
if (part.type === "PARENT"
|
|
1985
|
+
if (part.type === "PARENT") {
|
|
1986
|
+
if (!activeParentTableId) continue;
|
|
1987
|
+
if (part.parentTableId && part.parentTableId !== activeParentTableId) continue;
|
|
1988
|
+
if ((_d = (_c = context.parentRecord) == null ? void 0 : _c.data) == null ? void 0 : _d[part.columnId]) hasName = true;
|
|
1989
|
+
else if (((_e = context.parentRecord) == null ? void 0 : _e.recordId) || ((_f = context.parentRecord) == null ? void 0 : _f.id)) hasName = true;
|
|
1990
|
+
}
|
|
995
1991
|
}
|
|
996
1992
|
}
|
|
997
1993
|
if (!hasPhone) {
|
|
@@ -1021,6 +2017,10 @@ var FORM_INPUTS = {
|
|
|
1021
2017
|
emailCol: mapping.emailCol,
|
|
1022
2018
|
localRowData: rowData,
|
|
1023
2019
|
parentRecord: context.parentRecord,
|
|
2020
|
+
tableMetaId: targetTableMetaId,
|
|
2021
|
+
tableId: targetTableMetaId,
|
|
2022
|
+
recordId: rowId,
|
|
2023
|
+
orgId: targetOrgId,
|
|
1024
2024
|
accessToken,
|
|
1025
2025
|
userEmail
|
|
1026
2026
|
};
|
|
@@ -1031,10 +2031,12 @@ var FORM_INPUTS = {
|
|
|
1031
2031
|
} else {
|
|
1032
2032
|
onChange(res);
|
|
1033
2033
|
}
|
|
1034
|
-
if (
|
|
2034
|
+
if (targetTableMetaId && !rowId.startsWith("temp_")) {
|
|
1035
2035
|
await context.executeAction("UPDATE_RECORD", {
|
|
1036
|
-
tableId:
|
|
2036
|
+
tableId: targetTableMetaId,
|
|
2037
|
+
tableMetaId: targetTableMetaId,
|
|
1037
2038
|
recordId: rowId,
|
|
2039
|
+
orgId: targetOrgId,
|
|
1038
2040
|
data: { [column.name]: res }
|
|
1039
2041
|
});
|
|
1040
2042
|
}
|
|
@@ -1048,6 +2050,8 @@ var FORM_INPUTS = {
|
|
|
1048
2050
|
};
|
|
1049
2051
|
const handleUnlink = async () => {
|
|
1050
2052
|
let accessToken;
|
|
2053
|
+
const targetTableMetaId = (context == null ? void 0 : context.tableMetaId) || (context == null ? void 0 : context.tableId);
|
|
2054
|
+
const targetOrgId = context == null ? void 0 : context.orgId;
|
|
1051
2055
|
try {
|
|
1052
2056
|
let emailHint = value == null ? void 0 : value.userEmail;
|
|
1053
2057
|
if (!emailHint && (value == null ? void 0 : value.url)) {
|
|
@@ -1057,116 +2061,710 @@ var FORM_INPUTS = {
|
|
|
1057
2061
|
} catch (e) {
|
|
1058
2062
|
}
|
|
1059
2063
|
}
|
|
1060
|
-
const auth = await requestGisToken(emailHint);
|
|
1061
|
-
accessToken = auth.accessToken;
|
|
1062
|
-
} catch (err) {
|
|
1063
|
-
console.warn("[handleUnlink] Could not obtain token via GIS, falling back to server default token:", err);
|
|
2064
|
+
const auth = await requestGisToken(emailHint);
|
|
2065
|
+
accessToken = auth.accessToken;
|
|
2066
|
+
} catch (err) {
|
|
2067
|
+
console.warn("[handleUnlink] Could not obtain token via GIS, falling back to server default token:", err);
|
|
2068
|
+
}
|
|
2069
|
+
if ((value == null ? void 0 : value.resourceName) && (context == null ? void 0 : context.executeAction)) {
|
|
2070
|
+
await context.executeAction("DELETE_GOOGLE_CONTACT", {
|
|
2071
|
+
resourceName: value.resourceName,
|
|
2072
|
+
accessToken,
|
|
2073
|
+
tableMetaId: targetTableMetaId,
|
|
2074
|
+
tableId: targetTableMetaId,
|
|
2075
|
+
recordId: rowId,
|
|
2076
|
+
orgId: targetOrgId
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2079
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
2080
|
+
context.updateQuietly(rowId, column.name, null);
|
|
2081
|
+
} else {
|
|
2082
|
+
onChange(null);
|
|
2083
|
+
}
|
|
2084
|
+
if (targetTableMetaId && (context == null ? void 0 : context.executeAction) && !rowId.startsWith("temp_")) {
|
|
2085
|
+
await context.executeAction("UPDATE_RECORD", {
|
|
2086
|
+
tableId: targetTableMetaId,
|
|
2087
|
+
tableMetaId: targetTableMetaId,
|
|
2088
|
+
recordId: rowId,
|
|
2089
|
+
orgId: targetOrgId,
|
|
2090
|
+
data: { [column.name]: null }
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
};
|
|
2094
|
+
if (value && value.synced && value.url) {
|
|
2095
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5 h-8 px-2 group whitespace-nowrap overflow-hidden max-w-full", children: [
|
|
2096
|
+
/* @__PURE__ */ jsx7("a", { href: value.url, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:underline flex-1 truncate text-xs whitespace-nowrap", children: "\u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8 \u05D2\u05D5\u05D2\u05DC" }),
|
|
2097
|
+
/* @__PURE__ */ jsx7(
|
|
2098
|
+
"button",
|
|
2099
|
+
{
|
|
2100
|
+
type: "button",
|
|
2101
|
+
onClick: handleUnlink,
|
|
2102
|
+
className: "text-slate-400 hover:text-rose-500 opacity-0 group-hover:opacity-100 transition-opacity p-1 shrink-0",
|
|
2103
|
+
title: "\u05D1\u05D8\u05DC \u05E1\u05E0\u05DB\u05E8\u05D5\u05DF",
|
|
2104
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
2105
|
+
}
|
|
2106
|
+
)
|
|
2107
|
+
] });
|
|
2108
|
+
}
|
|
2109
|
+
return /* @__PURE__ */ jsx7("div", { className: "flex items-center h-8 px-2 whitespace-nowrap overflow-hidden max-w-full", children: /* @__PURE__ */ jsxs7(
|
|
2110
|
+
"button",
|
|
2111
|
+
{
|
|
2112
|
+
type: "button",
|
|
2113
|
+
onClick: handleSync,
|
|
2114
|
+
disabled: isSyncing,
|
|
2115
|
+
className: "inline-flex items-center gap-1.5 px-2.5 py-1 bg-blue-50 text-blue-600 hover:bg-blue-100 border border-blue-200 rounded-md text-xs font-medium transition-colors whitespace-nowrap shrink-0 disabled:opacity-50 cursor-pointer max-w-full overflow-hidden",
|
|
2116
|
+
children: [
|
|
2117
|
+
isSyncing ? /* @__PURE__ */ jsxs7("svg", { className: "w-3.5 h-3.5 animate-spin shrink-0", viewBox: "0 0 24 24", fill: "none", children: [
|
|
2118
|
+
/* @__PURE__ */ jsx7("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
2119
|
+
/* @__PURE__ */ jsx7("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
2120
|
+
] }) : /* @__PURE__ */ jsx7("svg", { className: "w-3.5 h-3.5 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 4v16m8-8H4" }) }),
|
|
2121
|
+
/* @__PURE__ */ jsx7("span", { className: "whitespace-nowrap truncate", children: "\u05E1\u05E0\u05DB\u05E8\u05DF \u05DC\u05D2\u05D5\u05D2\u05DC" })
|
|
2122
|
+
]
|
|
2123
|
+
}
|
|
2124
|
+
) });
|
|
2125
|
+
},
|
|
2126
|
+
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ jsx7(
|
|
2127
|
+
"input",
|
|
2128
|
+
{
|
|
2129
|
+
type: "text",
|
|
2130
|
+
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
2131
|
+
value: value !== void 0 && value !== null ? String(value) : "",
|
|
2132
|
+
onChange: (e) => onChange(e.target.value)
|
|
2133
|
+
}
|
|
2134
|
+
),
|
|
2135
|
+
SUB_TABLE: ({ value, column }) => {
|
|
2136
|
+
var _a, _b, _c;
|
|
2137
|
+
if (!Array.isArray(value)) return /* @__PURE__ */ jsx7("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
2138
|
+
const selected = value.filter((e) => e == null ? void 0 : e.isSelected);
|
|
2139
|
+
if (selected.length === 0) return /* @__PURE__ */ jsx7("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
2140
|
+
const displayFields = ((_a = column.config) == null ? void 0 : _a.subTableDisplayFields) || [];
|
|
2141
|
+
const isWhatsApp = ((_b = column.config) == null ? void 0 : _b.actionType) === "WHATSAPP";
|
|
2142
|
+
const actionPhoneCol = (_c = column.config) == null ? void 0 : _c.actionPhoneColumn;
|
|
2143
|
+
return /* @__PURE__ */ jsx7("div", { className: "px-1.5 py-1 flex flex-nowrap items-center gap-1 h-full overflow-hidden max-w-full", children: selected.map((entry, idx) => {
|
|
2144
|
+
var _a2, _b2;
|
|
2145
|
+
let label = "";
|
|
2146
|
+
if (entry._resolvedData) {
|
|
2147
|
+
if (displayFields.length > 0) {
|
|
2148
|
+
label = displayFields.map((f) => String(entry._resolvedData[f] || "")).filter(Boolean).join(" ");
|
|
2149
|
+
} else {
|
|
2150
|
+
const firstField = Object.keys(entry._resolvedData).find((k) => k !== "_id");
|
|
2151
|
+
if (firstField) label = String(entry._resolvedData[firstField] || "");
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
if (!label) label = ((_a2 = entry.recordId) == null ? void 0 : _a2.slice(-6)) || "...";
|
|
2155
|
+
if (isWhatsApp) {
|
|
2156
|
+
const rawPhone = actionPhoneCol ? (_b2 = entry._resolvedData) == null ? void 0 : _b2[actionPhoneCol] : null;
|
|
2157
|
+
const phone = rawPhone ? String(rawPhone).trim() : null;
|
|
2158
|
+
if (phone) {
|
|
2159
|
+
return /* @__PURE__ */ jsxs7(
|
|
2160
|
+
"button",
|
|
2161
|
+
{
|
|
2162
|
+
type: "button",
|
|
2163
|
+
onClick: (e) => {
|
|
2164
|
+
e.stopPropagation();
|
|
2165
|
+
openWhatsAppChat(phone);
|
|
2166
|
+
},
|
|
2167
|
+
className: "inline-flex items-center gap-1 px-1.5 py-0.5 bg-emerald-50 hover:bg-emerald-100 text-emerald-800 border border-emerald-300 hover:border-emerald-400 rounded-full text-xs font-medium max-w-full truncate cursor-pointer transition-colors shadow-xs shrink",
|
|
2168
|
+
title: `\u05E4\u05EA\u05D9\u05D7\u05EA \u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4 (${phone})`,
|
|
2169
|
+
children: [
|
|
2170
|
+
/* @__PURE__ */ jsx7("svg", { className: "w-3 h-3 text-emerald-600 shrink-0", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a5.816 5.816 0 00-.571-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" }) }),
|
|
2171
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", children: label })
|
|
2172
|
+
]
|
|
2173
|
+
},
|
|
2174
|
+
entry.recordId || idx
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
return /* @__PURE__ */ jsx7(
|
|
2179
|
+
"span",
|
|
2180
|
+
{
|
|
2181
|
+
className: "inline-flex items-center px-1.5 py-0.5 bg-amber-50 text-amber-800 border border-amber-200 rounded-full text-xs font-medium max-w-full truncate shrink",
|
|
2182
|
+
title: label,
|
|
2183
|
+
children: label
|
|
2184
|
+
},
|
|
2185
|
+
entry.recordId || idx
|
|
2186
|
+
);
|
|
2187
|
+
}) });
|
|
2188
|
+
}
|
|
2189
|
+
};
|
|
2190
|
+
|
|
2191
|
+
// src/components/TableBlock/fields/SubTableViewer.tsx
|
|
2192
|
+
import { useState as useState9, useEffect as useEffect7, useRef as useRef6, useCallback as useCallback8, useMemo as useMemo4 } from "react";
|
|
2193
|
+
import { isTextRepresentable } from "@universe-platform/shared";
|
|
2194
|
+
|
|
2195
|
+
// src/utils/phone.ts
|
|
2196
|
+
function sanitizePhoneNumber(phone) {
|
|
2197
|
+
if (!phone) return "";
|
|
2198
|
+
const trimmed = phone.trim();
|
|
2199
|
+
const hasLeadingPlus = trimmed.startsWith("+");
|
|
2200
|
+
const digitsOnly = trimmed.replace(/\D/g, "");
|
|
2201
|
+
return hasLeadingPlus ? `+${digitsOnly}` : digitsOnly;
|
|
2202
|
+
}
|
|
2203
|
+
function isValidPhoneNumber(phone) {
|
|
2204
|
+
if (!phone) return false;
|
|
2205
|
+
const cleaned = sanitizePhoneNumber(phone);
|
|
2206
|
+
return /^\+?[0-9]{9,15}$/.test(cleaned);
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
// src/components/TableBlock/useColumnResize.ts
|
|
2210
|
+
import { useState as useState7, useEffect as useEffect6, useCallback as useCallback6 } from "react";
|
|
2211
|
+
function useColumnResize({
|
|
2212
|
+
storageKey,
|
|
2213
|
+
defaultWidth = 200,
|
|
2214
|
+
minWidth = 60,
|
|
2215
|
+
maxWidth = 500,
|
|
2216
|
+
getMinColWidth
|
|
2217
|
+
}) {
|
|
2218
|
+
const [columnWidths, setColumnWidths] = useState7({});
|
|
2219
|
+
const [resizingCol, setResizingCol] = useState7(null);
|
|
2220
|
+
useEffect6(() => {
|
|
2221
|
+
if (typeof window === "undefined" || !storageKey) return;
|
|
2222
|
+
try {
|
|
2223
|
+
const saved = localStorage.getItem(storageKey);
|
|
2224
|
+
if (saved) {
|
|
2225
|
+
setColumnWidths(JSON.parse(saved));
|
|
2226
|
+
}
|
|
2227
|
+
} catch (e) {
|
|
2228
|
+
console.error(`Failed to load column widths for key "${storageKey}":`, e);
|
|
2229
|
+
}
|
|
2230
|
+
}, [storageKey]);
|
|
2231
|
+
useEffect6(() => {
|
|
2232
|
+
if (!resizingCol) return;
|
|
2233
|
+
const handleMouseMove = (e) => {
|
|
2234
|
+
const diffX = resizingCol.startX - e.clientX;
|
|
2235
|
+
const colMin = resizingCol.minWidth || minWidth;
|
|
2236
|
+
const newWidth = Math.max(colMin, Math.min(maxWidth, resizingCol.startWidth + diffX));
|
|
2237
|
+
setColumnWidths((prev) => __spreadProps(__spreadValues({}, prev), { [resizingCol.name]: newWidth }));
|
|
2238
|
+
};
|
|
2239
|
+
const handleMouseUp = () => {
|
|
2240
|
+
setResizingCol(null);
|
|
2241
|
+
setColumnWidths((prev) => {
|
|
2242
|
+
if (typeof window !== "undefined" && storageKey) {
|
|
2243
|
+
try {
|
|
2244
|
+
localStorage.setItem(storageKey, JSON.stringify(prev));
|
|
2245
|
+
} catch (e) {
|
|
2246
|
+
console.error(`Failed to save column widths for key "${storageKey}":`, e);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
return prev;
|
|
2250
|
+
});
|
|
2251
|
+
};
|
|
2252
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
2253
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
2254
|
+
return () => {
|
|
2255
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
2256
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
2257
|
+
};
|
|
2258
|
+
}, [resizingCol, storageKey, minWidth, maxWidth]);
|
|
2259
|
+
const startResize = useCallback6(
|
|
2260
|
+
(colName, currentWidth, clientX, customMinWidth) => {
|
|
2261
|
+
const colMin = customMinWidth != null ? customMinWidth : getMinColWidth ? getMinColWidth(colName) : minWidth;
|
|
2262
|
+
setResizingCol({
|
|
2263
|
+
name: colName,
|
|
2264
|
+
startWidth: currentWidth,
|
|
2265
|
+
startX: clientX,
|
|
2266
|
+
minWidth: colMin
|
|
2267
|
+
});
|
|
2268
|
+
},
|
|
2269
|
+
[getMinColWidth, minWidth]
|
|
2270
|
+
);
|
|
2271
|
+
const getWidth = useCallback6(
|
|
2272
|
+
(colName, fallback) => {
|
|
2273
|
+
const colMin = getMinColWidth ? getMinColWidth(colName) : minWidth;
|
|
2274
|
+
const saved = columnWidths[colName] || fallback || defaultWidth;
|
|
2275
|
+
return Math.max(colMin, saved);
|
|
2276
|
+
},
|
|
2277
|
+
[columnWidths, defaultWidth, getMinColWidth, minWidth]
|
|
2278
|
+
);
|
|
2279
|
+
return {
|
|
2280
|
+
columnWidths,
|
|
2281
|
+
setColumnWidths,
|
|
2282
|
+
resizingCol,
|
|
2283
|
+
startResize,
|
|
2284
|
+
getWidth,
|
|
2285
|
+
minWidth
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
// src/components/TableBlock/useColumnReorder.ts
|
|
2290
|
+
import { useState as useState8, useCallback as useCallback7 } from "react";
|
|
2291
|
+
function useColumnReorder({
|
|
2292
|
+
onReorder,
|
|
2293
|
+
disabled = false
|
|
2294
|
+
}) {
|
|
2295
|
+
const [draggedColName, setDraggedColName] = useState8(null);
|
|
2296
|
+
const [dragOverColName, setDragOverColName] = useState8(null);
|
|
2297
|
+
const getHeaderDragProps = useCallback7(
|
|
2298
|
+
(colName) => {
|
|
2299
|
+
if (disabled) {
|
|
2300
|
+
return {
|
|
2301
|
+
draggable: false
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2304
|
+
return {
|
|
2305
|
+
draggable: true,
|
|
2306
|
+
onDragStart: (e) => {
|
|
2307
|
+
e.dataTransfer.setData("text/plain", colName);
|
|
2308
|
+
e.dataTransfer.effectAllowed = "move";
|
|
2309
|
+
setDraggedColName(colName);
|
|
2310
|
+
},
|
|
2311
|
+
onDragOver: (e) => {
|
|
2312
|
+
e.preventDefault();
|
|
2313
|
+
e.dataTransfer.dropEffect = "move";
|
|
2314
|
+
if (dragOverColName !== colName) {
|
|
2315
|
+
setDragOverColName(colName);
|
|
2316
|
+
}
|
|
2317
|
+
},
|
|
2318
|
+
onDragLeave: () => {
|
|
2319
|
+
if (dragOverColName === colName) {
|
|
2320
|
+
setDragOverColName(null);
|
|
2321
|
+
}
|
|
2322
|
+
},
|
|
2323
|
+
onDrop: (e) => {
|
|
2324
|
+
e.preventDefault();
|
|
2325
|
+
if (draggedColName && draggedColName !== colName) {
|
|
2326
|
+
onReorder(draggedColName, colName);
|
|
2327
|
+
}
|
|
2328
|
+
setDraggedColName(null);
|
|
2329
|
+
setDragOverColName(null);
|
|
2330
|
+
},
|
|
2331
|
+
onDragEnd: () => {
|
|
2332
|
+
setDraggedColName(null);
|
|
2333
|
+
setDragOverColName(null);
|
|
2334
|
+
}
|
|
2335
|
+
};
|
|
2336
|
+
},
|
|
2337
|
+
[disabled, draggedColName, dragOverColName, onReorder]
|
|
2338
|
+
);
|
|
2339
|
+
const isDragging = useCallback7((colName) => draggedColName === colName, [draggedColName]);
|
|
2340
|
+
const isDragOver = useCallback7((colName) => dragOverColName === colName, [dragOverColName]);
|
|
2341
|
+
return {
|
|
2342
|
+
draggedColName,
|
|
2343
|
+
dragOverColName,
|
|
2344
|
+
isDragging,
|
|
2345
|
+
isDragOver,
|
|
2346
|
+
getHeaderDragProps
|
|
2347
|
+
};
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
// src/components/TableBlock/columnTitleUtils.tsx
|
|
2351
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2352
|
+
var canvas = null;
|
|
2353
|
+
function measureTextWidth(text, font = '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif') {
|
|
2354
|
+
if (typeof document === "undefined") return text.length * 9;
|
|
2355
|
+
if (!canvas) {
|
|
2356
|
+
canvas = document.createElement("canvas");
|
|
2357
|
+
}
|
|
2358
|
+
const ctx = canvas.getContext("2d");
|
|
2359
|
+
if (!ctx) return text.length * 9;
|
|
2360
|
+
ctx.font = font;
|
|
2361
|
+
return ctx.measureText(text).width;
|
|
2362
|
+
}
|
|
2363
|
+
function splitHeaderTitle(name) {
|
|
2364
|
+
if (!name) return { isSingleWord: true, line1: "" };
|
|
2365
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
2366
|
+
if (words.length <= 1) {
|
|
2367
|
+
return { isSingleWord: true, line1: words[0] || "" };
|
|
2368
|
+
}
|
|
2369
|
+
if (words.length === 2) {
|
|
2370
|
+
return { isSingleWord: false, line1: words[0], line2: words[1] };
|
|
2371
|
+
}
|
|
2372
|
+
let bestSplit = 1;
|
|
2373
|
+
let minDiff = Infinity;
|
|
2374
|
+
for (let i = 1; i < words.length; i++) {
|
|
2375
|
+
const l1 = words.slice(0, i).join(" ");
|
|
2376
|
+
const l2 = words.slice(i).join(" ");
|
|
2377
|
+
const diff = Math.abs(l1.length - l2.length);
|
|
2378
|
+
if (diff < minDiff) {
|
|
2379
|
+
minDiff = diff;
|
|
2380
|
+
bestSplit = i;
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
return {
|
|
2384
|
+
isSingleWord: false,
|
|
2385
|
+
line1: words.slice(0, bestSplit).join(" "),
|
|
2386
|
+
line2: words.slice(bestSplit).join(" ")
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
function calculateMinColumnWidth(name, isSubTable = false, colType) {
|
|
2390
|
+
const font = isSubTable ? '600 12px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' : '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2391
|
+
const chromeWidth = isSubTable ? 44 : 52;
|
|
2392
|
+
let baseMin = isSubTable ? 50 : 60;
|
|
2393
|
+
if ((colType == null ? void 0 : colType.toUpperCase()) === "GOOGLE_CONTACT") {
|
|
2394
|
+
baseMin = isSubTable ? 110 : 120;
|
|
2395
|
+
}
|
|
2396
|
+
if (!name) return baseMin;
|
|
2397
|
+
const { isSingleWord, line1, line2 } = splitHeaderTitle(name);
|
|
2398
|
+
if (isSingleWord) {
|
|
2399
|
+
const wordWidth = measureTextWidth(line1, font);
|
|
2400
|
+
return Math.max(baseMin, Math.ceil(wordWidth + chromeWidth));
|
|
2401
|
+
}
|
|
2402
|
+
const w1 = measureTextWidth(line1, font);
|
|
2403
|
+
const w2 = line2 ? measureTextWidth(line2, font) : 0;
|
|
2404
|
+
const maxLine = Math.max(w1, w2);
|
|
2405
|
+
return Math.max(baseMin, Math.ceil(maxLine + chromeWidth));
|
|
2406
|
+
}
|
|
2407
|
+
function ColumnHeaderTitle({ name, width, isSubTable = false }) {
|
|
2408
|
+
const { isSingleWord, line1, line2 } = splitHeaderTitle(name);
|
|
2409
|
+
if (isSingleWord || !line2) {
|
|
2410
|
+
return /* @__PURE__ */ jsx8("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children: line1 });
|
|
2411
|
+
}
|
|
2412
|
+
const font = isSubTable ? '600 12px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' : '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2413
|
+
const chromeWidth = isSubTable ? 44 : 52;
|
|
2414
|
+
const fullTitleWidth = measureTextWidth(name, font) + chromeWidth;
|
|
2415
|
+
if (width !== void 0 && width >= fullTitleWidth) {
|
|
2416
|
+
return /* @__PURE__ */ jsx8("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children: name });
|
|
2417
|
+
}
|
|
2418
|
+
return /* @__PURE__ */ jsxs8("span", { className: "flex flex-col justify-center leading-tight select-none overflow-hidden text-right flex-1", title: name, children: [
|
|
2419
|
+
/* @__PURE__ */ jsx8("span", { className: "whitespace-nowrap block", children: line1 }),
|
|
2420
|
+
/* @__PURE__ */ jsx8("span", { className: "whitespace-nowrap block", children: line2 })
|
|
2421
|
+
] });
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
// src/components/TableBlock/fields/SubTableViewer.tsx
|
|
2425
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2426
|
+
function formatConflictCellValue(rawVal, colDef, relationOptionsMap) {
|
|
2427
|
+
var _a, _b, _c;
|
|
2428
|
+
if (rawVal === void 0 || rawVal === null || rawVal === "") {
|
|
2429
|
+
return "-";
|
|
2430
|
+
}
|
|
2431
|
+
const colType = (_a = colDef == null ? void 0 : colDef.type) == null ? void 0 : _a.toUpperCase();
|
|
2432
|
+
if (typeof rawVal === "boolean" || colType === "BOOLEAN") {
|
|
2433
|
+
return rawVal ? "\u05DB\u05DF" : "\u05DC\u05D0";
|
|
2434
|
+
}
|
|
2435
|
+
if (colType === "GOOGLE_CONTACT" || typeof rawVal === "object" && rawVal !== null && ("resourceName" in rawVal || "synced" in rawVal)) {
|
|
2436
|
+
return /* @__PURE__ */ jsx9("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[11px] font-medium bg-violet-50 text-violet-700 border border-violet-200", children: "\u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8 \u05D2\u05D5\u05D2\u05DC" });
|
|
2437
|
+
}
|
|
2438
|
+
if (colType === "GOOGLE_DRIVE_FILE" || typeof rawVal === "object" && rawVal !== null && ("fileId" in rawVal || "fileUrl" in rawVal || "fileName" in rawVal)) {
|
|
2439
|
+
const fileName = rawVal == null ? void 0 : rawVal.fileName;
|
|
2440
|
+
return /* @__PURE__ */ jsx9("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[11px] font-medium bg-rose-50 text-rose-700 border border-rose-200 truncate max-w-[150px]", title: fileName || "\u05E7\u05D5\u05D1\u05E5 \u05DE\u05E6\u05D5\u05E8\u05E3", children: fileName ? String(fileName) : "\u05E7\u05D5\u05D1\u05E5 \u05DE\u05E6\u05D5\u05E8\u05E3" });
|
|
2441
|
+
}
|
|
2442
|
+
if (colType === "LINK" || typeof rawVal === "object" && rawVal !== null && ("url" in rawVal || "label" in rawVal)) {
|
|
2443
|
+
const text = (rawVal == null ? void 0 : rawVal.label) || (rawVal == null ? void 0 : rawVal.url);
|
|
2444
|
+
return text ? String(text) : "-";
|
|
2445
|
+
}
|
|
2446
|
+
if (colType === "SUB_TABLE" || Array.isArray(rawVal) && rawVal.length > 0 && typeof rawVal[0] === "object" && ("recordId" in rawVal[0] || "id" in rawVal[0])) {
|
|
2447
|
+
return /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[11px] font-medium bg-amber-50 text-amber-700 border border-amber-200", children: [
|
|
2448
|
+
rawVal.length,
|
|
2449
|
+
" \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA"
|
|
2450
|
+
] });
|
|
2451
|
+
}
|
|
2452
|
+
if (colType === "RELATION") {
|
|
2453
|
+
if (Array.isArray(rawVal)) {
|
|
2454
|
+
return /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[11px] font-medium bg-indigo-50 text-indigo-700 border border-indigo-200", children: [
|
|
2455
|
+
rawVal.length,
|
|
2456
|
+
" \u05DE\u05E7\u05D5\u05E9\u05E8\u05D9\u05DD"
|
|
2457
|
+
] });
|
|
2458
|
+
}
|
|
2459
|
+
const colOpts = (colDef == null ? void 0 : colDef.name) && relationOptionsMap ? relationOptionsMap[colDef.name] : void 0;
|
|
2460
|
+
if (Array.isArray(colOpts)) {
|
|
2461
|
+
const opt = colOpts.find((o) => String(o.id) === String(rawVal));
|
|
2462
|
+
if (opt) {
|
|
2463
|
+
const displayField = (_b = colDef == null ? void 0 : colDef.config) == null ? void 0 : _b.displayField;
|
|
2464
|
+
const disp = opt._displayLabel || displayField && ((_c = opt.data) == null ? void 0 : _c[displayField]) || (opt.label !== opt.id ? opt.label : "");
|
|
2465
|
+
if (disp && String(disp).trim() !== "" && !/^[a-f\d]{24}$/i.test(String(disp))) {
|
|
2466
|
+
return String(disp);
|
|
2467
|
+
}
|
|
1064
2468
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
2469
|
+
}
|
|
2470
|
+
if (typeof rawVal === "object" && rawVal !== null) {
|
|
2471
|
+
const relDisplay = rawVal.title || rawVal.name || rawVal.label;
|
|
2472
|
+
if (relDisplay && !/^[a-f\d]{24}$/i.test(String(relDisplay))) {
|
|
2473
|
+
return String(relDisplay);
|
|
1070
2474
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
2475
|
+
}
|
|
2476
|
+
return /* @__PURE__ */ jsx9("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[11px] font-medium bg-indigo-50 text-indigo-700 border border-indigo-200", children: "\u05E8\u05E9\u05D5\u05DE\u05D4 \u05DE\u05E7\u05D5\u05E9\u05E8\u05EA" });
|
|
2477
|
+
}
|
|
2478
|
+
if (Array.isArray(rawVal)) {
|
|
2479
|
+
const allPrimitives = rawVal.every((v) => typeof v !== "object");
|
|
2480
|
+
if (allPrimitives) {
|
|
2481
|
+
return rawVal.join(", ") || "-";
|
|
2482
|
+
}
|
|
2483
|
+
return /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[11px] font-medium bg-slate-100 text-slate-700 border border-slate-200", children: [
|
|
2484
|
+
rawVal.length,
|
|
2485
|
+
" \u05E4\u05E8\u05D9\u05D8\u05D9\u05DD"
|
|
2486
|
+
] });
|
|
2487
|
+
}
|
|
2488
|
+
if (typeof rawVal === "object" && rawVal !== null) {
|
|
2489
|
+
return "-";
|
|
2490
|
+
}
|
|
2491
|
+
if ((colDef == null ? void 0 : colDef.type) && !isTextRepresentable(colDef.type)) {
|
|
2492
|
+
return "-";
|
|
2493
|
+
}
|
|
2494
|
+
return String(rawVal);
|
|
2495
|
+
}
|
|
2496
|
+
function validateCellValue(val, col) {
|
|
2497
|
+
var _a;
|
|
2498
|
+
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
2499
|
+
const isEmpty = val === void 0 || val === null || typeof val === "string" && val.trim() === "";
|
|
2500
|
+
if (col.isRequired && isEmpty) {
|
|
2501
|
+
return {
|
|
2502
|
+
isValid: false,
|
|
2503
|
+
error: `\u05E9\u05D2\u05D9\u05D0\u05EA \u05D0\u05D9\u05DE\u05D5\u05EA: \u05E9\u05D3\u05D4 '${col.name}' \u05D4\u05D9\u05E0\u05D5 \u05E9\u05D3\u05D4 \u05D7\u05D5\u05D1\u05D4 \u05D5\u05DC\u05D0 \u05D9\u05DB\u05D5\u05DC \u05DC\u05D4\u05D9\u05E9\u05D0\u05E8 \u05E8\u05D9\u05E7.`
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
if (isEmpty) {
|
|
2507
|
+
return { isValid: true };
|
|
2508
|
+
}
|
|
2509
|
+
if (colType === "PHONE") {
|
|
2510
|
+
const strVal = String(val).trim();
|
|
2511
|
+
if (!isValidPhoneNumber(strVal)) {
|
|
2512
|
+
return {
|
|
2513
|
+
isValid: false,
|
|
2514
|
+
error: `\u05DE\u05E1\u05E4\u05E8 \u05D4\u05D8\u05DC\u05E4\u05D5\u05DF \u05D1\u05E9\u05D3\u05D4 '${col.name}' \u05D0\u05D9\u05E0\u05D5 \u05EA\u05E7\u05D9\u05DF. \u05D9\u05E9 \u05DC\u05D4\u05D6\u05D9\u05DF \u05DE\u05E1\u05E4\u05E8 \u05D1\u05D0\u05D5\u05E8\u05DA 9-15 \u05E1\u05E4\u05E8\u05D5\u05EA (\u05DC\u05D3\u05D5\u05D2\u05DE\u05D4 0501234567 \u05D0\u05D5 +972501234567).`
|
|
2515
|
+
};
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
if (colType === "NUMBER" || colType === "CURRENCY") {
|
|
2519
|
+
if (typeof val === "string" && isNaN(Number(val))) {
|
|
2520
|
+
return {
|
|
2521
|
+
isValid: false,
|
|
2522
|
+
error: `\u05D4\u05E2\u05E8\u05DA \u05D1\u05E9\u05D3\u05D4 '${col.name}' \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA \u05DE\u05E1\u05E4\u05E8 \u05EA\u05E7\u05D9\u05DF.`
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
return { isValid: true };
|
|
2527
|
+
}
|
|
2528
|
+
function SubTableCell({
|
|
2529
|
+
record,
|
|
2530
|
+
column,
|
|
2531
|
+
targetSchema,
|
|
2532
|
+
referencedTableId,
|
|
2533
|
+
parentRowId,
|
|
2534
|
+
context,
|
|
2535
|
+
relationOptions,
|
|
2536
|
+
setRelationOptions,
|
|
2537
|
+
refetchRelation,
|
|
2538
|
+
onCommit,
|
|
2539
|
+
onQuietUpdate,
|
|
2540
|
+
width
|
|
2541
|
+
}) {
|
|
2542
|
+
var _a, _b, _c, _d, _e;
|
|
2543
|
+
const colType = ((_a = column.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
2544
|
+
const isContact = colType === "GOOGLE_CONTACT";
|
|
2545
|
+
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
2546
|
+
const serverValue = (_b = record.data[column.name]) != null ? _b : colType === "BOOLEAN" ? false : "";
|
|
2547
|
+
const [draftValue, setDraftValue] = useState9(serverValue);
|
|
2548
|
+
const [isDirty, setIsDirty] = useState9(false);
|
|
2549
|
+
const [validationError, setValidationError] = useState9(null);
|
|
2550
|
+
const cellRef = useRef6(null);
|
|
2551
|
+
const draftRef = useRef6(draftValue);
|
|
2552
|
+
const isDirtyRef = useRef6(isDirty);
|
|
2553
|
+
const serverValueRef = useRef6(serverValue);
|
|
2554
|
+
const recordIdRef = useRef6(record.id);
|
|
2555
|
+
const columnRef = useRef6(column);
|
|
2556
|
+
const onCommitRef = useRef6(onCommit);
|
|
2557
|
+
const isCommittingRef = useRef6(false);
|
|
2558
|
+
const lastFailedValRef = useRef6(void 0);
|
|
2559
|
+
const { addToast } = useToast();
|
|
2560
|
+
draftRef.current = draftValue;
|
|
2561
|
+
isDirtyRef.current = isDirty;
|
|
2562
|
+
serverValueRef.current = serverValue;
|
|
2563
|
+
recordIdRef.current = record.id;
|
|
2564
|
+
columnRef.current = column;
|
|
2565
|
+
onCommitRef.current = onCommit;
|
|
2566
|
+
useEffect7(() => {
|
|
2567
|
+
if (!isDirtyRef.current) {
|
|
2568
|
+
setDraftValue(serverValue);
|
|
2569
|
+
draftRef.current = serverValue;
|
|
2570
|
+
setValidationError(null);
|
|
2571
|
+
lastFailedValRef.current = void 0;
|
|
2572
|
+
}
|
|
2573
|
+
}, [serverValue]);
|
|
2574
|
+
const commit = useCallback8(async (valToCommit) => {
|
|
2575
|
+
if (isCommittingRef.current) return false;
|
|
2576
|
+
if (!isDirtyRef.current) return true;
|
|
2577
|
+
if (valToCommit === serverValueRef.current) {
|
|
2578
|
+
setIsDirty(false);
|
|
2579
|
+
isDirtyRef.current = false;
|
|
2580
|
+
setValidationError(null);
|
|
2581
|
+
lastFailedValRef.current = void 0;
|
|
2582
|
+
return true;
|
|
2583
|
+
}
|
|
2584
|
+
const valRes = validateCellValue(valToCommit, columnRef.current);
|
|
2585
|
+
if (!valRes.isValid) {
|
|
2586
|
+
const errorMsg = valRes.error || "\u05E9\u05D2\u05D9\u05D0\u05EA \u05D0\u05D9\u05DE\u05D5\u05EA";
|
|
2587
|
+
setValidationError(errorMsg);
|
|
2588
|
+
if (lastFailedValRef.current !== valToCommit) {
|
|
2589
|
+
addToast({ type: "error", message: errorMsg });
|
|
2590
|
+
lastFailedValRef.current = valToCommit;
|
|
2591
|
+
}
|
|
2592
|
+
return false;
|
|
2593
|
+
}
|
|
2594
|
+
try {
|
|
2595
|
+
isCommittingRef.current = true;
|
|
2596
|
+
const success = await onCommitRef.current(recordIdRef.current, columnRef.current.name, valToCommit);
|
|
2597
|
+
if (success) {
|
|
2598
|
+
setIsDirty(false);
|
|
2599
|
+
isDirtyRef.current = false;
|
|
2600
|
+
serverValueRef.current = valToCommit;
|
|
2601
|
+
setValidationError(null);
|
|
2602
|
+
lastFailedValRef.current = void 0;
|
|
2603
|
+
return true;
|
|
1073
2604
|
} else {
|
|
1074
|
-
|
|
2605
|
+
setValidationError("\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E9\u05DE\u05D9\u05E8\u05EA \u05D4\u05E8\u05E9\u05D5\u05DE\u05D4");
|
|
2606
|
+
return false;
|
|
1075
2607
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
2608
|
+
} catch (e) {
|
|
2609
|
+
setValidationError("\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E9\u05DE\u05D9\u05E8\u05EA \u05D4\u05E8\u05E9\u05D5\u05DE\u05D4");
|
|
2610
|
+
return false;
|
|
2611
|
+
} finally {
|
|
2612
|
+
isCommittingRef.current = false;
|
|
2613
|
+
}
|
|
2614
|
+
}, [addToast]);
|
|
2615
|
+
const discard = useCallback8(() => {
|
|
2616
|
+
setDraftValue(serverValueRef.current);
|
|
2617
|
+
draftRef.current = serverValueRef.current;
|
|
2618
|
+
setIsDirty(false);
|
|
2619
|
+
isDirtyRef.current = false;
|
|
2620
|
+
setValidationError(null);
|
|
2621
|
+
lastFailedValRef.current = void 0;
|
|
2622
|
+
}, []);
|
|
2623
|
+
useEffect7(() => {
|
|
2624
|
+
return () => {
|
|
2625
|
+
if (isDirtyRef.current && !isCommittingRef.current) {
|
|
2626
|
+
const val = draftRef.current;
|
|
2627
|
+
const orig = serverValueRef.current;
|
|
2628
|
+
if (val !== orig) {
|
|
2629
|
+
const valRes = validateCellValue(val, columnRef.current);
|
|
2630
|
+
if (valRes.isValid) {
|
|
2631
|
+
onCommitRef.current(recordIdRef.current, columnRef.current.name, val);
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
1082
2634
|
}
|
|
1083
2635
|
};
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
children: /* @__PURE__ */ jsx4("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
1094
|
-
}
|
|
1095
|
-
)
|
|
1096
|
-
] });
|
|
2636
|
+
}, []);
|
|
2637
|
+
const handleChange = (newVal) => {
|
|
2638
|
+
setDraftValue(newVal);
|
|
2639
|
+
draftRef.current = newVal;
|
|
2640
|
+
setIsDirty(true);
|
|
2641
|
+
isDirtyRef.current = true;
|
|
2642
|
+
if (validationError) {
|
|
2643
|
+
setValidationError(null);
|
|
2644
|
+
lastFailedValRef.current = void 0;
|
|
1097
2645
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
{
|
|
1101
|
-
onClick: handleSync,
|
|
1102
|
-
disabled: isSyncing,
|
|
1103
|
-
className: "flex items-center gap-1.5 px-3 py-1 bg-blue-50 text-blue-600 hover:bg-blue-100 border border-blue-200 rounded-md text-xs font-medium transition-colors disabled:opacity-50",
|
|
1104
|
-
children: [
|
|
1105
|
-
isSyncing ? /* @__PURE__ */ jsxs4("svg", { className: "w-3.5 h-3.5 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
|
|
1106
|
-
/* @__PURE__ */ jsx4("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
1107
|
-
/* @__PURE__ */ jsx4("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
1108
|
-
] }) : /* @__PURE__ */ jsx4("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 4v16m8-8H4" }) }),
|
|
1109
|
-
"\u05E1\u05E0\u05DB\u05E8\u05DF \u05DC\u05D2\u05D5\u05D2\u05DC"
|
|
1110
|
-
]
|
|
1111
|
-
}
|
|
1112
|
-
) });
|
|
1113
|
-
},
|
|
1114
|
-
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ jsx4(
|
|
1115
|
-
"input",
|
|
1116
|
-
{
|
|
1117
|
-
type: "text",
|
|
1118
|
-
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
1119
|
-
value: value !== void 0 && value !== null ? String(value) : "",
|
|
1120
|
-
onChange: (e) => onChange(e.target.value)
|
|
2646
|
+
if (colType === "BOOLEAN" || colType === "GOOGLE_DRIVE_FILE") {
|
|
2647
|
+
commit(newVal);
|
|
1121
2648
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
if (
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
2649
|
+
};
|
|
2650
|
+
const handleBlur = (e) => {
|
|
2651
|
+
if (e.currentTarget.contains(e.relatedTarget)) {
|
|
2652
|
+
return;
|
|
2653
|
+
}
|
|
2654
|
+
if (isDirtyRef.current) {
|
|
2655
|
+
commit(draftRef.current);
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
const handleKeyDown = (e) => {
|
|
2659
|
+
var _a2, _b2, _c2, _d2;
|
|
2660
|
+
if (e.key === "Enter") {
|
|
2661
|
+
e.preventDefault();
|
|
2662
|
+
if (isDirtyRef.current) {
|
|
2663
|
+
commit(draftRef.current);
|
|
1133
2664
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
2665
|
+
(_b2 = (_a2 = e.target) == null ? void 0 : _a2.blur) == null ? void 0 : _b2.call(_a2);
|
|
2666
|
+
} else if (e.key === "Escape") {
|
|
2667
|
+
e.preventDefault();
|
|
2668
|
+
discard();
|
|
2669
|
+
(_d2 = (_c2 = e.target) == null ? void 0 : _c2.blur) == null ? void 0 : _d2.call(_c2);
|
|
2670
|
+
}
|
|
2671
|
+
};
|
|
2672
|
+
const subTableMetaId = (targetSchema == null ? void 0 : targetSchema.tableMetaId) || (targetSchema == null ? void 0 : targetSchema.id) || referencedTableId;
|
|
2673
|
+
const parentTableId = (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId);
|
|
2674
|
+
const effectiveParentRecordId = parentRowId || ((_c = context == null ? void 0 : context.parentRecord) == null ? void 0 : _c.recordId) || ((_d = context == null ? void 0 : context.parentRecord) == null ? void 0 : _d.id) || (context == null ? void 0 : context.rowId);
|
|
2675
|
+
return /* @__PURE__ */ jsx9(
|
|
2676
|
+
"td",
|
|
2677
|
+
{
|
|
2678
|
+
ref: cellRef,
|
|
2679
|
+
onBlur: handleBlur,
|
|
2680
|
+
onKeyDown: handleKeyDown,
|
|
2681
|
+
title: validationError || void 0,
|
|
2682
|
+
style: width ? { width, minWidth: width, maxWidth: width } : void 0,
|
|
2683
|
+
className: `border border-slate-200 p-0 relative h-8 transition-colors ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"} ${validationError ? "border-rose-400 ring-1 ring-rose-400 bg-rose-50/20" : ""}`,
|
|
2684
|
+
children: /* @__PURE__ */ jsx9(
|
|
2685
|
+
InputComponent,
|
|
1137
2686
|
{
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
2687
|
+
value: draftValue,
|
|
2688
|
+
column,
|
|
2689
|
+
rowId: record.id,
|
|
2690
|
+
onChange: handleChange,
|
|
2691
|
+
context: __spreadProps(__spreadValues({}, context), {
|
|
2692
|
+
tableName: (targetSchema == null ? void 0 : targetSchema.name) || (targetSchema == null ? void 0 : targetSchema.tableName) || (targetSchema == null ? void 0 : targetSchema.title) || (targetSchema == null ? void 0 : targetSchema.id) || "Table",
|
|
2693
|
+
relationOptions,
|
|
2694
|
+
updateRelationOptions: (name, opts) => setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [name]: opts })),
|
|
2695
|
+
refetchRelation,
|
|
2696
|
+
parentTableId,
|
|
2697
|
+
parentRecord: {
|
|
2698
|
+
tableId: parentTableId,
|
|
2699
|
+
recordId: effectiveParentRecordId,
|
|
2700
|
+
id: effectiveParentRecordId,
|
|
2701
|
+
data: (context == null ? void 0 : context.rowData) || ((_e = context == null ? void 0 : context.parentRecord) == null ? void 0 : _e.data)
|
|
2702
|
+
},
|
|
2703
|
+
rowData: record.data,
|
|
2704
|
+
tableId: subTableMetaId,
|
|
2705
|
+
tableMetaId: subTableMetaId,
|
|
2706
|
+
recordId: record.id,
|
|
2707
|
+
orgId: context == null ? void 0 : context.orgId,
|
|
2708
|
+
updateQuietly: (rid, colName, val) => {
|
|
2709
|
+
if (onQuietUpdate) {
|
|
2710
|
+
onQuietUpdate(rid, colName, val);
|
|
2711
|
+
} else {
|
|
2712
|
+
onCommitRef.current(rid, colName, val);
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
})
|
|
2716
|
+
}
|
|
2717
|
+
)
|
|
2718
|
+
}
|
|
2719
|
+
);
|
|
2720
|
+
}
|
|
1151
2721
|
function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
1152
|
-
var _a;
|
|
2722
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1153
2723
|
const { addToast } = useToast();
|
|
1154
2724
|
const entries = Array.isArray(value) ? value : [];
|
|
1155
|
-
const [linkedRecords, setLinkedRecords] =
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
const
|
|
1165
|
-
const
|
|
2725
|
+
const [linkedRecords, setLinkedRecords] = useState9(() => {
|
|
2726
|
+
const initial = [];
|
|
2727
|
+
for (const entry of entries) {
|
|
2728
|
+
if (entry.recordId && entry._resolvedData) {
|
|
2729
|
+
initial.push({ id: entry.recordId, data: entry._resolvedData });
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
return initial;
|
|
2733
|
+
});
|
|
2734
|
+
const [targetSchema, setTargetSchema] = useState9(null);
|
|
2735
|
+
const [isLoading, setIsLoading] = useState9(true);
|
|
2736
|
+
const [isSearchOpen, setIsSearchOpen] = useState9(false);
|
|
2737
|
+
const [searchQuery, setSearchQuery] = useState9("");
|
|
2738
|
+
const [searchResults, setSearchResults] = useState9([]);
|
|
2739
|
+
const [isSearching, setIsSearching] = useState9(false);
|
|
2740
|
+
const [isCreating, setIsCreating] = useState9(false);
|
|
2741
|
+
const [newRecordData, setNewRecordData] = useState9({});
|
|
2742
|
+
const [conflictModalState, setConflictModalState] = useState9({
|
|
2743
|
+
isOpen: false,
|
|
2744
|
+
fieldName: "",
|
|
2745
|
+
matchingRecords: []
|
|
2746
|
+
});
|
|
2747
|
+
const searchRef = useRef6(null);
|
|
2748
|
+
const searchTimerRef = useRef6(null);
|
|
1166
2749
|
const executeAction = context == null ? void 0 : context.executeAction;
|
|
1167
|
-
const referencedTableId = column.referencedTableId;
|
|
1168
|
-
const fetchedIdsRef =
|
|
1169
|
-
|
|
2750
|
+
const referencedTableId = ((_a = column.config) == null ? void 0 : _a.referencedTableId) || column.referencedTableId;
|
|
2751
|
+
const fetchedIdsRef = useRef6(/* @__PURE__ */ new Set());
|
|
2752
|
+
useEffect7(() => {
|
|
2753
|
+
if (entries.length > 0) {
|
|
2754
|
+
setLinkedRecords((prev) => {
|
|
2755
|
+
const existingIds = new Set(prev.map((r) => r.id));
|
|
2756
|
+
const toAdd = [];
|
|
2757
|
+
for (const entry of entries) {
|
|
2758
|
+
if (entry.recordId && entry._resolvedData && !existingIds.has(entry.recordId)) {
|
|
2759
|
+
toAdd.push({ id: entry.recordId, data: entry._resolvedData });
|
|
2760
|
+
existingIds.add(entry.recordId);
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
return toAdd.length > 0 ? [...prev, ...toAdd] : prev;
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2766
|
+
}, [entries]);
|
|
2767
|
+
useEffect7(() => {
|
|
1170
2768
|
if (!referencedTableId || !executeAction) {
|
|
1171
2769
|
setIsLoading(false);
|
|
1172
2770
|
return;
|
|
@@ -1193,7 +2791,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1193
2791
|
recordIdsToFetch.forEach((id) => fetchedIdsRef.current.delete(id));
|
|
1194
2792
|
}).finally(() => setIsLoading(false));
|
|
1195
2793
|
}, [referencedTableId, executeAction, entries, targetSchema]);
|
|
1196
|
-
|
|
2794
|
+
useEffect7(() => {
|
|
1197
2795
|
const handleClick = (e) => {
|
|
1198
2796
|
if (searchRef.current && !searchRef.current.contains(e.target)) {
|
|
1199
2797
|
setIsSearchOpen(false);
|
|
@@ -1202,7 +2800,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1202
2800
|
if (isSearchOpen) document.addEventListener("mousedown", handleClick);
|
|
1203
2801
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
1204
2802
|
}, [isSearchOpen]);
|
|
1205
|
-
const handleSearch =
|
|
2803
|
+
const handleSearch = useCallback8((query) => {
|
|
1206
2804
|
setSearchQuery(query);
|
|
1207
2805
|
if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
|
|
1208
2806
|
if (!query.trim()) {
|
|
@@ -1228,24 +2826,79 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1228
2826
|
}
|
|
1229
2827
|
}, 300);
|
|
1230
2828
|
}, [executeAction, referencedTableId, entries]);
|
|
1231
|
-
const
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
2829
|
+
const [localColumnOrder, setLocalColumnOrder] = useState9(null);
|
|
2830
|
+
useEffect7(() => {
|
|
2831
|
+
setLocalColumnOrder(null);
|
|
2832
|
+
}, [column.name, (_b = column.config) == null ? void 0 : _b.subTableColumnOrder]);
|
|
2833
|
+
const rawTargetColumns = useMemo4(() => {
|
|
2834
|
+
return ((targetSchema == null ? void 0 : targetSchema.columns) || []).filter(
|
|
2835
|
+
(c) => c.name !== "_id" && c.type !== "SUB_TABLE"
|
|
2836
|
+
);
|
|
2837
|
+
}, [targetSchema == null ? void 0 : targetSchema.columns]);
|
|
2838
|
+
const targetColumns = useMemo4(() => {
|
|
2839
|
+
var _a2;
|
|
2840
|
+
const activeOrder = localColumnOrder || ((_a2 = column.config) == null ? void 0 : _a2.subTableColumnOrder);
|
|
2841
|
+
if (!activeOrder || !Array.isArray(activeOrder) || activeOrder.length === 0) {
|
|
2842
|
+
return rawTargetColumns;
|
|
1235
2843
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
2844
|
+
const sorted = [...rawTargetColumns];
|
|
2845
|
+
sorted.sort((a, b) => {
|
|
2846
|
+
const idxA = activeOrder.indexOf(a.name);
|
|
2847
|
+
const idxB = activeOrder.indexOf(b.name);
|
|
2848
|
+
if (idxA === -1 && idxB === -1) return 0;
|
|
2849
|
+
if (idxA === -1) return 1;
|
|
2850
|
+
if (idxB === -1) return -1;
|
|
2851
|
+
return idxA - idxB;
|
|
2852
|
+
});
|
|
2853
|
+
return sorted;
|
|
2854
|
+
}, [rawTargetColumns, localColumnOrder, (_c = column.config) == null ? void 0 : _c.subTableColumnOrder]);
|
|
2855
|
+
const handleSubTableColumnReorder = async (draggedName, dropTargetName) => {
|
|
2856
|
+
if (draggedName === dropTargetName) return;
|
|
2857
|
+
const currentNames = targetColumns.map((c) => c.name);
|
|
2858
|
+
const fromIdx = currentNames.indexOf(draggedName);
|
|
2859
|
+
const toIdx = currentNames.indexOf(dropTargetName);
|
|
2860
|
+
if (fromIdx === -1 || toIdx === -1 || fromIdx === toIdx) return;
|
|
2861
|
+
const newOrder = [...currentNames];
|
|
2862
|
+
const [moved] = newOrder.splice(fromIdx, 1);
|
|
2863
|
+
newOrder.splice(toIdx, 0, moved);
|
|
2864
|
+
setLocalColumnOrder(newOrder);
|
|
2865
|
+
if (context == null ? void 0 : context.onUpdateColumnConfig) {
|
|
2866
|
+
try {
|
|
2867
|
+
await context.onUpdateColumnConfig(column.name, {
|
|
2868
|
+
subTableColumnOrder: newOrder
|
|
2869
|
+
});
|
|
2870
|
+
} catch (err) {
|
|
2871
|
+
console.error("[SubTableViewer] Failed to save sub-table column order:", err);
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
const { draggedColName, dragOverColName, getHeaderDragProps } = useColumnReorder({
|
|
2876
|
+
onReorder: handleSubTableColumnReorder,
|
|
2877
|
+
disabled: isLoading
|
|
2878
|
+
});
|
|
2879
|
+
const targetTableId = (targetSchema == null ? void 0 : targetSchema.tableMetaId) || (targetSchema == null ? void 0 : targetSchema.id) || referencedTableId || column.name;
|
|
2880
|
+
const { columnWidths, startResize } = useColumnResize({
|
|
2881
|
+
storageKey: `table_sub_${targetTableId}_widths`,
|
|
2882
|
+
minWidth: 60,
|
|
2883
|
+
defaultWidth: 150,
|
|
2884
|
+
getMinColWidth: (colName) => {
|
|
2885
|
+
const col = targetColumns.find((c) => c.name === colName);
|
|
2886
|
+
return calculateMinColumnWidth(colName, true, col == null ? void 0 : col.type);
|
|
2887
|
+
}
|
|
2888
|
+
});
|
|
2889
|
+
const [relationOptions, setRelationOptions] = useState9({});
|
|
2890
|
+
useEffect7(() => {
|
|
2891
|
+
if (!executeAction || !(targetSchema == null ? void 0 : targetSchema.columns) || targetSchema.columns.length === 0) return;
|
|
2892
|
+
const relationCols = targetSchema.columns.filter((c) => {
|
|
2893
|
+
var _a2, _b2;
|
|
2894
|
+
return ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION" && ((_b2 = c.config) == null ? void 0 : _b2.referencedTableId);
|
|
1243
2895
|
});
|
|
1244
2896
|
relationCols.forEach(async (col) => {
|
|
2897
|
+
var _a2, _b2;
|
|
1245
2898
|
try {
|
|
1246
2899
|
const options = await executeAction("FETCH_RELATION", {
|
|
1247
|
-
referencedTableId: col.referencedTableId,
|
|
1248
|
-
displayField: col.displayField
|
|
2900
|
+
referencedTableId: (_a2 = col.config) == null ? void 0 : _a2.referencedTableId,
|
|
2901
|
+
displayField: (_b2 = col.config) == null ? void 0 : _b2.displayField
|
|
1249
2902
|
});
|
|
1250
2903
|
if (options && Array.isArray(options)) {
|
|
1251
2904
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
@@ -1255,12 +2908,12 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1255
2908
|
}
|
|
1256
2909
|
});
|
|
1257
2910
|
}, [executeAction, targetColumns]);
|
|
1258
|
-
const refetchRelation =
|
|
1259
|
-
var _a2;
|
|
2911
|
+
const refetchRelation = useCallback8(async (colName) => {
|
|
2912
|
+
var _a2, _b2, _c2;
|
|
1260
2913
|
const col = targetColumns.find((c) => c.name === colName);
|
|
1261
|
-
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !col.referencedTableId || !executeAction) return;
|
|
2914
|
+
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !((_b2 = col.config) == null ? void 0 : _b2.referencedTableId) || !executeAction) return;
|
|
1262
2915
|
try {
|
|
1263
|
-
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
|
|
2916
|
+
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.config.referencedTableId, displayField: (_c2 = col.config) == null ? void 0 : _c2.displayField });
|
|
1264
2917
|
if (options && Array.isArray(options)) {
|
|
1265
2918
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
1266
2919
|
}
|
|
@@ -1291,20 +2944,102 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1291
2944
|
}
|
|
1292
2945
|
}
|
|
1293
2946
|
};
|
|
1294
|
-
const
|
|
1295
|
-
|
|
1296
|
-
const
|
|
1297
|
-
const
|
|
1298
|
-
|
|
2947
|
+
const handleLinkRecords = (recordsToLink) => {
|
|
2948
|
+
if (!recordsToLink || recordsToLink.length === 0) return;
|
|
2949
|
+
const existingEntryIds = new Set(entries.map((e) => e.recordId));
|
|
2950
|
+
const newEntries = [];
|
|
2951
|
+
const newRecordsToAdd = [];
|
|
2952
|
+
for (const record of recordsToLink) {
|
|
2953
|
+
fetchedIdsRef.current.add(record.id);
|
|
2954
|
+
const resolvedData = __spreadValues({}, record.data || {});
|
|
2955
|
+
targetColumns.forEach((col) => {
|
|
2956
|
+
if ((resolvedData[col.name] === void 0 || resolvedData[col.name] === null) && record[col.name] !== void 0) {
|
|
2957
|
+
resolvedData[col.name] = record[col.name];
|
|
2958
|
+
}
|
|
2959
|
+
});
|
|
2960
|
+
if (!existingEntryIds.has(record.id)) {
|
|
2961
|
+
newEntries.push({
|
|
2962
|
+
recordId: record.id,
|
|
2963
|
+
isSelected: true,
|
|
2964
|
+
_resolvedData: resolvedData
|
|
2965
|
+
});
|
|
2966
|
+
existingEntryIds.add(record.id);
|
|
2967
|
+
}
|
|
2968
|
+
newRecordsToAdd.push({
|
|
2969
|
+
id: record.id,
|
|
2970
|
+
data: resolvedData
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
const updatedEntries = [...entries, ...newEntries];
|
|
2974
|
+
updateParentLinkage(updatedEntries);
|
|
1299
2975
|
setLinkedRecords((prev) => {
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
2976
|
+
const map = new Map(prev.map((r) => [r.id, r]));
|
|
2977
|
+
newRecordsToAdd.forEach((r) => {
|
|
2978
|
+
const existing = map.get(r.id);
|
|
2979
|
+
if (existing) {
|
|
2980
|
+
map.set(r.id, __spreadProps(__spreadValues({}, existing), {
|
|
2981
|
+
data: __spreadValues(__spreadValues({}, existing.data), r.data)
|
|
2982
|
+
}));
|
|
2983
|
+
} else {
|
|
2984
|
+
map.set(r.id, r);
|
|
2985
|
+
}
|
|
2986
|
+
});
|
|
2987
|
+
return Array.from(map.values());
|
|
1303
2988
|
});
|
|
1304
2989
|
setSearchQuery("");
|
|
1305
2990
|
setSearchResults([]);
|
|
1306
2991
|
setIsSearchOpen(false);
|
|
1307
2992
|
};
|
|
2993
|
+
const handleLinkRecord = (record) => {
|
|
2994
|
+
handleLinkRecords([record]);
|
|
2995
|
+
};
|
|
2996
|
+
const handleUniqueConflict = (conflictData) => {
|
|
2997
|
+
const rawMatching = Array.isArray(conflictData == null ? void 0 : conflictData.matchingRecords) ? conflictData.matchingRecords : [];
|
|
2998
|
+
const resolvedMatching = rawMatching.map((r) => {
|
|
2999
|
+
var _a2;
|
|
3000
|
+
const recordId = String(r.id || ((_a2 = r._id) == null ? void 0 : _a2.$oid) || r._id);
|
|
3001
|
+
let dataObj = {};
|
|
3002
|
+
if (r.data && typeof r.data === "object") {
|
|
3003
|
+
dataObj = __spreadValues({}, r.data);
|
|
3004
|
+
}
|
|
3005
|
+
targetColumns.forEach((col) => {
|
|
3006
|
+
if ((dataObj[col.name] === void 0 || dataObj[col.name] === null) && r[col.name] !== void 0) {
|
|
3007
|
+
dataObj[col.name] = r[col.name];
|
|
3008
|
+
}
|
|
3009
|
+
});
|
|
3010
|
+
return {
|
|
3011
|
+
id: recordId,
|
|
3012
|
+
data: dataObj
|
|
3013
|
+
};
|
|
3014
|
+
});
|
|
3015
|
+
setConflictModalState({
|
|
3016
|
+
isOpen: true,
|
|
3017
|
+
fieldName: (conflictData == null ? void 0 : conflictData.fieldName) || "",
|
|
3018
|
+
matchingRecords: resolvedMatching
|
|
3019
|
+
});
|
|
3020
|
+
};
|
|
3021
|
+
const handleCancelConflict = () => {
|
|
3022
|
+
setConflictModalState((prev) => __spreadProps(__spreadValues({}, prev), { isOpen: false }));
|
|
3023
|
+
};
|
|
3024
|
+
const handleConfirmLinkConflict = async () => {
|
|
3025
|
+
const { matchingRecords } = conflictModalState;
|
|
3026
|
+
if (matchingRecords && matchingRecords.length > 0) {
|
|
3027
|
+
handleLinkRecords(matchingRecords);
|
|
3028
|
+
setNewRecordData({});
|
|
3029
|
+
setIsCreating(false);
|
|
3030
|
+
setConflictModalState({
|
|
3031
|
+
isOpen: false,
|
|
3032
|
+
fieldName: "",
|
|
3033
|
+
matchingRecords: []
|
|
3034
|
+
});
|
|
3035
|
+
addToast({
|
|
3036
|
+
type: "success",
|
|
3037
|
+
message: "\u05D4\u05E8\u05E9\u05D5\u05DE\u05D4 \u05E7\u05D5\u05E9\u05E8\u05D4 \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
3038
|
+
});
|
|
3039
|
+
} else {
|
|
3040
|
+
setConflictModalState((prev) => __spreadProps(__spreadValues({}, prev), { isOpen: false }));
|
|
3041
|
+
}
|
|
3042
|
+
};
|
|
1308
3043
|
const handleUnlinkRecord = (recordId) => {
|
|
1309
3044
|
const updated = entries.filter((e) => e.recordId !== recordId);
|
|
1310
3045
|
updateParentLinkage(updated);
|
|
@@ -1317,37 +3052,109 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1317
3052
|
);
|
|
1318
3053
|
updateParentLinkage(updated);
|
|
1319
3054
|
};
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
)
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
3055
|
+
const isMountedRef = useRef6(true);
|
|
3056
|
+
useEffect7(() => {
|
|
3057
|
+
isMountedRef.current = true;
|
|
3058
|
+
return () => {
|
|
3059
|
+
isMountedRef.current = false;
|
|
3060
|
+
};
|
|
3061
|
+
}, []);
|
|
3062
|
+
const handleCommitRecordCell = async (recordId, colName, value2) => {
|
|
3063
|
+
var _a2;
|
|
3064
|
+
const previousRecord = linkedRecords.find((r) => r.id === recordId);
|
|
3065
|
+
const previousValue = (_a2 = previousRecord == null ? void 0 : previousRecord.data) == null ? void 0 : _a2[colName];
|
|
3066
|
+
if (previousValue === value2) return true;
|
|
3067
|
+
const targetCol = targetColumns.find((c) => c.name === colName);
|
|
3068
|
+
const valRes = targetCol ? validateCellValue(value2, targetCol) : { isValid: true };
|
|
3069
|
+
if (!valRes.isValid) {
|
|
3070
|
+
addToast({
|
|
3071
|
+
type: "error",
|
|
3072
|
+
message: valRes.error || "\u05E9\u05D2\u05D9\u05D0\u05EA \u05D0\u05D9\u05DE\u05D5\u05EA"
|
|
3073
|
+
});
|
|
3074
|
+
return false;
|
|
1333
3075
|
}
|
|
1334
3076
|
if (executeAction && referencedTableId && !recordId.startsWith("temp_")) {
|
|
1335
3077
|
try {
|
|
1336
|
-
await executeAction("UPDATE_RECORD", {
|
|
3078
|
+
const res = await executeAction("UPDATE_RECORD", {
|
|
1337
3079
|
tableId: referencedTableId,
|
|
3080
|
+
tableMetaId: referencedTableId,
|
|
1338
3081
|
recordId,
|
|
3082
|
+
orgId: context == null ? void 0 : context.orgId,
|
|
1339
3083
|
data: { [colName]: value2 }
|
|
1340
3084
|
});
|
|
1341
|
-
if (
|
|
1342
|
-
|
|
3085
|
+
if (res && res.success === false) {
|
|
3086
|
+
const err = new Error(res.error || res.message || "Action execution failed");
|
|
3087
|
+
Object.assign(err, res);
|
|
3088
|
+
throw err;
|
|
3089
|
+
}
|
|
3090
|
+
if (isMountedRef.current) {
|
|
3091
|
+
const updatedRecords = linkedRecords.map(
|
|
3092
|
+
(r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r
|
|
3093
|
+
);
|
|
3094
|
+
setLinkedRecords(updatedRecords);
|
|
3095
|
+
const targetRecord = updatedRecords.find((r) => r.id === recordId);
|
|
3096
|
+
const updatedEntries = entries.map(
|
|
3097
|
+
(e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { _resolvedData: targetRecord == null ? void 0 : targetRecord.data }) : e
|
|
3098
|
+
);
|
|
3099
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
3100
|
+
context.updateQuietly(rowId, column.name, updatedEntries);
|
|
3101
|
+
} else {
|
|
3102
|
+
onChange(updatedEntries);
|
|
3103
|
+
}
|
|
3104
|
+
if (context == null ? void 0 : context.triggerSaveSuccess) {
|
|
3105
|
+
context.triggerSaveSuccess();
|
|
3106
|
+
}
|
|
1343
3107
|
}
|
|
3108
|
+
return true;
|
|
1344
3109
|
} catch (err) {
|
|
1345
3110
|
console.error("[SubTableViewer] Failed to auto-save linked record field", err);
|
|
3111
|
+
let errorMsg = (err == null ? void 0 : err.message) || (err == null ? void 0 : err.error) || "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E9\u05DE\u05D9\u05E8\u05EA \u05D4\u05E8\u05E9\u05D5\u05DE\u05D4";
|
|
3112
|
+
if ((err == null ? void 0 : err.error) === "UNIQUE_CONSTRAINT_CONFLICT" || (err == null ? void 0 : err.code) === "UNIQUE_CONSTRAINT_CONFLICT" || errorMsg.includes("must be unique") || errorMsg.includes("Duplicate value detected") || errorMsg.includes("\u05DB\u05D1\u05E8 \u05E7\u05D9\u05D9\u05DE\u05EA") || errorMsg.includes("UNIQUE_CONSTRAINT_CONFLICT")) {
|
|
3113
|
+
errorMsg = `\u05E9\u05D2\u05D9\u05D0\u05EA \u05D0\u05D9\u05DE\u05D5\u05EA: \u05D4\u05E2\u05E8\u05DA '${value2}' \u05DB\u05D1\u05E8 \u05E7\u05D9\u05D9\u05DD \u05D1\u05E9\u05D3\u05D4 '${colName}' (\u05E9\u05D3\u05D4 \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9).`;
|
|
3114
|
+
} else if (errorMsg.includes("is required") || errorMsg.includes("\u05E9\u05D3\u05D4 \u05D7\u05D5\u05D1\u05D4") || errorMsg.toLowerCase().includes("required")) {
|
|
3115
|
+
errorMsg = `\u05E9\u05D2\u05D9\u05D0\u05EA \u05D0\u05D9\u05DE\u05D5\u05EA: \u05E9\u05D3\u05D4 '${colName}' \u05D4\u05D9\u05E0\u05D5 \u05E9\u05D3\u05D4 \u05D7\u05D5\u05D1\u05D4 \u05D5\u05DC\u05D0 \u05D9\u05DB\u05D5\u05DC \u05DC\u05D4\u05D9\u05E9\u05D0\u05E8 \u05E8\u05D9\u05E7.`;
|
|
3116
|
+
}
|
|
3117
|
+
addToast({
|
|
3118
|
+
type: "error",
|
|
3119
|
+
message: errorMsg
|
|
3120
|
+
});
|
|
3121
|
+
return false;
|
|
3122
|
+
}
|
|
3123
|
+
} else {
|
|
3124
|
+
if (isMountedRef.current) {
|
|
3125
|
+
const updatedRecords = linkedRecords.map(
|
|
3126
|
+
(r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r
|
|
3127
|
+
);
|
|
3128
|
+
setLinkedRecords(updatedRecords);
|
|
3129
|
+
const targetRecord = updatedRecords.find((r) => r.id === recordId);
|
|
3130
|
+
const updatedEntries = entries.map(
|
|
3131
|
+
(e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { _resolvedData: targetRecord == null ? void 0 : targetRecord.data }) : e
|
|
3132
|
+
);
|
|
3133
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
3134
|
+
context.updateQuietly(rowId, column.name, updatedEntries);
|
|
3135
|
+
} else {
|
|
3136
|
+
onChange(updatedEntries);
|
|
3137
|
+
}
|
|
1346
3138
|
}
|
|
3139
|
+
return true;
|
|
1347
3140
|
}
|
|
1348
3141
|
};
|
|
3142
|
+
const handleRecordCellChange = handleCommitRecordCell;
|
|
3143
|
+
const handleQuietSubTableCellChange = useCallback8((recordId, colName, value2) => {
|
|
3144
|
+
setLinkedRecords(
|
|
3145
|
+
(prev) => prev.map((r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r)
|
|
3146
|
+
);
|
|
3147
|
+
const updatedEntries = entries.map(
|
|
3148
|
+
(e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { _resolvedData: __spreadProps(__spreadValues({}, e._resolvedData || {}), { [colName]: value2 }) }) : e
|
|
3149
|
+
);
|
|
3150
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
3151
|
+
context.updateQuietly(rowId, column.name, updatedEntries);
|
|
3152
|
+
} else {
|
|
3153
|
+
onChange(updatedEntries);
|
|
3154
|
+
}
|
|
3155
|
+
}, [entries, context, rowId, column.name, onChange]);
|
|
1349
3156
|
const handleCreateRecord = async () => {
|
|
1350
|
-
var _a2;
|
|
3157
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
1351
3158
|
if (!executeAction || !referencedTableId) return;
|
|
1352
3159
|
for (const col of targetColumns) {
|
|
1353
3160
|
if (col.isRequired) {
|
|
@@ -1360,16 +3167,32 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1360
3167
|
return;
|
|
1361
3168
|
}
|
|
1362
3169
|
}
|
|
3170
|
+
if (((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) === "PHONE") {
|
|
3171
|
+
const val = newRecordData[col.name];
|
|
3172
|
+
if (val !== void 0 && val !== null && String(val).trim() !== "" && !isValidPhoneNumber(String(val))) {
|
|
3173
|
+
addToast({
|
|
3174
|
+
type: "error",
|
|
3175
|
+
message: `\u05DE\u05E1\u05E4\u05E8 \u05D4\u05D8\u05DC\u05E4\u05D5\u05DF \u05D1\u05E9\u05D3\u05D4 '${col.name}' \u05D0\u05D9\u05E0\u05D5 \u05EA\u05E7\u05D9\u05DF. \u05D9\u05E9 \u05DC\u05D4\u05D6\u05D9\u05DF \u05DE\u05E1\u05E4\u05E8 \u05D1\u05D0\u05D5\u05E8\u05DA 9-15 \u05E1\u05E4\u05E8\u05D5\u05EA.`
|
|
3176
|
+
});
|
|
3177
|
+
return;
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
1363
3180
|
}
|
|
1364
3181
|
try {
|
|
1365
3182
|
const res = await executeAction("CREATE_RECORD", {
|
|
1366
3183
|
tableId: referencedTableId,
|
|
3184
|
+
tableMetaId: referencedTableId,
|
|
3185
|
+
orgId: context == null ? void 0 : context.orgId,
|
|
1367
3186
|
records: [newRecordData]
|
|
1368
3187
|
});
|
|
3188
|
+
if (res && (res.error === "UNIQUE_CONSTRAINT_CONFLICT" || res.code === "UNIQUE_CONSTRAINT_CONFLICT")) {
|
|
3189
|
+
handleUniqueConflict(res);
|
|
3190
|
+
return;
|
|
3191
|
+
}
|
|
1369
3192
|
if (res && res.success === false) {
|
|
1370
3193
|
throw new Error(res.error || "Action execution failed");
|
|
1371
3194
|
}
|
|
1372
|
-
const created = Array.isArray(res) ? res[0] : ((
|
|
3195
|
+
const created = Array.isArray(res) ? res[0] : ((_b2 = res == null ? void 0 : res.data) == null ? void 0 : _b2[0]) || res;
|
|
1373
3196
|
if (created) {
|
|
1374
3197
|
const newRecord = {
|
|
1375
3198
|
id: String(created.id || created._id),
|
|
@@ -1380,6 +3203,12 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1380
3203
|
setNewRecordData({});
|
|
1381
3204
|
}
|
|
1382
3205
|
} catch (err) {
|
|
3206
|
+
const isConflict = (err == null ? void 0 : err.error) === "UNIQUE_CONSTRAINT_CONFLICT" || (err == null ? void 0 : err.code) === "UNIQUE_CONSTRAINT_CONFLICT" || ((_c2 = err == null ? void 0 : err.data) == null ? void 0 : _c2.error) === "UNIQUE_CONSTRAINT_CONFLICT" || ((_d2 = err == null ? void 0 : err.message) == null ? void 0 : _d2.includes("UNIQUE_CONSTRAINT_CONFLICT"));
|
|
3207
|
+
if (isConflict) {
|
|
3208
|
+
const conflictPayload = (err == null ? void 0 : err.error) === "UNIQUE_CONSTRAINT_CONFLICT" ? err : ((_e2 = err == null ? void 0 : err.data) == null ? void 0 : _e2.error) === "UNIQUE_CONSTRAINT_CONFLICT" ? err.data : err;
|
|
3209
|
+
handleUniqueConflict(conflictPayload);
|
|
3210
|
+
return;
|
|
3211
|
+
}
|
|
1383
3212
|
const msg = (err == null ? void 0 : err.message) || String(err);
|
|
1384
3213
|
addToast({
|
|
1385
3214
|
type: "error",
|
|
@@ -1388,32 +3217,33 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1388
3217
|
}
|
|
1389
3218
|
};
|
|
1390
3219
|
const getDisplayLabel = (record) => {
|
|
1391
|
-
|
|
3220
|
+
var _a2;
|
|
3221
|
+
const fields = ((_a2 = column.config) == null ? void 0 : _a2.subTableDisplayFields) || [];
|
|
1392
3222
|
if (fields.length === 0) {
|
|
1393
3223
|
const firstField = Object.keys(record.data).find((k) => k !== "_id");
|
|
1394
3224
|
return firstField ? String(record.data[firstField] || "") : record.id;
|
|
1395
3225
|
}
|
|
1396
3226
|
return fields.map((f) => String(record.data[f] || "")).filter(Boolean).join(" ");
|
|
1397
3227
|
};
|
|
1398
|
-
return /* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
3228
|
+
return /* @__PURE__ */ jsxs9("div", { className: "p-3 animate-in fade-in slide-in-from-top-2 duration-200", dir: "rtl", children: [
|
|
3229
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-4 mb-2.5", children: [
|
|
3230
|
+
/* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx9("span", { className: "text-xs font-bold text-slate-600", children: (_e = targetSchema == null ? void 0 : targetSchema.name) != null ? _e : (_d = column.config) == null ? void 0 : _d.referencedTableName }) }),
|
|
3231
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
|
|
3232
|
+
/* @__PURE__ */ jsxs9("div", { className: "relative", ref: searchRef, children: [
|
|
3233
|
+
/* @__PURE__ */ jsxs9(
|
|
1404
3234
|
"button",
|
|
1405
3235
|
{
|
|
1406
3236
|
type: "button",
|
|
1407
3237
|
onClick: () => setIsSearchOpen((prev) => !prev),
|
|
1408
3238
|
className: "h-7 px-2.5 text-[11px] font-semibold bg-blue-50 hover:bg-blue-100 text-blue-700 border border-blue-200 rounded-md transition-colors cursor-pointer flex items-center gap-1",
|
|
1409
3239
|
children: [
|
|
1410
|
-
/* @__PURE__ */
|
|
3240
|
+
/* @__PURE__ */ jsx9("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
|
|
1411
3241
|
"\u05E7\u05D9\u05E9\u05D5\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA"
|
|
1412
3242
|
]
|
|
1413
3243
|
}
|
|
1414
3244
|
),
|
|
1415
|
-
isSearchOpen && /* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
3245
|
+
isSearchOpen && /* @__PURE__ */ jsxs9("div", { className: "absolute right-0 top-full mt-1 w-72 bg-white border border-slate-200 rounded-lg shadow-xl z-50 p-2", children: [
|
|
3246
|
+
/* @__PURE__ */ jsx9(
|
|
1417
3247
|
"input",
|
|
1418
3248
|
{
|
|
1419
3249
|
type: "text",
|
|
@@ -1424,7 +3254,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1424
3254
|
autoFocus: true
|
|
1425
3255
|
}
|
|
1426
3256
|
),
|
|
1427
|
-
/* @__PURE__ */
|
|
3257
|
+
/* @__PURE__ */ jsx9("div", { className: "max-h-48 overflow-y-auto", children: isSearching ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsx9("div", { className: "w-4 h-4 border-2 border-blue-400 border-t-transparent rounded-full animate-spin" }) }) : searchResults.length > 0 ? searchResults.map((r) => /* @__PURE__ */ jsx9(
|
|
1428
3258
|
"button",
|
|
1429
3259
|
{
|
|
1430
3260
|
type: "button",
|
|
@@ -1433,10 +3263,10 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1433
3263
|
children: getDisplayLabel(r)
|
|
1434
3264
|
},
|
|
1435
3265
|
r.id
|
|
1436
|
-
)) : searchQuery.trim() ? /* @__PURE__ */
|
|
3266
|
+
)) : searchQuery.trim() ? /* @__PURE__ */ jsx9("p", { className: "text-xs text-slate-400 text-center py-3", children: "\u05DC\u05D0 \u05E0\u05DE\u05E6\u05D0\u05D5 \u05EA\u05D5\u05E6\u05D0\u05D5\u05EA" }) : /* @__PURE__ */ jsx9("p", { className: "text-xs text-slate-400 text-center py-3", children: "\u05D4\u05E7\u05DC\u05D3 \u05DC\u05D7\u05D9\u05E4\u05D5\u05E9..." }) })
|
|
1437
3267
|
] })
|
|
1438
3268
|
] }),
|
|
1439
|
-
/* @__PURE__ */
|
|
3269
|
+
/* @__PURE__ */ jsxs9(
|
|
1440
3270
|
"button",
|
|
1441
3271
|
{
|
|
1442
3272
|
type: "button",
|
|
@@ -1456,24 +3286,69 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1456
3286
|
},
|
|
1457
3287
|
className: "h-7 px-2.5 text-[11px] font-semibold bg-emerald-50 hover:bg-emerald-100 text-emerald-700 border border-emerald-200 rounded-md transition-colors cursor-pointer flex items-center gap-1",
|
|
1458
3288
|
children: [
|
|
1459
|
-
/* @__PURE__ */
|
|
3289
|
+
/* @__PURE__ */ jsx9("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) }),
|
|
1460
3290
|
"\u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4"
|
|
1461
3291
|
]
|
|
1462
3292
|
}
|
|
1463
3293
|
)
|
|
1464
3294
|
] })
|
|
1465
3295
|
] }),
|
|
1466
|
-
isLoading ? /* @__PURE__ */
|
|
1467
|
-
/* @__PURE__ */
|
|
1468
|
-
/* @__PURE__ */
|
|
1469
|
-
targetColumns.map((col) =>
|
|
1470
|
-
|
|
3296
|
+
isLoading ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ jsx9("div", { className: "w-5 h-5 border-2 border-blue-400 border-t-transparent rounded-full animate-spin" }) }) : entries.length === 0 && !isCreating ? /* @__PURE__ */ jsx9("div", { className: "text-center py-6 text-xs text-slate-400", children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DE\u05E7\u05D5\u05E9\u05E8\u05D5\u05EA. \u05D4\u05E9\u05EA\u05DE\u05E9 \u05D1\u05D7\u05D9\u05E4\u05D5\u05E9 \u05DB\u05D3\u05D9 \u05DC\u05E7\u05E9\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05E7\u05D9\u05D9\u05DE\u05D5\u05EA, \u05D0\u05D5 \u05D4\u05D5\u05E1\u05E3 \u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4." }) : /* @__PURE__ */ jsx9("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-xs border-collapse table-auto", children: [
|
|
3297
|
+
/* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-slate-100/80 h-12 min-h-[48px]", children: [
|
|
3298
|
+
/* @__PURE__ */ jsx9("th", { className: "border border-slate-200 px-2 py-1.5 text-center w-10 font-semibold text-slate-500 h-12 min-h-[48px] align-middle", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: "\u05E0\u05D1\u05D7\u05E8" }),
|
|
3299
|
+
targetColumns.map((col) => {
|
|
3300
|
+
const dragProps = getHeaderDragProps(col.name);
|
|
3301
|
+
const isDragging = draggedColName === col.name;
|
|
3302
|
+
const isDragOver = dragOverColName === col.name;
|
|
3303
|
+
const colMinWidth = calculateMinColumnWidth(col.name, true, col.type);
|
|
3304
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 150);
|
|
3305
|
+
return /* @__PURE__ */ jsxs9(
|
|
3306
|
+
"th",
|
|
3307
|
+
__spreadProps(__spreadValues({
|
|
3308
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3309
|
+
title: col.name
|
|
3310
|
+
}, dragProps), {
|
|
3311
|
+
className: `relative border border-slate-200 px-3 py-1.5 font-semibold text-slate-600 select-none cursor-grab active:cursor-grabbing transition-colors h-12 min-h-[48px] align-middle ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : "hover:bg-slate-200/60"}`,
|
|
3312
|
+
children: [
|
|
3313
|
+
/* @__PURE__ */ jsx9(
|
|
3314
|
+
"div",
|
|
3315
|
+
{
|
|
3316
|
+
onMouseDown: (e) => {
|
|
3317
|
+
e.preventDefault();
|
|
3318
|
+
e.stopPropagation();
|
|
3319
|
+
startResize(col.name, currentWidth, e.clientX, colMinWidth);
|
|
3320
|
+
},
|
|
3321
|
+
className: "absolute left-0 top-0 bottom-0 w-1.5 cursor-col-resize hover:bg-brand active:bg-brand-hover z-20",
|
|
3322
|
+
title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
|
|
3323
|
+
}
|
|
3324
|
+
),
|
|
3325
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-1.5 group overflow-hidden w-full", title: col.name, children: [
|
|
3326
|
+
/* @__PURE__ */ jsx9(ColumnHeaderTitle, { name: col.name, width: currentWidth, isSubTable: true }),
|
|
3327
|
+
/* @__PURE__ */ jsx9(
|
|
3328
|
+
"svg",
|
|
3329
|
+
{
|
|
3330
|
+
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
3331
|
+
fill: "none",
|
|
3332
|
+
viewBox: "0 0 24 24",
|
|
3333
|
+
stroke: "currentColor",
|
|
3334
|
+
children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
|
|
3335
|
+
}
|
|
3336
|
+
)
|
|
3337
|
+
] })
|
|
3338
|
+
]
|
|
3339
|
+
}),
|
|
3340
|
+
col.name
|
|
3341
|
+
);
|
|
3342
|
+
}),
|
|
3343
|
+
/* @__PURE__ */ jsx9("th", { className: "border border-slate-200 px-2 py-1.5 w-14 h-12 min-h-[48px]", style: { width: 56, minWidth: 56, maxWidth: 56 } }),
|
|
3344
|
+
/* @__PURE__ */ jsx9("th", { className: "w-full min-w-[50px] border border-slate-200 pointer-events-none h-12 min-h-[48px]" })
|
|
1471
3345
|
] }) }),
|
|
1472
|
-
/* @__PURE__ */
|
|
3346
|
+
/* @__PURE__ */ jsxs9("tbody", { children: [
|
|
1473
3347
|
entries.map((entry) => {
|
|
3348
|
+
var _a2;
|
|
1474
3349
|
const record = linkedRecords.find((r) => r.id === entry.recordId);
|
|
1475
|
-
return /* @__PURE__ */
|
|
1476
|
-
/* @__PURE__ */
|
|
3350
|
+
return /* @__PURE__ */ jsxs9("tr", { className: "hover:bg-blue-50/30 transition-colors", children: [
|
|
3351
|
+
/* @__PURE__ */ jsx9("td", { className: "border border-slate-200 px-2 py-1 text-center", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: /* @__PURE__ */ jsx9(
|
|
1477
3352
|
"input",
|
|
1478
3353
|
{
|
|
1479
3354
|
type: "checkbox",
|
|
@@ -1483,74 +3358,129 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1483
3358
|
}
|
|
1484
3359
|
) }),
|
|
1485
3360
|
targetColumns.map((col) => {
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
3361
|
+
const currentWidth = columnWidths[col.name] || 150;
|
|
3362
|
+
if (!record) {
|
|
3363
|
+
return /* @__PURE__ */ jsx9(
|
|
3364
|
+
"td",
|
|
3365
|
+
{
|
|
3366
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3367
|
+
className: "border border-slate-200 p-0 relative h-8 overflow-hidden",
|
|
3368
|
+
children: /* @__PURE__ */ jsx9("span", { className: "text-slate-300 italic px-2", children: "\u05D8\u05D5\u05E2\u05DF..." })
|
|
3369
|
+
},
|
|
3370
|
+
col.name
|
|
3371
|
+
);
|
|
3372
|
+
}
|
|
3373
|
+
return /* @__PURE__ */ jsx9(
|
|
3374
|
+
SubTableCell,
|
|
1491
3375
|
{
|
|
1492
|
-
|
|
3376
|
+
record,
|
|
1493
3377
|
column: col,
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
) : /* @__PURE__ */ jsx5("span", { className: "text-slate-300 italic px-2", children: "\u05D8\u05D5\u05E2\u05DF..." }) }, col.name);
|
|
3378
|
+
targetSchema,
|
|
3379
|
+
referencedTableId,
|
|
3380
|
+
parentRowId: rowId,
|
|
3381
|
+
context,
|
|
3382
|
+
relationOptions,
|
|
3383
|
+
setRelationOptions,
|
|
3384
|
+
refetchRelation,
|
|
3385
|
+
onCommit: handleCommitRecordCell,
|
|
3386
|
+
onQuietUpdate: handleQuietSubTableCellChange,
|
|
3387
|
+
width: currentWidth
|
|
3388
|
+
},
|
|
3389
|
+
`${record.id}_${col.name}`
|
|
3390
|
+
);
|
|
1508
3391
|
}),
|
|
1509
|
-
/* @__PURE__ */
|
|
1510
|
-
"
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
3392
|
+
/* @__PURE__ */ jsx9("td", { className: "border border-slate-200 px-1 py-1 text-center", style: { width: 56, minWidth: 56, maxWidth: 56 }, children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-center gap-1", children: [
|
|
3393
|
+
((_a2 = column.config) == null ? void 0 : _a2.actionType) === "WHATSAPP" && (() => {
|
|
3394
|
+
var _a3, _b2, _c2;
|
|
3395
|
+
const actionPhoneCol = (_a3 = column.config) == null ? void 0 : _a3.actionPhoneColumn;
|
|
3396
|
+
const phone = actionPhoneCol ? ((_b2 = record == null ? void 0 : record.data) == null ? void 0 : _b2[actionPhoneCol]) || ((_c2 = entry._resolvedData) == null ? void 0 : _c2[actionPhoneCol]) : null;
|
|
3397
|
+
if (phone) {
|
|
3398
|
+
return /* @__PURE__ */ jsx9(
|
|
3399
|
+
"button",
|
|
3400
|
+
{
|
|
3401
|
+
type: "button",
|
|
3402
|
+
onClick: (e) => {
|
|
3403
|
+
e.stopPropagation();
|
|
3404
|
+
openWhatsAppChat(String(phone));
|
|
3405
|
+
},
|
|
3406
|
+
className: "text-emerald-500 hover:text-emerald-600 p-0.5 rounded hover:bg-emerald-50 transition-colors cursor-pointer",
|
|
3407
|
+
title: `\u05E4\u05EA\u05D9\u05D7\u05EA \u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4 (${phone})`,
|
|
3408
|
+
children: /* @__PURE__ */ jsx9("svg", { className: "w-3.5 h-3.5", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a5.816 5.816 0 00-.571-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" }) })
|
|
3409
|
+
}
|
|
3410
|
+
);
|
|
3411
|
+
}
|
|
3412
|
+
return null;
|
|
3413
|
+
})(),
|
|
3414
|
+
/* @__PURE__ */ jsx9(
|
|
3415
|
+
"button",
|
|
3416
|
+
{
|
|
3417
|
+
type: "button",
|
|
3418
|
+
onClick: (e) => {
|
|
3419
|
+
e.stopPropagation();
|
|
3420
|
+
handleUnlinkRecord(entry.recordId);
|
|
3421
|
+
},
|
|
3422
|
+
className: "text-slate-400 hover:text-rose-500 p-0.5 rounded transition-colors cursor-pointer inline-flex items-center justify-center",
|
|
3423
|
+
title: "\u05D4\u05E1\u05E8 \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
3424
|
+
children: /* @__PURE__ */ jsx9("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
3425
|
+
}
|
|
3426
|
+
)
|
|
3427
|
+
] }) }),
|
|
3428
|
+
/* @__PURE__ */ jsx9("td", { className: "border border-slate-200 bg-white pointer-events-none" })
|
|
1519
3429
|
] }, entry.recordId);
|
|
1520
3430
|
}),
|
|
1521
|
-
isCreating && /* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
3431
|
+
isCreating && /* @__PURE__ */ jsxs9("tr", { className: "bg-emerald-50/40", children: [
|
|
3432
|
+
/* @__PURE__ */ jsx9("td", { className: "border border-emerald-200 px-2 py-1 text-center", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: /* @__PURE__ */ jsx9("span", { className: "text-emerald-500 font-bold text-[10px]", children: "\u05D7\u05D3\u05E9" }) }),
|
|
1523
3433
|
targetColumns.map((col) => {
|
|
1524
|
-
var _a2,
|
|
3434
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
1525
3435
|
const colType = ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) || "DEFAULT";
|
|
1526
3436
|
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
1527
|
-
|
|
1528
|
-
|
|
3437
|
+
const currentWidth = columnWidths[col.name] || 150;
|
|
3438
|
+
const effectiveParentId = rowId || ((_b2 = context == null ? void 0 : context.parentRecord) == null ? void 0 : _b2.recordId) || ((_c2 = context == null ? void 0 : context.parentRecord) == null ? void 0 : _c2.id) || (context == null ? void 0 : context.rowId);
|
|
3439
|
+
return /* @__PURE__ */ jsx9(
|
|
3440
|
+
"td",
|
|
1529
3441
|
{
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
3442
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3443
|
+
className: `border border-emerald-200 p-0 relative h-8 ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
3444
|
+
children: /* @__PURE__ */ jsx9(
|
|
3445
|
+
InputComponent,
|
|
3446
|
+
{
|
|
3447
|
+
value: (_d2 = newRecordData[col.name]) != null ? _d2 : colType === "BOOLEAN" ? false : "",
|
|
3448
|
+
column: col,
|
|
3449
|
+
rowId: "new_record",
|
|
3450
|
+
onChange: (v) => setNewRecordData((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: v })),
|
|
3451
|
+
context: __spreadProps(__spreadValues({}, context), {
|
|
3452
|
+
tableName: (targetSchema == null ? void 0 : targetSchema.name) || (targetSchema == null ? void 0 : targetSchema.tableName) || (targetSchema == null ? void 0 : targetSchema.title) || (targetSchema == null ? void 0 : targetSchema.id) || "Table",
|
|
3453
|
+
relationOptions,
|
|
3454
|
+
refetchRelation,
|
|
3455
|
+
parentTableId: (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId),
|
|
3456
|
+
parentRecord: {
|
|
3457
|
+
tableId: (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId),
|
|
3458
|
+
recordId: effectiveParentId,
|
|
3459
|
+
id: effectiveParentId,
|
|
3460
|
+
data: (context == null ? void 0 : context.rowData) || ((_e2 = context == null ? void 0 : context.parentRecord) == null ? void 0 : _e2.data)
|
|
3461
|
+
},
|
|
3462
|
+
tableId: targetTableId,
|
|
3463
|
+
tableMetaId: targetTableId,
|
|
3464
|
+
orgId: context == null ? void 0 : context.orgId
|
|
3465
|
+
})
|
|
3466
|
+
}
|
|
3467
|
+
)
|
|
3468
|
+
},
|
|
3469
|
+
`new_${col.name}`
|
|
3470
|
+
);
|
|
1541
3471
|
}),
|
|
1542
|
-
/* @__PURE__ */
|
|
1543
|
-
/* @__PURE__ */
|
|
3472
|
+
/* @__PURE__ */ jsx9("td", { className: "border border-emerald-200 px-1 py-1 text-center", style: { width: 56, minWidth: 56, maxWidth: 56 }, children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-center gap-1", children: [
|
|
3473
|
+
/* @__PURE__ */ jsx9(
|
|
1544
3474
|
"button",
|
|
1545
3475
|
{
|
|
1546
3476
|
type: "button",
|
|
1547
3477
|
onClick: handleCreateRecord,
|
|
1548
3478
|
className: "p-1 text-emerald-600 hover:bg-emerald-100 rounded transition-colors",
|
|
1549
3479
|
title: "\u05E9\u05DE\u05D5\u05E8",
|
|
1550
|
-
children: /* @__PURE__ */
|
|
3480
|
+
children: /* @__PURE__ */ jsx9("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) })
|
|
1551
3481
|
}
|
|
1552
3482
|
),
|
|
1553
|
-
/* @__PURE__ */
|
|
3483
|
+
/* @__PURE__ */ jsx9(
|
|
1554
3484
|
"button",
|
|
1555
3485
|
{
|
|
1556
3486
|
type: "button",
|
|
@@ -1559,19 +3489,107 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1559
3489
|
},
|
|
1560
3490
|
className: "p-1 text-rose-500 hover:bg-rose-100 rounded transition-colors",
|
|
1561
3491
|
title: "\u05D1\u05D9\u05D8\u05D5\u05DC",
|
|
1562
|
-
children: /* @__PURE__ */
|
|
3492
|
+
children: /* @__PURE__ */ jsx9("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M6 18L18 6M6 6l12 12" }) })
|
|
1563
3493
|
}
|
|
1564
3494
|
)
|
|
1565
|
-
] }) })
|
|
3495
|
+
] }) }),
|
|
3496
|
+
/* @__PURE__ */ jsx9("td", { className: "border border-emerald-200 bg-emerald-50/40 pointer-events-none" })
|
|
1566
3497
|
] })
|
|
1567
3498
|
] })
|
|
1568
|
-
] }) })
|
|
3499
|
+
] }) }),
|
|
3500
|
+
conflictModalState.isOpen && /* @__PURE__ */ jsx9(
|
|
3501
|
+
"div",
|
|
3502
|
+
{
|
|
3503
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/60 backdrop-blur-sm animate-in fade-in duration-200",
|
|
3504
|
+
dir: "rtl",
|
|
3505
|
+
onClick: handleCancelConflict,
|
|
3506
|
+
children: /* @__PURE__ */ jsxs9(
|
|
3507
|
+
"div",
|
|
3508
|
+
{
|
|
3509
|
+
className: "bg-white rounded-xl shadow-2xl w-full max-w-lg sm:max-w-xl overflow-hidden border border-slate-200 animate-in fade-in zoom-in-95 duration-200",
|
|
3510
|
+
onClick: (e) => e.stopPropagation(),
|
|
3511
|
+
children: [
|
|
3512
|
+
/* @__PURE__ */ jsxs9("div", { className: "p-5 border-b border-slate-100 flex items-center gap-3", children: [
|
|
3513
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 rounded-full bg-blue-50 border border-blue-200 flex items-center justify-center text-blue-600 flex-shrink-0", children: /* @__PURE__ */ jsx9("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" }) }) }),
|
|
3514
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
3515
|
+
/* @__PURE__ */ jsx9("h3", { className: "text-base font-bold text-slate-800", children: conflictModalState.matchingRecords.length > 1 ? "\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05E7\u05D9\u05D9\u05DE\u05D5\u05EA \u05D1\u05D8\u05D1\u05DC\u05D4" : "\u05E8\u05E9\u05D5\u05DE\u05D4 \u05E7\u05D9\u05D9\u05DE\u05EA \u05D1\u05D8\u05D1\u05DC\u05D4" }),
|
|
3516
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-slate-500", children: "\u05E0\u05DE\u05E6\u05D0\u05D4 \u05E8\u05E9\u05D5\u05DE\u05D4 \u05E7\u05D9\u05D9\u05DE\u05EA \u05E2\u05DD \u05D0\u05D5\u05EA\u05D5 \u05E2\u05E8\u05DA \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9" })
|
|
3517
|
+
] })
|
|
3518
|
+
] }),
|
|
3519
|
+
/* @__PURE__ */ jsxs9("div", { className: "p-5 space-y-3", children: [
|
|
3520
|
+
/* @__PURE__ */ jsxs9("p", { className: "text-sm text-slate-700 leading-relaxed", children: [
|
|
3521
|
+
"\u05E7\u05D9\u05D9\u05DE\u05EA \u05DB\u05D1\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D4 \u05E2\u05DD \u05D4\u05E2\u05E8\u05DA \u05E9\u05E0\u05D1\u05D7\u05E8 \u05D1\u05E9\u05D3\u05D4",
|
|
3522
|
+
" ",
|
|
3523
|
+
/* @__PURE__ */ jsx9("span", { className: "font-bold text-slate-900 bg-slate-100 px-1.5 py-0.5 rounded border border-slate-200", children: conflictModalState.fieldName }),
|
|
3524
|
+
". \u05D4\u05D0\u05DD \u05EA\u05E8\u05E6\u05D4 \u05DC\u05E7\u05E9\u05E8 \u05D0\u05D5\u05EA\u05D4 \u05DC\u05EA\u05EA-\u05D4\u05D8\u05D1\u05DC\u05D4 \u05D1\u05DE\u05E7\u05D5\u05DD \u05DC\u05D9\u05E6\u05D5\u05E8 \u05D7\u05D3\u05E9\u05D4?"
|
|
3525
|
+
] }),
|
|
3526
|
+
conflictModalState.matchingRecords.length > 1 && /* @__PURE__ */ jsxs9("div", { className: "p-3 bg-blue-50 border border-blue-200 rounded-lg text-xs font-semibold text-blue-800", children: [
|
|
3527
|
+
"\u05E0\u05DE\u05E6\u05D0\u05D5 ",
|
|
3528
|
+
conflictModalState.matchingRecords.length,
|
|
3529
|
+
" \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05E7\u05D9\u05D9\u05DE\u05D5\u05EA. \u05D4\u05D0\u05DD \u05DC\u05E7\u05E9\u05E8 \u05D0\u05EA \u05DB\u05D5\u05DC\u05DF?"
|
|
3530
|
+
] }),
|
|
3531
|
+
conflictModalState.matchingRecords.length > 0 && /* @__PURE__ */ jsx9("div", { className: "overflow-x-auto border border-slate-200 rounded-lg max-h-48 text-xs bg-white", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-right border-collapse", children: [
|
|
3532
|
+
/* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsx9("tr", { className: "bg-slate-100 text-slate-700 font-semibold border-b whitespace-nowrap", children: (targetColumns.length > 0 ? targetColumns.filter((c) => c.name !== "_id" && c.name !== "id") : Object.keys(((_f = conflictModalState.matchingRecords[0]) == null ? void 0 : _f.data) || {}).filter((k) => k !== "_id" && k !== "id").map((name) => ({ name }))).map((col) => /* @__PURE__ */ jsx9(
|
|
3533
|
+
"th",
|
|
3534
|
+
{
|
|
3535
|
+
className: "bg-slate-100 text-slate-700 font-semibold p-2 border-b whitespace-nowrap",
|
|
3536
|
+
children: col.name
|
|
3537
|
+
},
|
|
3538
|
+
col.name
|
|
3539
|
+
)) }) }),
|
|
3540
|
+
/* @__PURE__ */ jsx9("tbody", { children: conflictModalState.matchingRecords.map((r, idx) => {
|
|
3541
|
+
const cols = targetColumns.length > 0 ? targetColumns.filter((c) => c.name !== "_id" && c.name !== "id") : Object.keys(r.data || {}).filter((k) => k !== "_id" && k !== "id").map((name) => ({ name }));
|
|
3542
|
+
return /* @__PURE__ */ jsx9("tr", { className: "hover:bg-slate-50/80 transition-colors", children: cols.map((col) => {
|
|
3543
|
+
var _a2;
|
|
3544
|
+
const rawVal = (_a2 = r.data) == null ? void 0 : _a2[col.name];
|
|
3545
|
+
const colDef = targetColumns.find((c) => c.name === col.name) || col;
|
|
3546
|
+
const displayVal = formatConflictCellValue(rawVal, colDef, relationOptions || (context == null ? void 0 : context.relationOptions));
|
|
3547
|
+
return /* @__PURE__ */ jsx9(
|
|
3548
|
+
"td",
|
|
3549
|
+
{
|
|
3550
|
+
className: "p-2 border-b border-slate-100 whitespace-nowrap text-slate-800",
|
|
3551
|
+
children: displayVal
|
|
3552
|
+
},
|
|
3553
|
+
col.name
|
|
3554
|
+
);
|
|
3555
|
+
}) }, r.id || idx);
|
|
3556
|
+
}) })
|
|
3557
|
+
] }) })
|
|
3558
|
+
] }),
|
|
3559
|
+
/* @__PURE__ */ jsxs9("div", { className: "p-4 bg-slate-50 border-t border-slate-100 flex items-center justify-end gap-2.5", children: [
|
|
3560
|
+
/* @__PURE__ */ jsx9(
|
|
3561
|
+
"button",
|
|
3562
|
+
{
|
|
3563
|
+
type: "button",
|
|
3564
|
+
onClick: handleCancelConflict,
|
|
3565
|
+
className: "px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-200/70 rounded-lg border border-slate-300 transition-colors cursor-pointer",
|
|
3566
|
+
children: "\u05D1\u05D9\u05D8\u05D5\u05DC"
|
|
3567
|
+
}
|
|
3568
|
+
),
|
|
3569
|
+
/* @__PURE__ */ jsxs9(
|
|
3570
|
+
"button",
|
|
3571
|
+
{
|
|
3572
|
+
type: "button",
|
|
3573
|
+
onClick: handleConfirmLinkConflict,
|
|
3574
|
+
className: "px-4 py-2 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-700 rounded-lg shadow transition-colors flex items-center gap-1.5 cursor-pointer",
|
|
3575
|
+
children: [
|
|
3576
|
+
/* @__PURE__ */ jsx9("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" }) }),
|
|
3577
|
+
conflictModalState.matchingRecords.length > 1 ? "\u05E7\u05E9\u05E8 \u05D0\u05EA \u05DB\u05D5\u05DC\u05DF" : "\u05E7\u05E9\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D4"
|
|
3578
|
+
]
|
|
3579
|
+
}
|
|
3580
|
+
)
|
|
3581
|
+
] })
|
|
3582
|
+
]
|
|
3583
|
+
}
|
|
3584
|
+
)
|
|
3585
|
+
}
|
|
3586
|
+
)
|
|
1569
3587
|
] });
|
|
1570
3588
|
}
|
|
1571
3589
|
|
|
1572
3590
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
1573
|
-
import { X as
|
|
1574
|
-
import { jsx as
|
|
3591
|
+
import { X as X7, Copy as Copy2, Search as Search2, RotateCcw } from "lucide-react";
|
|
3592
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1575
3593
|
function TableBlockClient({
|
|
1576
3594
|
data: initialRecords,
|
|
1577
3595
|
settings: schema,
|
|
@@ -1588,22 +3606,25 @@ function TableBlockClient({
|
|
|
1588
3606
|
"data-testid": dataTestId
|
|
1589
3607
|
}) {
|
|
1590
3608
|
const { showError, addToast } = useToast();
|
|
1591
|
-
const [columnWidths, setColumnWidths] = useState5({});
|
|
1592
|
-
const [isMounted, setIsMounted] = useState5(false);
|
|
1593
3609
|
const tableKey = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id) || (schema == null ? void 0 : schema.name) || "default";
|
|
1594
|
-
const
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
3610
|
+
const { columnWidths, startResize } = useColumnResize({
|
|
3611
|
+
storageKey: `table_widths_${tableKey}`,
|
|
3612
|
+
minWidth: 60,
|
|
3613
|
+
defaultWidth: 200,
|
|
3614
|
+
getMinColWidth: (colName) => {
|
|
3615
|
+
const col = (localColumns || []).find((c) => c.name === colName);
|
|
3616
|
+
return calculateMinColumnWidth(colName, false, col == null ? void 0 : col.type);
|
|
3617
|
+
}
|
|
3618
|
+
});
|
|
3619
|
+
const [isMounted, setIsMounted] = useState10(false);
|
|
3620
|
+
const [isInitialLoading, setIsInitialLoading] = useState10(true);
|
|
3621
|
+
const [page, setPage] = useState10(1);
|
|
3622
|
+
const [limit, setLimit] = useState10(50);
|
|
3623
|
+
const [totalRecords, setTotalRecords] = useState10(0);
|
|
3624
|
+
const [totalPages, setTotalPages] = useState10(1);
|
|
3625
|
+
const [showSummary, setShowSummary] = useState10(false);
|
|
3626
|
+
useEffect8(() => {
|
|
1599
3627
|
if (typeof window !== "undefined") {
|
|
1600
|
-
const savedWidths = localStorage.getItem(`table_widths_${tableKey}`);
|
|
1601
|
-
if (savedWidths) {
|
|
1602
|
-
try {
|
|
1603
|
-
setColumnWidths(JSON.parse(savedWidths));
|
|
1604
|
-
} catch (e) {
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
3628
|
const savedSummary = localStorage.getItem(`table_summary_${tableKey}`);
|
|
1608
3629
|
if (savedSummary !== null) {
|
|
1609
3630
|
setShowSummary(savedSummary === "true");
|
|
@@ -1618,7 +3639,6 @@ function TableBlockClient({
|
|
|
1618
3639
|
}
|
|
1619
3640
|
setIsMounted(true);
|
|
1620
3641
|
}, [tableKey]);
|
|
1621
|
-
const [showSummary, setShowSummary] = useState5(false);
|
|
1622
3642
|
const toggleSummary = () => {
|
|
1623
3643
|
setShowSummary((prev) => {
|
|
1624
3644
|
const next = !prev;
|
|
@@ -1627,29 +3647,6 @@ function TableBlockClient({
|
|
|
1627
3647
|
return next;
|
|
1628
3648
|
});
|
|
1629
3649
|
};
|
|
1630
|
-
const [resizingCol, setResizingCol] = useState5(null);
|
|
1631
|
-
useEffect4(() => {
|
|
1632
|
-
if (!resizingCol) return;
|
|
1633
|
-
const handleMouseMove = (e) => {
|
|
1634
|
-
const diffX = resizingCol.startX - e.clientX;
|
|
1635
|
-
const newWidth = Math.max(100, Math.min(500, resizingCol.startWidth + diffX));
|
|
1636
|
-
setColumnWidths((prev) => __spreadProps(__spreadValues({}, prev), { [resizingCol.name]: newWidth }));
|
|
1637
|
-
};
|
|
1638
|
-
const handleMouseUp = () => {
|
|
1639
|
-
setResizingCol(null);
|
|
1640
|
-
setColumnWidths((prev) => {
|
|
1641
|
-
const tableKey2 = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id) || (schema == null ? void 0 : schema.name) || "default";
|
|
1642
|
-
localStorage.setItem(`table_widths_${tableKey2}`, JSON.stringify(prev));
|
|
1643
|
-
return prev;
|
|
1644
|
-
});
|
|
1645
|
-
};
|
|
1646
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
1647
|
-
document.addEventListener("mouseup", handleMouseUp);
|
|
1648
|
-
return () => {
|
|
1649
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
1650
|
-
document.removeEventListener("mouseup", handleMouseUp);
|
|
1651
|
-
};
|
|
1652
|
-
}, [resizingCol, schema]);
|
|
1653
3650
|
const normalizeRecords = (records) => {
|
|
1654
3651
|
return (records || []).map((row) => {
|
|
1655
3652
|
var _c;
|
|
@@ -1675,7 +3672,7 @@ function TableBlockClient({
|
|
|
1675
3672
|
return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
|
|
1676
3673
|
});
|
|
1677
3674
|
};
|
|
1678
|
-
const mergeColumnDefs =
|
|
3675
|
+
const mergeColumnDefs = useCallback9((existingCols, incomingCols) => {
|
|
1679
3676
|
if (!incomingCols || incomingCols.length === 0) return existingCols || [];
|
|
1680
3677
|
if (!existingCols || existingCols.length === 0) return incomingCols;
|
|
1681
3678
|
const existingMap = new Map(existingCols.map((c) => [c.name, c]));
|
|
@@ -1695,18 +3692,18 @@ function TableBlockClient({
|
|
|
1695
3692
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
1696
3693
|
});
|
|
1697
3694
|
}, []);
|
|
1698
|
-
const [localColumns, setLocalColumns] =
|
|
1699
|
-
|
|
3695
|
+
const [localColumns, setLocalColumns] = useState10(() => (schema == null ? void 0 : schema.columns) || []);
|
|
3696
|
+
useEffect8(() => {
|
|
1700
3697
|
if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
|
|
1701
3698
|
setLocalColumns((prev) => mergeColumnDefs(prev, schema.columns));
|
|
1702
3699
|
}
|
|
1703
3700
|
}, [schema == null ? void 0 : schema.columns, mergeColumnDefs]);
|
|
1704
|
-
const [dirty, setDirty] =
|
|
1705
|
-
const dirtyRef =
|
|
1706
|
-
|
|
3701
|
+
const [dirty, setDirty] = useState10({ added: [], modified: {}, deleted: [] });
|
|
3702
|
+
const dirtyRef = useRef7(dirty);
|
|
3703
|
+
useEffect8(() => {
|
|
1707
3704
|
dirtyRef.current = dirty;
|
|
1708
3705
|
}, [dirty]);
|
|
1709
|
-
const mergeWithDirty =
|
|
3706
|
+
const mergeWithDirty = useCallback9((baseRecords) => {
|
|
1710
3707
|
const { added, modified, deleted } = dirtyRef.current;
|
|
1711
3708
|
const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
|
|
1712
3709
|
const modifiedRecords = nonDeleted.map((r) => {
|
|
@@ -1719,10 +3716,13 @@ function TableBlockClient({
|
|
|
1719
3716
|
const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
|
|
1720
3717
|
return [...uniqueAdded, ...modifiedRecords];
|
|
1721
3718
|
}, []);
|
|
1722
|
-
const [data, setData] =
|
|
1723
|
-
|
|
3719
|
+
const [data, setData] = useState10(() => normalizeRecords(initialRecords));
|
|
3720
|
+
const [serverRecords, setServerRecords] = useState10(() => normalizeRecords(initialRecords));
|
|
3721
|
+
useEffect8(() => {
|
|
1724
3722
|
if (initialRecords) {
|
|
1725
|
-
|
|
3723
|
+
const norm = normalizeRecords(initialRecords);
|
|
3724
|
+
setServerRecords(norm);
|
|
3725
|
+
setData(mergeWithDirty(norm));
|
|
1726
3726
|
}
|
|
1727
3727
|
}, [initialRecords, mergeWithDirty]);
|
|
1728
3728
|
const isEqualValues = (a, b) => {
|
|
@@ -1735,19 +3735,19 @@ function TableBlockClient({
|
|
|
1735
3735
|
}
|
|
1736
3736
|
return false;
|
|
1737
3737
|
};
|
|
1738
|
-
const [baseRecordsMap, setBaseRecordsMap] =
|
|
3738
|
+
const [baseRecordsMap, setBaseRecordsMap] = useState10(() => {
|
|
1739
3739
|
const map = /* @__PURE__ */ new Map();
|
|
1740
3740
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
1741
3741
|
return map;
|
|
1742
3742
|
});
|
|
1743
|
-
|
|
3743
|
+
useEffect8(() => {
|
|
1744
3744
|
if (initialRecords && initialRecords.length > 0) {
|
|
1745
3745
|
const map = /* @__PURE__ */ new Map();
|
|
1746
3746
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
1747
3747
|
setBaseRecordsMap(map);
|
|
1748
3748
|
}
|
|
1749
3749
|
}, [initialRecords]);
|
|
1750
|
-
const refetchTableData =
|
|
3750
|
+
const refetchTableData = useCallback9((targetPage) => {
|
|
1751
3751
|
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
1752
3752
|
if (!tableId || !executeAction) return Promise.resolve();
|
|
1753
3753
|
const activePage = targetPage !== void 0 ? targetPage : page;
|
|
@@ -1763,7 +3763,8 @@ function TableBlockClient({
|
|
|
1763
3763
|
const map = /* @__PURE__ */ new Map();
|
|
1764
3764
|
norm.forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
1765
3765
|
setBaseRecordsMap(map);
|
|
1766
|
-
|
|
3766
|
+
setServerRecords(norm);
|
|
3767
|
+
setData(mergeWithDirty(norm));
|
|
1767
3768
|
}
|
|
1768
3769
|
if (res.meta) {
|
|
1769
3770
|
const total = typeof res.meta.totalRecords === "number" ? res.meta.totalRecords : 0;
|
|
@@ -1781,9 +3782,22 @@ function TableBlockClient({
|
|
|
1781
3782
|
}).catch((err) => {
|
|
1782
3783
|
console.error("[TableBlock] Failed to auto-fetch table data:", err);
|
|
1783
3784
|
});
|
|
1784
|
-
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeColumnDefs]);
|
|
1785
|
-
|
|
1786
|
-
|
|
3785
|
+
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeColumnDefs, mergeWithDirty]);
|
|
3786
|
+
useEffect8(() => {
|
|
3787
|
+
let isMounted2 = true;
|
|
3788
|
+
const fetchPromise = refetchTableData();
|
|
3789
|
+
if (fetchPromise && typeof fetchPromise.finally === "function") {
|
|
3790
|
+
fetchPromise.finally(() => {
|
|
3791
|
+
if (isMounted2) {
|
|
3792
|
+
setIsInitialLoading(false);
|
|
3793
|
+
}
|
|
3794
|
+
});
|
|
3795
|
+
} else {
|
|
3796
|
+
setIsInitialLoading(false);
|
|
3797
|
+
}
|
|
3798
|
+
return () => {
|
|
3799
|
+
isMounted2 = false;
|
|
3800
|
+
};
|
|
1787
3801
|
}, [refetchTableData]);
|
|
1788
3802
|
const handleLimitChange = (newLimit) => {
|
|
1789
3803
|
setLimit(newLimit);
|
|
@@ -1798,31 +3812,50 @@ function TableBlockClient({
|
|
|
1798
3812
|
const handleNextPage = () => {
|
|
1799
3813
|
setPage((prev) => Math.min(totalPages, prev + 1));
|
|
1800
3814
|
};
|
|
1801
|
-
|
|
3815
|
+
useEffect8(() => {
|
|
1802
3816
|
if (error) {
|
|
1803
3817
|
showError(error, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E8\u05DB\u05D9\u05D1");
|
|
1804
3818
|
}
|
|
1805
3819
|
}, [error, showError]);
|
|
1806
|
-
const [searchQuery, setSearchQuery] =
|
|
1807
|
-
const [
|
|
1808
|
-
const [
|
|
1809
|
-
const
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
3820
|
+
const [searchQuery, setSearchQuery] = useState10("");
|
|
3821
|
+
const [columnFilters, setColumnFilters] = useState10({});
|
|
3822
|
+
const [activeSearchCol, setActiveSearchCol] = useState10(null);
|
|
3823
|
+
const activeSearchRef = useRef7(null);
|
|
3824
|
+
useEffect8(() => {
|
|
3825
|
+
if (!activeSearchCol) return;
|
|
3826
|
+
const handleMouseDown = (e) => {
|
|
3827
|
+
if (activeSearchRef.current && !activeSearchRef.current.contains(e.target)) {
|
|
3828
|
+
setActiveSearchCol(null);
|
|
3829
|
+
}
|
|
3830
|
+
};
|
|
3831
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
3832
|
+
return () => {
|
|
3833
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
3834
|
+
};
|
|
3835
|
+
}, [activeSearchCol]);
|
|
3836
|
+
const [selectedIds, setSelectedIds] = useState10(/* @__PURE__ */ new Set());
|
|
3837
|
+
const [pendingDeletions, setPendingDeletions] = useState10([]);
|
|
3838
|
+
const [isSaving, setIsSaving] = useState10(false);
|
|
3839
|
+
const isUpdatingActive = Boolean(isUpdating || isSaving);
|
|
3840
|
+
const [isSaveSuccess, setIsSaveSuccess] = useState10(false);
|
|
3841
|
+
const [relationOptions, setRelationOptions] = useState10({});
|
|
3842
|
+
const [expandedRowIds, setExpandedRowIds] = useState10(/* @__PURE__ */ new Set());
|
|
3843
|
+
const schemaColsString = useMemo5(() => JSON.stringify(localColumns || []), [localColumns]);
|
|
3844
|
+
const refetchRelation = useCallback9(async (colName) => {
|
|
3845
|
+
var _a, _b, _c;
|
|
1816
3846
|
let parsedCols = [];
|
|
1817
3847
|
try {
|
|
1818
3848
|
parsedCols = JSON.parse(schemaColsString);
|
|
1819
3849
|
} catch (e) {
|
|
1820
3850
|
}
|
|
1821
|
-
const col = parsedCols.find((c) =>
|
|
1822
|
-
|
|
3851
|
+
const col = parsedCols.find((c) => {
|
|
3852
|
+
var _a2;
|
|
3853
|
+
return c.name === colName && ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION";
|
|
3854
|
+
});
|
|
3855
|
+
if (!col || !((_a = col.config) == null ? void 0 : _a.referencedTableId)) return;
|
|
1823
3856
|
try {
|
|
1824
3857
|
if (executeAction) {
|
|
1825
|
-
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
|
|
3858
|
+
const options = await executeAction("FETCH_RELATION", { referencedTableId: (_b = col.config) == null ? void 0 : _b.referencedTableId, displayField: (_c = col.config) == null ? void 0 : _c.displayField });
|
|
1826
3859
|
if (options && Array.isArray(options)) {
|
|
1827
3860
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [colName]: options }));
|
|
1828
3861
|
}
|
|
@@ -1831,7 +3864,7 @@ function TableBlockClient({
|
|
|
1831
3864
|
console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
|
|
1832
3865
|
}
|
|
1833
3866
|
}, [schemaColsString, executeAction]);
|
|
1834
|
-
|
|
3867
|
+
useEffect8(() => {
|
|
1835
3868
|
let parsedCols = [];
|
|
1836
3869
|
try {
|
|
1837
3870
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -1845,7 +3878,7 @@ function TableBlockClient({
|
|
|
1845
3878
|
refetchRelation(col.name);
|
|
1846
3879
|
});
|
|
1847
3880
|
}, [schemaColsString, refetchRelation]);
|
|
1848
|
-
const normalizedColumns =
|
|
3881
|
+
const normalizedColumns = useMemo5(() => {
|
|
1849
3882
|
return (localColumns || []).map((col, idx) => {
|
|
1850
3883
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
1851
3884
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
@@ -1859,17 +3892,17 @@ function TableBlockClient({
|
|
|
1859
3892
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
1860
3893
|
});
|
|
1861
3894
|
}, [localColumns]);
|
|
1862
|
-
const filteredColumns =
|
|
3895
|
+
const filteredColumns = useMemo5(() => {
|
|
1863
3896
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
1864
3897
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name) && !col.isHidden);
|
|
1865
3898
|
}, [normalizedColumns]);
|
|
1866
|
-
const customizableColumns =
|
|
3899
|
+
const customizableColumns = useMemo5(() => {
|
|
1867
3900
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
1868
3901
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name));
|
|
1869
3902
|
}, [normalizedColumns]);
|
|
1870
|
-
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] =
|
|
1871
|
-
const dropdownRef =
|
|
1872
|
-
|
|
3903
|
+
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = useState10(false);
|
|
3904
|
+
const dropdownRef = useRef7(null);
|
|
3905
|
+
useEffect8(() => {
|
|
1873
3906
|
const handleClickOutside = (e) => {
|
|
1874
3907
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1875
3908
|
setIsColumnsDropdownOpen(false);
|
|
@@ -1947,8 +3980,6 @@ function TableBlockClient({
|
|
|
1947
3980
|
}
|
|
1948
3981
|
}
|
|
1949
3982
|
};
|
|
1950
|
-
const [draggedColName, setDraggedColName] = useState5(null);
|
|
1951
|
-
const [dragOverColName, setDragOverColName] = useState5(null);
|
|
1952
3983
|
const handleColumnReorder = async (draggedName, dropTargetName) => {
|
|
1953
3984
|
var _a;
|
|
1954
3985
|
if (draggedName === dropTargetName) return;
|
|
@@ -1983,6 +4014,43 @@ function TableBlockClient({
|
|
|
1983
4014
|
}
|
|
1984
4015
|
}
|
|
1985
4016
|
};
|
|
4017
|
+
const { draggedColName, dragOverColName, getHeaderDragProps } = useColumnReorder({
|
|
4018
|
+
onReorder: handleColumnReorder,
|
|
4019
|
+
disabled: isLoading || isUpdatingActive
|
|
4020
|
+
});
|
|
4021
|
+
const handleUpdateColumnConfig = async (columnName, partialConfig) => {
|
|
4022
|
+
var _a;
|
|
4023
|
+
let updatedColumns = [];
|
|
4024
|
+
setLocalColumns((prevCols) => {
|
|
4025
|
+
const nextCols = (prevCols || []).map((col) => {
|
|
4026
|
+
if (col.name === columnName) {
|
|
4027
|
+
return __spreadProps(__spreadValues({}, col), {
|
|
4028
|
+
config: __spreadValues(__spreadValues({}, col.config || {}), partialConfig)
|
|
4029
|
+
});
|
|
4030
|
+
}
|
|
4031
|
+
return col;
|
|
4032
|
+
});
|
|
4033
|
+
updatedColumns = nextCols;
|
|
4034
|
+
return nextCols;
|
|
4035
|
+
});
|
|
4036
|
+
const targetTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
4037
|
+
if (targetTableId && executeAction && updatedColumns.length > 0) {
|
|
4038
|
+
try {
|
|
4039
|
+
const res = await executeAction("UPDATE_TABLE_COLUMNS", {
|
|
4040
|
+
tableId: targetTableId,
|
|
4041
|
+
tableMetaId: targetTableId,
|
|
4042
|
+
columns: updatedColumns
|
|
4043
|
+
});
|
|
4044
|
+
const returnedCols = (res == null ? void 0 : res.columns) || ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.columns);
|
|
4045
|
+
if (returnedCols && Array.isArray(returnedCols)) {
|
|
4046
|
+
setLocalColumns((prev) => mergeColumnDefs(prev, returnedCols));
|
|
4047
|
+
}
|
|
4048
|
+
} catch (err) {
|
|
4049
|
+
console.error("[TableBlock] Failed to save column config:", err);
|
|
4050
|
+
showError((err == null ? void 0 : err.message) || String(err), "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E2\u05D3\u05DB\u05D5\u05DF \u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05E2\u05DE\u05D5\u05D3\u05D4");
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
};
|
|
1986
4054
|
const generateTempId = () => `temp_${Math.random().toString(36).substr(2, 9)}`;
|
|
1987
4055
|
const handleAddRow = () => {
|
|
1988
4056
|
const defaultData = {};
|
|
@@ -2077,13 +4145,13 @@ function TableBlockClient({
|
|
|
2077
4145
|
});
|
|
2078
4146
|
}
|
|
2079
4147
|
};
|
|
2080
|
-
const triggerSaveSuccess =
|
|
4148
|
+
const triggerSaveSuccess = useCallback9(() => {
|
|
2081
4149
|
setIsSaveSuccess(true);
|
|
2082
4150
|
setTimeout(() => {
|
|
2083
4151
|
setIsSaveSuccess(false);
|
|
2084
4152
|
}, 2500);
|
|
2085
4153
|
}, []);
|
|
2086
|
-
const handleQuietCellChange =
|
|
4154
|
+
const handleQuietCellChange = useCallback9((rowId, colName, value) => {
|
|
2087
4155
|
setData((prev) => prev.map(
|
|
2088
4156
|
(row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
|
|
2089
4157
|
));
|
|
@@ -2171,7 +4239,7 @@ function TableBlockClient({
|
|
|
2171
4239
|
const formatPayload = (payload) => {
|
|
2172
4240
|
const formatted = {};
|
|
2173
4241
|
(localColumns || []).forEach((col) => {
|
|
2174
|
-
var _a, _b;
|
|
4242
|
+
var _a, _b, _c;
|
|
2175
4243
|
if (["_id", "id", "createdAt", "updatedAt", "orgId", "tableId", "isSelected"].includes(col.name)) return;
|
|
2176
4244
|
let val = payload[col.name];
|
|
2177
4245
|
if (val !== void 0) {
|
|
@@ -2181,7 +4249,9 @@ function TableBlockClient({
|
|
|
2181
4249
|
if (((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "NUMBER") {
|
|
2182
4250
|
val = val === "" ? 0 : Number(val);
|
|
2183
4251
|
if (isNaN(val)) val = 0;
|
|
2184
|
-
} else if (((_b = col.type) == null ? void 0 : _b.toUpperCase()) === "
|
|
4252
|
+
} else if (((_b = col.type) == null ? void 0 : _b.toUpperCase()) === "PHONE") {
|
|
4253
|
+
val = sanitizePhoneNumber(String(val));
|
|
4254
|
+
} else if (((_c = col.type) == null ? void 0 : _c.toUpperCase()) === "SUB_TABLE" && Array.isArray(val)) {
|
|
2185
4255
|
val = val.map((item) => {
|
|
2186
4256
|
const _a2 = item, { _resolvedData } = _a2, rest = __objRest(_a2, ["_resolvedData"]);
|
|
2187
4257
|
return rest;
|
|
@@ -2194,8 +4264,17 @@ function TableBlockClient({
|
|
|
2194
4264
|
return formatted;
|
|
2195
4265
|
};
|
|
2196
4266
|
const hasChanges = dirty.added.length > 0 || Object.keys(dirty.modified).length > 0 || dirty.deleted.length > 0;
|
|
4267
|
+
const handleRevertChanges = () => {
|
|
4268
|
+
setDirty({ added: [], modified: {}, deleted: [] });
|
|
4269
|
+
setData(serverRecords.map((r) => __spreadProps(__spreadValues({}, r), { data: __spreadValues({}, r.data) })));
|
|
4270
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
4271
|
+
setPendingDeletions([]);
|
|
4272
|
+
if (emitEvent) {
|
|
4273
|
+
emitEvent("SELECTION_CHANGE", { selectedIds: [], componentId });
|
|
4274
|
+
}
|
|
4275
|
+
};
|
|
2197
4276
|
const handleSave = async () => {
|
|
2198
|
-
var _a;
|
|
4277
|
+
var _a, _b;
|
|
2199
4278
|
if (!hasChanges) {
|
|
2200
4279
|
return;
|
|
2201
4280
|
}
|
|
@@ -2218,6 +4297,28 @@ function TableBlockClient({
|
|
|
2218
4297
|
}
|
|
2219
4298
|
}
|
|
2220
4299
|
}
|
|
4300
|
+
const phoneCols = (localColumns || []).filter((c) => {
|
|
4301
|
+
var _a2;
|
|
4302
|
+
return ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "PHONE";
|
|
4303
|
+
});
|
|
4304
|
+
for (const col of phoneCols) {
|
|
4305
|
+
for (const row of dirty.added) {
|
|
4306
|
+
const val = row.data[col.name];
|
|
4307
|
+
if (!isEmpty(val) && !isValidPhoneNumber(val)) {
|
|
4308
|
+
showError(`\u05DE\u05E1\u05E4\u05E8 \u05D4\u05D8\u05DC\u05E4\u05D5\u05DF \u05D1\u05E9\u05D3\u05D4 "${col.name}" \u05D0\u05D9\u05E0\u05D5 \u05EA\u05E7\u05D9\u05DF. \u05D9\u05E9 \u05DC\u05D4\u05D6\u05D9\u05DF \u05DE\u05E1\u05E4\u05E8 \u05D1\u05D0\u05D5\u05E8\u05DA 9-15 \u05E1\u05E4\u05E8\u05D5\u05EA (\u05DC\u05D3\u05D5\u05D2\u05DE\u05D4 0501234567 \u05D0\u05D5 +972501234567).`, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05D5\u05D5\u05DC\u05D9\u05D3\u05E6\u05D9\u05D4");
|
|
4309
|
+
return;
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4312
|
+
for (const [rowId, mods] of Object.entries(dirty.modified)) {
|
|
4313
|
+
const rowData = ((_b = data.find((r) => r.id === rowId)) == null ? void 0 : _b.data) || {};
|
|
4314
|
+
const mergedData = __spreadValues(__spreadValues({}, rowData), mods);
|
|
4315
|
+
const val = mergedData[col.name];
|
|
4316
|
+
if (!isEmpty(val) && !isValidPhoneNumber(val)) {
|
|
4317
|
+
showError(`\u05DE\u05E1\u05E4\u05E8 \u05D4\u05D8\u05DC\u05E4\u05D5\u05DF \u05D1\u05E9\u05D3\u05D4 "${col.name}" \u05D0\u05D9\u05E0\u05D5 \u05EA\u05E7\u05D9\u05DF. \u05D9\u05E9 \u05DC\u05D4\u05D6\u05D9\u05DF \u05DE\u05E1\u05E4\u05E8 \u05D1\u05D0\u05D5\u05E8\u05DA 9-15 \u05E1\u05E4\u05E8\u05D5\u05EA (\u05DC\u05D3\u05D5\u05D2\u05DE\u05D4 0501234567 \u05D0\u05D5 +972501234567).`, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05D5\u05D5\u05DC\u05D9\u05D3\u05E6\u05D9\u05D4");
|
|
4318
|
+
return;
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
}
|
|
2221
4322
|
setIsSaving(true);
|
|
2222
4323
|
try {
|
|
2223
4324
|
if (!executeAction) {
|
|
@@ -2318,18 +4419,89 @@ function TableBlockClient({
|
|
|
2318
4419
|
setIsSaving(false);
|
|
2319
4420
|
}
|
|
2320
4421
|
};
|
|
2321
|
-
const
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
)
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
4422
|
+
const getRowRelationLabels = useCallback9((rowVal, col) => {
|
|
4423
|
+
const ids = normalizeRelationValue(rowVal);
|
|
4424
|
+
if (ids.length === 0) return [];
|
|
4425
|
+
const options = relationOptions[col.name] || [];
|
|
4426
|
+
return ids.map((id) => {
|
|
4427
|
+
const opt = options.find((o) => o.id === id || o._id === id);
|
|
4428
|
+
if (opt) {
|
|
4429
|
+
const resolved = resolveRelationLabel(opt, col);
|
|
4430
|
+
if (resolved) return resolved;
|
|
4431
|
+
if (opt.label) return String(opt.label);
|
|
4432
|
+
if (opt.name) return String(opt.name);
|
|
4433
|
+
}
|
|
4434
|
+
if (typeof rowVal === "object" && rowVal !== null) {
|
|
4435
|
+
if (rowVal._displayLabel) return String(rowVal._displayLabel);
|
|
4436
|
+
if (rowVal.label) return String(rowVal.label);
|
|
4437
|
+
}
|
|
4438
|
+
return id;
|
|
4439
|
+
});
|
|
4440
|
+
}, [relationOptions]);
|
|
4441
|
+
const getUniqueRelationOptions = useCallback9((col) => {
|
|
4442
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
4443
|
+
const results = [];
|
|
4444
|
+
const options = relationOptions[col.name] || [];
|
|
4445
|
+
data.forEach((row) => {
|
|
4446
|
+
if (!(row == null ? void 0 : row.data)) return;
|
|
4447
|
+
const ids = normalizeRelationValue(row.data[col.name]);
|
|
4448
|
+
ids.forEach((id) => {
|
|
4449
|
+
if (!seenIds.has(id)) {
|
|
4450
|
+
seenIds.add(id);
|
|
4451
|
+
const opt = options.find((o) => o.id === id || o._id === id);
|
|
4452
|
+
let label = opt ? resolveRelationLabel(opt, col) : "";
|
|
4453
|
+
if (!label && opt) label = opt.label || opt.name || opt.title || id;
|
|
4454
|
+
if (!label) label = id;
|
|
4455
|
+
results.push({ id, label });
|
|
4456
|
+
}
|
|
4457
|
+
});
|
|
4458
|
+
});
|
|
4459
|
+
return results.sort((a, b) => a.label.localeCompare(b.label));
|
|
4460
|
+
}, [data, relationOptions]);
|
|
4461
|
+
const filteredData = useMemo5(() => {
|
|
4462
|
+
const hasGlobalSearch = Boolean(searchQuery && searchQuery.trim() !== "");
|
|
4463
|
+
const activeFilters = Object.entries(columnFilters).filter(([, val]) => Boolean(val && val.trim() !== ""));
|
|
4464
|
+
const hasColumnFilters = activeFilters.length > 0;
|
|
4465
|
+
if (!hasGlobalSearch && !hasColumnFilters) return data;
|
|
4466
|
+
const lowerGlobal = hasGlobalSearch ? searchQuery.trim().toLowerCase() : "";
|
|
4467
|
+
return data.filter((row) => {
|
|
4468
|
+
var _a;
|
|
4469
|
+
if (!row || !row.data) return false;
|
|
4470
|
+
if (hasGlobalSearch) {
|
|
4471
|
+
const matchesGlobal = (localColumns || []).some((col) => {
|
|
4472
|
+
var _a2;
|
|
4473
|
+
const rawVal = row.data[col.name];
|
|
4474
|
+
if (rawVal === void 0 || rawVal === null) return false;
|
|
4475
|
+
if (((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION") {
|
|
4476
|
+
const labels = getRowRelationLabels(rawVal, col);
|
|
4477
|
+
return labels.some((l) => l.toLowerCase().includes(lowerGlobal));
|
|
4478
|
+
}
|
|
4479
|
+
if (typeof rawVal === "object") {
|
|
4480
|
+
return JSON.stringify(rawVal).toLowerCase().includes(lowerGlobal);
|
|
4481
|
+
}
|
|
4482
|
+
return String(rawVal).toLowerCase().includes(lowerGlobal);
|
|
4483
|
+
});
|
|
4484
|
+
if (!matchesGlobal) return false;
|
|
4485
|
+
}
|
|
4486
|
+
for (const [colName, filterVal] of activeFilters) {
|
|
4487
|
+
const lowerFilter = filterVal.trim().toLowerCase();
|
|
4488
|
+
const col = (localColumns || []).find((c) => c.name === colName);
|
|
4489
|
+
const rawVal = row.data[colName];
|
|
4490
|
+
if (((_a = col == null ? void 0 : col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION") {
|
|
4491
|
+
const labels = getRowRelationLabels(rawVal, col);
|
|
4492
|
+
const matches = labels.some((l) => l.toLowerCase().includes(lowerFilter));
|
|
4493
|
+
if (!matches) return false;
|
|
4494
|
+
} else {
|
|
4495
|
+
if (rawVal === void 0 || rawVal === null) return false;
|
|
4496
|
+
const strVal = typeof rawVal === "object" ? JSON.stringify(rawVal).toLowerCase() : String(rawVal).toLowerCase();
|
|
4497
|
+
if (!strVal.includes(lowerFilter)) return false;
|
|
4498
|
+
}
|
|
4499
|
+
}
|
|
4500
|
+
return true;
|
|
4501
|
+
});
|
|
4502
|
+
}, [data, searchQuery, columnFilters, localColumns, getRowRelationLabels]);
|
|
2331
4503
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
2332
|
-
const columnTotals =
|
|
4504
|
+
const columnTotals = useMemo5(() => {
|
|
2333
4505
|
const totals = {};
|
|
2334
4506
|
if (!showSummary) return totals;
|
|
2335
4507
|
filteredColumns.forEach((col) => {
|
|
@@ -2347,7 +4519,7 @@ function TableBlockClient({
|
|
|
2347
4519
|
});
|
|
2348
4520
|
return totals;
|
|
2349
4521
|
}, [filteredData, filteredColumns, showSummary]);
|
|
2350
|
-
return /* @__PURE__ */
|
|
4522
|
+
return /* @__PURE__ */ jsxs10(
|
|
2351
4523
|
"div",
|
|
2352
4524
|
{
|
|
2353
4525
|
id: componentId,
|
|
@@ -2355,34 +4527,34 @@ function TableBlockClient({
|
|
|
2355
4527
|
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs min-h-[350px] overflow-hidden ${className}`,
|
|
2356
4528
|
dir: "rtl",
|
|
2357
4529
|
children: [
|
|
2358
|
-
errorMessage && /* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
4530
|
+
errorMessage && /* @__PURE__ */ jsx10("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between", children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
4531
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
4532
|
+
/* @__PURE__ */ jsx10("span", { children: errorMessage })
|
|
2361
4533
|
] }) }),
|
|
2362
|
-
/* @__PURE__ */
|
|
2363
|
-
/* @__PURE__ */
|
|
2364
|
-
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */
|
|
2365
|
-
/* @__PURE__ */
|
|
4534
|
+
/* @__PURE__ */ jsxs10("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: [
|
|
4535
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
4536
|
+
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ jsx10("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ jsx10("span", { children: schema.title || schema.name }) }),
|
|
4537
|
+
/* @__PURE__ */ jsx10(
|
|
2366
4538
|
"button",
|
|
2367
4539
|
{
|
|
2368
4540
|
onClick: handleAddRow,
|
|
2369
|
-
disabled: isLoading || isUpdatingActive,
|
|
2370
|
-
className:
|
|
2371
|
-
title: "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
2372
|
-
children: /* @__PURE__ */
|
|
4541
|
+
disabled: isInitialLoading || isLoading || isUpdatingActive,
|
|
4542
|
+
className: `w-9 h-9 text-white rounded-lg shadow-xs flex items-center justify-center transition-all ${isInitialLoading || isLoading || isUpdatingActive ? "bg-emerald-950/80 text-emerald-400/60 pointer-events-none cursor-not-allowed" : "bg-emerald-600 hover:bg-emerald-700 active:bg-emerald-800 cursor-pointer"}`,
|
|
4543
|
+
title: isInitialLoading ? "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." : "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
4544
|
+
children: /* @__PURE__ */ jsx10("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
2373
4545
|
}
|
|
2374
4546
|
),
|
|
2375
|
-
/* @__PURE__ */
|
|
4547
|
+
/* @__PURE__ */ jsx10(
|
|
2376
4548
|
"button",
|
|
2377
4549
|
{
|
|
2378
4550
|
onClick: handleDuplicateRow,
|
|
2379
|
-
disabled: isLoading || isUpdatingActive || selectedIds.size !== 1,
|
|
4551
|
+
disabled: isInitialLoading || isLoading || isUpdatingActive || selectedIds.size !== 1,
|
|
2380
4552
|
className: "w-9 h-9 bg-blue-50 hover:bg-blue-100 border border-blue-200 text-blue-700 rounded-lg shadow-2xs flex items-center justify-center transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
2381
4553
|
title: "\u05E9\u05DB\u05E4\u05DC \u05E9\u05D5\u05E8\u05D4 \u05E0\u05D1\u05D7\u05E8\u05EA",
|
|
2382
|
-
children: /* @__PURE__ */
|
|
4554
|
+
children: /* @__PURE__ */ jsx10(Copy2, { className: "w-4 h-4 text-blue-600 shrink-0" })
|
|
2383
4555
|
}
|
|
2384
4556
|
),
|
|
2385
|
-
/* @__PURE__ */
|
|
4557
|
+
/* @__PURE__ */ jsxs10(
|
|
2386
4558
|
"button",
|
|
2387
4559
|
{
|
|
2388
4560
|
onClick: handleDeleteSelected,
|
|
@@ -2390,12 +4562,12 @@ function TableBlockClient({
|
|
|
2390
4562
|
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",
|
|
2391
4563
|
title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
|
|
2392
4564
|
children: [
|
|
2393
|
-
/* @__PURE__ */
|
|
2394
|
-
selectedIds.size > 0 && /* @__PURE__ */
|
|
4565
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("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" }) }),
|
|
4566
|
+
selectedIds.size > 0 && /* @__PURE__ */ jsx10("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 })
|
|
2395
4567
|
]
|
|
2396
4568
|
}
|
|
2397
4569
|
),
|
|
2398
|
-
/* @__PURE__ */
|
|
4570
|
+
/* @__PURE__ */ jsxs10(
|
|
2399
4571
|
"button",
|
|
2400
4572
|
{
|
|
2401
4573
|
onClick: toggleSummary,
|
|
@@ -2403,13 +4575,13 @@ function TableBlockClient({
|
|
|
2403
4575
|
className: `h-9 px-3 border font-semibold rounded-lg shadow-2xs flex items-center gap-1.5 text-xs transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer ${showSummary ? "bg-indigo-50 border-indigo-200 text-indigo-700 hover:bg-indigo-100" : "bg-white border-slate-300 text-slate-700 hover:bg-slate-100"}`,
|
|
2404
4576
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E9\u05D5\u05E8\u05EA \u05E1\u05D9\u05DB\u05D5\u05DD",
|
|
2405
4577
|
children: [
|
|
2406
|
-
/* @__PURE__ */
|
|
2407
|
-
/* @__PURE__ */
|
|
4578
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
4579
|
+
/* @__PURE__ */ jsx10("span", { className: "hidden sm:inline", children: "\u05E1\u05DB\u05D9\u05DE\u05D4" })
|
|
2408
4580
|
]
|
|
2409
4581
|
}
|
|
2410
4582
|
),
|
|
2411
|
-
/* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */
|
|
4583
|
+
/* @__PURE__ */ jsxs10("div", { className: "relative", ref: dropdownRef, children: [
|
|
4584
|
+
/* @__PURE__ */ jsxs10(
|
|
2413
4585
|
"button",
|
|
2414
4586
|
{
|
|
2415
4587
|
onClick: () => setIsColumnsDropdownOpen((prev) => !prev),
|
|
@@ -2417,16 +4589,16 @@ function TableBlockClient({
|
|
|
2417
4589
|
className: "h-9 px-3 bg-white hover:bg-slate-100 border border-slate-300 text-slate-700 font-semibold rounded-lg shadow-2xs flex items-center gap-1.5 text-xs transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
2418
4590
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA",
|
|
2419
4591
|
children: [
|
|
2420
|
-
/* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
4592
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-slate-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" }) }),
|
|
4593
|
+
/* @__PURE__ */ jsx10("svg", { className: `w-3.5 h-3.5 text-slate-500 transition-transform ${isColumnsDropdownOpen ? "rotate-180" : ""}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })
|
|
2422
4594
|
]
|
|
2423
4595
|
}
|
|
2424
4596
|
),
|
|
2425
|
-
isColumnsDropdownOpen && /* @__PURE__ */
|
|
2426
|
-
/* @__PURE__ */
|
|
2427
|
-
/* @__PURE__ */
|
|
2428
|
-
/* @__PURE__ */
|
|
2429
|
-
/* @__PURE__ */
|
|
4597
|
+
isColumnsDropdownOpen && /* @__PURE__ */ jsxs10("div", { className: "absolute right-0 top-full mt-1.5 w-56 bg-white border border-slate-200 rounded-xl shadow-xl z-50 p-1.5 dir-rtl animate-in fade-in slide-in-from-top-2 duration-150", children: [
|
|
4598
|
+
/* @__PURE__ */ jsxs10("div", { className: "px-2 py-1.5 text-xs font-bold text-slate-500 border-b border-slate-100 mb-1 flex items-center justify-between", children: [
|
|
4599
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1.5", children: [
|
|
4600
|
+
/* @__PURE__ */ jsx10("span", { children: "\u05D4\u05E6\u05D2\u05EA \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA" }),
|
|
4601
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-[10px] font-normal text-slate-400", children: [
|
|
2430
4602
|
"(",
|
|
2431
4603
|
customizableColumns.filter((c) => !c.isHidden).length,
|
|
2432
4604
|
"/",
|
|
@@ -2434,7 +4606,7 @@ function TableBlockClient({
|
|
|
2434
4606
|
")"
|
|
2435
4607
|
] })
|
|
2436
4608
|
] }),
|
|
2437
|
-
/* @__PURE__ */
|
|
4609
|
+
/* @__PURE__ */ jsx10(
|
|
2438
4610
|
"button",
|
|
2439
4611
|
{
|
|
2440
4612
|
type: "button",
|
|
@@ -2444,7 +4616,7 @@ function TableBlockClient({
|
|
|
2444
4616
|
}
|
|
2445
4617
|
)
|
|
2446
4618
|
] }),
|
|
2447
|
-
/* @__PURE__ */
|
|
4619
|
+
/* @__PURE__ */ jsx10("div", { className: "max-h-60 overflow-y-auto space-y-0.5", children: customizableColumns.map((col) => {
|
|
2448
4620
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
2449
4621
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
2450
4622
|
const isProtected = isRequired || isUnique;
|
|
@@ -2458,7 +4630,7 @@ function TableBlockClient({
|
|
|
2458
4630
|
protectedExplanation = "\u05E9\u05D3\u05D4 \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9 - \u05DC\u05D0 \u05E0\u05D9\u05EA\u05DF \u05DC\u05D4\u05D5\u05E8\u05D9\u05D3 \u05E2\u05DE\u05D5\u05D3\u05D4 \u05D6\u05D5 \u05DE\u05D4\u05EA\u05E6\u05D5\u05D2\u05D4";
|
|
2459
4631
|
}
|
|
2460
4632
|
const badgeLabel = isRequired && isUnique ? "\u05D7\u05D5\u05D1\u05D4 + \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9" : isRequired ? "\u05E9\u05D3\u05D4 \u05D7\u05D5\u05D1\u05D4" : "\u05E9\u05D3\u05D4 \u05D9\u05D9\u05D7\u05D5\u05D3\u05D9";
|
|
2461
|
-
return /* @__PURE__ */
|
|
4633
|
+
return /* @__PURE__ */ jsxs10(
|
|
2462
4634
|
"div",
|
|
2463
4635
|
{
|
|
2464
4636
|
onClick: () => {
|
|
@@ -2469,8 +4641,8 @@ function TableBlockClient({
|
|
|
2469
4641
|
title: isProtected ? protectedExplanation : void 0,
|
|
2470
4642
|
className: `group flex items-center justify-between px-2.5 py-1.5 rounded-lg text-xs transition-colors select-none ${isProtected ? "opacity-75 bg-slate-50 border border-slate-100/70 cursor-not-allowed" : "hover:bg-slate-100 active:bg-slate-200 cursor-pointer"}`,
|
|
2471
4643
|
children: [
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
4644
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
4645
|
+
/* @__PURE__ */ jsx10(
|
|
2474
4646
|
"input",
|
|
2475
4647
|
{
|
|
2476
4648
|
type: "checkbox",
|
|
@@ -2481,16 +4653,16 @@ function TableBlockClient({
|
|
|
2481
4653
|
className: "w-3.5 h-3.5 rounded border-slate-300 text-brand focus:ring-brand/20 cursor-pointer disabled:cursor-not-allowed disabled:opacity-60"
|
|
2482
4654
|
}
|
|
2483
4655
|
),
|
|
2484
|
-
/* @__PURE__ */
|
|
4656
|
+
/* @__PURE__ */ jsx10("span", { className: `font-medium truncate ${isProtected ? "text-slate-500" : "text-slate-700"}`, children: col.name })
|
|
2485
4657
|
] }),
|
|
2486
|
-
isProtected && /* @__PURE__ */
|
|
4658
|
+
isProtected && /* @__PURE__ */ jsxs10(
|
|
2487
4659
|
"div",
|
|
2488
4660
|
{
|
|
2489
4661
|
className: "flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold bg-amber-50 text-amber-800 border border-amber-200/80 cursor-help",
|
|
2490
4662
|
title: protectedExplanation,
|
|
2491
4663
|
children: [
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
/* @__PURE__ */
|
|
4664
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-3 h-3 text-amber-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: "2.2", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" }) }),
|
|
4665
|
+
/* @__PURE__ */ jsx10("span", { children: badgeLabel })
|
|
2494
4666
|
]
|
|
2495
4667
|
}
|
|
2496
4668
|
)
|
|
@@ -2501,9 +4673,9 @@ function TableBlockClient({
|
|
|
2501
4673
|
}) })
|
|
2502
4674
|
] })
|
|
2503
4675
|
] }),
|
|
2504
|
-
/* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
2506
|
-
/* @__PURE__ */
|
|
4676
|
+
/* @__PURE__ */ jsx10("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
|
|
4677
|
+
/* @__PURE__ */ jsxs10("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
|
|
4678
|
+
/* @__PURE__ */ jsx10(
|
|
2507
4679
|
"input",
|
|
2508
4680
|
{
|
|
2509
4681
|
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
@@ -2513,129 +4685,224 @@ function TableBlockClient({
|
|
|
2513
4685
|
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"
|
|
2514
4686
|
}
|
|
2515
4687
|
),
|
|
2516
|
-
searchQuery ? /* @__PURE__ */
|
|
4688
|
+
searchQuery ? /* @__PURE__ */ jsx10(
|
|
2517
4689
|
"button",
|
|
2518
4690
|
{
|
|
2519
4691
|
type: "button",
|
|
2520
4692
|
onClick: () => setSearchQuery(""),
|
|
2521
4693
|
className: "absolute right-2.5 top-2.5 text-slate-400 hover:text-slate-600 transition-colors p-0.5 rounded-full hover:bg-slate-100 cursor-pointer",
|
|
2522
4694
|
title: "Clear search",
|
|
2523
|
-
children: /* @__PURE__ */
|
|
4695
|
+
children: /* @__PURE__ */ jsx10(X7, { className: "w-3.5 h-3.5" })
|
|
2524
4696
|
}
|
|
2525
|
-
) : /* @__PURE__ */
|
|
4697
|
+
) : /* @__PURE__ */ jsx10("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__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
|
|
2526
4698
|
] })
|
|
2527
4699
|
] }),
|
|
2528
|
-
/* @__PURE__ */
|
|
2529
|
-
isUpdatingActive ? /* @__PURE__ */
|
|
2530
|
-
/* @__PURE__ */
|
|
4700
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
|
|
4701
|
+
isUpdatingActive ? /* @__PURE__ */ jsxs10("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: [
|
|
4702
|
+
/* @__PURE__ */ jsx10("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
|
|
2531
4703
|
"\u05DE\u05E2\u05D3\u05DB\u05DF..."
|
|
2532
|
-
] }) : isSaveSuccess ? /* @__PURE__ */
|
|
2533
|
-
/* @__PURE__ */
|
|
4704
|
+
] }) : isSaveSuccess ? /* @__PURE__ */ jsxs10("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: [
|
|
4705
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
2534
4706
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
2535
|
-
] }) : hasChanges ? /* @__PURE__ */
|
|
2536
|
-
|
|
4707
|
+
] }) : hasChanges ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1.5 animate-in fade-in", children: [
|
|
4708
|
+
/* @__PURE__ */ jsx10("span", { className: "text-xs font-semibold text-amber-700", children: "\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5" }),
|
|
4709
|
+
/* @__PURE__ */ jsx10(
|
|
4710
|
+
"button",
|
|
4711
|
+
{
|
|
4712
|
+
type: "button",
|
|
4713
|
+
onClick: handleRevertChanges,
|
|
4714
|
+
disabled: isUpdatingActive,
|
|
4715
|
+
className: "p-1 text-amber-700 hover:text-amber-900 hover:bg-amber-100/80 active:bg-amber-200/80 rounded-md transition-colors cursor-pointer disabled:opacity-50 disabled:pointer-events-none",
|
|
4716
|
+
title: "\u05D1\u05D8\u05DC \u05D0\u05EA \u05DB\u05DC \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5",
|
|
4717
|
+
"aria-label": "\u05D1\u05D8\u05DC \u05D0\u05EA \u05DB\u05DC \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5",
|
|
4718
|
+
children: /* @__PURE__ */ jsx10(RotateCcw, { className: "w-3.5 h-3.5" })
|
|
4719
|
+
}
|
|
4720
|
+
)
|
|
4721
|
+
] }) : null,
|
|
4722
|
+
/* @__PURE__ */ jsx10(
|
|
2537
4723
|
"button",
|
|
2538
4724
|
{
|
|
2539
4725
|
onClick: handleSave,
|
|
2540
4726
|
disabled: isUpdatingActive || isLoading || !hasChanges,
|
|
2541
4727
|
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"}`,
|
|
2542
|
-
children: /* @__PURE__ */
|
|
4728
|
+
children: /* @__PURE__ */ jsx10("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
|
|
2543
4729
|
}
|
|
2544
4730
|
)
|
|
2545
4731
|
] })
|
|
2546
4732
|
] }),
|
|
2547
|
-
/* @__PURE__ */
|
|
2548
|
-
isLoading && /* @__PURE__ */
|
|
2549
|
-
/* @__PURE__ */
|
|
2550
|
-
/* @__PURE__ */
|
|
4733
|
+
/* @__PURE__ */ jsxs10("div", { className: `overflow-x-auto relative min-h-[260px] flex-1 transition-opacity duration-200 ${isMounted ? "opacity-100" : "opacity-0"}`, children: [
|
|
4734
|
+
isLoading && /* @__PURE__ */ jsxs10("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
|
|
4735
|
+
/* @__PURE__ */ jsx10("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
|
|
4736
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
|
|
2551
4737
|
] }),
|
|
2552
|
-
/* @__PURE__ */
|
|
2553
|
-
/* @__PURE__ */
|
|
2554
|
-
/* @__PURE__ */
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
4738
|
+
/* @__PURE__ */ jsxs10("table", { className: "w-full text-sm text-right border-collapse table-auto", children: [
|
|
4739
|
+
/* @__PURE__ */ jsx10("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ jsxs10("tr", { className: "h-12 min-h-[48px]", children: [
|
|
4740
|
+
/* @__PURE__ */ jsx10("th", { className: "border-b border-l border-slate-200 p-1.5 text-center shrink-0 h-12 min-h-[48px] align-middle", style: { width: 72, minWidth: 72, maxWidth: 72 }, children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
4741
|
+
/* @__PURE__ */ jsx10(
|
|
4742
|
+
"input",
|
|
4743
|
+
{
|
|
4744
|
+
type: "checkbox",
|
|
4745
|
+
checked: filteredData.length > 0 && selectedIds.size === filteredData.length,
|
|
4746
|
+
onChange: (e) => toggleSelectAll(e.target.checked),
|
|
4747
|
+
disabled: isLoading || isUpdatingActive,
|
|
4748
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
4749
|
+
}
|
|
4750
|
+
),
|
|
4751
|
+
filteredColumns.some((c) => {
|
|
4752
|
+
var _a;
|
|
4753
|
+
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
4754
|
+
}) && /* @__PURE__ */ jsx10("div", { className: "w-5 h-5 shrink-0" })
|
|
4755
|
+
] }) }),
|
|
2564
4756
|
filteredColumns.map((col) => {
|
|
2565
|
-
|
|
2566
|
-
const
|
|
2567
|
-
const
|
|
2568
|
-
|
|
4757
|
+
var _a, _b;
|
|
4758
|
+
const isSearching = activeSearchCol === col.name;
|
|
4759
|
+
const dragProps = isSearching ? {} : getHeaderDragProps(col.name);
|
|
4760
|
+
const isDragging = !isSearching && draggedColName === col.name;
|
|
4761
|
+
const isDragOver = !isSearching && dragOverColName === col.name;
|
|
4762
|
+
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
4763
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
4764
|
+
const isRelation = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION";
|
|
4765
|
+
const filterVal = columnFilters[col.name] || "";
|
|
4766
|
+
return /* @__PURE__ */ jsxs10(
|
|
2569
4767
|
"th",
|
|
2570
|
-
{
|
|
4768
|
+
__spreadProps(__spreadValues({
|
|
2571
4769
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
e.dataTransfer.effectAllowed = "move";
|
|
2576
|
-
setDraggedColName(col.name);
|
|
2577
|
-
},
|
|
2578
|
-
onDragOver: (e) => {
|
|
2579
|
-
e.preventDefault();
|
|
2580
|
-
e.dataTransfer.dropEffect = "move";
|
|
2581
|
-
if (dragOverColName !== col.name) {
|
|
2582
|
-
setDragOverColName(col.name);
|
|
2583
|
-
}
|
|
2584
|
-
},
|
|
2585
|
-
onDragLeave: () => {
|
|
2586
|
-
if (dragOverColName === col.name) {
|
|
2587
|
-
setDragOverColName(null);
|
|
2588
|
-
}
|
|
2589
|
-
},
|
|
2590
|
-
onDrop: (e) => {
|
|
2591
|
-
e.preventDefault();
|
|
2592
|
-
if (draggedColName && draggedColName !== col.name) {
|
|
2593
|
-
handleColumnReorder(draggedColName, col.name);
|
|
2594
|
-
}
|
|
2595
|
-
setDraggedColName(null);
|
|
2596
|
-
setDragOverColName(null);
|
|
2597
|
-
},
|
|
2598
|
-
onDragEnd: () => {
|
|
2599
|
-
setDraggedColName(null);
|
|
2600
|
-
setDragOverColName(null);
|
|
2601
|
-
},
|
|
2602
|
-
className: `relative border-b border-l border-slate-200 px-4 py-2.5 font-semibold text-slate-700 whitespace-nowrap select-none cursor-grab active:cursor-grabbing transition-colors ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : "hover:bg-slate-200/60"}`,
|
|
4770
|
+
title: isSearching ? void 0 : col.name
|
|
4771
|
+
}, dragProps), {
|
|
4772
|
+
className: `relative border-b border-l border-slate-200 px-2.5 py-1.5 font-semibold text-slate-700 select-none transition-colors h-12 min-h-[48px] align-middle ${isSearching ? "cursor-default bg-blue-50/40" : "cursor-grab active:cursor-grabbing hover:bg-slate-200/60"} ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : ""}`,
|
|
2603
4773
|
children: [
|
|
2604
|
-
/* @__PURE__ */
|
|
4774
|
+
/* @__PURE__ */ jsx10(
|
|
2605
4775
|
"div",
|
|
2606
4776
|
{
|
|
2607
4777
|
onMouseDown: (e) => {
|
|
2608
4778
|
e.preventDefault();
|
|
2609
4779
|
e.stopPropagation();
|
|
2610
|
-
|
|
4780
|
+
startResize(col.name, currentWidth, e.clientX, colMinWidth);
|
|
2611
4781
|
},
|
|
2612
4782
|
className: "absolute left-0 top-0 bottom-0 w-1.5 cursor-col-resize hover:bg-brand active:bg-brand-hover z-20",
|
|
2613
4783
|
title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
|
|
2614
4784
|
}
|
|
2615
4785
|
),
|
|
2616
|
-
/* @__PURE__ */
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
4786
|
+
isSearching ? /* @__PURE__ */ jsxs10(
|
|
4787
|
+
"div",
|
|
4788
|
+
{
|
|
4789
|
+
ref: activeSearchRef,
|
|
4790
|
+
className: "flex items-center gap-1 w-full",
|
|
4791
|
+
onClick: (e) => e.stopPropagation(),
|
|
4792
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
4793
|
+
children: [
|
|
4794
|
+
isRelation ? /* @__PURE__ */ jsx10("div", { className: "relative flex items-center w-full min-w-0", children: /* @__PURE__ */ jsxs10(
|
|
4795
|
+
"select",
|
|
4796
|
+
{
|
|
4797
|
+
autoFocus: true,
|
|
4798
|
+
value: filterVal,
|
|
4799
|
+
onChange: (e) => {
|
|
4800
|
+
const val = e.target.value;
|
|
4801
|
+
setColumnFilters((prev) => {
|
|
4802
|
+
const next = __spreadValues({}, prev);
|
|
4803
|
+
if (val) next[col.name] = val;
|
|
4804
|
+
else delete next[col.name];
|
|
4805
|
+
return next;
|
|
4806
|
+
});
|
|
4807
|
+
},
|
|
4808
|
+
onKeyDown: (e) => {
|
|
4809
|
+
if (e.key === "Escape" || e.key === "Enter") {
|
|
4810
|
+
setActiveSearchCol(null);
|
|
4811
|
+
}
|
|
4812
|
+
},
|
|
4813
|
+
className: "h-7 text-xs px-1.5 w-full rounded border border-blue-400 bg-white text-slate-800 focus:outline-none focus:ring-1 focus:ring-blue-400 cursor-pointer truncate",
|
|
4814
|
+
children: [
|
|
4815
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "\u05D4\u05DB\u05DC" }),
|
|
4816
|
+
getUniqueRelationOptions(col).map((opt) => /* @__PURE__ */ jsx10("option", { value: opt.label, children: opt.label }, opt.id))
|
|
4817
|
+
]
|
|
4818
|
+
}
|
|
4819
|
+
) }) : /* @__PURE__ */ jsx10("div", { className: "relative flex items-center w-full min-w-0", children: /* @__PURE__ */ jsx10(
|
|
4820
|
+
"input",
|
|
4821
|
+
{
|
|
4822
|
+
autoFocus: true,
|
|
4823
|
+
type: "text",
|
|
4824
|
+
placeholder: `\u05D7\u05E4\u05E9 \u05D1-${col.name}...`,
|
|
4825
|
+
value: filterVal,
|
|
4826
|
+
onChange: (e) => {
|
|
4827
|
+
const val = e.target.value;
|
|
4828
|
+
setColumnFilters((prev) => {
|
|
4829
|
+
const next = __spreadValues({}, prev);
|
|
4830
|
+
if (val) next[col.name] = val;
|
|
4831
|
+
else delete next[col.name];
|
|
4832
|
+
return next;
|
|
4833
|
+
});
|
|
4834
|
+
},
|
|
4835
|
+
onKeyDown: (e) => {
|
|
4836
|
+
if (e.key === "Escape" || e.key === "Enter") {
|
|
4837
|
+
setActiveSearchCol(null);
|
|
4838
|
+
}
|
|
4839
|
+
},
|
|
4840
|
+
className: "h-7 text-xs px-2 w-full rounded border border-blue-400 bg-white text-slate-800 focus:outline-none focus:ring-1 focus:ring-blue-400"
|
|
4841
|
+
}
|
|
4842
|
+
) }),
|
|
4843
|
+
/* @__PURE__ */ jsx10(
|
|
4844
|
+
"button",
|
|
4845
|
+
{
|
|
4846
|
+
type: "button",
|
|
4847
|
+
onMouseDown: (e) => {
|
|
4848
|
+
e.preventDefault();
|
|
4849
|
+
e.stopPropagation();
|
|
4850
|
+
},
|
|
4851
|
+
onClick: (e) => {
|
|
4852
|
+
e.stopPropagation();
|
|
4853
|
+
setColumnFilters((prev) => {
|
|
4854
|
+
const next = __spreadValues({}, prev);
|
|
4855
|
+
delete next[col.name];
|
|
4856
|
+
return next;
|
|
4857
|
+
});
|
|
4858
|
+
setActiveSearchCol(null);
|
|
4859
|
+
},
|
|
4860
|
+
className: "p-1 text-slate-400 hover:text-slate-700 hover:bg-slate-200/70 rounded transition-colors cursor-pointer shrink-0",
|
|
4861
|
+
title: "\u05E0\u05E7\u05D4 \u05D5\u05E1\u05D2\u05D5\u05E8 \u05D7\u05D9\u05E4\u05D5\u05E9",
|
|
4862
|
+
children: /* @__PURE__ */ jsx10(X7, { className: "w-3.5 h-3.5" })
|
|
4863
|
+
}
|
|
4864
|
+
)
|
|
4865
|
+
]
|
|
4866
|
+
}
|
|
4867
|
+
) : /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-1.5 group overflow-hidden w-full", title: col.name, children: [
|
|
4868
|
+
/* @__PURE__ */ jsx10("div", { className: "flex items-center gap-1.5 min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx10(ColumnHeaderTitle, { name: col.name, width: currentWidth, isSubTable: false }) }),
|
|
4869
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
4870
|
+
((_b = col.type) == null ? void 0 : _b.toUpperCase()) !== "SUB_TABLE" && /* @__PURE__ */ jsx10(
|
|
4871
|
+
"button",
|
|
4872
|
+
{
|
|
4873
|
+
type: "button",
|
|
4874
|
+
onClick: (e) => {
|
|
4875
|
+
e.stopPropagation();
|
|
4876
|
+
e.preventDefault();
|
|
4877
|
+
setActiveSearchCol(col.name);
|
|
4878
|
+
},
|
|
4879
|
+
className: `p-1 rounded transition-all cursor-pointer ${filterVal ? "opacity-100 text-blue-600 bg-blue-100 hover:bg-blue-200" : "opacity-0 group-hover:opacity-100 text-slate-400 hover:text-slate-600 hover:bg-slate-200/60"}`,
|
|
4880
|
+
title: filterVal ? `\u05DE\u05E1\u05D5\u05E0\u05DF \u05DC\u05E4\u05D9: "${filterVal}" (\u05DC\u05D7\u05E5 \u05DC\u05E2\u05E8\u05D9\u05DB\u05D4)` : "\u05D7\u05E4\u05E9 \u05D5\u05E1\u05E0\u05DF \u05D1\u05E2\u05DE\u05D5\u05D3\u05D4 \u05D6\u05D5",
|
|
4881
|
+
children: /* @__PURE__ */ jsx10(Search2, { className: "w-3.5 h-3.5" })
|
|
4882
|
+
}
|
|
4883
|
+
),
|
|
4884
|
+
/* @__PURE__ */ jsx10(
|
|
4885
|
+
"svg",
|
|
4886
|
+
{
|
|
4887
|
+
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
4888
|
+
fill: "none",
|
|
4889
|
+
viewBox: "0 0 24 24",
|
|
4890
|
+
stroke: "currentColor",
|
|
4891
|
+
children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
|
|
4892
|
+
}
|
|
4893
|
+
)
|
|
4894
|
+
] })
|
|
2628
4895
|
] })
|
|
2629
4896
|
]
|
|
2630
|
-
},
|
|
4897
|
+
}),
|
|
2631
4898
|
col.name
|
|
2632
4899
|
);
|
|
2633
4900
|
}),
|
|
2634
|
-
/* @__PURE__ */
|
|
4901
|
+
/* @__PURE__ */ jsx10("th", { className: "w-full min-w-[50px] border-b border-slate-200 pointer-events-none h-12 min-h-[48px]" })
|
|
2635
4902
|
] }) }),
|
|
2636
|
-
/* @__PURE__ */
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
4903
|
+
/* @__PURE__ */ jsx10("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ jsx10("tr", { children: /* @__PURE__ */ jsx10("td", { colSpan: filteredColumns.length + 2, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
4904
|
+
/* @__PURE__ */ jsx10("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("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" }) }),
|
|
4905
|
+
/* @__PURE__ */ jsx10("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
|
|
2639
4906
|
] }) }) }) : filteredData.map((row) => {
|
|
2640
4907
|
const hasSubTableCols = filteredColumns.some((c) => {
|
|
2641
4908
|
var _a;
|
|
@@ -2646,10 +4913,20 @@ function TableBlockClient({
|
|
|
2646
4913
|
var _a;
|
|
2647
4914
|
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
2648
4915
|
});
|
|
2649
|
-
return /* @__PURE__ */
|
|
2650
|
-
/* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
|
|
4916
|
+
return /* @__PURE__ */ jsxs10(React9.Fragment, { children: [
|
|
4917
|
+
/* @__PURE__ */ jsxs10("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
|
|
4918
|
+
/* @__PURE__ */ jsx10("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", style: { width: 72, minWidth: 72, maxWidth: 72 }, children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
4919
|
+
/* @__PURE__ */ jsx10(
|
|
4920
|
+
"input",
|
|
4921
|
+
{
|
|
4922
|
+
type: "checkbox",
|
|
4923
|
+
checked: selectedIds.has(row.id),
|
|
4924
|
+
onChange: (e) => toggleSelectRow(row.id, e.target.checked),
|
|
4925
|
+
disabled: isLoading || isUpdatingActive,
|
|
4926
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
4927
|
+
}
|
|
4928
|
+
),
|
|
4929
|
+
hasSubTableCols && /* @__PURE__ */ jsx10(
|
|
2653
4930
|
"button",
|
|
2654
4931
|
{
|
|
2655
4932
|
type: "button",
|
|
@@ -2659,19 +4936,9 @@ function TableBlockClient({
|
|
|
2659
4936
|
else next.add(row.id);
|
|
2660
4937
|
return next;
|
|
2661
4938
|
}),
|
|
2662
|
-
className: "
|
|
4939
|
+
className: "w-5 h-5 rounded-full bg-slate-500 hover:bg-slate-600 text-white flex items-center justify-center transition-colors cursor-pointer shrink-0 shadow-sm",
|
|
2663
4940
|
title: isExpanded ? "\u05E1\u05D2\u05D5\u05E8 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4" : "\u05E4\u05EA\u05D7 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4",
|
|
2664
|
-
children: /* @__PURE__ */
|
|
2665
|
-
}
|
|
2666
|
-
),
|
|
2667
|
-
/* @__PURE__ */ jsx6(
|
|
2668
|
-
"input",
|
|
2669
|
-
{
|
|
2670
|
-
type: "checkbox",
|
|
2671
|
-
checked: selectedIds.has(row.id),
|
|
2672
|
-
onChange: (e) => toggleSelectRow(row.id, e.target.checked),
|
|
2673
|
-
disabled: isLoading || isUpdatingActive,
|
|
2674
|
-
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
4941
|
+
children: /* @__PURE__ */ jsx10("svg", { className: `w-3 h-3 transition-transform duration-150 ${isExpanded ? "rotate-90" : "rotate-180"}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx10("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "3", d: "M9 5l7 7-7 7" }) })
|
|
2675
4942
|
}
|
|
2676
4943
|
)
|
|
2677
4944
|
] }) }),
|
|
@@ -2679,6 +4946,8 @@ function TableBlockClient({
|
|
|
2679
4946
|
var _a;
|
|
2680
4947
|
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
2681
4948
|
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
4949
|
+
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
4950
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
2682
4951
|
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
2683
4952
|
if (value === void 0 && col.defaultValue !== void 0) {
|
|
2684
4953
|
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
@@ -2687,34 +4956,42 @@ function TableBlockClient({
|
|
|
2687
4956
|
}
|
|
2688
4957
|
}
|
|
2689
4958
|
if (value === void 0) value = null;
|
|
2690
|
-
return /* @__PURE__ */
|
|
2691
|
-
|
|
4959
|
+
return /* @__PURE__ */ jsx10(
|
|
4960
|
+
"td",
|
|
2692
4961
|
{
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
4962
|
+
className: `border-b border-l border-slate-200 p-0 relative ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
4963
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
4964
|
+
children: /* @__PURE__ */ jsx10(
|
|
4965
|
+
InputComponent,
|
|
4966
|
+
{
|
|
4967
|
+
value,
|
|
4968
|
+
column: col,
|
|
4969
|
+
rowId: row.id,
|
|
4970
|
+
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
4971
|
+
context: {
|
|
4972
|
+
tableName: (schema == null ? void 0 : schema.name) || (schema == null ? void 0 : schema.tableName) || (schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.id) || "Table",
|
|
4973
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
4974
|
+
onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
|
|
4975
|
+
relationOptions,
|
|
4976
|
+
refetchRelation,
|
|
4977
|
+
executeAction,
|
|
4978
|
+
emitEvent,
|
|
4979
|
+
pageState,
|
|
4980
|
+
componentId,
|
|
4981
|
+
orgId,
|
|
4982
|
+
updateQuietly: handleQuietCellChange,
|
|
4983
|
+
triggerSaveSuccess,
|
|
4984
|
+
rowData: row.data
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
)
|
|
4988
|
+
},
|
|
4989
|
+
col.name
|
|
4990
|
+
);
|
|
2714
4991
|
}),
|
|
2715
|
-
/* @__PURE__ */
|
|
4992
|
+
/* @__PURE__ */ jsx10("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
2716
4993
|
] }),
|
|
2717
|
-
isExpanded && /* @__PURE__ */
|
|
4994
|
+
isExpanded && /* @__PURE__ */ jsx10(
|
|
2718
4995
|
ExpandedSubTables,
|
|
2719
4996
|
{
|
|
2720
4997
|
rowId: row.id,
|
|
@@ -2729,37 +5006,38 @@ function TableBlockClient({
|
|
|
2729
5006
|
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
2730
5007
|
rowData: row.data,
|
|
2731
5008
|
updateQuietly: handleQuietCellChange,
|
|
2732
|
-
triggerSaveSuccess
|
|
5009
|
+
triggerSaveSuccess,
|
|
5010
|
+
onUpdateColumnConfig: handleUpdateColumnConfig
|
|
2733
5011
|
}
|
|
2734
5012
|
}
|
|
2735
5013
|
)
|
|
2736
5014
|
] }, row.id);
|
|
2737
5015
|
}) }),
|
|
2738
|
-
showSummary && filteredData.length > 0 && /* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
5016
|
+
showSummary && filteredData.length > 0 && /* @__PURE__ */ jsx10("tfoot", { className: "bg-slate-50 border-t-2 border-slate-300 sticky bottom-0 z-10 shadow-[0_-2px_4px_rgba(0,0,0,0.02)]", children: /* @__PURE__ */ jsxs10("tr", { children: [
|
|
5017
|
+
/* @__PURE__ */ jsx10("td", { className: "border-b border-l border-slate-200 p-1.5 text-center font-bold text-slate-600 text-xs", children: '\u05E1\u05D4"\u05DB' }),
|
|
2740
5018
|
filteredColumns.map((col) => {
|
|
2741
|
-
var _a;
|
|
5019
|
+
var _a, _b;
|
|
2742
5020
|
const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
|
|
2743
5021
|
const isNumeric = typeUpper === "CURRENCY" || typeUpper === "NUMBER";
|
|
2744
5022
|
const total = columnTotals[col.name];
|
|
2745
5023
|
let displayVal = "";
|
|
2746
5024
|
if (isNumeric && total !== void 0) {
|
|
2747
5025
|
displayVal = new Intl.NumberFormat("en-US").format(total);
|
|
2748
|
-
if (
|
|
2749
|
-
const symbol = getCurrencySymbol(col.currencySymbol);
|
|
5026
|
+
if (col.type === "CURRENCY") {
|
|
5027
|
+
const symbol = getCurrencySymbol((_b = col.config) == null ? void 0 : _b.currencySymbol);
|
|
2750
5028
|
displayVal = symbol ? `${symbol} ${displayVal}` : displayVal;
|
|
2751
5029
|
}
|
|
2752
5030
|
}
|
|
2753
|
-
return /* @__PURE__ */
|
|
5031
|
+
return /* @__PURE__ */ jsx10("td", { className: "border-b border-l border-slate-200 p-2 text-sm font-semibold text-slate-700 bg-slate-50 relative", children: isNumeric && /* @__PURE__ */ jsx10("div", { className: "flex items-center text-right justify-start", children: /* @__PURE__ */ jsx10("span", { className: "truncate", children: displayVal }) }) }, col.name);
|
|
2754
5032
|
}),
|
|
2755
|
-
/* @__PURE__ */
|
|
5033
|
+
/* @__PURE__ */ jsx10("td", { className: "border-b border-slate-200 bg-slate-50 pointer-events-none" })
|
|
2756
5034
|
] }) })
|
|
2757
5035
|
] })
|
|
2758
5036
|
] }),
|
|
2759
|
-
/* @__PURE__ */
|
|
2760
|
-
/* @__PURE__ */
|
|
2761
|
-
/* @__PURE__ */
|
|
2762
|
-
/* @__PURE__ */
|
|
5037
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-3 px-4 py-3 bg-slate-50 border-t border-slate-200 text-xs text-slate-600 rounded-b-xl", children: [
|
|
5038
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
|
|
5039
|
+
/* @__PURE__ */ jsx10("span", { className: "font-medium text-slate-700", children: "\u05E9\u05D5\u05E8\u05D5\u05EA \u05DC\u05E2\u05DE\u05D5\u05D3:" }),
|
|
5040
|
+
/* @__PURE__ */ jsxs10(
|
|
2763
5041
|
"select",
|
|
2764
5042
|
{
|
|
2765
5043
|
value: limit,
|
|
@@ -2767,27 +5045,27 @@ function TableBlockClient({
|
|
|
2767
5045
|
disabled: isLoading || isUpdatingActive,
|
|
2768
5046
|
className: "bg-white border border-slate-300 rounded-lg px-2.5 py-1 text-slate-700 font-semibold shadow-2xs cursor-pointer focus:outline-none focus:ring-2 focus:ring-brand disabled:opacity-50",
|
|
2769
5047
|
children: [
|
|
2770
|
-
/* @__PURE__ */
|
|
2771
|
-
/* @__PURE__ */
|
|
2772
|
-
/* @__PURE__ */
|
|
5048
|
+
/* @__PURE__ */ jsx10("option", { value: 20, children: "20" }),
|
|
5049
|
+
/* @__PURE__ */ jsx10("option", { value: 50, children: "50" }),
|
|
5050
|
+
/* @__PURE__ */ jsx10("option", { value: 100, children: "100" })
|
|
2773
5051
|
]
|
|
2774
5052
|
}
|
|
2775
5053
|
)
|
|
2776
5054
|
] }),
|
|
2777
|
-
/* @__PURE__ */
|
|
2778
|
-
/* @__PURE__ */
|
|
5055
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-4", children: [
|
|
5056
|
+
/* @__PURE__ */ jsxs10("span", { className: "font-medium text-slate-600", children: [
|
|
2779
5057
|
"\u05E2\u05DE\u05D5\u05D3 ",
|
|
2780
|
-
/* @__PURE__ */
|
|
5058
|
+
/* @__PURE__ */ jsx10("strong", { className: "text-slate-900", children: page }),
|
|
2781
5059
|
" \u05DE\u05EA\u05D5\u05DA ",
|
|
2782
|
-
/* @__PURE__ */
|
|
2783
|
-
totalRecords > 0 && /* @__PURE__ */
|
|
5060
|
+
/* @__PURE__ */ jsx10("strong", { className: "text-slate-900", children: totalPages || 1 }),
|
|
5061
|
+
totalRecords > 0 && /* @__PURE__ */ jsxs10("span", { className: "text-slate-500 font-normal", children: [
|
|
2784
5062
|
" (",
|
|
2785
5063
|
totalRecords,
|
|
2786
5064
|
' \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D1\u05E1\u05D4"\u05DB)'
|
|
2787
5065
|
] })
|
|
2788
5066
|
] }),
|
|
2789
|
-
/* @__PURE__ */
|
|
2790
|
-
/* @__PURE__ */
|
|
5067
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1.5", children: [
|
|
5068
|
+
/* @__PURE__ */ jsx10(
|
|
2791
5069
|
"button",
|
|
2792
5070
|
{
|
|
2793
5071
|
onClick: handlePrevPage,
|
|
@@ -2797,7 +5075,7 @@ function TableBlockClient({
|
|
|
2797
5075
|
children: "\u05D4\u05E7\u05D5\u05D3\u05DD"
|
|
2798
5076
|
}
|
|
2799
5077
|
),
|
|
2800
|
-
/* @__PURE__ */
|
|
5078
|
+
/* @__PURE__ */ jsx10(
|
|
2801
5079
|
"button",
|
|
2802
5080
|
{
|
|
2803
5081
|
onClick: handleNextPage,
|
|
@@ -2823,11 +5101,11 @@ function ExpandedSubTables({
|
|
|
2823
5101
|
context
|
|
2824
5102
|
}) {
|
|
2825
5103
|
var _a;
|
|
2826
|
-
const [activeTab, setActiveTab] =
|
|
5104
|
+
const [activeTab, setActiveTab] = useState10((_a = subTableColumns[0]) == null ? void 0 : _a.name);
|
|
2827
5105
|
if (subTableColumns.length === 0) return null;
|
|
2828
5106
|
if (subTableColumns.length === 1) {
|
|
2829
5107
|
const stCol = subTableColumns[0];
|
|
2830
|
-
return /* @__PURE__ */
|
|
5108
|
+
return /* @__PURE__ */ jsx10("tr", { children: /* @__PURE__ */ jsx10("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50", children: /* @__PURE__ */ jsx10(
|
|
2831
5109
|
SubTableViewer,
|
|
2832
5110
|
{
|
|
2833
5111
|
rowId,
|
|
@@ -2839,8 +5117,8 @@ function ExpandedSubTables({
|
|
|
2839
5117
|
) }) });
|
|
2840
5118
|
}
|
|
2841
5119
|
const activeCol = subTableColumns.find((c) => c.name === activeTab) || subTableColumns[0];
|
|
2842
|
-
return /* @__PURE__ */
|
|
2843
|
-
/* @__PURE__ */
|
|
5120
|
+
return /* @__PURE__ */ jsx10("tr", { children: /* @__PURE__ */ jsxs10("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50 overflow-hidden", children: [
|
|
5121
|
+
/* @__PURE__ */ jsx10("div", { className: "flex border-b border-slate-200 bg-slate-100/50 px-2 pt-2 gap-1 overflow-hidden", children: subTableColumns.map((col) => /* @__PURE__ */ jsx10(
|
|
2844
5122
|
"button",
|
|
2845
5123
|
{
|
|
2846
5124
|
type: "button",
|
|
@@ -2850,7 +5128,7 @@ function ExpandedSubTables({
|
|
|
2850
5128
|
},
|
|
2851
5129
|
col.name
|
|
2852
5130
|
)) }),
|
|
2853
|
-
/* @__PURE__ */
|
|
5131
|
+
/* @__PURE__ */ jsx10("div", { className: "bg-white", children: /* @__PURE__ */ jsx10(
|
|
2854
5132
|
SubTableViewer,
|
|
2855
5133
|
{
|
|
2856
5134
|
rowId,
|
|
@@ -2865,9 +5143,9 @@ function ExpandedSubTables({
|
|
|
2865
5143
|
}
|
|
2866
5144
|
|
|
2867
5145
|
// src/components/TableBlock/TableBlock.tsx
|
|
2868
|
-
import { jsx as
|
|
5146
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
2869
5147
|
function TableBlock(props) {
|
|
2870
|
-
return /* @__PURE__ */
|
|
5148
|
+
return /* @__PURE__ */ jsx11(TableBlockClient, __spreadValues({}, props));
|
|
2871
5149
|
}
|
|
2872
5150
|
|
|
2873
5151
|
// src/registry.ts
|
|
@@ -2875,10 +5153,31 @@ var UNIVERSE_COMPONENTS = {
|
|
|
2875
5153
|
TABLE: TableBlock
|
|
2876
5154
|
};
|
|
2877
5155
|
export {
|
|
5156
|
+
ColumnHeaderTitle,
|
|
5157
|
+
DatePickerCell,
|
|
5158
|
+
LinkPickerCell,
|
|
5159
|
+
PASTEL_PALETTES,
|
|
5160
|
+
RelationPickerCell,
|
|
2878
5161
|
TableBlock,
|
|
5162
|
+
TimePickerCell,
|
|
2879
5163
|
ToastContext,
|
|
2880
5164
|
ToastProvider,
|
|
2881
5165
|
UNIVERSE_COMPONENTS,
|
|
5166
|
+
calculateMinColumnWidth,
|
|
2882
5167
|
cn,
|
|
5168
|
+
formatConflictCellValue,
|
|
5169
|
+
formatPhoneDisplay,
|
|
5170
|
+
formatTimeInput,
|
|
5171
|
+
formatTimeIso,
|
|
5172
|
+
getDeterministicPastelBadge,
|
|
5173
|
+
measureTextWidth,
|
|
5174
|
+
normalizeRelationValue,
|
|
5175
|
+
openWhatsAppChat,
|
|
5176
|
+
parseLinkValue,
|
|
5177
|
+
parseTimeParts,
|
|
5178
|
+
resolveProtocol,
|
|
5179
|
+
splitHeaderTitle,
|
|
5180
|
+
useColumnReorder,
|
|
5181
|
+
useColumnResize,
|
|
2883
5182
|
useToast
|
|
2884
5183
|
};
|