@universe-platform/ui 0.1.0-beta.8 → 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 +394 -21
- package/dist/index.d.mts +153 -50
- package/dist/index.d.ts +153 -50
- package/dist/index.js +2278 -670
- package/dist/index.mjs +2307 -671
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
47
47
|
}
|
|
48
48
|
return to;
|
|
49
49
|
};
|
|
50
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
50
51
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
51
52
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
52
53
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -60,13 +61,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
60
61
|
// src/index.ts
|
|
61
62
|
var src_exports = {};
|
|
62
63
|
__export(src_exports, {
|
|
64
|
+
ColumnHeaderTitle: () => ColumnHeaderTitle,
|
|
65
|
+
DatePickerCell: () => DatePickerCell,
|
|
66
|
+
LinkPickerCell: () => LinkPickerCell,
|
|
67
|
+
PASTEL_PALETTES: () => PASTEL_PALETTES,
|
|
68
|
+
RelationPickerCell: () => RelationPickerCell,
|
|
63
69
|
TableBlock: () => TableBlock,
|
|
70
|
+
TimePickerCell: () => TimePickerCell,
|
|
64
71
|
ToastContext: () => ToastContext,
|
|
65
72
|
ToastProvider: () => ToastProvider,
|
|
66
73
|
UNIVERSE_COMPONENTS: () => UNIVERSE_COMPONENTS,
|
|
74
|
+
calculateMinColumnWidth: () => calculateMinColumnWidth,
|
|
67
75
|
cn: () => cn,
|
|
76
|
+
formatConflictCellValue: () => formatConflictCellValue,
|
|
68
77
|
formatPhoneDisplay: () => formatPhoneDisplay,
|
|
78
|
+
formatTimeInput: () => formatTimeInput,
|
|
79
|
+
formatTimeIso: () => formatTimeIso,
|
|
80
|
+
getDeterministicPastelBadge: () => getDeterministicPastelBadge,
|
|
81
|
+
measureTextWidth: () => measureTextWidth,
|
|
82
|
+
normalizeRelationValue: () => normalizeRelationValue,
|
|
69
83
|
openWhatsAppChat: () => openWhatsAppChat,
|
|
84
|
+
parseLinkValue: () => parseLinkValue,
|
|
85
|
+
parseTimeParts: () => parseTimeParts,
|
|
86
|
+
resolveProtocol: () => resolveProtocol,
|
|
87
|
+
splitHeaderTitle: () => splitHeaderTitle,
|
|
88
|
+
useColumnReorder: () => useColumnReorder,
|
|
89
|
+
useColumnResize: () => useColumnResize,
|
|
70
90
|
useToast: () => useToast
|
|
71
91
|
});
|
|
72
92
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -108,8 +128,46 @@ function formatPhoneDisplay(phone) {
|
|
|
108
128
|
return phone;
|
|
109
129
|
}
|
|
110
130
|
|
|
131
|
+
// src/utils/colors.ts
|
|
132
|
+
var PASTEL_PALETTES = [
|
|
133
|
+
{ bg: "bg-blue-50", text: "text-blue-700", border: "border-blue-200" },
|
|
134
|
+
{ bg: "bg-emerald-50", text: "text-emerald-700", border: "border-emerald-200" },
|
|
135
|
+
{ bg: "bg-violet-50", text: "text-violet-700", border: "border-violet-200" },
|
|
136
|
+
{ bg: "bg-amber-50", text: "text-amber-700", border: "border-amber-200" },
|
|
137
|
+
{ bg: "bg-rose-50", text: "text-rose-700", border: "border-rose-200" },
|
|
138
|
+
{ bg: "bg-cyan-50", text: "text-cyan-700", border: "border-cyan-200" },
|
|
139
|
+
{ bg: "bg-indigo-50", text: "text-indigo-700", border: "border-indigo-200" },
|
|
140
|
+
{ bg: "bg-teal-50", text: "text-teal-700", border: "border-teal-200" },
|
|
141
|
+
{ bg: "bg-sky-50", text: "text-sky-700", border: "border-sky-200" },
|
|
142
|
+
{ bg: "bg-fuchsia-50", text: "text-fuchsia-700", border: "border-fuchsia-200" },
|
|
143
|
+
{ bg: "bg-pink-50", text: "text-pink-700", border: "border-pink-200" },
|
|
144
|
+
{ bg: "bg-purple-50", text: "text-purple-700", border: "border-purple-200" },
|
|
145
|
+
{ bg: "bg-orange-50", text: "text-orange-700", border: "border-orange-200" },
|
|
146
|
+
{ bg: "bg-red-50", text: "text-red-700", border: "border-red-200" },
|
|
147
|
+
{ bg: "bg-lime-50", text: "text-lime-700", border: "border-lime-200" },
|
|
148
|
+
{ bg: "bg-green-50", text: "text-green-700", border: "border-green-200" },
|
|
149
|
+
{ bg: "bg-yellow-50", text: "text-yellow-700", border: "border-yellow-200" }
|
|
150
|
+
];
|
|
151
|
+
function getDeterministicPastelBadge(key) {
|
|
152
|
+
if (!key) return PASTEL_PALETTES[0];
|
|
153
|
+
let hash = 2166136261;
|
|
154
|
+
for (let i = 0; i < key.length; i++) {
|
|
155
|
+
hash ^= key.charCodeAt(i);
|
|
156
|
+
hash = Math.imul(hash, 16777619);
|
|
157
|
+
}
|
|
158
|
+
const index = Math.abs(hash) % PASTEL_PALETTES.length;
|
|
159
|
+
return PASTEL_PALETTES[index];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/types/data.types.ts
|
|
163
|
+
var data_types_exports = {};
|
|
164
|
+
__reExport(data_types_exports, require("@universe-platform/shared"));
|
|
165
|
+
|
|
166
|
+
// src/index.ts
|
|
167
|
+
__reExport(src_exports, data_types_exports, module.exports);
|
|
168
|
+
|
|
111
169
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
112
|
-
var
|
|
170
|
+
var import_react12 = __toESM(require("react"));
|
|
113
171
|
|
|
114
172
|
// src/hooks/useToast.ts
|
|
115
173
|
var import_react2 = require("react");
|
|
@@ -309,7 +367,7 @@ function useToast() {
|
|
|
309
367
|
}
|
|
310
368
|
|
|
311
369
|
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
312
|
-
var
|
|
370
|
+
var import_react8 = __toESM(require("react"));
|
|
313
371
|
|
|
314
372
|
// src/components/TableBlock/fields/DrivePickerCell.tsx
|
|
315
373
|
var import_react3 = __toESM(require("react"));
|
|
@@ -766,214 +824,1067 @@ function DatePickerCell({ value, onChange, readOnly = false }) {
|
|
|
766
824
|
] });
|
|
767
825
|
}
|
|
768
826
|
|
|
769
|
-
// src/components/TableBlock/fields/
|
|
827
|
+
// src/components/TableBlock/fields/TimePickerCell.tsx
|
|
828
|
+
var import_react5 = require("react");
|
|
829
|
+
var import_lucide_react4 = require("lucide-react");
|
|
770
830
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
};
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
831
|
+
function parseTimeParts(val) {
|
|
832
|
+
if (val === void 0 || val === null || val === "") return null;
|
|
833
|
+
if (typeof val === "string") {
|
|
834
|
+
const trimmed = val.trim();
|
|
835
|
+
if (!trimmed) return null;
|
|
836
|
+
const match = trimmed.match(/^(\d{1,2})[:.](\d{1,2})(?:[:.]\d{1,2})?$/);
|
|
837
|
+
if (match) {
|
|
838
|
+
const hour = parseInt(match[1], 10);
|
|
839
|
+
const minute = parseInt(match[2], 10);
|
|
840
|
+
if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59) {
|
|
841
|
+
return { hour, minute };
|
|
842
|
+
}
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
if (trimmed.includes("T")) {
|
|
846
|
+
const d = new Date(trimmed);
|
|
847
|
+
if (!isNaN(d.getTime())) {
|
|
848
|
+
return { hour: d.getHours(), minute: d.getMinutes() };
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
} else if (val instanceof Date && !isNaN(val.getTime())) {
|
|
852
|
+
return { hour: val.getHours(), minute: val.getMinutes() };
|
|
786
853
|
}
|
|
787
|
-
|
|
788
|
-
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
function formatTimeIso(hour, minute) {
|
|
857
|
+
const hh = String(hour).padStart(2, "0");
|
|
858
|
+
const mm = String(minute).padStart(2, "0");
|
|
859
|
+
return `${hh}:${mm}`;
|
|
860
|
+
}
|
|
861
|
+
function formatTimeInput(input) {
|
|
862
|
+
if (!input) return "";
|
|
863
|
+
const digits = String(input).replace(/\D/g, "");
|
|
864
|
+
if (!digits) return "";
|
|
865
|
+
if (digits.length === 1) {
|
|
866
|
+
const d = parseInt(digits, 10);
|
|
867
|
+
if (d > 2) {
|
|
868
|
+
return `0${d}:`;
|
|
869
|
+
}
|
|
870
|
+
return `${digits}:`;
|
|
789
871
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
if (typeof v === "string" && v.trim() !== "") return true;
|
|
795
|
-
if (typeof v === "number" && !isNaN(v)) return true;
|
|
796
|
-
return false;
|
|
797
|
-
});
|
|
798
|
-
if (fallbackField) return String(opt.data[fallbackField]);
|
|
872
|
+
const h = parseInt(digits.slice(0, 2), 10);
|
|
873
|
+
const hh = h > 23 ? "23" : digits.slice(0, 2);
|
|
874
|
+
if (digits.length === 2) {
|
|
875
|
+
return `${hh}:`;
|
|
799
876
|
}
|
|
800
|
-
if (
|
|
801
|
-
return
|
|
877
|
+
if (digits.length === 3) {
|
|
878
|
+
return `${hh}:${digits[2]}`;
|
|
802
879
|
}
|
|
803
|
-
|
|
880
|
+
const m = parseInt(digits.slice(2, 4), 10);
|
|
881
|
+
const mm = m > 59 ? "59" : digits.slice(2, 4);
|
|
882
|
+
return `${hh}:${mm}`;
|
|
804
883
|
}
|
|
805
|
-
var
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
884
|
+
var ALL_MINUTES = Array.from({ length: 60 }, (_, i) => i);
|
|
885
|
+
function TimePickerCell({ value, onChange, readOnly = false }) {
|
|
886
|
+
var _a, _b;
|
|
887
|
+
const [isOpen, setIsOpen] = (0, import_react5.useState)(false);
|
|
888
|
+
const containerRef = (0, import_react5.useRef)(null);
|
|
889
|
+
const hoursListRef = (0, import_react5.useRef)(null);
|
|
890
|
+
const minutesListRef = (0, import_react5.useRef)(null);
|
|
891
|
+
const [popoverPos, setPopoverPos] = (0, import_react5.useState)({ top: 0, right: 0 });
|
|
892
|
+
const parsedParts = (0, import_react5.useMemo)(() => parseTimeParts(value), [value]);
|
|
893
|
+
const displayString = (0, import_react5.useMemo)(() => {
|
|
894
|
+
return parsedParts ? formatTimeIso(parsedParts.hour, parsedParts.minute) : "";
|
|
895
|
+
}, [parsedParts]);
|
|
896
|
+
const [rawInput, setRawInput] = (0, import_react5.useState)(displayString);
|
|
897
|
+
(0, import_react5.useEffect)(() => {
|
|
898
|
+
setRawInput(displayString);
|
|
899
|
+
}, [displayString]);
|
|
900
|
+
const selectedHour = (_a = parsedParts == null ? void 0 : parsedParts.hour) != null ? _a : null;
|
|
901
|
+
const selectedMinute = (_b = parsedParts == null ? void 0 : parsedParts.minute) != null ? _b : null;
|
|
902
|
+
const updatePopoverPosition = (0, import_react5.useCallback)(() => {
|
|
903
|
+
if (containerRef.current) {
|
|
904
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
905
|
+
const right = window.innerWidth - rect.right;
|
|
906
|
+
const popoverHeight = 260;
|
|
907
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
908
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
909
|
+
setPopoverPos({
|
|
910
|
+
top: Math.max(10, rect.top - popoverHeight - 4),
|
|
911
|
+
right: Math.max(10, right)
|
|
912
|
+
});
|
|
913
|
+
} else {
|
|
914
|
+
setPopoverPos({
|
|
915
|
+
top: Math.min(window.innerHeight - popoverHeight - 10, rect.bottom + 4),
|
|
916
|
+
right: Math.max(10, right)
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}, []);
|
|
921
|
+
(0, import_react5.useEffect)(() => {
|
|
922
|
+
if (!isOpen) return;
|
|
923
|
+
updatePopoverPosition();
|
|
924
|
+
function handleScrollOrResize() {
|
|
925
|
+
updatePopoverPosition();
|
|
926
|
+
}
|
|
927
|
+
function handleClickOutside(event) {
|
|
928
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
929
|
+
const popoverEl = document.getElementById("time-picker-popover");
|
|
930
|
+
if (popoverEl && popoverEl.contains(event.target)) {
|
|
931
|
+
return;
|
|
826
932
|
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
},
|
|
830
|
-
TIME: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
831
|
-
"input",
|
|
832
|
-
{
|
|
833
|
-
type: "time",
|
|
834
|
-
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
835
|
-
value: value || "",
|
|
836
|
-
onChange: (e) => onChange(e.target.value)
|
|
933
|
+
setIsOpen(false);
|
|
934
|
+
}
|
|
837
935
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
936
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
937
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
938
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
939
|
+
return () => {
|
|
940
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
941
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
942
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
943
|
+
};
|
|
944
|
+
}, [isOpen, updatePopoverPosition]);
|
|
945
|
+
(0, import_react5.useEffect)(() => {
|
|
946
|
+
if (isOpen) {
|
|
947
|
+
if (selectedHour !== null && hoursListRef.current) {
|
|
948
|
+
const activeHourBtn = hoursListRef.current.querySelector('[data-selected="true"]');
|
|
949
|
+
if (activeHourBtn) {
|
|
950
|
+
activeHourBtn.scrollIntoView({ block: "center" });
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
if (selectedMinute !== null && minutesListRef.current) {
|
|
954
|
+
const activeMinBtn = minutesListRef.current.querySelector('[data-selected="true"]');
|
|
955
|
+
if (activeMinBtn) {
|
|
956
|
+
activeMinBtn.scrollIntoView({ block: "center" });
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}, [isOpen, selectedHour, selectedMinute]);
|
|
961
|
+
const handleInputChange = (e) => {
|
|
962
|
+
let val = e.target.value;
|
|
963
|
+
if (val.length === 2 && !val.includes(":") && rawInput.length === 1) {
|
|
964
|
+
val += ":";
|
|
965
|
+
}
|
|
966
|
+
if (val.length > 5) return;
|
|
967
|
+
setRawInput(val);
|
|
968
|
+
if (val.length === 5 && /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/.test(val)) {
|
|
969
|
+
onChange(val);
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
const handleKeyDown = (e) => {
|
|
973
|
+
if (e.key === "Enter") {
|
|
974
|
+
handleInputBlur();
|
|
975
|
+
setIsOpen(false);
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
if (e.key === "Backspace" || e.key === "Delete" || e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "Tab" || e.key === "Escape" || (e.ctrlKey || e.metaKey)) {
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
if (e.key === ":") return;
|
|
982
|
+
if (!/^\d$/.test(e.key)) {
|
|
983
|
+
e.preventDefault();
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
const handleInputBlur = () => {
|
|
987
|
+
let text = rawInput.trim();
|
|
988
|
+
if (!text) {
|
|
989
|
+
onChange(null);
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (!text.includes(":")) {
|
|
993
|
+
if (text.length === 1 || text.length === 2) {
|
|
994
|
+
text = `${text}:00`;
|
|
995
|
+
} else if (text.length === 3) {
|
|
996
|
+
text = `0${text[0]}:${text.slice(1)}`;
|
|
997
|
+
} else if (text.length === 4) {
|
|
998
|
+
text = `${text.slice(0, 2)}:${text.slice(2)}`;
|
|
999
|
+
}
|
|
1000
|
+
} else if (text.endsWith(":")) {
|
|
1001
|
+
text = `${text}00`;
|
|
1002
|
+
}
|
|
1003
|
+
const parts = parseTimeParts(text);
|
|
1004
|
+
if (parts) {
|
|
1005
|
+
const iso = formatTimeIso(parts.hour, parts.minute);
|
|
1006
|
+
setRawInput(iso);
|
|
1007
|
+
onChange(iso);
|
|
1008
|
+
} else {
|
|
1009
|
+
setRawInput(displayString);
|
|
856
1010
|
}
|
|
857
|
-
|
|
1011
|
+
};
|
|
1012
|
+
const handleSelectHour = (h) => {
|
|
1013
|
+
const m = selectedMinute != null ? selectedMinute : 0;
|
|
1014
|
+
const iso = formatTimeIso(h, m);
|
|
1015
|
+
onChange(iso);
|
|
1016
|
+
setRawInput(iso);
|
|
1017
|
+
};
|
|
1018
|
+
const handleSelectMinute = (m) => {
|
|
1019
|
+
const h = selectedHour != null ? selectedHour : (/* @__PURE__ */ new Date()).getHours();
|
|
1020
|
+
const iso = formatTimeIso(h, m);
|
|
1021
|
+
onChange(iso);
|
|
1022
|
+
setRawInput(iso);
|
|
1023
|
+
};
|
|
1024
|
+
const handleSetNow = () => {
|
|
1025
|
+
const now = /* @__PURE__ */ new Date();
|
|
1026
|
+
const iso = formatTimeIso(now.getHours(), now.getMinutes());
|
|
1027
|
+
onChange(iso);
|
|
1028
|
+
setRawInput(iso);
|
|
1029
|
+
};
|
|
1030
|
+
const handleClear = () => {
|
|
1031
|
+
onChange(null);
|
|
1032
|
+
setRawInput("");
|
|
1033
|
+
setIsOpen(false);
|
|
1034
|
+
};
|
|
1035
|
+
if (readOnly) {
|
|
1036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1.5 px-2 h-full", children: [
|
|
1037
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.Clock, { className: "w-3.5 h-3.5 text-slate-400 shrink-0" }),
|
|
1038
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-sm font-normal text-slate-800 tracking-wider", dir: "ltr", children: displayString || "-" })
|
|
1039
|
+
] });
|
|
1040
|
+
}
|
|
1041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref: containerRef, className: "relative w-full h-full flex items-center px-2", children: [
|
|
1042
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
858
1043
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
859
|
-
"
|
|
1044
|
+
"button",
|
|
860
1045
|
{
|
|
861
|
-
type: "
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1046
|
+
type: "button",
|
|
1047
|
+
onClick: () => {
|
|
1048
|
+
setIsOpen((prev) => {
|
|
1049
|
+
const next = !prev;
|
|
1050
|
+
if (next) updatePopoverPosition();
|
|
1051
|
+
return next;
|
|
1052
|
+
});
|
|
1053
|
+
},
|
|
1054
|
+
className: "p-1 text-slate-400 hover:text-blue-600 rounded transition-colors cursor-pointer shrink-0",
|
|
1055
|
+
title: "\u05D1\u05D7\u05E8 \u05E9\u05E2\u05D4",
|
|
1056
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.Clock, { className: "w-4 h-4" })
|
|
866
1057
|
}
|
|
867
1058
|
),
|
|
868
1059
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
869
1060
|
"input",
|
|
870
1061
|
{
|
|
871
|
-
type: "
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
"button",
|
|
880
|
-
{
|
|
881
|
-
onClick: () => setIsEditing(false),
|
|
882
|
-
className: "text-xs font-medium text-green-600 hover:text-green-700 p-1 mx-1 rounded transition-colors",
|
|
883
|
-
title: "\u05E9\u05DE\u05D5\u05E8",
|
|
884
|
-
children: "\u05E9\u05DE\u05D5\u05E8"
|
|
1062
|
+
type: "text",
|
|
1063
|
+
dir: "ltr",
|
|
1064
|
+
placeholder: "--:--",
|
|
1065
|
+
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",
|
|
1066
|
+
value: rawInput,
|
|
1067
|
+
onChange: handleInputChange,
|
|
1068
|
+
onKeyDown: handleKeyDown,
|
|
1069
|
+
onBlur: handleInputBlur
|
|
885
1070
|
}
|
|
886
1071
|
)
|
|
887
|
-
] })
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
"input",
|
|
891
|
-
{
|
|
892
|
-
type: "checkbox",
|
|
893
|
-
checked: !!value,
|
|
894
|
-
onChange: (e) => onChange(e.target.checked),
|
|
895
|
-
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
896
|
-
}
|
|
897
|
-
) }),
|
|
898
|
-
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
899
|
-
DrivePickerCell,
|
|
900
|
-
{
|
|
901
|
-
value: value || [],
|
|
902
|
-
onChange,
|
|
903
|
-
column,
|
|
904
|
-
rowId,
|
|
905
|
-
tableName: context == null ? void 0 : context.tableName,
|
|
906
|
-
onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
|
|
907
|
-
context
|
|
908
|
-
}
|
|
909
|
-
),
|
|
910
|
-
RELATION: ({ value, onChange, column, context }) => {
|
|
911
|
-
var _a;
|
|
912
|
-
const options = ((_a = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a[column.name]) || [];
|
|
913
|
-
import_react5.default.useEffect(() => {
|
|
914
|
-
if (typeof value === "string" && value !== "" && options.length > 0) {
|
|
915
|
-
const isValidId = options.some((o) => String(o.id) === String(value));
|
|
916
|
-
if (!isValidId) {
|
|
917
|
-
const match = options.find(
|
|
918
|
-
(o) => String(getRelationDisplayLabel(o, column)).trim() === String(value).trim()
|
|
919
|
-
);
|
|
920
|
-
if (match) {
|
|
921
|
-
onChange(match.id);
|
|
922
|
-
} else {
|
|
923
|
-
onChange("");
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
}, [value, options, column, onChange]);
|
|
928
|
-
const processedOptions = options.map((opt) => __spreadProps(__spreadValues({}, opt), {
|
|
929
|
-
_displayLabel: getRelationDisplayLabel(opt, column)
|
|
930
|
-
}));
|
|
931
|
-
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");
|
|
932
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
933
|
-
"select",
|
|
1072
|
+
] }),
|
|
1073
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1074
|
+
"div",
|
|
934
1075
|
{
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
if (context == null ? void 0 : context.refetchRelation) {
|
|
940
|
-
context.refetchRelation(column.name);
|
|
941
|
-
}
|
|
942
|
-
},
|
|
1076
|
+
id: "time-picker-popover",
|
|
1077
|
+
dir: "rtl",
|
|
1078
|
+
style: { top: `${popoverPos.top}px`, right: `${popoverPos.right}px` },
|
|
1079
|
+
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",
|
|
943
1080
|
children: [
|
|
944
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.
|
|
945
|
-
|
|
1081
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center justify-between pb-2 mb-2 border-b border-slate-100", children: [
|
|
1082
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1.5 text-xs font-semibold text-slate-700", children: [
|
|
1083
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.Clock, { className: "w-3.5 h-3.5 text-blue-600" }),
|
|
1084
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u05D1\u05D7\u05D9\u05E8\u05EA \u05E9\u05E2\u05D4" })
|
|
1085
|
+
] }),
|
|
1086
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
1087
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1088
|
+
"button",
|
|
1089
|
+
{
|
|
1090
|
+
type: "button",
|
|
1091
|
+
onClick: handleSetNow,
|
|
1092
|
+
className: "text-[11px] px-1.5 py-0.5 font-medium text-blue-600 hover:bg-blue-50 rounded transition-colors cursor-pointer",
|
|
1093
|
+
children: "\u05E2\u05DB\u05E9\u05D9\u05D5"
|
|
1094
|
+
}
|
|
1095
|
+
),
|
|
1096
|
+
displayString && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1097
|
+
"button",
|
|
1098
|
+
{
|
|
1099
|
+
type: "button",
|
|
1100
|
+
onClick: handleClear,
|
|
1101
|
+
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",
|
|
1102
|
+
children: "\u05E0\u05E7\u05D4"
|
|
1103
|
+
}
|
|
1104
|
+
),
|
|
1105
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1106
|
+
"button",
|
|
1107
|
+
{
|
|
1108
|
+
type: "button",
|
|
1109
|
+
onClick: () => setIsOpen(false),
|
|
1110
|
+
className: "p-0.5 text-slate-400 hover:text-slate-600 rounded transition-colors cursor-pointer mr-0.5",
|
|
1111
|
+
title: "\u05E1\u05D2\u05D5\u05E8",
|
|
1112
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.X, { className: "w-3.5 h-3.5" })
|
|
1113
|
+
}
|
|
1114
|
+
)
|
|
1115
|
+
] })
|
|
1116
|
+
] }),
|
|
1117
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center justify-center py-1 mb-2 bg-slate-50 border border-slate-100 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-base font-semibold text-slate-800 tracking-wider", dir: "ltr", children: displayString || "--:--" }) }),
|
|
1118
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
1119
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
1120
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-[11px] font-medium text-slate-400 text-center mb-1", children: "\u05D3\u05E7\u05D5\u05EA" }),
|
|
1121
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1122
|
+
"div",
|
|
1123
|
+
{
|
|
1124
|
+
ref: minutesListRef,
|
|
1125
|
+
className: "h-44 overflow-y-auto border border-slate-100 rounded-lg p-1 space-y-0.5 bg-slate-50/50",
|
|
1126
|
+
children: ALL_MINUTES.map((m) => {
|
|
1127
|
+
const isSelected = selectedMinute === m;
|
|
1128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1129
|
+
"button",
|
|
1130
|
+
{
|
|
1131
|
+
type: "button",
|
|
1132
|
+
"data-selected": isSelected,
|
|
1133
|
+
onClick: () => handleSelectMinute(m),
|
|
1134
|
+
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"}`,
|
|
1135
|
+
children: String(m).padStart(2, "0")
|
|
1136
|
+
},
|
|
1137
|
+
m
|
|
1138
|
+
);
|
|
1139
|
+
})
|
|
1140
|
+
}
|
|
1141
|
+
)
|
|
1142
|
+
] }),
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
1144
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-[11px] font-medium text-slate-400 text-center mb-1", children: "\u05E9\u05E2\u05D5\u05EA" }),
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1146
|
+
"div",
|
|
1147
|
+
{
|
|
1148
|
+
ref: hoursListRef,
|
|
1149
|
+
className: "h-44 overflow-y-auto border border-slate-100 rounded-lg p-1 space-y-0.5 bg-slate-50/50",
|
|
1150
|
+
children: Array.from({ length: 24 }, (_, i) => {
|
|
1151
|
+
const isSelected = selectedHour === i;
|
|
1152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1153
|
+
"button",
|
|
1154
|
+
{
|
|
1155
|
+
type: "button",
|
|
1156
|
+
"data-selected": isSelected,
|
|
1157
|
+
onClick: () => handleSelectHour(i),
|
|
1158
|
+
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"}`,
|
|
1159
|
+
children: String(i).padStart(2, "0")
|
|
1160
|
+
},
|
|
1161
|
+
i
|
|
1162
|
+
);
|
|
1163
|
+
})
|
|
1164
|
+
}
|
|
1165
|
+
)
|
|
1166
|
+
] })
|
|
1167
|
+
] })
|
|
946
1168
|
]
|
|
947
1169
|
}
|
|
948
|
-
)
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1170
|
+
)
|
|
1171
|
+
] });
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// src/components/TableBlock/fields/LinkPickerCell.tsx
|
|
1175
|
+
var import_react6 = require("react");
|
|
1176
|
+
var import_lucide_react5 = require("lucide-react");
|
|
1177
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1178
|
+
function parseLinkValue(val) {
|
|
1179
|
+
if (!val) return { url: "", label: "" };
|
|
1180
|
+
if (typeof val === "string") {
|
|
1181
|
+
return { url: val.trim(), label: "" };
|
|
1182
|
+
}
|
|
1183
|
+
if (typeof val === "object") {
|
|
1184
|
+
return {
|
|
1185
|
+
url: typeof val.url === "string" ? val.url.trim() : "",
|
|
1186
|
+
label: typeof val.label === "string" ? val.label.trim() : ""
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
return { url: "", label: "" };
|
|
1190
|
+
}
|
|
1191
|
+
function resolveProtocol(url) {
|
|
1192
|
+
const trimmed = url.trim();
|
|
1193
|
+
if (!trimmed) return "";
|
|
1194
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
1195
|
+
return trimmed;
|
|
1196
|
+
}
|
|
1197
|
+
return `https://${trimmed}`;
|
|
1198
|
+
}
|
|
1199
|
+
function LinkPickerCell({ value, onChange, readOnly = false }) {
|
|
1200
|
+
const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
|
|
1201
|
+
const containerRef = (0, import_react6.useRef)(null);
|
|
1202
|
+
const urlInputRef = (0, import_react6.useRef)(null);
|
|
1203
|
+
const [popoverPos, setPopoverPos] = (0, import_react6.useState)({ top: 0, right: 0 });
|
|
1204
|
+
const currentLink = parseLinkValue(value);
|
|
1205
|
+
const [draftUrl, setDraftUrl] = (0, import_react6.useState)(currentLink.url);
|
|
1206
|
+
const [draftLabel, setDraftLabel] = (0, import_react6.useState)(currentLink.label);
|
|
1207
|
+
const draftUrlRef = (0, import_react6.useRef)(draftUrl);
|
|
1208
|
+
const draftLabelRef = (0, import_react6.useRef)(draftLabel);
|
|
1209
|
+
(0, import_react6.useEffect)(() => {
|
|
1210
|
+
draftUrlRef.current = draftUrl;
|
|
1211
|
+
}, [draftUrl]);
|
|
1212
|
+
(0, import_react6.useEffect)(() => {
|
|
1213
|
+
draftLabelRef.current = draftLabel;
|
|
1214
|
+
}, [draftLabel]);
|
|
1215
|
+
(0, import_react6.useEffect)(() => {
|
|
1216
|
+
if (!isOpen) {
|
|
1217
|
+
setDraftUrl(currentLink.url);
|
|
1218
|
+
setDraftLabel(currentLink.label);
|
|
960
1219
|
}
|
|
961
|
-
)
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1220
|
+
}, [value, isOpen]);
|
|
1221
|
+
const updatePopoverPosition = (0, import_react6.useCallback)(() => {
|
|
1222
|
+
if (containerRef.current) {
|
|
1223
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
1224
|
+
const right = window.innerWidth - rect.right;
|
|
1225
|
+
const popoverHeight = 220;
|
|
1226
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1227
|
+
if (spaceBelow < popoverHeight && rect.top > popoverHeight) {
|
|
1228
|
+
setPopoverPos({
|
|
1229
|
+
top: Math.max(10, rect.top - popoverHeight - 4),
|
|
1230
|
+
right: Math.max(10, right)
|
|
1231
|
+
});
|
|
1232
|
+
} else {
|
|
1233
|
+
setPopoverPos({
|
|
1234
|
+
top: Math.min(window.innerHeight - popoverHeight - 10, rect.bottom + 4),
|
|
1235
|
+
right: Math.max(10, right)
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}, []);
|
|
1240
|
+
const handleSaveAndClose = (0, import_react6.useCallback)(() => {
|
|
1241
|
+
const rawUrl = draftUrlRef.current.trim();
|
|
1242
|
+
const rawLabel = draftLabelRef.current.trim();
|
|
1243
|
+
if (!rawUrl) {
|
|
1244
|
+
onChange(null);
|
|
1245
|
+
} else {
|
|
1246
|
+
const resolved = resolveProtocol(rawUrl);
|
|
1247
|
+
onChange({
|
|
1248
|
+
url: resolved,
|
|
1249
|
+
label: rawLabel
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
setIsOpen(false);
|
|
1253
|
+
}, [onChange]);
|
|
1254
|
+
const handleOpen = () => {
|
|
1255
|
+
setDraftUrl(currentLink.url);
|
|
1256
|
+
setDraftLabel(currentLink.label);
|
|
1257
|
+
updatePopoverPosition();
|
|
1258
|
+
setIsOpen(true);
|
|
1259
|
+
setTimeout(() => {
|
|
1260
|
+
var _a;
|
|
1261
|
+
(_a = urlInputRef.current) == null ? void 0 : _a.focus();
|
|
1262
|
+
}, 50);
|
|
1263
|
+
};
|
|
1264
|
+
(0, import_react6.useEffect)(() => {
|
|
1265
|
+
if (!isOpen) return;
|
|
1266
|
+
updatePopoverPosition();
|
|
1267
|
+
function handleScrollOrResize() {
|
|
1268
|
+
updatePopoverPosition();
|
|
1269
|
+
}
|
|
1270
|
+
function handleClickOutside(event) {
|
|
1271
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1272
|
+
const popoverEl = document.getElementById("link-picker-popover");
|
|
1273
|
+
if (popoverEl && popoverEl.contains(event.target)) {
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1276
|
+
handleSaveAndClose();
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
window.addEventListener("scroll", handleScrollOrResize, true);
|
|
1280
|
+
window.addEventListener("resize", handleScrollOrResize);
|
|
1281
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1282
|
+
return () => {
|
|
1283
|
+
window.removeEventListener("scroll", handleScrollOrResize, true);
|
|
1284
|
+
window.removeEventListener("resize", handleScrollOrResize);
|
|
1285
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1286
|
+
};
|
|
1287
|
+
}, [isOpen, updatePopoverPosition, handleSaveAndClose]);
|
|
1288
|
+
const handleClear = () => {
|
|
1289
|
+
onChange(null);
|
|
1290
|
+
setDraftUrl("");
|
|
1291
|
+
setDraftLabel("");
|
|
1292
|
+
setIsOpen(false);
|
|
1293
|
+
};
|
|
1294
|
+
if (readOnly) {
|
|
1295
|
+
if (!currentLink.url) {
|
|
1296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "px-2 py-1 flex items-center h-full text-slate-400 text-xs italic", children: "-" });
|
|
1297
|
+
}
|
|
1298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "px-2 py-1 flex items-center h-full w-full", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1299
|
+
"a",
|
|
1300
|
+
{
|
|
1301
|
+
href: currentLink.url,
|
|
1302
|
+
target: "_blank",
|
|
1303
|
+
rel: "noopener noreferrer",
|
|
1304
|
+
className: "text-blue-600 hover:underline truncate text-sm flex items-center gap-1.5",
|
|
1305
|
+
onClick: (e) => e.stopPropagation(),
|
|
1306
|
+
children: [
|
|
1307
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.ExternalLink, { className: "w-3.5 h-3.5 shrink-0 text-blue-500" }),
|
|
1308
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: currentLink.label || currentLink.url })
|
|
1309
|
+
]
|
|
1310
|
+
}
|
|
1311
|
+
) });
|
|
1312
|
+
}
|
|
1313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: containerRef, className: "relative w-full h-full flex items-center justify-between px-2 py-1 group", children: [
|
|
1314
|
+
currentLink.url ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1315
|
+
"a",
|
|
1316
|
+
{
|
|
1317
|
+
href: currentLink.url,
|
|
1318
|
+
target: "_blank",
|
|
1319
|
+
rel: "noopener noreferrer",
|
|
1320
|
+
className: "text-blue-600 hover:underline truncate text-sm flex items-center gap-1.5 flex-1 min-w-0",
|
|
1321
|
+
onClick: (e) => e.stopPropagation(),
|
|
1322
|
+
title: currentLink.url,
|
|
1323
|
+
children: [
|
|
1324
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.ExternalLink, { className: "w-3.5 h-3.5 shrink-0 text-blue-500" }),
|
|
1325
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: currentLink.label || currentLink.url })
|
|
1326
|
+
]
|
|
1327
|
+
}
|
|
1328
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1329
|
+
"span",
|
|
1330
|
+
{
|
|
1331
|
+
className: "text-slate-400 italic text-sm flex-1 cursor-pointer select-none",
|
|
1332
|
+
onClick: handleOpen,
|
|
1333
|
+
children: "\u05E8\u05D9\u05E7"
|
|
1334
|
+
}
|
|
1335
|
+
),
|
|
1336
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1337
|
+
"button",
|
|
1338
|
+
{
|
|
1339
|
+
type: "button",
|
|
1340
|
+
onClick: (e) => {
|
|
1341
|
+
e.stopPropagation();
|
|
1342
|
+
if (isOpen) {
|
|
1343
|
+
handleSaveAndClose();
|
|
1344
|
+
} else {
|
|
1345
|
+
handleOpen();
|
|
1346
|
+
}
|
|
1347
|
+
},
|
|
1348
|
+
className: "p-1 text-slate-400 hover:text-blue-600 hover:bg-slate-100 rounded transition-colors cursor-pointer shrink-0 ml-1",
|
|
1349
|
+
title: "\u05E2\u05E8\u05D9\u05DB\u05EA \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Link2, { className: "w-3.5 h-3.5" })
|
|
1351
|
+
}
|
|
1352
|
+
),
|
|
1353
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1354
|
+
"div",
|
|
1355
|
+
{
|
|
1356
|
+
id: "link-picker-popover",
|
|
1357
|
+
dir: "rtl",
|
|
1358
|
+
style: { top: `${popoverPos.top}px`, right: `${popoverPos.right}px` },
|
|
1359
|
+
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",
|
|
1360
|
+
onClick: (e) => e.stopPropagation(),
|
|
1361
|
+
children: [
|
|
1362
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between pb-2 mb-3 border-b border-slate-100", children: [
|
|
1363
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-1.5 text-xs font-semibold text-slate-700", children: [
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Link2, { className: "w-3.5 h-3.5 text-blue-600" }),
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u05E2\u05E8\u05D9\u05DB\u05EA \u05E7\u05D9\u05E9\u05D5\u05E8" })
|
|
1366
|
+
] }),
|
|
1367
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1368
|
+
"button",
|
|
1369
|
+
{
|
|
1370
|
+
type: "button",
|
|
1371
|
+
onClick: handleSaveAndClose,
|
|
1372
|
+
className: "p-0.5 text-slate-400 hover:text-slate-600 rounded transition-colors cursor-pointer",
|
|
1373
|
+
title: "\u05E1\u05D2\u05D5\u05E8 \u05D5\u05E9\u05DE\u05D5\u05E8",
|
|
1374
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.X, { className: "w-3.5 h-3.5" })
|
|
1375
|
+
}
|
|
1376
|
+
)
|
|
1377
|
+
] }),
|
|
1378
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "space-y-2.5 mb-3.5", children: [
|
|
1379
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
1380
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "block text-xs font-medium text-slate-700 mb-1", children: [
|
|
1381
|
+
"\u05DB\u05EA\u05D5\u05D1\u05EA URL ",
|
|
1382
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-rose-500", children: "*" })
|
|
1383
|
+
] }),
|
|
1384
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1385
|
+
"input",
|
|
1386
|
+
{
|
|
1387
|
+
ref: urlInputRef,
|
|
1388
|
+
type: "text",
|
|
1389
|
+
dir: "ltr",
|
|
1390
|
+
placeholder: "https://...",
|
|
1391
|
+
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",
|
|
1392
|
+
value: draftUrl,
|
|
1393
|
+
onChange: (e) => setDraftUrl(e.target.value),
|
|
1394
|
+
onKeyDown: (e) => {
|
|
1395
|
+
if (e.key === "Enter") {
|
|
1396
|
+
e.preventDefault();
|
|
1397
|
+
handleSaveAndClose();
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
)
|
|
1402
|
+
] }),
|
|
1403
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
1404
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "block text-xs font-medium text-slate-700 mb-1", children: [
|
|
1405
|
+
"\u05D8\u05E7\u05E1\u05D8 \u05DC\u05EA\u05E6\u05D5\u05D2\u05D4 ",
|
|
1406
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-slate-400 font-normal", children: "(\u05D0\u05D5\u05E4\u05E6\u05D9\u05D5\u05E0\u05DC\u05D9)" })
|
|
1407
|
+
] }),
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1409
|
+
"input",
|
|
1410
|
+
{
|
|
1411
|
+
type: "text",
|
|
1412
|
+
placeholder: "\u05E9\u05DD \u05D4\u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1413
|
+
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",
|
|
1414
|
+
value: draftLabel,
|
|
1415
|
+
onChange: (e) => setDraftLabel(e.target.value),
|
|
1416
|
+
onKeyDown: (e) => {
|
|
1417
|
+
if (e.key === "Enter") {
|
|
1418
|
+
e.preventDefault();
|
|
1419
|
+
handleSaveAndClose();
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
)
|
|
1424
|
+
] })
|
|
1425
|
+
] }),
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between pt-2 border-t border-slate-100", children: [
|
|
1427
|
+
currentLink.url ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1428
|
+
"button",
|
|
1429
|
+
{
|
|
1430
|
+
type: "button",
|
|
1431
|
+
onClick: handleClear,
|
|
1432
|
+
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",
|
|
1433
|
+
title: "\u05DE\u05D7\u05E7 \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1434
|
+
children: [
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Trash2, { className: "w-3 h-3" }),
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u05E0\u05E7\u05D4" })
|
|
1437
|
+
]
|
|
1438
|
+
}
|
|
1439
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1441
|
+
"button",
|
|
1442
|
+
{
|
|
1443
|
+
type: "button",
|
|
1444
|
+
onClick: handleSaveAndClose,
|
|
1445
|
+
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",
|
|
1446
|
+
children: [
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Check, { className: "w-3.5 h-3.5" }),
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u05E9\u05DE\u05D5\u05E8" })
|
|
1449
|
+
]
|
|
1450
|
+
}
|
|
1451
|
+
)
|
|
1452
|
+
] })
|
|
1453
|
+
]
|
|
1454
|
+
}
|
|
1455
|
+
)
|
|
1456
|
+
] });
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
// src/components/TableBlock/fields/RelationPickerCell.tsx
|
|
1460
|
+
var import_react7 = require("react");
|
|
1461
|
+
var import_lucide_react6 = require("lucide-react");
|
|
1462
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1463
|
+
function isRawObjectId(str) {
|
|
1464
|
+
if (typeof str !== "string") return false;
|
|
1465
|
+
const trimmed = str.trim();
|
|
1466
|
+
return /^[0-9a-fA-F]{24}$/.test(trimmed) || trimmed.startsWith("temp_");
|
|
1467
|
+
}
|
|
1468
|
+
function normalizeRelationValue(val) {
|
|
1469
|
+
if (val === null || val === void 0 || val === "") return [];
|
|
1470
|
+
if (Array.isArray(val)) {
|
|
1471
|
+
return val.map((item) => {
|
|
1472
|
+
if (typeof item === "string") return item.trim();
|
|
1473
|
+
if (typeof item === "object" && item !== null) {
|
|
1474
|
+
return String(item.id || item._id || item.value || "").trim();
|
|
1475
|
+
}
|
|
1476
|
+
return String(item).trim();
|
|
1477
|
+
}).filter((id) => Boolean(id) && id !== "");
|
|
1478
|
+
}
|
|
1479
|
+
if (typeof val === "string") {
|
|
1480
|
+
const trimmed = val.trim();
|
|
1481
|
+
return trimmed ? [trimmed] : [];
|
|
1482
|
+
}
|
|
1483
|
+
if (typeof val === "object" && val !== null) {
|
|
1484
|
+
const id = String(val.id || val._id || val.value || "").trim();
|
|
1485
|
+
return id ? [id] : [];
|
|
1486
|
+
}
|
|
1487
|
+
return [];
|
|
1488
|
+
}
|
|
1489
|
+
function resolveRelationLabel(opt, column) {
|
|
1490
|
+
var _a;
|
|
1491
|
+
if (!opt) return "";
|
|
1492
|
+
const displayField = (_a = column.config) == null ? void 0 : _a.displayField;
|
|
1493
|
+
if (displayField && opt.data) {
|
|
1494
|
+
const val = opt.data[displayField];
|
|
1495
|
+
if (val !== void 0 && val !== null) {
|
|
1496
|
+
const s = String(val).trim();
|
|
1497
|
+
if (s !== "" && !isRawObjectId(s)) {
|
|
1498
|
+
return s;
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
if (opt.label && typeof opt.label === "string") {
|
|
1503
|
+
const s = opt.label.trim();
|
|
1504
|
+
if (s !== "" && !isRawObjectId(s) && s !== opt.id) {
|
|
1505
|
+
return s;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
if (opt.data) {
|
|
1509
|
+
const defaultLabel = opt.data.name || opt.data.title || opt.data.fullName;
|
|
1510
|
+
if (defaultLabel !== void 0 && defaultLabel !== null) {
|
|
1511
|
+
const s = String(defaultLabel).trim();
|
|
1512
|
+
if (s !== "" && !isRawObjectId(s)) {
|
|
1513
|
+
return s;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
return "";
|
|
1518
|
+
}
|
|
1519
|
+
function RelationPickerCell({
|
|
1520
|
+
value,
|
|
1521
|
+
onChange,
|
|
1522
|
+
column,
|
|
1523
|
+
context,
|
|
1524
|
+
rowId,
|
|
1525
|
+
readOnly = false
|
|
1526
|
+
}) {
|
|
1527
|
+
var _a;
|
|
1528
|
+
const [isOpen, setIsOpen] = (0, import_react7.useState)(false);
|
|
1529
|
+
const [searchQuery, setSearchQuery] = (0, import_react7.useState)("");
|
|
1530
|
+
const containerRef = (0, import_react7.useRef)(null);
|
|
1531
|
+
const searchInputRef = (0, import_react7.useRef)(null);
|
|
1532
|
+
const allowMultiple = Boolean((_a = column.config) == null ? void 0 : _a.allowMultiple);
|
|
1533
|
+
const selectedIds = (0, import_react7.useMemo)(() => normalizeRelationValue(value), [value]);
|
|
1534
|
+
const isStandalone = !context || context.relationOptions === void 0;
|
|
1535
|
+
const optionsLoaded = isStandalone || context.relationOptions[column.name] !== void 0;
|
|
1536
|
+
const rawOptions = (0, import_react7.useMemo)(() => {
|
|
1537
|
+
var _a2;
|
|
1538
|
+
return ((_a2 = context == null ? void 0 : context.relationOptions) == null ? void 0 : _a2[column.name]) || [];
|
|
1539
|
+
}, [context == null ? void 0 : context.relationOptions, column.name]);
|
|
1540
|
+
const processedOptions = (0, import_react7.useMemo)(() => {
|
|
1541
|
+
return rawOptions.map((opt) => {
|
|
1542
|
+
const label = resolveRelationLabel(opt, column);
|
|
1543
|
+
return {
|
|
1544
|
+
id: String(opt.id),
|
|
1545
|
+
_displayLabel: label
|
|
1546
|
+
};
|
|
1547
|
+
}).filter((opt) => opt._displayLabel && opt._displayLabel.trim() !== "" && !isRawObjectId(opt._displayLabel));
|
|
1548
|
+
}, [rawOptions, column]);
|
|
1549
|
+
const getDisplayForId = (0, import_react7.useCallback)((id) => {
|
|
1550
|
+
const found = processedOptions.find((o) => String(o.id) === String(id));
|
|
1551
|
+
if (found && found._displayLabel && !isRawObjectId(found._displayLabel)) {
|
|
1552
|
+
return found._displayLabel;
|
|
1553
|
+
}
|
|
1554
|
+
return "-";
|
|
1555
|
+
}, [processedOptions]);
|
|
1556
|
+
const handleOpen = (e) => {
|
|
1557
|
+
if (readOnly) return;
|
|
1558
|
+
e == null ? void 0 : e.stopPropagation();
|
|
1559
|
+
setIsOpen((prev) => !prev);
|
|
1560
|
+
setSearchQuery("");
|
|
1561
|
+
if (context == null ? void 0 : context.refetchRelation) {
|
|
1562
|
+
context.refetchRelation(column.name);
|
|
1563
|
+
}
|
|
1564
|
+
};
|
|
1565
|
+
(0, import_react7.useEffect)(() => {
|
|
1566
|
+
if (isOpen) {
|
|
1567
|
+
setTimeout(() => {
|
|
1568
|
+
var _a2;
|
|
1569
|
+
(_a2 = searchInputRef.current) == null ? void 0 : _a2.focus();
|
|
1570
|
+
}, 50);
|
|
1571
|
+
}
|
|
1572
|
+
}, [isOpen]);
|
|
1573
|
+
const handleSelectOption = (optId) => {
|
|
1574
|
+
if (!allowMultiple) {
|
|
1575
|
+
onChange([optId]);
|
|
1576
|
+
setIsOpen(false);
|
|
1577
|
+
} else {
|
|
1578
|
+
if (selectedIds.includes(optId)) {
|
|
1579
|
+
onChange(selectedIds.filter((id) => id !== optId));
|
|
1580
|
+
} else {
|
|
1581
|
+
onChange([...selectedIds, optId]);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
const handleRemove = (idToRemove) => {
|
|
1586
|
+
onChange(selectedIds.filter((id) => id !== idToRemove));
|
|
1587
|
+
};
|
|
1588
|
+
const handleClearSingle = (e) => {
|
|
1589
|
+
e.stopPropagation();
|
|
1590
|
+
onChange([]);
|
|
1591
|
+
};
|
|
1592
|
+
(0, import_react7.useEffect)(() => {
|
|
1593
|
+
if (!isOpen) return;
|
|
1594
|
+
function handleClickOutside(event) {
|
|
1595
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1596
|
+
setIsOpen(false);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
function handleKeyDown(event) {
|
|
1600
|
+
if (event.key === "Escape") {
|
|
1601
|
+
setIsOpen(false);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1605
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1606
|
+
return () => {
|
|
1607
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1608
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1609
|
+
};
|
|
1610
|
+
}, [isOpen]);
|
|
1611
|
+
const filteredOptions = (0, import_react7.useMemo)(() => {
|
|
1612
|
+
const query = searchQuery.trim().toLowerCase();
|
|
1613
|
+
if (!query) return processedOptions;
|
|
1614
|
+
return processedOptions.filter((opt) => {
|
|
1615
|
+
return (opt._displayLabel || "").toLowerCase().includes(query);
|
|
1616
|
+
});
|
|
1617
|
+
}, [processedOptions, searchQuery]);
|
|
1618
|
+
if (!optionsLoaded && selectedIds.length > 0) {
|
|
1619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "px-2 py-1 flex items-center h-full w-full", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "inline-block w-16 h-4 bg-slate-100 animate-pulse rounded" }) });
|
|
1620
|
+
}
|
|
1621
|
+
if (readOnly) {
|
|
1622
|
+
if (selectedIds.length === 0) {
|
|
1623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "-" });
|
|
1624
|
+
}
|
|
1625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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) => {
|
|
1626
|
+
const displayText = getDisplayForId(id);
|
|
1627
|
+
if (displayText === "-") {
|
|
1628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-slate-400 text-xs", children: "-" }, id);
|
|
1629
|
+
}
|
|
1630
|
+
const palette = getDeterministicPastelBadge(displayText);
|
|
1631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1632
|
+
"span",
|
|
1633
|
+
{
|
|
1634
|
+
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}`,
|
|
1635
|
+
title: displayText,
|
|
1636
|
+
children: displayText
|
|
1637
|
+
},
|
|
1638
|
+
id
|
|
1639
|
+
);
|
|
1640
|
+
}) });
|
|
1641
|
+
}
|
|
1642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1643
|
+
"div",
|
|
1644
|
+
{
|
|
1645
|
+
ref: containerRef,
|
|
1646
|
+
className: `relative w-full h-full flex items-center justify-between px-1.5 py-1 ${isOpen ? "z-50" : ""}`,
|
|
1647
|
+
dir: "rtl",
|
|
1648
|
+
children: [
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1650
|
+
"div",
|
|
1651
|
+
{
|
|
1652
|
+
className: "flex items-center justify-between w-full h-full overflow-hidden cursor-pointer gap-1",
|
|
1653
|
+
onClick: handleOpen,
|
|
1654
|
+
children: !allowMultiple ? (
|
|
1655
|
+
// Single Select Mode
|
|
1656
|
+
(() => {
|
|
1657
|
+
const singleId = selectedIds[0];
|
|
1658
|
+
const displayText = singleId ? getDisplayForId(singleId) : "";
|
|
1659
|
+
const hasValidSelection = singleId && displayText !== "-" && displayText !== "";
|
|
1660
|
+
if (hasValidSelection) {
|
|
1661
|
+
const palette = getDeterministicPastelBadge(displayText);
|
|
1662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between w-full overflow-hidden", children: [
|
|
1663
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1664
|
+
"span",
|
|
1665
|
+
{
|
|
1666
|
+
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}`,
|
|
1667
|
+
title: displayText,
|
|
1668
|
+
children: [
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: displayText }),
|
|
1670
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1671
|
+
"button",
|
|
1672
|
+
{
|
|
1673
|
+
type: "button",
|
|
1674
|
+
onClick: handleClearSingle,
|
|
1675
|
+
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",
|
|
1676
|
+
title: "\u05E0\u05E7\u05D4",
|
|
1677
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.X, { className: "w-3 h-3" })
|
|
1678
|
+
}
|
|
1679
|
+
)
|
|
1680
|
+
]
|
|
1681
|
+
}
|
|
1682
|
+
),
|
|
1683
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-0 hover:opacity-60 transition-opacity shrink-0 ml-1" })
|
|
1684
|
+
] });
|
|
1685
|
+
}
|
|
1686
|
+
if (singleId && displayText === "-") {
|
|
1687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between w-full text-slate-400 text-xs", children: [
|
|
1688
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "-" }),
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-0 hover:opacity-60 transition-opacity shrink-0 ml-1" })
|
|
1690
|
+
] });
|
|
1691
|
+
}
|
|
1692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between w-full text-slate-400 italic text-xs select-none", children: [
|
|
1693
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u05D1\u05D7\u05E8..." }),
|
|
1694
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-60 shrink-0 ml-1" })
|
|
1695
|
+
] });
|
|
1696
|
+
})()
|
|
1697
|
+
) : (
|
|
1698
|
+
// Multi Select Mode
|
|
1699
|
+
selectedIds.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between w-full text-slate-400 italic text-xs select-none", children: [
|
|
1700
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u05D1\u05D7\u05E8..." }),
|
|
1701
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-60 shrink-0 ml-1" })
|
|
1702
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between w-full overflow-hidden", children: [
|
|
1703
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex flex-wrap items-center gap-1 overflow-hidden max-h-full flex-1 py-0.5", children: selectedIds.map((id) => {
|
|
1704
|
+
const displayText = getDisplayForId(id);
|
|
1705
|
+
if (displayText === "-") {
|
|
1706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-slate-400 text-xs px-1", children: "-" }, id);
|
|
1707
|
+
}
|
|
1708
|
+
const palette = getDeterministicPastelBadge(displayText);
|
|
1709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1710
|
+
"span",
|
|
1711
|
+
{
|
|
1712
|
+
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}`,
|
|
1713
|
+
title: displayText,
|
|
1714
|
+
children: [
|
|
1715
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: displayText }),
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1717
|
+
"button",
|
|
1718
|
+
{
|
|
1719
|
+
type: "button",
|
|
1720
|
+
onClick: (e) => {
|
|
1721
|
+
e.stopPropagation();
|
|
1722
|
+
handleRemove(id);
|
|
1723
|
+
},
|
|
1724
|
+
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",
|
|
1725
|
+
title: "\u05D4\u05E1\u05E8",
|
|
1726
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.X, { className: "w-3 h-3" })
|
|
1727
|
+
}
|
|
1728
|
+
)
|
|
1729
|
+
]
|
|
1730
|
+
},
|
|
1731
|
+
id
|
|
1732
|
+
);
|
|
1733
|
+
}) }),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.ChevronDown, { className: "w-3.5 h-3.5 text-slate-400 opacity-0 hover:opacity-60 transition-opacity shrink-0 ml-1" })
|
|
1735
|
+
] })
|
|
1736
|
+
)
|
|
1737
|
+
}
|
|
1738
|
+
),
|
|
1739
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1740
|
+
"div",
|
|
1741
|
+
{
|
|
1742
|
+
id: `relation-dropdown-${column.name}-${rowId || "cell"}`,
|
|
1743
|
+
dir: "rtl",
|
|
1744
|
+
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",
|
|
1745
|
+
onClick: (e) => e.stopPropagation(),
|
|
1746
|
+
children: [
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative mb-1", children: [
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Search, { className: "w-3.5 h-3.5 text-slate-400 absolute right-2 top-2 pointer-events-none" }),
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1750
|
+
"input",
|
|
1751
|
+
{
|
|
1752
|
+
ref: searchInputRef,
|
|
1753
|
+
type: "text",
|
|
1754
|
+
placeholder: "\u05D7\u05E4\u05E9...",
|
|
1755
|
+
value: searchQuery,
|
|
1756
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
1757
|
+
onKeyDown: (e) => {
|
|
1758
|
+
if (e.key === "Escape") {
|
|
1759
|
+
e.stopPropagation();
|
|
1760
|
+
setIsOpen(false);
|
|
1761
|
+
}
|
|
1762
|
+
},
|
|
1763
|
+
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"
|
|
1764
|
+
}
|
|
1765
|
+
)
|
|
1766
|
+
] }),
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "overflow-y-auto max-h-[180px] space-y-0.5", children: filteredOptions.length > 0 ? filteredOptions.map((opt) => {
|
|
1768
|
+
const isSelected = selectedIds.includes(opt.id);
|
|
1769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1770
|
+
"div",
|
|
1771
|
+
{
|
|
1772
|
+
onClick: () => handleSelectOption(opt.id),
|
|
1773
|
+
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"}`,
|
|
1774
|
+
children: [
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate flex-1", children: opt._displayLabel }),
|
|
1776
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Check, { className: "w-3.5 h-3.5 text-blue-600 shrink-0 mr-1" })
|
|
1777
|
+
]
|
|
1778
|
+
},
|
|
1779
|
+
opt.id
|
|
1780
|
+
);
|
|
1781
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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" }) })
|
|
1782
|
+
]
|
|
1783
|
+
}
|
|
1784
|
+
)
|
|
1785
|
+
]
|
|
1786
|
+
}
|
|
1787
|
+
);
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
// src/components/TableBlock/fields/fieldRegistry.tsx
|
|
1791
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1792
|
+
var CURRENCY_SYMBOLS = {
|
|
1793
|
+
USD: "$",
|
|
1794
|
+
EUR: "\u20AC",
|
|
1795
|
+
ILS: "\u20AA",
|
|
1796
|
+
GBP: "\xA3"
|
|
1797
|
+
};
|
|
1798
|
+
function getCurrencySymbol(code) {
|
|
1799
|
+
if (!code) return "";
|
|
1800
|
+
return CURRENCY_SYMBOLS[code.toUpperCase()] || code;
|
|
1801
|
+
}
|
|
1802
|
+
var FORM_INPUTS = {
|
|
1803
|
+
DATE: ({ value, onChange, column }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DatePickerCell, { value, onChange, column }),
|
|
1804
|
+
CURRENCY: ({ value, column, onChange }) => {
|
|
1805
|
+
var _a;
|
|
1806
|
+
const symbol = getCurrencySymbol((_a = column.config) == null ? void 0 : _a.currencySymbol);
|
|
1807
|
+
const [isFocused, setIsFocused] = import_react8.default.useState(false);
|
|
1808
|
+
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 : "";
|
|
1809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "relative w-full h-full", children: [
|
|
1810
|
+
symbol && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none text-sm", children: symbol }),
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1812
|
+
"input",
|
|
1813
|
+
{
|
|
1814
|
+
type: isFocused ? "number" : "text",
|
|
1815
|
+
step: "any",
|
|
1816
|
+
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`,
|
|
1817
|
+
value: displayValue,
|
|
1818
|
+
onFocus: () => setIsFocused(true),
|
|
1819
|
+
onBlur: () => setIsFocused(false),
|
|
1820
|
+
onChange: (e) => {
|
|
1821
|
+
const val = e.target.value;
|
|
1822
|
+
onChange(val === "" ? null : Number(val));
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
)
|
|
1826
|
+
] });
|
|
1827
|
+
},
|
|
1828
|
+
TIME: ({ value, onChange, column }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TimePickerCell, { value, onChange, column }),
|
|
1829
|
+
LINK: ({ value, onChange, column }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LinkPickerCell, { value, onChange, column }),
|
|
1830
|
+
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex items-center justify-center w-full h-full p-2", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1831
|
+
"input",
|
|
1832
|
+
{
|
|
1833
|
+
type: "checkbox",
|
|
1834
|
+
checked: !!value,
|
|
1835
|
+
onChange: (e) => onChange(e.target.checked),
|
|
1836
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
1837
|
+
}
|
|
1838
|
+
) }),
|
|
1839
|
+
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1840
|
+
DrivePickerCell,
|
|
1841
|
+
{
|
|
1842
|
+
value: value || [],
|
|
1843
|
+
onChange,
|
|
1844
|
+
column,
|
|
1845
|
+
rowId,
|
|
1846
|
+
tableName: context == null ? void 0 : context.tableName,
|
|
1847
|
+
onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
|
|
1848
|
+
context
|
|
1849
|
+
}
|
|
1850
|
+
),
|
|
1851
|
+
RELATION: ({ value, onChange, column, context, rowId }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1852
|
+
RelationPickerCell,
|
|
1853
|
+
{
|
|
1854
|
+
value,
|
|
1855
|
+
onChange,
|
|
1856
|
+
column,
|
|
1857
|
+
context,
|
|
1858
|
+
rowId
|
|
1859
|
+
}
|
|
1860
|
+
),
|
|
1861
|
+
NUMBER: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1862
|
+
"input",
|
|
1863
|
+
{
|
|
1864
|
+
type: "number",
|
|
1865
|
+
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
1866
|
+
value: value !== void 0 && value !== null ? value : "",
|
|
1867
|
+
onChange: (e) => {
|
|
1868
|
+
const val = e.target.value;
|
|
1869
|
+
onChange(val === "" ? null : Number(val));
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
),
|
|
1873
|
+
PHONE: ({ value, onChange, column }) => {
|
|
1874
|
+
var _a;
|
|
1875
|
+
const enableWhatsApp = (_a = column == null ? void 0 : column.config) == null ? void 0 : _a.enableWhatsApp;
|
|
1876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center w-full h-full px-2 gap-1.5 overflow-hidden", children: [
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1878
|
+
"input",
|
|
1879
|
+
{
|
|
969
1880
|
type: "tel",
|
|
970
|
-
className: "w-full h-8 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm flex-1",
|
|
1881
|
+
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",
|
|
971
1882
|
value: value !== void 0 && value !== null ? String(value) : "",
|
|
972
|
-
onChange: (e) => onChange(e.target.value),
|
|
1883
|
+
onChange: (e) => onChange(e.target.value || null),
|
|
973
1884
|
dir: "ltr"
|
|
974
1885
|
}
|
|
975
1886
|
),
|
|
976
|
-
enableWhatsApp && value && /* @__PURE__ */ (0,
|
|
1887
|
+
enableWhatsApp && value && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
977
1888
|
"button",
|
|
978
1889
|
{
|
|
979
1890
|
type: "button",
|
|
@@ -983,16 +1894,16 @@ var FORM_INPUTS = {
|
|
|
983
1894
|
e.stopPropagation();
|
|
984
1895
|
openWhatsAppChat(String(value));
|
|
985
1896
|
},
|
|
986
|
-
children: /* @__PURE__ */ (0,
|
|
1897
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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" }) })
|
|
987
1898
|
}
|
|
988
1899
|
)
|
|
989
1900
|
] });
|
|
990
1901
|
},
|
|
991
1902
|
GOOGLE_CONTACT: ({ value, column, rowId, onChange, context }) => {
|
|
992
|
-
const [isSyncing, setIsSyncing] =
|
|
1903
|
+
const [isSyncing, setIsSyncing] = import_react8.default.useState(false);
|
|
993
1904
|
const { addToast } = useToast();
|
|
994
|
-
const googleClientIdRef =
|
|
995
|
-
const ensureGisScript =
|
|
1905
|
+
const googleClientIdRef = import_react8.default.useRef(null);
|
|
1906
|
+
const ensureGisScript = import_react8.default.useCallback(() => {
|
|
996
1907
|
return new Promise((resolve, reject) => {
|
|
997
1908
|
var _a, _b, _c;
|
|
998
1909
|
if ((_c = (_b = (_a = window.google) == null ? void 0 : _a.accounts) == null ? void 0 : _b.oauth2) == null ? void 0 : _c.initTokenClient) {
|
|
@@ -1021,7 +1932,7 @@ var FORM_INPUTS = {
|
|
|
1021
1932
|
document.head.appendChild(script);
|
|
1022
1933
|
});
|
|
1023
1934
|
}, []);
|
|
1024
|
-
const requestGisToken =
|
|
1935
|
+
const requestGisToken = import_react8.default.useCallback(async (hint) => {
|
|
1025
1936
|
await ensureGisScript();
|
|
1026
1937
|
if (!googleClientIdRef.current && (context == null ? void 0 : context.executeAction)) {
|
|
1027
1938
|
try {
|
|
@@ -1068,19 +1979,27 @@ var FORM_INPUTS = {
|
|
|
1068
1979
|
return { accessToken, email };
|
|
1069
1980
|
}, [ensureGisScript, context]);
|
|
1070
1981
|
const handleSync = async () => {
|
|
1071
|
-
var _a, _b, _c;
|
|
1982
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1072
1983
|
if (!(context == null ? void 0 : context.executeAction)) return;
|
|
1073
1984
|
setIsSyncing(true);
|
|
1074
1985
|
try {
|
|
1075
|
-
const mapping = column.contactMapping || {};
|
|
1986
|
+
const mapping = ((_a = column.config) == null ? void 0 : _a.contactMapping) || {};
|
|
1076
1987
|
const rowData = context.rowData || {};
|
|
1988
|
+
const targetTableMetaId = (context == null ? void 0 : context.tableMetaId) || (context == null ? void 0 : context.tableId);
|
|
1989
|
+
const targetOrgId = context == null ? void 0 : context.orgId;
|
|
1077
1990
|
let hasPhone = false;
|
|
1078
1991
|
if (mapping.phoneCol && rowData[mapping.phoneCol]) hasPhone = true;
|
|
1992
|
+
const activeParentTableId = ((_b = context.parentRecord) == null ? void 0 : _b.tableId) || (context == null ? void 0 : context.parentTableId);
|
|
1079
1993
|
let hasName = false;
|
|
1080
1994
|
if (mapping.nameParts && Array.isArray(mapping.nameParts)) {
|
|
1081
1995
|
for (const part of mapping.nameParts) {
|
|
1082
1996
|
if (part.type === "LOCAL" && rowData[part.columnId]) hasName = true;
|
|
1083
|
-
if (part.type === "PARENT"
|
|
1997
|
+
if (part.type === "PARENT") {
|
|
1998
|
+
if (!activeParentTableId) continue;
|
|
1999
|
+
if (part.parentTableId && part.parentTableId !== activeParentTableId) continue;
|
|
2000
|
+
if ((_d = (_c = context.parentRecord) == null ? void 0 : _c.data) == null ? void 0 : _d[part.columnId]) hasName = true;
|
|
2001
|
+
else if (((_e = context.parentRecord) == null ? void 0 : _e.recordId) || ((_f = context.parentRecord) == null ? void 0 : _f.id)) hasName = true;
|
|
2002
|
+
}
|
|
1084
2003
|
}
|
|
1085
2004
|
}
|
|
1086
2005
|
if (!hasPhone) {
|
|
@@ -1110,6 +2029,10 @@ var FORM_INPUTS = {
|
|
|
1110
2029
|
emailCol: mapping.emailCol,
|
|
1111
2030
|
localRowData: rowData,
|
|
1112
2031
|
parentRecord: context.parentRecord,
|
|
2032
|
+
tableMetaId: targetTableMetaId,
|
|
2033
|
+
tableId: targetTableMetaId,
|
|
2034
|
+
recordId: rowId,
|
|
2035
|
+
orgId: targetOrgId,
|
|
1113
2036
|
accessToken,
|
|
1114
2037
|
userEmail
|
|
1115
2038
|
};
|
|
@@ -1120,10 +2043,12 @@ var FORM_INPUTS = {
|
|
|
1120
2043
|
} else {
|
|
1121
2044
|
onChange(res);
|
|
1122
2045
|
}
|
|
1123
|
-
if (
|
|
2046
|
+
if (targetTableMetaId && !rowId.startsWith("temp_")) {
|
|
1124
2047
|
await context.executeAction("UPDATE_RECORD", {
|
|
1125
|
-
tableId:
|
|
2048
|
+
tableId: targetTableMetaId,
|
|
2049
|
+
tableMetaId: targetTableMetaId,
|
|
1126
2050
|
recordId: rowId,
|
|
2051
|
+
orgId: targetOrgId,
|
|
1127
2052
|
data: { [column.name]: res }
|
|
1128
2053
|
});
|
|
1129
2054
|
}
|
|
@@ -1137,6 +2062,8 @@ var FORM_INPUTS = {
|
|
|
1137
2062
|
};
|
|
1138
2063
|
const handleUnlink = async () => {
|
|
1139
2064
|
let accessToken;
|
|
2065
|
+
const targetTableMetaId = (context == null ? void 0 : context.tableMetaId) || (context == null ? void 0 : context.tableId);
|
|
2066
|
+
const targetOrgId = context == null ? void 0 : context.orgId;
|
|
1140
2067
|
try {
|
|
1141
2068
|
let emailHint = value == null ? void 0 : value.userEmail;
|
|
1142
2069
|
if (!emailHint && (value == null ? void 0 : value.url)) {
|
|
@@ -1154,7 +2081,11 @@ var FORM_INPUTS = {
|
|
|
1154
2081
|
if ((value == null ? void 0 : value.resourceName) && (context == null ? void 0 : context.executeAction)) {
|
|
1155
2082
|
await context.executeAction("DELETE_GOOGLE_CONTACT", {
|
|
1156
2083
|
resourceName: value.resourceName,
|
|
1157
|
-
accessToken
|
|
2084
|
+
accessToken,
|
|
2085
|
+
tableMetaId: targetTableMetaId,
|
|
2086
|
+
tableId: targetTableMetaId,
|
|
2087
|
+
recordId: rowId,
|
|
2088
|
+
orgId: targetOrgId
|
|
1158
2089
|
});
|
|
1159
2090
|
}
|
|
1160
2091
|
if (context == null ? void 0 : context.updateQuietly) {
|
|
@@ -1162,47 +2093,49 @@ var FORM_INPUTS = {
|
|
|
1162
2093
|
} else {
|
|
1163
2094
|
onChange(null);
|
|
1164
2095
|
}
|
|
1165
|
-
if (
|
|
2096
|
+
if (targetTableMetaId && (context == null ? void 0 : context.executeAction) && !rowId.startsWith("temp_")) {
|
|
1166
2097
|
await context.executeAction("UPDATE_RECORD", {
|
|
1167
|
-
tableId:
|
|
2098
|
+
tableId: targetTableMetaId,
|
|
2099
|
+
tableMetaId: targetTableMetaId,
|
|
1168
2100
|
recordId: rowId,
|
|
2101
|
+
orgId: targetOrgId,
|
|
1169
2102
|
data: { [column.name]: null }
|
|
1170
2103
|
});
|
|
1171
2104
|
}
|
|
1172
2105
|
};
|
|
1173
2106
|
if (value && value.synced && value.url) {
|
|
1174
|
-
return /* @__PURE__ */ (0,
|
|
1175
|
-
/* @__PURE__ */ (0,
|
|
1176
|
-
/* @__PURE__ */ (0,
|
|
2107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1.5 h-8 px-2 group whitespace-nowrap overflow-hidden max-w-full", children: [
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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" }),
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1177
2110
|
"button",
|
|
1178
2111
|
{
|
|
1179
2112
|
type: "button",
|
|
1180
2113
|
onClick: handleUnlink,
|
|
1181
2114
|
className: "text-slate-400 hover:text-rose-500 opacity-0 group-hover:opacity-100 transition-opacity p-1 shrink-0",
|
|
1182
2115
|
title: "\u05D1\u05D8\u05DC \u05E1\u05E0\u05DB\u05E8\u05D5\u05DF",
|
|
1183
|
-
children: /* @__PURE__ */ (0,
|
|
2116
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
1184
2117
|
}
|
|
1185
2118
|
)
|
|
1186
2119
|
] });
|
|
1187
2120
|
}
|
|
1188
|
-
return /* @__PURE__ */ (0,
|
|
2121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex items-center h-8 px-2 whitespace-nowrap overflow-hidden max-w-full", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1189
2122
|
"button",
|
|
1190
2123
|
{
|
|
1191
2124
|
type: "button",
|
|
1192
2125
|
onClick: handleSync,
|
|
1193
2126
|
disabled: isSyncing,
|
|
1194
|
-
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",
|
|
2127
|
+
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",
|
|
1195
2128
|
children: [
|
|
1196
|
-
isSyncing ? /* @__PURE__ */ (0,
|
|
1197
|
-
/* @__PURE__ */ (0,
|
|
1198
|
-
/* @__PURE__ */ (0,
|
|
1199
|
-
] }) : /* @__PURE__ */ (0,
|
|
1200
|
-
/* @__PURE__ */ (0,
|
|
2129
|
+
isSyncing ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { className: "w-3.5 h-3.5 animate-spin shrink-0", viewBox: "0 0 24 24", fill: "none", children: [
|
|
2130
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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" })
|
|
2132
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "w-3.5 h-3.5 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 4v16m8-8H4" }) }),
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "whitespace-nowrap truncate", children: "\u05E1\u05E0\u05DB\u05E8\u05DF \u05DC\u05D2\u05D5\u05D2\u05DC" })
|
|
1201
2134
|
]
|
|
1202
2135
|
}
|
|
1203
2136
|
) });
|
|
1204
2137
|
},
|
|
1205
|
-
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ (0,
|
|
2138
|
+
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1206
2139
|
"input",
|
|
1207
2140
|
{
|
|
1208
2141
|
type: "text",
|
|
@@ -1212,14 +2145,14 @@ var FORM_INPUTS = {
|
|
|
1212
2145
|
}
|
|
1213
2146
|
),
|
|
1214
2147
|
SUB_TABLE: ({ value, column }) => {
|
|
1215
|
-
var _a, _b;
|
|
1216
|
-
if (!Array.isArray(value)) return /* @__PURE__ */ (0,
|
|
2148
|
+
var _a, _b, _c;
|
|
2149
|
+
if (!Array.isArray(value)) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
1217
2150
|
const selected = value.filter((e) => e == null ? void 0 : e.isSelected);
|
|
1218
|
-
if (selected.length === 0) return /* @__PURE__ */ (0,
|
|
1219
|
-
const displayFields = column.subTableDisplayFields || [];
|
|
1220
|
-
const isWhatsApp = ((
|
|
1221
|
-
const actionPhoneCol = (
|
|
1222
|
-
return /* @__PURE__ */ (0,
|
|
2151
|
+
if (selected.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
2152
|
+
const displayFields = ((_a = column.config) == null ? void 0 : _a.subTableDisplayFields) || [];
|
|
2153
|
+
const isWhatsApp = ((_b = column.config) == null ? void 0 : _b.actionType) === "WHATSAPP";
|
|
2154
|
+
const actionPhoneCol = (_c = column.config) == null ? void 0 : _c.actionPhoneColumn;
|
|
2155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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) => {
|
|
1223
2156
|
var _a2, _b2;
|
|
1224
2157
|
let label = "";
|
|
1225
2158
|
if (entry._resolvedData) {
|
|
@@ -1235,7 +2168,7 @@ var FORM_INPUTS = {
|
|
|
1235
2168
|
const rawPhone = actionPhoneCol ? (_b2 = entry._resolvedData) == null ? void 0 : _b2[actionPhoneCol] : null;
|
|
1236
2169
|
const phone = rawPhone ? String(rawPhone).trim() : null;
|
|
1237
2170
|
if (phone) {
|
|
1238
|
-
return /* @__PURE__ */ (0,
|
|
2171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1239
2172
|
"button",
|
|
1240
2173
|
{
|
|
1241
2174
|
type: "button",
|
|
@@ -1243,21 +2176,21 @@ var FORM_INPUTS = {
|
|
|
1243
2176
|
e.stopPropagation();
|
|
1244
2177
|
openWhatsAppChat(phone);
|
|
1245
2178
|
},
|
|
1246
|
-
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-
|
|
2179
|
+
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",
|
|
1247
2180
|
title: `\u05E4\u05EA\u05D9\u05D7\u05EA \u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4 (${phone})`,
|
|
1248
2181
|
children: [
|
|
1249
|
-
/* @__PURE__ */ (0,
|
|
1250
|
-
/* @__PURE__ */ (0,
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "w-3 h-3 text-emerald-600 shrink-0", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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" }) }),
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate", children: label })
|
|
1251
2184
|
]
|
|
1252
2185
|
},
|
|
1253
2186
|
entry.recordId || idx
|
|
1254
2187
|
);
|
|
1255
2188
|
}
|
|
1256
2189
|
}
|
|
1257
|
-
return /* @__PURE__ */ (0,
|
|
2190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1258
2191
|
"span",
|
|
1259
2192
|
{
|
|
1260
|
-
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-
|
|
2193
|
+
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",
|
|
1261
2194
|
title: label,
|
|
1262
2195
|
children: label
|
|
1263
2196
|
},
|
|
@@ -1268,7 +2201,8 @@ var FORM_INPUTS = {
|
|
|
1268
2201
|
};
|
|
1269
2202
|
|
|
1270
2203
|
// src/components/TableBlock/fields/SubTableViewer.tsx
|
|
1271
|
-
var
|
|
2204
|
+
var import_react11 = require("react");
|
|
2205
|
+
var import_shared = require("@universe-platform/shared");
|
|
1272
2206
|
|
|
1273
2207
|
// src/utils/phone.ts
|
|
1274
2208
|
function sanitizePhoneNumber(phone) {
|
|
@@ -1284,8 +2218,293 @@ function isValidPhoneNumber(phone) {
|
|
|
1284
2218
|
return /^\+?[0-9]{9,15}$/.test(cleaned);
|
|
1285
2219
|
}
|
|
1286
2220
|
|
|
2221
|
+
// src/components/TableBlock/useColumnResize.ts
|
|
2222
|
+
var import_react9 = require("react");
|
|
2223
|
+
function useColumnResize({
|
|
2224
|
+
storageKey,
|
|
2225
|
+
defaultWidth = 200,
|
|
2226
|
+
minWidth = 60,
|
|
2227
|
+
maxWidth = 500,
|
|
2228
|
+
getMinColWidth
|
|
2229
|
+
}) {
|
|
2230
|
+
const [columnWidths, setColumnWidths] = (0, import_react9.useState)({});
|
|
2231
|
+
const [resizingCol, setResizingCol] = (0, import_react9.useState)(null);
|
|
2232
|
+
(0, import_react9.useEffect)(() => {
|
|
2233
|
+
if (typeof window === "undefined" || !storageKey) return;
|
|
2234
|
+
try {
|
|
2235
|
+
const saved = localStorage.getItem(storageKey);
|
|
2236
|
+
if (saved) {
|
|
2237
|
+
setColumnWidths(JSON.parse(saved));
|
|
2238
|
+
}
|
|
2239
|
+
} catch (e) {
|
|
2240
|
+
console.error(`Failed to load column widths for key "${storageKey}":`, e);
|
|
2241
|
+
}
|
|
2242
|
+
}, [storageKey]);
|
|
2243
|
+
(0, import_react9.useEffect)(() => {
|
|
2244
|
+
if (!resizingCol) return;
|
|
2245
|
+
const handleMouseMove = (e) => {
|
|
2246
|
+
const diffX = resizingCol.startX - e.clientX;
|
|
2247
|
+
const colMin = resizingCol.minWidth || minWidth;
|
|
2248
|
+
const newWidth = Math.max(colMin, Math.min(maxWidth, resizingCol.startWidth + diffX));
|
|
2249
|
+
setColumnWidths((prev) => __spreadProps(__spreadValues({}, prev), { [resizingCol.name]: newWidth }));
|
|
2250
|
+
};
|
|
2251
|
+
const handleMouseUp = () => {
|
|
2252
|
+
setResizingCol(null);
|
|
2253
|
+
setColumnWidths((prev) => {
|
|
2254
|
+
if (typeof window !== "undefined" && storageKey) {
|
|
2255
|
+
try {
|
|
2256
|
+
localStorage.setItem(storageKey, JSON.stringify(prev));
|
|
2257
|
+
} catch (e) {
|
|
2258
|
+
console.error(`Failed to save column widths for key "${storageKey}":`, e);
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
return prev;
|
|
2262
|
+
});
|
|
2263
|
+
};
|
|
2264
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
2265
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
2266
|
+
return () => {
|
|
2267
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
2268
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
2269
|
+
};
|
|
2270
|
+
}, [resizingCol, storageKey, minWidth, maxWidth]);
|
|
2271
|
+
const startResize = (0, import_react9.useCallback)(
|
|
2272
|
+
(colName, currentWidth, clientX, customMinWidth) => {
|
|
2273
|
+
const colMin = customMinWidth != null ? customMinWidth : getMinColWidth ? getMinColWidth(colName) : minWidth;
|
|
2274
|
+
setResizingCol({
|
|
2275
|
+
name: colName,
|
|
2276
|
+
startWidth: currentWidth,
|
|
2277
|
+
startX: clientX,
|
|
2278
|
+
minWidth: colMin
|
|
2279
|
+
});
|
|
2280
|
+
},
|
|
2281
|
+
[getMinColWidth, minWidth]
|
|
2282
|
+
);
|
|
2283
|
+
const getWidth = (0, import_react9.useCallback)(
|
|
2284
|
+
(colName, fallback) => {
|
|
2285
|
+
const colMin = getMinColWidth ? getMinColWidth(colName) : minWidth;
|
|
2286
|
+
const saved = columnWidths[colName] || fallback || defaultWidth;
|
|
2287
|
+
return Math.max(colMin, saved);
|
|
2288
|
+
},
|
|
2289
|
+
[columnWidths, defaultWidth, getMinColWidth, minWidth]
|
|
2290
|
+
);
|
|
2291
|
+
return {
|
|
2292
|
+
columnWidths,
|
|
2293
|
+
setColumnWidths,
|
|
2294
|
+
resizingCol,
|
|
2295
|
+
startResize,
|
|
2296
|
+
getWidth,
|
|
2297
|
+
minWidth
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
// src/components/TableBlock/useColumnReorder.ts
|
|
2302
|
+
var import_react10 = require("react");
|
|
2303
|
+
function useColumnReorder({
|
|
2304
|
+
onReorder,
|
|
2305
|
+
disabled = false
|
|
2306
|
+
}) {
|
|
2307
|
+
const [draggedColName, setDraggedColName] = (0, import_react10.useState)(null);
|
|
2308
|
+
const [dragOverColName, setDragOverColName] = (0, import_react10.useState)(null);
|
|
2309
|
+
const getHeaderDragProps = (0, import_react10.useCallback)(
|
|
2310
|
+
(colName) => {
|
|
2311
|
+
if (disabled) {
|
|
2312
|
+
return {
|
|
2313
|
+
draggable: false
|
|
2314
|
+
};
|
|
2315
|
+
}
|
|
2316
|
+
return {
|
|
2317
|
+
draggable: true,
|
|
2318
|
+
onDragStart: (e) => {
|
|
2319
|
+
e.dataTransfer.setData("text/plain", colName);
|
|
2320
|
+
e.dataTransfer.effectAllowed = "move";
|
|
2321
|
+
setDraggedColName(colName);
|
|
2322
|
+
},
|
|
2323
|
+
onDragOver: (e) => {
|
|
2324
|
+
e.preventDefault();
|
|
2325
|
+
e.dataTransfer.dropEffect = "move";
|
|
2326
|
+
if (dragOverColName !== colName) {
|
|
2327
|
+
setDragOverColName(colName);
|
|
2328
|
+
}
|
|
2329
|
+
},
|
|
2330
|
+
onDragLeave: () => {
|
|
2331
|
+
if (dragOverColName === colName) {
|
|
2332
|
+
setDragOverColName(null);
|
|
2333
|
+
}
|
|
2334
|
+
},
|
|
2335
|
+
onDrop: (e) => {
|
|
2336
|
+
e.preventDefault();
|
|
2337
|
+
if (draggedColName && draggedColName !== colName) {
|
|
2338
|
+
onReorder(draggedColName, colName);
|
|
2339
|
+
}
|
|
2340
|
+
setDraggedColName(null);
|
|
2341
|
+
setDragOverColName(null);
|
|
2342
|
+
},
|
|
2343
|
+
onDragEnd: () => {
|
|
2344
|
+
setDraggedColName(null);
|
|
2345
|
+
setDragOverColName(null);
|
|
2346
|
+
}
|
|
2347
|
+
};
|
|
2348
|
+
},
|
|
2349
|
+
[disabled, draggedColName, dragOverColName, onReorder]
|
|
2350
|
+
);
|
|
2351
|
+
const isDragging = (0, import_react10.useCallback)((colName) => draggedColName === colName, [draggedColName]);
|
|
2352
|
+
const isDragOver = (0, import_react10.useCallback)((colName) => dragOverColName === colName, [dragOverColName]);
|
|
2353
|
+
return {
|
|
2354
|
+
draggedColName,
|
|
2355
|
+
dragOverColName,
|
|
2356
|
+
isDragging,
|
|
2357
|
+
isDragOver,
|
|
2358
|
+
getHeaderDragProps
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// src/components/TableBlock/columnTitleUtils.tsx
|
|
2363
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2364
|
+
var canvas = null;
|
|
2365
|
+
function measureTextWidth(text, font = '600 14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif') {
|
|
2366
|
+
if (typeof document === "undefined") return text.length * 9;
|
|
2367
|
+
if (!canvas) {
|
|
2368
|
+
canvas = document.createElement("canvas");
|
|
2369
|
+
}
|
|
2370
|
+
const ctx = canvas.getContext("2d");
|
|
2371
|
+
if (!ctx) return text.length * 9;
|
|
2372
|
+
ctx.font = font;
|
|
2373
|
+
return ctx.measureText(text).width;
|
|
2374
|
+
}
|
|
2375
|
+
function splitHeaderTitle(name) {
|
|
2376
|
+
if (!name) return { isSingleWord: true, line1: "" };
|
|
2377
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
2378
|
+
if (words.length <= 1) {
|
|
2379
|
+
return { isSingleWord: true, line1: words[0] || "" };
|
|
2380
|
+
}
|
|
2381
|
+
if (words.length === 2) {
|
|
2382
|
+
return { isSingleWord: false, line1: words[0], line2: words[1] };
|
|
2383
|
+
}
|
|
2384
|
+
let bestSplit = 1;
|
|
2385
|
+
let minDiff = Infinity;
|
|
2386
|
+
for (let i = 1; i < words.length; i++) {
|
|
2387
|
+
const l1 = words.slice(0, i).join(" ");
|
|
2388
|
+
const l2 = words.slice(i).join(" ");
|
|
2389
|
+
const diff = Math.abs(l1.length - l2.length);
|
|
2390
|
+
if (diff < minDiff) {
|
|
2391
|
+
minDiff = diff;
|
|
2392
|
+
bestSplit = i;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return {
|
|
2396
|
+
isSingleWord: false,
|
|
2397
|
+
line1: words.slice(0, bestSplit).join(" "),
|
|
2398
|
+
line2: words.slice(bestSplit).join(" ")
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
function calculateMinColumnWidth(name, isSubTable = false, colType) {
|
|
2402
|
+
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';
|
|
2403
|
+
const chromeWidth = isSubTable ? 44 : 52;
|
|
2404
|
+
let baseMin = isSubTable ? 50 : 60;
|
|
2405
|
+
if ((colType == null ? void 0 : colType.toUpperCase()) === "GOOGLE_CONTACT") {
|
|
2406
|
+
baseMin = isSubTable ? 110 : 120;
|
|
2407
|
+
}
|
|
2408
|
+
if (!name) return baseMin;
|
|
2409
|
+
const { isSingleWord, line1, line2 } = splitHeaderTitle(name);
|
|
2410
|
+
if (isSingleWord) {
|
|
2411
|
+
const wordWidth = measureTextWidth(line1, font);
|
|
2412
|
+
return Math.max(baseMin, Math.ceil(wordWidth + chromeWidth));
|
|
2413
|
+
}
|
|
2414
|
+
const w1 = measureTextWidth(line1, font);
|
|
2415
|
+
const w2 = line2 ? measureTextWidth(line2, font) : 0;
|
|
2416
|
+
const maxLine = Math.max(w1, w2);
|
|
2417
|
+
return Math.max(baseMin, Math.ceil(maxLine + chromeWidth));
|
|
2418
|
+
}
|
|
2419
|
+
function ColumnHeaderTitle({ name, width, isSubTable = false }) {
|
|
2420
|
+
const { isSingleWord, line1, line2 } = splitHeaderTitle(name);
|
|
2421
|
+
if (isSingleWord || !line2) {
|
|
2422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children: line1 });
|
|
2423
|
+
}
|
|
2424
|
+
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';
|
|
2425
|
+
const chromeWidth = isSubTable ? 44 : 52;
|
|
2426
|
+
const fullTitleWidth = measureTextWidth(name, font) + chromeWidth;
|
|
2427
|
+
if (width !== void 0 && width >= fullTitleWidth) {
|
|
2428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap select-none overflow-hidden text-right flex-1", title: name, children: name });
|
|
2429
|
+
}
|
|
2430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "flex flex-col justify-center leading-tight select-none overflow-hidden text-right flex-1", title: name, children: [
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap block", children: line1 }),
|
|
2432
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "whitespace-nowrap block", children: line2 })
|
|
2433
|
+
] });
|
|
2434
|
+
}
|
|
2435
|
+
|
|
1287
2436
|
// src/components/TableBlock/fields/SubTableViewer.tsx
|
|
1288
|
-
var
|
|
2437
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2438
|
+
function formatConflictCellValue(rawVal, colDef, relationOptionsMap) {
|
|
2439
|
+
var _a, _b, _c;
|
|
2440
|
+
if (rawVal === void 0 || rawVal === null || rawVal === "") {
|
|
2441
|
+
return "-";
|
|
2442
|
+
}
|
|
2443
|
+
const colType = (_a = colDef == null ? void 0 : colDef.type) == null ? void 0 : _a.toUpperCase();
|
|
2444
|
+
if (typeof rawVal === "boolean" || colType === "BOOLEAN") {
|
|
2445
|
+
return rawVal ? "\u05DB\u05DF" : "\u05DC\u05D0";
|
|
2446
|
+
}
|
|
2447
|
+
if (colType === "GOOGLE_CONTACT" || typeof rawVal === "object" && rawVal !== null && ("resourceName" in rawVal || "synced" in rawVal)) {
|
|
2448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" });
|
|
2449
|
+
}
|
|
2450
|
+
if (colType === "GOOGLE_DRIVE_FILE" || typeof rawVal === "object" && rawVal !== null && ("fileId" in rawVal || "fileUrl" in rawVal || "fileName" in rawVal)) {
|
|
2451
|
+
const fileName = rawVal == null ? void 0 : rawVal.fileName;
|
|
2452
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" });
|
|
2453
|
+
}
|
|
2454
|
+
if (colType === "LINK" || typeof rawVal === "object" && rawVal !== null && ("url" in rawVal || "label" in rawVal)) {
|
|
2455
|
+
const text = (rawVal == null ? void 0 : rawVal.label) || (rawVal == null ? void 0 : rawVal.url);
|
|
2456
|
+
return text ? String(text) : "-";
|
|
2457
|
+
}
|
|
2458
|
+
if (colType === "SUB_TABLE" || Array.isArray(rawVal) && rawVal.length > 0 && typeof rawVal[0] === "object" && ("recordId" in rawVal[0] || "id" in rawVal[0])) {
|
|
2459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("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: [
|
|
2460
|
+
rawVal.length,
|
|
2461
|
+
" \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA"
|
|
2462
|
+
] });
|
|
2463
|
+
}
|
|
2464
|
+
if (colType === "RELATION") {
|
|
2465
|
+
if (Array.isArray(rawVal)) {
|
|
2466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("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: [
|
|
2467
|
+
rawVal.length,
|
|
2468
|
+
" \u05DE\u05E7\u05D5\u05E9\u05E8\u05D9\u05DD"
|
|
2469
|
+
] });
|
|
2470
|
+
}
|
|
2471
|
+
const colOpts = (colDef == null ? void 0 : colDef.name) && relationOptionsMap ? relationOptionsMap[colDef.name] : void 0;
|
|
2472
|
+
if (Array.isArray(colOpts)) {
|
|
2473
|
+
const opt = colOpts.find((o) => String(o.id) === String(rawVal));
|
|
2474
|
+
if (opt) {
|
|
2475
|
+
const displayField = (_b = colDef == null ? void 0 : colDef.config) == null ? void 0 : _b.displayField;
|
|
2476
|
+
const disp = opt._displayLabel || displayField && ((_c = opt.data) == null ? void 0 : _c[displayField]) || (opt.label !== opt.id ? opt.label : "");
|
|
2477
|
+
if (disp && String(disp).trim() !== "" && !/^[a-f\d]{24}$/i.test(String(disp))) {
|
|
2478
|
+
return String(disp);
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
if (typeof rawVal === "object" && rawVal !== null) {
|
|
2483
|
+
const relDisplay = rawVal.title || rawVal.name || rawVal.label;
|
|
2484
|
+
if (relDisplay && !/^[a-f\d]{24}$/i.test(String(relDisplay))) {
|
|
2485
|
+
return String(relDisplay);
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" });
|
|
2489
|
+
}
|
|
2490
|
+
if (Array.isArray(rawVal)) {
|
|
2491
|
+
const allPrimitives = rawVal.every((v) => typeof v !== "object");
|
|
2492
|
+
if (allPrimitives) {
|
|
2493
|
+
return rawVal.join(", ") || "-";
|
|
2494
|
+
}
|
|
2495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("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: [
|
|
2496
|
+
rawVal.length,
|
|
2497
|
+
" \u05E4\u05E8\u05D9\u05D8\u05D9\u05DD"
|
|
2498
|
+
] });
|
|
2499
|
+
}
|
|
2500
|
+
if (typeof rawVal === "object" && rawVal !== null) {
|
|
2501
|
+
return "-";
|
|
2502
|
+
}
|
|
2503
|
+
if ((colDef == null ? void 0 : colDef.type) && !(0, import_shared.isTextRepresentable)(colDef.type)) {
|
|
2504
|
+
return "-";
|
|
2505
|
+
}
|
|
2506
|
+
return String(rawVal);
|
|
2507
|
+
}
|
|
1289
2508
|
function validateCellValue(val, col) {
|
|
1290
2509
|
var _a;
|
|
1291
2510
|
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
@@ -1323,29 +2542,32 @@ function SubTableCell({
|
|
|
1323
2542
|
column,
|
|
1324
2543
|
targetSchema,
|
|
1325
2544
|
referencedTableId,
|
|
2545
|
+
parentRowId,
|
|
1326
2546
|
context,
|
|
1327
2547
|
relationOptions,
|
|
1328
2548
|
setRelationOptions,
|
|
1329
2549
|
refetchRelation,
|
|
1330
|
-
onCommit
|
|
2550
|
+
onCommit,
|
|
2551
|
+
onQuietUpdate,
|
|
2552
|
+
width
|
|
1331
2553
|
}) {
|
|
1332
|
-
var _a, _b;
|
|
2554
|
+
var _a, _b, _c, _d, _e;
|
|
1333
2555
|
const colType = ((_a = column.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
1334
2556
|
const isContact = colType === "GOOGLE_CONTACT";
|
|
1335
2557
|
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
1336
2558
|
const serverValue = (_b = record.data[column.name]) != null ? _b : colType === "BOOLEAN" ? false : "";
|
|
1337
|
-
const [draftValue, setDraftValue] = (0,
|
|
1338
|
-
const [isDirty, setIsDirty] = (0,
|
|
1339
|
-
const [validationError, setValidationError] = (0,
|
|
1340
|
-
const cellRef = (0,
|
|
1341
|
-
const draftRef = (0,
|
|
1342
|
-
const isDirtyRef = (0,
|
|
1343
|
-
const serverValueRef = (0,
|
|
1344
|
-
const recordIdRef = (0,
|
|
1345
|
-
const columnRef = (0,
|
|
1346
|
-
const onCommitRef = (0,
|
|
1347
|
-
const isCommittingRef = (0,
|
|
1348
|
-
const lastFailedValRef = (0,
|
|
2559
|
+
const [draftValue, setDraftValue] = (0, import_react11.useState)(serverValue);
|
|
2560
|
+
const [isDirty, setIsDirty] = (0, import_react11.useState)(false);
|
|
2561
|
+
const [validationError, setValidationError] = (0, import_react11.useState)(null);
|
|
2562
|
+
const cellRef = (0, import_react11.useRef)(null);
|
|
2563
|
+
const draftRef = (0, import_react11.useRef)(draftValue);
|
|
2564
|
+
const isDirtyRef = (0, import_react11.useRef)(isDirty);
|
|
2565
|
+
const serverValueRef = (0, import_react11.useRef)(serverValue);
|
|
2566
|
+
const recordIdRef = (0, import_react11.useRef)(record.id);
|
|
2567
|
+
const columnRef = (0, import_react11.useRef)(column);
|
|
2568
|
+
const onCommitRef = (0, import_react11.useRef)(onCommit);
|
|
2569
|
+
const isCommittingRef = (0, import_react11.useRef)(false);
|
|
2570
|
+
const lastFailedValRef = (0, import_react11.useRef)(void 0);
|
|
1349
2571
|
const { addToast } = useToast();
|
|
1350
2572
|
draftRef.current = draftValue;
|
|
1351
2573
|
isDirtyRef.current = isDirty;
|
|
@@ -1353,7 +2575,7 @@ function SubTableCell({
|
|
|
1353
2575
|
recordIdRef.current = record.id;
|
|
1354
2576
|
columnRef.current = column;
|
|
1355
2577
|
onCommitRef.current = onCommit;
|
|
1356
|
-
(0,
|
|
2578
|
+
(0, import_react11.useEffect)(() => {
|
|
1357
2579
|
if (!isDirtyRef.current) {
|
|
1358
2580
|
setDraftValue(serverValue);
|
|
1359
2581
|
draftRef.current = serverValue;
|
|
@@ -1361,7 +2583,7 @@ function SubTableCell({
|
|
|
1361
2583
|
lastFailedValRef.current = void 0;
|
|
1362
2584
|
}
|
|
1363
2585
|
}, [serverValue]);
|
|
1364
|
-
const commit = (0,
|
|
2586
|
+
const commit = (0, import_react11.useCallback)(async (valToCommit) => {
|
|
1365
2587
|
if (isCommittingRef.current) return false;
|
|
1366
2588
|
if (!isDirtyRef.current) return true;
|
|
1367
2589
|
if (valToCommit === serverValueRef.current) {
|
|
@@ -1402,7 +2624,7 @@ function SubTableCell({
|
|
|
1402
2624
|
isCommittingRef.current = false;
|
|
1403
2625
|
}
|
|
1404
2626
|
}, [addToast]);
|
|
1405
|
-
const discard = (0,
|
|
2627
|
+
const discard = (0, import_react11.useCallback)(() => {
|
|
1406
2628
|
setDraftValue(serverValueRef.current);
|
|
1407
2629
|
draftRef.current = serverValueRef.current;
|
|
1408
2630
|
setIsDirty(false);
|
|
@@ -1410,7 +2632,7 @@ function SubTableCell({
|
|
|
1410
2632
|
setValidationError(null);
|
|
1411
2633
|
lastFailedValRef.current = void 0;
|
|
1412
2634
|
}, []);
|
|
1413
|
-
(0,
|
|
2635
|
+
(0, import_react11.useEffect)(() => {
|
|
1414
2636
|
return () => {
|
|
1415
2637
|
if (isDirtyRef.current && !isCommittingRef.current) {
|
|
1416
2638
|
const val = draftRef.current;
|
|
@@ -1446,7 +2668,7 @@ function SubTableCell({
|
|
|
1446
2668
|
}
|
|
1447
2669
|
};
|
|
1448
2670
|
const handleKeyDown = (e) => {
|
|
1449
|
-
var _a2, _b2,
|
|
2671
|
+
var _a2, _b2, _c2, _d2;
|
|
1450
2672
|
if (e.key === "Enter") {
|
|
1451
2673
|
e.preventDefault();
|
|
1452
2674
|
if (isDirtyRef.current) {
|
|
@@ -1456,18 +2678,22 @@ function SubTableCell({
|
|
|
1456
2678
|
} else if (e.key === "Escape") {
|
|
1457
2679
|
e.preventDefault();
|
|
1458
2680
|
discard();
|
|
1459
|
-
(
|
|
2681
|
+
(_d2 = (_c2 = e.target) == null ? void 0 : _c2.blur) == null ? void 0 : _d2.call(_c2);
|
|
1460
2682
|
}
|
|
1461
2683
|
};
|
|
1462
|
-
|
|
2684
|
+
const subTableMetaId = (targetSchema == null ? void 0 : targetSchema.tableMetaId) || (targetSchema == null ? void 0 : targetSchema.id) || referencedTableId;
|
|
2685
|
+
const parentTableId = (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId);
|
|
2686
|
+
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);
|
|
2687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1463
2688
|
"td",
|
|
1464
2689
|
{
|
|
1465
2690
|
ref: cellRef,
|
|
1466
2691
|
onBlur: handleBlur,
|
|
1467
2692
|
onKeyDown: handleKeyDown,
|
|
1468
2693
|
title: validationError || void 0,
|
|
1469
|
-
|
|
1470
|
-
|
|
2694
|
+
style: width ? { width, minWidth: width, maxWidth: width } : void 0,
|
|
2695
|
+
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" : ""}`,
|
|
2696
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1471
2697
|
InputComponent,
|
|
1472
2698
|
{
|
|
1473
2699
|
value: draftValue,
|
|
@@ -1479,10 +2705,25 @@ function SubTableCell({
|
|
|
1479
2705
|
relationOptions,
|
|
1480
2706
|
updateRelationOptions: (name, opts) => setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [name]: opts })),
|
|
1481
2707
|
refetchRelation,
|
|
1482
|
-
|
|
2708
|
+
parentTableId,
|
|
2709
|
+
parentRecord: {
|
|
2710
|
+
tableId: parentTableId,
|
|
2711
|
+
recordId: effectiveParentRecordId,
|
|
2712
|
+
id: effectiveParentRecordId,
|
|
2713
|
+
data: (context == null ? void 0 : context.rowData) || ((_e = context == null ? void 0 : context.parentRecord) == null ? void 0 : _e.data)
|
|
2714
|
+
},
|
|
1483
2715
|
rowData: record.data,
|
|
1484
|
-
tableId:
|
|
1485
|
-
|
|
2716
|
+
tableId: subTableMetaId,
|
|
2717
|
+
tableMetaId: subTableMetaId,
|
|
2718
|
+
recordId: record.id,
|
|
2719
|
+
orgId: context == null ? void 0 : context.orgId,
|
|
2720
|
+
updateQuietly: (rid, colName, val) => {
|
|
2721
|
+
if (onQuietUpdate) {
|
|
2722
|
+
onQuietUpdate(rid, colName, val);
|
|
2723
|
+
} else {
|
|
2724
|
+
onCommitRef.current(rid, colName, val);
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
1486
2727
|
})
|
|
1487
2728
|
}
|
|
1488
2729
|
)
|
|
@@ -1490,39 +2731,37 @@ function SubTableCell({
|
|
|
1490
2731
|
);
|
|
1491
2732
|
}
|
|
1492
2733
|
function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
1493
|
-
var _a, _b;
|
|
2734
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1494
2735
|
const { addToast } = useToast();
|
|
1495
2736
|
const entries = Array.isArray(value) ? value : [];
|
|
1496
|
-
const [linkedRecords, setLinkedRecords] = (0,
|
|
2737
|
+
const [linkedRecords, setLinkedRecords] = (0, import_react11.useState)(() => {
|
|
1497
2738
|
const initial = [];
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
initial.push({ id: entry.recordId, data: entry._resolvedData });
|
|
1502
|
-
}
|
|
2739
|
+
for (const entry of entries) {
|
|
2740
|
+
if (entry.recordId && entry._resolvedData) {
|
|
2741
|
+
initial.push({ id: entry.recordId, data: entry._resolvedData });
|
|
1503
2742
|
}
|
|
1504
2743
|
}
|
|
1505
2744
|
return initial;
|
|
1506
2745
|
});
|
|
1507
|
-
const [targetSchema, setTargetSchema] = (0,
|
|
1508
|
-
const [isLoading, setIsLoading] = (0,
|
|
1509
|
-
const [isSearchOpen, setIsSearchOpen] = (0,
|
|
1510
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
1511
|
-
const [searchResults, setSearchResults] = (0,
|
|
1512
|
-
const [isSearching, setIsSearching] = (0,
|
|
1513
|
-
const [isCreating, setIsCreating] = (0,
|
|
1514
|
-
const [newRecordData, setNewRecordData] = (0,
|
|
1515
|
-
const [conflictModalState, setConflictModalState] = (0,
|
|
2746
|
+
const [targetSchema, setTargetSchema] = (0, import_react11.useState)(null);
|
|
2747
|
+
const [isLoading, setIsLoading] = (0, import_react11.useState)(true);
|
|
2748
|
+
const [isSearchOpen, setIsSearchOpen] = (0, import_react11.useState)(false);
|
|
2749
|
+
const [searchQuery, setSearchQuery] = (0, import_react11.useState)("");
|
|
2750
|
+
const [searchResults, setSearchResults] = (0, import_react11.useState)([]);
|
|
2751
|
+
const [isSearching, setIsSearching] = (0, import_react11.useState)(false);
|
|
2752
|
+
const [isCreating, setIsCreating] = (0, import_react11.useState)(false);
|
|
2753
|
+
const [newRecordData, setNewRecordData] = (0, import_react11.useState)({});
|
|
2754
|
+
const [conflictModalState, setConflictModalState] = (0, import_react11.useState)({
|
|
1516
2755
|
isOpen: false,
|
|
1517
2756
|
fieldName: "",
|
|
1518
2757
|
matchingRecords: []
|
|
1519
2758
|
});
|
|
1520
|
-
const searchRef = (0,
|
|
1521
|
-
const searchTimerRef = (0,
|
|
2759
|
+
const searchRef = (0, import_react11.useRef)(null);
|
|
2760
|
+
const searchTimerRef = (0, import_react11.useRef)(null);
|
|
1522
2761
|
const executeAction = context == null ? void 0 : context.executeAction;
|
|
1523
|
-
const referencedTableId = column.referencedTableId;
|
|
1524
|
-
const fetchedIdsRef = (0,
|
|
1525
|
-
(0,
|
|
2762
|
+
const referencedTableId = ((_a = column.config) == null ? void 0 : _a.referencedTableId) || column.referencedTableId;
|
|
2763
|
+
const fetchedIdsRef = (0, import_react11.useRef)(/* @__PURE__ */ new Set());
|
|
2764
|
+
(0, import_react11.useEffect)(() => {
|
|
1526
2765
|
if (entries.length > 0) {
|
|
1527
2766
|
setLinkedRecords((prev) => {
|
|
1528
2767
|
const existingIds = new Set(prev.map((r) => r.id));
|
|
@@ -1537,7 +2776,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1537
2776
|
});
|
|
1538
2777
|
}
|
|
1539
2778
|
}, [entries]);
|
|
1540
|
-
(0,
|
|
2779
|
+
(0, import_react11.useEffect)(() => {
|
|
1541
2780
|
if (!referencedTableId || !executeAction) {
|
|
1542
2781
|
setIsLoading(false);
|
|
1543
2782
|
return;
|
|
@@ -1564,7 +2803,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1564
2803
|
recordIdsToFetch.forEach((id) => fetchedIdsRef.current.delete(id));
|
|
1565
2804
|
}).finally(() => setIsLoading(false));
|
|
1566
2805
|
}, [referencedTableId, executeAction, entries, targetSchema]);
|
|
1567
|
-
(0,
|
|
2806
|
+
(0, import_react11.useEffect)(() => {
|
|
1568
2807
|
const handleClick = (e) => {
|
|
1569
2808
|
if (searchRef.current && !searchRef.current.contains(e.target)) {
|
|
1570
2809
|
setIsSearchOpen(false);
|
|
@@ -1573,7 +2812,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1573
2812
|
if (isSearchOpen) document.addEventListener("mousedown", handleClick);
|
|
1574
2813
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
1575
2814
|
}, [isSearchOpen]);
|
|
1576
|
-
const handleSearch = (0,
|
|
2815
|
+
const handleSearch = (0, import_react11.useCallback)((query) => {
|
|
1577
2816
|
setSearchQuery(query);
|
|
1578
2817
|
if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
|
|
1579
2818
|
if (!query.trim()) {
|
|
@@ -1599,24 +2838,79 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1599
2838
|
}
|
|
1600
2839
|
}, 300);
|
|
1601
2840
|
}, [executeAction, referencedTableId, entries]);
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
2841
|
+
const [localColumnOrder, setLocalColumnOrder] = (0, import_react11.useState)(null);
|
|
2842
|
+
(0, import_react11.useEffect)(() => {
|
|
2843
|
+
setLocalColumnOrder(null);
|
|
2844
|
+
}, [column.name, (_b = column.config) == null ? void 0 : _b.subTableColumnOrder]);
|
|
2845
|
+
const rawTargetColumns = (0, import_react11.useMemo)(() => {
|
|
2846
|
+
return ((targetSchema == null ? void 0 : targetSchema.columns) || []).filter(
|
|
2847
|
+
(c) => c.name !== "_id" && c.type !== "SUB_TABLE"
|
|
2848
|
+
);
|
|
2849
|
+
}, [targetSchema == null ? void 0 : targetSchema.columns]);
|
|
2850
|
+
const targetColumns = (0, import_react11.useMemo)(() => {
|
|
2851
|
+
var _a2;
|
|
2852
|
+
const activeOrder = localColumnOrder || ((_a2 = column.config) == null ? void 0 : _a2.subTableColumnOrder);
|
|
2853
|
+
if (!activeOrder || !Array.isArray(activeOrder) || activeOrder.length === 0) {
|
|
2854
|
+
return rawTargetColumns;
|
|
1606
2855
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
2856
|
+
const sorted = [...rawTargetColumns];
|
|
2857
|
+
sorted.sort((a, b) => {
|
|
2858
|
+
const idxA = activeOrder.indexOf(a.name);
|
|
2859
|
+
const idxB = activeOrder.indexOf(b.name);
|
|
2860
|
+
if (idxA === -1 && idxB === -1) return 0;
|
|
2861
|
+
if (idxA === -1) return 1;
|
|
2862
|
+
if (idxB === -1) return -1;
|
|
2863
|
+
return idxA - idxB;
|
|
2864
|
+
});
|
|
2865
|
+
return sorted;
|
|
2866
|
+
}, [rawTargetColumns, localColumnOrder, (_c = column.config) == null ? void 0 : _c.subTableColumnOrder]);
|
|
2867
|
+
const handleSubTableColumnReorder = async (draggedName, dropTargetName) => {
|
|
2868
|
+
if (draggedName === dropTargetName) return;
|
|
2869
|
+
const currentNames = targetColumns.map((c) => c.name);
|
|
2870
|
+
const fromIdx = currentNames.indexOf(draggedName);
|
|
2871
|
+
const toIdx = currentNames.indexOf(dropTargetName);
|
|
2872
|
+
if (fromIdx === -1 || toIdx === -1 || fromIdx === toIdx) return;
|
|
2873
|
+
const newOrder = [...currentNames];
|
|
2874
|
+
const [moved] = newOrder.splice(fromIdx, 1);
|
|
2875
|
+
newOrder.splice(toIdx, 0, moved);
|
|
2876
|
+
setLocalColumnOrder(newOrder);
|
|
2877
|
+
if (context == null ? void 0 : context.onUpdateColumnConfig) {
|
|
2878
|
+
try {
|
|
2879
|
+
await context.onUpdateColumnConfig(column.name, {
|
|
2880
|
+
subTableColumnOrder: newOrder
|
|
2881
|
+
});
|
|
2882
|
+
} catch (err) {
|
|
2883
|
+
console.error("[SubTableViewer] Failed to save sub-table column order:", err);
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
};
|
|
2887
|
+
const { draggedColName, dragOverColName, getHeaderDragProps } = useColumnReorder({
|
|
2888
|
+
onReorder: handleSubTableColumnReorder,
|
|
2889
|
+
disabled: isLoading
|
|
2890
|
+
});
|
|
2891
|
+
const targetTableId = (targetSchema == null ? void 0 : targetSchema.tableMetaId) || (targetSchema == null ? void 0 : targetSchema.id) || referencedTableId || column.name;
|
|
2892
|
+
const { columnWidths, startResize } = useColumnResize({
|
|
2893
|
+
storageKey: `table_sub_${targetTableId}_widths`,
|
|
2894
|
+
minWidth: 60,
|
|
2895
|
+
defaultWidth: 150,
|
|
2896
|
+
getMinColWidth: (colName) => {
|
|
2897
|
+
const col = targetColumns.find((c) => c.name === colName);
|
|
2898
|
+
return calculateMinColumnWidth(colName, true, col == null ? void 0 : col.type);
|
|
2899
|
+
}
|
|
2900
|
+
});
|
|
2901
|
+
const [relationOptions, setRelationOptions] = (0, import_react11.useState)({});
|
|
2902
|
+
(0, import_react11.useEffect)(() => {
|
|
2903
|
+
if (!executeAction || !(targetSchema == null ? void 0 : targetSchema.columns) || targetSchema.columns.length === 0) return;
|
|
2904
|
+
const relationCols = targetSchema.columns.filter((c) => {
|
|
2905
|
+
var _a2, _b2;
|
|
2906
|
+
return ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION" && ((_b2 = c.config) == null ? void 0 : _b2.referencedTableId);
|
|
1614
2907
|
});
|
|
1615
2908
|
relationCols.forEach(async (col) => {
|
|
2909
|
+
var _a2, _b2;
|
|
1616
2910
|
try {
|
|
1617
2911
|
const options = await executeAction("FETCH_RELATION", {
|
|
1618
|
-
referencedTableId: col.referencedTableId,
|
|
1619
|
-
displayField: col.displayField
|
|
2912
|
+
referencedTableId: (_a2 = col.config) == null ? void 0 : _a2.referencedTableId,
|
|
2913
|
+
displayField: (_b2 = col.config) == null ? void 0 : _b2.displayField
|
|
1620
2914
|
});
|
|
1621
2915
|
if (options && Array.isArray(options)) {
|
|
1622
2916
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
@@ -1626,12 +2920,12 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1626
2920
|
}
|
|
1627
2921
|
});
|
|
1628
2922
|
}, [executeAction, targetColumns]);
|
|
1629
|
-
const refetchRelation = (0,
|
|
1630
|
-
var _a2;
|
|
2923
|
+
const refetchRelation = (0, import_react11.useCallback)(async (colName) => {
|
|
2924
|
+
var _a2, _b2, _c2;
|
|
1631
2925
|
const col = targetColumns.find((c) => c.name === colName);
|
|
1632
|
-
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !col.referencedTableId || !executeAction) return;
|
|
2926
|
+
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !((_b2 = col.config) == null ? void 0 : _b2.referencedTableId) || !executeAction) return;
|
|
1633
2927
|
try {
|
|
1634
|
-
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
|
|
2928
|
+
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.config.referencedTableId, displayField: (_c2 = col.config) == null ? void 0 : _c2.displayField });
|
|
1635
2929
|
if (options && Array.isArray(options)) {
|
|
1636
2930
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
1637
2931
|
}
|
|
@@ -1770,8 +3064,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1770
3064
|
);
|
|
1771
3065
|
updateParentLinkage(updated);
|
|
1772
3066
|
};
|
|
1773
|
-
const isMountedRef = (0,
|
|
1774
|
-
(0,
|
|
3067
|
+
const isMountedRef = (0, import_react11.useRef)(true);
|
|
3068
|
+
(0, import_react11.useEffect)(() => {
|
|
1775
3069
|
isMountedRef.current = true;
|
|
1776
3070
|
return () => {
|
|
1777
3071
|
isMountedRef.current = false;
|
|
@@ -1795,7 +3089,9 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1795
3089
|
try {
|
|
1796
3090
|
const res = await executeAction("UPDATE_RECORD", {
|
|
1797
3091
|
tableId: referencedTableId,
|
|
3092
|
+
tableMetaId: referencedTableId,
|
|
1798
3093
|
recordId,
|
|
3094
|
+
orgId: context == null ? void 0 : context.orgId,
|
|
1799
3095
|
data: { [colName]: value2 }
|
|
1800
3096
|
});
|
|
1801
3097
|
if (res && res.success === false) {
|
|
@@ -1856,8 +3152,21 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1856
3152
|
}
|
|
1857
3153
|
};
|
|
1858
3154
|
const handleRecordCellChange = handleCommitRecordCell;
|
|
3155
|
+
const handleQuietSubTableCellChange = (0, import_react11.useCallback)((recordId, colName, value2) => {
|
|
3156
|
+
setLinkedRecords(
|
|
3157
|
+
(prev) => prev.map((r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r)
|
|
3158
|
+
);
|
|
3159
|
+
const updatedEntries = entries.map(
|
|
3160
|
+
(e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { _resolvedData: __spreadProps(__spreadValues({}, e._resolvedData || {}), { [colName]: value2 }) }) : e
|
|
3161
|
+
);
|
|
3162
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
3163
|
+
context.updateQuietly(rowId, column.name, updatedEntries);
|
|
3164
|
+
} else {
|
|
3165
|
+
onChange(updatedEntries);
|
|
3166
|
+
}
|
|
3167
|
+
}, [entries, context, rowId, column.name, onChange]);
|
|
1859
3168
|
const handleCreateRecord = async () => {
|
|
1860
|
-
var _a2, _b2,
|
|
3169
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
1861
3170
|
if (!executeAction || !referencedTableId) return;
|
|
1862
3171
|
for (const col of targetColumns) {
|
|
1863
3172
|
if (col.isRequired) {
|
|
@@ -1884,6 +3193,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1884
3193
|
try {
|
|
1885
3194
|
const res = await executeAction("CREATE_RECORD", {
|
|
1886
3195
|
tableId: referencedTableId,
|
|
3196
|
+
tableMetaId: referencedTableId,
|
|
3197
|
+
orgId: context == null ? void 0 : context.orgId,
|
|
1887
3198
|
records: [newRecordData]
|
|
1888
3199
|
});
|
|
1889
3200
|
if (res && (res.error === "UNIQUE_CONSTRAINT_CONFLICT" || res.code === "UNIQUE_CONSTRAINT_CONFLICT")) {
|
|
@@ -1904,9 +3215,9 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1904
3215
|
setNewRecordData({});
|
|
1905
3216
|
}
|
|
1906
3217
|
} catch (err) {
|
|
1907
|
-
const isConflict = (err == null ? void 0 : err.error) === "UNIQUE_CONSTRAINT_CONFLICT" || (err == null ? void 0 : err.code) === "UNIQUE_CONSTRAINT_CONFLICT" || ((
|
|
3218
|
+
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"));
|
|
1908
3219
|
if (isConflict) {
|
|
1909
|
-
const conflictPayload = (err == null ? void 0 : err.error) === "UNIQUE_CONSTRAINT_CONFLICT" ? err : ((
|
|
3220
|
+
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;
|
|
1910
3221
|
handleUniqueConflict(conflictPayload);
|
|
1911
3222
|
return;
|
|
1912
3223
|
}
|
|
@@ -1918,32 +3229,33 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1918
3229
|
}
|
|
1919
3230
|
};
|
|
1920
3231
|
const getDisplayLabel = (record) => {
|
|
1921
|
-
|
|
3232
|
+
var _a2;
|
|
3233
|
+
const fields = ((_a2 = column.config) == null ? void 0 : _a2.subTableDisplayFields) || [];
|
|
1922
3234
|
if (fields.length === 0) {
|
|
1923
3235
|
const firstField = Object.keys(record.data).find((k) => k !== "_id");
|
|
1924
3236
|
return firstField ? String(record.data[firstField] || "") : record.id;
|
|
1925
3237
|
}
|
|
1926
3238
|
return fields.map((f) => String(record.data[f] || "")).filter(Boolean).join(" ");
|
|
1927
3239
|
};
|
|
1928
|
-
return /* @__PURE__ */ (0,
|
|
1929
|
-
/* @__PURE__ */ (0,
|
|
1930
|
-
/* @__PURE__ */ (0,
|
|
1931
|
-
/* @__PURE__ */ (0,
|
|
1932
|
-
/* @__PURE__ */ (0,
|
|
1933
|
-
/* @__PURE__ */ (0,
|
|
3240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "p-3 animate-in fade-in slide-in-from-top-2 duration-200", dir: "rtl", children: [
|
|
3241
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-4 mb-2.5", children: [
|
|
3242
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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 }) }),
|
|
3243
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
3244
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative", ref: searchRef, children: [
|
|
3245
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1934
3246
|
"button",
|
|
1935
3247
|
{
|
|
1936
3248
|
type: "button",
|
|
1937
3249
|
onClick: () => setIsSearchOpen((prev) => !prev),
|
|
1938
3250
|
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",
|
|
1939
3251
|
children: [
|
|
1940
|
-
/* @__PURE__ */ (0,
|
|
3252
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
|
|
1941
3253
|
"\u05E7\u05D9\u05E9\u05D5\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA"
|
|
1942
3254
|
]
|
|
1943
3255
|
}
|
|
1944
3256
|
),
|
|
1945
|
-
isSearchOpen && /* @__PURE__ */ (0,
|
|
1946
|
-
/* @__PURE__ */ (0,
|
|
3257
|
+
isSearchOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("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: [
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1947
3259
|
"input",
|
|
1948
3260
|
{
|
|
1949
3261
|
type: "text",
|
|
@@ -1954,7 +3266,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1954
3266
|
autoFocus: true
|
|
1955
3267
|
}
|
|
1956
3268
|
),
|
|
1957
|
-
/* @__PURE__ */ (0,
|
|
3269
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "max-h-48 overflow-y-auto", children: isSearching ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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__ */ (0, import_jsx_runtime9.jsx)(
|
|
1958
3270
|
"button",
|
|
1959
3271
|
{
|
|
1960
3272
|
type: "button",
|
|
@@ -1963,10 +3275,10 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1963
3275
|
children: getDisplayLabel(r)
|
|
1964
3276
|
},
|
|
1965
3277
|
r.id
|
|
1966
|
-
)) : searchQuery.trim() ? /* @__PURE__ */ (0,
|
|
3278
|
+
)) : searchQuery.trim() ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-xs text-slate-400 text-center py-3", children: "\u05D4\u05E7\u05DC\u05D3 \u05DC\u05D7\u05D9\u05E4\u05D5\u05E9..." }) })
|
|
1967
3279
|
] })
|
|
1968
3280
|
] }),
|
|
1969
|
-
/* @__PURE__ */ (0,
|
|
3281
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1970
3282
|
"button",
|
|
1971
3283
|
{
|
|
1972
3284
|
type: "button",
|
|
@@ -1986,36 +3298,69 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
1986
3298
|
},
|
|
1987
3299
|
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",
|
|
1988
3300
|
children: [
|
|
1989
|
-
/* @__PURE__ */ (0,
|
|
3301
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) }),
|
|
1990
3302
|
"\u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4"
|
|
1991
3303
|
]
|
|
1992
3304
|
}
|
|
1993
3305
|
)
|
|
1994
3306
|
] })
|
|
1995
3307
|
] }),
|
|
1996
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
1997
|
-
/* @__PURE__ */ (0,
|
|
1998
|
-
/* @__PURE__ */ (0,
|
|
3308
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "w-5 h-5 border-2 border-blue-400 border-t-transparent rounded-full animate-spin" }) }) : entries.length === 0 && !isCreating ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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__ */ (0, import_jsx_runtime9.jsx)("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: "w-full text-xs border-collapse table-auto", children: [
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("tr", { className: "bg-slate-100/80 h-12 min-h-[48px]", children: [
|
|
3310
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" }),
|
|
1999
3311
|
targetColumns.map((col) => {
|
|
2000
|
-
|
|
2001
|
-
const
|
|
2002
|
-
|
|
3312
|
+
const dragProps = getHeaderDragProps(col.name);
|
|
3313
|
+
const isDragging = draggedColName === col.name;
|
|
3314
|
+
const isDragOver = dragOverColName === col.name;
|
|
3315
|
+
const colMinWidth = calculateMinColumnWidth(col.name, true, col.type);
|
|
3316
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 150);
|
|
3317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2003
3318
|
"th",
|
|
2004
|
-
{
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
},
|
|
3319
|
+
__spreadProps(__spreadValues({
|
|
3320
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3321
|
+
title: col.name
|
|
3322
|
+
}, dragProps), {
|
|
3323
|
+
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"}`,
|
|
3324
|
+
children: [
|
|
3325
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3326
|
+
"div",
|
|
3327
|
+
{
|
|
3328
|
+
onMouseDown: (e) => {
|
|
3329
|
+
e.preventDefault();
|
|
3330
|
+
e.stopPropagation();
|
|
3331
|
+
startResize(col.name, currentWidth, e.clientX, colMinWidth);
|
|
3332
|
+
},
|
|
3333
|
+
className: "absolute left-0 top-0 bottom-0 w-1.5 cursor-col-resize hover:bg-brand active:bg-brand-hover z-20",
|
|
3334
|
+
title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
|
|
3335
|
+
}
|
|
3336
|
+
),
|
|
3337
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between gap-1.5 group overflow-hidden w-full", title: col.name, children: [
|
|
3338
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ColumnHeaderTitle, { name: col.name, width: currentWidth, isSubTable: true }),
|
|
3339
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3340
|
+
"svg",
|
|
3341
|
+
{
|
|
3342
|
+
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
3343
|
+
fill: "none",
|
|
3344
|
+
viewBox: "0 0 24 24",
|
|
3345
|
+
stroke: "currentColor",
|
|
3346
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
|
|
3347
|
+
}
|
|
3348
|
+
)
|
|
3349
|
+
] })
|
|
3350
|
+
]
|
|
3351
|
+
}),
|
|
2008
3352
|
col.name
|
|
2009
3353
|
);
|
|
2010
3354
|
}),
|
|
2011
|
-
/* @__PURE__ */ (0,
|
|
3355
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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 } }),
|
|
3356
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("th", { className: "w-full min-w-[50px] border border-slate-200 pointer-events-none h-12 min-h-[48px]" })
|
|
2012
3357
|
] }) }),
|
|
2013
|
-
/* @__PURE__ */ (0,
|
|
3358
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("tbody", { children: [
|
|
2014
3359
|
entries.map((entry) => {
|
|
2015
3360
|
var _a2;
|
|
2016
3361
|
const record = linkedRecords.find((r) => r.id === entry.recordId);
|
|
2017
|
-
return /* @__PURE__ */ (0,
|
|
2018
|
-
/* @__PURE__ */ (0,
|
|
3362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("tr", { className: "hover:bg-blue-50/30 transition-colors", children: [
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "border border-slate-200 px-2 py-1 text-center", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2019
3364
|
"input",
|
|
2020
3365
|
{
|
|
2021
3366
|
type: "checkbox",
|
|
@@ -2025,41 +3370,44 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2025
3370
|
}
|
|
2026
3371
|
) }),
|
|
2027
3372
|
targetColumns.map((col) => {
|
|
2028
|
-
|
|
2029
|
-
const isContact = ((_a3 = col.type) == null ? void 0 : _a3.toUpperCase()) === "GOOGLE_CONTACT";
|
|
3373
|
+
const currentWidth = columnWidths[col.name] || 150;
|
|
2030
3374
|
if (!record) {
|
|
2031
|
-
return /* @__PURE__ */ (0,
|
|
3375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2032
3376
|
"td",
|
|
2033
3377
|
{
|
|
2034
|
-
|
|
2035
|
-
|
|
3378
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3379
|
+
className: "border border-slate-200 p-0 relative h-8 overflow-hidden",
|
|
3380
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-slate-300 italic px-2", children: "\u05D8\u05D5\u05E2\u05DF..." })
|
|
2036
3381
|
},
|
|
2037
3382
|
col.name
|
|
2038
3383
|
);
|
|
2039
3384
|
}
|
|
2040
|
-
return /* @__PURE__ */ (0,
|
|
3385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2041
3386
|
SubTableCell,
|
|
2042
3387
|
{
|
|
2043
3388
|
record,
|
|
2044
3389
|
column: col,
|
|
2045
3390
|
targetSchema,
|
|
2046
3391
|
referencedTableId,
|
|
3392
|
+
parentRowId: rowId,
|
|
2047
3393
|
context,
|
|
2048
3394
|
relationOptions,
|
|
2049
3395
|
setRelationOptions,
|
|
2050
3396
|
refetchRelation,
|
|
2051
|
-
onCommit: handleCommitRecordCell
|
|
3397
|
+
onCommit: handleCommitRecordCell,
|
|
3398
|
+
onQuietUpdate: handleQuietSubTableCellChange,
|
|
3399
|
+
width: currentWidth
|
|
2052
3400
|
},
|
|
2053
3401
|
`${record.id}_${col.name}`
|
|
2054
3402
|
);
|
|
2055
3403
|
}),
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
3404
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "border border-slate-200 px-1 py-1 text-center", style: { width: 56, minWidth: 56, maxWidth: 56 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
|
|
2057
3405
|
((_a2 = column.config) == null ? void 0 : _a2.actionType) === "WHATSAPP" && (() => {
|
|
2058
|
-
var _a3, _b2,
|
|
3406
|
+
var _a3, _b2, _c2;
|
|
2059
3407
|
const actionPhoneCol = (_a3 = column.config) == null ? void 0 : _a3.actionPhoneColumn;
|
|
2060
|
-
const phone = actionPhoneCol ? ((_b2 = record == null ? void 0 : record.data) == null ? void 0 : _b2[actionPhoneCol]) || ((
|
|
3408
|
+
const phone = actionPhoneCol ? ((_b2 = record == null ? void 0 : record.data) == null ? void 0 : _b2[actionPhoneCol]) || ((_c2 = entry._resolvedData) == null ? void 0 : _c2[actionPhoneCol]) : null;
|
|
2061
3409
|
if (phone) {
|
|
2062
|
-
return /* @__PURE__ */ (0,
|
|
3410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2063
3411
|
"button",
|
|
2064
3412
|
{
|
|
2065
3413
|
type: "button",
|
|
@@ -2069,13 +3417,13 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2069
3417
|
},
|
|
2070
3418
|
className: "text-emerald-500 hover:text-emerald-600 p-0.5 rounded hover:bg-emerald-50 transition-colors cursor-pointer",
|
|
2071
3419
|
title: `\u05E4\u05EA\u05D9\u05D7\u05EA \u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4 (${phone})`,
|
|
2072
|
-
children: /* @__PURE__ */ (0,
|
|
3420
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-3.5 h-3.5", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" }) })
|
|
2073
3421
|
}
|
|
2074
3422
|
);
|
|
2075
3423
|
}
|
|
2076
3424
|
return null;
|
|
2077
3425
|
})(),
|
|
2078
|
-
/* @__PURE__ */ (0,
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2079
3427
|
"button",
|
|
2080
3428
|
{
|
|
2081
3429
|
type: "button",
|
|
@@ -2085,27 +3433,30 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2085
3433
|
},
|
|
2086
3434
|
className: "text-slate-400 hover:text-rose-500 p-0.5 rounded transition-colors cursor-pointer inline-flex items-center justify-center",
|
|
2087
3435
|
title: "\u05D4\u05E1\u05E8 \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
2088
|
-
children: /* @__PURE__ */ (0,
|
|
3436
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
2089
3437
|
}
|
|
2090
3438
|
)
|
|
2091
|
-
] }) })
|
|
3439
|
+
] }) }),
|
|
3440
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "border border-slate-200 bg-white pointer-events-none" })
|
|
2092
3441
|
] }, entry.recordId);
|
|
2093
3442
|
}),
|
|
2094
|
-
isCreating && /* @__PURE__ */ (0,
|
|
2095
|
-
/* @__PURE__ */ (0,
|
|
3443
|
+
isCreating && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("tr", { className: "bg-emerald-50/40", children: [
|
|
3444
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "border border-emerald-200 px-2 py-1 text-center", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-emerald-500 font-bold text-[10px]", children: "\u05D7\u05D3\u05E9" }) }),
|
|
2096
3445
|
targetColumns.map((col) => {
|
|
2097
|
-
var _a2, _b2;
|
|
3446
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
2098
3447
|
const colType = ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) || "DEFAULT";
|
|
2099
3448
|
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
2100
|
-
const
|
|
2101
|
-
|
|
3449
|
+
const currentWidth = columnWidths[col.name] || 150;
|
|
3450
|
+
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);
|
|
3451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2102
3452
|
"td",
|
|
2103
3453
|
{
|
|
2104
|
-
|
|
2105
|
-
|
|
3454
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3455
|
+
className: `border border-emerald-200 p-0 relative h-8 ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
3456
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2106
3457
|
InputComponent,
|
|
2107
3458
|
{
|
|
2108
|
-
value: (
|
|
3459
|
+
value: (_d2 = newRecordData[col.name]) != null ? _d2 : colType === "BOOLEAN" ? false : "",
|
|
2109
3460
|
column: col,
|
|
2110
3461
|
rowId: "new_record",
|
|
2111
3462
|
onChange: (v) => setNewRecordData((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: v })),
|
|
@@ -2113,7 +3464,16 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2113
3464
|
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",
|
|
2114
3465
|
relationOptions,
|
|
2115
3466
|
refetchRelation,
|
|
2116
|
-
|
|
3467
|
+
parentTableId: (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId),
|
|
3468
|
+
parentRecord: {
|
|
3469
|
+
tableId: (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId),
|
|
3470
|
+
recordId: effectiveParentId,
|
|
3471
|
+
id: effectiveParentId,
|
|
3472
|
+
data: (context == null ? void 0 : context.rowData) || ((_e2 = context == null ? void 0 : context.parentRecord) == null ? void 0 : _e2.data)
|
|
3473
|
+
},
|
|
3474
|
+
tableId: targetTableId,
|
|
3475
|
+
tableMetaId: targetTableId,
|
|
3476
|
+
orgId: context == null ? void 0 : context.orgId
|
|
2117
3477
|
})
|
|
2118
3478
|
}
|
|
2119
3479
|
)
|
|
@@ -2121,18 +3481,18 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2121
3481
|
`new_${col.name}`
|
|
2122
3482
|
);
|
|
2123
3483
|
}),
|
|
2124
|
-
/* @__PURE__ */ (0,
|
|
2125
|
-
/* @__PURE__ */ (0,
|
|
3484
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "border border-emerald-200 px-1 py-1 text-center", style: { width: 56, minWidth: 56, maxWidth: 56 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
|
|
3485
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2126
3486
|
"button",
|
|
2127
3487
|
{
|
|
2128
3488
|
type: "button",
|
|
2129
3489
|
onClick: handleCreateRecord,
|
|
2130
3490
|
className: "p-1 text-emerald-600 hover:bg-emerald-100 rounded transition-colors",
|
|
2131
3491
|
title: "\u05E9\u05DE\u05D5\u05E8",
|
|
2132
|
-
children: /* @__PURE__ */ (0,
|
|
3492
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) })
|
|
2133
3493
|
}
|
|
2134
3494
|
),
|
|
2135
|
-
/* @__PURE__ */ (0,
|
|
3495
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2136
3496
|
"button",
|
|
2137
3497
|
{
|
|
2138
3498
|
type: "button",
|
|
@@ -2141,46 +3501,47 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2141
3501
|
},
|
|
2142
3502
|
className: "p-1 text-rose-500 hover:bg-rose-100 rounded transition-colors",
|
|
2143
3503
|
title: "\u05D1\u05D9\u05D8\u05D5\u05DC",
|
|
2144
|
-
children: /* @__PURE__ */ (0,
|
|
3504
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M6 18L18 6M6 6l12 12" }) })
|
|
2145
3505
|
}
|
|
2146
3506
|
)
|
|
2147
|
-
] }) })
|
|
3507
|
+
] }) }),
|
|
3508
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { className: "border border-emerald-200 bg-emerald-50/40 pointer-events-none" })
|
|
2148
3509
|
] })
|
|
2149
3510
|
] })
|
|
2150
3511
|
] }) }),
|
|
2151
|
-
conflictModalState.isOpen && /* @__PURE__ */ (0,
|
|
3512
|
+
conflictModalState.isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2152
3513
|
"div",
|
|
2153
3514
|
{
|
|
2154
3515
|
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",
|
|
2155
3516
|
dir: "rtl",
|
|
2156
3517
|
onClick: handleCancelConflict,
|
|
2157
|
-
children: /* @__PURE__ */ (0,
|
|
3518
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2158
3519
|
"div",
|
|
2159
3520
|
{
|
|
2160
3521
|
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",
|
|
2161
3522
|
onClick: (e) => e.stopPropagation(),
|
|
2162
3523
|
children: [
|
|
2163
|
-
/* @__PURE__ */ (0,
|
|
2164
|
-
/* @__PURE__ */ (0,
|
|
2165
|
-
/* @__PURE__ */ (0,
|
|
2166
|
-
/* @__PURE__ */ (0,
|
|
2167
|
-
/* @__PURE__ */ (0,
|
|
3524
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "p-5 border-b border-slate-100 flex items-center gap-3", children: [
|
|
3525
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" }) }) }),
|
|
3526
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" }),
|
|
3528
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" })
|
|
2168
3529
|
] })
|
|
2169
3530
|
] }),
|
|
2170
|
-
/* @__PURE__ */ (0,
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
3531
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "p-5 space-y-3", children: [
|
|
3532
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "text-sm text-slate-700 leading-relaxed", children: [
|
|
2172
3533
|
"\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",
|
|
2173
3534
|
" ",
|
|
2174
|
-
/* @__PURE__ */ (0,
|
|
3535
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-bold text-slate-900 bg-slate-100 px-1.5 py-0.5 rounded border border-slate-200", children: conflictModalState.fieldName }),
|
|
2175
3536
|
". \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?"
|
|
2176
3537
|
] }),
|
|
2177
|
-
conflictModalState.matchingRecords.length > 1 && /* @__PURE__ */ (0,
|
|
3538
|
+
conflictModalState.matchingRecords.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "p-3 bg-blue-50 border border-blue-200 rounded-lg text-xs font-semibold text-blue-800", children: [
|
|
2178
3539
|
"\u05E0\u05DE\u05E6\u05D0\u05D5 ",
|
|
2179
3540
|
conflictModalState.matchingRecords.length,
|
|
2180
3541
|
" \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?"
|
|
2181
3542
|
] }),
|
|
2182
|
-
conflictModalState.matchingRecords.length > 0 && /* @__PURE__ */ (0,
|
|
2183
|
-
/* @__PURE__ */ (0,
|
|
3543
|
+
conflictModalState.matchingRecords.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "overflow-x-auto border border-slate-200 rounded-lg max-h-48 text-xs bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: "w-full text-right border-collapse", children: [
|
|
3544
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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__ */ (0, import_jsx_runtime9.jsx)(
|
|
2184
3545
|
"th",
|
|
2185
3546
|
{
|
|
2186
3547
|
className: "bg-slate-100 text-slate-700 font-semibold p-2 border-b whitespace-nowrap",
|
|
@@ -2188,22 +3549,14 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2188
3549
|
},
|
|
2189
3550
|
col.name
|
|
2190
3551
|
)) }) }),
|
|
2191
|
-
/* @__PURE__ */ (0,
|
|
3552
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { children: conflictModalState.matchingRecords.map((r, idx) => {
|
|
2192
3553
|
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 }));
|
|
2193
|
-
return /* @__PURE__ */ (0,
|
|
3554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { className: "hover:bg-slate-50/80 transition-colors", children: cols.map((col) => {
|
|
2194
3555
|
var _a2;
|
|
2195
3556
|
const rawVal = (_a2 = r.data) == null ? void 0 : _a2[col.name];
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
displayVal = rawVal ? "\u05DB\u05DF" : "\u05DC\u05D0";
|
|
2200
|
-
} else if (typeof rawVal === "object") {
|
|
2201
|
-
displayVal = Array.isArray(rawVal) ? rawVal.join(", ") : JSON.stringify(rawVal);
|
|
2202
|
-
} else {
|
|
2203
|
-
displayVal = String(rawVal);
|
|
2204
|
-
}
|
|
2205
|
-
}
|
|
2206
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3557
|
+
const colDef = targetColumns.find((c) => c.name === col.name) || col;
|
|
3558
|
+
const displayVal = formatConflictCellValue(rawVal, colDef, relationOptions || (context == null ? void 0 : context.relationOptions));
|
|
3559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2207
3560
|
"td",
|
|
2208
3561
|
{
|
|
2209
3562
|
className: "p-2 border-b border-slate-100 whitespace-nowrap text-slate-800",
|
|
@@ -2215,8 +3568,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2215
3568
|
}) })
|
|
2216
3569
|
] }) })
|
|
2217
3570
|
] }),
|
|
2218
|
-
/* @__PURE__ */ (0,
|
|
2219
|
-
/* @__PURE__ */ (0,
|
|
3571
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "p-4 bg-slate-50 border-t border-slate-100 flex items-center justify-end gap-2.5", children: [
|
|
3572
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2220
3573
|
"button",
|
|
2221
3574
|
{
|
|
2222
3575
|
type: "button",
|
|
@@ -2225,14 +3578,14 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2225
3578
|
children: "\u05D1\u05D9\u05D8\u05D5\u05DC"
|
|
2226
3579
|
}
|
|
2227
3580
|
),
|
|
2228
|
-
/* @__PURE__ */ (0,
|
|
3581
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2229
3582
|
"button",
|
|
2230
3583
|
{
|
|
2231
3584
|
type: "button",
|
|
2232
3585
|
onClick: handleConfirmLinkConflict,
|
|
2233
3586
|
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",
|
|
2234
3587
|
children: [
|
|
2235
|
-
/* @__PURE__ */ (0,
|
|
3588
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("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" }) }),
|
|
2236
3589
|
conflictModalState.matchingRecords.length > 1 ? "\u05E7\u05E9\u05E8 \u05D0\u05EA \u05DB\u05D5\u05DC\u05DF" : "\u05E7\u05E9\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D4"
|
|
2237
3590
|
]
|
|
2238
3591
|
}
|
|
@@ -2247,8 +3600,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
2247
3600
|
}
|
|
2248
3601
|
|
|
2249
3602
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
2250
|
-
var
|
|
2251
|
-
var
|
|
3603
|
+
var import_lucide_react7 = require("lucide-react");
|
|
3604
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2252
3605
|
function TableBlockClient({
|
|
2253
3606
|
data: initialRecords,
|
|
2254
3607
|
settings: schema,
|
|
@@ -2265,22 +3618,25 @@ function TableBlockClient({
|
|
|
2265
3618
|
"data-testid": dataTestId
|
|
2266
3619
|
}) {
|
|
2267
3620
|
const { showError, addToast } = useToast();
|
|
2268
|
-
const [columnWidths, setColumnWidths] = (0, import_react7.useState)({});
|
|
2269
|
-
const [isMounted, setIsMounted] = (0, import_react7.useState)(false);
|
|
2270
3621
|
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";
|
|
2271
|
-
const
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
3622
|
+
const { columnWidths, startResize } = useColumnResize({
|
|
3623
|
+
storageKey: `table_widths_${tableKey}`,
|
|
3624
|
+
minWidth: 60,
|
|
3625
|
+
defaultWidth: 200,
|
|
3626
|
+
getMinColWidth: (colName) => {
|
|
3627
|
+
const col = (localColumns || []).find((c) => c.name === colName);
|
|
3628
|
+
return calculateMinColumnWidth(colName, false, col == null ? void 0 : col.type);
|
|
3629
|
+
}
|
|
3630
|
+
});
|
|
3631
|
+
const [isMounted, setIsMounted] = (0, import_react12.useState)(false);
|
|
3632
|
+
const [isInitialLoading, setIsInitialLoading] = (0, import_react12.useState)(true);
|
|
3633
|
+
const [page, setPage] = (0, import_react12.useState)(1);
|
|
3634
|
+
const [limit, setLimit] = (0, import_react12.useState)(50);
|
|
3635
|
+
const [totalRecords, setTotalRecords] = (0, import_react12.useState)(0);
|
|
3636
|
+
const [totalPages, setTotalPages] = (0, import_react12.useState)(1);
|
|
3637
|
+
const [showSummary, setShowSummary] = (0, import_react12.useState)(false);
|
|
3638
|
+
(0, import_react12.useEffect)(() => {
|
|
2276
3639
|
if (typeof window !== "undefined") {
|
|
2277
|
-
const savedWidths = localStorage.getItem(`table_widths_${tableKey}`);
|
|
2278
|
-
if (savedWidths) {
|
|
2279
|
-
try {
|
|
2280
|
-
setColumnWidths(JSON.parse(savedWidths));
|
|
2281
|
-
} catch (e) {
|
|
2282
|
-
}
|
|
2283
|
-
}
|
|
2284
3640
|
const savedSummary = localStorage.getItem(`table_summary_${tableKey}`);
|
|
2285
3641
|
if (savedSummary !== null) {
|
|
2286
3642
|
setShowSummary(savedSummary === "true");
|
|
@@ -2295,7 +3651,6 @@ function TableBlockClient({
|
|
|
2295
3651
|
}
|
|
2296
3652
|
setIsMounted(true);
|
|
2297
3653
|
}, [tableKey]);
|
|
2298
|
-
const [showSummary, setShowSummary] = (0, import_react7.useState)(false);
|
|
2299
3654
|
const toggleSummary = () => {
|
|
2300
3655
|
setShowSummary((prev) => {
|
|
2301
3656
|
const next = !prev;
|
|
@@ -2304,29 +3659,6 @@ function TableBlockClient({
|
|
|
2304
3659
|
return next;
|
|
2305
3660
|
});
|
|
2306
3661
|
};
|
|
2307
|
-
const [resizingCol, setResizingCol] = (0, import_react7.useState)(null);
|
|
2308
|
-
(0, import_react7.useEffect)(() => {
|
|
2309
|
-
if (!resizingCol) return;
|
|
2310
|
-
const handleMouseMove = (e) => {
|
|
2311
|
-
const diffX = resizingCol.startX - e.clientX;
|
|
2312
|
-
const newWidth = Math.max(100, Math.min(500, resizingCol.startWidth + diffX));
|
|
2313
|
-
setColumnWidths((prev) => __spreadProps(__spreadValues({}, prev), { [resizingCol.name]: newWidth }));
|
|
2314
|
-
};
|
|
2315
|
-
const handleMouseUp = () => {
|
|
2316
|
-
setResizingCol(null);
|
|
2317
|
-
setColumnWidths((prev) => {
|
|
2318
|
-
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";
|
|
2319
|
-
localStorage.setItem(`table_widths_${tableKey2}`, JSON.stringify(prev));
|
|
2320
|
-
return prev;
|
|
2321
|
-
});
|
|
2322
|
-
};
|
|
2323
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
2324
|
-
document.addEventListener("mouseup", handleMouseUp);
|
|
2325
|
-
return () => {
|
|
2326
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
2327
|
-
document.removeEventListener("mouseup", handleMouseUp);
|
|
2328
|
-
};
|
|
2329
|
-
}, [resizingCol, schema]);
|
|
2330
3662
|
const normalizeRecords = (records) => {
|
|
2331
3663
|
return (records || []).map((row) => {
|
|
2332
3664
|
var _c;
|
|
@@ -2352,7 +3684,7 @@ function TableBlockClient({
|
|
|
2352
3684
|
return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
|
|
2353
3685
|
});
|
|
2354
3686
|
};
|
|
2355
|
-
const mergeColumnDefs = (0,
|
|
3687
|
+
const mergeColumnDefs = (0, import_react12.useCallback)((existingCols, incomingCols) => {
|
|
2356
3688
|
if (!incomingCols || incomingCols.length === 0) return existingCols || [];
|
|
2357
3689
|
if (!existingCols || existingCols.length === 0) return incomingCols;
|
|
2358
3690
|
const existingMap = new Map(existingCols.map((c) => [c.name, c]));
|
|
@@ -2372,18 +3704,18 @@ function TableBlockClient({
|
|
|
2372
3704
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
2373
3705
|
});
|
|
2374
3706
|
}, []);
|
|
2375
|
-
const [localColumns, setLocalColumns] = (0,
|
|
2376
|
-
(0,
|
|
3707
|
+
const [localColumns, setLocalColumns] = (0, import_react12.useState)(() => (schema == null ? void 0 : schema.columns) || []);
|
|
3708
|
+
(0, import_react12.useEffect)(() => {
|
|
2377
3709
|
if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
|
|
2378
3710
|
setLocalColumns((prev) => mergeColumnDefs(prev, schema.columns));
|
|
2379
3711
|
}
|
|
2380
3712
|
}, [schema == null ? void 0 : schema.columns, mergeColumnDefs]);
|
|
2381
|
-
const [dirty, setDirty] = (0,
|
|
2382
|
-
const dirtyRef = (0,
|
|
2383
|
-
(0,
|
|
3713
|
+
const [dirty, setDirty] = (0, import_react12.useState)({ added: [], modified: {}, deleted: [] });
|
|
3714
|
+
const dirtyRef = (0, import_react12.useRef)(dirty);
|
|
3715
|
+
(0, import_react12.useEffect)(() => {
|
|
2384
3716
|
dirtyRef.current = dirty;
|
|
2385
3717
|
}, [dirty]);
|
|
2386
|
-
const mergeWithDirty = (0,
|
|
3718
|
+
const mergeWithDirty = (0, import_react12.useCallback)((baseRecords) => {
|
|
2387
3719
|
const { added, modified, deleted } = dirtyRef.current;
|
|
2388
3720
|
const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
|
|
2389
3721
|
const modifiedRecords = nonDeleted.map((r) => {
|
|
@@ -2396,10 +3728,13 @@ function TableBlockClient({
|
|
|
2396
3728
|
const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
|
|
2397
3729
|
return [...uniqueAdded, ...modifiedRecords];
|
|
2398
3730
|
}, []);
|
|
2399
|
-
const [data, setData] = (0,
|
|
2400
|
-
(0,
|
|
3731
|
+
const [data, setData] = (0, import_react12.useState)(() => normalizeRecords(initialRecords));
|
|
3732
|
+
const [serverRecords, setServerRecords] = (0, import_react12.useState)(() => normalizeRecords(initialRecords));
|
|
3733
|
+
(0, import_react12.useEffect)(() => {
|
|
2401
3734
|
if (initialRecords) {
|
|
2402
|
-
|
|
3735
|
+
const norm = normalizeRecords(initialRecords);
|
|
3736
|
+
setServerRecords(norm);
|
|
3737
|
+
setData(mergeWithDirty(norm));
|
|
2403
3738
|
}
|
|
2404
3739
|
}, [initialRecords, mergeWithDirty]);
|
|
2405
3740
|
const isEqualValues = (a, b) => {
|
|
@@ -2412,19 +3747,19 @@ function TableBlockClient({
|
|
|
2412
3747
|
}
|
|
2413
3748
|
return false;
|
|
2414
3749
|
};
|
|
2415
|
-
const [baseRecordsMap, setBaseRecordsMap] = (0,
|
|
3750
|
+
const [baseRecordsMap, setBaseRecordsMap] = (0, import_react12.useState)(() => {
|
|
2416
3751
|
const map = /* @__PURE__ */ new Map();
|
|
2417
3752
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
2418
3753
|
return map;
|
|
2419
3754
|
});
|
|
2420
|
-
(0,
|
|
3755
|
+
(0, import_react12.useEffect)(() => {
|
|
2421
3756
|
if (initialRecords && initialRecords.length > 0) {
|
|
2422
3757
|
const map = /* @__PURE__ */ new Map();
|
|
2423
3758
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
2424
3759
|
setBaseRecordsMap(map);
|
|
2425
3760
|
}
|
|
2426
3761
|
}, [initialRecords]);
|
|
2427
|
-
const refetchTableData = (0,
|
|
3762
|
+
const refetchTableData = (0, import_react12.useCallback)((targetPage) => {
|
|
2428
3763
|
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
2429
3764
|
if (!tableId || !executeAction) return Promise.resolve();
|
|
2430
3765
|
const activePage = targetPage !== void 0 ? targetPage : page;
|
|
@@ -2440,7 +3775,8 @@ function TableBlockClient({
|
|
|
2440
3775
|
const map = /* @__PURE__ */ new Map();
|
|
2441
3776
|
norm.forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
2442
3777
|
setBaseRecordsMap(map);
|
|
2443
|
-
|
|
3778
|
+
setServerRecords(norm);
|
|
3779
|
+
setData(mergeWithDirty(norm));
|
|
2444
3780
|
}
|
|
2445
3781
|
if (res.meta) {
|
|
2446
3782
|
const total = typeof res.meta.totalRecords === "number" ? res.meta.totalRecords : 0;
|
|
@@ -2458,9 +3794,22 @@ function TableBlockClient({
|
|
|
2458
3794
|
}).catch((err) => {
|
|
2459
3795
|
console.error("[TableBlock] Failed to auto-fetch table data:", err);
|
|
2460
3796
|
});
|
|
2461
|
-
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeColumnDefs]);
|
|
2462
|
-
(0,
|
|
2463
|
-
|
|
3797
|
+
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeColumnDefs, mergeWithDirty]);
|
|
3798
|
+
(0, import_react12.useEffect)(() => {
|
|
3799
|
+
let isMounted2 = true;
|
|
3800
|
+
const fetchPromise = refetchTableData();
|
|
3801
|
+
if (fetchPromise && typeof fetchPromise.finally === "function") {
|
|
3802
|
+
fetchPromise.finally(() => {
|
|
3803
|
+
if (isMounted2) {
|
|
3804
|
+
setIsInitialLoading(false);
|
|
3805
|
+
}
|
|
3806
|
+
});
|
|
3807
|
+
} else {
|
|
3808
|
+
setIsInitialLoading(false);
|
|
3809
|
+
}
|
|
3810
|
+
return () => {
|
|
3811
|
+
isMounted2 = false;
|
|
3812
|
+
};
|
|
2464
3813
|
}, [refetchTableData]);
|
|
2465
3814
|
const handleLimitChange = (newLimit) => {
|
|
2466
3815
|
setLimit(newLimit);
|
|
@@ -2475,31 +3824,50 @@ function TableBlockClient({
|
|
|
2475
3824
|
const handleNextPage = () => {
|
|
2476
3825
|
setPage((prev) => Math.min(totalPages, prev + 1));
|
|
2477
3826
|
};
|
|
2478
|
-
(0,
|
|
3827
|
+
(0, import_react12.useEffect)(() => {
|
|
2479
3828
|
if (error) {
|
|
2480
3829
|
showError(error, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E8\u05DB\u05D9\u05D1");
|
|
2481
3830
|
}
|
|
2482
3831
|
}, [error, showError]);
|
|
2483
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
2484
|
-
const [
|
|
2485
|
-
const [
|
|
2486
|
-
const
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
3832
|
+
const [searchQuery, setSearchQuery] = (0, import_react12.useState)("");
|
|
3833
|
+
const [columnFilters, setColumnFilters] = (0, import_react12.useState)({});
|
|
3834
|
+
const [activeSearchCol, setActiveSearchCol] = (0, import_react12.useState)(null);
|
|
3835
|
+
const activeSearchRef = (0, import_react12.useRef)(null);
|
|
3836
|
+
(0, import_react12.useEffect)(() => {
|
|
3837
|
+
if (!activeSearchCol) return;
|
|
3838
|
+
const handleMouseDown = (e) => {
|
|
3839
|
+
if (activeSearchRef.current && !activeSearchRef.current.contains(e.target)) {
|
|
3840
|
+
setActiveSearchCol(null);
|
|
3841
|
+
}
|
|
3842
|
+
};
|
|
3843
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
3844
|
+
return () => {
|
|
3845
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
3846
|
+
};
|
|
3847
|
+
}, [activeSearchCol]);
|
|
3848
|
+
const [selectedIds, setSelectedIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
3849
|
+
const [pendingDeletions, setPendingDeletions] = (0, import_react12.useState)([]);
|
|
3850
|
+
const [isSaving, setIsSaving] = (0, import_react12.useState)(false);
|
|
3851
|
+
const isUpdatingActive = Boolean(isUpdating || isSaving);
|
|
3852
|
+
const [isSaveSuccess, setIsSaveSuccess] = (0, import_react12.useState)(false);
|
|
3853
|
+
const [relationOptions, setRelationOptions] = (0, import_react12.useState)({});
|
|
3854
|
+
const [expandedRowIds, setExpandedRowIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
3855
|
+
const schemaColsString = (0, import_react12.useMemo)(() => JSON.stringify(localColumns || []), [localColumns]);
|
|
3856
|
+
const refetchRelation = (0, import_react12.useCallback)(async (colName) => {
|
|
3857
|
+
var _a, _b, _c;
|
|
2493
3858
|
let parsedCols = [];
|
|
2494
3859
|
try {
|
|
2495
3860
|
parsedCols = JSON.parse(schemaColsString);
|
|
2496
3861
|
} catch (e) {
|
|
2497
3862
|
}
|
|
2498
|
-
const col = parsedCols.find((c) =>
|
|
2499
|
-
|
|
3863
|
+
const col = parsedCols.find((c) => {
|
|
3864
|
+
var _a2;
|
|
3865
|
+
return c.name === colName && ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION";
|
|
3866
|
+
});
|
|
3867
|
+
if (!col || !((_a = col.config) == null ? void 0 : _a.referencedTableId)) return;
|
|
2500
3868
|
try {
|
|
2501
3869
|
if (executeAction) {
|
|
2502
|
-
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
|
|
3870
|
+
const options = await executeAction("FETCH_RELATION", { referencedTableId: (_b = col.config) == null ? void 0 : _b.referencedTableId, displayField: (_c = col.config) == null ? void 0 : _c.displayField });
|
|
2503
3871
|
if (options && Array.isArray(options)) {
|
|
2504
3872
|
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [colName]: options }));
|
|
2505
3873
|
}
|
|
@@ -2508,7 +3876,7 @@ function TableBlockClient({
|
|
|
2508
3876
|
console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
|
|
2509
3877
|
}
|
|
2510
3878
|
}, [schemaColsString, executeAction]);
|
|
2511
|
-
(0,
|
|
3879
|
+
(0, import_react12.useEffect)(() => {
|
|
2512
3880
|
let parsedCols = [];
|
|
2513
3881
|
try {
|
|
2514
3882
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -2522,7 +3890,7 @@ function TableBlockClient({
|
|
|
2522
3890
|
refetchRelation(col.name);
|
|
2523
3891
|
});
|
|
2524
3892
|
}, [schemaColsString, refetchRelation]);
|
|
2525
|
-
const normalizedColumns = (0,
|
|
3893
|
+
const normalizedColumns = (0, import_react12.useMemo)(() => {
|
|
2526
3894
|
return (localColumns || []).map((col, idx) => {
|
|
2527
3895
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
2528
3896
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
@@ -2536,17 +3904,17 @@ function TableBlockClient({
|
|
|
2536
3904
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
2537
3905
|
});
|
|
2538
3906
|
}, [localColumns]);
|
|
2539
|
-
const filteredColumns = (0,
|
|
3907
|
+
const filteredColumns = (0, import_react12.useMemo)(() => {
|
|
2540
3908
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
2541
3909
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name) && !col.isHidden);
|
|
2542
3910
|
}, [normalizedColumns]);
|
|
2543
|
-
const customizableColumns = (0,
|
|
3911
|
+
const customizableColumns = (0, import_react12.useMemo)(() => {
|
|
2544
3912
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
2545
3913
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name));
|
|
2546
3914
|
}, [normalizedColumns]);
|
|
2547
|
-
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = (0,
|
|
2548
|
-
const dropdownRef = (0,
|
|
2549
|
-
(0,
|
|
3915
|
+
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = (0, import_react12.useState)(false);
|
|
3916
|
+
const dropdownRef = (0, import_react12.useRef)(null);
|
|
3917
|
+
(0, import_react12.useEffect)(() => {
|
|
2550
3918
|
const handleClickOutside = (e) => {
|
|
2551
3919
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
2552
3920
|
setIsColumnsDropdownOpen(false);
|
|
@@ -2624,8 +3992,6 @@ function TableBlockClient({
|
|
|
2624
3992
|
}
|
|
2625
3993
|
}
|
|
2626
3994
|
};
|
|
2627
|
-
const [draggedColName, setDraggedColName] = (0, import_react7.useState)(null);
|
|
2628
|
-
const [dragOverColName, setDragOverColName] = (0, import_react7.useState)(null);
|
|
2629
3995
|
const handleColumnReorder = async (draggedName, dropTargetName) => {
|
|
2630
3996
|
var _a;
|
|
2631
3997
|
if (draggedName === dropTargetName) return;
|
|
@@ -2660,6 +4026,43 @@ function TableBlockClient({
|
|
|
2660
4026
|
}
|
|
2661
4027
|
}
|
|
2662
4028
|
};
|
|
4029
|
+
const { draggedColName, dragOverColName, getHeaderDragProps } = useColumnReorder({
|
|
4030
|
+
onReorder: handleColumnReorder,
|
|
4031
|
+
disabled: isLoading || isUpdatingActive
|
|
4032
|
+
});
|
|
4033
|
+
const handleUpdateColumnConfig = async (columnName, partialConfig) => {
|
|
4034
|
+
var _a;
|
|
4035
|
+
let updatedColumns = [];
|
|
4036
|
+
setLocalColumns((prevCols) => {
|
|
4037
|
+
const nextCols = (prevCols || []).map((col) => {
|
|
4038
|
+
if (col.name === columnName) {
|
|
4039
|
+
return __spreadProps(__spreadValues({}, col), {
|
|
4040
|
+
config: __spreadValues(__spreadValues({}, col.config || {}), partialConfig)
|
|
4041
|
+
});
|
|
4042
|
+
}
|
|
4043
|
+
return col;
|
|
4044
|
+
});
|
|
4045
|
+
updatedColumns = nextCols;
|
|
4046
|
+
return nextCols;
|
|
4047
|
+
});
|
|
4048
|
+
const targetTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
4049
|
+
if (targetTableId && executeAction && updatedColumns.length > 0) {
|
|
4050
|
+
try {
|
|
4051
|
+
const res = await executeAction("UPDATE_TABLE_COLUMNS", {
|
|
4052
|
+
tableId: targetTableId,
|
|
4053
|
+
tableMetaId: targetTableId,
|
|
4054
|
+
columns: updatedColumns
|
|
4055
|
+
});
|
|
4056
|
+
const returnedCols = (res == null ? void 0 : res.columns) || ((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.columns);
|
|
4057
|
+
if (returnedCols && Array.isArray(returnedCols)) {
|
|
4058
|
+
setLocalColumns((prev) => mergeColumnDefs(prev, returnedCols));
|
|
4059
|
+
}
|
|
4060
|
+
} catch (err) {
|
|
4061
|
+
console.error("[TableBlock] Failed to save column config:", err);
|
|
4062
|
+
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");
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
};
|
|
2663
4066
|
const generateTempId = () => `temp_${Math.random().toString(36).substr(2, 9)}`;
|
|
2664
4067
|
const handleAddRow = () => {
|
|
2665
4068
|
const defaultData = {};
|
|
@@ -2754,13 +4157,13 @@ function TableBlockClient({
|
|
|
2754
4157
|
});
|
|
2755
4158
|
}
|
|
2756
4159
|
};
|
|
2757
|
-
const triggerSaveSuccess = (0,
|
|
4160
|
+
const triggerSaveSuccess = (0, import_react12.useCallback)(() => {
|
|
2758
4161
|
setIsSaveSuccess(true);
|
|
2759
4162
|
setTimeout(() => {
|
|
2760
4163
|
setIsSaveSuccess(false);
|
|
2761
4164
|
}, 2500);
|
|
2762
4165
|
}, []);
|
|
2763
|
-
const handleQuietCellChange = (0,
|
|
4166
|
+
const handleQuietCellChange = (0, import_react12.useCallback)((rowId, colName, value) => {
|
|
2764
4167
|
setData((prev) => prev.map(
|
|
2765
4168
|
(row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
|
|
2766
4169
|
));
|
|
@@ -2873,6 +4276,15 @@ function TableBlockClient({
|
|
|
2873
4276
|
return formatted;
|
|
2874
4277
|
};
|
|
2875
4278
|
const hasChanges = dirty.added.length > 0 || Object.keys(dirty.modified).length > 0 || dirty.deleted.length > 0;
|
|
4279
|
+
const handleRevertChanges = () => {
|
|
4280
|
+
setDirty({ added: [], modified: {}, deleted: [] });
|
|
4281
|
+
setData(serverRecords.map((r) => __spreadProps(__spreadValues({}, r), { data: __spreadValues({}, r.data) })));
|
|
4282
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
4283
|
+
setPendingDeletions([]);
|
|
4284
|
+
if (emitEvent) {
|
|
4285
|
+
emitEvent("SELECTION_CHANGE", { selectedIds: [], componentId });
|
|
4286
|
+
}
|
|
4287
|
+
};
|
|
2876
4288
|
const handleSave = async () => {
|
|
2877
4289
|
var _a, _b;
|
|
2878
4290
|
if (!hasChanges) {
|
|
@@ -3019,18 +4431,89 @@ function TableBlockClient({
|
|
|
3019
4431
|
setIsSaving(false);
|
|
3020
4432
|
}
|
|
3021
4433
|
};
|
|
3022
|
-
const
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
)
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
4434
|
+
const getRowRelationLabels = (0, import_react12.useCallback)((rowVal, col) => {
|
|
4435
|
+
const ids = normalizeRelationValue(rowVal);
|
|
4436
|
+
if (ids.length === 0) return [];
|
|
4437
|
+
const options = relationOptions[col.name] || [];
|
|
4438
|
+
return ids.map((id) => {
|
|
4439
|
+
const opt = options.find((o) => o.id === id || o._id === id);
|
|
4440
|
+
if (opt) {
|
|
4441
|
+
const resolved = resolveRelationLabel(opt, col);
|
|
4442
|
+
if (resolved) return resolved;
|
|
4443
|
+
if (opt.label) return String(opt.label);
|
|
4444
|
+
if (opt.name) return String(opt.name);
|
|
4445
|
+
}
|
|
4446
|
+
if (typeof rowVal === "object" && rowVal !== null) {
|
|
4447
|
+
if (rowVal._displayLabel) return String(rowVal._displayLabel);
|
|
4448
|
+
if (rowVal.label) return String(rowVal.label);
|
|
4449
|
+
}
|
|
4450
|
+
return id;
|
|
4451
|
+
});
|
|
4452
|
+
}, [relationOptions]);
|
|
4453
|
+
const getUniqueRelationOptions = (0, import_react12.useCallback)((col) => {
|
|
4454
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
4455
|
+
const results = [];
|
|
4456
|
+
const options = relationOptions[col.name] || [];
|
|
4457
|
+
data.forEach((row) => {
|
|
4458
|
+
if (!(row == null ? void 0 : row.data)) return;
|
|
4459
|
+
const ids = normalizeRelationValue(row.data[col.name]);
|
|
4460
|
+
ids.forEach((id) => {
|
|
4461
|
+
if (!seenIds.has(id)) {
|
|
4462
|
+
seenIds.add(id);
|
|
4463
|
+
const opt = options.find((o) => o.id === id || o._id === id);
|
|
4464
|
+
let label = opt ? resolveRelationLabel(opt, col) : "";
|
|
4465
|
+
if (!label && opt) label = opt.label || opt.name || opt.title || id;
|
|
4466
|
+
if (!label) label = id;
|
|
4467
|
+
results.push({ id, label });
|
|
4468
|
+
}
|
|
4469
|
+
});
|
|
4470
|
+
});
|
|
4471
|
+
return results.sort((a, b) => a.label.localeCompare(b.label));
|
|
4472
|
+
}, [data, relationOptions]);
|
|
4473
|
+
const filteredData = (0, import_react12.useMemo)(() => {
|
|
4474
|
+
const hasGlobalSearch = Boolean(searchQuery && searchQuery.trim() !== "");
|
|
4475
|
+
const activeFilters = Object.entries(columnFilters).filter(([, val]) => Boolean(val && val.trim() !== ""));
|
|
4476
|
+
const hasColumnFilters = activeFilters.length > 0;
|
|
4477
|
+
if (!hasGlobalSearch && !hasColumnFilters) return data;
|
|
4478
|
+
const lowerGlobal = hasGlobalSearch ? searchQuery.trim().toLowerCase() : "";
|
|
4479
|
+
return data.filter((row) => {
|
|
4480
|
+
var _a;
|
|
4481
|
+
if (!row || !row.data) return false;
|
|
4482
|
+
if (hasGlobalSearch) {
|
|
4483
|
+
const matchesGlobal = (localColumns || []).some((col) => {
|
|
4484
|
+
var _a2;
|
|
4485
|
+
const rawVal = row.data[col.name];
|
|
4486
|
+
if (rawVal === void 0 || rawVal === null) return false;
|
|
4487
|
+
if (((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION") {
|
|
4488
|
+
const labels = getRowRelationLabels(rawVal, col);
|
|
4489
|
+
return labels.some((l) => l.toLowerCase().includes(lowerGlobal));
|
|
4490
|
+
}
|
|
4491
|
+
if (typeof rawVal === "object") {
|
|
4492
|
+
return JSON.stringify(rawVal).toLowerCase().includes(lowerGlobal);
|
|
4493
|
+
}
|
|
4494
|
+
return String(rawVal).toLowerCase().includes(lowerGlobal);
|
|
4495
|
+
});
|
|
4496
|
+
if (!matchesGlobal) return false;
|
|
4497
|
+
}
|
|
4498
|
+
for (const [colName, filterVal] of activeFilters) {
|
|
4499
|
+
const lowerFilter = filterVal.trim().toLowerCase();
|
|
4500
|
+
const col = (localColumns || []).find((c) => c.name === colName);
|
|
4501
|
+
const rawVal = row.data[colName];
|
|
4502
|
+
if (((_a = col == null ? void 0 : col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION") {
|
|
4503
|
+
const labels = getRowRelationLabels(rawVal, col);
|
|
4504
|
+
const matches = labels.some((l) => l.toLowerCase().includes(lowerFilter));
|
|
4505
|
+
if (!matches) return false;
|
|
4506
|
+
} else {
|
|
4507
|
+
if (rawVal === void 0 || rawVal === null) return false;
|
|
4508
|
+
const strVal = typeof rawVal === "object" ? JSON.stringify(rawVal).toLowerCase() : String(rawVal).toLowerCase();
|
|
4509
|
+
if (!strVal.includes(lowerFilter)) return false;
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
return true;
|
|
4513
|
+
});
|
|
4514
|
+
}, [data, searchQuery, columnFilters, localColumns, getRowRelationLabels]);
|
|
3032
4515
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
3033
|
-
const columnTotals = (0,
|
|
4516
|
+
const columnTotals = (0, import_react12.useMemo)(() => {
|
|
3034
4517
|
const totals = {};
|
|
3035
4518
|
if (!showSummary) return totals;
|
|
3036
4519
|
filteredColumns.forEach((col) => {
|
|
@@ -3048,7 +4531,7 @@ function TableBlockClient({
|
|
|
3048
4531
|
});
|
|
3049
4532
|
return totals;
|
|
3050
4533
|
}, [filteredData, filteredColumns, showSummary]);
|
|
3051
|
-
return /* @__PURE__ */ (0,
|
|
4534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3052
4535
|
"div",
|
|
3053
4536
|
{
|
|
3054
4537
|
id: componentId,
|
|
@@ -3056,34 +4539,34 @@ function TableBlockClient({
|
|
|
3056
4539
|
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs min-h-[350px] overflow-hidden ${className}`,
|
|
3057
4540
|
dir: "rtl",
|
|
3058
4541
|
children: [
|
|
3059
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
3060
|
-
/* @__PURE__ */ (0,
|
|
3061
|
-
/* @__PURE__ */ (0,
|
|
4542
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4543
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
4544
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: errorMessage })
|
|
3062
4545
|
] }) }),
|
|
3063
|
-
/* @__PURE__ */ (0,
|
|
3064
|
-
/* @__PURE__ */ (0,
|
|
3065
|
-
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0,
|
|
3066
|
-
/* @__PURE__ */ (0,
|
|
4546
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 p-3.5 sm:p-4 bg-slate-50 border-b border-slate-200", children: [
|
|
4547
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
4548
|
+
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: schema.title || schema.name }) }),
|
|
4549
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3067
4550
|
"button",
|
|
3068
4551
|
{
|
|
3069
4552
|
onClick: handleAddRow,
|
|
3070
|
-
disabled: isLoading || isUpdatingActive,
|
|
3071
|
-
className:
|
|
3072
|
-
title: "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
3073
|
-
children: /* @__PURE__ */ (0,
|
|
4553
|
+
disabled: isInitialLoading || isLoading || isUpdatingActive,
|
|
4554
|
+
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"}`,
|
|
4555
|
+
title: isInitialLoading ? "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." : "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
4556
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
3074
4557
|
}
|
|
3075
4558
|
),
|
|
3076
|
-
/* @__PURE__ */ (0,
|
|
4559
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3077
4560
|
"button",
|
|
3078
4561
|
{
|
|
3079
4562
|
onClick: handleDuplicateRow,
|
|
3080
|
-
disabled: isLoading || isUpdatingActive || selectedIds.size !== 1,
|
|
4563
|
+
disabled: isInitialLoading || isLoading || isUpdatingActive || selectedIds.size !== 1,
|
|
3081
4564
|
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",
|
|
3082
4565
|
title: "\u05E9\u05DB\u05E4\u05DC \u05E9\u05D5\u05E8\u05D4 \u05E0\u05D1\u05D7\u05E8\u05EA",
|
|
3083
|
-
children: /* @__PURE__ */ (0,
|
|
4566
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.Copy, { className: "w-4 h-4 text-blue-600 shrink-0" })
|
|
3084
4567
|
}
|
|
3085
4568
|
),
|
|
3086
|
-
/* @__PURE__ */ (0,
|
|
4569
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3087
4570
|
"button",
|
|
3088
4571
|
{
|
|
3089
4572
|
onClick: handleDeleteSelected,
|
|
@@ -3091,12 +4574,12 @@ function TableBlockClient({
|
|
|
3091
4574
|
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",
|
|
3092
4575
|
title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
|
|
3093
4576
|
children: [
|
|
3094
|
-
/* @__PURE__ */ (0,
|
|
3095
|
-
selectedIds.size > 0 && /* @__PURE__ */ (0,
|
|
4577
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
|
|
4578
|
+
selectedIds.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "absolute -top-1.5 -right-1.5 bg-rose-600 text-white min-w-[18px] h-[18px] px-1 rounded-full text-[10px] font-bold flex items-center justify-center shadow-xs", children: selectedIds.size })
|
|
3096
4579
|
]
|
|
3097
4580
|
}
|
|
3098
4581
|
),
|
|
3099
|
-
/* @__PURE__ */ (0,
|
|
4582
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3100
4583
|
"button",
|
|
3101
4584
|
{
|
|
3102
4585
|
onClick: toggleSummary,
|
|
@@ -3104,13 +4587,13 @@ function TableBlockClient({
|
|
|
3104
4587
|
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"}`,
|
|
3105
4588
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E9\u05D5\u05E8\u05EA \u05E1\u05D9\u05DB\u05D5\u05DD",
|
|
3106
4589
|
children: [
|
|
3107
|
-
/* @__PURE__ */ (0,
|
|
3108
|
-
/* @__PURE__ */ (0,
|
|
4590
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
4591
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "hidden sm:inline", children: "\u05E1\u05DB\u05D9\u05DE\u05D4" })
|
|
3109
4592
|
]
|
|
3110
4593
|
}
|
|
3111
4594
|
),
|
|
3112
|
-
/* @__PURE__ */ (0,
|
|
3113
|
-
/* @__PURE__ */ (0,
|
|
4595
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative", ref: dropdownRef, children: [
|
|
4596
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3114
4597
|
"button",
|
|
3115
4598
|
{
|
|
3116
4599
|
onClick: () => setIsColumnsDropdownOpen((prev) => !prev),
|
|
@@ -3118,16 +4601,16 @@ function TableBlockClient({
|
|
|
3118
4601
|
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",
|
|
3119
4602
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA",
|
|
3120
4603
|
children: [
|
|
3121
|
-
/* @__PURE__ */ (0,
|
|
3122
|
-
/* @__PURE__ */ (0,
|
|
4604
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4 h-4 text-slate-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }) }),
|
|
4605
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })
|
|
3123
4606
|
]
|
|
3124
4607
|
}
|
|
3125
4608
|
),
|
|
3126
|
-
isColumnsDropdownOpen && /* @__PURE__ */ (0,
|
|
3127
|
-
/* @__PURE__ */ (0,
|
|
3128
|
-
/* @__PURE__ */ (0,
|
|
3129
|
-
/* @__PURE__ */ (0,
|
|
3130
|
-
/* @__PURE__ */ (0,
|
|
4609
|
+
isColumnsDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("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: [
|
|
4610
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("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: [
|
|
4611
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
4612
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "\u05D4\u05E6\u05D2\u05EA \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA" }),
|
|
4613
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-[10px] font-normal text-slate-400", children: [
|
|
3131
4614
|
"(",
|
|
3132
4615
|
customizableColumns.filter((c) => !c.isHidden).length,
|
|
3133
4616
|
"/",
|
|
@@ -3135,7 +4618,7 @@ function TableBlockClient({
|
|
|
3135
4618
|
")"
|
|
3136
4619
|
] })
|
|
3137
4620
|
] }),
|
|
3138
|
-
/* @__PURE__ */ (0,
|
|
4621
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3139
4622
|
"button",
|
|
3140
4623
|
{
|
|
3141
4624
|
type: "button",
|
|
@@ -3145,7 +4628,7 @@ function TableBlockClient({
|
|
|
3145
4628
|
}
|
|
3146
4629
|
)
|
|
3147
4630
|
] }),
|
|
3148
|
-
/* @__PURE__ */ (0,
|
|
4631
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-h-60 overflow-y-auto space-y-0.5", children: customizableColumns.map((col) => {
|
|
3149
4632
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
3150
4633
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
3151
4634
|
const isProtected = isRequired || isUnique;
|
|
@@ -3159,7 +4642,7 @@ function TableBlockClient({
|
|
|
3159
4642
|
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";
|
|
3160
4643
|
}
|
|
3161
4644
|
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";
|
|
3162
|
-
return /* @__PURE__ */ (0,
|
|
4645
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3163
4646
|
"div",
|
|
3164
4647
|
{
|
|
3165
4648
|
onClick: () => {
|
|
@@ -3170,8 +4653,8 @@ function TableBlockClient({
|
|
|
3170
4653
|
title: isProtected ? protectedExplanation : void 0,
|
|
3171
4654
|
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"}`,
|
|
3172
4655
|
children: [
|
|
3173
|
-
/* @__PURE__ */ (0,
|
|
3174
|
-
/* @__PURE__ */ (0,
|
|
4656
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
4657
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3175
4658
|
"input",
|
|
3176
4659
|
{
|
|
3177
4660
|
type: "checkbox",
|
|
@@ -3182,16 +4665,16 @@ function TableBlockClient({
|
|
|
3182
4665
|
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"
|
|
3183
4666
|
}
|
|
3184
4667
|
),
|
|
3185
|
-
/* @__PURE__ */ (0,
|
|
4668
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `font-medium truncate ${isProtected ? "text-slate-500" : "text-slate-700"}`, children: col.name })
|
|
3186
4669
|
] }),
|
|
3187
|
-
isProtected && /* @__PURE__ */ (0,
|
|
4670
|
+
isProtected && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3188
4671
|
"div",
|
|
3189
4672
|
{
|
|
3190
4673
|
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",
|
|
3191
4674
|
title: protectedExplanation,
|
|
3192
4675
|
children: [
|
|
3193
|
-
/* @__PURE__ */ (0,
|
|
3194
|
-
/* @__PURE__ */ (0,
|
|
4676
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsx)("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" }) }),
|
|
4677
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: badgeLabel })
|
|
3195
4678
|
]
|
|
3196
4679
|
}
|
|
3197
4680
|
)
|
|
@@ -3202,9 +4685,9 @@ function TableBlockClient({
|
|
|
3202
4685
|
}) })
|
|
3203
4686
|
] })
|
|
3204
4687
|
] }),
|
|
3205
|
-
/* @__PURE__ */ (0,
|
|
3206
|
-
/* @__PURE__ */ (0,
|
|
3207
|
-
/* @__PURE__ */ (0,
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
|
|
4689
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
|
|
4690
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3208
4691
|
"input",
|
|
3209
4692
|
{
|
|
3210
4693
|
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
@@ -3214,129 +4697,224 @@ function TableBlockClient({
|
|
|
3214
4697
|
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"
|
|
3215
4698
|
}
|
|
3216
4699
|
),
|
|
3217
|
-
searchQuery ? /* @__PURE__ */ (0,
|
|
4700
|
+
searchQuery ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3218
4701
|
"button",
|
|
3219
4702
|
{
|
|
3220
4703
|
type: "button",
|
|
3221
4704
|
onClick: () => setSearchQuery(""),
|
|
3222
4705
|
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",
|
|
3223
4706
|
title: "Clear search",
|
|
3224
|
-
children: /* @__PURE__ */ (0,
|
|
4707
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.X, { className: "w-3.5 h-3.5" })
|
|
3225
4708
|
}
|
|
3226
|
-
) : /* @__PURE__ */ (0,
|
|
4709
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4 h-4 text-slate-400 absolute right-2.5 top-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
|
|
3227
4710
|
] })
|
|
3228
4711
|
] }),
|
|
3229
|
-
/* @__PURE__ */ (0,
|
|
3230
|
-
isUpdatingActive ? /* @__PURE__ */ (0,
|
|
3231
|
-
/* @__PURE__ */ (0,
|
|
4712
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
4713
|
+
isUpdatingActive ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-xs text-blue-600 font-semibold flex items-center gap-1.5 bg-blue-50 border border-blue-200 px-3 py-1.5 rounded-lg animate-pulse", children: [
|
|
4714
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
|
|
3232
4715
|
"\u05DE\u05E2\u05D3\u05DB\u05DF..."
|
|
3233
|
-
] }) : isSaveSuccess ? /* @__PURE__ */ (0,
|
|
3234
|
-
/* @__PURE__ */ (0,
|
|
4716
|
+
] }) : isSaveSuccess ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-xs text-emerald-700 font-semibold flex items-center gap-1.5 bg-emerald-50 border border-emerald-200 px-3 py-1.5 rounded-lg animate-in fade-in duration-200", children: [
|
|
4717
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
3235
4718
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
3236
|
-
] }) : hasChanges ? /* @__PURE__ */ (0,
|
|
3237
|
-
|
|
4719
|
+
] }) : hasChanges ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1.5 animate-in fade-in", children: [
|
|
4720
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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" }),
|
|
4721
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4722
|
+
"button",
|
|
4723
|
+
{
|
|
4724
|
+
type: "button",
|
|
4725
|
+
onClick: handleRevertChanges,
|
|
4726
|
+
disabled: isUpdatingActive,
|
|
4727
|
+
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",
|
|
4728
|
+
title: "\u05D1\u05D8\u05DC \u05D0\u05EA \u05DB\u05DC \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5",
|
|
4729
|
+
"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",
|
|
4730
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.RotateCcw, { className: "w-3.5 h-3.5" })
|
|
4731
|
+
}
|
|
4732
|
+
)
|
|
4733
|
+
] }) : null,
|
|
4734
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3238
4735
|
"button",
|
|
3239
4736
|
{
|
|
3240
4737
|
onClick: handleSave,
|
|
3241
4738
|
disabled: isUpdatingActive || isLoading || !hasChanges,
|
|
3242
4739
|
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"}`,
|
|
3243
|
-
children: /* @__PURE__ */ (0,
|
|
4740
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
|
|
3244
4741
|
}
|
|
3245
4742
|
)
|
|
3246
4743
|
] })
|
|
3247
4744
|
] }),
|
|
3248
|
-
/* @__PURE__ */ (0,
|
|
3249
|
-
isLoading && /* @__PURE__ */ (0,
|
|
3250
|
-
/* @__PURE__ */ (0,
|
|
3251
|
-
/* @__PURE__ */ (0,
|
|
4745
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `overflow-x-auto relative min-h-[260px] flex-1 transition-opacity duration-200 ${isMounted ? "opacity-100" : "opacity-0"}`, children: [
|
|
4746
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
|
|
4747
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
|
|
4748
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
|
|
3252
4749
|
] }),
|
|
3253
|
-
/* @__PURE__ */ (0,
|
|
3254
|
-
/* @__PURE__ */ (0,
|
|
3255
|
-
/* @__PURE__ */ (0,
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
4750
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("table", { className: "w-full text-sm text-right border-collapse table-auto", children: [
|
|
4751
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("tr", { className: "h-12 min-h-[48px]", children: [
|
|
4752
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
4753
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4754
|
+
"input",
|
|
4755
|
+
{
|
|
4756
|
+
type: "checkbox",
|
|
4757
|
+
checked: filteredData.length > 0 && selectedIds.size === filteredData.length,
|
|
4758
|
+
onChange: (e) => toggleSelectAll(e.target.checked),
|
|
4759
|
+
disabled: isLoading || isUpdatingActive,
|
|
4760
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
4761
|
+
}
|
|
4762
|
+
),
|
|
4763
|
+
filteredColumns.some((c) => {
|
|
4764
|
+
var _a;
|
|
4765
|
+
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
4766
|
+
}) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "w-5 h-5 shrink-0" })
|
|
4767
|
+
] }) }),
|
|
3265
4768
|
filteredColumns.map((col) => {
|
|
3266
|
-
|
|
3267
|
-
const
|
|
3268
|
-
const
|
|
3269
|
-
|
|
4769
|
+
var _a, _b;
|
|
4770
|
+
const isSearching = activeSearchCol === col.name;
|
|
4771
|
+
const dragProps = isSearching ? {} : getHeaderDragProps(col.name);
|
|
4772
|
+
const isDragging = !isSearching && draggedColName === col.name;
|
|
4773
|
+
const isDragOver = !isSearching && dragOverColName === col.name;
|
|
4774
|
+
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
4775
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
4776
|
+
const isRelation = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION";
|
|
4777
|
+
const filterVal = columnFilters[col.name] || "";
|
|
4778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3270
4779
|
"th",
|
|
3271
|
-
{
|
|
4780
|
+
__spreadProps(__spreadValues({
|
|
3272
4781
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
e.dataTransfer.effectAllowed = "move";
|
|
3277
|
-
setDraggedColName(col.name);
|
|
3278
|
-
},
|
|
3279
|
-
onDragOver: (e) => {
|
|
3280
|
-
e.preventDefault();
|
|
3281
|
-
e.dataTransfer.dropEffect = "move";
|
|
3282
|
-
if (dragOverColName !== col.name) {
|
|
3283
|
-
setDragOverColName(col.name);
|
|
3284
|
-
}
|
|
3285
|
-
},
|
|
3286
|
-
onDragLeave: () => {
|
|
3287
|
-
if (dragOverColName === col.name) {
|
|
3288
|
-
setDragOverColName(null);
|
|
3289
|
-
}
|
|
3290
|
-
},
|
|
3291
|
-
onDrop: (e) => {
|
|
3292
|
-
e.preventDefault();
|
|
3293
|
-
if (draggedColName && draggedColName !== col.name) {
|
|
3294
|
-
handleColumnReorder(draggedColName, col.name);
|
|
3295
|
-
}
|
|
3296
|
-
setDraggedColName(null);
|
|
3297
|
-
setDragOverColName(null);
|
|
3298
|
-
},
|
|
3299
|
-
onDragEnd: () => {
|
|
3300
|
-
setDraggedColName(null);
|
|
3301
|
-
setDragOverColName(null);
|
|
3302
|
-
},
|
|
3303
|
-
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"}`,
|
|
4782
|
+
title: isSearching ? void 0 : col.name
|
|
4783
|
+
}, dragProps), {
|
|
4784
|
+
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" : ""}`,
|
|
3304
4785
|
children: [
|
|
3305
|
-
/* @__PURE__ */ (0,
|
|
4786
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3306
4787
|
"div",
|
|
3307
4788
|
{
|
|
3308
4789
|
onMouseDown: (e) => {
|
|
3309
4790
|
e.preventDefault();
|
|
3310
4791
|
e.stopPropagation();
|
|
3311
|
-
|
|
4792
|
+
startResize(col.name, currentWidth, e.clientX, colMinWidth);
|
|
3312
4793
|
},
|
|
3313
4794
|
className: "absolute left-0 top-0 bottom-0 w-1.5 cursor-col-resize hover:bg-brand active:bg-brand-hover z-20",
|
|
3314
4795
|
title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
|
|
3315
4796
|
}
|
|
3316
4797
|
),
|
|
3317
|
-
/* @__PURE__ */ (0,
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
4798
|
+
isSearching ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4799
|
+
"div",
|
|
4800
|
+
{
|
|
4801
|
+
ref: activeSearchRef,
|
|
4802
|
+
className: "flex items-center gap-1 w-full",
|
|
4803
|
+
onClick: (e) => e.stopPropagation(),
|
|
4804
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
4805
|
+
children: [
|
|
4806
|
+
isRelation ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "relative flex items-center w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
4807
|
+
"select",
|
|
4808
|
+
{
|
|
4809
|
+
autoFocus: true,
|
|
4810
|
+
value: filterVal,
|
|
4811
|
+
onChange: (e) => {
|
|
4812
|
+
const val = e.target.value;
|
|
4813
|
+
setColumnFilters((prev) => {
|
|
4814
|
+
const next = __spreadValues({}, prev);
|
|
4815
|
+
if (val) next[col.name] = val;
|
|
4816
|
+
else delete next[col.name];
|
|
4817
|
+
return next;
|
|
4818
|
+
});
|
|
4819
|
+
},
|
|
4820
|
+
onKeyDown: (e) => {
|
|
4821
|
+
if (e.key === "Escape" || e.key === "Enter") {
|
|
4822
|
+
setActiveSearchCol(null);
|
|
4823
|
+
}
|
|
4824
|
+
},
|
|
4825
|
+
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",
|
|
4826
|
+
children: [
|
|
4827
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "\u05D4\u05DB\u05DC" }),
|
|
4828
|
+
getUniqueRelationOptions(col).map((opt) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: opt.label, children: opt.label }, opt.id))
|
|
4829
|
+
]
|
|
4830
|
+
}
|
|
4831
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "relative flex items-center w-full min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4832
|
+
"input",
|
|
4833
|
+
{
|
|
4834
|
+
autoFocus: true,
|
|
4835
|
+
type: "text",
|
|
4836
|
+
placeholder: `\u05D7\u05E4\u05E9 \u05D1-${col.name}...`,
|
|
4837
|
+
value: filterVal,
|
|
4838
|
+
onChange: (e) => {
|
|
4839
|
+
const val = e.target.value;
|
|
4840
|
+
setColumnFilters((prev) => {
|
|
4841
|
+
const next = __spreadValues({}, prev);
|
|
4842
|
+
if (val) next[col.name] = val;
|
|
4843
|
+
else delete next[col.name];
|
|
4844
|
+
return next;
|
|
4845
|
+
});
|
|
4846
|
+
},
|
|
4847
|
+
onKeyDown: (e) => {
|
|
4848
|
+
if (e.key === "Escape" || e.key === "Enter") {
|
|
4849
|
+
setActiveSearchCol(null);
|
|
4850
|
+
}
|
|
4851
|
+
},
|
|
4852
|
+
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"
|
|
4853
|
+
}
|
|
4854
|
+
) }),
|
|
4855
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4856
|
+
"button",
|
|
4857
|
+
{
|
|
4858
|
+
type: "button",
|
|
4859
|
+
onMouseDown: (e) => {
|
|
4860
|
+
e.preventDefault();
|
|
4861
|
+
e.stopPropagation();
|
|
4862
|
+
},
|
|
4863
|
+
onClick: (e) => {
|
|
4864
|
+
e.stopPropagation();
|
|
4865
|
+
setColumnFilters((prev) => {
|
|
4866
|
+
const next = __spreadValues({}, prev);
|
|
4867
|
+
delete next[col.name];
|
|
4868
|
+
return next;
|
|
4869
|
+
});
|
|
4870
|
+
setActiveSearchCol(null);
|
|
4871
|
+
},
|
|
4872
|
+
className: "p-1 text-slate-400 hover:text-slate-700 hover:bg-slate-200/70 rounded transition-colors cursor-pointer shrink-0",
|
|
4873
|
+
title: "\u05E0\u05E7\u05D4 \u05D5\u05E1\u05D2\u05D5\u05E8 \u05D7\u05D9\u05E4\u05D5\u05E9",
|
|
4874
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.X, { className: "w-3.5 h-3.5" })
|
|
4875
|
+
}
|
|
4876
|
+
)
|
|
4877
|
+
]
|
|
4878
|
+
}
|
|
4879
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-1.5 group overflow-hidden w-full", title: col.name, children: [
|
|
4880
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center gap-1.5 min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ColumnHeaderTitle, { name: col.name, width: currentWidth, isSubTable: false }) }),
|
|
4881
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
4882
|
+
((_b = col.type) == null ? void 0 : _b.toUpperCase()) !== "SUB_TABLE" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4883
|
+
"button",
|
|
4884
|
+
{
|
|
4885
|
+
type: "button",
|
|
4886
|
+
onClick: (e) => {
|
|
4887
|
+
e.stopPropagation();
|
|
4888
|
+
e.preventDefault();
|
|
4889
|
+
setActiveSearchCol(col.name);
|
|
4890
|
+
},
|
|
4891
|
+
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"}`,
|
|
4892
|
+
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",
|
|
4893
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.Search, { className: "w-3.5 h-3.5" })
|
|
4894
|
+
}
|
|
4895
|
+
),
|
|
4896
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4897
|
+
"svg",
|
|
4898
|
+
{
|
|
4899
|
+
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
4900
|
+
fill: "none",
|
|
4901
|
+
viewBox: "0 0 24 24",
|
|
4902
|
+
stroke: "currentColor",
|
|
4903
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
|
|
4904
|
+
}
|
|
4905
|
+
)
|
|
4906
|
+
] })
|
|
3329
4907
|
] })
|
|
3330
4908
|
]
|
|
3331
|
-
},
|
|
4909
|
+
}),
|
|
3332
4910
|
col.name
|
|
3333
4911
|
);
|
|
3334
4912
|
}),
|
|
3335
|
-
/* @__PURE__ */ (0,
|
|
4913
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("th", { className: "w-full min-w-[50px] border-b border-slate-200 pointer-events-none h-12 min-h-[48px]" })
|
|
3336
4914
|
] }) }),
|
|
3337
|
-
/* @__PURE__ */ (0,
|
|
3338
|
-
/* @__PURE__ */ (0,
|
|
3339
|
-
/* @__PURE__ */ (0,
|
|
4915
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { colSpan: filteredColumns.length + 2, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
4916
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" }) }),
|
|
4917
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
|
|
3340
4918
|
] }) }) }) : filteredData.map((row) => {
|
|
3341
4919
|
const hasSubTableCols = filteredColumns.some((c) => {
|
|
3342
4920
|
var _a;
|
|
@@ -3347,10 +4925,20 @@ function TableBlockClient({
|
|
|
3347
4925
|
var _a;
|
|
3348
4926
|
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
3349
4927
|
});
|
|
3350
|
-
return /* @__PURE__ */ (0,
|
|
3351
|
-
/* @__PURE__ */ (0,
|
|
3352
|
-
/* @__PURE__ */ (0,
|
|
3353
|
-
|
|
4928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react12.default.Fragment, { children: [
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
|
|
4930
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
4931
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4932
|
+
"input",
|
|
4933
|
+
{
|
|
4934
|
+
type: "checkbox",
|
|
4935
|
+
checked: selectedIds.has(row.id),
|
|
4936
|
+
onChange: (e) => toggleSelectRow(row.id, e.target.checked),
|
|
4937
|
+
disabled: isLoading || isUpdatingActive,
|
|
4938
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
4939
|
+
}
|
|
4940
|
+
),
|
|
4941
|
+
hasSubTableCols && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3354
4942
|
"button",
|
|
3355
4943
|
{
|
|
3356
4944
|
type: "button",
|
|
@@ -3360,19 +4948,9 @@ function TableBlockClient({
|
|
|
3360
4948
|
else next.add(row.id);
|
|
3361
4949
|
return next;
|
|
3362
4950
|
}),
|
|
3363
|
-
className: "
|
|
4951
|
+
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",
|
|
3364
4952
|
title: isExpanded ? "\u05E1\u05D2\u05D5\u05E8 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4" : "\u05E4\u05EA\u05D7 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4",
|
|
3365
|
-
children: /* @__PURE__ */ (0,
|
|
3366
|
-
}
|
|
3367
|
-
),
|
|
3368
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3369
|
-
"input",
|
|
3370
|
-
{
|
|
3371
|
-
type: "checkbox",
|
|
3372
|
-
checked: selectedIds.has(row.id),
|
|
3373
|
-
onChange: (e) => toggleSelectRow(row.id, e.target.checked),
|
|
3374
|
-
disabled: isLoading || isUpdatingActive,
|
|
3375
|
-
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
4953
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "3", d: "M9 5l7 7-7 7" }) })
|
|
3376
4954
|
}
|
|
3377
4955
|
)
|
|
3378
4956
|
] }) }),
|
|
@@ -3380,6 +4958,8 @@ function TableBlockClient({
|
|
|
3380
4958
|
var _a;
|
|
3381
4959
|
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
3382
4960
|
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
4961
|
+
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
4962
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
3383
4963
|
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
3384
4964
|
if (value === void 0 && col.defaultValue !== void 0) {
|
|
3385
4965
|
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
@@ -3388,34 +4968,42 @@ function TableBlockClient({
|
|
|
3388
4968
|
}
|
|
3389
4969
|
}
|
|
3390
4970
|
if (value === void 0) value = null;
|
|
3391
|
-
return /* @__PURE__ */ (0,
|
|
3392
|
-
|
|
4971
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4972
|
+
"td",
|
|
3393
4973
|
{
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
4974
|
+
className: `border-b border-l border-slate-200 p-0 relative ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
4975
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
4976
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4977
|
+
InputComponent,
|
|
4978
|
+
{
|
|
4979
|
+
value,
|
|
4980
|
+
column: col,
|
|
4981
|
+
rowId: row.id,
|
|
4982
|
+
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
4983
|
+
context: {
|
|
4984
|
+
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",
|
|
4985
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
4986
|
+
onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
|
|
4987
|
+
relationOptions,
|
|
4988
|
+
refetchRelation,
|
|
4989
|
+
executeAction,
|
|
4990
|
+
emitEvent,
|
|
4991
|
+
pageState,
|
|
4992
|
+
componentId,
|
|
4993
|
+
orgId,
|
|
4994
|
+
updateQuietly: handleQuietCellChange,
|
|
4995
|
+
triggerSaveSuccess,
|
|
4996
|
+
rowData: row.data
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
)
|
|
5000
|
+
},
|
|
5001
|
+
col.name
|
|
5002
|
+
);
|
|
3415
5003
|
}),
|
|
3416
|
-
/* @__PURE__ */ (0,
|
|
5004
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
3417
5005
|
] }),
|
|
3418
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
5006
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3419
5007
|
ExpandedSubTables,
|
|
3420
5008
|
{
|
|
3421
5009
|
rowId: row.id,
|
|
@@ -3430,37 +5018,38 @@ function TableBlockClient({
|
|
|
3430
5018
|
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
3431
5019
|
rowData: row.data,
|
|
3432
5020
|
updateQuietly: handleQuietCellChange,
|
|
3433
|
-
triggerSaveSuccess
|
|
5021
|
+
triggerSaveSuccess,
|
|
5022
|
+
onUpdateColumnConfig: handleUpdateColumnConfig
|
|
3434
5023
|
}
|
|
3435
5024
|
}
|
|
3436
5025
|
)
|
|
3437
5026
|
] }, row.id);
|
|
3438
5027
|
}) }),
|
|
3439
|
-
showSummary && filteredData.length > 0 && /* @__PURE__ */ (0,
|
|
3440
|
-
/* @__PURE__ */ (0,
|
|
5028
|
+
showSummary && filteredData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsxs)("tr", { children: [
|
|
5029
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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' }),
|
|
3441
5030
|
filteredColumns.map((col) => {
|
|
3442
|
-
var _a;
|
|
5031
|
+
var _a, _b;
|
|
3443
5032
|
const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
|
|
3444
5033
|
const isNumeric = typeUpper === "CURRENCY" || typeUpper === "NUMBER";
|
|
3445
5034
|
const total = columnTotals[col.name];
|
|
3446
5035
|
let displayVal = "";
|
|
3447
5036
|
if (isNumeric && total !== void 0) {
|
|
3448
5037
|
displayVal = new Intl.NumberFormat("en-US").format(total);
|
|
3449
|
-
if (
|
|
3450
|
-
const symbol = getCurrencySymbol(col.currencySymbol);
|
|
5038
|
+
if (col.type === "CURRENCY") {
|
|
5039
|
+
const symbol = getCurrencySymbol((_b = col.config) == null ? void 0 : _b.currencySymbol);
|
|
3451
5040
|
displayVal = symbol ? `${symbol} ${displayVal}` : displayVal;
|
|
3452
5041
|
}
|
|
3453
5042
|
}
|
|
3454
|
-
return /* @__PURE__ */ (0,
|
|
5043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex items-center text-right justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "truncate", children: displayVal }) }) }, col.name);
|
|
3455
5044
|
}),
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
5045
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { className: "border-b border-slate-200 bg-slate-50 pointer-events-none" })
|
|
3457
5046
|
] }) })
|
|
3458
5047
|
] })
|
|
3459
5048
|
] }),
|
|
3460
|
-
/* @__PURE__ */ (0,
|
|
3461
|
-
/* @__PURE__ */ (0,
|
|
3462
|
-
/* @__PURE__ */ (0,
|
|
3463
|
-
/* @__PURE__ */ (0,
|
|
5049
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("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: [
|
|
5050
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5051
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-medium text-slate-700", children: "\u05E9\u05D5\u05E8\u05D5\u05EA \u05DC\u05E2\u05DE\u05D5\u05D3:" }),
|
|
5052
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3464
5053
|
"select",
|
|
3465
5054
|
{
|
|
3466
5055
|
value: limit,
|
|
@@ -3468,27 +5057,27 @@ function TableBlockClient({
|
|
|
3468
5057
|
disabled: isLoading || isUpdatingActive,
|
|
3469
5058
|
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",
|
|
3470
5059
|
children: [
|
|
3471
|
-
/* @__PURE__ */ (0,
|
|
3472
|
-
/* @__PURE__ */ (0,
|
|
3473
|
-
/* @__PURE__ */ (0,
|
|
5060
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: 20, children: "20" }),
|
|
5061
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: 50, children: "50" }),
|
|
5062
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: 100, children: "100" })
|
|
3474
5063
|
]
|
|
3475
5064
|
}
|
|
3476
5065
|
)
|
|
3477
5066
|
] }),
|
|
3478
|
-
/* @__PURE__ */ (0,
|
|
3479
|
-
/* @__PURE__ */ (0,
|
|
5067
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
5068
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-medium text-slate-600", children: [
|
|
3480
5069
|
"\u05E2\u05DE\u05D5\u05D3 ",
|
|
3481
|
-
/* @__PURE__ */ (0,
|
|
5070
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { className: "text-slate-900", children: page }),
|
|
3482
5071
|
" \u05DE\u05EA\u05D5\u05DA ",
|
|
3483
|
-
/* @__PURE__ */ (0,
|
|
3484
|
-
totalRecords > 0 && /* @__PURE__ */ (0,
|
|
5072
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { className: "text-slate-900", children: totalPages || 1 }),
|
|
5073
|
+
totalRecords > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-slate-500 font-normal", children: [
|
|
3485
5074
|
" (",
|
|
3486
5075
|
totalRecords,
|
|
3487
5076
|
' \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D1\u05E1\u05D4"\u05DB)'
|
|
3488
5077
|
] })
|
|
3489
5078
|
] }),
|
|
3490
|
-
/* @__PURE__ */ (0,
|
|
3491
|
-
/* @__PURE__ */ (0,
|
|
5079
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
5080
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3492
5081
|
"button",
|
|
3493
5082
|
{
|
|
3494
5083
|
onClick: handlePrevPage,
|
|
@@ -3498,7 +5087,7 @@ function TableBlockClient({
|
|
|
3498
5087
|
children: "\u05D4\u05E7\u05D5\u05D3\u05DD"
|
|
3499
5088
|
}
|
|
3500
5089
|
),
|
|
3501
|
-
/* @__PURE__ */ (0,
|
|
5090
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3502
5091
|
"button",
|
|
3503
5092
|
{
|
|
3504
5093
|
onClick: handleNextPage,
|
|
@@ -3524,11 +5113,11 @@ function ExpandedSubTables({
|
|
|
3524
5113
|
context
|
|
3525
5114
|
}) {
|
|
3526
5115
|
var _a;
|
|
3527
|
-
const [activeTab, setActiveTab] = (0,
|
|
5116
|
+
const [activeTab, setActiveTab] = (0, import_react12.useState)((_a = subTableColumns[0]) == null ? void 0 : _a.name);
|
|
3528
5117
|
if (subTableColumns.length === 0) return null;
|
|
3529
5118
|
if (subTableColumns.length === 1) {
|
|
3530
5119
|
const stCol = subTableColumns[0];
|
|
3531
|
-
return /* @__PURE__ */ (0,
|
|
5120
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3532
5121
|
SubTableViewer,
|
|
3533
5122
|
{
|
|
3534
5123
|
rowId,
|
|
@@ -3540,8 +5129,8 @@ function ExpandedSubTables({
|
|
|
3540
5129
|
) }) });
|
|
3541
5130
|
}
|
|
3542
5131
|
const activeCol = subTableColumns.find((c) => c.name === activeTab) || subTableColumns[0];
|
|
3543
|
-
return /* @__PURE__ */ (0,
|
|
3544
|
-
/* @__PURE__ */ (0,
|
|
5132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50 overflow-hidden", children: [
|
|
5133
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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__ */ (0, import_jsx_runtime10.jsx)(
|
|
3545
5134
|
"button",
|
|
3546
5135
|
{
|
|
3547
5136
|
type: "button",
|
|
@@ -3551,7 +5140,7 @@ function ExpandedSubTables({
|
|
|
3551
5140
|
},
|
|
3552
5141
|
col.name
|
|
3553
5142
|
)) }),
|
|
3554
|
-
/* @__PURE__ */ (0,
|
|
5143
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3555
5144
|
SubTableViewer,
|
|
3556
5145
|
{
|
|
3557
5146
|
rowId,
|
|
@@ -3566,9 +5155,9 @@ function ExpandedSubTables({
|
|
|
3566
5155
|
}
|
|
3567
5156
|
|
|
3568
5157
|
// src/components/TableBlock/TableBlock.tsx
|
|
3569
|
-
var
|
|
5158
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3570
5159
|
function TableBlock(props) {
|
|
3571
|
-
return /* @__PURE__ */ (0,
|
|
5160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableBlockClient, __spreadValues({}, props));
|
|
3572
5161
|
}
|
|
3573
5162
|
|
|
3574
5163
|
// src/registry.ts
|
|
@@ -3577,12 +5166,31 @@ var UNIVERSE_COMPONENTS = {
|
|
|
3577
5166
|
};
|
|
3578
5167
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3579
5168
|
0 && (module.exports = {
|
|
5169
|
+
ColumnHeaderTitle,
|
|
5170
|
+
DatePickerCell,
|
|
5171
|
+
LinkPickerCell,
|
|
5172
|
+
PASTEL_PALETTES,
|
|
5173
|
+
RelationPickerCell,
|
|
3580
5174
|
TableBlock,
|
|
5175
|
+
TimePickerCell,
|
|
3581
5176
|
ToastContext,
|
|
3582
5177
|
ToastProvider,
|
|
3583
5178
|
UNIVERSE_COMPONENTS,
|
|
5179
|
+
calculateMinColumnWidth,
|
|
3584
5180
|
cn,
|
|
5181
|
+
formatConflictCellValue,
|
|
3585
5182
|
formatPhoneDisplay,
|
|
5183
|
+
formatTimeInput,
|
|
5184
|
+
formatTimeIso,
|
|
5185
|
+
getDeterministicPastelBadge,
|
|
5186
|
+
measureTextWidth,
|
|
5187
|
+
normalizeRelationValue,
|
|
3586
5188
|
openWhatsAppChat,
|
|
5189
|
+
parseLinkValue,
|
|
5190
|
+
parseTimeParts,
|
|
5191
|
+
resolveProtocol,
|
|
5192
|
+
splitHeaderTitle,
|
|
5193
|
+
useColumnReorder,
|
|
5194
|
+
useColumnResize,
|
|
3587
5195
|
useToast
|
|
3588
5196
|
});
|