@fctc/widget-logic 1.10.0 → 1.10.1

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.
Files changed (65) hide show
  1. package/dist/config.d.mts +6 -0
  2. package/dist/config.d.ts +6 -0
  3. package/dist/config.js +24 -0
  4. package/dist/config.mjs +2 -0
  5. package/dist/constants.d.mts +1 -0
  6. package/dist/constants.d.ts +1 -0
  7. package/dist/constants.js +24 -0
  8. package/dist/constants.mjs +2 -0
  9. package/dist/environment.d.mts +1 -0
  10. package/dist/environment.d.ts +1 -0
  11. package/dist/environment.js +24 -0
  12. package/dist/environment.mjs +2 -0
  13. package/dist/hooks.d.mts +970 -0
  14. package/dist/hooks.d.ts +970 -0
  15. package/dist/hooks.js +882 -0
  16. package/dist/hooks.mjs +883 -0
  17. package/dist/icons.d.mts +27 -0
  18. package/dist/icons.d.ts +27 -0
  19. package/dist/icons.js +273 -0
  20. package/dist/icons.mjs +239 -0
  21. package/dist/index.d.mts +18 -4
  22. package/dist/index.d.ts +18 -4
  23. package/dist/index.js +7473 -249
  24. package/dist/index.mjs +7544 -221
  25. package/dist/provider.d.mts +1 -0
  26. package/dist/provider.d.ts +1 -0
  27. package/dist/provider.js +24 -0
  28. package/dist/provider.mjs +2 -0
  29. package/dist/services.d.mts +1 -0
  30. package/dist/services.d.ts +1 -0
  31. package/dist/services.js +24 -0
  32. package/dist/services.mjs +2 -0
  33. package/dist/store.d.mts +1 -0
  34. package/dist/store.d.ts +1 -0
  35. package/dist/store.js +24 -0
  36. package/dist/store.mjs +2 -0
  37. package/dist/types.d.mts +33 -0
  38. package/dist/types.d.ts +33 -0
  39. package/dist/types.js +24 -0
  40. package/dist/types.mjs +2 -0
  41. package/dist/utils.d.mts +47 -0
  42. package/dist/utils.d.ts +47 -0
  43. package/dist/utils.js +321 -0
  44. package/dist/utils.mjs +302 -0
  45. package/dist/widget.d.mts +296 -0
  46. package/dist/widget.d.ts +296 -0
  47. package/dist/widget.js +7254 -0
  48. package/dist/widget.mjs +7291 -0
  49. package/package.json +96 -52
  50. package/dist/action.d.mts +0 -68
  51. package/dist/action.d.ts +0 -68
  52. package/dist/action.js +0 -152
  53. package/dist/action.mjs +0 -122
  54. package/dist/common.d.mts +0 -13
  55. package/dist/common.d.ts +0 -13
  56. package/dist/common.js +0 -60
  57. package/dist/common.mjs +0 -33
  58. package/dist/form.d.mts +0 -42
  59. package/dist/form.d.ts +0 -42
  60. package/dist/form.js +0 -116
  61. package/dist/form.mjs +0 -87
  62. package/dist/table.d.mts +0 -22
  63. package/dist/table.d.ts +0 -22
  64. package/dist/table.js +0 -118
  65. package/dist/table.mjs +0 -91
