@universe-platform/ui 0.1.0-beta.12 → 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 +225 -197
- package/dist/index.mjs +224 -197
- 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}`,
|
|
@@ -5413,6 +5421,13 @@ function TableBlockClient({
|
|
|
5413
5421
|
link.click();
|
|
5414
5422
|
document.body.removeChild(link);
|
|
5415
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
|
+
}
|
|
5416
5431
|
} catch (err) {
|
|
5417
5432
|
console.error("[TableBlock] Export to CSV failed:", err);
|
|
5418
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");
|
|
@@ -5435,7 +5450,7 @@ function TableBlockClient({
|
|
|
5435
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: [
|
|
5436
5451
|
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2.5", children: [
|
|
5437
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 }) }),
|
|
5438
|
-
/* @__PURE__ */ jsx11(
|
|
5453
|
+
!effectiveReadOnly && effectivePermissions.canCreate && /* @__PURE__ */ jsx11(
|
|
5439
5454
|
"button",
|
|
5440
5455
|
{
|
|
5441
5456
|
onClick: handleAddRow,
|
|
@@ -5445,7 +5460,7 @@ function TableBlockClient({
|
|
|
5445
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" }) })
|
|
5446
5461
|
}
|
|
5447
5462
|
),
|
|
5448
|
-
/* @__PURE__ */ jsx11(
|
|
5463
|
+
!effectiveReadOnly && effectivePermissions.canCreate && /* @__PURE__ */ jsx11(
|
|
5449
5464
|
"button",
|
|
5450
5465
|
{
|
|
5451
5466
|
onClick: handleDuplicateRow,
|
|
@@ -5455,7 +5470,7 @@ function TableBlockClient({
|
|
|
5455
5470
|
children: /* @__PURE__ */ jsx11(Copy2, { className: "w-4 h-4 text-blue-600 shrink-0" })
|
|
5456
5471
|
}
|
|
5457
5472
|
),
|
|
5458
|
-
/* @__PURE__ */ jsxs11(
|
|
5473
|
+
!effectiveReadOnly && effectivePermissions.canDelete && /* @__PURE__ */ jsxs11(
|
|
5459
5474
|
"button",
|
|
5460
5475
|
{
|
|
5461
5476
|
onClick: handleDeleteSelected,
|
|
@@ -5481,7 +5496,7 @@ function TableBlockClient({
|
|
|
5481
5496
|
]
|
|
5482
5497
|
}
|
|
5483
5498
|
),
|
|
5484
|
-
/* @__PURE__ */ jsxs11("div", { className: "relative", ref: dropdownRef, children: [
|
|
5499
|
+
!effectiveReadOnly && effectivePermissions.canUpdate && /* @__PURE__ */ jsxs11("div", { className: "relative", ref: dropdownRef, children: [
|
|
5485
5500
|
/* @__PURE__ */ jsxs11(
|
|
5486
5501
|
"button",
|
|
5487
5502
|
{
|
|
@@ -5619,7 +5634,7 @@ function TableBlockClient({
|
|
|
5619
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: [
|
|
5620
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" }) }),
|
|
5621
5636
|
"\u05E2\u05D5\u05D3\u05DB\u05DF \u05D1\u05D4\u05E6\u05DC\u05D7\u05D4"
|
|
5622
|
-
] }) : 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: [
|
|
5623
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" }),
|
|
5624
5639
|
/* @__PURE__ */ jsx11(
|
|
5625
5640
|
"button",
|
|
@@ -5634,7 +5649,7 @@ function TableBlockClient({
|
|
|
5634
5649
|
}
|
|
5635
5650
|
)
|
|
5636
5651
|
] }) : null,
|
|
5637
|
-
/* @__PURE__ */ jsx11(
|
|
5652
|
+
!effectiveReadOnly && effectivePermissions.canUpdate && /* @__PURE__ */ jsx11(
|
|
5638
5653
|
"button",
|
|
5639
5654
|
{
|
|
5640
5655
|
onClick: handleSave,
|
|
@@ -5672,9 +5687,10 @@ function TableBlockClient({
|
|
|
5672
5687
|
filteredColumns.map((col) => {
|
|
5673
5688
|
var _a, _b;
|
|
5674
5689
|
const isSearching = activeSearchCol === col.name;
|
|
5675
|
-
const
|
|
5676
|
-
const
|
|
5677
|
-
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;
|
|
5678
5694
|
const colMinWidth = calculateMinColumnWidth(col.name, false, col.type);
|
|
5679
5695
|
const currentWidth = Math.max(colMinWidth, columnWidths[col.name] || 200);
|
|
5680
5696
|
const isRelation = ((_a = col.type) == null ? void 0 : _a.toUpperCase()) === "RELATION";
|
|
@@ -5694,7 +5710,7 @@ function TableBlockClient({
|
|
|
5694
5710
|
style: { width: currentWidth, minWidth: currentWidth, maxWidth: currentWidth },
|
|
5695
5711
|
title: isSearching ? void 0 : col.name
|
|
5696
5712
|
}, dragProps), {
|
|
5697
|
-
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" : ""}`,
|
|
5698
5714
|
children: [
|
|
5699
5715
|
/* @__PURE__ */ jsx11(
|
|
5700
5716
|
"div",
|
|
@@ -5835,7 +5851,9 @@ function TableBlockClient({
|
|
|
5835
5851
|
relationDictionaryRef,
|
|
5836
5852
|
refetchRelation,
|
|
5837
5853
|
executeAction,
|
|
5838
|
-
emitEvent
|
|
5854
|
+
emitEvent,
|
|
5855
|
+
readOnly: effectiveReadOnly || !effectivePermissions.canUpdate,
|
|
5856
|
+
permissions: effectivePermissions
|
|
5839
5857
|
},
|
|
5840
5858
|
row.id
|
|
5841
5859
|
);
|
|
@@ -5986,7 +6004,8 @@ function ExpandedSubTables({
|
|
|
5986
6004
|
column: activeCol,
|
|
5987
6005
|
value: (rowData == null ? void 0 : rowData[activeCol.name]) || [],
|
|
5988
6006
|
onChange: (newVal) => handleCellChange(rowId, activeCol.name, newVal),
|
|
5989
|
-
context
|
|
6007
|
+
context,
|
|
6008
|
+
readOnly: context == null ? void 0 : context.readOnly
|
|
5990
6009
|
},
|
|
5991
6010
|
activeCol.name
|
|
5992
6011
|
) })
|
|
@@ -6017,7 +6036,9 @@ var TableRow = React11.memo(function TableRow2({
|
|
|
6017
6036
|
relationDictionaryRef,
|
|
6018
6037
|
refetchRelation,
|
|
6019
6038
|
executeAction,
|
|
6020
|
-
emitEvent
|
|
6039
|
+
emitEvent,
|
|
6040
|
+
readOnly,
|
|
6041
|
+
permissions
|
|
6021
6042
|
}) {
|
|
6022
6043
|
return /* @__PURE__ */ jsxs11(React11.Fragment, { children: [
|
|
6023
6044
|
/* @__PURE__ */ jsxs11("tr", { className: `hover:bg-blue-50/30 transition-colors group ${isSelected ? "bg-blue-50/40" : ""}`, children: [
|
|
@@ -6069,6 +6090,7 @@ var TableRow = React11.memo(function TableRow2({
|
|
|
6069
6090
|
column: col,
|
|
6070
6091
|
rowId: row.id,
|
|
6071
6092
|
onChange: (v) => handleCellChange(row.id, col.name, v),
|
|
6093
|
+
readOnly,
|
|
6072
6094
|
context: {
|
|
6073
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",
|
|
6074
6096
|
tableId: (schema == null ? void 0 : schema.tableMetaId) || (schema == null ? void 0 : schema.tableId) || (schema == null ? void 0 : schema.id),
|
|
@@ -6083,7 +6105,9 @@ var TableRow = React11.memo(function TableRow2({
|
|
|
6083
6105
|
orgId,
|
|
6084
6106
|
updateQuietly: handleQuietCellChange,
|
|
6085
6107
|
triggerSaveSuccess,
|
|
6086
|
-
rowData: row.data
|
|
6108
|
+
rowData: row.data,
|
|
6109
|
+
readOnly,
|
|
6110
|
+
permissions
|
|
6087
6111
|
}
|
|
6088
6112
|
}
|
|
6089
6113
|
)
|
|
@@ -6109,7 +6133,9 @@ var TableRow = React11.memo(function TableRow2({
|
|
|
6109
6133
|
rowData: row.data,
|
|
6110
6134
|
updateQuietly: handleQuietCellChange,
|
|
6111
6135
|
triggerSaveSuccess,
|
|
6112
|
-
onUpdateColumnConfig: handleUpdateColumnConfig
|
|
6136
|
+
onUpdateColumnConfig: handleUpdateColumnConfig,
|
|
6137
|
+
readOnly,
|
|
6138
|
+
permissions
|
|
6113
6139
|
}
|
|
6114
6140
|
}
|
|
6115
6141
|
)
|
|
@@ -6150,6 +6176,7 @@ export {
|
|
|
6150
6176
|
formatTimeInput,
|
|
6151
6177
|
formatTimeIso,
|
|
6152
6178
|
getDeterministicPastelBadge,
|
|
6179
|
+
getRolePermissions,
|
|
6153
6180
|
isTextRepresentable,
|
|
6154
6181
|
measureTextWidth,
|
|
6155
6182
|
normalizeRelationValue,
|