@fctc/widget-logic 1.9.2 → 1.9.4

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/widget.mjs CHANGED
@@ -4978,6 +4978,7 @@ var many2oneFieldController = (props) => {
4978
4978
  options: fieldOptions,
4979
4979
  showDetail
4980
4980
  } = props;
4981
+ const { env } = (0, provider_exports.useEnv)();
4981
4982
  const [options, setOptions] = useState7([]);
4982
4983
  const [inputValue, setInputValue] = useState7("");
4983
4984
  const [debouncedInputValue] = useDebounce(inputValue, 1e3);
@@ -4987,13 +4988,12 @@ var many2oneFieldController = (props) => {
4987
4988
  const [domainObject, setDomainObject] = useState7(null);
4988
4989
  const actionData = sessionStorageUtils.getActionData();
4989
4990
  const { menuList } = (0, store_exports.useAppSelector)(store_exports.selectNavbar);
4990
- const { context } = (0, store_exports.useAppSelector)(store_exports.selectEnv);
4991
4991
  const initValue = methods?.getValues(name);
4992
4992
  const optionsObject = (0, utils_exports.evalJSONContext)(fieldOptions) || {};
4993
4993
  const contextObject = {
4994
4994
  ...(0, utils_exports.evalJSONContext)(actionData?.context) || {},
4995
4995
  ...fieldContext,
4996
- ...context
4996
+ ...env?.context
4997
4997
  };
4998
4998
  const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
4999
4999
  const data = {
@@ -5165,15 +5165,9 @@ var many2oneButtonController = (props) => {
5165
5165
 
5166
5166
  // src/widget/basic/many2many-field/controller.ts
5167
5167
  import { useEffect as useEffect11, useMemo as useMemo10, useState as useState8 } from "react";
5168
- import {
5169
- useAppDispatch as useAppDispatch5,
5170
- setFirstDomain,
5171
- setViewDataStore,
5172
- setPage,
5173
- setGroupByDomain
5174
- } from "@fctc/interface-logic/store";
5175
5168
  import {
5176
5169
  evalJSONContext as evalJSONContext4,
5170
+ evalJSONDomain as evalJSONDomain4,
5177
5171
  formatSortingString as formatSortingString2
5178
5172
  } from "@fctc/interface-logic/utils";
5179
5173
  var many2manyFieldController = (props) => {
@@ -5181,45 +5175,41 @@ var many2manyFieldController = (props) => {
5181
5175
  relation,
5182
5176
  domain,
5183
5177
  context,
5178
+ options,
5184
5179
  tab,
5185
- model,
5186
- aid,
5187
5180
  setSelectedRowKeys: setSelectedRowKeys4,
5188
- fields,
5189
- setFields,
5190
5181
  groupByDomain,
5191
- page,
5192
- options,
5193
5182
  sessionStorageUtils
5194
5183
  } = props;
5195
- const appDispatch = useAppDispatch5();
5196
- const actionData = sessionStorageUtils.getActionData();
5197
- const [debouncedPage] = useDebounce(page, 500);
5198
- const [order, setOrder] = useState8();
5199
- const [isLoadedData, setIsLoadedData] = useState8(false);
5200
- const [domainMany2Many, setDomainMany2Many] = useState8(domain);
5201
5184
  const { env } = (0, provider_exports.useEnv)();
5202
5185
  const { useGetView: useGetView2, useGetListData: useGetListData3, useGetFormView } = (0, provider_exports.useService)();
5186
+ const [order, setOrder] = useState8();
5187
+ const [isLoadedData, setIsLoadedData] = useState8(false);
5188
+ const [page, setPage] = useState8(0);
5189
+ const [domainMany2Many, setDomainMany2Many] = useState8(null);
5190
+ const [debouncedPage] = useDebounce(page, 500);
5191
+ const actionData = sessionStorageUtils.getActionData();
5192
+ const contextObject = { ...env.context, ...context };
5203
5193
  const viewParams = {
5204
5194
  model: relation,
5205
5195
  views: [
5206
5196
  [false, "list"],
5207
5197
  [false, "search"]
5208
5198
  ],
5209
- context
5199
+ context: contextObject
5210
5200
  };
5211
5201
  const { data: viewResponse } = useGetView2(viewParams, actionData);
5212
5202
  const baseModel = useMemo10(
5213
5203
  () => ({
5214
5204
  name: String(relation),
5215
5205
  view: viewResponse || {},
5216
- actContext: context,
5206
+ actContext: contextObject,
5217
5207
  fields: [
5218
5208
  ...Object.values(viewResponse?.views?.list?.fields ?? {}),
5219
5209
  ...tab?.fields ? tab.fields : []
5220
5210
  ]
5221
5211
  }),
5222
- [model, viewResponse]
5212
+ [relation, viewResponse]
5223
5213
  );
5224
5214
  const initModel = (0, hooks_exports.useModel)();
5225
5215
  const modelInstance = useMemo10(() => {
@@ -5238,26 +5228,15 @@ var many2manyFieldController = (props) => {
5238
5228
  const optionsObject = tab?.options ? evalJSONContext4(tab?.options) : (options ? evalJSONContext4(options) : {}) || {};
5239
5229
  const fetchData = async () => {
5240
5230
  try {
5241
- setDomainMany2Many(domain);
5242
- appDispatch(setFirstDomain(domain));
5243
- appDispatch(setViewDataStore(viewResponse));
5244
- const modalData = viewResponse?.views?.list?.fields.map((field) => ({
5245
- ...viewResponse?.models?.[String(model)]?.[field?.name],
5246
- ...field
5247
- }));
5248
- if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
5249
- setFields({
5250
- ...fields,
5251
- [`${aid}_${relation}_popupmany2many`]: modalData
5252
- });
5253
- }
5254
- appDispatch(setPage(0));
5231
+ const domainParse = typeof domain === "string" ? evalJSONDomain4(domain, contextObject) : Array.isArray(domain) ? domain : [];
5232
+ setDomainMany2Many(domainParse);
5233
+ setPage(0);
5255
5234
  } catch (err) {
5256
5235
  console.log(err);
5257
5236
  }
5258
5237
  };
5259
5238
  const queryKey = [
5260
- `view-${relation}-${aid}`,
5239
+ `view-${relation}`,
5261
5240
  specification,
5262
5241
  domainMany2Many,
5263
5242
  debouncedPage,
@@ -5270,7 +5249,7 @@ var many2manyFieldController = (props) => {
5270
5249
  domain: domainMany2Many,
5271
5250
  offset: debouncedPage * 10,
5272
5251
  limit: 10,
5273
- context,
5252
+ context: contextObject,
5274
5253
  fields: groupByDomain?.fields,
5275
5254
  groupby: [groupByDomain?.contexts[0]?.group_by],
5276
5255
  sort: order ? order : default_order ? formatSortingString2(default_order) : ""
@@ -5278,8 +5257,8 @@ var many2manyFieldController = (props) => {
5278
5257
  const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
5279
5258
  const {
5280
5259
  data: dataResponse,
5281
- isLoading: isDataLoading,
5282
- isFetched: isDataResponseFetched,
5260
+ isLoading,
5261
+ isFetched,
5283
5262
  isPlaceholderData
5284
5263
  } = useGetListData3(data, queryKey, enabled);
5285
5264
  useEffect11(() => {
@@ -5287,12 +5266,7 @@ var many2manyFieldController = (props) => {
5287
5266
  fetchData();
5288
5267
  }
5289
5268
  return () => {
5290
- appDispatch(setGroupByDomain(null));
5291
- setFields((prevFields) => ({
5292
- ...prevFields,
5293
- [`${aid}_${relation}_popupmany2many`]: null
5294
- }));
5295
- appDispatch(setPage(0));
5269
+ setPage(0);
5296
5270
  setSelectedRowKeys4([]);
5297
5271
  setDomainMany2Many(null);
5298
5272
  setIsLoadedData(false);
@@ -5300,44 +5274,19 @@ var many2manyFieldController = (props) => {
5300
5274
  }, [viewResponse]);
5301
5275
  const { rows, columns, typeTable } = tableController({
5302
5276
  data: {
5303
- fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
5277
+ fields: viewResponse?.views?.list?.fields,
5304
5278
  records: dataResponse?.records ?? dataResponse?.groups,
5305
5279
  dataModel: viewResponse?.models?.[String(relation)],
5306
- context: { ...env.context, ...context },
5280
+ context: contextObject,
5307
5281
  typeTable: dataResponse?.groups ? "group" : "list"
5308
5282
  }
5309
5283
  });
5310
- const dataFormView = {
5311
- id: null,
5312
- model: relation,
5313
- context
5314
- };
5315
- const {
5316
- refetch,
5317
- data: dataFormViewResponse,
5318
- isSuccess
5319
- } = useGetFormView({
5320
- data: dataFormView,
5321
- queryKey: [`form-view-action-${relation}`],
5322
- enabled: false
5323
- });
5324
- useEffect11(() => {
5325
- if (isSuccess && dataFormViewResponse) {
5326
- sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
5327
- window.location.href = `/form/menu?model=${relation}`;
5328
- }
5329
- }, [isSuccess]);
5330
5284
  useEffect11(() => {
5331
5285
  if (domainMany2Many && !isLoadedData) {
5332
5286
  setIsLoadedData(true);
5333
5287
  }
5334
5288
  }, [domainMany2Many]);
5335
5289
  const handleCreateNewOnPage = async () => {
5336
- try {
5337
- refetch();
5338
- } catch (error) {
5339
- console.log(error);
5340
- }
5341
5290
  };
5342
5291
  return {
5343
5292
  handleCreateNewOnPage,
@@ -5345,9 +5294,13 @@ var many2manyFieldController = (props) => {
5345
5294
  rows,
5346
5295
  columns,
5347
5296
  typeTable,
5348
- isDataLoading,
5349
- isDataResponseFetched,
5350
- isPlaceholderData
5297
+ isLoading,
5298
+ isFetched,
5299
+ isPlaceholderData,
5300
+ setPage,
5301
+ page,
5302
+ domain: domainMany2Many,
5303
+ setDomain: setDomainMany2Many
5351
5304
  };
5352
5305
  };
5353
5306
 
@@ -5356,7 +5309,7 @@ import { useMemo as useMemo11 } from "react";
5356
5309
  import { WIDGETAVATAR, WIDGETCOLOR } from "@fctc/interface-logic/constants";
5357
5310
  import { getEnv as getEnv7 } from "@fctc/interface-logic/environment";
5358
5311
  import { useGetSelection as useGetSelection2 } from "@fctc/interface-logic/hooks";
5359
- import { evalJSONContext as evalJSONContext5, evalJSONDomain as evalJSONDomain4 } from "@fctc/interface-logic/utils";
5312
+ import { evalJSONContext as evalJSONContext5, evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
5360
5313
  var many2manyTagsController = (props) => {
5361
5314
  const {
5362
5315
  relation,
@@ -5370,7 +5323,7 @@ var many2manyTagsController = (props) => {
5370
5323
  const env = getEnv7();
5371
5324
  const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
5372
5325
  const domainObject = useMemo11(
5373
- () => evalJSONDomain4(domain, JSON.parse(JSON.stringify(formValues || {}))),
5326
+ () => evalJSONDomain5(domain, JSON.parse(JSON.stringify(formValues || {}))),
5374
5327
  [domain, formValues]
5375
5328
  );
5376
5329
  const data = {
@@ -5413,7 +5366,7 @@ var many2manyTagsController = (props) => {
5413
5366
 
5414
5367
  // src/widget/basic/status-bar-field/controller.ts
5415
5368
  import { useState as useState9 } from "react";
5416
- import { evalJSONDomain as evalJSONDomain5 } from "@fctc/interface-logic/utils";
5369
+ import { evalJSONDomain as evalJSONDomain6 } from "@fctc/interface-logic/utils";
5417
5370
  var durationController = (props) => {
5418
5371
  const { relation, domain, formValues, name, id, model, onRefetch } = props;
5419
5372
  const specification = {
@@ -5429,7 +5382,7 @@ var durationController = (props) => {
5429
5382
  const listDataProps = {
5430
5383
  model: relation,
5431
5384
  specification,
5432
- domain: evalJSONDomain5(domain, JSON.parse(JSON.stringify(formValues))),
5385
+ domain: evalJSONDomain6(domain, JSON.parse(JSON.stringify(formValues))),
5433
5386
  limit: 10,
5434
5387
  offset: 0,
5435
5388
  fields: "",
@@ -5529,98 +5482,63 @@ var priorityFieldController = (props) => {
5529
5482
  };
5530
5483
  };
5531
5484
 
5532
- // src/widget/basic/float-time-field/controller.ts
5533
- import { useState as useState10 } from "react";
5534
- import {
5535
- convertFloatToTime,
5536
- convertTimeToFloat
5537
- } from "@fctc/interface-logic/utils";
5538
- var floatTimeFiledController = ({
5539
- onChange: fieldOnChange,
5540
- onBlur,
5541
- value,
5542
- isDirty,
5543
- props
5544
- }) => {
5545
- const { name, defaultValue = 0, onChange } = props;
5546
- const [input, setInput] = useState10(
5547
- convertFloatToTime(value ?? defaultValue)
5548
- );
5549
- const [formattedTime, setFormattedTime] = useState10("");
5550
- const [errors, setErrors] = useState10("");
5551
- const handleInputChange = (e) => {
5552
- const raw = e.target.value.replace(/[^\d:]/g, "");
5553
- setInput(raw);
5554
- const timeRegex = /^(\d{1,2}):?(\d{0,2})$/;
5555
- const match = raw.match(timeRegex);
5556
- if (!match) {
5557
- setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
5558
- setFormattedTime("");
5559
- return;
5560
- }
5561
- let hours = parseInt(match[1] ?? "0", 10);
5562
- let minutes = parseInt(match[2] ?? "0", 10);
5563
- if (isNaN(hours)) hours = 0;
5564
- if (isNaN(minutes)) minutes = 0;
5565
- if (hours >= 24) {
5566
- hours = 0;
5567
- }
5568
- if (minutes >= 60) {
5569
- minutes = 0;
5570
- }
5571
- const formatted = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
5572
- setErrors("");
5573
- setFormattedTime(formatted);
5574
- fieldOnChange(formatted);
5485
+ // src/widget/basic/download-file-field/controller.ts
5486
+ import { useId, useState as useState10 } from "react";
5487
+ var downloadFileController = () => {
5488
+ const inputId = useId();
5489
+ const [file, setFile] = useState10(null);
5490
+ const handleFileChange = (e) => {
5491
+ setFile(e.target.files[0]);
5575
5492
  };
5576
- const handleBlur = () => {
5577
- if (!isDirty) return;
5578
- if (formattedTime) {
5579
- setInput(formattedTime);
5580
- const floatVal = convertTimeToFloat(formattedTime);
5581
- fieldOnChange(floatVal);
5582
- if (onChange) {
5583
- onChange(name ?? "", floatVal);
5584
- }
5585
- } else {
5586
- setInput("00:00");
5587
- fieldOnChange(0);
5588
- if (onChange) {
5589
- onChange(name ?? "", 0);
5590
- }
5591
- setErrors("");
5592
- }
5593
- onBlur();
5493
+ const handleFileDownload = () => {
5494
+ const url = URL.createObjectURL(file);
5495
+ const link = document.createElement("a");
5496
+ link.href = url;
5497
+ link.download = file.name;
5498
+ document.body.appendChild(link);
5499
+ link.click();
5500
+ document.body.removeChild(link);
5594
5501
  };
5595
- const handleKeyDown = (e) => {
5596
- {
5597
- const allowed = [
5598
- "Backspace",
5599
- "Tab",
5600
- "ArrowLeft",
5601
- "ArrowRight",
5602
- "Delete",
5603
- "Home",
5604
- "End",
5605
- ":"
5606
- ];
5607
- const isNumber = /^[0-9]$/.test(e.key);
5608
- if (!isNumber && !allowed.includes(e.key)) {
5609
- e.preventDefault();
5502
+ return {
5503
+ inputId,
5504
+ file,
5505
+ handleFileChange,
5506
+ handleFileDownload
5507
+ };
5508
+ };
5509
+
5510
+ // src/widget/basic/download-binary-field/controller.ts
5511
+ var downLoadBinaryController = (props) => {
5512
+ const { value, defaultValue, formValues } = props;
5513
+ const handleFileDownload = async (e) => {
5514
+ e.stopPropagation();
5515
+ await downloadFile(value || defaultValue, formValues?.name);
5516
+ };
5517
+ const downloadFile = async (url, filename) => {
5518
+ try {
5519
+ const response = await fetch(url);
5520
+ if (response) {
5521
+ const blob = await response.blob();
5522
+ const urlBlob = window.URL.createObjectURL(blob);
5523
+ const link = document.createElement("a");
5524
+ link.href = urlBlob;
5525
+ link.download = filename || "downloaded-file";
5526
+ document.body.appendChild(link);
5527
+ link.click();
5528
+ document.body.removeChild(link);
5529
+ window.URL.revokeObjectURL(urlBlob);
5610
5530
  }
5531
+ } catch (error) {
5532
+ console.error("File download failed:", error);
5611
5533
  }
5612
5534
  };
5613
5535
  return {
5614
- handleInputChange,
5615
- handleBlur,
5616
- handleKeyDown,
5617
- input,
5618
- errors
5536
+ handleFileDownload
5619
5537
  };
5620
5538
  };
5621
5539
 
5622
- // src/widget/basic/float-field/controller.ts
5623
- import { useEffect as useEffect12, useRef as useRef4, useState as useState11 } from "react";
5540
+ // src/widget/basic/date-field/controller.ts
5541
+ var import_moment = __toESM(require_moment());
5624
5542
 
5625
5543
  // src/utils/i18n.ts
5626
5544
  import { initReactI18next } from "react-i18next";
@@ -6388,184 +6306,7 @@ i18n.use(LanguageDetector).use(initReactI18next).init({
6388
6306
  });
6389
6307
  var i18n_default = i18n;
6390
6308
 
6391
- // src/widget/basic/float-field/controller.ts
6392
- var floatController = ({
6393
- onChange,
6394
- value,
6395
- props
6396
- }) => {
6397
- const { name, required, methods, onChange: handleOnchange, string } = props;
6398
- const { setError, clearErrors } = methods;
6399
- const [inputValue, setInputValue] = useState11(
6400
- value !== void 0 && value !== null ? useFormatFloatNumber(value) : ""
6401
- );
6402
- useEffect12(() => {
6403
- if (value !== void 0 && value !== null && value !== parseFloat(inputValue?.replace(/,/g, ""))) {
6404
- setInputValue(useFormatFloatNumber(value));
6405
- clearErrors(name);
6406
- } else if (value === null || value === void 0) {
6407
- setInputValue("");
6408
- }
6409
- }, [value, name, clearErrors]);
6410
- const isDirtyRef = useRef4(false);
6411
- const inputRef = useRef4(null);
6412
- const lastCommittedValueRef = useRef4(null);
6413
- const handleInputChange = (e) => {
6414
- const newValue = e.target.value;
6415
- const valueWithoutCommas = newValue.replace(/,/g, "");
6416
- if (/^[0-9]*[.,]?[0-9]*$/.test(valueWithoutCommas) || newValue === "") {
6417
- const parts = valueWithoutCommas.split(".");
6418
- let integerPart = parts[0] || "";
6419
- const decimalPart = parts[1] || "";
6420
- if (decimalPart.length > 100) return;
6421
- if (integerPart) {
6422
- integerPart = Number(integerPart).toLocaleString("en-US");
6423
- }
6424
- const formattedValue = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
6425
- setInputValue(formattedValue);
6426
- const parsedValue = parseFloat(valueWithoutCommas.replace(",", "."));
6427
- if (!isNaN(parsedValue)) {
6428
- if (parsedValue < 0) {
6429
- setError(name, {
6430
- type: "validate",
6431
- message: i18n_default.t("invalid_number")
6432
- });
6433
- } else {
6434
- onChange(parsedValue);
6435
- clearErrors(name);
6436
- isDirtyRef.current = true;
6437
- }
6438
- } else {
6439
- onChange(null);
6440
- clearErrors(name);
6441
- }
6442
- }
6443
- };
6444
- const handleInputMouseLeave = () => {
6445
- if (!isDirtyRef.current) {
6446
- inputRef.current?.blur();
6447
- return;
6448
- }
6449
- const rawValue = inputValue.replace(/,/g, "");
6450
- const parsedValue = parseFloat(rawValue);
6451
- if (rawValue === "" || rawValue === ".") {
6452
- if (required) {
6453
- setError(name, {
6454
- type: "required",
6455
- message: `${string} ${i18n_default.t("must_required")}`
6456
- });
6457
- }
6458
- onChange(null);
6459
- setInputValue("");
6460
- lastCommittedValueRef.current = null;
6461
- } else if (!isNaN(parsedValue)) {
6462
- if (parsedValue < 0) {
6463
- setError(name, {
6464
- type: "validate",
6465
- message: i18n_default.t("invalid_number")
6466
- });
6467
- setInputValue("");
6468
- lastCommittedValueRef.current = null;
6469
- } else {
6470
- if (lastCommittedValueRef.current !== parsedValue) {
6471
- const parts = rawValue.split(".");
6472
- let integerPart = parts[0];
6473
- const decimalPart = parts[1] || "";
6474
- integerPart = Number(integerPart).toLocaleString("en-US");
6475
- const formattedValue = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
6476
- onChange(parsedValue);
6477
- setInputValue(formattedValue);
6478
- handleOnchange?.(name ?? "", parsedValue);
6479
- clearErrors(name);
6480
- lastCommittedValueRef.current = parsedValue;
6481
- }
6482
- }
6483
- } else {
6484
- setError(name, {
6485
- type: "validate",
6486
- message: i18n_default.t("invalid_number")
6487
- });
6488
- setInputValue("");
6489
- lastCommittedValueRef.current = null;
6490
- }
6491
- isDirtyRef.current = false;
6492
- inputRef.current?.blur();
6493
- };
6494
- return {
6495
- handleInputMouseLeave,
6496
- handleInputChange,
6497
- useFormatFloatNumber,
6498
- inputRef,
6499
- inputValue
6500
- };
6501
- };
6502
- var useFormatFloatNumber = (value) => {
6503
- if (value === void 0 || value === null || value === "") return "";
6504
- const numValue = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
6505
- if (isNaN(numValue)) return "";
6506
- return numValue.toLocaleString("en-US", {
6507
- minimumFractionDigits: numValue % 1 === 0 ? 0 : 1,
6508
- maximumFractionDigits: 20
6509
- });
6510
- };
6511
-
6512
- // src/widget/basic/download-file-field/controller.ts
6513
- import { useId, useState as useState12 } from "react";
6514
- var downloadFileController = () => {
6515
- const inputId = useId();
6516
- const [file, setFile] = useState12(null);
6517
- const handleFileChange = (e) => {
6518
- setFile(e.target.files[0]);
6519
- };
6520
- const handleFileDownload = () => {
6521
- const url = URL.createObjectURL(file);
6522
- const link = document.createElement("a");
6523
- link.href = url;
6524
- link.download = file.name;
6525
- document.body.appendChild(link);
6526
- link.click();
6527
- document.body.removeChild(link);
6528
- };
6529
- return {
6530
- inputId,
6531
- file,
6532
- handleFileChange,
6533
- handleFileDownload
6534
- };
6535
- };
6536
-
6537
- // src/widget/basic/download-binary-field/controller.ts
6538
- var downLoadBinaryController = (props) => {
6539
- const { value, defaultValue, formValues } = props;
6540
- const handleFileDownload = async (e) => {
6541
- e.stopPropagation();
6542
- await downloadFile(value || defaultValue, formValues?.name);
6543
- };
6544
- const downloadFile = async (url, filename) => {
6545
- try {
6546
- const response = await fetch(url);
6547
- if (response) {
6548
- const blob = await response.blob();
6549
- const urlBlob = window.URL.createObjectURL(blob);
6550
- const link = document.createElement("a");
6551
- link.href = urlBlob;
6552
- link.download = filename || "downloaded-file";
6553
- document.body.appendChild(link);
6554
- link.click();
6555
- document.body.removeChild(link);
6556
- window.URL.revokeObjectURL(urlBlob);
6557
- }
6558
- } catch (error) {
6559
- console.error("File download failed:", error);
6560
- }
6561
- };
6562
- return {
6563
- handleFileDownload
6564
- };
6565
- };
6566
-
6567
6309
  // src/widget/basic/date-field/controller.ts
6568
- var import_moment = __toESM(require_moment());
6569
6310
  var DURATIONS = {
6570
6311
  PAST: "past",
6571
6312
  NOW: "now",
@@ -6677,11 +6418,11 @@ var dateFieldController = (props) => {
6677
6418
  };
6678
6419
 
6679
6420
  // src/widget/basic/copy-link-button/controller.ts
6680
- import { useState as useState13 } from "react";
6421
+ import { useState as useState11 } from "react";
6681
6422
  import { copyTextToClipboard } from "@fctc/interface-logic/utils";
6682
6423
  var copyLinkButtonController = (props) => {
6683
6424
  const { value, defaultValue } = props;
6684
- const [isCopied, setIsCopied] = useState13(false);
6425
+ const [isCopied, setIsCopied] = useState11(false);
6685
6426
  const handleCopyToClipboard = async (value2) => {
6686
6427
  await copyTextToClipboard(value2);
6687
6428
  setIsCopied(true);
@@ -6729,16 +6470,16 @@ var colorFieldController = (props) => {
6729
6470
  };
6730
6471
 
6731
6472
  // src/widget/basic/binary-field/controller.ts
6732
- import { useEffect as useEffect13, useId as useId2, useRef as useRef5, useState as useState14 } from "react";
6473
+ import { useEffect as useEffect12, useId as useId2, useRef as useRef4, useState as useState12 } from "react";
6733
6474
  import { isBase64Image } from "@fctc/interface-logic/utils";
6734
6475
  var binaryFieldController = (props) => {
6735
6476
  const { name, methods, readonly = false, value } = props;
6736
6477
  const inputId = useId2();
6737
- const [selectedImage, setSelectedImage] = useState14(null);
6738
- const [initialImage, setInitialImage] = useState14(value || null);
6739
- const [isInsideTable, setIsInsideTable] = useState14(false);
6478
+ const [selectedImage, setSelectedImage] = useState12(null);
6479
+ const [initialImage, setInitialImage] = useState12(value || null);
6480
+ const [isInsideTable, setIsInsideTable] = useState12(false);
6740
6481
  const { setValue } = methods;
6741
- const binaryRef = useRef5(null);
6482
+ const binaryRef = useRef4(null);
6742
6483
  const convertUrlToBase64 = async (url) => {
6743
6484
  try {
6744
6485
  const response = await fetch(url);
@@ -6800,14 +6541,14 @@ var binaryFieldController = (props) => {
6800
6541
  else if (base64.startsWith("UklGR")) mimeType = "image/webp";
6801
6542
  return mimeType ? `data:${mimeType};base64,${base64}` : null;
6802
6543
  };
6803
- useEffect13(() => {
6544
+ useEffect12(() => {
6804
6545
  return () => {
6805
6546
  if (selectedImage) {
6806
6547
  URL.revokeObjectURL(selectedImage);
6807
6548
  }
6808
6549
  };
6809
6550
  }, [selectedImage]);
6810
- useEffect13(() => {
6551
+ useEffect12(() => {
6811
6552
  if (binaryRef.current) {
6812
6553
  const isInsideTable2 = !!binaryRef.current.closest("table");
6813
6554
  setIsInsideTable(isInsideTable2);
@@ -6827,8 +6568,8 @@ var binaryFieldController = (props) => {
6827
6568
  };
6828
6569
 
6829
6570
  // src/widget/advance/table/table-body/controller.ts
6830
- import { useAppDispatch as useAppDispatch6, setSelectedRowKeys } from "@fctc/interface-logic/store";
6831
- import { useEffect as useEffect14, useMemo as useMemo12 } from "react";
6571
+ import { useAppDispatch as useAppDispatch5, setSelectedRowKeys } from "@fctc/interface-logic/store";
6572
+ import { useEffect as useEffect13, useMemo as useMemo12 } from "react";
6832
6573
  var tableBodyController = (props) => {
6833
6574
  const {
6834
6575
  checkedAll,
@@ -6840,7 +6581,7 @@ var tableBodyController = (props) => {
6840
6581
  selectedRowKeysRef,
6841
6582
  onClickRow
6842
6583
  } = props;
6843
- const appDispatch = useAppDispatch6();
6584
+ const appDispatch = useAppDispatch5();
6844
6585
  const checked = useMemo12(() => {
6845
6586
  if (!row?.id) return false;
6846
6587
  if (selectedRowKeys?.includes(row.id)) {
@@ -6862,7 +6603,7 @@ var tableBodyController = (props) => {
6862
6603
  const handleClickRow = (col, row2) => {
6863
6604
  onClickRow(col, row2);
6864
6605
  };
6865
- useEffect14(() => {
6606
+ useEffect13(() => {
6866
6607
  if (!row?.id) return;
6867
6608
  if (isAutoSelect) {
6868
6609
  if (checkboxRef?.current === "uncheck") {
@@ -6880,7 +6621,7 @@ var tableBodyController = (props) => {
6880
6621
  }
6881
6622
  }
6882
6623
  }, [isAutoSelect]);
6883
- useEffect14(() => {
6624
+ useEffect13(() => {
6884
6625
  if (!checkedAll) {
6885
6626
  checkboxRef.current = "enabled";
6886
6627
  false;
@@ -6895,14 +6636,14 @@ var tableBodyController = (props) => {
6895
6636
 
6896
6637
  // src/widget/advance/table/table-head/controller.ts
6897
6638
  import {
6898
- useAppDispatch as useAppDispatch7,
6639
+ useAppDispatch as useAppDispatch6,
6899
6640
  useAppSelector as useAppSelector4,
6900
6641
  selectSearch as selectSearch3,
6901
6642
  setSelectedRowKeys as setSelectedRowKeys2
6902
6643
  } from "@fctc/interface-logic/store";
6903
6644
  var tableHeadController = (props) => {
6904
6645
  const { typeTable, rows, selectedRowKeysRef } = props;
6905
- const appDispatch = useAppDispatch7();
6646
+ const appDispatch = useAppDispatch6();
6906
6647
  const { groupByDomain } = useAppSelector4(selectSearch3);
6907
6648
  const handleCheckBoxAll = (event) => {
6908
6649
  if (event?.target?.checked && typeTable === "list") {
@@ -6936,7 +6677,7 @@ var tableHeadController = (props) => {
6936
6677
  };
6937
6678
 
6938
6679
  // src/widget/advance/table/table-view/controller.ts
6939
- import { useEffect as useEffect15, useMemo as useMemo13, useRef as useRef6, useState as useState15 } from "react";
6680
+ import { useEffect as useEffect14, useMemo as useMemo13, useRef as useRef5, useState as useState13 } from "react";
6940
6681
  import {
6941
6682
  useAppSelector as useAppSelector5,
6942
6683
  selectSearch as selectSearch4,
@@ -6944,8 +6685,8 @@ import {
6944
6685
  } from "@fctc/interface-logic/store";
6945
6686
  import { domainHelper } from "@fctc/interface-logic/utils";
6946
6687
  var tableController = ({ data }) => {
6947
- const [rows, setRows] = useState15(data.records || []);
6948
- const [columns, setColumns] = useState15([]);
6688
+ const [rows, setRows] = useState13(data.records || []);
6689
+ const [columns, setColumns] = useState13([]);
6949
6690
  const dataModelFields = data.fields?.map((field) => {
6950
6691
  return {
6951
6692
  ...data.dataModel?.[field?.name],
@@ -6973,7 +6714,7 @@ var tableController = ({ data }) => {
6973
6714
  return item.display_name ? { ...transformedItem, item: item.display_name } : transformedItem;
6974
6715
  });
6975
6716
  };
6976
- useEffect15(() => {
6717
+ useEffect14(() => {
6977
6718
  setRows(transformData(data.records || null));
6978
6719
  }, [data.records]);
6979
6720
  const handleGetColumns = () => {
@@ -6994,7 +6735,7 @@ var tableController = ({ data }) => {
6994
6735
  }
6995
6736
  return cols;
6996
6737
  };
6997
- useEffect15(() => {
6738
+ useEffect14(() => {
6998
6739
  const columns2 = handleGetColumns();
6999
6740
  setColumns(columns2);
7000
6741
  }, [data.records]);
@@ -7019,7 +6760,7 @@ var tableController = ({ data }) => {
7019
6760
  };
7020
6761
 
7021
6762
  // src/widget/advance/table/table-group/controller.ts
7022
- import { useEffect as useEffect16, useMemo as useMemo14, useState as useState16 } from "react";
6763
+ import { useEffect as useEffect15, useMemo as useMemo14, useState as useState14 } from "react";
7023
6764
  import {
7024
6765
  useOdooDataTransform,
7025
6766
  useGetListData as useGetListData2
@@ -7028,7 +6769,7 @@ import {
7028
6769
  useAppSelector as useAppSelector6,
7029
6770
  selectSearch as selectSearch5,
7030
6771
  selectList as selectList4,
7031
- useAppDispatch as useAppDispatch8,
6772
+ useAppDispatch as useAppDispatch7,
7032
6773
  setSelectedRowKeys as setSelectedRowKeys3
7033
6774
  } from "@fctc/interface-logic/store";
7034
6775
 
@@ -7058,14 +6799,14 @@ var tableGroupController = (props) => {
7058
6799
  setIsAutoSelect,
7059
6800
  selectedRowKeysRef
7060
6801
  } = props;
7061
- const [pageGroup, setPageGroup] = useState16(0);
6802
+ const [pageGroup, setPageGroup] = useState14(0);
7062
6803
  const { groupByDomain, selectedTags } = useAppSelector6(selectSearch5);
7063
6804
  const { selectedRowKeys } = useAppSelector6(selectList4);
7064
- const appDispatch = useAppDispatch8();
6805
+ const appDispatch = useAppDispatch7();
7065
6806
  const { toDataJS } = useOdooDataTransform();
7066
6807
  const initVal = toDataJS(row, viewData, model);
7067
- const [isShowGroup, setIsShowGroup] = useState16(false);
7068
- const [colEmptyGroup, setColEmptyGroup] = useState16({
6808
+ const [isShowGroup, setIsShowGroup] = useState14(false);
6809
+ const [colEmptyGroup, setColEmptyGroup] = useState14({
7069
6810
  fromStart: 1,
7070
6811
  fromEnd: 1
7071
6812
  });
@@ -7124,7 +6865,7 @@ var tableGroupController = (props) => {
7124
6865
  }
7125
6866
  });
7126
6867
  const leftPadding = level > 1 ? level * 8 + "px" : "0px";
7127
- useEffect16(() => {
6868
+ useEffect15(() => {
7128
6869
  if (isShowGroup && selectedTags?.length > 0) {
7129
6870
  setIsShowGroup(false);
7130
6871
  }
@@ -7158,7 +6899,7 @@ var tableGroupController = (props) => {
7158
6899
  }
7159
6900
  toggleShowGroup();
7160
6901
  };
7161
- useEffect16(() => {
6902
+ useEffect15(() => {
7162
6903
  if (!isQueryFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
7163
6904
  return;
7164
6905
  }
@@ -7202,10 +6943,10 @@ var import_moment2 = __toESM(require_moment());
7202
6943
  import { SearchType } from "@fctc/interface-logic/constants";
7203
6944
  import {
7204
6945
  domainHelper as domainHelper2,
7205
- evalJSONDomain as evalJSONDomain6,
6946
+ evalJSONDomain as evalJSONDomain7,
7206
6947
  validateAndParseDate
7207
6948
  } from "@fctc/interface-logic/utils";
7208
- import { useCallback as useCallback3, useEffect as useEffect17, useState as useState17 } from "react";
6949
+ import { useCallback as useCallback3, useEffect as useEffect16, useState as useState15 } from "react";
7209
6950
  var searchController = ({
7210
6951
  viewData,
7211
6952
  actionData,
@@ -7214,12 +6955,12 @@ var searchController = ({
7214
6955
  setSearchMap,
7215
6956
  searchMap
7216
6957
  }) => {
7217
- const [filterBy, setFilterBy] = useState17(null);
7218
- const [searchBy, setSearchBy] = useState17(null);
7219
- const [groupBy, setGroupBy] = useState17(null);
7220
- const [selectedTags, setSelectedTags] = useState17(null);
7221
- const [searchString, setSearchString] = useState17("");
7222
- const domainAction = actionData?.domain ? Array.isArray(actionData?.domain) ? [...actionData?.domain] : evalJSONDomain6(actionData?.domain, contextSearch) : [];
6958
+ const [filterBy, setFilterBy] = useState15(null);
6959
+ const [searchBy, setSearchBy] = useState15(null);
6960
+ const [groupBy, setGroupBy] = useState15(null);
6961
+ const [selectedTags, setSelectedTags] = useState15(null);
6962
+ const [searchString, setSearchString] = useState15("");
6963
+ const domainAction = actionData?.domain ? Array.isArray(actionData?.domain) ? [...actionData?.domain] : evalJSONDomain7(actionData?.domain, contextSearch) : [];
7223
6964
  const aid = actionData?.id;
7224
6965
  const model = actionData?.res_model;
7225
6966
  const clearSearch = () => {
@@ -7265,7 +7006,7 @@ var searchController = ({
7265
7006
  }
7266
7007
  }
7267
7008
  };
7268
- useEffect17(() => {
7009
+ useEffect16(() => {
7269
7010
  clearSearch();
7270
7011
  fetchData();
7271
7012
  }, [aid, model, viewData]);
@@ -7411,7 +7152,7 @@ var searchController = ({
7411
7152
  },
7412
7153
  [searchMap]
7413
7154
  );
7414
- useEffect17(() => {
7155
+ useEffect16(() => {
7415
7156
  setSelectedTags(null);
7416
7157
  setTagSearch(searchMap);
7417
7158
  }, [searchMap]);
@@ -7475,8 +7216,6 @@ export {
7475
7216
  downLoadBinaryController,
7476
7217
  downloadFileController,
7477
7218
  durationController,
7478
- floatController,
7479
- floatTimeFiledController,
7480
7219
  many2manyFieldController,
7481
7220
  many2manyTagsController,
7482
7221
  many2oneButtonController,