@fctc/widget-logic 3.7.0 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5671,35 +5671,45 @@ var many2manyTagsController = (props) => {
5671
5671
  options: optionsFields,
5672
5672
  widget,
5673
5673
  formValues,
5674
- placeholderNoOption,
5675
5674
  service,
5676
5675
  xNode,
5677
- context: fieldContext
5676
+ context: fieldContext,
5677
+ onChange,
5678
+ methods,
5679
+ name
5678
5680
  } = props;
5679
5681
  const isUser = relation === "res.users" || relation === "res.partner";
5680
5682
  const { env } = (0, provider_exports.useEnv)();
5681
5683
  const { action } = useAppProvider();
5682
5684
  const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
5685
+ const [options, setOptions] = (0, import_react18.useState)([]);
5686
+ const [inputValue, setInputValue] = (0, import_react18.useState)("");
5687
+ const [debouncedInputValue] = useDebounce(inputValue, 1e3);
5688
+ const [domainObject, setDomainObject] = (0, import_react18.useState)(null);
5689
+ const [isShowModalMany2Many, setIsShowModalMany2Many] = (0, import_react18.useState)(false);
5690
+ const addtionalFields = optionsFields ? (0, import_utils10.evalJSONContext)(optionsFields) : null;
5683
5691
  const contextObject = {
5684
5692
  ...(0, import_utils10.evalJSONContext)(action?.context) || {},
5685
5693
  ...fieldContext ?? {},
5686
5694
  ...env?.context
5687
5695
  };
