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