@fctc/widget-logic 3.6.9 → 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,
@@ -5710,32 +5720,62 @@ var many2manyTagsController = (props) => {
5710
5720
  ...widget && import_constants2.WIDGETAVATAR[widget] ? { image_256: {} } : {},
5711
5721
  ...widget && import_constants2.WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
5712
5722
  },
5713
- enabled: true,
5714
5723
  context: env.context
5715
5724
  };
5716
- const { data: dataOfSelection } = useGetSelection3({
5725
+ const queryKey = [`data_${relation}`, domainObject];
5726
+ const {
5727
+ data: dataOfSelection,
5728
+ refetch,
5729
+ isFetching
5730
+ } = useGetSelection3({
5717
5731
  data,
5718
- queryKey: [`data_${relation}`],
5732
+ queryKey,
5719
5733
  service,
5720
- xNode
5734
+ xNode,
5735
+ enabled: false
5721
5736
  });
5722
- 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]);
5723
5750
  const transfer = (data2) => {
5724
5751
  return data2?.map((val) => ({
5725
5752
  id: val.value,
5726
5753
  display_name: val.label
5727
5754
  })) || [];
5728
5755
  };
5729
- const options = dataOfSelection?.records?.map((val) => ({
5730
- value: val.id,
5731
- label: val.name ?? val.display_name,
5732
- ...val
5733
- })) || [];
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), []);
5734
5766
  return {
5735
5767
  options,
5736
- customNoOptionsMessage,
5737
5768
  transfer,
5738
- isUser
5769
+ isUser,
5770
+ isFetching,
5771
+ fetchMoreOptions,
5772
+ setInputValue,
5773
+ domainObject,
5774
+ setDomainObject,
5775
+ handleChooseRecord,
5776
+ handleClose,
5777
+ isShowModalMany2Many,
5778
+ setIsShowModalMany2Many
5739
5779
  };
5740
5780
  };
5741
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,
@@ -5791,37 +5801,67 @@ var many2manyTagsController = (props) => {
5791
5801
  ...widget && WIDGETAVATAR[widget] ? { image_256: {} } : {},
5792
5802
  ...widget && WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
5793
5803
  },
5794
- enabled: true,
5795
5804
  context: env.context
5796
5805
  };
5797
- const { data: dataOfSelection } = useGetSelection3({
5806
+ const queryKey = [`data_${relation}`, domainObject];
5807
+ const {
5808
+ data: dataOfSelection,
5809
+ refetch,
5810
+ isFetching
5811
+ } = useGetSelection3({
5798
5812
  data,
5799
- queryKey: [`data_${relation}`],
5813
+ queryKey,
5800
5814
  service,
5801
- xNode
5815
+ xNode,
5816
+ enabled: false
5802
5817
  });
5803
- 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]);
5804
5831
  const transfer = (data2) => {
5805
5832
  return data2?.map((val) => ({
5806
5833
  id: val.value,
5807
5834
  display_name: val.label
5808
5835
  })) || [];
5809
5836
  };
5810
- const options = dataOfSelection?.records?.map((val) => ({
5811
- value: val.id,
5812
- label: val.name ?? val.display_name,
5813
- ...val
5814
- })) || [];
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), []);
5815
5847
  return {
5816
5848
  options,
5817
- customNoOptionsMessage,
5818
5849
  transfer,
5819
- isUser
5850
+ isUser,
5851
+ isFetching,
5852
+ fetchMoreOptions,
5853
+ setInputValue,
5854
+ domainObject,
5855
+ setDomainObject,
5856
+ handleChooseRecord,
5857
+ handleClose,
5858
+ isShowModalMany2Many,
5859
+ setIsShowModalMany2Many
5820
5860
  };
5821
5861
  };
5822
5862
 
5823
5863
  // src/widget/basic/status-bar-field/controller.ts