package/dist/hooks.mjs ADDED
@@ -0,0 +1,883 @@
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/hooks/core/use-call-action.ts
20
+ import { useState } from "react";
21
+ import { getEnv } from "@fctc/interface-logic/environment";
22
+ import { useLoadAction, useRunAction } from "@fctc/interface-logic/hooks";
23
+ var useCallAction = () => {
24
+ const queryLoadAction = useLoadAction();
25
+ const queryRunAction = useRunAction();
26
+ const [data, setData] = useState(void 0);
27
+ const callAction = async ({
28
+ aid,
29
+ actionType = "ir.actions.act_window"
30
+ }) => {
31
+ const context = getEnv().context;
32
+ let res = void 0;
33
+ if (actionType === "ir.actions.act_window") {
34
+ res = await queryLoadAction.mutateAsync({
35
+ idAction: aid,
36
+ context
37
+ });
38
+ } else if (actionType === "ir.actions.server") {
39
+ res = await queryRunAction.mutateAsync({
40
+ idAction: aid,
41
+ context
42
+ });
43
+ }
44
+ setData(res);
45
+ return res;
46
+ };
47
+ return [data, callAction];
48
+ };
49
+
50
+ // src/hooks/core/use-config.ts
51
+ import { useEffect, useMemo } from "react";
52
+ import { getEnv as getEnv2 } from "@fctc/interface-logic/environment";
53
+ import { useAppDispatch, setEnvFile } from "@fctc/interface-logic/store";
54
+ var useConfig = ({ localStorageUtils, sessionStorageUtils }) => {
55
+ const dispatch = useAppDispatch();
56
+ const envConfig = useMemo(() => {
57
+ return {
58
+ mode: "development",
59
+ baseUrl: "https://api.vitrust.app/c2/api/v2",
60
+ config: {
61
+ grantType: "password",
62
+ clientId: "C52foVQSMpnNOcAP2CBIIkupOSfxUarF8nlOPfXM",
63
+ clientSecret: "rColINr4a9QBFQPqQB8YU1XfBjqzwerDMJGBxsFK"
64
+ }
65
+ };
66
+ }, []);
67
+ const config = useMemo(() => {
68
+ return {
69
+ VITE_SIDEBAR_TYPE: "grid/sidebar",
70
+ VITE_APP_DOMAIN: "https://api.vitrust.app/c2/",
71
+ VITE_IS_EDU: true,
72
+ VITE_LOGO_WHITE_LOGIN: "https://static.vitrust.app/vitrust/3a/3a1301f614dea6ee19ebf99b68f57e3fd46011d2.png",
73
+ VITE_LOGO_BLACK_LOGIN: "https://static.vitrust.app/vitrust/32/3223918780da7a439f916faac9abf0bfe98dfa07.png",
74
+ VITE_BACKGROUND_SIDEBAR: "linear-gradient(178deg, rgb(1, 106, 13) -0.89%, rgb(4, 179, 66) 99.46%",
75
+ VITE_BANNER: "https://static.vitrust.app/vitrust/5d/5d20cab0627182b4ed5cba4ee42c58b98b663e5b.svg",
76
+ VITE_BG_BUTTON: "#008F3C",
77
+ VITE_BACKGROUND_PAGE: "#F9FAFB"
78
+ };
79
+ }, []);
80
+ useEffect(() => {
81
+ try {
82
+ const env = getEnv2();
83
+ env.setupEnv({
84
+ baseUrl: envConfig.baseUrl,
85
+ port: 3e3,
86
+ config: {
87
+ grantType: envConfig.config.grantType,
88
+ clientId: envConfig.config.clientId,
89
+ clientSecret: envConfig.config.clientSecret
90
+ },
91
+ db: "preschool",
92
+ localStorageUtils: localStorageUtils(),
93
+ sessionStorageUtils: sessionStorageUtils()
94
+ });
95
+ dispatch(setEnvFile(config));
96
+ } catch (error) {
97
+ console.error("Error loading env or config:", error);
98
+ }
99
+ }, [dispatch, envConfig, config]);
100
+ return { envConfig, config };
101
+ };
102
+
103
+ // src/hooks/core/use-detail.ts
104
+ import { setProfile, useAppDispatch as useAppDispatch2 } from "@fctc/interface-logic/store";
105
+ import { useQuery } from "@tanstack/react-query";
106
+ import { useEffect as useEffect2 } from "react";
107
+ import { useGetDetail } from "@fctc/interface-logic/hooks";
108
+ var useDetail = (accessToken, sub) => {
109
+ const dispatch = useAppDispatch2();
110
+ const fetchGetDetail = useGetDetail();
111
+ const userDetailQuery = useQuery({
112
+ queryKey: ["userDetailQuery", sub && accessToken],
113
+ queryFn: () => {
114
+ return fetchGetDetail.mutateAsync({
115
+ model: "res.users",
116
+ ids: [sub],
117
+ specification: { image_256: {} }
118
+ });
119
+ },
120
+ enabled: !!sub && !!accessToken
121
+ });
122
+ useEffect2(() => {
123
+ if (userDetailQuery.data) {
124
+ const userPicture = userDetailQuery.data;
125
+ dispatch(
126
+ setProfile({ ...userPicture, image: userPicture?.[0]?.image_256 })
127
+ );
128
+ }
129
+ }, [userDetailQuery.data, dispatch]);
130
+ return userDetailQuery;
131
+ };
132
+
133
+ // src/hooks/core/use-list-data.ts
134
+ import { useMemo as useMemo3, useState as useState3 } from "react";
135
+
136
+ // src/utils/function.ts
137
+ import {
138
+ useCallback,
139
+ useEffect as useEffect3,
140
+ useMemo as useMemo2,
141
+ useReducer,
142
+ useRef,
143
+ useState as useState2
144
+ } from "react";
145
+
146
+ // src/store.ts
147
+ var store_exports = {};
148
+ __reExport(store_exports, store_star);
149
+ import * as store_star from "@fctc/interface-logic/store";
150
+
151
+ // src/utils/function.ts
152
+ var countSum = (data, field) => {
153
+ if (!data || !field) return 0;
154
+ return data.reduce(
155
+ (total, item) => total + (item?.[`${field}_count`] || 0),
156
+ 0
157
+ );
158
+ };
159
+ function mergeButtons(fields) {
160
+ const buttons = fields?.filter((f) => f.type_co === "button");
161
+ const others = fields?.filter((f) => f.type_co !== "button");
162
+ if (buttons?.length) {
163
+ others.push({
164
+ type_co: "buttons",
165
+ buttons
166
+ });
167
+ }
168
+ return others;
169
+ }
170
+ function isElementVisible(el) {
171
+ const style = window.getComputedStyle(el);
172
+ return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0";
173
+ }
174
+ function arraysAreEqual(a, b) {
175
+ if (a.length !== b.length) return false;
176
+ const setA = new Set(a);
177
+ const setB = new Set(b);
178
+ if (setA.size !== setB.size) return false;
179
+ for (const val of setA) {
180
+ if (!setB.has(val)) return false;
181
+ }
182
+ return true;
183
+ }
184
+ function useGetRowIds(tableRef) {
185
+ const [rowIds, setRowIds] = useState2([]);
186
+ const lastRowIdsRef = useRef([]);
187
+ const updateVisibleRowIds = useCallback(() => {
188
+ const table = tableRef?.current;
189
+ if (!table) return;
190
+ const rows = table.querySelectorAll("tr[data-row-id]");
191
+ const ids = [];
192
+ rows.forEach((row) => {
193
+ const el = row;
194
+ if (isElementVisible(el)) {
195
+ const id = el.getAttribute("data-row-id");
196
+ if (id) ids.push(id);
197
+ }
198
+ });
199
+ const uniqueIds = Array.from(new Set(ids));
200
+ if (!arraysAreEqual(lastRowIdsRef.current, uniqueIds)) {
201
+ lastRowIdsRef.current = uniqueIds;
202
+ setRowIds(uniqueIds);
203
+ }
204
+ }, [tableRef]);
205
+ useEffect3(() => {
206
+ const table = tableRef?.current;
207
+ if (!table) return;
208
+ const observer = new MutationObserver(() => {
209
+ updateVisibleRowIds();
210
+ });
211
+ observer.observe(table, {
212
+ childList: true,
213
+ subtree: true,
214
+ attributes: true,
215
+ attributeFilter: ["style", "class"]
216
+ });
217
+ updateVisibleRowIds();
218
+ return () => {
219
+ observer.disconnect();
220
+ };
221
+ }, [updateVisibleRowIds, tableRef]);
222
+ return { rowIds, refresh: updateVisibleRowIds };
223
+ }
224
+ var useSelectionState = ({
225
+ typeTable,
226
+ tableRef,
227
+ rows
228
+ }) => {
229
+ const { groupByDomain } = (0, store_exports.useAppSelector)(store_exports.selectSearch);
230
+ const { selectedRowKeys } = (0, store_exports.useAppSelector)(store_exports.selectList);
231
+ const { rowIds: recordIds } = useGetRowIds(tableRef);
232
+ const selectedRowKeysRef = useRef(recordIds);
233
+ const isGroupTable = typeTable === "group";
234
+ const recordsCheckedGroup = useMemo2(() => {
235
+ if (!rows || !groupByDomain) return 0;
236
+ const groupBy = typeof groupByDomain === "object" ? groupByDomain?.contexts?.[0]?.group_by : void 0;
237
+ return countSum(rows, groupBy);
238
+ }, [rows, groupByDomain]);
239
+ const isAllGroupChecked = useMemo2(() => {
240
+ if (!isGroupTable || !selectedRowKeys?.length) return false;
241
+ const selectedLength = selectedRowKeys.filter((id) => id !== -1).length;
242
+ const allRecordsSelected = recordIds.length === selectedRowKeys.length ? recordIds.length === selectedLength : false;
243
+ const allGroupsSelected = recordsCheckedGroup === selectedRowKeys.length;
244
+ return allGroupsSelected || allRecordsSelected;
245
+ }, [isGroupTable, selectedRowKeys, recordIds, recordsCheckedGroup]);
246
+ const isAllNormalChecked = useMemo2(() => {
247
+ if (isGroupTable || !selectedRowKeys?.length || !rows?.length) return false;
248
+ return selectedRowKeys.length === rows.length && selectedRowKeys.every(
249
+ (id) => rows.some((record) => record.id === id)
250
+ );
251
+ }, [isGroupTable, selectedRowKeys, rows]);
252
+ const checkedAll = isAllGroupChecked || isAllNormalChecked;
253
+ return { checkedAll, selectedRowKeysRef };
254
+ };
255
+ var getDateRange = (currentDate, unit) => {
256
+ const date = new Date(currentDate);
257
+ let dateStart, dateEnd;
258
+ function formatDate(d) {
259
+ return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0") + " " + String(d.getHours()).padStart(2, "0") + ":" + String(d.getMinutes()).padStart(2, "0") + ":" + String(d.getSeconds()).padStart(2, "0");
260
+ }
261
+ switch (unit) {
262
+ case "month":
263
+ dateStart = new Date(
264
+ date.getFullYear(),
265
+ date.getMonth() + 1,
266
+ date.getDate(),
267
+ 23,
268
+ 59,
269
+ 59
270
+ );
271
+ dateStart.setHours(dateStart.getHours() - 7);
272
+ dateEnd = new Date(date.getFullYear(), date.getMonth(), 0, 0, 0, 0);
273
+ dateEnd.setHours(dateEnd.getHours() - 7);
274
+ break;
275
+ case "day":
276
+ dateStart = new Date(
277
+ date.getFullYear(),
278
+ date.getMonth(),
279
+ date.getDate(),
280
+ 23,
281
+ 59,
282
+ 59
283
+ );
284
+ dateStart.setHours(dateStart.getHours() - 7);
285
+ dateEnd = new Date(
286
+ date.getFullYear(),
287
+ date.getMonth(),
288
+ date.getDate(),
289
+ 0,
290
+ 0,
291
+ 0
292
+ );
293
+ dateEnd.setHours(dateEnd.getHours() - 7);
294
+ break;
295
+ case "week":
296
+ const dayOfWeek = date.getDay();
297
+ const daysToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
298
+ const daysToSunday = dayOfWeek === 0 ? 0 : 7 - dayOfWeek;
299
+ dateStart = new Date(
300
+ date.getFullYear(),
301
+ date.getMonth(),
302
+ date.getDate() + daysToSunday,
303
+ 23,
304
+ 59,
305
+ 59
306
+ );
307
+ dateStart.setHours(dateStart.getHours() - 7);
308
+ dateEnd = new Date(
309
+ date.getFullYear(),
310
+ date.getMonth(),
311
+ date.getDate() + daysToMonday,
312
+ 0,
313
+ 0,
314
+ 0
315
+ );
316
+ dateEnd.setHours(dateEnd.getHours() - 7);
317
+ break;
318
+ case "year":
319
+ dateStart = new Date(date.getFullYear(), 11, 31, 23, 59, 59);
320
+ dateStart.setHours(dateStart.getHours() - 7);
321
+ dateEnd = new Date(date.getFullYear() - 1, 11, 31, 0, 0, 0);
322
+ dateEnd.setHours(dateEnd.getHours() - 7);
323
+ break;
324
+ default:
325
+ throw new Error(
326
+ "\u0110\u01A1n v\u1ECB kh\xF4ng h\u1EE3p l\u1EC7. Ch\u1EC9 ch\u1EA5p nh\u1EADn: week, day, month, year"
327
+ );
328
+ }
329
+ return [
330
+ ["date_start", "<=", formatDate(dateStart)],
331
+ ["date_end", ">=", formatDate(dateEnd)]
332
+ ];
333
+ };
334
+ var convertFieldsToArray = (fields) => {
335
+ const defaultFields = ["display_name", "date_start", "date_end"];
336
+ if (!fields || !Array.isArray(fields)) {
337
+ return defaultFields;
338
+ }
339
+ const inputFields = fields.filter((field) => field && field.type_co === "field").map((field) => field.name);
340
+ return [...defaultFields, ...inputFields];
341
+ };
342
+ function combineContexts(contexts) {
343
+ if (contexts.some((context) => !context)) {
344
+ return void 0;
345
+ } else {
346
+ const res = contexts.reduce((acc, context) => {
347
+ return { ...acc, ...context };
348
+ }, {});
349
+ return res;
350
+ }
351
+ }
352
+ var STORAGES = {
353
+ TOKEN: "accessToken",
354
+ USER_INFO: "USER_INFO"
355
+ };
356
+ function useAsyncState(initialValue = [true, null]) {
357
+ return useReducer(
358
+ (_state, action = null) => [false, action],
359
+ initialValue
360
+ );
361
+ }
362
+ async function setStorageItemAsync(key, value) {
363
+ try {
364
+ if (value === null) {
365
+ localStorage.removeItem(key);
366
+ } else {
367
+ localStorage.setItem(key, value);
368
+ }
369
+ } catch (e) {
370
+ console.error("Local storage is unavailable:", e);
371
+ }
372
+ }
373
+ function useStorageState(key) {
374
+ const [state, setState] = useAsyncState();
375
+ useEffect3(() => {
376
+ try {
377
+ const storedValue = localStorage.getItem(key);
378
+ setState(storedValue);
379
+ } catch (e) {
380
+ console.error("Local storage is unavailable:", e);
381
+ }
382
+ }, [key]);
383
+ const setValue = useCallback(
384
+ (value) => {
385
+ setState(value);
386
+ setStorageItemAsync(key, value);
387
+ },
388
+ [key]
389
+ );
390
+ return [state, setValue];
391
+ }
392
+
393
+ // src/hooks/core/use-list-data.ts
394
+ import { useModel, useGetListData } from "@fctc/interface-logic/hooks";
395
+ import {
396
+ useAppSelector as useAppSelector2,
397
+ selectSearch as selectSearch2,
398
+ selectList as selectList2
399
+ } from "@fctc/interface-logic/store";
400
+ import {
401
+ evalJSONDomain,
402
+ formatSortingString
403
+ } from "@fctc/interface-logic/utils";
404
+ var useListData = ({
405
+ action,
406
+ context,
407
+ viewResponse
408
+ }) => {
409
+ const { groupByDomain } = useAppSelector2(selectSearch2);
410
+ const initModel = useModel();
411
+ const [type, setType] = useState3("list");
412
+ const [mode, setMode] = useState3("month");
413
+ const [currentDate, setCurrentDate] = useState3(/* @__PURE__ */ new Date());
414
+ const { pageLimit, page, order } = useAppSelector2(selectList2);
415
+ const listDataProps = useMemo3(() => {
416
+ const actData = action?.result;
417
+ if (!viewResponse || !actData || !context) {
418
+ return null;
419
+ }
420
+ const specification = initModel.initModel({
421
+ name: String(actData.res_model),
422
+ view: viewResponse || {},
423
+ actContext: context,
424
+ fields: type === "kanban" ? viewResponse?.views?.kanban?.fields : type === "calendar" ? viewResponse?.views?.calendar?.fields : viewResponse?.views?.list?.fields
425
+ }).getSpecification();
426
+ const domain = type === "calendar" ? getDateRange(currentDate, mode) : actData?.domain ? Array.isArray(actData?.domain) ? [...actData?.domain] : evalJSONDomain(actData?.domain, context) : [];
427
+ const limit = type === "calendar" ? 2500 : pageLimit;
428
+ const offset = page * pageLimit;
429
+ const fields = type === "calendar" ? convertFieldsToArray(viewResponse?.views?.calendar?.fields) || [] : typeof groupByDomain === "object" ? groupByDomain?.fields : void 0;
430
+ const groupby = typeof groupByDomain === "object" ? [groupByDomain?.contexts?.[0]?.group_by] : [];
431
+ const sort = order ? order : viewResponse?.views?.list?.default_order ? formatSortingString(viewResponse?.views?.list?.default_order) : "";
432
+ return {
433
+ model: actData.res_model,
434
+ specification,
435
+ domain,
436
+ limit,
437
+ offset,
438
+ fields,
439
+ groupby,
440
+ context,
441
+ sort,
442
+ type
443
+ };
444
+ }, [
445
+ action?.result,
446
+ context,
447
+ currentDate,
448
+ groupByDomain,
449
+ initModel,
450
+ mode,
451
+ order,
452
+ page,
453
+ pageLimit,
454
+ type,
455
+ viewResponse
456
+ ]);
457
+ const list = useGetListData(
458
+ listDataProps,
459
+ [listDataProps],
460
+ !!listDataProps
461
+ );
462
+ return {
463
+ ...list,
464
+ state: {
465
+ type,
466
+ setType,
467
+ mode,
468
+ setMode,
469
+ currentDate,
470
+ setCurrentDate
471
+ }
472
+ };
473
+ };
474
+
475
+ // src/hooks/core/use-menu.ts
476
+ import { useEffect as useEffect4, useMemo as useMemo4, useState as useState4 } from "react";
477
+
478
+ // src/utils/constants.ts
479
+ var languages = [
480
+ { id: "vi_VN", name: "VIE" },
481
+ { id: "en_US", name: "ENG" }
482
+ ];
483
+ var API_PRESCHOOL_URL = {
484
+ baseURL: "https://preschool.vitrust.app"
485
+ };
486
+ var API_APP_URL = {
487
+ baseUrl: "https://api.vitrust.app",
488
+ c2: "https://api.vitrust.app/c2",
489
+ apiV2: "https://api.vitrust.app/c2/api/v2"
490
+ };
491
+
492
+ // src/hooks/core/use-menu.ts
493
+ import { useGetMenu } from "@fctc/interface-logic/hooks";
494
+ var useMenu = ({ context }) => {
495
+ const menuData = useGetMenu(context, !!context);
496
+ const [menuid, setMenuId] = useState4(void 0);
497
+ const [action, setAction] = useCallAction();
498
+ const configedIconData = useMemo4(() => {
499
+ const data = menuData.data;
500
+ return data?.map((item) => {
501
+ return {
502
+ ...item,
503
+ child_id: item?.child_id?.map((child) => {
504
+ return {
505
+ ...child,
506
+ url_icon: API_APP_URL.c2 + "/" + child.url_icon
507
+ };
508
+ }) ?? [],
509
+ url_icon: API_APP_URL.c2 + "/" + item.url_icon
510
+ };
511
+ });
512
+ }, [menuData.data]);
513
+ const handleChangeMenu = async ({
514
+ menu,
515
+ subMenu
516
+ }) => {
517
+ const aid = subMenu?.action?.id?.id;
518
+ const actionType = subMenu?.action?.type;
519
+ await setAction({
520
+ aid: Number(aid),
521
+ actionType
522
+ });
523
+ if (menu) {
524
+ setMenuId(menu.id?.toString() ?? "");
525
+ }
526
+ };
527
+ useEffect4(() => {
528
+ const firstRecord = configedIconData?.[0];
529
+ const firstChild = firstRecord?.child_id?.[0];
530
+ if (firstChild && firstRecord) {
531
+ handleChangeMenu({ menu: firstRecord, subMenu: firstChild });
532
+ }
533
+ }, [configedIconData]);
534
+ return {
535
+ ...menuData,
536
+ data: configedIconData,
537
+ action: { handleChangeMenu },
538
+ state: { menuid, action },
539
+ context
540
+ };
541
+ };
542
+
543
+ // src/hooks/core/use-profile.ts
544
+ import { useQuery as useQuery2 } from "@tanstack/react-query";
545
+ import { useEffect as useEffect5, useMemo as useMemo5 } from "react";
546
+ import { useTranslation } from "react-i18next";
547
+ import { getEnv as getEnv3 } from "@fctc/interface-logic/environment";
548
+ import { useGetProfile } from "@fctc/interface-logic/hooks";
549
+ import { useAppDispatch as useAppDispatch3, setDataUser } from "@fctc/interface-logic/store";
550
+ var useProfile = (accessToken) => {
551
+ const getProfile = useGetProfile();
552
+ const dispatch = useAppDispatch3();
553
+ const { i18n } = useTranslation();
554
+ const fetchUserProfile = async () => {
555
+ return await getProfile.mutateAsync();
556
+ };
557
+ const userInfoQuery = useQuery2({
558
+ queryKey: ["userInfo", accessToken],
559
+ queryFn: fetchUserProfile,
560
+ enabled: !!accessToken
561
+ });
562
+ useEffect5(() => {
563
+ if (userInfoQuery.data) {
564
+ const userInfo = userInfoQuery.data;
565
+ const env = getEnv3();
566
+ env.setUid(userInfo?.sub);
567
+ dispatch(setDataUser(userInfo));
568
+ const userLocale = languages.find((lang) => lang?.id === userInfo?.locale);
569
+ env.setLang(userLocale?.id);
570
+ i18n.changeLanguage(userLocale?.id.split("_")[0]);
571
+ }
572
+ }, [dispatch, userInfoQuery.data]);
573
+ const context = useMemo5(() => {
574
+ if (userInfoQuery.data?.sub && userInfoQuery.data?.locale) {
575
+ return {
576
+ uid: Number(userInfoQuery.data.sub),
577
+ allowed_company_ids: [],
578
+ lang: String(userInfoQuery.data.locale),
579
+ tz: "Asia/Saigon"
580
+ };
581
+ }
582
+ return void 0;
583
+ }, [userInfoQuery.data]);
584
+ return { ...userInfoQuery, context };
585
+ };
586
+
587
+ // src/hooks/core/use-user.ts
588
+ var useUser = (accessToken) => {
589
+ const userProfile = useProfile(accessToken);
590
+ const userDetail = useDetail(accessToken, userProfile.data?.sub);
591
+ return { userProfile, userDetail, context: userProfile.context };
592
+ };
593
+
594
+ // src/hooks/core/use-view-v2.ts
595
+ import { useMemo as useMemo6 } from "react";
596
+ import { useGetView } from "@fctc/interface-logic/hooks";
597
+ var useViewV2 = ({
598
+ action,
599
+ context
600
+ }) => {
601
+ const viewParams = useMemo6(() => {
602
+ if (!action?.result) {
603
+ return void 0;
604
+ }
605
+ const actionResult = action?.result;
606
+ return {
607
+ model: String(actionResult?.res_model),
608
+ views: [
609
+ ...Array.isArray(actionResult?.views) ? actionResult?.views.map(
610
+ (view2) => view2[1] === "list" ? [view2[0], "list"] : view2
611
+ ) : [],
612
+ [
613
+ Array.isArray(actionResult?.search_view_id) ? actionResult?.search_view_id[0] : actionResult?.search_view_id,
614
+ "search"
615
+ ]
616
+ ],
617
+ context
618
+ };
619
+ }, [action, context]);
620
+ const view = useGetView(
621
+ viewParams || {},
622
+ !!viewParams
623
+ );
624
+ return {
625
+ ...view,
626
+ context
627
+ };
628
+ };
629
+
630
+ // src/hooks/core/use-auth.ts
631
+ import { useLoginCredential } from "@fctc/interface-logic/hooks";
632
+ import {
633
+ setDataUser as setDataUser2,
634
+ setMenuList,
635
+ setProfile as setProfile2,
636
+ useAppDispatch as useAppDispatch4
637
+ } from "@fctc/interface-logic/store";
638
+ var useAuth = () => {
639
+ const [[isLoading, accessToken], setAccessToken] = useStorageState("TOKEN");
640
+ const loginMutate = useLoginCredential();
641
+ const dispatch = useAppDispatch4();
642
+ const signIn = async (email, password) => {
643
+ try {
644
+ loginMutate.mutate(
645
+ {
646
+ email,
647
+ password,
648
+ path: "/authentication/oauth2/token"
649
+ },
650
+ {
651
+ onSuccess: (res) => {
652
+ },
653
+ onError: (err) => {
654
+ }
655
+ }
656
+ );
657
+ } catch (error) {
658
+ throw new Error("Login failed");
659
+ }
660
+ };
661
+ const signOut = async () => {
662
+ dispatch(setMenuList([]));
663
+ dispatch(setDataUser2({}));
664
+ dispatch(setProfile2({}));
665
+ setAccessToken(null);
666
+ };
667
+ return {
668
+ signIn,
669
+ signOut,
670
+ accessToken,
671
+ isLoading
672
+ };
673
+ };
674
+
675
+ // src/hooks/core/use-app-provider.tsx
676
+ import { createContext, useContext, useMemo as useMemo8 } from "react";
677
+
678
+ // src/hooks/core/use-company.ts
679
+ import { useQuery as useQuery3 } from "@tanstack/react-query";
680
+ import { useEffect as useEffect6, useMemo as useMemo7 } from "react";
681
+ import { getEnv as getEnv4 } from "@fctc/interface-logic/environment";
682
+ import {
683
+ useGetCurrentCompany,
684
+ useGetCompanyInfo
685
+ } from "@fctc/interface-logic/hooks";
686
+ var useCompany = (accessToken) => {
687
+ const getCurrentCompany = useGetCurrentCompany();
688
+ const fetchCurrentCompany = async () => {
689
+ return await getCurrentCompany.mutateAsync();
690
+ };
691
+ const currentCompany = useQuery3({
692
+ queryKey: ["currentCompany", accessToken],
693
+ queryFn: fetchCurrentCompany,
694
+ enabled: !!accessToken
695
+ });
696
+ const current_company_id = useMemo7(() => {
697
+ return currentCompany.data?.current_company_id;
698
+ }, [currentCompany.data]);
699
+ useEffect6(() => {
700
+ if (current_company_id) {
701
+ const companyIDs = [current_company_id];
702
+ const env = getEnv4();
703
+ env.setAllowCompanies([...companyIDs]);
704
+ env.setCompanies(companyIDs);
705
+ }
706
+ }, [current_company_id]);
707
+ const getCompanyInfo = useGetCompanyInfo();
708
+ const companyInfo = useQuery3({
709
+ queryKey: ["companyInfoQuery", current_company_id, accessToken],
710
+ queryFn: () => getCompanyInfo.mutateAsync(Number(current_company_id)),
711
+ enabled: !!current_company_id && !!accessToken
712
+ });
713
+ useEffect6(() => {
714
+ if (companyInfo.data) {
715
+ const companyInfoData = companyInfo.data;
716
+ if (companyInfoData?.length) {
717
+ const env = getEnv4();
718
+ env.setDefaultCompany(companyInfoData[0]);
719
+ }
720
+ }
721
+ }, [companyInfo.data]);
722
+ return {
723
+ currentCompany,
724
+ companyInfo,
725
+ context: { allowed_company_ids: [current_company_id] }
726
+ };
727
+ };
728
+ var use_company_default = useCompany;
729
+
730
+ // src/hooks/core/use-app-provider.tsx
731
+ import { evalJSONContext } from "@fctc/interface-logic/utils";
732
+ import { jsx } from "react/jsx-runtime";
733
+ var AppProviderInitialValue = {
734
+ config: {},
735
+ user: {},
736
+ auth: {},
737
+ company: {},
738
+ action: {},
739
+ menu: {},
740
+ view: {},
741
+ list: {}
742
+ };
743
+ var ReactContext = createContext(AppProviderInitialValue);
744
+ var AppProvider = ({ children }) => {
745
+ const config = useConfig({});
746
+ const auth = useAuth();
747
+ const user = useUser(auth.accessToken);
748
+ const company = use_company_default(auth.accessToken);
749
+ const menuContext = useMemo8(() => {
750
+ return combineContexts([user.context, company.context]);
751
+ }, [user.context, company.context]);
752
+ const menu = useMenu({ context: menuContext });
753
+ const action = useMemo8(() => {
754
+ return menu.state.action;
755
+ }, [menu.state.action]);
756
+ const viewContext = useMemo8(() => {
757
+ return combineContexts([
758
+ menuContext,
759
+ { ...evalJSONContext(action?.result?.context) }
760
+ ]);
761
+ }, [menuContext, action?.result?.context]);
762
+ const view = useViewV2({
763
+ action,
764
+ context: viewContext
765
+ });
766
+ const list = useListData({
767
+ action,
768
+ viewResponse: view.data,
769
+ context: viewContext
770
+ });
771
+ return /* @__PURE__ */ jsx(
772
+ ReactContext.Provider,
773
+ {
774
+ value: {
775
+ config,
776
+ auth,
777
+ user,
778
+ company,
779
+ menu,
780
+ list,
781
+ action,
782
+ view
783
+ },
784
+ children
785
+ }
786
+ );
787
+ };
788
+ var useAppProvider = () => {
789
+ const context = useContext(ReactContext);
790
+ if (!context) {
791
+ return AppProviderInitialValue;
792
+ }
793
+ return context;
794
+ };
795
+
796
+ // src/hooks/core/use-menu-item.tsx
797
+ import { getEnv as getEnv5 } from "@fctc/interface-logic/environment";
798
+ import { useGetActionDetail } from "@fctc/interface-logic/hooks";
799
+ import { useState as useState5 } from "react";
800
+
801
+ // src/utils.ts
802
+ var utils_exports = {};
803
+ __export(utils_exports, {
804
+ API_APP_URL: () => API_APP_URL,
805
+ API_PRESCHOOL_URL: () => API_PRESCHOOL_URL,
806
+ STORAGES: () => STORAGES,
807
+ combineContexts: () => combineContexts,
808
+ convertFieldsToArray: () => convertFieldsToArray,
809
+ countSum: () => countSum,
810
+ getDateRange: () => getDateRange,
811
+ languages: () => languages,
812
+ mergeButtons: () => mergeButtons,
813
+ setStorageItemAsync: () => setStorageItemAsync,
814
+ useGetRowIds: () => useGetRowIds,
815
+ useSelectionState: () => useSelectionState,
816
+ useStorageState: () => useStorageState
817
+ });
818
+ __reExport(utils_exports, utils_star);
819
+ import * as utils_star from "@fctc/interface-logic/utils";
820
+
821
+ // src/hooks/utils/use-click-outside.ts
822
+ import { useEffect as useEffect7, useRef as useRef2 } from "react";
823
+ var DEFAULT_EVENTS = ["mousedown", "touchstart"];
824
+ var useClickOutside = ({
825
+ handler,
826
+ events = DEFAULT_EVENTS,
827
+ nodes = [],
828
+ refs
829
+ }) => {
830
+ const ref = useRef2(null);
831
+ useEffect7(() => {
832
+ const listener = (event) => {
833
+ const { target } = event;
834
+ if (refs && refs?.length > 0 && refs?.some((r) => r.current?.contains(target))) {
835
+ return;
836
+ }
837
+ if (!(target instanceof HTMLElement)) return;
838
+ const shouldIgnore = target.hasAttribute("data-ignore-outside-clicks") || !document.body.contains(target) && target.tagName !== "HTML";
839
+ const shouldTrigger = nodes.length > 0 ? nodes.every((node) => node && !event.composedPath().includes(node)) : ref.current && !ref.current.contains(target);
840
+ if (shouldTrigger && !shouldIgnore) {
841
+ handler(event);
842
+ }
843
+ };
844
+ events.forEach((event) => document.addEventListener(event, listener));
845
+ return () => {
846
+ events.forEach((event) => document.removeEventListener(event, listener));
847
+ };
848
+ }, [handler, nodes, events]);
849
+ return ref;
850
+ };
851
+
852
+ // src/hooks/utils/use-debounce.ts
853
+ import { useEffect as useEffect8, useState as useState6 } from "react";
854
+ function useDebounce(value, delay) {
855
+ const [debouncedValue, setDebouncedValue] = useState6(value);
856
+ useEffect8(() => {
857
+ const handler = setTimeout(() => {
858
+ setDebouncedValue(value);
859
+ }, delay);
860
+ return () => {
861
+ clearTimeout(handler);
862
+ };
863
+ }, [value, delay]);
864
+ return [debouncedValue];
865
+ }
866
+
867
+ // src/hooks.ts
868
+ export * from "@fctc/interface-logic/hooks";
869
+ export {
870
+ AppProvider,
871
+ useAppProvider,
872
+ useAuth,
873
+ useCallAction,
874
+ useClickOutside,
875
+ useConfig,
876
+ useDebounce,
877
+ useDetail,
878
+ useListData,
879
+ useMenu,
880
+ useProfile,
881
+ useUser,
882
+ useViewV2
883
+ };