@fctc/widget-logic 1.8.5 → 1.8.7
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 +1482 -1430
- package/dist/index.mjs +1512 -1463
- package/dist/widget.d.mts +26 -18
- package/dist/widget.d.ts +26 -18
- package/dist/widget.js +1843 -1674
- package/dist/widget.mjs +2541 -2373
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5209,48 +5209,63 @@ var statusDropdownController = (props) => {
|
|
|
5209
5209
|
|
|
5210
5210
|
// src/widget/basic/many2one-field/controller.ts
|
|
5211
5211
|
var import_react14 = require("react");
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
var
|
|
5212
|
+
|
|
5213
|
+
// src/utils.ts
|
|
5214
|
+
var utils_exports = {};
|
|
5215
|
+
__export(utils_exports, {
|
|
5216
|
+
API_APP_URL: () => API_APP_URL,
|
|
5217
|
+
API_PRESCHOOL_URL: () => API_PRESCHOOL_URL,
|
|
5218
|
+
STORAGES: () => STORAGES,
|
|
5219
|
+
combineContexts: () => combineContexts,
|
|
5220
|
+
convertFieldsToArray: () => convertFieldsToArray,
|
|
5221
|
+
countSum: () => countSum,
|
|
5222
|
+
getDateRange: () => getDateRange,
|
|
5223
|
+
languages: () => languages,
|
|
5224
|
+
mergeButtons: () => mergeButtons,
|
|
5225
|
+
setStorageItemAsync: () => setStorageItemAsync,
|
|
5226
|
+
useGetRowIds: () => useGetRowIds,
|
|
5227
|
+
useSelectionState: () => useSelectionState,
|
|
5228
|
+
useStorageState: () => useStorageState
|
|
5229
|
+
});
|
|
5230
|
+
__reExport(utils_exports, require("@fctc/interface-logic/utils"));
|
|
5231
|
+
|
|
5232
|
+
// src/provider.ts
|
|
5233
|
+
var provider_exports = {};
|
|
5234
|
+
__reExport(provider_exports, require("@fctc/interface-logic/provider"));
|
|
5235
|
+
|
|
5236
|
+
// src/widget/basic/many2one-field/controller.ts
|
|
5215
5237
|
var many2oneFieldController = (props) => {
|
|
5216
5238
|
const {
|
|
5217
|
-
|
|
5239
|
+
sessionStorageUtils,
|
|
5218
5240
|
methods,
|
|
5219
|
-
formValues,
|
|
5220
|
-
domain,
|
|
5221
5241
|
relation,
|
|
5222
|
-
|
|
5242
|
+
domain,
|
|
5243
|
+
formValues,
|
|
5223
5244
|
value: propValue,
|
|
5245
|
+
onChange,
|
|
5246
|
+
name,
|
|
5224
5247
|
context: fieldContext,
|
|
5225
5248
|
options: fieldOptions,
|
|
5226
|
-
showDetail
|
|
5227
|
-
actionData
|
|
5249
|
+
showDetail
|
|
5228
5250
|
} = props;
|
|
5229
5251
|
const [options, setOptions] = (0, import_react14.useState)([]);
|
|
5252
|
+
const [inputValue, setInputValue] = (0, import_react14.useState)("");
|
|
5253
|
+
const [debouncedInputValue] = useDebounce(inputValue, 1e3);
|
|
5230
5254
|
const [isShowModalMany2Many, setIsShowModalMany2Many] = (0, import_react14.useState)(false);
|
|
5231
5255
|
const [tempSelectedOption, setTempSelectedOption] = (0, import_react14.useState)(null);
|
|
5232
|
-
const { menuList } = (0, import_store7.useAppSelector)(import_store7.selectNavbar);
|
|
5233
|
-
const { context } = (0, import_store7.useAppSelector)(import_store7.selectEnv);
|
|
5234
5256
|
const [domainModal, setDomainModal] = (0, import_react14.useState)(null);
|
|
5257
|
+
const [domainObject, setDomainObject] = (0, import_react14.useState)(null);
|
|
5258
|
+
const actionData = sessionStorageUtils.getActionData();
|
|
5259
|
+
const { menuList } = (0, store_exports.useAppSelector)(store_exports.selectNavbar);
|
|
5260
|
+
const { context } = (0, store_exports.useAppSelector)(store_exports.selectEnv);
|
|
5235
5261
|
const initValue = methods?.getValues(name);
|
|
5236
|
-
const
|
|
5237
|
-
() => (0, import_utils3.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues)) ?? {}),
|
|
5238
|
-
[domain, formValues]
|
|
5239
|
-
);
|
|
5240
|
-
const optionsObject = (0, import_utils3.evalJSONContext)(fieldOptions) || {};
|
|
5262
|
+
const optionsObject = (0, utils_exports.evalJSONContext)(fieldOptions) || {};
|
|
5241
5263
|
const contextObject = {
|
|
5242
|
-
...(0,
|
|
5264
|
+
...(0, utils_exports.evalJSONContext)(actionData?.context) || {},
|
|
5243
5265
|
...fieldContext,
|
|
5244
5266
|
...context
|
|
5245
5267
|
};
|
|
5246
|
-
const
|
|
5247
|
-
() => menuList?.flatMap(
|
|
5248
|
-
(item) => item?.child_id.filter(
|
|
5249
|
-
(childItem) => childItem?.is_display && childItem?.action?.res_model === relation
|
|
5250
|
-
)
|
|
5251
|
-
)?.[0]?.action?.id,
|
|
5252
|
-
[menuList, relation]
|
|
5253
|
-
);
|
|
5268
|
+
const { useGetSelection: useGetSelection3 } = (0, provider_exports.useService)();
|
|
5254
5269
|
const data = {
|
|
5255
5270
|
model: relation,
|
|
5256
5271
|
domain: domainObject,
|
|
@@ -5264,9 +5279,9 @@ var many2oneFieldController = (props) => {
|
|
|
5264
5279
|
const queryKey = [`data_${relation}`, domainObject];
|
|
5265
5280
|
const {
|
|
5266
5281
|
data: dataOfSelection,
|
|
5267
|
-
|
|
5282
|
+
refetch,
|
|
5268
5283
|
isFetching
|
|
5269
|
-
} = (
|
|
5284
|
+
} = useGetSelection3({
|
|
5270
5285
|
data,
|
|
5271
5286
|
queryKey,
|
|
5272
5287
|
enabled: false
|
|
@@ -5280,8 +5295,16 @@ var many2oneFieldController = (props) => {
|
|
|
5280
5295
|
(0, import_react14.useEffect)(() => {
|
|
5281
5296
|
setOptions(selectOptions);
|
|
5282
5297
|
setDomainModal(domainObject);
|
|
5283
|
-
if (relation === "student.subject") (0,
|
|
5298
|
+
if (relation === "student.subject") (0, store_exports.setListSubject)(selectOptions);
|
|
5284
5299
|
}, [selectOptions]);
|
|
5300
|
+
(0, import_react14.useEffect)(() => {
|
|
5301
|
+
setDomainObject(
|
|
5302
|
+
(0, utils_exports.evalJSONDomain)(
|
|
5303
|
+
domain,
|
|
5304
|
+
JSON.parse(JSON.stringify({ ...formValues, context: contextObject })) ?? {}
|
|
5305
|
+
)
|
|
5306
|
+
);
|
|
5307
|
+
}, [domain, formValues]);
|
|
5285
5308
|
(0, import_react14.useEffect)(() => {
|
|
5286
5309
|
if (!propValue && tempSelectedOption) {
|
|
5287
5310
|
methods.setValue(name, null);
|
|
@@ -5293,11 +5316,24 @@ var many2oneFieldController = (props) => {
|
|
|
5293
5316
|
});
|
|
5294
5317
|
}
|
|
5295
5318
|
}, [propValue]);
|
|
5319
|
+
const fetchMoreOptions = (0, import_react14.useCallback)(() => {
|
|
5320
|
+
refetch();
|
|
5321
|
+
}, [refetch]);
|
|
5296
5322
|
(0, import_react14.useEffect)(() => {
|
|
5297
|
-
if (
|
|
5298
|
-
|
|
5323
|
+
if (debouncedInputValue) {
|
|
5324
|
+
const filteredDomain = [...domainObject ?? []]?.filter(
|
|
5325
|
+
(d) => !(Array.isArray(d) && d[0] === "name" && d[1] === "ilike")
|
|
5326
|
+
) || [];
|
|
5327
|
+
const newDomain = [
|
|
5328
|
+
...filteredDomain,
|
|
5329
|
+
...debouncedInputValue ? [["name", "ilike", debouncedInputValue]] : []
|
|
5330
|
+
];
|
|
5331
|
+
setDomainObject(newDomain);
|
|
5332
|
+
setTimeout(() => {
|
|
5333
|
+
fetchMoreOptions();
|
|
5334
|
+
}, 50);
|
|
5299
5335
|
}
|
|
5300
|
-
}, [
|
|
5336
|
+
}, [debouncedInputValue]);
|
|
5301
5337
|
const handleChooseRecord = (0, import_react14.useCallback)(
|
|
5302
5338
|
(idRecord) => {
|
|
5303
5339
|
const newOption = options.find(
|
|
@@ -5349,52 +5385,42 @@ var many2oneFieldController = (props) => {
|
|
|
5349
5385
|
[methods, name, onChange]
|
|
5350
5386
|
);
|
|
5351
5387
|
const allowShowDetail = showDetail && contextObject?.form_view_ref && (!("no_open" in optionsObject) || optionsObject?.no_open === false);
|
|
5352
|
-
const fetchMoreOptions = (0, import_react14.useCallback)(() => {
|
|
5353
|
-
if (typeof dataOfSelection?.refetch === "function") {
|
|
5354
|
-
;
|
|
5355
|
-
dataOfSelection.refetch();
|
|
5356
|
-
}
|
|
5357
|
-
}, [dataOfSelection]);
|
|
5358
5388
|
return {
|
|
5359
|
-
|
|
5360
|
-
|
|
5389
|
+
isShowModalMany2Many,
|
|
5390
|
+
isFetching,
|
|
5391
|
+
initValue,
|
|
5392
|
+
menuList,
|
|
5361
5393
|
handleChooseRecord,
|
|
5394
|
+
handleClose,
|
|
5362
5395
|
handleSelectChange,
|
|
5363
|
-
initValue,
|
|
5364
|
-
isFetching,
|
|
5365
|
-
isShowModalMany2Many,
|
|
5366
|
-
options,
|
|
5367
|
-
fetchMoreOptions,
|
|
5368
5396
|
domainModal,
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
setDomainModal,
|
|
5372
|
-
dataOfSelection,
|
|
5373
|
-
refetch: dataOfSelection?.refetch ?? (() => {
|
|
5374
|
-
}),
|
|
5375
|
-
selectOptions,
|
|
5376
|
-
optionsObject,
|
|
5397
|
+
setInputValue,
|
|
5398
|
+
allowShowDetail,
|
|
5377
5399
|
contextObject,
|
|
5378
|
-
|
|
5379
|
-
|
|
5400
|
+
tempSelectedOption,
|
|
5401
|
+
options,
|
|
5402
|
+
fetchMoreOptions,
|
|
5403
|
+
domainObject,
|
|
5404
|
+
setIsShowModalMany2Many,
|
|
5405
|
+
setDomainObject
|
|
5380
5406
|
};
|
|
5381
5407
|
};
|
|
5382
5408
|
|
|
5383
5409
|
// src/widget/basic/many2one-button-field/controller.ts
|
|
5384
5410
|
var import_environment6 = require("@fctc/interface-logic/environment");
|
|
5385
5411
|
var import_hooks12 = require("@fctc/interface-logic/hooks");
|
|
5386
|
-
var
|
|
5412
|
+
var import_utils5 = require("@fctc/interface-logic/utils");
|
|
5387
5413
|
var many2oneButtonController = (props) => {
|
|
5388
5414
|
const { domain, methods, relation } = props;
|
|
5389
5415
|
const actionDataString = sessionStorage.getItem("actionData");
|
|
5390
5416
|
const env = (0, import_environment6.getEnv)();
|
|
5391
|
-
const domainObject = (0,
|
|
5417
|
+
const domainObject = (0, import_utils5.evalJSONDomain)(domain, methods?.getValues() || {});
|
|
5392
5418
|
const actionData = actionDataString && actionDataString !== "undefined" ? JSON.parse(actionDataString) : {};
|
|
5393
5419
|
const { data: dataOfSelection } = (0, import_hooks12.useGetSelection)({
|
|
5394
5420
|
data: {
|
|
5395
5421
|
model: relation ?? "",
|
|
5396
5422
|
domain: domainObject,
|
|
5397
|
-
context: { ...env.context, ...(0,
|
|
5423
|
+
context: { ...env.context, ...(0, import_utils5.evalJSONContext)(actionData?.context) }
|
|
5398
5424
|
},
|
|
5399
5425
|
queryKey: [`data_${relation}`, domainObject]
|
|
5400
5426
|
});
|
|
@@ -5408,204 +5434,473 @@ var many2oneButtonController = (props) => {
|
|
|
5408
5434
|
};
|
|
5409
5435
|
|
|
5410
5436
|
// src/widget/basic/many2many-field/controller.ts
|
|
5411
|
-
var import_react19 = require("react");
|
|
5412
|
-
|
|
5413
|
-
// src/widget/advance/table/table-body/controller.ts
|
|
5414
|
-
var import_store8 = require("@fctc/interface-logic/store");
|
|
5415
5437
|
var import_react15 = require("react");
|
|
5416
|
-
var
|
|
5438
|
+
var import_store8 = require("@fctc/interface-logic/store");
|
|
5439
|
+
var import_utils6 = require("@fctc/interface-logic/utils");
|
|
5440
|
+
var many2manyFieldController = (props) => {
|
|
5417
5441
|
const {
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5442
|
+
relation,
|
|
5443
|
+
domain,
|
|
5444
|
+
context,
|
|
5445
|
+
tab,
|
|
5446
|
+
model,
|
|
5447
|
+
aid,
|
|
5448
|
+
setSelectedRowKeys: setSelectedRowKeys4,
|
|
5449
|
+
fields,
|
|
5450
|
+
setFields,
|
|
5451
|
+
groupByDomain,
|
|
5452
|
+
page,
|
|
5453
|
+
options,
|
|
5454
|
+
sessionStorageUtils
|
|
5426
5455
|
} = props;
|
|
5427
5456
|
const appDispatch = (0, import_store8.useAppDispatch)();
|
|
5428
|
-
const
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5457
|
+
const actionData = sessionStorageUtils.getActionData();
|
|
5458
|
+
const [debouncedPage] = useDebounce(page, 500);
|
|
5459
|
+
const [order, setOrder] = (0, import_react15.useState)();
|
|
5460
|
+
const [isLoadedData, setIsLoadedData] = (0, import_react15.useState)(false);
|
|
5461
|
+
const [domainMany2Many, setDomainMany2Many] = (0, import_react15.useState)(domain);
|
|
5462
|
+
const { env } = (0, provider_exports.useEnv)();
|
|
5463
|
+
const { useGetView: useGetView2, useGetListData: useGetListData4, useGetFormView } = (0, provider_exports.useService)();
|
|
5464
|
+
const viewParams = {
|
|
5465
|
+
model: relation,
|
|
5466
|
+
views: [
|
|
5467
|
+
[false, "list"],
|
|
5468
|
+
[false, "search"]
|
|
5469
|
+
],
|
|
5470
|
+
context
|
|
5471
|
+
};
|
|
5472
|
+
const { data: viewResponse } = useGetView2(viewParams, actionData);
|
|
5473
|
+
const baseModel = (0, import_react15.useMemo)(
|
|
5474
|
+
() => ({
|
|
5475
|
+
name: String(relation),
|
|
5476
|
+
view: viewResponse || {},
|
|
5477
|
+
actContext: context,
|
|
5478
|
+
fields: [
|
|
5479
|
+
...Object.values(viewResponse?.views?.list?.fields ?? {}),
|
|
5480
|
+
...tab?.fields ? tab.fields : []
|
|
5481
|
+
]
|
|
5482
|
+
}),
|
|
5483
|
+
[model, viewResponse]
|
|
5484
|
+
);
|
|
5485
|
+
const initModel = (0, hooks_exports.useModel)();
|
|
5486
|
+
const modelInstance = (0, import_react15.useMemo)(() => {
|
|
5487
|
+
if (viewResponse) {
|
|
5488
|
+
return initModel.initModel(baseModel);
|
|
5432
5489
|
}
|
|
5433
|
-
return
|
|
5434
|
-
}, [
|
|
5435
|
-
const
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5490
|
+
return null;
|
|
5491
|
+
}, [baseModel, viewResponse]);
|
|
5492
|
+
const specification = (0, import_react15.useMemo)(() => {
|
|
5493
|
+
if (modelInstance) {
|
|
5494
|
+
return modelInstance.getSpecification();
|
|
5495
|
+
}
|
|
5496
|
+
return null;
|
|
5497
|
+
}, [modelInstance]);
|
|
5498
|
+
const default_order = viewResponse && viewResponse?.views?.list?.default_order;
|
|
5499
|
+
const optionsObject = tab?.options ? (0, import_utils6.evalJSONContext)(tab?.options) : (options ? (0, import_utils6.evalJSONContext)(options) : {}) || {};
|
|
5500
|
+
const fetchData = async () => {
|
|
5501
|
+
try {
|
|
5502
|
+
setDomainMany2Many(domain);
|
|
5503
|
+
appDispatch((0, import_store8.setFirstDomain)(domain));
|
|
5504
|
+
appDispatch((0, import_store8.setViewDataStore)(viewResponse));
|
|
5505
|
+
const modalData = viewResponse?.views?.list?.fields.map((field) => ({
|
|
5506
|
+
...viewResponse?.models?.[String(model)]?.[field?.name],
|
|
5507
|
+
...field
|
|
5508
|
+
}));
|
|
5509
|
+
if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
|
|
5510
|
+
setFields({
|
|
5511
|
+
...fields,
|
|
5512
|
+
[`${aid}_${relation}_popupmany2many`]: modalData
|
|
5513
|
+
});
|
|
5514
|
+
}
|
|
5515
|
+
appDispatch((0, import_store8.setPage)(0));
|
|
5516
|
+
} catch (err) {
|
|
5517
|
+
console.log(err);
|
|
5441
5518
|
}
|
|
5442
|
-
const newSelectedRowKeys = selectedRowKeys?.includes(row.id) ? selectedRowKeys?.filter((key) => key !== row.id) : [...selectedRowKeys, row.id];
|
|
5443
|
-
console.log("newSelectedRowKeys", newSelectedRowKeys);
|
|
5444
|
-
appDispatch((0, import_store8.setSelectedRowKeys)(newSelectedRowKeys));
|
|
5445
5519
|
};
|
|
5446
|
-
const
|
|
5447
|
-
|
|
5520
|
+
const queryKey = [
|
|
5521
|
+
`view-${relation}-${aid}`,
|
|
5522
|
+
specification,
|
|
5523
|
+
domainMany2Many,
|
|
5524
|
+
debouncedPage,
|
|
5525
|
+
groupByDomain,
|
|
5526
|
+
order
|
|
5527
|
+
];
|
|
5528
|
+
const data = {
|
|
5529
|
+
model: relation,
|
|
5530
|
+
specification,
|
|
5531
|
+
domain: domainMany2Many,
|
|
5532
|
+
offset: debouncedPage * 10,
|
|
5533
|
+
limit: 10,
|
|
5534
|
+
context,
|
|
5535
|
+
fields: groupByDomain?.fields,
|
|
5536
|
+
groupby: [groupByDomain?.contexts[0]?.group_by],
|
|
5537
|
+
sort: order ? order : default_order ? (0, import_utils6.formatSortingString)(default_order) : ""
|
|
5448
5538
|
};
|
|
5539
|
+
const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
|
|
5540
|
+
const {
|
|
5541
|
+
data: dataResponse,
|
|
5542
|
+
isLoading: isDataLoading,
|
|
5543
|
+
isFetched: isDataResponseFetched,
|
|
5544
|
+
isPlaceholderData
|
|
5545
|
+
} = useGetListData4(data, queryKey, enabled);
|
|
5449
5546
|
(0, import_react15.useEffect)(() => {
|
|
5450
|
-
if (
|
|
5451
|
-
|
|
5452
|
-
if (checkboxRef?.current === "uncheck") {
|
|
5453
|
-
const filtered = selectedRowKeysRef.current.filter(
|
|
5454
|
-
(id) => id !== row.id
|
|
5455
|
-
);
|
|
5456
|
-
selectedRowKeysRef.current = filtered;
|
|
5457
|
-
appDispatch((0, import_store8.setSelectedRowKeys)(filtered));
|
|
5458
|
-
} else {
|
|
5459
|
-
const unique = Array.from(
|
|
5460
|
-
/* @__PURE__ */ new Set([...selectedRowKeysRef?.current, row?.id])
|
|
5461
|
-
);
|
|
5462
|
-
selectedRowKeysRef.current = unique;
|
|
5463
|
-
appDispatch((0, import_store8.setSelectedRowKeys)(unique));
|
|
5464
|
-
}
|
|
5547
|
+
if (viewResponse) {
|
|
5548
|
+
fetchData();
|
|
5465
5549
|
}
|
|
5466
|
-
|
|
5550
|
+
return () => {
|
|
5551
|
+
appDispatch((0, import_store8.setGroupByDomain)(null));
|
|
5552
|
+
setFields((prevFields) => ({
|
|
5553
|
+
...prevFields,
|
|
5554
|
+
[`${aid}_${relation}_popupmany2many`]: null
|
|
5555
|
+
}));
|
|
5556
|
+
appDispatch((0, import_store8.setPage)(0));
|
|
5557
|
+
setSelectedRowKeys4([]);
|
|
5558
|
+
setDomainMany2Many(null);
|
|
5559
|
+
setIsLoadedData(false);
|
|
5560
|
+
};
|
|
5561
|
+
}, [viewResponse]);
|
|
5562
|
+
const { rows, columns, typeTable } = tableController({
|
|
5563
|
+
data: {
|
|
5564
|
+
fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
|
|
5565
|
+
records: dataResponse?.records ?? dataResponse?.groups,
|
|
5566
|
+
dataModel: viewResponse?.models?.[String(relation)],
|
|
5567
|
+
context: { ...env.context, ...context },
|
|
5568
|
+
typeTable: dataResponse?.groups ? "group" : "list"
|
|
5569
|
+
}
|
|
5570
|
+
});
|
|
5571
|
+
const dataFormView = {
|
|
5572
|
+
id: null,
|
|
5573
|
+
model: relation,
|
|
5574
|
+
context
|
|
5575
|
+
};
|
|
5576
|
+
const {
|
|
5577
|
+
refetch,
|
|
5578
|
+
data: dataFormViewResponse,
|
|
5579
|
+
isSuccess
|
|
5580
|
+
} = useGetFormView({
|
|
5581
|
+
data: dataFormView,
|
|
5582
|
+
queryKey: [`form-view-action-${relation}`],
|
|
5583
|
+
enabled: false
|
|
5584
|
+
});
|
|
5467
5585
|
(0, import_react15.useEffect)(() => {
|
|
5468
|
-
if (
|
|
5469
|
-
|
|
5470
|
-
|
|
5586
|
+
if (isSuccess && dataFormViewResponse) {
|
|
5587
|
+
sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
|
|
5588
|
+
window.location.href = `/form/menu?model=${relation}`;
|
|
5471
5589
|
}
|
|
5472
|
-
}, [
|
|
5590
|
+
}, [isSuccess]);
|
|
5591
|
+
(0, import_react15.useEffect)(() => {
|
|
5592
|
+
if (domainMany2Many && !isLoadedData) {
|
|
5593
|
+
setIsLoadedData(true);
|
|
5594
|
+
}
|
|
5595
|
+
}, [domainMany2Many]);
|
|
5596
|
+
const handleCreateNewOnPage = async () => {
|
|
5597
|
+
try {
|
|
5598
|
+
refetch();
|
|
5599
|
+
} catch (error) {
|
|
5600
|
+
console.log(error);
|
|
5601
|
+
}
|
|
5602
|
+
};
|
|
5473
5603
|
return {
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5604
|
+
handleCreateNewOnPage,
|
|
5605
|
+
optionsObject,
|
|
5606
|
+
rows,
|
|
5607
|
+
columns,
|
|
5608
|
+
typeTable,
|
|
5609
|
+
isDataLoading,
|
|
5610
|
+
isDataResponseFetched,
|
|
5611
|
+
isPlaceholderData
|
|
5477
5612
|
};
|
|
5478
5613
|
};
|
|
5479
5614
|
|
|
5480
|
-
// src/widget/
|
|
5481
|
-
var
|
|
5482
|
-
var
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
}
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5615
|
+
// src/widget/basic/many2many-tags-field/controller.ts
|
|
5616
|
+
var import_react16 = require("react");
|
|
5617
|
+
var import_constants4 = require("@fctc/interface-logic/constants");
|
|
5618
|
+
var import_environment7 = require("@fctc/interface-logic/environment");
|
|
5619
|
+
var import_hooks14 = require("@fctc/interface-logic/hooks");
|
|
5620
|
+
var import_utils7 = require("@fctc/interface-logic/utils");
|
|
5621
|
+
var many2manyTagsController = (props) => {
|
|
5622
|
+
const {
|
|
5623
|
+
relation,
|
|
5624
|
+
domain,
|
|
5625
|
+
options: optionsFields,
|
|
5626
|
+
widget,
|
|
5627
|
+
formValues,
|
|
5628
|
+
placeholderNoOption
|
|
5629
|
+
} = props;
|
|
5630
|
+
const isUser = relation === "res.users" || relation === "res.partner";
|
|
5631
|
+
const env = (0, import_environment7.getEnv)();
|
|
5632
|
+
const addtionalFields = optionsFields ? (0, import_utils7.evalJSONContext)(optionsFields) : null;
|
|
5633
|
+
const domainObject = (0, import_react16.useMemo)(
|
|
5634
|
+
() => (0, import_utils7.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues || {}))),
|
|
5635
|
+
[domain, formValues]
|
|
5636
|
+
);
|
|
5637
|
+
const data = {
|
|
5638
|
+
model: relation ?? "",
|
|
5639
|
+
domain: domainObject,
|
|
5640
|
+
specification: {
|
|
5641
|
+
id: {},
|
|
5642
|
+
name: {},
|
|
5643
|
+
display_name: {},
|
|
5644
|
+
...widget && import_constants4.WIDGETAVATAR[widget] ? { image_256: {} } : {},
|
|
5645
|
+
...widget && import_constants4.WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
|
|
5646
|
+
},
|
|
5647
|
+
enabled: true,
|
|
5648
|
+
context: env.context
|
|
5649
|
+
};
|
|
5650
|
+
const { data: dataOfSelection } = (0, import_hooks14.useGetSelection)({
|
|
5651
|
+
data,
|
|
5652
|
+
queryKey: [`data_${relation}`, domainObject]
|
|
5653
|
+
});
|
|
5654
|
+
const customNoOptionsMessage = () => placeholderNoOption;
|
|
5655
|
+
const tranfer = (data2) => {
|
|
5656
|
+
return data2?.map((val) => ({
|
|
5657
|
+
id: val.value,
|
|
5658
|
+
display_name: val.label
|
|
5659
|
+
})) || [];
|
|
5511
5660
|
};
|
|
5661
|
+
const options = dataOfSelection?.records?.map((val) => ({
|
|
5662
|
+
value: val.id,
|
|
5663
|
+
label: val.name ?? val.display_name,
|
|
5664
|
+
...val
|
|
5665
|
+
})) || [];
|
|
5512
5666
|
return {
|
|
5513
|
-
|
|
5667
|
+
options,
|
|
5668
|
+
customNoOptionsMessage,
|
|
5669
|
+
tranfer,
|
|
5670
|
+
dataOfSelection,
|
|
5671
|
+
isUser
|
|
5514
5672
|
};
|
|
5515
5673
|
};
|
|
5516
5674
|
|
|
5517
|
-
// src/widget/
|
|
5518
|
-
var
|
|
5519
|
-
var
|
|
5520
|
-
var
|
|
5521
|
-
var
|
|
5522
|
-
|
|
5523
|
-
const
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5675
|
+
// src/widget/basic/status-bar-field/controller.ts
|
|
5676
|
+
var import_react17 = require("react");
|
|
5677
|
+
var import_hooks15 = require("@fctc/interface-logic/hooks");
|
|
5678
|
+
var import_store9 = require("@fctc/interface-logic/store");
|
|
5679
|
+
var import_utils8 = require("@fctc/interface-logic/utils");
|
|
5680
|
+
var durationController = (props) => {
|
|
5681
|
+
const {
|
|
5682
|
+
relation,
|
|
5683
|
+
defaultValue,
|
|
5684
|
+
domain,
|
|
5685
|
+
formValues,
|
|
5686
|
+
name,
|
|
5687
|
+
id,
|
|
5688
|
+
model,
|
|
5689
|
+
onRefetch
|
|
5690
|
+
} = props;
|
|
5691
|
+
const specification = {
|
|
5692
|
+
id: 0,
|
|
5693
|
+
name: "",
|
|
5694
|
+
fold: ""
|
|
5695
|
+
};
|
|
5696
|
+
const [disabled, setDisabled] = (0, import_react17.useState)(false);
|
|
5697
|
+
const [modelStatus, setModalStatus] = (0, import_react17.useState)(false);
|
|
5698
|
+
const { context } = (0, import_store9.useAppSelector)(import_store9.selectEnv);
|
|
5699
|
+
const queryKey = [`data-status-duration`, specification];
|
|
5700
|
+
const listDataProps = {
|
|
5701
|
+
model: relation,
|
|
5702
|
+
specification,
|
|
5703
|
+
domain: (0, import_utils8.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues))),
|
|
5704
|
+
limit: 10,
|
|
5705
|
+
offset: 0,
|
|
5706
|
+
fields: "",
|
|
5707
|
+
groupby: [],
|
|
5708
|
+
context: {
|
|
5709
|
+
lang: context.lang
|
|
5710
|
+
},
|
|
5711
|
+
sort: ""
|
|
5712
|
+
};
|
|
5713
|
+
const { data: dataResponse } = (0, import_hooks15.useGetListData)(listDataProps, queryKey);
|
|
5714
|
+
const { mutate: fetchChangeStatus } = (0, import_hooks15.useChangeStatus)();
|
|
5715
|
+
const handleClick = async (stage_id) => {
|
|
5716
|
+
setDisabled(true);
|
|
5717
|
+
if (stage_id) {
|
|
5718
|
+
fetchChangeStatus(
|
|
5719
|
+
{
|
|
5720
|
+
data: {
|
|
5721
|
+
stage_id,
|
|
5722
|
+
name,
|
|
5723
|
+
id,
|
|
5724
|
+
model,
|
|
5725
|
+
lang: context.lang
|
|
5726
|
+
}
|
|
5727
|
+
},
|
|
5728
|
+
{
|
|
5729
|
+
onSuccess: (res) => {
|
|
5730
|
+
if (res) {
|
|
5731
|
+
setDisabled(false);
|
|
5732
|
+
onRefetch && onRefetch();
|
|
5543
5733
|
}
|
|
5544
|
-
transformedItem[field] = item[field];
|
|
5545
5734
|
}
|
|
5546
5735
|
}
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
});
|
|
5736
|
+
);
|
|
5737
|
+
}
|
|
5550
5738
|
};
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5739
|
+
return {
|
|
5740
|
+
defaultValue,
|
|
5741
|
+
dataResponse,
|
|
5742
|
+
handleClick,
|
|
5743
|
+
disabled,
|
|
5744
|
+
modelStatus,
|
|
5745
|
+
setModalStatus
|
|
5746
|
+
};
|
|
5747
|
+
};
|
|
5748
|
+
|
|
5749
|
+
// src/widget/basic/priority-field/controller.ts
|
|
5750
|
+
var import_hooks16 = require("@fctc/interface-logic/hooks");
|
|
5751
|
+
var import_utils9 = require("@fctc/interface-logic/utils");
|
|
5752
|
+
var priorityFieldController = (props) => {
|
|
5753
|
+
const {
|
|
5754
|
+
value,
|
|
5755
|
+
isForm,
|
|
5756
|
+
name,
|
|
5757
|
+
methods,
|
|
5758
|
+
onChange,
|
|
5759
|
+
model,
|
|
5760
|
+
selection,
|
|
5761
|
+
id,
|
|
5762
|
+
actionData,
|
|
5763
|
+
viewData,
|
|
5764
|
+
context
|
|
5765
|
+
} = props;
|
|
5766
|
+
const _context = { ...(0, import_utils9.evalJSONContext)(actionData?.context) };
|
|
5767
|
+
const contextObject = { ...context, ..._context };
|
|
5768
|
+
const defaultPriority = parseInt(value) + 1;
|
|
5769
|
+
const label = viewData?.models?.[model]?.[name ?? ""]?.string ?? name;
|
|
5770
|
+
const { mutateAsync: fetchSave } = (0, import_hooks16.useSave)();
|
|
5771
|
+
const savePriorities = async ({
|
|
5772
|
+
value: value2,
|
|
5773
|
+
resetPriority
|
|
5774
|
+
}) => {
|
|
5775
|
+
const priorityValue = value2 <= 0 ? 0 : value2 - 1;
|
|
5556
5776
|
try {
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
optional: field?.optional,
|
|
5563
|
-
title: field?.type_co === "button" ? "" : field?.string,
|
|
5564
|
-
field: { ...field }
|
|
5565
|
-
};
|
|
5777
|
+
fetchSave({
|
|
5778
|
+
ids: id ? [id] : [],
|
|
5779
|
+
data: { [name ?? ""]: String(priorityValue) },
|
|
5780
|
+
model: model ?? "",
|
|
5781
|
+
context: contextObject
|
|
5566
5782
|
});
|
|
5783
|
+
if (typeof onChange === "function") {
|
|
5784
|
+
onChange(name ?? "", String(priorityValue));
|
|
5785
|
+
}
|
|
5567
5786
|
} catch (error) {
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
return cols;
|
|
5571
|
-
};
|
|
5572
|
-
(0, import_react16.useEffect)(() => {
|
|
5573
|
-
const columns2 = handleGetColumns();
|
|
5574
|
-
setColumns(columns2);
|
|
5575
|
-
}, [data.records]);
|
|
5576
|
-
const onToggleColumnOptional = (item) => {
|
|
5577
|
-
const tempColumn = [...columns]?.map((val) => {
|
|
5578
|
-
if (item?.name === val?.name) {
|
|
5579
|
-
return {
|
|
5580
|
-
...val,
|
|
5581
|
-
optional: item?.optional === "show" ? "hide" : "show"
|
|
5582
|
-
};
|
|
5787
|
+
if (resetPriority) {
|
|
5788
|
+
resetPriority();
|
|
5583
5789
|
}
|
|
5584
|
-
|
|
5585
|
-
});
|
|
5586
|
-
setColumns(tempColumn);
|
|
5790
|
+
}
|
|
5587
5791
|
};
|
|
5588
5792
|
return {
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5793
|
+
selection,
|
|
5794
|
+
isForm,
|
|
5795
|
+
methods,
|
|
5796
|
+
defaultPriority,
|
|
5797
|
+
savePriorities,
|
|
5798
|
+
label,
|
|
5799
|
+
id,
|
|
5800
|
+
onChange
|
|
5593
5801
|
};
|
|
5594
5802
|
};
|
|
5595
5803
|
|
|
5596
|
-
// src/widget/
|
|
5597
|
-
var
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5804
|
+
// src/widget/basic/float-time-field/controller.ts
|
|
5805
|
+
var import_react18 = require("react");
|
|
5806
|
+
var import_utils10 = require("@fctc/interface-logic/utils");
|
|
5807
|
+
var floatTimeFiledController = ({
|
|
5808
|
+
onChange: fieldOnChange,
|
|
5809
|
+
onBlur,
|
|
5810
|
+
value,
|
|
5811
|
+
isDirty,
|
|
5812
|
+
props
|
|
5813
|
+
}) => {
|
|
5814
|
+
const { name, defaultValue = 0, onChange } = props;
|
|
5815
|
+
const [input, setInput] = (0, import_react18.useState)(
|
|
5816
|
+
(0, import_utils10.convertFloatToTime)(value ?? defaultValue)
|
|
5817
|
+
);
|
|
5818
|
+
const [formattedTime, setFormattedTime] = (0, import_react18.useState)("");
|
|
5819
|
+
const [errors, setErrors] = (0, import_react18.useState)("");
|
|
5820
|
+
const handleInputChange = (e) => {
|
|
5821
|
+
const raw = e.target.value.replace(/[^\d:]/g, "");
|
|
5822
|
+
setInput(raw);
|
|
5823
|
+
const timeRegex = /^(\d{1,2}):?(\d{0,2})$/;
|
|
5824
|
+
const match = raw.match(timeRegex);
|
|
5825
|
+
if (!match) {
|
|
5826
|
+
setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
|
|
5827
|
+
setFormattedTime("");
|
|
5828
|
+
return;
|
|
5829
|
+
}
|
|
5830
|
+
let hours = parseInt(match[1] ?? "0", 10);
|
|
5831
|
+
let minutes = parseInt(match[2] ?? "0", 10);
|
|
5832
|
+
if (isNaN(hours)) hours = 0;
|
|
5833
|
+
if (isNaN(minutes)) minutes = 0;
|
|
5834
|
+
if (hours >= 24) {
|
|
5835
|
+
hours = 0;
|
|
5836
|
+
}
|
|
5837
|
+
if (minutes >= 60) {
|
|
5838
|
+
minutes = 0;
|
|
5839
|
+
}
|
|
5840
|
+
const formatted = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
5841
|
+
setErrors("");
|
|
5842
|
+
setFormattedTime(formatted);
|
|
5843
|
+
fieldOnChange(formatted);
|
|
5844
|
+
};
|
|
5845
|
+
const handleBlur = () => {
|
|
5846
|
+
if (!isDirty) return;
|
|
5847
|
+
if (formattedTime) {
|
|
5848
|
+
setInput(formattedTime);
|
|
5849
|
+
const floatVal = (0, import_utils10.convertTimeToFloat)(formattedTime);
|
|
5850
|
+
fieldOnChange(floatVal);
|
|
5851
|
+
if (onChange) {
|
|
5852
|
+
onChange(name ?? "", floatVal);
|
|
5853
|
+
}
|
|
5854
|
+
} else {
|
|
5855
|
+
setInput("00:00");
|
|
5856
|
+
fieldOnChange(0);
|
|
5857
|
+
if (onChange) {
|
|
5858
|
+
onChange(name ?? "", 0);
|
|
5859
|
+
}
|
|
5860
|
+
setErrors("");
|
|
5861
|
+
}
|
|
5862
|
+
onBlur();
|
|
5863
|
+
};
|
|
5864
|
+
const handleKeyDown = (e) => {
|
|
5865
|
+
{
|
|
5866
|
+
const allowed = [
|
|
5867
|
+
"Backspace",
|
|
5868
|
+
"Tab",
|
|
5869
|
+
"ArrowLeft",
|
|
5870
|
+
"ArrowRight",
|
|
5871
|
+
"Delete",
|
|
5872
|
+
"Home",
|
|
5873
|
+
"End",
|
|
5874
|
+
":"
|
|
5875
|
+
];
|
|
5876
|
+
const isNumber = /^[0-9]$/.test(e.key);
|
|
5877
|
+
if (!isNumber && !allowed.includes(e.key)) {
|
|
5878
|
+
e.preventDefault();
|
|
5879
|
+
}
|
|
5880
|
+
}
|
|
5881
|
+
};
|
|
5882
|
+
return {
|
|
5883
|
+
handleInputChange,
|
|
5884
|
+
handleBlur,
|
|
5885
|
+
handleKeyDown,
|
|
5886
|
+
input,
|
|
5887
|
+
errors
|
|
5888
|
+
};
|
|
5889
|
+
};
|
|
5890
|
+
|
|
5891
|
+
// src/widget/basic/float-field/controller.ts
|
|
5892
|
+
var import_react19 = require("react");
|
|
5893
|
+
|
|
5894
|
+
// src/utils/i18n.ts
|
|
5895
|
+
var import_react_i18next2 = require("react-i18next");
|
|
5896
|
+
var import_i18next = __toESM(require("i18next"));
|
|
5897
|
+
var import_i18next_browser_languagedetector = __toESM(require("i18next-browser-languagedetector"));
|
|
5898
|
+
|
|
5899
|
+
// src/locales/vi.json
|
|
5900
|
+
var vi_default = {
|
|
5901
|
+
login: "\u0110\u0103ng Nh\u1EADp",
|
|
5902
|
+
english: "Ti\u1EBFng Anh",
|
|
5903
|
+
vietnamese: "Ti\u1EBFng Vi\u1EC7t",
|
|
5609
5904
|
note_login: "Xin h\xE3y \u0111\u0103ng nh\u1EADp v\xE0o t\xE0i kho\u1EA3n c\u1EE7a b\u1EA1n",
|
|
5610
5905
|
"note-forgotpassword": "Vui l\xF2ng nh\u1EADp \u0111\u1ECBa ch\u1EC9 email b\u1EA1n mu\u1ED1n th\xF4ng tin \u0111\u1EB7t l\u1EA1i m\u1EADt kh\u1EA9u c\u1EE7a b\u1EA1n \u0111\u01B0\u1EE3c g\u1EEDi t\u1EDBi ",
|
|
5611
5906
|
placeholder_email: "Nh\u1EADp \u0111\u1ECBa ch\u1EC9 email c\u1EE7a b\u1EA1n",
|
|
@@ -6362,1301 +6657,1064 @@ import_i18next.default.use(import_i18next_browser_languagedetector.default).use(
|
|
|
6362
6657
|
});
|
|
6363
6658
|
var i18n_default = import_i18next.default;
|
|
6364
6659
|
|
|
6365
|
-
// src/widget/
|
|
6366
|
-
var
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
viewData,
|
|
6383
|
-
renderField,
|
|
6384
|
-
level,
|
|
6385
|
-
specification,
|
|
6386
|
-
domain,
|
|
6387
|
-
context,
|
|
6388
|
-
checkedAll,
|
|
6389
|
-
isDisplayCheckbox,
|
|
6390
|
-
isAutoSelect,
|
|
6391
|
-
setIsAutoSelect,
|
|
6392
|
-
selectedRowKeysRef
|
|
6393
|
-
} = props;
|
|
6394
|
-
const [pageGroup, setPageGroup] = (0, import_react17.useState)(0);
|
|
6395
|
-
const { groupByDomain, selectedTags } = (0, import_store11.useAppSelector)(import_store11.selectSearch);
|
|
6396
|
-
const { selectedRowKeys } = (0, import_store11.useAppSelector)(import_store11.selectList);
|
|
6397
|
-
const appDispatch = (0, import_store11.useAppDispatch)();
|
|
6398
|
-
const { toDataJS } = (0, import_hooks13.useOdooDataTransform)();
|
|
6399
|
-
const initVal = toDataJS(row, viewData, model);
|
|
6400
|
-
const [isShowGroup, setIsShowGroup] = (0, import_react17.useState)(false);
|
|
6401
|
-
const [colEmptyGroup, setColEmptyGroup] = (0, import_react17.useState)({
|
|
6402
|
-
fromStart: 1,
|
|
6403
|
-
fromEnd: 1
|
|
6404
|
-
});
|
|
6405
|
-
const processedData = (0, import_react17.useMemo)(() => {
|
|
6406
|
-
const calculateColSpanEmpty = () => {
|
|
6407
|
-
const startIndex = columns.findIndex(
|
|
6408
|
-
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
|
|
6409
|
-
);
|
|
6410
|
-
const endIndex = columns.findLastIndex(
|
|
6411
|
-
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
|
|
6412
|
-
);
|
|
6413
|
-
const fromStart = startIndex === -1 ? columns.length : startIndex;
|
|
6414
|
-
const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
|
|
6415
|
-
setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
|
|
6416
|
-
return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
|
|
6417
|
-
};
|
|
6418
|
-
return calculateColSpanEmpty();
|
|
6419
|
-
}, [columns, row]);
|
|
6420
|
-
const shouldFetchData = (0, import_react17.useMemo)(() => {
|
|
6421
|
-
return !!isShowGroup;
|
|
6422
|
-
}, [isShowGroup]);
|
|
6423
|
-
const enabled = shouldFetchData && !!processedData;
|
|
6424
|
-
const listDataProps = {
|
|
6425
|
-
model,
|
|
6426
|
-
specification,
|
|
6427
|
-
domain,
|
|
6428
|
-
context,
|
|
6429
|
-
offset: pageGroup * 10,
|
|
6430
|
-
fields: groupByDomain?.fields,
|
|
6431
|
-
groupby: [groupByDomain?.contexts[level]?.group_by]
|
|
6432
|
-
};
|
|
6433
|
-
const queryKey = [
|
|
6434
|
-
`data-${model}--${level}-row${indexRow}`,
|
|
6435
|
-
specification,
|
|
6436
|
-
domain,
|
|
6437
|
-
pageGroup
|
|
6438
|
-
];
|
|
6439
|
-
const {
|
|
6440
|
-
data: dataResponse,
|
|
6441
|
-
isFetched: isQueryFetched,
|
|
6442
|
-
isPlaceholderData,
|
|
6443
|
-
isLoading,
|
|
6444
|
-
isFetching
|
|
6445
|
-
} = (0, import_hooks13.useGetListData)(listDataProps, queryKey, enabled);
|
|
6446
|
-
const {
|
|
6447
|
-
columns: columnsGroup,
|
|
6448
|
-
rows: rowsGroup,
|
|
6449
|
-
typeTable: typeTableGroup
|
|
6450
|
-
} = tableController({
|
|
6451
|
-
data: {
|
|
6452
|
-
fields: viewData?.views?.list?.fields,
|
|
6453
|
-
records: dataResponse?.records ?? dataResponse?.groups,
|
|
6454
|
-
dataModel: viewData?.models?.[model],
|
|
6455
|
-
context: env.context,
|
|
6456
|
-
typeTable: dataResponse?.groups ? "group" : "list"
|
|
6457
|
-
}
|
|
6458
|
-
});
|
|
6459
|
-
const leftPadding = level > 1 ? level * 8 + "px" : "0px";
|
|
6460
|
-
(0, import_react17.useEffect)(() => {
|
|
6461
|
-
if (isShowGroup && selectedTags?.length > 0) {
|
|
6462
|
-
setIsShowGroup(false);
|
|
6463
|
-
}
|
|
6464
|
-
}, [selectedTags]);
|
|
6465
|
-
const group_by_field_name = groupByDomain?.contexts[level - 1]?.group_by;
|
|
6466
|
-
const nameGroup = Array.isArray(row[group_by_field_name]) ? row?.string ?? row[`${group_by_field_name}`][1] : viewData?.models?.[model]?.[group_by_field_name]?.selection ? viewData.models[model][group_by_field_name].selection.find(
|
|
6467
|
-
(selectItem) => selectItem?.[0] === row[group_by_field_name]
|
|
6468
|
-
)?.[1] : row[group_by_field_name];
|
|
6469
|
-
const nameGroupWithCount = `${typeof nameGroup === "string" ? nameGroup : typeof nameGroup === "boolean" && nameGroup ? i18n_default.t("yes") : i18n_default.t("no")} (${row[`${group_by_field_name?.split(":")?.[0]}_count`]})`;
|
|
6470
|
-
const allIdsNull = selectedRowKeys?.every((item) => item === void 0);
|
|
6471
|
-
const handleExpandChildGroup = () => {
|
|
6472
|
-
if (isLoading || isFetching) return;
|
|
6473
|
-
const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
|
|
6474
|
-
if (allIdsNull || typeTableGroup === "group") {
|
|
6475
|
-
toggleShowGroup();
|
|
6476
|
-
return;
|
|
6660
|
+
// src/widget/basic/float-field/controller.ts
|
|
6661
|
+
var floatController = ({
|
|
6662
|
+
onChange,
|
|
6663
|
+
value,
|
|
6664
|
+
props
|
|
6665
|
+
}) => {
|
|
6666
|
+
const { name, required, methods, onChange: handleOnchange, string } = props;
|
|
6667
|
+
const { setError, clearErrors } = methods;
|
|
6668
|
+
const [inputValue, setInputValue] = (0, import_react19.useState)(
|
|
6669
|
+
value !== void 0 && value !== null ? useFormatFloatNumber(value) : ""
|
|
6670
|
+
);
|
|
6671
|
+
(0, import_react19.useEffect)(() => {
|
|
6672
|
+
if (value !== void 0 && value !== null && value !== parseFloat(inputValue?.replace(/,/g, ""))) {
|
|
6673
|
+
setInputValue(useFormatFloatNumber(value));
|
|
6674
|
+
clearErrors(name);
|
|
6675
|
+
} else if (value === null || value === void 0) {
|
|
6676
|
+
setInputValue("");
|
|
6477
6677
|
}
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6678
|
+
}, [value, name, clearErrors]);
|
|
6679
|
+
const isDirtyRef = (0, import_react19.useRef)(false);
|
|
6680
|
+
const inputRef = (0, import_react19.useRef)(null);
|
|
6681
|
+
const lastCommittedValueRef = (0, import_react19.useRef)(null);
|
|
6682
|
+
const handleInputChange = (e) => {
|
|
6683
|
+
const newValue = e.target.value;
|
|
6684
|
+
const valueWithoutCommas = newValue.replace(/,/g, "");
|
|
6685
|
+
if (/^[0-9]*[.,]?[0-9]*$/.test(valueWithoutCommas) || newValue === "") {
|
|
6686
|
+
const parts = valueWithoutCommas.split(".");
|
|
6687
|
+
let integerPart = parts[0] || "";
|
|
6688
|
+
const decimalPart = parts[1] || "";
|
|
6689
|
+
if (decimalPart.length > 100) return;
|
|
6690
|
+
if (integerPart) {
|
|
6691
|
+
integerPart = Number(integerPart).toLocaleString("en-US");
|
|
6692
|
+
}
|
|
6693
|
+
const formattedValue = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
|
|
6694
|
+
setInputValue(formattedValue);
|
|
6695
|
+
const parsedValue = parseFloat(valueWithoutCommas.replace(",", "."));
|
|
6696
|
+
if (!isNaN(parsedValue)) {
|
|
6697
|
+
if (parsedValue < 0) {
|
|
6698
|
+
setError(name, {
|
|
6699
|
+
type: "validate",
|
|
6700
|
+
message: i18n_default.t("invalid_number")
|
|
6701
|
+
});
|
|
6702
|
+
} else {
|
|
6703
|
+
onChange(parsedValue);
|
|
6704
|
+
clearErrors(name);
|
|
6705
|
+
isDirtyRef.current = true;
|
|
6706
|
+
}
|
|
6707
|
+
} else {
|
|
6708
|
+
onChange(null);
|
|
6709
|
+
clearErrors(name);
|
|
6710
|
+
}
|
|
6491
6711
|
}
|
|
6492
|
-
toggleShowGroup();
|
|
6493
6712
|
};
|
|
6494
|
-
|
|
6495
|
-
if (!
|
|
6713
|
+
const handleInputMouseLeave = () => {
|
|
6714
|
+
if (!isDirtyRef.current) {
|
|
6715
|
+
inputRef.current?.blur();
|
|
6496
6716
|
return;
|
|
6497
6717
|
}
|
|
6498
|
-
const
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
isShowGroup,
|
|
6507
|
-
isQueryFetched,
|
|
6508
|
-
nameGroupWithCount,
|
|
6509
|
-
columns,
|
|
6510
|
-
row,
|
|
6511
|
-
isPlaceholderData,
|
|
6512
|
-
columnsGroup,
|
|
6513
|
-
indexRow,
|
|
6514
|
-
rowsGroup,
|
|
6515
|
-
model,
|
|
6516
|
-
viewData,
|
|
6517
|
-
renderField,
|
|
6518
|
-
level,
|
|
6519
|
-
specification,
|
|
6520
|
-
context,
|
|
6521
|
-
checkedAll,
|
|
6522
|
-
isDisplayCheckbox,
|
|
6523
|
-
isAutoSelect,
|
|
6524
|
-
setIsAutoSelect,
|
|
6525
|
-
selectedRowKeysRef,
|
|
6526
|
-
initVal,
|
|
6527
|
-
dataResponse,
|
|
6528
|
-
pageGroup,
|
|
6529
|
-
setPageGroup
|
|
6530
|
-
};
|
|
6531
|
-
};
|
|
6532
|
-
|
|
6533
|
-
// src/widget/advance/search/controller.ts
|
|
6534
|
-
var import_constants3 = require("@fctc/interface-logic/constants");
|
|
6535
|
-
var import_utils6 = require("@fctc/interface-logic/utils");
|
|
6536
|
-
var import_react18 = require("react");
|
|
6537
|
-
var searchController = ({
|
|
6538
|
-
viewData,
|
|
6539
|
-
actionData,
|
|
6540
|
-
fieldsList,
|
|
6541
|
-
contextSearch,
|
|
6542
|
-
setSearchMap,
|
|
6543
|
-
searchMap
|
|
6544
|
-
}) => {
|
|
6545
|
-
const [filterBy, setFilterBy] = (0, import_react18.useState)(null);
|
|
6546
|
-
const [searchBy, setSearchBy] = (0, import_react18.useState)(null);
|
|
6547
|
-
const [groupBy, setGroupBy] = (0, import_react18.useState)(null);
|
|
6548
|
-
const [selectedTags, setSelectedTags] = (0, import_react18.useState)(null);
|
|
6549
|
-
const [searchString, setSearchString] = (0, import_react18.useState)("");
|
|
6550
|
-
const aid = actionData?.id;
|
|
6551
|
-
const model = actionData?.res_model;
|
|
6552
|
-
const clearSearch = () => {
|
|
6553
|
-
setFilterBy([]);
|
|
6554
|
-
setGroupBy([]);
|
|
6555
|
-
setSearchBy([]);
|
|
6556
|
-
setSelectedTags(null);
|
|
6557
|
-
setSearchString("");
|
|
6558
|
-
setSearchMap({});
|
|
6559
|
-
};
|
|
6560
|
-
const fetchData = async () => {
|
|
6561
|
-
if (viewData) {
|
|
6562
|
-
try {
|
|
6563
|
-
const dataModel = viewData?.models?.[model];
|
|
6564
|
-
const searchViews = viewData?.views?.search;
|
|
6565
|
-
const searchByItems = searchViews?.search_by?.filter(
|
|
6566
|
-
(item) => !import_utils6.domainHelper.matchDomains(contextSearch, item.invisible)
|
|
6567
|
-
)?.map(
|
|
6568
|
-
({ string, name, filter_domain, operator, widget }, index) => ({
|
|
6569
|
-
dataIndex: index,
|
|
6570
|
-
title: string ?? dataModel[name]?.string,
|
|
6571
|
-
name: name ?? dataModel[name]?.name,
|
|
6572
|
-
filter_domain,
|
|
6573
|
-
operator,
|
|
6574
|
-
widget,
|
|
6575
|
-
type: dataModel[name]?.type
|
|
6576
|
-
})
|
|
6577
|
-
);
|
|
6578
|
-
const filterByItems = searchViews?.filter_by.filter((item) => {
|
|
6579
|
-
return !import_utils6.domainHelper.matchDomains(contextSearch, item?.invisible);
|
|
6580
|
-
})?.map((item) => ({ ...item, active: false }));
|
|
6581
|
-
const groupByItems = searchViews?.group_by.filter(
|
|
6582
|
-
(item) => !import_utils6.domainHelper.matchDomains(contextSearch, item?.invisible)
|
|
6583
|
-
).map((item) => ({
|
|
6584
|
-
...item,
|
|
6585
|
-
string: item.string ?? viewData?.models?.[model]?.[item?.name?.split("group_by_")?.[1]]?.string
|
|
6586
|
-
}));
|
|
6587
|
-
setSearchBy(searchByItems);
|
|
6588
|
-
setFilterBy(filterByItems);
|
|
6589
|
-
setGroupBy(groupByItems);
|
|
6590
|
-
} catch (error) {
|
|
6591
|
-
console.error("Error fetching data:", error);
|
|
6718
|
+
const rawValue = inputValue.replace(/,/g, "");
|
|
6719
|
+
const parsedValue = parseFloat(rawValue);
|
|
6720
|
+
if (rawValue === "" || rawValue === ".") {
|
|
6721
|
+
if (required) {
|
|
6722
|
+
setError(name, {
|
|
6723
|
+
type: "required",
|
|
6724
|
+
message: `${string} ${i18n_default.t("must_required")}`
|
|
6725
|
+
});
|
|
6592
6726
|
}
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
item
|
|
6605
|
-
}) => {
|
|
6606
|
-
const values = searchMap[key];
|
|
6607
|
-
if (!values) return searchMap;
|
|
6608
|
-
const newSearchMap = { ...searchMap };
|
|
6609
|
-
if (item) {
|
|
6610
|
-
const filtered = values.filter((value) => value.name !== item.name);
|
|
6611
|
-
if (filtered.length > 0) {
|
|
6612
|
-
newSearchMap[key] = filtered;
|
|
6727
|
+
onChange(null);
|
|
6728
|
+
setInputValue("");
|
|
6729
|
+
lastCommittedValueRef.current = null;
|
|
6730
|
+
} else if (!isNaN(parsedValue)) {
|
|
6731
|
+
if (parsedValue < 0) {
|
|
6732
|
+
setError(name, {
|
|
6733
|
+
type: "validate",
|
|
6734
|
+
message: i18n_default.t("invalid_number")
|
|
6735
|
+
});
|
|
6736
|
+
setInputValue("");
|
|
6737
|
+
lastCommittedValueRef.current = null;
|
|
6613
6738
|
} else {
|
|
6614
|
-
|
|
6739
|
+
if (lastCommittedValueRef.current !== parsedValue) {
|
|
6740
|
+
const parts = rawValue.split(".");
|
|
6741
|
+
let integerPart = parts[0];
|
|
6742
|
+
const decimalPart = parts[1] || "";
|
|
6743
|
+
integerPart = Number(integerPart).toLocaleString("en-US");
|
|
6744
|
+
const formattedValue = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
|
|
6745
|
+
onChange(parsedValue);
|
|
6746
|
+
setInputValue(formattedValue);
|
|
6747
|
+
handleOnchange?.(name ?? "", parsedValue);
|
|
6748
|
+
clearErrors(name);
|
|
6749
|
+
lastCommittedValueRef.current = parsedValue;
|
|
6750
|
+
}
|
|
6615
6751
|
}
|
|
6616
6752
|
} else {
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
};
|
|
6621
|
-
const updateSearchMap = ({ key, item }) => {
|
|
6622
|
-
const newSearchMap = { ...searchMap };
|
|
6623
|
-
const currentValues = searchMap[key] ?? [];
|
|
6624
|
-
newSearchMap[key] = [...currentValues, item];
|
|
6625
|
-
setSearchMap(newSearchMap);
|
|
6626
|
-
};
|
|
6627
|
-
const removeSearchItems = (key, item) => {
|
|
6628
|
-
removeKeyFromSearchMap({ key: String(key), item });
|
|
6629
|
-
};
|
|
6630
|
-
const addSearchItems = (key, newItem) => {
|
|
6631
|
-
updateSearchMap({ key, item: newItem });
|
|
6632
|
-
};
|
|
6633
|
-
const setTagSearch = (0, import_react18.useCallback)(
|
|
6634
|
-
(updatedMap) => {
|
|
6635
|
-
if (!updatedMap) return;
|
|
6636
|
-
const tagsSearch = Object.entries(updatedMap).map(
|
|
6637
|
-
([key, objValues]) => {
|
|
6638
|
-
const {
|
|
6639
|
-
title,
|
|
6640
|
-
name,
|
|
6641
|
-
groupIndex,
|
|
6642
|
-
type,
|
|
6643
|
-
widget,
|
|
6644
|
-
modelType,
|
|
6645
|
-
dataIndex
|
|
6646
|
-
} = objValues[0];
|
|
6647
|
-
if (!key?.includes(import_constants3.SearchType.GROUP)) {
|
|
6648
|
-
const values = objValues?.map((objValue) => objValue.value);
|
|
6649
|
-
return {
|
|
6650
|
-
title,
|
|
6651
|
-
name: type === import_constants3.SearchType.SEARCH ? `${import_constants3.SearchType.SEARCH}_${String(dataIndex)}` : groupIndex ?? name,
|
|
6652
|
-
values,
|
|
6653
|
-
type,
|
|
6654
|
-
widget,
|
|
6655
|
-
modelType
|
|
6656
|
-
};
|
|
6657
|
-
} else {
|
|
6658
|
-
const contexts = [];
|
|
6659
|
-
let groupValues = [];
|
|
6660
|
-
objValues?.forEach((objValue) => {
|
|
6661
|
-
const { context, value, active, groupIndex: groupIndex2, isDefault } = objValue;
|
|
6662
|
-
const indexAppend = groupIndex2 != null ? groupIndex2 : viewData?.views?.search?.filters_by?.length ?? 0;
|
|
6663
|
-
contexts.push(
|
|
6664
|
-
...Array.isArray(context?.group_by) ? context.group_by.map((item) => ({ group_by: item })) : [context]
|
|
6665
|
-
);
|
|
6666
|
-
groupValues[indexAppend] = {
|
|
6667
|
-
contexts: [
|
|
6668
|
-
...Array.isArray(context?.group_by) ? context.group_by.map((item) => ({
|
|
6669
|
-
group_by: item
|
|
6670
|
-
})) : [context]
|
|
6671
|
-
],
|
|
6672
|
-
strings: isDefault ? [value] : [...groupValues[indexAppend]?.strings ?? [], value]
|
|
6673
|
-
};
|
|
6674
|
-
});
|
|
6675
|
-
const fields = [
|
|
6676
|
-
...new Set(fieldsList?.map((item) => item?.name))
|
|
6677
|
-
];
|
|
6678
|
-
const groupByTag = {
|
|
6679
|
-
title,
|
|
6680
|
-
values: groupValues?.filter(
|
|
6681
|
-
(item) => item !== void 0
|
|
6682
|
-
),
|
|
6683
|
-
type,
|
|
6684
|
-
contexts,
|
|
6685
|
-
fields
|
|
6686
|
-
};
|
|
6687
|
-
return groupByTag;
|
|
6688
|
-
}
|
|
6689
|
-
}
|
|
6690
|
-
);
|
|
6691
|
-
setSelectedTags(tagsSearch);
|
|
6692
|
-
setSearchString("");
|
|
6693
|
-
},
|
|
6694
|
-
[searchMap]
|
|
6695
|
-
);
|
|
6696
|
-
(0, import_react18.useEffect)(() => {
|
|
6697
|
-
setSelectedTags(null);
|
|
6698
|
-
setTagSearch(searchMap);
|
|
6699
|
-
}, [searchMap]);
|
|
6700
|
-
const handleAddTagSearch = (tag) => {
|
|
6701
|
-
const {
|
|
6702
|
-
domain,
|
|
6703
|
-
groupIndex,
|
|
6704
|
-
value,
|
|
6705
|
-
type,
|
|
6706
|
-
title,
|
|
6707
|
-
context,
|
|
6708
|
-
active,
|
|
6709
|
-
dataIndex
|
|
6710
|
-
} = tag;
|
|
6711
|
-
const domainFormat = new import_utils6.domainHelper.Domain(domain);
|
|
6712
|
-
if (type === import_constants3.SearchType.FILTER) {
|
|
6713
|
-
addSearchItems(`${import_constants3.SearchType.FILTER}_${groupIndex}`, {
|
|
6714
|
-
...tag,
|
|
6715
|
-
domain: domain ? domainFormat.toList(context) : null
|
|
6716
|
-
});
|
|
6717
|
-
} else if (type === import_constants3.SearchType.SEARCH) {
|
|
6718
|
-
addSearchItems(`${import_constants3.SearchType.SEARCH}_${String(dataIndex)}`, {
|
|
6719
|
-
...tag,
|
|
6720
|
-
domain: domain ? domainFormat.toList({
|
|
6721
|
-
...context,
|
|
6722
|
-
self: value
|
|
6723
|
-
}) : null
|
|
6724
|
-
});
|
|
6725
|
-
} else if (type === import_constants3.SearchType.GROUP) {
|
|
6726
|
-
addSearchItems(`${import_constants3.SearchType.GROUP}`, {
|
|
6727
|
-
...tag,
|
|
6728
|
-
domain: domain ? domainFormat.toList({
|
|
6729
|
-
context,
|
|
6730
|
-
self: value
|
|
6731
|
-
}) : null
|
|
6753
|
+
setError(name, {
|
|
6754
|
+
type: "validate",
|
|
6755
|
+
message: i18n_default.t("invalid_number")
|
|
6732
6756
|
});
|
|
6757
|
+
setInputValue("");
|
|
6758
|
+
lastCommittedValueRef.current = null;
|
|
6733
6759
|
}
|
|
6760
|
+
isDirtyRef.current = false;
|
|
6761
|
+
inputRef.current?.blur();
|
|
6734
6762
|
};
|
|
6735
6763
|
return {
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
};
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
var
|
|
6755
|
-
var
|
|
6756
|
-
|
|
6757
|
-
const
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
options,
|
|
6770
|
-
sessionStorageUtils
|
|
6771
|
-
} = props;
|
|
6772
|
-
const appDispatch = (0, import_store12.useAppDispatch)();
|
|
6773
|
-
const actionData = sessionStorageUtils.getActionData();
|
|
6774
|
-
const [debouncedPage] = useDebounce(page, 500);
|
|
6775
|
-
const [order, setOrder] = (0, import_react19.useState)();
|
|
6776
|
-
const [isLoadedData, setIsLoadedData] = (0, import_react19.useState)(false);
|
|
6777
|
-
const [domainMany2Many, setDomainMany2Many] = (0, import_react19.useState)(domain);
|
|
6778
|
-
const env = (0, import_environment8.getEnv)();
|
|
6779
|
-
const { selectedTags } = (0, import_store12.useAppSelector)(import_store12.selectSearch);
|
|
6780
|
-
const viewParams = {
|
|
6781
|
-
model: relation,
|
|
6782
|
-
views: [
|
|
6783
|
-
[false, "list"],
|
|
6784
|
-
[false, "search"]
|
|
6785
|
-
],
|
|
6786
|
-
context
|
|
6787
|
-
};
|
|
6788
|
-
const { data: viewResponse, isFetched: isViewReponseFetched } = (0, hooks_exports.useGetView)(
|
|
6789
|
-
viewParams,
|
|
6790
|
-
actionData
|
|
6791
|
-
);
|
|
6792
|
-
const baseModel = (0, import_react19.useMemo)(
|
|
6793
|
-
() => ({
|
|
6794
|
-
name: String(relation),
|
|
6795
|
-
view: viewResponse || {},
|
|
6796
|
-
actContext: context,
|
|
6797
|
-
fields: [
|
|
6798
|
-
...Object.values(viewResponse?.views?.list?.fields ?? {}),
|
|
6799
|
-
...tab?.fields ? tab.fields : []
|
|
6800
|
-
]
|
|
6801
|
-
}),
|
|
6802
|
-
[model, viewResponse]
|
|
6803
|
-
);
|
|
6804
|
-
const initModel = (0, hooks_exports.useModel)();
|
|
6805
|
-
const modelInstance = (0, import_react19.useMemo)(() => {
|
|
6806
|
-
if (viewResponse) {
|
|
6807
|
-
return initModel.initModel(baseModel);
|
|
6808
|
-
}
|
|
6809
|
-
return null;
|
|
6810
|
-
}, [baseModel, viewResponse]);
|
|
6811
|
-
const specification = (0, import_react19.useMemo)(() => {
|
|
6812
|
-
if (modelInstance) {
|
|
6813
|
-
return modelInstance.getSpecification();
|
|
6814
|
-
}
|
|
6815
|
-
return null;
|
|
6816
|
-
}, [modelInstance]);
|
|
6817
|
-
const default_order = viewResponse && viewResponse?.views?.list?.default_order;
|
|
6818
|
-
const optionsObject = tab?.options ? (0, import_utils7.evalJSONContext)(tab?.options) : (options ? (0, import_utils7.evalJSONContext)(options) : {}) || {};
|
|
6819
|
-
const fetchData = async () => {
|
|
6820
|
-
try {
|
|
6821
|
-
setDomainMany2Many(domain);
|
|
6822
|
-
appDispatch((0, import_store12.setFirstDomain)(domain));
|
|
6823
|
-
appDispatch((0, import_store12.setViewDataStore)(viewResponse));
|
|
6824
|
-
const modalData = viewResponse?.views?.list?.fields.map((field) => ({
|
|
6825
|
-
...viewResponse?.models?.[String(model)]?.[field?.name],
|
|
6826
|
-
...field
|
|
6827
|
-
}));
|
|
6828
|
-
if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
|
|
6829
|
-
setFields({
|
|
6830
|
-
...fields,
|
|
6831
|
-
[`${aid}_${relation}_popupmany2many`]: modalData
|
|
6832
|
-
});
|
|
6833
|
-
}
|
|
6834
|
-
appDispatch((0, import_store12.setPage)(0));
|
|
6835
|
-
} catch (err) {
|
|
6836
|
-
console.log(err);
|
|
6837
|
-
}
|
|
6838
|
-
};
|
|
6839
|
-
const queryKey = [
|
|
6840
|
-
`view-${relation}-${aid}`,
|
|
6841
|
-
specification,
|
|
6842
|
-
domainMany2Many,
|
|
6843
|
-
debouncedPage,
|
|
6844
|
-
groupByDomain,
|
|
6845
|
-
order
|
|
6846
|
-
];
|
|
6847
|
-
const data = {
|
|
6848
|
-
model: relation,
|
|
6849
|
-
specification,
|
|
6850
|
-
domain: domainMany2Many,
|
|
6851
|
-
offset: debouncedPage * 10,
|
|
6852
|
-
limit: 10,
|
|
6853
|
-
context,
|
|
6854
|
-
fields: groupByDomain?.fields,
|
|
6855
|
-
groupby: [groupByDomain?.contexts[0]?.group_by],
|
|
6856
|
-
sort: order ? order : default_order ? (0, import_utils7.formatSortingString)(default_order) : ""
|
|
6857
|
-
};
|
|
6858
|
-
const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
|
|
6859
|
-
const {
|
|
6860
|
-
data: dataResponse,
|
|
6861
|
-
isLoading: isDataLoading,
|
|
6862
|
-
isFetched: isDataResponseFetched,
|
|
6863
|
-
isPlaceholderData
|
|
6864
|
-
} = (0, hooks_exports.useGetListData)(data, queryKey, enabled);
|
|
6865
|
-
(0, import_react19.useEffect)(() => {
|
|
6866
|
-
if (viewResponse) {
|
|
6867
|
-
fetchData();
|
|
6868
|
-
}
|
|
6869
|
-
return () => {
|
|
6870
|
-
appDispatch((0, import_store12.setGroupByDomain)(null));
|
|
6871
|
-
setFields((prevFields) => ({
|
|
6872
|
-
...prevFields,
|
|
6873
|
-
[`${aid}_${relation}_popupmany2many`]: null
|
|
6874
|
-
}));
|
|
6875
|
-
appDispatch((0, import_store12.setPage)(0));
|
|
6876
|
-
setSelectedRowKeys4([]);
|
|
6877
|
-
setDomainMany2Many(null);
|
|
6878
|
-
setIsLoadedData(false);
|
|
6879
|
-
};
|
|
6880
|
-
}, [viewResponse]);
|
|
6881
|
-
const { rows, columns, typeTable } = tableController({
|
|
6882
|
-
data: {
|
|
6883
|
-
fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
|
|
6884
|
-
records: dataResponse?.records ?? dataResponse?.groups,
|
|
6885
|
-
dataModel: viewResponse?.models?.[String(relation)],
|
|
6886
|
-
context: { ...env.context, ...context },
|
|
6887
|
-
typeTable: dataResponse?.groups ? "group" : "list"
|
|
6888
|
-
}
|
|
6889
|
-
});
|
|
6890
|
-
const dataFormView = {
|
|
6891
|
-
id: null,
|
|
6892
|
-
model: relation,
|
|
6893
|
-
context
|
|
6894
|
-
};
|
|
6895
|
-
const {
|
|
6896
|
-
refetch,
|
|
6897
|
-
data: dataFormViewResponse,
|
|
6898
|
-
isSuccess
|
|
6899
|
-
} = (0, hooks_exports.useGetFormView)({
|
|
6900
|
-
data: dataFormView,
|
|
6901
|
-
queryKey: [`form-view-action-${relation}`],
|
|
6902
|
-
enabled: false
|
|
6903
|
-
});
|
|
6904
|
-
(0, import_react19.useEffect)(() => {
|
|
6905
|
-
if (isSuccess && dataFormViewResponse) {
|
|
6906
|
-
sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
|
|
6907
|
-
window.location.href = `/form/menu?model=${relation}`;
|
|
6908
|
-
}
|
|
6909
|
-
}, [isSuccess]);
|
|
6910
|
-
(0, import_react19.useEffect)(() => {
|
|
6911
|
-
if (domainMany2Many && !isLoadedData) {
|
|
6912
|
-
setIsLoadedData(true);
|
|
6913
|
-
}
|
|
6914
|
-
}, [domainMany2Many]);
|
|
6915
|
-
const handleCreateNewOnPage = async () => {
|
|
6916
|
-
try {
|
|
6917
|
-
refetch();
|
|
6918
|
-
} catch (error) {
|
|
6919
|
-
console.log(error);
|
|
6920
|
-
}
|
|
6921
|
-
};
|
|
6922
|
-
return {};
|
|
6923
|
-
};
|
|
6924
|
-
|
|
6925
|
-
// src/widget/basic/many2many-tags-field/controller.ts
|
|
6926
|
-
var import_react20 = require("react");
|
|
6927
|
-
var import_constants4 = require("@fctc/interface-logic/constants");
|
|
6928
|
-
var import_environment9 = require("@fctc/interface-logic/environment");
|
|
6929
|
-
var import_hooks15 = require("@fctc/interface-logic/hooks");
|
|
6930
|
-
var import_utils8 = require("@fctc/interface-logic/utils");
|
|
6931
|
-
var many2manyTagsController = (props) => {
|
|
6932
|
-
const {
|
|
6933
|
-
relation,
|
|
6934
|
-
domain,
|
|
6935
|
-
options: optionsFields,
|
|
6936
|
-
widget,
|
|
6937
|
-
formValues,
|
|
6938
|
-
placeholderNoOption
|
|
6939
|
-
} = props;
|
|
6940
|
-
const isUser = relation === "res.users" || relation === "res.partner";
|
|
6941
|
-
const env = (0, import_environment9.getEnv)();
|
|
6942
|
-
const addtionalFields = optionsFields ? (0, import_utils8.evalJSONContext)(optionsFields) : null;
|
|
6943
|
-
const domainObject = (0, import_react20.useMemo)(
|
|
6944
|
-
() => (0, import_utils8.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues || {}))),
|
|
6945
|
-
[domain, formValues]
|
|
6946
|
-
);
|
|
6947
|
-
const data = {
|
|
6948
|
-
model: relation ?? "",
|
|
6949
|
-
domain: domainObject,
|
|
6950
|
-
specification: {
|
|
6951
|
-
id: {},
|
|
6952
|
-
name: {},
|
|
6953
|
-
display_name: {},
|
|
6954
|
-
...widget && import_constants4.WIDGETAVATAR[widget] ? { image_256: {} } : {},
|
|
6955
|
-
...widget && import_constants4.WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
|
|
6956
|
-
},
|
|
6957
|
-
enabled: true,
|
|
6958
|
-
context: env.context
|
|
6959
|
-
};
|
|
6960
|
-
const { data: dataOfSelection } = (0, import_hooks15.useGetSelection)({
|
|
6961
|
-
data,
|
|
6962
|
-
queryKey: [`data_${relation}`, domainObject]
|
|
6963
|
-
});
|
|
6964
|
-
const customNoOptionsMessage = () => placeholderNoOption;
|
|
6965
|
-
const tranfer = (data2) => {
|
|
6966
|
-
return data2?.map((val) => ({
|
|
6967
|
-
id: val.value,
|
|
6968
|
-
display_name: val.label
|
|
6969
|
-
})) || [];
|
|
6970
|
-
};
|
|
6971
|
-
const options = dataOfSelection?.records?.map((val) => ({
|
|
6972
|
-
value: val.id,
|
|
6973
|
-
label: val.name ?? val.display_name,
|
|
6974
|
-
...val
|
|
6975
|
-
})) || [];
|
|
6976
|
-
return {
|
|
6977
|
-
options,
|
|
6978
|
-
customNoOptionsMessage,
|
|
6979
|
-
tranfer,
|
|
6980
|
-
dataOfSelection,
|
|
6981
|
-
isUser
|
|
6982
|
-
};
|
|
6983
|
-
};
|
|
6984
|
-
|
|
6985
|
-
// src/widget/basic/status-bar-field/controller.ts
|
|
6986
|
-
var import_react21 = require("react");
|
|
6987
|
-
var import_hooks16 = require("@fctc/interface-logic/hooks");
|
|
6988
|
-
var import_store13 = require("@fctc/interface-logic/store");
|
|
6989
|
-
var import_utils9 = require("@fctc/interface-logic/utils");
|
|
6990
|
-
var durationController = (props) => {
|
|
6991
|
-
const {
|
|
6992
|
-
relation,
|
|
6993
|
-
defaultValue,
|
|
6994
|
-
domain,
|
|
6995
|
-
formValues,
|
|
6996
|
-
name,
|
|
6997
|
-
id,
|
|
6998
|
-
model,
|
|
6999
|
-
onRefetch
|
|
7000
|
-
} = props;
|
|
7001
|
-
const specification = {
|
|
7002
|
-
id: 0,
|
|
7003
|
-
name: "",
|
|
7004
|
-
fold: ""
|
|
7005
|
-
};
|
|
7006
|
-
const [disabled, setDisabled] = (0, import_react21.useState)(false);
|
|
7007
|
-
const [modelStatus, setModalStatus] = (0, import_react21.useState)(false);
|
|
7008
|
-
const { context } = (0, import_store13.useAppSelector)(import_store13.selectEnv);
|
|
7009
|
-
const queryKey = [`data-status-duration`, specification];
|
|
7010
|
-
const listDataProps = {
|
|
7011
|
-
model: relation,
|
|
7012
|
-
specification,
|
|
7013
|
-
domain: (0, import_utils9.evalJSONDomain)(domain, JSON.parse(JSON.stringify(formValues))),
|
|
7014
|
-
limit: 10,
|
|
7015
|
-
offset: 0,
|
|
7016
|
-
fields: "",
|
|
7017
|
-
groupby: [],
|
|
7018
|
-
context: {
|
|
7019
|
-
lang: context.lang
|
|
7020
|
-
},
|
|
7021
|
-
sort: ""
|
|
7022
|
-
};
|
|
7023
|
-
const { data: dataResponse } = (0, import_hooks16.useGetListData)(listDataProps, queryKey);
|
|
7024
|
-
const { mutate: fetchChangeStatus } = (0, import_hooks16.useChangeStatus)();
|
|
7025
|
-
const handleClick = async (stage_id) => {
|
|
7026
|
-
setDisabled(true);
|
|
7027
|
-
if (stage_id) {
|
|
7028
|
-
fetchChangeStatus(
|
|
7029
|
-
{
|
|
7030
|
-
data: {
|
|
7031
|
-
stage_id,
|
|
7032
|
-
name,
|
|
7033
|
-
id,
|
|
7034
|
-
model,
|
|
7035
|
-
lang: context.lang
|
|
7036
|
-
}
|
|
7037
|
-
},
|
|
7038
|
-
{
|
|
7039
|
-
onSuccess: (res) => {
|
|
7040
|
-
if (res) {
|
|
7041
|
-
setDisabled(false);
|
|
7042
|
-
onRefetch && onRefetch();
|
|
7043
|
-
}
|
|
7044
|
-
}
|
|
7045
|
-
}
|
|
7046
|
-
);
|
|
7047
|
-
}
|
|
6764
|
+
handleInputMouseLeave,
|
|
6765
|
+
handleInputChange,
|
|
6766
|
+
useFormatFloatNumber,
|
|
6767
|
+
inputRef,
|
|
6768
|
+
inputValue
|
|
6769
|
+
};
|
|
6770
|
+
};
|
|
6771
|
+
var useFormatFloatNumber = (value) => {
|
|
6772
|
+
if (value === void 0 || value === null || value === "") return "";
|
|
6773
|
+
const numValue = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
|
|
6774
|
+
if (isNaN(numValue)) return "";
|
|
6775
|
+
return numValue.toLocaleString("en-US", {
|
|
6776
|
+
minimumFractionDigits: numValue % 1 === 0 ? 0 : 1,
|
|
6777
|
+
maximumFractionDigits: 20
|
|
6778
|
+
});
|
|
6779
|
+
};
|
|
6780
|
+
|
|
6781
|
+
// src/widget/basic/download-file-field/controller.ts
|
|
6782
|
+
var import_react20 = require("react");
|
|
6783
|
+
var downloadFileController = () => {
|
|
6784
|
+
const inputId = (0, import_react20.useId)();
|
|
6785
|
+
const [file, setFile] = (0, import_react20.useState)(null);
|
|
6786
|
+
const handleFileChange = (e) => {
|
|
6787
|
+
setFile(e.target.files[0]);
|
|
6788
|
+
};
|
|
6789
|
+
const handleFileDownload = () => {
|
|
6790
|
+
const url = URL.createObjectURL(file);
|
|
6791
|
+
const link = document.createElement("a");
|
|
6792
|
+
link.href = url;
|
|
6793
|
+
link.download = file.name;
|
|
6794
|
+
document.body.appendChild(link);
|
|
6795
|
+
link.click();
|
|
6796
|
+
document.body.removeChild(link);
|
|
7048
6797
|
};
|
|
7049
6798
|
return {
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
modelStatus,
|
|
7055
|
-
setModalStatus
|
|
6799
|
+
inputId,
|
|
6800
|
+
file,
|
|
6801
|
+
handleFileChange,
|
|
6802
|
+
handleFileDownload
|
|
7056
6803
|
};
|
|
7057
6804
|
};
|
|
7058
6805
|
|
|
7059
|
-
// src/widget/basic/
|
|
7060
|
-
var
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
value,
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
methods,
|
|
7068
|
-
onChange,
|
|
7069
|
-
model,
|
|
7070
|
-
selection,
|
|
7071
|
-
id,
|
|
7072
|
-
actionData,
|
|
7073
|
-
viewData,
|
|
7074
|
-
context
|
|
7075
|
-
} = props;
|
|
7076
|
-
const _context = { ...(0, import_utils10.evalJSONContext)(actionData?.context) };
|
|
7077
|
-
const contextObject = { ...context, ..._context };
|
|
7078
|
-
const defaultPriority = parseInt(value) + 1;
|
|
7079
|
-
const label = viewData?.models?.[model]?.[name ?? ""]?.string ?? name;
|
|
7080
|
-
const { mutateAsync: fetchSave } = (0, import_hooks17.useSave)();
|
|
7081
|
-
const savePriorities = async ({
|
|
7082
|
-
value: value2,
|
|
7083
|
-
resetPriority
|
|
7084
|
-
}) => {
|
|
7085
|
-
const priorityValue = value2 <= 0 ? 0 : value2 - 1;
|
|
6806
|
+
// src/widget/basic/download-binary-field/controller.ts
|
|
6807
|
+
var downLoadBinaryController = (props) => {
|
|
6808
|
+
const { value, defaultValue, formValues } = props;
|
|
6809
|
+
const handleFileDownload = async (e) => {
|
|
6810
|
+
e.stopPropagation();
|
|
6811
|
+
await downloadFile(value || defaultValue, formValues?.name);
|
|
6812
|
+
};
|
|
6813
|
+
const downloadFile = async (url, filename) => {
|
|
7086
6814
|
try {
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
6815
|
+
const response = await fetch(url);
|
|
6816
|
+
if (response) {
|
|
6817
|
+
const blob = await response.blob();
|
|
6818
|
+
const urlBlob = window.URL.createObjectURL(blob);
|
|
6819
|
+
const link = document.createElement("a");
|
|
6820
|
+
link.href = urlBlob;
|
|
6821
|
+
link.download = filename || "downloaded-file";
|
|
6822
|
+
document.body.appendChild(link);
|
|
6823
|
+
link.click();
|
|
6824
|
+
document.body.removeChild(link);
|
|
6825
|
+
window.URL.revokeObjectURL(urlBlob);
|
|
7095
6826
|
}
|
|
7096
6827
|
} catch (error) {
|
|
7097
|
-
|
|
7098
|
-
resetPriority();
|
|
7099
|
-
}
|
|
6828
|
+
console.error("File download failed:", error);
|
|
7100
6829
|
}
|
|
7101
6830
|
};
|
|
7102
6831
|
return {
|
|
7103
|
-
|
|
7104
|
-
isForm,
|
|
7105
|
-
methods,
|
|
7106
|
-
defaultPriority,
|
|
7107
|
-
savePriorities,
|
|
7108
|
-
label,
|
|
7109
|
-
id,
|
|
7110
|
-
onChange
|
|
6832
|
+
handleFileDownload
|
|
7111
6833
|
};
|
|
7112
6834
|
};
|
|
7113
6835
|
|
|
7114
|
-
// src/widget/basic/
|
|
7115
|
-
var
|
|
7116
|
-
var
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
const
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
|
|
7137
|
-
setFormattedTime("");
|
|
7138
|
-
return;
|
|
7139
|
-
}
|
|
7140
|
-
let hours = parseInt(match[1] ?? "0", 10);
|
|
7141
|
-
let minutes = parseInt(match[2] ?? "0", 10);
|
|
7142
|
-
if (isNaN(hours)) hours = 0;
|
|
7143
|
-
if (isNaN(minutes)) minutes = 0;
|
|
7144
|
-
if (hours >= 24) {
|
|
7145
|
-
hours = 0;
|
|
7146
|
-
}
|
|
7147
|
-
if (minutes >= 60) {
|
|
7148
|
-
minutes = 0;
|
|
6836
|
+
// src/widget/basic/date-field/controller.ts
|
|
6837
|
+
var import_moment = __toESM(require_moment());
|
|
6838
|
+
var DURATIONS = {
|
|
6839
|
+
PAST: "past",
|
|
6840
|
+
NOW: "now",
|
|
6841
|
+
FUTURE: "future"
|
|
6842
|
+
};
|
|
6843
|
+
var dateFieldController = (props) => {
|
|
6844
|
+
const {
|
|
6845
|
+
string,
|
|
6846
|
+
showTime = false,
|
|
6847
|
+
widget,
|
|
6848
|
+
min,
|
|
6849
|
+
max,
|
|
6850
|
+
viewData,
|
|
6851
|
+
formValues,
|
|
6852
|
+
model
|
|
6853
|
+
} = props;
|
|
6854
|
+
const range = (start, end, step = 1) => {
|
|
6855
|
+
const arr = [];
|
|
6856
|
+
for (let i = start; i < end; i += step) {
|
|
6857
|
+
arr.push(i);
|
|
7149
6858
|
}
|
|
7150
|
-
|
|
7151
|
-
setErrors("");
|
|
7152
|
-
setFormattedTime(formatted);
|
|
7153
|
-
fieldOnChange(formatted);
|
|
6859
|
+
return arr;
|
|
7154
6860
|
};
|
|
7155
|
-
const
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
6861
|
+
const formatDate = showTime ? "DD/MM/YYYY HH:mm:ss" : "DD/MM/YYYY";
|
|
6862
|
+
const formatDateParse = showTime ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD";
|
|
6863
|
+
const fieldForCustom = widget === "datetime_custom" || widget === "date_custom";
|
|
6864
|
+
const minNowValue = fieldForCustom && (min === DURATIONS.NOW ? true : typeof min === "string" && Object.keys(formValues)?.includes(min) && formValues?.[min] ? (0, import_moment.default)(formValues?.[min], formatDateParse).add(7, "hours") : null);
|
|
6865
|
+
const maxNowValue = fieldForCustom && (max === DURATIONS.NOW ? true : typeof max === "string" && Object.keys(formValues)?.includes(max) && formValues?.[max] ? (0, import_moment.default)(formValues?.[max], formatDateParse).add(7, "hours") : null);
|
|
6866
|
+
const years = range(
|
|
6867
|
+
minNowValue ? (/* @__PURE__ */ new Date()).getFullYear() : 1990,
|
|
6868
|
+
(/* @__PURE__ */ new Date()).getFullYear() + 4,
|
|
6869
|
+
1
|
|
6870
|
+
);
|
|
6871
|
+
const months_vi = [
|
|
6872
|
+
"Th\xE1ng 1",
|
|
6873
|
+
"Th\xE1ng 2",
|
|
6874
|
+
"Th\xE1ng 3",
|
|
6875
|
+
"Th\xE1ng 4",
|
|
6876
|
+
"Th\xE1ng 5",
|
|
6877
|
+
"Th\xE1ng 6",
|
|
6878
|
+
"Th\xE1ng 7",
|
|
6879
|
+
"Th\xE1ng 8",
|
|
6880
|
+
"Th\xE1ng 9",
|
|
6881
|
+
"Th\xE1ng 10",
|
|
6882
|
+
"Th\xE1ng 11",
|
|
6883
|
+
"Th\xE1ng 12"
|
|
6884
|
+
];
|
|
6885
|
+
const months_en = [
|
|
6886
|
+
"January",
|
|
6887
|
+
"February",
|
|
6888
|
+
"March",
|
|
6889
|
+
"April",
|
|
6890
|
+
"May",
|
|
6891
|
+
"June",
|
|
6892
|
+
"July",
|
|
6893
|
+
"August",
|
|
6894
|
+
"September",
|
|
6895
|
+
"October",
|
|
6896
|
+
"November",
|
|
6897
|
+
"December"
|
|
6898
|
+
];
|
|
6899
|
+
const customValidateMinMax = (date) => {
|
|
6900
|
+
const selected = (0, import_moment.default)(date, formatDateParse);
|
|
6901
|
+
const now = (0, import_moment.default)();
|
|
6902
|
+
const compareSelected = showTime ? selected : selected.clone().startOf("day");
|
|
6903
|
+
const compareNow = showTime ? now : now.clone().startOf("day");
|
|
6904
|
+
if (minNowValue) {
|
|
6905
|
+
if (compareSelected.isBefore(compareNow) && typeof minNowValue === "boolean" && minNowValue === true) {
|
|
6906
|
+
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
6907
|
+
"greater_or_equal_now"
|
|
6908
|
+
)}`;
|
|
6909
|
+
} else if (import_moment.default.isMoment(minNowValue)) {
|
|
6910
|
+
const compareMin = showTime ? minNowValue : minNowValue.clone().startOf("day");
|
|
6911
|
+
if (compareSelected.isBefore(compareMin)) {
|
|
6912
|
+
const fieldRelationDate = viewData?.models?.[model]?.[min ?? ""];
|
|
6913
|
+
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
6914
|
+
"greater_or_equal"
|
|
6915
|
+
)} ${fieldRelationDate?.string}`;
|
|
6916
|
+
}
|
|
7169
6917
|
}
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
"End",
|
|
7184
|
-
":"
|
|
7185
|
-
];
|
|
7186
|
-
const isNumber = /^[0-9]$/.test(e.key);
|
|
7187
|
-
if (!isNumber && !allowed.includes(e.key)) {
|
|
7188
|
-
e.preventDefault();
|
|
6918
|
+
} else if (maxNowValue) {
|
|
6919
|
+
if (compareSelected.isAfter(compareNow) && typeof maxNowValue === "boolean" && maxNowValue === true) {
|
|
6920
|
+
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
6921
|
+
"less_or_equal_now"
|
|
6922
|
+
)}`;
|
|
6923
|
+
} else if (import_moment.default.isMoment(maxNowValue)) {
|
|
6924
|
+
const compareMax = showTime ? maxNowValue : maxNowValue.clone().startOf("day");
|
|
6925
|
+
if (compareSelected.isAfter(compareMax)) {
|
|
6926
|
+
const fieldRelationDate = viewData?.models?.[model]?.[max ?? ""];
|
|
6927
|
+
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
6928
|
+
"less_or_equal"
|
|
6929
|
+
)} ${fieldRelationDate?.string}`;
|
|
6930
|
+
}
|
|
7189
6931
|
}
|
|
7190
6932
|
}
|
|
6933
|
+
return false;
|
|
7191
6934
|
};
|
|
7192
6935
|
return {
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
6936
|
+
formatDate,
|
|
6937
|
+
formatDateParse,
|
|
6938
|
+
range,
|
|
6939
|
+
years,
|
|
6940
|
+
months_vi,
|
|
6941
|
+
months_en,
|
|
6942
|
+
customValidateMinMax,
|
|
6943
|
+
minNowValue,
|
|
6944
|
+
maxNowValue
|
|
7198
6945
|
};
|
|
7199
6946
|
};
|
|
7200
6947
|
|
|
7201
|
-
// src/widget/basic/
|
|
7202
|
-
var
|
|
7203
|
-
var
|
|
7204
|
-
|
|
7205
|
-
value,
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
value !== void 0 && value !== null ? useFormatFloatNumber(value) : ""
|
|
7212
|
-
);
|
|
7213
|
-
(0, import_react23.useEffect)(() => {
|
|
7214
|
-
if (value !== void 0 && value !== null && value !== parseFloat(inputValue?.replace(/,/g, ""))) {
|
|
7215
|
-
setInputValue(useFormatFloatNumber(value));
|
|
7216
|
-
clearErrors(name);
|
|
7217
|
-
} else if (value === null || value === void 0) {
|
|
7218
|
-
setInputValue("");
|
|
7219
|
-
}
|
|
7220
|
-
}, [value, name, clearErrors]);
|
|
7221
|
-
const isDirtyRef = (0, import_react23.useRef)(false);
|
|
7222
|
-
const inputRef = (0, import_react23.useRef)(null);
|
|
7223
|
-
const lastCommittedValueRef = (0, import_react23.useRef)(null);
|
|
7224
|
-
const handleInputChange = (e) => {
|
|
7225
|
-
const newValue = e.target.value;
|
|
7226
|
-
const valueWithoutCommas = newValue.replace(/,/g, "");
|
|
7227
|
-
if (/^[0-9]*[.,]?[0-9]*$/.test(valueWithoutCommas) || newValue === "") {
|
|
7228
|
-
const parts = valueWithoutCommas.split(".");
|
|
7229
|
-
let integerPart = parts[0] || "";
|
|
7230
|
-
const decimalPart = parts[1] || "";
|
|
7231
|
-
if (decimalPart.length > 100) return;
|
|
7232
|
-
if (integerPart) {
|
|
7233
|
-
integerPart = Number(integerPart).toLocaleString("en-US");
|
|
7234
|
-
}
|
|
7235
|
-
const formattedValue = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
|
|
7236
|
-
setInputValue(formattedValue);
|
|
7237
|
-
const parsedValue = parseFloat(valueWithoutCommas.replace(",", "."));
|
|
7238
|
-
if (!isNaN(parsedValue)) {
|
|
7239
|
-
if (parsedValue < 0) {
|
|
7240
|
-
setError(name, {
|
|
7241
|
-
type: "validate",
|
|
7242
|
-
message: i18n_default.t("invalid_number")
|
|
7243
|
-
});
|
|
7244
|
-
} else {
|
|
7245
|
-
onChange(parsedValue);
|
|
7246
|
-
clearErrors(name);
|
|
7247
|
-
isDirtyRef.current = true;
|
|
7248
|
-
}
|
|
7249
|
-
} else {
|
|
7250
|
-
onChange(null);
|
|
7251
|
-
clearErrors(name);
|
|
7252
|
-
}
|
|
7253
|
-
}
|
|
6948
|
+
// src/widget/basic/copy-link-button/controller.ts
|
|
6949
|
+
var import_react21 = require("react");
|
|
6950
|
+
var import_utils11 = require("@fctc/interface-logic/utils");
|
|
6951
|
+
var copyLinkButtonController = (props) => {
|
|
6952
|
+
const { value, defaultValue } = props;
|
|
6953
|
+
const [isCopied, setIsCopied] = (0, import_react21.useState)(false);
|
|
6954
|
+
const handleCopyToClipboard = async (value2) => {
|
|
6955
|
+
await (0, import_utils11.copyTextToClipboard)(value2);
|
|
6956
|
+
setIsCopied(true);
|
|
6957
|
+
setTimeout(() => setIsCopied(false), 2e3);
|
|
7254
6958
|
};
|
|
7255
|
-
const
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
onChange(parsedValue);
|
|
7288
|
-
setInputValue(formattedValue);
|
|
7289
|
-
handleOnchange?.(name ?? "", parsedValue);
|
|
7290
|
-
clearErrors(name);
|
|
7291
|
-
lastCommittedValueRef.current = parsedValue;
|
|
7292
|
-
}
|
|
7293
|
-
}
|
|
7294
|
-
} else {
|
|
7295
|
-
setError(name, {
|
|
7296
|
-
type: "validate",
|
|
7297
|
-
message: i18n_default.t("invalid_number")
|
|
6959
|
+
const propValue = value || defaultValue;
|
|
6960
|
+
return {
|
|
6961
|
+
isCopied,
|
|
6962
|
+
handleCopyToClipboard,
|
|
6963
|
+
propValue
|
|
6964
|
+
};
|
|
6965
|
+
};
|
|
6966
|
+
|
|
6967
|
+
// src/widget/basic/color-field/color-controller.ts
|
|
6968
|
+
var import_environment8 = require("@fctc/interface-logic/environment");
|
|
6969
|
+
var import_hooks17 = require("@fctc/interface-logic/hooks");
|
|
6970
|
+
var import_utils12 = require("@fctc/interface-logic/utils");
|
|
6971
|
+
var colorFieldController = (props) => {
|
|
6972
|
+
const { value, isForm, name, formValues, idForm, model, actionData } = props;
|
|
6973
|
+
const env = (0, import_environment8.getEnv)();
|
|
6974
|
+
const _context = { ...(0, import_utils12.evalJSONContext)(actionData?.context) || {} };
|
|
6975
|
+
const contextObject = { ...env.context, ..._context };
|
|
6976
|
+
const idDefault = isForm ? idForm : formValues?.id;
|
|
6977
|
+
const { mutate: onSave } = (0, import_hooks17.useSave)();
|
|
6978
|
+
const savePickColor = async (colorObject) => {
|
|
6979
|
+
const { id } = colorObject;
|
|
6980
|
+
if (value === id) return;
|
|
6981
|
+
try {
|
|
6982
|
+
onSave({
|
|
6983
|
+
ids: idDefault !== null ? [idDefault] : [],
|
|
6984
|
+
model: model ?? "",
|
|
6985
|
+
data: { [name ?? ""]: id },
|
|
6986
|
+
specification: {
|
|
6987
|
+
name: {},
|
|
6988
|
+
color: {}
|
|
6989
|
+
},
|
|
6990
|
+
context: contextObject
|
|
7298
6991
|
});
|
|
7299
|
-
|
|
7300
|
-
|
|
6992
|
+
} catch (error) {
|
|
6993
|
+
console.log(error);
|
|
7301
6994
|
}
|
|
7302
|
-
isDirtyRef.current = false;
|
|
7303
|
-
inputRef.current?.blur();
|
|
7304
6995
|
};
|
|
7305
6996
|
return {
|
|
7306
|
-
|
|
7307
|
-
handleInputChange,
|
|
7308
|
-
useFormatFloatNumber,
|
|
7309
|
-
inputRef,
|
|
7310
|
-
inputValue
|
|
6997
|
+
savePickColor
|
|
7311
6998
|
};
|
|
7312
6999
|
};
|
|
7313
|
-
var useFormatFloatNumber = (value) => {
|
|
7314
|
-
if (value === void 0 || value === null || value === "") return "";
|
|
7315
|
-
const numValue = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
|
|
7316
|
-
if (isNaN(numValue)) return "";
|
|
7317
|
-
return numValue.toLocaleString("en-US", {
|
|
7318
|
-
minimumFractionDigits: numValue % 1 === 0 ? 0 : 1,
|
|
7319
|
-
maximumFractionDigits: 20
|
|
7320
|
-
});
|
|
7321
|
-
};
|
|
7322
7000
|
|
|
7323
|
-
// src/widget/basic/
|
|
7324
|
-
var
|
|
7325
|
-
var
|
|
7326
|
-
|
|
7327
|
-
const
|
|
7328
|
-
const
|
|
7329
|
-
|
|
7001
|
+
// src/widget/basic/binary-field/controller.ts
|
|
7002
|
+
var import_react22 = require("react");
|
|
7003
|
+
var import_utils13 = require("@fctc/interface-logic/utils");
|
|
7004
|
+
var binaryFieldController = (props) => {
|
|
7005
|
+
const { name, methods, readonly = false, value } = props;
|
|
7006
|
+
const inputId = (0, import_react22.useId)();
|
|
7007
|
+
const [selectedImage, setSelectedImage] = (0, import_react22.useState)(null);
|
|
7008
|
+
const [initialImage, setInitialImage] = (0, import_react22.useState)(value || null);
|
|
7009
|
+
const [isInsideTable, setIsInsideTable] = (0, import_react22.useState)(false);
|
|
7010
|
+
const { setValue } = methods;
|
|
7011
|
+
const binaryRef = (0, import_react22.useRef)(null);
|
|
7012
|
+
const convertUrlToBase64 = async (url) => {
|
|
7013
|
+
try {
|
|
7014
|
+
const response = await fetch(url);
|
|
7015
|
+
const blob = await response.blob();
|
|
7016
|
+
return new Promise((resolve, reject) => {
|
|
7017
|
+
const reader = new FileReader();
|
|
7018
|
+
reader.onloadend = () => {
|
|
7019
|
+
resolve(reader.result);
|
|
7020
|
+
};
|
|
7021
|
+
reader.onerror = reject;
|
|
7022
|
+
reader.readAsDataURL(blob);
|
|
7023
|
+
});
|
|
7024
|
+
} catch (error) {
|
|
7025
|
+
console.error("Error converting URL to Base64:", error);
|
|
7026
|
+
throw error;
|
|
7027
|
+
}
|
|
7330
7028
|
};
|
|
7331
|
-
const
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7029
|
+
const extractBase64Data = (base64Url) => {
|
|
7030
|
+
if (base64Url.includes("base64,")) {
|
|
7031
|
+
return base64Url.split("base64,")[1];
|
|
7032
|
+
}
|
|
7033
|
+
return base64Url;
|
|
7034
|
+
};
|
|
7035
|
+
const handleImageChange = async (e, onChange) => {
|
|
7036
|
+
if (readonly) return;
|
|
7037
|
+
const file = e?.target?.files?.[0];
|
|
7038
|
+
if (file) {
|
|
7039
|
+
const imageUrl = URL.createObjectURL(file);
|
|
7040
|
+
setSelectedImage(imageUrl);
|
|
7041
|
+
setInitialImage(null);
|
|
7042
|
+
onChange(file);
|
|
7043
|
+
const compressedBase64 = await convertUrlToBase64(imageUrl);
|
|
7044
|
+
const base64Data = extractBase64Data(compressedBase64);
|
|
7045
|
+
setValue(name, base64Data, {
|
|
7046
|
+
shouldDirty: true
|
|
7047
|
+
});
|
|
7048
|
+
}
|
|
7049
|
+
};
|
|
7050
|
+
const handleRemoveImage = (onChange) => {
|
|
7051
|
+
setSelectedImage(null);
|
|
7052
|
+
setInitialImage(null);
|
|
7053
|
+
onChange(null);
|
|
7054
|
+
};
|
|
7055
|
+
const isBlobUrl = (url) => {
|
|
7056
|
+
return /^blob:/.test(url);
|
|
7057
|
+
};
|
|
7058
|
+
const checkIsImageLink = (url) => {
|
|
7059
|
+
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
7060
|
+
return imageExtensions.test(url) || (0, import_utils13.isBase64Image)(url) || isBlobUrl(url);
|
|
7061
|
+
};
|
|
7062
|
+
const getImageBase64WithMimeType = (base64) => {
|
|
7063
|
+
if (typeof base64 !== "string" || base64.length < 10) return null;
|
|
7064
|
+
if ((0, import_utils13.isBase64Image)(base64)) return base64;
|
|
7065
|
+
let mimeType = null;
|
|
7066
|
+
if (base64.startsWith("iVBORw0KGgo")) mimeType = "image/png";
|
|
7067
|
+
else if (base64.startsWith("/9j/")) mimeType = "image/jpeg";
|
|
7068
|
+
else if (base64.startsWith("R0lGOD")) mimeType = "image/gif";
|
|
7069
|
+
else if (base64.startsWith("Qk")) mimeType = "image/bmp";
|
|
7070
|
+
else if (base64.startsWith("UklGR")) mimeType = "image/webp";
|
|
7071
|
+
return mimeType ? `data:${mimeType};base64,${base64}` : null;
|
|
7339
7072
|
};
|
|
7073
|
+
(0, import_react22.useEffect)(() => {
|
|
7074
|
+
return () => {
|
|
7075
|
+
if (selectedImage) {
|
|
7076
|
+
URL.revokeObjectURL(selectedImage);
|
|
7077
|
+
}
|
|
7078
|
+
};
|
|
7079
|
+
}, [selectedImage]);
|
|
7080
|
+
(0, import_react22.useEffect)(() => {
|
|
7081
|
+
if (binaryRef.current) {
|
|
7082
|
+
const isInsideTable2 = !!binaryRef.current.closest("table");
|
|
7083
|
+
setIsInsideTable(isInsideTable2);
|
|
7084
|
+
}
|
|
7085
|
+
}, []);
|
|
7340
7086
|
return {
|
|
7341
7087
|
inputId,
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7088
|
+
selectedImage,
|
|
7089
|
+
initialImage,
|
|
7090
|
+
isInsideTable,
|
|
7091
|
+
binaryRef,
|
|
7092
|
+
handleImageChange,
|
|
7093
|
+
handleRemoveImage,
|
|
7094
|
+
checkIsImageLink,
|
|
7095
|
+
getImageBase64WithMimeType
|
|
7345
7096
|
};
|
|
7346
7097
|
};
|
|
7347
7098
|
|
|
7348
|
-
// src/widget/
|
|
7349
|
-
var
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7099
|
+
// src/widget/advance/table/table-body/controller.ts
|
|
7100
|
+
var import_store10 = require("@fctc/interface-logic/store");
|
|
7101
|
+
var import_react23 = require("react");
|
|
7102
|
+
var tableBodyController = (props) => {
|
|
7103
|
+
const {
|
|
7104
|
+
checkedAll,
|
|
7105
|
+
checkboxRef,
|
|
7106
|
+
setIsAutoSelect,
|
|
7107
|
+
selectedRowKeys,
|
|
7108
|
+
row,
|
|
7109
|
+
isAutoSelect,
|
|
7110
|
+
selectedRowKeysRef,
|
|
7111
|
+
onClickRow
|
|
7112
|
+
} = props;
|
|
7113
|
+
const appDispatch = (0, import_store10.useAppDispatch)();
|
|
7114
|
+
const checked = (0, import_react23.useMemo)(() => {
|
|
7115
|
+
if (!row?.id) return false;
|
|
7116
|
+
if (selectedRowKeys?.includes(row.id)) {
|
|
7117
|
+
return true;
|
|
7118
|
+
}
|
|
7119
|
+
return checkedAll;
|
|
7120
|
+
}, [row?.id, selectedRowKeys, checkedAll]);
|
|
7121
|
+
const handleCheckBoxSingle = (event) => {
|
|
7122
|
+
event.stopPropagation();
|
|
7123
|
+
if (checkedAll) {
|
|
7124
|
+
checkboxRef.current = "uncheck";
|
|
7125
|
+
setIsAutoSelect(true);
|
|
7126
|
+
return;
|
|
7127
|
+
}
|
|
7128
|
+
const newSelectedRowKeys = selectedRowKeys?.includes(row.id) ? selectedRowKeys?.filter((key) => key !== row.id) : [...selectedRowKeys, row.id];
|
|
7129
|
+
console.log("newSelectedRowKeys", newSelectedRowKeys);
|
|
7130
|
+
appDispatch((0, import_store10.setSelectedRowKeys)(newSelectedRowKeys));
|
|
7354
7131
|
};
|
|
7355
|
-
const
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7132
|
+
const handleClickRow = (col, row2) => {
|
|
7133
|
+
onClickRow(col, row2);
|
|
7134
|
+
};
|
|
7135
|
+
(0, import_react23.useEffect)(() => {
|
|
7136
|
+
if (!row?.id) return;
|
|
7137
|
+
if (isAutoSelect) {
|
|
7138
|
+
if (checkboxRef?.current === "uncheck") {
|
|
7139
|
+
const filtered = selectedRowKeysRef.current.filter(
|
|
7140
|
+
(id) => id !== row.id
|
|
7141
|
+
);
|
|
7142
|
+
selectedRowKeysRef.current = filtered;
|
|
7143
|
+
appDispatch((0, import_store10.setSelectedRowKeys)(filtered));
|
|
7144
|
+
} else {
|
|
7145
|
+
const unique = Array.from(
|
|
7146
|
+
/* @__PURE__ */ new Set([...selectedRowKeysRef?.current, row?.id])
|
|
7147
|
+
);
|
|
7148
|
+
selectedRowKeysRef.current = unique;
|
|
7149
|
+
appDispatch((0, import_store10.setSelectedRowKeys)(unique));
|
|
7368
7150
|
}
|
|
7369
|
-
} catch (error) {
|
|
7370
|
-
console.error("File download failed:", error);
|
|
7371
7151
|
}
|
|
7372
|
-
};
|
|
7152
|
+
}, [isAutoSelect]);
|
|
7153
|
+
(0, import_react23.useEffect)(() => {
|
|
7154
|
+
if (!checkedAll) {
|
|
7155
|
+
checkboxRef.current = "enabled";
|
|
7156
|
+
false;
|
|
7157
|
+
}
|
|
7158
|
+
}, [checkedAll]);
|
|
7373
7159
|
return {
|
|
7374
|
-
|
|
7160
|
+
handleCheckBoxSingle,
|
|
7161
|
+
checked,
|
|
7162
|
+
handleClickRow
|
|
7375
7163
|
};
|
|
7376
7164
|
};
|
|
7377
7165
|
|
|
7378
|
-
// src/widget/
|
|
7379
|
-
var
|
|
7380
|
-
var
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7166
|
+
// src/widget/advance/table/table-head/controller.ts
|
|
7167
|
+
var import_store11 = require("@fctc/interface-logic/store");
|
|
7168
|
+
var tableHeadController = (props) => {
|
|
7169
|
+
const { typeTable, rows, selectedRowKeysRef } = props;
|
|
7170
|
+
const appDispatch = (0, import_store11.useAppDispatch)();
|
|
7171
|
+
const { groupByDomain } = (0, import_store11.useAppSelector)(import_store11.selectSearch);
|
|
7172
|
+
const handleCheckBoxAll = (event) => {
|
|
7173
|
+
if (event?.target?.checked && typeTable === "list") {
|
|
7174
|
+
const allRowKeys = Array.isArray(rows) ? rows.map((record) => record?.id) : [];
|
|
7175
|
+
appDispatch((0, import_store11.setSelectedRowKeys)(allRowKeys));
|
|
7176
|
+
} else if (event?.target?.checked && typeTable === "group") {
|
|
7177
|
+
const rowsIDs = document.querySelectorAll("tr[data-row-id]");
|
|
7178
|
+
const ids = Array.from(rowsIDs)?.map(
|
|
7179
|
+
(row) => Number(row?.getAttribute("data-row-id"))
|
|
7180
|
+
);
|
|
7181
|
+
if (ids?.length > 0) {
|
|
7182
|
+
appDispatch((0, import_store11.setSelectedRowKeys)(ids));
|
|
7183
|
+
} else {
|
|
7184
|
+
const sum = countSum(
|
|
7185
|
+
rows,
|
|
7186
|
+
typeof groupByDomain === "object" ? groupByDomain?.contexts?.[0]?.group_by : void 0
|
|
7187
|
+
);
|
|
7188
|
+
const keys = Array.from({ length: sum }, (_) => void 0);
|
|
7189
|
+
appDispatch((0, import_store11.setSelectedRowKeys)(keys));
|
|
7190
|
+
}
|
|
7191
|
+
if (selectedRowKeysRef) {
|
|
7192
|
+
selectedRowKeysRef.current = [];
|
|
7193
|
+
}
|
|
7194
|
+
} else {
|
|
7195
|
+
appDispatch((0, import_store11.setSelectedRowKeys)([]));
|
|
7400
7196
|
}
|
|
7401
|
-
return arr;
|
|
7402
7197
|
};
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
const
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
"October",
|
|
7438
|
-
"November",
|
|
7439
|
-
"December"
|
|
7440
|
-
];
|
|
7441
|
-
const customValidateMinMax = (date) => {
|
|
7442
|
-
const selected = (0, import_moment.default)(date, formatDateParse);
|
|
7443
|
-
const now = (0, import_moment.default)();
|
|
7444
|
-
const compareSelected = showTime ? selected : selected.clone().startOf("day");
|
|
7445
|
-
const compareNow = showTime ? now : now.clone().startOf("day");
|
|
7446
|
-
if (minNowValue) {
|
|
7447
|
-
if (compareSelected.isBefore(compareNow) && typeof minNowValue === "boolean" && minNowValue === true) {
|
|
7448
|
-
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
7449
|
-
"greater_or_equal_now"
|
|
7450
|
-
)}`;
|
|
7451
|
-
} else if (import_moment.default.isMoment(minNowValue)) {
|
|
7452
|
-
const compareMin = showTime ? minNowValue : minNowValue.clone().startOf("day");
|
|
7453
|
-
if (compareSelected.isBefore(compareMin)) {
|
|
7454
|
-
const fieldRelationDate = viewData?.models?.[model]?.[min ?? ""];
|
|
7455
|
-
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
7456
|
-
"greater_or_equal"
|
|
7457
|
-
)} ${fieldRelationDate?.string}`;
|
|
7458
|
-
}
|
|
7459
|
-
}
|
|
7460
|
-
} else if (maxNowValue) {
|
|
7461
|
-
if (compareSelected.isAfter(compareNow) && typeof maxNowValue === "boolean" && maxNowValue === true) {
|
|
7462
|
-
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
7463
|
-
"less_or_equal_now"
|
|
7464
|
-
)}`;
|
|
7465
|
-
} else if (import_moment.default.isMoment(maxNowValue)) {
|
|
7466
|
-
const compareMax = showTime ? maxNowValue : maxNowValue.clone().startOf("day");
|
|
7467
|
-
if (compareSelected.isAfter(compareMax)) {
|
|
7468
|
-
const fieldRelationDate = viewData?.models?.[model]?.[max ?? ""];
|
|
7469
|
-
return `${i18n_default.t("please_enter")} ${string} ${i18n_default.t(
|
|
7470
|
-
"less_or_equal"
|
|
7471
|
-
)} ${fieldRelationDate?.string}`;
|
|
7198
|
+
return {
|
|
7199
|
+
handleCheckBoxAll
|
|
7200
|
+
};
|
|
7201
|
+
};
|
|
7202
|
+
|
|
7203
|
+
// src/widget/advance/table/table-view/controller.ts
|
|
7204
|
+
var import_react24 = require("react");
|
|
7205
|
+
var import_store12 = require("@fctc/interface-logic/store");
|
|
7206
|
+
var import_utils14 = require("@fctc/interface-logic/utils");
|
|
7207
|
+
var tableController = ({ data }) => {
|
|
7208
|
+
const [rows, setRows] = (0, import_react24.useState)(data.records || []);
|
|
7209
|
+
const [columns, setColumns] = (0, import_react24.useState)([]);
|
|
7210
|
+
const dataModelFields = data.fields?.map((field) => {
|
|
7211
|
+
return {
|
|
7212
|
+
...data.dataModel?.[field?.name],
|
|
7213
|
+
...field,
|
|
7214
|
+
string: field?.string || data.dataModel?.[field?.name]?.string
|
|
7215
|
+
};
|
|
7216
|
+
});
|
|
7217
|
+
const mergeFields = mergeButtons(dataModelFields);
|
|
7218
|
+
const transformData = (dataList) => {
|
|
7219
|
+
if (!dataList) return;
|
|
7220
|
+
return dataList?.map((item) => {
|
|
7221
|
+
const transformedItem = { ...item };
|
|
7222
|
+
Object.keys(item).forEach((field) => {
|
|
7223
|
+
if (field !== "__domain") {
|
|
7224
|
+
if (item[field] && typeof item[field] === "object" && item[field].display_name) {
|
|
7225
|
+
transformedItem[field] = item[field];
|
|
7226
|
+
} else if (Array.isArray(item[field]) && item[field].length > 0) {
|
|
7227
|
+
if (data.typeTable === "group" && item[field]?.length === 2 && typeof item[field]?.[1] === "string") {
|
|
7228
|
+
transformedItem["string"] = item[field]?.[1];
|
|
7229
|
+
}
|
|
7230
|
+
transformedItem[field] = item[field];
|
|
7231
|
+
}
|
|
7472
7232
|
}
|
|
7473
|
-
}
|
|
7233
|
+
});
|
|
7234
|
+
return item.display_name ? { ...transformedItem, item: item.display_name } : transformedItem;
|
|
7235
|
+
});
|
|
7236
|
+
};
|
|
7237
|
+
(0, import_react24.useEffect)(() => {
|
|
7238
|
+
setRows(transformData(data.records || null));
|
|
7239
|
+
}, [data.records]);
|
|
7240
|
+
const handleGetColumns = () => {
|
|
7241
|
+
let cols = [];
|
|
7242
|
+
try {
|
|
7243
|
+
cols = mergeFields?.filter((item) => {
|
|
7244
|
+
return item?.widget !== "details_Receive_money" && !(item?.column_invisible ? import_utils14.domainHelper.matchDomains(data.context, item?.column_invisible) : item?.invisible ? import_utils14.domainHelper.matchDomains(data.context, item?.invisible) : false);
|
|
7245
|
+
})?.map((field) => {
|
|
7246
|
+
return {
|
|
7247
|
+
name: field?.name,
|
|
7248
|
+
optional: field?.optional,
|
|
7249
|
+
title: field?.type_co === "button" ? "" : field?.string,
|
|
7250
|
+
field: { ...field }
|
|
7251
|
+
};
|
|
7252
|
+
});
|
|
7253
|
+
} catch (error) {
|
|
7254
|
+
console.error("Error in useTable:", error);
|
|
7474
7255
|
}
|
|
7475
|
-
return
|
|
7476
|
-
};
|
|
7477
|
-
return {
|
|
7478
|
-
formatDate,
|
|
7479
|
-
formatDateParse,
|
|
7480
|
-
range,
|
|
7481
|
-
years,
|
|
7482
|
-
months_vi,
|
|
7483
|
-
months_en,
|
|
7484
|
-
customValidateMinMax,
|
|
7485
|
-
minNowValue,
|
|
7486
|
-
maxNowValue
|
|
7256
|
+
return cols;
|
|
7487
7257
|
};
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7258
|
+
(0, import_react24.useEffect)(() => {
|
|
7259
|
+
const columns2 = handleGetColumns();
|
|
7260
|
+
setColumns(columns2);
|
|
7261
|
+
}, [data.records]);
|
|
7262
|
+
const onToggleColumnOptional = (item) => {
|
|
7263
|
+
const tempColumn = [...columns]?.map((val) => {
|
|
7264
|
+
if (item?.name === val?.name) {
|
|
7265
|
+
return {
|
|
7266
|
+
...val,
|
|
7267
|
+
optional: item?.optional === "show" ? "hide" : "show"
|
|
7268
|
+
};
|
|
7269
|
+
}
|
|
7270
|
+
return val;
|
|
7271
|
+
});
|
|
7272
|
+
setColumns(tempColumn);
|
|
7500
7273
|
};
|
|
7501
|
-
const propValue = value || defaultValue;
|
|
7502
7274
|
return {
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7275
|
+
rows,
|
|
7276
|
+
columns,
|
|
7277
|
+
onToggleColumnOptional,
|
|
7278
|
+
typeTable: data.typeTable
|
|
7506
7279
|
};
|
|
7507
7280
|
};
|
|
7508
7281
|
|
|
7509
|
-
// src/widget/
|
|
7510
|
-
var
|
|
7282
|
+
// src/widget/advance/table/table-group/controller.ts
|
|
7283
|
+
var import_react25 = require("react");
|
|
7511
7284
|
var import_hooks18 = require("@fctc/interface-logic/hooks");
|
|
7512
|
-
var
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
const
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7285
|
+
var import_store13 = require("@fctc/interface-logic/store");
|
|
7286
|
+
|
|
7287
|
+
// src/environment.ts
|
|
7288
|
+
var environment_exports = {};
|
|
7289
|
+
__reExport(environment_exports, require("@fctc/interface-logic/environment"));
|
|
7290
|
+
|
|
7291
|
+
// src/widget/advance/table/table-group/controller.ts
|
|
7292
|
+
var tableGroupController = (props) => {
|
|
7293
|
+
const env = (0, environment_exports.getEnv)();
|
|
7294
|
+
const {
|
|
7295
|
+
rows,
|
|
7296
|
+
columns,
|
|
7297
|
+
indexRow,
|
|
7298
|
+
row,
|
|
7299
|
+
model,
|
|
7300
|
+
viewData,
|
|
7301
|
+
renderField,
|
|
7302
|
+
level,
|
|
7303
|
+
specification,
|
|
7304
|
+
domain,
|
|
7305
|
+
context,
|
|
7306
|
+
checkedAll,
|
|
7307
|
+
isDisplayCheckbox,
|
|
7308
|
+
isAutoSelect,
|
|
7309
|
+
setIsAutoSelect,
|
|
7310
|
+
selectedRowKeysRef
|
|
7311
|
+
} = props;
|
|
7312
|
+
const [pageGroup, setPageGroup] = (0, import_react25.useState)(0);
|
|
7313
|
+
const { groupByDomain, selectedTags } = (0, import_store13.useAppSelector)(import_store13.selectSearch);
|
|
7314
|
+
const { selectedRowKeys } = (0, import_store13.useAppSelector)(import_store13.selectList);
|
|
7315
|
+
const appDispatch = (0, import_store13.useAppDispatch)();
|
|
7316
|
+
const { toDataJS } = (0, import_hooks18.useOdooDataTransform)();
|
|
7317
|
+
const initVal = toDataJS(row, viewData, model);
|
|
7318
|
+
const [isShowGroup, setIsShowGroup] = (0, import_react25.useState)(false);
|
|
7319
|
+
const [colEmptyGroup, setColEmptyGroup] = (0, import_react25.useState)({
|
|
7320
|
+
fromStart: 1,
|
|
7321
|
+
fromEnd: 1
|
|
7322
|
+
});
|
|
7323
|
+
const processedData = (0, import_react25.useMemo)(() => {
|
|
7324
|
+
const calculateColSpanEmpty = () => {
|
|
7325
|
+
const startIndex = columns.findIndex(
|
|
7326
|
+
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
|
|
7327
|
+
);
|
|
7328
|
+
const endIndex = columns.findLastIndex(
|
|
7329
|
+
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
|
|
7330
|
+
);
|
|
7331
|
+
const fromStart = startIndex === -1 ? columns.length : startIndex;
|
|
7332
|
+
const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
|
|
7333
|
+
setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
|
|
7334
|
+
return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
|
|
7335
|
+
};
|
|
7336
|
+
return calculateColSpanEmpty();
|
|
7337
|
+
}, [columns, row]);
|
|
7338
|
+
const shouldFetchData = (0, import_react25.useMemo)(() => {
|
|
7339
|
+
return !!isShowGroup;
|
|
7340
|
+
}, [isShowGroup]);
|
|
7341
|
+
const enabled = shouldFetchData && !!processedData;
|
|
7342
|
+
const listDataProps = {
|
|
7343
|
+
model,
|
|
7344
|
+
specification,
|
|
7345
|
+
domain,
|
|
7346
|
+
context,
|
|
7347
|
+
offset: pageGroup * 10,
|
|
7348
|
+
fields: groupByDomain?.fields,
|
|
7349
|
+
groupby: [groupByDomain?.contexts[level]?.group_by]
|
|
7350
|
+
};
|
|
7351
|
+
const queryKey = [
|
|
7352
|
+
`data-${model}--${level}-row${indexRow}`,
|
|
7353
|
+
specification,
|
|
7354
|
+
domain,
|
|
7355
|
+
pageGroup
|
|
7356
|
+
];
|
|
7357
|
+
const {
|
|
7358
|
+
data: dataResponse,
|
|
7359
|
+
isFetched: isQueryFetched,
|
|
7360
|
+
isPlaceholderData,
|
|
7361
|
+
isLoading,
|
|
7362
|
+
isFetching
|
|
7363
|
+
} = (0, import_hooks18.useGetListData)(listDataProps, queryKey, enabled);
|
|
7364
|
+
const {
|
|
7365
|
+
columns: columnsGroup,
|
|
7366
|
+
rows: rowsGroup,
|
|
7367
|
+
typeTable: typeTableGroup
|
|
7368
|
+
} = tableController({
|
|
7369
|
+
data: {
|
|
7370
|
+
fields: viewData?.views?.list?.fields,
|
|
7371
|
+
records: dataResponse?.records ?? dataResponse?.groups,
|
|
7372
|
+
dataModel: viewData?.models?.[model],
|
|
7373
|
+
context: env.context,
|
|
7374
|
+
typeTable: dataResponse?.groups ? "group" : "list"
|
|
7375
|
+
}
|
|
7376
|
+
});
|
|
7377
|
+
const leftPadding = level > 1 ? level * 8 + "px" : "0px";
|
|
7378
|
+
(0, import_react25.useEffect)(() => {
|
|
7379
|
+
if (isShowGroup && selectedTags?.length > 0) {
|
|
7380
|
+
setIsShowGroup(false);
|
|
7381
|
+
}
|
|
7382
|
+
}, [selectedTags]);
|
|
7383
|
+
const group_by_field_name = groupByDomain?.contexts[level - 1]?.group_by;
|
|
7384
|
+
const nameGroup = Array.isArray(row[group_by_field_name]) ? row?.string ?? row[`${group_by_field_name}`][1] : viewData?.models?.[model]?.[group_by_field_name]?.selection ? viewData.models[model][group_by_field_name].selection.find(
|
|
7385
|
+
(selectItem) => selectItem?.[0] === row[group_by_field_name]
|
|
7386
|
+
)?.[1] : row[group_by_field_name];
|
|
7387
|
+
const nameGroupWithCount = `${typeof nameGroup === "string" ? nameGroup : typeof nameGroup === "boolean" && nameGroup ? i18n_default.t("yes") : i18n_default.t("no")} (${row[`${group_by_field_name?.split(":")?.[0]}_count`]})`;
|
|
7388
|
+
const allIdsNull = selectedRowKeys?.every((item) => item === void 0);
|
|
7389
|
+
const handleExpandChildGroup = () => {
|
|
7390
|
+
if (isLoading || isFetching) return;
|
|
7391
|
+
const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
|
|
7392
|
+
if (allIdsNull || typeTableGroup === "group") {
|
|
7393
|
+
toggleShowGroup();
|
|
7394
|
+
return;
|
|
7395
|
+
}
|
|
7396
|
+
if (isShowGroup && checkedAll) {
|
|
7397
|
+
const ids = rowsGroup?.map((item) => item?.id) || [];
|
|
7398
|
+
const filteredIds = selectedRowKeys.filter(
|
|
7399
|
+
(id) => !ids.includes(id)
|
|
7400
|
+
);
|
|
7401
|
+
appDispatch((0, import_store13.setSelectedRowKeys)(filteredIds));
|
|
7402
|
+
} else if (!isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && checkedAll && !allIdsNull && isQueryFetched) {
|
|
7403
|
+
const clonedKeys = [...selectedRowKeys];
|
|
7404
|
+
appDispatch((0, import_store13.setSelectedRowKeys)([...clonedKeys, -1]));
|
|
7405
|
+
setTimeout(() => appDispatch((0, import_store13.setSelectedRowKeys)(clonedKeys)), 500);
|
|
7406
|
+
} else if (isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && !checkedAll && !allIdsNull) {
|
|
7407
|
+
const filteredKeys = selectedRowKeys.filter((id) => id > -1);
|
|
7408
|
+
appDispatch((0, import_store13.setSelectedRowKeys)(filteredKeys));
|
|
7536
7409
|
}
|
|
7410
|
+
toggleShowGroup();
|
|
7537
7411
|
};
|
|
7412
|
+
(0, import_react25.useEffect)(() => {
|
|
7413
|
+
if (!isQueryFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
|
|
7414
|
+
return;
|
|
7415
|
+
}
|
|
7416
|
+
const clonedKeys = [...selectedRowKeys];
|
|
7417
|
+
(0, import_store13.setSelectedRowKeys)([...clonedKeys, -1]);
|
|
7418
|
+
setTimeout(() => (0, import_store13.setSelectedRowKeys)(clonedKeys), 500);
|
|
7419
|
+
}, [isQueryFetched]);
|
|
7538
7420
|
return {
|
|
7539
|
-
|
|
7421
|
+
handleExpandChildGroup,
|
|
7422
|
+
colEmptyGroup,
|
|
7423
|
+
leftPadding,
|
|
7424
|
+
isShowGroup,
|
|
7425
|
+
isQueryFetched,
|
|
7426
|
+
nameGroupWithCount,
|
|
7427
|
+
columns,
|
|
7428
|
+
row,
|
|
7429
|
+
isPlaceholderData,
|
|
7430
|
+
columnsGroup,
|
|
7431
|
+
indexRow,
|
|
7432
|
+
rowsGroup,
|
|
7433
|
+
model,
|
|
7434
|
+
viewData,
|
|
7435
|
+
renderField,
|
|
7436
|
+
level,
|
|
7437
|
+
specification,
|
|
7438
|
+
context,
|
|
7439
|
+
checkedAll,
|
|
7440
|
+
isDisplayCheckbox,
|
|
7441
|
+
isAutoSelect,
|
|
7442
|
+
setIsAutoSelect,
|
|
7443
|
+
selectedRowKeysRef,
|
|
7444
|
+
initVal,
|
|
7445
|
+
dataResponse,
|
|
7446
|
+
pageGroup,
|
|
7447
|
+
setPageGroup
|
|
7540
7448
|
};
|
|
7541
7449
|
};
|
|
7542
7450
|
|
|
7543
|
-
// src/widget/
|
|
7451
|
+
// src/widget/advance/search/controller.ts
|
|
7452
|
+
var import_constants5 = require("@fctc/interface-logic/constants");
|
|
7453
|
+
var import_utils15 = require("@fctc/interface-logic/utils");
|
|
7454
|
+
var import_moment2 = __toESM(require_moment());
|
|
7544
7455
|
var import_react26 = require("react");
|
|
7545
|
-
var
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
const
|
|
7554
|
-
const
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7456
|
+
var searchController = ({
|
|
7457
|
+
viewData,
|
|
7458
|
+
actionData,
|
|
7459
|
+
fieldsList,
|
|
7460
|
+
contextSearch,
|
|
7461
|
+
setSearchMap,
|
|
7462
|
+
searchMap
|
|
7463
|
+
}) => {
|
|
7464
|
+
const [filterBy, setFilterBy] = (0, import_react26.useState)(null);
|
|
7465
|
+
const [searchBy, setSearchBy] = (0, import_react26.useState)(null);
|
|
7466
|
+
const [groupBy, setGroupBy] = (0, import_react26.useState)(null);
|
|
7467
|
+
const [selectedTags, setSelectedTags] = (0, import_react26.useState)(null);
|
|
7468
|
+
const [searchString, setSearchString] = (0, import_react26.useState)("");
|
|
7469
|
+
const domainAction = actionData?.domain ? Array.isArray(actionData?.domain) ? [...actionData?.domain] : (0, import_utils15.evalJSONDomain)(actionData?.domain, contextSearch) : [];
|
|
7470
|
+
const aid = actionData?.id;
|
|
7471
|
+
const model = actionData?.res_model;
|
|
7472
|
+
const clearSearch = () => {
|
|
7473
|
+
setFilterBy([]);
|
|
7474
|
+
setGroupBy([]);
|
|
7475
|
+
setSearchBy([]);
|
|
7476
|
+
setSelectedTags(null);
|
|
7477
|
+
setSearchString("");
|
|
7478
|
+
setSearchMap({});
|
|
7479
|
+
};
|
|
7480
|
+
const fetchData = async () => {
|
|
7481
|
+
if (viewData) {
|
|
7482
|
+
try {
|
|
7483
|
+
const dataModel = viewData?.models?.[model];
|
|
7484
|
+
const searchViews = viewData?.views?.search;
|
|
7485
|
+
const searchByItems = searchViews?.search_by?.filter(
|
|
7486
|
+
(item) => !import_utils15.domainHelper.matchDomains(contextSearch, item.invisible)
|
|
7487
|
+
)?.map(
|
|
7488
|
+
({ string, name, filter_domain, operator, widget }, index) => ({
|
|
7489
|
+
dataIndex: index,
|
|
7490
|
+
title: string ?? dataModel[name]?.string,
|
|
7491
|
+
name: name ?? dataModel[name]?.name,
|
|
7492
|
+
filter_domain,
|
|
7493
|
+
operator,
|
|
7494
|
+
widget,
|
|
7495
|
+
type: dataModel[name]?.type
|
|
7496
|
+
})
|
|
7497
|
+
);
|
|
7498
|
+
const filterByItems = searchViews?.filter_by.filter((item) => {
|
|
7499
|
+
return !import_utils15.domainHelper.matchDomains(contextSearch, item?.invisible);
|
|
7500
|
+
})?.map((item) => ({ ...item, active: false }));
|
|
7501
|
+
const groupByItems = searchViews?.group_by.filter(
|
|
7502
|
+
(item) => !import_utils15.domainHelper.matchDomains(contextSearch, item?.invisible)
|
|
7503
|
+
).map((item) => ({
|
|
7504
|
+
...item,
|
|
7505
|
+
string: item.string ?? viewData?.models?.[model]?.[item?.name?.split("group_by_")?.[1]]?.string
|
|
7506
|
+
}));
|
|
7507
|
+
setSearchBy(searchByItems);
|
|
7508
|
+
setFilterBy(filterByItems);
|
|
7509
|
+
setGroupBy(groupByItems);
|
|
7510
|
+
} catch (error) {
|
|
7511
|
+
console.error("Error fetching data:", error);
|
|
7512
|
+
}
|
|
7569
7513
|
}
|
|
7570
7514
|
};
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7515
|
+
(0, import_react26.useEffect)(() => {
|
|
7516
|
+
clearSearch();
|
|
7517
|
+
fetchData();
|
|
7518
|
+
}, [aid, model, viewData]);
|
|
7519
|
+
const onChangeSearchInput = (search_string) => {
|
|
7520
|
+
setSearchString(search_string);
|
|
7576
7521
|
};
|
|
7577
|
-
const
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
const
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7522
|
+
const removeKeyFromSearchMap = ({
|
|
7523
|
+
key,
|
|
7524
|
+
item
|
|
7525
|
+
}) => {
|
|
7526
|
+
const values = searchMap[key];
|
|
7527
|
+
if (!values) return searchMap;
|
|
7528
|
+
const newSearchMap = { ...searchMap };
|
|
7529
|
+
if (item) {
|
|
7530
|
+
const filtered = values.filter((value) => value.name !== item.name);
|
|
7531
|
+
if (filtered.length > 0) {
|
|
7532
|
+
newSearchMap[key] = filtered;
|
|
7533
|
+
} else {
|
|
7534
|
+
delete newSearchMap[key];
|
|
7535
|
+
}
|
|
7536
|
+
} else {
|
|
7537
|
+
delete newSearchMap[key];
|
|
7590
7538
|
}
|
|
7539
|
+
setSearchMap(newSearchMap);
|
|
7591
7540
|
};
|
|
7592
|
-
const
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
const isBlobUrl = (url) => {
|
|
7598
|
-
return /^blob:/.test(url);
|
|
7541
|
+
const updateSearchMap = ({ key, item }) => {
|
|
7542
|
+
const newSearchMap = { ...searchMap };
|
|
7543
|
+
const currentValues = searchMap[key] ?? [];
|
|
7544
|
+
newSearchMap[key] = [...currentValues, item];
|
|
7545
|
+
setSearchMap(newSearchMap);
|
|
7599
7546
|
};
|
|
7600
|
-
const
|
|
7601
|
-
|
|
7602
|
-
return imageExtensions.test(url) || (0, import_utils14.isBase64Image)(url) || isBlobUrl(url);
|
|
7547
|
+
const removeSearchItems = (key, item) => {
|
|
7548
|
+
removeKeyFromSearchMap({ key: String(key), item });
|
|
7603
7549
|
};
|
|
7604
|
-
const
|
|
7605
|
-
|
|
7606
|
-
if ((0, import_utils14.isBase64Image)(base64)) return base64;
|
|
7607
|
-
let mimeType = null;
|
|
7608
|
-
if (base64.startsWith("iVBORw0KGgo")) mimeType = "image/png";
|
|
7609
|
-
else if (base64.startsWith("/9j/")) mimeType = "image/jpeg";
|
|
7610
|
-
else if (base64.startsWith("R0lGOD")) mimeType = "image/gif";
|
|
7611
|
-
else if (base64.startsWith("Qk")) mimeType = "image/bmp";
|
|
7612
|
-
else if (base64.startsWith("UklGR")) mimeType = "image/webp";
|
|
7613
|
-
return mimeType ? `data:${mimeType};base64,${base64}` : null;
|
|
7550
|
+
const addSearchItems = (key, newItem) => {
|
|
7551
|
+
updateSearchMap({ key, item: newItem });
|
|
7614
7552
|
};
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7553
|
+
const formatDomain = () => {
|
|
7554
|
+
if (domainAction) {
|
|
7555
|
+
const domain = [];
|
|
7556
|
+
if (domainAction?.length > 0) {
|
|
7557
|
+
if (Object.keys(searchMap).length > 0) {
|
|
7558
|
+
domain.push("&");
|
|
7559
|
+
}
|
|
7560
|
+
domainAction.forEach((domainItem) => {
|
|
7561
|
+
domain.push(domainItem);
|
|
7562
|
+
});
|
|
7619
7563
|
}
|
|
7620
|
-
|
|
7621
|
-
|
|
7564
|
+
Object.keys(searchMap).forEach((key, keyIndex, keys) => {
|
|
7565
|
+
if (!key?.includes(import_constants5.SearchType.GROUP)) {
|
|
7566
|
+
if (keys.length > 1 && keyIndex < keys.length - 1) {
|
|
7567
|
+
domain.push("&");
|
|
7568
|
+
}
|
|
7569
|
+
const valuesOfKey = searchMap[key];
|
|
7570
|
+
valuesOfKey.forEach((value, index) => {
|
|
7571
|
+
if (index < valuesOfKey.length - 1) {
|
|
7572
|
+
domain.push("|");
|
|
7573
|
+
}
|
|
7574
|
+
if (value.domain) {
|
|
7575
|
+
domain.push(...value.domain);
|
|
7576
|
+
return;
|
|
7577
|
+
}
|
|
7578
|
+
let valueDomainItem = value?.value;
|
|
7579
|
+
if (value?.modelType === "date") {
|
|
7580
|
+
valueDomainItem = (0, import_utils15.validateAndParseDate)(value?.value);
|
|
7581
|
+
} else if (value?.modelType === "datetime") {
|
|
7582
|
+
if (value?.operator === "<=" || value?.operator === "<") {
|
|
7583
|
+
const parsedDate = (0, import_utils15.validateAndParseDate)(value?.value, true);
|
|
7584
|
+
const hasTime = (0, import_moment2.default)(value?.value).format("HH:mm:ss") !== "00:00:00";
|
|
7585
|
+
valueDomainItem = hasTime ? (0, import_moment2.default)(parsedDate).format("YYYY-MM-DD HH:mm:ss") : (0, import_moment2.default)(parsedDate).add(1, "day").subtract(1, "second").format("YYYY-MM-DD HH:mm:ss");
|
|
7586
|
+
} else {
|
|
7587
|
+
valueDomainItem = (0, import_utils15.validateAndParseDate)(value?.value, true);
|
|
7588
|
+
}
|
|
7589
|
+
}
|
|
7590
|
+
const operator = value?.modelType === "date" || value?.modelType === "datetime" || value?.modelType === "boolean" || value?.modelType === "integer" ? value?.operator ?? "=" : value.operator ?? "ilike";
|
|
7591
|
+
domain.push([value.name, operator, valueDomainItem]);
|
|
7592
|
+
});
|
|
7593
|
+
}
|
|
7594
|
+
});
|
|
7595
|
+
return [...domain];
|
|
7596
|
+
}
|
|
7597
|
+
};
|
|
7598
|
+
const setTagSearch = (0, import_react26.useCallback)(
|
|
7599
|
+
(updatedMap) => {
|
|
7600
|
+
if (!updatedMap) return;
|
|
7601
|
+
const tagsSearch = Object.entries(updatedMap).map(
|
|
7602
|
+
([key, objValues]) => {
|
|
7603
|
+
const {
|
|
7604
|
+
title,
|
|
7605
|
+
name,
|
|
7606
|
+
groupIndex,
|
|
7607
|
+
type,
|
|
7608
|
+
widget,
|
|
7609
|
+
modelType,
|
|
7610
|
+
dataIndex
|
|
7611
|
+
} = objValues[0];
|
|
7612
|
+
if (!key?.includes(import_constants5.SearchType.GROUP)) {
|
|
7613
|
+
const values = objValues?.map((objValue) => objValue.value);
|
|
7614
|
+
return {
|
|
7615
|
+
title,
|
|
7616
|
+
name: type === import_constants5.SearchType.SEARCH ? `${import_constants5.SearchType.SEARCH}_${String(dataIndex)}` : groupIndex ?? name,
|
|
7617
|
+
values,
|
|
7618
|
+
type,
|
|
7619
|
+
widget,
|
|
7620
|
+
modelType
|
|
7621
|
+
};
|
|
7622
|
+
} else {
|
|
7623
|
+
const contexts = [];
|
|
7624
|
+
let groupValues = [];
|
|
7625
|
+
objValues?.forEach((objValue) => {
|
|
7626
|
+
const { context, value, active, groupIndex: groupIndex2, isDefault } = objValue;
|
|
7627
|
+
const indexAppend = groupIndex2 != null ? groupIndex2 : viewData?.views?.search?.filters_by?.length ?? 0;
|
|
7628
|
+
contexts.push(
|
|
7629
|
+
...Array.isArray(context?.group_by) ? context.group_by.map((item) => ({ group_by: item })) : [context]
|
|
7630
|
+
);
|
|
7631
|
+
groupValues[indexAppend] = {
|
|
7632
|
+
contexts: [
|
|
7633
|
+
...Array.isArray(context?.group_by) ? context.group_by.map((item) => ({
|
|
7634
|
+
group_by: item
|
|
7635
|
+
})) : [context]
|
|
7636
|
+
],
|
|
7637
|
+
strings: isDefault ? [value] : [...groupValues[indexAppend]?.strings ?? [], value]
|
|
7638
|
+
};
|
|
7639
|
+
});
|
|
7640
|
+
const fields = [
|
|
7641
|
+
...new Set(fieldsList?.map((item) => item?.name))
|
|
7642
|
+
];
|
|
7643
|
+
const groupByTag = {
|
|
7644
|
+
title,
|
|
7645
|
+
values: groupValues?.filter(
|
|
7646
|
+
(item) => item !== void 0
|
|
7647
|
+
),
|
|
7648
|
+
type,
|
|
7649
|
+
contexts,
|
|
7650
|
+
fields
|
|
7651
|
+
};
|
|
7652
|
+
return groupByTag;
|
|
7653
|
+
}
|
|
7654
|
+
}
|
|
7655
|
+
);
|
|
7656
|
+
setSelectedTags(tagsSearch);
|
|
7657
|
+
setSearchString("");
|
|
7658
|
+
},
|
|
7659
|
+
[searchMap]
|
|
7660
|
+
);
|
|
7622
7661
|
(0, import_react26.useEffect)(() => {
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7662
|
+
setSelectedTags(null);
|
|
7663
|
+
setTagSearch(searchMap);
|
|
7664
|
+
}, [searchMap]);
|
|
7665
|
+
const handleAddTagSearch = (tag) => {
|
|
7666
|
+
const {
|
|
7667
|
+
domain,
|
|
7668
|
+
groupIndex,
|
|
7669
|
+
value,
|
|
7670
|
+
type,
|
|
7671
|
+
title,
|
|
7672
|
+
context,
|
|
7673
|
+
active,
|
|
7674
|
+
dataIndex
|
|
7675
|
+
} = tag;
|
|
7676
|
+
const domainFormat = new import_utils15.domainHelper.Domain(domain);
|
|
7677
|
+
if (type === import_constants5.SearchType.FILTER) {
|
|
7678
|
+
addSearchItems(`${import_constants5.SearchType.FILTER}_${groupIndex}`, {
|
|
7679
|
+
...tag,
|
|
7680
|
+
domain: domain ? domainFormat.toList(context) : null
|
|
7681
|
+
});
|
|
7682
|
+
} else if (type === import_constants5.SearchType.SEARCH) {
|
|
7683
|
+
addSearchItems(`${import_constants5.SearchType.SEARCH}_${String(dataIndex)}`, {
|
|
7684
|
+
...tag,
|
|
7685
|
+
domain: domain ? domainFormat.toList({
|
|
7686
|
+
...context,
|
|
7687
|
+
self: value
|
|
7688
|
+
}) : null
|
|
7689
|
+
});
|
|
7690
|
+
} else if (type === import_constants5.SearchType.GROUP) {
|
|
7691
|
+
addSearchItems(`${import_constants5.SearchType.GROUP}`, {
|
|
7692
|
+
...tag,
|
|
7693
|
+
domain: domain ? domainFormat.toList({
|
|
7694
|
+
context,
|
|
7695
|
+
self: value
|
|
7696
|
+
}) : null
|
|
7697
|
+
});
|
|
7626
7698
|
}
|
|
7627
|
-
}
|
|
7699
|
+
};
|
|
7628
7700
|
return {
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7701
|
+
groupBy,
|
|
7702
|
+
searchBy,
|
|
7703
|
+
filterBy,
|
|
7704
|
+
selectedTags,
|
|
7705
|
+
searchString,
|
|
7706
|
+
setFilterBy,
|
|
7707
|
+
setGroupBy,
|
|
7708
|
+
setSearchBy,
|
|
7709
|
+
clearSearch,
|
|
7710
|
+
setSelectedTags,
|
|
7711
|
+
removeSearchItems,
|
|
7712
|
+
onSearchString: onChangeSearchInput,
|
|
7713
|
+
handleAddTagSearch,
|
|
7714
|
+
domain: formatDomain()
|
|
7638
7715
|
};
|
|
7639
7716
|
};
|
|
7640
7717
|
|
|
7641
|
-
// src/utils.ts
|
|
7642
|
-
var utils_exports = {};
|
|
7643
|
-
__export(utils_exports, {
|
|
7644
|
-
API_APP_URL: () => API_APP_URL,
|
|
7645
|
-
API_PRESCHOOL_URL: () => API_PRESCHOOL_URL,
|
|
7646
|
-
STORAGES: () => STORAGES,
|
|
7647
|
-
combineContexts: () => combineContexts,
|
|
7648
|
-
convertFieldsToArray: () => convertFieldsToArray,
|
|
7649
|
-
countSum: () => countSum,
|
|
7650
|
-
getDateRange: () => getDateRange,
|
|
7651
|
-
languages: () => languages,
|
|
7652
|
-
mergeButtons: () => mergeButtons,
|
|
7653
|
-
setStorageItemAsync: () => setStorageItemAsync,
|
|
7654
|
-
useGetRowIds: () => useGetRowIds,
|
|
7655
|
-
useSelectionState: () => useSelectionState,
|
|
7656
|
-
useStorageState: () => useStorageState
|
|
7657
|
-
});
|
|
7658
|
-
__reExport(utils_exports, require("@fctc/interface-logic/utils"));
|
|
7659
|
-
|
|
7660
7718
|
// src/index.ts
|
|
7661
7719
|
__reExport(index_exports, utils_exports, module.exports);
|
|
7662
7720
|
__reExport(index_exports, store_exports, module.exports);
|
|
@@ -7668,12 +7726,6 @@ __reExport(constants_exports, require("@fctc/interface-logic/constants"));
|
|
|
7668
7726
|
// src/index.ts
|
|
7669
7727
|
__reExport(index_exports, constants_exports, module.exports);
|
|
7670
7728
|
__reExport(index_exports, environment_exports, module.exports);
|
|
7671
|
-
|
|
7672
|
-
// src/provider.ts
|
|
7673
|
-
var provider_exports = {};
|
|
7674
|
-
__reExport(provider_exports, require("@fctc/interface-logic/provider"));
|
|
7675
|
-
|
|
7676
|
-
// src/index.ts
|
|
7677
7729
|
__reExport(index_exports, provider_exports, module.exports);
|
|
7678
7730
|
|
|
7679
7731
|
// src/services.ts
|