@fctc/widget-logic 1.1.4 → 1.1.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/index.mjs CHANGED
@@ -4031,8 +4031,623 @@ var require_moment = __commonJS({
4031
4031
  }
4032
4032
  });
4033
4033
 
4034
- // src/hooks/use-click-outside.ts
4035
- import { useEffect, useRef } from "react";
4034
+ // src/hooks/core/use-call-action.ts
4035
+ import { getEnv, useLoadAction, useRunAction } from "@fctc/interface-logic";
4036
+ import { useState } from "react";
4037
+ var useCallAction = () => {
4038
+ const queryLoadAction = useLoadAction();
4039
+ const queryRunAction = useRunAction();
4040
+ const [data, setData] = useState(void 0);
4041
+ const callAction = async ({
4042
+ aid,
4043
+ actionType = "ir.actions.act_window"
4044
+ }) => {
4045
+ const context = getEnv().context;
4046
+ let res = void 0;
4047
+ if (actionType === "ir.actions.act_window") {
4048
+ res = await queryLoadAction.mutateAsync({
4049
+ idAction: aid,
4050
+ context
4051
+ });
4052
+ } else if (actionType === "ir.actions.server") {
4053
+ res = await queryRunAction.mutateAsync({
4054
+ idAction: aid,
4055
+ context
4056
+ });
4057
+ }
4058
+ setData(res);
4059
+ return res;
4060
+ };
4061
+ return [data, callAction];
4062
+ };
4063
+
4064
+ // src/hooks/core/use-config.ts
4065
+ import {
4066
+ getEnv as getEnv2,
4067
+ setEnvFile,
4068
+ useAppDispatch
4069
+ } from "@fctc/interface-logic";
4070
+ import { useEffect, useMemo } from "react";
4071
+ var useConfig = ({ localStorageUtils, sessionStorageUtils }) => {
4072
+ const dispatch = useAppDispatch();
4073
+ const envConfig = useMemo(() => {
4074
+ return {
4075
+ mode: "development",
4076
+ baseUrl: "https://api.vitrust.app/c2/api/v2",
4077
+ config: {
4078
+ grantType: "password",
4079
+ clientId: "C52foVQSMpnNOcAP2CBIIkupOSfxUarF8nlOPfXM",
4080
+ clientSecret: "rColINr4a9QBFQPqQB8YU1XfBjqzwerDMJGBxsFK"
4081
+ }
4082
+ };
4083
+ }, []);
4084
+ const config = useMemo(() => {
4085
+ return {
4086
+ VITE_SIDEBAR_TYPE: "grid/sidebar",
4087
+ VITE_APP_DOMAIN: "https://api.vitrust.app/c2/",
4088
+ VITE_IS_EDU: true,
4089
+ VITE_LOGO_WHITE_LOGIN: "https://static.vitrust.app/vitrust/3a/3a1301f614dea6ee19ebf99b68f57e3fd46011d2.png",
4090
+ VITE_LOGO_BLACK_LOGIN: "https://static.vitrust.app/vitrust/32/3223918780da7a439f916faac9abf0bfe98dfa07.png",
4091
+ VITE_BACKGROUND_SIDEBAR: "linear-gradient(178deg, rgb(1, 106, 13) -0.89%, rgb(4, 179, 66) 99.46%",
4092
+ VITE_BANNER: "https://static.vitrust.app/vitrust/5d/5d20cab0627182b4ed5cba4ee42c58b98b663e5b.svg",
4093
+ VITE_BG_BUTTON: "#008F3C",
4094
+ VITE_BACKGROUND_PAGE: "#F9FAFB"
4095
+ };
4096
+ }, []);
4097
+ useEffect(() => {
4098
+ try {
4099
+ const env = getEnv2();
4100
+ env.setupEnv({
4101
+ baseUrl: envConfig.baseUrl,
4102
+ port: 3e3,
4103
+ config: {
4104
+ grantType: envConfig.config.grantType,
4105
+ clientId: envConfig.config.clientId,
4106
+ clientSecret: envConfig.config.clientSecret
4107
+ },
4108
+ db: "preschool",
4109
+ localStorageUtils: localStorageUtils(),
4110
+ sessionStorageUtils: sessionStorageUtils()
4111
+ });
4112
+ dispatch(setEnvFile(config));
4113
+ } catch (error) {
4114
+ console.error("Error loading env or config:", error);
4115
+ }
4116
+ }, [dispatch, envConfig, config]);
4117
+ return { envConfig, config };
4118
+ };
4119
+
4120
+ // src/hooks/core/use-detail.ts
4121
+ import { setProfile, useAppDispatch as useAppDispatch2, useGetDetail } from "@fctc/interface-logic";
4122
+ import { useQuery } from "@tanstack/react-query";
4123
+ import { useEffect as useEffect2 } from "react";
4124
+ var useDetail = (accessToken, sub) => {
4125
+ const dispatch = useAppDispatch2();
4126
+ const fetchGetDetail = useGetDetail();
4127
+ const userDetailQuery = useQuery({
4128
+ queryKey: ["userDetailQuery", sub && accessToken],
4129
+ queryFn: () => {
4130
+ return fetchGetDetail.mutateAsync({
4131
+ model: "res.users",
4132
+ ids: [sub],
4133
+ specification: { image_256: {} }
4134
+ });
4135
+ },
4136
+ enabled: !!sub && !!accessToken
4137
+ });
4138
+ useEffect2(() => {
4139
+ if (userDetailQuery.data) {
4140
+ const userPicture = userDetailQuery.data;
4141
+ dispatch(
4142
+ setProfile({ ...userPicture, image: userPicture?.[0]?.image_256 })
4143
+ );
4144
+ }
4145
+ }, [userDetailQuery.data, dispatch]);
4146
+ return userDetailQuery;
4147
+ };
4148
+
4149
+ // src/hooks/core/use-list-data.ts
4150
+ import { useMemo as useMemo2, useState as useState3 } from "react";
4151
+ import {
4152
+ evalJSONDomain,
4153
+ formatSortingString,
4154
+ selectList,
4155
+ selectSearch,
4156
+ useAppSelector,
4157
+ useGetListData,
4158
+ useModel
4159
+ } from "@fctc/interface-logic";
4160
+
4161
+ // src/utils/function.ts
4162
+ import { useCallback, useEffect as useEffect3, useReducer, useRef, useState as useState2 } from "react";
4163
+ var countSum = (data, field) => {
4164
+ if (!data || !field) return 0;
4165
+ return data.reduce(
4166
+ (total, item) => total + (item?.[`${field}_count`] || 0),
4167
+ 0
4168
+ );
4169
+ };
4170
+ function mergeButtons(fields) {
4171
+ const buttons = fields?.filter((f) => f.type_co === "button");
4172
+ const others = fields?.filter((f) => f.type_co !== "button");
4173
+ if (buttons?.length) {
4174
+ others.push({
4175
+ type_co: "buttons",
4176
+ buttons
4177
+ });
4178
+ }
4179
+ return others;
4180
+ }
4181
+ function isElementVisible(el) {
4182
+ const style = window.getComputedStyle(el);
4183
+ return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0";
4184
+ }
4185
+ function arraysAreEqual(a, b) {
4186
+ if (a.length !== b.length) return false;
4187
+ const setA = new Set(a);
4188
+ const setB = new Set(b);
4189
+ if (setA.size !== setB.size) return false;
4190
+ for (const val of setA) {
4191
+ if (!setB.has(val)) return false;
4192
+ }
4193
+ return true;
4194
+ }
4195
+ function useGetRowIds(tableRef) {
4196
+ const [rowIds, setRowIds] = useState2([]);
4197
+ const lastRowIdsRef = useRef([]);
4198
+ const updateVisibleRowIds = useCallback(() => {
4199
+ const table = tableRef?.current;
4200
+ if (!table) return;
4201
+ const rows = table.querySelectorAll("tr[data-row-id]");
4202
+ const ids = [];
4203
+ rows.forEach((row) => {
4204
+ const el = row;
4205
+ if (isElementVisible(el)) {
4206
+ const id = el.getAttribute("data-row-id");
4207
+ if (id) ids.push(id);
4208
+ }
4209
+ });
4210
+ const uniqueIds = Array.from(new Set(ids));
4211
+ if (!arraysAreEqual(lastRowIdsRef.current, uniqueIds)) {
4212
+ lastRowIdsRef.current = uniqueIds;
4213
+ setRowIds(uniqueIds);
4214
+ }
4215
+ }, [tableRef]);
4216
+ useEffect3(() => {
4217
+ const table = tableRef?.current;
4218
+ if (!table) return;
4219
+ const observer = new MutationObserver(() => {
4220
+ updateVisibleRowIds();
4221
+ });
4222
+ observer.observe(table, {
4223
+ childList: true,
4224
+ subtree: true,
4225
+ attributes: true,
4226
+ attributeFilter: ["style", "class"]
4227
+ });
4228
+ updateVisibleRowIds();
4229
+ return () => {
4230
+ observer.disconnect();
4231
+ };
4232
+ }, [updateVisibleRowIds, tableRef]);
4233
+ return { rowIds, refresh: updateVisibleRowIds };
4234
+ }
4235
+ var getDateRange = (currentDate, unit) => {
4236
+ const date = new Date(currentDate);
4237
+ let dateStart, dateEnd;
4238
+ function formatDate(d) {
4239
+ 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");
4240
+ }
4241
+ switch (unit) {
4242
+ case "month":
4243
+ dateStart = new Date(
4244
+ date.getFullYear(),
4245
+ date.getMonth() + 1,
4246
+ date.getDate(),
4247
+ 23,
4248
+ 59,
4249
+ 59
4250
+ );
4251
+ dateStart.setHours(dateStart.getHours() - 7);
4252
+ dateEnd = new Date(date.getFullYear(), date.getMonth(), 0, 0, 0, 0);
4253
+ dateEnd.setHours(dateEnd.getHours() - 7);
4254
+ break;
4255
+ case "day":
4256
+ dateStart = new Date(
4257
+ date.getFullYear(),
4258
+ date.getMonth(),
4259
+ date.getDate(),
4260
+ 23,
4261
+ 59,
4262
+ 59
4263
+ );
4264
+ dateStart.setHours(dateStart.getHours() - 7);
4265
+ dateEnd = new Date(
4266
+ date.getFullYear(),
4267
+ date.getMonth(),
4268
+ date.getDate(),
4269
+ 0,
4270
+ 0,
4271
+ 0
4272
+ );
4273
+ dateEnd.setHours(dateEnd.getHours() - 7);
4274
+ break;
4275
+ case "week":
4276
+ const dayOfWeek = date.getDay();
4277
+ const daysToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
4278
+ const daysToSunday = dayOfWeek === 0 ? 0 : 7 - dayOfWeek;
4279
+ dateStart = new Date(
4280
+ date.getFullYear(),
4281
+ date.getMonth(),
4282
+ date.getDate() + daysToSunday,
4283
+ 23,
4284
+ 59,
4285
+ 59
4286
+ );
4287
+ dateStart.setHours(dateStart.getHours() - 7);
4288
+ dateEnd = new Date(
4289
+ date.getFullYear(),
4290
+ date.getMonth(),
4291
+ date.getDate() + daysToMonday,
4292
+ 0,
4293
+ 0,
4294
+ 0
4295
+ );
4296
+ dateEnd.setHours(dateEnd.getHours() - 7);
4297
+ break;
4298
+ case "year":
4299
+ dateStart = new Date(date.getFullYear(), 11, 31, 23, 59, 59);
4300
+ dateStart.setHours(dateStart.getHours() - 7);
4301
+ dateEnd = new Date(date.getFullYear() - 1, 11, 31, 0, 0, 0);
4302
+ dateEnd.setHours(dateEnd.getHours() - 7);
4303
+ break;
4304
+ default:
4305
+ throw new Error(
4306
+ "\u0110\u01A1n v\u1ECB kh\xF4ng h\u1EE3p l\u1EC7. Ch\u1EC9 ch\u1EA5p nh\u1EADn: week, day, month, year"
4307
+ );
4308
+ }
4309
+ return [
4310
+ ["date_start", "<=", formatDate(dateStart)],
4311
+ ["date_end", ">=", formatDate(dateEnd)]
4312
+ ];
4313
+ };
4314
+ var convertFieldsToArray = (fields) => {
4315
+ const defaultFields = ["display_name", "date_start", "date_end"];
4316
+ if (!fields || !Array.isArray(fields)) {
4317
+ return defaultFields;
4318
+ }
4319
+ const inputFields = fields.filter((field) => field && field.type_co === "field").map((field) => field.name);
4320
+ return [...defaultFields, ...inputFields];
4321
+ };
4322
+ function combineContexts(contexts) {
4323
+ if (contexts.some((context) => !context)) {
4324
+ return void 0;
4325
+ } else {
4326
+ const res = contexts.reduce((acc, context) => {
4327
+ return { ...acc, ...context };
4328
+ }, {});
4329
+ return res;
4330
+ }
4331
+ }
4332
+ var STORAGES = {
4333
+ TOKEN: "accessToken",
4334
+ USER_INFO: "USER_INFO"
4335
+ };
4336
+ function useAsyncState(initialValue = [true, null]) {
4337
+ return useReducer(
4338
+ (_state, action = null) => [false, action],
4339
+ initialValue
4340
+ );
4341
+ }
4342
+ async function setStorageItemAsync(key, value) {
4343
+ try {
4344
+ if (value === null) {
4345
+ localStorage.removeItem(key);
4346
+ } else {
4347
+ localStorage.setItem(key, value);
4348
+ }
4349
+ } catch (e) {
4350
+ console.error("Local storage is unavailable:", e);
4351
+ }
4352
+ }
4353
+ function useStorageState(key) {
4354
+ const [state, setState] = useAsyncState();
4355
+ useEffect3(() => {
4356
+ try {
4357
+ const storedValue = localStorage.getItem(key);
4358
+ setState(storedValue);
4359
+ } catch (e) {
4360
+ console.error("Local storage is unavailable:", e);
4361
+ }
4362
+ }, [key]);
4363
+ const setValue = useCallback(
4364
+ (value) => {
4365
+ setState(value);
4366
+ setStorageItemAsync(key, value);
4367
+ },
4368
+ [key]
4369
+ );
4370
+ return [state, setValue];
4371
+ }
4372
+
4373
+ // src/hooks/core/use-list-data.ts
4374
+ var useListData = ({
4375
+ action,
4376
+ context,
4377
+ viewResponse
4378
+ }) => {
4379
+ const { groupByDomain } = useAppSelector(selectSearch);
4380
+ const initModel = useModel();
4381
+ const [type, setType] = useState3("list");
4382
+ const [mode, setMode] = useState3("month");
4383
+ const [currentDate, setCurrentDate] = useState3(/* @__PURE__ */ new Date());
4384
+ const { pageLimit, page, order } = useAppSelector(selectList);
4385
+ const listDataProps = useMemo2(() => {
4386
+ const actData = action?.result;
4387
+ if (!viewResponse || !actData || !context) {
4388
+ return null;
4389
+ }
4390
+ const specification = initModel.initModel({
4391
+ name: String(actData.res_model),
4392
+ view: viewResponse || {},
4393
+ actContext: context,
4394
+ fields: type === "kanban" ? viewResponse?.views?.kanban?.fields : type === "calendar" ? viewResponse?.views?.calendar?.fields : viewResponse?.views?.list?.fields
4395
+ }).getSpecification();
4396
+ const domain = type === "calendar" ? getDateRange(currentDate, mode) : actData?.domain ? Array.isArray(actData?.domain) ? [...actData?.domain] : evalJSONDomain(actData?.domain, context) : [];
4397
+ const limit = type === "calendar" ? 2500 : pageLimit;
4398
+ const offset = page * pageLimit;
4399
+ const fields = type === "calendar" ? convertFieldsToArray(viewResponse?.views?.calendar?.fields) || [] : typeof groupByDomain === "object" ? groupByDomain?.fields : void 0;
4400
+ const groupby = typeof groupByDomain === "object" ? [groupByDomain?.contexts?.[0]?.group_by] : [];
4401
+ const sort = order ? order : viewResponse?.views?.list?.default_order ? formatSortingString(viewResponse?.views?.list?.default_order) : "";
4402
+ return {
4403
+ model: actData.res_model,
4404
+ specification,
4405
+ domain,
4406
+ limit,
4407
+ offset,
4408
+ fields,
4409
+ groupby,
4410
+ context,
4411
+ sort,
4412
+ type
4413
+ };
4414
+ }, [
4415
+ action?.result,
4416
+ context,
4417
+ currentDate,
4418
+ groupByDomain,
4419
+ initModel,
4420
+ mode,
4421
+ order,
4422
+ page,
4423
+ pageLimit,
4424
+ type,
4425
+ viewResponse
4426
+ ]);
4427
+ const list = useGetListData(
4428
+ listDataProps,
4429
+ [listDataProps],
4430
+ !!listDataProps
4431
+ );
4432
+ return {
4433
+ ...list,
4434
+ state: {
4435
+ type,
4436
+ setType,
4437
+ mode,
4438
+ setMode,
4439
+ currentDate,
4440
+ setCurrentDate
4441
+ }
4442
+ };
4443
+ };
4444
+
4445
+ // src/hooks/core/use-menu.ts
4446
+ import { useEffect as useEffect4, useMemo as useMemo3, useState as useState4 } from "react";
4447
+ import { useGetMenu } from "@fctc/interface-logic";
4448
+
4449
+ // src/utils/constants.ts
4450
+ var languages = [
4451
+ { id: "vi_VN", name: "VIE" },
4452
+ { id: "en_US", name: "ENG" }
4453
+ ];
4454
+ var API_PRESCHOOL_URL = {
4455
+ baseURL: "https://preschool.vitrust.app"
4456
+ };
4457
+ var API_APP_URL = {
4458
+ baseUrl: "https://api.vitrust.app",
4459
+ c2: "https://api.vitrust.app/c2",
4460
+ apiV2: "https://api.vitrust.app/c2/api/v2"
4461
+ };
4462
+
4463
+ // src/hooks/core/use-menu.ts
4464
+ var useMenu = ({ context }) => {
4465
+ const menuData = useGetMenu(context, !!context);
4466
+ const [menuid, setMenuId] = useState4(void 0);
4467
+ const [action, setAction] = useCallAction();
4468
+ const configedIconData = useMemo3(() => {
4469
+ const data = menuData.data;
4470
+ return data?.map((item) => {
4471
+ return {
4472
+ ...item,
4473
+ child_id: item?.child_id?.map((child) => {
4474
+ return {
4475
+ ...child,
4476
+ url_icon: API_APP_URL.c2 + "/" + child.url_icon
4477
+ };
4478
+ }) ?? [],
4479
+ url_icon: API_APP_URL.c2 + "/" + item.url_icon
4480
+ };
4481
+ });
4482
+ }, [menuData.data]);
4483
+ const handleChangeMenu = async ({
4484
+ menu,
4485
+ subMenu
4486
+ }) => {
4487
+ const aid = subMenu?.action?.id?.id;
4488
+ const actionType = subMenu?.action?.type;
4489
+ await setAction({
4490
+ aid: Number(aid),
4491
+ actionType
4492
+ });
4493
+ if (menu) {
4494
+ setMenuId(menu.id?.toString() ?? "");
4495
+ }
4496
+ };
4497
+ useEffect4(() => {
4498
+ const firstRecord = configedIconData?.[0];
4499
+ const firstChild = firstRecord?.child_id?.[0];
4500
+ if (firstChild && firstRecord) {
4501
+ handleChangeMenu({ menu: firstRecord, subMenu: firstChild });
4502
+ }
4503
+ }, [configedIconData]);
4504
+ return {
4505
+ ...menuData,
4506
+ data: configedIconData,
4507
+ action: { handleChangeMenu },
4508
+ state: { menuid, action },
4509
+ context
4510
+ };
4511
+ };
4512
+
4513
+ // src/hooks/core/use-profile.ts
4514
+ import { useQuery as useQuery2 } from "@tanstack/react-query";
4515
+ import { useEffect as useEffect5, useMemo as useMemo4 } from "react";
4516
+ import { useTranslation } from "react-i18next";
4517
+ import {
4518
+ getEnv as getEnv3,
4519
+ setDataUser,
4520
+ useAppDispatch as useAppDispatch3,
4521
+ useGetProfile
4522
+ } from "@fctc/interface-logic";
4523
+ var useProfile = (accessToken) => {
4524
+ const getProfile = useGetProfile();
4525
+ const dispatch = useAppDispatch3();
4526
+ const { i18n: i18n2 } = useTranslation();
4527
+ const fetchUserProfile = async () => {
4528
+ return await getProfile.mutateAsync();
4529
+ };
4530
+ const userInfoQuery = useQuery2({
4531
+ queryKey: ["userInfo", accessToken],
4532
+ queryFn: fetchUserProfile,
4533
+ enabled: !!accessToken
4534
+ });
4535
+ useEffect5(() => {
4536
+ if (userInfoQuery.data) {
4537
+ const userInfo = userInfoQuery.data;
4538
+ const env = getEnv3();
4539
+ env.setUid(userInfo?.sub);
4540
+ dispatch(setDataUser(userInfo));
4541
+ const userLocale = languages.find((lang) => lang?.id === userInfo?.locale);
4542
+ env.setLang(userLocale?.id);
4543
+ i18n2.changeLanguage(userLocale?.id.split("_")[0]);
4544
+ }
4545
+ }, [dispatch, userInfoQuery.data]);
4546
+ const context = useMemo4(() => {
4547
+ if (userInfoQuery.data?.sub && userInfoQuery.data?.locale) {
4548
+ return {
4549
+ uid: Number(userInfoQuery.data.sub),
4550
+ allowed_company_ids: [],
4551
+ lang: String(userInfoQuery.data.locale),
4552
+ tz: "Asia/Saigon"
4553
+ };
4554
+ }
4555
+ return void 0;
4556
+ }, [userInfoQuery.data]);
4557
+ return { ...userInfoQuery, context };
4558
+ };
4559
+
4560
+ // src/hooks/core/use-user.ts
4561
+ var useUser = (accessToken) => {
4562
+ const userProfile = useProfile(accessToken);
4563
+ const userDetail = useDetail(accessToken, userProfile.data?.sub);
4564
+ return { userProfile, userDetail, context: userProfile.context };
4565
+ };
4566
+
4567
+ // src/hooks/core/use-view-v2.ts
4568
+ import { useMemo as useMemo5 } from "react";
4569
+ import { useGetView } from "@fctc/interface-logic";
4570
+ var useViewV2 = ({
4571
+ action,
4572
+ context
4573
+ }) => {
4574
+ const viewParams = useMemo5(() => {
4575
+ if (!action?.result) {
4576
+ return void 0;
4577
+ }
4578
+ const actionResult = action?.result;
4579
+ return {
4580
+ model: String(actionResult?.res_model),
4581
+ views: [
4582
+ ...Array.isArray(actionResult?.views) ? actionResult?.views.map(
4583
+ (view2) => view2[1] === "list" ? [view2[0], "list"] : view2
4584
+ ) : [],
4585
+ [
4586
+ Array.isArray(actionResult?.search_view_id) ? actionResult?.search_view_id[0] : actionResult?.search_view_id,
4587
+ "search"
4588
+ ]
4589
+ ],
4590
+ context
4591
+ };
4592
+ }, [action, context]);
4593
+ const view = useGetView(
4594
+ viewParams || {},
4595
+ !!viewParams
4596
+ );
4597
+ return {
4598
+ ...view,
4599
+ context
4600
+ };
4601
+ };
4602
+
4603
+ // src/hooks/core/use-auth.ts
4604
+ import {
4605
+ setDataUser as setDataUser2,
4606
+ setMenuList,
4607
+ setProfile as setProfile2,
4608
+ useAppDispatch as useAppDispatch4,
4609
+ useLoginCredential
4610
+ } from "@fctc/interface-logic";
4611
+ var useAuth = () => {
4612
+ const [[isLoading, accessToken], setAccessToken] = useStorageState("TOKEN");
4613
+ const loginMutate = useLoginCredential();
4614
+ const dispatch = useAppDispatch4();
4615
+ const signIn = async (email, password) => {
4616
+ try {
4617
+ loginMutate.mutate(
4618
+ {
4619
+ email,
4620
+ password,
4621
+ path: "/authentication/oauth2/token"
4622
+ },
4623
+ {
4624
+ onSuccess: (res) => {
4625
+ setAccessToken(res.access_token);
4626
+ },
4627
+ onError: (err) => {
4628
+ }
4629
+ }
4630
+ );
4631
+ } catch (error) {
4632
+ throw new Error("Login failed");
4633
+ }
4634
+ };
4635
+ const signOut = async () => {
4636
+ dispatch(setMenuList([]));
4637
+ dispatch(setDataUser2({}));
4638
+ dispatch(setProfile2({}));
4639
+ setAccessToken(null);
4640
+ };
4641
+ return {
4642
+ signIn,
4643
+ signOut,
4644
+ accessToken,
4645
+ isLoading
4646
+ };
4647
+ };
4648
+
4649
+ // src/hooks/utils/use-click-outside.ts
4650
+ import { useEffect as useEffect6, useRef as useRef2 } from "react";
4036
4651
  var DEFAULT_EVENTS = ["mousedown", "touchstart"];
