@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/index.mjs CHANGED
@@ -39,7 +39,7 @@ function cn(...inputs) {
39
39
  }
40
40
 
41
41
  // src/components/TableBlock/TableBlockClient.tsx
42
- import { useState as useState4, useMemo as useMemo2, useEffect as useEffect2, useCallback as useCallback3, useRef as useRef3 } from "react";
42
+ import React6, { useState as useState5, useMemo as useMemo2, useEffect as useEffect4, useCallback as useCallback4, useRef as useRef4 } from "react";
43
43
 
44
44
  // src/hooks/useToast.ts
45
45
  import { useContext as useContext2 } from "react";
@@ -242,12 +242,36 @@ function useToast() {
242
242
  import React4 from "react";
243
243
 
244
244
  // src/components/TableBlock/fields/DrivePickerCell.tsx
245
- import { useState as useState2 } from "react";
245
+ import React2, { useState as useState2, useEffect } from "react";
246
246
  import { FileText, Upload, X as X2 } from "lucide-react";
247
247
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
248
- function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, context }) {
248
+ function DrivePickerCell({ value, onChange, tableName, column, rowId, onMarkForDeletion, context }) {
249
249
  const [isOpening, setIsOpening] = useState2(false);
250
250
  const { showError } = useToast();
251
+ const cellContextId = React2.useMemo(() => {
252
+ const colName = (column == null ? void 0 : column.name) || "col";
253
+ const rId = rowId || "row";
254
+ return `${rId}-${colName}`;
255
+ }, [rowId, column == null ? void 0 : column.name]);
256
+ const fileList = React2.useMemo(() => {
257
+ if (!value) return [];
258
+ if (Array.isArray(value)) return value;
259
+ if (typeof value === "object" && (value.fileId || value.fileUrl || value.url)) {
260
+ return [value];
261
+ }
262
+ return [];
263
+ }, [value]);
264
+ useEffect(() => {
265
+ const handleMessage = (event) => {
266
+ var _a, _b, _c;
267
+ 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) {
268
+ const incoming = Array.isArray(event.data.payload) ? event.data.payload : [event.data.payload];
269
+ onChange([...fileList, ...incoming]);
270
+ }
271
+ };
272
+ window.addEventListener("message", handleMessage);
273
+ return () => window.removeEventListener("message", handleMessage);
274
+ }, [fileList, onChange, cellContextId]);
251
275
  const openUploadPopup = async () => {
252
276
  if (isOpening) return;
253
277
  setIsOpening(true);
@@ -276,34 +300,35 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
276
300
  } catch (e) {
277
301
  }
278
302
  }
279
- const actionResult = await context.executeAction("UPLOAD_DRIVE_FILE", { tableName });
303
+ const actionResult = await context.executeAction("UPLOAD_DRIVE_FILE", { tableName, cellContextId });
280
304
  const folderId = actionResult == null ? void 0 : actionResult.folderId;
281
- const pickerUrl = (actionResult == null ? void 0 : actionResult.pickerUrl) || (folderId ? `/embed/picker?folderId=${encodeURIComponent(folderId)}` : `/embed/picker`);
305
+ let pickerUrl = (actionResult == null ? void 0 : actionResult.pickerUrl) || (folderId ? `/embed/picker?folderId=${encodeURIComponent(folderId)}` : `/embed/picker`);
306
+ if (!pickerUrl.includes("cellContextId=")) {
307
+ const separator = pickerUrl.includes("?") ? "&" : "?";
308
+ pickerUrl = `${pickerUrl}${separator}cellContextId=${encodeURIComponent(cellContextId)}`;
309
+ }
282
310
  if (popup) {
283
311
  popup.location.href = pickerUrl;
284
312
  }
285
- const newFile = await new Promise((resolve) => {
313
+ await new Promise((resolve) => {
286
314
  let timer = null;
287
- const handleMessage = (event) => {
315
+ const handlePopupMessage = (event) => {
288
316
  var _a, _b;
289
- if (((_a = event.data) == null ? void 0 : _a.type) === "DRIVE_UPLOAD_SUCCESS" && ((_b = event.data) == null ? void 0 : _b.payload)) {
290
- window.removeEventListener("message", handleMessage);
317
+ if (((_a = event.data) == null ? void 0 : _a.type) === "DRIVE_UPLOAD_SUCCESS" && ((_b = event.data) == null ? void 0 : _b.cellContextId) === cellContextId) {
318
+ window.removeEventListener("message", handlePopupMessage);
291
319
  if (timer) clearInterval(timer);
292
- resolve(event.data.payload);
320
+ resolve();
293
321
  }
294
322
  };
295
323
  timer = setInterval(() => {
296
324
  if (!popup || popup.closed) {
297
325
  if (timer) clearInterval(timer);
298
- window.removeEventListener("message", handleMessage);
299
- resolve(null);
326
+ window.removeEventListener("message", handlePopupMessage);
327
+ resolve();
300
328
  }
301
329
  }, 800);
302
- window.addEventListener("message", handleMessage);
330
+ window.addEventListener("message", handlePopupMessage);
303
331
  });
304
- if (newFile) {
305
- onChange(newFile);
306
- }
307
332
  }
308
333
  } catch (error) {
309
334
  console.error("[DrivePickerCell] Error uploading file:", error);
@@ -313,40 +338,15 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
313
338
  setIsOpening(false);
314
339
  }
315
340
  };
316
- if (value == null ? void 0 : value.fileUrl) {
317
- return /* @__PURE__ */ jsxs2("div", { className: "flex items-center w-full h-8 px-2 gap-1", children: [
318
- /* @__PURE__ */ jsxs2(
319
- "a",
320
- {
321
- href: value.fileUrl,
322
- target: "_blank",
323
- rel: "noopener noreferrer",
324
- 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",
325
- title: value.fileName || "Open file",
326
- children: [
327
- /* @__PURE__ */ jsx2(FileText, { className: "w-3.5 h-3.5 shrink-0" }),
328
- /* @__PURE__ */ jsx2("span", { className: "truncate", children: value.fileName || "Unnamed file" })
329
- ]
330
- }
331
- ),
332
- /* @__PURE__ */ jsx2(
333
- "button",
334
- {
335
- type: "button",
336
- onClick: () => {
337
- if ((value == null ? void 0 : value.fileId) && onMarkForDeletion) {
338
- onMarkForDeletion(value.fileId);
339
- }
340
- onChange(null);
341
- },
342
- className: "shrink-0 p-0.5 rounded hover:bg-rose-100 text-slate-400 hover:text-rose-500 transition-colors",
343
- title: "Remove file",
344
- children: /* @__PURE__ */ jsx2(X2, { className: "w-3.5 h-3.5" })
345
- }
346
- )
347
- ] });
348
- }
349
- return /* @__PURE__ */ jsx2("div", { className: "flex items-center w-full h-8 px-2", children: /* @__PURE__ */ jsxs2(
341
+ const handleRemoveFile = (indexToRemove) => {
342
+ const fileToRemove = fileList[indexToRemove];
343
+ if ((fileToRemove == null ? void 0 : fileToRemove.fileId) && onMarkForDeletion) {
344
+ onMarkForDeletion(fileToRemove.fileId);
345
+ }
346
+ const updated = fileList.filter((_, idx) => idx !== indexToRemove);
347
+ onChange(updated);
348
+ };
349
+ const renderUploadButton = () => /* @__PURE__ */ jsx2("div", { className: "flex items-center w-full h-8 px-2", children: /* @__PURE__ */ jsxs2(
350
350
  "button",
351
351
  {
352
352
  type: "button",
@@ -359,10 +359,42 @@ function DrivePickerCell({ value, onChange, tableName, onMarkForDeletion, contex
359
359
  ]
360
360
  }
361
361
  ) });
362
+ if (fileList.length > 0) {
363
+ return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col w-full py-1 gap-1", children: [
364
+ fileList.map((file, idx) => /* @__PURE__ */ jsxs2("div", { className: "flex items-center w-full h-8 px-2 gap-1", children: [
365
+ /* @__PURE__ */ jsxs2(
366
+ "a",
367
+ {
368
+ href: file.fileUrl || file.url,
369
+ target: "_blank",
370
+ rel: "noopener noreferrer",
371
+ 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",
372
+ title: file.fileName || "Open file",
373
+ children: [
374
+ /* @__PURE__ */ jsx2(FileText, { className: "w-3.5 h-3.5 shrink-0" }),
375
+ /* @__PURE__ */ jsx2("span", { className: "truncate", children: file.fileName || "Unnamed file" })
376
+ ]
377
+ }
378
+ ),
379
+ /* @__PURE__ */ jsx2(
380
+ "button",
381
+ {
382
+ type: "button",
383
+ onClick: () => handleRemoveFile(idx),
384
+ className: "shrink-0 p-0.5 rounded hover:bg-rose-100 text-slate-400 hover:text-rose-500 transition-colors",
385
+ title: "Remove file",
386
+ children: /* @__PURE__ */ jsx2(X2, { className: "w-3.5 h-3.5" })
387
+ }
388
+ )
389
+ ] }, file.fileId || idx)),
390
+ renderUploadButton()
391
+ ] });
392
+ }
393
+ return renderUploadButton();
362
394
  }
363
395
 
364
396
  // src/components/TableBlock/fields/DatePickerCell.tsx
365
- import { useState as useState3, useRef as useRef2, useEffect, useMemo, useCallback as useCallback2 } from "react";
397
+ import { useState as useState3, useRef as useRef2, useEffect as useEffect2, useMemo, useCallback as useCallback2 } from "react";
366
398
  import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, X as X3 } from "lucide-react";