5688
- const addtionalFields = optionsFields ? (0, import_utils10.evalJSONContext)(optionsFields) : null;
5689
- const domainObject = (0, import_react18.useMemo)(
5690
- () => (0, import_utils10.evalJSONDomain)(
5691
- domain,
5692
- JSON.parse(
5693
- JSON.stringify({
5694
- ...formValues,
5695
- ...contextObject,
5696
- context: contextObject,
5697
- parent: { ...formValues }
5698
- })
5699
- )
5700
- ),
5701
- [domain]
5696
+ const parsedFormValues = (0, import_react18.useMemo)(
5697
+ () => JSON.parse(
5698
+ JSON.stringify({
5699
+ ...formValues,
5700
+ ...contextObject,
5701
+ context: contextObject,
5702
+ parent: { ...formValues }
5703
+ })
5704
+ ) ?? {},
5705
+ [formValues, contextObject]
5702
5706
  );
5707
+ (0, import_react18.useEffect)(() => {
5708
+ const newDomain = (0, import_utils10.evalJSONDomain)(domain, parsedFormValues);
5709
+ setDomainObject(
5710
+ (prev) => JSON.stringify(prev) === JSON.stringify(newDomain) ? prev : newDomain
5711
+ );
5712
+ }, [domain, parsedFormValues]);
5703
5713
  const data = {
5704
5714
  model: relation ?? "",
5705
5715
  domain: domainObject,
@@ -5712,36 +5722,60 @@ var many2manyTagsController = (props) => {
5712
5722
  },
5713
5723
  context: env.context
5714
5724
  };
5715
- const { data: dataOfSelection } = useGetSelection3({
5725
+ const queryKey = [`data_${relation}`, domainObject];
5726
+ const {
5727
+ data: dataOfSelection,
5728
+ refetch,
5729
+ isFetching
5730
+ } = useGetSelection3({
5716
5731
  data,
5717
- queryKey: [
5718
- `data_${relation}`,
5719
- domainObject,
5720
- formValues?.id,
5721
- action?.id,
5722
- action?.res_model
5723
- ],
5732
+ queryKey,
5724
5733
  service,
5725
5734
  xNode,
5726
- enabled: true
5735
+ enabled: false
5727
5736
  });
5728
- const customNoOptionsMessage = () => placeholderNoOption;
5737
+ const selectOptions = (0, import_react18.useMemo)(() => {
5738
+ return dataOfSelection?.records?.map((val) => ({
5739
+ value: val.id,
5740
+ label: val.name ?? val.display_name,
5741
+ ...val
5742
+ })) || [];
5743
+ }, [dataOfSelection]);
5744
+ (0, import_react18.useEffect)(() => {
5745
+ setOptions(selectOptions);
5746
+ }, [selectOptions]);
5747
+ const fetchMoreOptions = (0, import_react18.useCallback)(() => {
5748
+ refetch();
5749
+ }, [refetch]);
5729
5750
  const transfer = (data2) => {
5730
5751
  return data2?.map((val) => ({
5731
5752
  id: val.value,
5732
5753
  display_name: val.label
5733
5754
  })) || [];
5734
5755
  };
5735
- const options = dataOfSelection?.records?.map((val) => ({
5736
- value: val.id,
5737
- label: val.name ?? val.display_name,
5738
- ...val
5739
- })) || [];
5756
+ const handleChooseRecord = (0, import_react18.useCallback)(
5757
+ (idRecord) => {
5758
+ const newOption = options.find(
5759
+ (option) => option.value === idRecord
5760
+ );
5761
+ setIsShowModalMany2Many(false);
5762
+ },
5763
+ [options, methods, name, onChange]
5764
+ );
5765
+ const handleClose = (0, import_react18.useCallback)(() => setIsShowModalMany2Many(false), []);
5740
5766
  return {
5741
5767
  options,
5742
- customNoOptionsMessage,
5743
5768
  transfer,
5744
- isUser
5769
+ isUser,
5770
+ isFetching,
5771
+ fetchMoreOptions,
5772
+ setInputValue,
5773
+ domainObject,
5774
+ setDomainObject,
5775
+ handleChooseRecord,
5776
+ handleClose,
5777
+ isShowModalMany2Many,
5778
+ setIsShowModalMany2Many
5745
5779
  };
5746
5780
  };
5747
5781
 
package/dist/index.mjs CHANGED
@@ -5742,7 +5742,7 @@ var many2manyFieldController = (props) => {
5742
5742
  };
5743
5743
 
5744
5744
  // src/widget/basic/many2many-tags-field/controller.ts
5745
- import { useMemo as useMemo9 } from "react";
5745
+ import { useCallback as useCallback5, useEffect as useEffect12, useMemo as useMemo9, useState as useState8 } from "react";
5746
5746
  import { WIDGETAVATAR, WIDGETCOLOR } from "@fctc/interface-logic/constants";
5747
5747
  import { evalJSONContext as evalJSONContext5, evalJSONDomain as evalJSONDomain4 } from "@fctc/interface-logic/utils";
5748
5748
  var many2manyTagsController = (props) => {
@@ -5752,35 +5752,45 @@ var many2manyTagsController = (props) => {
5752
5752
  options: optionsFields,
5753
5753
  widget,
5754
5754
  formValues,
5755
- placeholderNoOption,
5756
5755
  service,
5757
5756
  xNode,
5758
- context: fieldContext
5757
+ context: fieldContext,
5758
+ onChange,
5759
+ methods,
5760
+ name
5759
5761
  } = props;
5760
5762
  const isUser = relation === "res.users" || relation === "res.partner";
5761
5763
  const { env } = (0, provider_exports.useEnv)();
5762
5764
  const { action } = useAppProvider();
5763
5765
  const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
5766
+ const [options, setOptions] = useState8([]);
5767
+ const [inputValue, setInputValue] = useState8("");
5768
+ const [debouncedInputValue] = useDebounce(inputValue, 1e3);
5769
+ const [domainObject, setDomainObject] = useState8(null);
5770
+ const [isShowModalMany2Many, setIsShowModalMany2Many] = useState8(false);
5771
+ const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
5764
5772
  const contextObject = {
5765
5773
  ...evalJSONContext5(action?.context) || {},
5766
5774
  ...fieldContext ?? {},
5767
5775
  ...env?.context
5768
5776
  };
5769
- const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
5770
- const domainObject = useMemo9(
5771
- () => evalJSONDomain4(
5772
- domain,
5773
- JSON.parse(
5774
- JSON.stringify({
5775
- ...formValues,
5776
- ...contextObject,
5777
- context: contextObject,
5778
- parent: { ...formValues }
5779
- })
5780
- )
5781
- ),
5782
- [domain]
5777
+ const parsedFormValues = useMemo9(
5778
+ () => JSON.parse(
5779
+ JSON.stringify({
5780
+ ...formValues,
5781
+ ...contextObject,
5782
+ context: contextObject,
5783
+ parent: { ...formValues }
5784
+ })
5785
+ ) ?? {},
5786
+ [formValues, contextObject]
5783
5787
  );
5788
+ useEffect12(() => {
5789
+ const newDomain = evalJSONDomain4(domain, parsedFormValues);
5790
+ setDomainObject(
5791
+ (prev) => JSON.stringify(prev) === JSON.stringify(newDomain) ? prev : newDomain
5792
+ );
5793
+ }, [domain, parsedFormValues]);
5784
5794
  const data = {
5785
5795
  model: relation ?? "",
5786
5796
  domain: domainObject,
@@ -5793,41 +5803,65 @@ var many2manyTagsController = (props) => {
5793
5803
  },
5794
5804
  context: env.context
5795
5805
  };
5796
- const { data: dataOfSelection } = useGetSelection3({
5806
+ const queryKey = [`data_${relation}`, domainObject];
5807
+ const {
5808
+ data: dataOfSelection,
5809
+ refetch,
5810
+ isFetching
5811
+ } = useGetSelection3({
5797
5812
  data,
5798
- queryKey: [
5799
- `data_${relation}`,
5800
- domainObject,
5801
- formValues?.id,
5802
- action?.id,
5803
- action?.res_model
5804
- ],
5813
+ queryKey,
5805
5814
  service,
5806
5815
  xNode,
5807
- enabled: true
5816
+ enabled: false
5808
5817
  });
5809
- const customNoOptionsMessage = () => placeholderNoOption;
5818
+ const selectOptions = useMemo9(() => {
5819
+ return dataOfSelection?.records?.map((val) => ({
5820
+ value: val.id,
5821
+ label: val.name ?? val.display_name,
5822
+ ...val
5823
+ })) || [];
5824
+ }, [dataOfSelection]);
5825
+ useEffect12(() => {
5826
+ setOptions(selectOptions);
5827
+ }, [selectOptions]);
5828
+ const fetchMoreOptions = useCallback5(() => {
5829
+ refetch();
5830
+ }, [refetch]);
5810
5831
  const transfer = (data2) => {
5811
5832
  return data2?.map((val) => ({
5812
5833
  id: val.value,
5813
5834
  display_name: val.label
5814
5835
  })) || [];
5815
5836
  };
5816
- const options = dataOfSelection?.records?.map((val) => ({
5817
- value: val.id,
5818
- label: val.name ?? val.display_name,
5819
- ...val
5820
- })) || [];
5837
+ const handleChooseRecord = useCallback5(
5838
+ (idRecord) => {
5839
+ const newOption = options.find(
5840
+ (option) => option.value === idRecord
5841
+ );
5842
+ setIsShowModalMany2Many(false);
5843
+ },
5844
+ [options, methods, name, onChange]
5845
+ );
5846
+ const handleClose = useCallback5(() => setIsShowModalMany2Many(false), []);
5821
5847
  return {
5822
5848
  options,
5823
- customNoOptionsMessage,
5824
5849
  transfer,
5825
- isUser
5850
+ isUser,
5851
+ isFetching,
5852
+ fetchMoreOptions,
5853
+ setInputValue,
5854
+ domainObject,
5855
+ setDomainObject,
5856
+ handleChooseRecord,
5857
+ handleClose,
5858
+ isShowModalMany2Many,
5859
+ setIsShowModalMany2Many
5826
5860
  };
5827
5861
  };
5828
5862
 
5829
5863
  // src/widget/basic/status-bar-field/controller.ts
5830
- import { useState as useState8 } from "react";
5864
+ import { useState as useState9 } from "react";
5831
5865
  import { evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
5832
5866
  var durationController = (props) => {
5833
5867
  const { relation, domain, formValues, name, id, model, onRefetch, enabled } = props;
@@ -5838,8 +5872,8 @@ var durationController = (props) => {
5838
5872
  };
5839
5873
  const { useGetListData: useGetListData2, useChangeStatus: useChangeStatus2 } = (0, provider_exports.useService)();
5840
5874
  const { env } = (0, provider_exports.useEnv)();
5841
- const [disabled, setDisabled] = useState8(false);
5842
- const [modelStatus, setModalStatus] = useState8(false);
5875
+ const [disabled, setDisabled] = useState9(false);
5876
+ const [modelStatus, setModalStatus] = useState9(false);
5843
5877
  const queryKey = [`data-status-duration`, specification];
5844
5878
  const listDataProps = {
5845
5879
  model: relation,
@@ -5929,10 +5963,10 @@ var priorityFieldController = (props) => {
5929
5963
  };
5930
5964
 
5931
5965
  // src/widget/basic/download-file-field/controller.ts
5932
- import { useId, useState as useState9 } from "react";
5966
+ import { useId, useState as useState10 } from "react";
5933
5967
  var downloadFileController = () => {
5934
5968
  const inputId = useId();
5935
- const [file, setFile] = useState9(null);
5969
+ const [file, setFile] = useState10(null);
5936
5970
  const handleFileChange = (e) => {
5937
5971
  setFile(e.target.files[0]);
5938
5972
  };
@@ -6864,11 +6898,11 @@ var dateFieldController = (props) => {
6864
6898
  };
6865
6899
 
6866
6900
  // src/widget/basic/copy-link-button/controller.ts
6867
- import { useState as useState10 } from "react";
6901
+ import { useState as useState11 } from "react";
6868
6902
  import { copyTextToClipboard } from "@fctc/interface-logic/utils";
6869
6903
  var copyLinkButtonController = (props) => {
6870
6904
  const { value, defaultValue } = props;
6871
- const [isCopied, setIsCopied] = useState10(false);
6905
+ const [isCopied, setIsCopied] = useState11(false);
6872
6906
  const handleCopyToClipboard = async (value2) => {
6873
6907
  await copyTextToClipboard(value2);
6874
6908
  setIsCopied(true);
@@ -6916,14 +6950,14 @@ var colorFieldController = (props) => {
6916
6950
  };
6917
6951
 
6918
6952
  // src/widget/basic/binary-field/controller.ts
6919
- import { useEffect as useEffect12, useId as useId2, useRef as useRef4, useState as useState11 } from "react";
6953
+ import { useEffect as useEffect13, useId as useId2, useRef as useRef4, useState as useState12 } from "react";
6920
6954
  import { isBase64Image } from "@fctc/interface-logic/utils";
6921
6955
  var binaryFieldController = (props) => {
6922
6956
  const { name, methods, readonly = false, value } = props;
6923
6957
  const inputId = useId2();
6924
- const [selectedImage, setSelectedImage] = useState11(null);
6925
- const [initialImage, setInitialImage] = useState11(value || null);
6926
- const [isInsideTable, setIsInsideTable] = useState11(false);
6958
+ const [selectedImage, setSelectedImage] = useState12(null);
6959
+ const [initialImage, setInitialImage] = useState12(value || null);
6960
+ const [isInsideTable, setIsInsideTable] = useState12(false);
6927
6961
  const { setValue } = methods;
6928
6962
  const binaryRef = useRef4(null);
6929
6963
  const convertUrlToBase64 = async (url) => {
@@ -6987,14 +7021,14 @@ var binaryFieldController = (props) => {
6987
7021
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
6988
7022
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
6989
7023
  };
6990
- useEffect12(() => {
7024
+ useEffect13(() => {
6991
7025
  return () => {
6992
7026
  if (selectedImage) {
6993
7027
  URL.revokeObjectURL(selectedImage);
6994
7028
  }
6995
7029
  };
6996
7030
  }, [selectedImage]);
6997
- useEffect12(() => {
7031
+ useEffect13(() => {
6998
7032
  if (binaryRef.current) {
6999
7033
  const isInsideTable2 = !!binaryRef.current.closest("table");
7000
7034
  setIsInsideTable(isInsideTable2);
@@ -7080,11 +7114,11 @@ var tableHeadController = (props) => {
7080
7114
  };
7081
7115
 
7082
7116
  // src/widget/advance/table/table-view/controller.ts
7083
- import { useCallback as useCallback5, useEffect as useEffect13, useMemo as useMemo11, useState as useState12 } from "react";
7117
+ import { useCallback as useCallback6, useEffect as useEffect14, useMemo as useMemo11, useState as useState13 } from "react";
7084
7118
  import { domainHelper } from "@fctc/interface-logic/utils";
7085
7119
  var tableController = ({ data }) => {
7086
- const [rows, setRows] = useState12([]);
7087
- const [columnVisibility, setColumnVisibility] = useState12({});
7120
+ const [rows, setRows] = useState13([]);
7121
+ const [columnVisibility, setColumnVisibility] = useState13({});
7088
7122
  const dataModelFields = useMemo11(() => {
7089
7123
  return data?.fields?.map((field) => ({
7090
7124
  ...data.dataModel?.[field?.name],
@@ -7096,7 +7130,7 @@ var tableController = ({ data }) => {
7096
7130
  () => mergeButtons(dataModelFields),
7097
7131
  [dataModelFields]
7098
7132
  );
7099
- const transformData = useCallback5(
7133
+ const transformData = useCallback6(
7100
7134
  (dataList) => {
7101
7135
  if (!dataList) return [];
7102
7136
  return dataList.map((item) => {
@@ -7118,7 +7152,7 @@ var tableController = ({ data }) => {
7118
7152
  },
7119
7153
  [data?.typeTable]
7120
7154
  );
7121
- useEffect13(() => {
7155
+ useEffect14(() => {
7122
7156
  setRows(transformData(data?.records));
7123
7157
  }, [data?.records, transformData]);
7124
7158
  const columns = useMemo11(() => {
@@ -7142,7 +7176,7 @@ var tableController = ({ data }) => {
7142
7176
  return [];
7143
7177
  }
7144
7178
  }, [mergeFields, data?.context, columnVisibility]);
7145
- const onToggleColumnOptional = useCallback5((item) => {
7179
+ const onToggleColumnOptional = useCallback6((item) => {
7146
7180
  setColumnVisibility((prev) => ({
7147
7181
  ...prev,
7148
7182
  [item?.name]: item?.optional === "show" ? "hide" : "show"
@@ -7157,7 +7191,7 @@ var tableController = ({ data }) => {
7157
7191
  };
7158
7192
 
7159
7193
  // src/widget/advance/table/table-group/controller.ts
7160
- import { useEffect as useEffect14, useMemo as useMemo12, useState as useState13 } from "react";
7194
+ import { useEffect as useEffect15, useMemo as useMemo12, useState as useState14 } from "react";
7161
7195
  import { useAppSelector as useAppSelector2, selectList } from "@fctc/interface-logic/store";
7162
7196
  var tableGroupController = (props) => {
7163
7197
  const { env } = (0, provider_exports.useEnv)();
@@ -7174,10 +7208,10 @@ var tableGroupController = (props) => {
7174
7208
  groupByList,
7175
7209
  setSelectedRowKeys
7176
7210
  } = props;
7177
- const [pageGroup, setPageGroup] = useState13(0);
7211
+ const [pageGroup, setPageGroup] = useState14(0);
7178
7212
  const { selectedRowKeys } = useAppSelector2(selectList);
7179
- const [isShowGroup, setIsShowGroup] = useState13(false);
7180
- const [colEmptyGroup, setColEmptyGroup] = useState13({
7213
+ const [isShowGroup, setIsShowGroup] = useState14(false);
7214
+ const [colEmptyGroup, setColEmptyGroup] = useState14({
7181
7215
  fromStart: 1,
7182
7216
  fromEnd: 1
7183
7217
  });
@@ -7266,7 +7300,7 @@ var tableGroupController = (props) => {
7266
7300
  }
7267
7301
  toggleShowGroup();
7268
7302
  };
7269
- useEffect14(() => {
7303
+ useEffect15(() => {
7270
7304
  if (!isDataGroupFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
7271
7305
  return;
7272
7306
  }
@@ -7299,7 +7333,7 @@ import {
7299
7333
  evalJSONDomain as evalJSONDomain6,
7300
7334
  validateAndParseDate
7301
7335
  } from "@fctc/interface-logic/utils";
7302
- import { useCallback as useCallback6, useEffect as useEffect15, useState as useState14 } from "react";
7336
+ import { useCallback as useCallback7, useEffect as useEffect16, useState as useState15 } from "react";
7303
7337
  var searchController = ({
7304
7338
  viewData,
7305
7339
  model,
@@ -7308,12 +7342,12 @@ var searchController = ({
7308
7342
  fieldsList
7309
7343
  }) => {
7310
7344
  const { env } = (0, provider_exports.useEnv)();
7311
- const [filterBy, setFilterBy] = useState14(null);
7312
- const [searchBy, setSearchBy] = useState14(null);
7313
- const [groupBy, setGroupBy] = useState14(null);
7314
- const [selectedTags, setSelectedTags] = useState14(null);
7315
- const [searchString, setSearchString] = useState14("");
7316
- const [searchMap, setSearchMap] = useState14({});
7345
+ const [filterBy, setFilterBy] = useState15(null);
7346
+ const [searchBy, setSearchBy] = useState15(null);
7347
+ const [groupBy, setGroupBy] = useState15(null);
7348
+ const [selectedTags, setSelectedTags] = useState15(null);
7349
+ const [searchString, setSearchString] = useState15("");
7350
+ const [searchMap, setSearchMap] = useState15({});
7317
7351
  const actionContext = typeof context === "string" ? evalJSONContext8(context) : context;
7318
7352
  const contextSearch = { ...env.context, ...actionContext };
7319
7353
  const domainAction = domain ? Array.isArray(domain) ? [...domain] : evalJSONDomain6(domain, contextSearch) : [];
@@ -7360,7 +7394,7 @@ var searchController = ({
7360
7394
  }
7361
7395
  }
7362
7396
  };
7363
- useEffect15(() => {
7397
+ useEffect16(() => {
7364
7398
  fetchData();
7365
7399
  }, [model, viewData]);
7366
7400
  const onChangeSearchInput = (search_string) => {
@@ -7442,7 +7476,7 @@ var searchController = ({
7442
7476
  return [...domain2];
7443
7477
  }
7444
7478
  };
7445
- const setTagSearch = useCallback6(
7479
+ const setTagSearch = useCallback7(
7446
7480
  (updatedMap) => {
7447
7481
  if (!updatedMap) return;
7448
7482
  const tagsSearch = Object.entries(updatedMap).map(
@@ -7505,7 +7539,7 @@ var searchController = ({
7505
7539
  },
7506
7540
  [searchMap]
7507
7541
  );
7508
- useEffect15(() => {
7542
+ useEffect16(() => {
7509
7543
  setTagSearch(searchMap);
7510
7544
  }, [searchMap]);
7511
7545
  const handleAddTagSearch = (tag) => {
package/dist/widget.d.mts CHANGED
@@ -119,10 +119,18 @@ interface IMany2ManyTagFieldProps extends IInputFieldProps {
119
119
  }
120
120
 
121
121
  declare const many2manyTagsController: (props: IMany2ManyTagFieldProps) => {
122
- options: any;
123
- customNoOptionsMessage: () => string;
122
+ options: any[];
124
123
  transfer: (data: any) => any;
125
124
  isUser: boolean;
125
+ isFetching: boolean;
126
+ fetchMoreOptions: () => void;
127
+ setInputValue: react.Dispatch<react.SetStateAction<string>>;
128
+ domainObject: any;
129
+ setDomainObject: react.Dispatch<any>;
130
+ handleChooseRecord: (idRecord: number) => void;
131
+ handleClose: () => void;
132
+ isShowModalMany2Many: boolean;
133
+ setIsShowModalMany2Many: react.Dispatch<react.SetStateAction<boolean>>;
126
134
  };
127
135
 
128
136
  interface IDurationFieldProps extends IInputFieldProps {
package/dist/widget.d.ts CHANGED
@@ -119,10 +119,18 @@ interface IMany2ManyTagFieldProps extends IInputFieldProps {
119
119
  }
120
120
 
121
121
  declare const many2manyTagsController: (props: IMany2ManyTagFieldProps) => {
122
- options: any;
123
- customNoOptionsMessage: () => string;
122
+ options: any[];
124
123
  transfer: (data: any) => any;
125
124
  isUser: boolean;
125
+ isFetching: boolean;
126
+ fetchMoreOptions: () => void;
127
+ setInputValue: react.Dispatch<react.SetStateAction<string>>;
128
+ domainObject: any;
129
+ setDomainObject: react.Dispatch<any>;
130
+ handleChooseRecord: (idRecord: number) => void;
131
+ handleClose: () => void;
132
+ isShowModalMany2Many: boolean;
133
+ setIsShowModalMany2Many: react.Dispatch<react.SetStateAction<boolean>>;
126
134
  };
127
135
 
128
136
  interface IDurationFieldProps extends IInputFieldProps {
package/dist/widget.js CHANGED
@@ -4906,35 +4906,45 @@ var many2manyTagsController = (props) => {
4906
4906
  options: optionsFields,
4907
4907
  widget,
4908
4908
  formValues,
4909
- placeholderNoOption,
4910
4909
  service,
4911
4910
  xNode,
4912
- context: fieldContext
4911
+ context: fieldContext,
4912
+ onChange,
4913
+ methods,
4914
+ name
4913
4915
  } = props;
4914
4916
  const isUser = relation === "res.users" || relation === "res.partner";
4915
4917
  const { env } = (0, provider_exports.useEnv)();
4916
4918
  const { action } = useAppProvider();
4917
4919
  const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
4920
+ const [options, setOptions] = (0, import_react18.useState)([]);
4921
+ const [inputValue, setInputValue] = (0, import_react18.useState)("");
4922
+ const [debouncedInputValue] = useDebounce(inputValue, 1e3);
4923
+ const [domainObject, setDomainObject] = (0, import_react18.useState)(null);
4924
+ const [isShowModalMany2Many, setIsShowModalMany2Many] = (0, import_react18.useState)(false);
4925
+ const addtionalFields = optionsFields ? (0, import_utils10.evalJSONContext)(optionsFields) : null;
4918
4926
  const contextObject = {
4919
4927
  ...(0, import_utils10.evalJSONContext)(action?.context) || {},
4920
4928
  ...fieldContext ?? {},
4921
4929
  ...env?.context
4922
4930
  };
4923
- const addtionalFields = optionsFields ? (0, import_utils10.evalJSONContext)(optionsFields) : null;
4924
- const domainObject = (0, import_react18.useMemo)(
4925
- () => (0, import_utils10.evalJSONDomain)(
4926
- domain,
4927
- JSON.parse(
4928
- JSON.stringify({
4929
- ...formValues,
4930
- ...contextObject,
4931
- context: contextObject,
4932
- parent: { ...formValues }
4933
- })
4934
- )
4935
- ),
4936
- [domain]
4931
+ const parsedFormValues = (0, import_react18.useMemo)(
4932
+ () => JSON.parse(
4933
+ JSON.stringify({
4934
+ ...formValues,
4935
+ ...contextObject,
4936
+ context: contextObject,
4937
+ parent: { ...formValues }
4938
+ })
4939
+ ) ?? {},
4940
+ [formValues, contextObject]
4937
4941
  );
4942
+ (0, import_react18.useEffect)(() => {
4943
+ const newDomain = (0, import_utils10.evalJSONDomain)(domain, parsedFormValues);
4944
+ setDomainObject(
4945
+ (prev) => JSON.stringify(prev) === JSON.stringify(newDomain) ? prev : newDomain
4946
+ );
4947
+ }, [domain, parsedFormValues]);
4938
4948
  const data = {
4939
4949
  model: relation ?? "",
4940
4950
  domain: domainObject,
@@ -4947,36 +4957,60 @@ var many2manyTagsController = (props) => {
4947
4957
  },
4948
4958
  context: env.context
4949
4959
  };
4950
- const { data: dataOfSelection } = useGetSelection3({
4960
+ const queryKey = [`data_${relation}`, domainObject];
4961
+ const {
4962
+ data: dataOfSelection,
4963
+ refetch,
4964
+ isFetching
4965
+ } = useGetSelection3({
4951
4966
  data,
4952
- queryKey: [
4953
- `data_${relation}`,
4954
- domainObject,
4955
- formValues?.id,
4956
- action?.id,
4957
- action?.res_model
4958
- ],
4967
+ queryKey,
4959
4968
  service,
4960
4969
  xNode,
4961
- enabled: true
4970
+ enabled: false
4962
4971
  });
4963
- const customNoOptionsMessage = () => placeholderNoOption;
4972
+ const selectOptions = (0, import_react18.useMemo)(() => {
4973
+ return dataOfSelection?.records?.map((val) => ({
4974
+ value: val.id,
4975
+ label: val.name ?? val.display_name,
4976
+ ...val
4977
+ })) || [];
4978
+ }, [dataOfSelection]);
4979
+ (0, import_react18.useEffect)(() => {
4980
+ setOptions(selectOptions);
4981
+ }, [selectOptions]);
4982
+ const fetchMoreOptions = (0, import_react18.useCallback)(() => {
4983
+ refetch();
4984
+ }, [refetch]);
4964
4985
  const transfer = (data2) => {
4965
4986
  return data2?.map((val) => ({
4966
4987
  id: val.value,
4967
4988
  display_name: val.label
4968
4989
  })) || [];
4969
4990
  };
4970
- const options = dataOfSelection?.records?.map((val) => ({
4971
- value: val.id,
4972
- label: val.name ?? val.display_name,
4973
- ...val
4974
- })) || [];
4991
+ const handleChooseRecord = (0, import_react18.useCallback)(
4992
+ (idRecord) => {
4993
+ const newOption = options.find(
4994
+ (option) => option.value === idRecord
4995
+ );
4996
+ setIsShowModalMany2Many(false);
4997
+ },
4998
+ [options, methods, name, onChange]
4999
+ );
5000
+ const handleClose = (0, import_react18.useCallback)(() => setIsShowModalMany2Many(false), []);
4975
5001
  return {
4976
5002
  options,
4977
- customNoOptionsMessage,
4978
5003
  transfer,
4979
- isUser
5004
+ isUser,
5005
+ isFetching,
5006
+ fetchMoreOptions,
5007
+ setInputValue,
5008
+ domainObject,
5009
+ setDomainObject,
5010
+ handleChooseRecord,
5011
+ handleClose,
5012
+ isShowModalMany2Many,
5013
+ setIsShowModalMany2Many
4980
5014
  };
4981
5015
  };
4982
5016
 
package/dist/widget.mjs CHANGED
@@ -4954,7 +4954,7 @@ var many2manyFieldController = (props) => {
4954
4954
  };
4955
4955
 
4956
4956
  // src/widget/basic/many2many-tags-field/controller.ts
4957
- import { useMemo as useMemo9 } from "react";
4957
+ import { useCallback as useCallback5, useEffect as useEffect12, useMemo as useMemo9, useState as useState8 } from "react";
4958
4958
  import { WIDGETAVATAR, WIDGETCOLOR } from "@fctc/interface-logic/constants";
4959
4959
  import { evalJSONContext as evalJSONContext5, evalJSONDomain as evalJSONDomain4 } from "@fctc/interface-logic/utils";
4960
4960
  var many2manyTagsController = (props) => {
@@ -4964,35 +4964,45 @@ var many2manyTagsController = (props) => {
4964
4964
  options: optionsFields,
4965
4965
  widget,
4966
4966
  formValues,
4967
- placeholderNoOption,
4968
4967
  service,
4969
4968
  xNode,
4970
- context: fieldContext
4969
+ context: fieldContext,
4970
+ onChange,
4971
+ methods,
4972
+ name
4971
4973
  } = props;
4972
4974
  const isUser = relation === "res.users" || relation === "res.partner";
4973
4975
  const { env } = (0, provider_exports.useEnv)();
4974
4976
  const { action } = useAppProvider();
4975
4977
  const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
4978
+ const [options, setOptions] = useState8([]);
4979
+ const [inputValue, setInputValue] = useState8("");
4980
+ const [debouncedInputValue] = useDebounce(inputValue, 1e3);
4981
+ const [domainObject, setDomainObject] = useState8(null);
4982
+ const [isShowModalMany2Many, setIsShowModalMany2Many] = useState8(false);
4983
+ const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
4976
4984
  const contextObject = {
4977
4985
  ...evalJSONContext5(action?.context) || {},
4978
4986
  ...fieldContext ?? {},
4979
4987
  ...env?.context
4980
4988
  };
4981
- const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
4982
- const domainObject = useMemo9(
4983
- () => evalJSONDomain4(
4984
- domain,
4985
- JSON.parse(
4986
- JSON.stringify({
4987
- ...formValues,
4988
- ...contextObject,
4989
- context: contextObject,
4990
- parent: { ...formValues }
4991
- })
4992
- )
4993
- ),
4994
- [domain]
4989
+ const parsedFormValues = useMemo9(
4990
+ () => JSON.parse(
4991
+ JSON.stringify({
4992
+ ...formValues,
4993
+ ...contextObject,
4994
+ context: contextObject,
4995
+ parent: { ...formValues }
4996
+ })
4997
+ ) ?? {},
4998
+ [formValues, contextObject]
4995
4999
  );
5000
+ useEffect12(() => {
5001
+ const newDomain = evalJSONDomain4(domain, parsedFormValues);
5002
+ setDomainObject(
5003
+ (prev) => JSON.stringify(prev) === JSON.stringify(newDomain) ? prev : newDomain
5004
+ );
5005
+ }, [domain, parsedFormValues]);
4996
5006
  const data = {
4997
5007
  model: relation ?? "",
4998
5008
  domain: domainObject,
@@ -5005,41 +5015,65 @@ var many2manyTagsController = (props) => {
5005
5015
  },
5006
5016
  context: env.context
5007
5017
  };
5008
- const { data: dataOfSelection } = useGetSelection3({
5018
+ const queryKey = [`data_${relation}`, domainObject];
5019
+ const {
5020
+ data: dataOfSelection,
5021
+ refetch,
5022
+ isFetching
5023
+ } = useGetSelection3({
5009
5024
  data,
5010
- queryKey: [
5011
- `data_${relation}`,
5012
- domainObject,
5013
- formValues?.id,
5014
- action?.id,
5015
- action?.res_model
5016
- ],
5025
+ queryKey,
5017
5026
  service,
5018
5027
  xNode,
5019
- enabled: true
5028
+ enabled: false
5020
5029
  });
5021
- const customNoOptionsMessage = () => placeholderNoOption;
5030
+ const selectOptions = useMemo9(() => {
5031
+ return dataOfSelection?.records?.map((val) => ({
5032
+ value: val.id,
5033
+ label: val.name ?? val.display_name,
5034
+ ...val
5035
+ })) || [];
5036
+ }, [dataOfSelection]);
5037
+ useEffect12(() => {
5038
+ setOptions(selectOptions);
5039
+ }, [selectOptions]);
5040
+ const fetchMoreOptions = useCallback5(() => {
5041
+ refetch();
5042
+ }, [refetch]);
5022
5043
  const transfer = (data2) => {
5023
5044
  return data2?.map((val) => ({
5024
5045
  id: val.value,
5025
5046
  display_name: val.label
5026
5047
  })) || [];
5027
5048
  };
5028
- const options = dataOfSelection?.records?.map((val) => ({
5029
- value: val.id,
5030
- label: val.name ?? val.display_name,
5031
- ...val
5032
- })) || [];
5049
+ const handleChooseRecord = useCallback5(
5050
+ (idRecord) => {
5051
+ const newOption = options.find(
5052
+ (option) => option.value === idRecord
5053
+ );
5054
+ setIsShowModalMany2Many(false);
5055
+ },
5056
+ [options, methods, name, onChange]
5057
+ );
5058
+ const handleClose = useCallback5(() => setIsShowModalMany2Many(false), []);
5033
5059
  return {
5034
5060
  options,
5035
- customNoOptionsMessage,
5036
5061
  transfer,
5037
- isUser
5062
+ isUser,
5063
+ isFetching,
5064
+ fetchMoreOptions,
5065
+ setInputValue,
5066
+ domainObject,
5067
+ setDomainObject,
5068
+ handleChooseRecord,
5069
+ handleClose,
5070
+ isShowModalMany2Many,
5071
+ setIsShowModalMany2Many
5038
5072
  };
5039
5073
  };
5040
5074
 
5041
5075
  // src/widget/basic/status-bar-field/controller.ts
5042
- import { useState as useState8 } from "react";
5076
+ import { useState as useState9 } from "react";
5043
5077
  import { evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
5044
5078
  var durationController = (props) => {
5045
5079
  const { relation, domain, formValues, name, id, model, onRefetch, enabled } = props;
@@ -5050,8 +5084,8 @@ var durationController = (props) => {
5050
5084
  };
5051
5085
  const { useGetListData: useGetListData2, useChangeStatus: useChangeStatus2 } = (0, provider_exports.useService)();
5052
5086
  const { env } = (0, provider_exports.useEnv)();
5053
- const [disabled, setDisabled] = useState8(false);
5054
- const [modelStatus, setModalStatus] = useState8(false);
5087
+ const [disabled, setDisabled] = useState9(false);
5088
+ const [modelStatus, setModalStatus] = useState9(false);
5055
5089
  const queryKey = [`data-status-duration`, specification];
5056
5090
  const listDataProps = {
5057
5091
  model: relation,
@@ -5141,10 +5175,10 @@ var priorityFieldController = (props) => {
5141
5175
  };
5142
5176
 
5143
5177
  // src/widget/basic/download-file-field/controller.ts
5144
- import { useId, useState as useState9 } from "react";
5178
+ import { useId, useState as useState10 } from "react";
5145
5179
  var downloadFileController = () => {
5146
5180
  const inputId = useId();
5147
- const [file, setFile] = useState9(null);
5181
+ const [file, setFile] = useState10(null);
5148
5182
  const handleFileChange = (e) => {
5149
5183
  setFile(e.target.files[0]);
5150
5184
  };
@@ -6076,11 +6110,11 @@ var dateFieldController = (props) => {
6076
6110
  };
6077
6111
 
6078
6112
  // src/widget/basic/copy-link-button/controller.ts
6079
- import { useState as useState10 } from "react";
6113
+ import { useState as useState11 } from "react";
6080
6114
  import { copyTextToClipboard } from "@fctc/interface-logic/utils";
6081
6115
  var copyLinkButtonController = (props) => {
6082
6116
  const { value, defaultValue } = props;
6083
- const [isCopied, setIsCopied] = useState10(false);
6117
+ const [isCopied, setIsCopied] = useState11(false);
6084
6118
  const handleCopyToClipboard = async (value2) => {
6085
6119
  await copyTextToClipboard(value2);
6086
6120
  setIsCopied(true);
@@ -6128,14 +6162,14 @@ var colorFieldController = (props) => {
6128
6162
  };
6129
6163
 
6130
6164
  // src/widget/basic/binary-field/controller.ts
6131
- import { useEffect as useEffect12, useId as useId2, useRef as useRef4, useState as useState11 } from "react";
6165
+ import { useEffect as useEffect13, useId as useId2, useRef as useRef4, useState as useState12 } from "react";
6132
6166
  import { isBase64Image } from "@fctc/interface-logic/utils";
6133
6167
  var binaryFieldController = (props) => {
6134
6168
  const { name, methods, readonly = false, value } = props;
6135
6169
  const inputId = useId2();
6136
- const [selectedImage, setSelectedImage] = useState11(null);
6137
- const [initialImage, setInitialImage] = useState11(value || null);
6138
- const [isInsideTable, setIsInsideTable] = useState11(false);
6170
+ const [selectedImage, setSelectedImage] = useState12(null);
6171
+ const [initialImage, setInitialImage] = useState12(value || null);
6172
+ const [isInsideTable, setIsInsideTable] = useState12(false);
6139
6173
  const { setValue } = methods;
6140
6174
  const binaryRef = useRef4(null);
6141
6175
  const convertUrlToBase64 = async (url) => {
@@ -6199,14 +6233,14 @@ var binaryFieldController = (props) => {
6199
6233
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
6200
6234
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
6201
6235
  };
6202
- useEffect12(() => {
6236
+ useEffect13(() => {
6203
6237
  return () => {
6204
6238
  if (selectedImage) {
6205
6239
  URL.revokeObjectURL(selectedImage);
6206
6240
  }
6207
6241
  };
6208
6242
  }, [selectedImage]);
6209
- useEffect12(() => {
6243
+ useEffect13(() => {
6210
6244
  if (binaryRef.current) {
6211
6245
  const isInsideTable2 = !!binaryRef.current.closest("table");
6212
6246
  setIsInsideTable(isInsideTable2);
@@ -6292,11 +6326,11 @@ var tableHeadController = (props) => {
6292
6326
  };
6293
6327
 
6294
6328
  // src/widget/advance/table/table-view/controller.ts
6295
- import { useCallback as useCallback5, useEffect as useEffect13, useMemo as useMemo11, useState as useState12 } from "react";
6329
+ import { useCallback as useCallback6, useEffect as useEffect14, useMemo as useMemo11, useState as useState13 } from "react";
6296
6330
  import { domainHelper } from "@fctc/interface-logic/utils";
6297
6331
  var tableController = ({ data }) => {
6298
- const [rows, setRows] = useState12([]);
6299
- const [columnVisibility, setColumnVisibility] = useState12({});
6332
+ const [rows, setRows] = useState13([]);
6333
+ const [columnVisibility, setColumnVisibility] = useState13({});
6300
6334
  const dataModelFields = useMemo11(() => {
6301
6335
  return data?.fields?.map((field) => ({
6302
6336
  ...data.dataModel?.[field?.name],
@@ -6308,7 +6342,7 @@ var tableController = ({ data }) => {
6308
6342
  () => mergeButtons(dataModelFields),
6309
6343
  [dataModelFields]
6310
6344
  );
6311
- const transformData = useCallback5(
6345
+ const transformData = useCallback6(
6312
6346
  (dataList) => {
6313
6347
  if (!dataList) return [];
6314
6348
  return dataList.map((item) => {
@@ -6330,7 +6364,7 @@ var tableController = ({ data }) => {
6330
6364
  },
6331
6365
  [data?.typeTable]
6332
6366
  );
6333
- useEffect13(() => {
6367
+ useEffect14(() => {
6334
6368
  setRows(transformData(data?.records));
6335
6369
  }, [data?.records, transformData]);
6336
6370
  const columns = useMemo11(() => {
@@ -6354,7 +6388,7 @@ var tableController = ({ data }) => {
6354
6388
  return [];
6355
6389
  }
6356
6390
  }, [mergeFields, data?.context, columnVisibility]);
6357
- const onToggleColumnOptional = useCallback5((item) => {
6391
+ const onToggleColumnOptional = useCallback6((item) => {
6358
6392
  setColumnVisibility((prev) => ({
6359
6393
  ...prev,
6360
6394
  [item?.name]: item?.optional === "show" ? "hide" : "show"
@@ -6369,7 +6403,7 @@ var tableController = ({ data }) => {
6369
6403
  };
6370
6404
 
6371
6405
  // src/widget/advance/table/table-group/controller.ts
6372
- import { useEffect as useEffect14, useMemo as useMemo12, useState as useState13 } from "react";
6406
+ import { useEffect as useEffect15, useMemo as useMemo12, useState as useState14 } from "react";
6373
6407
  import { useAppSelector as useAppSelector2, selectList } from "@fctc/interface-logic/store";
6374
6408
  var tableGroupController = (props) => {
6375
6409
  const { env } = (0, provider_exports.useEnv)();
@@ -6386,10 +6420,10 @@ var tableGroupController = (props) => {
6386
6420
  groupByList,
6387
6421
  setSelectedRowKeys
6388
6422
  } = props;
6389
- const [pageGroup, setPageGroup] = useState13(0);
6423
+ const [pageGroup, setPageGroup] = useState14(0);
6390
6424
  const { selectedRowKeys } = useAppSelector2(selectList);
6391
- const [isShowGroup, setIsShowGroup] = useState13(false);
6392
- const [colEmptyGroup, setColEmptyGroup] = useState13({
6425
+ const [isShowGroup, setIsShowGroup] = useState14(false);
6426
+ const [colEmptyGroup, setColEmptyGroup] = useState14({
6393
6427
  fromStart: 1,
6394
6428
  fromEnd: 1
6395
6429
  });
@@ -6478,7 +6512,7 @@ var tableGroupController = (props) => {
6478
6512
  }
6479
6513
  toggleShowGroup();
6480
6514
  };
6481
- useEffect14(() => {
6515
+ useEffect15(() => {
6482
6516
  if (!isDataGroupFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
6483
6517
  return;
6484
6518
  }
@@ -6511,7 +6545,7 @@ import {
6511
6545
  evalJSONDomain as evalJSONDomain6,
6512
6546
  validateAndParseDate
6513
6547
  } from "@fctc/interface-logic/utils";
6514
- import { useCallback as useCallback6, useEffect as useEffect15, useState as useState14 } from "react";
6548
+ import { useCallback as useCallback7, useEffect as useEffect16, useState as useState15 } from "react";
6515
6549
  var searchController = ({
6516
6550
  viewData,
6517
6551
  model,
@@ -6520,12 +6554,12 @@ var searchController = ({
6520
6554
  fieldsList
6521
6555
  }) => {
6522
6556
  const { env } = (0, provider_exports.useEnv)();
6523
- const [filterBy, setFilterBy] = useState14(null);
6524
- const [searchBy, setSearchBy] = useState14(null);
6525
- const [groupBy, setGroupBy] = useState14(null);
6526
- const [selectedTags, setSelectedTags] = useState14(null);
6527
- const [searchString, setSearchString] = useState14("");
6528
- const [searchMap, setSearchMap] = useState14({});
6557
+ const [filterBy, setFilterBy] = useState15(null);
6558
+ const [searchBy, setSearchBy] = useState15(null);
6559
+ const [groupBy, setGroupBy] = useState15(null);
6560
+ const [selectedTags, setSelectedTags] = useState15(null);
6561
+ const [searchString, setSearchString] = useState15("");
6562
+ const [searchMap, setSearchMap] = useState15({});
6529
6563
  const actionContext = typeof context === "string" ? evalJSONContext8(context) : context;
6530
6564
  const contextSearch = { ...env.context, ...actionContext };
6531
6565
  const domainAction = domain ? Array.isArray(domain) ? [...domain] : evalJSONDomain6(domain, contextSearch) : [];
@@ -6572,7 +6606,7 @@ var searchController = ({
6572
6606
  }
6573
6607
  }
6574
6608
  };
6575
- useEffect15(() => {
6609
+ useEffect16(() => {
6576
6610
  fetchData();
6577
6611
  }, [model, viewData]);
6578
6612
  const onChangeSearchInput = (search_string) => {
@@ -6654,7 +6688,7 @@ var searchController = ({
6654
6688
  return [...domain2];
6655
6689
  }
6656
6690
  };
6657
- const setTagSearch = useCallback6(
6691
+ const setTagSearch = useCallback7(
6658
6692
  (updatedMap) => {
6659
6693
  if (!updatedMap) return;
6660
6694
  const tagsSearch = Object.entries(updatedMap).map(
@@ -6717,7 +6751,7 @@ var searchController = ({
6717
6751
  },
6718
6752
  [searchMap]
6719
6753
  );
6720
- useEffect15(() => {
6754
+ useEffect16(() => {
6721
6755
  setTagSearch(searchMap);
6722
6756
  }, [searchMap]);
6723
6757
  const handleAddTagSearch = (tag) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fctc/widget-logic",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "types": "dist/index.d.ts",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",