@fctc/widget-logic 5.3.7-beta.14 → 5.3.7-beta.16
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/package.json +1 -1
- package/dist/config.d.mts +0 -5
- package/dist/config.d.ts +0 -5
- package/dist/config.js +0 -24
- package/dist/config.mjs +0 -2
- package/dist/constants.d.mts +0 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -24
- package/dist/constants.mjs +0 -2
- package/dist/environment.d.mts +0 -1
- package/dist/environment.d.ts +0 -1
- package/dist/environment.js +0 -24
- package/dist/environment.mjs +0 -2
- package/dist/hooks.d.mts +0 -1179
- package/dist/hooks.d.ts +0 -1179
- package/dist/hooks.js +0 -1273
- package/dist/hooks.mjs +0 -1247
- package/dist/index.d.mts +0 -15
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -3009
- package/dist/index.mjs +0 -3089
- package/dist/provider.d.mts +0 -1
- package/dist/provider.d.ts +0 -1
- package/dist/provider.js +0 -24
- package/dist/provider.mjs +0 -2
- package/dist/services.d.mts +0 -1
- package/dist/services.d.ts +0 -1
- package/dist/services.js +0 -24
- package/dist/services.mjs +0 -2
- package/dist/types.d.mts +0 -36
- package/dist/types.d.ts +0 -36
- package/dist/types.js +0 -24
- package/dist/types.mjs +0 -2
- package/dist/utils.d.mts +0 -23
- package/dist/utils.d.ts +0 -23
- package/dist/utils.js +0 -436
- package/dist/utils.mjs +0 -389
- package/dist/widget.d.mts +0 -328
- package/dist/widget.d.ts +0 -328
- package/dist/widget.js +0 -2379
- package/dist/widget.mjs +0 -2432
package/dist/widget.mjs
DELETED
|
@@ -1,2432 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
18
|
-
|
|
19
|
-
// src/widget/basic/status-dropdown-field/controller.ts
|
|
20
|
-
import { useEffect, useRef, useState } from "react";
|
|
21
|
-
import { getEnv } from "@fctc/interface-logic/environment";
|
|
22
|
-
import { useSave } from "@fctc/interface-logic/hooks";
|
|
23
|
-
var statusDropdownController = (props) => {
|
|
24
|
-
const { selection, isForm, id, model, name, state, onRefetch } = props;
|
|
25
|
-
const env = getEnv();
|
|
26
|
-
const colors = {
|
|
27
|
-
normal: "bg-[#e9ecef]",
|
|
28
|
-
done: "bg-primary",
|
|
29
|
-
blocked: "bg-red-500"
|
|
30
|
-
};
|
|
31
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
32
|
-
const buttonRef = useRef(null);
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
const handleClickOutside = (event) => {
|
|
35
|
-
if (buttonRef.current && !buttonRef.current.contains(event.target)) {
|
|
36
|
-
setIsOpen(false);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
40
|
-
return () => {
|
|
41
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
42
|
-
};
|
|
43
|
-
}, []);
|
|
44
|
-
const { mutate: onSave } = useSave();
|
|
45
|
-
const handleClick = async (status) => {
|
|
46
|
-
setIsOpen(!isOpen);
|
|
47
|
-
onSave(
|
|
48
|
-
{
|
|
49
|
-
ids: id ? [id] : [],
|
|
50
|
-
model: model ?? "",
|
|
51
|
-
data: { [name ?? ""]: status },
|
|
52
|
-
context: env.context
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
onSuccess: () => {
|
|
56
|
-
onRefetch && onRefetch();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
return {
|
|
62
|
-
handleClick,
|
|
63
|
-
buttonRef,
|
|
64
|
-
isForm,
|
|
65
|
-
setIsOpen,
|
|
66
|
-
isOpen,
|
|
67
|
-
selection,
|
|
68
|
-
state,
|
|
69
|
-
colors
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// src/widget/basic/many2one-field/controller.ts
|
|
74
|
-
import { useCallback as useCallback4, useEffect as useEffect9, useMemo as useMemo7, useState as useState7 } from "react";
|
|
75
|
-
|
|
76
|
-
// src/hooks.ts
|
|
77
|
-
import {
|
|
78
|
-
useModel,
|
|
79
|
-
useButton,
|
|
80
|
-
useChangeStatus,
|
|
81
|
-
useDelete,
|
|
82
|
-
useDeleteComment,
|
|
83
|
-
useDuplicateRecord,
|
|
84
|
-
useExecuteImport,
|
|
85
|
-
useExportExcel,
|
|
86
|
-
useForgotPassword,
|
|
87
|
-
useForgotPasswordSSO,
|
|
88
|
-
useGet2FAMethods,
|
|
89
|
-
useGetAccessByCode,
|
|
90
|
-
useGetActionDetail,
|
|
91
|
-
useGetAll,
|
|
92
|
-
useGetCalendar,
|
|
93
|
-
useGetComment,
|
|
94
|
-
useGetCompanyInfo,
|
|
95
|
-
useGetConversionRate,
|
|
96
|
-
useGetCurrency,
|
|
97
|
-
useGetCurrentCompany,
|
|
98
|
-
useGetDetail,
|
|
99
|
-
useGetFieldExport,
|
|
100
|
-
useGetFieldOnChange,
|
|
101
|
-
useGetFileExcel,
|
|
102
|
-
useGetFormView,
|
|
103
|
-
useGetGroups,
|
|
104
|
-
useGetListCompany,
|
|
105
|
-
useGetListData,
|
|
106
|
-
useGetListMyBankAccount,
|
|
107
|
-
useGetMenu,
|
|
108
|
-
useGetPrintReport,
|
|
109
|
-
useGetProGressBar,
|
|
110
|
-
useGetProfile,
|
|
111
|
-
useGetProvider,
|
|
112
|
-
useGetResequence,
|
|
113
|
-
useGetSelection,
|
|
114
|
-
useGetUser,
|
|
115
|
-
useGetView,
|
|
116
|
-
useGrantAccess,
|
|
117
|
-
useIsValidToken,
|
|
118
|
-
useLoadAction,
|
|
119
|
-
useLoadMessage,
|
|
120
|
-
useLoginCredential,
|
|
121
|
-
useLoginSocial,
|
|
122
|
-
useLogout,
|
|
123
|
-
useOdooDataTransform,
|
|
124
|
-
useOnChangeForm,
|
|
125
|
-
useParsePreview,
|
|
126
|
-
usePrint,
|
|
127
|
-
useRemoveRow,
|
|
128
|
-
useRemoveTotpSetup,
|
|
129
|
-
useRequestSetupTotp,
|
|
130
|
-
useResetPassword,
|
|
131
|
-
useResetPasswordSSO,
|
|
132
|
-
useRunAction,
|
|
133
|
-
useSave as useSave2,
|
|
134
|
-
useSendComment,
|
|
135
|
-
useSettingsWebRead2fa,
|
|
136
|
-
useSignInSSO,
|
|
137
|
-
useSwitchLocale,
|
|
138
|
-
useUpdatePassword,
|
|
139
|
-
useUploadFile,
|
|
140
|
-
useUploadFileExcel,
|
|
141
|
-
useUploadIdFile,
|
|
142
|
-
useUploadImage,
|
|
143
|
-
useValidateActionToken,
|
|
144
|
-
useVerify2FA,
|
|
145
|
-
useVerifyTotp,
|
|
146
|
-
useAddEntity,
|
|
147
|
-
useChangeOrderPreparationState,
|
|
148
|
-
useCheckPayment,
|
|
149
|
-
useCreateEntity,
|
|
150
|
-
useCreatePosConfig,
|
|
151
|
-
useCreateSession,
|
|
152
|
-
useDeleteEntity,
|
|
153
|
-
useGenSerialNumber,
|
|
154
|
-
useGeneratePaymentQrInfo,
|
|
155
|
-
useGetASession,
|
|
156
|
-
useGetExternalTabs,
|
|
157
|
-
useGetList,
|
|
158
|
-
useGetOrderLine,
|
|
159
|
-
useReadGroup,
|
|
160
|
-
useGetPinCode
|
|
161
|
-
} from "@fctc/interface-logic/hooks";
|
|
162
|
-
|
|
163
|
-
// src/hooks/core/use-app-provider.tsx
|
|
164
|
-
import { createContext, useContext, useMemo as useMemo4 } from "react";
|
|
165
|
-
|
|
166
|
-
// src/hooks/core/use-menu.ts
|
|
167
|
-
import { useState as useState3 } from "react";
|
|
168
|
-
|
|
169
|
-
// src/hooks/core/use-call-action.ts
|
|
170
|
-
import { useCallback, useState as useState2 } from "react";
|
|
171
|
-
|
|
172
|
-
// src/provider.ts
|
|
173
|
-
var provider_exports = {};
|
|
174
|
-
__reExport(provider_exports, provider_star);
|
|
175
|
-
import * as provider_star from "@fctc/interface-logic/provider";
|
|
176
|
-
|
|
177
|
-
// src/utils.ts
|
|
178
|
-
var utils_exports = {};
|
|
179
|
-
__export(utils_exports, {
|
|
180
|
-
STORAGES: () => STORAGES,
|
|
181
|
-
countSum: () => countSum,
|
|
182
|
-
guessTypeFromUrl: () => guessTypeFromUrl,
|
|
183
|
-
isObjectEmpty: () => isObjectEmpty,
|
|
184
|
-
languages: () => languages,
|
|
185
|
-
mergeButtons: () => mergeButtons,
|
|
186
|
-
setStorageItemAsync: () => setStorageItemAsync,
|
|
187
|
-
useStorageState: () => useStorageState,
|
|
188
|
-
validateAndParseDate: () => validateAndParseDate
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
// src/utils/constants.ts
|
|
192
|
-
var languages = [
|
|
193
|
-
{ id: "vi_VN", name: "VIE" },
|
|
194
|
-
{ id: "en_US", name: "ENG" }
|
|
195
|
-
];
|
|
196
|
-
var isBlobUrl = (url) => url.startsWith("blob:");
|
|
197
|
-
|
|
198
|
-
// src/utils/function.ts
|
|
199
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useReducer } from "react";
|
|
200
|
-
var countSum = (data, field) => {
|
|
201
|
-
if (!data || !field) return 0;
|
|
202
|
-
return data.reduce(
|
|
203
|
-
(total, item) => total + (item?.[`${field}_count`] || 0),
|
|
204
|
-
0
|
|
205
|
-
);
|
|
206
|
-
};
|
|
207
|
-
var isObjectEmpty = (obj) => {
|
|
208
|
-
return Object.keys(obj).length === 0;
|
|
209
|
-
};
|
|
210
|
-
function mergeButtons(fields) {
|
|
211
|
-
const buttons = fields?.filter((f) => f.type_co === "button");
|
|
212
|
-
const others = fields?.filter((f) => f.type_co !== "button");
|
|
213
|
-
if (buttons?.length) {
|
|
214
|
-
others.push({
|
|
215
|
-
type_co: "buttons",
|
|
216
|
-
buttons
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
return others;
|
|
220
|
-
}
|
|
221
|
-
var STORAGES = {
|
|
222
|
-
TOKEN: "accessToken",
|
|
223
|
-
USER_INFO: "USER_INFO"
|
|
224
|
-
};
|
|
225
|
-
function useAsyncState(initialValue = [true, null]) {
|
|
226
|
-
return useReducer(
|
|
227
|
-
(_state, action = null) => [false, action],
|
|
228
|
-
initialValue
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
async function setStorageItemAsync(key, value) {
|
|
232
|
-
try {
|
|
233
|
-
if (value === null) {
|
|
234
|
-
localStorage.removeItem(key);
|
|
235
|
-
} else {
|
|
236
|
-
localStorage.setItem(key, value);
|
|
237
|
-
}
|
|
238
|
-
} catch (e) {
|
|
239
|
-
console.error("Local storage is unavailable:", e);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
function useStorageState(key) {
|
|
243
|
-
const [state, setState] = useAsyncState();
|
|
244
|
-
useEffect2(() => {
|
|
245
|
-
try {
|
|
246
|
-
const storedValue = localStorage.getItem(key);
|
|
247
|
-
setState(storedValue);
|
|
248
|
-
} catch (e) {
|
|
249
|
-
console.error("Local storage is unavailable:", e);
|
|
250
|
-
}
|
|
251
|
-
}, [key]);
|
|
252
|
-
const setValue = useCallback2(
|
|
253
|
-
(value) => {
|
|
254
|
-
setState(value);
|
|
255
|
-
setStorageItemAsync(key, value);
|
|
256
|
-
},
|
|
257
|
-
[key]
|
|
258
|
-
);
|
|
259
|
-
return [state, setValue];
|
|
260
|
-
}
|
|
261
|
-
var guessTypeFromUrl = (url) => {
|
|
262
|
-
const ext = url.split(".").pop()?.toLowerCase();
|
|
263
|
-
if (!ext) return null;
|
|
264
|
-
const map = {
|
|
265
|
-
jpg: "image/jpeg",
|
|
266
|
-
jpeg: "image/jpeg",
|
|
267
|
-
png: "image/png",
|
|
268
|
-
webp: "image/webp",
|
|
269
|
-
gif: "image/gif",
|
|
270
|
-
svg: "image/svg+xml",
|
|
271
|
-
bmp: "image/bmp",
|
|
272
|
-
tiff: "image/tiff",
|
|
273
|
-
pdf: "application/pdf",
|
|
274
|
-
zip: "application/zip",
|
|
275
|
-
rar: "application/x-rar-compressed",
|
|
276
|
-
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
277
|
-
xls: "application/vnd.ms-excel",
|
|
278
|
-
mp4: "video/mp4",
|
|
279
|
-
mov: "video/quicktime"
|
|
280
|
-
};
|
|
281
|
-
return map[ext] || null;
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// src/utils/format-date.ts
|
|
285
|
-
import moment from "moment";
|
|
286
|
-
var validateAndParseDate = (input, isDateTime = false) => {
|
|
287
|
-
if (!input || typeof input !== "string") return null;
|
|
288
|
-
const cleanInput = input.replace(/[^0-9-\/:\s]/g, "");
|
|
289
|
-
const dateFormat = "YYYY-MM-DD";
|
|
290
|
-
const dateTimeFormat = "YYYY-MM-DD HH:mm:ss";
|
|
291
|
-
const currentDay = moment().format("DD");
|
|
292
|
-
const currentMonth = moment().format("MM");
|
|
293
|
-
const currentYear = moment().format("YYYY");
|
|
294
|
-
const defaultTime = "00:00:00";
|
|
295
|
-
const maxYear = parseInt(currentYear) + 10;
|
|
296
|
-
const isValidDate = (day, month, year) => {
|
|
297
|
-
const date = moment(`${day}-${month}-${year}`, "DD-MM-YYYY", true);
|
|
298
|
-
return date.isValid();
|
|
299
|
-
};
|
|
300
|
-
const isValidTime = (hour, minute = "00", second = "00") => {
|
|
301
|
-
const h = parseInt(hour, 10);
|
|
302
|
-
const m = parseInt(minute, 10);
|
|
303
|
-
const s = parseInt(second, 10);
|
|
304
|
-
return h >= 0 && h <= 23 && m >= 0 && m <= 59 && s >= 0 && s <= 59;
|
|
305
|
-
};
|
|
306
|
-
const formatOutput = (day, month, year, time = defaultTime) => {
|
|
307
|
-
let result = moment(
|
|
308
|
-
`${day}-${month}-${year} ${time}`,
|
|
309
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
310
|
-
);
|
|
311
|
-
if (!result.isValid()) return null;
|
|
312
|
-
if (isDateTime) {
|
|
313
|
-
result = result.subtract(7, "hours");
|
|
314
|
-
return result.format(dateTimeFormat);
|
|
315
|
-
}
|
|
316
|
-
return result.format(dateFormat);
|
|
317
|
-
};
|
|
318
|
-
if (isDateTime && input.match(
|
|
319
|
-
/^\d{1,2}[\/-]\d{1,2}[\/-]\d{2,4}\s+\d{1,2}(:\d{1,2}(:\d{1,2})?)?$/
|
|
320
|
-
)) {
|
|
321
|
-
const [datePart, timePart] = input.split(/\s+/);
|
|
322
|
-
const dateParts = datePart.split(/[\/-]/);
|
|
323
|
-
const timeParts = timePart.split(":");
|
|
324
|
-
const day = dateParts[0].padStart(2, "0");
|
|
325
|
-
const month = dateParts[1].padStart(2, "0");
|
|
326
|
-
const year = dateParts[2].length <= 2 ? `20${dateParts[2].padStart(2, "0")}` : dateParts[2].padStart(4, "0");
|
|
327
|
-
const hour = timeParts[0].padStart(2, "0");
|
|
328
|
-
const minute = timeParts[1] ? timeParts[1].padStart(2, "0") : "00";
|
|
329
|
-
const second = timeParts[2] ? timeParts[2].padStart(2, "0") : "00";
|
|
330
|
-
if (isValidDate(day, month, year) && isValidTime(hour, minute, second)) {
|
|
331
|
-
let result = moment(
|
|
332
|
-
`${day}-${month}-${year} ${hour}:${minute}:${second}`,
|
|
333
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
334
|
-
);
|
|
335
|
-
if (!result.isValid()) return null;
|
|
336
|
-
result = result.subtract(7, "hours");
|
|
337
|
-
return result.format(dateTimeFormat);
|
|
338
|
-
}
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
if (cleanInput.match(/^\d{4}-\d{2}-\d{2}$/)) {
|
|
342
|
-
const [year, month, day] = cleanInput.split("-");
|
|
343
|
-
if (isValidDate(day, month, year)) {
|
|
344
|
-
return formatOutput(day, month, year);
|
|
345
|
-
}
|
|
346
|
-
return null;
|
|
347
|
-
}
|
|
348
|
-
if (cleanInput.match(/^\d{1,2}\/\d{1,2}\/\d{2,4}$/)) {
|
|
349
|
-
const [day, month, year] = cleanInput.split("/");
|
|
350
|
-
const paddedDay = day.padStart(2, "0");
|
|
351
|
-
const paddedMonth = month.padStart(2, "0");
|
|
352
|
-
const fullYear = year.length <= 2 ? `20${year.padStart(2, "0")}` : year.padStart(4, "0");
|
|
353
|
-
if (isValidDate(paddedDay, paddedMonth, fullYear)) {
|
|
354
|
-
return formatOutput(paddedDay, paddedMonth, fullYear);
|
|
355
|
-
}
|
|
356
|
-
return null;
|
|
357
|
-
}
|
|
358
|
-
if (cleanInput.match(/^\d{1,2}-\d{1,2}-\d{2,4}$/)) {
|
|
359
|
-
const [day, month, year] = cleanInput.split("-");
|
|
360
|
-
const paddedDay = day.padStart(2, "0");
|
|
361
|
-
const paddedMonth = month.padStart(2, "0");
|
|
362
|
-
const fullYear = year.length <= 2 ? `20${year.padStart(2, "0")}` : year.padStart(4, "0");
|
|
363
|
-
if (isValidDate(paddedDay, paddedMonth, fullYear)) {
|
|
364
|
-
return formatOutput(paddedDay, paddedMonth, fullYear);
|
|
365
|
-
}
|
|
366
|
-
return null;
|
|
367
|
-
}
|
|
368
|
-
if (cleanInput.match(/^\d{1,2}[\/-]\d{1,2}$/)) {
|
|
369
|
-
const [day, month] = cleanInput.split(/[\/-]/);
|
|
370
|
-
const paddedDay = day.padStart(2, "0");
|
|
371
|
-
const paddedMonth = month.padStart(2, "0");
|
|
372
|
-
if (isValidDate(paddedDay, paddedMonth, currentYear)) {
|
|
373
|
-
return formatOutput(paddedDay, paddedMonth, currentYear);
|
|
374
|
-
}
|
|
375
|
-
return null;
|
|
376
|
-
}
|
|
377
|
-
if (cleanInput.match(/^\d{4}$/)) {
|
|
378
|
-
const num = parseInt(cleanInput, 10);
|
|
379
|
-
if (num >= 2e3 && num <= maxYear) {
|
|
380
|
-
if (isValidDate(currentDay, currentMonth, num.toString())) {
|
|
381
|
-
return formatOutput(currentDay, currentMonth, num.toString());
|
|
382
|
-
}
|
|
383
|
-
return null;
|
|
384
|
-
}
|
|
385
|
-
const day = cleanInput.slice(0, 2);
|
|
386
|
-
const month = cleanInput.slice(2, 4);
|
|
387
|
-
if (isValidDate(day, month, currentYear)) {
|
|
388
|
-
return formatOutput(day, month, currentYear);
|
|
389
|
-
}
|
|
390
|
-
return null;
|
|
391
|
-
}
|
|
392
|
-
if (cleanInput.startsWith("-") && /^\-\d+$/.test(cleanInput)) {
|
|
393
|
-
const daysToSubtract = Math.abs(parseInt(cleanInput, 10));
|
|
394
|
-
let result = moment().subtract(daysToSubtract, "days");
|
|
395
|
-
if (isDateTime) {
|
|
396
|
-
result = result.subtract(7, "hours");
|
|
397
|
-
}
|
|
398
|
-
if (result.isValid()) {
|
|
399
|
-
return isDateTime ? result.format(dateTimeFormat) : result.format(dateFormat);
|
|
400
|
-
}
|
|
401
|
-
return null;
|
|
402
|
-
}
|
|
403
|
-
if (input.match(/^\d{1,2}[^0-9-\/]+\d{1,2}[^0-9-\/]+\d{2,4}.*$/)) {
|
|
404
|
-
const parts = input.split(/[^0-9-\/]+/).filter(Boolean);
|
|
405
|
-
const day = parts[0].padStart(2, "0");
|
|
406
|
-
const month = parts[1].padStart(2, "0");
|
|
407
|
-
let year = parts[2];
|
|
408
|
-
year = year.length === 2 ? `20${year}` : year.padStart(4, "0");
|
|
409
|
-
if (isValidDate(day, month, year)) {
|
|
410
|
-
return formatOutput(day, month, year);
|
|
411
|
-
}
|
|
412
|
-
return null;
|
|
413
|
-
}
|
|
414
|
-
if (isDateTime) {
|
|
415
|
-
if (cleanInput.length === 9) {
|
|
416
|
-
const day = cleanInput.slice(0, 2);
|
|
417
|
-
const month = cleanInput.slice(2, 4);
|
|
418
|
-
const year = cleanInput.slice(4, 8);
|
|
419
|
-
const hour = cleanInput.slice(8, 9).padStart(2, "0");
|
|
420
|
-
if (isValidDate(day, month, year) && isValidTime(hour)) {
|
|
421
|
-
let result = moment(
|
|
422
|
-
`${day}-${month}-${year} ${hour}:00:00`,
|
|
423
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
424
|
-
);
|
|
425
|
-
if (!result.isValid()) return null;
|
|
426
|
-
result = result.subtract(7, "hours");
|
|
427
|
-
return result.format(dateTimeFormat);
|
|
428
|
-
}
|
|
429
|
-
return null;
|
|
430
|
-
}
|
|
431
|
-
if (cleanInput.length === 10) {
|
|
432
|
-
const day = cleanInput.slice(0, 2);
|
|
433
|
-
const month = cleanInput.slice(2, 4);
|
|
434
|
-
const year = cleanInput.slice(4, 8);
|
|
435
|
-
const hour = cleanInput.slice(8, 10);
|
|
436
|
-
if (isValidDate(day, month, year) && isValidTime(hour)) {
|
|
437
|
-
let result = moment(
|
|
438
|
-
`${day}-${month}-${year} ${hour}:00:00`,
|
|
439
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
440
|
-
);
|
|
441
|
-
if (!result.isValid()) return null;
|
|
442
|
-
result = result.subtract(7, "hours");
|
|
443
|
-
return result.format(dateTimeFormat);
|
|
444
|
-
}
|
|
445
|
-
return null;
|
|
446
|
-
}
|
|
447
|
-
if (cleanInput.length === 11) {
|
|
448
|
-
const day = cleanInput.slice(0, 2);
|
|
449
|
-
const month = cleanInput.slice(2, 4);
|
|
450
|
-
const year = cleanInput.slice(4, 8);
|
|
451
|
-
const hour = cleanInput.slice(8, 10);
|
|
452
|
-
const minute = cleanInput.slice(10, 11).padStart(2, "0");
|
|
453
|
-
if (isValidDate(day, month, year) && isValidTime(hour, minute)) {
|
|
454
|
-
let result = moment(
|
|
455
|
-
`${day}-${month}-${year} ${hour}:${minute}:00`,
|
|
456
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
457
|
-
);
|
|
458
|
-
if (!result.isValid()) return null;
|
|
459
|
-
result = result.subtract(7, "hours");
|
|
460
|
-
return result.format(dateTimeFormat);
|
|
461
|
-
}
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
if (cleanInput.length === 12) {
|
|
465
|
-
const day = cleanInput.slice(0, 2);
|
|
466
|
-
const month = cleanInput.slice(2, 4);
|
|
467
|
-
const year = cleanInput.slice(4, 8);
|
|
468
|
-
const hour = cleanInput.slice(8, 10);
|
|
469
|
-
const minute = cleanInput.slice(10, 12);
|
|
470
|
-
if (isValidDate(day, month, year) && isValidTime(hour, minute)) {
|
|
471
|
-
let result = moment(
|
|
472
|
-
`${day}-${month}-${year} ${hour}:${minute}:00`,
|
|
473
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
474
|
-
);
|
|
475
|
-
if (!result.isValid()) return null;
|
|
476
|
-
result = result.subtract(7, "hours");
|
|
477
|
-
return result.format(dateTimeFormat);
|
|
478
|
-
}
|
|
479
|
-
return null;
|
|
480
|
-
}
|
|
481
|
-
if (cleanInput.length === 13) {
|
|
482
|
-
const day = cleanInput.slice(0, 2);
|
|
483
|
-
const month = cleanInput.slice(2, 4);
|
|
484
|
-
const year = cleanInput.slice(4, 8);
|
|
485
|
-
const hour = cleanInput.slice(8, 10);
|
|
486
|
-
const minute = cleanInput.slice(10, 12);
|
|
487
|
-
const second = cleanInput.slice(12, 13).padStart(2, "0");
|
|
488
|
-
if (isValidDate(day, month, year) && isValidTime(hour, minute, second)) {
|
|
489
|
-
let result = moment(
|
|
490
|
-
`${day}-${month}-${year} ${hour}:${minute}:${second}`,
|
|
491
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
492
|
-
);
|
|
493
|
-
if (!result.isValid()) return null;
|
|
494
|
-
result = result.subtract(7, "hours");
|
|
495
|
-
return result.format(dateTimeFormat);
|
|
496
|
-
}
|
|
497
|
-
return null;
|
|
498
|
-
}
|
|
499
|
-
if (cleanInput.length === 14) {
|
|
500
|
-
const day = cleanInput.slice(0, 2);
|
|
501
|
-
const month = cleanInput.slice(2, 4);
|
|
502
|
-
const year = cleanInput.slice(4, 8);
|
|
503
|
-
const hour = cleanInput.slice(8, 10);
|
|
504
|
-
const minute = cleanInput.slice(10, 12);
|
|
505
|
-
const second = cleanInput.slice(12, 14);
|
|
506
|
-
if (isValidDate(day, month, year) && isValidTime(hour, minute, second)) {
|
|
507
|
-
let result = moment(
|
|
508
|
-
`${day}-${month}-${year} ${hour}:${minute}:${second}`,
|
|
509
|
-
"DD-MM-YYYY HH:mm:ss"
|
|
510
|
-
);
|
|
511
|
-
if (!result.isValid()) return null;
|
|
512
|
-
result = result.subtract(7, "hours");
|
|
513
|
-
return result.format(dateTimeFormat);
|
|
514
|
-
}
|
|
515
|
-
return null;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
const len = cleanInput.length;
|
|
519
|
-
if (len === 1 || len === 2) {
|
|
520
|
-
const paddedDay = cleanInput.padStart(2, "0");
|
|
521
|
-
if (isValidDate(paddedDay, currentMonth, currentYear)) {
|
|
522
|
-
return formatOutput(paddedDay, currentMonth, currentYear);
|
|
523
|
-
}
|
|
524
|
-
return null;
|
|
525
|
-
}
|
|
526
|
-
if (len === 3) {
|
|
527
|
-
const day = cleanInput.slice(0, 2);
|
|
528
|
-
const month = cleanInput.slice(2, 3).padStart(2, "0");
|
|
529
|
-
if (isValidDate(day, month, currentYear)) {
|
|
530
|
-
return formatOutput(day, month, currentYear);
|
|
531
|
-
}
|
|
532
|
-
return null;
|
|
533
|
-
}
|
|
534
|
-
if (len === 6) {
|
|
535
|
-
const day = cleanInput.slice(0, 2);
|
|
536
|
-
const month = cleanInput.slice(2, 4);
|
|
537
|
-
let year = cleanInput.slice(4, 6);
|
|
538
|
-
year = `20${year}`;
|
|
539
|
-
if (parseInt(month) > 12) {
|
|
540
|
-
if (isValidDate(day, currentMonth, currentYear)) {
|
|
541
|
-
return formatOutput(day, currentMonth, currentYear);
|
|
542
|
-
}
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
if (isValidDate(day, month, year)) {
|
|
546
|
-
return formatOutput(day, month, year);
|
|
547
|
-
}
|
|
548
|
-
return null;
|
|
549
|
-
}
|
|
550
|
-
if (len === 7) {
|
|
551
|
-
return null;
|
|
552
|
-
}
|
|
553
|
-
if (len === 8) {
|
|
554
|
-
const day = cleanInput.slice(0, 2);
|
|
555
|
-
const month = cleanInput.slice(2, 4);
|
|
556
|
-
const year = cleanInput.slice(4, 8);
|
|
557
|
-
if (isValidDate(day, month, year)) {
|
|
558
|
-
return formatOutput(day, month, year);
|
|
559
|
-
}
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
if (len > 8 && !isDateTime) {
|
|
563
|
-
return null;
|
|
564
|
-
}
|
|
565
|
-
return null;
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
// src/utils.ts
|
|
569
|
-
__reExport(utils_exports, utils_star);
|
|
570
|
-
import * as utils_star from "@fctc/interface-logic/utils";
|
|
571
|
-
|
|
572
|
-
// src/hooks/core/use-detail.ts
|
|
573
|
-
import { useQuery } from "@tanstack/react-query";
|
|
574
|
-
import { useEffect as useEffect3 } from "react";
|
|
575
|
-
|
|
576
|
-
// src/hooks/core/use-profile.ts
|
|
577
|
-
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
578
|
-
import { useEffect as useEffect4, useMemo } from "react";
|
|
579
|
-
|
|
580
|
-
// src/hooks/core/use-view-v2.ts
|
|
581
|
-
import { useMemo as useMemo2 } from "react";
|
|
582
|
-
|
|
583
|
-
// src/hooks/core/use-company.ts
|
|
584
|
-
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
585
|
-
import { useEffect as useEffect5, useMemo as useMemo3 } from "react";
|
|
586
|
-
|
|
587
|
-
// src/hooks/core/use-app-provider.tsx
|
|
588
|
-
import { jsx } from "react/jsx-runtime";
|
|
589
|
-
var AppProviderInitialValue = {
|
|
590
|
-
user: {},
|
|
591
|
-
company: {},
|
|
592
|
-
action: {},
|
|
593
|
-
menu: {},
|
|
594
|
-
view: {}
|
|
595
|
-
};
|
|
596
|
-
var ReactContext = createContext(AppProviderInitialValue);
|
|
597
|
-
var useAppProvider = () => {
|
|
598
|
-
const context = useContext(ReactContext);
|
|
599
|
-
if (!context) {
|
|
600
|
-
return AppProviderInitialValue;
|
|
601
|
-
}
|
|
602
|
-
return context;
|
|
603
|
-
};
|
|
604
|
-
|
|
605
|
-
// src/hooks/core/use-config.ts
|
|
606
|
-
import { useEffect as useEffect6 } from "react";
|
|
607
|
-
|
|
608
|
-
// src/hooks/core/use-get-specification.ts
|
|
609
|
-
import { useMemo as useMemo5 } from "react";
|
|
610
|
-
var useGetSpecification = ({
|
|
611
|
-
model,
|
|
612
|
-
viewData,
|
|
613
|
-
fields
|
|
614
|
-
}) => {
|
|
615
|
-
const baseModel = useMemo5(
|
|
616
|
-
() => ({
|
|
617
|
-
name: String(model),
|
|
618
|
-
view: viewData,
|
|
619
|
-
fields
|
|
620
|
-
}),
|
|
621
|
-
[model, viewData, fields]
|
|
622
|
-
);
|
|
623
|
-
const initModel = useModel();
|
|
624
|
-
const modelInstance = useMemo5(() => {
|
|
625
|
-
if (viewData) {
|
|
626
|
-
return initModel.initModel(baseModel);
|
|
627
|
-
}
|
|
628
|
-
return null;
|
|
629
|
-
}, [baseModel, viewData, model]);
|
|
630
|
-
const specification = useMemo5(() => {
|
|
631
|
-
if (modelInstance) {
|
|
632
|
-
return modelInstance.getSpecification();
|
|
633
|
-
}
|
|
634
|
-
return null;
|
|
635
|
-
}, [modelInstance, model]);
|
|
636
|
-
return { specification };
|
|
637
|
-
};
|
|
638
|
-
|
|
639
|
-
// src/hooks/core/use-list-data.ts
|
|
640
|
-
import { useMemo as useMemo6, useState as useState6 } from "react";
|
|
641
|
-
import {
|
|
642
|
-
evalJSONDomain,
|
|
643
|
-
formatSortingString
|
|
644
|
-
} from "@fctc/interface-logic/utils";
|
|
645
|
-
|
|
646
|
-
// src/hooks/utils/use-debounce.ts
|
|
647
|
-
import { useEffect as useEffect7, useState as useState4 } from "react";
|
|
648
|
-
function useDebounce(value, delay) {
|
|
649
|
-
const [debouncedValue, setDebouncedValue] = useState4(value);
|
|
650
|
-
useEffect7(() => {
|
|
651
|
-
const handler = setTimeout(() => {
|
|
652
|
-
setDebouncedValue(value);
|
|
653
|
-
}, delay);
|
|
654
|
-
return () => {
|
|
655
|
-
clearTimeout(handler);
|
|
656
|
-
};
|
|
657
|
-
}, [value, delay]);
|
|
658
|
-
return [debouncedValue];
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// src/hooks/utils/use-get-rowids.ts
|
|
662
|
-
import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef2, useState as useState5 } from "react";
|
|
663
|
-
var useGetRowIds = (tableRef) => {
|
|
664
|
-
function isElementVisible(el) {
|
|
665
|
-
const style = window.getComputedStyle(el);
|
|
666
|
-
return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0";
|
|
667
|
-
}
|
|
668
|
-
function arraysAreEqual(a, b) {
|
|
669
|
-
if (a.length !== b.length) return false;
|
|
670
|
-
if (a.length === 0 && b.length === 0) return true;
|
|
671
|
-
const setA = new Set(a);
|
|
672
|
-
const setB = new Set(b);
|
|
673
|
-
if (setA.size !== setB.size) return false;
|
|
674
|
-
for (const val of setA) {
|
|
675
|
-
if (!setB.has(val)) return false;
|
|
676
|
-
}
|
|
677
|
-
return true;
|
|
678
|
-
}
|
|
679
|
-
const [rowIds, setRowIds] = useState5([]);
|
|
680
|
-
const lastRowIdsRef = useRef2([]);
|
|
681
|
-
const updateVisibleRowIds = useCallback3(() => {
|
|
682
|
-
const table = tableRef.current;
|
|
683
|
-
if (!table) return;
|
|
684
|
-
const rows = table.querySelectorAll("tr[data-row-id]");
|
|
685
|
-
const ids = [];
|
|
686
|
-
rows.forEach((row) => {
|
|
687
|
-
const el = row;
|
|
688
|
-
if (isElementVisible(el)) {
|
|
689
|
-
const id = el.getAttribute("data-row-id");
|
|
690
|
-
if (id) ids.push(id);
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
const uniqueIds = Array.from(new Set(ids));
|
|
694
|
-
if (!arraysAreEqual(lastRowIdsRef.current, uniqueIds)) {
|
|
695
|
-
lastRowIdsRef.current = uniqueIds;
|
|
696
|
-
setRowIds(uniqueIds);
|
|
697
|
-
}
|
|
698
|
-
}, [tableRef]);
|
|
699
|
-
useEffect8(() => {
|
|
700
|
-
const table = tableRef.current;
|
|
701
|
-
if (!table) return;
|
|
702
|
-
const mutationObserver = new MutationObserver(() => {
|
|
703
|
-
updateVisibleRowIds();
|
|
704
|
-
});
|
|
705
|
-
mutationObserver.observe(table, {
|
|
706
|
-
childList: true,
|
|
707
|
-
subtree: true,
|
|
708
|
-
attributes: true,
|
|
709
|
-
attributeFilter: ["style", "class"]
|
|
710
|
-
});
|
|
711
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
712
|
-
updateVisibleRowIds();
|
|
713
|
-
});
|
|
714
|
-
resizeObserver.observe(table);
|
|
715
|
-
const handleScroll = () => updateVisibleRowIds();
|
|
716
|
-
table.addEventListener("scroll", handleScroll, true);
|
|
717
|
-
updateVisibleRowIds();
|
|
718
|
-
return () => {
|
|
719
|
-
mutationObserver.disconnect();
|
|
720
|
-
resizeObserver.disconnect();
|
|
721
|
-
table.removeEventListener("scroll", handleScroll, true);
|
|
722
|
-
};
|
|
723
|
-
}, [updateVisibleRowIds, tableRef?.current]);
|
|
724
|
-
return { rowIds, refresh: updateVisibleRowIds };
|
|
725
|
-
};
|
|
726
|
-
|
|
727
|
-
// src/hooks/core/use-list-data.ts
|
|
728
|
-
var useListData = ({
|
|
729
|
-
action,
|
|
730
|
-
context,
|
|
731
|
-
viewData,
|
|
732
|
-
model,
|
|
733
|
-
service,
|
|
734
|
-
xNode,
|
|
735
|
-
mode,
|
|
736
|
-
limit = 10
|
|
737
|
-
}) => {
|
|
738
|
-
const { useGetListData: useGetListData2 } = (0, provider_exports.useService)();
|
|
739
|
-
const [page, setPage] = useState6(0);
|
|
740
|
-
const [pageLimit, setPageLimit] = useState6(limit);
|
|
741
|
-
const [groupByList, setGroupByList] = useState6(null);
|
|
742
|
-
const [domain, setDomain] = useState6(null);
|
|
743
|
-
const [order, setOrder] = useState6("");
|
|
744
|
-
const [selectedRowKeys, setSelectedRowKeys] = useState6([]);
|
|
745
|
-
const [debouncedPage] = useDebounce(page, 500);
|
|
746
|
-
const [debouncedDomain] = useDebounce(domain, 500);
|
|
747
|
-
const { specification } = useGetSpecification({
|
|
748
|
-
model,
|
|
749
|
-
viewData,
|
|
750
|
-
fields: mode === "kanban" ? viewData?.views?.kanban?.fields : viewData?.views?.list?.fields
|
|
751
|
-
});
|
|
752
|
-
const listDataProps = useMemo6(() => {
|
|
753
|
-
if (!viewData || !action || !context) {
|
|
754
|
-
return null;
|
|
755
|
-
}
|
|
756
|
-
const domainParse = domain ? [...domain] : action?.domain ? Array.isArray(action?.domain) ? [...action?.domain] : evalJSONDomain(action?.domain, context) : [];
|
|
757
|
-
const limit2 = pageLimit;
|
|
758
|
-
const offset = debouncedPage * pageLimit;
|
|
759
|
-
const fields = typeof groupByList === "object" ? groupByList?.fields : void 0;
|
|
760
|
-
const groupby = typeof groupByList === "object" ? [groupByList?.contexts?.[0]?.group_by] : [];
|
|
761
|
-
const sort = order ?? formatSortingString(
|
|
762
|
-
(mode === "kanban" ? viewData?.views?.kanban : viewData?.views?.list)?.default_order
|
|
763
|
-
) ?? "";
|
|
764
|
-
return {
|
|
765
|
-
model: action?.res_model,
|
|
766
|
-
specification,
|
|
767
|
-
domain: domainParse,
|
|
768
|
-
limit: limit2,
|
|
769
|
-
offset,
|
|
770
|
-
fields,
|
|
771
|
-
groupby,
|
|
772
|
-
context,
|
|
773
|
-
sort,
|
|
774
|
-
mode
|
|
775
|
-
};
|
|
776
|
-
}, [
|
|
777
|
-
action,
|
|
778
|
-
groupByList,
|
|
779
|
-
order,
|
|
780
|
-
debouncedPage,
|
|
781
|
-
pageLimit,
|
|
782
|
-
debouncedDomain,
|
|
783
|
-
context,
|
|
784
|
-
model
|
|
785
|
-
]);
|
|
786
|
-
const list = useGetListData2(
|
|
787
|
-
{ ...listDataProps },
|
|
788
|
-
[
|
|
789
|
-
listDataProps?.domain,
|
|
790
|
-
listDataProps?.groupby,
|
|
791
|
-
listDataProps?.limit,
|
|
792
|
-
listDataProps?.offset,
|
|
793
|
-
listDataProps?.sort,
|
|
794
|
-
listDataProps?.context,
|
|
795
|
-
listDataProps?.specification,
|
|
796
|
-
listDataProps?.mode
|
|
797
|
-
],
|
|
798
|
-
!!listDataProps && !!specification && !isObjectEmpty(specification) && !!domain,
|
|
799
|
-
service,
|
|
800
|
-
xNode
|
|
801
|
-
);
|
|
802
|
-
return {
|
|
803
|
-
...list,
|
|
804
|
-
state: {
|
|
805
|
-
specification,
|
|
806
|
-
page,
|
|
807
|
-
order,
|
|
808
|
-
domain: listDataProps?.domain,
|
|
809
|
-
pageLimit,
|
|
810
|
-
groupByList,
|
|
811
|
-
selectedRowKeys,
|
|
812
|
-
setPage,
|
|
813
|
-
setOrder,
|
|
814
|
-
setDomain,
|
|
815
|
-
setPageLimit,
|
|
816
|
-
setGroupByList,
|
|
817
|
-
setSelectedRowKeys
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
|
-
};
|
|
821
|
-
|
|
822
|
-
// src/widget/basic/many2one-field/controller.ts
|
|
823
|
-
var MANY2ONE_EXTERNAL = "many2one_external";
|
|
824
|
-
var many2oneFieldController = (props) => {
|
|
825
|
-
const {
|
|
826
|
-
methods,
|
|
827
|
-
relation,
|
|
828
|
-
domain,
|
|
829
|
-
formValues,
|
|
830
|
-
value: propValue,
|
|
831
|
-
onChange,
|
|
832
|
-
name,
|
|
833
|
-
context: fieldContext,
|
|
834
|
-
options: fieldOptions,
|
|
835
|
-
showDetail,
|
|
836
|
-
service,
|
|
837
|
-
xNode,
|
|
838
|
-
isForm,
|
|
839
|
-
widget,
|
|
840
|
-
in_list_view,
|
|
841
|
-
isEditTable
|
|
842
|
-
} = props;
|
|
843
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
844
|
-
const { action } = useAppProvider();
|
|
845
|
-
const { useGetSelection: useGetSelection3, useGetDetail: useGetDetail2 } = (0, provider_exports.useService)();
|
|
846
|
-
const [listOptions, setListOptions] = useState7([]);
|
|
847
|
-
const [inputValue, setInputValue] = useState7("");
|
|
848
|
-
const [debouncedInputValue] = useDebounce(inputValue, 1e3);
|
|
849
|
-
const [isShowModalMany2Many, setIsShowModalMany2Many] = useState7(false);
|
|
850
|
-
const [tempSelectedOption, setTempSelectedOption] = useState7(null);
|
|
851
|
-
const [domainModal, setDomainModal] = useState7(null);
|
|
852
|
-
const [domainObject, setDomainObject] = useState7(null);
|
|
853
|
-
const initValue = methods?.getValues(name);
|
|
854
|
-
const contextObject = {
|
|
855
|
-
...(typeof action?.context === "string" ? (0, utils_exports.evalJSONContext)(action?.context) : action?.context) || {},
|
|
856
|
-
...fieldContext,
|
|
857
|
-
...env?.context
|
|
858
|
-
};
|
|
859
|
-
const optionsObject = typeof fieldOptions === "string" ? (0, utils_exports.evalJSONContext)(fieldOptions, {
|
|
860
|
-
...formValues,
|
|
861
|
-
...contextObject,
|
|
862
|
-
context: contextObject,
|
|
863
|
-
parent: { ...formValues }
|
|
864
|
-
}) : fieldOptions;
|
|
865
|
-
const fetchGetDetail = useGetDetail2();
|
|
866
|
-
const data = {
|
|
867
|
-
model: widget === MANY2ONE_EXTERNAL ? optionsObject?.model : relation,
|
|
868
|
-
domain: widget === MANY2ONE_EXTERNAL ? optionsObject?.domain : domainObject,
|
|
869
|
-
context: {
|
|
870
|
-
...contextObject,
|
|
871
|
-
...optionsObject?.context
|
|
872
|
-
},
|
|
873
|
-
specification: widget === MANY2ONE_EXTERNAL ? optionsObject?.specification : {
|
|
874
|
-
id: {},
|
|
875
|
-
name: {},
|
|
876
|
-
display_name: {}
|
|
877
|
-
}
|
|
878
|
-
};
|
|
879
|
-
const {
|
|
880
|
-
data: dataOfSelection,
|
|
881
|
-
refetch,
|
|
882
|
-
isFetching
|
|
883
|
-
} = useGetSelection3({
|
|
884
|
-
data,
|
|
885
|
-
queryKey: [`data_${relation}`, domainObject],
|
|
886
|
-
enabled: false,
|
|
887
|
-
service: widget === MANY2ONE_EXTERNAL ? optionsObject?.service : service,
|
|
888
|
-
xNode
|
|
889
|
-
});
|
|
890
|
-
const selectOptions = useMemo7(() => {
|
|
891
|
-
return dataOfSelection?.records?.map((val) => ({
|
|
892
|
-
value: val?.id,
|
|
893
|
-
label: val?.display_name || val?.name,
|
|
894
|
-
...widget === MANY2ONE_EXTERNAL ? val : {}
|
|
895
|
-
})) || [];
|
|
896
|
-
}, [dataOfSelection]);
|
|
897
|
-
useEffect9(() => {
|
|
898
|
-
setListOptions(selectOptions);
|
|
899
|
-
setDomainModal(domainObject);
|
|
900
|
-
}, [selectOptions]);
|
|
901
|
-
const parsedFormValues = useMemo7(
|
|
902
|
-
() => JSON.parse(
|
|
903
|
-
JSON.stringify({
|
|
904
|
-
...formValues,
|
|
905
|
-
...contextObject,
|
|
906
|
-
context: contextObject
|
|
907
|
-
})
|
|
908
|
-
) ?? {},
|
|
909
|
-
[formValues, contextObject]
|
|
910
|
-
);
|
|
911
|
-
useEffect9(() => {
|
|
912
|
-
const newDomain = (0, utils_exports.evalJSONDomain)(domain, parsedFormValues);
|
|
913
|
-
const parsedDomain = typeof newDomain === "string" ? JSON.parse(
|
|
914
|
-
newDomain.replace(/\(/g, "[").replace(/\)/g, "]").replace(/'/g, '"')
|
|
915
|
-
) : newDomain;
|
|
916
|
-
setDomainObject((prev) => {
|
|
917
|
-
const prevStr = JSON.stringify(prev);
|
|
918
|
-
const nextStr = JSON.stringify(parsedDomain);
|
|
919
|
-
return prevStr === nextStr ? prev : parsedDomain;
|
|
920
|
-
});
|
|
921
|
-
}, [domain, parsedFormValues]);
|
|
922
|
-
useEffect9(() => {
|
|
923
|
-
if (!propValue && tempSelectedOption) {
|
|
924
|
-
methods?.setValue(name, null, { shouldDirty: true });
|
|
925
|
-
setTempSelectedOption(null);
|
|
926
|
-
} else if (propValue) {
|
|
927
|
-
if (isForm && !isEditTable && optionsObject?.service && optionsObject?.model && !propValue?.display_name && !in_list_view) {
|
|
928
|
-
fetchGetDetail.mutate(
|
|
929
|
-
{
|
|
930
|
-
model: optionsObject?.model,
|
|
931
|
-
ids: propValue?.id ?? propValue,
|
|
932
|
-
specification: widget === MANY2ONE_EXTERNAL ? optionsObject?.specification : {
|
|
933
|
-
id: {},
|
|
934
|
-
display_name: {}
|
|
935
|
-
},
|
|
936
|
-
context: { ...env.context },
|
|
937
|
-
service: optionsObject ? optionsObject?.service : service,
|
|
938
|
-
xNode
|
|
939
|
-
},
|
|
940
|
-
{
|
|
941
|
-
onSuccess: (dataResponse) => {
|
|
942
|
-
const detailData = dataResponse?.[0];
|
|
943
|
-
setTempSelectedOption({
|
|
944
|
-
value: detailData?.id,
|
|
945
|
-
label: detailData?.display_name
|
|
946
|
-
});
|
|
947
|
-
if (widget === MANY2ONE_EXTERNAL && optionsObject?.values_included) {
|
|
948
|
-
Object.keys(optionsObject?.values_included)?.forEach(
|
|
949
|
-
(field) => {
|
|
950
|
-
methods?.setValue(
|
|
951
|
-
optionsObject?.values_included[field]?.name,
|
|
952
|
-
detailData?.[field]
|
|
953
|
-
);
|
|
954
|
-
}
|
|
955
|
-
);
|
|
956
|
-
methods?.setValue(name, detailData);
|
|
957
|
-
}
|
|
958
|
-
},
|
|
959
|
-
onError: (error) => {
|
|
960
|
-
console.log("error", error);
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
);
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
966
|
-
setTempSelectedOption({
|
|
967
|
-
value: propValue?.id,
|
|
968
|
-
label: propValue?.display_name
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
|
-
}, [propValue]);
|
|
972
|
-
const fetchMoreOptions = useCallback4(() => {
|
|
973
|
-
refetch();
|
|
974
|
-
}, [refetch]);
|
|
975
|
-
useEffect9(() => {
|
|
976
|
-
if (debouncedInputValue) {
|
|
977
|
-
const filteredDomain = [...domainObject ?? []]?.filter(
|
|
978
|
-
(d) => !(Array.isArray(d) && d[0] === "name" && d[1] === "ilike")
|
|
979
|
-
) || [];
|
|
980
|
-
const newDomain = [
|
|
981
|
-
...filteredDomain,
|
|
982
|
-
...debouncedInputValue ? [["name", "ilike", debouncedInputValue]] : []
|
|
983
|
-
];
|
|
984
|
-
setDomainObject(newDomain);
|
|
985
|
-
setTimeout(() => {
|
|
986
|
-
fetchMoreOptions();
|
|
987
|
-
}, 50);
|
|
988
|
-
}
|
|
989
|
-
}, [debouncedInputValue]);
|
|
990
|
-
const handleChooseRecord = useCallback4(
|
|
991
|
-
(idRecord) => {
|
|
992
|
-
const newOption = listOptions?.find(
|
|
993
|
-
(option) => option.value === idRecord
|
|
994
|
-
);
|
|
995
|
-
const newValue = widget === MANY2ONE_EXTERNAL && optionsObject?.field_name ? newOption?.[optionsObject?.field_name] : newOption.value;
|
|
996
|
-
if (widget === MANY2ONE_EXTERNAL && optionsObject?.values_included) {
|
|
997
|
-
Object.keys(optionsObject?.values_included)?.forEach((field) => {
|
|
998
|
-
methods?.setValue(
|
|
999
|
-
optionsObject?.values_included[field]?.name,
|
|
1000
|
-
newOption?.[field],
|
|
1001
|
-
{ shouldDirty: true }
|
|
1002
|
-
);
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
if (newOption) {
|
|
1006
|
-
methods?.setValue(
|
|
1007
|
-
name,
|
|
1008
|
-
{
|
|
1009
|
-
...newOption,
|
|
1010
|
-
id: newValue,
|
|
1011
|
-
display_name: newOption?.label
|
|
1012
|
-
},
|
|
1013
|
-
{ shouldDirty: true }
|
|
1014
|
-
);
|
|
1015
|
-
setTempSelectedOption(newOption);
|
|
1016
|
-
onChange && onChange(String(name), {
|
|
1017
|
-
...newOption,
|
|
1018
|
-
id: newValue,
|
|
1019
|
-
display_name: newOption?.label
|
|
1020
|
-
});
|
|
1021
|
-
methods.trigger(name);
|
|
1022
|
-
}
|
|
1023
|
-
setIsShowModalMany2Many(false);
|
|
1024
|
-
},
|
|
1025
|
-
[listOptions, methods, name, onChange]
|
|
1026
|
-
);
|
|
1027
|
-
const handleClose = useCallback4(() => setIsShowModalMany2Many(false), []);
|
|
1028
|
-
const handleSelectChange = useCallback4(
|
|
1029
|
-
(selectedOption) => {
|
|
1030
|
-
if (!selectedOption) {
|
|
1031
|
-
if (widget === MANY2ONE_EXTERNAL && optionsObject?.values_included) {
|
|
1032
|
-
Object.keys(optionsObject?.values_included)?.forEach((field) => {
|
|
1033
|
-
methods?.setValue(
|
|
1034
|
-
optionsObject?.values_included[field]?.name,
|
|
1035
|
-
null,
|
|
1036
|
-
{ shouldDirty: true }
|
|
1037
|
-
);
|
|
1038
|
-
});
|
|
1039
|
-
}
|
|
1040
|
-
methods.setValue(name, null, { shouldDirty: true });
|
|
1041
|
-
setTempSelectedOption(null);
|
|
1042
|
-
onChange && onChange(String(name), null);
|
|
1043
|
-
methods.trigger(name);
|
|
1044
|
-
return;
|
|
1045
|
-
}
|
|
1046
|
-
const newValue = widget === MANY2ONE_EXTERNAL && optionsObject?.field_name ? selectedOption?.[optionsObject?.field_name] : selectedOption.value;
|
|
1047
|
-
if (widget === MANY2ONE_EXTERNAL && optionsObject?.values_included) {
|
|
1048
|
-
Object.keys(optionsObject?.values_included)?.forEach((field) => {
|
|
1049
|
-
methods?.setValue(
|
|
1050
|
-
optionsObject?.values_included[field]?.name,
|
|
1051
|
-
selectedOption?.[field],
|
|
1052
|
-
{ shouldDirty: true }
|
|
1053
|
-
);
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
methods?.setValue(
|
|
1057
|
-
name,
|
|
1058
|
-
{
|
|
1059
|
-
id: newValue,
|
|
1060
|
-
display_name: selectedOption?.label
|
|
1061
|
-
},
|
|
1062
|
-
{ shouldDirty: true }
|
|
1063
|
-
);
|
|
1064
|
-
setTempSelectedOption(selectedOption);
|
|
1065
|
-
onChange && onChange(String(name), {
|
|
1066
|
-
id: newValue,
|
|
1067
|
-
display_name: selectedOption.label
|
|
1068
|
-
});
|
|
1069
|
-
methods.trigger(name);
|
|
1070
|
-
},
|
|
1071
|
-
[methods, name, onChange]
|
|
1072
|
-
);
|
|
1073
|
-
const allowShowDetail = showDetail && contextObject?.form_view_ref && (!optionsObject || !("no_open" in optionsObject) || optionsObject.no_open === false);
|
|
1074
|
-
return {
|
|
1075
|
-
isShowModalMany2Many,
|
|
1076
|
-
isFetching,
|
|
1077
|
-
initValue,
|
|
1078
|
-
handleChooseRecord,
|
|
1079
|
-
handleClose,
|
|
1080
|
-
handleSelectChange,
|
|
1081
|
-
domainModal,
|
|
1082
|
-
setInputValue,
|
|
1083
|
-
allowShowDetail,
|
|
1084
|
-
contextObject: {
|
|
1085
|
-
...contextObject,
|
|
1086
|
-
...optionsObject?.context
|
|
1087
|
-
},
|
|
1088
|
-
tempSelectedOption,
|
|
1089
|
-
listOptions,
|
|
1090
|
-
fetchMoreOptions,
|
|
1091
|
-
domainObject: widget === MANY2ONE_EXTERNAL ? optionsObject?.domain : domainObject,
|
|
1092
|
-
setIsShowModalMany2Many,
|
|
1093
|
-
setDomainObject,
|
|
1094
|
-
options: optionsObject,
|
|
1095
|
-
relation: widget === MANY2ONE_EXTERNAL ? optionsObject?.model : relation,
|
|
1096
|
-
service: widget === MANY2ONE_EXTERNAL ? optionsObject?.service : service
|
|
1097
|
-
};
|
|
1098
|
-
};
|
|
1099
|
-
|
|
1100
|
-
// src/widget/basic/many2one-button-field/controller.ts
|
|
1101
|
-
import { getEnv as getEnv2 } from "@fctc/interface-logic/environment";
|
|
1102
|
-
import { useGetSelection as useGetSelection2 } from "@fctc/interface-logic/hooks";
|
|
1103
|
-
import { evalJSONDomain as evalJSONDomain3, evalJSONContext as evalJSONContext3 } from "@fctc/interface-logic/utils";
|
|
1104
|
-
var many2oneButtonController = (props) => {
|
|
1105
|
-
const { domain, methods, relation, service, xNode } = props;
|
|
1106
|
-
const actionDataString = sessionStorage.getItem("actionData");
|
|
1107
|
-
const env = getEnv2();
|
|
1108
|
-
const domainObject = evalJSONDomain3(domain, methods?.getValues() || {});
|
|
1109
|
-
const actionData = actionDataString && actionDataString !== "undefined" ? JSON.parse(actionDataString) : {};
|
|
1110
|
-
const { data: dataOfSelection } = useGetSelection2({
|
|
1111
|
-
data: {
|
|
1112
|
-
model: relation ?? "",
|
|
1113
|
-
domain: domainObject,
|
|
1114
|
-
context: { ...env.context, ...evalJSONContext3(actionData?.context) }
|
|
1115
|
-
},
|
|
1116
|
-
queryKey: [`data_${relation}`, domainObject],
|
|
1117
|
-
service,
|
|
1118
|
-
xNode
|
|
1119
|
-
});
|
|
1120
|
-
const options = dataOfSelection?.records?.map((val) => ({
|
|
1121
|
-
value: val.id,
|
|
1122
|
-
label: val.name
|
|
1123
|
-
})) || [];
|
|
1124
|
-
return {
|
|
1125
|
-
options
|
|
1126
|
-
};
|
|
1127
|
-
};
|
|
1128
|
-
|
|
1129
|
-
// src/widget/basic/many2many-field/controller.ts
|
|
1130
|
-
import { useEffect as useEffect10, useMemo as useMemo8 } from "react";
|
|
1131
|
-
import { evalJSONContext as evalJSONContext4 } from "@fctc/interface-logic/utils";
|
|
1132
|
-
var many2manyFieldController = (props) => {
|
|
1133
|
-
const {
|
|
1134
|
-
relation,
|
|
1135
|
-
domain,
|
|
1136
|
-
context,
|
|
1137
|
-
options,
|
|
1138
|
-
enabled: enabledCallAPI,
|
|
1139
|
-
service
|
|
1140
|
-
} = props;
|
|
1141
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
1142
|
-
const { user } = useAppProvider();
|
|
1143
|
-
const { useGetView: useGetView2 } = (0, provider_exports.useService)();
|
|
1144
|
-
const dataUser = user?.userProfile?.data;
|
|
1145
|
-
const contextObject = useMemo8(
|
|
1146
|
-
() => ({
|
|
1147
|
-
...env.context,
|
|
1148
|
-
...context || {}
|
|
1149
|
-
}),
|
|
1150
|
-
[env?.context, context]
|
|
1151
|
-
);
|
|
1152
|
-
const viewParams = useMemo8(
|
|
1153
|
-
() => ({
|
|
1154
|
-
model: relation,
|
|
1155
|
-
views: [
|
|
1156
|
-
[false, "list"],
|
|
1157
|
-
[false, "search"]
|
|
1158
|
-
],
|
|
1159
|
-
context: contextObject,
|
|
1160
|
-
service,
|
|
1161
|
-
xNode: service == "wesap" && dataUser?.x_node
|
|
1162
|
-
}),
|
|
1163
|
-
[relation, contextObject, service, dataUser?.x_node]
|
|
1164
|
-
);
|
|
1165
|
-
const { data: viewResponse } = useGetView2({
|
|
1166
|
-
viewParams,
|
|
1167
|
-
enabled: enabledCallAPI
|
|
1168
|
-
});
|
|
1169
|
-
const default_order = viewResponse && viewResponse?.views?.list?.default_order;
|
|
1170
|
-
const optionsObject = useMemo8(
|
|
1171
|
-
() => (options && typeof options === "string" ? evalJSONContext4(options) : options) || {},
|
|
1172
|
-
[options]
|
|
1173
|
-
);
|
|
1174
|
-
const {
|
|
1175
|
-
data: dataResponse,
|
|
1176
|
-
isFetched,
|
|
1177
|
-
isLoading,
|
|
1178
|
-
state,
|
|
1179
|
-
isPlaceholderData
|
|
1180
|
-
} = useListData({
|
|
1181
|
-
action: {
|
|
1182
|
-
domain,
|
|
1183
|
-
res_model: relation
|
|
1184
|
-
},
|
|
1185
|
-
context: contextObject,
|
|
1186
|
-
model: relation ?? "",
|
|
1187
|
-
viewData: viewResponse,
|
|
1188
|
-
service,
|
|
1189
|
-
xNode: service == "wesap" && dataUser?.x_node
|
|
1190
|
-
});
|
|
1191
|
-
const {
|
|
1192
|
-
selectedRowKeys,
|
|
1193
|
-
groupByList,
|
|
1194
|
-
domain: domainList,
|
|
1195
|
-
page,
|
|
1196
|
-
pageLimit,
|
|
1197
|
-
setDomain,
|
|
1198
|
-
setOrder,
|
|
1199
|
-
setPage,
|
|
1200
|
-
setSelectedRowKeys,
|
|
1201
|
-
setGroupByList,
|
|
1202
|
-
setPageLimit,
|
|
1203
|
-
specification
|
|
1204
|
-
} = state;
|
|
1205
|
-
useEffect10(() => {
|
|
1206
|
-
return () => {
|
|
1207
|
-
setDomain(null);
|
|
1208
|
-
setOrder("");
|
|
1209
|
-
setGroupByList(null);
|
|
1210
|
-
setPageLimit(10);
|
|
1211
|
-
};
|
|
1212
|
-
}, []);
|
|
1213
|
-
const { rows, columns, typeTable, onToggleColumnOptional } = tableController({
|
|
1214
|
-
data: {
|
|
1215
|
-
fields: viewResponse?.views?.list?.fields,
|
|
1216
|
-
records: dataResponse?.records ?? dataResponse?.groups,
|
|
1217
|
-
dataModel: viewResponse?.models?.[String(relation)],
|
|
1218
|
-
context: contextObject,
|
|
1219
|
-
typeTable: dataResponse?.groups ? "group" : "list"
|
|
1220
|
-
}
|
|
1221
|
-
});
|
|
1222
|
-
const searchControllers = searchController({
|
|
1223
|
-
viewData: viewResponse,
|
|
1224
|
-
model: relation ?? "",
|
|
1225
|
-
context: contextObject,
|
|
1226
|
-
domain,
|
|
1227
|
-
fieldsList: [
|
|
1228
|
-
...columns?.filter(
|
|
1229
|
-
(col) => col?.field?.type_co === "field" && col?.optional !== "hide"
|
|
1230
|
-
)?.map((col) => ({ ...col.field })) ?? []
|
|
1231
|
-
]
|
|
1232
|
-
});
|
|
1233
|
-
const handleCreateNewOnPage = async () => {
|
|
1234
|
-
};
|
|
1235
|
-
return {
|
|
1236
|
-
rows,
|
|
1237
|
-
columns,
|
|
1238
|
-
optionsObject,
|
|
1239
|
-
viewData: viewResponse,
|
|
1240
|
-
totalRows: dataResponse?.length ?? 0,
|
|
1241
|
-
onToggleColumnOptional,
|
|
1242
|
-
typeTable,
|
|
1243
|
-
isLoading,
|
|
1244
|
-
isFetched,
|
|
1245
|
-
isPlaceholderData,
|
|
1246
|
-
page,
|
|
1247
|
-
pageLimit,
|
|
1248
|
-
groupByList,
|
|
1249
|
-
selectedRowKeys,
|
|
1250
|
-
domain: domainList,
|
|
1251
|
-
setPage,
|
|
1252
|
-
setDomain,
|
|
1253
|
-
setPageLimit,
|
|
1254
|
-
setGroupByList,
|
|
1255
|
-
setSelectedRowKeys,
|
|
1256
|
-
searchController: searchControllers,
|
|
1257
|
-
handleCreateNewOnPage,
|
|
1258
|
-
specification
|
|
1259
|
-
};
|
|
1260
|
-
};
|
|
1261
|
-
|
|
1262
|
-
// src/widget/basic/many2many-tags-field/controller.ts
|
|
1263
|
-
import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo9, useState as useState8 } from "react";
|
|
1264
|
-
import { WIDGETAVATAR, WIDGETCOLOR } from "@fctc/interface-logic/constants";
|
|
1265
|
-
import { evalJSONContext as evalJSONContext5, evalJSONDomain as evalJSONDomain4 } from "@fctc/interface-logic/utils";
|
|
1266
|
-
var many2manyTagsController = (props) => {
|
|
1267
|
-
const {
|
|
1268
|
-
relation,
|
|
1269
|
-
domain,
|
|
1270
|
-
options: optionsFields,
|
|
1271
|
-
widget,
|
|
1272
|
-
formValues,
|
|
1273
|
-
service,
|
|
1274
|
-
xNode,
|
|
1275
|
-
context: fieldContext,
|
|
1276
|
-
onChange,
|
|
1277
|
-
methods,
|
|
1278
|
-
name
|
|
1279
|
-
} = props;
|
|
1280
|
-
const isUser = relation === "res.users" || relation === "res.partner";
|
|
1281
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
1282
|
-
const { action } = useAppProvider();
|
|
1283
|
-
const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
|
|
1284
|
-
const [options, setOptions] = useState8([]);
|
|
1285
|
-
const [domainObject, setDomainObject] = useState8(null);
|
|
1286
|
-
const [isShowModalMany2Many, setIsShowModalMany2Many] = useState8(false);
|
|
1287
|
-
const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
|
|
1288
|
-
const contextObject = {
|
|
1289
|
-
...evalJSONContext5(action?.context) || {},
|
|
1290
|
-
...fieldContext ?? {},
|
|
1291
|
-
...env?.context
|
|
1292
|
-
};
|
|
1293
|
-
const parsedFormValues = useMemo9(
|
|
1294
|
-
() => JSON.parse(
|
|
1295
|
-
JSON.stringify({
|
|
1296
|
-
...formValues,
|
|
1297
|
-
...contextObject,
|
|
1298
|
-
context: contextObject,
|
|
1299
|
-
parent: { ...formValues }
|
|
1300
|
-
})
|
|
1301
|
-
) ?? {},
|
|
1302
|
-
[formValues, contextObject]
|
|
1303
|
-
);
|
|
1304
|
-
useEffect11(() => {
|
|
1305
|
-
const newDomain = evalJSONDomain4(domain, parsedFormValues);
|
|
1306
|
-
setDomainObject(
|
|
1307
|
-
(prev) => JSON.stringify(prev) === JSON.stringify(newDomain) ? prev : newDomain
|
|
1308
|
-
);
|
|
1309
|
-
}, [domain, parsedFormValues]);
|
|
1310
|
-
const data = {
|
|
1311
|
-
model: relation ?? "",
|
|
1312
|
-
domain: domainObject,
|
|
1313
|
-
specification: {
|
|
1314
|
-
id: {},
|
|
1315
|
-
name: {},
|
|
1316
|
-
display_name: {},
|
|
1317
|
-
...widget && WIDGETAVATAR[widget] ? { image_256: {} } : {},
|
|
1318
|
-
...widget && WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
|
|
1319
|
-
},
|
|
1320
|
-
context: env.context
|
|
1321
|
-
};
|
|
1322
|
-
const queryKey = [`data_${relation}`, domainObject];
|
|
1323
|
-
const {
|
|
1324
|
-
data: dataOfSelection,
|
|
1325
|
-
refetch,
|
|
1326
|
-
isFetching
|
|
1327
|
-
} = useGetSelection3({
|
|
1328
|
-
data,
|
|
1329
|
-
queryKey,
|
|
1330
|
-
service,
|
|
1331
|
-
xNode,
|
|
1332
|
-
enabled: false
|
|
1333
|
-
});
|
|
1334
|
-
const selectOptions = useMemo9(() => {
|
|
1335
|
-
return dataOfSelection?.records?.map((val) => ({
|
|
1336
|
-
value: val.id,
|
|
1337
|
-
label: val.name ?? val.display_name,
|
|
1338
|
-
...val
|
|
1339
|
-
})) || [];
|
|
1340
|
-
}, [dataOfSelection]);
|
|
1341
|
-
useEffect11(() => {
|
|
1342
|
-
setOptions(selectOptions);
|
|
1343
|
-
}, [selectOptions]);
|
|
1344
|
-
const fetchMoreOptions = useCallback5(() => {
|
|
1345
|
-
refetch();
|
|
1346
|
-
}, [refetch]);
|
|
1347
|
-
const transfer = (data2) => {
|
|
1348
|
-
return data2?.map((val) => ({
|
|
1349
|
-
id: val.value,
|
|
1350
|
-
display_name: val.label
|
|
1351
|
-
})) || [];
|
|
1352
|
-
};
|
|
1353
|
-
const handleChooseRecord = useCallback5(
|
|
1354
|
-
(idRecord) => {
|
|
1355
|
-
const newOption = options.find(
|
|
1356
|
-
(option) => option.value === idRecord
|
|
1357
|
-
);
|
|
1358
|
-
setIsShowModalMany2Many(false);
|
|
1359
|
-
},
|
|
1360
|
-
[options, methods, name, onChange]
|
|
1361
|
-
);
|
|
1362
|
-
const handleClose = useCallback5(() => setIsShowModalMany2Many(false), []);
|
|
1363
|
-
return {
|
|
1364
|
-
options,
|
|
1365
|
-
transfer,
|
|
1366
|
-
isUser,
|
|
1367
|
-
isFetching,
|
|
1368
|
-
fetchMoreOptions,
|
|
1369
|
-
domainObject,
|
|
1370
|
-
setDomainObject,
|
|
1371
|
-
handleChooseRecord,
|
|
1372
|
-
handleClose,
|
|
1373
|
-
isShowModalMany2Many,
|
|
1374
|
-
setIsShowModalMany2Many
|
|
1375
|
-
};
|
|
1376
|
-
};
|
|
1377
|
-
|
|
1378
|
-
// src/widget/basic/status-bar-field/controller.ts
|
|
1379
|
-
import { useState as useState9 } from "react";
|
|
1380
|
-
import { evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
|
|
1381
|
-
var durationController = (props) => {
|
|
1382
|
-
const { relation, domain, formValues, name, id, model, onRefetch, enabled } = props;
|
|
1383
|
-
const specification = {
|
|
1384
|
-
id: 0,
|
|
1385
|
-
name: "",
|
|
1386
|
-
fold: ""
|
|
1387
|
-
};
|
|
1388
|
-
const { useGetListData: useGetListData2, useChangeStatus: useChangeStatus2 } = (0, provider_exports.useService)();
|
|
1389
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
1390
|
-
const [disabled, setDisabled] = useState9(false);
|
|
1391
|
-
const [modelStatus, setModalStatus] = useState9(false);
|
|
1392
|
-
const queryKey = [`data-status-duration`, specification];
|
|
1393
|
-
const listDataProps = {
|
|
1394
|
-
model: relation,
|
|
1395
|
-
specification,
|
|
1396
|
-
domain: evalJSONDomain5(domain, JSON.parse(JSON.stringify(formValues))),
|
|
1397
|
-
limit: 10,
|
|
1398
|
-
offset: 0,
|
|
1399
|
-
fields: "",
|
|
1400
|
-
groupby: [],
|
|
1401
|
-
context: {
|
|
1402
|
-
lang: env.context.lang
|
|
1403
|
-
},
|
|
1404
|
-
sort: ""
|
|
1405
|
-
};
|
|
1406
|
-
const { data: dataResponse } = useGetListData2(
|
|
1407
|
-
listDataProps,
|
|
1408
|
-
queryKey,
|
|
1409
|
-
enabled
|
|
1410
|
-
);
|
|
1411
|
-
const { mutate: fetchChangeStatus } = useChangeStatus2();
|
|
1412
|
-
const handleClick = async (stage_id) => {
|
|
1413
|
-
setDisabled(true);
|
|
1414
|
-
if (stage_id) {
|
|
1415
|
-
fetchChangeStatus(
|
|
1416
|
-
{
|
|
1417
|
-
data: {
|
|
1418
|
-
stage_id,
|
|
1419
|
-
name,
|
|
1420
|
-
id,
|
|
1421
|
-
model,
|
|
1422
|
-
lang: env.context.lang
|
|
1423
|
-
}
|
|
1424
|
-
},
|
|
1425
|
-
{
|
|
1426
|
-
onSuccess: (res) => {
|
|
1427
|
-
if (res) {
|
|
1428
|
-
setDisabled(false);
|
|
1429
|
-
onRefetch && onRefetch();
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
);
|
|
1434
|
-
}
|
|
1435
|
-
};
|
|
1436
|
-
return {
|
|
1437
|
-
dataResponse,
|
|
1438
|
-
handleClick,
|
|
1439
|
-
disabled,
|
|
1440
|
-
modelStatus,
|
|
1441
|
-
setModalStatus
|
|
1442
|
-
};
|
|
1443
|
-
};
|
|
1444
|
-
|
|
1445
|
-
// src/widget/basic/priority-field/controller.ts
|
|
1446
|
-
import { evalJSONContext as evalJSONContext6 } from "@fctc/interface-logic/utils";
|
|
1447
|
-
var priorityFieldController = (props) => {
|
|
1448
|
-
const { name, model, index, actionData, context, onChange, specification } = props;
|
|
1449
|
-
const _context = { ...evalJSONContext6(actionData?.context) };
|
|
1450
|
-
const contextObject = { ...context, ..._context };
|
|
1451
|
-
const { useSave: useSave3 } = (0, provider_exports.useService)();
|
|
1452
|
-
const { mutateAsync: fetchSave } = useSave3();
|
|
1453
|
-
const savePriorities = async ({
|
|
1454
|
-
value,
|
|
1455
|
-
resetPriority
|
|
1456
|
-
}) => {
|
|
1457
|
-
const priorityValue = value <= 0 ? 0 : value - 1;
|
|
1458
|
-
try {
|
|
1459
|
-
fetchSave({
|
|
1460
|
-
ids: index ? [index] : [],
|
|
1461
|
-
data: { [String(name)]: String(priorityValue) },
|
|
1462
|
-
model: String(model),
|
|
1463
|
-
context: contextObject,
|
|
1464
|
-
specification
|
|
1465
|
-
});
|
|
1466
|
-
if (typeof onChange === "function") {
|
|
1467
|
-
onChange(String(name), String(priorityValue));
|
|
1468
|
-
}
|
|
1469
|
-
} catch (error) {
|
|
1470
|
-
if (resetPriority) {
|
|
1471
|
-
resetPriority();
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
};
|
|
1475
|
-
return {
|
|
1476
|
-
savePriorities
|
|
1477
|
-
};
|
|
1478
|
-
};
|
|
1479
|
-
|
|
1480
|
-
// src/widget/basic/download-file-field/controller.ts
|
|
1481
|
-
import { useId, useState as useState10 } from "react";
|
|
1482
|
-
var downloadFileController = () => {
|
|
1483
|
-
const inputId = useId();
|
|
1484
|
-
const [file, setFile] = useState10(null);
|
|
1485
|
-
const handleFileChange = (e) => {
|
|
1486
|
-
setFile(e.target.files[0]);
|
|
1487
|
-
};
|
|
1488
|
-
const handleFileDownload = () => {
|
|
1489
|
-
const url = URL.createObjectURL(file);
|
|
1490
|
-
const link = document.createElement("a");
|
|
1491
|
-
link.href = url;
|
|
1492
|
-
link.download = file.name;
|
|
1493
|
-
document.body.appendChild(link);
|
|
1494
|
-
link.click();
|
|
1495
|
-
document.body.removeChild(link);
|
|
1496
|
-
};
|
|
1497
|
-
return {
|
|
1498
|
-
inputId,
|
|
1499
|
-
file,
|
|
1500
|
-
handleFileChange,
|
|
1501
|
-
handleFileDownload
|
|
1502
|
-
};
|
|
1503
|
-
};
|
|
1504
|
-
|
|
1505
|
-
// src/widget/basic/download-binary-field/controller.ts
|
|
1506
|
-
var downLoadBinaryController = (props) => {
|
|
1507
|
-
const { value, defaultValue, formValues } = props;
|
|
1508
|
-
const downloadFile = async (url, filename) => {
|
|
1509
|
-
try {
|
|
1510
|
-
const response = await fetch(url);
|
|
1511
|
-
if (!response.ok) throw new Error(`Failed to fetch ${url}`);
|
|
1512
|
-
const contentType = response.headers.get("Content-Type") || "";
|
|
1513
|
-
let ext = "";
|
|
1514
|
-
if (contentType.includes("pdf")) ext = ".pdf";
|
|
1515
|
-
else if (contentType.includes("png")) ext = ".png";
|
|
1516
|
-
else if (contentType.includes("jpeg") || contentType.includes("jpg"))
|
|
1517
|
-
ext = ".jpg";
|
|
1518
|
-
else if (contentType.includes("zip")) ext = ".zip";
|
|
1519
|
-
else if (contentType.includes("msword")) ext = ".doc";
|
|
1520
|
-
else if (contentType.includes("spreadsheet")) ext = ".xls";
|
|
1521
|
-
else if (contentType.includes("json")) ext = ".json";
|
|
1522
|
-
else if (contentType.includes("text")) ext = ".txt";
|
|
1523
|
-
else {
|
|
1524
|
-
ext = "";
|
|
1525
|
-
}
|
|
1526
|
-
const blob = await response.blob();
|
|
1527
|
-
const urlBlob = window.URL.createObjectURL(blob);
|
|
1528
|
-
const link = document.createElement("a");
|
|
1529
|
-
link.href = urlBlob;
|
|
1530
|
-
link.download = (filename || "file") + ext;
|
|
1531
|
-
document.body.appendChild(link);
|
|
1532
|
-
link.click();
|
|
1533
|
-
document.body.removeChild(link);
|
|
1534
|
-
window.URL.revokeObjectURL(urlBlob);
|
|
1535
|
-
} catch (error) {
|
|
1536
|
-
console.error("File download failed:", error);
|
|
1537
|
-
}
|
|
1538
|
-
};
|
|
1539
|
-
const handleFileDownload = async (e) => {
|
|
1540
|
-
e.stopPropagation();
|
|
1541
|
-
await downloadFile(value || defaultValue, formValues?.name);
|
|
1542
|
-
};
|
|
1543
|
-
return {
|
|
1544
|
-
handleFileDownload
|
|
1545
|
-
};
|
|
1546
|
-
};
|
|
1547
|
-
|
|
1548
|
-
// src/widget/basic/copy-link-button/controller.ts
|
|
1549
|
-
import { useState as useState11 } from "react";
|
|
1550
|
-
var copyTextToClipboard = async (text) => {
|
|
1551
|
-
if ("clipboard" in navigator) {
|
|
1552
|
-
return await navigator.clipboard.writeText(text);
|
|
1553
|
-
} else {
|
|
1554
|
-
const textArea = document.createElement("textarea");
|
|
1555
|
-
textArea.value = text;
|
|
1556
|
-
textArea.style.position = "fixed";
|
|
1557
|
-
document.body.appendChild(textArea);
|
|
1558
|
-
textArea.focus();
|
|
1559
|
-
textArea.select();
|
|
1560
|
-
try {
|
|
1561
|
-
document.execCommand("copy");
|
|
1562
|
-
} finally {
|
|
1563
|
-
document.body.removeChild(textArea);
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1567
|
-
var copyLinkButtonController = (props) => {
|
|
1568
|
-
const { value, defaultValue } = props;
|
|
1569
|
-
const [isCopied, setIsCopied] = useState11(false);
|
|
1570
|
-
const handleCopyToClipboard = async (value2) => {
|
|
1571
|
-
await copyTextToClipboard(value2);
|
|
1572
|
-
setIsCopied(true);
|
|
1573
|
-
setTimeout(() => setIsCopied(false), 2e3);
|
|
1574
|
-
};
|
|
1575
|
-
const propValue = value || defaultValue;
|
|
1576
|
-
return {
|
|
1577
|
-
isCopied,
|
|
1578
|
-
handleCopyToClipboard,
|
|
1579
|
-
propValue
|
|
1580
|
-
};
|
|
1581
|
-
};
|
|
1582
|
-
|
|
1583
|
-
// src/widget/basic/color-field/color-controller.ts
|
|
1584
|
-
import { evalJSONContext as evalJSONContext7 } from "@fctc/interface-logic/utils";
|
|
1585
|
-
var colorFieldController = (props) => {
|
|
1586
|
-
const { value, isForm, name, formValues, idForm, model, actionData } = props;
|
|
1587
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
1588
|
-
const { useSave: useSave3 } = (0, provider_exports.useService)();
|
|
1589
|
-
const _context = { ...evalJSONContext7(actionData?.context) || {} };
|
|
1590
|
-
const contextObject = { ...env.context, ..._context };
|
|
1591
|
-
const idDefault = isForm ? idForm : formValues?.id;
|
|
1592
|
-
const { mutate: onSave } = useSave3();
|
|
1593
|
-
const savePickColor = async (colorObject) => {
|
|
1594
|
-
const { id } = colorObject;
|
|
1595
|
-
if (value === id) return;
|
|
1596
|
-
try {
|
|
1597
|
-
onSave({
|
|
1598
|
-
ids: idDefault !== null ? [idDefault] : [],
|
|
1599
|
-
model: String(model),
|
|
1600
|
-
data: { [String(name)]: id },
|
|
1601
|
-
specification: {
|
|
1602
|
-
name: {},
|
|
1603
|
-
color: {}
|
|
1604
|
-
},
|
|
1605
|
-
context: contextObject
|
|
1606
|
-
});
|
|
1607
|
-
} catch (error) {
|
|
1608
|
-
console.log(error);
|
|
1609
|
-
}
|
|
1610
|
-
};
|
|
1611
|
-
return {
|
|
1612
|
-
savePickColor
|
|
1613
|
-
};
|
|
1614
|
-
};
|
|
1615
|
-
|
|
1616
|
-
// src/widget/basic/binary-field/controller.ts
|
|
1617
|
-
import { useEffect as useEffect12, useState as useState12 } from "react";
|
|
1618
|
-
var binaryFieldController = (props) => {
|
|
1619
|
-
const {
|
|
1620
|
-
name,
|
|
1621
|
-
methods,
|
|
1622
|
-
readonly = false,
|
|
1623
|
-
filename,
|
|
1624
|
-
onChange: handleOnchange,
|
|
1625
|
-
service,
|
|
1626
|
-
xNode,
|
|
1627
|
-
path,
|
|
1628
|
-
rootField,
|
|
1629
|
-
index,
|
|
1630
|
-
value
|
|
1631
|
-
} = props;
|
|
1632
|
-
const { useUploadFile: useUploadFile2 } = (0, provider_exports.useService)();
|
|
1633
|
-
const { mutateAsync } = useUploadFile2();
|
|
1634
|
-
const [url, setUrl] = useState12(value || null);
|
|
1635
|
-
const [fileInfo, setFileInfo] = useState12(null);
|
|
1636
|
-
useEffect12(() => {
|
|
1637
|
-
if (!value) {
|
|
1638
|
-
setUrl(null);
|
|
1639
|
-
setFileInfo(null);
|
|
1640
|
-
return;
|
|
1641
|
-
}
|
|
1642
|
-
fetchFileMeta(value);
|
|
1643
|
-
}, [value]);
|
|
1644
|
-
const formatSize = (bytes) => {
|
|
1645
|
-
if (bytes < 1024) return bytes + " B";
|
|
1646
|
-
let kb = bytes / 1024;
|
|
1647
|
-
if (kb < 1024) return kb.toFixed(2) + " KB";
|
|
1648
|
-
let mb = kb / 1024;
|
|
1649
|
-
if (mb < 1024) return mb.toFixed(2) + " MB";
|
|
1650
|
-
return (mb / 1024).toFixed(2) + " GB";
|
|
1651
|
-
};
|
|
1652
|
-
const fetchFileMeta = async (url2) => {
|
|
1653
|
-
try {
|
|
1654
|
-
const res = await fetch(url2, { method: "HEAD" });
|
|
1655
|
-
const size = res.headers.get("content-length") || "";
|
|
1656
|
-
let type = res.headers.get("content-type") || "";
|
|
1657
|
-
const date = res.headers.get("last-modified") || "";
|
|
1658
|
-
const guessed = guessTypeFromUrl(url2);
|
|
1659
|
-
if (guessed) type = guessed;
|
|
1660
|
-
setFileInfo({
|
|
1661
|
-
size: size ? formatSize(Number(size)) : "--",
|
|
1662
|
-
type,
|
|
1663
|
-
date: date ? new Date(date).toLocaleString() : "--"
|
|
1664
|
-
});
|
|
1665
|
-
setUrl(url2);
|
|
1666
|
-
} catch (e) {
|
|
1667
|
-
console.error(e);
|
|
1668
|
-
}
|
|
1669
|
-
};
|
|
1670
|
-
const onUploadFile = async (formData) => {
|
|
1671
|
-
const res = await mutateAsync({
|
|
1672
|
-
formData,
|
|
1673
|
-
service,
|
|
1674
|
-
xNode,
|
|
1675
|
-
path
|
|
1676
|
-
});
|
|
1677
|
-
const url2 = res?.url;
|
|
1678
|
-
methods?.setValue(name, url2, { shouldDirty: true });
|
|
1679
|
-
handleOnchange && handleOnchange(name ?? "", url2);
|
|
1680
|
-
if (filename) {
|
|
1681
|
-
methods?.setValue(
|
|
1682
|
-
rootField ? `${rootField?.name}.${index}.${filename}` : filename,
|
|
1683
|
-
url2?.split("/").pop(),
|
|
1684
|
-
{ shouldDirty: true }
|
|
1685
|
-
);
|
|
1686
|
-
handleOnchange && handleOnchange(
|
|
1687
|
-
rootField ? `${rootField?.name}.${index}.${filename}` : filename,
|
|
1688
|
-
url2?.split("/").pop()
|
|
1689
|
-
);
|
|
1690
|
-
}
|
|
1691
|
-
setUrl(url2);
|
|
1692
|
-
fetchFileMeta(url2);
|
|
1693
|
-
return url2;
|
|
1694
|
-
};
|
|
1695
|
-
const onDeleteFile = () => {
|
|
1696
|
-
if (filename) {
|
|
1697
|
-
methods?.setValue(
|
|
1698
|
-
rootField ? `${rootField?.name}.${index}.${filename}` : filename,
|
|
1699
|
-
null,
|
|
1700
|
-
{ shouldDirty: true }
|
|
1701
|
-
);
|
|
1702
|
-
handleOnchange && handleOnchange(
|
|
1703
|
-
rootField ? `${rootField?.name}.${index}.${filename}` : filename,
|
|
1704
|
-
null
|
|
1705
|
-
);
|
|
1706
|
-
}
|
|
1707
|
-
setUrl(null);
|
|
1708
|
-
setFileInfo(null);
|
|
1709
|
-
methods?.setValue(name, null, { shouldDirty: true });
|
|
1710
|
-
handleOnchange && handleOnchange(name ?? "", null);
|
|
1711
|
-
};
|
|
1712
|
-
return {
|
|
1713
|
-
onUploadFile,
|
|
1714
|
-
onDeleteFile,
|
|
1715
|
-
fileInfo,
|
|
1716
|
-
url
|
|
1717
|
-
};
|
|
1718
|
-
};
|
|
1719
|
-
|
|
1720
|
-
// src/widget/basic/many2many-binary-field/controller.tsx
|
|
1721
|
-
import { useId as useId2, useRef as useRef3, useState as useState13 } from "react";
|
|
1722
|
-
var many2manyBinaryController = (props) => {
|
|
1723
|
-
const {
|
|
1724
|
-
name,
|
|
1725
|
-
methods,
|
|
1726
|
-
value,
|
|
1727
|
-
onChange: handleOnchange,
|
|
1728
|
-
service,
|
|
1729
|
-
xNode,
|
|
1730
|
-
path
|
|
1731
|
-
} = props;
|
|
1732
|
-
const inputId = useId2();
|
|
1733
|
-
const { useUploadFile: useUploadFile2 } = (0, provider_exports.useService)();
|
|
1734
|
-
const { mutateAsync } = useUploadFile2();
|
|
1735
|
-
const binaryRef = useRef3(null);
|
|
1736
|
-
const [initialFiles, setInitialFiles] = useState13(
|
|
1737
|
-
Array.isArray(value) ? value : value ? [value] : []
|
|
1738
|
-
);
|
|
1739
|
-
const checkIsImageLink = (url) => {
|
|
1740
|
-
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
1741
|
-
return imageExtensions.test(url) || isBase64Image(url) || isBlobUrl(url);
|
|
1742
|
-
};
|
|
1743
|
-
const sanitizeForBE = (list) => list.filter((x) => x?.datas && !isBlobUrl(x.datas)).map((x) => ({ name: x.name, datas: x.datas, mimetype: x.mimetype }));
|
|
1744
|
-
const isBase64Image = (str) => {
|
|
1745
|
-
const base64Regex = /^data:image\/(png|jpeg|jpg|gif|webp);base64,/;
|
|
1746
|
-
if (!base64Regex.test(str)) {
|
|
1747
|
-
return false;
|
|
1748
|
-
}
|
|
1749
|
-
try {
|
|
1750
|
-
const base64Data = str.split(",")[1];
|
|
1751
|
-
return !!base64Data && atob(base64Data).length > 0;
|
|
1752
|
-
} catch (error) {
|
|
1753
|
-
return false;
|
|
1754
|
-
}
|
|
1755
|
-
};
|
|
1756
|
-
const handleFileChange = async (files, e, oldValues) => {
|
|
1757
|
-
try {
|
|
1758
|
-
const uploadedUrls = await Promise.all(
|
|
1759
|
-
files.map(async (f) => {
|
|
1760
|
-
const formData = new FormData();
|
|
1761
|
-
formData.append("file", f);
|
|
1762
|
-
const res = await mutateAsync({ formData, service, xNode, path });
|
|
1763
|
-
return res?.url;
|
|
1764
|
-
})
|
|
1765
|
-
);
|
|
1766
|
-
const uploadedItems = files.map((f, i) => ({
|
|
1767
|
-
name: f.name,
|
|
1768
|
-
datas: uploadedUrls[i] ?? "",
|
|
1769
|
-
mimetype: f.type
|
|
1770
|
-
}));
|
|
1771
|
-
const finalList = [...oldValues, ...uploadedItems];
|
|
1772
|
-
methods?.setValue(name, finalList, { shouldDirty: true });
|
|
1773
|
-
const payloadForBE = sanitizeForBE(finalList);
|
|
1774
|
-
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
1775
|
-
} catch (err) {
|
|
1776
|
-
console.error(err);
|
|
1777
|
-
} finally {
|
|
1778
|
-
e.target.value = "";
|
|
1779
|
-
}
|
|
1780
|
-
};
|
|
1781
|
-
const handleRemoveAt = (idx) => {
|
|
1782
|
-
const current = methods?.getValues(name) || [];
|
|
1783
|
-
const next = current.filter((_, i) => i !== idx);
|
|
1784
|
-
setInitialFiles((p) => p.filter((_, i) => i !== idx));
|
|
1785
|
-
methods?.setValue(name, next.length ? next : null, { shouldDirty: true });
|
|
1786
|
-
const payloadForBE = next.length ? sanitizeForBE(next) : null;
|
|
1787
|
-
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
1788
|
-
};
|
|
1789
|
-
const handleRemoveAll = () => {
|
|
1790
|
-
setInitialFiles([]);
|
|
1791
|
-
methods?.setValue(name, null, { shouldDirty: true });
|
|
1792
|
-
handleOnchange && handleOnchange(name ?? "", null);
|
|
1793
|
-
};
|
|
1794
|
-
return {
|
|
1795
|
-
inputId,
|
|
1796
|
-
initialFiles,
|
|
1797
|
-
binaryRef,
|
|
1798
|
-
handleFileChange,
|
|
1799
|
-
handleRemoveAt,
|
|
1800
|
-
handleRemoveAll,
|
|
1801
|
-
checkIsImageLink,
|
|
1802
|
-
setInitialFiles
|
|
1803
|
-
};
|
|
1804
|
-
};
|
|
1805
|
-
|
|
1806
|
-
// src/widget/basic/provider-einvoice-field/controller.ts
|
|
1807
|
-
var providerEinvoiceFieldController = (props) => {
|
|
1808
|
-
const { relation, formValues, options: fieldOptions, xNode } = props;
|
|
1809
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
1810
|
-
const { action } = useAppProvider();
|
|
1811
|
-
const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
|
|
1812
|
-
const contextObject = {
|
|
1813
|
-
...(typeof action?.context === "string" ? (0, utils_exports.evalJSONContext)(action?.context) : action?.context) || {},
|
|
1814
|
-
...env?.context
|
|
1815
|
-
};
|
|
1816
|
-
const optionsObject = typeof fieldOptions === "string" ? (0, utils_exports.evalJSONContext)(fieldOptions, {
|
|
1817
|
-
...formValues,
|
|
1818
|
-
...contextObject,
|
|
1819
|
-
context: contextObject,
|
|
1820
|
-
parent: { ...formValues }
|
|
1821
|
-
}) : fieldOptions;
|
|
1822
|
-
const data = {
|
|
1823
|
-
model: optionsObject?.model,
|
|
1824
|
-
domain: optionsObject?.domain,
|
|
1825
|
-
context: {
|
|
1826
|
-
...contextObject,
|
|
1827
|
-
...optionsObject?.context
|
|
1828
|
-
},
|
|
1829
|
-
specification: optionsObject?.specification
|
|
1830
|
-
};
|
|
1831
|
-
const { data: listDataCard } = useGetSelection3({
|
|
1832
|
-
data,
|
|
1833
|
-
queryKey: [`data_${relation}`],
|
|
1834
|
-
enabled: true,
|
|
1835
|
-
service: optionsObject?.service,
|
|
1836
|
-
xNode
|
|
1837
|
-
});
|
|
1838
|
-
return {
|
|
1839
|
-
listDataCard
|
|
1840
|
-
};
|
|
1841
|
-
};
|
|
1842
|
-
|
|
1843
|
-
// src/widget/advance/table/table-head/controller.ts
|
|
1844
|
-
import { useMemo as useMemo10, useRef as useRef4 } from "react";
|
|
1845
|
-
var tableHeadController = (props) => {
|
|
1846
|
-
const {
|
|
1847
|
-
typeTable,
|
|
1848
|
-
rows,
|
|
1849
|
-
tableRef,
|
|
1850
|
-
groupByList,
|
|
1851
|
-
selectedRowKeys,
|
|
1852
|
-
setSelectedRowKeys
|
|
1853
|
-
} = props;
|
|
1854
|
-
const { rowIds: recordIds } = useGetRowIds(tableRef);
|
|
1855
|
-
const selectedRowKeysRef = useRef4(recordIds);
|
|
1856
|
-
const isGroupTable = typeTable === "group";
|
|
1857
|
-
const recordsCheckedGroup = useMemo10(() => {
|
|
1858
|
-
if (!rows || !groupByList) return 0;
|
|
1859
|
-
const groupBy = typeof groupByList === "object" ? groupByList?.contexts?.[0]?.group_by : void 0;
|
|
1860
|
-
return countSum(rows, groupBy);
|
|
1861
|
-
}, [rows, groupByList]);
|
|
1862
|
-
const isAllGroupChecked = useMemo10(() => {
|
|
1863
|
-
if (!isGroupTable || !selectedRowKeys?.length) return false;
|
|
1864
|
-
const selectedLength = selectedRowKeys.filter((id) => id !== -1).length;
|
|
1865
|
-
const allRecordsSelected = recordIds.length === selectedRowKeys.length ? recordIds.length === selectedLength : false;
|
|
1866
|
-
const allGroupsSelected = recordsCheckedGroup === selectedRowKeys.length;
|
|
1867
|
-
return allGroupsSelected || allRecordsSelected;
|
|
1868
|
-
}, [isGroupTable, selectedRowKeys, recordIds, recordsCheckedGroup]);
|
|
1869
|
-
const isAllNormalChecked = useMemo10(() => {
|
|
1870
|
-
if (isGroupTable || !selectedRowKeys?.length || !rows?.length) return false;
|
|
1871
|
-
return selectedRowKeys.length === rows.length && selectedRowKeys.every(
|
|
1872
|
-
(id) => rows.some((record) => record.id === id)
|
|
1873
|
-
);
|
|
1874
|
-
}, [isGroupTable, selectedRowKeys, rows]);
|
|
1875
|
-
const checkedAll = isAllGroupChecked || isAllNormalChecked;
|
|
1876
|
-
const handleCheckBoxAll = (event) => {
|
|
1877
|
-
if (event?.target?.checked && typeTable === "list") {
|
|
1878
|
-
const allRowKeys = Array.isArray(rows) ? rows.map((record) => record?.id) : [];
|
|
1879
|
-
setSelectedRowKeys(allRowKeys);
|
|
1880
|
-
} else if (event?.target?.checked && typeTable === "group") {
|
|
1881
|
-
const rowsIDs = document.querySelectorAll("tr[data-row-id]");
|
|
1882
|
-
const ids = Array.from(rowsIDs)?.map(
|
|
1883
|
-
(row) => Number(row?.getAttribute("data-row-id"))
|
|
1884
|
-
);
|
|
1885
|
-
if (ids?.length > 0) {
|
|
1886
|
-
setSelectedRowKeys(ids);
|
|
1887
|
-
} else {
|
|
1888
|
-
const sum = countSum(
|
|
1889
|
-
rows,
|
|
1890
|
-
typeof groupByList === "object" ? groupByList?.contexts?.[0]?.group_by : void 0
|
|
1891
|
-
);
|
|
1892
|
-
const keys = Array.from({ length: sum }, (_) => void 0);
|
|
1893
|
-
setSelectedRowKeys(keys);
|
|
1894
|
-
}
|
|
1895
|
-
if (selectedRowKeysRef) {
|
|
1896
|
-
selectedRowKeysRef.current = [];
|
|
1897
|
-
}
|
|
1898
|
-
} else {
|
|
1899
|
-
setSelectedRowKeys([]);
|
|
1900
|
-
}
|
|
1901
|
-
};
|
|
1902
|
-
return {
|
|
1903
|
-
handleCheckBoxAll,
|
|
1904
|
-
checkedAll,
|
|
1905
|
-
selectedRowKeysRef
|
|
1906
|
-
};
|
|
1907
|
-
};
|
|
1908
|
-
|
|
1909
|
-
// src/widget/advance/table/table-view/controller.ts
|
|
1910
|
-
import { useCallback as useCallback6, useEffect as useEffect13, useMemo as useMemo11, useState as useState14 } from "react";
|
|
1911
|
-
import { domainHelper } from "@fctc/interface-logic/utils";
|
|
1912
|
-
var tableController = ({ data }) => {
|
|
1913
|
-
const [rows, setRows] = useState14([]);
|
|
1914
|
-
const [columnVisibility, setColumnVisibility] = useState14({});
|
|
1915
|
-
const dataModelFields = useMemo11(() => {
|
|
1916
|
-
return data?.fields?.map((field) => ({
|
|
1917
|
-
...data.dataModel?.[field?.name],
|
|
1918
|
-
...field,
|
|
1919
|
-
string: field?.string || data.dataModel?.[field?.name]?.string
|
|
1920
|
-
})) ?? [];
|
|
1921
|
-
}, [data?.fields, data?.dataModel]);
|
|
1922
|
-
const mergeFields = useMemo11(
|
|
1923
|
-
() => mergeButtons(dataModelFields),
|
|
1924
|
-
[dataModelFields]
|
|
1925
|
-
);
|
|
1926
|
-
const transformData = useCallback6(
|
|
1927
|
-
(dataList) => {
|
|
1928
|
-
if (!dataList) return [];
|
|
1929
|
-
return dataList.map((item) => {
|
|
1930
|
-
const transformedItem = { ...item };
|
|
1931
|
-
Object.keys(item).forEach((field) => {
|
|
1932
|
-
if (field !== "__domain") {
|
|
1933
|
-
if (item[field] && typeof item[field] === "object" && item[field].display_name) {
|
|
1934
|
-
transformedItem[field] = item[field];
|
|
1935
|
-
} else if (Array.isArray(item[field]) && item[field].length > 0) {
|
|
1936
|
-
if (data.typeTable === "group" && item[field]?.length === 2 && typeof item[field]?.[1] === "string") {
|
|
1937
|
-
transformedItem["string"] = item[field]?.[1];
|
|
1938
|
-
}
|
|
1939
|
-
transformedItem[field] = item[field];
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
});
|
|
1943
|
-
return item.display_name ? { ...transformedItem, item: item.display_name } : transformedItem;
|
|
1944
|
-
});
|
|
1945
|
-
},
|
|
1946
|
-
[data?.typeTable]
|
|
1947
|
-
);
|
|
1948
|
-
useEffect13(() => {
|
|
1949
|
-
setRows(transformData(data?.records));
|
|
1950
|
-
}, [data?.records, transformData]);
|
|
1951
|
-
const columns = useMemo11(() => {
|
|
1952
|
-
try {
|
|
1953
|
-
return mergeFields?.filter((item) => {
|
|
1954
|
-
return item?.widget !== "details_Receive_money" && !(item?.column_invisible ? domainHelper.matchDomains(
|
|
1955
|
-
data.context,
|
|
1956
|
-
item?.column_invisible
|
|
1957
|
-
) : item?.invisible ? domainHelper.matchDomains(data.context, item?.invisible) : false);
|
|
1958
|
-
})?.map((field) => {
|
|
1959
|
-
const overridden = columnVisibility[field?.name];
|
|
1960
|
-
return {
|
|
1961
|
-
name: field?.name,
|
|
1962
|
-
optional: overridden ?? field?.optional,
|
|
1963
|
-
title: field?.type_co === "button" ? "" : field?.string,
|
|
1964
|
-
field: { ...field }
|
|
1965
|
-
};
|
|
1966
|
-
}) ?? [];
|
|
1967
|
-
} catch (error) {
|
|
1968
|
-
console.error("Error in useTable:", error);
|
|
1969
|
-
return [];
|
|
1970
|
-
}
|
|
1971
|
-
}, [mergeFields, data?.context, columnVisibility]);
|
|
1972
|
-
const onToggleColumnOptional = useCallback6((item) => {
|
|
1973
|
-
setColumnVisibility((prev) => ({
|
|
1974
|
-
...prev,
|
|
1975
|
-
[item?.name]: item?.optional === "show" ? "hide" : "show"
|
|
1976
|
-
}));
|
|
1977
|
-
}, []);
|
|
1978
|
-
return {
|
|
1979
|
-
rows,
|
|
1980
|
-
columns,
|
|
1981
|
-
onToggleColumnOptional,
|
|
1982
|
-
typeTable: data?.typeTable
|
|
1983
|
-
};
|
|
1984
|
-
};
|
|
1985
|
-
|
|
1986
|
-
// src/widget/advance/table/table-group/controller.ts
|
|
1987
|
-
import { useMemo as useMemo12, useState as useState15 } from "react";
|
|
1988
|
-
var tableGroupController = (props) => {
|
|
1989
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
1990
|
-
const { useGetListData: useGetListData2 } = (0, provider_exports.useService)();
|
|
1991
|
-
const {
|
|
1992
|
-
columns,
|
|
1993
|
-
row,
|
|
1994
|
-
model,
|
|
1995
|
-
viewData,
|
|
1996
|
-
level,
|
|
1997
|
-
specification,
|
|
1998
|
-
context,
|
|
1999
|
-
checkedAll,
|
|
2000
|
-
groupByList,
|
|
2001
|
-
setSelectedRowKeys
|
|
2002
|
-
} = props;
|
|
2003
|
-
const [pageGroup, setPageGroup] = useState15(0);
|
|
2004
|
-
const [isShowGroup, setIsShowGroup] = useState15(false);
|
|
2005
|
-
const [colEmptyGroup, setColEmptyGroup] = useState15({
|
|
2006
|
-
fromStart: 1,
|
|
2007
|
-
fromEnd: 1
|
|
2008
|
-
});
|
|
2009
|
-
const domain = row?.__domain;
|
|
2010
|
-
const processedData = useMemo12(() => {
|
|
2011
|
-
const calculateColSpanEmpty = () => {
|
|
2012
|
-
const startIndex = columns.findIndex(
|
|
2013
|
-
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
|
|
2014
|
-
);
|
|
2015
|
-
const endIndex = columns.findLastIndex(
|
|
2016
|
-
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
|
|
2017
|
-
);
|
|
2018
|
-
const fromStart = startIndex === -1 ? columns.length : startIndex;
|
|
2019
|
-
const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
|
|
2020
|
-
setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
|
|
2021
|
-
return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
|
|
2022
|
-
};
|
|
2023
|
-
return calculateColSpanEmpty();
|
|
2024
|
-
}, [columns, row]);
|
|
2025
|
-
const shouldFetchData = useMemo12(() => {
|
|
2026
|
-
return !!isShowGroup;
|
|
2027
|
-
}, [isShowGroup]);
|
|
2028
|
-
const enabled = shouldFetchData && !!processedData;
|
|
2029
|
-
const listDataProps = {
|
|
2030
|
-
model,
|
|
2031
|
-
specification,
|
|
2032
|
-
domain,
|
|
2033
|
-
context,
|
|
2034
|
-
offset: pageGroup * 10,
|
|
2035
|
-
fields: groupByList?.fields,
|
|
2036
|
-
groupby: [groupByList?.contexts[level]?.group_by],
|
|
2037
|
-
limit: 10
|
|
2038
|
-
};
|
|
2039
|
-
const queryKey = [
|
|
2040
|
-
`data-${model}-level_${level}-row-${row?.id}`,
|
|
2041
|
-
specification,
|
|
2042
|
-
domain,
|
|
2043
|
-
pageGroup
|
|
2044
|
-
];
|
|
2045
|
-
const {
|
|
2046
|
-
data: dataGroup,
|
|
2047
|
-
isFetched: isDataGroupFetched,
|
|
2048
|
-
isLoading,
|
|
2049
|
-
isFetching,
|
|
2050
|
-
isPlaceholderData: isDataPlaceHolder
|
|
2051
|
-
} = useGetListData2(listDataProps, queryKey, enabled);
|
|
2052
|
-
const {
|
|
2053
|
-
columns: columnsGroup,
|
|
2054
|
-
rows: rowsGroup,
|
|
2055
|
-
typeTable: typeTableGroup
|
|
2056
|
-
} = tableController({
|
|
2057
|
-
data: {
|
|
2058
|
-
fields: viewData?.views?.list?.fields,
|
|
2059
|
-
records: dataGroup?.records ?? dataGroup?.groups,
|
|
2060
|
-
dataModel: viewData?.models?.[model],
|
|
2061
|
-
context: env.context,
|
|
2062
|
-
typeTable: dataGroup?.groups ? "group" : "list"
|
|
2063
|
-
}
|
|
2064
|
-
});
|
|
2065
|
-
const group_by_field_name = groupByList?.contexts[level - 1]?.group_by;
|
|
2066
|
-
const nameGroup = Array.isArray(row[group_by_field_name]) ? row?.string ?? row[`${group_by_field_name}`][1] : viewData?.models?.[model]?.[group_by_field_name]?.selection ? viewData.models[model][group_by_field_name].selection.find(
|
|
2067
|
-
(selectItem) => selectItem?.[0] === row[group_by_field_name]
|
|
2068
|
-
)?.[1] : row[group_by_field_name];
|
|
2069
|
-
const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
|
|
2070
|
-
return {
|
|
2071
|
-
// onExpandChildGroup,
|
|
2072
|
-
colEmptyGroup,
|
|
2073
|
-
isShowGroup,
|
|
2074
|
-
isDataGroupFetched,
|
|
2075
|
-
isDataPlaceHolder,
|
|
2076
|
-
// nameGroupWithCount,
|
|
2077
|
-
columnsGroup,
|
|
2078
|
-
rowsGroup,
|
|
2079
|
-
dataGroup,
|
|
2080
|
-
pageGroup,
|
|
2081
|
-
setPageGroup,
|
|
2082
|
-
typeTableGroup
|
|
2083
|
-
};
|
|
2084
|
-
};
|
|
2085
|
-
|
|
2086
|
-
// src/widget/advance/search/controller.ts
|
|
2087
|
-
import moment2 from "moment";
|
|
2088
|
-
import { useCallback as useCallback7, useEffect as useEffect14, useState as useState16 } from "react";
|
|
2089
|
-
|
|
2090
|
-
// src/constants.ts
|
|
2091
|
-
var constants_exports = {};
|
|
2092
|
-
__reExport(constants_exports, constants_star);
|
|
2093
|
-
import * as constants_star from "@fctc/interface-logic/constants";
|
|
2094
|
-
|
|
2095
|
-
// src/widget/advance/search/controller.ts
|
|
2096
|
-
var searchController = ({
|
|
2097
|
-
viewData,
|
|
2098
|
-
model,
|
|
2099
|
-
domain,
|
|
2100
|
-
context,
|
|
2101
|
-
fieldsList
|
|
2102
|
-
}) => {
|
|
2103
|
-
const { env } = (0, provider_exports.useEnv)();
|
|
2104
|
-
const [filterBy, setFilterBy] = useState16(null);
|
|
2105
|
-
const [searchBy, setSearchBy] = useState16(null);
|
|
2106
|
-
const [groupBy, setGroupBy] = useState16(null);
|
|
2107
|
-
const [selectedTags, setSelectedTags] = useState16(null);
|
|
2108
|
-
const [searchString, setSearchString] = useState16("");
|
|
2109
|
-
const [searchMap, setSearchMap] = useState16({});
|
|
2110
|
-
const [hoveredIndex, setHoveredIndex] = useState16(0);
|
|
2111
|
-
const [hoveredIndexSearchList, setHoveredIndexSearchList] = useState16(0);
|
|
2112
|
-
const actionContext = typeof context === "string" ? (0, utils_exports.evalJSONContext)(context) : context;
|
|
2113
|
-
const contextSearch = { ...env.context, ...actionContext };
|
|
2114
|
-
const domainAction = domain ? Array.isArray(domain) ? [...domain] : (0, utils_exports.evalJSONDomain)(domain, contextSearch) : [];
|
|
2115
|
-
const clearSearch = () => {
|
|
2116
|
-
setFilterBy([]);
|
|
2117
|
-
setGroupBy([]);
|
|
2118
|
-
setSearchBy([]);
|
|
2119
|
-
setSelectedTags(null);
|
|
2120
|
-
setSearchString("");
|
|
2121
|
-
setSearchMap({});
|
|
2122
|
-
};
|
|
2123
|
-
const fetchData = async () => {
|
|
2124
|
-
if (viewData) {
|
|
2125
|
-
try {
|
|
2126
|
-
const dataModel = viewData?.models?.[model];
|
|
2127
|
-
const searchViews = viewData?.views?.search;
|
|
2128
|
-
const searchByItems = searchViews?.search_by?.filter(
|
|
2129
|
-
(item) => !utils_exports.domainHelper.matchDomains(contextSearch, item.invisible)
|
|
2130
|
-
)?.map(
|
|
2131
|
-
({ string, name, filter_domain, operator, widget }, index) => ({
|
|
2132
|
-
dataIndex: index,
|
|
2133
|
-
title: string ?? dataModel?.[name]?.string,
|
|
2134
|
-
name: name ?? dataModel?.[name]?.name,
|
|
2135
|
-
filter_domain,
|
|
2136
|
-
operator,
|
|
2137
|
-
widget,
|
|
2138
|
-
type: dataModel?.[name]?.type
|
|
2139
|
-
})
|
|
2140
|
-
);
|
|
2141
|
-
const filterByItems = searchViews?.filter_by.filter((item) => {
|
|
2142
|
-
return !utils_exports.domainHelper.matchDomains(contextSearch, item?.invisible);
|
|
2143
|
-
})?.map((item) => ({ ...item, active: false }));
|
|
2144
|
-
const groupByItems = searchViews?.group_by.filter(
|
|
2145
|
-
(item) => !utils_exports.domainHelper.matchDomains(contextSearch, item?.invisible)
|
|
2146
|
-
).map((item) => ({
|
|
2147
|
-
...item,
|
|
2148
|
-
string: item.string ?? viewData?.models?.[model]?.[item?.name?.split("group_by_")?.[1]]?.string
|
|
2149
|
-
}));
|
|
2150
|
-
setSearchBy(searchByItems);
|
|
2151
|
-
setFilterBy(filterByItems);
|
|
2152
|
-
setGroupBy(groupByItems);
|
|
2153
|
-
} catch (error) {
|
|
2154
|
-
console.error("Error fetching data:", error);
|
|
2155
|
-
}
|
|
2156
|
-
}
|
|
2157
|
-
};
|
|
2158
|
-
useEffect14(() => {
|
|
2159
|
-
fetchData();
|
|
2160
|
-
}, [model, viewData]);
|
|
2161
|
-
const onChangeSearchInput = (search_string) => {
|
|
2162
|
-
setSearchString(search_string);
|
|
2163
|
-
};
|
|
2164
|
-
const removeKeyFromSearchMap = ({
|
|
2165
|
-
key,
|
|
2166
|
-
item
|
|
2167
|
-
}) => {
|
|
2168
|
-
const values = searchMap[key];
|
|
2169
|
-
if (!values) return searchMap;
|
|
2170
|
-
const newSearchMap = { ...searchMap };
|
|
2171
|
-
if (item) {
|
|
2172
|
-
const filtered = values.filter((value) => value.name !== item.name);
|
|
2173
|
-
if (filtered.length > 0) {
|
|
2174
|
-
newSearchMap[key] = filtered;
|
|
2175
|
-
} else {
|
|
2176
|
-
delete newSearchMap[key];
|
|
2177
|
-
}
|
|
2178
|
-
} else {
|
|
2179
|
-
delete newSearchMap[key];
|
|
2180
|
-
}
|
|
2181
|
-
setSearchMap(newSearchMap);
|
|
2182
|
-
};
|
|
2183
|
-
const updateSearchMap = ({ key, item }) => {
|
|
2184
|
-
const newSearchMap = { ...searchMap };
|
|
2185
|
-
const currentValues = searchMap[key] ?? [];
|
|
2186
|
-
newSearchMap[key] = [...currentValues, item];
|
|
2187
|
-
setSearchMap(newSearchMap);
|
|
2188
|
-
};
|
|
2189
|
-
const removeSearchItems = (key, item) => {
|
|
2190
|
-
removeKeyFromSearchMap({ key: String(key), item });
|
|
2191
|
-
};
|
|
2192
|
-
const addSearchItems = (key, newItem) => {
|
|
2193
|
-
updateSearchMap({ key, item: newItem });
|
|
2194
|
-
};
|
|
2195
|
-
const formatDomain = () => {
|
|
2196
|
-
if (domainAction) {
|
|
2197
|
-
const domain2 = [];
|
|
2198
|
-
if (Array.isArray(domainAction) && domainAction.length > 0) {
|
|
2199
|
-
if (Object.keys(searchMap).some((key) => !key.includes(constants_exports.SearchType.GROUP))) {
|
|
2200
|
-
domain2.push("&");
|
|
2201
|
-
}
|
|
2202
|
-
domainAction.forEach((domainItem) => {
|
|
2203
|
-
domain2.push(domainItem);
|
|
2204
|
-
});
|
|
2205
|
-
}
|
|
2206
|
-
Object.keys(searchMap).forEach((key, keyIndex, keys) => {
|
|
2207
|
-
if (!key?.includes(constants_exports.SearchType.GROUP)) {
|
|
2208
|
-
if (keys.length > 1 && keyIndex < keys.length - 1) {
|
|
2209
|
-
domain2.push("&");
|
|
2210
|
-
}
|
|
2211
|
-
const valuesOfKey = searchMap[key];
|
|
2212
|
-
valuesOfKey.forEach((value, index) => {
|
|
2213
|
-
if (index < valuesOfKey.length - 1) {
|
|
2214
|
-
domain2.push("|");
|
|
2215
|
-
}
|
|
2216
|
-
if (value.domain) {
|
|
2217
|
-
domain2.push(...value.domain);
|
|
2218
|
-
return;
|
|
2219
|
-
}
|
|
2220
|
-
let valueDomainItem = value?.value;
|
|
2221
|
-
if (value?.modelType === "date") {
|
|
2222
|
-
valueDomainItem = validateAndParseDate(value?.value);
|
|
2223
|
-
} else if (value?.modelType === "datetime") {
|
|
2224
|
-
if (value?.operator === "<=" || value?.operator === "<") {
|
|
2225
|
-
const parsedDate = validateAndParseDate(value?.value, true);
|
|
2226
|
-
const hasTime = moment2(value?.value).format("HH:mm:ss") !== "00:00:00";
|
|
2227
|
-
valueDomainItem = hasTime ? moment2(parsedDate).format("YYYY-MM-DD HH:mm:ss") : moment2(parsedDate).add(1, "day").subtract(1, "second").format("YYYY-MM-DD HH:mm:ss");
|
|
2228
|
-
} else {
|
|
2229
|
-
valueDomainItem = validateAndParseDate(value?.value, true);
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
const operator = value?.modelType === "date" || value?.modelType === "datetime" || value?.modelType === "boolean" || value?.modelType === "integer" ? value?.operator ?? "=" : value.operator ?? "ilike";
|
|
2233
|
-
domain2.push([value.name, operator, valueDomainItem]);
|
|
2234
|
-
});
|
|
2235
|
-
}
|
|
2236
|
-
});
|
|
2237
|
-
return [...domain2];
|
|
2238
|
-
}
|
|
2239
|
-
};
|
|
2240
|
-
const setTagSearch = useCallback7(
|
|
2241
|
-
(updatedMap) => {
|
|
2242
|
-
if (!updatedMap) return;
|
|
2243
|
-
const tagsSearch = Object.entries(updatedMap).map(
|
|
2244
|
-
([key, objValues]) => {
|
|
2245
|
-
const {
|
|
2246
|
-
title,
|
|
2247
|
-
name,
|
|
2248
|
-
groupIndex,
|
|
2249
|
-
type,
|
|
2250
|
-
widget,
|
|
2251
|
-
modelType,
|
|
2252
|
-
dataIndex
|
|
2253
|
-
} = objValues[0];
|
|
2254
|
-
if (!key?.includes(constants_exports.SearchType.GROUP)) {
|
|
2255
|
-
const values = objValues?.map((objValue) => objValue.value);
|
|
2256
|
-
return {
|
|
2257
|
-
title,
|
|
2258
|
-
name: type === constants_exports.SearchType.SEARCH ? `${constants_exports.SearchType.SEARCH}_${String(dataIndex)}` : groupIndex ?? name,
|
|
2259
|
-
values,
|
|
2260
|
-
type,
|
|
2261
|
-
widget,
|
|
2262
|
-
modelType
|
|
2263
|
-
};
|
|
2264
|
-
} else {
|
|
2265
|
-
const contexts = [];
|
|
2266
|
-
let groupValues = [];
|
|
2267
|
-
objValues?.forEach((objValue) => {
|
|
2268
|
-
const { context: context2, value, active, groupIndex: groupIndex2, isDefault } = objValue;
|
|
2269
|
-
const indexAppend = groupIndex2 != null ? groupIndex2 : viewData?.views?.search?.filters_by?.length ?? 0;
|
|
2270
|
-
contexts.push(
|
|
2271
|
-
...Array.isArray(context2?.group_by) ? context2.group_by.map((item) => ({ group_by: item })) : [context2]
|
|
2272
|
-
);
|
|
2273
|
-
groupValues[indexAppend] = {
|
|
2274
|
-
contexts: [
|
|
2275
|
-
...Array.isArray(context2?.group_by) ? context2.group_by.map((item) => ({
|
|
2276
|
-
group_by: item
|
|
2277
|
-
})) : [context2]
|
|
2278
|
-
],
|
|
2279
|
-
strings: isDefault ? [value] : [...groupValues[indexAppend]?.strings ?? [], value]
|
|
2280
|
-
};
|
|
2281
|
-
});
|
|
2282
|
-
const fields = [
|
|
2283
|
-
...new Set(fieldsList?.map((item) => item?.name))
|
|
2284
|
-
];
|
|
2285
|
-
const groupByTag = {
|
|
2286
|
-
title,
|
|
2287
|
-
values: groupValues?.filter(
|
|
2288
|
-
(item) => item !== void 0
|
|
2289
|
-
),
|
|
2290
|
-
type,
|
|
2291
|
-
contexts,
|
|
2292
|
-
fields
|
|
2293
|
-
};
|
|
2294
|
-
return groupByTag;
|
|
2295
|
-
}
|
|
2296
|
-
}
|
|
2297
|
-
);
|
|
2298
|
-
setSelectedTags(tagsSearch);
|
|
2299
|
-
setSearchString("");
|
|
2300
|
-
},
|
|
2301
|
-
[searchMap]
|
|
2302
|
-
);
|
|
2303
|
-
useEffect14(() => {
|
|
2304
|
-
setTagSearch(searchMap);
|
|
2305
|
-
}, [searchMap]);
|
|
2306
|
-
const handleAddTagSearch = (tag) => {
|
|
2307
|
-
const { domain: domain2, groupIndex, value, type, context: context2, dataIndex } = tag;
|
|
2308
|
-
const domainFormat = new utils_exports.domainHelper.Domain(domain2);
|
|
2309
|
-
if (type === constants_exports.SearchType.FILTER) {
|
|
2310
|
-
addSearchItems(`${constants_exports.SearchType.FILTER}_${groupIndex}`, {
|
|
2311
|
-
...tag,
|
|
2312
|
-
domain: domain2 ? domainFormat.toList(context2) : null
|
|
2313
|
-
});
|
|
2314
|
-
} else if (type === constants_exports.SearchType.SEARCH) {
|
|
2315
|
-
addSearchItems(`${constants_exports.SearchType.SEARCH}_${String(dataIndex)}`, {
|
|
2316
|
-
...tag,
|
|
2317
|
-
domain: domain2 ? domainFormat.toList({
|
|
2318
|
-
...context2,
|
|
2319
|
-
self: value
|
|
2320
|
-
}) : null
|
|
2321
|
-
});
|
|
2322
|
-
} else if (type === constants_exports.SearchType.GROUP) {
|
|
2323
|
-
addSearchItems(`${constants_exports.SearchType.GROUP}`, {
|
|
2324
|
-
...tag,
|
|
2325
|
-
domain: domain2 ? domainFormat.toList({
|
|
2326
|
-
context: context2,
|
|
2327
|
-
self: value
|
|
2328
|
-
}) : null
|
|
2329
|
-
});
|
|
2330
|
-
}
|
|
2331
|
-
};
|
|
2332
|
-
const onKeyDown = (e) => {
|
|
2333
|
-
if (!searchBy || searchBy.length === 0) return;
|
|
2334
|
-
switch (e.key) {
|
|
2335
|
-
case "Backspace": {
|
|
2336
|
-
if (!searchString && selectedTags && selectedTags.length > 0) {
|
|
2337
|
-
const lastTag = selectedTags[selectedTags.length - 1];
|
|
2338
|
-
if (!lastTag) return;
|
|
2339
|
-
const key = lastTag.type === constants_exports.SearchType.GROUP ? constants_exports.SearchType.GROUP : lastTag.name;
|
|
2340
|
-
removeKeyFromSearchMap({ key: String(key) });
|
|
2341
|
-
}
|
|
2342
|
-
break;
|
|
2343
|
-
}
|
|
2344
|
-
case "ArrowDown": {
|
|
2345
|
-
e.preventDefault();
|
|
2346
|
-
setHoveredIndex((prev) => {
|
|
2347
|
-
const maxIndex = searchBy.length - 1;
|
|
2348
|
-
const next = prev < maxIndex ? prev + 1 : prev;
|
|
2349
|
-
setHoveredIndexSearchList(next);
|
|
2350
|
-
return next;
|
|
2351
|
-
});
|
|
2352
|
-
break;
|
|
2353
|
-
}
|
|
2354
|
-
case "ArrowUp": {
|
|
2355
|
-
e.preventDefault();
|
|
2356
|
-
setHoveredIndex((prev) => {
|
|
2357
|
-
const next = prev > 0 ? prev - 1 : prev;
|
|
2358
|
-
setHoveredIndexSearchList(next);
|
|
2359
|
-
return next;
|
|
2360
|
-
});
|
|
2361
|
-
break;
|
|
2362
|
-
}
|
|
2363
|
-
case "Enter": {
|
|
2364
|
-
e.preventDefault();
|
|
2365
|
-
if (!searchString.trim()) return;
|
|
2366
|
-
const head = searchBy[hoveredIndex];
|
|
2367
|
-
if (!head) return;
|
|
2368
|
-
handleAddTagSearch({
|
|
2369
|
-
title: head.title,
|
|
2370
|
-
name: head.name,
|
|
2371
|
-
value: searchString,
|
|
2372
|
-
type: constants_exports.SearchType.SEARCH,
|
|
2373
|
-
domain: head.filter_domain,
|
|
2374
|
-
operator: head.operator,
|
|
2375
|
-
dataIndex: head.dataIndex,
|
|
2376
|
-
widget: head.widget,
|
|
2377
|
-
modelType: head.type
|
|
2378
|
-
});
|
|
2379
|
-
break;
|
|
2380
|
-
}
|
|
2381
|
-
default:
|
|
2382
|
-
break;
|
|
2383
|
-
}
|
|
2384
|
-
};
|
|
2385
|
-
const handleMouseEnter = (index) => {
|
|
2386
|
-
setHoveredIndexSearchList(index);
|
|
2387
|
-
};
|
|
2388
|
-
const handleMouseLeave = () => {
|
|
2389
|
-
setHoveredIndexSearchList(null);
|
|
2390
|
-
};
|
|
2391
|
-
return {
|
|
2392
|
-
groupBy,
|
|
2393
|
-
searchBy,
|
|
2394
|
-
filterBy,
|
|
2395
|
-
selectedTags,
|
|
2396
|
-
searchString,
|
|
2397
|
-
setFilterBy,
|
|
2398
|
-
setGroupBy,
|
|
2399
|
-
setSearchBy,
|
|
2400
|
-
clearSearch,
|
|
2401
|
-
setSelectedTags,
|
|
2402
|
-
removeSearchItems,
|
|
2403
|
-
onSearchString: onChangeSearchInput,
|
|
2404
|
-
handleAddTagSearch,
|
|
2405
|
-
domain: formatDomain(),
|
|
2406
|
-
context: contextSearch,
|
|
2407
|
-
onKeyDown,
|
|
2408
|
-
handleMouseEnter,
|
|
2409
|
-
handleMouseLeave,
|
|
2410
|
-
hoveredIndexSearchList
|
|
2411
|
-
};
|
|
2412
|
-
};
|
|
2413
|
-
export {
|
|
2414
|
-
binaryFieldController,
|
|
2415
|
-
colorFieldController,
|
|
2416
|
-
copyLinkButtonController,
|
|
2417
|
-
downLoadBinaryController,
|
|
2418
|
-
downloadFileController,
|
|
2419
|
-
durationController,
|
|
2420
|
-
many2manyBinaryController,
|
|
2421
|
-
many2manyFieldController,
|
|
2422
|
-
many2manyTagsController,
|
|
2423
|
-
many2oneButtonController,
|
|
2424
|
-
many2oneFieldController,
|
|
2425
|
-
priorityFieldController,
|
|
2426
|
-
providerEinvoiceFieldController,
|
|
2427
|
-
searchController,
|
|
2428
|
-
statusDropdownController,
|
|
2429
|
-
tableController,
|
|
2430
|
-
tableGroupController,
|
|
2431
|
-
tableHeadController
|
|
2432
|
-
};
|