367
399
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
368
400
  function parseDateParts(val) {
@@ -447,13 +479,13 @@ function DatePickerCell({ value, onChange, readOnly = false }) {
447
479
  const parsedParts = useMemo(() => parseDateParts(value), [value]);
448
480
  const displayString = useMemo(() => formatDateDisplay(parsedParts), [parsedParts]);
449
481
  const [rawInput, setRawInput] = useState3(displayString);
450
- useEffect(() => {
482
+ useEffect2(() => {
451
483
  setRawInput(displayString);
452
484
  }, [displayString]);
453
485
  const now = /* @__PURE__ */ new Date();
454
486
  const [viewYear, setViewYear] = useState3((parsedParts == null ? void 0 : parsedParts.year) || now.getFullYear());
455
487
  const [viewMonth, setViewMonth] = useState3((parsedParts == null ? void 0 : parsedParts.month) || now.getMonth() + 1);
456
- useEffect(() => {
488
+ useEffect2(() => {
457
489
  if (parsedParts) {
458
490
  setViewYear(parsedParts.year);
459
491
  setViewMonth(parsedParts.month);
@@ -478,7 +510,7 @@ function DatePickerCell({ value, onChange, readOnly = false }) {
478
510
  }
479
511
  }
480
512
  }, []);
481
- useEffect(() => {
513
+ useEffect2(() => {
482
514
  if (!isOpen) return;
483
515
  updatePopoverPosition();
484
516
  function handleScrollOrResize() {
@@ -793,11 +825,13 @@ var FORM_INPUTS = {
793
825
  className: "w-4 h-4 rounded border-slate-300 text-brand"
794
826
  }
795
827
  ) }),
796
- GOOGLE_DRIVE_FILE: ({ value, onChange, context }) => /* @__PURE__ */ jsx4(
828
+ GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ jsx4(
797
829
  DrivePickerCell,
798
830
  {
799
- value: value || null,
831
+ value: value || [],
800
832
  onChange,
833
+ column,
834
+ rowId,
801
835
  tableName: context == null ? void 0 : context.tableName,
802
836
  onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
803
837
  context
@@ -855,6 +889,228 @@ var FORM_INPUTS = {
855
889
  }
856
890
  }
857
891
  ),
892
+ PHONE: ({ value, onChange }) => /* @__PURE__ */ jsx4(
893
+ "input",
894
+ {
895
+ type: "tel",
896
+ className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
897
+ value: value !== void 0 && value !== null ? String(value) : "",
898
+ onChange: (e) => onChange(e.target.value),
899
+ dir: "ltr"
900
+ }
901
+ ),
902
+ GOOGLE_CONTACT: ({ value, column, rowId, onChange, context }) => {
903
+ const [isSyncing, setIsSyncing] = React4.useState(false);
904
+ const { addToast } = useToast();
905
+ const googleClientIdRef = React4.useRef(null);
906
+ const ensureGisScript = React4.useCallback(() => {
907
+ return new Promise((resolve, reject) => {
908
+ var _a, _b, _c;
909
+ if ((_c = (_b = (_a = window.google) == null ? void 0 : _a.accounts) == null ? void 0 : _b.oauth2) == null ? void 0 : _c.initTokenClient) {
910
+ resolve();
911
+ return;
912
+ }
913
+ if (document.querySelector('script[src*="accounts.google.com/gsi/client"]')) {
914
+ const waitForLoad = setInterval(() => {
915
+ var _a2, _b2, _c2;
916
+ if ((_c2 = (_b2 = (_a2 = window.google) == null ? void 0 : _a2.accounts) == null ? void 0 : _b2.oauth2) == null ? void 0 : _c2.initTokenClient) {
917
+ clearInterval(waitForLoad);
918
+ resolve();
919
+ }
920
+ }, 100);
921
+ setTimeout(() => {
922
+ clearInterval(waitForLoad);
923
+ reject(new Error("GIS script load timeout"));
924
+ }, 1e4);
925
+ return;
926
+ }
927
+ const script = document.createElement("script");
928
+ script.src = "https://accounts.google.com/gsi/client";
929
+ script.async = true;
930
+ script.onload = () => resolve();
931
+ script.onerror = () => reject(new Error("Failed to load Google Identity Services"));
932
+ document.head.appendChild(script);
933
+ });
934
+ }, []);
935
+ const requestGisToken = React4.useCallback(async (hint) => {
936
+ await ensureGisScript();
937
+ if (!googleClientIdRef.current && (context == null ? void 0 : context.executeAction)) {
938
+ try {
939
+ const config = await context.executeAction("GET_GOOGLE_CONFIG", {});
940
+ googleClientIdRef.current = (config == null ? void 0 : config.clientId) || "";
941
+ } catch (e) {
942
+ throw new Error("Failed to fetch Google configuration");
943
+ }
944
+ }
945
+ const clientId = googleClientIdRef.current;
946
+ if (!clientId) {
947
+ throw new Error("Google Client ID is not configured");
948
+ }
949
+ const accessToken = await new Promise((resolve, reject) => {
950
+ const tokenClient = window.google.accounts.oauth2.initTokenClient({
951
+ client_id: clientId,
952
+ scope: "https://www.googleapis.com/auth/contacts https://www.googleapis.com/auth/userinfo.email",
953
+ prompt: hint ? "" : "select_account",
954
+ hint: hint || void 0,
955
+ callback: (tokenResponse) => {
956
+ if (tokenResponse == null ? void 0 : tokenResponse.access_token) {
957
+ resolve(tokenResponse.access_token);
958
+ } else {
959
+ reject(new Error("Google authorization was cancelled or failed"));
960
+ }
961
+ },
962
+ error_callback: (err) => {
963
+ reject(new Error((err == null ? void 0 : err.message) || "Google authorization error"));
964
+ }
965
+ });
966
+ tokenClient.requestAccessToken({ hint: hint || void 0 });
967
+ });
968
+ let email = "";
969
+ try {
970
+ const res = await fetch("https://www.googleapis.com/oauth2/v3/userinfo", {
971
+ headers: { Authorization: `Bearer ${accessToken}` }
972
+ });
973
+ if (res.ok) {
974
+ const info = await res.json();
975
+ email = info.email || "";
976
+ }
977
+ } catch (e) {
978
+ }
979
+ return { accessToken, email };
980
+ }, [ensureGisScript, context]);
981
+ const handleSync = async () => {
982
+ var _a, _b, _c;
983
+ if (!(context == null ? void 0 : context.executeAction)) return;
984
+ setIsSyncing(true);
985
+ try {
986
+ const mapping = column.contactMapping || {};
987
+ const rowData = context.rowData || {};
988
+ let hasPhone = false;
989
+ if (mapping.phoneCol && rowData[mapping.phoneCol]) hasPhone = true;
990
+ let hasName = false;
991
+ if (mapping.nameParts && Array.isArray(mapping.nameParts)) {
992
+ for (const part of mapping.nameParts) {
993
+ if (part.type === "LOCAL" && rowData[part.columnId]) hasName = true;
994
+ 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;
995
+ }
996
+ }
997
+ if (!hasPhone) {
998
+ 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" });
999
+ setIsSyncing(false);
1000
+ return;
1001
+ }
1002
+ if (!hasName) {
1003
+ 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" });
1004
+ setIsSyncing(false);
1005
+ return;
1006
+ }
1007
+ let accessToken;
1008
+ let userEmail = "";
1009
+ try {
1010
+ const gisResult = await requestGisToken();
1011
+ accessToken = gisResult.accessToken;
1012
+ userEmail = gisResult.email;
1013
+ } catch (gisError) {
1014
+ addToast({ type: "warning", message: gisError.message || "\u05D4\u05D4\u05E8\u05E9\u05D0\u05D4 \u05DC\u05D2\u05D5\u05D2\u05DC \u05E0\u05DB\u05E9\u05DC\u05D4" });
1015
+ setIsSyncing(false);
1016
+ return;
1017
+ }
1018
+ const payload = {
1019
+ nameParts: mapping.nameParts || [],
1020
+ phoneCol: mapping.phoneCol,
1021
+ emailCol: mapping.emailCol,
1022
+ localRowData: rowData,
1023
+ parentRecord: context.parentRecord,
1024
+ accessToken,
1025
+ userEmail
1026
+ };
1027
+ const res = await context.executeAction("SYNC_GOOGLE_CONTACT", payload);
1028
+ if (res && res.synced) {
1029
+ if (context.updateQuietly) {
1030
+ context.updateQuietly(rowId, column.name, res);
1031
+ } else {
1032
+ onChange(res);
1033
+ }
1034
+ if (context.tableId && !rowId.startsWith("temp_")) {
1035
+ await context.executeAction("UPDATE_RECORD", {
1036
+ tableId: context.tableId,
1037
+ recordId: rowId,
1038
+ data: { [column.name]: res }
1039
+ });
1040
+ }
1041
+ }
1042
+ } catch (error) {
1043
+ console.error("Failed to sync contact:", error);
1044
+ addToast({ type: "warning", message: "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E1\u05E0\u05DB\u05E8\u05D5\u05DF \u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8: " + error.message });
1045
+ } finally {
1046
+ setIsSyncing(false);
1047
+ }
1048
+ };
1049
+ const handleUnlink = async () => {
1050
+ let accessToken;
1051
+ try {
1052
+ let emailHint = value == null ? void 0 : value.userEmail;
1053
+ if (!emailHint && (value == null ? void 0 : value.url)) {
1054
+ try {
1055
+ const parsed = new URL(value.url);
1056
+ emailHint = parsed.searchParams.get("authuser") || void 0;
1057
+ } catch (e) {
1058
+ }
1059
+ }
1060
+ const auth = await requestGisToken(emailHint);
1061
+ accessToken = auth.accessToken;
1062
+ } catch (err) {
1063
+ console.warn("[handleUnlink] Could not obtain token via GIS, falling back to server default token:", err);
1064
+ }
1065
+ if ((value == null ? void 0 : value.resourceName) && (context == null ? void 0 : context.executeAction)) {
1066
+ await context.executeAction("DELETE_GOOGLE_CONTACT", {
1067
+ resourceName: value.resourceName,
1068
+ accessToken
1069
+ });
1070
+ }
1071
+ if (context == null ? void 0 : context.updateQuietly) {
1072
+ context.updateQuietly(rowId, column.name, null);
1073
+ } else {
1074
+ onChange(null);
1075
+ }
1076
+ if ((context == null ? void 0 : context.tableId) && (context == null ? void 0 : context.executeAction) && !rowId.startsWith("temp_")) {
1077
+ await context.executeAction("UPDATE_RECORD", {
1078
+ tableId: context.tableId,
1079
+ recordId: rowId,
1080
+ data: { [column.name]: null }
1081
+ });
1082
+ }
1083
+ };
1084
+ if (value && value.synced && value.url) {
1085
+ return /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 h-8 px-2 group", children: [
1086
+ /* @__PURE__ */ jsx4("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" }),
1087
+ /* @__PURE__ */ jsx4(
1088
+ "button",
1089
+ {
1090
+ onClick: handleUnlink,
1091
+ className: "text-slate-400 hover:text-rose-500 opacity-0 group-hover:opacity-100 transition-opacity p-1",
1092
+ title: "\u05D1\u05D8\u05DC \u05E1\u05E0\u05DB\u05E8\u05D5\u05DF",
1093
+ children: /* @__PURE__ */ jsx4("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
1094
+ }
1095
+ )
1096
+ ] });
1097
+ }
1098
+ return /* @__PURE__ */ jsx4("div", { className: "flex items-center h-8 px-2", children: /* @__PURE__ */ jsxs4(
1099
+ "button",
1100
+ {
1101
+ onClick: handleSync,
1102
+ disabled: isSyncing,
1103
+ className: "flex items-center gap-1.5 px-3 py-1 bg-blue-50 text-blue-600 hover:bg-blue-100 border border-blue-200 rounded-md text-xs font-medium transition-colors disabled:opacity-50",
1104
+ children: [
1105
+ isSyncing ? /* @__PURE__ */ jsxs4("svg", { className: "w-3.5 h-3.5 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
1106
+ /* @__PURE__ */ jsx4("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
1107
+ /* @__PURE__ */ jsx4("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
1108
+ ] }) : /* @__PURE__ */ jsx4("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 4v16m8-8H4" }) }),
1109
+ "\u05E1\u05E0\u05DB\u05E8\u05DF \u05DC\u05D2\u05D5\u05D2\u05DC"
1110
+ ]
1111
+ }
1112
+ ) });
1113
+ },
858
1114
  DEFAULT: ({ value, onChange }) => /* @__PURE__ */ jsx4(
859
1115
  "input",
860
1116
  {
@@ -863,12 +1119,459 @@ var FORM_INPUTS = {
863
1119
  value: value !== void 0 && value !== null ? String(value) : "",
864
1120
  onChange: (e) => onChange(e.target.value)
865
1121
  }
866
- )
1122
+ ),
1123
+ SUB_TABLE: ({ value, column }) => {
1124
+ if (!Array.isArray(value)) return /* @__PURE__ */ jsx4("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
1125
+ const selected = value.filter((e) => e == null ? void 0 : e.isSelected);
1126
+ if (selected.length === 0) return /* @__PURE__ */ jsx4("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
1127
+ const displayFields = column.subTableDisplayFields || [];
1128
+ return /* @__PURE__ */ jsx4("div", { className: "px-1.5 py-1 flex flex-wrap items-center gap-1 h-full", children: selected.map((entry, idx) => {
1129
+ var _a;
1130
+ let label = "";
1131
+ if (entry._resolvedData && displayFields.length > 0) {
1132
+ label = displayFields.map((f) => String(entry._resolvedData[f] || "")).filter(Boolean).join(" ");
1133
+ }
1134
+ if (!label) label = ((_a = entry.recordId) == null ? void 0 : _a.slice(-6)) || "...";
1135
+ return /* @__PURE__ */ jsx4(
1136
+ "span",
1137
+ {
1138
+ 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",
1139
+ title: label,
1140
+ children: label
1141
+ },
1142
+ entry.recordId || idx
1143
+ );
1144
+ }) });
1145
+ }
867
1146
  };
868
1147
 
1148
+ // src/components/TableBlock/fields/SubTableViewer.tsx
1149
+ import { useState as useState4, useEffect as useEffect3, useRef as useRef3, useCallback as useCallback3 } from "react";
1150
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1151
+ function SubTableViewer({ rowId, column, value, onChange, context }) {
1152
+ var _a;
1153
+ const { addToast } = useToast();
1154
+ const entries = Array.isArray(value) ? value : [];
1155
+ const [linkedRecords, setLinkedRecords] = useState4([]);
1156
+ const [targetSchema, setTargetSchema] = useState4(null);
1157
+ const [isLoading, setIsLoading] = useState4(true);
1158
+ const [isSearchOpen, setIsSearchOpen] = useState4(false);
1159
+ const [searchQuery, setSearchQuery] = useState4("");
1160
+ const [searchResults, setSearchResults] = useState4([]);
1161
+ const [isSearching, setIsSearching] = useState4(false);
1162
+ const [isCreating, setIsCreating] = useState4(false);
1163
+ const [newRecordData, setNewRecordData] = useState4({});
1164
+ const searchRef = useRef3(null);
1165
+ const searchTimerRef = useRef3(null);
1166
+ const executeAction = context == null ? void 0 : context.executeAction;
1167
+ const referencedTableId = column.referencedTableId;
1168
+ const fetchedIdsRef = useRef3(/* @__PURE__ */ new Set());
1169
+ useEffect3(() => {
1170
+ if (!referencedTableId || !executeAction) {
1171
+ setIsLoading(false);
1172
+ return;
1173
+ }
1174
+ const recordIdsToFetch = entries.map((e) => e.recordId).filter((id) => !fetchedIdsRef.current.has(id));
1175
+ if (recordIdsToFetch.length === 0 && targetSchema) return;
1176
+ if (recordIdsToFetch.length > 0) {
1177
+ recordIdsToFetch.forEach((id) => fetchedIdsRef.current.add(id));
1178
+ }
1179
+ setIsLoading(true);
1180
+ executeAction("FETCH_SUB_TABLE_RECORDS", { referencedTableId, recordIds: recordIdsToFetch }).then((res) => {
1181
+ const payload = (res == null ? void 0 : res.data) || res;
1182
+ if (payload == null ? void 0 : payload.records) {
1183
+ setLinkedRecords((prev) => {
1184
+ const map = new Map(prev.map((r) => [r.id, r]));
1185
+ payload.records.forEach((r) => map.set(r.id, r));
1186
+ return Array.from(map.values());
1187
+ });
1188
+ }
1189
+ if (payload == null ? void 0 : payload.schema) {
1190
+ setTargetSchema(payload.schema);
1191
+ }
1192
+ }).catch(() => {
1193
+ recordIdsToFetch.forEach((id) => fetchedIdsRef.current.delete(id));
1194
+ }).finally(() => setIsLoading(false));
1195
+ }, [referencedTableId, executeAction, entries, targetSchema]);
1196
+ useEffect3(() => {
1197
+ const handleClick = (e) => {
1198
+ if (searchRef.current && !searchRef.current.contains(e.target)) {
1199
+ setIsSearchOpen(false);
1200
+ }
1201
+ };
1202
+ if (isSearchOpen) document.addEventListener("mousedown", handleClick);
1203
+ return () => document.removeEventListener("mousedown", handleClick);
1204
+ }, [isSearchOpen]);
1205
+ const handleSearch = useCallback3((query) => {
1206
+ setSearchQuery(query);
1207
+ if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
1208
+ if (!query.trim()) {
1209
+ setSearchResults([]);
1210
+ return;
1211
+ }
1212
+ searchTimerRef.current = setTimeout(async () => {
1213
+ if (!executeAction || !referencedTableId) return;
1214
+ setIsSearching(true);
1215
+ try {
1216
+ const excludeIds = entries.map((e) => e.recordId);
1217
+ const res = await executeAction("SEARCH_SUB_TABLE_RECORDS", {
1218
+ referencedTableId,
1219
+ query: query.trim(),
1220
+ excludeIds,
1221
+ limit: 15
1222
+ });
1223
+ setSearchResults(Array.isArray(res) ? res : []);
1224
+ } catch (e) {
1225
+ setSearchResults([]);
1226
+ } finally {
1227
+ setIsSearching(false);
1228
+ }
1229
+ }, 300);
1230
+ }, [executeAction, referencedTableId, entries]);
1231
+ const targetColumns = ((targetSchema == null ? void 0 : targetSchema.columns) || []).filter(
1232
+ (c) => {
1233
+ if (c.name === "_id" || c.type === "SUB_TABLE") return false;
1234
+ return true;
1235
+ }
1236
+ );
1237
+ const [relationOptions, setRelationOptions] = useState4({});
1238
+ useEffect3(() => {
1239
+ if (!executeAction || targetColumns.length === 0) return;
1240
+ const relationCols = targetColumns.filter((c) => {
1241
+ var _a2;
1242
+ return ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION" && c.referencedTableId;
1243
+ });
1244
+ relationCols.forEach(async (col) => {
1245
+ try {
1246
+ const options = await executeAction("FETCH_RELATION", {
1247
+ referencedTableId: col.referencedTableId,
1248
+ displayField: col.displayField
1249
+ });
1250
+ if (options && Array.isArray(options)) {
1251
+ setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
1252
+ }
1253
+ } catch (err) {
1254
+ console.warn(`[SubTableViewer] Could not fetch relation options for column ${col.name}:`, err);
1255
+ }
1256
+ });
1257
+ }, [executeAction, targetColumns]);
1258
+ const refetchRelation = useCallback3(async (colName) => {
1259
+ var _a2;
1260
+ const col = targetColumns.find((c) => c.name === colName);
1261
+ if (!col || ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) !== "RELATION" || !col.referencedTableId || !executeAction) return;
1262
+ try {
1263
+ const options = await executeAction("FETCH_RELATION", { referencedTableId: col.referencedTableId, displayField: col.displayField });
1264
+ if (options && Array.isArray(options)) {
1265
+ setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [col.name]: options }));
1266
+ }
1267
+ } catch (err) {
1268
+ console.warn(`[SubTableViewer] Could not refetch relation options for column ${col.name}:`, err);
1269
+ }
1270
+ }, [targetColumns, executeAction]);
1271
+ const updateParentLinkage = async (updated) => {
1272
+ const isNewRow = rowId.startsWith("temp_");
1273
+ if (context == null ? void 0 : context.updateQuietly) {
1274
+ context.updateQuietly(rowId, column.name, updated);
1275
+ } else {
1276
+ onChange(updated);
1277
+ }
1278
+ if (executeAction && (context == null ? void 0 : context.parentTableId) && !isNewRow) {
1279
+ try {
1280
+ const payloadToSave = updated.map(({ recordId, isSelected }) => ({ recordId, isSelected }));
1281
+ await executeAction("UPDATE_RECORD", {
1282
+ tableId: context.parentTableId,
1283
+ recordId: rowId,
1284
+ data: { [column.name]: payloadToSave }
1285
+ });
1286
+ if (context == null ? void 0 : context.triggerSaveSuccess) {
1287
+ context.triggerSaveSuccess();
1288
+ }
1289
+ } catch (err) {
1290
+ console.error("Failed to auto-save parent linkage", err);
1291
+ }
1292
+ }
1293
+ };
1294
+ const handleLinkRecord = (record) => {
1295
+ fetchedIdsRef.current.add(record.id);
1296
+ const newEntry = { recordId: record.id, isSelected: true, _resolvedData: record.data };
1297
+ const updated = [...entries, newEntry];
1298
+ updateParentLinkage(updated);
1299
+ setLinkedRecords((prev) => {
1300
+ const exists = prev.find((r) => r.id === record.id);
1301
+ if (exists) return prev;
1302
+ return [...prev, record];
1303
+ });
1304
+ setSearchQuery("");
1305
+ setSearchResults([]);
1306
+ setIsSearchOpen(false);
1307
+ };
1308
+ const handleUnlinkRecord = (recordId) => {
1309
+ const updated = entries.filter((e) => e.recordId !== recordId);
1310
+ updateParentLinkage(updated);
1311
+ setLinkedRecords((prev) => prev.filter((r) => r.id !== recordId));
1312
+ };
1313
+ const handleToggleSelected = (recordId) => {
1314
+ const record = linkedRecords.find((r) => r.id === recordId);
1315
+ const updated = entries.map(
1316
+ (e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { isSelected: !e.isSelected, _resolvedData: (record == null ? void 0 : record.data) || e._resolvedData }) : e
1317
+ );
1318
+ updateParentLinkage(updated);
1319
+ };
1320
+ const handleRecordCellChange = async (recordId, colName, value2) => {
1321
+ const updatedRecords = linkedRecords.map(
1322
+ (r) => r.id === recordId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value2 }) }) : r
1323
+ );
1324
+ setLinkedRecords(updatedRecords);
1325
+ const targetRecord = updatedRecords.find((r) => r.id === recordId);
1326
+ const updatedEntries = entries.map(
1327
+ (e) => e.recordId === recordId ? __spreadProps(__spreadValues({}, e), { _resolvedData: targetRecord == null ? void 0 : targetRecord.data }) : e
1328
+ );
1329
+ if (context == null ? void 0 : context.updateQuietly) {
1330
+ context.updateQuietly(rowId, column.name, updatedEntries);
1331
+ } else {
1332
+ onChange(updatedEntries);
1333
+ }
1334
+ if (executeAction && referencedTableId && !recordId.startsWith("temp_")) {
1335
+ try {
1336
+ await executeAction("UPDATE_RECORD", {
1337
+ tableId: referencedTableId,
1338
+ recordId,
1339
+ data: { [colName]: value2 }
1340
+ });
1341
+ if (context == null ? void 0 : context.triggerSaveSuccess) {
1342
+ context.triggerSaveSuccess();
1343
+ }
1344
+ } catch (err) {
1345
+ console.error("[SubTableViewer] Failed to auto-save linked record field", err);
1346
+ }
1347
+ }
1348
+ };
1349
+ const handleCreateRecord = async () => {
1350
+ var _a2;
1351
+ if (!executeAction || !referencedTableId) return;
1352
+ for (const col of targetColumns) {
1353
+ if (col.isRequired) {
1354
+ const val = newRecordData[col.name];
1355
+ if (val === void 0 || val === null || typeof val === "string" && val.trim() === "") {
1356
+ addToast({
1357
+ type: "error",
1358
+ message: `Validation Error: Field '${col.name}' is required but was not provided.`
1359
+ });
1360
+ return;
1361
+ }
1362
+ }
1363
+ }
1364
+ try {
1365
+ const res = await executeAction("CREATE_RECORD", {
1366
+ tableId: referencedTableId,
1367
+ records: [newRecordData]
1368
+ });
1369
+ if (res && res.success === false) {
1370
+ throw new Error(res.error || "Action execution failed");
1371
+ }
1372
+ const created = Array.isArray(res) ? res[0] : ((_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2[0]) || res;
1373
+ if (created) {
1374
+ const newRecord = {
1375
+ id: String(created.id || created._id),
1376
+ data: created.data || newRecordData
1377
+ };
1378
+ handleLinkRecord(newRecord);
1379
+ setIsCreating(false);
1380
+ setNewRecordData({});
1381
+ }
1382
+ } catch (err) {
1383
+ const msg = (err == null ? void 0 : err.message) || String(err);
1384
+ addToast({
1385
+ type: "error",
1386
+ message: msg
1387
+ });
1388
+ }
1389
+ };
1390
+ const getDisplayLabel = (record) => {
1391
+ const fields = column.subTableDisplayFields || [];
1392
+ if (fields.length === 0) {
1393
+ const firstField = Object.keys(record.data).find((k) => k !== "_id");
1394
+ return firstField ? String(record.data[firstField] || "") : record.id;
1395
+ }
1396
+ return fields.map((f) => String(record.data[f] || "")).filter(Boolean).join(" ");
1397
+ };
1398
+ return /* @__PURE__ */ jsxs5("div", { className: "p-3 animate-in fade-in slide-in-from-top-2 duration-200", dir: "rtl", children: [
1399
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-4 mb-2.5", children: [
1400
+ /* @__PURE__ */ jsx5("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx5("span", { className: "text-xs font-bold text-slate-600", children: (_a = targetSchema == null ? void 0 : targetSchema.name) != null ? _a : column.referencedTableName }) }),
1401
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1.5", children: [
1402
+ /* @__PURE__ */ jsxs5("div", { className: "relative", ref: searchRef, children: [
1403
+ /* @__PURE__ */ jsxs5(
1404
+ "button",
1405
+ {
1406
+ type: "button",
1407
+ onClick: () => setIsSearchOpen((prev) => !prev),
1408
+ className: "h-7 px-2.5 text-[11px] font-semibold bg-blue-50 hover:bg-blue-100 text-blue-700 border border-blue-200 rounded-md transition-colors cursor-pointer flex items-center gap-1",
1409
+ children: [
1410
+ /* @__PURE__ */ jsx5("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
1411
+ "\u05E7\u05D9\u05E9\u05D5\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA"
1412
+ ]
1413
+ }
1414
+ ),
1415
+ isSearchOpen && /* @__PURE__ */ jsxs5("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: [
1416
+ /* @__PURE__ */ jsx5(
1417
+ "input",
1418
+ {
1419
+ type: "text",
1420
+ value: searchQuery,
1421
+ onChange: (e) => handleSearch(e.target.value),
1422
+ placeholder: "\u05D7\u05E4\u05E9 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
1423
+ 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",
1424
+ autoFocus: true
1425
+ }
1426
+ ),
1427
+ /* @__PURE__ */ jsx5("div", { className: "max-h-48 overflow-y-auto", children: isSearching ? /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsx5("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__ */ jsx5(
1428
+ "button",
1429
+ {
1430
+ type: "button",
1431
+ onClick: () => handleLinkRecord(r),
1432
+ className: "w-full text-right px-2 py-1.5 text-xs hover:bg-blue-50 rounded cursor-pointer transition-colors",
1433
+ children: getDisplayLabel(r)
1434
+ },
1435
+ r.id
1436
+ )) : searchQuery.trim() ? /* @__PURE__ */ jsx5("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__ */ jsx5("p", { className: "text-xs text-slate-400 text-center py-3", children: "\u05D4\u05E7\u05DC\u05D3 \u05DC\u05D7\u05D9\u05E4\u05D5\u05E9..." }) })
1437
+ ] })
1438
+ ] }),
1439
+ /* @__PURE__ */ jsxs5(
1440
+ "button",
1441
+ {
1442
+ type: "button",
1443
+ onClick: () => {
1444
+ setIsCreating(true);
1445
+ const initialData = {};
1446
+ targetColumns.forEach((c) => {
1447
+ if (c.defaultValue !== void 0 && c.defaultValue !== null) {
1448
+ initialData[c.name] = c.type === "NUMBER" || c.type === "CURRENCY" ? parseFloat(c.defaultValue) : c.type === "BOOLEAN" ? c.defaultValue === "true" || c.defaultValue === true : c.defaultValue;
1449
+ } else {
1450
+ if (c.type === "NUMBER" || c.type === "CURRENCY") initialData[c.name] = 0;
1451
+ else if (c.type === "BOOLEAN") initialData[c.name] = false;
1452
+ else initialData[c.name] = "";
1453
+ }
1454
+ });
1455
+ setNewRecordData(initialData);
1456
+ },
1457
+ className: "h-7 px-2.5 text-[11px] font-semibold bg-emerald-50 hover:bg-emerald-100 text-emerald-700 border border-emerald-200 rounded-md transition-colors cursor-pointer flex items-center gap-1",
1458
+ children: [
1459
+ /* @__PURE__ */ jsx5("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) }),
1460
+ "\u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4"
1461
+ ]
1462
+ }
1463
+ )
1464
+ ] })
1465
+ ] }),
1466
+ isLoading ? /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ jsx5("div", { className: "w-5 h-5 border-2 border-blue-400 border-t-transparent rounded-full animate-spin" }) }) : entries.length === 0 && !isCreating ? /* @__PURE__ */ jsx5("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__ */ jsx5("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ jsxs5("table", { className: "w-full text-xs border-collapse", children: [
1467
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs5("tr", { className: "bg-slate-100/80", children: [
1468
+ /* @__PURE__ */ jsx5("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" }),
1469
+ targetColumns.map((col) => /* @__PURE__ */ jsx5("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)),
1470
+ /* @__PURE__ */ jsx5("th", { className: "border border-slate-200 px-2 py-1.5 w-14" })
1471
+ ] }) }),
1472
+ /* @__PURE__ */ jsxs5("tbody", { children: [
1473
+ entries.map((entry) => {
1474
+ const record = linkedRecords.find((r) => r.id === entry.recordId);
1475
+ return /* @__PURE__ */ jsxs5("tr", { className: "hover:bg-blue-50/30 transition-colors", children: [
1476
+ /* @__PURE__ */ jsx5("td", { className: "border border-slate-200 px-2 py-1 text-center", children: /* @__PURE__ */ jsx5(
1477
+ "input",
1478
+ {
1479
+ type: "checkbox",
1480
+ checked: entry.isSelected,
1481
+ onChange: () => handleToggleSelected(entry.recordId),
1482
+ className: "w-3.5 h-3.5 rounded border-slate-300 text-blue-600 cursor-pointer"
1483
+ }
1484
+ ) }),
1485
+ targetColumns.map((col) => {
1486
+ var _a2, _b;
1487
+ const colType = ((_a2 = col.type) == null ? void 0 : _a2.toUpperCase()) || "DEFAULT";
1488
+ const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
1489
+ return /* @__PURE__ */ jsx5("td", { className: "border border-slate-200 p-0 relative h-8", children: record ? /* @__PURE__ */ jsx5(
1490
+ InputComponent,
1491
+ {
1492
+ value: (_b = record.data[col.name]) != null ? _b : colType === "BOOLEAN" ? false : "",
1493
+ column: col,
1494
+ rowId: record.id,
1495
+ onChange: (v) => handleRecordCellChange(record.id, col.name, v),
1496
+ context: __spreadProps(__spreadValues({}, context), {
1497
+ 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",
1498
+ relationOptions,
1499
+ updateRelationOptions: (name, opts) => setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [name]: opts })),
1500
+ refetchRelation,
1501
+ parentRecord: { tableId: (context == null ? void 0 : context.parentTableId) || (context == null ? void 0 : context.tableId), data: context == null ? void 0 : context.rowData },
1502
+ rowData: record.data,
1503
+ tableId: targetSchema == null ? void 0 : targetSchema.id,
1504
+ updateQuietly: (rid, colName, val) => handleRecordCellChange(rid, colName, val)
1505
+ })
1506
+ }
1507
+ ) : /* @__PURE__ */ jsx5("span", { className: "text-slate-300 italic px-2", children: "\u05D8\u05D5\u05E2\u05DF..." }) }, col.name);
1508
+ }),
1509
+ /* @__PURE__ */ jsx5("td", { className: "border border-slate-200 px-1 py-1 text-center", children: /* @__PURE__ */ jsx5(
1510
+ "button",
1511
+ {
1512
+ type: "button",
1513
+ onClick: () => handleUnlinkRecord(entry.recordId),
1514
+ className: "text-slate-400 hover:text-rose-500 p-0.5 rounded transition-colors cursor-pointer inline-flex items-center justify-center w-full",
1515
+ title: "\u05D4\u05E1\u05E8 \u05E7\u05D9\u05E9\u05D5\u05E8",
1516
+ children: /* @__PURE__ */ jsx5("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
1517
+ }
1518
+ ) })
1519
+ ] }, entry.recordId);
1520
+ }),
1521
+ isCreating && /* @__PURE__ */ jsxs5("tr", { className: "bg-emerald-50/40", children: [
1522
+ /* @__PURE__ */ jsx5("td", { className: "border border-emerald-200 px-2 py-1 text-center", children: /* @__PURE__ */ jsx5("span", { className: "text-emerald-500 font-bold text-[10px]", children: "\u05D7\u05D3\u05E9" }) }),
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__ */ jsx5("td", { className: "border border-emerald-200 p-0 relative h-8", children: /* @__PURE__ */ jsx5(
1528
+ InputComponent,
1529
+ {
1530
+ value: (_b = newRecordData[col.name]) != null ? _b : colType === "BOOLEAN" ? false : "",
1531
+ column: col,
1532
+ rowId: "new_record",
1533
+ onChange: (v) => setNewRecordData((prev) => __spreadProps(__spreadValues({}, prev), { [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
+ refetchRelation
1538
+ })
1539
+ }
1540
+ ) }, `new_${col.name}`);
1541
+ }),
1542
+ /* @__PURE__ */ jsx5("td", { className: "border border-emerald-200 px-1 py-1 text-center", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-center gap-1", children: [
1543
+ /* @__PURE__ */ jsx5(
1544
+ "button",
1545
+ {
1546
+ type: "button",
1547
+ onClick: handleCreateRecord,
1548
+ className: "p-1 text-emerald-600 hover:bg-emerald-100 rounded transition-colors",
1549
+ title: "\u05E9\u05DE\u05D5\u05E8",
1550
+ children: /* @__PURE__ */ jsx5("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) })
1551
+ }
1552
+ ),
1553
+ /* @__PURE__ */ jsx5(
1554
+ "button",
1555
+ {
1556
+ type: "button",
1557
+ onClick: () => {
1558
+ setIsCreating(false);
1559
+ },
1560
+ className: "p-1 text-rose-500 hover:bg-rose-100 rounded transition-colors",
1561
+ title: "\u05D1\u05D9\u05D8\u05D5\u05DC",
1562
+ children: /* @__PURE__ */ jsx5("svg", { className: "w-3.5 h-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M6 18L18 6M6 6l12 12" }) })
1563
+ }
1564
+ )
1565
+ ] }) })
1566
+ ] })
1567
+ ] })
1568
+ ] }) })
1569
+ ] });
1570
+ }
1571
+
869
1572
  // src/components/TableBlock/TableBlockClient.tsx
