@fctc/widget-logic 2.4.3 → 2.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hooks.mjs CHANGED
@@ -16,100 +16,191 @@ var __copyProps = (to, from, except, desc) => {
16
16
  };
17
17
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
18
 
19
+ // src/hooks.ts
20
+ import {
21
+ useModel,
22
+ useButton,
23
+ useChangeStatus,
24
+ useDelete,
25
+ useDeleteComment,
26
+ useDuplicateRecord,
27
+ useExecuteImport,
28
+ useExportExcel,
29
+ useForgotPassword,
30
+ useForgotPasswordSSO,
31
+ useGet2FAMethods,
32
+ useGetAccessByCode,
33
+ useGetActionDetail,
34
+ useGetAll,
35
+ useGetCalendar,
36
+ useGetComment,
37
+ useGetCompanyInfo,
38
+ useGetConversionRate,
39
+ useGetCurrency,
40
+ useGetCurrentCompany,
41
+ useGetDetail,
42
+ useGetFieldExport,
43
+ useGetFieldOnChange,
44
+ useGetFileExcel,
45
+ useGetFormView,
46
+ useGetGroups,
47
+ useGetImage,
48
+ useGetListCompany,
49
+ useGetListData,
50
+ useGetListMyBankAccount,
51
+ useGetMenu,
52
+ useGetPrintReport,
53
+ useGetProGressBar,
54
+ useGetProfile,
55
+ useGetProvider,
56
+ useGetResequence,
57
+ useGetSelection,
58
+ useGetUser,
59
+ useGetView,
60
+ useGrantAccess,
61
+ useIsValidToken,
62
+ useLoadAction,
63
+ useLoadMessage,
64
+ useLoginCredential,
65
+ useLoginSocial,
66
+ useLogout,
67
+ useOdooDataTransform,
68
+ useOnChangeForm,
69
+ useParsePreview,
70
+ usePrint,
71
+ useRemoveRow,
72
+ useRemoveTotpSetup,
73
+ useRequestSetupTotp,
74
+ useResetPassword,
75
+ useResetPasswordSSO,
76
+ useRunAction,
77
+ useSave,
78
+ useSendComment,
79
+ useSettingsWebRead2fa,
80
+ useSignInSSO,
81
+ useSwitchLocale,
82
+ useUpdatePassword,
83
+ useUploadFile,
84
+ useUploadFileExcel,
85
+ useUploadIdFile,
86
+ useUploadImage,
87
+ useValidateActionToken,
88
+ useVerify2FA,
89
+ useVerifyTotp
90
+ } from "@fctc/interface-logic/hooks";
91
+
92
+ // src/hooks/core/use-app-provider.tsx
93
+ import { createContext, useContext, useMemo as useMemo5 } from "react";
94
+
95
+ // src/hooks/core/use-menu.ts
96
+ import { useMemo, useState as useState2 } from "react";
97
+
98
+ // src/hooks/core/use-call-action.ts
99
+ import { useCallback, useState } from "react";
100
+
101
+ // src/provider.ts
102
+ var provider_exports = {};
103
+ __reExport(provider_exports, provider_star);
104
+ import * as provider_star from "@fctc/interface-logic/provider";
105
+
19
106
  // 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
107
  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];
108
+ const { env } = (0, provider_exports.useEnv)();
109
+ const { useLoadAction: useLoadAction2, useRunAction: useRunAction2 } = (0, provider_exports.useService)();
110
+ const queryLoadAction = useLoadAction2();
111
+ const queryRunAction = useRunAction2();
112
+ const [actionData, setActionData] = useState(
113
+ void 0
114
+ );
115
+ const callAction = useCallback(
116
+ async ({
117
+ aid
118
+ }) => {
119
+ try {
120
+ const loadRes = await queryLoadAction.mutateAsync({
121
+ idAction: aid,
122
+ context: env.context
123
+ });
124
+ if (loadRes?.result?.type === "ir.actions.server") {
125
+ const runRes = await queryRunAction.mutateAsync({
126
+ idAction: aid,
127
+ context: env.context
128
+ });
129
+ setActionData(runRes?.result);
130
+ return runRes?.result;
131
+ } else {
132
+ setActionData(loadRes?.result);
133
+ return loadRes?.result;
134
+ }
135
+ } catch (err) {
136
+ console.error("callAction error:", err);
137
+ return void 0;
138
+ }
139
+ },
140
+ [env?.context?.lang]
141
+ );
142
+ return [actionData, callAction];
48
143
  };
49
144
 
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()
145
+ // src/hooks/core/use-menu.ts
146
+ var useMenu = ({
147
+ context,
148
+ specification
149
+ }) => {
150
+ const { env } = (0, provider_exports.useEnv)();
151
+ const { useGetMenu: useGetMenu2 } = (0, provider_exports.useService)();
152
+ const [action, callAction] = useCallAction();
153
+ const menuData = useGetMenu2(context, specification, !!context);
154
+ const [menuId, setMenuId] = useState2(void 0);
155
+ const configedIconData = useMemo(() => {
156
+ const data = menuData.data;
157
+ return data?.map((item) => {
158
+ return {
159
+ ...item,
160
+ child_id: item?.child_id?.map((child) => {
161
+ return {
162
+ ...child,
163
+ url_icon: env?.envFile?.VITE_APP_DOMAIN + "/" + child.url_icon
164
+ };
165
+ }) ?? [],
166
+ url_icon: env?.envFile?.VITE_APP_DOMAIN + "/" + item.url_icon
167
+ };
168
+ });
169
+ }, [menuData.data, env?.envFile?.VITE_APP_DOMAIN]);
170
+ const handleChangeMenu = async ({ menu }) => {
171
+ const aidMenu = menu?.action?.id?.id;
172
+ if (menu) {
173
+ setMenuId(menu.id?.toString() ?? "");
174
+ }
175
+ if (aidMenu) {
176
+ const actionResponse = await callAction({
177
+ aid: Number(aidMenu)
94
178
  });
95
- dispatch(setEnvFile(config));
96
- } catch (error) {
97
- console.error("Error loading env or config:", error);
179
+ return actionResponse;
98
180
  }
99
- }, [dispatch, envConfig, config]);
100
- return { envConfig, config };
181
+ };
182
+ return {
183
+ ...menuData,
184
+ data: configedIconData,
185
+ action: { handleChangeMenu },
186
+ state: { menuId, action },
187
+ context,
188
+ isLoading: menuData.isLoading,
189
+ isError: menuData.isError,
190
+ error: menuData.error,
191
+ refetch: menuData.refetch
192
+ };
101
193
  };