5824
- import { useState as useState8 } from "react";
5864
+ import { useState as useState9 } from "react";
5825
5865
  import { evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
5826
5866
  var durationController = (props) => {
5827
5867
  const { relation, domain, formValues, name, id, model, onRefetch, enabled } = props;
@@ -5832,8 +5872,8 @@ var durationController = (props) => {
5832
5872
  };
5833
5873
  const { useGetListData: useGetListData2, useChangeStatus: useChangeStatus2 } = (0, provider_exports.useService)();
5834
5874
  const { env } = (0, provider_exports.useEnv)();
5835
- const [disabled, setDisabled] = useState8(false);
5836
- const [modelStatus, setModalStatus] = useState8(false);
5875
+ const [disabled, setDisabled] = useState9(false);
5876
+ const [modelStatus, setModalStatus] = useState9(false);
5837
5877
  const queryKey = [`data-status-duration`, specification];
5838
5878
  const listDataProps = {
5839
5879
  model: relation,
@@ -5923,10 +5963,10 @@ var priorityFieldController = (props) => {
5923
5963
  };
5924
5964
 
5925
5965
  // src/widget/basic/download-file-field/controller.ts
5926
- import { useId, useState as useState9 } from "react";
5966
+ import { useId, useState as useState10 } from "react";
5927
5967
  var downloadFileController = () => {
5928
5968
  const inputId = useId();
5929
- const [file, setFile] = useState9(null);
5969
+ const [file, setFile] = useState10(null);
5930
5970
  const handleFileChange = (e) => {
5931
5971
  setFile(e.target.files[0]);
5932
5972
  };
@@ -6858,11 +6898,11 @@ var dateFieldController = (props) => {
6858
6898
  };
6859
6899
 
6860
6900
  // src/widget/basic/copy-link-button/controller.ts
6861
- import { useState as useState10 } from "react";
6901
+ import { useState as useState11 } from "react";
6862
6902
  import { copyTextToClipboard } from "@fctc/interface-logic/utils";
6863
6903
  var copyLinkButtonController = (props) => {
6864
6904
  const { value, defaultValue } = props;
6865
- const [isCopied, setIsCopied] = useState10(false);
6905
+ const [isCopied, setIsCopied] = useState11(false);
6866
6906
  const handleCopyToClipboard = async (value2) => {
6867
6907
  await copyTextToClipboard(value2);
6868
6908
  setIsCopied(true);
@@ -6910,14 +6950,14 @@ var colorFieldController = (props) => {
6910
6950
  };
6911
6951
 
6912
6952
  // src/widget/basic/binary-field/controller.ts
6913
- 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";
6914
6954
  import { isBase64Image } from "@fctc/interface-logic/utils";
6915
6955
  var binaryFieldController = (props) => {
6916
6956
  const { name, methods, readonly = false, value } = props;
6917
6957
  const inputId = useId2();
6918
- const [selectedImage, setSelectedImage] = useState11(null);
6919
- const [initialImage, setInitialImage] = useState11(value || null);
6920
- const [isInsideTable, setIsInsideTable] = useState11(false);
6958
+ const [selectedImage, setSelectedImage] = useState12(null);
6959
+ const [initialImage, setInitialImage] = useState12(value || null);
6960
+ const [isInsideTable, setIsInsideTable] = useState12(false);
6921
6961
  const { setValue } = methods;
6922
6962
  const binaryRef = useRef4(null);
6923
6963
  const convertUrlToBase64 = async (url) => {
@@ -6981,14 +7021,14 @@ var binaryFieldController = (props) => {
6981
7021
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
6982
7022
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
6983
7023
  };
6984
- useEffect12(() => {
7024
+ useEffect13(() => {
6985
7025
  return () => {
6986
7026
  if (selectedImage) {
6987
7027
  URL.revokeObjectURL(selectedImage);
6988
7028
  }
6989
7029
  };
6990
7030
  }, [selectedImage]);
6991
- useEffect12(() => {
7031
+ useEffect13(() => {
6992
7032
  if (binaryRef.current) {
6993
7033
  const isInsideTable2 = !!binaryRef.current.closest("table");
6994
7034
  setIsInsideTable(isInsideTable2);
@@ -7074,11 +7114,11 @@ var tableHeadController = (props) => {
7074
7114
  };
7075
7115
 
7076
7116
  // src/widget/advance/table/table-view/controller.ts
7077
- 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";
7078
7118
  import { domainHelper } from "@fctc/interface-logic/utils";
7079
7119
  var tableController = ({ data }) => {
7080
- const [rows, setRows] = useState12([]);
7081
- const [columnVisibility, setColumnVisibility] = useState12({});
7120
+ const [rows, setRows] = useState13([]);
7121
+ const [columnVisibility, setColumnVisibility] = useState13({});
7082
7122
  const dataModelFields = useMemo11(() => {
7083
7123
  return data?.fields?.map((field) => ({
7084
7124
  ...data.dataModel?.[field?.name],
@@ -7090,7 +7130,7 @@ var tableController = ({ data }) => {
7090
7130
  () => mergeButtons(dataModelFields),
7091
7131
  [dataModelFields]
7092
7132
  );
7093
- const transformData = useCallback5(
7133
+ const transformData = useCallback6(
7094
7134
  (dataList) => {
7095
7135
  if (!dataList) return [];
7096
7136
  return dataList.map((item) => {
@@ -7112,7 +7152,7 @@ var tableController = ({ data }) => {
7112
7152
  },
7113
7153
  [data?.typeTable]
7114
7154
  );
7115
- useEffect13(() => {
7155
+ useEffect14(() => {
7116
7156
  setRows(transformData(data?.records));
7117
7157
  }, [data?.records, transformData]);
7118
7158
  const columns = useMemo11(() => {
@@ -7136,7 +7176,7 @@ var tableController = ({ data }) => {
7136
7176
  return [];
7137
7177
  }
7138
7178
  }, [mergeFields, data?.context, columnVisibility]);
7139
- const onToggleColumnOptional = useCallback5((item) => {
7179
+ const onToggleColumnOptional = useCallback6((item) => {
7140
7180
  setColumnVisibility((prev) => ({
7141
7181
  ...prev,
7142
7182
  [item?.name]: item?.optional === "show" ? "hide" : "show"
@@ -7151,7 +7191,7 @@ var tableController = ({ data }) => {
7151
7191
  };
7152
7192
 
7153
7193
  // src/widget/advance/table/table-group/controller.ts
7154
- 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";
7155
7195
  import { useAppSelector as useAppSelector2, selectList } from "@fctc/interface-logic/store";
7156
7196
  var tableGroupController = (props) => {
7157
7197
  const { env } = (0, provider_exports.useEnv)();
@@ -7168,10 +7208,10 @@ var tableGroupController = (props) => {
7168
7208
  groupByList,
7169
7209
  setSelectedRowKeys
7170
7210
  } = props;
7171
- const [pageGroup, setPageGroup] = useState13(0);
7211
+ const [pageGroup, setPageGroup] = useState14(0);
7172
7212
  const { selectedRowKeys } = useAppSelector2(selectList);
7173
- const [isShowGroup, setIsShowGroup] = useState13(false);
7174
- const [colEmptyGroup, setColEmptyGroup] = useState13({
7213
+ const [isShowGroup, setIsShowGroup] = useState14(false);
7214
+ const [colEmptyGroup, setColEmptyGroup] = useState14({
7175
7215
  fromStart: 1,
7176
7216
  fromEnd: 1
7177
7217
  });
@@ -7260,7 +7300,7 @@ var tableGroupController = (props) => {
7260
7300
  }
7261
7301
  toggleShowGroup();
7262
7302
  };
7263
- useEffect14(() => {
7303
+ useEffect15(() => {
7264
7304
  if (!isDataGroupFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
7265
7305
  return;
7266
7306
  }
@@ -7293,7 +7333,7 @@ import {
7293
7333
  evalJSONDomain as evalJSONDomain6,
7294
7334
  validateAndParseDate
7295
7335
  } from "@fctc/interface-logic/utils";
7296
- 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";
7297
7337
  var searchController = ({
7298
7338
  viewData,
7299
7339
  model,
@@ -7302,12 +7342,12 @@ var searchController = ({
7302
7342
  fieldsList
7303
7343
  }) => {
7304
7344
  const { env } = (0, provider_exports.useEnv)();
7305
- const [filterBy, setFilterBy] = useState14(null);
7306
- const [searchBy, setSearchBy] = useState14(null);
7307
- const [groupBy, setGroupBy] = useState14(null);
7308
- const [selectedTags, setSelectedTags] = useState14(null);
7309
- const [searchString, setSearchString] = useState14("");
7310
- 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({});
7311
7351
  const actionContext = typeof context === "string" ? evalJSONContext8(context) : context;
7312
7352
  const contextSearch = { ...env.context, ...actionContext };
7313
7353
  const domainAction = domain ? Array.isArray(domain) ? [...domain] : evalJSONDomain6(domain, contextSearch) : [];
@@ -7354,7 +7394,7 @@ var searchController = ({
7354
7394
  }
7355
7395
  }
7356
7396
  };
7357
- useEffect15(() => {
7397
+ useEffect16(() => {
7358
7398
  fetchData();
7359
7399
  }, [model, viewData]);
7360
7400
  const onChangeSearchInput = (search_string) => {
@@ -7436,7 +7476,7 @@ var searchController = ({
7436
7476
  return [...domain2];
7437
7477
  }
7438
7478
  };
7439
- const setTagSearch = useCallback6(
7479
+ const setTagSearch = useCallback7(
7440
7480
  (updatedMap) => {
7441
7481
  if (!updatedMap) return;
7442
7482
  const tagsSearch = Object.entries(updatedMap).map(
@@ -7499,7 +7539,7 @@ var searchController = ({
7499
7539
  },
7500
7540
  [searchMap]
7501
7541
  );
7502
- useEffect15(() => {
7542
+ useEffect16(() => {
7503
7543
  setTagSearch(searchMap);
7504
7544
  }, [searchMap]);
7505
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,
@@ -4945,32 +4955,62 @@ var many2manyTagsController = (props) => {
4945
4955
  ...widget && import_constants2.WIDGETAVATAR[widget] ? { image_256: {} } : {},
4946
4956
  ...widget && import_constants2.WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
4947
4957
  },
4948
- enabled: true,
4949
4958
  context: env.context
4950
4959
  };
4951
- const { data: dataOfSelection } = useGetSelection3({
4960
+ const queryKey = [`data_${relation}`, domainObject];
4961
+ const {
4962
+ data: dataOfSelection,
4963
+ refetch,
4964
+ isFetching
4965
+ } = useGetSelection3({
4952
4966
  data,
4953
- queryKey: [`data_${relation}`],
4967
+ queryKey,
4954
4968
  service,
4955
- xNode
4969
+ xNode,
4970
+ enabled: false
4956
4971
  });
4957
- 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]);
4958
4985
  const transfer = (data2) => {
4959
4986
  return data2?.map((val) => ({
4960
4987
  id: val.value,
4961
4988
  display_name: val.label
4962
4989
  })) || [];
4963
4990
  };
4964
- const options = dataOfSelection?.records?.map((val) => ({
4965
- value: val.id,
4966
- label: val.name ?? val.display_name,
4967
- ...val
4968
- })) || [];
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), []);
4969
5001
  return {
4970
5002
  options,
4971
- customNoOptionsMessage,
4972
5003
  transfer,
4973
- isUser
5004
+ isUser,
5005
+ isFetching,
5006
+ fetchMoreOptions,
5007
+ setInputValue,
5008
+ domainObject,
5009
+ setDomainObject,
5010
+ handleChooseRecord,
5011
+ handleClose,
5012
+ isShowModalMany2Many,
5013
+ setIsShowModalMany2Many
4974
5014
  };
4975
5015
  };
4976
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,
@@ -5003,37 +5013,67 @@ var many2manyTagsController = (props) => {
5003
5013
  ...widget && WIDGETAVATAR[widget] ? { image_256: {} } : {},
5004
5014
  ...widget && WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
5005
5015
  },
5006
- enabled: true,
5007
5016
  context: env.context
5008
5017
  };
5009
- const { data: dataOfSelection } = useGetSelection3({
5018
+ const queryKey = [`data_${relation}`, domainObject];
5019
+ const {
5020
+ data: dataOfSelection,
5021
+ refetch,
5022
+ isFetching
5023
+ } = useGetSelection3({
5010
5024
  data,
5011
- queryKey: [`data_${relation}`],
5025
+ queryKey,
5012
5026
  service,
5013
- xNode
5027
+ xNode,
5028
+ enabled: false
5014
5029
  });
5015
- 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]);
5016
5043
  const transfer = (data2) => {
5017
5044
  return data2?.map((val) => ({
5018
5045
  id: val.value,
5019
5046
  display_name: val.label
5020
5047
  })) || [];
5021
5048
  };
5022
- const options = dataOfSelection?.records?.map((val) => ({
5023
- value: val.id,
5024
- label: val.name ?? val.display_name,
5025
- ...val
5026
- })) || [];
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), []);
5027
5059
  return {
5028
5060
  options,
5029
- customNoOptionsMessage,
5030
5061
  transfer,
5031
- isUser
5062
+ isUser,
5063
+ isFetching,
5064
+ fetchMoreOptions,
5065
+ setInputValue,
5066
+ domainObject,
5067
+ setDomainObject,
5068
+ handleChooseRecord,
5069
+ handleClose,
5070
+ isShowModalMany2Many,
5071
+ setIsShowModalMany2Many
5032
5072
  };
5033
5073
  };
5034
5074
 
5035
5075
  // src/widget/basic/status-bar-field/controller.ts
5036
- import { useState as useState8 } from "react";
5076
+ import { useState as useState9 } from "react";
5037
5077
  import { evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
5038
5078
  var durationController = (props) => {
5039
5079
  const { relation, domain, formValues, name, id, model, onRefetch, enabled } = props;
@@ -5044,8 +5084,8 @@ var durationController = (props) => {
5044
5084
  };
5045
5085
  const { useGetListData: useGetListData2, useChangeStatus: useChangeStatus2 } = (0, provider_exports.useService)();
5046
5086
  const { env } = (0, provider_exports.useEnv)();
5047
- const [disabled, setDisabled] = useState8(false);
5048
- const [modelStatus, setModalStatus] = useState8(false);
5087
+ const [disabled, setDisabled] = useState9(false);
5088
+ const [modelStatus, setModalStatus] = useState9(false);
5049
5089
  const queryKey = [`data-status-duration`, specification];
5050
5090
  const listDataProps = {
5051
5091
  model: relation,
@@ -5135,10 +5175,10 @@ var priorityFieldController = (props) => {
5135
5175
  };
5136
5176
 
5137
5177
  // src/widget/basic/download-file-field/controller.ts
5138
- import { useId, useState as useState9 } from "react";
5178
+ import { useId, useState as useState10 } from "react";
5139
5179
  var downloadFileController = () => {
5140
5180
  const inputId = useId();
5141
- const [file, setFile] = useState9(null);
5181
+ const [file, setFile] = useState10(null);
5142
5182
  const handleFileChange = (e) => {
5143
5183
  setFile(e.target.files[0]);
5144
5184
  };
@@ -6070,11 +6110,11 @@ var dateFieldController = (props) => {
6070
6110
  };
6071
6111
 
6072
6112
  // src/widget/basic/copy-link-button/controller.ts
6073
- import { useState as useState10 } from "react";
6113
+ import { useState as useState11 } from "react";
6074
6114
  import { copyTextToClipboard } from "@fctc/interface-logic/utils";
6075
6115
  var copyLinkButtonController = (props) => {
6076
6116
  const { value, defaultValue } = props;
6077
- const [isCopied, setIsCopied] = useState10(false);
6117
+ const [isCopied, setIsCopied] = useState11(false);
6078
6118
  const handleCopyToClipboard = async (value2) => {
6079
6119
  await copyTextToClipboard(value2);
6080
6120
  setIsCopied(true);
@@ -6122,14 +6162,14 @@ var colorFieldController = (props) => {
6122
6162
  };
6123
6163
 
6124
6164
  // src/widget/basic/binary-field/controller.ts
6125
- 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";
6126
6166
  import { isBase64Image } from "@fctc/interface-logic/utils";
6127
6167
  var binaryFieldController = (props) => {
6128
6168
  const { name, methods, readonly = false, value } = props;
6129
6169
  const inputId = useId2();
6130
- const [selectedImage, setSelectedImage] = useState11(null);
6131
- const [initialImage, setInitialImage] = useState11(value || null);
6132
- const [isInsideTable, setIsInsideTable] = useState11(false);
6170
+ const [selectedImage, setSelectedImage] = useState12(null);
6171
+ const [initialImage, setInitialImage] = useState12(value || null);
6172
+ const [isInsideTable, setIsInsideTable] = useState12(false);
6133
6173
  const { setValue } = methods;
6134
6174
  const binaryRef = useRef4(null);
6135
6175
  const convertUrlToBase64 = async (url) => {
@@ -6193,14 +6233,14 @@ var binaryFieldController = (props) => {
6193
6233
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
6194
6234
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
6195
6235
  };
6196
- useEffect12(() => {
6236
+ useEffect13(() => {
6197
6237
  return () => {
6198
6238
  if (selectedImage) {
6199
6239
  URL.revokeObjectURL(selectedImage);
6200
6240
  }
6201
6241
  };
6202
6242
  }, [selectedImage]);
6203
- useEffect12(() => {
6243
+ useEffect13(() => {
6204
6244
  if (binaryRef.current) {
6205
6245
  const isInsideTable2 = !!binaryRef.current.closest("table");
6206
6246
  setIsInsideTable(isInsideTable2);
@@ -6286,11 +6326,11 @@ var tableHeadController = (props) => {
6286
6326
  };
6287
6327
 
6288
6328
  // src/widget/advance/table/table-view/controller.ts
6289
- 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";
6290
6330
  import { domainHelper } from "@fctc/interface-logic/utils";
6291
6331
  var tableController = ({ data }) => {
6292
- const [rows, setRows] = useState12([]);
6293
- const [columnVisibility, setColumnVisibility] = useState12({});
6332
+ const [rows, setRows] = useState13([]);
6333
+ const [columnVisibility, setColumnVisibility] = useState13({});
6294
6334
  const dataModelFields = useMemo11(() => {
6295
6335
  return data?.fields?.map((field) => ({
6296
6336
  ...data.dataModel?.[field?.name],
@@ -6302,7 +6342,7 @@ var tableController = ({ data }) => {
6302
6342
  () => mergeButtons(dataModelFields),
6303
6343
  [dataModelFields]
6304
6344
  );
6305
- const transformData = useCallback5(
6345
+ const transformData = useCallback6(
6306
6346
  (dataList) => {
6307
6347
  if (!dataList) return [];
6308
6348
  return dataList.map((item) => {
@@ -6324,7 +6364,7 @@ var tableController = ({ data }) => {
6324
6364
  },
6325
6365
  [data?.typeTable]
6326
6366
  );
6327
- useEffect13(() => {
6367
+ useEffect14(() => {
6328
6368
  setRows(transformData(data?.records));
6329
6369
  }, [data?.records, transformData]);
6330
6370
  const columns = useMemo11(() => {
@@ -6348,7 +6388,7 @@ var tableController = ({ data }) => {
6348
6388
  return [];
6349
6389
  }
6350
6390
  }, [mergeFields, data?.context, columnVisibility]);
6351
- const onToggleColumnOptional = useCallback5((item) => {
6391
+ const onToggleColumnOptional = useCallback6((item) => {
6352
6392
  setColumnVisibility((prev) => ({
6353
6393
  ...prev,
6354
6394
  [item?.name]: item?.optional === "show" ? "hide" : "show"
@@ -6363,7 +6403,7 @@ var tableController = ({ data }) => {
6363
6403
  };
6364
6404
 
6365
6405
  // src/widget/advance/table/table-group/controller.ts
6366
- 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";
6367
6407
  import { useAppSelector as useAppSelector2, selectList } from "@fctc/interface-logic/store";
6368
6408
  var tableGroupController = (props) => {
6369
6409
  const { env } = (0, provider_exports.useEnv)();
@@ -6380,10 +6420,10 @@ var tableGroupController = (props) => {
6380
6420
  groupByList,
6381
6421
  setSelectedRowKeys
6382
6422
  } = props;
6383
- const [pageGroup, setPageGroup] = useState13(0);
6423
+ const [pageGroup, setPageGroup] = useState14(0);
6384
6424
  const { selectedRowKeys } = useAppSelector2(selectList);
6385
- const [isShowGroup, setIsShowGroup] = useState13(false);
6386
- const [colEmptyGroup, setColEmptyGroup] = useState13({
6425
+ const [isShowGroup, setIsShowGroup] = useState14(false);
6426
+ const [colEmptyGroup, setColEmptyGroup] = useState14({
6387
6427
  fromStart: 1,
6388
6428
  fromEnd: 1
6389
6429
  });
@@ -6472,7 +6512,7 @@ var tableGroupController = (props) => {
6472
6512
  }
6473
6513
  toggleShowGroup();
6474
6514
  };
6475
- useEffect14(() => {
6515
+ useEffect15(() => {
6476
6516
  if (!isDataGroupFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
6477
6517
  return;
6478
6518
  }
@@ -6505,7 +6545,7 @@ import {
6505
6545
  evalJSONDomain as evalJSONDomain6,
6506
6546
  validateAndParseDate
6507
6547
  } from "@fctc/interface-logic/utils";
6508
- 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";
6509
6549
  var searchController = ({
6510
6550
  viewData,
6511
6551
  model,
@@ -6514,12 +6554,12 @@ var searchController = ({
6514
6554
  fieldsList
6515
6555
  }) => {
6516
6556
  const { env } = (0, provider_exports.useEnv)();
6517
- const [filterBy, setFilterBy] = useState14(null);
6518
- const [searchBy, setSearchBy] = useState14(null);
6519
- const [groupBy, setGroupBy] = useState14(null);
6520
- const [selectedTags, setSelectedTags] = useState14(null);
6521
- const [searchString, setSearchString] = useState14("");
6522
- 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({});
6523
6563
  const actionContext = typeof context === "string" ? evalJSONContext8(context) : context;
6524
6564
  const contextSearch = { ...env.context, ...actionContext };
6525
6565
  const domainAction = domain ? Array.isArray(domain) ? [...domain] : evalJSONDomain6(domain, contextSearch) : [];
@@ -6566,7 +6606,7 @@ var searchController = ({
6566
6606
  }
6567
6607
  }
6568
6608
  };
6569
- useEffect15(() => {
6609
+ useEffect16(() => {
6570
6610
  fetchData();
6571
6611
  }, [model, viewData]);
6572
6612
  const onChangeSearchInput = (search_string) => {
@@ -6648,7 +6688,7 @@ var searchController = ({
6648
6688
  return [...domain2];
6649
6689
  }
6650
6690
  };
6651
- const setTagSearch = useCallback6(
6691
+ const setTagSearch = useCallback7(
6652
6692
  (updatedMap) => {
6653
6693
  if (!updatedMap) return;
6654
6694
  const tagsSearch = Object.entries(updatedMap).map(
@@ -6711,7 +6751,7 @@ var searchController = ({
6711
6751
  },
6712
6752
  [searchMap]
6713
6753
  );
6714
- useEffect15(() => {
6754
+ useEffect16(() => {
6715
6755
  setTagSearch(searchMap);
6716
6756
  }, [searchMap]);
6717
6757
  const handleAddTagSearch = (tag) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fctc/widget-logic",
3
- "version": "3.6.9",
3
+ "version": "3.7.1",
4
4
  "types": "dist/index.d.ts",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",