870
1573
  import { X as X4, Copy as Copy2 } from "lucide-react";
871
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1574
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
872
1575
  function TableBlockClient({
873
1576
  data: initialRecords,
874
1577
  settings: schema,
@@ -885,14 +1588,14 @@ function TableBlockClient({
885
1588
  "data-testid": dataTestId
886
1589
  }) {
887
1590
  const { showError, addToast } = useToast();
888
- const [columnWidths, setColumnWidths] = useState4({});
889
- const [isMounted, setIsMounted] = useState4(false);
1591
+ const [columnWidths, setColumnWidths] = useState5({});
1592
+ const [isMounted, setIsMounted] = useState5(false);
890
1593
  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";
891
- const [page, setPage] = useState4(1);
892
- const [limit, setLimit] = useState4(50);
893
- const [totalRecords, setTotalRecords] = useState4(0);
894
- const [totalPages, setTotalPages] = useState4(1);
895
- useEffect2(() => {
1594
+ const [page, setPage] = useState5(1);
1595
+ const [limit, setLimit] = useState5(50);
1596
+ const [totalRecords, setTotalRecords] = useState5(0);
1597
+ const [totalPages, setTotalPages] = useState5(1);
1598
+ useEffect4(() => {
896
1599
  if (typeof window !== "undefined") {
897
1600
  const savedWidths = localStorage.getItem(`table_widths_${tableKey}`);
898
1601
  if (savedWidths) {
@@ -915,7 +1618,7 @@ function TableBlockClient({
915
1618
  }
916
1619
  setIsMounted(true);
917
1620
  }, [tableKey]);
918
- const [showSummary, setShowSummary] = useState4(false);
1621
+ const [showSummary, setShowSummary] = useState5(false);
919
1622
  const toggleSummary = () => {
920
1623
  setShowSummary((prev) => {
921
1624
  const next = !prev;
@@ -924,8 +1627,8 @@ function TableBlockClient({
924
1627
  return next;
925
1628
  });
926
1629
  };
927
- const [resizingCol, setResizingCol] = useState4(null);
928
- useEffect2(() => {
1630
+ const [resizingCol, setResizingCol] = useState5(null);
1631
+ useEffect4(() => {
929
1632
  if (!resizingCol) return;
930
1633
  const handleMouseMove = (e) => {
931
1634
  const diffX = resizingCol.startX - e.clientX;
@@ -972,7 +1675,7 @@ function TableBlockClient({
972
1675
  return __spreadProps(__spreadValues({}, row), { id: String(row.id || ""), data: rowData });
973
1676
  });
974
1677
  };
975
- const mergeColumnDefs = useCallback3((existingCols, incomingCols) => {
1678
+ const mergeColumnDefs = useCallback4((existingCols, incomingCols) => {
976
1679
  if (!incomingCols || incomingCols.length === 0) return existingCols || [];
977
1680
  if (!existingCols || existingCols.length === 0) return incomingCols;
978
1681
  const existingMap = new Map(existingCols.map((c) => [c.name, c]));
@@ -992,18 +1695,18 @@ function TableBlockClient({
992
1695
  return ((_a = a.order) != null ? _a : 0) - ((_b = b.order) != null ? _b : 0);
993
1696
  });
994
1697
  }, []);
995
- const [localColumns, setLocalColumns] = useState4(() => (schema == null ? void 0 : schema.columns) || []);
996
- useEffect2(() => {
1698
+ const [localColumns, setLocalColumns] = useState5(() => (schema == null ? void 0 : schema.columns) || []);
1699
+ useEffect4(() => {
997
1700
  if ((schema == null ? void 0 : schema.columns) && schema.columns.length > 0) {
998
1701
  setLocalColumns((prev) => mergeColumnDefs(prev, schema.columns));
999
1702
  }
1000
1703
  }, [schema == null ? void 0 : schema.columns, mergeColumnDefs]);
1001
- const [dirty, setDirty] = useState4({ added: [], modified: {}, deleted: [] });
1002
- const dirtyRef = useRef3(dirty);
1003
- useEffect2(() => {
1704
+ const [dirty, setDirty] = useState5({ added: [], modified: {}, deleted: [] });
1705
+ const dirtyRef = useRef4(dirty);
1706
+ useEffect4(() => {
1004
1707
  dirtyRef.current = dirty;
1005
1708
  }, [dirty]);
1006
- const mergeWithDirty = useCallback3((baseRecords) => {
1709
+ const mergeWithDirty = useCallback4((baseRecords) => {
1007
1710
  const { added, modified, deleted } = dirtyRef.current;
1008
1711
  const nonDeleted = (baseRecords || []).filter((r) => !deleted.includes(r.id));
1009
1712
  const modifiedRecords = nonDeleted.map((r) => {
@@ -1016,8 +1719,8 @@ function TableBlockClient({
1016
1719
  const uniqueAdded = added.filter((r) => !baseIds.has(r.id));
1017
1720
  return [...uniqueAdded, ...modifiedRecords];
1018
1721
  }, []);
1019
- const [data, setData] = useState4(() => normalizeRecords(initialRecords));
1020
- useEffect2(() => {
1722
+ const [data, setData] = useState5(() => normalizeRecords(initialRecords));
1723
+ useEffect4(() => {
1021
1724
  if (initialRecords) {
1022
1725
  setData(mergeWithDirty(normalizeRecords(initialRecords)));
1023
1726
  }
@@ -1032,19 +1735,19 @@ function TableBlockClient({
1032
1735
  }
1033
1736
  return false;
1034
1737
  };
1035
- const [baseRecordsMap, setBaseRecordsMap] = useState4(() => {
1738
+ const [baseRecordsMap, setBaseRecordsMap] = useState5(() => {
1036
1739
  const map = /* @__PURE__ */ new Map();
1037
1740
  (normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
1038
1741
  return map;
1039
1742
  });
1040
- useEffect2(() => {
1743
+ useEffect4(() => {
1041
1744
  if (initialRecords && initialRecords.length > 0) {
1042
1745
  const map = /* @__PURE__ */ new Map();
1043
1746
  (normalizeRecords(initialRecords) || []).forEach((r) => map.set(r.id, __spreadValues({}, r.data)));
1044
1747
  setBaseRecordsMap(map);
1045
1748
  }
1046
1749
  }, [initialRecords]);
1047
- const refetchTableData = useCallback3((targetPage) => {
1750
+ const refetchTableData = useCallback4((targetPage) => {
1048
1751
  const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
1049
1752
  if (!tableId || !executeAction) return Promise.resolve();
1050
1753
  const activePage = targetPage !== void 0 ? targetPage : page;
@@ -1078,8 +1781,8 @@ function TableBlockClient({
1078
1781
  }).catch((err) => {
1079
1782
  console.error("[TableBlock] Failed to auto-fetch table data:", err);
1080
1783
  });
1081
- }, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeWithDirty, mergeColumnDefs]);
1082
- useEffect2(() => {
1784
+ }, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, page, limit, executeAction, mergeColumnDefs]);
1785
+ useEffect4(() => {
1083
1786
  refetchTableData();
1084
1787
  }, [refetchTableData]);
1085
1788
  const handleLimitChange = (newLimit) => {
@@ -1095,19 +1798,20 @@ function TableBlockClient({
1095
1798
  const handleNextPage = () => {
1096
1799
  setPage((prev) => Math.min(totalPages, prev + 1));
1097
1800
  };
1098
- useEffect2(() => {
1801
+ useEffect4(() => {
1099
1802
  if (error) {
1100
1803
  showError(error, "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E8\u05DB\u05D9\u05D1");
1101
1804
  }
1102
1805
  }, [error, showError]);
1103
- const [searchQuery, setSearchQuery] = useState4("");
1104
- const [selectedIds, setSelectedIds] = useState4(/* @__PURE__ */ new Set());
1105
- const [pendingDeletions, setPendingDeletions] = useState4([]);
1106
- const [isSaving, setIsSaving] = useState4(false);
1107
- const [isSaveSuccess, setIsSaveSuccess] = useState4(false);
1108
- const [relationOptions, setRelationOptions] = useState4({});
1806
+ const [searchQuery, setSearchQuery] = useState5("");
1807
+ const [selectedIds, setSelectedIds] = useState5(/* @__PURE__ */ new Set());
1808
+ const [pendingDeletions, setPendingDeletions] = useState5([]);
1809
+ const [isSaving, setIsSaving] = useState5(false);
1810
+ const [isSaveSuccess, setIsSaveSuccess] = useState5(false);
1811
+ const [relationOptions, setRelationOptions] = useState5({});
1812
+ const [expandedRowIds, setExpandedRowIds] = useState5(/* @__PURE__ */ new Set());
1109
1813
  const schemaColsString = useMemo2(() => JSON.stringify(localColumns || []), [localColumns]);
1110
- const refetchRelation = useCallback3(async (colName) => {
1814
+ const refetchRelation = useCallback4(async (colName) => {
1111
1815
  var _a;
1112
1816
  let parsedCols = [];
1113
1817
  try {
@@ -1127,7 +1831,7 @@ function TableBlockClient({
1127
1831
  console.warn(`[TableBlock] Could not fetch relation options for column ${colName}:`, err);
1128
1832
  }
1129
1833
  }, [schemaColsString, executeAction]);
1130
- useEffect2(() => {
1834
+ useEffect4(() => {
1131
1835
  let parsedCols = [];
1132
1836
  try {
1133
1837
  parsedCols = JSON.parse(schemaColsString);
@@ -1163,9 +1867,9 @@ function TableBlockClient({
1163
1867
  const systemFields = ["_id", "createdAt", "updatedAt", "orgId", "tableId"];
1164
1868
  return normalizedColumns.filter((col) => !systemFields.includes(col.name));
1165
1869
  }, [normalizedColumns]);
1166
- const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = useState4(false);
1167
- const dropdownRef = useRef3(null);
1168
- useEffect2(() => {
1870
+ const [isColumnsDropdownOpen, setIsColumnsDropdownOpen] = useState5(false);
1871
+ const dropdownRef = useRef4(null);
1872
+ useEffect4(() => {
1169
1873
  const handleClickOutside = (e) => {
1170
1874
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
1171
1875
  setIsColumnsDropdownOpen(false);
@@ -1243,8 +1947,8 @@ function TableBlockClient({
1243
1947
  }
1244
1948
  }
1245
1949
  };
1246
- const [draggedColName, setDraggedColName] = useState4(null);
1247
- const [dragOverColName, setDragOverColName] = useState4(null);
1950
+ const [draggedColName, setDraggedColName] = useState5(null);
1951
+ const [dragOverColName, setDragOverColName] = useState5(null);
1248
1952
  const handleColumnReorder = async (draggedName, dropTargetName) => {
1249
1953
  var _a;
1250
1954
  if (draggedName === dropTargetName) return;
@@ -1286,6 +1990,10 @@ function TableBlockClient({
1286
1990
  var _a;
1287
1991
  const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
1288
1992
  let initialValue = col.defaultValue;
1993
+ if (typeUpper === "SUB_TABLE") {
1994
+ defaultData[col.name] = [];
1995
+ return;
1996
+ }
1289
1997
  if (initialValue !== void 0 && initialValue !== null && initialValue !== "") {
1290
1998
  if (typeUpper === "CURRENCY" || typeUpper === "NUMBER") {
1291
1999
  initialValue = parseFloat(initialValue);
@@ -1369,6 +2077,36 @@ function TableBlockClient({
1369
2077
  });
1370
2078
  }
1371
2079
  };
2080
+ const triggerSaveSuccess = useCallback4(() => {
2081
+ setIsSaveSuccess(true);
2082
+ setTimeout(() => {
2083
+ setIsSaveSuccess(false);
2084
+ }, 2500);
2085
+ }, []);
2086
+ const handleQuietCellChange = useCallback4((rowId, colName, value) => {
2087
+ setData((prev) => prev.map(
2088
+ (row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
2089
+ ));
2090
+ if (rowId.startsWith("temp_")) {
2091
+ setDirty((prev) => {
2092
+ if (!prev.added.some((r) => r.id === rowId)) return prev;
2093
+ return __spreadProps(__spreadValues({}, prev), {
2094
+ added: prev.added.map(
2095
+ (r) => r.id === rowId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value }) }) : r
2096
+ )
2097
+ });
2098
+ });
2099
+ } else {
2100
+ setBaseRecordsMap((prev) => {
2101
+ const next = new Map(prev);
2102
+ const rowData = next.get(rowId);
2103
+ if (rowData) {
2104
+ next.set(rowId, __spreadProps(__spreadValues({}, rowData), { [colName]: value }));
2105
+ }
2106
+ return next;
2107
+ });
2108
+ }
2109
+ }, []);
1372
2110
  const toggleSelectAll = (checked) => {
1373
2111
  const nextSelected = checked ? new Set(filteredData.map((r) => r.id)) : /* @__PURE__ */ new Set();
1374
2112
  setSelectedIds(nextSelected);
@@ -1398,9 +2136,15 @@ function TableBlockClient({
1398
2136
  const row = data.find((r) => r.id === id);
1399
2137
  if (row) {
1400
2138
  driveCols.forEach((col) => {
1401
- const fileObj = row.data[col.name];
1402
- if (fileObj && fileObj.fileId) {
1403
- filesToDelete.push(fileObj.fileId);
2139
+ const fileVal = row.data[col.name];
2140
+ if (Array.isArray(fileVal)) {
2141
+ fileVal.forEach((fileObj) => {
2142
+ if (fileObj && fileObj.fileId) {
2143
+ filesToDelete.push(fileObj.fileId);
2144
+ }
2145
+ });
2146
+ } else if (fileVal && fileVal.fileId) {
2147
+ filesToDelete.push(fileVal.fileId);
1404
2148
  }
1405
2149
  });
1406
2150
  }
@@ -1427,7 +2171,7 @@ function TableBlockClient({
1427
2171
  const formatPayload = (payload) => {
1428
2172
  const formatted = {};
1429
2173
  (localColumns || []).forEach((col) => {
1430
- var _a;
2174
+ var _a, _b;
1431
2175
  if (["_id", "id", "createdAt", "updatedAt", "orgId", "tableId", "isSelected"].includes(col.name)) return;
1432
2176
  let val = payload[col.name];
1433
2177
  if (val !== void 0) {
@@ -1437,6 +2181,11 @@ function TableBlockClient({
1437
2181
  if (((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "NUMBER") {
1438
2182
  val = val === "" ? 0 : Number(val);
1439
2183
  if (isNaN(val)) val = 0;
2184
+ } else if (((_b = col.type) == null ? void 0 : _b.toUpperCase()) === "SUB_TABLE" && Array.isArray(val)) {
2185
+ val = val.map((item) => {
2186
+ const _a2 = item, { _resolvedData } = _a2, rest = __objRest(_a2, ["_resolvedData"]);
2187
+ return rest;
2188
+ });
1440
2189
  }
1441
2190
  formatted[col.name] = val;
1442
2191
  }
@@ -1598,7 +2347,7 @@ function TableBlockClient({
1598
2347
  });
1599
2348
  return totals;
1600
2349
  }, [filteredData, filteredColumns, showSummary]);
1601
- return /* @__PURE__ */ jsxs5(
2350
+ return /* @__PURE__ */ jsxs6(
1602
2351
  "div",
1603
2352
  {
1604
2353
  id: componentId,
@@ -1606,34 +2355,34 @@ function TableBlockClient({
1606
2355
  className: `flex flex-col w-full bg-white border border-slate-200 rounded-xl shadow-xs min-h-[350px] overflow-hidden ${className}`,
1607
2356
  dir: "rtl",
1608
2357
  children: [
1609
- errorMessage && /* @__PURE__ */ jsx5("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1610
- /* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
1611
- /* @__PURE__ */ jsx5("span", { children: errorMessage })
2358
+ errorMessage && /* @__PURE__ */ jsx6("div", { className: "p-3 bg-rose-50 border-b border-rose-200 text-rose-700 text-sm flex items-center justify-between", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
2359
+ /* @__PURE__ */ jsx6("svg", { className: "w-4 h-4 text-rose-500 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
2360
+ /* @__PURE__ */ jsx6("span", { children: errorMessage })
1612
2361
  ] }) }),
1613
- /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center justify-between gap-3 p-3.5 sm:p-4 bg-slate-50 border-b border-slate-200", children: [
1614
- /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-2.5", children: [
1615
- ((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ jsx5("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ jsx5("span", { children: schema.title || schema.name }) }),
1616
- /* @__PURE__ */ jsx5(
2362
+ /* @__PURE__ */ jsxs6("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: [
2363
+ /* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center gap-2.5", children: [
2364
+ ((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ jsx6("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ jsx6("span", { children: schema.title || schema.name }) }),
2365
+ /* @__PURE__ */ jsx6(
1617
2366
  "button",
1618
2367
  {
1619
2368
  onClick: handleAddRow,
1620
2369
  disabled: isLoading || isUpdatingActive,
1621
2370
  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",
1622
2371
  title: "\u05D4\u05D5\u05E1\u05E3 \u05E9\u05D5\u05E8\u05D4 \u05D7\u05D3\u05E9\u05D4",
1623
- children: /* @__PURE__ */ jsx5("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
2372
+ children: /* @__PURE__ */ jsx6("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
1624
2373
  }
1625
2374
  ),
1626
- /* @__PURE__ */ jsx5(
2375
+ /* @__PURE__ */ jsx6(
1627
2376
  "button",
1628
2377
  {
1629
2378
  onClick: handleDuplicateRow,
1630
2379
  disabled: isLoading || isUpdatingActive || selectedIds.size !== 1,
1631
2380
  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",
1632
2381
  title: "\u05E9\u05DB\u05E4\u05DC \u05E9\u05D5\u05E8\u05D4 \u05E0\u05D1\u05D7\u05E8\u05EA",
1633
- children: /* @__PURE__ */ jsx5(Copy2, { className: "w-4 h-4 text-blue-600 shrink-0" })
2382
+ children: /* @__PURE__ */ jsx6(Copy2, { className: "w-4 h-4 text-blue-600 shrink-0" })
1634
2383
  }
1635
2384
  ),
1636
- /* @__PURE__ */ jsxs5(
2385
+ /* @__PURE__ */ jsxs6(
1637
2386
  "button",
1638
2387
  {
1639
2388
  onClick: handleDeleteSelected,
@@ -1641,12 +2390,12 @@ function TableBlockClient({
1641
2390
  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",
1642
2391
  title: "\u05DE\u05D7\u05E7 \u05E9\u05D5\u05E8\u05D5\u05EA \u05E0\u05D1\u05D7\u05E8\u05D5\u05EA",
1643
2392
  children: [
1644
- /* @__PURE__ */ jsx5("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
1645
- selectedIds.size > 0 && /* @__PURE__ */ jsx5("span", { className: "absolute -top-1.5 -right-1.5 bg-rose-600 text-white min-w-[18px] h-[18px] px-1 rounded-full text-[10px] font-bold flex items-center justify-center shadow-xs", children: selectedIds.size })
2393
+ /* @__PURE__ */ jsx6("svg", { className: "w-4.5 h-4.5 text-rose-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("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" }) }),
2394
+ selectedIds.size > 0 && /* @__PURE__ */ jsx6("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 })
1646
2395
  ]
1647
2396
  }
1648
2397
  ),
1649
- /* @__PURE__ */ jsxs5(
2398
+ /* @__PURE__ */ jsxs6(
1650
2399
  "button",
1651
2400
  {
1652
2401
  onClick: toggleSummary,
@@ -1654,13 +2403,13 @@ function TableBlockClient({
1654
2403
  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"}`,
1655
2404
  title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E9\u05D5\u05E8\u05EA \u05E1\u05D9\u05DB\u05D5\u05DD",
1656
2405
  children: [
1657
- /* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
1658
- /* @__PURE__ */ jsx5("span", { className: "hidden sm:inline", children: "\u05E1\u05DB\u05D9\u05DE\u05D4" })
2406
+ /* @__PURE__ */ jsx6("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
2407
+ /* @__PURE__ */ jsx6("span", { className: "hidden sm:inline", children: "\u05E1\u05DB\u05D9\u05DE\u05D4" })
1659
2408
  ]
1660
2409
  }
1661
2410
  ),
1662
- /* @__PURE__ */ jsxs5("div", { className: "relative", ref: dropdownRef, children: [
1663
- /* @__PURE__ */ jsxs5(
2411
+ /* @__PURE__ */ jsxs6("div", { className: "relative", ref: dropdownRef, children: [
2412
+ /* @__PURE__ */ jsxs6(
1664
2413
  "button",
1665
2414
  {
1666
2415
  onClick: () => setIsColumnsDropdownOpen((prev) => !prev),
@@ -1668,16 +2417,16 @@ function TableBlockClient({
1668
2417
  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",
1669
2418
  title: "\u05D4\u05E6\u05D2/\u05D4\u05E1\u05EA\u05E8 \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA",
1670
2419
  children: [
1671
- /* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 text-slate-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("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" }) }),
1672
- /* @__PURE__ */ jsx5("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__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })
2420
+ /* @__PURE__ */ jsx6("svg", { className: "w-4 h-4 text-slate-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("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" }) }),
2421
+ /* @__PURE__ */ jsx6("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__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M19 9l-7 7-7-7" }) })
1673
2422
  ]
1674
2423
  }
1675
2424
  ),
1676
- isColumnsDropdownOpen && /* @__PURE__ */ jsxs5("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: [
1677
- /* @__PURE__ */ jsxs5("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: [
1678
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1.5", children: [
1679
- /* @__PURE__ */ jsx5("span", { children: "\u05D4\u05E6\u05D2\u05EA \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA" }),
1680
- /* @__PURE__ */ jsxs5("span", { className: "text-[10px] font-normal text-slate-400", children: [
2425
+ isColumnsDropdownOpen && /* @__PURE__ */ jsxs6("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: [
2426
+ /* @__PURE__ */ jsxs6("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: [
2427
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1.5", children: [
2428
+ /* @__PURE__ */ jsx6("span", { children: "\u05D4\u05E6\u05D2\u05EA \u05E2\u05DE\u05D5\u05D3\u05D5\u05EA" }),
2429
+ /* @__PURE__ */ jsxs6("span", { className: "text-[10px] font-normal text-slate-400", children: [
1681
2430
  "(",
1682
2431
  customizableColumns.filter((c) => !c.isHidden).length,
1683
2432
  "/",
@@ -1685,7 +2434,7 @@ function TableBlockClient({
1685
2434
  ")"
1686
2435
  ] })
1687
2436
  ] }),
1688
- /* @__PURE__ */ jsx5(
2437
+ /* @__PURE__ */ jsx6(
1689
2438
  "button",
1690
2439
  {
1691
2440
  type: "button",
@@ -1695,7 +2444,7 @@ function TableBlockClient({
1695
2444
  }
1696
2445
  )
1697
2446
  ] }),
1698
- /* @__PURE__ */ jsx5("div", { className: "max-h-60 overflow-y-auto space-y-0.5", children: customizableColumns.map((col) => {
2447
+ /* @__PURE__ */ jsx6("div", { className: "max-h-60 overflow-y-auto space-y-0.5", children: customizableColumns.map((col) => {
1699
2448
  const isRequired = col.isRequired === true || String(col.isRequired) === "true";
1700
2449
  const isUnique = col.isUnique === true || String(col.isUnique) === "true";
1701
2450
  const isProtected = isRequired || isUnique;
@@ -1709,7 +2458,7 @@ function TableBlockClient({
1709
2458
  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";
1710
2459
  }
1711
2460
  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";
1712
- return /* @__PURE__ */ jsxs5(
2461
+ return /* @__PURE__ */ jsxs6(
1713
2462
  "div",
1714
2463
  {
1715
2464
  onClick: () => {
@@ -1720,8 +2469,8 @@ function TableBlockClient({
1720
2469
  title: isProtected ? protectedExplanation : void 0,
1721
2470
  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"}`,
1722
2471
  children: [
1723
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 min-w-0", children: [
1724
- /* @__PURE__ */ jsx5(
2472
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 min-w-0", children: [
2473
+ /* @__PURE__ */ jsx6(
1725
2474
  "input",
1726
2475
  {
1727
2476
  type: "checkbox",
@@ -1732,16 +2481,16 @@ function TableBlockClient({
1732
2481
  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"
1733
2482
  }
1734
2483
  ),
1735
- /* @__PURE__ */ jsx5("span", { className: `font-medium truncate ${isProtected ? "text-slate-500" : "text-slate-700"}`, children: col.name })
2484
+ /* @__PURE__ */ jsx6("span", { className: `font-medium truncate ${isProtected ? "text-slate-500" : "text-slate-700"}`, children: col.name })
1736
2485
  ] }),
1737
- isProtected && /* @__PURE__ */ jsxs5(
2486
+ isProtected && /* @__PURE__ */ jsxs6(
1738
2487
  "div",
1739
2488
  {
1740
2489
  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",
1741
2490
  title: protectedExplanation,
1742
2491
  children: [
1743
- /* @__PURE__ */ jsx5("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__ */ jsx5("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" }) }),
1744
- /* @__PURE__ */ jsx5("span", { children: badgeLabel })
2492
+ /* @__PURE__ */ jsx6("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__ */ jsx6("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" }) }),
2493
+ /* @__PURE__ */ jsx6("span", { children: badgeLabel })
1745
2494
  ]
1746
2495
  }
1747
2496
  )
@@ -1752,9 +2501,9 @@ function TableBlockClient({
1752
2501
  }) })
1753
2502
  ] })
1754
2503
  ] }),
1755
- /* @__PURE__ */ jsx5("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
1756
- /* @__PURE__ */ jsxs5("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
1757
- /* @__PURE__ */ jsx5(
2504
+ /* @__PURE__ */ jsx6("div", { className: "h-5 w-px bg-slate-300 mx-1 hidden sm:block" }),
2505
+ /* @__PURE__ */ jsxs6("div", { className: "relative flex-1 sm:w-64 max-w-xs", children: [
2506
+ /* @__PURE__ */ jsx6(
1758
2507
  "input",
1759
2508
  {
1760
2509
  placeholder: "\u05D7\u05D9\u05E4\u05D5\u05E9 \u05D1\u05E8\u05E9\u05D5\u05DE\u05D5\u05EA...",
@@ -1764,45 +2513,45 @@ function TableBlockClient({
1764
2513
  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"
1765
2514
  }
1766
2515
  ),
1767
- searchQuery ? /* @__PURE__ */ jsx5(
2516
+ searchQuery ? /* @__PURE__ */ jsx6(
1768
2517
  "button",
1769
2518
  {
1770
2519
  type: "button",
1771
2520
  onClick: () => setSearchQuery(""),
1772
2521
  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",
1773
2522
  title: "Clear search",
1774
- children: /* @__PURE__ */ jsx5(X4, { className: "w-3.5 h-3.5" })
2523
+ children: /* @__PURE__ */ jsx6(X4, { className: "w-3.5 h-3.5" })
1775
2524
  }
1776
- ) : /* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 text-slate-400 absolute right-2.5 top-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
2525
+ ) : /* @__PURE__ */ jsx6("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__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) })
1777
2526
  ] })
1778
2527
  ] }),
1779
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
1780
- isUpdatingActive ? /* @__PURE__ */ jsxs5("span", { className: "text-xs text-blue-600 font-semibold flex items-center gap-1.5 bg-blue-50 border border-blue-200 px-3 py-1.5 rounded-lg animate-pulse", children: [
1781
- /* @__PURE__ */ jsx5("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
2528
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
2529
+ isUpdatingActive ? /* @__PURE__ */ jsxs6("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: [
2530
+ /* @__PURE__ */ jsx6("span", { className: "w-2 h-2 rounded-full bg-blue-500 inline-block" }),
1782
2531
  "\u05DE\u05E2\u05D3\u05DB\u05DF..."
1783
- ] }) : isSaveSuccess ? /* @__PURE__ */ jsxs5("span", { className: "text-xs text-emerald-700 font-semibold flex items-center gap-1.5 bg-emerald-50 border border-emerald-200 px-3 py-1.5 rounded-lg animate-in fade-in duration-200", children: [
1784
- /* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
2532
+ ] }) : isSaveSuccess ? /* @__PURE__ */ jsxs6("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: [
2533
+ /* @__PURE__ */ jsx6("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
1785
2534
  "\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
1786
- ] }) : hasChanges ? /* @__PURE__ */ jsx5("span", { className: "text-xs font-semibold text-amber-700 animate-in fade-in", children: "\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5" }) : null,
1787
- /* @__PURE__ */ jsx5(
2535
+ ] }) : hasChanges ? /* @__PURE__ */ jsx6("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,
2536
+ /* @__PURE__ */ jsx6(
1788
2537
  "button",
1789
2538
  {
1790
2539
  onClick: handleSave,
1791
2540
  disabled: isUpdatingActive || isLoading || !hasChanges,
1792
2541
  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"}`,
1793
- children: /* @__PURE__ */ jsx5("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
2542
+ children: /* @__PURE__ */ jsx6("span", { children: isUpdatingActive ? "\u05E9\u05D5\u05DE\u05E8..." : "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD" })
1794
2543
  }
1795
2544
  )
1796
2545
  ] })
1797
2546
  ] }),
1798
- /* @__PURE__ */ jsxs5("div", { className: `overflow-x-auto relative min-h-[260px] flex-1 transition-opacity duration-200 ${isMounted ? "opacity-100" : "opacity-0"}`, children: [
1799
- isLoading && /* @__PURE__ */ jsxs5("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
1800
- /* @__PURE__ */ jsx5("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
1801
- /* @__PURE__ */ jsx5("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
2547
+ /* @__PURE__ */ jsxs6("div", { className: `overflow-x-auto relative min-h-[260px] flex-1 transition-opacity duration-200 ${isMounted ? "opacity-100" : "opacity-0"}`, children: [
2548
+ isLoading && /* @__PURE__ */ jsxs6("div", { className: "absolute inset-0 bg-white/80 backdrop-blur-xs z-20 flex flex-col items-center justify-center gap-2", children: [
2549
+ /* @__PURE__ */ jsx6("div", { className: "w-6 h-6 border-2 border-brand border-t-transparent rounded-full animate-spin" }),
2550
+ /* @__PURE__ */ jsx6("span", { className: "text-sm font-medium text-slate-600", children: "\u05D8\u05D5\u05E2\u05DF \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD..." })
1802
2551
  ] }),
1803
- /* @__PURE__ */ jsxs5("table", { className: "w-full text-sm text-right border-collapse table-auto", children: [
1804
- /* @__PURE__ */ jsx5("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ jsxs5("tr", { children: [
1805
- /* @__PURE__ */ jsx5("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__ */ jsx5(
2552
+ /* @__PURE__ */ jsxs6("table", { className: "w-full text-sm text-right border-collapse table-auto", children: [
2553
+ /* @__PURE__ */ jsx6("thead", { className: "bg-slate-100/80 text-slate-700 sticky top-0 z-10", children: /* @__PURE__ */ jsxs6("tr", { children: [
2554
+ /* @__PURE__ */ jsx6("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__ */ jsx6(
1806
2555
  "input",
1807
2556
  {
1808
2557
  type: "checkbox",
@@ -1816,7 +2565,7 @@ function TableBlockClient({
1816
2565
  const isDragging = draggedColName === col.name;
1817
2566
  const isDragOver = dragOverColName === col.name;
1818
2567
  const currentWidth = columnWidths[col.name] || 200;
1819
- return /* @__PURE__ */ jsxs5(
2568
+ return /* @__PURE__ */ jsxs6(
1820
2569
  "th",
1821
2570
  {
1822
2571
  style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
@@ -1852,7 +2601,7 @@ function TableBlockClient({
1852
2601
  },
1853
2602
  className: `relative border-b border-l border-slate-200 px-4 py-2.5 font-semibold text-slate-700 whitespace-nowrap select-none cursor-grab active:cursor-grabbing transition-colors ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : "hover:bg-slate-200/60"}`,
1854
2603
  children: [
1855
- /* @__PURE__ */ jsx5(
2604
+ /* @__PURE__ */ jsx6(
1856
2605
  "div",
1857
2606
  {
1858
2607
  onMouseDown: (e) => {
@@ -1864,16 +2613,16 @@ function TableBlockClient({
1864
2613
  title: "\u05E9\u05E0\u05D4 \u05D2\u05D5\u05D3\u05DC \u05E2\u05DE\u05D5\u05D3\u05D4"
1865
2614
  }
1866
2615
  ),
1867
- /* @__PURE__ */ jsxs5("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: [
1868
- /* @__PURE__ */ jsx5("span", { className: "truncate", children: col.name }),
1869
- /* @__PURE__ */ jsx5(
2616
+ /* @__PURE__ */ jsxs6("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: [
2617
+ /* @__PURE__ */ jsx6("span", { className: "truncate", children: col.name }),
2618
+ /* @__PURE__ */ jsx6(
1870
2619
  "svg",
1871
2620
  {
1872
2621
  className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
1873
2622
  fill: "none",
1874
2623
  viewBox: "0 0 24 24",
1875
2624
  stroke: "currentColor",
1876
- children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
2625
+ children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M8 9h.01M8 15h.01M16 9h.01M16 15h.01" })
1877
2626
  }
1878
2627
  )
1879
2628
  ] })
@@ -1882,59 +2631,112 @@ function TableBlockClient({
1882
2631
  col.name
1883
2632
  );
1884
2633
  }),
1885
- /* @__PURE__ */ jsx5("th", { className: "w-full min-w-[50px] border-b border-slate-200 pointer-events-none" })
2634
+ /* @__PURE__ */ jsx6("th", { className: "w-full min-w-[50px] border-b border-slate-200 pointer-events-none" })
1886
2635
  ] }) }),
1887
- /* @__PURE__ */ jsx5("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: filteredColumns.length + 2, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center justify-center gap-2", children: [
1888
- /* @__PURE__ */ jsx5("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", d: "M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" }) }),
1889
- /* @__PURE__ */ jsx5("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
1890
- ] }) }) }) : filteredData.map((row) => /* @__PURE__ */ jsxs5("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
1891
- /* @__PURE__ */ jsx5("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", children: /* @__PURE__ */ jsx5(
1892
- "input",
1893
- {
1894
- type: "checkbox",
1895
- checked: selectedIds.has(row.id),
1896
- onChange: (e) => toggleSelectRow(row.id, e.target.checked),
1897
- disabled: isLoading || isUpdatingActive,
1898
- className: "w-4 h-4 rounded border-slate-300 text-brand"
1899
- }
1900
- ) }),
1901
- filteredColumns.map((col) => {
2636
+ /* @__PURE__ */ jsx6("tbody", { className: "bg-white", children: (isStateEmpty || filteredData.length === 0) && !isLoading ? /* @__PURE__ */ jsx6("tr", { children: /* @__PURE__ */ jsx6("td", { colSpan: filteredColumns.length + 2, className: "text-center py-12 text-slate-400", children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center gap-2", children: [
2637
+ /* @__PURE__ */ jsx6("svg", { className: "w-8 h-8 text-slate-300", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6("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" }) }),
2638
+ /* @__PURE__ */ jsx6("span", { children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." })
2639
+ ] }) }) }) : filteredData.map((row) => {
2640
+ const hasSubTableCols = filteredColumns.some((c) => {
1902
2641
  var _a;
1903
- const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
1904
- const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
1905
- let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
1906
- if (value === void 0 && col.defaultValue !== void 0) {
1907
- value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
1908
- if (colType === "CURRENCY" || colType === "NUMBER") {
1909
- if (isNaN(value)) value = null;
1910
- }
1911
- }
1912
- if (value === void 0) value = null;
1913
- return /* @__PURE__ */ jsx5("td", { className: "border-b border-l border-slate-200 p-0 relative", children: /* @__PURE__ */ jsx5(
1914
- InputComponent,
2642
+ return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
2643
+ });
2644
+ const isExpanded = expandedRowIds.has(row.id);
2645
+ const subTableColumns = filteredColumns.filter((c) => {
2646
+ var _a;
2647
+ return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
2648
+ });
2649
+ return /* @__PURE__ */ jsxs6(React6.Fragment, { children: [
2650
+ /* @__PURE__ */ jsxs6("tr", { className: "hover:bg-blue-50/30 transition-colors group", children: [
2651
+ /* @__PURE__ */ jsx6("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-center gap-1", children: [
2652
+ hasSubTableCols && /* @__PURE__ */ jsx6(
2653
+ "button",
2654
+ {
2655
+ type: "button",
2656
+ onClick: () => setExpandedRowIds((prev) => {
2657
+ const next = new Set(prev);
2658
+ if (next.has(row.id)) next.delete(row.id);
2659
+ else next.add(row.id);
2660
+ return next;
2661
+ }),
2662
+ className: "text-slate-400 hover:text-blue-600 p-0.5 rounded transition-colors cursor-pointer",
2663
+ title: isExpanded ? "\u05E1\u05D2\u05D5\u05E8 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4" : "\u05E4\u05EA\u05D7 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4",
2664
+ children: /* @__PURE__ */ jsx6("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__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M9 5l7 7-7 7" }) })
2665
+ }
2666
+ ),
2667
+ /* @__PURE__ */ jsx6(
2668
+ "input",
2669
+ {
2670
+ type: "checkbox",
2671
+ checked: selectedIds.has(row.id),
2672
+ onChange: (e) => toggleSelectRow(row.id, e.target.checked),
2673
+ disabled: isLoading || isUpdatingActive,
2674
+ className: "w-4 h-4 rounded border-slate-300 text-brand"
2675
+ }
2676
+ )
2677
+ ] }) }),
2678
+ filteredColumns.map((col) => {
2679
+ var _a;
2680
+ const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
2681
+ const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
2682
+ let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
2683
+ if (value === void 0 && col.defaultValue !== void 0) {
2684
+ value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
2685
+ if (colType === "CURRENCY" || colType === "NUMBER") {
2686
+ if (isNaN(value)) value = null;
2687
+ }
2688
+ }
2689
+ if (value === void 0) value = null;
2690
+ return /* @__PURE__ */ jsx6("td", { className: "border-b border-l border-slate-200 p-0 relative", children: /* @__PURE__ */ jsx6(
2691
+ InputComponent,
2692
+ {
2693
+ value,
2694
+ column: col,
2695
+ rowId: row.id,
2696
+ onChange: (v) => handleCellChange(row.id, col.name, v),
2697
+ context: {
2698
+ 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",
2699
+ tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
2700
+ onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
2701
+ relationOptions,
2702
+ refetchRelation,
2703
+ executeAction,
2704
+ emitEvent,
2705
+ pageState,
2706
+ componentId,
2707
+ orgId,
2708
+ updateQuietly: handleQuietCellChange,
2709
+ triggerSaveSuccess,
2710
+ rowData: row.data
2711
+ }
2712
+ }
2713
+ ) }, col.name);
2714
+ }),
2715
+ /* @__PURE__ */ jsx6("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
2716
+ ] }),
2717
+ isExpanded && /* @__PURE__ */ jsx6(
2718
+ ExpandedSubTables,
1915
2719
  {
1916
- value,
1917
- column: col,
1918
2720
  rowId: row.id,
1919
- onChange: (v) => handleCellChange(row.id, col.name, v),
2721
+ rowData: row.data,
2722
+ subTableColumns,
2723
+ filteredColumnsLength: filteredColumns.length,
2724
+ handleCellChange,
1920
2725
  context: {
1921
- 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",
1922
- onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
1923
- relationOptions,
1924
- refetchRelation,
1925
2726
  executeAction,
1926
- emitEvent,
1927
- pageState,
1928
- componentId,
1929
- orgId
2727
+ orgId,
2728
+ parentTableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
2729
+ tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
2730
+ rowData: row.data,
2731
+ updateQuietly: handleQuietCellChange,
2732
+ triggerSaveSuccess
1930
2733
  }
1931
2734
  }
1932
- ) }, col.name);
1933
- }),
1934
- /* @__PURE__ */ jsx5("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
1935
- ] }, row.id)) }),
1936
- showSummary && filteredData.length > 0 && /* @__PURE__ */ jsx5("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__ */ jsxs5("tr", { children: [
1937
- /* @__PURE__ */ jsx5("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' }),
2735
+ )
2736
+ ] }, row.id);
2737
+ }) }),
2738
+ showSummary && filteredData.length > 0 && /* @__PURE__ */ jsx6("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__ */ jsxs6("tr", { children: [
2739
+ /* @__PURE__ */ jsx6("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' }),
1938
2740
  filteredColumns.map((col) => {
1939
2741
  var _a;
1940
2742
  const typeUpper = (_a = col.type) == null ? void 0 : _a.toUpperCase();
@@ -1948,16 +2750,16 @@ function TableBlockClient({
1948
2750
  displayVal = symbol ? `${symbol} ${displayVal}` : displayVal;
1949
2751
  }
1950
2752
  }
1951
- return /* @__PURE__ */ jsx5("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__ */ jsx5("div", { className: "flex items-center text-right justify-start", children: /* @__PURE__ */ jsx5("span", { className: "truncate", children: displayVal }) }) }, col.name);
2753
+ return /* @__PURE__ */ jsx6("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__ */ jsx6("div", { className: "flex items-center text-right justify-start", children: /* @__PURE__ */ jsx6("span", { className: "truncate", children: displayVal }) }) }, col.name);
1952
2754
  }),
1953
- /* @__PURE__ */ jsx5("td", { className: "border-b border-slate-200 bg-slate-50 pointer-events-none" })
2755
+ /* @__PURE__ */ jsx6("td", { className: "border-b border-slate-200 bg-slate-50 pointer-events-none" })
1954
2756
  ] }) })
1955
2757
  ] })
1956
2758
  ] }),
1957
- /* @__PURE__ */ jsxs5("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: [
1958
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1959
- /* @__PURE__ */ jsx5("span", { className: "font-medium text-slate-700", children: "\u05E9\u05D5\u05E8\u05D5\u05EA \u05DC\u05E2\u05DE\u05D5\u05D3:" }),
1960
- /* @__PURE__ */ jsxs5(
2759
+ /* @__PURE__ */ jsxs6("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: [
2760
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
2761
+ /* @__PURE__ */ jsx6("span", { className: "font-medium text-slate-700", children: "\u05E9\u05D5\u05E8\u05D5\u05EA \u05DC\u05E2\u05DE\u05D5\u05D3:" }),
2762
+ /* @__PURE__ */ jsxs6(
1961
2763
  "select",
1962
2764
  {
1963
2765
  value: limit,
@@ -1965,27 +2767,27 @@ function TableBlockClient({
1965
2767
  disabled: isLoading || isUpdatingActive,
1966
2768
  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",
1967
2769
  children: [
1968
- /* @__PURE__ */ jsx5("option", { value: 20, children: "20" }),
1969
- /* @__PURE__ */ jsx5("option", { value: 50, children: "50" }),
1970
- /* @__PURE__ */ jsx5("option", { value: 100, children: "100" })
2770
+ /* @__PURE__ */ jsx6("option", { value: 20, children: "20" }),
2771
+ /* @__PURE__ */ jsx6("option", { value: 50, children: "50" }),
2772
+ /* @__PURE__ */ jsx6("option", { value: 100, children: "100" })
1971
2773
  ]
1972
2774
  }
1973
2775
  )
1974
2776
  ] }),
1975
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-4", children: [
1976
- /* @__PURE__ */ jsxs5("span", { className: "font-medium text-slate-600", children: [
2777
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-4", children: [
2778
+ /* @__PURE__ */ jsxs6("span", { className: "font-medium text-slate-600", children: [
1977
2779
  "\u05E2\u05DE\u05D5\u05D3 ",
1978
- /* @__PURE__ */ jsx5("strong", { className: "text-slate-900", children: page }),
2780
+ /* @__PURE__ */ jsx6("strong", { className: "text-slate-900", children: page }),
1979
2781
  " \u05DE\u05EA\u05D5\u05DA ",
1980
- /* @__PURE__ */ jsx5("strong", { className: "text-slate-900", children: totalPages || 1 }),
1981
- totalRecords > 0 && /* @__PURE__ */ jsxs5("span", { className: "text-slate-500 font-normal", children: [
2782
+ /* @__PURE__ */ jsx6("strong", { className: "text-slate-900", children: totalPages || 1 }),
2783
+ totalRecords > 0 && /* @__PURE__ */ jsxs6("span", { className: "text-slate-500 font-normal", children: [
1982
2784
  " (",
1983
2785
  totalRecords,
1984
2786
  ' \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05D1\u05E1\u05D4"\u05DB)'
1985
2787
  ] })
1986
2788
  ] }),
1987
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1.5", children: [
1988
- /* @__PURE__ */ jsx5(
2789
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1.5", children: [
2790
+ /* @__PURE__ */ jsx6(
1989
2791
  "button",
1990
2792
  {
1991
2793
  onClick: handlePrevPage,
@@ -1995,7 +2797,7 @@ function TableBlockClient({
1995
2797
  children: "\u05D4\u05E7\u05D5\u05D3\u05DD"
1996
2798
  }
1997
2799
  ),
1998
- /* @__PURE__ */ jsx5(
2800
+ /* @__PURE__ */ jsx6(
1999
2801
  "button",
2000
2802
  {
2001
2803
  onClick: handleNextPage,
@@ -2012,11 +2814,60 @@ function TableBlockClient({
2012
2814
  }
2013
2815
  );
2014
2816
  }
2817
+ function ExpandedSubTables({
2818
+ rowId,
2819
+ rowData,
2820
+ subTableColumns,
2821
+ filteredColumnsLength,
2822
+ handleCellChange,
2823
+ context
2824
+ }) {
2825
+ var _a;
2826
+ const [activeTab, setActiveTab] = useState5((_a = subTableColumns[0]) == null ? void 0 : _a.name);
2827
+ if (subTableColumns.length === 0) return null;
2828
+ if (subTableColumns.length === 1) {
2829
+ const stCol = subTableColumns[0];
2830
+ return /* @__PURE__ */ jsx6("tr", { children: /* @__PURE__ */ jsx6("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50", children: /* @__PURE__ */ jsx6(
2831
+ SubTableViewer,
2832
+ {
2833
+ rowId,
2834
+ column: stCol,
2835
+ value: (rowData == null ? void 0 : rowData[stCol.name]) || [],
2836
+ onChange: (newVal) => handleCellChange(rowId, stCol.name, newVal),
2837
+ context
2838
+ }
2839
+ ) }) });
2840
+ }
2841
+ const activeCol = subTableColumns.find((c) => c.name === activeTab) || subTableColumns[0];
2842
+ return /* @__PURE__ */ jsx6("tr", { children: /* @__PURE__ */ jsxs6("td", { colSpan: filteredColumnsLength + 2, className: "p-0 border-b border-slate-200 bg-slate-50/50 overflow-hidden", children: [
2843
+ /* @__PURE__ */ jsx6("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__ */ jsx6(
2844
+ "button",
2845
+ {
2846
+ type: "button",
2847
+ onClick: () => setActiveTab(col.name),
2848
+ 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"}`,
2849
+ children: col.name
2850
+ },
2851
+ col.name
2852
+ )) }),
2853
+ /* @__PURE__ */ jsx6("div", { className: "bg-white", children: /* @__PURE__ */ jsx6(
2854
+ SubTableViewer,
2855
+ {
2856
+ rowId,
2857
+ column: activeCol,
2858
+ value: (rowData == null ? void 0 : rowData[activeCol.name]) || [],
2859
+ onChange: (newVal) => handleCellChange(rowId, activeCol.name, newVal),
2860
+ context
2861
+ },
2862
+ activeCol.name
2863
+ ) })
2864
+ ] }) });
2865
+ }
2015
2866
 
2016
2867
  // src/components/TableBlock/TableBlock.tsx
2017
- import { jsx as jsx6 } from "react/jsx-runtime";
2868
+ import { jsx as jsx7 } from "react/jsx-runtime";
2018
2869
  function TableBlock(props) {
2019
- return /* @__PURE__ */ jsx6(TableBlockClient, __spreadValues({}, props));
2870
+ return /* @__PURE__ */ jsx7(TableBlockClient, __spreadValues({}, props));
2020
2871
  }
2021
2872
 
2022
2873
  // src/registry.ts