102
194
 
103
195
  // src/hooks/core/use-detail.ts
104
- import { setProfile, useAppDispatch as useAppDispatch2 } from "@fctc/interface-logic/store";
105
196
  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();
197
+ import { useEffect } from "react";
198
+ var useDetail = (sub) => {
199
+ const { setUserInfo, env } = (0, provider_exports.useEnv)();
200
+ const { useGetDetail: useGetDetail2 } = (0, provider_exports.useService)();
201
+ const fetchGetDetail = useGetDetail2();
111
202
  const userDetailQuery = useQuery({
112
- queryKey: ["userDetailQuery", sub && accessToken],
203
+ queryKey: ["userDetailQuery", sub],
113
204
  queryFn: () => {
114
205
  return fetchGetDetail.mutateAsync({
115
206
  model: "res.users",
@@ -117,24 +208,44 @@ var useDetail = (accessToken, sub) => {
117
208
  specification: { image_256: {} }
118
209
  });
119
210
  },
120
- enabled: !!sub && !!accessToken
211
+ enabled: !!sub
121
212
  });
122
- useEffect2(() => {
213
+ useEffect(() => {
123
214
  if (userDetailQuery.data) {
124
215
  const userPicture = userDetailQuery.data;
125
- dispatch(
126
- setProfile({ ...userPicture, image: userPicture?.[0]?.image_256 })
127
- );
216
+ setUserInfo({ ...env?.user, image: userPicture?.[0]?.image_256 });
128
217
  }
129
- }, [userDetailQuery.data, dispatch]);
130
- return userDetailQuery;
218
+ }, [userDetailQuery.isFetched]);
219
+ return { ...userDetailQuery };
131
220
  };
132
221
 
133
- // src/hooks/core/use-list-data.ts
134
- import { useMemo as useMemo2, useState as useState2 } from "react";
222
+ // src/hooks/core/use-profile.ts
223
+ import { useQuery as useQuery2 } from "@tanstack/react-query";
224
+ import { useEffect as useEffect3, useMemo as useMemo2 } from "react";
225
+ import { useTranslation } from "react-i18next";
226
+
227
+ // src/utils.ts
228
+ var utils_exports = {};
229
+ __export(utils_exports, {
230
+ STORAGES: () => STORAGES,
231
+ combineContexts: () => combineContexts,
232
+ convertFieldsToArray: () => convertFieldsToArray,
233
+ countSum: () => countSum,
234
+ getDateRange: () => getDateRange,
235
+ languages: () => languages,
236
+ mergeButtons: () => mergeButtons,
237
+ setStorageItemAsync: () => setStorageItemAsync,
238
+ useStorageState: () => useStorageState
239
+ });
240
+
241
+ // src/utils/constants.ts
242
+ var languages = [
243
+ { id: "vi_VN", name: "VIE" },
244
+ { id: "en_US", name: "ENG" }
245
+ ];
135
246
 
136
247
  // src/utils/function.ts
137
- import { useCallback, useEffect as useEffect3, useReducer } from "react";
248
+ import { useCallback as useCallback2, useEffect as useEffect2, useReducer } from "react";
138
249
  var countSum = (data, field) => {
139
250
  if (!data || !field) return 0;
140
251
  return data.reduce(
@@ -273,7 +384,7 @@ async function setStorageItemAsync(key, value) {
273
384
  }
274
385
  function useStorageState(key) {
275
386
  const [state, setState] = useAsyncState();
276
- useEffect3(() => {
387
+ useEffect2(() => {
277
388
  try {
278
389
  const storedValue = localStorage.getItem(key);
279
390
  setState(storedValue);
@@ -281,7 +392,7 @@ function useStorageState(key) {
281
392
  console.error("Local storage is unavailable:", e);
282
393
  }
283
394
  }, [key]);
284
- const setValue = useCallback(
395
+ const setValue = useCallback2(
285
396
  (value) => {
286
397
  setState(value);
287
398
  setStorageItemAsync(key, value);
@@ -291,187 +402,32 @@ function useStorageState(key) {
291
402
  return [state, setValue];
292
403
  }
293
404
 
294
- // src/hooks/core/use-list-data.ts
295
- import { useModel, useGetListData } from "@fctc/interface-logic/hooks";
296
- import {
297
- useAppSelector,
298
- selectSearch,
299
- selectList
300
- } from "@fctc/interface-logic/store";
301
- import {
302
- evalJSONDomain,
303
- formatSortingString
304
- } from "@fctc/interface-logic/utils";
305
- var useListData = ({
306
- action,
307
- context,
308
- viewResponse
309
- }) => {
310
- const { groupByDomain } = useAppSelector(selectSearch);
311
- const initModel = useModel();
312
- const [type, setType] = useState2("list");
313
- const [mode, setMode] = useState2("month");
314
- const [currentDate, setCurrentDate] = useState2(/* @__PURE__ */ new Date());
315
- const { pageLimit, page, order } = useAppSelector(selectList);
316
- const listDataProps = useMemo2(() => {
317
- const actData = action?.result;
318
- if (!viewResponse || !actData || !context) {
319
- return null;
320
- }
321
- const specification = initModel.initModel({
322
- name: String(actData.res_model),
323
- view: viewResponse || {},
324
- actContext: context,
325
- fields: type === "kanban" ? viewResponse?.views?.kanban?.fields : type === "calendar" ? viewResponse?.views?.calendar?.fields : viewResponse?.views?.list?.fields
326
- }).getSpecification();
327
- const domain = type === "calendar" ? getDateRange(currentDate, mode) : actData?.domain ? Array.isArray(actData?.domain) ? [...actData?.domain] : evalJSONDomain(actData?.domain, context) : [];
328
- const limit = type === "calendar" ? 2500 : pageLimit;
329
- const offset = page * pageLimit;
330
- const fields = type === "calendar" ? convertFieldsToArray(viewResponse?.views?.calendar?.fields) || [] : typeof groupByDomain === "object" ? groupByDomain?.fields : void 0;
331
- const groupby = typeof groupByDomain === "object" ? [groupByDomain?.contexts?.[0]?.group_by] : [];
332
- const sort = order ? order : viewResponse?.views?.list?.default_order ? formatSortingString(viewResponse?.views?.list?.default_order) : "";
333
- return {
334
- model: actData.res_model,
335
- specification,
336
- domain,
337
- limit,
338
- offset,
339
- fields,
340
- groupby,
341
- context,
342
- sort,
343
- type
344
- };
345
- }, [
346
- action?.result,
347
- context,
348
- currentDate,
349
- groupByDomain,
350
- initModel,
351
- mode,
352
- order,
353
- page,
354
- pageLimit,
355
- type,
356
- viewResponse
357
- ]);
358
- const list = useGetListData(
359
- listDataProps,
360
- [listDataProps],
361
- !!listDataProps
362
- );
363
- return {
364
- ...list,
365
- state: {
366
- type,
367
- setType,
368
- mode,
369
- setMode,
370
- currentDate,
371
- setCurrentDate
372
- }
373
- };
374
- };
375
-
376
- // src/hooks/core/use-menu.ts
377
- import { useEffect as useEffect4, useMemo as useMemo3, useState as useState3 } from "react";
378
-
379
- // src/utils/constants.ts
380
- var languages = [
381
- { id: "vi_VN", name: "VIE" },
382
- { id: "en_US", name: "ENG" }
383
- ];
384
- var API_PRESCHOOL_URL = {
385
- baseURL: "https://preschool.vitrust.app"
386
- };
387
- var API_APP_URL = {
388
- baseUrl: "https://api.vitrust.app",
389
- c2: "https://api.vitrust.app/c2",
390
- apiV2: "https://api.vitrust.app/c2/api/v2"
391
- };
392
-
393
- // src/hooks/core/use-menu.ts
394
- import { useGetMenu } from "@fctc/interface-logic/hooks";
395
- var useMenu = ({ context }) => {
396
- const menuData = useGetMenu(context, !!context);
397
- const [menuid, setMenuId] = useState3(void 0);
398
- const [action, setAction] = useCallAction();
399
- const configedIconData = useMemo3(() => {
400
- const data = menuData.data;
401
- return data?.map((item) => {
402
- return {
403
- ...item,
404
- child_id: item?.child_id?.map((child) => {
405
- return {
406
- ...child,
407
- url_icon: API_APP_URL.c2 + "/" + child.url_icon
408
- };
409
- }) ?? [],
410
- url_icon: API_APP_URL.c2 + "/" + item.url_icon
411
- };
412
- });
413
- }, [menuData.data]);
414
- const handleChangeMenu = async ({
415
- menu,
416
- subMenu
417
- }) => {
418
- const aid = subMenu?.action?.id?.id;
419
- const actionType = subMenu?.action?.type;
420
- await setAction({
421
- aid: Number(aid),
422
- actionType
423
- });
424
- if (menu) {
425
- setMenuId(menu.id?.toString() ?? "");
426
- }
427
- };
428
- useEffect4(() => {
429
- const firstRecord = configedIconData?.[0];
430
- const firstChild = firstRecord?.child_id?.[0];
431
- if (firstChild && firstRecord) {
432
- handleChangeMenu({ menu: firstRecord, subMenu: firstChild });
433
- }
434
- }, [configedIconData]);
435
- return {
436
- ...menuData,
437
- data: configedIconData,
438
- action: { handleChangeMenu },
439
- state: { menuid, action },
440
- context
441
- };
442
- };
405
+ // src/utils.ts
406
+ __reExport(utils_exports, utils_star);
407
+ import * as utils_star from "@fctc/interface-logic/utils";
443
408
 
444
409
  // src/hooks/core/use-profile.ts
445
- import { useQuery as useQuery2 } from "@tanstack/react-query";
446
- import { useEffect as useEffect5, useMemo as useMemo4 } from "react";
447
- import { useTranslation } from "react-i18next";
448
- import { getEnv as getEnv3 } from "@fctc/interface-logic/environment";
449
- import { useGetProfile } from "@fctc/interface-logic/hooks";
450
- import { useAppDispatch as useAppDispatch3, setDataUser } from "@fctc/interface-logic/store";
451
- var useProfile = (accessToken) => {
452
- const getProfile = useGetProfile();
453
- const dispatch = useAppDispatch3();
410
+ var useProfile = () => {
411
+ const { setUid, setLang, setUserInfo, env } = (0, provider_exports.useEnv)();
412
+ const { useGetProfile: useGetProfile2 } = (0, provider_exports.useService)();
413
+ const getProfile = useGetProfile2();
454
414
  const { i18n } = useTranslation();
455
- const fetchUserProfile = async () => {
456
- return await getProfile.mutateAsync();
457
- };
458
415
  const userInfoQuery = useQuery2({
459
- queryKey: ["userInfo", accessToken],
460
- queryFn: fetchUserProfile,
461
- enabled: !!accessToken
416
+ queryKey: ["userInfo"],
417
+ queryFn: () => getProfile.mutateAsync(),
418
+ enabled: (0, utils_exports.isObjectEmpty)(env?.user)
462
419
  });
463
- useEffect5(() => {
420
+ useEffect3(() => {
464
421
  if (userInfoQuery.data) {
465
422
  const userInfo = userInfoQuery.data;
466
- const env = getEnv3();
467
- env.setUid(userInfo?.sub);
468
- dispatch(setDataUser(userInfo));
423
+ setUid(userInfo?.sub);
424
+ setUserInfo(userInfo);
469
425
  const userLocale = languages.find((lang) => lang?.id === userInfo?.locale);
470
- env.setLang(userLocale?.id);
426
+ setLang(userLocale?.id);
471
427
  i18n.changeLanguage(userLocale?.id.split("_")[0]);
472
428
  }
473
- }, [dispatch, userInfoQuery.data]);
474
- const context = useMemo4(() => {
429
+ }, [userInfoQuery.isFetched]);
430
+ const context = useMemo2(() => {
475
431
  if (userInfoQuery.data?.sub && userInfoQuery.data?.locale) {
476
432
  return {
477
433
  uid: Number(userInfoQuery.data.sub),
@@ -481,44 +437,42 @@ var useProfile = (accessToken) => {
481
437
  };
482
438
  }
483
439
  return void 0;
484
- }, [userInfoQuery.data]);
440
+ }, [userInfoQuery.isFetched]);
441
+ if (userInfoQuery.isLoading || !userInfoQuery.data) {
442
+ return null;
443
+ }
485
444
  return { ...userInfoQuery, context };
486
445
  };
487
446
 
488
447
  // src/hooks/core/use-user.ts
489
- var useUser = (accessToken) => {
490
- const userProfile = useProfile(accessToken);
491
- const userDetail = useDetail(accessToken, userProfile.data?.sub);
492
- return { userProfile, userDetail, context: userProfile.context };
448
+ var useUser = () => {
449
+ const userProfile = useProfile();
450
+ const userDetail = useDetail(userProfile?.data?.sub);
451
+ return { userProfile, userDetail, context: userProfile?.context };
493
452
  };
494
453
 
495
454
  // src/hooks/core/use-view-v2.ts
496
- import { useMemo as useMemo5 } from "react";
497
- import { useGetView } from "@fctc/interface-logic/hooks";
455
+ import { useMemo as useMemo3 } from "react";
498
456
  var useViewV2 = ({
499
457
  action,
500
- context
458
+ context,
459
+ aid,
460
+ views,
461
+ model
501
462
  }) => {
502
- const viewParams = useMemo5(() => {
503
- if (!action?.result) {
463
+ const { useGetView: useGetView2 } = (0, provider_exports.useService)();
464
+ const viewParams = useMemo3(() => {
465
+ if (!action) {
504
466
  return void 0;
505
467
  }
506
- const actionResult = action?.result;
507
468
  return {
508
- model: String(actionResult?.res_model),
509
- views: [
510
- ...Array.isArray(actionResult?.views) ? actionResult?.views.map(
511
- (view2) => view2[1] === "list" ? [view2[0], "list"] : view2
512
- ) : [],
513
- [
514
- Array.isArray(actionResult?.search_view_id) ? actionResult?.search_view_id[0] : actionResult?.search_view_id,
515
- "search"
516
- ]
517
- ],
518
- context
469
+ model,
470
+ views,
471
+ context,
472
+ id: isNaN(Number(aid)) ? action?.id : aid
519
473
  };
520
- }, [action, context]);
521
- const view = useGetView(
474
+ }, [action, context, aid]);
475
+ const view = useGetView2(
522
476
  viewParams || {},
523
477
  !!viewParams
524
478
  );
@@ -528,157 +482,117 @@ var useViewV2 = ({
528
482
  };
529
483
  };
530
484
 
531
- // src/hooks/core/use-auth.ts
532
- import { useLoginCredential } from "@fctc/interface-logic/hooks";
533
- import {
534
- setDataUser as setDataUser2,
535
- setMenuList,
536
- setProfile as setProfile2,
537
- useAppDispatch as useAppDispatch4
538
- } from "@fctc/interface-logic/store";
539
- var useAuth = () => {
540
- const [[isLoading, accessToken], setAccessToken] = useStorageState("TOKEN");
541
- const loginMutate = useLoginCredential();
542
- const dispatch = useAppDispatch4();
543
- const signIn = async (email, password) => {
544
- try {
545
- loginMutate.mutate(
546
- {
547
- email,
548
- password,
549
- path: "/authentication/oauth2/token"
550
- },
551
- {
552
- onSuccess: (res) => {
553
- },
554
- onError: (err) => {
555
- }
556
- }
557
- );
558
- } catch (error) {
559
- throw new Error("Login failed");
560
- }
561
- };
562
- const signOut = async () => {
563
- dispatch(setMenuList([]));
564
- dispatch(setDataUser2({}));
565
- dispatch(setProfile2({}));
566
- setAccessToken(null);
567
- };
568
- return {
569
- signIn,
570
- signOut,
571
- accessToken,
572
- isLoading
573
- };
574
- };
575
-
576
- // src/hooks/core/use-app-provider.tsx
577
- import { createContext, useContext, useMemo as useMemo7 } from "react";
578
-
579
485
  // src/hooks/core/use-company.ts
580
486
  import { useQuery as useQuery3 } from "@tanstack/react-query";
581
- import { useEffect as useEffect6, useMemo as useMemo6 } from "react";
582
- import { getEnv as getEnv4 } from "@fctc/interface-logic/environment";
583
- import {
584
- useGetCurrentCompany,
585
- useGetCompanyInfo
586
- } from "@fctc/interface-logic/hooks";
587
- var useCompany = (accessToken) => {
588
- const getCurrentCompany = useGetCurrentCompany();
487
+ import { useEffect as useEffect4, useMemo as useMemo4 } from "react";
488
+ var useCompany = () => {
489
+ const { setAllowCompanies, setCompanies, setDefaultCompany, env } = (0, provider_exports.useEnv)();
490
+ const { useGetCurrentCompany: useGetCurrentCompany2, useGetCompanyInfo: useGetCompanyInfo2 } = (0, provider_exports.useService)();
491
+ const getCurrentCompany = useGetCurrentCompany2();
589
492
  const fetchCurrentCompany = async () => {
590
493
  return await getCurrentCompany.mutateAsync();
591
494
  };
592
495
  const currentCompany = useQuery3({
593
- queryKey: ["currentCompany", accessToken],
496
+ queryKey: ["currentCompany"],
594
497
  queryFn: fetchCurrentCompany,
595
- enabled: !!accessToken
498
+ enabled: !!env?.defaultCompany
596
499
  });
597
- const current_company_id = useMemo6(() => {
500
+ const current_company_id = useMemo4(() => {
598
501
  return currentCompany.data?.current_company_id;
599
502
  }, [currentCompany.data]);
600
- useEffect6(() => {
503
+ useEffect4(() => {
601
504
  if (current_company_id) {
602
505
  const companyIDs = [current_company_id];
603
- const env = getEnv4();
604
- env.setAllowCompanies([...companyIDs]);
605
- env.setCompanies(companyIDs);
506
+ setAllowCompanies([...companyIDs]);
507
+ setCompanies(companyIDs);
606
508
  }
607
509
  }, [current_company_id]);
608
- const getCompanyInfo = useGetCompanyInfo();
510
+ const getCompanyInfo = useGetCompanyInfo2();
609
511
  const companyInfo = useQuery3({
610
- queryKey: ["companyInfoQuery", current_company_id, accessToken],
512
+ queryKey: ["companyInfoQuery", current_company_id],
611
513
  queryFn: () => getCompanyInfo.mutateAsync(Number(current_company_id)),
612
- enabled: !!current_company_id && !!accessToken
514
+ enabled: !!current_company_id
613
515
  });
614
- useEffect6(() => {
516
+ useEffect4(() => {
615
517
  if (companyInfo.data) {
616
518
  const companyInfoData = companyInfo.data;
617
519
  if (companyInfoData?.length) {
618
- const env = getEnv4();
619
- env.setDefaultCompany(companyInfoData[0]);
520
+ setDefaultCompany(companyInfoData[0]);
620
521
  }
621
522
  }
622
523
  }, [companyInfo.data]);
524
+ if (!companyInfo?.data || !currentCompany?.data) return;
623
525
  return {
624
- currentCompany,
625
- companyInfo,
526
+ currentCompany: { ...currentCompany },
527
+ companyInfo: { ...companyInfo },
626
528
  context: { allowed_company_ids: [current_company_id] }
627
529
  };
628
530
  };
629
- var use_company_default = useCompany;
630
531
 
631
532
  // src/hooks/core/use-app-provider.tsx
632
- import { evalJSONContext } from "@fctc/interface-logic/utils";
633
533
  import { jsx } from "react/jsx-runtime";
634
534
  var AppProviderInitialValue = {
635
- config: {},
636
535
  user: {},
637
- auth: {},
638
536
  company: {},
639
537
  action: {},
640
538
  menu: {},
641
- view: {},
642
- list: {}
539
+ view: {}
643
540
  };
644
541
  var ReactContext = createContext(AppProviderInitialValue);
645
- var AppProvider = ({ children }) => {
646
- const config = useConfig({});
647
- const auth = useAuth();
648
- const user = useUser(auth.accessToken);
649
- const company = use_company_default(auth.accessToken);
650
- const menuContext = useMemo7(() => {
651
- return combineContexts([user.context, company.context]);
652
- }, [user.context, company.context]);
653
- const menu = useMenu({ context: menuContext });
654
- const action = useMemo7(() => {
655
- return menu.state.action;
656
- }, [menu.state.action]);
657
- const viewContext = useMemo7(() => {
542
+ var AppProvider = ({
543
+ children,
544
+ menuSpecification,
545
+ aid
546
+ }) => {
547
+ const { env } = (0, provider_exports.useEnv)();
548
+ const user = useUser();
549
+ const company = useCompany();
550
+ const menuContext = useMemo5(() => {
551
+ return combineContexts([
552
+ {
553
+ ...user?.context,
554
+ ...!(0, utils_exports.isObjectEmpty)(env?.user) && company?.context?.allowed_company_ids ? { lang: env?.context?.lang } : {}
555
+ },
556
+ company?.context
557
+ ]);
558
+ }, [user?.context, company?.context]);
559
+ const menu = useMenu({
560
+ context: {
561
+ ...menuContext
562
+ },
563
+ specification: menuSpecification
564
+ });
565
+ const action = useMemo5(() => {
566
+ return menu?.state?.action;
567
+ }, [menu?.state?.action, env?.context?.lang]);
568
+ const viewContext = useMemo5(() => {
658
569
  return combineContexts([
659
570
  menuContext,
660
- { ...evalJSONContext(action?.result?.context) }
571
+ { ...(0, utils_exports.evalJSONContext)(action?.context) }
661
572
  ]);
662
- }, [menuContext, action?.result?.context]);
573
+ }, [menuContext, action?.context, env?.context?.lang]);
663
574
  const view = useViewV2({
664
575
  action,
665
- context: viewContext
666
- });
667
- const list = useListData({
668
- action,
669
- viewResponse: view.data,
670
- context: viewContext
576
+ context: viewContext,
577
+ aid,
578
+ views: [
579
+ ...Array.isArray(action?.views) ? action?.views.map(
580
+ (view2) => view2[1] === "list" ? [view2[0], "list"] : view2
581
+ ) : [],
582
+ [
583
+ Array.isArray(action?.search_view_id) ? action?.search_view_id[0] : action?.search_view_id,
584
+ "search"
585
+ ]
586
+ ],
587
+ model: String(action?.res_model)
671
588
  });
672
589
  return /* @__PURE__ */ jsx(
673
590
  ReactContext.Provider,
674
591
  {
675
592
  value: {
676
- config,
677
- auth,
678
593
  user,
679
594
  company,
680
595
  menu,
681
- list,
682
596
  action,
683
597
  view
684
598
  },
@@ -694,68 +608,161 @@ var useAppProvider = () => {
694
608
  return context;
695
609
  };
696
610
 
697
- // src/hooks/core/use-menu-item.tsx
698
- import { getEnv as getEnv5 } from "@fctc/interface-logic/environment";
699
- import { useGetActionDetail } from "@fctc/interface-logic/hooks";
700
- import { useState as useState4 } from "react";
701
-
702
- // src/utils.ts
703
- var utils_exports = {};
704
- __export(utils_exports, {
705
- API_APP_URL: () => API_APP_URL,
706
- API_PRESCHOOL_URL: () => API_PRESCHOOL_URL,
707
- STORAGES: () => STORAGES,
708
- combineContexts: () => combineContexts,
709
- convertFieldsToArray: () => convertFieldsToArray,
710
- countSum: () => countSum,
711
- getDateRange: () => getDateRange,
712
- languages: () => languages,
713
- mergeButtons: () => mergeButtons,
714
- setStorageItemAsync: () => setStorageItemAsync,
715
- useStorageState: () => useStorageState
716
- });
717
- __reExport(utils_exports, utils_star);
718
- import * as utils_star from "@fctc/interface-logic/utils";
611
+ // src/hooks/core/use-config.ts
612
+ import { useEffect as useEffect5 } from "react";
613
+ var useConfig = ({
614
+ envConfig,
615
+ config,
616
+ localStorageUtils,
617
+ sessionStorageUtils
618
+ }) => {
619
+ const { setupEnv, setEnvFile } = (0, provider_exports.useEnv)();
620
+ useEffect5(() => {
621
+ try {
622
+ setupEnv({
623
+ baseUrl: envConfig.baseUrl,
624
+ config: envConfig.config,
625
+ default_service: "",
626
+ localStorageUtils: localStorageUtils && localStorageUtils(),
627
+ sessionStorageUtils: localStorageUtils && sessionStorageUtils()
628
+ });
629
+ setEnvFile(config);
630
+ } catch (error) {
631
+ console.error("Error loading env or config:", error);
632
+ }
633
+ }, [envConfig, config]);
634
+ return { envConfig, config };
635
+ };
719
636
 
720
- // src/hooks/core/use-menu-item.tsx
721
- var useMenuItem = (props) => {
722
- const { menu, activeMenuId } = props;
723
- const model = menu?.action?.res_model;
724
- const aid = menu?.action?.id?.id;
725
- const id = menu?.id;
726
- const context = getEnv5().context;
727
- const queryActionDetail = useGetActionDetail({
728
- aid,
729
- id,
730
- model,
731
- context,
732
- enabled: true,
733
- queryKey: [`action-${aid}`]
734
- }).data;
735
- const [path, setPath] = useState4("");
736
- const handleClick = () => {
737
- if (location?.pathname === "/list/menu" && activeMenuId === menu?.id) {
738
- return;
637
+ // src/hooks/core/use-get-action.ts
638
+ var useGetAction = ({
639
+ aid,
640
+ context
641
+ }) => {
642
+ const { useLoadAction: useLoadAction2, useRunAction: useRunAction2 } = (0, provider_exports.useService)();
643
+ const queryLoadAction = useLoadAction2();
644
+ const queryRunAction = useRunAction2();
645
+ const handleActionResult = (data) => {
646
+ if (data && data.result && data.result.views && Array.isArray(data.result.views) && data.result.views.length > 0) {
739
647
  }
740
- const hasListView = queryActionDetail.views.some(
741
- ([id2, type]) => type === "list"
648
+ };
649
+ const onLoadAction = () => {
650
+ queryLoadAction.mutate(
651
+ {
652
+ idAction: aid,
653
+ context
654
+ },
655
+ {
656
+ onSuccess: (data) => {
657
+ if (data?.result?.type === "ir.actions.act_window") {
658
+ handleActionResult(data);
659
+ } else if (data?.result?.type === "ir.actions.server") {
660
+ queryRunAction.mutate(
661
+ {
662
+ idAction: aid,
663
+ context
664
+ },
665
+ {
666
+ onSuccess: handleActionResult
667
+ }
668
+ );
669
+ }
670
+ }
671
+ }
742
672
  );
743
- const viewType = hasListView ? "list" : "form";
744
- const isAccountPayment = menu?.action?.res_model === "account.payment" && menu?.action?.id?.id === 1551;
745
- const isConvertCurrencyMenu = menu?.action?.res_model === "currency.convert" && menu?.action?.id?.id === 1562;
746
- const path2 = (0, utils_exports.formatUrlPath)({
747
- viewType,
748
- actionPath: isConvertCurrencyMenu ? "menu" : isAccountPayment ? "menu" : menu?.action?.path || "menu",
749
- aid: menu?.action?.id?.id,
750
- model: queryActionDetail.res_model
751
- });
752
- setPath(path2);
753
673
  };
754
- return { handleClick, path, queryActionDetail };
674
+ return {
675
+ onLoadAction
676
+ };
677
+ };
678
+
679
+ // src/hooks/core/use-get-specification.ts
680
+ import { useMemo as useMemo6 } from "react";
681
+ var useGetSpecification = ({
682
+ model,
683
+ viewData,
684
+ fields
685
+ }) => {
686
+ const baseModel = useMemo6(
687
+ () => ({
688
+ name: String(model),
689
+ view: viewData || {},
690
+ fields
691
+ }),
692
+ [model, viewData]
693
+ );
694
+ const initModel = useModel();
695
+ const modelInstance = useMemo6(() => {
696
+ if (viewData) {
697
+ return initModel.initModel(baseModel);
698
+ }
699
+ return null;
700
+ }, [baseModel, viewData]);
701
+ const specification = useMemo6(() => {
702
+ if (modelInstance) {
703
+ return modelInstance.getSpecification();
704
+ }
705
+ return null;
706
+ }, [modelInstance]);
707
+ return { specification };
708
+ };
709
+
710
+ // src/hooks/core/use-list-data.ts
711
+ import { useMemo as useMemo7, useState as useState5 } from "react";
712
+ import {
713
+ evalJSONDomain,
714
+ formatSortingString,
715
+ isObjectEmpty as isObjectEmpty3
716
+ } from "@fctc/interface-logic/utils";
717
+
718
+ // src/hooks/utils/use-click-outside.ts
719
+ import { useEffect as useEffect6, useRef } from "react";
720
+ var DEFAULT_EVENTS = ["mousedown", "touchstart"];
721
+ var useClickOutside = ({
722
+ handler,
723
+ events = DEFAULT_EVENTS,
724
+ nodes = [],
725
+ refs
726
+ }) => {
727
+ const ref = useRef(null);
728
+ useEffect6(() => {
729
+ const listener = (event) => {
730
+ const { target } = event;
731
+ if (refs && refs?.length > 0 && refs?.some((r) => r.current?.contains(target))) {
732
+ return;
733
+ }
734
+ if (!(target instanceof HTMLElement)) return;
735
+ const shouldIgnore = target.hasAttribute("data-ignore-outside-clicks") || !document.body.contains(target) && target.tagName !== "HTML";
736
+ const shouldTrigger = nodes.length > 0 ? nodes.every((node) => node && !event.composedPath().includes(node)) : ref.current && !ref.current.contains(target);
737
+ if (shouldTrigger && !shouldIgnore) {
738
+ handler(event);
739
+ }
740
+ };
741
+ events.forEach((event) => document.addEventListener(event, listener));
742
+ return () => {
743
+ events.forEach((event) => document.removeEventListener(event, listener));
744
+ };
745
+ }, [handler, nodes, events]);
746
+ return ref;
755
747
  };
756
748
 
757
- // src/hooks/core/use-get-rowids.ts
758
- import { useCallback as useCallback2, useEffect as useEffect7, useRef, useState as useState5 } from "react";
749
+ // src/hooks/utils/use-debounce.ts
750
+ import { useEffect as useEffect7, useState as useState3 } from "react";
751
+ function useDebounce(value, delay) {
752
+ const [debouncedValue, setDebouncedValue] = useState3(value);
753
+ useEffect7(() => {
754
+ const handler = setTimeout(() => {
755
+ setDebouncedValue(value);
756
+ }, delay);
757
+ return () => {
758
+ clearTimeout(handler);
759
+ };
760
+ }, [value, delay]);
761
+ return [debouncedValue];
762
+ }
763
+
764
+ // src/hooks/utils/use-get-rowids.ts
765
+ import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef2, useState as useState4 } from "react";
759
766
  var useGetRowIds = (tableRef) => {
760
767
  function isElementVisible(el) {
761
768
  const style = window.getComputedStyle(el);
@@ -772,9 +779,9 @@ var useGetRowIds = (tableRef) => {
772
779
  }
773
780
  return true;
774
781
  }
775
- const [rowIds, setRowIds] = useState5([]);
776
- const lastRowIdsRef = useRef([]);
777
- const updateVisibleRowIds = useCallback2(() => {
782
+ const [rowIds, setRowIds] = useState4([]);
783
+ const lastRowIdsRef = useRef2([]);
784
+ const updateVisibleRowIds = useCallback3(() => {
778
785
  const table = tableRef.current;
779
786
  if (!table) return;
780
787
  const rows = table.querySelectorAll("tr[data-row-id]");
@@ -792,7 +799,7 @@ var useGetRowIds = (tableRef) => {
792
799
  setRowIds(uniqueIds);
793
800
  }
794
801
  }, [tableRef]);
795
- useEffect7(() => {
802
+ useEffect8(() => {
796
803
  const table = tableRef.current;
797
804
  if (!table) return;
798
805
  const mutationObserver = new MutationObserver(() => {
@@ -820,68 +827,178 @@ var useGetRowIds = (tableRef) => {
820
827
  return { rowIds, refresh: updateVisibleRowIds };
821
828
  };
822
829
 
823
- // src/hooks/utils/use-click-outside.ts
824
- import { useEffect as useEffect8, useRef as useRef2 } from "react";
825
- var DEFAULT_EVENTS = ["mousedown", "touchstart"];
826
- var useClickOutside = ({
827
- handler,
828
- events = DEFAULT_EVENTS,
829
- nodes = [],
830
- refs
830
+ // src/hooks/core/use-list-data.ts
831
+ var useListData = ({
832
+ action,
833
+ context,
834
+ viewData,
835
+ model
831
836
  }) => {
832
- const ref = useRef2(null);
833
- useEffect8(() => {
834
- const listener = (event) => {
835
- const { target } = event;
836
- if (refs && refs?.length > 0 && refs?.some((r) => r.current?.contains(target))) {
837
- return;
838
- }
839
- if (!(target instanceof HTMLElement)) return;
840
- const shouldIgnore = target.hasAttribute("data-ignore-outside-clicks") || !document.body.contains(target) && target.tagName !== "HTML";
841
- const shouldTrigger = nodes.length > 0 ? nodes.every((node) => node && !event.composedPath().includes(node)) : ref.current && !ref.current.contains(target);
842
- if (shouldTrigger && !shouldIgnore) {
843
- handler(event);
844
- }
845
- };
846
- events.forEach((event) => document.addEventListener(event, listener));
847
- return () => {
848
- events.forEach((event) => document.removeEventListener(event, listener));
837
+ const { useGetListData: useGetListData2 } = (0, provider_exports.useService)();
838
+ const [page, setPage] = useState5(0);
839
+ const [pageLimit, setPageLimit] = useState5(10);
840
+ const [groupByList, setGroupByList] = useState5(null);
841
+ const [domain, setDomain] = useState5(null);
842
+ const [order, setOrder] = useState5("");
843
+ const [mode, setMode] = useState5("month");
844
+ const [type, setType] = useState5("list");
845
+ const [currentDate, setCurrentDate] = useState5(/* @__PURE__ */ new Date());
846
+ const [selectedRowKeys, setSelectedRowKeys] = useState5([]);
847
+ const [debouncedPage] = useDebounce(page, 500);
848
+ const [debouncedDomain] = useDebounce(domain, 500);
849
+ const { specification } = useGetSpecification({
850
+ model,
851
+ viewData,
852
+ fields: viewData?.views?.list?.fields
853
+ });
854
+ const listDataProps = useMemo7(() => {
855
+ if (!viewData || !action || !context) {
856
+ return null;
857
+ }
858
+ const domainParse = type === "calendar" ? getDateRange(currentDate, mode) : action?.domain ? Array.isArray(action?.domain) ? [...action?.domain] : evalJSONDomain(action?.domain, context) : [];
859
+ const limit = type === "calendar" ? 2500 : pageLimit;
860
+ const offset = debouncedPage * pageLimit;
861
+ const fields = type === "calendar" ? convertFieldsToArray(viewData?.views?.calendar?.fields) || [] : typeof groupByList === "object" ? groupByList?.fields : void 0;
862
+ const groupby = typeof groupByList === "object" ? [groupByList?.contexts?.[0]?.group_by] : [];
863
+ const sort = order ? order : viewData?.views?.list?.default_order ? formatSortingString(viewData?.views?.list?.default_order) : "";
864
+ return {
865
+ model: action.res_model,
866
+ specification,
867
+ domain: domainParse,
868
+ limit,
869
+ offset,
870
+ fields,
871
+ groupby,
872
+ context,
873
+ sort,
874
+ type
849
875
  };
850
- }, [handler, nodes, events]);
851
- return ref;
876
+ }, [
877
+ action,
878
+ context,
879
+ currentDate,
880
+ groupByList,
881
+ mode,
882
+ order,
883
+ debouncedPage,
884
+ pageLimit,
885
+ type,
886
+ debouncedDomain
887
+ ]);
888
+ const list = useGetListData2(
889
+ listDataProps,
890
+ [listDataProps],
891
+ !!listDataProps && !!specification && !isObjectEmpty3(specification)
892
+ );
893
+ return {
894
+ ...list,
895
+ state: {
896
+ specification,
897
+ type,
898
+ page,
899
+ mode,
900
+ order,
901
+ domain: listDataProps?.domain,
902
+ pageLimit,
903
+ groupByList,
904
+ currentDate,
905
+ selectedRowKeys,
906
+ setType,
907
+ setMode,
908
+ setPage,
909
+ setOrder,
910
+ setDomain,
911
+ setPageLimit,
912
+ setGroupByList,
913
+ setCurrentDate,
914
+ setSelectedRowKeys
915
+ }
916
+ };
852
917
  };
853
-
854
- // src/hooks/utils/use-debounce.ts
855
- import { useEffect as useEffect9, useState as useState6 } from "react";
856
- function useDebounce(value, delay) {
857
- const [debouncedValue, setDebouncedValue] = useState6(value);
858
- useEffect9(() => {
859
- const handler = setTimeout(() => {
860
- setDebouncedValue(value);
861
- }, delay);
862
- return () => {
863
- clearTimeout(handler);
864
- };
865
- }, [value, delay]);
866
- return [debouncedValue];
867
- }
868
-
869
- // src/hooks.ts
870
- export * from "@fctc/interface-logic/hooks";
871
918
  export {
872
919
  AppProvider,
873
920
  useAppProvider,
874
- useAuth,
921
+ useButton,
875
922
  useCallAction,
923
+ useChangeStatus,
876
924
  useClickOutside,
925
+ useCompany,
877
926
  useConfig,
878
927
  useDebounce,
928
+ useDelete,
929
+ useDeleteComment,
879
930
  useDetail,
931
+ useDuplicateRecord,
932
+ useExecuteImport,
933
+ useExportExcel,
934
+ useForgotPassword,
935
+ useForgotPasswordSSO,
936
+ useGet2FAMethods,
937
+ useGetAccessByCode,
938
+ useGetAction,
939
+ useGetActionDetail,
940
+ useGetAll,
941
+ useGetCalendar,
942
+ useGetComment,
943
+ useGetCompanyInfo,
944
+ useGetConversionRate,
945
+ useGetCurrency,
946
+ useGetCurrentCompany,
947
+ useGetDetail,
948
+ useGetFieldExport,
949
+ useGetFieldOnChange,
950
+ useGetFileExcel,
951
+ useGetFormView,
952
+ useGetGroups,
953
+ useGetImage,
954
+ useGetListCompany,
955
+ useGetListData,
956
+ useGetListMyBankAccount,
957
+ useGetMenu,
958
+ useGetPrintReport,
959
+ useGetProGressBar,
960
+ useGetProfile,
961
+ useGetProvider,
962
+ useGetResequence,
880
963
  useGetRowIds,
964
+ useGetSelection,
965
+ useGetSpecification,
966
+ useGetUser,
967
+ useGetView,
968
+ useGrantAccess,
969
+ useIsValidToken,
881
970
  useListData,
971
+ useLoadAction,
972
+ useLoadMessage,
973
+ useLoginCredential,
974
+ useLoginSocial,
975
+ useLogout,
882
976
  useMenu,
883
- useMenuItem,
977
+ useModel,
978
+ useOdooDataTransform,
979
+ useOnChangeForm,
980
+ useParsePreview,
981
+ usePrint,
884
982
  useProfile,
983
+ useRemoveRow,
984
+ useRemoveTotpSetup,
985
+ useRequestSetupTotp,
986
+ useResetPassword,
987
+ useResetPasswordSSO,
988
+ useRunAction,
989
+ useSave,
990
+ useSendComment,
991
+ useSettingsWebRead2fa,
992
+ useSignInSSO,
993
+ useSwitchLocale,
994
+ useUpdatePassword,
995
+ useUploadFile,
996
+ useUploadFileExcel,
997
+ useUploadIdFile,
998
+ useUploadImage,
885
999
  useUser,
1000
+ useValidateActionToken,
1001
+ useVerify2FA,
1002
+ useVerifyTotp,
886
1003
  useViewV2
887
1004
  };