@universe-platform/ui 0.1.0-beta.11 → 0.1.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/globals.css +11 -2
- package/dist/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +477 -364
- package/dist/index.mjs +476 -364
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -99,6 +99,30 @@ function getDeterministicPastelBadge(key) {
|
|
|
99
99
|
return PASTEL_PALETTES[index];
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// src/utils/permissions.ts
|
|
103
|
+
function getRolePermissions(role) {
|
|
104
|
+
if (role === "VIEWER" || !role) {
|
|
105
|
+
return {
|
|
106
|
+
permissions: {
|
|
107
|
+
canCreate: false,
|
|
108
|
+
canRead: true,
|
|
109
|
+
canUpdate: false,
|
|
110
|
+
canDelete: false
|
|
111
|
+
},
|
|
112
|
+
readOnly: true
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
permissions: {
|
|
117
|
+
canCreate: true,
|
|
118
|
+
canRead: true,
|
|
119
|
+
canUpdate: true,
|
|
120
|
+
canDelete: true
|
|
121
|
+
},
|
|
122
|
+
readOnly: false
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
102
126
|
// ../shared/src/columns.ts
|
|
103
127
|
var COLUMN_TYPES = [
|
|
104
128
|
"STRING",
|
|
@@ -376,7 +400,7 @@ import React7 from "react";
|
|
|
376
400
|
import React2, { useState as useState2, useEffect } from "react";
|
|
377
401
|
import { FileText, Upload, X as X2 } from "lucide-react";
|
|
378
402
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
379
|
-
function DrivePickerCell({ value, onChange, tableName, column, rowId, onMarkForDeletion, context }) {
|
|
403
|
+
function DrivePickerCell({ value, onChange, tableName, column, rowId, onMarkForDeletion, context, readOnly = false }) {
|
|
380
404
|
const [isOpening, setIsOpening] = useState2(false);
|
|
381
405
|
const { showError } = useToast();
|
|
382
406
|
const cellContextId = React2.useMemo(() => {
|
|
@@ -477,29 +501,33 @@ function DrivePickerCell({ value, onChange, tableName, column, rowId, onMarkForD
|
|
|
477
501
|
const updated = fileList.filter((_, idx) => idx !== indexToRemove);
|
|
478
502
|
onChange(updated);
|
|
479
503
|
};
|
|
480
|
-
const renderUploadButton = () =>
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
504
|
+
const renderUploadButton = (iconOnly) => {
|
|
505
|
+
if (readOnly) return null;
|
|
506
|
+
return /* @__PURE__ */ jsxs2(
|
|
507
|
+
"button",
|
|
508
|
+
{
|
|
509
|
+
type: "button",
|
|
510
|
+
onClick: openUploadPopup,
|
|
511
|
+
disabled: isOpening || !(context == null ? void 0 : context.executeAction),
|
|
512
|
+
className: `inline-flex items-center justify-center gap-1.5 rounded-md text-xs font-medium text-slate-500 bg-slate-100 hover:bg-slate-200 hover:text-slate-700 transition-colors disabled:opacity-50 ${iconOnly ? "w-7 h-7 shrink-0" : "px-2 py-1"}`,
|
|
513
|
+
title: "Upload File",
|
|
514
|
+
children: [
|
|
515
|
+
/* @__PURE__ */ jsx2(Upload, { className: "w-3.5 h-3.5 shrink-0" }),
|
|
516
|
+
!iconOnly && /* @__PURE__ */ jsx2("span", { className: "truncate", children: isOpening ? "Loading..." : "Upload File" })
|
|
517
|
+
]
|
|
518
|
+
}
|
|
519
|
+
);
|
|
520
|
+
};
|
|
493
521
|
if (fileList.length > 0) {
|
|
494
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-
|
|
495
|
-
fileList.map((file, idx) => /* @__PURE__ */ jsxs2("div", { className: "flex items-center
|
|
522
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-wrap items-center w-full py-1 px-2 gap-1.5", children: [
|
|
523
|
+
fileList.map((file, idx) => /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1 max-w-full", children: [
|
|
496
524
|
/* @__PURE__ */ jsxs2(
|
|
497
525
|
"a",
|
|
498
526
|
{
|
|
499
527
|
href: file.fileUrl || file.url,
|
|
500
528
|
target: "_blank",
|
|
501
529
|
rel: "noopener noreferrer",
|
|
502
|
-
className:
|
|
530
|
+
className: `inline-flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium text-blue-700 bg-blue-50 hover:bg-blue-100 transition-colors truncate ${readOnly ? "max-w-full" : "max-w-[calc(100%-28px)]"}`,
|
|
503
531
|
title: file.fileName || "Open file",
|
|
504
532
|
children: [
|
|
505
533
|
/* @__PURE__ */ jsx2(FileText, { className: "w-3.5 h-3.5 shrink-0" }),
|
|
@@ -507,21 +535,24 @@ function DrivePickerCell({ value, onChange, tableName, column, rowId, onMarkForD
|
|
|
507
535
|
]
|
|
508
536
|
}
|
|
509
537
|
),
|
|
510
|
-
/* @__PURE__ */ jsx2(
|
|
538
|
+
!readOnly && /* @__PURE__ */ jsx2(
|
|
511
539
|
"button",
|
|
512
540
|
{
|
|
513
541
|
type: "button",
|
|
514
542
|
onClick: () => handleRemoveFile(idx),
|
|
515
|
-
className: "shrink-0
|
|
543
|
+
className: "shrink-0 inline-flex items-center justify-center w-6 h-6 rounded hover:bg-rose-100 text-slate-400 hover:text-rose-500 transition-colors",
|
|
516
544
|
title: "Remove file",
|
|
517
|
-
children: /* @__PURE__ */ jsx2(X2, { className: "w-3.5 h-3.5" })
|
|
545
|
+
children: /* @__PURE__ */ jsx2(X2, { className: "w-3.5 h-3.5 shrink-0" })
|
|
518
546
|
}
|
|
519
547
|
)
|
|
520
548
|
] }, file.fileId || idx)),
|
|
521
|
-
renderUploadButton()
|
|
549
|
+
renderUploadButton(true)
|
|
522
550
|
] });
|
|
523
551
|
}
|
|
524
|
-
|
|
552
|
+
if (readOnly) {
|
|
553
|
+
return /* @__PURE__ */ jsx2("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "-" });
|
|
554
|
+
}
|
|
555
|
+
return /* @__PURE__ */ jsx2("div", { className: "flex items-center w-full h-8 px-2", children: renderUploadButton(false) });
|
|
525
556
|
}
|
|
526
557
|
|
|
527
558
|
// src/components/TableBlock/fields/DatePickerCell.tsx
|
|
@@ -2088,11 +2119,19 @@ function getCurrencySymbol(code) {
|
|
|
2088
2119
|
return CURRENCY_SYMBOLS[code.toUpperCase()] || code;
|
|
2089
2120
|
}
|
|
2090
2121
|
var FORM_INPUTS = {
|
|
2091
|
-
DATE: ({ value, onChange, column }) => /* @__PURE__ */ jsx7(DatePickerCell, { value, onChange, column }),
|
|
2092
|
-
CURRENCY: ({ value, column, onChange }) => {
|
|
2122
|
+
DATE: ({ value, onChange, column, readOnly }) => /* @__PURE__ */ jsx7(DatePickerCell, { value, onChange, column, readOnly }),
|
|
2123
|
+
CURRENCY: ({ value, column, onChange, readOnly }) => {
|
|
2093
2124
|
var _a;
|
|
2094
2125
|
const symbol = getCurrencySymbol((_a = column.config) == null ? void 0 : _a.currencySymbol);
|
|
2095
2126
|
const [isFocused, setIsFocused] = React7.useState(false);
|
|
2127
|
+
if (readOnly) {
|
|
2128
|
+
const num = Number(value);
|
|
2129
|
+
const formattedValue = value !== null && value !== void 0 && !isNaN(num) ? new Intl.NumberFormat("en-US").format(num) : "";
|
|
2130
|
+
return /* @__PURE__ */ jsxs7("span", { className: "px-2 py-1 flex items-center h-full text-sm select-text truncate", children: [
|
|
2131
|
+
symbol && /* @__PURE__ */ jsx7("span", { className: "text-slate-400 mr-1", children: symbol }),
|
|
2132
|
+
formattedValue
|
|
2133
|
+
] });
|
|
2134
|
+
}
|
|
2096
2135
|
const displayValue = !isFocused && value !== void 0 && value !== null && !isNaN(Number(value)) ? new Intl.NumberFormat("en-US").format(Number(value)) : value !== void 0 && value !== null ? value : "";
|
|
2097
2136
|
return /* @__PURE__ */ jsxs7("div", { className: "relative w-full h-full", children: [
|
|
2098
2137
|
symbol && /* @__PURE__ */ jsx7("span", { className: "absolute left-2 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none text-sm", children: symbol }),
|
|
@@ -2113,18 +2152,19 @@ var FORM_INPUTS = {
|
|
|
2113
2152
|
)
|
|
2114
2153
|
] });
|
|
2115
2154
|
},
|
|
2116
|
-
TIME: ({ value, onChange, column }) => /* @__PURE__ */ jsx7(TimePickerCell, { value, onChange, column }),
|
|
2117
|
-
LINK: ({ value, onChange, column }) => /* @__PURE__ */ jsx7(LinkPickerCell, { value, onChange, column }),
|
|
2118
|
-
BOOLEAN: ({ value, onChange }) => /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center w-full h-full p-2", children: /* @__PURE__ */ jsx7(
|
|
2155
|
+
TIME: ({ value, onChange, column, readOnly }) => /* @__PURE__ */ jsx7(TimePickerCell, { value, onChange, column, readOnly }),
|
|
2156
|
+
LINK: ({ value, onChange, column, readOnly }) => /* @__PURE__ */ jsx7(LinkPickerCell, { value, onChange, column, readOnly }),
|
|
2157
|
+
BOOLEAN: ({ value, onChange, readOnly }) => /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center w-full h-full p-2", children: /* @__PURE__ */ jsx7(
|
|
2119
2158
|
"input",
|
|
2120
2159
|
{
|
|
2121
2160
|
type: "checkbox",
|
|
2122
2161
|
checked: !!value,
|
|
2162
|
+
disabled: readOnly,
|
|
2123
2163
|
onChange: (e) => onChange(e.target.checked),
|
|
2124
|
-
className:
|
|
2164
|
+
className: `w-4 h-4 rounded border-slate-300 text-brand ${readOnly ? "cursor-not-allowed opacity-70" : "cursor-pointer"}`
|
|
2125
2165
|
}
|
|
2126
2166
|
) }),
|
|
2127
|
-
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context }) => /* @__PURE__ */ jsx7(
|
|
2167
|
+
GOOGLE_DRIVE_FILE: ({ value, onChange, column, rowId, context, readOnly }) => /* @__PURE__ */ jsx7(
|
|
2128
2168
|
DrivePickerCell,
|
|
2129
2169
|
{
|
|
2130
2170
|
value: value || [],
|
|
@@ -2133,34 +2173,60 @@ var FORM_INPUTS = {
|
|
|
2133
2173
|
rowId,
|
|
2134
2174
|
tableName: context == null ? void 0 : context.tableName,
|
|
2135
2175
|
onMarkForDeletion: context == null ? void 0 : context.onMarkForDeletion,
|
|
2136
|
-
context
|
|
2176
|
+
context,
|
|
2177
|
+
readOnly
|
|
2137
2178
|
}
|
|
2138
2179
|
),
|
|
2139
|
-
RELATION: ({ value, onChange, column, context, rowId }) => /* @__PURE__ */ jsx7(
|
|
2180
|
+
RELATION: ({ value, onChange, column, context, rowId, readOnly }) => /* @__PURE__ */ jsx7(
|
|
2140
2181
|
RelationPickerCell,
|
|
2141
2182
|
{
|
|
2142
2183
|
value,
|
|
2143
2184
|
onChange,
|
|
2144
2185
|
column,
|
|
2145
2186
|
context,
|
|
2146
|
-
rowId
|
|
2187
|
+
rowId,
|
|
2188
|
+
readOnly
|
|
2147
2189
|
}
|
|
2148
2190
|
),
|
|
2149
|
-
NUMBER: ({ value, onChange }) =>
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
type: "number",
|
|
2153
|
-
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
2154
|
-
value: value !== void 0 && value !== null ? value : "",
|
|
2155
|
-
onChange: (e) => {
|
|
2156
|
-
const val = e.target.value;
|
|
2157
|
-
onChange(val === "" ? null : Number(val));
|
|
2158
|
-
}
|
|
2191
|
+
NUMBER: ({ value, onChange, readOnly }) => {
|
|
2192
|
+
if (readOnly) {
|
|
2193
|
+
return /* @__PURE__ */ jsx7("span", { className: "px-2 py-1 flex items-center h-full text-sm select-text truncate", children: value !== void 0 && value !== null ? value : "" });
|
|
2159
2194
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2195
|
+
return /* @__PURE__ */ jsx7(
|
|
2196
|
+
"input",
|
|
2197
|
+
{
|
|
2198
|
+
type: "number",
|
|
2199
|
+
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
2200
|
+
value: value !== void 0 && value !== null ? value : "",
|
|
2201
|
+
onChange: (e) => {
|
|
2202
|
+
const val = e.target.value;
|
|
2203
|
+
onChange(val === "" ? null : Number(val));
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
);
|
|
2207
|
+
},
|
|
2208
|
+
PHONE: ({ value, onChange, column, readOnly }) => {
|
|
2162
2209
|
var _a;
|
|
2163
2210
|
const enableWhatsApp = (_a = column == null ? void 0 : column.config) == null ? void 0 : _a.enableWhatsApp;
|
|
2211
|
+
const formatted = value ? formatPhoneDisplay(String(value)) : "";
|
|
2212
|
+
if (readOnly) {
|
|
2213
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between w-full h-full px-2 gap-1.5 overflow-hidden", children: [
|
|
2214
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate text-sm", dir: "ltr", children: formatted }),
|
|
2215
|
+
enableWhatsApp && value && /* @__PURE__ */ jsx7(
|
|
2216
|
+
"button",
|
|
2217
|
+
{
|
|
2218
|
+
type: "button",
|
|
2219
|
+
className: "text-emerald-500 cursor-pointer hover:opacity-80 transition-opacity shrink-0 p-1 rounded hover:bg-emerald-50",
|
|
2220
|
+
title: "\u05E4\u05EA\u05D9\u05D7\u05EA \u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4",
|
|
2221
|
+
onClick: (e) => {
|
|
2222
|
+
e.stopPropagation();
|
|
2223
|
+
openWhatsAppChat(String(value));
|
|
2224
|
+
},
|
|
2225
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a5.816 5.816 0 00-.571-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" }) })
|
|
2226
|
+
}
|
|
2227
|
+
)
|
|
2228
|
+
] });
|
|
2229
|
+
}
|
|
2164
2230
|
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center w-full h-full px-2 gap-1.5 overflow-hidden", children: [
|
|
2165
2231
|
/* @__PURE__ */ jsx7(
|
|
2166
2232
|
"input",
|
|
@@ -2187,85 +2253,9 @@ var FORM_INPUTS = {
|
|
|
2187
2253
|
)
|
|
2188
2254
|
] });
|
|
2189
2255
|
},
|
|
2190
|
-
GOOGLE_CONTACT: ({ value, column, rowId, onChange, context }) => {
|
|
2256
|
+
GOOGLE_CONTACT: ({ value, column, rowId, onChange, context, readOnly }) => {
|
|
2191
2257
|
const [isSyncing, setIsSyncing] = React7.useState(false);
|
|
2192
2258
|
const { addToast } = useToast();
|
|
2193
|
-
const googleClientIdRef = React7.useRef(null);
|
|
2194
|
-
const ensureGisScript = React7.useCallback(() => {
|
|
2195
|
-
return new Promise((resolve, reject) => {
|
|
2196
|
-
var _a, _b, _c;
|
|
2197
|
-
if ((_c = (_b = (_a = window.google) == null ? void 0 : _a.accounts) == null ? void 0 : _b.oauth2) == null ? void 0 : _c.initTokenClient) {
|
|
2198
|
-
resolve();
|
|
2199
|
-
return;
|
|
2200
|
-
}
|
|
2201
|
-
if (document.querySelector('script[src*="accounts.google.com/gsi/client"]')) {
|
|
2202
|
-
const waitForLoad = setInterval(() => {
|
|
2203
|
-
var _a2, _b2, _c2;
|
|
2204
|
-
if ((_c2 = (_b2 = (_a2 = window.google) == null ? void 0 : _a2.accounts) == null ? void 0 : _b2.oauth2) == null ? void 0 : _c2.initTokenClient) {
|
|
2205
|
-
clearInterval(waitForLoad);
|
|
2206
|
-
resolve();
|
|
2207
|
-
}
|
|
2208
|
-
}, 100);
|
|
2209
|
-
setTimeout(() => {
|
|
2210
|
-
clearInterval(waitForLoad);
|
|
2211
|
-
reject(new Error("GIS script load timeout"));
|
|
2212
|
-
}, 1e4);
|
|
2213
|
-
return;
|
|
2214
|
-
}
|
|
2215
|
-
const script = document.createElement("script");
|
|
2216
|
-
script.src = "https://accounts.google.com/gsi/client";
|
|
2217
|
-
script.async = true;
|
|
2218
|
-
script.onload = () => resolve();
|
|
2219
|
-
script.onerror = () => reject(new Error("Failed to load Google Identity Services"));
|
|
2220
|
-
document.head.appendChild(script);
|
|
2221
|
-
});
|
|
2222
|
-
}, []);
|
|
2223
|
-
const requestGisToken = React7.useCallback(async (hint) => {
|
|
2224
|
-
await ensureGisScript();
|
|
2225
|
-
if (!googleClientIdRef.current && (context == null ? void 0 : context.executeAction)) {
|
|
2226
|
-
try {
|
|
2227
|
-
const config = await context.executeAction("GET_GOOGLE_CONFIG", {});
|
|
2228
|
-
googleClientIdRef.current = (config == null ? void 0 : config.clientId) || "";
|
|
2229
|
-
} catch (e) {
|
|
2230
|
-
throw new Error("Failed to fetch Google configuration");
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
const clientId = googleClientIdRef.current;
|
|
2234
|
-
if (!clientId) {
|
|
2235
|
-
throw new Error("Google Client ID is not configured");
|
|
2236
|
-
}
|
|
2237
|
-
const accessToken = await new Promise((resolve, reject) => {
|
|
2238
|
-
const tokenClient = window.google.accounts.oauth2.initTokenClient({
|
|
2239
|
-
client_id: clientId,
|
|
2240
|
-
scope: "https://www.googleapis.com/auth/contacts https://www.googleapis.com/auth/userinfo.email",
|
|
2241
|
-
prompt: hint ? "" : "select_account",
|
|
2242
|
-
hint: hint || void 0,
|
|
2243
|
-
callback: (tokenResponse) => {
|
|
2244
|
-
if (tokenResponse == null ? void 0 : tokenResponse.access_token) {
|
|
2245
|
-
resolve(tokenResponse.access_token);
|
|
2246
|
-
} else {
|
|
2247
|
-
reject(new Error("Google authorization was cancelled or failed"));
|
|
2248
|
-
}
|
|
2249
|
-
},
|
|
2250
|
-
error_callback: (err) => {
|
|
2251
|
-
reject(new Error((err == null ? void 0 : err.message) || "Google authorization error"));
|
|
2252
|
-
}
|
|
2253
|
-
});
|
|
2254
|
-
tokenClient.requestAccessToken({ hint: hint || void 0 });
|
|
2255
|
-
});
|
|
2256
|
-
let email = "";
|
|
2257
|
-
try {
|
|
2258
|
-
const res = await fetch("https://www.googleapis.com/oauth2/v3/userinfo", {
|
|
2259
|
-
headers: { Authorization: `Bearer ${accessToken}` }
|
|
2260
|
-
});
|
|
2261
|
-
if (res.ok) {
|
|
2262
|
-
const info = await res.json();
|
|
2263
|
-
email = info.email || "";
|
|
2264
|
-
}
|
|
2265
|
-
} catch (e) {
|
|
2266
|
-
}
|
|
2267
|
-
return { accessToken, email };
|
|
2268
|
-
}, [ensureGisScript, context]);
|
|
2269
2259
|
const handleSync = async () => {
|
|
2270
2260
|
var _a, _b, _c, _d, _e, _f;
|
|
2271
2261
|
if (!(context == null ? void 0 : context.executeAction)) return;
|
|
@@ -2300,17 +2290,6 @@ var FORM_INPUTS = {
|
|
|
2300
2290
|
setIsSyncing(false);
|
|
2301
2291
|
return;
|
|
2302
2292
|
}
|
|
2303
|
-
let accessToken;
|
|
2304
|
-
let userEmail = "";
|
|
2305
|
-
try {
|
|
2306
|
-
const gisResult = await requestGisToken();
|
|
2307
|
-
accessToken = gisResult.accessToken;
|
|
2308
|
-
userEmail = gisResult.email;
|
|
2309
|
-
} catch (gisError) {
|
|
2310
|
-
addToast({ type: "warning", message: gisError.message || "\u05D4\u05D4\u05E8\u05E9\u05D0\u05D4 \u05DC\u05D2\u05D5\u05D2\u05DC \u05E0\u05DB\u05E9\u05DC\u05D4" });
|
|
2311
|
-
setIsSyncing(false);
|
|
2312
|
-
return;
|
|
2313
|
-
}
|
|
2314
2293
|
const payload = {
|
|
2315
2294
|
nameParts: mapping.nameParts || [],
|
|
2316
2295
|
phoneCol: mapping.phoneCol,
|
|
@@ -2320,9 +2299,7 @@ var FORM_INPUTS = {
|
|
|
2320
2299
|
tableMetaId: targetTableMetaId,
|
|
2321
2300
|
tableId: targetTableMetaId,
|
|
2322
2301
|
recordId: rowId,
|
|
2323
|
-
orgId: targetOrgId
|
|
2324
|
-
accessToken,
|
|
2325
|
-
userEmail
|
|
2302
|
+
orgId: targetOrgId
|
|
2326
2303
|
};
|
|
2327
2304
|
const res = await context.executeAction("SYNC_GOOGLE_CONTACT", payload);
|
|
2328
2305
|
if (res && res.synced) {
|
|
@@ -2342,39 +2319,44 @@ var FORM_INPUTS = {
|
|
|
2342
2319
|
}
|
|
2343
2320
|
}
|
|
2344
2321
|
} catch (error) {
|
|
2345
|
-
|
|
2346
|
-
|
|
2322
|
+
const errorMessage = (error == null ? void 0 : error.message) || (error == null ? void 0 : error.error) || (typeof error === "string" ? error : "");
|
|
2323
|
+
if (errorMessage.includes("OAUTH_REQUIRED") || errorMessage.includes("Access Denied") || errorMessage.includes("No refresh token")) {
|
|
2324
|
+
addToast({
|
|
2325
|
+
type: "warning",
|
|
2326
|
+
message: "\u05D8\u05E8\u05DD \u05D4\u05D5\u05D2\u05D3\u05E8 \u05D7\u05E9\u05D1\u05D5\u05DF \u05D2\u05D5\u05D2\u05DC \u05D0\u05E8\u05D2\u05D5\u05E0\u05D9. \u05D9\u05E9 \u05DC\u05E4\u05E0\u05D5\u05EA \u05DC\u05DE\u05E0\u05D4\u05DC \u05D4\u05DE\u05E2\u05E8\u05DB\u05EA \u05DC\u05D7\u05D9\u05D1\u05D5\u05E8 \u05D4\u05D7\u05E9\u05D1\u05D5\u05DF \u05D1\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05D4\u05D0\u05E8\u05D2\u05D5\u05DF."
|
|
2327
|
+
});
|
|
2328
|
+
} else {
|
|
2329
|
+
console.error("Failed to sync contact:", error);
|
|
2330
|
+
addToast({
|
|
2331
|
+
type: "warning",
|
|
2332
|
+
message: "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05E1\u05E0\u05DB\u05E8\u05D5\u05DF \u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8: " + error.message
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2347
2335
|
} finally {
|
|
2348
2336
|
setIsSyncing(false);
|
|
2349
2337
|
}
|
|
2350
2338
|
};
|
|
2351
2339
|
const handleUnlink = async () => {
|
|
2352
|
-
let accessToken;
|
|
2353
2340
|
const targetTableMetaId = (context == null ? void 0 : context.tableMetaId) || (context == null ? void 0 : context.tableId);
|
|
2354
2341
|
const targetOrgId = context == null ? void 0 : context.orgId;
|
|
2355
2342
|
try {
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2343
|
+
if ((value == null ? void 0 : value.resourceName) && (context == null ? void 0 : context.executeAction)) {
|
|
2344
|
+
await context.executeAction("DELETE_GOOGLE_CONTACT", {
|
|
2345
|
+
resourceName: value.resourceName,
|
|
2346
|
+
tableMetaId: targetTableMetaId,
|
|
2347
|
+
tableId: targetTableMetaId,
|
|
2348
|
+
recordId: rowId,
|
|
2349
|
+
orgId: targetOrgId
|
|
2350
|
+
});
|
|
2363
2351
|
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
accessToken,
|
|
2373
|
-
tableMetaId: targetTableMetaId,
|
|
2374
|
-
tableId: targetTableMetaId,
|
|
2375
|
-
recordId: rowId,
|
|
2376
|
-
orgId: targetOrgId
|
|
2377
|
-
});
|
|
2352
|
+
} catch (error) {
|
|
2353
|
+
if (error.message === "OAUTH_REQUIRED" || error.error === "OAUTH_REQUIRED") {
|
|
2354
|
+
addToast({ type: "warning", message: "\u05D8\u05E8\u05DD \u05D4\u05D5\u05D2\u05D3\u05E8 \u05D7\u05E9\u05D1\u05D5\u05DF \u05D2\u05D5\u05D2\u05DC \u05D0\u05E8\u05D2\u05D5\u05E0\u05D9. \u05D9\u05E9 \u05DC\u05E4\u05E0\u05D5\u05EA \u05DC\u05DE\u05E0\u05D4\u05DC \u05D4\u05DE\u05E2\u05E8\u05DB\u05EA \u05DC\u05D7\u05D9\u05D1\u05D5\u05E8 \u05D4\u05D7\u05E9\u05D1\u05D5\u05DF \u05D1\u05D4\u05D2\u05D3\u05E8\u05D5\u05EA \u05D4\u05D0\u05E8\u05D2\u05D5\u05DF." });
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
console.error("Failed to unlink contact:", error);
|
|
2358
|
+
addToast({ type: "warning", message: "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05D4\u05E1\u05E8\u05EA \u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8: " + error.message });
|
|
2359
|
+
return;
|
|
2378
2360
|
}
|
|
2379
2361
|
if (context == null ? void 0 : context.updateQuietly) {
|
|
2380
2362
|
context.updateQuietly(rowId, column.name, null);
|
|
@@ -2394,7 +2376,7 @@ var FORM_INPUTS = {
|
|
|
2394
2376
|
if (value && value.synced && value.url) {
|
|
2395
2377
|
return /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5 h-8 px-2 group whitespace-nowrap overflow-hidden max-w-full", children: [
|
|
2396
2378
|
/* @__PURE__ */ jsx7("a", { href: value.url, target: "_blank", rel: "noopener noreferrer", className: "text-blue-600 hover:underline flex-1 truncate text-xs whitespace-nowrap", children: "\u05D0\u05D9\u05E9 \u05E7\u05E9\u05E8 \u05D2\u05D5\u05D2\u05DC" }),
|
|
2397
|
-
/* @__PURE__ */ jsx7(
|
|
2379
|
+
!readOnly && /* @__PURE__ */ jsx7(
|
|
2398
2380
|
"button",
|
|
2399
2381
|
{
|
|
2400
2382
|
type: "button",
|
|
@@ -2406,6 +2388,9 @@ var FORM_INPUTS = {
|
|
|
2406
2388
|
)
|
|
2407
2389
|
] });
|
|
2408
2390
|
}
|
|
2391
|
+
if (readOnly) {
|
|
2392
|
+
return /* @__PURE__ */ jsx7("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05DC\u05D0 \u05DE\u05E1\u05D5\u05E0\u05DB\u05E8\u05DF" });
|
|
2393
|
+
}
|
|
2409
2394
|
return /* @__PURE__ */ jsx7("div", { className: "flex items-center h-8 px-2 whitespace-nowrap overflow-hidden max-w-full", children: /* @__PURE__ */ jsxs7(
|
|
2410
2395
|
"button",
|
|
2411
2396
|
{
|
|
@@ -2423,15 +2408,20 @@ var FORM_INPUTS = {
|
|
|
2423
2408
|
}
|
|
2424
2409
|
) });
|
|
2425
2410
|
},
|
|
2426
|
-
DEFAULT: ({ value, onChange }) =>
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
type: "text",
|
|
2430
|
-
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
2431
|
-
value: value !== void 0 && value !== null ? String(value) : "",
|
|
2432
|
-
onChange: (e) => onChange(e.target.value)
|
|
2411
|
+
DEFAULT: ({ value, onChange, readOnly }) => {
|
|
2412
|
+
if (readOnly) {
|
|
2413
|
+
return /* @__PURE__ */ jsx7("span", { className: "px-2 py-1 flex items-center h-full text-sm select-text truncate", children: value !== void 0 && value !== null ? String(value) : "" });
|
|
2433
2414
|
}
|
|
2434
|
-
|
|
2415
|
+
return /* @__PURE__ */ jsx7(
|
|
2416
|
+
"input",
|
|
2417
|
+
{
|
|
2418
|
+
type: "text",
|
|
2419
|
+
className: "w-full h-8 px-2 bg-transparent focus:bg-white focus:outline-none focus:ring-1 focus:ring-blue-400 text-sm",
|
|
2420
|
+
value: value !== void 0 && value !== null ? String(value) : "",
|
|
2421
|
+
onChange: (e) => onChange(e.target.value)
|
|
2422
|
+
}
|
|
2423
|
+
);
|
|
2424
|
+
},
|
|
2435
2425
|
SUB_TABLE: ({ value, column }) => {
|
|
2436
2426
|
var _a, _b, _c;
|
|
2437
2427
|
if (!Array.isArray(value)) return /* @__PURE__ */ jsx7("span", { className: "px-2 py-1 flex items-center h-full text-slate-300 text-xs italic", children: "\u05E8\u05D9\u05E7" });
|
|
@@ -2841,7 +2831,8 @@ function SubTableCell({
|
|
|
2841
2831
|
refetchRelation,
|
|
2842
2832
|
onCommit,
|
|
2843
2833
|
onQuietUpdate,
|
|
2844
|
-
width
|
|
2834
|
+
width,
|
|
2835
|
+
readOnly
|
|
2845
2836
|
}) {
|
|
2846
2837
|
var _a, _b, _c, _d, _e;
|
|
2847
2838
|
const colType = ((_a = column.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
@@ -2876,6 +2867,7 @@ function SubTableCell({
|
|
|
2876
2867
|
}
|
|
2877
2868
|
}, [serverValue]);
|
|
2878
2869
|
const commit = useCallback8(async (valToCommit) => {
|
|
2870
|
+
if (readOnly) return true;
|
|
2879
2871
|
if (isCommittingRef.current) return false;
|
|
2880
2872
|
if (!isDirtyRef.current) return true;
|
|
2881
2873
|
if (valToCommit === serverValueRef.current) {
|
|
@@ -2992,7 +2984,9 @@ function SubTableCell({
|
|
|
2992
2984
|
column,
|
|
2993
2985
|
rowId: record.id,
|
|
2994
2986
|
onChange: handleChange,
|
|
2987
|
+
readOnly,
|
|
2995
2988
|
context: __spreadProps(__spreadValues({}, context), {
|
|
2989
|
+
readOnly,
|
|
2996
2990
|
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",
|
|
2997
2991
|
relationOptions,
|
|
2998
2992
|
updateRelationOptions: (name, opts) => setRelationOptions((prev) => __spreadProps(__spreadValues({}, prev), { [name]: opts })),
|
|
@@ -3022,8 +3016,9 @@ function SubTableCell({
|
|
|
3022
3016
|
}
|
|
3023
3017
|
);
|
|
3024
3018
|
}
|
|
3025
|
-
function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
3019
|
+
function SubTableViewer({ rowId, column, value, onChange, context, readOnly }) {
|
|
3026
3020
|
var _a, _b, _c, _d, _e, _f;
|
|
3021
|
+
const isReadOnly = readOnly != null ? readOnly : Boolean(context == null ? void 0 : context.readOnly);
|
|
3027
3022
|
const { addToast } = useToast();
|
|
3028
3023
|
const entries = Array.isArray(value) ? value : [];
|
|
3029
3024
|
const [linkedRecords, setLinkedRecords] = useState10(() => {
|
|
@@ -3550,7 +3545,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3550
3545
|
return /* @__PURE__ */ jsxs9("div", { className: "p-3 animate-in fade-in slide-in-from-top-2 duration-200", dir: "rtl", children: [
|
|
3551
3546
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-4 mb-2.5", children: [
|
|
3552
3547
|
/* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx9("span", { className: "text-xs font-bold text-slate-600", children: (_e = targetSchema == null ? void 0 : targetSchema.name) != null ? _e : (_d = column.config) == null ? void 0 : _d.referencedTableName }) }),
|
|
3553
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
|
|
3548
|
+
!isReadOnly && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
|
|
3554
3549
|
/* @__PURE__ */ jsxs9("div", { className: "relative", ref: searchRef, children: [
|
|
3555
3550
|
/* @__PURE__ */ jsxs9(
|
|
3556
3551
|
"button",
|
|
@@ -3615,13 +3610,13 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3615
3610
|
)
|
|
3616
3611
|
] })
|
|
3617
3612
|
] }),
|
|
3618
|
-
isLoading ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ jsx9("div", { className: "w-5 h-5 border-2 border-blue-400 border-t-transparent rounded-full animate-spin" }) }) : entries.length === 0 && !isCreating ? /* @__PURE__ */ jsx9("div", { className: "text-center py-6 text-xs text-slate-400", children: "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DE\u05E7\u05D5\u05E9\u05E8\u05D5\u05EA. \u05D4\u05E9\u05EA\u05DE\u05E9 \u05D1\u05D7\u05D9\u05E4\u05D5\u05E9 \u05DB\u05D3\u05D9 \u05DC\u05E7\u05E9\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05E7\u05D9\u05D9\u05DE\u05D5\u05EA, \u05D0\u05D5 \u05D4\u05D5\u05E1\u05E3 \u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4." }) : /* @__PURE__ */ jsx9("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-xs border-collapse table-auto", children: [
|
|
3613
|
+
isLoading ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ jsx9("div", { className: "w-5 h-5 border-2 border-blue-400 border-t-transparent rounded-full animate-spin" }) }) : entries.length === 0 && !isCreating ? /* @__PURE__ */ jsx9("div", { className: "text-center py-6 text-xs text-slate-400", children: isReadOnly ? "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DE\u05E7\u05D5\u05E9\u05E8\u05D5\u05EA \u05DC\u05D4\u05E6\u05D2\u05D4." : "\u05D0\u05D9\u05DF \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05DE\u05E7\u05D5\u05E9\u05E8\u05D5\u05EA. \u05D4\u05E9\u05EA\u05DE\u05E9 \u05D1\u05D7\u05D9\u05E4\u05D5\u05E9 \u05DB\u05D3\u05D9 \u05DC\u05E7\u05E9\u05E8 \u05E8\u05E9\u05D5\u05DE\u05D5\u05EA \u05E7\u05D9\u05D9\u05DE\u05D5\u05EA, \u05D0\u05D5 \u05D4\u05D5\u05E1\u05E3 \u05E8\u05E9\u05D5\u05DE\u05D4 \u05D7\u05D3\u05E9\u05D4." }) : /* @__PURE__ */ jsx9("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-xs border-collapse table-auto", children: [
|
|
3619
3614
|
/* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "bg-slate-100/80 h-12 min-h-[48px]", children: [
|
|
3620
3615
|
/* @__PURE__ */ jsx9("th", { className: "border border-slate-200 px-2 py-1.5 text-center w-10 font-semibold text-slate-500 h-12 min-h-[48px] align-middle", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: "\u05E0\u05D1\u05D7\u05E8" }),
|
|
3621
3616
|
targetColumns.map((col) => {
|
|
3622
|
-
const dragProps = getHeaderDragProps(col.name);
|
|
3623
|
-
const isDragging = draggedColName === col.name;
|
|
3624
|
-
const isDragOver = dragOverColName === col.name;
|
|
3617
|
+
const dragProps = isReadOnly ? {} : getHeaderDragProps(col.name);
|
|
3618
|
+
const isDragging = !isReadOnly && draggedColName === col.name;
|
|
3619
|
+
const isDragOver = !isReadOnly && dragOverColName === col.name;
|
|
3625
3620
|
const colMinWidth = calculateMinColumnWidth(col.name, true, col.type);
|
|
3626
3621
|
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 150);
|
|
3627
3622
|
return /* @__PURE__ */ jsxs9(
|
|
@@ -3630,7 +3625,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3630
3625
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
3631
3626
|
title: col.name
|
|
3632
3627
|
}, dragProps), {
|
|
3633
|
-
className: `relative border border-slate-200 px-3 py-1.5 font-semibold text-slate-600 select-none cursor-grab active:cursor-grabbing transition-colors h-12 min-h-[48px] align-middle ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : "hover:bg-slate-200/60"}`,
|
|
3628
|
+
className: `relative border border-slate-200 px-3 py-1.5 font-semibold text-slate-600 select-none ${isReadOnly ? "cursor-default" : "cursor-grab active:cursor-grabbing"} transition-colors h-12 min-h-[48px] align-middle ${isDragging ? "opacity-40 bg-slate-200 border-dashed border-2 border-brand" : ""} ${isDragOver ? "bg-blue-50 border-r-4 border-r-brand text-brand font-bold" : isReadOnly ? "" : "hover:bg-slate-200/60"}`,
|
|
3634
3629
|
children: [
|
|
3635
3630
|
/* @__PURE__ */ jsx9(
|
|
3636
3631
|
"div",
|
|
@@ -3646,7 +3641,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3646
3641
|
),
|
|
3647
3642
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-1.5 group overflow-hidden w-full", title: col.name, children: [
|
|
3648
3643
|
/* @__PURE__ */ jsx9(ColumnHeaderTitle, { name: col.name, width: currentWidth, isSubTable: true }),
|
|
3649
|
-
/* @__PURE__ */ jsx9(
|
|
3644
|
+
!isReadOnly && /* @__PURE__ */ jsx9(
|
|
3650
3645
|
"svg",
|
|
3651
3646
|
{
|
|
3652
3647
|
className: "w-3.5 h-3.5 text-slate-400 opacity-40 group-hover:opacity-100 transition-opacity shrink-0 cursor-grab",
|
|
@@ -3675,8 +3670,9 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3675
3670
|
{
|
|
3676
3671
|
type: "checkbox",
|
|
3677
3672
|
checked: entry.isSelected,
|
|
3673
|
+
disabled: isReadOnly,
|
|
3678
3674
|
onChange: () => handleToggleSelected(entry.recordId),
|
|
3679
|
-
className:
|
|
3675
|
+
className: `w-3.5 h-3.5 rounded border-slate-300 text-blue-600 ${isReadOnly ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`
|
|
3680
3676
|
}
|
|
3681
3677
|
) }),
|
|
3682
3678
|
targetColumns.map((col) => {
|
|
@@ -3706,7 +3702,8 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3706
3702
|
refetchRelation,
|
|
3707
3703
|
onCommit: handleCommitRecordCell,
|
|
3708
3704
|
onQuietUpdate: handleQuietSubTableCellChange,
|
|
3709
|
-
width: currentWidth
|
|
3705
|
+
width: currentWidth,
|
|
3706
|
+
readOnly: isReadOnly
|
|
3710
3707
|
},
|
|
3711
3708
|
`${record.id}_${col.name}`
|
|
3712
3709
|
);
|
|
@@ -3733,7 +3730,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3733
3730
|
}
|
|
3734
3731
|
return null;
|
|
3735
3732
|
})(),
|
|
3736
|
-
/* @__PURE__ */ jsx9(
|
|
3733
|
+
!isReadOnly && /* @__PURE__ */ jsx9(
|
|
3737
3734
|
"button",
|
|
3738
3735
|
{
|
|
3739
3736
|
type: "button",
|
|
@@ -3750,7 +3747,7 @@ function SubTableViewer({ rowId, column, value, onChange, context }) {
|
|
|
3750
3747
|
/* @__PURE__ */ jsx9("td", { className: "border border-slate-200 bg-white pointer-events-none" })
|
|
3751
3748
|
] }, entry.recordId);
|
|
3752
3749
|
}),
|
|
3753
|
-
isCreating && /* @__PURE__ */ jsxs9("tr", { className: "bg-emerald-50/40", children: [
|
|
3750
|
+
isCreating && !isReadOnly && /* @__PURE__ */ jsxs9("tr", { className: "bg-emerald-50/40", children: [
|
|
3754
3751
|
/* @__PURE__ */ jsx9("td", { className: "border border-emerald-200 px-2 py-1 text-center", style: { width: 40, minWidth: 40, maxWidth: 40 }, children: /* @__PURE__ */ jsx9("span", { className: "text-emerald-500 font-bold text-[10px]", children: "\u05D7\u05D3\u05E9" }) }),
|
|
3755
3752
|
targetColumns.map((col) => {
|
|
3756
3753
|
var _a2, _b2, _c2, _d2, _e2;
|
|
@@ -4265,10 +4262,21 @@ function TableBlockClient({
|
|
|
4265
4262
|
componentId,
|
|
4266
4263
|
orgId,
|
|
4267
4264
|
className = "",
|
|
4268
|
-
"data-testid": dataTestId
|
|
4265
|
+
"data-testid": dataTestId,
|
|
4266
|
+
role,
|
|
4267
|
+
permissions,
|
|
4268
|
+
readOnly
|
|
4269
4269
|
}) {
|
|
4270
4270
|
const { showError, addToast } = useToast();
|
|
4271
4271
|
const [isExporting, setIsExporting] = useState12(false);
|
|
4272
|
+
const resolvedRole = role ? getRolePermissions(role) : void 0;
|
|
4273
|
+
const effectivePermissions = permissions || (resolvedRole == null ? void 0 : resolvedRole.permissions) || {
|
|
4274
|
+
canCreate: !readOnly,
|
|
4275
|
+
canRead: true,
|
|
4276
|
+
canUpdate: !readOnly,
|
|
4277
|
+
canDelete: !readOnly
|
|
4278
|
+
};
|
|
4279
|
+
const effectiveReadOnly = readOnly != null ? readOnly : resolvedRole ? resolvedRole.readOnly : !effectivePermissions.canUpdate && !effectivePermissions.canCreate && !effectivePermissions.canDelete;
|
|
4272
4280
|
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";
|
|
4273
4281
|
const { columnWidths, startResize } = useColumnResize({
|
|
4274
4282
|
storageKey: `table_widths_${tableKey}`,
|
|
@@ -4279,6 +4287,10 @@ function TableBlockClient({
|
|
|
4279
4287
|
return calculateMinColumnWidth(colName, false, col == null ? void 0 : col.type);
|
|
4280
4288
|
}
|
|
4281
4289
|
});
|
|
4290
|
+
const executeActionRef = useRef8(executeAction);
|
|
4291
|
+
useEffect10(() => {
|
|
4292
|
+
executeActionRef.current = executeAction;
|
|
4293
|
+
}, [executeAction]);
|
|
4282
4294
|
const [isMounted, setIsMounted] = useState12(false);
|
|
4283
4295
|
const [isInitialLoading, setIsInitialLoading] = useState12(true);
|
|
4284
4296
|
const [page, setPage] = useState12(1);
|
|
@@ -4381,6 +4393,7 @@ function TableBlockClient({
|
|
|
4381
4393
|
}, []);
|
|
4382
4394
|
const [data, setData] = useState12(() => normalizeRecords(initialRecords));
|
|
4383
4395
|
const [serverRecords, setServerRecords] = useState12(() => normalizeRecords(initialRecords));
|
|
4396
|
+
const filteredData = data;
|
|
4384
4397
|
useEffect10(() => {
|
|
4385
4398
|
if (initialRecords) {
|
|
4386
4399
|
const norm = normalizeRecords(initialRecords);
|
|
@@ -4418,6 +4431,8 @@ function TableBlockClient({
|
|
|
4418
4431
|
const [relationTriggerRect, setRelationTriggerRect] = useState12(null);
|
|
4419
4432
|
const filterButtonRefs = useRef8({});
|
|
4420
4433
|
const [relationOptions, setRelationOptions] = useState12({});
|
|
4434
|
+
const [relationFilterOptions, setRelationFilterOptions] = useState12({});
|
|
4435
|
+
const [loadingFilterCol, setLoadingFilterCol] = useState12(null);
|
|
4421
4436
|
const relationDictionaryRef = useRef8({});
|
|
4422
4437
|
const mergeRelationOptions = useCallback10((colName, newOptions) => {
|
|
4423
4438
|
if (!Array.isArray(newOptions) || newOptions.length === 0) return;
|
|
@@ -4482,7 +4497,8 @@ function TableBlockClient({
|
|
|
4482
4497
|
const fetchRequestIdRef = useRef8(0);
|
|
4483
4498
|
const fetchTableData = useCallback10((targetPage, targetLimit, targetSearch, targetFiltersKey) => {
|
|
4484
4499
|
const tableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
4485
|
-
|
|
4500
|
+
const action = executeActionRef.current;
|
|
4501
|
+
if (!tableId || !action) return Promise.resolve();
|
|
4486
4502
|
const currentRequestId = ++fetchRequestIdRef.current;
|
|
4487
4503
|
setIsFetching(true);
|
|
4488
4504
|
let activeFilters = {};
|
|
@@ -4491,7 +4507,7 @@ function TableBlockClient({
|
|
|
4491
4507
|
} catch (e) {
|
|
4492
4508
|
}
|
|
4493
4509
|
const skip = (targetPage - 1) * targetLimit;
|
|
4494
|
-
return
|
|
4510
|
+
return action("FETCH_TABLE_DATA", {
|
|
4495
4511
|
tableId,
|
|
4496
4512
|
page: targetPage,
|
|
4497
4513
|
limit: targetLimit,
|
|
@@ -4540,7 +4556,7 @@ function TableBlockClient({
|
|
|
4540
4556
|
setIsInitialLoading(false);
|
|
4541
4557
|
}
|
|
4542
4558
|
});
|
|
4543
|
-
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id,
|
|
4559
|
+
}, [schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, mergeColumnDefs, mergeWithDirty, mergeRelationOptions]);
|
|
4544
4560
|
useEffect10(() => {
|
|
4545
4561
|
fetchTableData(page, limit, debouncedSearch, filtersKey);
|
|
4546
4562
|
}, [page, limit, debouncedSearch, filtersKey, fetchTableData]);
|
|
@@ -4618,6 +4634,42 @@ function TableBlockClient({
|
|
|
4618
4634
|
}
|
|
4619
4635
|
return [];
|
|
4620
4636
|
}, [schemaColsString, executeAction, mergeRelationOptions]);
|
|
4637
|
+
const fetchRelationFilterOptions = useCallback10(async (colName) => {
|
|
4638
|
+
var _a;
|
|
4639
|
+
let parsedCols = [];
|
|
4640
|
+
try {
|
|
4641
|
+
parsedCols = JSON.parse(schemaColsString);
|
|
4642
|
+
} catch (e) {
|
|
4643
|
+
}
|
|
4644
|
+
const col = parsedCols.find((c) => {
|
|
4645
|
+
var _a2;
|
|
4646
|
+
return c.name === colName && ((_a2 = c.type) == null ? void 0 : _a2.toUpperCase()) === "RELATION";
|
|
4647
|
+
});
|
|
4648
|
+
if (!col || !((_a = col.config) == null ? void 0 : _a.referencedTableId) || !executeAction) return;
|
|
4649
|
+
const currentTableId = (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id);
|
|
4650
|
+
setLoadingFilterCol(colName);
|
|
4651
|
+
try {
|
|
4652
|
+
const res = await executeAction("FETCH_RELATION", {
|
|
4653
|
+
referencedTableId: col.config.referencedTableId,
|
|
4654
|
+
currentTableId,
|
|
4655
|
+
columnName: colName,
|
|
4656
|
+
isFilter: true,
|
|
4657
|
+
displayField: col.config.displayField,
|
|
4658
|
+
take: 1e3
|
|
4659
|
+
});
|
|
4660
|
+
const list = Array.isArray(res) ? res : (res == null ? void 0 : res.data) && Array.isArray(res.data) ? res.data : [];
|
|
4661
|
+
setRelationFilterOptions((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
4662
|
+
[colName]: list
|
|
4663
|
+
}));
|
|
4664
|
+
if (list.length > 0) {
|
|
4665
|
+
mergeRelationOptions(colName, list);
|
|
4666
|
+
}
|
|
4667
|
+
} catch (err) {
|
|
4668
|
+
console.warn(`[TableBlock] Failed to fetch distinct relation filter options for ${colName}:`, err);
|
|
4669
|
+
} finally {
|
|
4670
|
+
setLoadingFilterCol(null);
|
|
4671
|
+
}
|
|
4672
|
+
}, [schemaColsString, schema == null ? void 0 : schema.tableMetaId, schema == null ? void 0 : schema.tableId, schema == null ? void 0 : schema.id, executeAction, mergeRelationOptions]);
|
|
4621
4673
|
const requestedRelationIdsRef = useRef8({});
|
|
4622
4674
|
useEffect10(() => {
|
|
4623
4675
|
if (!executeAction || !data || data.length === 0) return;
|
|
@@ -4920,39 +4972,38 @@ function TableBlockClient({
|
|
|
4920
4972
|
setData((prev) => [newRow, ...prev]);
|
|
4921
4973
|
setDirty((prev) => __spreadProps(__spreadValues({}, prev), { added: [newRow, ...prev.added] }));
|
|
4922
4974
|
};
|
|
4923
|
-
const handleCellChange = (rowId, colName, value) => {
|
|
4975
|
+
const handleCellChange = useCallback10((rowId, colName, value) => {
|
|
4924
4976
|
setData((prev) => prev.map(
|
|
4925
4977
|
(row) => row.id === rowId ? __spreadProps(__spreadValues({}, row), { data: __spreadProps(__spreadValues({}, row.data), { [colName]: value }) }) : row
|
|
4926
4978
|
));
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
added: prev.added.map(
|
|
4931
|
-
(r) => r.id === rowId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value }) }) : r
|
|
4932
|
-
)
|
|
4933
|
-
}));
|
|
4934
|
-
} else {
|
|
4935
|
-
const origData = baseRecordsMap.get(rowId) || {};
|
|
4936
|
-
const origValue = origData[colName];
|
|
4937
|
-
setDirty((prev) => {
|
|
4938
|
-
const currentMods = __spreadValues({}, prev.modified[rowId] || {});
|
|
4939
|
-
if (isEqualValues(value, origValue)) {
|
|
4940
|
-
delete currentMods[colName];
|
|
4941
|
-
} else {
|
|
4942
|
-
currentMods[colName] = value;
|
|
4943
|
-
}
|
|
4944
|
-
const nextModified = __spreadValues({}, prev.modified);
|
|
4945
|
-
if (Object.keys(currentMods).length === 0) {
|
|
4946
|
-
delete nextModified[rowId];
|
|
4947
|
-
} else {
|
|
4948
|
-
nextModified[rowId] = currentMods;
|
|
4949
|
-
}
|
|
4979
|
+
setDirty((prev) => {
|
|
4980
|
+
const isAdded = prev.added.some((r) => r.id === rowId);
|
|
4981
|
+
if (isAdded) {
|
|
4950
4982
|
return __spreadProps(__spreadValues({}, prev), {
|
|
4951
|
-
|
|
4983
|
+
added: prev.added.map(
|
|
4984
|
+
(r) => r.id === rowId ? __spreadProps(__spreadValues({}, r), { data: __spreadProps(__spreadValues({}, r.data), { [colName]: value }) }) : r
|
|
4985
|
+
)
|
|
4952
4986
|
});
|
|
4987
|
+
}
|
|
4988
|
+
const origData = baseRecordsMap.get(rowId) || {};
|
|
4989
|
+
const origValue = origData[colName];
|
|
4990
|
+
const currentMods = __spreadValues({}, prev.modified[rowId] || {});
|
|
4991
|
+
if (isEqualValues(value, origValue)) {
|
|
4992
|
+
delete currentMods[colName];
|
|
4993
|
+
} else {
|
|
4994
|
+
currentMods[colName] = value;
|
|
4995
|
+
}
|
|
4996
|
+
const nextModified = __spreadValues({}, prev.modified);
|
|
4997
|
+
if (Object.keys(currentMods).length === 0) {
|
|
4998
|
+
delete nextModified[rowId];
|
|
4999
|
+
} else {
|
|
5000
|
+
nextModified[rowId] = currentMods;
|
|
5001
|
+
}
|
|
5002
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
5003
|
+
modified: nextModified
|
|
4953
5004
|
});
|
|
4954
|
-
}
|
|
4955
|
-
};
|
|
5005
|
+
});
|
|
5006
|
+
}, [baseRecordsMap]);
|
|
4956
5007
|
const triggerSaveSuccess = useCallback10(() => {
|
|
4957
5008
|
setIsSaveSuccess(true);
|
|
4958
5009
|
setTimeout(() => {
|
|
@@ -4983,22 +5034,28 @@ function TableBlockClient({
|
|
|
4983
5034
|
});
|
|
4984
5035
|
}
|
|
4985
5036
|
}, []);
|
|
4986
|
-
const toggleSelectAll = (checked) => {
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5037
|
+
const toggleSelectAll = useCallback10((checked) => {
|
|
5038
|
+
setSelectedIds(checked ? new Set(filteredData.map((r) => r.id)) : /* @__PURE__ */ new Set());
|
|
5039
|
+
}, [filteredData]);
|
|
5040
|
+
const toggleSelectRow = useCallback10((rowId, checked) => {
|
|
5041
|
+
setSelectedIds((prev) => {
|
|
5042
|
+
const next = new Set(prev);
|
|
5043
|
+
if (checked) next.add(rowId);
|
|
5044
|
+
else next.delete(rowId);
|
|
5045
|
+
return next;
|
|
5046
|
+
});
|
|
5047
|
+
}, []);
|
|
5048
|
+
const handleToggleExpand = useCallback10((rowId) => {
|
|
5049
|
+
setExpandedRowIds((prev) => {
|
|
5050
|
+
const next = new Set(prev);
|
|
5051
|
+
if (next.has(rowId)) next.delete(rowId);
|
|
5052
|
+
else next.add(rowId);
|
|
5053
|
+
return next;
|
|
5054
|
+
});
|
|
5055
|
+
}, []);
|
|
5056
|
+
const handleMarkForDeletion = useCallback10((fileId) => {
|
|
5057
|
+
setPendingDeletions((prev) => [...prev, fileId]);
|
|
5058
|
+
}, []);
|
|
5002
5059
|
const handleDeleteSelected = () => {
|
|
5003
5060
|
const idsToDelete = Array.from(selectedIds);
|
|
5004
5061
|
if (idsToDelete.length === 0) return;
|
|
@@ -5077,9 +5134,6 @@ function TableBlockClient({
|
|
|
5077
5134
|
setData(serverRecords.map((r) => __spreadProps(__spreadValues({}, r), { data: __spreadValues({}, r.data) })));
|
|
5078
5135
|
setSelectedIds(/* @__PURE__ */ new Set());
|
|
5079
5136
|
setPendingDeletions([]);
|
|
5080
|
-
if (emitEvent) {
|
|
5081
|
-
emitEvent("SELECTION_CHANGE", { selectedIds: [], componentId });
|
|
5082
|
-
}
|
|
5083
5137
|
};
|
|
5084
5138
|
const handleSave = async () => {
|
|
5085
5139
|
var _a, _b;
|
|
@@ -5247,26 +5301,13 @@ function TableBlockClient({
|
|
|
5247
5301
|
}).filter(Boolean);
|
|
5248
5302
|
}, [relationOptions]);
|
|
5249
5303
|
const getUniqueRelationOptions = useCallback10((col) => {
|
|
5304
|
+
if (relationFilterOptions[col.name]) {
|
|
5305
|
+
return relationFilterOptions[col.name];
|
|
5306
|
+
}
|
|
5250
5307
|
const seenIds = /* @__PURE__ */ new Set();
|
|
5251
5308
|
const seenLabels = /* @__PURE__ */ new Set();
|
|
5252
5309
|
const results = [];
|
|
5253
5310
|
const options = relationOptions[col.name] || [];
|
|
5254
|
-
options.forEach((opt) => {
|
|
5255
|
-
const id = String(opt.id || opt._id || "");
|
|
5256
|
-
if (!id) return;
|
|
5257
|
-
let label = resolveRelationLabel(opt, col);
|
|
5258
|
-
if (!label) {
|
|
5259
|
-
const fallback = opt.label || opt.name || opt.title;
|
|
5260
|
-
if (fallback && typeof fallback === "string" && !isRawObjectId(fallback)) {
|
|
5261
|
-
label = fallback.trim();
|
|
5262
|
-
}
|
|
5263
|
-
}
|
|
5264
|
-
if (label && label.trim() && !isRawObjectId(label) && !seenLabels.has(label.trim())) {
|
|
5265
|
-
seenIds.add(id);
|
|
5266
|
-
seenLabels.add(label.trim());
|
|
5267
|
-
results.push({ id, label: label.trim() });
|
|
5268
|
-
}
|
|
5269
|
-
});
|
|
5270
5311
|
data.forEach((row) => {
|
|
5271
5312
|
if (!(row == null ? void 0 : row.data)) return;
|
|
5272
5313
|
const ids = normalizeRelationValue(row.data[col.name]);
|
|
@@ -5289,8 +5330,7 @@ function TableBlockClient({
|
|
|
5289
5330
|
});
|
|
5290
5331
|
});
|
|
5291
5332
|
return results.sort((a, b) => a.label.localeCompare(b.label));
|
|
5292
|
-
}, [data, relationOptions]);
|
|
5293
|
-
const filteredData = data;
|
|
5333
|
+
}, [data, relationOptions, relationFilterOptions]);
|
|
5294
5334
|
const errorMessage = error ? typeof error === "string" ? error : error.message || String(error) : null;
|
|
5295
5335
|
const columnTotals = useMemo6(() => {
|
|
5296
5336
|
const totals = {};
|
|
@@ -5381,6 +5421,13 @@ function TableBlockClient({
|
|
|
5381
5421
|
link.click();
|
|
5382
5422
|
document.body.removeChild(link);
|
|
5383
5423
|
URL.revokeObjectURL(url);
|
|
5424
|
+
if (result == null ? void 0 : result.isTruncated) {
|
|
5425
|
+
addToast({
|
|
5426
|
+
message: "\u05D9\u05D5\u05E6\u05D0\u05D5 10,000 \u05D4\u05E9\u05D5\u05E8\u05D5\u05EA \u05D4\u05E8\u05D0\u05E9\u05D5\u05E0\u05D5\u05EA. \u05DE\u05D5\u05DE\u05DC\u05E5 \u05DC\u05E1\u05E0\u05DF \u05D0\u05EA \u05D4\u05D8\u05D1\u05DC\u05D4 \u05DB\u05D3\u05D9 \u05DC\u05E6\u05DE\u05E6\u05DD \u05D0\u05EA \u05D4\u05DB\u05DE\u05D5\u05EA",
|
|
5427
|
+
type: "warning",
|
|
5428
|
+
duration: 5e3
|
|
5429
|
+
});
|
|
5430
|
+
}
|
|
5384
5431
|
} catch (err) {
|
|
5385
5432
|
console.error("[TableBlock] Export to CSV failed:", err);
|
|
5386
5433
|
showError((err == null ? void 0 : err.message) || String(err), "\u05E9\u05D2\u05D9\u05D0\u05D4 \u05D1\u05D9\u05D9\u05E6\u05D5\u05D0 \u05D4\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD");
|
|
@@ -5403,7 +5450,7 @@ function TableBlockClient({
|
|
|
5403
5450
|
/* @__PURE__ */ jsxs11("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 shrink-0", children: [
|
|
5404
5451
|
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
5405
5452
|
((schema == null ? void 0 : schema.title) || (schema == null ? void 0 : schema.name)) && /* @__PURE__ */ jsx11("div", { className: "font-bold text-slate-800 text-sm sm:text-base border-l border-slate-300 pl-3 ml-1", children: /* @__PURE__ */ jsx11("span", { children: schema.title || schema.name }) }),
|
|
5406
|
-
/* @__PURE__ */ jsx11(
|
|
5453
|
+
!effectiveReadOnly && effectivePermissions.canCreate && /* @__PURE__ */ jsx11(
|
|
5407
5454
|
"button",
|
|
5408
5455
|
{
|
|
5409
5456
|
onClick: handleAddRow,
|
|
@@ -5413,7 +5460,7 @@ function TableBlockClient({
|
|
|
5413
5460
|
children: /* @__PURE__ */ jsx11("svg", { className: "w-4.5 h-4.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M12 4v16m8-8H4" }) })
|
|
5414
5461
|
}
|
|
5415
5462
|
),
|
|
5416
|
-
/* @__PURE__ */ jsx11(
|
|
5463
|
+
!effectiveReadOnly && effectivePermissions.canCreate && /* @__PURE__ */ jsx11(
|
|
5417
5464
|
"button",
|
|
5418
5465
|
{
|
|
5419
5466
|
onClick: handleDuplicateRow,
|
|
@@ -5423,7 +5470,7 @@ function TableBlockClient({
|
|
|
5423
5470
|
children: /* @__PURE__ */ jsx11(Copy2, { className: "w-4 h-4 text-blue-600 shrink-0" })
|
|
5424
5471
|
}
|
|
5425
5472
|
),
|
|
5426
|
-
/* @__PURE__ */ jsxs11(
|
|
5473
|
+
!effectiveReadOnly && effectivePermissions.canDelete && /* @__PURE__ */ jsxs11(
|
|
5427
5474
|
"button",
|
|
5428
5475
|
{
|
|
5429
5476
|
onClick: handleDeleteSelected,
|
|
@@ -5449,7 +5496,7 @@ function TableBlockClient({
|
|
|
5449
5496
|
]
|
|
5450
5497
|
}
|
|
5451
5498
|
),
|
|
5452
|
-
/* @__PURE__ */ jsxs11("div", { className: "relative", ref: dropdownRef, children: [
|
|
5499
|
+
!effectiveReadOnly && effectivePermissions.canUpdate && /* @__PURE__ */ jsxs11("div", { className: "relative", ref: dropdownRef, children: [
|
|
5453
5500
|
/* @__PURE__ */ jsxs11(
|
|
5454
5501
|
"button",
|
|
5455
5502
|
{
|
|
@@ -5587,7 +5634,7 @@ function TableBlockClient({
|
|
|
5587
5634
|
] }) : isSaveSuccess ? /* @__PURE__ */ jsxs11("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: [
|
|
5588
5635
|
/* @__PURE__ */ jsx11("svg", { className: "w-4 h-4 text-emerald-600 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.5", d: "M5 13l4 4L19 7" }) }),
|
|
5589
5636
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
5590
|
-
] }) : hasChanges ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 animate-in fade-in", children: [
|
|
5637
|
+
] }) : !effectiveReadOnly && effectivePermissions.canUpdate && hasChanges ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 animate-in fade-in", children: [
|
|
5591
5638
|
/* @__PURE__ */ jsx11("span", { className: "text-xs font-semibold text-amber-700", children: "\u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD \u05E9\u05DC\u05D0 \u05E0\u05E9\u05DE\u05E8\u05D5" }),
|
|
5592
5639
|
/* @__PURE__ */ jsx11(
|
|
5593
5640
|
"button",
|
|
@@ -5602,7 +5649,7 @@ function TableBlockClient({
|
|
|
5602
5649
|
}
|
|
5603
5650
|
)
|
|
5604
5651
|
] }) : null,
|
|
5605
|
-
/* @__PURE__ */ jsx11(
|
|
5652
|
+
!effectiveReadOnly && effectivePermissions.canUpdate && /* @__PURE__ */ jsx11(
|
|
5606
5653
|
"button",
|
|
5607
5654
|
{
|
|
5608
5655
|
onClick: handleSave,
|
|
@@ -5640,9 +5687,10 @@ function TableBlockClient({
|
|
|
5640
5687
|
filteredColumns.map((col) => {
|
|
5641
5688
|
var _a, _b;
|
|
5642
5689
|
const isSearching = activeSearchCol === col.name;
|
|
5643
|
-
const
|
|
5644
|
-
const
|
|
5645
|
-
const
|
|
5690
|
+
const canReorderColumns = !effectiveReadOnly && effectivePermissions.canUpdate && !isSearching;
|
|
5691
|
+
const dragProps = canReorderColumns ? getHeaderDragProps(col.name) : {};
|
|
5692
|
+
const isDragging = canReorderColumns && draggedColName === col.name;
|
|
5693
|
+
const isDragOver = canReorderColumns && dragOverColName === col.name;
|
|
5646
5694
|
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
5647
5695
|
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
5648
5696
|
const isRelation = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION";
|
|
@@ -5662,7 +5710,7 @@ function TableBlockClient({
|
|
|
5662
5710
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
5663
5711
|
title: isSearching ? void 0 : col.name
|
|
5664
5712
|
}, dragProps), {
|
|
5665
|
-
className: `group relative border-b border-l border-slate-200 px-2 py-1 font-semibold text-slate-700 select-none transition-colors h-12 min-h-[48px] align-middle bg-white ${isSearching ? "cursor-default bg-blue-50/40" : "cursor-grab active:cursor-grabbing hover:bg-slate-100"} ${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" : ""}`,
|
|
5713
|
+
className: `group relative border-b border-l border-slate-200 px-2 py-1 font-semibold text-slate-700 select-none transition-colors h-12 min-h-[48px] align-middle bg-white ${isSearching ? "cursor-default bg-blue-50/40" : canReorderColumns ? "cursor-grab active:cursor-grabbing hover:bg-slate-100" : "cursor-default"} ${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" : ""}`,
|
|
5666
5714
|
children: [
|
|
5667
5715
|
/* @__PURE__ */ jsx11(
|
|
5668
5716
|
"div",
|
|
@@ -5743,9 +5791,7 @@ function TableBlockClient({
|
|
|
5743
5791
|
setRelationTriggerRect(btn.getBoundingClientRect());
|
|
5744
5792
|
}
|
|
5745
5793
|
setActiveRelationCol(col.name);
|
|
5746
|
-
|
|
5747
|
-
refetchRelation(col.name, { take: 1e3 });
|
|
5748
|
-
}
|
|
5794
|
+
fetchRelationFilterOptions(col.name);
|
|
5749
5795
|
}
|
|
5750
5796
|
} else {
|
|
5751
5797
|
setActiveSearchCol(col.name);
|
|
@@ -5778,106 +5824,39 @@ function TableBlockClient({
|
|
|
5778
5824
|
var _a;
|
|
5779
5825
|
return ((_a = c.type) == null ? void 0 : _a.toUpperCase()) === "SUB_TABLE";
|
|
5780
5826
|
});
|
|
5781
|
-
return /* @__PURE__ */
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
5815
|
-
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
5816
|
-
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
5817
|
-
if (value === void 0 && col.defaultValue !== void 0) {
|
|
5818
|
-
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
5819
|
-
if (colType === "CURRENCY" || colType === "NUMBER") {
|
|
5820
|
-
if (isNaN(value)) value = null;
|
|
5821
|
-
}
|
|
5822
|
-
}
|
|
5823
|
-
if (value === void 0) value = null;
|
|
5824
|
-
return /* @__PURE__ */ jsx11(
|
|
5825
|
-
"td",
|
|
5826
|
-
{
|
|
5827
|
-
className: `border-b border-l border-slate-200 p-0 relative ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
5828
|
-
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
5829
|
-
children: /* @__PURE__ */ jsx11(
|
|
5830
|
-
InputComponent,
|
|
5831
|
-
{
|
|
5832
|
-
value,
|
|
5833
|
-
column: col,
|
|
5834
|
-
rowId: row.id,
|
|
5835
|
-
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
5836
|
-
context: {
|
|
5837
|
-
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",
|
|
5838
|
-
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
5839
|
-
onMarkForDeletion: (fileId) => setPendingDeletions((prev) => [...prev, fileId]),
|
|
5840
|
-
relationOptions,
|
|
5841
|
-
relationDictionaryRef,
|
|
5842
|
-
refetchRelation,
|
|
5843
|
-
executeAction,
|
|
5844
|
-
emitEvent,
|
|
5845
|
-
pageState,
|
|
5846
|
-
componentId,
|
|
5847
|
-
orgId,
|
|
5848
|
-
updateQuietly: handleQuietCellChange,
|
|
5849
|
-
triggerSaveSuccess,
|
|
5850
|
-
rowData: row.data
|
|
5851
|
-
}
|
|
5852
|
-
}
|
|
5853
|
-
)
|
|
5854
|
-
},
|
|
5855
|
-
col.name
|
|
5856
|
-
);
|
|
5857
|
-
}),
|
|
5858
|
-
/* @__PURE__ */ jsx11("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
5859
|
-
] }),
|
|
5860
|
-
isExpanded && /* @__PURE__ */ jsx11(
|
|
5861
|
-
ExpandedSubTables,
|
|
5862
|
-
{
|
|
5863
|
-
rowId: row.id,
|
|
5864
|
-
rowData: row.data,
|
|
5865
|
-
subTableColumns,
|
|
5866
|
-
filteredColumnsLength: filteredColumns.length,
|
|
5867
|
-
handleCellChange,
|
|
5868
|
-
context: {
|
|
5869
|
-
executeAction,
|
|
5870
|
-
orgId,
|
|
5871
|
-
parentTableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
5872
|
-
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
5873
|
-
rowData: row.data,
|
|
5874
|
-
updateQuietly: handleQuietCellChange,
|
|
5875
|
-
triggerSaveSuccess,
|
|
5876
|
-
onUpdateColumnConfig: handleUpdateColumnConfig
|
|
5877
|
-
}
|
|
5878
|
-
}
|
|
5879
|
-
)
|
|
5880
|
-
] }, row.id);
|
|
5827
|
+
return /* @__PURE__ */ jsx11(
|
|
5828
|
+
TableRow,
|
|
5829
|
+
{
|
|
5830
|
+
row,
|
|
5831
|
+
isSelected: selectedIds.has(row.id),
|
|
5832
|
+
isExpanded,
|
|
5833
|
+
filteredColumns,
|
|
5834
|
+
columnWidths,
|
|
5835
|
+
hasSubTableCols,
|
|
5836
|
+
subTableColumns,
|
|
5837
|
+
isLoading: isLoading || isFetching,
|
|
5838
|
+
isUpdatingActive,
|
|
5839
|
+
onToggleSelect: toggleSelectRow,
|
|
5840
|
+
onToggleExpand: handleToggleExpand,
|
|
5841
|
+
handleCellChange,
|
|
5842
|
+
handleQuietCellChange,
|
|
5843
|
+
handleUpdateColumnConfig,
|
|
5844
|
+
onMarkForDeletion: handleMarkForDeletion,
|
|
5845
|
+
triggerSaveSuccess,
|
|
5846
|
+
schema,
|
|
5847
|
+
orgId,
|
|
5848
|
+
componentId,
|
|
5849
|
+
pageState,
|
|
5850
|
+
relationOptions,
|
|
5851
|
+
relationDictionaryRef,
|
|
5852
|
+
refetchRelation,
|
|
5853
|
+
executeAction,
|
|
5854
|
+
emitEvent,
|
|
5855
|
+
readOnly: effectiveReadOnly || !effectivePermissions.canUpdate,
|
|
5856
|
+
permissions: effectivePermissions
|
|
5857
|
+
},
|
|
5858
|
+
row.id
|
|
5859
|
+
);
|
|
5881
5860
|
}) }),
|
|
5882
5861
|
showSummary && filteredData.length > 0 && /* @__PURE__ */ jsx11("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__ */ jsxs11("tr", { children: [
|
|
5883
5862
|
/* @__PURE__ */ jsx11("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' }),
|
|
@@ -5973,7 +5952,8 @@ function TableBlockClient({
|
|
|
5973
5952
|
filterValue: currentSelected,
|
|
5974
5953
|
onSelectionChange: (newSelected) => {
|
|
5975
5954
|
handleApplyColumnFilter(activeRelationCol, newSelected);
|
|
5976
|
-
}
|
|
5955
|
+
},
|
|
5956
|
+
isLoading: loadingFilterCol === activeRelationCol
|
|
5977
5957
|
}
|
|
5978
5958
|
);
|
|
5979
5959
|
})()
|
|
@@ -6024,12 +6004,143 @@ function ExpandedSubTables({
|
|
|
6024
6004
|
column: activeCol,
|
|
6025
6005
|
value: (rowData == null ? void 0 : rowData[activeCol.name]) || [],
|
|
6026
6006
|
onChange: (newVal) => handleCellChange(rowId, activeCol.name, newVal),
|
|
6027
|
-
context
|
|
6007
|
+
context,
|
|
6008
|
+
readOnly: context == null ? void 0 : context.readOnly
|
|
6028
6009
|
},
|
|
6029
6010
|
activeCol.name
|
|
6030
6011
|
) })
|
|
6031
6012
|
] }) });
|
|
6032
6013
|
}
|
|
6014
|
+
var TableRow = React11.memo(function TableRow2({
|
|
6015
|
+
row,
|
|
6016
|
+
isSelected,
|
|
6017
|
+
isExpanded,
|
|
6018
|
+
filteredColumns,
|
|
6019
|
+
columnWidths,
|
|
6020
|
+
hasSubTableCols,
|
|
6021
|
+
subTableColumns,
|
|
6022
|
+
isLoading,
|
|
6023
|
+
isUpdatingActive,
|
|
6024
|
+
onToggleSelect,
|
|
6025
|
+
onToggleExpand,
|
|
6026
|
+
handleCellChange,
|
|
6027
|
+
handleQuietCellChange,
|
|
6028
|
+
handleUpdateColumnConfig,
|
|
6029
|
+
onMarkForDeletion,
|
|
6030
|
+
triggerSaveSuccess,
|
|
6031
|
+
schema,
|
|
6032
|
+
orgId,
|
|
6033
|
+
componentId,
|
|
6034
|
+
pageState,
|
|
6035
|
+
relationOptions,
|
|
6036
|
+
relationDictionaryRef,
|
|
6037
|
+
refetchRelation,
|
|
6038
|
+
executeAction,
|
|
6039
|
+
emitEvent,
|
|
6040
|
+
readOnly,
|
|
6041
|
+
permissions
|
|
6042
|
+
}) {
|
|
6043
|
+
return /* @__PURE__ */ jsxs11(React11.Fragment, { children: [
|
|
6044
|
+
/* @__PURE__ */ jsxs11("tr", { className: `hover:bg-blue-50/30 transition-colors group ${isSelected ? "bg-blue-50/40" : ""}`, children: [
|
|
6045
|
+
/* @__PURE__ */ jsx11("td", { className: "border-b border-l border-slate-200 p-1.5 text-center bg-white group-hover:bg-transparent", style: { width: 72, minWidth: 72, maxWidth: 72 }, children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-center gap-1.5", children: [
|
|
6046
|
+
/* @__PURE__ */ jsx11(
|
|
6047
|
+
"input",
|
|
6048
|
+
{
|
|
6049
|
+
type: "checkbox",
|
|
6050
|
+
checked: isSelected,
|
|
6051
|
+
onChange: (e) => onToggleSelect(row.id, e.target.checked),
|
|
6052
|
+
disabled: isLoading || isUpdatingActive,
|
|
6053
|
+
className: "w-4 h-4 rounded border-slate-300 text-brand"
|
|
6054
|
+
}
|
|
6055
|
+
),
|
|
6056
|
+
hasSubTableCols && /* @__PURE__ */ jsx11(
|
|
6057
|
+
"button",
|
|
6058
|
+
{
|
|
6059
|
+
type: "button",
|
|
6060
|
+
onClick: () => onToggleExpand(row.id),
|
|
6061
|
+
className: "w-5 h-5 rounded-full bg-slate-500 hover:bg-slate-600 text-white flex items-center justify-center transition-colors cursor-pointer shrink-0 shadow-sm",
|
|
6062
|
+
title: isExpanded ? "\u05E1\u05D2\u05D5\u05E8 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4" : "\u05E4\u05EA\u05D7 \u05EA\u05EA-\u05D8\u05D1\u05DC\u05D4",
|
|
6063
|
+
children: /* @__PURE__ */ jsx11("svg", { className: `w-3 h-3 transition-transform duration-150 ${isExpanded ? "rotate-90" : "rotate-180"}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "3", d: "M9 5l7 7-7 7" }) })
|
|
6064
|
+
}
|
|
6065
|
+
)
|
|
6066
|
+
] }) }),
|
|
6067
|
+
filteredColumns.map((col) => {
|
|
6068
|
+
var _a;
|
|
6069
|
+
const colType = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) || "DEFAULT";
|
|
6070
|
+
const InputComponent = FORM_INPUTS[colType] || FORM_INPUTS.DEFAULT;
|
|
6071
|
+
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
6072
|
+
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
6073
|
+
let value = (row == null ? void 0 : row.data) ? row.data[col.name] : void 0;
|
|
6074
|
+
if (value === void 0 && col.defaultValue !== void 0) {
|
|
6075
|
+
value = colType === "CURRENCY" || colType === "NUMBER" ? parseFloat(col.defaultValue) : col.defaultValue;
|
|
6076
|
+
if (colType === "CURRENCY" || colType === "NUMBER") {
|
|
6077
|
+
if (isNaN(value)) value = null;
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6080
|
+
if (value === void 0) value = null;
|
|
6081
|
+
return /* @__PURE__ */ jsx11(
|
|
6082
|
+
"td",
|
|
6083
|
+
{
|
|
6084
|
+
className: `border-b border-l border-slate-200 p-0 relative ${colType === "RELATION" ? "overflow-visible" : "overflow-hidden"}`,
|
|
6085
|
+
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
6086
|
+
children: /* @__PURE__ */ jsx11(
|
|
6087
|
+
InputComponent,
|
|
6088
|
+
{
|
|
6089
|
+
value,
|
|
6090
|
+
column: col,
|
|
6091
|
+
rowId: row.id,
|
|
6092
|
+
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
6093
|
+
readOnly,
|
|
6094
|
+
context: {
|
|
6095
|
+
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",
|
|
6096
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
6097
|
+
onMarkForDeletion,
|
|
6098
|
+
relationOptions,
|
|
6099
|
+
relationDictionaryRef,
|
|
6100
|
+
refetchRelation,
|
|
6101
|
+
executeAction,
|
|
6102
|
+
emitEvent,
|
|
6103
|
+
pageState,
|
|
6104
|
+
componentId,
|
|
6105
|
+
orgId,
|
|
6106
|
+
updateQuietly: handleQuietCellChange,
|
|
6107
|
+
triggerSaveSuccess,
|
|
6108
|
+
rowData: row.data,
|
|
6109
|
+
readOnly,
|
|
6110
|
+
permissions
|
|
6111
|
+
}
|
|
6112
|
+
}
|
|
6113
|
+
)
|
|
6114
|
+
},
|
|
6115
|
+
col.name
|
|
6116
|
+
);
|
|
6117
|
+
}),
|
|
6118
|
+
/* @__PURE__ */ jsx11("td", { className: "border-b border-slate-200 bg-white pointer-events-none" })
|
|
6119
|
+
] }),
|
|
6120
|
+
isExpanded && /* @__PURE__ */ jsx11(
|
|
6121
|
+
ExpandedSubTables,
|
|
6122
|
+
{
|
|
6123
|
+
rowId: row.id,
|
|
6124
|
+
rowData: row.data,
|
|
6125
|
+
subTableColumns,
|
|
6126
|
+
filteredColumnsLength: filteredColumns.length,
|
|
6127
|
+
handleCellChange,
|
|
6128
|
+
context: {
|
|
6129
|
+
executeAction,
|
|
6130
|
+
orgId,
|
|
6131
|
+
parentTableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
6132
|
+
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
6133
|
+
rowData: row.data,
|
|
6134
|
+
updateQuietly: handleQuietCellChange,
|
|
6135
|
+
triggerSaveSuccess,
|
|
6136
|
+
onUpdateColumnConfig: handleUpdateColumnConfig,
|
|
6137
|
+
readOnly,
|
|
6138
|
+
permissions
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
)
|
|
6142
|
+
] });
|
|
6143
|
+
});
|
|
6033
6144
|
|
|
6034
6145
|
// src/components/TableBlock/TableBlock.tsx
|
|
6035
6146
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
@@ -6065,6 +6176,7 @@ export {
|
|
|
6065
6176
|
formatTimeInput,
|
|
6066
6177
|
formatTimeIso,
|
|
6067
6178
|
getDeterministicPastelBadge,
|
|
6179
|
+
getRolePermissions,
|
|
6068
6180
|
isTextRepresentable,
|
|
6069
6181
|
measureTextWidth,
|
|
6070
6182
|
normalizeRelationValue,
|