4037
4652
  var useClickOutside = ({
4038
4653
  handler,
@@ -4040,8 +4655,8 @@ var useClickOutside = ({
4040
4655
  nodes = [],
4041
4656
  refs
4042
4657
  }) => {
4043
- const ref = useRef(null);
4044
- useEffect(() => {
4658
+ const ref = useRef2(null);
4659
+ useEffect6(() => {
4045
4660
  const listener = (event) => {
4046
4661
  const { target } = event;
4047
4662
  if (refs && refs?.length > 0 && refs?.some((r) => r.current?.contains(target))) {
@@ -4062,11 +4677,11 @@ var useClickOutside = ({
4062
4677
  return ref;
4063
4678
  };
4064
4679
 
4065
- // src/hooks/use-debounce.ts
4066
- import { useEffect as useEffect2, useState } from "react";
4680
+ // src/hooks/utils/use-debounce.ts
4681
+ import { useEffect as useEffect7, useState as useState5 } from "react";
4067
4682
  function useDebounce(value, delay) {
4068
- const [debouncedValue, setDebouncedValue] = useState(value);
4069
- useEffect2(() => {
4683
+ const [debouncedValue, setDebouncedValue] = useState5(value);
4684
+ useEffect7(() => {
4070
4685
  const handler = setTimeout(() => {
4071
4686
  setDebouncedValue(value);
4072
4687
  }, delay);
@@ -4184,19 +4799,19 @@ var CloseIcon = ({ className = "" }) => {
4184
4799
  };
4185
4800
 
4186
4801
  // src/widget/basic/status-dropdown-field/controller.ts
4187
- import { useEffect as useEffect3, useRef as useRef2, useState as useState2 } from "react";
4188
- import { getEnv, useSave } from "@fctc/interface-logic";
4802
+ import { useEffect as useEffect8, useRef as useRef3, useState as useState6 } from "react";
4803
+ import { getEnv as getEnv4, useSave } from "@fctc/interface-logic";
4189
4804
  var statusDropdownController = (props) => {
4190
4805
  const { selection, isForm, id, model, name, state, onRefetch } = props;
4191
- const env = getEnv();
4806
+ const env = getEnv4();
4192
4807
  const colors = {
4193
4808
  normal: "bg-[#e9ecef]",
4194
4809
  done: "bg-primary",
4195
4810
  blocked: "bg-red-500"
4196
4811
  };
4197
- const [isOpen, setIsOpen] = useState2(false);
4198
- const buttonRef = useRef2(null);
4199
- useEffect3(() => {
4812
+ const [isOpen, setIsOpen] = useState6(false);
4813
+ const buttonRef = useRef3(null);
4814
+ useEffect8(() => {
4200
4815
  const handleClickOutside = (event) => {
4201
4816
  if (buttonRef.current && !buttonRef.current.contains(event.target)) {
4202
4817
  setIsOpen(false);
@@ -4237,14 +4852,14 @@ var statusDropdownController = (props) => {
4237
4852
  };
4238
4853
 
4239
4854
  // src/widget/basic/many2one-field/controller.ts
4240
- import { useCallback, useEffect as useEffect4, useMemo, useState as useState3 } from "react";
4855
+ import { useCallback as useCallback2, useEffect as useEffect9, useMemo as useMemo6, useState as useState7 } from "react";
4241
4856
  import {
4242
4857
  evalJSONContext,
4243
- evalJSONDomain,
4858
+ evalJSONDomain as evalJSONDomain2,
4244
4859
  selectEnv,
4245
4860
  selectNavbar,
4246
4861
  setListSubject,
4247
- useAppSelector,
4862
+ useAppSelector as useAppSelector2,
4248
4863
  useGetSelection
4249
4864
  } from "@fctc/interface-logic";
4250
4865
  var many2oneFieldController = (props) => {
@@ -4261,15 +4876,15 @@ var many2oneFieldController = (props) => {
4261
4876
  showDetail = true,
4262
4877
  actionData
4263
4878
  } = props;
4264
- const [options, setOptions] = useState3([]);
4265
- const [isShowModalMany2Many, setIsShowModalMany2Many] = useState3(false);
4266
- const [tempSelectedOption, setTempSelectedOption] = useState3(null);
4267
- const { menuList } = useAppSelector(selectNavbar);
4268
- const { context } = useAppSelector(selectEnv);
4269
- const [domainModal, setDomainModal] = useState3(null);
4879
+ const [options, setOptions] = useState7([]);
4880
+ const [isShowModalMany2Many, setIsShowModalMany2Many] = useState7(false);
4881
+ const [tempSelectedOption, setTempSelectedOption] = useState7(null);
4882
+ const { menuList } = useAppSelector2(selectNavbar);
4883
+ const { context } = useAppSelector2(selectEnv);
4884
+ const [domainModal, setDomainModal] = useState7(null);
4270
4885
  const initValue = methods?.getValues(name);
4271
- const domainObject = useMemo(
4272
- () => evalJSONDomain(domain, JSON.parse(JSON.stringify(formValues)) ?? {}),
4886
+ const domainObject = useMemo6(
4887
+ () => evalJSONDomain2(domain, JSON.parse(JSON.stringify(formValues)) ?? {}),
4273
4888
  [domain, formValues]
4274
4889
  );
4275
4890
  const optionsObject = evalJSONContext(fieldOptions) || {};
@@ -4278,7 +4893,7 @@ var many2oneFieldController = (props) => {
4278
4893
  ...fieldContext,
4279
4894
  ...context
4280
4895
  };
4281
- const actionId = useMemo(
4896
+ const actionId = useMemo6(
4282
4897
  () => menuList?.flatMap(
4283
4898
  (item) => item?.child_id.filter(
4284
4899
  (childItem) => childItem?.is_display && childItem?.action?.res_model === relation
@@ -4299,25 +4914,25 @@ var many2oneFieldController = (props) => {
4299
4914
  const queryKey = [`data_${relation}`, domainObject];
4300
4915
  const {
4301
4916
  data: dataOfSelection,
4302
- refetch,
4917
+ // refetch,
4303
4918
  isFetching
4304
4919
  } = useGetSelection({
4305
4920
  data,
4306
4921
  queryKey,
4307
4922
  enabled: false
4308
4923
  });
4309
- const selectOptions = useMemo(() => {
4924
+ const selectOptions = useMemo6(() => {
4310
4925
  return dataOfSelection?.records?.map((val) => ({
4311
4926
  value: val?.id,
4312
4927
  label: val?.display_name || val?.name
4313
4928
  })) || [];
4314
4929
  }, [dataOfSelection]);
4315
- useEffect4(() => {
4930
+ useEffect9(() => {
4316
4931
  setOptions(selectOptions);
4317
4932
  setDomainModal(domainObject);
4318
4933
  if (relation === "student.subject") setListSubject(selectOptions);
4319
4934
  }, [selectOptions]);
4320
- useEffect4(() => {
4935
+ useEffect9(() => {
4321
4936
  if (!propValue && tempSelectedOption) {
4322
4937
  methods.setValue(name, null);
4323
4938
  setTempSelectedOption(null);
@@ -4328,15 +4943,12 @@ var many2oneFieldController = (props) => {
4328
4943
  });
4329
4944
  }
4330
4945
  }, [propValue]);
4331
- const fetchMoreOptions = useCallback(() => {
4332
- refetch();
4333
- }, [refetch]);
4334
- useEffect4(() => {
4946
+ useEffect9(() => {
4335
4947
  if (actionId) {
4336
4948
  localStorage.setItem("aid", actionId);
4337
4949
  }
4338
4950
  }, [actionId]);
4339
- const handleChooseRecord = useCallback(
4951
+ const handleChooseRecord = useCallback2(
4340
4952
  (idRecord) => {
4341
4953
  const newOption = options.find(
4342
4954
  (option) => option.value === idRecord
@@ -4361,8 +4973,8 @@ var many2oneFieldController = (props) => {
4361
4973
  },
4362
4974
  [options, methods, name, onChange]
4363
4975
  );
4364
- const handleClose = useCallback(() => setIsShowModalMany2Many(false), []);
4365
- const handleSelectChange = useCallback(
4976
+ const handleClose = useCallback2(() => setIsShowModalMany2Many(false), []);
4977
+ const handleSelectChange = useCallback2(
4366
4978
  (selectedOption) => {
4367
4979
  if (!selectedOption) {
4368
4980
  methods.setValue(name, null, { shouldDirty: true });
@@ -4396,13 +5008,13 @@ var many2oneFieldController = (props) => {
4396
5008
  isFetching,
4397
5009
  isShowModalMany2Many,
4398
5010
  options,
4399
- fetchMoreOptions,
5011
+ // fetchMoreOptions,
4400
5012
  domainModal,
4401
5013
  tempSelectedOption,
4402
5014
  setTempSelectedOption,
4403
5015
  setDomainModal,
4404
5016
  dataOfSelection,
4405
- refetch,
5017
+ // refetch,
4406
5018
  selectOptions,
4407
5019
  optionsObject,
4408
5020
  contextObject,
@@ -4414,18 +5026,15 @@ var many2oneFieldController = (props) => {
4414
5026
  // src/widget/basic/many2one-button-field/controller.ts
4415
5027
  import {
4416
5028
  evalJSONContext as evalJSONContext2,
4417
- evalJSONDomain as evalJSONDomain2,
4418
- getEnv as getEnv2,
5029
+ evalJSONDomain as evalJSONDomain3,
5030
+ getEnv as getEnv5,
4419
5031
  useGetSelection as useGetSelection2
4420
5032
  } from "@fctc/interface-logic";
4421
- var many2oneButtonController = ({
4422
- relation,
4423
- methods,
4424
- domain
4425
- }) => {
5033
+ var many2oneButtonController = (props) => {
5034
+ const { domain, methods, relation } = props;
4426
5035
  const actionDataString = sessionStorage.getItem("actionData");
4427
- const env = getEnv2();
4428
- const domainObject = evalJSONDomain2(domain, methods?.getValues() || {});
5036
+ const env = getEnv5();
5037
+ const domainObject = evalJSONDomain3(domain, methods?.getValues() || {});
4429
5038
  const actionData = actionDataString && actionDataString !== "undefined" ? JSON.parse(actionDataString) : {};
4430
5039
  const { data: dataOfSelection } = useGetSelection2({
4431
5040
  data: {
@@ -4445,41 +5054,47 @@ var many2oneButtonController = ({
4445
5054
  };
4446
5055
 
4447
5056
  // src/widget/basic/many2many-field/controller.ts
4448
- import { useEffect as useEffect6, useMemo as useMemo2, useState as useState5 } from "react";
5057
+ import { useEffect as useEffect13, useMemo as useMemo10, useState as useState10 } from "react";
4449
5058
  import {
4450
5059
  evalJSONContext as evalJSONContext3,
4451
- formatSortingString,
4452
- getEnv as getEnv3,
4453
- selectSearch,
5060
+ formatSortingString as formatSortingString2,
5061
+ getEnv as getEnv7,
5062
+ selectSearch as selectSearch5,
4454
5063
  setFirstDomain,
4455
5064
  setGroupByDomain,
4456
5065
  setPage,
4457
5066
  setViewDataStore,
4458
- useAppDispatch,
4459
- useAppSelector as useAppSelector2,
5067
+ useAppDispatch as useAppDispatch8,
5068
+ useAppSelector as useAppSelector6,
4460
5069
  useGetFormView,
4461
- useGetListData,
4462
- useGetView,
4463
- useModel
5070
+ useGetListData as useGetListData3,
5071
+ useGetView as useGetView2,
5072
+ useModel as useModel2
4464
5073
  } from "@fctc/interface-logic";
4465
5074
 
4466
- // src/widget/table/use-table.ts
4467
- import { domainHelper } from "@fctc/interface-logic";
4468
- import { useEffect as useEffect5, useState as useState4 } from "react";
4469
- function mergeButtons(fields) {
4470
- const buttons = fields?.filter((f) => f.type_co === "button");
4471
- const others = fields?.filter((f) => f.type_co !== "button");
4472
- if (buttons?.length) {
4473
- others.push({
4474
- type_co: "buttons",
4475
- buttons
4476
- });
4477
- }
4478
- return others;
4479
- }
4480
- var useTableHandler = ({ data }) => {
4481
- const [rows, setRows] = useState4(data.records || []);
4482
- const [columns, setColumns] = useState4([]);
5075
+ // src/widget/advance/table/table-body/controller.ts
5076
+ import { setSelectedRowKeys, useAppDispatch as useAppDispatch5 } from "@fctc/interface-logic";
5077
+ import { useEffect as useEffect10, useMemo as useMemo7 } from "react";
5078
+
5079
+ // src/widget/advance/table/table-head/controller.ts
5080
+ import {
5081
+ selectSearch as selectSearch2,
5082
+ setSelectedRowKeys as setSelectedRowKeys2,
5083
+ useAppDispatch as useAppDispatch6,
5084
+ useAppSelector as useAppSelector3
5085
+ } from "@fctc/interface-logic";
5086
+
5087
+ // src/widget/advance/table/table-view/controller.ts
5088
+ import {
5089
+ domainHelper,
5090
+ selectList as selectList2,
5091
+ selectSearch as selectSearch3,
5092
+ useAppSelector as useAppSelector4
5093
+ } from "@fctc/interface-logic";
5094
+ import { useEffect as useEffect11, useMemo as useMemo8, useRef as useRef4, useState as useState8 } from "react";
5095
+ var tableController = ({ data }) => {
5096
+ const [rows, setRows] = useState8(data.records || []);
5097
+ const [columns, setColumns] = useState8([]);
4483
5098
  const dataModelFields = data.fields?.map((field) => {
4484
5099
  return {
4485
5100
  ...data.dataModel?.[field?.name],
@@ -4507,7 +5122,7 @@ var useTableHandler = ({ data }) => {
4507
5122
  return item.display_name ? { ...transformedItem, item: item.display_name } : transformedItem;
4508
5123
  });
4509
5124
  };
4510
- useEffect5(() => {
5125
+ useEffect11(() => {
4511
5126
  setRows(transformData(data.records || null));
4512
5127
  }, [data.records]);
4513
5128
  const handleGetColumns = () => {
@@ -4528,7 +5143,7 @@ var useTableHandler = ({ data }) => {
4528
5143
  }
4529
5144
  return cols;
4530
5145
  };
4531
- useEffect5(() => {
5146
+ useEffect11(() => {
4532
5147
  const columns2 = handleGetColumns();
4533
5148
  setColumns(columns2);
4534
5149
  }, [data.records]);
@@ -4552,6 +5167,41 @@ var useTableHandler = ({ data }) => {
4552
5167
  };
4553
5168
  };
4554
5169
 
5170
+ // src/widget/advance/table/table-group/controller.ts
5171
+ import {
5172
+ getEnv as getEnv6,
5173
+ selectList as selectList3,
5174
+ selectSearch as selectSearch4,
5175
+ setSelectedRowKeys as setSelectedRowKeys3,
5176
+ useAppDispatch as useAppDispatch7,
5177
+ useAppSelector as useAppSelector5,
5178
+ useGetListData as useGetListData2,
5179
+ useOdooDataTransform
5180
+ } from "@fctc/interface-logic";
5181
+ import { useEffect as useEffect12, useMemo as useMemo9, useState as useState9 } from "react";
5182
+
5183
+ // src/utils/i18n.ts
5184
+ import { initReactI18next } from "react-i18next";
5185
+ import i18n from "i18next";
5186
+ import LanguageDetector from "i18next-browser-languagedetector";
5187
+ i18n.use(LanguageDetector).use(initReactI18next).init({
5188
+ resources: {
5189
+ vi: { translation: vi },
5190
+ en: { translation: en }
5191
+ },
5192
+ fallbackLng: "vi",
5193
+ lng: "vi_VN",
5194
+ debug: false,
5195
+ nonExplicitSupportedLngs: true,
5196
+ interpolation: {
5197
+ escapeValue: false
5198
+ },
5199
+ detection: {
5200
+ caches: ["cookie"]
5201
+ }
5202
+ });
5203
+ var i18n_default = i18n;
5204
+
4555
5205
  // src/widget/basic/many2many-field/controller.ts
4556
5206
  var many2manyFieldController = (props) => {
4557
5207
  const {
@@ -4561,7 +5211,7 @@ var many2manyFieldController = (props) => {
4561
5211
  tab,
4562
5212
  model,
4563
5213
  aid,
4564
- setSelectedRowKeys,
5214
+ setSelectedRowKeys: setSelectedRowKeys4,
4565
5215
  fields,
4566
5216
  setFields,
4567
5217
  groupByDomain,
@@ -4569,17 +5219,17 @@ var many2manyFieldController = (props) => {
4569
5219
  options,
4570
5220
  sessionStorageUtils
4571
5221
  } = props;
4572
- const appDispatch = useAppDispatch();
5222
+ const appDispatch = useAppDispatch8();
4573
5223
  const actionData = sessionStorageUtils.getActionData();
4574
5224
  const [debouncedPage] = useDebounce(page, 500);
4575
- const [order, setOrder] = useState5();
4576
- const [isLoadedData, setIsLoadedData] = useState5(false);
4577
- const [domainMany2Many, setDomainMany2Many] = useState5(domain);
4578
- const env = getEnv3();
5225
+ const [order, setOrder] = useState10();
5226
+ const [isLoadedData, setIsLoadedData] = useState10(false);
5227
+ const [domainMany2Many, setDomainMany2Many] = useState10(domain);
5228
+ const env = getEnv7();
4579
5229
  const {
4580
5230
  // tableHead,
4581
5231
  selectedTags
4582
- } = useAppSelector2(selectSearch);
5232
+ } = useAppSelector6(selectSearch5);
4583
5233
  const viewParams = {
4584
5234
  model: relation,
4585
5235
  views: [
@@ -4588,11 +5238,11 @@ var many2manyFieldController = (props) => {
4588
5238
  ],
4589
5239
  context
4590
5240
  };
4591
- const { data: viewResponse, isFetched: isViewReponseFetched } = useGetView(
5241
+ const { data: viewResponse, isFetched: isViewReponseFetched } = useGetView2(
4592
5242
  viewParams,
4593
5243
  actionData
4594
5244
  );
4595
- const baseModel = useMemo2(
5245
+ const baseModel = useMemo10(
4596
5246
  () => ({
4597
5247
  name: String(relation),
4598
5248
  view: viewResponse || {},
@@ -4604,14 +5254,14 @@ var many2manyFieldController = (props) => {
4604
5254
  }),
4605
5255
  [model, viewResponse]
4606
5256
  );
4607
- const initModel = useModel();
4608
- const modelInstance = useMemo2(() => {
5257
+ const initModel = useModel2();
5258
+ const modelInstance = useMemo10(() => {
4609
5259
  if (viewResponse) {
4610
5260
  return initModel.initModel(baseModel);
4611
5261
  }
4612
5262
  return null;
4613
5263
  }, [baseModel, viewResponse]);
4614
- const specification = useMemo2(() => {
5264
+ const specification = useMemo10(() => {
4615
5265
  if (modelInstance) {
4616
5266
  return modelInstance.getSpecification();
4617
5267
  }
@@ -4656,7 +5306,7 @@ var many2manyFieldController = (props) => {
4656
5306
  context,
4657
5307
  fields: groupByDomain?.fields,
4658
5308
  groupby: [groupByDomain?.contexts[0]?.group_by],
4659
- sort: order ? order : default_order ? formatSortingString(default_order) : ""
5309
+ sort: order ? order : default_order ? formatSortingString2(default_order) : ""
4660
5310
  };
4661
5311
  const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
4662
5312
  const {
@@ -4664,8 +5314,8 @@ var many2manyFieldController = (props) => {
4664
5314
  isLoading: isDataLoading,
4665
5315
  isFetched: isDataResponseFetched,
4666
5316
  isPlaceholderData
4667
- } = useGetListData(data, queryKey, enabled);
4668
- useEffect6(() => {
5317
+ } = useGetListData3(data, queryKey, enabled);
5318
+ useEffect13(() => {
4669
5319
  if (viewResponse) {
4670
5320
  fetchData();
4671
5321
  }
@@ -4676,12 +5326,12 @@ var many2manyFieldController = (props) => {
4676
5326
  [`${aid}_${relation}_popupmany2many`]: null
4677
5327
  }));
4678
5328
  appDispatch(setPage(0));
4679
- setSelectedRowKeys([]);
5329
+ setSelectedRowKeys4([]);
4680
5330
  setDomainMany2Many(null);
4681
5331
  setIsLoadedData(false);
4682
5332
  };
4683
5333
  }, [viewResponse]);
4684
- const { rows, columns, typeTable } = useTableHandler({
5334
+ const { rows, columns, typeTable } = tableController({
4685
5335
  data: {
4686
5336
  fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
4687
5337
  records: dataResponse?.records ?? dataResponse?.groups,
@@ -4704,13 +5354,13 @@ var many2manyFieldController = (props) => {
4704
5354
  queryKey: [`form-view-action-${relation}`],
4705
5355
  enabled: false
4706
5356
  });
4707
- useEffect6(() => {
5357
+ useEffect13(() => {
4708
5358
  if (isSuccess && dataFormViewResponse) {
4709
5359
  sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
4710
5360
  window.location.href = `/form/menu?model=${relation}`;
4711
5361
  }
4712
5362
  }, [isSuccess]);
4713
- useEffect6(() => {
5363
+ useEffect13(() => {
4714
5364
  if (domainMany2Many && !isLoadedData) {
4715
5365
  setIsLoadedData(true);
4716
5366
  }
@@ -4756,11 +5406,11 @@ var many2manyFieldController = (props) => {
4756
5406
  };
4757
5407
 
4758
5408
  // src/widget/basic/many2many-tags-field/controller.ts
4759
- import { useMemo as useMemo3 } from "react";
5409
+ import { useMemo as useMemo11 } from "react";
4760
5410
  import {
4761
5411
  evalJSONContext as evalJSONContext4,
4762
- evalJSONDomain as evalJSONDomain3,
4763
- getEnv as getEnv4,
5412
+ evalJSONDomain as evalJSONDomain4,
5413
+ getEnv as getEnv8,
4764
5414
  useGetSelection as useGetSelection3,
4765
5415
  WIDGETAVATAR,
4766
5416
  WIDGETCOLOR
@@ -4775,10 +5425,10 @@ var many2manyTagsController = (props) => {
4775
5425
  placeholderNoOption
4776
5426
  } = props;
4777
5427
  const isUser = relation === "res.users" || relation === "res.partner";
4778
- const env = getEnv4();
5428
+ const env = getEnv8();
4779
5429
  const addtionalFields = optionsFields ? evalJSONContext4(optionsFields) : null;
4780
- const domainObject = useMemo3(
4781
- () => evalJSONDomain3(domain, JSON.parse(JSON.stringify(formValues || {}))),
5430
+ const domainObject = useMemo11(
5431
+ () => evalJSONDomain4(domain, JSON.parse(JSON.stringify(formValues || {}))),
4782
5432
  [domain, formValues]
4783
5433
  );
4784
5434
  const data = {
@@ -4820,13 +5470,13 @@ var many2manyTagsController = (props) => {
4820
5470
  };
4821
5471
 
4822
5472
  // src/widget/basic/status-bar-field/controller.ts
4823
- import { useState as useState6 } from "react";
5473
+ import { useState as useState11 } from "react";
4824
5474
  import {
4825
- evalJSONDomain as evalJSONDomain4,
5475
+ evalJSONDomain as evalJSONDomain5,
4826
5476
  selectEnv as selectEnv2,
4827
- useAppSelector as useAppSelector3,
5477
+ useAppSelector as useAppSelector7,
4828
5478
  useChangeStatus,
4829
- useGetListData as useGetListData2
5479
+ useGetListData as useGetListData4
4830
5480
  } from "@fctc/interface-logic";
4831
5481
  var durationController = (props) => {
4832
5482
  const {
@@ -4844,14 +5494,14 @@ var durationController = (props) => {
4844
5494
  name: "",
4845
5495
  fold: ""
4846
5496
  };
4847
- const [disabled, setDisabled] = useState6(false);
4848
- const [modelStatus, setModalStatus] = useState6(false);
4849
- const { context } = useAppSelector3(selectEnv2);
5497
+ const [disabled, setDisabled] = useState11(false);
5498
+ const [modelStatus, setModalStatus] = useState11(false);
5499
+ const { context } = useAppSelector7(selectEnv2);
4850
5500
  const queryKey = [`data-status-duration`, specification];
4851
5501
  const listDataProps = {
4852
5502
  model: relation,
4853
5503
  specification,
4854
- domain: evalJSONDomain4(domain, JSON.parse(JSON.stringify(formValues))),
5504
+ domain: evalJSONDomain5(domain, JSON.parse(JSON.stringify(formValues))),
4855
5505
  limit: 10,
4856
5506
  offset: 0,
4857
5507
  fields: "",
@@ -4861,7 +5511,7 @@ var durationController = (props) => {
4861
5511
  },
4862
5512
  sort: ""
4863
5513
  };
4864
- const { data: dataResponse } = useGetListData2(listDataProps, queryKey);
5514
+ const { data: dataResponse } = useGetListData4(listDataProps, queryKey);
4865
5515
  const { mutate: fetchChangeStatus } = useChangeStatus();
4866
5516
  const handleClick = async (stage_id) => {
4867
5517
  setDisabled(true);
@@ -4902,13 +5552,13 @@ import { evalJSONContext as evalJSONContext5, useSave as useSave2 } from "@fctc/
4902
5552
  var priorityFieldController = (props) => {
4903
5553
  const {
4904
5554
  value,
4905
- selection,
4906
5555
  isForm,
4907
5556
  name,
4908
5557
  methods,
4909
- id,
4910
5558
  onChange,
4911
5559
  model,
5560
+ selection,
5561
+ id,
4912
5562
  actionData,
4913
5563
  viewData,
4914
5564
  context
@@ -4952,7 +5602,7 @@ var priorityFieldController = (props) => {
4952
5602
  };
4953
5603
 
4954
5604
  // src/widget/basic/float-time-field/controller.ts
4955
- import { useState as useState7 } from "react";
5605
+ import { useState as useState12 } from "react";
4956
5606
  import { convertFloatToTime, convertTimeToFloat } from "@fctc/interface-logic";
4957
5607
  var floatTimeFiledController = ({
4958
5608
  onChange: fieldOnChange,
@@ -4962,11 +5612,11 @@ var floatTimeFiledController = ({
4962
5612
  props
4963
5613
  }) => {
4964
5614
  const { name, defaultValue = 0, onChange } = props;
4965
- const [input, setInput] = useState7(
5615
+ const [input, setInput] = useState12(
4966
5616
  convertFloatToTime(value ?? defaultValue)
4967
5617
  );
4968
- const [formattedTime, setFormattedTime] = useState7("");
4969
- const [errors, setErrors] = useState7("");
5618
+ const [formattedTime, setFormattedTime] = useState12("");
5619
+ const [errors, setErrors] = useState12("");
4970
5620
  const handleInputChange = (e) => {
4971
5621
  const raw = e.target.value.replace(/[^\d:]/g, "");
4972
5622
  setInput(raw);
@@ -5039,7 +5689,7 @@ var floatTimeFiledController = ({
5039
5689
  };
5040
5690
 
5041
5691
  // src/widget/basic/float-field/controller.ts
5042
- import { useEffect as useEffect7, useRef as useRef3, useState as useState8 } from "react";
5692
+ import { useEffect as useEffect14, useRef as useRef5, useState as useState13 } from "react";
5043
5693
  var floatController = ({
5044
5694
  onChange,
5045
5695
  value,
@@ -5047,10 +5697,10 @@ var floatController = ({
5047
5697
  }) => {
5048
5698
  const { name, required, methods, onChange: handleOnchange, string } = props;
5049
5699
  const { setError, clearErrors } = methods;
5050
- const [inputValue, setInputValue] = useState8(
5700
+ const [inputValue, setInputValue] = useState13(
5051
5701
  value !== void 0 && value !== null ? useFormatFloatNumber(value) : ""
5052
5702
  );
5053
- useEffect7(() => {
5703
+ useEffect14(() => {
5054
5704
  if (value !== void 0 && value !== null && value !== parseFloat(inputValue?.replace(/,/g, ""))) {
5055
5705
  setInputValue(useFormatFloatNumber(value));
5056
5706
  clearErrors(name);
@@ -5058,9 +5708,9 @@ var floatController = ({
5058
5708
  setInputValue("");
5059
5709
  }
5060
5710
  }, [value, name, clearErrors]);
5061
- const isDirtyRef = useRef3(false);
5062
- const inputRef = useRef3(null);
5063
- const lastCommittedValueRef = useRef3(null);
5711
+ const isDirtyRef = useRef5(false);
5712
+ const inputRef = useRef5(null);
5713
+ const lastCommittedValueRef = useRef5(null);
5064
5714
  const handleInputChange = (e) => {
5065
5715
  const newValue = e.target.value;
5066
5716
  const valueWithoutCommas = newValue.replace(/,/g, "");
@@ -5078,8 +5728,8 @@ var floatController = ({
5078
5728
  if (!isNaN(parsedValue)) {
5079
5729
  if (parsedValue < 0) {
5080
5730
  setError(name, {
5081
- type: "validate"
5082
- // message: i18n.t('invalid_number'),
5731
+ type: "validate",
5732
+ message: i18n_default.t("invalid_number")
5083
5733
  });
5084
5734
  } else {
5085
5735
  onChange(parsedValue);
@@ -5102,8 +5752,8 @@ var floatController = ({
5102
5752
  if (rawValue === "" || rawValue === ".") {
5103
5753
  if (required) {
5104
5754
  setError(name, {
5105
- type: "required"
5106
- // message: `${string} ${t('must_required')}`,
5755
+ type: "required",
5756
+ message: `${string} ${i18n_default.t("must_required")}`
5107
5757
  });
5108
5758
  }
5109
5759
  onChange(null);
@@ -5112,8 +5762,8 @@ var floatController = ({
5112
5762
  } else if (!isNaN(parsedValue)) {
5113
5763
  if (parsedValue < 0) {
5114
5764
  setError(name, {
5115
- type: "validate"
5116
- // message: i18n.t('invalid_number'),
5765
+ type: "validate",
5766
+ message: i18n_default.t("invalid_number")
5117
5767
  });
5118
5768
  setInputValue("");
5119
5769
  lastCommittedValueRef.current = null;
@@ -5133,8 +5783,8 @@ var floatController = ({
5133
5783
  }
5134
5784
  } else {
5135
5785
  setError(name, {
5136
- type: "validate"
5137
- // message: i18n.t('invalid_number'),
5786
+ type: "validate",
5787
+ message: i18n_default.t("invalid_number")
5138
5788
  });
5139
5789
  setInputValue("");
5140
5790
  lastCommittedValueRef.current = null;
@@ -5161,10 +5811,10 @@ var useFormatFloatNumber = (value) => {
5161
5811
  };
5162
5812
 
5163
5813
  // src/widget/basic/download-file-field/controller.ts
5164
- import { useId, useState as useState9 } from "react";
5814
+ import { useId, useState as useState14 } from "react";
5165
5815
  var downloadFileController = () => {
5166
5816
  const inputId = useId();
5167
- const [file, setFile] = useState9(null);
5817
+ const [file, setFile] = useState14(null);
5168
5818
  const handleFileChange = (e) => {
5169
5819
  setFile(e.target.files[0]);
5170
5820
  };
@@ -5232,8 +5882,8 @@ var dateFieldController = (props) => {
5232
5882
  widget,
5233
5883
  min,
5234
5884
  max,
5235
- formValues,
5236
5885
  viewData,
5886
+ formValues,
5237
5887
  model
5238
5888
  } = props;
5239
5889
  const range = (start, end, step = 1) => {
@@ -5288,18 +5938,30 @@ var dateFieldController = (props) => {
5288
5938
  const compareNow = showTime ? now : now.clone().startOf("day");
5289
5939
  if (minNowValue) {
5290
5940
  if (compareSelected.isBefore(compareNow) && typeof minNowValue === "boolean" && minNowValue === true) {
5941
+ return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
5942
+ "greater_or_equal_now"
5943
+ )}`;
5291
5944
  } else if (import_moment.default.isMoment(minNowValue)) {
5292
5945
  const compareMin = showTime ? minNowValue : minNowValue.clone().startOf("day");
5293
5946
  if (compareSelected.isBefore(compareMin)) {
5294
5947
  const fieldRelationDate = viewData?.models?.[model]?.[min ?? ""];
5948
+ return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
5949
+ "greater_or_equal"
5950
+ )} ${fieldRelationDate?.string}`;
5295
5951
  }
5296
5952
  }
5297
5953
  } else if (maxNowValue) {
5298
5954
  if (compareSelected.isAfter(compareNow) && typeof maxNowValue === "boolean" && maxNowValue === true) {
5955
+ return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
5956
+ "less_or_equal_now"
5957
+ )}`;
5299
5958
  } else if (import_moment.default.isMoment(maxNowValue)) {
5300
5959
  const compareMax = showTime ? maxNowValue : maxNowValue.clone().startOf("day");
5301
5960
  if (compareSelected.isAfter(compareMax)) {
5302
5961
  const fieldRelationDate = viewData?.models?.[model]?.[max ?? ""];
5962
+ return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
5963
+ "less_or_equal"
5964
+ )} ${fieldRelationDate?.string}`;
5303
5965
  }
5304
5966
  }
5305
5967
  }
@@ -5322,11 +5984,11 @@ var dateFieldController = (props) => {
5322
5984
  };
5323
5985
 
5324
5986
  // src/widget/basic/copy-link-button/controller.ts
5325
- import { useState as useState10 } from "react";
5987
+ import { useState as useState15 } from "react";
5326
5988
  import { copyTextToClipboard } from "@fctc/interface-logic";
5327
5989
  var copyLinkButtonController = (props) => {
5328
5990
  const { value, defaultValue } = props;
5329
- const [isCopied, setIsCopied] = useState10(false);
5991
+ const [isCopied, setIsCopied] = useState15(false);
5330
5992
  const handleCopyToClipboard = async (value2) => {
5331
5993
  await copyTextToClipboard(value2);
5332
5994
  setIsCopied(true);
@@ -5340,45 +6002,11 @@ var copyLinkButtonController = (props) => {
5340
6002
  };
5341
6003
  };
5342
6004
 
5343
- // src/widget/basic/color-field/color-wrapper-controller.ts
5344
- import { useEffect as useEffect8, useRef as useRef4, useState as useState11 } from "react";
5345
- var colorWrapperController = (props) => {
5346
- const { savePickColor, defaultColor, colors } = props;
5347
- const [selectedColor, setSelectedColor] = useState11(colors[defaultColor]);
5348
- const [showFullColors, setIsShowFullColor] = useState11(false);
5349
- useEffect8(() => {
5350
- setSelectedColor(colors[defaultColor]);
5351
- }, [defaultColor]);
5352
- const handleShowFullColors = () => {
5353
- setIsShowFullColor(!showFullColors);
5354
- };
5355
- const pickColorsRef = useRef4(null);
5356
- useEffect8(() => {
5357
- const handleClickOutside = (event) => {
5358
- if (pickColorsRef.current && !pickColorsRef.current.contains(event.target)) {
5359
- setIsShowFullColor(false);
5360
- }
5361
- };
5362
- document.addEventListener("mousedown", handleClickOutside);
5363
- return () => {
5364
- document.removeEventListener("mousedown", handleClickOutside);
5365
- };
5366
- }, []);
5367
- return {
5368
- selectedColor,
5369
- showFullColors,
5370
- setSelectedColor,
5371
- handleShowFullColors,
5372
- pickColorsRef,
5373
- savePickColor
5374
- };
5375
- };
5376
-
5377
6005
  // src/widget/basic/color-field/color-controller.ts
5378
- import { evalJSONContext as evalJSONContext6, getEnv as getEnv5, useSave as useSave3 } from "@fctc/interface-logic";
6006
+ import { evalJSONContext as evalJSONContext6, getEnv as getEnv9, useSave as useSave3 } from "@fctc/interface-logic";
5379
6007
  var colorFieldController = (props) => {
5380
6008
  const { value, isForm, name, formValues, idForm, model, actionData } = props;
5381
- const env = getEnv5();
6009
+ const env = getEnv9();
5382
6010
  const _context = { ...evalJSONContext6(actionData?.context) || {} };
5383
6011
  const contextObject = { ...env.context, ..._context };
5384
6012
  const idDefault = isForm ? idForm : formValues?.id;
@@ -5407,16 +6035,16 @@ var colorFieldController = (props) => {
5407
6035
  };
5408
6036
 
5409
6037
  // src/widget/basic/binary-field/controller.ts
5410
- import { useEffect as useEffect9, useId as useId2, useRef as useRef5, useState as useState12 } from "react";
6038
+ import { useEffect as useEffect15, useId as useId2, useRef as useRef6, useState as useState16 } from "react";
5411
6039
  import { isBase64Image } from "@fctc/interface-logic";
5412
6040
  var binaryFieldController = (props) => {
5413
6041
  const { name, methods, readonly = false, value } = props;
5414
6042
  const inputId = useId2();
5415
- const [selectedImage, setSelectedImage] = useState12(null);
5416
- const [initialImage, setInitialImage] = useState12(value || null);
5417
- const [isInsideTable, setIsInsideTable] = useState12(false);
6043
+ const [selectedImage, setSelectedImage] = useState16(null);
6044
+ const [initialImage, setInitialImage] = useState16(value || null);
6045
+ const [isInsideTable, setIsInsideTable] = useState16(false);
5418
6046
  const { setValue } = methods;
5419
- const binaryRef = useRef5(null);
6047
+ const binaryRef = useRef6(null);
5420
6048
  const convertUrlToBase64 = async (url) => {
5421
6049
  try {
5422
6050
  const response = await fetch(url);
@@ -5478,14 +6106,14 @@ var binaryFieldController = (props) => {
5478
6106
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
5479
6107
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
5480
6108
  };
5481
- useEffect9(() => {
6109
+ useEffect15(() => {
5482
6110
  return () => {
5483
6111
  if (selectedImage) {
5484
6112
  URL.revokeObjectURL(selectedImage);
5485
6113
  }
5486
6114
  };
5487
6115
  }, [selectedImage]);
5488
- useEffect9(() => {
6116
+ useEffect15(() => {
5489
6117
  if (binaryRef.current) {
5490
6118
  const isInsideTable2 = !!binaryRef.current.closest("table");
5491
6119
  setIsInsideTable(isInsideTable2);
@@ -5504,28 +6132,47 @@ var binaryFieldController = (props) => {
5504
6132
  };
5505
6133
  };
5506
6134
  export {
6135
+ API_APP_URL,
6136
+ API_PRESCHOOL_URL,
5507
6137
  CloseIcon,
5508
6138
  EyeIcon,
5509
6139
  LoadingIcon,
6140
+ STORAGES,
5510
6141
  binaryFieldController,
5511
6142
  colorFieldController,
5512
- colorWrapperController,
6143
+ combineContexts,
6144
+ convertFieldsToArray,
5513
6145
  copyLinkButtonController,
6146
+ countSum,
5514
6147
  dateFieldController,
5515
6148
  downLoadBinaryController,
5516
6149
  downloadFileController,
5517
6150
  durationController,
5518
6151
  floatController,
5519
6152
  floatTimeFiledController,
6153
+ getDateRange,
6154
+ languages,
5520
6155
  many2manyFieldController,
5521
6156
  many2manyTagsController,
5522
6157
  many2oneButtonController,
5523
6158
  many2oneFieldController,
6159
+ mergeButtons,
5524
6160
  priorityFieldController,
6161
+ setStorageItemAsync,
5525
6162
  statusDropdownController,
6163
+ useAuth,
6164
+ useCallAction,
5526
6165
  useClickOutside,
6166
+ useConfig,
5527
6167
  useDebounce,
5528
- useTableHandler
6168
+ useDetail,
6169
+ useGetRowIds,
6170
+ useListData,
6171
+ useMenu,
6172
+ useProfile,
6173
+ useStorageState,
6174
+ useUser,
6175
+ useViewV2
5529
6176
  };
5530
6177
  /*! Bundled license information:
5531
6178