@fctc/widget-logic 1.2.1 → 1.2.3

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.js CHANGED
@@ -4785,7 +4785,7 @@ var AppProvider = ({ children }) => {
4785
4785
  action,
4786
4786
  view
4787
4787
  },
4788
- children
4788
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_interface_logic10.MainProvider, { children })
4789
4789
  }
4790
4790
  );
4791
4791
  };
@@ -5180,7 +5180,7 @@ var many2oneFieldController = (props) => {
5180
5180
  const queryKey = [`data_${relation}`, domainObject];
5181
5181
  const {
5182
5182
  data: dataOfSelection,
5183
- refetch,
5183
+ // refetch,
5184
5184
  isFetching
5185
5185
  } = (0, import_interface_logic16.useGetSelection)({
5186
5186
  data,
@@ -5209,9 +5209,6 @@ var many2oneFieldController = (props) => {
5209
5209
  });
5210
5210
  }
5211
5211
  }, [propValue]);
5212
- const fetchMoreOptions = (0, import_react18.useCallback)(() => {
5213
- refetch();
5214
- }, [refetch]);
5215
5212
  (0, import_react18.useEffect)(() => {
5216
5213
  if (actionId) {
5217
5214
  localStorage.setItem("aid", actionId);
@@ -5268,6 +5265,12 @@ var many2oneFieldController = (props) => {
5268
5265
  [methods, name, onChange]
5269
5266
  );
5270
5267
  const allowShowDetail = showDetail && contextObject?.form_view_ref && (!("no_open" in optionsObject) || optionsObject?.no_open === false);
5268
+ const fetchMoreOptions = (0, import_react18.useCallback)(() => {
5269
+ if (typeof dataOfSelection?.refetch === "function") {
5270
+ ;
5271
+ dataOfSelection.refetch();
5272
+ }
5273
+ }, [dataOfSelection]);
5271
5274
  return {
5272
5275
  allowShowDetail,
5273
5276
  handleClose,
@@ -5283,7 +5286,8 @@ var many2oneFieldController = (props) => {
5283
5286
  setTempSelectedOption,
5284
5287
  setDomainModal,
5285
5288
  dataOfSelection,
5286
- refetch,
5289
+ refetch: dataOfSelection?.refetch ?? (() => {
5290
+ }),
5287
5291
  selectOptions,
5288
5292
  optionsObject,
5289
5293
  contextObject,
@@ -5318,15 +5322,119 @@ var many2oneButtonController = (props) => {
5318
5322
  };
5319
5323
 
5320
5324
  // src/widget/basic/many2many-field/controller.ts
5321
- var import_react20 = require("react");
5322
- var import_interface_logic19 = require("@fctc/interface-logic");
5325
+ var import_react22 = require("react");
5326
+ var import_interface_logic22 = require("@fctc/interface-logic");
5323
5327
 
5324
- // src/widget/advance/table/table-view/controller.ts
5328
+ // src/widget/advance/table/table-body/controller.ts
5325
5329
  var import_interface_logic18 = require("@fctc/interface-logic");
5326
5330
  var import_react19 = require("react");
5331
+ var tableBodyController = (props) => {
5332
+ const {
5333
+ checkedAll,
5334
+ checkboxRef,
5335
+ setIsAutoSelect,
5336
+ selectedRowKeys,
5337
+ row,
5338
+ isAutoSelect,
5339
+ selectedRowKeysRef,
5340
+ onClickRow
5341
+ } = props;
5342
+ const appDispatch = (0, import_interface_logic18.useAppDispatch)();
5343
+ const checked = (0, import_react19.useMemo)(() => {
5344
+ if (!row?.id) return false;
5345
+ if (selectedRowKeys?.includes(row.id)) {
5346
+ return true;
5347
+ }
5348
+ return checkedAll;
5349
+ }, [row?.id, selectedRowKeys, checkedAll]);
5350
+ const handleCheckBoxSingle = (event) => {
5351
+ event.stopPropagation();
5352
+ if (checkedAll) {
5353
+ checkboxRef.current = "uncheck";
5354
+ setIsAutoSelect(true);
5355
+ return;
5356
+ }
5357
+ const newSelectedRowKeys = selectedRowKeys?.includes(row.id) ? selectedRowKeys?.filter((key) => key !== row.id) : [...selectedRowKeys, row.id];
5358
+ console.log("newSelectedRowKeys", newSelectedRowKeys);
5359
+ appDispatch((0, import_interface_logic18.setSelectedRowKeys)(newSelectedRowKeys));
5360
+ };
5361
+ const handleClickRow = (col, row2) => {
5362
+ onClickRow(col, row2);
5363
+ };
5364
+ (0, import_react19.useEffect)(() => {
5365
+ if (!row?.id) return;
5366
+ if (isAutoSelect) {
5367
+ if (checkboxRef?.current === "uncheck") {
5368
+ const filtered = selectedRowKeysRef.current.filter(
5369
+ (id) => id !== row.id
5370
+ );
5371
+ selectedRowKeysRef.current = filtered;
5372
+ appDispatch((0, import_interface_logic18.setSelectedRowKeys)(filtered));
5373
+ } else {
5374
+ const unique = Array.from(
5375
+ /* @__PURE__ */ new Set([...selectedRowKeysRef?.current, row?.id])
5376
+ );
5377
+ selectedRowKeysRef.current = unique;
5378
+ appDispatch((0, import_interface_logic18.setSelectedRowKeys)(unique));
5379
+ }
5380
+ }
5381
+ }, [isAutoSelect]);
5382
+ (0, import_react19.useEffect)(() => {
5383
+ if (!checkedAll) {
5384
+ checkboxRef.current = "enabled";
5385
+ false;
5386
+ }
5387
+ }, [checkedAll]);
5388
+ return {
5389
+ handleCheckBoxSingle,
5390
+ checked,
5391
+ handleClickRow
5392
+ };
5393
+ };
5394
+
5395
+ // src/widget/advance/table/table-head/controller.ts
5396
+ var import_interface_logic19 = require("@fctc/interface-logic");
5397
+ var tableHeadController = (props) => {
5398
+ const { typeTable, rows, selectedRowKeysRef } = props;
5399
+ const appDispatch = (0, import_interface_logic19.useAppDispatch)();
5400
+ const { groupByDomain } = (0, import_interface_logic19.useAppSelector)(import_interface_logic19.selectSearch);
5401
+ const handleCheckBoxAll = (event) => {
5402
+ if (event?.target?.checked && typeTable === "list") {
5403
+ const allRowKeys = Array.isArray(rows) ? rows.map((record) => record?.id) : [];
5404
+ appDispatch((0, import_interface_logic19.setSelectedRowKeys)(allRowKeys));
5405
+ } else if (event?.target?.checked && typeTable === "group") {
5406
+ const rowsIDs = document.querySelectorAll("tr[data-row-id]");
5407
+ const ids = Array.from(rowsIDs)?.map(
5408
+ (row) => Number(row?.getAttribute("data-row-id"))
5409
+ );
5410
+ if (ids?.length > 0) {
5411
+ appDispatch((0, import_interface_logic19.setSelectedRowKeys)(ids));
5412
+ } else {
5413
+ const sum = countSum(
5414
+ rows,
5415
+ typeof groupByDomain === "object" ? groupByDomain?.contexts?.[0]?.group_by : void 0
5416
+ );
5417
+ const keys = Array.from({ length: sum }, (_) => void 0);
5418
+ appDispatch((0, import_interface_logic19.setSelectedRowKeys)(keys));
5419
+ }
5420
+ if (selectedRowKeysRef) {
5421
+ selectedRowKeysRef.current = [];
5422
+ }
5423
+ } else {
5424
+ appDispatch((0, import_interface_logic19.setSelectedRowKeys)([]));
5425
+ }
5426
+ };
5427
+ return {
5428
+ handleCheckBoxAll
5429
+ };
5430
+ };
5431
+
5432
+ // src/widget/advance/table/table-view/controller.ts
5433
+ var import_interface_logic20 = require("@fctc/interface-logic");
5434
+ var import_react20 = require("react");
5327
5435
  var tableController = ({ data }) => {
5328
- const [rows, setRows] = (0, import_react19.useState)(data.records || []);
5329
- const [columns, setColumns] = (0, import_react19.useState)([]);
5436
+ const [rows, setRows] = (0, import_react20.useState)(data.records || []);
5437
+ const [columns, setColumns] = (0, import_react20.useState)([]);
5330
5438
  const dataModelFields = data.fields?.map((field) => {
5331
5439
  return {
5332
5440
  ...data.dataModel?.[field?.name],
@@ -5354,14 +5462,14 @@ var tableController = ({ data }) => {
5354
5462
  return item.display_name ? { ...transformedItem, item: item.display_name } : transformedItem;
5355
5463
  });
5356
5464
  };
5357
- (0, import_react19.useEffect)(() => {
5465
+ (0, import_react20.useEffect)(() => {
5358
5466
  setRows(transformData(data.records || null));
5359
5467
  }, [data.records]);
5360
5468
  const handleGetColumns = () => {
5361
5469
  let cols = [];
5362
5470
  try {
5363
5471
  cols = mergeFields?.filter((item) => {
5364
- return item?.widget !== "details_Receive_money" && !(item?.column_invisible ? import_interface_logic18.domainHelper.matchDomains(data.context, item?.column_invisible) : item?.invisible ? import_interface_logic18.domainHelper.matchDomains(data.context, item?.invisible) : false);
5472
+ return item?.widget !== "details_Receive_money" && !(item?.column_invisible ? import_interface_logic20.domainHelper.matchDomains(data.context, item?.column_invisible) : item?.invisible ? import_interface_logic20.domainHelper.matchDomains(data.context, item?.invisible) : false);
5365
5473
  })?.map((field) => {
5366
5474
  return {
5367
5475
  name: field?.name,
@@ -5375,7 +5483,7 @@ var tableController = ({ data }) => {
5375
5483
  }
5376
5484
  return cols;
5377
5485
  };
5378
- (0, import_react19.useEffect)(() => {
5486
+ (0, import_react20.useEffect)(() => {
5379
5487
  const columns2 = handleGetColumns();
5380
5488
  setColumns(columns2);
5381
5489
  }, [data.records]);
@@ -5399,453 +5507,14 @@ var tableController = ({ data }) => {
5399
5507
  };
5400
5508
  };
5401
5509
 
5402
- // src/widget/basic/many2many-field/controller.ts
5403
- var many2manyFieldController = (props) => {
5404
- const {
5405
- relation,
5406
- domain,
5407
- context,
5408
- tab,
5409
- model,
5410
- aid,
5411
- setSelectedRowKeys: setSelectedRowKeys4,
5412
- fields,
5413
- setFields,
5414
- groupByDomain,
5415
- page,
5416
- options,
5417
- sessionStorageUtils
5418
- } = props;
5419
- const appDispatch = (0, import_interface_logic19.useAppDispatch)();
5420
- const actionData = sessionStorageUtils.getActionData();
5421
- const [debouncedPage] = useDebounce(page, 500);
5422
- const [order, setOrder] = (0, import_react20.useState)();
5423
- const [isLoadedData, setIsLoadedData] = (0, import_react20.useState)(false);
5424
- const [domainMany2Many, setDomainMany2Many] = (0, import_react20.useState)(domain);
5425
- const env = (0, import_interface_logic19.getEnv)();
5426
- const { selectedTags } = (0, import_interface_logic19.useAppSelector)(import_interface_logic19.selectSearch);
5427
- const viewParams = {
5428
- model: relation,
5429
- views: [
5430
- [false, "list"],
5431
- [false, "search"]
5432
- ],
5433
- context
5434
- };
5435
- const { data: viewResponse, isFetched: isViewReponseFetched } = (0, import_interface_logic19.useGetView)(
5436
- viewParams,
5437
- actionData
5438
- );
5439
- const baseModel = (0, import_react20.useMemo)(
5440
- () => ({
5441
- name: String(relation),
5442
- view: viewResponse || {},
5443
- actContext: context,
5444
- fields: [
5445
- ...Object.values(viewResponse?.views?.list?.fields ?? {}),
5446
- ...tab?.fields ? tab.fields : []
5447
- ]
5448
- }),
5449
- [model, viewResponse]
5450
- );
5451
- const initModel = (0, import_interface_logic19.useModel)();
5452
- const modelInstance = (0, import_react20.useMemo)(() => {
5453
- if (viewResponse) {
5454
- return initModel.initModel(baseModel);
5455
- }
5456
- return null;
5457
- }, [baseModel, viewResponse]);
5458
- const specification = (0, import_react20.useMemo)(() => {
5459
- if (modelInstance) {
5460
- return modelInstance.getSpecification();
5461
- }
5462
- return null;
5463
- }, [modelInstance]);
5464
- const default_order = viewResponse && viewResponse?.views?.list?.default_order;
5465
- const optionsObject = tab?.options ? (0, import_interface_logic19.evalJSONContext)(tab?.options) : (options ? (0, import_interface_logic19.evalJSONContext)(options) : {}) || {};
5466
- const fetchData = async () => {
5467
- try {
5468
- setDomainMany2Many(domain);
5469
- appDispatch((0, import_interface_logic19.setFirstDomain)(domain));
5470
- appDispatch((0, import_interface_logic19.setViewDataStore)(viewResponse));
5471
- const modalData = viewResponse?.views?.list?.fields.map((field) => ({
5472
- ...viewResponse?.models?.[String(model)]?.[field?.name],
5473
- ...field
5474
- }));
5475
- if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
5476
- setFields({
5477
- ...fields,
5478
- [`${aid}_${relation}_popupmany2many`]: modalData
5479
- });
5480
- }
5481
- appDispatch((0, import_interface_logic19.setPage)(0));
5482
- } catch (err) {
5483
- console.log(err);
5484
- }
5485
- };
5486
- const queryKey = [
5487
- `view-${relation}-${aid}`,
5488
- specification,
5489
- domainMany2Many,
5490
- debouncedPage,
5491
- groupByDomain,
5492
- order
5493
- ];
5494
- const data = {
5495
- model: relation,
5496
- specification,
5497
- domain: domainMany2Many,
5498
- offset: debouncedPage * 10,
5499
- limit: 10,
5500
- context,
5501
- fields: groupByDomain?.fields,
5502
- groupby: [groupByDomain?.contexts[0]?.group_by],
5503
- sort: order ? order : default_order ? (0, import_interface_logic19.formatSortingString)(default_order) : ""
5504
- };
5505
- const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
5506
- const {
5507
- data: dataResponse,
5508
- isLoading: isDataLoading,
5509
- isFetched: isDataResponseFetched,
5510
- isPlaceholderData
5511
- } = (0, import_interface_logic19.useGetListData)(data, queryKey, enabled);
5512
- (0, import_react20.useEffect)(() => {
5513
- if (viewResponse) {
5514
- fetchData();
5515
- }
5516
- return () => {
5517
- appDispatch((0, import_interface_logic19.setGroupByDomain)(null));
5518
- setFields((prevFields) => ({
5519
- ...prevFields,
5520
- [`${aid}_${relation}_popupmany2many`]: null
5521
- }));
5522
- appDispatch((0, import_interface_logic19.setPage)(0));
5523
- setSelectedRowKeys4([]);
5524
- setDomainMany2Many(null);
5525
- setIsLoadedData(false);
5526
- };
5527
- }, [viewResponse]);
5528
- const { rows, columns, typeTable } = tableController({
5529
- data: {
5530
- fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
5531
- records: dataResponse?.records ?? dataResponse?.groups,
5532
- dataModel: viewResponse?.models?.[String(relation)],
5533
- context: { ...env.context, ...context },
5534
- typeTable: dataResponse?.groups ? "group" : "list"
5535
- }
5536
- });
5537
- const dataFormView = {
5538
- id: null,
5539
- model: relation,
5540
- context
5541
- };
5542
- const {
5543
- refetch,
5544
- data: dataFormViewResponse,
5545
- isSuccess
5546
- } = (0, import_interface_logic19.useGetFormView)({
5547
- data: dataFormView,
5548
- queryKey: [`form-view-action-${relation}`],
5549
- enabled: false
5550
- });
5551
- (0, import_react20.useEffect)(() => {
5552
- if (isSuccess && dataFormViewResponse) {
5553
- sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
5554
- window.location.href = `/form/menu?model=${relation}`;
5555
- }
5556
- }, [isSuccess]);
5557
- (0, import_react20.useEffect)(() => {
5558
- if (domainMany2Many && !isLoadedData) {
5559
- setIsLoadedData(true);
5560
- }
5561
- }, [domainMany2Many]);
5562
- const handleCreateNewOnPage = async () => {
5563
- try {
5564
- refetch();
5565
- } catch (error) {
5566
- console.log(error);
5567
- }
5568
- };
5569
- return {};
5570
- };
5571
-
5572
- // src/widget/basic/many2many-tags-field/controller.ts
5573
- var import_react21 = require("react");
5574
- var import_interface_logic20 = require("@fctc/interface-logic");
5575
- var many2manyTagsController = (props) => {
5576
- const {
5577
- relation,
5578
- domain,
5579
- options: optionsFields,
5580
- widget,
5581
- formValues,
5582
- placeholderNoOption
5583
- } = props;
5584
- const isUser = relation === "res.users" || relation === "res.partner";
5585
- const env = (0, import_interface_logic20.getEnv)();
5586
- const addtionalFields = optionsFields ? (0, import_interface_logic20.evalJSONContext)(optionsFields) : null;
5587
- const domainObject = (0, import_react21.useMemo)(
5588
- () => (0, import_interface_logic20.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues || {}))),
5589
- [domain, formValues]
5590
- );
5591
- const data = {
5592
- model: relation ?? "",
5593
- domain: domainObject,
5594
- specification: {
5595
- id: {},
5596
- name: {},
5597
- display_name: {},
5598
- ...widget && import_interface_logic20.WIDGETAVATAR[widget] ? { image_256: {} } : {},
5599
- ...widget && import_interface_logic20.WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
5600
- },
5601
- enabled: true,
5602
- context: env.context
5603
- };
5604
- const { data: dataOfSelection } = (0, import_interface_logic20.useGetSelection)({
5605
- data,
5606
- queryKey: [`data_${relation}`, domainObject]
5607
- });
5608
- const customNoOptionsMessage = () => placeholderNoOption;
5609
- const tranfer = (data2) => {
5610
- return data2?.map((val) => ({
5611
- id: val.value,
5612
- display_name: val.label
5613
- })) || [];
5614
- };
5615
- const options = dataOfSelection?.records?.map((val) => ({
5616
- value: val.id,
5617
- label: val.name ?? val.display_name,
5618
- ...val
5619
- })) || [];
5620
- return {
5621
- options,
5622
- customNoOptionsMessage,
5623
- tranfer,
5624
- dataOfSelection,
5625
- isUser
5626
- };
5627
- };
5628
-
5629
- // src/widget/basic/status-bar-field/controller.ts
5630
- var import_react22 = require("react");
5510
+ // src/widget/advance/table/table-group/controller.ts
5631
5511
  var import_interface_logic21 = require("@fctc/interface-logic");
5632
- var durationController = (props) => {
5633
- const {
5634
- relation,
5635
- defaultValue,
5636
- domain,
5637
- formValues,
5638
- name,
5639
- id,
5640
- model,
5641
- onRefetch
5642
- } = props;
5643
- const specification = {
5644
- id: 0,
5645
- name: "",
5646
- fold: ""
5647
- };
5648
- const [disabled, setDisabled] = (0, import_react22.useState)(false);
5649
- const [modelStatus, setModalStatus] = (0, import_react22.useState)(false);
5650
- const { context } = (0, import_interface_logic21.useAppSelector)(import_interface_logic21.selectEnv);
5651
- const queryKey = [`data-status-duration`, specification];
5652
- const listDataProps = {
5653
- model: relation,
5654
- specification,
5655
- domain: (0, import_interface_logic21.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues))),
5656
- limit: 10,
5657
- offset: 0,
5658
- fields: "",
5659
- groupby: [],
5660
- context: {
5661
- lang: context.lang
5662
- },
5663
- sort: ""
5664
- };
5665
- const { data: dataResponse } = (0, import_interface_logic21.useGetListData)(listDataProps, queryKey);
5666
- const { mutate: fetchChangeStatus } = (0, import_interface_logic21.useChangeStatus)();
5667
- const handleClick = async (stage_id) => {
5668
- setDisabled(true);
5669
- if (stage_id) {
5670
- fetchChangeStatus(
5671
- {
5672
- data: {
5673
- stage_id,
5674
- name,
5675
- id,
5676
- model,
5677
- lang: context.lang
5678
- }
5679
- },
5680
- {
5681
- onSuccess: (res) => {
5682
- if (res) {
5683
- setDisabled(false);
5684
- onRefetch && onRefetch();
5685
- }
5686
- }
5687
- }
5688
- );
5689
- }
5690
- };
5691
- return {
5692
- defaultValue,
5693
- dataResponse,
5694
- handleClick,
5695
- disabled,
5696
- modelStatus,
5697
- setModalStatus
5698
- };
5699
- };
5512
+ var import_react21 = require("react");
5700
5513
 
5701
- // src/widget/basic/priority-field/controller.ts
5702
- var import_interface_logic22 = require("@fctc/interface-logic");
5703
- var priorityFieldController = (props) => {
5704
- const {
5705
- value,
5706
- isForm,
5707
- name,
5708
- methods,
5709
- onChange,
5710
- model,
5711
- selection,
5712
- id,
5713
- actionData,
5714
- viewData,
5715
- context
5716
- } = props;
5717
- const _context = { ...(0, import_interface_logic22.evalJSONContext)(actionData?.context) };
5718
- const contextObject = { ...context, ..._context };
5719
- const defaultPriority = parseInt(value) + 1;
5720
- const label = viewData?.models?.[model]?.[name ?? ""]?.string ?? name;
5721
- const { mutateAsync: fetchSave } = (0, import_interface_logic22.useSave)();
5722
- const savePriorities = async ({
5723
- value: value2,
5724
- resetPriority
5725
- }) => {
5726
- const priorityValue = value2 <= 0 ? 0 : value2 - 1;
5727
- try {
5728
- fetchSave({
5729
- ids: id ? [id] : [],
5730
- data: { [name ?? ""]: String(priorityValue) },
5731
- model: model ?? "",
5732
- context: contextObject
5733
- });
5734
- if (typeof onChange === "function") {
5735
- onChange(name ?? "", String(priorityValue));
5736
- }
5737
- } catch (error) {
5738
- if (resetPriority) {
5739
- resetPriority();
5740
- }
5741
- }
5742
- };
5743
- return {
5744
- selection,
5745
- isForm,
5746
- methods,
5747
- defaultPriority,
5748
- savePriorities,
5749
- label,
5750
- id,
5751
- onChange
5752
- };
5753
- };
5754
-
5755
- // src/widget/basic/float-time-field/controller.ts
5756
- var import_react23 = require("react");
5757
- var import_interface_logic23 = require("@fctc/interface-logic");
5758
- var floatTimeFiledController = ({
5759
- onChange: fieldOnChange,
5760
- onBlur,
5761
- value,
5762
- isDirty,
5763
- props
5764
- }) => {
5765
- const { name, defaultValue = 0, onChange } = props;
5766
- const [input, setInput] = (0, import_react23.useState)(
5767
- (0, import_interface_logic23.convertFloatToTime)(value ?? defaultValue)
5768
- );
5769
- const [formattedTime, setFormattedTime] = (0, import_react23.useState)("");
5770
- const [errors, setErrors] = (0, import_react23.useState)("");
5771
- const handleInputChange = (e) => {
5772
- const raw = e.target.value.replace(/[^\d:]/g, "");
5773
- setInput(raw);
5774
- const timeRegex = /^(\d{1,2}):?(\d{0,2})$/;
5775
- const match = raw.match(timeRegex);
5776
- if (!match) {
5777
- setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
5778
- setFormattedTime("");
5779
- return;
5780
- }
5781
- let hours = parseInt(match[1] ?? "0", 10);
5782
- let minutes = parseInt(match[2] ?? "0", 10);
5783
- if (isNaN(hours)) hours = 0;
5784
- if (isNaN(minutes)) minutes = 0;
5785
- if (hours >= 24) {
5786
- hours = 0;
5787
- }
5788
- if (minutes >= 60) {
5789
- minutes = 0;
5790
- }
5791
- const formatted = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
5792
- setErrors("");
5793
- setFormattedTime(formatted);
5794
- fieldOnChange(formatted);
5795
- };
5796
- const handleBlur = () => {
5797
- if (!isDirty) return;
5798
- if (formattedTime) {
5799
- setInput(formattedTime);
5800
- const floatVal = (0, import_interface_logic23.convertTimeToFloat)(formattedTime);
5801
- fieldOnChange(floatVal);
5802
- if (onChange) {
5803
- onChange(name ?? "", floatVal);
5804
- }
5805
- } else {
5806
- setInput("00:00");
5807
- fieldOnChange(0);
5808
- if (onChange) {
5809
- onChange(name ?? "", 0);
5810
- }
5811
- setErrors("");
5812
- }
5813
- onBlur();
5814
- };
5815
- const handleKeyDown = (e) => {
5816
- {
5817
- const allowed = [
5818
- "Backspace",
5819
- "Tab",
5820
- "ArrowLeft",
5821
- "ArrowRight",
5822
- "Delete",
5823
- "Home",
5824
- "End",
5825
- ":"
5826
- ];
5827
- const isNumber = /^[0-9]$/.test(e.key);
5828
- if (!isNumber && !allowed.includes(e.key)) {
5829
- e.preventDefault();
5830
- }
5831
- }
5832
- };
5833
- return {
5834
- handleInputChange,
5835
- handleBlur,
5836
- handleKeyDown,
5837
- input,
5838
- errors
5839
- };
5840
- };
5841
-
5842
- // src/widget/basic/float-field/controller.ts
5843
- var import_react24 = require("react");
5844
-
5845
- // src/utils/i18n.ts
5846
- var import_react_i18next2 = require("react-i18next");
5847
- var import_i18next = __toESM(require("i18next"));
5848
- var import_i18next_browser_languagedetector = __toESM(require("i18next-browser-languagedetector"));
5514
+ // src/utils/i18n.ts
5515
+ var import_react_i18next2 = require("react-i18next");
5516
+ var import_i18next = __toESM(require("i18next"));
5517
+ var import_i18next_browser_languagedetector = __toESM(require("i18next-browser-languagedetector"));
5849
5518
 
5850
5519
  // src/locales/vi.json
5851
5520
  var vi_default = {
@@ -6032,8 +5701,6 @@ var vi_default = {
6032
5701
  add_new_attribute: "Th\xEAm thu\u1ED9c t\xEDnh",
6033
5702
  add_attribute_name: "T\xEAn thu\u1ED9c t\xEDnh",
6034
5703
  images_product: "H\xECnh \u1EA3nh",
6035
- selected: "\u0111\u01B0\u1EE3c ch\u1ECDn",
6036
- print: "In",
6037
5704
  generate_code_product: "T\u1EA1o m\xE3 s\u1EA3n ph\u1EA9m",
6038
5705
  order_today: "\u0110\u01A1n h\xE0ng",
6039
5706
  list_best_selling_product: "S\u1EA3n ph\u1EA9m b\xE1n ch\u1EA1y",
@@ -6610,7 +6277,608 @@ import_i18next.default.use(import_i18next_browser_languagedetector.default).use(
6610
6277
  });
6611
6278
  var i18n_default = import_i18next.default;
6612
6279
 
6280
+ // src/widget/advance/table/table-group/controller.ts
6281
+ var tableGroupController = (props) => {
6282
+ const env = (0, import_interface_logic21.getEnv)();
6283
+ const {
6284
+ rows,
6285
+ columns,
6286
+ indexRow,
6287
+ row,
6288
+ model,
6289
+ viewData,
6290
+ renderField,
6291
+ level,
6292
+ specification,
6293
+ domain,
6294
+ context,
6295
+ checkedAll,
6296
+ isDisplayCheckbox,
6297
+ isAutoSelect,
6298
+ setIsAutoSelect,
6299
+ selectedRowKeysRef
6300
+ } = props;
6301
+ const [pageGroup, setPageGroup] = (0, import_react21.useState)(0);
6302
+ const { groupByDomain, selectedTags } = (0, import_interface_logic21.useAppSelector)(import_interface_logic21.selectSearch);
6303
+ const { selectedRowKeys } = (0, import_interface_logic21.useAppSelector)(import_interface_logic21.selectList);
6304
+ const appDispatch = (0, import_interface_logic21.useAppDispatch)();
6305
+ const { toDataJS } = (0, import_interface_logic21.useOdooDataTransform)();
6306
+ const initVal = toDataJS(row, viewData, model);
6307
+ const [isShowGroup, setIsShowGroup] = (0, import_react21.useState)(false);
6308
+ const [colEmptyGroup, setColEmptyGroup] = (0, import_react21.useState)({
6309
+ fromStart: 1,
6310
+ fromEnd: 1
6311
+ });
6312
+ const processedData = (0, import_react21.useMemo)(() => {
6313
+ const calculateColSpanEmpty = () => {
6314
+ const startIndex = columns.findIndex(
6315
+ (col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
6316
+ );
6317
+ const endIndex = columns.findLastIndex(
6318
+ (col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
6319
+ );
6320
+ const fromStart = startIndex === -1 ? columns.length : startIndex;
6321
+ const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
6322
+ setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
6323
+ return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
6324
+ };
6325
+ return calculateColSpanEmpty();
6326
+ }, [columns, row]);
6327
+ const shouldFetchData = (0, import_react21.useMemo)(() => {
6328
+ return !!isShowGroup;
6329
+ }, [isShowGroup]);
6330
+ const enabled = shouldFetchData && !!processedData;
6331
+ const listDataProps = {
6332
+ model,
6333
+ specification,
6334
+ domain,
6335
+ context,
6336
+ offset: pageGroup * 10,
6337
+ fields: groupByDomain?.fields,
6338
+ groupby: [groupByDomain?.contexts[level]?.group_by]
6339
+ };
6340
+ const queryKey = [
6341
+ `data-${model}--${level}-row${indexRow}`,
6342
+ specification,
6343
+ domain,
6344
+ pageGroup
6345
+ ];
6346
+ const {
6347
+ data: dataResponse,
6348
+ isFetched: isQueryFetched,
6349
+ isPlaceholderData,
6350
+ isLoading,
6351
+ isFetching
6352
+ } = (0, import_interface_logic21.useGetListData)(listDataProps, queryKey, enabled);
6353
+ const {
6354
+ columns: columnsGroup,
6355
+ rows: rowsGroup,
6356
+ typeTable: typeTableGroup
6357
+ } = tableController({
6358
+ data: {
6359
+ fields: viewData?.views?.list?.fields,
6360
+ records: dataResponse?.records ?? dataResponse?.groups,
6361
+ dataModel: viewData?.models?.[model],
6362
+ context: env.context,
6363
+ typeTable: dataResponse?.groups ? "group" : "list"
6364
+ }
6365
+ });
6366
+ const leftPadding = level > 1 ? level * 8 + "px" : "0px";
6367
+ (0, import_react21.useEffect)(() => {
6368
+ if (isShowGroup && selectedTags?.length > 0) {
6369
+ setIsShowGroup(false);
6370
+ }
6371
+ }, [selectedTags]);
6372
+ const group_by_field_name = groupByDomain?.contexts[level - 1]?.group_by;
6373
+ const nameGroup = Array.isArray(row[group_by_field_name]) ? row?.string ?? row[`${group_by_field_name}`][1] : viewData?.models?.[model]?.[group_by_field_name]?.selection ? viewData.models[model][group_by_field_name].selection.find(
6374
+ (selectItem) => selectItem?.[0] === row[group_by_field_name]
6375
+ )?.[1] : row[group_by_field_name];
6376
+ const nameGroupWithCount = `${typeof nameGroup === "string" ? nameGroup : typeof nameGroup === "boolean" && nameGroup ? i18n_default.t("yes") : i18n_default.t("no")} (${row[`${group_by_field_name?.split(":")?.[0]}_count`]})`;
6377
+ const allIdsNull = selectedRowKeys?.every((item) => item === void 0);
6378
+ const handleExpandChildGroup = () => {
6379
+ if (isLoading || isFetching) return;
6380
+ const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
6381
+ if (allIdsNull || typeTableGroup === "group") {
6382
+ toggleShowGroup();
6383
+ return;
6384
+ }
6385
+ if (isShowGroup && checkedAll) {
6386
+ const ids = rowsGroup?.map((item) => item?.id) || [];
6387
+ const filteredIds = selectedRowKeys.filter(
6388
+ (id) => !ids.includes(id)
6389
+ );
6390
+ appDispatch((0, import_interface_logic21.setSelectedRowKeys)(filteredIds));
6391
+ } else if (!isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && checkedAll && !allIdsNull && isQueryFetched) {
6392
+ const clonedKeys = [...selectedRowKeys];
6393
+ appDispatch((0, import_interface_logic21.setSelectedRowKeys)([...clonedKeys, -1]));
6394
+ setTimeout(() => appDispatch((0, import_interface_logic21.setSelectedRowKeys)(clonedKeys)), 500);
6395
+ } else if (isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && !checkedAll && !allIdsNull) {
6396
+ const filteredKeys = selectedRowKeys.filter((id) => id > -1);
6397
+ appDispatch((0, import_interface_logic21.setSelectedRowKeys)(filteredKeys));
6398
+ }
6399
+ toggleShowGroup();
6400
+ };
6401
+ (0, import_react21.useEffect)(() => {
6402
+ if (!isQueryFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
6403
+ return;
6404
+ }
6405
+ const clonedKeys = [...selectedRowKeys];
6406
+ (0, import_interface_logic21.setSelectedRowKeys)([...clonedKeys, -1]);
6407
+ setTimeout(() => (0, import_interface_logic21.setSelectedRowKeys)(clonedKeys), 500);
6408
+ }, [isQueryFetched]);
6409
+ return {
6410
+ handleExpandChildGroup,
6411
+ colEmptyGroup,
6412
+ leftPadding,
6413
+ isShowGroup,
6414
+ isQueryFetched,
6415
+ nameGroupWithCount,
6416
+ columns,
6417
+ row,
6418
+ isPlaceholderData,
6419
+ columnsGroup,
6420
+ indexRow,
6421
+ rowsGroup,
6422
+ model,
6423
+ viewData,
6424
+ renderField,
6425
+ level,
6426
+ specification,
6427
+ context,
6428
+ checkedAll,
6429
+ isDisplayCheckbox,
6430
+ isAutoSelect,
6431
+ setIsAutoSelect,
6432
+ selectedRowKeysRef,
6433
+ initVal,
6434
+ dataResponse,
6435
+ pageGroup,
6436
+ setPageGroup
6437
+ };
6438
+ };
6439
+
6440
+ // src/widget/basic/many2many-field/controller.ts
6441
+ var many2manyFieldController = (props) => {
6442
+ const {
6443
+ relation,
6444
+ domain,
6445
+ context,
6446
+ tab,
6447
+ model,
6448
+ aid,
6449
+ setSelectedRowKeys: setSelectedRowKeys4,
6450
+ fields,
6451
+ setFields,
6452
+ groupByDomain,
6453
+ page,
6454
+ options,
6455
+ sessionStorageUtils
6456
+ } = props;
6457
+ const appDispatch = (0, import_interface_logic22.useAppDispatch)();
6458
+ const actionData = sessionStorageUtils.getActionData();
6459
+ const [debouncedPage] = useDebounce(page, 500);
6460
+ const [order, setOrder] = (0, import_react22.useState)();
6461
+ const [isLoadedData, setIsLoadedData] = (0, import_react22.useState)(false);
6462
+ const [domainMany2Many, setDomainMany2Many] = (0, import_react22.useState)(domain);
6463
+ const env = (0, import_interface_logic22.getEnv)();
6464
+ const { selectedTags } = (0, import_interface_logic22.useAppSelector)(import_interface_logic22.selectSearch);
6465
+ const viewParams = {
6466
+ model: relation,
6467
+ views: [
6468
+ [false, "list"],
6469
+ [false, "search"]
6470
+ ],
6471
+ context
6472
+ };
6473
+ const { data: viewResponse, isFetched: isViewReponseFetched } = (0, import_interface_logic22.useGetView)(
6474
+ viewParams,
6475
+ actionData
6476
+ );
6477
+ const baseModel = (0, import_react22.useMemo)(
6478
+ () => ({
6479
+ name: String(relation),
6480
+ view: viewResponse || {},
6481
+ actContext: context,
6482
+ fields: [
6483
+ ...Object.values(viewResponse?.views?.list?.fields ?? {}),
6484
+ ...tab?.fields ? tab.fields : []
6485
+ ]
6486
+ }),
6487
+ [model, viewResponse]
6488
+ );
6489
+ const initModel = (0, import_interface_logic22.useModel)();
6490
+ const modelInstance = (0, import_react22.useMemo)(() => {
6491
+ if (viewResponse) {
6492
+ return initModel.initModel(baseModel);
6493
+ }
6494
+ return null;
6495
+ }, [baseModel, viewResponse]);
6496
+ const specification = (0, import_react22.useMemo)(() => {
6497
+ if (modelInstance) {
6498
+ return modelInstance.getSpecification();
6499
+ }
6500
+ return null;
6501
+ }, [modelInstance]);
6502
+ const default_order = viewResponse && viewResponse?.views?.list?.default_order;
6503
+ const optionsObject = tab?.options ? (0, import_interface_logic22.evalJSONContext)(tab?.options) : (options ? (0, import_interface_logic22.evalJSONContext)(options) : {}) || {};
6504
+ const fetchData = async () => {
6505
+ try {
6506
+ setDomainMany2Many(domain);
6507
+ appDispatch((0, import_interface_logic22.setFirstDomain)(domain));
6508
+ appDispatch((0, import_interface_logic22.setViewDataStore)(viewResponse));
6509
+ const modalData = viewResponse?.views?.list?.fields.map((field) => ({
6510
+ ...viewResponse?.models?.[String(model)]?.[field?.name],
6511
+ ...field
6512
+ }));
6513
+ if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
6514
+ setFields({
6515
+ ...fields,
6516
+ [`${aid}_${relation}_popupmany2many`]: modalData
6517
+ });
6518
+ }
6519
+ appDispatch((0, import_interface_logic22.setPage)(0));
6520
+ } catch (err) {
6521
+ console.log(err);
6522
+ }
6523
+ };
6524
+ const queryKey = [
6525
+ `view-${relation}-${aid}`,
6526
+ specification,
6527
+ domainMany2Many,
6528
+ debouncedPage,
6529
+ groupByDomain,
6530
+ order
6531
+ ];
6532
+ const data = {
6533
+ model: relation,
6534
+ specification,
6535
+ domain: domainMany2Many,
6536
+ offset: debouncedPage * 10,
6537
+ limit: 10,
6538
+ context,
6539
+ fields: groupByDomain?.fields,
6540
+ groupby: [groupByDomain?.contexts[0]?.group_by],
6541
+ sort: order ? order : default_order ? (0, import_interface_logic22.formatSortingString)(default_order) : ""
6542
+ };
6543
+ const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
6544
+ const {
6545
+ data: dataResponse,
6546
+ isLoading: isDataLoading,
6547
+ isFetched: isDataResponseFetched,
6548
+ isPlaceholderData
6549
+ } = (0, import_interface_logic22.useGetListData)(data, queryKey, enabled);
6550
+ (0, import_react22.useEffect)(() => {
6551
+ if (viewResponse) {
6552
+ fetchData();
6553
+ }
6554
+ return () => {
6555
+ appDispatch((0, import_interface_logic22.setGroupByDomain)(null));
6556
+ setFields((prevFields) => ({
6557
+ ...prevFields,
6558
+ [`${aid}_${relation}_popupmany2many`]: null
6559
+ }));
6560
+ appDispatch((0, import_interface_logic22.setPage)(0));
6561
+ setSelectedRowKeys4([]);
6562
+ setDomainMany2Many(null);
6563
+ setIsLoadedData(false);
6564
+ };
6565
+ }, [viewResponse]);
6566
+ const { rows, columns, typeTable } = tableController({
6567
+ data: {
6568
+ fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
6569
+ records: dataResponse?.records ?? dataResponse?.groups,
6570
+ dataModel: viewResponse?.models?.[String(relation)],
6571
+ context: { ...env.context, ...context },
6572
+ typeTable: dataResponse?.groups ? "group" : "list"
6573
+ }
6574
+ });
6575
+ const dataFormView = {
6576
+ id: null,
6577
+ model: relation,
6578
+ context
6579
+ };
6580
+ const {
6581
+ refetch,
6582
+ data: dataFormViewResponse,
6583
+ isSuccess
6584
+ } = (0, import_interface_logic22.useGetFormView)({
6585
+ data: dataFormView,
6586
+ queryKey: [`form-view-action-${relation}`],
6587
+ enabled: false
6588
+ });
6589
+ (0, import_react22.useEffect)(() => {
6590
+ if (isSuccess && dataFormViewResponse) {
6591
+ sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
6592
+ window.location.href = `/form/menu?model=${relation}`;
6593
+ }
6594
+ }, [isSuccess]);
6595
+ (0, import_react22.useEffect)(() => {
6596
+ if (domainMany2Many && !isLoadedData) {
6597
+ setIsLoadedData(true);
6598
+ }
6599
+ }, [domainMany2Many]);
6600
+ const handleCreateNewOnPage = async () => {
6601
+ try {
6602
+ refetch();
6603
+ } catch (error) {
6604
+ console.log(error);
6605
+ }
6606
+ };
6607
+ return {};
6608
+ };
6609
+
6610
+ // src/widget/basic/many2many-tags-field/controller.ts
6611
+ var import_react23 = require("react");
6612
+ var import_interface_logic23 = require("@fctc/interface-logic");
6613
+ var many2manyTagsController = (props) => {
6614
+ const {
6615
+ relation,
6616
+ domain,
6617
+ options: optionsFields,
6618
+ widget,
6619
+ formValues,
6620
+ placeholderNoOption
6621
+ } = props;
6622
+ const isUser = relation === "res.users" || relation === "res.partner";
6623
+ const env = (0, import_interface_logic23.getEnv)();
6624
+ const addtionalFields = optionsFields ? (0, import_interface_logic23.evalJSONContext)(optionsFields) : null;
6625
+ const domainObject = (0, import_react23.useMemo)(
6626
+ () => (0, import_interface_logic23.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues || {}))),
6627
+ [domain, formValues]
6628
+ );
6629
+ const data = {
6630
+ model: relation ?? "",
6631
+ domain: domainObject,
6632
+ specification: {
6633
+ id: {},
6634
+ name: {},
6635
+ display_name: {},
6636
+ ...widget && import_interface_logic23.WIDGETAVATAR[widget] ? { image_256: {} } : {},
6637
+ ...widget && import_interface_logic23.WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
6638
+ },
6639
+ enabled: true,
6640
+ context: env.context
6641
+ };
6642
+ const { data: dataOfSelection } = (0, import_interface_logic23.useGetSelection)({
6643
+ data,
6644
+ queryKey: [`data_${relation}`, domainObject]
6645
+ });
6646
+ const customNoOptionsMessage = () => placeholderNoOption;
6647
+ const tranfer = (data2) => {
6648
+ return data2?.map((val) => ({
6649
+ id: val.value,
6650
+ display_name: val.label
6651
+ })) || [];
6652
+ };
6653
+ const options = dataOfSelection?.records?.map((val) => ({
6654
+ value: val.id,
6655
+ label: val.name ?? val.display_name,
6656
+ ...val
6657
+ })) || [];
6658
+ return {
6659
+ options,
6660
+ customNoOptionsMessage,
6661
+ tranfer,
6662
+ dataOfSelection,
6663
+ isUser
6664
+ };
6665
+ };
6666
+
6667
+ // src/widget/basic/status-bar-field/controller.ts
6668
+ var import_react24 = require("react");
6669
+ var import_interface_logic24 = require("@fctc/interface-logic");
6670
+ var durationController = (props) => {
6671
+ const {
6672
+ relation,
6673
+ defaultValue,
6674
+ domain,
6675
+ formValues,
6676
+ name,
6677
+ id,
6678
+ model,
6679
+ onRefetch
6680
+ } = props;
6681
+ const specification = {
6682
+ id: 0,
6683
+ name: "",
6684
+ fold: ""
6685
+ };
6686
+ const [disabled, setDisabled] = (0, import_react24.useState)(false);
6687
+ const [modelStatus, setModalStatus] = (0, import_react24.useState)(false);
6688
+ const { context } = (0, import_interface_logic24.useAppSelector)(import_interface_logic24.selectEnv);
6689
+ const queryKey = [`data-status-duration`, specification];
6690
+ const listDataProps = {
6691
+ model: relation,
6692
+ specification,
6693
+ domain: (0, import_interface_logic24.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues))),
6694
+ limit: 10,
6695
+ offset: 0,
6696
+ fields: "",
6697
+ groupby: [],
6698
+ context: {
6699
+ lang: context.lang
6700
+ },
6701
+ sort: ""
6702
+ };
6703
+ const { data: dataResponse } = (0, import_interface_logic24.useGetListData)(listDataProps, queryKey);
6704
+ const { mutate: fetchChangeStatus } = (0, import_interface_logic24.useChangeStatus)();
6705
+ const handleClick = async (stage_id) => {
6706
+ setDisabled(true);
6707
+ if (stage_id) {
6708
+ fetchChangeStatus(
6709
+ {
6710
+ data: {
6711
+ stage_id,
6712
+ name,
6713
+ id,
6714
+ model,
6715
+ lang: context.lang
6716
+ }
6717
+ },
6718
+ {
6719
+ onSuccess: (res) => {
6720
+ if (res) {
6721
+ setDisabled(false);
6722
+ onRefetch && onRefetch();
6723
+ }
6724
+ }
6725
+ }
6726
+ );
6727
+ }
6728
+ };
6729
+ return {
6730
+ defaultValue,
6731
+ dataResponse,
6732
+ handleClick,
6733
+ disabled,
6734
+ modelStatus,
6735
+ setModalStatus
6736
+ };
6737
+ };
6738
+
6739
+ // src/widget/basic/priority-field/controller.ts
6740
+ var import_interface_logic25 = require("@fctc/interface-logic");
6741
+ var priorityFieldController = (props) => {
6742
+ const {
6743
+ value,
6744
+ isForm,
6745
+ name,
6746
+ methods,
6747
+ onChange,
6748
+ model,
6749
+ selection,
6750
+ id,
6751
+ actionData,
6752
+ viewData,
6753
+ context
6754
+ } = props;
6755
+ const _context = { ...(0, import_interface_logic25.evalJSONContext)(actionData?.context) };
6756
+ const contextObject = { ...context, ..._context };
6757
+ const defaultPriority = parseInt(value) + 1;
6758
+ const label = viewData?.models?.[model]?.[name ?? ""]?.string ?? name;
6759
+ const { mutateAsync: fetchSave } = (0, import_interface_logic25.useSave)();
6760
+ const savePriorities = async ({
6761
+ value: value2,
6762
+ resetPriority
6763
+ }) => {
6764
+ const priorityValue = value2 <= 0 ? 0 : value2 - 1;
6765
+ try {
6766
+ fetchSave({
6767
+ ids: id ? [id] : [],
6768
+ data: { [name ?? ""]: String(priorityValue) },
6769
+ model: model ?? "",
6770
+ context: contextObject
6771
+ });
6772
+ if (typeof onChange === "function") {
6773
+ onChange(name ?? "", String(priorityValue));
6774
+ }
6775
+ } catch (error) {
6776
+ if (resetPriority) {
6777
+ resetPriority();
6778
+ }
6779
+ }
6780
+ };
6781
+ return {
6782
+ selection,
6783
+ isForm,
6784
+ methods,
6785
+ defaultPriority,
6786
+ savePriorities,
6787
+ label,
6788
+ id,
6789
+ onChange
6790
+ };
6791
+ };
6792
+
6793
+ // src/widget/basic/float-time-field/controller.ts
6794
+ var import_react25 = require("react");
6795
+ var import_interface_logic26 = require("@fctc/interface-logic");
6796
+ var floatTimeFiledController = ({
6797
+ onChange: fieldOnChange,
6798
+ onBlur,
6799
+ value,
6800
+ isDirty,
6801
+ props
6802
+ }) => {
6803
+ const { name, defaultValue = 0, onChange } = props;
6804
+ const [input, setInput] = (0, import_react25.useState)(
6805
+ (0, import_interface_logic26.convertFloatToTime)(value ?? defaultValue)
6806
+ );
6807
+ const [formattedTime, setFormattedTime] = (0, import_react25.useState)("");
6808
+ const [errors, setErrors] = (0, import_react25.useState)("");
6809
+ const handleInputChange = (e) => {
6810
+ const raw = e.target.value.replace(/[^\d:]/g, "");
6811
+ setInput(raw);
6812
+ const timeRegex = /^(\d{1,2}):?(\d{0,2})$/;
6813
+ const match = raw.match(timeRegex);
6814
+ if (!match) {
6815
+ setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
6816
+ setFormattedTime("");
6817
+ return;
6818
+ }
6819
+ let hours = parseInt(match[1] ?? "0", 10);
6820
+ let minutes = parseInt(match[2] ?? "0", 10);
6821
+ if (isNaN(hours)) hours = 0;
6822
+ if (isNaN(minutes)) minutes = 0;
6823
+ if (hours >= 24) {
6824
+ hours = 0;
6825
+ }
6826
+ if (minutes >= 60) {
6827
+ minutes = 0;
6828
+ }
6829
+ const formatted = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
6830
+ setErrors("");
6831
+ setFormattedTime(formatted);
6832
+ fieldOnChange(formatted);
6833
+ };
6834
+ const handleBlur = () => {
6835
+ if (!isDirty) return;
6836
+ if (formattedTime) {
6837
+ setInput(formattedTime);
6838
+ const floatVal = (0, import_interface_logic26.convertTimeToFloat)(formattedTime);
6839
+ fieldOnChange(floatVal);
6840
+ if (onChange) {
6841
+ onChange(name ?? "", floatVal);
6842
+ }
6843
+ } else {
6844
+ setInput("00:00");
6845
+ fieldOnChange(0);
6846
+ if (onChange) {
6847
+ onChange(name ?? "", 0);
6848
+ }
6849
+ setErrors("");
6850
+ }
6851
+ onBlur();
6852
+ };
6853
+ const handleKeyDown = (e) => {
6854
+ {
6855
+ const allowed = [
6856
+ "Backspace",
6857
+ "Tab",
6858
+ "ArrowLeft",
6859
+ "ArrowRight",
6860
+ "Delete",
6861
+ "Home",
6862
+ "End",
6863
+ ":"
6864
+ ];
6865
+ const isNumber = /^[0-9]$/.test(e.key);
6866
+ if (!isNumber && !allowed.includes(e.key)) {
6867
+ e.preventDefault();
6868
+ }
6869
+ }
6870
+ };
6871
+ return {
6872
+ handleInputChange,
6873
+ handleBlur,
6874
+ handleKeyDown,
6875
+ input,
6876
+ errors
6877
+ };
6878
+ };
6879
+
6613
6880
  // src/widget/basic/float-field/controller.ts
6881
+ var import_react26 = require("react");
6614
6882
  var floatController = ({
6615
6883
  onChange,
6616
6884
  value,
@@ -6618,10 +6886,10 @@ var floatController = ({
6618
6886
  }) => {
6619
6887
  const { name, required, methods, onChange: handleOnchange, string } = props;
6620
6888
  const { setError, clearErrors } = methods;
6621
- const [inputValue, setInputValue] = (0, import_react24.useState)(
6889
+ const [inputValue, setInputValue] = (0, import_react26.useState)(
6622
6890
  value !== void 0 && value !== null ? useFormatFloatNumber(value) : ""
6623
6891
  );
6624
- (0, import_react24.useEffect)(() => {
6892
+ (0, import_react26.useEffect)(() => {
6625
6893
  if (value !== void 0 && value !== null && value !== parseFloat(inputValue?.replace(/,/g, ""))) {
6626
6894
  setInputValue(useFormatFloatNumber(value));
6627
6895
  clearErrors(name);
@@ -6629,9 +6897,9 @@ var floatController = ({
6629
6897
  setInputValue("");
6630
6898
  }
6631
6899
  }, [value, name, clearErrors]);
6632
- const isDirtyRef = (0, import_react24.useRef)(false);
6633
- const inputRef = (0, import_react24.useRef)(null);
6634
- const lastCommittedValueRef = (0, import_react24.useRef)(null);
6900
+ const isDirtyRef = (0, import_react26.useRef)(false);
6901
+ const inputRef = (0, import_react26.useRef)(null);
6902
+ const lastCommittedValueRef = (0, import_react26.useRef)(null);
6635
6903
  const handleInputChange = (e) => {
6636
6904
  const newValue = e.target.value;
6637
6905
  const valueWithoutCommas = newValue.replace(/,/g, "");
@@ -6732,10 +7000,10 @@ var useFormatFloatNumber = (value) => {
6732
7000
  };
6733
7001
 
6734
7002
  // src/widget/basic/download-file-field/controller.ts
6735
- var import_react25 = require("react");
7003
+ var import_react27 = require("react");
6736
7004
  var downloadFileController = () => {
6737
- const inputId = (0, import_react25.useId)();
6738
- const [file, setFile] = (0, import_react25.useState)(null);
7005
+ const inputId = (0, import_react27.useId)();
7006
+ const [file, setFile] = (0, import_react27.useState)(null);
6739
7007
  const handleFileChange = (e) => {
6740
7008
  setFile(e.target.files[0]);
6741
7009
  };
@@ -6899,13 +7167,13 @@ var dateFieldController = (props) => {
6899
7167
  };
6900
7168
 
6901
7169
  // src/widget/basic/copy-link-button/controller.ts
6902
- var import_react26 = require("react");
6903
- var import_interface_logic24 = require("@fctc/interface-logic");
7170
+ var import_react28 = require("react");
7171
+ var import_interface_logic27 = require("@fctc/interface-logic");
6904
7172
  var copyLinkButtonController = (props) => {
6905
7173
  const { value, defaultValue } = props;
6906
- const [isCopied, setIsCopied] = (0, import_react26.useState)(false);
7174
+ const [isCopied, setIsCopied] = (0, import_react28.useState)(false);
6907
7175
  const handleCopyToClipboard = async (value2) => {
6908
- await (0, import_interface_logic24.copyTextToClipboard)(value2);
7176
+ await (0, import_interface_logic27.copyTextToClipboard)(value2);
6909
7177
  setIsCopied(true);
6910
7178
  setTimeout(() => setIsCopied(false), 2e3);
6911
7179
  };
@@ -6918,14 +7186,14 @@ var copyLinkButtonController = (props) => {
6918
7186
  };
6919
7187
 
6920
7188
  // src/widget/basic/color-field/color-controller.ts
6921
- var import_interface_logic25 = require("@fctc/interface-logic");
7189
+ var import_interface_logic28 = require("@fctc/interface-logic");
6922
7190
  var colorFieldController = (props) => {
6923
7191
  const { value, isForm, name, formValues, idForm, model, actionData } = props;
6924
- const env = (0, import_interface_logic25.getEnv)();
6925
- const _context = { ...(0, import_interface_logic25.evalJSONContext)(actionData?.context) || {} };
7192
+ const env = (0, import_interface_logic28.getEnv)();
7193
+ const _context = { ...(0, import_interface_logic28.evalJSONContext)(actionData?.context) || {} };
6926
7194
  const contextObject = { ...env.context, ..._context };
6927
7195
  const idDefault = isForm ? idForm : formValues?.id;
6928
- const { mutate: onSave } = (0, import_interface_logic25.useSave)();
7196
+ const { mutate: onSave } = (0, import_interface_logic28.useSave)();
6929
7197
  const savePickColor = async (colorObject) => {
6930
7198
  const { id } = colorObject;
6931
7199
  if (value === id) return;
@@ -6950,16 +7218,16 @@ var colorFieldController = (props) => {
6950
7218
  };
6951
7219
 
6952
7220
  // src/widget/basic/binary-field/controller.ts
6953
- var import_react27 = require("react");
6954
- var import_interface_logic26 = require("@fctc/interface-logic");
7221
+ var import_react29 = require("react");
7222
+ var import_interface_logic29 = require("@fctc/interface-logic");
6955
7223
  var binaryFieldController = (props) => {
6956
7224
  const { name, methods, readonly = false, value } = props;
6957
- const inputId = (0, import_react27.useId)();
6958
- const [selectedImage, setSelectedImage] = (0, import_react27.useState)(null);
6959
- const [initialImage, setInitialImage] = (0, import_react27.useState)(value || null);
6960
- const [isInsideTable, setIsInsideTable] = (0, import_react27.useState)(false);
7225
+ const inputId = (0, import_react29.useId)();
7226
+ const [selectedImage, setSelectedImage] = (0, import_react29.useState)(null);
7227
+ const [initialImage, setInitialImage] = (0, import_react29.useState)(value || null);
7228
+ const [isInsideTable, setIsInsideTable] = (0, import_react29.useState)(false);
6961
7229
  const { setValue } = methods;
6962
- const binaryRef = (0, import_react27.useRef)(null);
7230
+ const binaryRef = (0, import_react29.useRef)(null);
6963
7231
  const convertUrlToBase64 = async (url) => {
6964
7232
  try {
6965
7233
  const response = await fetch(url);
@@ -7008,11 +7276,11 @@ var binaryFieldController = (props) => {
7008
7276
  };
7009
7277
  const checkIsImageLink = (url) => {
7010
7278
  const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
7011
- return imageExtensions.test(url) || (0, import_interface_logic26.isBase64Image)(url) || isBlobUrl(url);
7279
+ return imageExtensions.test(url) || (0, import_interface_logic29.isBase64Image)(url) || isBlobUrl(url);
7012
7280
  };
7013
7281
  const getImageBase64WithMimeType = (base64) => {
7014
7282
  if (typeof base64 !== "string" || base64.length < 10) return null;
7015
- if ((0, import_interface_logic26.isBase64Image)(base64)) return base64;
7283
+ if ((0, import_interface_logic29.isBase64Image)(base64)) return base64;
7016
7284
  let mimeType = null;
7017
7285
  if (base64.startsWith("iVBORw0KGgo")) mimeType = "image/png";
7018
7286
  else if (base64.startsWith("/9j/")) mimeType = "image/jpeg";
@@ -7021,14 +7289,14 @@ var binaryFieldController = (props) => {
7021
7289
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
7022
7290
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
7023
7291
  };
7024
- (0, import_react27.useEffect)(() => {
7292
+ (0, import_react29.useEffect)(() => {
7025
7293
  return () => {
7026
7294
  if (selectedImage) {
7027
7295
  URL.revokeObjectURL(selectedImage);
7028
7296
  }
7029
7297
  };
7030
7298
  }, [selectedImage]);
7031
- (0, import_react27.useEffect)(() => {
7299
+ (0, import_react29.useEffect)(() => {
7032
7300
  if (binaryRef.current) {
7033
7301
  const isInsideTable2 = !!binaryRef.current.closest("table");
7034
7302
  setIsInsideTable(isInsideTable2);
@@ -7046,272 +7314,6 @@ var binaryFieldController = (props) => {
7046
7314
  getImageBase64WithMimeType
7047
7315
  };
7048
7316
  };
7049
-
7050
- // src/widget/advance/table/table-body/controller.ts
7051
- var import_interface_logic27 = require("@fctc/interface-logic");
7052
- var import_react28 = require("react");
7053
- var tableBodyController = (props) => {
7054
- const {
7055
- checkedAll,
7056
- checkboxRef,
7057
- setIsAutoSelect,
7058
- selectedRowKeys,
7059
- row,
7060
- isAutoSelect,
7061
- selectedRowKeysRef,
7062
- onClickRow
7063
- } = props;
7064
- const appDispatch = (0, import_interface_logic27.useAppDispatch)();
7065
- const checked = (0, import_react28.useMemo)(() => {
7066
- if (!row?.id) return false;
7067
- if (selectedRowKeys?.includes(row.id)) {
7068
- return true;
7069
- }
7070
- return checkedAll;
7071
- }, [row?.id, selectedRowKeys, checkedAll]);
7072
- const handleCheckBoxSingle = (event) => {
7073
- event.stopPropagation();
7074
- if (checkedAll) {
7075
- checkboxRef.current = "uncheck";
7076
- setIsAutoSelect(true);
7077
- return;
7078
- }
7079
- const newSelectedRowKeys = selectedRowKeys?.includes(row.id) ? selectedRowKeys?.filter((key) => key !== row.id) : [...selectedRowKeys, row.id];
7080
- console.log("newSelectedRowKeys", newSelectedRowKeys);
7081
- appDispatch((0, import_interface_logic27.setSelectedRowKeys)(newSelectedRowKeys));
7082
- };
7083
- const handleClickRow = (col, row2) => {
7084
- onClickRow(col, row2);
7085
- };
7086
- (0, import_react28.useEffect)(() => {
7087
- if (!row?.id) return;
7088
- if (isAutoSelect) {
7089
- if (checkboxRef?.current === "uncheck") {
7090
- const filtered = selectedRowKeysRef.current.filter(
7091
- (id) => id !== row.id
7092
- );
7093
- selectedRowKeysRef.current = filtered;
7094
- appDispatch((0, import_interface_logic27.setSelectedRowKeys)(filtered));
7095
- } else {
7096
- const unique = Array.from(
7097
- /* @__PURE__ */ new Set([...selectedRowKeysRef?.current, row?.id])
7098
- );
7099
- selectedRowKeysRef.current = unique;
7100
- appDispatch((0, import_interface_logic27.setSelectedRowKeys)(unique));
7101
- }
7102
- }
7103
- }, [isAutoSelect]);
7104
- (0, import_react28.useEffect)(() => {
7105
- if (!checkedAll) {
7106
- checkboxRef.current = "enabled";
7107
- false;
7108
- }
7109
- }, [checkedAll]);
7110
- return {
7111
- handleCheckBoxSingle,
7112
- checked,
7113
- handleClickRow
7114
- };
7115
- };
7116
-
7117
- // src/widget/advance/table/table-head/controller.ts
7118
- var import_interface_logic28 = require("@fctc/interface-logic");
7119
- var tableHeadController = (props) => {
7120
- const { typeTable, rows, selectedRowKeysRef } = props;
7121
- const appDispatch = (0, import_interface_logic28.useAppDispatch)();
7122
- const { groupByDomain } = (0, import_interface_logic28.useAppSelector)(import_interface_logic28.selectSearch);
7123
- const handleCheckBoxAll = (event) => {
7124
- if (event?.target?.checked && typeTable === "list") {
7125
- const allRowKeys = Array.isArray(rows) ? rows.map((record) => record?.id) : [];
7126
- appDispatch((0, import_interface_logic28.setSelectedRowKeys)(allRowKeys));
7127
- } else if (event?.target?.checked && typeTable === "group") {
7128
- const rowsIDs = document.querySelectorAll("tr[data-row-id]");
7129
- const ids = Array.from(rowsIDs)?.map(
7130
- (row) => Number(row?.getAttribute("data-row-id"))
7131
- );
7132
- if (ids?.length > 0) {
7133
- appDispatch((0, import_interface_logic28.setSelectedRowKeys)(ids));
7134
- } else {
7135
- const sum = countSum(
7136
- rows,
7137
- typeof groupByDomain === "object" ? groupByDomain?.contexts?.[0]?.group_by : void 0
7138
- );
7139
- const keys = Array.from({ length: sum }, (_) => void 0);
7140
- appDispatch((0, import_interface_logic28.setSelectedRowKeys)(keys));
7141
- }
7142
- if (selectedRowKeysRef) {
7143
- selectedRowKeysRef.current = [];
7144
- }
7145
- } else {
7146
- appDispatch((0, import_interface_logic28.setSelectedRowKeys)([]));
7147
- }
7148
- };
7149
- return {
7150
- handleCheckBoxAll
7151
- };
7152
- };
7153
-
7154
- // src/widget/advance/table/table-group/controller.ts
7155
- var import_interface_logic29 = require("@fctc/interface-logic");
7156
- var import_react29 = require("react");
7157
- var tableGroupController = (props) => {
7158
- const env = (0, import_interface_logic29.getEnv)();
7159
- const {
7160
- rows,
7161
- columns,
7162
- indexRow,
7163
- row,
7164
- model,
7165
- viewData,
7166
- renderField,
7167
- level,
7168
- specification,
7169
- domain,
7170
- context,
7171
- checkedAll,
7172
- isDisplayCheckbox,
7173
- isAutoSelect,
7174
- setIsAutoSelect,
7175
- selectedRowKeysRef
7176
- } = props;
7177
- const [pageGroup, setPageGroup] = (0, import_react29.useState)(0);
7178
- const { groupByDomain, selectedTags } = (0, import_interface_logic29.useAppSelector)(import_interface_logic29.selectSearch);
7179
- const { selectedRowKeys } = (0, import_interface_logic29.useAppSelector)(import_interface_logic29.selectList);
7180
- const appDispatch = (0, import_interface_logic29.useAppDispatch)();
7181
- const { toDataJS } = (0, import_interface_logic29.useOdooDataTransform)();
7182
- const initVal = toDataJS(row, viewData, model);
7183
- const [isShowGroup, setIsShowGroup] = (0, import_react29.useState)(false);
7184
- const [colEmptyGroup, setColEmptyGroup] = (0, import_react29.useState)({
7185
- fromStart: 1,
7186
- fromEnd: 1
7187
- });
7188
- const processedData = (0, import_react29.useMemo)(() => {
7189
- const calculateColSpanEmpty = () => {
7190
- const startIndex = columns.findIndex(
7191
- (col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
7192
- );
7193
- const endIndex = columns.findLastIndex(
7194
- (col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
7195
- );
7196
- const fromStart = startIndex === -1 ? columns.length : startIndex;
7197
- const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
7198
- setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
7199
- return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
7200
- };
7201
- return calculateColSpanEmpty();
7202
- }, [columns, row]);
7203
- const shouldFetchData = (0, import_react29.useMemo)(() => {
7204
- return !!isShowGroup;
7205
- }, [isShowGroup]);
7206
- const enabled = shouldFetchData && !!processedData;
7207
- const listDataProps = {
7208
- model,
7209
- specification,
7210
- domain,
7211
- context,
7212
- offset: pageGroup * 10,
7213
- fields: groupByDomain?.fields,
7214
- groupby: [groupByDomain?.contexts[level]?.group_by]
7215
- };
7216
- const queryKey = [
7217
- `data-${model}--${level}-row${indexRow}`,
7218
- specification,
7219
- domain,
7220
- pageGroup
7221
- ];
7222
- const {
7223
- data: dataResponse,
7224
- isFetched: isQueryFetched,
7225
- isPlaceholderData,
7226
- isLoading,
7227
- isFetching
7228
- } = (0, import_interface_logic29.useGetListData)(listDataProps, queryKey, enabled);
7229
- const {
7230
- columns: columnsGroup,
7231
- rows: rowsGroup,
7232
- typeTable: typeTableGroup
7233
- } = tableController({
7234
- data: {
7235
- fields: viewData?.views?.list?.fields,
7236
- records: dataResponse?.records ?? dataResponse?.groups,
7237
- dataModel: viewData?.models?.[model],
7238
- context: env.context,
7239
- typeTable: dataResponse?.groups ? "group" : "list"
7240
- }
7241
- });
7242
- const leftPadding = level > 1 ? level * 8 + "px" : "0px";
7243
- (0, import_react29.useEffect)(() => {
7244
- if (isShowGroup && selectedTags?.length > 0) {
7245
- setIsShowGroup(false);
7246
- }
7247
- }, [selectedTags]);
7248
- const group_by_field_name = groupByDomain?.contexts[level - 1]?.group_by;
7249
- const nameGroup = Array.isArray(row[group_by_field_name]) ? row?.string ?? row[`${group_by_field_name}`][1] : viewData?.models?.[model]?.[group_by_field_name]?.selection ? viewData.models[model][group_by_field_name].selection.find(
7250
- (selectItem) => selectItem?.[0] === row[group_by_field_name]
7251
- )?.[1] : row[group_by_field_name];
7252
- const nameGroupWithCount = `${typeof nameGroup === "string" ? nameGroup : typeof nameGroup === "boolean" && nameGroup ? i18n_default.t("yes") : i18n_default.t("no")} (${row[`${group_by_field_name?.split(":")?.[0]}_count`]})`;
7253
- const allIdsNull = selectedRowKeys?.every((item) => item === void 0);
7254
- const handleExpandChildGroup = () => {
7255
- if (isLoading || isFetching) return;
7256
- const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
7257
- if (allIdsNull || typeTableGroup === "group") {
7258
- toggleShowGroup();
7259
- return;
7260
- }
7261
- if (isShowGroup && checkedAll) {
7262
- const ids = rowsGroup?.map((item) => item?.id) || [];
7263
- const filteredIds = selectedRowKeys.filter(
7264
- (id) => !ids.includes(id)
7265
- );
7266
- appDispatch((0, import_interface_logic29.setSelectedRowKeys)(filteredIds));
7267
- } else if (!isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && checkedAll && !allIdsNull && isQueryFetched) {
7268
- const clonedKeys = [...selectedRowKeys];
7269
- appDispatch((0, import_interface_logic29.setSelectedRowKeys)([...clonedKeys, -1]));
7270
- setTimeout(() => appDispatch((0, import_interface_logic29.setSelectedRowKeys)(clonedKeys)), 500);
7271
- } else if (isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && !checkedAll && !allIdsNull) {
7272
- const filteredKeys = selectedRowKeys.filter((id) => id > -1);
7273
- appDispatch((0, import_interface_logic29.setSelectedRowKeys)(filteredKeys));
7274
- }
7275
- toggleShowGroup();
7276
- };
7277
- (0, import_react29.useEffect)(() => {
7278
- if (!isQueryFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
7279
- return;
7280
- }
7281
- const clonedKeys = [...selectedRowKeys];
7282
- (0, import_interface_logic29.setSelectedRowKeys)([...clonedKeys, -1]);
7283
- setTimeout(() => (0, import_interface_logic29.setSelectedRowKeys)(clonedKeys), 500);
7284
- }, [isQueryFetched]);
7285
- return {
7286
- handleExpandChildGroup,
7287
- colEmptyGroup,
7288
- leftPadding,
7289
- isShowGroup,
7290
- isQueryFetched,
7291
- nameGroupWithCount,
7292
- columns,
7293
- row,
7294
- isPlaceholderData,
7295
- columnsGroup,
7296
- indexRow,
7297
- rowsGroup,
7298
- model,
7299
- viewData,
7300
- renderField,
7301
- level,
7302
- specification,
7303
- context,
7304
- checkedAll,
7305
- isDisplayCheckbox,
7306
- isAutoSelect,
7307
- setIsAutoSelect,
7308
- selectedRowKeysRef,
7309
- initVal,
7310
- dataResponse,
7311
- pageGroup,
7312
- setPageGroup
7313
- };
7314
- };
7315
7317
  // Annotate the CommonJS export names for ESM import in node:
7316
7318
  0 && (module.exports = {
7317
7319
  API_APP_URL,