@universe-platform/ui 0.1.0-beta.6 → 0.1.0-beta.7
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 +111 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1079 -228
- package/dist/index.mjs +1077 -226
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ function cn(...inputs) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
80
|
-
var
|
|
80
|
+
var import_react7 = __toESM(require("react"));
|
|
81
81
|
|
|
82
82
|
// src/hooks/useToast.ts
|
|
83
83
|
var import_react2 = require("react");
|
|
@@ -280,12 +280,36 @@ function useToast() {
|
|
|
280
280
|
var import_react5 = __toESM(require("react"));
|
|
281
281
|
|
|
282
282
|
// src/components/TableBlock/fields/DrivePickerCell.tsx
|
|
283
|
-
var import_react3 = require("react");
|
|
283
|
+
var import_react3 = __toESM(require("react"));
|
|
284
284
|
var import_lucide_react2 = require("lucide-react");
|
|
285
285
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
286
|
-
function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, context }) {
|
|
286
|
+
function DrivePickerCell({ value, onChange, tableName, column, rowId, onMarkForDeletion, context }) {
|
|
287
287
|
const [isOpening, setIsOpening] = (0, import_react3.useState)(false);
|
|
288
288
|
const { showError } = useToast();
|
|
289
|
+
const cellContextId = import_react3.default.useMemo(() => {
|
|
290
|
+
const colName = (column == null ? void 0 : column.name) || "col";
|
|
291
|
+
const rId = rowId || "row";
|
|
292
|
+
return `${rId}-${colName}`;
|
|
293
|
+
}, [rowId, column == null ? void 0 : column.name]);
|
|
294
|
+
const fileList = import_react3.default.useMemo(() => {
|
|
295
|
+
if (!value) return [];
|
|
296
|
+
if (Array.isArray(value)) return value;
|
|
297
|
+
if (typeof value === "object" && (value.fileId || value.fileUrl || value.url)) {
|
|
298
|
+
return [value];
|
|
299
|
+
}
|
|
300
|
+
return [];
|
|
301
|
+
}, [value]);
|
|
302
|
+
(0, import_react3.useEffect)(() => {
|
|
303
|
+
const handleMessage = (event) => {
|
|
304
|
+
var _a, _b, _c;
|
|
305
|
+
if (((_a = event.data) == null ? void 0 : _a.type) === "DRIVE_UPLOAD_SUCCESS" && ((_b = event.data) == null ? void 0 : _b.payload) && ((_c = event.data) == null ? void 0 : _c.cellContextId) === cellContextId) {
|
|
306
|
+
const incoming = Array.isArray(event.data.payload) ? event.data.payload : [event.data.payload];
|
|
307
|
+
onChange([...fileList, ...incoming]);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
window.addEventListener("message", handleMessage);
|
|
311
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
312
|
+
}, [fileList, onChange, cellContextId]);
|
|
289
313
|
const openUploadPopup = async () => {
|
|
290
314
|
if (isOpening) return;
|
|
291
315
|
setIsOpening(true);
|
|
@@ -314,34 +338,35 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
|
|
|
314
338
|
} catch (e) {
|
|
315
339
|
}
|
|
316
340
|
}
|
|
317
|
-
const actionResult = await context.executeAction("UPLOAD_DRIVE_FILE", { tableName });
|
|
341
|
+
const actionResult = await context.executeAction("UPLOAD_DRIVE_FILE", { tableName, cellContextId });
|
|
318
342
|
const folderId = actionResult == null ? void 0 : actionResult.folderId;
|
|
319
|
-
|
|
343
|
+
let pickerUrl = (actionResult == null ? void 0 : actionResult.pickerUrl) || (folderId ? `/embed/picker?folderId=${encodeURIComponent(folderId)}` : `/embed/picker`);
|
|
344
|
+
if (!pickerUrl.includes("cellContextId=")) {
|
|
345
|
+
const separator = pickerUrl.includes("?") ? "&" : "?";
|
|
346
|
+
pickerUrl = `${pickerUrl}${separator}cellContextId=${encodeURIComponent(cellContextId)}`;
|
|
347
|
+
}
|
|
320
348
|
if (popup) {
|
|
321
349
|
popup.location.href = pickerUrl;
|
|
322
350
|
}
|
|
323
|
-
|
|
351
|
+
await new Promise((resolve) => {
|
|
324
352
|
let timer = null;
|
|
325
|
-
const
|
|
353
|
+
const handlePopupMessage = (event) => {
|
|
326
354
|
var _a, _b;
|
|
327
|
-
if (((_a = event.data) == null ? void 0 : _a.type) === "DRIVE_UPLOAD_SUCCESS" && ((_b = event.data) == null ? void 0 : _b.
|
|
328
|
-
window.removeEventListener("message",
|
|
355
|
+
if (((_a = event.data) == null ? void 0 : _a.type) === "DRIVE_UPLOAD_SUCCESS" && ((_b = event.data) == null ? void 0 : _b.cellContextId) === cellContextId) {
|
|
356
|
+
window.removeEventListener("message", handlePopupMessage);
|
|
329
357
|
if (timer) clearInterval(timer);
|
|
330
|
-
resolve(
|
|
358
|
+
resolve();
|
|
331
359
|
}
|
|
332
360
|
};
|
|
333
361
|
timer = setInterval(() => {
|
|
334
362
|
if (!popup || popup.closed) {
|
|
335
363
|
if (timer) clearInterval(timer);
|
|
336
|
-
window.removeEventListener("message",
|
|
337
|
-
resolve(
|
|
364
|
+
window.removeEventListener("message", handlePopupMessage);
|
|
365
|
+
resolve();
|
|
338
366
|
}
|
|
339
367
|
}, 800);
|
|
340
|
-
window.addEventListener("message",
|
|
368
|
+
window.addEventListener("message", handlePopupMessage);
|
|
341
369
|
});
|
|
342
|
-
if (newFile) {
|
|
343
|
-
onChange(newFile);
|
|
344
|
-
}
|
|
345
370
|
}
|
|
346
371
|
} catch (error) {
|
|
347
372
|
console.error("[DrivePickerCell] Error uploading file:", error);
|
|
@@ -351,40 +376,15 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
|
|
|
351
376
|
setIsOpening(false);
|
|
352
377
|
}
|
|
353
378
|
};
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
title: value.fileName || "Open file",
|
|
364
|
-
children: [
|
|
365
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.FileText, { className: "w-3.5 h-3.5 shrink-0" }),
|
|
366
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "truncate", children: value.fileName || "Unnamed file" })
|
|
367
|
-
]
|
|
368
|
-
}
|
|
369
|
-
),
|
|
370
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
371
|
-
"button",
|
|
372
|
-
{
|
|
373
|
-
type: "button",
|
|
374
|
-
onClick: () => {
|
|
375
|
-
if ((value == null ? void 0 : value.fileId) && onMarkForDeletion) {
|
|
376
|
-
onMarkForDeletion(value.fileId);
|
|
377
|
-
}
|
|
378
|
-
onChange(null);
|
|
379
|
-
},
|
|
380
|
-
className: "shrink-0 p-0.5 rounded hover:bg-rose-100 text-slate-400 hover:text-rose-500 transition-colors",
|
|
381
|
-
title: "Remove file",
|
|
382
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.X, { className: "w-3.5 h-3.5" })
|
|
383
|
-
}
|
|
384
|
-
)
|
|
385
|
-
] });
|
|
386
|
-
}
|
|
387
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center w-full h-8 px-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
379
|
+
const handleRemoveFile = (indexToRemove) => {
|
|
380
|
+
const fileToRemove = fileList[indexToRemove];
|
|
381
|
+
if ((fileToRemove == null ? void 0 : fileToRemove.fileId) && onMarkForDeletion) {
|
|
382
|
+
onMarkForDeletion(fileToRemove.fileId);
|
|
383
|
+
}
|
|
384
|
+
const updated = fileList.filter((_, idx) => idx !== indexToRemove);
|
|
385
|
+
onChange(updated);
|
|
386
|
+
};
|
|
387
|
+
const renderUploadButton = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center w-full h-8 px-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
388
388
|
"button",
|
|
389
389
|
{
|
|
390
390
|
type: "button",
|
|
@@ -397,6 +397,38 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
|
|
|
397
397
|
]
|
|
398
398
|
}
|
|
399
399
|
) });
|
|
400
|
+
if (fileList.length > 0) {
|
|
401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col w-full py-1 gap-1", children: [
|
|
402
|
+
fileList.map((file, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center w-full h-8 px-2 gap-1", children: [
|
|
403
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
404
|
+
"a",
|
|
405
|
+
{
|
|
406
|
+
href: file.fileUrl || file.url,
|
|
407
|
+
target: "_blank",
|
|
408
|
+
rel: "noopener noreferrer",
|
|
409
|
+
className: "inline-flex items-center gap-1.5 max-w-[calc(100%-24px)] px-2 py-1 rounded-md text-xs font-medium text-blue-700 bg-blue-50 hover:bg-blue-100 transition-colors truncate",
|
|
410
|
+
title: file.fileName || "Open file",
|
|
411
|
+
children: [
|
|
412
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.FileText, { className: "w-3.5 h-3.5 shrink-0" }),
|
|
413
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "truncate", children: file.fileName || "Unnamed file" })
|
|
414
|
+
]
|
|
415
|
+
}
|
|
416
|
+
),
|
|
417
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
418
|
+
"button",
|
|
419
|
+
{
|
|
420
|
+
type: "button",
|
|
421
|
+
onClick: () => handleRemoveFile(idx),
|
|
422
|
+
className: "shrink-0 p-0.5 rounded hover:bg-rose-100 text-slate-400 hover:text-rose-500 transition-colors",
|
|
423
|
+
title: "Remove file",
|
|
424
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.X, { className: "w-3.5 h-3.5" })
|
|
425
|
+
}
|
|
426
|
+
)
|
|
427
|
+
] }, file.fileId || idx)),
|
|
428
|
+
renderUploadButton()
|
|
429
|
+
] });
|
|
430
|
+
}
|
|
431
|
+
return renderUploadButton();
|
|
400
432
|
}
|
|
401
433
|
|
|
402
434
|
// src/components/TableBlock/fields/DatePickerCell.tsx
|
|
@@ -831,11 +863,13 @@ var FORM_INPUTS = {
|
|
|
831
863
|
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
832
864
|
}
|
|
833
865
|
) }),
|
|
834
|
-
GOOGLE_DRIVE_FILE: ({ value, onChange, context }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
866
|
+
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
835
867
|
DrivePickerCell,
|
|
836
868
|
{
|
|
837
|
-
value: value ||
|
|
869
|
+
value: value || [],
|
|
838
870
|
onChange,
|
|
871
|
+
column,
|
|
872
|
+
rowId,
|
|
839
873
|
tableName: context == null ? void 0 : context.tableName,
|
|
840
874
|
onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
|
|
841
875
|
context
|
|
@@ -893,6 +927,228 @@ var FORM_INPUTS = {
|
|
|
893
927
|
}
|
|
894
928
|
}
|
|
895
929
|
),
|
|
930
|
+
PHONE: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
931
|
+
"input",
|
|
932
|
+
{
|
|
933
|
+
type: "tel",
|
|
934
|
+
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
935
|
+
value: value !== void 0 && value !== null ? String(value) : "",
|
|
936
|
+
onChange: (e) => onChange(e.target.value),
|
|
937
|
+
dir: "ltr"
|
|
938
|
+
}
|
|
939
|
+
),
|
|
940
|
+
GOOGLE_CONTACT: ({ value, column, rowId, onChange, context }) => {
|
|
941
|
+
const [isSyncing, setIsSyncing] = import_react5.default.useState(false);
|
|
942
|
+
const { addToast } = useToast();
|
|
943
|
+
const googleClientIdRef = import_react5.default.useRef(null);
|
|
944
|
+
const ensureGisScript = import_react5.default.useCallback(() => {
|
|
945
|
+
return new Promise((resolve, reject) => {
|
|
946
|
+
var _a, _b, _c;
|
|
947
|
+
if ((_c = (_b = (_a = window.google) == null ? void 0 : _a.accounts) == null ? void 0 : _b.oauth2) == null ? void 0 : _c.initTokenClient) {
|
|
948
|
+
resolve();
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
if (document.querySelector('script[src*="accounts.google.com/gsi/client"]')) {
|
|
952
|
+
const waitForLoad = setInterval(() => {
|
|
953
|
+
var _a2, _b2, _c2;
|
|
954
|
+
if ((_c2 = (_b2 = (_a2 = window.google) == null ? void 0 : _a2.accounts) == null ? void 0 : _b2.oauth2) == null ? void 0 : _c2.initTokenClient) {
|
|
955
|
+
clearInterval(waitForLoad);
|
|
956
|
+
resolve();
|
|
957
|
+
}
|
|
958
|
+
}, 100);
|
|
959
|
+
setTimeout(() => {
|
|
960
|
+
clearInterval(waitForLoad);
|
|
961
|
+
reject(new Error("GIS script load timeout"));
|
|
962
|
+
}, 1e4);
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const script = document.createElement("script");
|
|
966
|
+
script.src = "https://accounts.google.com/gsi/client";
|
|
967
|
+
script.async = true;
|
|
968
|
+
script.onload = () => resolve();
|
|
969
|
+
script.onerror = () => reject(new Error("Failed to load Google Identity Services"));
|
|
970
|
+
document.head.appendChild(script);
|
|
971
|
+
});
|
|
972
|
+
}, []);
|
|
973
|
+
const requestGisToken = import_react5.default.useCallback(async (hint) => {
|
|
974
|
+
await ensureGisScript();
|
|
975
|
+
if (!googleClientIdRef.current && (context == null ? void 0 : context.executeAction)) {
|
|
976
|
+
try {
|
|
977
|
+
const config = await context.executeAction("GET_GOOGLE_CONFIG", {});
|
|
978
|
+
googleClientIdRef.current = (config == null ? void 0 : config.clientId) || "";
|
|
979
|
+
} catch (e) {
|
|
980
|
+
throw new Error("Failed to fetch Google configuration");
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
const clientId = googleClientIdRef.current;
|
|
984
|
+
if (!clientId) {
|
|
985
|
+
throw new Error("Google Client ID is not configured");
|
|
986
|
+
}
|
|
987
|
+
const accessToken = await new Promise((resolve, reject) => {
|
|
988
|
+
const tokenClient = window.google.accounts.oauth2.initTokenClient({
|
|
989
|
+
client_id: clientId,
|
|
990
|
+
scope: "https://www.googleapis.com/auth/contacts https://www.googleapis.com/auth/userinfo.email",
|
|
991
|
+
prompt: hint ? "" : "select_account",
|
|
992
|
+
hint: hint || void 0,
|
|
993
|
+
callback: (tokenResponse) => {
|
|
994
|
+
if (tokenResponse == null ? void 0 : tokenResponse.access_token) {
|
|
995
|
+
resolve(tokenResponse.access_token);
|
|
996
|
+
} else {
|
|
997
|
+
reject(new Error("Google authorization was cancelled or failed"));
|
|
998
|
+
}
|
|
999
|
+
},
|
|
1000
|
+
error_callback: (err) => {
|
|
1001
|
+
reject(new Error((err == null ? void 0 : err.message) || "Google authorization error"));
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
tokenClient.requestAccessToken({ hint: hint || void 0 });
|
|
1005
|
+
});
|
|
1006
|
+
let email = "";
|
|
1007
|
+
try {
|
|
1008
|
+
const res = await fetch("https://www.googleapis.com/oauth2/v3/userinfo", {
|
|
1009
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
1010
|
+
});
|
|
1011
|
+
if (res.ok) {
|
|
1012
|
+
const info = await res.json();
|
|
1013
|
+
email = info.email || "";
|
|
1014
|
+
}
|
|
1015
|
+
} catch (e) {
|
|
1016
|
+
}
|
|
1017
|
+
return { accessToken, email };
|
|
1018
|
+
}, [ensureGisScript, context]);
|
|
1019
|
+
const handleSync = async () => {
|
|
1020
|
+
var _a, _b, _c;
|
|
1021
|
+
if (!(context == null ? void 0 : context.executeAction)) return;
|
|
1022
|
+
setIsSyncing(true);
|
|
1023
|
+
try {
|
|
1024
|
+
const mapping = column.contactMapping || {};
|
|
1025
|
+
const rowData = context.rowData || {};
|
|
1026
|
+
let hasPhone = false;
|
|
1027
|
+
if (mapping.phoneCol && rowData[mapping.phoneCol]) hasPhone = true;
|
|
1028
|
+
let hasName = false;
|
|
1029
|
+
if (mapping.nameParts && Array.isArray(mapping.nameParts)) {
|
|
1030
|
+
for (const part of mapping.nameParts) {
|
|
1031
|
+
if (part.type === "LOCAL" && rowData[part.columnId]) hasName = true;
|
|
1032
|
+
if (part.type === "PARENT" && ((_a = context.parentRecord) == null ? void 0 : _a.tableId) === part.parentTableId && ((_c = (_b = context.parentRecord) == null ? void 0 : _b.data) == null ? void 0 : _c[part.columnId])) hasName = true;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
if (!hasPhone) {
|
|
1036
|
+
addToast({ type: "warning", message: "\u05E0\u05D0 \u05DC\u05DE\u05DC\u05D0 \u05DE\u05E1\u05E4\u05E8 \u05D8\u05DC\u05E4\u05D5\u05DF \u05DB\u05D3\u05D9 \u05DC\u05E1\u05E0\u05DB\u05E8\u05DF \u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8 \u05DC\u05D2\u05D5\u05D2\u05DC" });
|
|
1037
|
+
setIsSyncing(false);
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (!hasName) {
|
|
1041
|
+
addToast({ type: "warning", message: "\u05E0\u05D0 \u05DC\u05DE\u05DC\u05D0 \u05E9\u05DD \u05DB\u05D3\u05D9 \u05DC\u05E1\u05E0\u05DB\u05E8\u05DF \u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8 \u05DC\u05D2\u05D5\u05D2\u05DC" });
|
|
1042
|
+
setIsSyncing(false);
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
let accessToken;
|
|
1046
|
+
let userEmail = "";
|
|
1047
|
+
try {
|
|
1048
|
+
const gisResult = await requestGisToken();
|
|
1049
|
+
accessToken = gisResult.accessToken;
|
|
1050
|
+
userEmail = gisResult.email;
|
|
1051
|
+
} catch (gisError) {
|
|
1052
|
+
addToast({ type: "warning", message: gisError.message || "\u05D4\u05D4\u05E8\u05E9\u05D0\u05D4 \u05DC\u05D2\u05D5\u05D2\u05DC \u05E0\u05DB\u05E9\u05DC\u05D4" });
|
|
1053
|
+
setIsSyncing(false);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
const payload = {
|
|
1057
|
+
nameParts: mapping.nameParts || [],
|
|
1058
|
+
phoneCol: mapping.phoneCol,
|
|
1059
|
+
emailCol: mapping.emailCol,
|
|
1060
|
+
localRowData: rowData,
|
|
1061
|
+
parentRecord: context.parentRecord,
|
|
1062
|
+
accessToken,
|
|
1063
|
+
userEmail
|
|
1064
|
+
};
|
|
1065
|
+
const res = await context.executeAction("SYNC_GOOGLE_CONTACT", payload);
|
|
1066
|
+
if (res && res.synced) {
|
|
1067
|
+
if (context.updateQuietly) {
|
|
1068
|
+
context.updateQuietly(rowId, column.name, res);
|
|
1069
|
+
} else {
|
|
1070
|
+
onChange(res);
|
|
1071
|
+
}
|
|
1072
|
+
if (context.tableId && !rowId.startsWith("temp_")) {
|
|
1073
|
+
await context.executeAction("UPDATE_RECORD", {
|
|
1074
|
+
tableId: context.tableId,
|
|
1075
|
+
recordId: rowId,
|
|
1076
|
+
data: { [column.name]: res }
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
} catch (error) {
|
|
1081
|
+
console.error("Failed to sync contact:", error);
|
|
1082
|
+
addToast({ type: "warning", message: "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E1\u05E0\u05DB\u05E8\u05D5\u05DF \u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8: " + error.message });
|
|
1083
|
+
} finally {
|
|
1084
|
+
setIsSyncing(false);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
const handleUnlink = async () => {
|
|
1088
|
+
let accessToken;
|
|
1089
|
+
try {
|
|
1090
|
+
let emailHint = value == null ? void 0 : value.userEmail;
|
|
1091
|
+
if (!emailHint && (value == null ? void 0 : value.url)) {
|
|
1092
|
+
try {
|
|
1093
|
+
const parsed = new URL(value.url);
|
|
1094
|
+
emailHint = parsed.searchParams.get("authuser") || void 0;
|
|
1095
|
+
} catch (e) {
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
const auth = await requestGisToken(emailHint);
|
|
1099
|
+
accessToken = auth.accessToken;
|
|
1100
|
+
} catch (err) {
|
|
1101
|
+
console.warn("[handleUnlink] Could not obtain token via GIS, falling back to server default token:", err);
|
|
1102
|
+
}
|
|
1103
|
+
if ((value == null ? void 0 : value.resourceName) && (context == null ? void 0 : context.executeAction)) {
|
|
1104
|
+
await context.executeAction("DELETE_GOOGLE_CONTACT", {
|
|
1105
|
+
resourceName: value.resourceName,
|
|
1106
|
+
accessToken
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
1110
|
+
context.updateQuietly(rowId, column.name, null);
|
|
1111
|
+
} else {
|
|
1112
|
+
onChange(null);
|
|
1113
|
+
}
|
|
1114
|
+
if ((context == null ? void 0 : context.tableId) && (context == null ? void 0 : context.executeAction) && !rowId.startsWith("temp_")) {
|
|
1115
|
+
await context.executeAction("UPDATE_RECORD", {
|
|
1116
|
+
tableId: context.tableId,
|
|
1117
|
+
recordId: rowId,
|
|
1118
|
+
data: { [column.name]: null }
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
if (value && value.synced && value.url) {
|
|
1123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 h-8 px-2 group", children: [
|
|
1124
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: value.url, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:underline flex-1 truncate text-sm", children: "\u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8 \u05D2\u05D5\u05D2\u05DC" }),
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1126
|
+
"button",
|
|
1127
|
+
{
|
|
1128
|
+
onClick: handleUnlink,
|
|
1129
|
+
className: "text-slate-400 hover:text-rose-500 opacity-0 group-hover:opacity-100 transition-opacity p-1",
|
|
1130
|
+
title: "\u05D1\u05D8\u05DC \u05E1\u05E0\u05DB\u05E8\u05D5\u05DF",
|
|
1131
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
1132
|
+
}
|
|
1133
|
+
)
|
|
1134
|
+
] });
|
|
1135
|
+
}
|
|
1136
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center h-8 px-2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1137
|
+
"button",
|
|
1138
|
+
{
|
|
1139
|
+
onClick: handleSync,
|
|
1140
|
+
disabled: isSyncing,
|
|
1141
|
+
className: "flex items-center gap-1.5 px-3 py-1 bg-blue-50 text-blue-600 hover:bg-blue-100 border border-blue-200 rounded-md text-xs font-medium transition-colors disabled:opacity-50",
|
|
1142
|
+
children: [
|
|
1143
|
+
isSyncing ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { className: "w-3.5 h-3.5 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
|
|
1144
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.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" })
|
|
1146
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 4v16m8-8H4" }) }),
|
|
1147
|
+
"\u05E1\u05E0\u05DB\u05E8\u05DF \u05DC\u05D2\u05D5\u05D2\u05DC"
|
|
1148
|
+
]
|
|
1149
|
+
}
|
|
1150
|
+
) });
|
|
1151
|
+
},
|
|
896
1152
|
DEFAULT: ({ value, onChange }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
897
1153
|
"input",
|
|
898
1154
|
{
|
|
@@ -901,12 +1157,459 @@ var FORM_INPUTS = {
|
|
|
901
1157
|
value: value !== void 0 && value !== null ? String(value) : "",
|
|
902
1158
|
onChange: (e) => onChange(e.target.value)
|
|
903
1159
|
}
|
|
904
|
-
)
|
|
1160
|
+
),
|
|
1161
|
+
SUB_TABLE: ({ value, column }) => {
|
|
1162
|
+
if (!Array.isArray(value)) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
1163
|
+
const selected = value.filter((e) => e == null ? void 0 : e.isSelected);
|
|
1164
|
+
if (selected.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
1165
|
+
const displayFields = column.subTableDisplayFields || [];
|
|
1166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "px-1.5 py-1 flex flex-wrap items-center gap-1 h-full", children: selected.map((entry, idx) => {
|
|
1167
|
+
var _a;
|
|
1168
|
+
let label = "";
|
|
1169
|
+
if (entry._resolvedData && displayFields.length > 0) {
|
|
1170
|
+
label = displayFields.map((f) => String(entry._resolvedData[f] || "")).filter(Boolean).join(" ");
|
|
1171
|
+
}
|
|
1172
|
+
if (!label) label = ((_a = entry.recordId) == null ? void 0 : _a.slice(-6)) || "...";
|
|
1173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1174
|
+
"span",
|
|
1175
|
+
{
|
|
1176
|
+
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-[140px] truncate",
|
|
1177
|
+
title: label,
|
|
1178
|
+
children: label
|
|
1179
|
+
},
|
|
1180
|
+
entry.recordId || idx
|
|
1181
|
+
);
|
|
1182
|
+
}) });
|
|
1183
|
+
}
|
|
905
1184
|
};
|
|
906
1185
|
|
|
1186
|
+
// src/components/TableBlock/fields/SubTableViewer.tsx
|
|
1187
|
+
var import_react6 = require("react");
|
|
1188
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1189
|
+
function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
1190
|
+
var _a;
|
|
1191
|
+
const { addToast } = useToast();
|
|
1192
|
+
const entries = Array.isArray(value) ? value : [];
|
|
1193
|
+
const [linkedRecords, setLinkedRecords] = (0, import_react6.useState)([]);
|
|
1194
|
+
const [targetSchema, setTargetSchema] = (0, import_react6.useState)(null);
|
|
1195
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(true);
|
|
1196
|
+
const [isSearchOpen, setIsSearchOpen] = (0, import_react6.useState)(false);
|
|
1197
|
+
const [searchQuery, setSearchQuery] = (0, import_react6.useState)("");
|
|
1198
|
+
const [searchResults, setSearchResults] = (0, import_react6.useState)([]);
|
|
1199
|
+
const [isSearching, setIsSearching] = (0, import_react6.useState)(false);
|
|
1200
|
+
const [isCreating, setIsCreating] = (0, import_react6.useState)(false);
|
|
1201
|
+
const [newRecordData, setNewRecordData] = (0, import_react6.useState)({});
|
|
1202
|
+
const searchRef = (0, import_react6.useRef)(null);
|
|
1203
|
+
const searchTimerRef = (0, import_react6.useRef)(null);
|
|
1204
|
+
const executeAction = context == null ? void 0 : context.executeAction;
|
|
1205
|
+
const referencedTableId = column.referencedTableId;
|
|
1206
|
+
const fetchedIdsRef = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1207
|
+
(0, import_react6.useEffect)(() => {
|
|
1208
|
+
if (!referencedTableId || !executeAction) {
|
|
1209
|
+
setIsLoading(false);
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const recordIdsToFetch = entries.map((e) => e.recordId).filter((id) => !fetchedIdsRef.current.has(id));
|
|
1213
|
+
if (recordIdsToFetch.length === 0 && targetSchema) return;
|
|
1214
|
+
if (recordIdsToFetch.length > 0) {
|
|
1215
|
+
recordIdsToFetch.forEach((id) => fetchedIdsRef.current.add(id));
|
|
1216
|
+
}
|
|
1217
|
+
setIsLoading(true);
|
|
1218
|
+
executeAction("FETCH_SUB_TABLE_RECORDS", { referencedTableId, recordIds: recordIdsToFetch }).then((res) => {
|
|
1219
|
+
const payload = (res == null ? void 0 : res.data) || res;
|
|
1220
|
+
if (payload == null ? void 0 : payload.records) {
|
|
1221
|
+
setLinkedRecords((prev) => {
|
|
1222
|
+
const map = new Map(prev.map((r) => [r.id, r]));
|
|
1223
|
+
payload.records.forEach((r) => map.set(r.id, r));
|
|
1224
|
+
return Array.from(map.values());
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
if (payload == null ? void 0 : payload.schema) {
|
|
1228
|
+
setTargetSchema(payload.schema);
|
|
1229
|
+
}
|
|
1230
|
+
}).catch(() => {
|
|
1231
|
+
recordIdsToFetch.forEach((id) => fetchedIdsRef.current.delete(id));
|
|
1232
|
+
}).finally(() => setIsLoading(false));
|
|
1233
|
+
}, [referencedTableId, executeAction, entries, targetSchema]);
|
|
1234
|
+
(0, import_react6.useEffect)(() => {
|
|
1235
|
+
const handleClick = (e) => {
|
|
1236
|
+
if (searchRef.current && !searchRef.current.contains(e.target)) {
|
|
1237
|
+
setIsSearchOpen(false);
|
|
1238
|
+
}
|
|
1239
|
+
};
|
|
1240
|
+
if (isSearchOpen) document.addEventListener("mousedown", handleClick);
|
|
1241
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
1242
|
+
}, [isSearchOpen]);
|
|
1243
|
+
const handleSearch = (0, import_react6.useCallback)((query) => {
|
|
1244
|
+
setSearchQuery(query);
|
|
1245
|
+
if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
|
|
1246
|
+
if (!query.trim()) {
|
|
1247
|
+
setSearchResults([]);
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
searchTimerRef.current = setTimeout(async () => {
|
|
1251
|
+
if (!executeAction || !referencedTableId) return;
|
|
1252
|
+
setIsSearching(true);
|
|
1253
|
+
try {
|
|
1254
|
+
const excludeIds = entries.map((e) => e.recordId);
|
|
1255
|
+
const res = await executeAction("SEARCH_SUB_TABLE_RECORDS", {
|
|
1256
|
+
referencedTableId,
|
|
1257
|
+
query: query.trim(),
|
|
1258
|
+
excludeIds,
|
|
1259
|
+
limit: 15
|
|
1260
|
+
});
|
|
1261
|
+
setSearchResults(Array.isArray(res) ? res : []);
|
|
1262
|
+
} catch (e) {
|
|
1263
|
+
setSearchResults([]);
|
|
1264
|
+
} finally {
|
|
1265
|
+
setIsSearching(false);
|
|
1266
|
+
}
|
|
1267
|
+
}, 300);
|
|
1268
|
+
}, [executeAction, referencedTableId, entries]);
|
|
1269
|
+
const targetColumns = ((targetSchema == null ? void 0 : targetSchema.columns) || []).filter(
|
|
1270
|
+
(c) => {
|
|
1271
|
+
if (c.name === "_id" || c.type === "SUB_TABLE") return false;
|
|
1272
|
+
return true;
|
|
1273
|
+
}
|
|
1274
|
+
);
|
|
1275
|
+
const [relationOptions, setRelationOptions] = (0, import_react6.useState)({});
|
|
1276
|
+
(0, import_react6.useEffect)(() => {
|
|
1277
|
+
if (!executeAction || targetColumns.length === 0) return;
|
|
1278
|
+
const relationCols = targetColumns.filter((c) => {
|
|
1279
|
+
var _a2;
|
|
1280
|
+
return ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION" && c.referencedTableId;
|
|
1281
|
+
});
|
|
1282
|
+
relationCols.forEach(async (col) => {
|
|
1283
|
+
try {
|
|
1284
|
+
const options = await executeAction("FETCH_RELATION", {
|
|
1285
|
+
referencedTableId: col.referencedTableId,
|
|
1286
|
+
displayField: col.displayField
|
|
1287
|
+
});
|
|
1288
|
+
if (options && Array.isArray(options)) {
|
|
1289
|
+
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
1290
|
+
}
|
|
1291
|
+
} catch (err) {
|
|
1292
|
+
console.warn(`[SubTableViewer] Could not fetch relation options for column ${col.name}:`, err);
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
}, [executeAction, targetColumns]);
|
|
1296
|
+
const refetchRelation = (0, import_react6.useCallback)(async (colName) => {
|
|
1297
|
+
var _a2;
|
|
1298
|
+
const col = targetColumns.find((c) => c.name === colName);
|
|
1299
|
+
if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !col.referencedTableId || !executeAction) return;
|
|
1300
|
+
try {
|
|
1301
|
+
const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
|
|
1302
|
+
if (options && Array.isArray(options)) {
|
|
1303
|
+
setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
|
|
1304
|
+
}
|
|
1305
|
+
} catch (err) {
|
|
1306
|
+
console.warn(`[SubTableViewer] Could not refetch relation options for column ${col.name}:`, err);
|
|
1307
|
+
}
|
|
1308
|
+
}, [targetColumns, executeAction]);
|
|
1309
|
+
const updateParentLinkage = async (updated) => {
|
|
1310
|
+
const isNewRow = rowId.startsWith("temp_");
|
|
1311
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
1312
|
+
context.updateQuietly(rowId, column.name, updated);
|
|
1313
|
+
} else {
|
|
1314
|
+
onChange(updated);
|
|
1315
|
+
}
|
|
1316
|
+
if (executeAction && (context == null ? void 0 : context.parentTableId) && !isNewRow) {
|
|
1317
|
+
try {
|
|
1318
|
+
const payloadToSave = updated.map(({ recordId, isSelected }) => ({ recordId, isSelected }));
|
|
1319
|
+
await executeAction("UPDATE_RECORD", {
|
|
1320
|
+
tableId: context.parentTableId,
|
|
1321
|
+
recordId: rowId,
|
|
1322
|
+
data: { [column.name]: payloadToSave }
|
|
1323
|
+
});
|
|
1324
|
+
if (context == null ? void 0 : context.triggerSaveSuccess) {
|
|
1325
|
+
context.triggerSaveSuccess();
|
|
1326
|
+
}
|
|
1327
|
+
} catch (err) {
|
|
1328
|
+
console.error("Failed to auto-save parent linkage", err);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
const handleLinkRecord = (record) => {
|
|
1333
|
+
fetchedIdsRef.current.add(record.id);
|
|
1334
|
+
const newEntry = { recordId: record.id, isSelected: true, _resolvedData: record.data };
|
|
1335
|
+
const updated = [...entries, newEntry];
|
|
1336
|
+
updateParentLinkage(updated);
|
|
1337
|
+
setLinkedRecords((prev) => {
|
|
1338
|
+
const exists = prev.find((r) => r.id === record.id);
|
|
1339
|
+
if (exists) return prev;
|
|
1340
|
+
return [...prev, record];
|
|
1341
|
+
});
|
|
1342
|
+
setSearchQuery("");
|
|
1343
|
+
setSearchResults([]);
|
|
1344
|
+
setIsSearchOpen(false);
|
|
1345
|
+
};
|
|
1346
|
+
const handleUnlinkRecord = (recordId) => {
|
|
1347
|
+
const updated = entries.filter((e) => e.recordId !== recordId);
|
|
1348
|
+
updateParentLinkage(updated);
|
|
1349
|
+
setLinkedRecords((prev) => prev.filter((r) => r.id !== recordId));
|
|
1350
|
+
};
|
|
1351
|
+
const handleToggleSelected = (recordId) => {
|
|
1352
|
+
const record = linkedRecords.find((r) => r.id === recordId);
|
|
1353
|
+
const updated = entries.map(
|
|
1354
|
+
(e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { isSelected: !e.isSelected, _resolvedData: (record == null ? void 0 : record.data) || e._resolvedData }) : e
|
|
1355
|
+
);
|
|
1356
|
+
updateParentLinkage(updated);
|
|
1357
|
+
};
|
|
1358
|
+
const handleRecordCellChange = async (recordId, colName, value2) => {
|
|
1359
|
+
const updatedRecords = linkedRecords.map(
|
|
1360
|
+
(r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r
|
|
1361
|
+
);
|
|
1362
|
+
setLinkedRecords(updatedRecords);
|
|
1363
|
+
const targetRecord = updatedRecords.find((r) => r.id === recordId);
|
|
1364
|
+
const updatedEntries = entries.map(
|
|
1365
|
+
(e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { _resolvedData: targetRecord == null ? void 0 : targetRecord.data }) : e
|
|
1366
|
+
);
|
|
1367
|
+
if (context == null ? void 0 : context.updateQuietly) {
|
|
1368
|
+
context.updateQuietly(rowId, column.name, updatedEntries);
|
|
1369
|
+
} else {
|
|
1370
|
+
onChange(updatedEntries);
|
|
1371
|
+
}
|
|
1372
|
+
if (executeAction && referencedTableId && !recordId.startsWith("temp_")) {
|
|
1373
|
+
try {
|
|
1374
|
+
await executeAction("UPDATE_RECORD", {
|
|
1375
|
+
tableId: referencedTableId,
|
|
1376
|
+
recordId,
|
|
1377
|
+
data: { [colName]: value2 }
|
|
1378
|
+
});
|
|
1379
|
+
if (context == null ? void 0 : context.triggerSaveSuccess) {
|
|
1380
|
+
context.triggerSaveSuccess();
|
|
1381
|
+
}
|
|
1382
|
+
} catch (err) {
|
|
1383
|
+
console.error("[SubTableViewer] Failed to auto-save linked record field", err);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
};
|
|
1387
|
+
const handleCreateRecord = async () => {
|
|
1388
|
+
var _a2;
|
|
1389
|
+
if (!executeAction || !referencedTableId) return;
|
|
1390
|
+
for (const col of targetColumns) {
|
|
1391
|
+
if (col.isRequired) {
|
|
1392
|
+
const val = newRecordData[col.name];
|
|
1393
|
+
if (val === void 0 || val === null || typeof val === "string" && val.trim() === "") {
|
|
1394
|
+
addToast({
|
|
1395
|
+
type: "error",
|
|
1396
|
+
message: `Validation Error: Field '${col.name}' is required but was not provided.`
|
|
1397
|
+
});
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
try {
|
|
1403
|
+
const res = await executeAction("CREATE_RECORD", {
|
|
1404
|
+
tableId: referencedTableId,
|
|
1405
|
+
records: [newRecordData]
|
|
1406
|
+
});
|
|
1407
|
+
if (res && res.success === false) {
|
|
1408
|
+
throw new Error(res.error || "Action execution failed");
|
|
1409
|
+
}
|
|
1410
|
+
const created = Array.isArray(res) ? res[0] : ((_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2[0]) || res;
|
|
1411
|
+
if (created) {
|
|
1412
|
+
const newRecord = {
|
|
1413
|
+
id: String(created.id || created._id),
|
|
1414
|
+
data: created.data || newRecordData
|
|
1415
|
+
};
|
|
1416
|
+
handleLinkRecord(newRecord);
|
|
1417
|
+
setIsCreating(false);
|
|
1418
|
+
setNewRecordData({});
|
|
1419
|
+
}
|
|
1420
|
+
} catch (err) {
|
|
1421
|
+
const msg = (err == null ? void 0 : err.message) || String(err);
|
|
1422
|
+
addToast({
|
|
1423
|
+
type: "error",
|
|
1424
|
+
message: msg
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
const getDisplayLabel = (record) => {
|
|
1429
|
+
const fields = column.subTableDisplayFields || [];
|
|
1430
|
+
if (fields.length === 0) {
|
|
1431
|
+
const firstField = Object.keys(record.data).find((k) => k !== "_id");
|
|
1432
|
+
return firstField ? String(record.data[firstField] || "") : record.id;
|
|
1433
|
+
}
|
|
1434
|
+
return fields.map((f) => String(record.data[f] || "")).filter(Boolean).join(" ");
|
|
1435
|
+
};
|
|
1436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "p-3 animate-in fade-in slide-in-from-top-2 duration-200", dir: "rtl", children: [
|
|
1437
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-4 mb-2.5", children: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-xs font-bold text-slate-600", children: (_a = targetSchema == null ? void 0 : targetSchema.name) != null ? _a : column.referencedTableName }) }),
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative", ref: searchRef, children: [
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1442
|
+
"button",
|
|
1443
|
+
{
|
|
1444
|
+
type: "button",
|
|
1445
|
+
onClick: () => setIsSearchOpen((prev) => !prev),
|
|
1446
|
+
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",
|
|
1447
|
+
children: [
|
|
1448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
|
|
1449
|
+
"\u05E7\u05D9\u05E9\u05D5\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA"
|
|
1450
|
+
]
|
|
1451
|
+
}
|
|
1452
|
+
),
|
|
1453
|
+
isSearchOpen && /* @__PURE__ */ (0, import_jsx_runtime5.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: [
|
|
1454
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1455
|
+
"input",
|
|
1456
|
+
{
|
|
1457
|
+
type: "text",
|
|
1458
|
+
value: searchQuery,
|
|
1459
|
+
onChange: (e) => handleSearch(e.target.value),
|
|
1460
|
+
placeholder: "\u05D7\u05E4\u05E9 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
1461
|
+
className: "w-full h-8 px-2.5 text-xs border border-slate-300 rounded-md focus:outline-none focus:ring-1 focus:ring-blue-400 mb-1.5",
|
|
1462
|
+
autoFocus: true
|
|
1463
|
+
}
|
|
1464
|
+
),
|
|
1465
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "max-h-48 overflow-y-auto", children: isSearching ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ (0, import_jsx_runtime5.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_runtime5.jsx)(
|
|
1466
|
+
"button",
|
|
1467
|
+
{
|
|
1468
|
+
type: "button",
|
|
1469
|
+
onClick: () => handleLinkRecord(r),
|
|
1470
|
+
className: "w-full text-right px-2 py-1.5 text-xs hover:bg-blue-50 rounded cursor-pointer transition-colors",
|
|
1471
|
+
children: getDisplayLabel(r)
|
|
1472
|
+
},
|
|
1473
|
+
r.id
|
|
1474
|
+
)) : searchQuery.trim() ? /* @__PURE__ */ (0, import_jsx_runtime5.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_runtime5.jsx)("p", { className: "text-xs text-slate-400 text-center py-3", children: "\u05D4\u05E7\u05DC\u05D3 \u05DC\u05D7\u05D9\u05E4\u05D5\u05E9..." }) })
|
|
1475
|
+
] })
|
|
1476
|
+
] }),
|
|
1477
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1478
|
+
"button",
|
|
1479
|
+
{
|
|
1480
|
+
type: "button",
|
|
1481
|
+
onClick: () => {
|
|
1482
|
+
setIsCreating(true);
|
|
1483
|
+
const initialData = {};
|
|
1484
|
+
targetColumns.forEach((c) => {
|
|
1485
|
+
if (c.defaultValue !== void 0 && c.defaultValue !== null) {
|
|
1486
|
+
initialData[c.name] = c.type === "NUMBER" || c.type === "CURRENCY" ? parseFloat(c.defaultValue) : c.type === "BOOLEAN" ? c.defaultValue === "true" || c.defaultValue === true : c.defaultValue;
|
|
1487
|
+
} else {
|
|
1488
|
+
if (c.type === "NUMBER" || c.type === "CURRENCY") initialData[c.name] = 0;
|
|
1489
|
+
else if (c.type === "BOOLEAN") initialData[c.name] = false;
|
|
1490
|
+
else initialData[c.name] = "";
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
setNewRecordData(initialData);
|
|
1494
|
+
},
|
|
1495
|
+
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",
|
|
1496
|
+
children: [
|
|
1497
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) }),
|
|
1498
|
+
"\u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4"
|
|
1499
|
+
]
|
|
1500
|
+
}
|
|
1501
|
+
)
|
|
1502
|
+
] })
|
|
1503
|
+
] }),
|
|
1504
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ (0, import_jsx_runtime5.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_runtime5.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_runtime5.jsx)("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("table", { className: "w-full text-xs border-collapse", children: [
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "bg-slate-100/80", children: [
|
|
1506
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { className: "border border-slate-200 px-2 py-1.5 text-center w-10 font-semibold text-slate-500", children: "\u05E0\u05D1\u05D7\u05E8" }),
|
|
1507
|
+
targetColumns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { className: "border border-slate-200 px-2 py-1.5 text-right font-semibold text-slate-600 whitespace-nowrap", children: col.name }, col.name)),
|
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("th", { className: "border border-slate-200 px-2 py-1.5 w-14" })
|
|
1509
|
+
] }) }),
|
|
1510
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tbody", { children: [
|
|
1511
|
+
entries.map((entry) => {
|
|
1512
|
+
const record = linkedRecords.find((r) => r.id === entry.recordId);
|
|
1513
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "hover:bg-blue-50/30 transition-colors", children: [
|
|
1514
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border border-slate-200 px-2 py-1 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1515
|
+
"input",
|
|
1516
|
+
{
|
|
1517
|
+
type: "checkbox",
|
|
1518
|
+
checked: entry.isSelected,
|
|
1519
|
+
onChange: () => handleToggleSelected(entry.recordId),
|
|
1520
|
+
className: "w-3.5 h-3.5 rounded border-slate-300 text-blue-600 cursor-pointer"
|
|
1521
|
+
}
|
|
1522
|
+
) }),
|
|
1523
|
+
targetColumns.map((col) => {
|
|
1524
|
+
var _a2, _b;
|
|
1525
|
+
const colType = ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) || "DEFAULT";
|
|
1526
|
+
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
1527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border border-slate-200 p-0 relative h-8", children: record ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1528
|
+
InputComponent,
|
|
1529
|
+
{
|
|
1530
|
+
value: (_b = record.data[col.name]) != null ? _b : colType === "BOOLEAN" ? false : "",
|
|
1531
|
+
column: col,
|
|
1532
|
+
rowId: record.id,
|
|
1533
|
+
onChange: (v) => handleRecordCellChange(record.id, col.name, v),
|
|
1534
|
+
context: __spreadProps(__spreadValues({}, context), {
|
|
1535
|
+
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",
|
|
1536
|
+
relationOptions,
|
|
1537
|
+
updateRelationOptions: (name, opts) => setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [name]: opts })),
|
|
1538
|
+
refetchRelation,
|
|
1539
|
+
parentRecord: { tableId: (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId), data: context == null ? void 0 : context.rowData },
|
|
1540
|
+
rowData: record.data,
|
|
1541
|
+
tableId: targetSchema == null ? void 0 : targetSchema.id,
|
|
1542
|
+
updateQuietly: (rid, colName, val) => handleRecordCellChange(rid, colName, val)
|
|
1543
|
+
})
|
|
1544
|
+
}
|
|
1545
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-slate-300 italic px-2", children: "\u05D8\u05D5\u05E2\u05DF..." }) }, col.name);
|
|
1546
|
+
}),
|
|
1547
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border border-slate-200 px-1 py-1 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1548
|
+
"button",
|
|
1549
|
+
{
|
|
1550
|
+
type: "button",
|
|
1551
|
+
onClick: () => handleUnlinkRecord(entry.recordId),
|
|
1552
|
+
className: "text-slate-400 hover:text-rose-500 p-0.5 rounded transition-colors cursor-pointer inline-flex items-center justify-center w-full",
|
|
1553
|
+
title: "\u05D4\u05E1\u05E8 \u05E7\u05D9\u05E9\u05D5\u05E8",
|
|
1554
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
1555
|
+
}
|
|
1556
|
+
) })
|
|
1557
|
+
] }, entry.recordId);
|
|
1558
|
+
}),
|
|
1559
|
+
isCreating && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("tr", { className: "bg-emerald-50/40", children: [
|
|
1560
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border border-emerald-200 px-2 py-1 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-emerald-500 font-bold text-[10px]", children: "\u05D7\u05D3\u05E9" }) }),
|
|
1561
|
+
targetColumns.map((col) => {
|
|
1562
|
+
var _a2, _b;
|
|
1563
|
+
const colType = ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) || "DEFAULT";
|
|
1564
|
+
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
1565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border border-emerald-200 p-0 relative h-8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1566
|
+
InputComponent,
|
|
1567
|
+
{
|
|
1568
|
+
value: (_b = newRecordData[col.name]) != null ? _b : colType === "BOOLEAN" ? false : "",
|
|
1569
|
+
column: col,
|
|
1570
|
+
rowId: "new_record",
|
|
1571
|
+
onChange: (v) => setNewRecordData((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: v })),
|
|
1572
|
+
context: __spreadProps(__spreadValues({}, context), {
|
|
1573
|
+
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",
|
|
1574
|
+
relationOptions,
|
|
1575
|
+
refetchRelation
|
|
1576
|
+
})
|
|
1577
|
+
}
|
|
1578
|
+
) }, `new_${col.name}`);
|
|
1579
|
+
}),
|
|
1580
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { className: "border border-emerald-200 px-1 py-1 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
|
|
1581
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1582
|
+
"button",
|
|
1583
|
+
{
|
|
1584
|
+
type: "button",
|
|
1585
|
+
onClick: handleCreateRecord,
|
|
1586
|
+
className: "p-1 text-emerald-600 hover:bg-emerald-100 rounded transition-colors",
|
|
1587
|
+
title: "\u05E9\u05DE\u05D5\u05E8",
|
|
1588
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) })
|
|
1589
|
+
}
|
|
1590
|
+
),
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1592
|
+
"button",
|
|
1593
|
+
{
|
|
1594
|
+
type: "button",
|
|
1595
|
+
onClick: () => {
|
|
1596
|
+
setIsCreating(false);
|
|
1597
|
+
},
|
|
1598
|
+
className: "p-1 text-rose-500 hover:bg-rose-100 rounded transition-colors",
|
|
1599
|
+
title: "\u05D1\u05D9\u05D8\u05D5\u05DC",
|
|
1600
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M6 18L18 6M6 6l12 12" }) })
|
|
1601
|
+
}
|
|
1602
|
+
)
|
|
1603
|
+
] }) })
|
|
1604
|
+
] })
|
|
1605
|
+
] })
|
|
1606
|
+
] }) })
|
|
1607
|
+
] });
|
|
1608
|
+
}
|
|
1609
|
+
|
|
907
1610
|
// src/components/TableBlock/TableBlockClient.tsx
|
|
908
1611
|
var import_lucide_react4 = require("lucide-react");
|
|
909
|
-
var
|
|
1612
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
910
1613
|
function TableBlockClient({
|
|
911
1614
|
data: initialRecords,
|
|
912
1615
|
settings: schema,
|
|
@@ -923,14 +1626,14 @@ function TableBlockClient({
|
|
|
923
1626
|
"data-testid": dataTestId
|
|
924
1627
|
}) {
|
|
925
1628
|
const { showError, addToast } = useToast();
|
|
926
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
927
|
-
const [isMounted, setIsMounted] = (0,
|
|
1629
|
+
const [columnWidths, setColumnWidths] = (0, import_react7.useState)({});
|
|
1630
|
+
const [isMounted, setIsMounted] = (0, import_react7.useState)(false);
|
|
928
1631
|
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";
|
|
929
|
-
const [page, setPage] = (0,
|
|
930
|
-
const [limit, setLimit] = (0,
|
|
931
|
-
const [totalRecords, setTotalRecords] = (0,
|
|
932
|
-
const [totalPages, setTotalPages] = (0,
|
|
933
|
-
(0,
|
|
1632
|
+
const [page, setPage] = (0, import_react7.useState)(1);
|
|
1633
|
+
const [limit, setLimit] = (0, import_react7.useState)(50);
|
|
1634
|
+
const [totalRecords, setTotalRecords] = (0, import_react7.useState)(0);
|
|
1635
|
+
const [totalPages, setTotalPages] = (0, import_react7.useState)(1);
|
|
1636
|
+
(0, import_react7.useEffect)(() => {
|
|
934
1637
|
if (typeof window !== "undefined") {
|
|
935
1638
|
const savedWidths = localStorage.getItem(`table_widths_${tableKey}`);
|
|
936
1639
|
if (savedWidths) {
|
|
@@ -953,7 +1656,7 @@ function TableBlockClient({
|
|
|
953
1656
|
}
|
|
954
1657
|
setIsMounted(true);
|
|
955
1658
|
}, [tableKey]);
|
|
956
|
-
const [showSummary, setShowSummary] = (0,
|
|
1659
|
+
const [showSummary, setShowSummary] = (0, import_react7.useState)(false);
|
|
957
1660
|
const toggleSummary = () => {
|
|
958
1661
|
setShowSummary((prev) => {
|
|
959
1662
|
const next = !prev;
|
|
@@ -962,8 +1665,8 @@ function TableBlockClient({
|
|
|
962
1665
|
return next;
|
|
963
1666
|
});
|
|
964
1667
|
};
|
|
965
|
-
const [resizingCol, setResizingCol] = (0,
|
|
966
|
-
(0,
|
|
1668
|
+
const [resizingCol, setResizingCol] = (0, import_react7.useState)(null);
|
|
1669
|
+
(0, import_react7.useEffect)(() => {
|
|
967
1670
|
if (!resizingCol) return;
|
|
968
1671
|
const handleMouseMove = (e) => {
|
|
969
1672
|
const diffX = resizingCol.startX - e.clientX;
|
|
@@ -1010,7 +1713,7 @@ function TableBlockClient({
|
|
|
1010
1713
|
return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
|
|
1011
1714
|
});
|
|
1012
1715
|
};
|
|
1013
|
-
const mergeColumnDefs = (0,
|
|
1716
|
+
const mergeColumnDefs = (0, import_react7.useCallback)((existingCols, incomingCols) => {
|
|
1014
1717
|
if (!incomingCols || incomingCols.length === 0) return existingCols || [];
|
|
1015
1718
|
if (!existingCols || existingCols.length === 0) return incomingCols;
|
|
1016
1719
|
const existingMap = new Map(existingCols.map((c) => [c.name, c]));
|
|
@@ -1030,18 +1733,18 @@ function TableBlockClient({
|
|
|
1030
1733
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
1031
1734
|
});
|
|
1032
1735
|
}, []);
|
|
1033
|
-
const [localColumns, setLocalColumns] = (0,
|
|
1034
|
-
(0,
|
|
1736
|
+
const [localColumns, setLocalColumns] = (0, import_react7.useState)(() => (schema == null ? void 0 : schema.columns) || []);
|
|
1737
|
+
(0, import_react7.useEffect)(() => {
|
|
1035
1738
|
if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
|
|
1036
1739
|
setLocalColumns((prev) => mergeColumnDefs(prev, schema.columns));
|
|
1037
1740
|
}
|
|
1038
1741
|
}, [schema == null ? void 0 : schema.columns, mergeColumnDefs]);
|
|
1039
|
-
const [dirty, setDirty] = (0,
|
|
1040
|
-
const dirtyRef = (0,
|
|
1041
|
-
(0,
|
|
1742
|
+
const [dirty, setDirty] = (0, import_react7.useState)({ added: [], modified: {}, deleted: [] });
|
|
1743
|
+
const dirtyRef = (0, import_react7.useRef)(dirty);
|
|
1744
|
+
(0, import_react7.useEffect)(() => {
|
|
1042
1745
|
dirtyRef.current = dirty;
|
|
1043
1746
|
}, [dirty]);
|
|
1044
|
-
const mergeWithDirty = (0,
|
|
1747
|
+
const mergeWithDirty = (0, import_react7.useCallback)((baseRecords) => {
|
|
1045
1748
|
const { added, modified, deleted } = dirtyRef.current;
|
|
1046
1749
|
const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
|
|
1047
1750
|
const modifiedRecords = nonDeleted.map((r) => {
|
|
@@ -1054,8 +1757,8 @@ function TableBlockClient({
|
|
|
1054
1757
|
const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
|
|
1055
1758
|
return [...uniqueAdded, ...modifiedRecords];
|
|
1056
1759
|
}, []);
|
|
1057
|
-
const [data, setData] = (0,
|
|
1058
|
-
(0,
|
|
1760
|
+
const [data, setData] = (0, import_react7.useState)(() => normalizeRecords(initialRecords));
|
|
1761
|
+
(0, import_react7.useEffect)(() => {
|
|
1059
1762
|
if (initialRecords) {
|
|
1060
1763
|
setData(mergeWithDirty(normalizeRecords(initialRecords)));
|
|
1061
1764
|
}
|
|
@@ -1070,19 +1773,19 @@ function TableBlockClient({
|
|
|
1070
1773
|
}
|
|
1071
1774
|
return false;
|
|
1072
1775
|
};
|
|
1073
|
-
const [baseRecordsMap, setBaseRecordsMap] = (0,
|
|
1776
|
+
const [baseRecordsMap, setBaseRecordsMap] = (0, import_react7.useState)(() => {
|
|
1074
1777
|
const map = /* @__PURE__ */ new Map();
|
|
1075
1778
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
1076
1779
|
return map;
|
|
1077
1780
|
});
|
|
1078
|
-
(0,
|
|
1781
|
+
(0, import_react7.useEffect)(() => {
|
|
1079
1782
|
if (initialRecords && initialRecords.length > 0) {
|
|
1080
1783
|
const map = /* @__PURE__ */ new Map();
|
|
1081
1784
|
(normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
|
|
1082
1785
|
setBaseRecordsMap(map);
|
|
1083
1786
|
}
|
|
1084
1787
|
}, [initialRecords]);
|
|
1085
|
-
const refetchTableData = (0,
|
|
1788
|
+
const refetchTableData = (0, import_react7.useCallback)((targetPage) => {
|
|
1086
1789
|
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
1087
1790
|
if (!tableId || !executeAction) return Promise.resolve();
|
|
1088
1791
|
const activePage = targetPage !== void 0 ? targetPage : page;
|
|
@@ -1116,8 +1819,8 @@ function TableBlockClient({
|
|
|
1116
1819
|
}).catch((err) => {
|
|
1117
1820
|
console.error("[TableBlock] Failed to auto-fetch table data:", err);
|
|
1118
1821
|
});
|
|
1119
|
-
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction,
|
|
1120
|
-
(0,
|
|
1822
|
+
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeColumnDefs]);
|
|
1823
|
+
(0, import_react7.useEffect)(() => {
|
|
1121
1824
|
refetchTableData();
|
|
1122
1825
|
}, [refetchTableData]);
|
|
1123
1826
|
const handleLimitChange = (newLimit) => {
|
|
@@ -1133,19 +1836,20 @@ function TableBlockClient({
|
|
|
1133
1836
|
const handleNextPage = () => {
|
|
1134
1837
|
setPage((prev) => Math.min(totalPages, prev + 1));
|
|
1135
1838
|
};
|
|
1136
|
-
(0,
|
|
1839
|
+
(0, import_react7.useEffect)(() => {
|
|
1137
1840
|
if (error) {
|
|
1138
1841
|
showError(error, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E8\u05DB\u05D9\u05D1");
|
|
1139
1842
|
}
|
|
1140
1843
|
}, [error, showError]);
|
|
1141
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
1142
|
-
const [selectedIds, setSelectedIds] = (0,
|
|
1143
|
-
const [pendingDeletions, setPendingDeletions] = (0,
|
|
1144
|
-
const [isSaving, setIsSaving] = (0,
|
|
1145
|
-
const [isSaveSuccess, setIsSaveSuccess] = (0,
|
|
1146
|
-
const [relationOptions, setRelationOptions] = (0,
|
|
1147
|
-
const
|
|
1148
|
-
const
|
|
1844
|
+
const [searchQuery, setSearchQuery] = (0, import_react7.useState)("");
|
|
1845
|
+
const [selectedIds, setSelectedIds] = (0, import_react7.useState)(/* @__PURE__ */ new Set());
|
|
1846
|
+
const [pendingDeletions, setPendingDeletions] = (0, import_react7.useState)([]);
|
|
1847
|
+
const [isSaving, setIsSaving] = (0, import_react7.useState)(false);
|
|
1848
|
+
const [isSaveSuccess, setIsSaveSuccess] = (0, import_react7.useState)(false);
|
|
1849
|
+
const [relationOptions, setRelationOptions] = (0, import_react7.useState)({});
|
|
1850
|
+
const [expandedRowIds, setExpandedRowIds] = (0, import_react7.useState)(/* @__PURE__ */ new Set());
|
|
1851
|
+
const schemaColsString = (0, import_react7.useMemo)(() => JSON.stringify(localColumns || []), [localColumns]);
|
|
1852
|
+
const refetchRelation = (0, import_react7.useCallback)(async (colName) => {
|
|
1149
1853
|
var _a;
|
|
1150
1854
|
let parsedCols = [];
|
|
1151
1855
|
try {
|
|
@@ -1165,7 +1869,7 @@ function TableBlockClient({
|
|
|
1165
1869
|
console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
|
|
1166
1870
|
}
|
|
1167
1871
|
}, [schemaColsString, executeAction]);
|
|
1168
|
-
(0,
|
|
1872
|
+
(0, import_react7.useEffect)(() => {
|
|
1169
1873
|
let parsedCols = [];
|
|
1170
1874
|
try {
|
|
1171
1875
|
parsedCols = JSON.parse(schemaColsString);
|
|
@@ -1179,7 +1883,7 @@ function TableBlockClient({
|
|
|
1179
1883
|
refetchRelation(col.name);
|
|
1180
1884
|
});
|
|
1181
1885
|
}, [schemaColsString, refetchRelation]);
|
|
1182
|
-
const normalizedColumns = (0,
|
|
1886
|
+
const normalizedColumns = (0, import_react7.useMemo)(() => {
|
|
1183
1887
|
return (localColumns || []).map((col, idx) => {
|
|
1184
1888
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
1185
1889
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
@@ -1193,17 +1897,17 @@ function TableBlockClient({
|
|
|
1193
1897
|
return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
|
|
1194
1898
|
});
|
|
1195
1899
|
}, [localColumns]);
|
|
1196
|
-
const filteredColumns = (0,
|
|
1900
|
+
const filteredColumns = (0, import_react7.useMemo)(() => {
|
|
1197
1901
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
1198
1902
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name) && !col.isHidden);
|
|
1199
1903
|
}, [normalizedColumns]);
|
|
1200
|
-
const customizableColumns = (0,
|
|
1904
|
+
const customizableColumns = (0, import_react7.useMemo)(() => {
|
|
1201
1905
|
const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
|
|
1202
1906
|
return normalizedColumns.filter((col) => !systemFields.includes(col.name));
|
|
1203
1907
|
}, [normalizedColumns]);
|
|
1204
|
-
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = (0,
|
|
1205
|
-
const dropdownRef = (0,
|
|
1206
|
-
(0,
|
|
1908
|
+
const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = (0, import_react7.useState)(false);
|
|
1909
|
+
const dropdownRef = (0, import_react7.useRef)(null);
|
|
1910
|
+
(0, import_react7.useEffect)(() => {
|
|
1207
1911
|
const handleClickOutside = (e) => {
|
|
1208
1912
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1209
1913
|
setIsColumnsDropdownOpen(false);
|
|
@@ -1281,8 +1985,8 @@ function TableBlockClient({
|
|
|
1281
1985
|
}
|
|
1282
1986
|
}
|
|
1283
1987
|
};
|
|
1284
|
-
const [draggedColName, setDraggedColName] = (0,
|
|
1285
|
-
const [dragOverColName, setDragOverColName] = (0,
|
|
1988
|
+
const [draggedColName, setDraggedColName] = (0, import_react7.useState)(null);
|
|
1989
|
+
const [dragOverColName, setDragOverColName] = (0, import_react7.useState)(null);
|
|
1286
1990
|
const handleColumnReorder = async (draggedName, dropTargetName) => {
|
|
1287
1991
|
var _a;
|
|
1288
1992
|
if (draggedName === dropTargetName) return;
|
|
@@ -1324,6 +2028,10 @@ function TableBlockClient({
|
|
|
1324
2028
|
var _a;
|
|
1325
2029
|
const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
|
|
1326
2030
|
let initialValue = col.defaultValue;
|
|
2031
|
+
if (typeUpper === "SUB_TABLE") {
|
|
2032
|
+
defaultData[col.name] = [];
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
1327
2035
|
if (initialValue !== void 0 && initialValue !== null && initialValue !== "") {
|
|
1328
2036
|
if (typeUpper === "CURRENCY" || typeUpper === "NUMBER") {
|
|
1329
2037
|
initialValue = parseFloat(initialValue);
|
|
@@ -1407,6 +2115,36 @@ function TableBlockClient({
|
|
|
1407
2115
|
});
|
|
1408
2116
|
}
|
|
1409
2117
|
};
|
|
2118
|
+
const triggerSaveSuccess = (0, import_react7.useCallback)(() => {
|
|
2119
|
+
setIsSaveSuccess(true);
|
|
2120
|
+
setTimeout(() => {
|
|
2121
|
+
setIsSaveSuccess(false);
|
|
2122
|
+
}, 2500);
|
|
2123
|
+
}, []);
|
|
2124
|
+
const handleQuietCellChange = (0, import_react7.useCallback)((rowId, colName, value) => {
|
|
2125
|
+
setData((prev) => prev.map(
|
|
2126
|
+
(row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
|
|
2127
|
+
));
|
|
2128
|
+
if (rowId.startsWith("temp_")) {
|
|
2129
|
+
setDirty((prev) => {
|
|
2130
|
+
if (!prev.added.some((r) => r.id === rowId)) return prev;
|
|
2131
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
2132
|
+
added: prev.added.map(
|
|
2133
|
+
(r) => r.id === rowId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value }) }) : r
|
|
2134
|
+
)
|
|
2135
|
+
});
|
|
2136
|
+
});
|
|
2137
|
+
} else {
|
|
2138
|
+
setBaseRecordsMap((prev) => {
|
|
2139
|
+
const next = new Map(prev);
|
|
2140
|
+
const rowData = next.get(rowId);
|
|
2141
|
+
if (rowData) {
|
|
2142
|
+
next.set(rowId, __spreadProps(__spreadValues({}, rowData), { [colName]: value }));
|
|
2143
|
+
}
|
|
2144
|
+
return next;
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2147
|
+
}, []);
|
|
1410
2148
|
const toggleSelectAll = (checked) => {
|
|
1411
2149
|
const nextSelected = checked ? new Set(filteredData.map((r) => r.id)) : /* @__PURE__ */ new Set();
|
|
1412
2150
|
setSelectedIds(nextSelected);
|
|
@@ -1436,9 +2174,15 @@ function TableBlockClient({
|
|
|
1436
2174
|
const row = data.find((r) => r.id === id);
|
|
1437
2175
|
if (row) {
|
|
1438
2176
|
driveCols.forEach((col) => {
|
|
1439
|
-
const
|
|
1440
|
-
if (
|
|
1441
|
-
|
|
2177
|
+
const fileVal = row.data[col.name];
|
|
2178
|
+
if (Array.isArray(fileVal)) {
|
|
2179
|
+
fileVal.forEach((fileObj) => {
|
|
2180
|
+
if (fileObj && fileObj.fileId) {
|
|
2181
|
+
filesToDelete.push(fileObj.fileId);
|
|
2182
|
+
}
|
|
2183
|
+
});
|
|
2184
|
+
} else if (fileVal && fileVal.fileId) {
|
|
2185
|
+
filesToDelete.push(fileVal.fileId);
|
|
1442
2186
|
}
|
|
1443
2187
|
});
|
|
1444
2188
|
}
|
|
@@ -1465,7 +2209,7 @@ function TableBlockClient({
|
|
|
1465
2209
|
const formatPayload = (payload) => {
|
|
1466
2210
|
const formatted = {};
|
|
1467
2211
|
(localColumns || []).forEach((col) => {
|
|
1468
|
-
var _a;
|
|
2212
|
+
var _a, _b;
|
|
1469
2213
|
if (["_id", "id", "createdAt", "updatedAt", "orgId", "tableId", "isSelected"].includes(col.name)) return;
|
|
1470
2214
|
let val = payload[col.name];
|
|
1471
2215
|
if (val !== void 0) {
|
|
@@ -1475,6 +2219,11 @@ function TableBlockClient({
|
|
|
1475
2219
|
if (((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "NUMBER") {
|
|
1476
2220
|
val = val === "" ? 0 : Number(val);
|
|
1477
2221
|
if (isNaN(val)) val = 0;
|
|
2222
|
+
} else if (((_b = col.type) == null ? void 0 : _b.toUpperCase()) === "SUB_TABLE" && Array.isArray(val)) {
|
|
2223
|
+
val = val.map((item) => {
|
|
2224
|
+
const _a2 = item, { _resolvedData } = _a2, rest = __objRest(_a2, ["_resolvedData"]);
|
|
2225
|
+
return rest;
|
|
2226
|
+
});
|
|
1478
2227
|
}
|
|
1479
2228
|
formatted[col.name] = val;
|
|
1480
2229
|
}
|
|
@@ -1607,7 +2356,7 @@ function TableBlockClient({
|
|
|
1607
2356
|
setIsSaving(false);
|
|
1608
2357
|
}
|
|
1609
2358
|
};
|
|
1610
|
-
const filteredData = (0,
|
|
2359
|
+
const filteredData = (0, import_react7.useMemo)(() => {
|
|
1611
2360
|
if (!searchQuery) return data;
|
|
1612
2361
|
const lowerQuery = searchQuery.toLowerCase();
|
|
1613
2362
|
return data.filter(
|
|
@@ -1618,7 +2367,7 @@ function TableBlockClient({
|
|
|
1618
2367
|
}, [data, searchQuery]);
|
|
1619
2368
|
const isUpdatingActive = Boolean(isUpdating || isSaving);
|
|
1620
2369
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
1621
|
-
const columnTotals = (0,
|
|
2370
|
+
const columnTotals = (0, import_react7.useMemo)(() => {
|
|
1622
2371
|
const totals = {};
|
|
1623
2372
|
if (!showSummary) return totals;
|
|
1624
2373
|
filteredColumns.forEach((col) => {
|
|
@@ -1636,7 +2385,7 @@ function TableBlockClient({
|
|
|
1636
2385
|
});
|
|
1637
2386
|
return totals;
|
|
1638
2387
|
}, [filteredData, filteredColumns, showSummary]);
|
|
1639
|
-
return /* @__PURE__ */ (0,
|
|
2388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1640
2389
|
"div",
|
|
1641
2390
|
{
|
|
1642
2391
|
id: componentId,
|
|
@@ -1644,34 +2393,34 @@ function TableBlockClient({
|
|
|
1644
2393
|
className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs min-h-[350px] overflow-hidden ${className}`,
|
|
1645
2394
|
dir: "rtl",
|
|
1646
2395
|
children: [
|
|
1647
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
1648
|
-
/* @__PURE__ */ (0,
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
2396
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2397
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
2398
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: errorMessage })
|
|
1650
2399
|
] }) }),
|
|
1651
|
-
/* @__PURE__ */ (0,
|
|
1652
|
-
/* @__PURE__ */ (0,
|
|
1653
|
-
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0,
|
|
1654
|
-
/* @__PURE__ */ (0,
|
|
2400
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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: [
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
2402
|
+
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)("span", { children: schema.title || schema.name }) }),
|
|
2403
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1655
2404
|
"button",
|
|
1656
2405
|
{
|
|
1657
2406
|
onClick: handleAddRow,
|
|
1658
2407
|
disabled: isLoading || isUpdatingActive,
|
|
1659
2408
|
className: "w-9 h-9 bg-emerald-600 hover:bg-emerald-700 active:bg-emerald-800 text-white rounded-lg shadow-xs flex items-center justify-center transition-all disabled:opacity-40 disabled:pointer-events-none cursor-pointer",
|
|
1660
2409
|
title: "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
|
|
1661
|
-
children: /* @__PURE__ */ (0,
|
|
2410
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
1662
2411
|
}
|
|
1663
2412
|
),
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1665
2414
|
"button",
|
|
1666
2415
|
{
|
|
1667
2416
|
onClick: handleDuplicateRow,
|
|
1668
2417
|
disabled: isLoading || isUpdatingActive || selectedIds.size !== 1,
|
|
1669
2418
|
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",
|
|
1670
2419
|
title: "\u05E9\u05DB\u05E4\u05DC \u05E9\u05D5\u05E8\u05D4 \u05E0\u05D1\u05D7\u05E8\u05EA",
|
|
1671
|
-
children: /* @__PURE__ */ (0,
|
|
2420
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Copy, { className: "w-4 h-4 text-blue-600 shrink-0" })
|
|
1672
2421
|
}
|
|
1673
2422
|
),
|
|
1674
|
-
/* @__PURE__ */ (0,
|
|
2423
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1675
2424
|
"button",
|
|
1676
2425
|
{
|
|
1677
2426
|
onClick: handleDeleteSelected,
|
|
@@ -1679,12 +2428,12 @@ function TableBlockClient({
|
|
|
1679
2428
|
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",
|
|
1680
2429
|
title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
|
|
1681
2430
|
children: [
|
|
1682
|
-
/* @__PURE__ */ (0,
|
|
1683
|
-
selectedIds.size > 0 && /* @__PURE__ */ (0,
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.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" }) }),
|
|
2432
|
+
selectedIds.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.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 })
|
|
1684
2433
|
]
|
|
1685
2434
|
}
|
|
1686
2435
|
),
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1688
2437
|
"button",
|
|
1689
2438
|
{
|
|
1690
2439
|
onClick: toggleSummary,
|
|
@@ -1692,13 +2441,13 @@ function TableBlockClient({
|
|
|
1692
2441
|
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"}`,
|
|
1693
2442
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E9\u05D5\u05E8\u05EA \u05E1\u05D9\u05DB\u05D5\u05DD",
|
|
1694
2443
|
children: [
|
|
1695
|
-
/* @__PURE__ */ (0,
|
|
1696
|
-
/* @__PURE__ */ (0,
|
|
2444
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
2445
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hidden sm:inline", children: "\u05E1\u05DB\u05D9\u05DE\u05D4" })
|
|
1697
2446
|
]
|
|
1698
2447
|
}
|
|
1699
2448
|
),
|
|
1700
|
-
/* @__PURE__ */ (0,
|
|
1701
|
-
/* @__PURE__ */ (0,
|
|
2449
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative", ref: dropdownRef, children: [
|
|
2450
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1702
2451
|
"button",
|
|
1703
2452
|
{
|
|
1704
2453
|
onClick: () => setIsColumnsDropdownOpen((prev) => !prev),
|
|
@@ -1706,16 +2455,16 @@ function TableBlockClient({
|
|
|
1706
2455
|
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",
|
|
1707
2456
|
title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA",
|
|
1708
2457
|
children: [
|
|
1709
|
-
/* @__PURE__ */ (0,
|
|
1710
|
-
/* @__PURE__ */ (0,
|
|
2458
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.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" }) }),
|
|
2459
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })
|
|
1711
2460
|
]
|
|
1712
2461
|
}
|
|
1713
2462
|
),
|
|
1714
|
-
isColumnsDropdownOpen && /* @__PURE__ */ (0,
|
|
1715
|
-
/* @__PURE__ */ (0,
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
1718
|
-
/* @__PURE__ */ (0,
|
|
2463
|
+
isColumnsDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime6.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: [
|
|
2464
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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: [
|
|
2465
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2466
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u05D4\u05E6\u05D2\u05EA \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA" }),
|
|
2467
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "text-[10px] font-normal text-slate-400", children: [
|
|
1719
2468
|
"(",
|
|
1720
2469
|
customizableColumns.filter((c) => !c.isHidden).length,
|
|
1721
2470
|
"/",
|
|
@@ -1723,7 +2472,7 @@ function TableBlockClient({
|
|
|
1723
2472
|
")"
|
|
1724
2473
|
] })
|
|
1725
2474
|
] }),
|
|
1726
|
-
/* @__PURE__ */ (0,
|
|
2475
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1727
2476
|
"button",
|
|
1728
2477
|
{
|
|
1729
2478
|
type: "button",
|
|
@@ -1733,7 +2482,7 @@ function TableBlockClient({
|
|
|
1733
2482
|
}
|
|
1734
2483
|
)
|
|
1735
2484
|
] }),
|
|
1736
|
-
/* @__PURE__ */ (0,
|
|
2485
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "max-h-60 overflow-y-auto space-y-0.5", children: customizableColumns.map((col) => {
|
|
1737
2486
|
const isRequired = col.isRequired === true || String(col.isRequired) === "true";
|
|
1738
2487
|
const isUnique = col.isUnique === true || String(col.isUnique) === "true";
|
|
1739
2488
|
const isProtected = isRequired || isUnique;
|
|
@@ -1747,7 +2496,7 @@ function TableBlockClient({
|
|
|
1747
2496
|
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";
|
|
1748
2497
|
}
|
|
1749
2498
|
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";
|
|
1750
|
-
return /* @__PURE__ */ (0,
|
|
2499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1751
2500
|
"div",
|
|
1752
2501
|
{
|
|
1753
2502
|
onClick: () => {
|
|
@@ -1758,8 +2507,8 @@ function TableBlockClient({
|
|
|
1758
2507
|
title: isProtected ? protectedExplanation : void 0,
|
|
1759
2508
|
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"}`,
|
|
1760
2509
|
children: [
|
|
1761
|
-
/* @__PURE__ */ (0,
|
|
1762
|
-
/* @__PURE__ */ (0,
|
|
2510
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
2511
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1763
2512
|
"input",
|
|
1764
2513
|
{
|
|
1765
2514
|
type: "checkbox",
|
|
@@ -1770,16 +2519,16 @@ function TableBlockClient({
|
|
|
1770
2519
|
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"
|
|
1771
2520
|
}
|
|
1772
2521
|
),
|
|
1773
|
-
/* @__PURE__ */ (0,
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `font-medium truncate ${isProtected ? "text-slate-500" : "text-slate-700"}`, children: col.name })
|
|
1774
2523
|
] }),
|
|
1775
|
-
isProtected && /* @__PURE__ */ (0,
|
|
2524
|
+
isProtected && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1776
2525
|
"div",
|
|
1777
2526
|
{
|
|
1778
2527
|
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",
|
|
1779
2528
|
title: protectedExplanation,
|
|
1780
2529
|
children: [
|
|
1781
|
-
/* @__PURE__ */ (0,
|
|
1782
|
-
/* @__PURE__ */ (0,
|
|
2530
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.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" }) }),
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: badgeLabel })
|
|
1783
2532
|
]
|
|
1784
2533
|
}
|
|
1785
2534
|
)
|
|
@@ -1790,9 +2539,9 @@ function TableBlockClient({
|
|
|
1790
2539
|
}) })
|
|
1791
2540
|
] })
|
|
1792
2541
|
] }),
|
|
1793
|
-
/* @__PURE__ */ (0,
|
|
1794
|
-
/* @__PURE__ */ (0,
|
|
1795
|
-
/* @__PURE__ */ (0,
|
|
2542
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
|
|
2543
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
|
|
2544
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1796
2545
|
"input",
|
|
1797
2546
|
{
|
|
1798
2547
|
placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
|
|
@@ -1802,45 +2551,45 @@ function TableBlockClient({
|
|
|
1802
2551
|
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"
|
|
1803
2552
|
}
|
|
1804
2553
|
),
|
|
1805
|
-
searchQuery ? /* @__PURE__ */ (0,
|
|
2554
|
+
searchQuery ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1806
2555
|
"button",
|
|
1807
2556
|
{
|
|
1808
2557
|
type: "button",
|
|
1809
2558
|
onClick: () => setSearchQuery(""),
|
|
1810
2559
|
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",
|
|
1811
2560
|
title: "Clear search",
|
|
1812
|
-
children: /* @__PURE__ */ (0,
|
|
2561
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.X, { className: "w-3.5 h-3.5" })
|
|
1813
2562
|
}
|
|
1814
|
-
) : /* @__PURE__ */ (0,
|
|
2563
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
|
|
1815
2564
|
] })
|
|
1816
2565
|
] }),
|
|
1817
|
-
/* @__PURE__ */ (0,
|
|
1818
|
-
isUpdatingActive ? /* @__PURE__ */ (0,
|
|
1819
|
-
/* @__PURE__ */ (0,
|
|
2566
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
2567
|
+
isUpdatingActive ? /* @__PURE__ */ (0, import_jsx_runtime6.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: [
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
|
|
1820
2569
|
"\u05DE\u05E2\u05D3\u05DB\u05DF..."
|
|
1821
|
-
] }) : isSaveSuccess ? /* @__PURE__ */ (0,
|
|
1822
|
-
/* @__PURE__ */ (0,
|
|
2570
|
+
] }) : isSaveSuccess ? /* @__PURE__ */ (0, import_jsx_runtime6.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: [
|
|
2571
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
1823
2572
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
1824
|
-
] }) : hasChanges ? /* @__PURE__ */ (0,
|
|
1825
|
-
/* @__PURE__ */ (0,
|
|
2573
|
+
] }) : hasChanges ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-xs font-semibold text-amber-700 animate-in fade-in", children: "\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5" }) : null,
|
|
2574
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1826
2575
|
"button",
|
|
1827
2576
|
{
|
|
1828
2577
|
onClick: handleSave,
|
|
1829
2578
|
disabled: isUpdatingActive || isLoading || !hasChanges,
|
|
1830
2579
|
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"}`,
|
|
1831
|
-
children: /* @__PURE__ */ (0,
|
|
2580
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
|
|
1832
2581
|
}
|
|
1833
2582
|
)
|
|
1834
2583
|
] })
|
|
1835
2584
|
] }),
|
|
1836
|
-
/* @__PURE__ */ (0,
|
|
1837
|
-
isLoading && /* @__PURE__ */ (0,
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
1839
|
-
/* @__PURE__ */ (0,
|
|
2585
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `overflow-x-auto relative min-h-[260px] flex-1 transition-opacity duration-200 ${isMounted ? "opacity-100" : "opacity-0"}`, children: [
|
|
2586
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
|
|
2587
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
|
|
1840
2589
|
] }),
|
|
1841
|
-
/* @__PURE__ */ (0,
|
|
1842
|
-
/* @__PURE__ */ (0,
|
|
1843
|
-
/* @__PURE__ */ (0,
|
|
2590
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("table", { className: "w-full text-sm text-right border-collapse table-auto", children: [
|
|
2591
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { children: [
|
|
2592
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("th", { className: "border-b border-l border-slate-200 p-2.5 w-10 text-center shrink-0", style: { width: 50, minWidth: 50, maxWidth: 50 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1844
2593
|
"input",
|
|
1845
2594
|
{
|
|
1846
2595
|
type: "checkbox",
|
|
@@ -1854,7 +2603,7 @@ function TableBlockClient({
|
|
|
1854
2603
|
const isDragging = draggedColName === col.name;
|
|
1855
2604
|
const isDragOver = dragOverColName === col.name;
|
|
1856
2605
|
const currentWidth = columnWidths[col.name] || 200;
|
|
1857
|
-
return /* @__PURE__ */ (0,
|
|
2606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1858
2607
|
"th",
|
|
1859
2608
|
{
|
|
1860
2609
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
@@ -1890,7 +2639,7 @@ function TableBlockClient({
|
|
|
1890
2639
|
},
|
|
1891
2640
|
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"}`,
|
|
1892
2641
|
children: [
|
|
1893
|
-
/* @__PURE__ */ (0,
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1894
2643
|
"div",
|
|
1895
2644
|
{
|
|
1896
2645
|
onMouseDown: (e) => {
|
|
@@ -1902,16 +2651,16 @@ function TableBlockClient({
|
|
|
1902
2651
|
title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
|
|
1903
2652
|
}
|
|
1904
2653
|
),
|
|
1905
|
-
/* @__PURE__ */ (0,
|
|
1906
|
-
/* @__PURE__ */ (0,
|
|
1907
|
-
/* @__PURE__ */ (0,
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-between gap-2 group overflow-hidden", title: "\u05D2\u05E8\u05D5\u05E8 \u05DC\u05E9\u05D9\u05E0\u05D5\u05D9 \u05E1\u05D3\u05E8 \u05D4\u05E2\u05DE\u05D5\u05D3\u05D4", children: [
|
|
2655
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: col.name }),
|
|
2656
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1908
2657
|
"svg",
|
|
1909
2658
|
{
|
|
1910
2659
|
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
1911
2660
|
fill: "none",
|
|
1912
2661
|
viewBox: "0 0 24 24",
|
|
1913
2662
|
stroke: "currentColor",
|
|
1914
|
-
children: /* @__PURE__ */ (0,
|
|
2663
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
|
|
1915
2664
|
}
|
|
1916
2665
|
)
|
|
1917
2666
|
] })
|
|
@@ -1920,59 +2669,112 @@ function TableBlockClient({
|
|
|
1920
2669
|
col.name
|
|
1921
2670
|
);
|
|
1922
2671
|
}),
|
|
1923
|
-
/* @__PURE__ */ (0,
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("th", { className: "w-full min-w-[50px] border-b border-slate-200 pointer-events-none" })
|
|
1924
2673
|
] }) }),
|
|
1925
|
-
/* @__PURE__ */ (0,
|
|
1926
|
-
/* @__PURE__ */ (0,
|
|
1927
|
-
/* @__PURE__ */ (0,
|
|
1928
|
-
] }) }) }) : filteredData.map((row) =>
|
|
1929
|
-
|
|
1930
|
-
"input",
|
|
1931
|
-
{
|
|
1932
|
-
type: "checkbox",
|
|
1933
|
-
checked: selectedIds.has(row.id),
|
|
1934
|
-
onChange: (e) => toggleSelectRow(row.id, e.target.checked),
|
|
1935
|
-
disabled: isLoading || isUpdatingActive,
|
|
1936
|
-
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
1937
|
-
}
|
|
1938
|
-
) }),
|
|
1939
|
-
filteredColumns.map((col) => {
|
|
2674
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { colSpan: filteredColumns.length + 2, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
2675
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime6.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" }) }),
|
|
2676
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
|
|
2677
|
+
] }) }) }) : filteredData.map((row) => {
|
|
2678
|
+
const hasSubTableCols = filteredColumns.some((c) => {
|
|
1940
2679
|
var _a;
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
2680
|
+
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
2681
|
+
});
|
|
2682
|
+
const isExpanded = expandedRowIds.has(row.id);
|
|
2683
|
+
const subTableColumns = filteredColumns.filter((c) => {
|
|
2684
|
+
var _a;
|
|
2685
|
+
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
2686
|
+
});
|
|
2687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react7.default.Fragment, { children: [
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
|
|
2689
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
|
|
2690
|
+
hasSubTableCols && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2691
|
+
"button",
|
|
2692
|
+
{
|
|
2693
|
+
type: "button",
|
|
2694
|
+
onClick: () => setExpandedRowIds((prev) => {
|
|
2695
|
+
const next = new Set(prev);
|
|
2696
|
+
if (next.has(row.id)) next.delete(row.id);
|
|
2697
|
+
else next.add(row.id);
|
|
2698
|
+
return next;
|
|
2699
|
+
}),
|
|
2700
|
+
className: "text-slate-400 hover:text-blue-600 p-0.5 rounded transition-colors cursor-pointer",
|
|
2701
|
+
title: isExpanded ? "\u05E1\u05D2\u05D5\u05E8 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4" : "\u05E4\u05EA\u05D7 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4",
|
|
2702
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: `w-3.5 h-3.5 transition-transform duration-150 ${isExpanded ? "rotate-90" : ""}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 5l7 7-7 7" }) })
|
|
2703
|
+
}
|
|
2704
|
+
),
|
|
2705
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2706
|
+
"input",
|
|
2707
|
+
{
|
|
2708
|
+
type: "checkbox",
|
|
2709
|
+
checked: selectedIds.has(row.id),
|
|
2710
|
+
onChange: (e) => toggleSelectRow(row.id, e.target.checked),
|
|
2711
|
+
disabled: isLoading || isUpdatingActive,
|
|
2712
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
2713
|
+
}
|
|
2714
|
+
)
|
|
2715
|
+
] }) }),
|
|
2716
|
+
filteredColumns.map((col) => {
|
|
2717
|
+
var _a;
|
|
2718
|
+
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
2719
|
+
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
2720
|
+
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
2721
|
+
if (value === void 0 && col.defaultValue !== void 0) {
|
|
2722
|
+
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
2723
|
+
if (colType === "CURRENCY" || colType === "NUMBER") {
|
|
2724
|
+
if (isNaN(value)) value = null;
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
if (value === void 0) value = null;
|
|
2728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "border-b border-l border-slate-200 p-0 relative", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2729
|
+
InputComponent,
|
|
2730
|
+
{
|
|
2731
|
+
value,
|
|
2732
|
+
column: col,
|
|
2733
|
+
rowId: row.id,
|
|
2734
|
+
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
2735
|
+
context: {
|
|
2736
|
+
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",
|
|
2737
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
2738
|
+
onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
|
|
2739
|
+
relationOptions,
|
|
2740
|
+
refetchRelation,
|
|
2741
|
+
executeAction,
|
|
2742
|
+
emitEvent,
|
|
2743
|
+
pageState,
|
|
2744
|
+
componentId,
|
|
2745
|
+
orgId,
|
|
2746
|
+
updateQuietly: handleQuietCellChange,
|
|
2747
|
+
triggerSaveSuccess,
|
|
2748
|
+
rowData: row.data
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
) }, col.name);
|
|
2752
|
+
}),
|
|
2753
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
2754
|
+
] }),
|
|
2755
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2756
|
+
ExpandedSubTables,
|
|
1953
2757
|
{
|
|
1954
|
-
value,
|
|
1955
|
-
column: col,
|
|
1956
2758
|
rowId: row.id,
|
|
1957
|
-
|
|
2759
|
+
rowData: row.data,
|
|
2760
|
+
subTableColumns,
|
|
2761
|
+
filteredColumnsLength: filteredColumns.length,
|
|
2762
|
+
handleCellChange,
|
|
1958
2763
|
context: {
|
|
1959
|
-
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",
|
|
1960
|
-
onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
|
|
1961
|
-
relationOptions,
|
|
1962
|
-
refetchRelation,
|
|
1963
2764
|
executeAction,
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
2765
|
+
orgId,
|
|
2766
|
+
parentTableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
2767
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
2768
|
+
rowData: row.data,
|
|
2769
|
+
updateQuietly: handleQuietCellChange,
|
|
2770
|
+
triggerSaveSuccess
|
|
1968
2771
|
}
|
|
1969
2772
|
}
|
|
1970
|
-
)
|
|
1971
|
-
})
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.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' }),
|
|
2773
|
+
)
|
|
2774
|
+
] }, row.id);
|
|
2775
|
+
}) }),
|
|
2776
|
+
showSummary && filteredData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsxs)("tr", { children: [
|
|
2777
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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' }),
|
|
1976
2778
|
filteredColumns.map((col) => {
|
|
1977
2779
|
var _a;
|
|
1978
2780
|
const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
|
|
@@ -1986,16 +2788,16 @@ function TableBlockClient({
|
|
|
1986
2788
|
displayVal = symbol ? `${symbol} ${displayVal}` : displayVal;
|
|
1987
2789
|
}
|
|
1988
2790
|
}
|
|
1989
|
-
return /* @__PURE__ */ (0,
|
|
2791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)("div", { className: "flex items-center text-right justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: displayVal }) }) }, col.name);
|
|
1990
2792
|
}),
|
|
1991
|
-
/* @__PURE__ */ (0,
|
|
2793
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "border-b border-slate-200 bg-slate-50 pointer-events-none" })
|
|
1992
2794
|
] }) })
|
|
1993
2795
|
] })
|
|
1994
2796
|
] }),
|
|
1995
|
-
/* @__PURE__ */ (0,
|
|
1996
|
-
/* @__PURE__ */ (0,
|
|
1997
|
-
/* @__PURE__ */ (0,
|
|
1998
|
-
/* @__PURE__ */ (0,
|
|
2797
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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: [
|
|
2798
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2799
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-medium text-slate-700", children: "\u05E9\u05D5\u05E8\u05D5\u05EA \u05DC\u05E2\u05DE\u05D5\u05D3:" }),
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1999
2801
|
"select",
|
|
2000
2802
|
{
|
|
2001
2803
|
value: limit,
|
|
@@ -2003,27 +2805,27 @@ function TableBlockClient({
|
|
|
2003
2805
|
disabled: isLoading || isUpdatingActive,
|
|
2004
2806
|
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",
|
|
2005
2807
|
children: [
|
|
2006
|
-
/* @__PURE__ */ (0,
|
|
2007
|
-
/* @__PURE__ */ (0,
|
|
2008
|
-
/* @__PURE__ */ (0,
|
|
2808
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: 20, children: "20" }),
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: 50, children: "50" }),
|
|
2810
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: 100, children: "100" })
|
|
2009
2811
|
]
|
|
2010
2812
|
}
|
|
2011
2813
|
)
|
|
2012
2814
|
] }),
|
|
2013
|
-
/* @__PURE__ */ (0,
|
|
2014
|
-
/* @__PURE__ */ (0,
|
|
2815
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "font-medium text-slate-600", children: [
|
|
2015
2817
|
"\u05E2\u05DE\u05D5\u05D3 ",
|
|
2016
|
-
/* @__PURE__ */ (0,
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { className: "text-slate-900", children: page }),
|
|
2017
2819
|
" \u05DE\u05EA\u05D5\u05DA ",
|
|
2018
|
-
/* @__PURE__ */ (0,
|
|
2019
|
-
totalRecords > 0 && /* @__PURE__ */ (0,
|
|
2820
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { className: "text-slate-900", children: totalPages || 1 }),
|
|
2821
|
+
totalRecords > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "text-slate-500 font-normal", children: [
|
|
2020
2822
|
" (",
|
|
2021
2823
|
totalRecords,
|
|
2022
2824
|
' \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D1\u05E1\u05D4"\u05DB)'
|
|
2023
2825
|
] })
|
|
2024
2826
|
] }),
|
|
2025
|
-
/* @__PURE__ */ (0,
|
|
2026
|
-
/* @__PURE__ */ (0,
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2027
2829
|
"button",
|
|
2028
2830
|
{
|
|
2029
2831
|
onClick: handlePrevPage,
|
|
@@ -2033,7 +2835,7 @@ function TableBlockClient({
|
|
|
2033
2835
|
children: "\u05D4\u05E7\u05D5\u05D3\u05DD"
|
|
2034
2836
|
}
|
|
2035
2837
|
),
|
|
2036
|
-
/* @__PURE__ */ (0,
|
|
2838
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2037
2839
|
"button",
|
|
2038
2840
|
{
|
|
2039
2841
|
onClick: handleNextPage,
|
|
@@ -2050,11 +2852,60 @@ function TableBlockClient({
|
|
|
2050
2852
|
}
|
|
2051
2853
|
);
|
|
2052
2854
|
}
|
|
2855
|
+
function ExpandedSubTables({
|
|
2856
|
+
rowId,
|
|
2857
|
+
rowData,
|
|
2858
|
+
subTableColumns,
|
|
2859
|
+
filteredColumnsLength,
|
|
2860
|
+
handleCellChange,
|
|
2861
|
+
context
|
|
2862
|
+
}) {
|
|
2863
|
+
var _a;
|
|
2864
|
+
const [activeTab, setActiveTab] = (0, import_react7.useState)((_a = subTableColumns[0]) == null ? void 0 : _a.name);
|
|
2865
|
+
if (subTableColumns.length === 0) return null;
|
|
2866
|
+
if (subTableColumns.length === 1) {
|
|
2867
|
+
const stCol = subTableColumns[0];
|
|
2868
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2869
|
+
SubTableViewer,
|
|
2870
|
+
{
|
|
2871
|
+
rowId,
|
|
2872
|
+
column: stCol,
|
|
2873
|
+
value: (rowData == null ? void 0 : rowData[stCol.name]) || [],
|
|
2874
|
+
onChange: (newVal) => handleCellChange(rowId, stCol.name, newVal),
|
|
2875
|
+
context
|
|
2876
|
+
}
|
|
2877
|
+
) }) });
|
|
2878
|
+
}
|
|
2879
|
+
const activeCol = subTableColumns.find((c) => c.name === activeTab) || subTableColumns[0];
|
|
2880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50 overflow-hidden", children: [
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.jsx)(
|
|
2882
|
+
"button",
|
|
2883
|
+
{
|
|
2884
|
+
type: "button",
|
|
2885
|
+
onClick: () => setActiveTab(col.name),
|
|
2886
|
+
className: `px-4 py-2 text-sm font-semibold rounded-t-lg transition-colors whitespace-nowrap cursor-pointer relative top-[1px] ${activeTab === col.name ? "bg-white border border-slate-200 border-b-transparent text-brand" : "bg-transparent border border-transparent text-slate-500 hover:text-slate-700 hover:bg-slate-200/50"}`,
|
|
2887
|
+
children: col.name
|
|
2888
|
+
},
|
|
2889
|
+
col.name
|
|
2890
|
+
)) }),
|
|
2891
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2892
|
+
SubTableViewer,
|
|
2893
|
+
{
|
|
2894
|
+
rowId,
|
|
2895
|
+
column: activeCol,
|
|
2896
|
+
value: (rowData == null ? void 0 : rowData[activeCol.name]) || [],
|
|
2897
|
+
onChange: (newVal) => handleCellChange(rowId, activeCol.name, newVal),
|
|
2898
|
+
context
|
|
2899
|
+
},
|
|
2900
|
+
activeCol.name
|
|
2901
|
+
) })
|
|
2902
|
+
] }) });
|
|
2903
|
+
}
|
|
2053
2904
|
|
|
2054
2905
|
// src/components/TableBlock/TableBlock.tsx
|
|
2055
|
-
var
|
|
2906
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2056
2907
|
function TableBlock(props) {
|
|
2057
|
-
return /* @__PURE__ */ (0,
|
|
2908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TableBlockClient, __spreadValues({}, props));
|
|
2058
2909
|
}
|
|
2059
2910
|
|
|
2060
2911
|
// src/registry.ts
|