@fctc/widget-logic 1.2.2 → 1.2.3
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 +755 -753
- package/dist/index.mjs +892 -890
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -5163,7 +5163,7 @@ var many2oneFieldController = (props) => {
|
|
|
5163
5163
|
const queryKey = [`data_${relation}`, domainObject];
|
|
5164
5164
|
const {
|
|
5165
5165
|
data: dataOfSelection,
|
|
5166
|
-
refetch,
|
|
5166
|
+
// refetch,
|
|
5167
5167
|
isFetching
|
|
5168
5168
|
} = useGetSelection({
|
|
5169
5169
|
data,
|
|
@@ -5192,9 +5192,6 @@ var many2oneFieldController = (props) => {
|
|
|
5192
5192
|
});
|
|
5193
5193
|
}
|
|
5194
5194
|
}, [propValue]);
|
|
5195
|
-
const fetchMoreOptions = useCallback6(() => {
|
|
5196
|
-
refetch();
|
|
5197
|
-
}, [refetch]);
|
|
5198
5195
|
useEffect10(() => {
|
|
5199
5196
|
if (actionId) {
|
|
5200
5197
|
localStorage.setItem("aid", actionId);
|
|
@@ -5251,6 +5248,12 @@ var many2oneFieldController = (props) => {
|
|
|
5251
5248
|
[methods, name, onChange]
|
|
5252
5249
|
);
|
|
5253
5250
|
const allowShowDetail = showDetail && contextObject?.form_view_ref && (!("no_open" in optionsObject) || optionsObject?.no_open === false);
|
|
5251
|
+
const fetchMoreOptions = useCallback6(() => {
|
|
5252
|
+
if (typeof dataOfSelection?.refetch === "function") {
|
|
5253
|
+
;
|
|
5254
|
+
dataOfSelection.refetch();
|
|
5255
|
+
}
|
|
5256
|
+
}, [dataOfSelection]);
|
|
5254
5257
|
return {
|
|
5255
5258
|
allowShowDetail,
|
|
5256
5259
|
handleClose,
|
|
@@ -5266,7 +5269,8 @@ var many2oneFieldController = (props) => {
|
|
|
5266
5269
|
setTempSelectedOption,
|
|
5267
5270
|
setDomainModal,
|
|
5268
5271
|
dataOfSelection,
|
|
5269
|
-
refetch
|
|
5272
|
+
refetch: dataOfSelection?.refetch ?? (() => {
|
|
5273
|
+
}),
|
|
5270
5274
|
selectOptions,
|
|
5271
5275
|
optionsObject,
|
|
5272
5276
|
contextObject,
|
|
@@ -5306,32 +5310,141 @@ var many2oneButtonController = (props) => {
|
|
|
5306
5310
|
};
|
|
5307
5311
|
|
|
5308
5312
|
// src/widget/basic/many2many-field/controller.ts
|
|
5309
|
-
import { useEffect as
|
|
5313
|
+
import { useEffect as useEffect14, useMemo as useMemo12, useState as useState10 } from "react";
|
|
5310
5314
|
import {
|
|
5311
5315
|
evalJSONContext as evalJSONContext4,
|
|
5312
5316
|
formatSortingString as formatSortingString2,
|
|
5313
|
-
getEnv as
|
|
5314
|
-
selectSearch as
|
|
5317
|
+
getEnv as getEnv9,
|
|
5318
|
+
selectSearch as selectSearch5,
|
|
5315
5319
|
setFirstDomain,
|
|
5316
5320
|
setGroupByDomain,
|
|
5317
5321
|
setPage,
|
|
5318
5322
|
setViewDataStore,
|
|
5319
|
-
useAppDispatch as
|
|
5320
|
-
useAppSelector as
|
|
5323
|
+
useAppDispatch as useAppDispatch8,
|
|
5324
|
+
useAppSelector as useAppSelector7,
|
|
5321
5325
|
useGetFormView,
|
|
5322
|
-
useGetListData as
|
|
5326
|
+
useGetListData as useGetListData3,
|
|
5323
5327
|
useGetView as useGetView2,
|
|
5324
5328
|
useModel as useModel2
|
|
5325
5329
|
} from "@fctc/interface-logic";
|
|
5326
5330
|
|
|
5331
|
+
// src/widget/advance/table/table-body/controller.ts
|
|
5332
|
+
import { setSelectedRowKeys, useAppDispatch as useAppDispatch5 } from "@fctc/interface-logic";
|
|
5333
|
+
import { useEffect as useEffect11, useMemo as useMemo9 } from "react";
|
|
5334
|
+
var tableBodyController = (props) => {
|
|
5335
|
+
const {
|
|
5336
|
+
checkedAll,
|
|
5337
|
+
checkboxRef,
|
|
5338
|
+
setIsAutoSelect,
|
|
5339
|
+
selectedRowKeys,
|
|
5340
|
+
row,
|
|
5341
|
+
isAutoSelect,
|
|
5342
|
+
selectedRowKeysRef,
|
|
5343
|
+
onClickRow
|
|
5344
|
+
} = props;
|
|
5345
|
+
const appDispatch = useAppDispatch5();
|
|
5346
|
+
const checked = useMemo9(() => {
|
|
5347
|
+
if (!row?.id) return false;
|
|
5348
|
+
if (selectedRowKeys?.includes(row.id)) {
|
|
5349
|
+
return true;
|
|
5350
|
+
}
|
|
5351
|
+
return checkedAll;
|
|
5352
|
+
}, [row?.id, selectedRowKeys, checkedAll]);
|
|
5353
|
+
const handleCheckBoxSingle = (event) => {
|
|
5354
|
+
event.stopPropagation();
|
|
5355
|
+
if (checkedAll) {
|
|
5356
|
+
checkboxRef.current = "uncheck";
|
|
5357
|
+
setIsAutoSelect(true);
|
|
5358
|
+
return;
|
|
5359
|
+
}
|
|
5360
|
+
const newSelectedRowKeys = selectedRowKeys?.includes(row.id) ? selectedRowKeys?.filter((key) => key !== row.id) : [...selectedRowKeys, row.id];
|
|
5361
|
+
console.log("newSelectedRowKeys", newSelectedRowKeys);
|
|
5362
|
+
appDispatch(setSelectedRowKeys(newSelectedRowKeys));
|
|
5363
|
+
};
|
|
5364
|
+
const handleClickRow = (col, row2) => {
|
|
5365
|
+
onClickRow(col, row2);
|
|
5366
|
+
};
|
|
5367
|
+
useEffect11(() => {
|
|
5368
|
+
if (!row?.id) return;
|
|
5369
|
+
if (isAutoSelect) {
|
|
5370
|
+
if (checkboxRef?.current === "uncheck") {
|
|
5371
|
+
const filtered = selectedRowKeysRef.current.filter(
|
|
5372
|
+
(id) => id !== row.id
|
|
5373
|
+
);
|
|
5374
|
+
selectedRowKeysRef.current = filtered;
|
|
5375
|
+
appDispatch(setSelectedRowKeys(filtered));
|
|
5376
|
+
} else {
|
|
5377
|
+
const unique = Array.from(
|
|
5378
|
+
/* @__PURE__ */ new Set([...selectedRowKeysRef?.current, row?.id])
|
|
5379
|
+
);
|
|
5380
|
+
selectedRowKeysRef.current = unique;
|
|
5381
|
+
appDispatch(setSelectedRowKeys(unique));
|
|
5382
|
+
}
|
|
5383
|
+
}
|
|
5384
|
+
}, [isAutoSelect]);
|
|
5385
|
+
useEffect11(() => {
|
|
5386
|
+
if (!checkedAll) {
|
|
5387
|
+
checkboxRef.current = "enabled";
|
|
5388
|
+
false;
|
|
5389
|
+
}
|
|
5390
|
+
}, [checkedAll]);
|
|
5391
|
+
return {
|
|
5392
|
+
handleCheckBoxSingle,
|
|
5393
|
+
checked,
|
|
5394
|
+
handleClickRow
|
|
5395
|
+
};
|
|
5396
|
+
};
|
|
5397
|
+
|
|
5398
|
+
// src/widget/advance/table/table-head/controller.ts
|
|
5399
|
+
import {
|
|
5400
|
+
selectSearch as selectSearch2,
|
|
5401
|
+
setSelectedRowKeys as setSelectedRowKeys2,
|
|
5402
|
+
useAppDispatch as useAppDispatch6,
|
|
5403
|
+
useAppSelector as useAppSelector4
|
|
5404
|
+
} from "@fctc/interface-logic";
|
|
5405
|
+
var tableHeadController = (props) => {
|
|
5406
|
+
const { typeTable, rows, selectedRowKeysRef } = props;
|
|
5407
|
+
const appDispatch = useAppDispatch6();
|
|
5408
|
+
const { groupByDomain } = useAppSelector4(selectSearch2);
|
|
5409
|
+
const handleCheckBoxAll = (event) => {
|
|
5410
|
+
if (event?.target?.checked && typeTable === "list") {
|
|
5411
|
+
const allRowKeys = Array.isArray(rows) ? rows.map((record) => record?.id) : [];
|
|
5412
|
+
appDispatch(setSelectedRowKeys2(allRowKeys));
|
|
5413
|
+
} else if (event?.target?.checked && typeTable === "group") {
|
|
5414
|
+
const rowsIDs = document.querySelectorAll("tr[data-row-id]");
|
|
5415
|
+
const ids = Array.from(rowsIDs)?.map(
|
|
5416
|
+
(row) => Number(row?.getAttribute("data-row-id"))
|
|
5417
|
+
);
|
|
5418
|
+
if (ids?.length > 0) {
|
|
5419
|
+
appDispatch(setSelectedRowKeys2(ids));
|
|
5420
|
+
} else {
|
|
5421
|
+
const sum = countSum(
|
|
5422
|
+
rows,
|
|
5423
|
+
typeof groupByDomain === "object" ? groupByDomain?.contexts?.[0]?.group_by : void 0
|
|
5424
|
+
);
|
|
5425
|
+
const keys = Array.from({ length: sum }, (_) => void 0);
|
|
5426
|
+
appDispatch(setSelectedRowKeys2(keys));
|
|
5427
|
+
}
|
|
5428
|
+
if (selectedRowKeysRef) {
|
|
5429
|
+
selectedRowKeysRef.current = [];
|
|
5430
|
+
}
|
|
5431
|
+
} else {
|
|
5432
|
+
appDispatch(setSelectedRowKeys2([]));
|
|
5433
|
+
}
|
|
5434
|
+
};
|
|
5435
|
+
return {
|
|
5436
|
+
handleCheckBoxAll
|
|
5437
|
+
};
|
|
5438
|
+
};
|
|
5439
|
+
|
|
5327
5440
|
// src/widget/advance/table/table-view/controller.ts
|
|
5328
5441
|
import {
|
|
5329
5442
|
domainHelper,
|
|
5330
5443
|
selectList as selectList2,
|
|
5331
|
-
selectSearch as
|
|
5332
|
-
useAppSelector as
|
|
5444
|
+
selectSearch as selectSearch3,
|
|
5445
|
+
useAppSelector as useAppSelector5
|
|
5333
5446
|
} from "@fctc/interface-logic";
|
|
5334
|
-
import { useEffect as
|
|
5447
|
+
import { useEffect as useEffect12, useMemo as useMemo10, useRef as useRef4, useState as useState8 } from "react";
|
|
5335
5448
|
var tableController = ({ data }) => {
|
|
5336
5449
|
const [rows, setRows] = useState8(data.records || []);
|
|
5337
5450
|
const [columns, setColumns] = useState8([]);
|
|
@@ -5362,7 +5475,7 @@ var tableController = ({ data }) => {
|
|
|
5362
5475
|
return item.display_name ? { ...transformedItem, item: item.display_name } : transformedItem;
|
|
5363
5476
|
});
|
|
5364
5477
|
};
|
|
5365
|
-
|
|
5478
|
+
useEffect12(() => {
|
|
5366
5479
|
setRows(transformData(data.records || null));
|
|
5367
5480
|
}, [data.records]);
|
|
5368
5481
|
const handleGetColumns = () => {
|
|
@@ -5383,7 +5496,7 @@ var tableController = ({ data }) => {
|
|
|
5383
5496
|
}
|
|
5384
5497
|
return cols;
|
|
5385
5498
|
};
|
|
5386
|
-
|
|
5499
|
+
useEffect12(() => {
|
|
5387
5500
|
const columns2 = handleGetColumns();
|
|
5388
5501
|
setColumns(columns2);
|
|
5389
5502
|
}, [data.records]);
|
|
@@ -5407,466 +5520,23 @@ var tableController = ({ data }) => {
|
|
|
5407
5520
|
};
|
|
5408
5521
|
};
|
|
5409
5522
|
|
|
5410
|
-
// src/widget/
|
|
5411
|
-
var many2manyFieldController = (props) => {
|
|
5412
|
-
const {
|
|
5413
|
-
relation,
|
|
5414
|
-
domain,
|
|
5415
|
-
context,
|
|
5416
|
-
tab,
|
|
5417
|
-
model,
|
|
5418
|
-
aid,
|
|
5419
|
-
setSelectedRowKeys: setSelectedRowKeys4,
|
|
5420
|
-
fields,
|
|
5421
|
-
setFields,
|
|
5422
|
-
groupByDomain,
|
|
5423
|
-
page,
|
|
5424
|
-
options,
|
|
5425
|
-
sessionStorageUtils
|
|
5426
|
-
} = props;
|
|
5427
|
-
const appDispatch = useAppDispatch5();
|
|
5428
|
-
const actionData = sessionStorageUtils.getActionData();
|
|
5429
|
-
const [debouncedPage] = useDebounce(page, 500);
|
|
5430
|
-
const [order, setOrder] = useState9();
|
|
5431
|
-
const [isLoadedData, setIsLoadedData] = useState9(false);
|
|
5432
|
-
const [domainMany2Many, setDomainMany2Many] = useState9(domain);
|
|
5433
|
-
const env = getEnv8();
|
|
5434
|
-
const { selectedTags } = useAppSelector5(selectSearch3);
|
|
5435
|
-
const viewParams = {
|
|
5436
|
-
model: relation,
|
|
5437
|
-
views: [
|
|
5438
|
-
[false, "list"],
|
|
5439
|
-
[false, "search"]
|
|
5440
|
-
],
|
|
5441
|
-
context
|
|
5442
|
-
};
|
|
5443
|
-
const { data: viewResponse, isFetched: isViewReponseFetched } = useGetView2(
|
|
5444
|
-
viewParams,
|
|
5445
|
-
actionData
|
|
5446
|
-
);
|
|
5447
|
-
const baseModel = useMemo10(
|
|
5448
|
-
() => ({
|
|
5449
|
-
name: String(relation),
|
|
5450
|
-
view: viewResponse || {},
|
|
5451
|
-
actContext: context,
|
|
5452
|
-
fields: [
|
|
5453
|
-
...Object.values(viewResponse?.views?.list?.fields ?? {}),
|
|
5454
|
-
...tab?.fields ? tab.fields : []
|
|
5455
|
-
]
|
|
5456
|
-
}),
|
|
5457
|
-
[model, viewResponse]
|
|
5458
|
-
);
|
|
5459
|
-
const initModel = useModel2();
|
|
5460
|
-
const modelInstance = useMemo10(() => {
|
|
5461
|
-
if (viewResponse) {
|
|
5462
|
-
return initModel.initModel(baseModel);
|
|
5463
|
-
}
|
|
5464
|
-
return null;
|
|
5465
|
-
}, [baseModel, viewResponse]);
|
|
5466
|
-
const specification = useMemo10(() => {
|
|
5467
|
-
if (modelInstance) {
|
|
5468
|
-
return modelInstance.getSpecification();
|
|
5469
|
-
}
|
|
5470
|
-
return null;
|
|
5471
|
-
}, [modelInstance]);
|
|
5472
|
-
const default_order = viewResponse && viewResponse?.views?.list?.default_order;
|
|
5473
|
-
const optionsObject = tab?.options ? evalJSONContext4(tab?.options) : (options ? evalJSONContext4(options) : {}) || {};
|
|
5474
|
-
const fetchData = async () => {
|
|
5475
|
-
try {
|
|
5476
|
-
setDomainMany2Many(domain);
|
|
5477
|
-
appDispatch(setFirstDomain(domain));
|
|
5478
|
-
appDispatch(setViewDataStore(viewResponse));
|
|
5479
|
-
const modalData = viewResponse?.views?.list?.fields.map((field) => ({
|
|
5480
|
-
...viewResponse?.models?.[String(model)]?.[field?.name],
|
|
5481
|
-
...field
|
|
5482
|
-
}));
|
|
5483
|
-
if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
|
|
5484
|
-
setFields({
|
|
5485
|
-
...fields,
|
|
5486
|
-
[`${aid}_${relation}_popupmany2many`]: modalData
|
|
5487
|
-
});
|
|
5488
|
-
}
|
|
5489
|
-
appDispatch(setPage(0));
|
|
5490
|
-
} catch (err) {
|
|
5491
|
-
console.log(err);
|
|
5492
|
-
}
|
|
5493
|
-
};
|
|
5494
|
-
const queryKey = [
|
|
5495
|
-
`view-${relation}-${aid}`,
|
|
5496
|
-
specification,
|
|
5497
|
-
domainMany2Many,
|
|
5498
|
-
debouncedPage,
|
|
5499
|
-
groupByDomain,
|
|
5500
|
-
order
|
|
5501
|
-
];
|
|
5502
|
-
const data = {
|
|
5503
|
-
model: relation,
|
|
5504
|
-
specification,
|
|
5505
|
-
domain: domainMany2Many,
|
|
5506
|
-
offset: debouncedPage * 10,
|
|
5507
|
-
limit: 10,
|
|
5508
|
-
context,
|
|
5509
|
-
fields: groupByDomain?.fields,
|
|
5510
|
-
groupby: [groupByDomain?.contexts[0]?.group_by],
|
|
5511
|
-
sort: order ? order : default_order ? formatSortingString2(default_order) : ""
|
|
5512
|
-
};
|
|
5513
|
-
const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
|
|
5514
|
-
const {
|
|
5515
|
-
data: dataResponse,
|
|
5516
|
-
isLoading: isDataLoading,
|
|
5517
|
-
isFetched: isDataResponseFetched,
|
|
5518
|
-
isPlaceholderData
|
|
5519
|
-
} = useGetListData2(data, queryKey, enabled);
|
|
5520
|
-
useEffect12(() => {
|
|
5521
|
-
if (viewResponse) {
|
|
5522
|
-
fetchData();
|
|
5523
|
-
}
|
|
5524
|
-
return () => {
|
|
5525
|
-
appDispatch(setGroupByDomain(null));
|
|
5526
|
-
setFields((prevFields) => ({
|
|
5527
|
-
...prevFields,
|
|
5528
|
-
[`${aid}_${relation}_popupmany2many`]: null
|
|
5529
|
-
}));
|
|
5530
|
-
appDispatch(setPage(0));
|
|
5531
|
-
setSelectedRowKeys4([]);
|
|
5532
|
-
setDomainMany2Many(null);
|
|
5533
|
-
setIsLoadedData(false);
|
|
5534
|
-
};
|
|
5535
|
-
}, [viewResponse]);
|
|
5536
|
-
const { rows, columns, typeTable } = tableController({
|
|
5537
|
-
data: {
|
|
5538
|
-
fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
|
|
5539
|
-
records: dataResponse?.records ?? dataResponse?.groups,
|
|
5540
|
-
dataModel: viewResponse?.models?.[String(relation)],
|
|
5541
|
-
context: { ...env.context, ...context },
|
|
5542
|
-
typeTable: dataResponse?.groups ? "group" : "list"
|
|
5543
|
-
}
|
|
5544
|
-
});
|
|
5545
|
-
const dataFormView = {
|
|
5546
|
-
id: null,
|
|
5547
|
-
model: relation,
|
|
5548
|
-
context
|
|
5549
|
-
};
|
|
5550
|
-
const {
|
|
5551
|
-
refetch,
|
|
5552
|
-
data: dataFormViewResponse,
|
|
5553
|
-
isSuccess
|
|
5554
|
-
} = useGetFormView({
|
|
5555
|
-
data: dataFormView,
|
|
5556
|
-
queryKey: [`form-view-action-${relation}`],
|
|
5557
|
-
enabled: false
|
|
5558
|
-
});
|
|
5559
|
-
useEffect12(() => {
|
|
5560
|
-
if (isSuccess && dataFormViewResponse) {
|
|
5561
|
-
sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
|
|
5562
|
-
window.location.href = `/form/menu?model=${relation}`;
|
|
5563
|
-
}
|
|
5564
|
-
}, [isSuccess]);
|
|
5565
|
-
useEffect12(() => {
|
|
5566
|
-
if (domainMany2Many && !isLoadedData) {
|
|
5567
|
-
setIsLoadedData(true);
|
|
5568
|
-
}
|
|
5569
|
-
}, [domainMany2Many]);
|
|
5570
|
-
const handleCreateNewOnPage = async () => {
|
|
5571
|
-
try {
|
|
5572
|
-
refetch();
|
|
5573
|
-
} catch (error) {
|
|
5574
|
-
console.log(error);
|
|
5575
|
-
}
|
|
5576
|
-
};
|
|
5577
|
-
return {};
|
|
5578
|
-
};
|
|
5579
|
-
|
|
5580
|
-
// src/widget/basic/many2many-tags-field/controller.ts
|
|
5581
|
-
import { useMemo as useMemo11 } from "react";
|
|
5582
|
-
import {
|
|
5583
|
-
evalJSONContext as evalJSONContext5,
|
|
5584
|
-
evalJSONDomain as evalJSONDomain4,
|
|
5585
|
-
getEnv as getEnv9,
|
|
5586
|
-
useGetSelection as useGetSelection3,
|
|
5587
|
-
WIDGETAVATAR,
|
|
5588
|
-
WIDGETCOLOR
|
|
5589
|
-
} from "@fctc/interface-logic";
|
|
5590
|
-
var many2manyTagsController = (props) => {
|
|
5591
|
-
const {
|
|
5592
|
-
relation,
|
|
5593
|
-
domain,
|
|
5594
|
-
options: optionsFields,
|
|
5595
|
-
widget,
|
|
5596
|
-
formValues,
|
|
5597
|
-
placeholderNoOption
|
|
5598
|
-
} = props;
|
|
5599
|
-
const isUser = relation === "res.users" || relation === "res.partner";
|
|
5600
|
-
const env = getEnv9();
|
|
5601
|
-
const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
|
|
5602
|
-
const domainObject = useMemo11(
|
|
5603
|
-
() => evalJSONDomain4(domain, JSON.parse(JSON.stringify(formValues || {}))),
|
|
5604
|
-
[domain, formValues]
|
|
5605
|
-
);
|
|
5606
|
-
const data = {
|
|
5607
|
-
model: relation ?? "",
|
|
5608
|
-
domain: domainObject,
|
|
5609
|
-
specification: {
|
|
5610
|
-
id: {},
|
|
5611
|
-
name: {},
|
|
5612
|
-
display_name: {},
|
|
5613
|
-
...widget && WIDGETAVATAR[widget] ? { image_256: {} } : {},
|
|
5614
|
-
...widget && WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
|
|
5615
|
-
},
|
|
5616
|
-
enabled: true,
|
|
5617
|
-
context: env.context
|
|
5618
|
-
};
|
|
5619
|
-
const { data: dataOfSelection } = useGetSelection3({
|
|
5620
|
-
data,
|
|
5621
|
-
queryKey: [`data_${relation}`, domainObject]
|
|
5622
|
-
});
|
|
5623
|
-
const customNoOptionsMessage = () => placeholderNoOption;
|
|
5624
|
-
const tranfer = (data2) => {
|
|
5625
|
-
return data2?.map((val) => ({
|
|
5626
|
-
id: val.value,
|
|
5627
|
-
display_name: val.label
|
|
5628
|
-
})) || [];
|
|
5629
|
-
};
|
|
5630
|
-
const options = dataOfSelection?.records?.map((val) => ({
|
|
5631
|
-
value: val.id,
|
|
5632
|
-
label: val.name ?? val.display_name,
|
|
5633
|
-
...val
|
|
5634
|
-
})) || [];
|
|
5635
|
-
return {
|
|
5636
|
-
options,
|
|
5637
|
-
customNoOptionsMessage,
|
|
5638
|
-
tranfer,
|
|
5639
|
-
dataOfSelection,
|
|
5640
|
-
isUser
|
|
5641
|
-
};
|
|
5642
|
-
};
|
|
5643
|
-
|
|
5644
|
-
// src/widget/basic/status-bar-field/controller.ts
|
|
5645
|
-
import { useState as useState10 } from "react";
|
|
5523
|
+
// src/widget/advance/table/table-group/controller.ts
|
|
5646
5524
|
import {
|
|
5647
|
-
|
|
5648
|
-
|
|
5525
|
+
getEnv as getEnv8,
|
|
5526
|
+
selectList as selectList3,
|
|
5527
|
+
selectSearch as selectSearch4,
|
|
5528
|
+
setSelectedRowKeys as setSelectedRowKeys3,
|
|
5529
|
+
useAppDispatch as useAppDispatch7,
|
|
5649
5530
|
useAppSelector as useAppSelector6,
|
|
5650
|
-
|
|
5651
|
-
|
|
5531
|
+
useGetListData as useGetListData2,
|
|
5532
|
+
useOdooDataTransform
|
|
5652
5533
|
} from "@fctc/interface-logic";
|
|
5653
|
-
|
|
5654
|
-
const {
|
|
5655
|
-
relation,
|
|
5656
|
-
defaultValue,
|
|
5657
|
-
domain,
|
|
5658
|
-
formValues,
|
|
5659
|
-
name,
|
|
5660
|
-
id,
|
|
5661
|
-
model,
|
|
5662
|
-
onRefetch
|
|
5663
|
-
} = props;
|
|
5664
|
-
const specification = {
|
|
5665
|
-
id: 0,
|
|
5666
|
-
name: "",
|
|
5667
|
-
fold: ""
|
|
5668
|
-
};
|
|
5669
|
-
const [disabled, setDisabled] = useState10(false);
|
|
5670
|
-
const [modelStatus, setModalStatus] = useState10(false);
|
|
5671
|
-
const { context } = useAppSelector6(selectEnv3);
|
|
5672
|
-
const queryKey = [`data-status-duration`, specification];
|
|
5673
|
-
const listDataProps = {
|
|
5674
|
-
model: relation,
|
|
5675
|
-
specification,
|
|
5676
|
-
domain: evalJSONDomain5(domain, JSON.parse(JSON.stringify(formValues))),
|
|
5677
|
-
limit: 10,
|
|
5678
|
-
offset: 0,
|
|
5679
|
-
fields: "",
|
|
5680
|
-
groupby: [],
|
|
5681
|
-
context: {
|
|
5682
|
-
lang: context.lang
|
|
5683
|
-
},
|
|
5684
|
-
sort: ""
|
|
5685
|
-
};
|
|
5686
|
-
const { data: dataResponse } = useGetListData3(listDataProps, queryKey);
|
|
5687
|
-
const { mutate: fetchChangeStatus } = useChangeStatus();
|
|
5688
|
-
const handleClick = async (stage_id) => {
|
|
5689
|
-
setDisabled(true);
|
|
5690
|
-
if (stage_id) {
|
|
5691
|
-
fetchChangeStatus(
|
|
5692
|
-
{
|
|
5693
|
-
data: {
|
|
5694
|
-
stage_id,
|
|
5695
|
-
name,
|
|
5696
|
-
id,
|
|
5697
|
-
model,
|
|
5698
|
-
lang: context.lang
|
|
5699
|
-
}
|
|
5700
|
-
},
|
|
5701
|
-
{
|
|
5702
|
-
onSuccess: (res) => {
|
|
5703
|
-
if (res) {
|
|
5704
|
-
setDisabled(false);
|
|
5705
|
-
onRefetch && onRefetch();
|
|
5706
|
-
}
|
|
5707
|
-
}
|
|
5708
|
-
}
|
|
5709
|
-
);
|
|
5710
|
-
}
|
|
5711
|
-
};
|
|
5712
|
-
return {
|
|
5713
|
-
defaultValue,
|
|
5714
|
-
dataResponse,
|
|
5715
|
-
handleClick,
|
|
5716
|
-
disabled,
|
|
5717
|
-
modelStatus,
|
|
5718
|
-
setModalStatus
|
|
5719
|
-
};
|
|
5720
|
-
};
|
|
5534
|
+
import { useEffect as useEffect13, useMemo as useMemo11, useState as useState9 } from "react";
|
|
5721
5535
|
|
|
5722
|
-
// src/
|
|
5723
|
-
import {
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
value,
|
|
5727
|
-
isForm,
|
|
5728
|
-
name,
|
|
5729
|
-
methods,
|
|
5730
|
-
onChange,
|
|
5731
|
-
model,
|
|
5732
|
-
selection,
|
|
5733
|
-
id,
|
|
5734
|
-
actionData,
|
|
5735
|
-
viewData,
|
|
5736
|
-
context
|
|
5737
|
-
} = props;
|
|
5738
|
-
const _context = { ...evalJSONContext6(actionData?.context) };
|
|
5739
|
-
const contextObject = { ...context, ..._context };
|
|
5740
|
-
const defaultPriority = parseInt(value) + 1;
|
|
5741
|
-
const label = viewData?.models?.[model]?.[name ?? ""]?.string ?? name;
|
|
5742
|
-
const { mutateAsync: fetchSave } = useSave2();
|
|
5743
|
-
const savePriorities = async ({
|
|
5744
|
-
value: value2,
|
|
5745
|
-
resetPriority
|
|
5746
|
-
}) => {
|
|
5747
|
-
const priorityValue = value2 <= 0 ? 0 : value2 - 1;
|
|
5748
|
-
try {
|
|
5749
|
-
fetchSave({
|
|
5750
|
-
ids: id ? [id] : [],
|
|
5751
|
-
data: { [name ?? ""]: String(priorityValue) },
|
|
5752
|
-
model: model ?? "",
|
|
5753
|
-
context: contextObject
|
|
5754
|
-
});
|
|
5755
|
-
if (typeof onChange === "function") {
|
|
5756
|
-
onChange(name ?? "", String(priorityValue));
|
|
5757
|
-
}
|
|
5758
|
-
} catch (error) {
|
|
5759
|
-
if (resetPriority) {
|
|
5760
|
-
resetPriority();
|
|
5761
|
-
}
|
|
5762
|
-
}
|
|
5763
|
-
};
|
|
5764
|
-
return {
|
|
5765
|
-
selection,
|
|
5766
|
-
isForm,
|
|
5767
|
-
methods,
|
|
5768
|
-
defaultPriority,
|
|
5769
|
-
savePriorities,
|
|
5770
|
-
label,
|
|
5771
|
-
id,
|
|
5772
|
-
onChange
|
|
5773
|
-
};
|
|
5774
|
-
};
|
|
5775
|
-
|
|
5776
|
-
// src/widget/basic/float-time-field/controller.ts
|
|
5777
|
-
import { useState as useState11 } from "react";
|
|
5778
|
-
import { convertFloatToTime, convertTimeToFloat } from "@fctc/interface-logic";
|
|
5779
|
-
var floatTimeFiledController = ({
|
|
5780
|
-
onChange: fieldOnChange,
|
|
5781
|
-
onBlur,
|
|
5782
|
-
value,
|
|
5783
|
-
isDirty,
|
|
5784
|
-
props
|
|
5785
|
-
}) => {
|
|
5786
|
-
const { name, defaultValue = 0, onChange } = props;
|
|
5787
|
-
const [input, setInput] = useState11(
|
|
5788
|
-
convertFloatToTime(value ?? defaultValue)
|
|
5789
|
-
);
|
|
5790
|
-
const [formattedTime, setFormattedTime] = useState11("");
|
|
5791
|
-
const [errors, setErrors] = useState11("");
|
|
5792
|
-
const handleInputChange = (e) => {
|
|
5793
|
-
const raw = e.target.value.replace(/[^\d:]/g, "");
|
|
5794
|
-
setInput(raw);
|
|
5795
|
-
const timeRegex = /^(\d{1,2}):?(\d{0,2})$/;
|
|
5796
|
-
const match = raw.match(timeRegex);
|
|
5797
|
-
if (!match) {
|
|
5798
|
-
setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
|
|
5799
|
-
setFormattedTime("");
|
|
5800
|
-
return;
|
|
5801
|
-
}
|
|
5802
|
-
let hours = parseInt(match[1] ?? "0", 10);
|
|
5803
|
-
let minutes = parseInt(match[2] ?? "0", 10);
|
|
5804
|
-
if (isNaN(hours)) hours = 0;
|
|
5805
|
-
if (isNaN(minutes)) minutes = 0;
|
|
5806
|
-
if (hours >= 24) {
|
|
5807
|
-
hours = 0;
|
|
5808
|
-
}
|
|
5809
|
-
if (minutes >= 60) {
|
|
5810
|
-
minutes = 0;
|
|
5811
|
-
}
|
|
5812
|
-
const formatted = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
5813
|
-
setErrors("");
|
|
5814
|
-
setFormattedTime(formatted);
|
|
5815
|
-
fieldOnChange(formatted);
|
|
5816
|
-
};
|
|
5817
|
-
const handleBlur = () => {
|
|
5818
|
-
if (!isDirty) return;
|
|
5819
|
-
if (formattedTime) {
|
|
5820
|
-
setInput(formattedTime);
|
|
5821
|
-
const floatVal = convertTimeToFloat(formattedTime);
|
|
5822
|
-
fieldOnChange(floatVal);
|
|
5823
|
-
if (onChange) {
|
|
5824
|
-
onChange(name ?? "", floatVal);
|
|
5825
|
-
}
|
|
5826
|
-
} else {
|
|
5827
|
-
setInput("00:00");
|
|
5828
|
-
fieldOnChange(0);
|
|
5829
|
-
if (onChange) {
|
|
5830
|
-
onChange(name ?? "", 0);
|
|
5831
|
-
}
|
|
5832
|
-
setErrors("");
|
|
5833
|
-
}
|
|
5834
|
-
onBlur();
|
|
5835
|
-
};
|
|
5836
|
-
const handleKeyDown = (e) => {
|
|
5837
|
-
{
|
|
5838
|
-
const allowed = [
|
|
5839
|
-
"Backspace",
|
|
5840
|
-
"Tab",
|
|
5841
|
-
"ArrowLeft",
|
|
5842
|
-
"ArrowRight",
|
|
5843
|
-
"Delete",
|
|
5844
|
-
"Home",
|
|
5845
|
-
"End",
|
|
5846
|
-
":"
|
|
5847
|
-
];
|
|
5848
|
-
const isNumber = /^[0-9]$/.test(e.key);
|
|
5849
|
-
if (!isNumber && !allowed.includes(e.key)) {
|
|
5850
|
-
e.preventDefault();
|
|
5851
|
-
}
|
|
5852
|
-
}
|
|
5853
|
-
};
|
|
5854
|
-
return {
|
|
5855
|
-
handleInputChange,
|
|
5856
|
-
handleBlur,
|
|
5857
|
-
handleKeyDown,
|
|
5858
|
-
input,
|
|
5859
|
-
errors
|
|
5860
|
-
};
|
|
5861
|
-
};
|
|
5862
|
-
|
|
5863
|
-
// src/widget/basic/float-field/controller.ts
|
|
5864
|
-
import { useEffect as useEffect13, useRef as useRef5, useState as useState12 } from "react";
|
|
5865
|
-
|
|
5866
|
-
// src/utils/i18n.ts
|
|
5867
|
-
import { initReactI18next } from "react-i18next";
|
|
5868
|
-
import i18n from "i18next";
|
|
5869
|
-
import LanguageDetector from "i18next-browser-languagedetector";
|
|
5536
|
+
// src/utils/i18n.ts
|
|
5537
|
+
import { initReactI18next } from "react-i18next";
|
|
5538
|
+
import i18n from "i18next";
|
|
5539
|
+
import LanguageDetector from "i18next-browser-languagedetector";
|
|
5870
5540
|
|
|
5871
5541
|
// src/locales/vi.json
|
|
5872
5542
|
var vi_default = {
|
|
@@ -6053,8 +5723,6 @@ var vi_default = {
|
|
|
6053
5723
|
add_new_attribute: "Th\xEAm thu\u1ED9c t\xEDnh",
|
|
6054
5724
|
add_attribute_name: "T\xEAn thu\u1ED9c t\xEDnh",
|
|
6055
5725
|
images_product: "H\xECnh \u1EA3nh",
|
|
6056
|
-
selected: "\u0111\u01B0\u1EE3c ch\u1ECDn",
|
|
6057
|
-
print: "In",
|
|
6058
5726
|
generate_code_product: "T\u1EA1o m\xE3 s\u1EA3n ph\u1EA9m",
|
|
6059
5727
|
order_today: "\u0110\u01A1n h\xE0ng",
|
|
6060
5728
|
list_best_selling_product: "S\u1EA3n ph\u1EA9m b\xE1n ch\u1EA1y",
|
|
@@ -6612,26 +6280,640 @@ var vi_default = {
|
|
|
6612
6280
|
"export-all-data-error": "Xu\u1EA5t d\u1EEF li\u1EC7u kh\xF4ng th\xE0nh c\xF4ng, vui l\xF2ng th\u1EED l\u1EA1i sau"
|
|
6613
6281
|
};
|
|
6614
6282
|
|
|
6615
|
-
// src/utils/i18n.ts
|
|
6616
|
-
i18n.use(LanguageDetector).use(initReactI18next).init({
|
|
6617
|
-
resources: {
|
|
6618
|
-
vi: { translation: vi_default },
|
|
6619
|
-
en: { translation: vi_default }
|
|
6620
|
-
},
|
|
6621
|
-
fallbackLng: "vi",
|
|
6622
|
-
lng: "vi_VN",
|
|
6623
|
-
debug: false,
|
|
6624
|
-
nonExplicitSupportedLngs: true,
|
|
6625
|
-
interpolation: {
|
|
6626
|
-
escapeValue: false
|
|
6627
|
-
},
|
|
6628
|
-
detection: {
|
|
6629
|
-
caches: ["cookie"]
|
|
6630
|
-
}
|
|
6631
|
-
});
|
|
6632
|
-
var i18n_default = i18n;
|
|
6633
|
-
|
|
6283
|
+
// src/utils/i18n.ts
|
|
6284
|
+
i18n.use(LanguageDetector).use(initReactI18next).init({
|
|
6285
|
+
resources: {
|
|
6286
|
+
vi: { translation: vi_default },
|
|
6287
|
+
en: { translation: vi_default }
|
|
6288
|
+
},
|
|
6289
|
+
fallbackLng: "vi",
|
|
6290
|
+
lng: "vi_VN",
|
|
6291
|
+
debug: false,
|
|
6292
|
+
nonExplicitSupportedLngs: true,
|
|
6293
|
+
interpolation: {
|
|
6294
|
+
escapeValue: false
|
|
6295
|
+
},
|
|
6296
|
+
detection: {
|
|
6297
|
+
caches: ["cookie"]
|
|
6298
|
+
}
|
|
6299
|
+
});
|
|
6300
|
+
var i18n_default = i18n;
|
|
6301
|
+
|
|
6302
|
+
// src/widget/advance/table/table-group/controller.ts
|
|
6303
|
+
var tableGroupController = (props) => {
|
|
6304
|
+
const env = getEnv8();
|
|
6305
|
+
const {
|
|
6306
|
+
rows,
|
|
6307
|
+
columns,
|
|
6308
|
+
indexRow,
|
|
6309
|
+
row,
|
|
6310
|
+
model,
|
|
6311
|
+
viewData,
|
|
6312
|
+
renderField,
|
|
6313
|
+
level,
|
|
6314
|
+
specification,
|
|
6315
|
+
domain,
|
|
6316
|
+
context,
|
|
6317
|
+
checkedAll,
|
|
6318
|
+
isDisplayCheckbox,
|
|
6319
|
+
isAutoSelect,
|
|
6320
|
+
setIsAutoSelect,
|
|
6321
|
+
selectedRowKeysRef
|
|
6322
|
+
} = props;
|
|
6323
|
+
const [pageGroup, setPageGroup] = useState9(0);
|
|
6324
|
+
const { groupByDomain, selectedTags } = useAppSelector6(selectSearch4);
|
|
6325
|
+
const { selectedRowKeys } = useAppSelector6(selectList3);
|
|
6326
|
+
const appDispatch = useAppDispatch7();
|
|
6327
|
+
const { toDataJS } = useOdooDataTransform();
|
|
6328
|
+
const initVal = toDataJS(row, viewData, model);
|
|
6329
|
+
const [isShowGroup, setIsShowGroup] = useState9(false);
|
|
6330
|
+
const [colEmptyGroup, setColEmptyGroup] = useState9({
|
|
6331
|
+
fromStart: 1,
|
|
6332
|
+
fromEnd: 1
|
|
6333
|
+
});
|
|
6334
|
+
const processedData = useMemo11(() => {
|
|
6335
|
+
const calculateColSpanEmpty = () => {
|
|
6336
|
+
const startIndex = columns.findIndex(
|
|
6337
|
+
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
|
|
6338
|
+
);
|
|
6339
|
+
const endIndex = columns.findLastIndex(
|
|
6340
|
+
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
|
|
6341
|
+
);
|
|
6342
|
+
const fromStart = startIndex === -1 ? columns.length : startIndex;
|
|
6343
|
+
const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
|
|
6344
|
+
setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
|
|
6345
|
+
return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
|
|
6346
|
+
};
|
|
6347
|
+
return calculateColSpanEmpty();
|
|
6348
|
+
}, [columns, row]);
|
|
6349
|
+
const shouldFetchData = useMemo11(() => {
|
|
6350
|
+
return !!isShowGroup;
|
|
6351
|
+
}, [isShowGroup]);
|
|
6352
|
+
const enabled = shouldFetchData && !!processedData;
|
|
6353
|
+
const listDataProps = {
|
|
6354
|
+
model,
|
|
6355
|
+
specification,
|
|
6356
|
+
domain,
|
|
6357
|
+
context,
|
|
6358
|
+
offset: pageGroup * 10,
|
|
6359
|
+
fields: groupByDomain?.fields,
|
|
6360
|
+
groupby: [groupByDomain?.contexts[level]?.group_by]
|
|
6361
|
+
};
|
|
6362
|
+
const queryKey = [
|
|
6363
|
+
`data-${model}--${level}-row${indexRow}`,
|
|
6364
|
+
specification,
|
|
6365
|
+
domain,
|
|
6366
|
+
pageGroup
|
|
6367
|
+
];
|
|
6368
|
+
const {
|
|
6369
|
+
data: dataResponse,
|
|
6370
|
+
isFetched: isQueryFetched,
|
|
6371
|
+
isPlaceholderData,
|
|
6372
|
+
isLoading,
|
|
6373
|
+
isFetching
|
|
6374
|
+
} = useGetListData2(listDataProps, queryKey, enabled);
|
|
6375
|
+
const {
|
|
6376
|
+
columns: columnsGroup,
|
|
6377
|
+
rows: rowsGroup,
|
|
6378
|
+
typeTable: typeTableGroup
|
|
6379
|
+
} = tableController({
|
|
6380
|
+
data: {
|
|
6381
|
+
fields: viewData?.views?.list?.fields,
|
|
6382
|
+
records: dataResponse?.records ?? dataResponse?.groups,
|
|
6383
|
+
dataModel: viewData?.models?.[model],
|
|
6384
|
+
context: env.context,
|
|
6385
|
+
typeTable: dataResponse?.groups ? "group" : "list"
|
|
6386
|
+
}
|
|
6387
|
+
});
|
|
6388
|
+
const leftPadding = level > 1 ? level * 8 + "px" : "0px";
|
|
6389
|
+
useEffect13(() => {
|
|
6390
|
+
if (isShowGroup && selectedTags?.length > 0) {
|
|
6391
|
+
setIsShowGroup(false);
|
|
6392
|
+
}
|
|
6393
|
+
}, [selectedTags]);
|
|
6394
|
+
const group_by_field_name = groupByDomain?.contexts[level - 1]?.group_by;
|
|
6395
|
+
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(
|
|
6396
|
+
(selectItem) => selectItem?.[0] === row[group_by_field_name]
|
|
6397
|
+
)?.[1] : row[group_by_field_name];
|
|
6398
|
+
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`]})`;
|
|
6399
|
+
const allIdsNull = selectedRowKeys?.every((item) => item === void 0);
|
|
6400
|
+
const handleExpandChildGroup = () => {
|
|
6401
|
+
if (isLoading || isFetching) return;
|
|
6402
|
+
const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
|
|
6403
|
+
if (allIdsNull || typeTableGroup === "group") {
|
|
6404
|
+
toggleShowGroup();
|
|
6405
|
+
return;
|
|
6406
|
+
}
|
|
6407
|
+
if (isShowGroup && checkedAll) {
|
|
6408
|
+
const ids = rowsGroup?.map((item) => item?.id) || [];
|
|
6409
|
+
const filteredIds = selectedRowKeys.filter(
|
|
6410
|
+
(id) => !ids.includes(id)
|
|
6411
|
+
);
|
|
6412
|
+
appDispatch(setSelectedRowKeys3(filteredIds));
|
|
6413
|
+
} else if (!isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && checkedAll && !allIdsNull && isQueryFetched) {
|
|
6414
|
+
const clonedKeys = [...selectedRowKeys];
|
|
6415
|
+
appDispatch(setSelectedRowKeys3([...clonedKeys, -1]));
|
|
6416
|
+
setTimeout(() => appDispatch(setSelectedRowKeys3(clonedKeys)), 500);
|
|
6417
|
+
} else if (isShowGroup && selectedRowKeys?.length > 0 && typeTableGroup === "list" && !checkedAll && !allIdsNull) {
|
|
6418
|
+
const filteredKeys = selectedRowKeys.filter((id) => id > -1);
|
|
6419
|
+
appDispatch(setSelectedRowKeys3(filteredKeys));
|
|
6420
|
+
}
|
|
6421
|
+
toggleShowGroup();
|
|
6422
|
+
};
|
|
6423
|
+
useEffect13(() => {
|
|
6424
|
+
if (!isQueryFetched || !rowsGroup || !checkedAll || allIdsNull || typeTableGroup === "group") {
|
|
6425
|
+
return;
|
|
6426
|
+
}
|
|
6427
|
+
const clonedKeys = [...selectedRowKeys];
|
|
6428
|
+
setSelectedRowKeys3([...clonedKeys, -1]);
|
|
6429
|
+
setTimeout(() => setSelectedRowKeys3(clonedKeys), 500);
|
|
6430
|
+
}, [isQueryFetched]);
|
|
6431
|
+
return {
|
|
6432
|
+
handleExpandChildGroup,
|
|
6433
|
+
colEmptyGroup,
|
|
6434
|
+
leftPadding,
|
|
6435
|
+
isShowGroup,
|
|
6436
|
+
isQueryFetched,
|
|
6437
|
+
nameGroupWithCount,
|
|
6438
|
+
columns,
|
|
6439
|
+
row,
|
|
6440
|
+
isPlaceholderData,
|
|
6441
|
+
columnsGroup,
|
|
6442
|
+
indexRow,
|
|
6443
|
+
rowsGroup,
|
|
6444
|
+
model,
|
|
6445
|
+
viewData,
|
|
6446
|
+
renderField,
|
|
6447
|
+
level,
|
|
6448
|
+
specification,
|
|
6449
|
+
context,
|
|
6450
|
+
checkedAll,
|
|
6451
|
+
isDisplayCheckbox,
|
|
6452
|
+
isAutoSelect,
|
|
6453
|
+
setIsAutoSelect,
|
|
6454
|
+
selectedRowKeysRef,
|
|
6455
|
+
initVal,
|
|
6456
|
+
dataResponse,
|
|
6457
|
+
pageGroup,
|
|
6458
|
+
setPageGroup
|
|
6459
|
+
};
|
|
6460
|
+
};
|
|
6461
|
+
|
|
6462
|
+
// src/widget/basic/many2many-field/controller.ts
|
|
6463
|
+
var many2manyFieldController = (props) => {
|
|
6464
|
+
const {
|
|
6465
|
+
relation,
|
|
6466
|
+
domain,
|
|
6467
|
+
context,
|
|
6468
|
+
tab,
|
|
6469
|
+
model,
|
|
6470
|
+
aid,
|
|
6471
|
+
setSelectedRowKeys: setSelectedRowKeys4,
|
|
6472
|
+
fields,
|
|
6473
|
+
setFields,
|
|
6474
|
+
groupByDomain,
|
|
6475
|
+
page,
|
|
6476
|
+
options,
|
|
6477
|
+
sessionStorageUtils
|
|
6478
|
+
} = props;
|
|
6479
|
+
const appDispatch = useAppDispatch8();
|
|
6480
|
+
const actionData = sessionStorageUtils.getActionData();
|
|
6481
|
+
const [debouncedPage] = useDebounce(page, 500);
|
|
6482
|
+
const [order, setOrder] = useState10();
|
|
6483
|
+
const [isLoadedData, setIsLoadedData] = useState10(false);
|
|
6484
|
+
const [domainMany2Many, setDomainMany2Many] = useState10(domain);
|
|
6485
|
+
const env = getEnv9();
|
|
6486
|
+
const { selectedTags } = useAppSelector7(selectSearch5);
|
|
6487
|
+
const viewParams = {
|
|
6488
|
+
model: relation,
|
|
6489
|
+
views: [
|
|
6490
|
+
[false, "list"],
|
|
6491
|
+
[false, "search"]
|
|
6492
|
+
],
|
|
6493
|
+
context
|
|
6494
|
+
};
|
|
6495
|
+
const { data: viewResponse, isFetched: isViewReponseFetched } = useGetView2(
|
|
6496
|
+
viewParams,
|
|
6497
|
+
actionData
|
|
6498
|
+
);
|
|
6499
|
+
const baseModel = useMemo12(
|
|
6500
|
+
() => ({
|
|
6501
|
+
name: String(relation),
|
|
6502
|
+
view: viewResponse || {},
|
|
6503
|
+
actContext: context,
|
|
6504
|
+
fields: [
|
|
6505
|
+
...Object.values(viewResponse?.views?.list?.fields ?? {}),
|
|
6506
|
+
...tab?.fields ? tab.fields : []
|
|
6507
|
+
]
|
|
6508
|
+
}),
|
|
6509
|
+
[model, viewResponse]
|
|
6510
|
+
);
|
|
6511
|
+
const initModel = useModel2();
|
|
6512
|
+
const modelInstance = useMemo12(() => {
|
|
6513
|
+
if (viewResponse) {
|
|
6514
|
+
return initModel.initModel(baseModel);
|
|
6515
|
+
}
|
|
6516
|
+
return null;
|
|
6517
|
+
}, [baseModel, viewResponse]);
|
|
6518
|
+
const specification = useMemo12(() => {
|
|
6519
|
+
if (modelInstance) {
|
|
6520
|
+
return modelInstance.getSpecification();
|
|
6521
|
+
}
|
|
6522
|
+
return null;
|
|
6523
|
+
}, [modelInstance]);
|
|
6524
|
+
const default_order = viewResponse && viewResponse?.views?.list?.default_order;
|
|
6525
|
+
const optionsObject = tab?.options ? evalJSONContext4(tab?.options) : (options ? evalJSONContext4(options) : {}) || {};
|
|
6526
|
+
const fetchData = async () => {
|
|
6527
|
+
try {
|
|
6528
|
+
setDomainMany2Many(domain);
|
|
6529
|
+
appDispatch(setFirstDomain(domain));
|
|
6530
|
+
appDispatch(setViewDataStore(viewResponse));
|
|
6531
|
+
const modalData = viewResponse?.views?.list?.fields.map((field) => ({
|
|
6532
|
+
...viewResponse?.models?.[String(model)]?.[field?.name],
|
|
6533
|
+
...field
|
|
6534
|
+
}));
|
|
6535
|
+
if (!fields?.[`${aid}_${relation}_popupmany2many`] && modalData) {
|
|
6536
|
+
setFields({
|
|
6537
|
+
...fields,
|
|
6538
|
+
[`${aid}_${relation}_popupmany2many`]: modalData
|
|
6539
|
+
});
|
|
6540
|
+
}
|
|
6541
|
+
appDispatch(setPage(0));
|
|
6542
|
+
} catch (err) {
|
|
6543
|
+
console.log(err);
|
|
6544
|
+
}
|
|
6545
|
+
};
|
|
6546
|
+
const queryKey = [
|
|
6547
|
+
`view-${relation}-${aid}`,
|
|
6548
|
+
specification,
|
|
6549
|
+
domainMany2Many,
|
|
6550
|
+
debouncedPage,
|
|
6551
|
+
groupByDomain,
|
|
6552
|
+
order
|
|
6553
|
+
];
|
|
6554
|
+
const data = {
|
|
6555
|
+
model: relation,
|
|
6556
|
+
specification,
|
|
6557
|
+
domain: domainMany2Many,
|
|
6558
|
+
offset: debouncedPage * 10,
|
|
6559
|
+
limit: 10,
|
|
6560
|
+
context,
|
|
6561
|
+
fields: groupByDomain?.fields,
|
|
6562
|
+
groupby: [groupByDomain?.contexts[0]?.group_by],
|
|
6563
|
+
sort: order ? order : default_order ? formatSortingString2(default_order) : ""
|
|
6564
|
+
};
|
|
6565
|
+
const enabled = isLoadedData && !!specification && !!relation && !!domainMany2Many && !!viewResponse;
|
|
6566
|
+
const {
|
|
6567
|
+
data: dataResponse,
|
|
6568
|
+
isLoading: isDataLoading,
|
|
6569
|
+
isFetched: isDataResponseFetched,
|
|
6570
|
+
isPlaceholderData
|
|
6571
|
+
} = useGetListData3(data, queryKey, enabled);
|
|
6572
|
+
useEffect14(() => {
|
|
6573
|
+
if (viewResponse) {
|
|
6574
|
+
fetchData();
|
|
6575
|
+
}
|
|
6576
|
+
return () => {
|
|
6577
|
+
appDispatch(setGroupByDomain(null));
|
|
6578
|
+
setFields((prevFields) => ({
|
|
6579
|
+
...prevFields,
|
|
6580
|
+
[`${aid}_${relation}_popupmany2many`]: null
|
|
6581
|
+
}));
|
|
6582
|
+
appDispatch(setPage(0));
|
|
6583
|
+
setSelectedRowKeys4([]);
|
|
6584
|
+
setDomainMany2Many(null);
|
|
6585
|
+
setIsLoadedData(false);
|
|
6586
|
+
};
|
|
6587
|
+
}, [viewResponse]);
|
|
6588
|
+
const { rows, columns, typeTable } = tableController({
|
|
6589
|
+
data: {
|
|
6590
|
+
fields: fields?.[`${aid}_${relation}_popupmany2many`] || viewResponse?.views?.list?.fields,
|
|
6591
|
+
records: dataResponse?.records ?? dataResponse?.groups,
|
|
6592
|
+
dataModel: viewResponse?.models?.[String(relation)],
|
|
6593
|
+
context: { ...env.context, ...context },
|
|
6594
|
+
typeTable: dataResponse?.groups ? "group" : "list"
|
|
6595
|
+
}
|
|
6596
|
+
});
|
|
6597
|
+
const dataFormView = {
|
|
6598
|
+
id: null,
|
|
6599
|
+
model: relation,
|
|
6600
|
+
context
|
|
6601
|
+
};
|
|
6602
|
+
const {
|
|
6603
|
+
refetch,
|
|
6604
|
+
data: dataFormViewResponse,
|
|
6605
|
+
isSuccess
|
|
6606
|
+
} = useGetFormView({
|
|
6607
|
+
data: dataFormView,
|
|
6608
|
+
queryKey: [`form-view-action-${relation}`],
|
|
6609
|
+
enabled: false
|
|
6610
|
+
});
|
|
6611
|
+
useEffect14(() => {
|
|
6612
|
+
if (isSuccess && dataFormViewResponse) {
|
|
6613
|
+
sessionStorage.setItem("actionData", JSON.stringify(dataFormViewResponse));
|
|
6614
|
+
window.location.href = `/form/menu?model=${relation}`;
|
|
6615
|
+
}
|
|
6616
|
+
}, [isSuccess]);
|
|
6617
|
+
useEffect14(() => {
|
|
6618
|
+
if (domainMany2Many && !isLoadedData) {
|
|
6619
|
+
setIsLoadedData(true);
|
|
6620
|
+
}
|
|
6621
|
+
}, [domainMany2Many]);
|
|
6622
|
+
const handleCreateNewOnPage = async () => {
|
|
6623
|
+
try {
|
|
6624
|
+
refetch();
|
|
6625
|
+
} catch (error) {
|
|
6626
|
+
console.log(error);
|
|
6627
|
+
}
|
|
6628
|
+
};
|
|
6629
|
+
return {};
|
|
6630
|
+
};
|
|
6631
|
+
|
|
6632
|
+
// src/widget/basic/many2many-tags-field/controller.ts
|
|
6633
|
+
import { useMemo as useMemo13 } from "react";
|
|
6634
|
+
import {
|
|
6635
|
+
evalJSONContext as evalJSONContext5,
|
|
6636
|
+
evalJSONDomain as evalJSONDomain4,
|
|
6637
|
+
getEnv as getEnv10,
|
|
6638
|
+
useGetSelection as useGetSelection3,
|
|
6639
|
+
WIDGETAVATAR,
|
|
6640
|
+
WIDGETCOLOR
|
|
6641
|
+
} from "@fctc/interface-logic";
|
|
6642
|
+
var many2manyTagsController = (props) => {
|
|
6643
|
+
const {
|
|
6644
|
+
relation,
|
|
6645
|
+
domain,
|
|
6646
|
+
options: optionsFields,
|
|
6647
|
+
widget,
|
|
6648
|
+
formValues,
|
|
6649
|
+
placeholderNoOption
|
|
6650
|
+
} = props;
|
|
6651
|
+
const isUser = relation === "res.users" || relation === "res.partner";
|
|
6652
|
+
const env = getEnv10();
|
|
6653
|
+
const addtionalFields = optionsFields ? evalJSONContext5(optionsFields) : null;
|
|
6654
|
+
const domainObject = useMemo13(
|
|
6655
|
+
() => evalJSONDomain4(domain, JSON.parse(JSON.stringify(formValues || {}))),
|
|
6656
|
+
[domain, formValues]
|
|
6657
|
+
);
|
|
6658
|
+
const data = {
|
|
6659
|
+
model: relation ?? "",
|
|
6660
|
+
domain: domainObject,
|
|
6661
|
+
specification: {
|
|
6662
|
+
id: {},
|
|
6663
|
+
name: {},
|
|
6664
|
+
display_name: {},
|
|
6665
|
+
...widget && WIDGETAVATAR[widget] ? { image_256: {} } : {},
|
|
6666
|
+
...widget && WIDGETCOLOR[widget] && addtionalFields?.color_field ? { color: {} } : {}
|
|
6667
|
+
},
|
|
6668
|
+
enabled: true,
|
|
6669
|
+
context: env.context
|
|
6670
|
+
};
|
|
6671
|
+
const { data: dataOfSelection } = useGetSelection3({
|
|
6672
|
+
data,
|
|
6673
|
+
queryKey: [`data_${relation}`, domainObject]
|
|
6674
|
+
});
|
|
6675
|
+
const customNoOptionsMessage = () => placeholderNoOption;
|
|
6676
|
+
const tranfer = (data2) => {
|
|
6677
|
+
return data2?.map((val) => ({
|
|
6678
|
+
id: val.value,
|
|
6679
|
+
display_name: val.label
|
|
6680
|
+
})) || [];
|
|
6681
|
+
};
|
|
6682
|
+
const options = dataOfSelection?.records?.map((val) => ({
|
|
6683
|
+
value: val.id,
|
|
6684
|
+
label: val.name ?? val.display_name,
|
|
6685
|
+
...val
|
|
6686
|
+
})) || [];
|
|
6687
|
+
return {
|
|
6688
|
+
options,
|
|
6689
|
+
customNoOptionsMessage,
|
|
6690
|
+
tranfer,
|
|
6691
|
+
dataOfSelection,
|
|
6692
|
+
isUser
|
|
6693
|
+
};
|
|
6694
|
+
};
|
|
6695
|
+
|
|
6696
|
+
// src/widget/basic/status-bar-field/controller.ts
|
|
6697
|
+
import { useState as useState11 } from "react";
|
|
6698
|
+
import {
|
|
6699
|
+
evalJSONDomain as evalJSONDomain5,
|
|
6700
|
+
selectEnv as selectEnv3,
|
|
6701
|
+
useAppSelector as useAppSelector8,
|
|
6702
|
+
useChangeStatus,
|
|
6703
|
+
useGetListData as useGetListData4
|
|
6704
|
+
} from "@fctc/interface-logic";
|
|
6705
|
+
var durationController = (props) => {
|
|
6706
|
+
const {
|
|
6707
|
+
relation,
|
|
6708
|
+
defaultValue,
|
|
6709
|
+
domain,
|
|
6710
|
+
formValues,
|
|
6711
|
+
name,
|
|
6712
|
+
id,
|
|
6713
|
+
model,
|
|
6714
|
+
onRefetch
|
|
6715
|
+
} = props;
|
|
6716
|
+
const specification = {
|
|
6717
|
+
id: 0,
|
|
6718
|
+
name: "",
|
|
6719
|
+
fold: ""
|
|
6720
|
+
};
|
|
6721
|
+
const [disabled, setDisabled] = useState11(false);
|
|
6722
|
+
const [modelStatus, setModalStatus] = useState11(false);
|
|
6723
|
+
const { context } = useAppSelector8(selectEnv3);
|
|
6724
|
+
const queryKey = [`data-status-duration`, specification];
|
|
6725
|
+
const listDataProps = {
|
|
6726
|
+
model: relation,
|
|
6727
|
+
specification,
|
|
6728
|
+
domain: evalJSONDomain5(domain, JSON.parse(JSON.stringify(formValues))),
|
|
6729
|
+
limit: 10,
|
|
6730
|
+
offset: 0,
|
|
6731
|
+
fields: "",
|
|
6732
|
+
groupby: [],
|
|
6733
|
+
context: {
|
|
6734
|
+
lang: context.lang
|
|
6735
|
+
},
|
|
6736
|
+
sort: ""
|
|
6737
|
+
};
|
|
6738
|
+
const { data: dataResponse } = useGetListData4(listDataProps, queryKey);
|
|
6739
|
+
const { mutate: fetchChangeStatus } = useChangeStatus();
|
|
6740
|
+
const handleClick = async (stage_id) => {
|
|
6741
|
+
setDisabled(true);
|
|
6742
|
+
if (stage_id) {
|
|
6743
|
+
fetchChangeStatus(
|
|
6744
|
+
{
|
|
6745
|
+
data: {
|
|
6746
|
+
stage_id,
|
|
6747
|
+
name,
|
|
6748
|
+
id,
|
|
6749
|
+
model,
|
|
6750
|
+
lang: context.lang
|
|
6751
|
+
}
|
|
6752
|
+
},
|
|
6753
|
+
{
|
|
6754
|
+
onSuccess: (res) => {
|
|
6755
|
+
if (res) {
|
|
6756
|
+
setDisabled(false);
|
|
6757
|
+
onRefetch && onRefetch();
|
|
6758
|
+
}
|
|
6759
|
+
}
|
|
6760
|
+
}
|
|
6761
|
+
);
|
|
6762
|
+
}
|
|
6763
|
+
};
|
|
6764
|
+
return {
|
|
6765
|
+
defaultValue,
|
|
6766
|
+
dataResponse,
|
|
6767
|
+
handleClick,
|
|
6768
|
+
disabled,
|
|
6769
|
+
modelStatus,
|
|
6770
|
+
setModalStatus
|
|
6771
|
+
};
|
|
6772
|
+
};
|
|
6773
|
+
|
|
6774
|
+
// src/widget/basic/priority-field/controller.ts
|
|
6775
|
+
import { evalJSONContext as evalJSONContext6, useSave as useSave2 } from "@fctc/interface-logic";
|
|
6776
|
+
var priorityFieldController = (props) => {
|
|
6777
|
+
const {
|
|
6778
|
+
value,
|
|
6779
|
+
isForm,
|
|
6780
|
+
name,
|
|
6781
|
+
methods,
|
|
6782
|
+
onChange,
|
|
6783
|
+
model,
|
|
6784
|
+
selection,
|
|
6785
|
+
id,
|
|
6786
|
+
actionData,
|
|
6787
|
+
viewData,
|
|
6788
|
+
context
|
|
6789
|
+
} = props;
|
|
6790
|
+
const _context = { ...evalJSONContext6(actionData?.context) };
|
|
6791
|
+
const contextObject = { ...context, ..._context };
|
|
6792
|
+
const defaultPriority = parseInt(value) + 1;
|
|
6793
|
+
const label = viewData?.models?.[model]?.[name ?? ""]?.string ?? name;
|
|
6794
|
+
const { mutateAsync: fetchSave } = useSave2();
|
|
6795
|
+
const savePriorities = async ({
|
|
6796
|
+
value: value2,
|
|
6797
|
+
resetPriority
|
|
6798
|
+
}) => {
|
|
6799
|
+
const priorityValue = value2 <= 0 ? 0 : value2 - 1;
|
|
6800
|
+
try {
|
|
6801
|
+
fetchSave({
|
|
6802
|
+
ids: id ? [id] : [],
|
|
6803
|
+
data: { [name ?? ""]: String(priorityValue) },
|
|
6804
|
+
model: model ?? "",
|
|
6805
|
+
context: contextObject
|
|
6806
|
+
});
|
|
6807
|
+
if (typeof onChange === "function") {
|
|
6808
|
+
onChange(name ?? "", String(priorityValue));
|
|
6809
|
+
}
|
|
6810
|
+
} catch (error) {
|
|
6811
|
+
if (resetPriority) {
|
|
6812
|
+
resetPriority();
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6815
|
+
};
|
|
6816
|
+
return {
|
|
6817
|
+
selection,
|
|
6818
|
+
isForm,
|
|
6819
|
+
methods,
|
|
6820
|
+
defaultPriority,
|
|
6821
|
+
savePriorities,
|
|
6822
|
+
label,
|
|
6823
|
+
id,
|
|
6824
|
+
onChange
|
|
6825
|
+
};
|
|
6826
|
+
};
|
|
6827
|
+
|
|
6828
|
+
// src/widget/basic/float-time-field/controller.ts
|
|
6829
|
+
import { useState as useState12 } from "react";
|
|
6830
|
+
import { convertFloatToTime, convertTimeToFloat } from "@fctc/interface-logic";
|
|
6831
|
+
var floatTimeFiledController = ({
|
|
6832
|
+
onChange: fieldOnChange,
|
|
6833
|
+
onBlur,
|
|
6834
|
+
value,
|
|
6835
|
+
isDirty,
|
|
6836
|
+
props
|
|
6837
|
+
}) => {
|
|
6838
|
+
const { name, defaultValue = 0, onChange } = props;
|
|
6839
|
+
const [input, setInput] = useState12(
|
|
6840
|
+
convertFloatToTime(value ?? defaultValue)
|
|
6841
|
+
);
|
|
6842
|
+
const [formattedTime, setFormattedTime] = useState12("");
|
|
6843
|
+
const [errors, setErrors] = useState12("");
|
|
6844
|
+
const handleInputChange = (e) => {
|
|
6845
|
+
const raw = e.target.value.replace(/[^\d:]/g, "");
|
|
6846
|
+
setInput(raw);
|
|
6847
|
+
const timeRegex = /^(\d{1,2}):?(\d{0,2})$/;
|
|
6848
|
+
const match = raw.match(timeRegex);
|
|
6849
|
+
if (!match) {
|
|
6850
|
+
setErrors("\u0110\u1ECBnh d\u1EA1ng kh\xF4ng h\u1EE3p l\u1EC7");
|
|
6851
|
+
setFormattedTime("");
|
|
6852
|
+
return;
|
|
6853
|
+
}
|
|
6854
|
+
let hours = parseInt(match[1] ?? "0", 10);
|
|
6855
|
+
let minutes = parseInt(match[2] ?? "0", 10);
|
|
6856
|
+
if (isNaN(hours)) hours = 0;
|
|
6857
|
+
if (isNaN(minutes)) minutes = 0;
|
|
6858
|
+
if (hours >= 24) {
|
|
6859
|
+
hours = 0;
|
|
6860
|
+
}
|
|
6861
|
+
if (minutes >= 60) {
|
|
6862
|
+
minutes = 0;
|
|
6863
|
+
}
|
|
6864
|
+
const formatted = `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
6865
|
+
setErrors("");
|
|
6866
|
+
setFormattedTime(formatted);
|
|
6867
|
+
fieldOnChange(formatted);
|
|
6868
|
+
};
|
|
6869
|
+
const handleBlur = () => {
|
|
6870
|
+
if (!isDirty) return;
|
|
6871
|
+
if (formattedTime) {
|
|
6872
|
+
setInput(formattedTime);
|
|
6873
|
+
const floatVal = convertTimeToFloat(formattedTime);
|
|
6874
|
+
fieldOnChange(floatVal);
|
|
6875
|
+
if (onChange) {
|
|
6876
|
+
onChange(name ?? "", floatVal);
|
|
6877
|
+
}
|
|
6878
|
+
} else {
|
|
6879
|
+
setInput("00:00");
|
|
6880
|
+
fieldOnChange(0);
|
|
6881
|
+
if (onChange) {
|
|
6882
|
+
onChange(name ?? "", 0);
|
|
6883
|
+
}
|
|
6884
|
+
setErrors("");
|
|
6885
|
+
}
|
|
6886
|
+
onBlur();
|
|
6887
|
+
};
|
|
6888
|
+
const handleKeyDown = (e) => {
|
|
6889
|
+
{
|
|
6890
|
+
const allowed = [
|
|
6891
|
+
"Backspace",
|
|
6892
|
+
"Tab",
|
|
6893
|
+
"ArrowLeft",
|
|
6894
|
+
"ArrowRight",
|
|
6895
|
+
"Delete",
|
|
6896
|
+
"Home",
|
|
6897
|
+
"End",
|
|
6898
|
+
":"
|
|
6899
|
+
];
|
|
6900
|
+
const isNumber = /^[0-9]$/.test(e.key);
|
|
6901
|
+
if (!isNumber && !allowed.includes(e.key)) {
|
|
6902
|
+
e.preventDefault();
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
};
|
|
6906
|
+
return {
|
|
6907
|
+
handleInputChange,
|
|
6908
|
+
handleBlur,
|
|
6909
|
+
handleKeyDown,
|
|
6910
|
+
input,
|
|
6911
|
+
errors
|
|
6912
|
+
};
|
|
6913
|
+
};
|
|
6914
|
+
|
|
6634
6915
|
// src/widget/basic/float-field/controller.ts
|
|
6916
|
+
import { useEffect as useEffect15, useRef as useRef5, useState as useState13 } from "react";
|
|
6635
6917
|
var floatController = ({
|
|
6636
6918
|
onChange,
|
|
6637
6919
|
value,
|
|
@@ -6639,10 +6921,10 @@ var floatController = ({
|
|
|
6639
6921
|
}) => {
|
|
6640
6922
|
const { name, required, methods, onChange: handleOnchange, string } = props;
|
|
6641
6923
|
const { setError, clearErrors } = methods;
|
|
6642
|
-
const [inputValue, setInputValue] =
|
|
6924
|
+
const [inputValue, setInputValue] = useState13(
|
|
6643
6925
|
value !== void 0 && value !== null ? useFormatFloatNumber(value) : ""
|
|
6644
6926
|
);
|
|
6645
|
-
|
|
6927
|
+
useEffect15(() => {
|
|
6646
6928
|
if (value !== void 0 && value !== null && value !== parseFloat(inputValue?.replace(/,/g, ""))) {
|
|
6647
6929
|
setInputValue(useFormatFloatNumber(value));
|
|
6648
6930
|
clearErrors(name);
|
|
@@ -6753,10 +7035,10 @@ var useFormatFloatNumber = (value) => {
|
|
|
6753
7035
|
};
|
|
6754
7036
|
|
|
6755
7037
|
// src/widget/basic/download-file-field/controller.ts
|
|
6756
|
-
import { useId, useState as
|
|
7038
|
+
import { useId, useState as useState14 } from "react";
|
|
6757
7039
|
var downloadFileController = () => {
|
|
6758
7040
|
const inputId = useId();
|
|
6759
|
-
const [file, setFile] =
|
|
7041
|
+
const [file, setFile] = useState14(null);
|
|
6760
7042
|
const handleFileChange = (e) => {
|
|
6761
7043
|
setFile(e.target.files[0]);
|
|
6762
7044
|
};
|
|
@@ -6920,11 +7202,11 @@ var dateFieldController = (props) => {
|
|
|
6920
7202
|
};
|
|
6921
7203
|
|
|
6922
7204
|
// src/widget/basic/copy-link-button/controller.ts
|
|
6923
|
-
import { useState as
|
|
7205
|
+
import { useState as useState15 } from "react";
|
|
6924
7206
|
import { copyTextToClipboard } from "@fctc/interface-logic";
|
|
6925
7207
|
var copyLinkButtonController = (props) => {
|
|
6926
7208
|
const { value, defaultValue } = props;
|
|
6927
|
-
const [isCopied, setIsCopied] =
|
|
7209
|
+
const [isCopied, setIsCopied] = useState15(false);
|
|
6928
7210
|
const handleCopyToClipboard = async (value2) => {
|
|
6929
7211
|
await copyTextToClipboard(value2);
|
|
6930
7212
|
setIsCopied(true);
|
|
@@ -6939,412 +7221,132 @@ var copyLinkButtonController = (props) => {
|
|
|
6939
7221
|
};
|
|
6940
7222
|
|
|
6941
7223
|
// src/widget/basic/color-field/color-controller.ts
|
|
6942
|
-
import { evalJSONContext as evalJSONContext7, getEnv as
|
|
7224
|
+
import { evalJSONContext as evalJSONContext7, getEnv as getEnv11, useSave as useSave3 } from "@fctc/interface-logic";
|
|
6943
7225
|
var colorFieldController = (props) => {
|
|
6944
7226
|
const { value, isForm, name, formValues, idForm, model, actionData } = props;
|
|
6945
|
-
const env =
|
|
6946
|
-
const _context = { ...evalJSONContext7(actionData?.context) || {} };
|
|
6947
|
-
const contextObject = { ...env.context, ..._context };
|
|
6948
|
-
const idDefault = isForm ? idForm : formValues?.id;
|
|
6949
|
-
const { mutate: onSave } = useSave3();
|
|
6950
|
-
const savePickColor = async (colorObject) => {
|
|
6951
|
-
const { id } = colorObject;
|
|
6952
|
-
if (value === id) return;
|
|
6953
|
-
try {
|
|
6954
|
-
onSave({
|
|
6955
|
-
ids: idDefault !== null ? [idDefault] : [],
|
|
6956
|
-
model: model ?? "",
|
|
6957
|
-
data: { [name ?? ""]: id },
|
|
6958
|
-
specification: {
|
|
6959
|
-
name: {},
|
|
6960
|
-
color: {}
|
|
6961
|
-
},
|
|
6962
|
-
context: contextObject
|
|
6963
|
-
});
|
|
6964
|
-
} catch (error) {
|
|
6965
|
-
console.log(error);
|
|
6966
|
-
}
|
|
6967
|
-
};
|
|
6968
|
-
return {
|
|
6969
|
-
savePickColor
|
|
6970
|
-
};
|
|
6971
|
-
};
|
|
6972
|
-
|
|
6973
|
-
// src/widget/basic/binary-field/controller.ts
|
|
6974
|
-
import { useEffect as useEffect14, useId as useId2, useRef as useRef6, useState as useState15 } from "react";
|
|
6975
|
-
import { isBase64Image } from "@fctc/interface-logic";
|
|
6976
|
-
var binaryFieldController = (props) => {
|
|
6977
|
-
const { name, methods, readonly = false, value } = props;
|
|
6978
|
-
const inputId = useId2();
|
|
6979
|
-
const [selectedImage, setSelectedImage] = useState15(null);
|
|
6980
|
-
const [initialImage, setInitialImage] = useState15(value || null);
|
|
6981
|
-
const [isInsideTable, setIsInsideTable] = useState15(false);
|
|
6982
|
-
const { setValue } = methods;
|
|
6983
|
-
const binaryRef = useRef6(null);
|
|
6984
|
-
const convertUrlToBase64 = async (url) => {
|
|
6985
|
-
try {
|
|
6986
|
-
const response = await fetch(url);
|
|
6987
|
-
const blob = await response.blob();
|
|
6988
|
-
return new Promise((resolve, reject) => {
|
|
6989
|
-
const reader = new FileReader();
|
|
6990
|
-
reader.onloadend = () => {
|
|
6991
|
-
resolve(reader.result);
|
|
6992
|
-
};
|
|
6993
|
-
reader.onerror = reject;
|
|
6994
|
-
reader.readAsDataURL(blob);
|
|
6995
|
-
});
|
|
6996
|
-
} catch (error) {
|
|
6997
|
-
console.error("Error converting URL to Base64:", error);
|
|
6998
|
-
throw error;
|
|
6999
|
-
}
|
|
7000
|
-
};
|
|
7001
|
-
const extractBase64Data = (base64Url) => {
|
|
7002
|
-
if (base64Url.includes("base64,")) {
|
|
7003
|
-
return base64Url.split("base64,")[1];
|
|
7004
|
-
}
|
|
7005
|
-
return base64Url;
|
|
7006
|
-
};
|
|
7007
|
-
const handleImageChange = async (e, onChange) => {
|
|
7008
|
-
if (readonly) return;
|
|
7009
|
-
const file = e?.target?.files?.[0];
|
|
7010
|
-
if (file) {
|
|
7011
|
-
const imageUrl = URL.createObjectURL(file);
|
|
7012
|
-
setSelectedImage(imageUrl);
|
|
7013
|
-
setInitialImage(null);
|
|
7014
|
-
onChange(file);
|
|
7015
|
-
const compressedBase64 = await convertUrlToBase64(imageUrl);
|
|
7016
|
-
const base64Data = extractBase64Data(compressedBase64);
|
|
7017
|
-
setValue(name, base64Data, {
|
|
7018
|
-
shouldDirty: true
|
|
7019
|
-
});
|
|
7020
|
-
}
|
|
7021
|
-
};
|
|
7022
|
-
const handleRemoveImage = (onChange) => {
|
|
7023
|
-
setSelectedImage(null);
|
|
7024
|
-
setInitialImage(null);
|
|
7025
|
-
onChange(null);
|
|
7026
|
-
};
|
|
7027
|
-
const isBlobUrl = (url) => {
|
|
7028
|
-
return /^blob:/.test(url);
|
|
7029
|
-
};
|
|
7030
|
-
const checkIsImageLink = (url) => {
|
|
7031
|
-
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
7032
|
-
return imageExtensions.test(url) || isBase64Image(url) || isBlobUrl(url);
|
|
7033
|
-
};
|
|
7034
|
-
const getImageBase64WithMimeType = (base64) => {
|
|
7035
|
-
if (typeof base64 !== "string" || base64.length < 10) return null;
|
|
7036
|
-
if (isBase64Image(base64)) return base64;
|
|
7037
|
-
let mimeType = null;
|
|
7038
|
-
if (base64.startsWith("iVBORw0KGgo")) mimeType = "image/png";
|
|
7039
|
-
else if (base64.startsWith("/9j/")) mimeType = "image/jpeg";
|
|
7040
|
-
else if (base64.startsWith("R0lGOD")) mimeType = "image/gif";
|
|
7041
|
-
else if (base64.startsWith("Qk")) mimeType = "image/bmp";
|
|
7042
|
-
else if (base64.startsWith("UklGR")) mimeType = "image/webp";
|
|
7043
|
-
return mimeType ? `data:${mimeType};base64,${base64}` : null;
|
|
7044
|
-
};
|
|
7045
|
-
useEffect14(() => {
|
|
7046
|
-
return () => {
|
|
7047
|
-
if (selectedImage) {
|
|
7048
|
-
URL.revokeObjectURL(selectedImage);
|
|
7049
|
-
}
|
|
7050
|
-
};
|
|
7051
|
-
}, [selectedImage]);
|
|
7052
|
-
useEffect14(() => {
|
|
7053
|
-
if (binaryRef.current) {
|
|
7054
|
-
const isInsideTable2 = !!binaryRef.current.closest("table");
|
|
7055
|
-
setIsInsideTable(isInsideTable2);
|
|
7056
|
-
}
|
|
7057
|
-
}, []);
|
|
7058
|
-
return {
|
|
7059
|
-
inputId,
|
|
7060
|
-
selectedImage,
|
|
7061
|
-
initialImage,
|
|
7062
|
-
isInsideTable,
|
|
7063
|
-
binaryRef,
|
|
7064
|
-
handleImageChange,
|
|
7065
|
-
handleRemoveImage,
|
|
7066
|
-
checkIsImageLink,
|
|
7067
|
-
getImageBase64WithMimeType
|
|
7068
|
-
};
|
|
7069
|
-
};
|
|
7070
|
-
|
|
7071
|
-
// src/widget/advance/table/table-body/controller.ts
|
|
7072
|
-
import { setSelectedRowKeys, useAppDispatch as useAppDispatch6 } from "@fctc/interface-logic";
|
|
7073
|
-
import { useEffect as useEffect15, useMemo as useMemo12 } from "react";
|
|
7074
|
-
var tableBodyController = (props) => {
|
|
7075
|
-
const {
|
|
7076
|
-
checkedAll,
|
|
7077
|
-
checkboxRef,
|
|
7078
|
-
setIsAutoSelect,
|
|
7079
|
-
selectedRowKeys,
|
|
7080
|
-
row,
|
|
7081
|
-
isAutoSelect,
|
|
7082
|
-
selectedRowKeysRef,
|
|
7083
|
-
onClickRow
|
|
7084
|
-
} = props;
|
|
7085
|
-
const appDispatch = useAppDispatch6();
|
|
7086
|
-
const checked = useMemo12(() => {
|
|
7087
|
-
if (!row?.id) return false;
|
|
7088
|
-
if (selectedRowKeys?.includes(row.id)) {
|
|
7089
|
-
return true;
|
|
7090
|
-
}
|
|
7091
|
-
return checkedAll;
|
|
7092
|
-
}, [row?.id, selectedRowKeys, checkedAll]);
|
|
7093
|
-
const handleCheckBoxSingle = (event) => {
|
|
7094
|
-
event.stopPropagation();
|
|
7095
|
-
if (checkedAll) {
|
|
7096
|
-
checkboxRef.current = "uncheck";
|
|
7097
|
-
setIsAutoSelect(true);
|
|
7098
|
-
return;
|
|
7099
|
-
}
|
|
7100
|
-
const newSelectedRowKeys = selectedRowKeys?.includes(row.id) ? selectedRowKeys?.filter((key) => key !== row.id) : [...selectedRowKeys, row.id];
|
|
7101
|
-
console.log("newSelectedRowKeys", newSelectedRowKeys);
|
|
7102
|
-
appDispatch(setSelectedRowKeys(newSelectedRowKeys));
|
|
7103
|
-
};
|
|
7104
|
-
const handleClickRow = (col, row2) => {
|
|
7105
|
-
onClickRow(col, row2);
|
|
7106
|
-
};
|
|
7107
|
-
useEffect15(() => {
|
|
7108
|
-
if (!row?.id) return;
|
|
7109
|
-
if (isAutoSelect) {
|
|
7110
|
-
if (checkboxRef?.current === "uncheck") {
|
|
7111
|
-
const filtered = selectedRowKeysRef.current.filter(
|
|
7112
|
-
(id) => id !== row.id
|
|
7113
|
-
);
|
|
7114
|
-
selectedRowKeysRef.current = filtered;
|
|
7115
|
-
appDispatch(setSelectedRowKeys(filtered));
|
|
7116
|
-
} else {
|
|
7117
|
-
const unique = Array.from(
|
|
7118
|
-
/* @__PURE__ */ new Set([...selectedRowKeysRef?.current, row?.id])
|
|
7119
|
-
);
|
|
7120
|
-
selectedRowKeysRef.current = unique;
|
|
7121
|
-
appDispatch(setSelectedRowKeys(unique));
|
|
7122
|
-
}
|
|
7123
|
-
}
|
|
7124
|
-
}, [isAutoSelect]);
|
|
7125
|
-
useEffect15(() => {
|
|
7126
|
-
if (!checkedAll) {
|
|
7127
|
-
checkboxRef.current = "enabled";
|
|
7128
|
-
false;
|
|
7129
|
-
}
|
|
7130
|
-
}, [checkedAll]);
|
|
7131
|
-
return {
|
|
7132
|
-
handleCheckBoxSingle,
|
|
7133
|
-
checked,
|
|
7134
|
-
handleClickRow
|
|
7135
|
-
};
|
|
7136
|
-
};
|
|
7137
|
-
|
|
7138
|
-
// src/widget/advance/table/table-head/controller.ts
|
|
7139
|
-
import {
|
|
7140
|
-
selectSearch as selectSearch4,
|
|
7141
|
-
setSelectedRowKeys as setSelectedRowKeys2,
|
|
7142
|
-
useAppDispatch as useAppDispatch7,
|
|
7143
|
-
useAppSelector as useAppSelector7
|
|
7144
|
-
} from "@fctc/interface-logic";
|
|
7145
|
-
var tableHeadController = (props) => {
|
|
7146
|
-
const { typeTable, rows, selectedRowKeysRef } = props;
|
|
7147
|
-
const appDispatch = useAppDispatch7();
|
|
7148
|
-
const { groupByDomain } = useAppSelector7(selectSearch4);
|
|
7149
|
-
const handleCheckBoxAll = (event) => {
|
|
7150
|
-
if (event?.target?.checked && typeTable === "list") {
|
|
7151
|
-
const allRowKeys = Array.isArray(rows) ? rows.map((record) => record?.id) : [];
|
|
7152
|
-
appDispatch(setSelectedRowKeys2(allRowKeys));
|
|
7153
|
-
} else if (event?.target?.checked && typeTable === "group") {
|
|
7154
|
-
const rowsIDs = document.querySelectorAll("tr[data-row-id]");
|
|
7155
|
-
const ids = Array.from(rowsIDs)?.map(
|
|
7156
|
-
(row) => Number(row?.getAttribute("data-row-id"))
|
|
7157
|
-
);
|
|
7158
|
-
if (ids?.length > 0) {
|
|
7159
|
-
appDispatch(setSelectedRowKeys2(ids));
|
|
7160
|
-
} else {
|
|
7161
|
-
const sum = countSum(
|
|
7162
|
-
rows,
|
|
7163
|
-
typeof groupByDomain === "object" ? groupByDomain?.contexts?.[0]?.group_by : void 0
|
|
7164
|
-
);
|
|
7165
|
-
const keys = Array.from({ length: sum }, (_) => void 0);
|
|
7166
|
-
appDispatch(setSelectedRowKeys2(keys));
|
|
7167
|
-
}
|
|
7168
|
-
if (selectedRowKeysRef) {
|
|
7169
|
-
selectedRowKeysRef.current = [];
|
|
7170
|
-
}
|
|
7171
|
-
} else {
|
|
7172
|
-
appDispatch(setSelectedRowKeys2([]));
|
|
7227
|
+
const env = getEnv11();
|
|
7228
|
+
const _context = { ...evalJSONContext7(actionData?.context) || {} };
|
|
7229
|
+
const contextObject = { ...env.context, ..._context };
|
|
7230
|
+
const idDefault = isForm ? idForm : formValues?.id;
|
|
7231
|
+
const { mutate: onSave } = useSave3();
|
|
7232
|
+
const savePickColor = async (colorObject) => {
|
|
7233
|
+
const { id } = colorObject;
|
|
7234
|
+
if (value === id) return;
|
|
7235
|
+
try {
|
|
7236
|
+
onSave({
|
|
7237
|
+
ids: idDefault !== null ? [idDefault] : [],
|
|
7238
|
+
model: model ?? "",
|
|
7239
|
+
data: { [name ?? ""]: id },
|
|
7240
|
+
specification: {
|
|
7241
|
+
name: {},
|
|
7242
|
+
color: {}
|
|
7243
|
+
},
|
|
7244
|
+
context: contextObject
|
|
7245
|
+
});
|
|
7246
|
+
} catch (error) {
|
|
7247
|
+
console.log(error);
|
|
7173
7248
|
}
|
|
7174
7249
|
};
|
|
7175
7250
|
return {
|
|
7176
|
-
|
|
7251
|
+
savePickColor
|
|
7177
7252
|
};
|
|
7178
7253
|
};
|
|
7179
7254
|
|
|
7180
|
-
// src/widget/
|
|
7181
|
-
import {
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
checkedAll,
|
|
7207
|
-
isDisplayCheckbox,
|
|
7208
|
-
isAutoSelect,
|
|
7209
|
-
setIsAutoSelect,
|
|
7210
|
-
selectedRowKeysRef
|
|
7211
|
-
} = props;
|
|
7212
|
-
const [pageGroup, setPageGroup] = useState16(0);
|
|
7213
|
-
const { groupByDomain, selectedTags } = useAppSelector8(selectSearch5);
|
|
7214
|
-
const { selectedRowKeys } = useAppSelector8(selectList3);
|
|
7215
|
-
const appDispatch = useAppDispatch8();
|
|
7216
|
-
const { toDataJS } = useOdooDataTransform();
|
|
7217
|
-
const initVal = toDataJS(row, viewData, model);
|
|
7218
|
-
const [isShowGroup, setIsShowGroup] = useState16(false);
|
|
7219
|
-
const [colEmptyGroup, setColEmptyGroup] = useState16({
|
|
7220
|
-
fromStart: 1,
|
|
7221
|
-
fromEnd: 1
|
|
7222
|
-
});
|
|
7223
|
-
const processedData = useMemo13(() => {
|
|
7224
|
-
const calculateColSpanEmpty = () => {
|
|
7225
|
-
const startIndex = columns.findIndex(
|
|
7226
|
-
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator === "sum"
|
|
7227
|
-
);
|
|
7228
|
-
const endIndex = columns.findLastIndex(
|
|
7229
|
-
(col) => col.field.type === "monetary" && typeof row[col.key] === "number" || col.field.aggregator !== "sum"
|
|
7230
|
-
);
|
|
7231
|
-
const fromStart = startIndex === -1 ? columns.length : startIndex;
|
|
7232
|
-
const fromEnd = endIndex === -1 ? columns.length : columns.length - 1 - endIndex;
|
|
7233
|
-
setColEmptyGroup({ fromStart: fromStart + 1, fromEnd: fromEnd + 1 });
|
|
7234
|
-
return { fromStart: fromStart + 1, fromEnd: fromEnd + 1 };
|
|
7235
|
-
};
|
|
7236
|
-
return calculateColSpanEmpty();
|
|
7237
|
-
}, [columns, row]);
|
|
7238
|
-
const shouldFetchData = useMemo13(() => {
|
|
7239
|
-
return !!isShowGroup;
|
|
7240
|
-
}, [isShowGroup]);
|
|
7241
|
-
const enabled = shouldFetchData && !!processedData;
|
|
7242
|
-
const listDataProps = {
|
|
7243
|
-
model,
|
|
7244
|
-
specification,
|
|
7245
|
-
domain,
|
|
7246
|
-
context,
|
|
7247
|
-
offset: pageGroup * 10,
|
|
7248
|
-
fields: groupByDomain?.fields,
|
|
7249
|
-
groupby: [groupByDomain?.contexts[level]?.group_by]
|
|
7250
|
-
};
|
|
7251
|
-
const queryKey = [
|
|
7252
|
-
`data-${model}--${level}-row${indexRow}`,
|
|
7253
|
-
specification,
|
|
7254
|
-
domain,
|
|
7255
|
-
pageGroup
|
|
7256
|
-
];
|
|
7257
|
-
const {
|
|
7258
|
-
data: dataResponse,
|
|
7259
|
-
isFetched: isQueryFetched,
|
|
7260
|
-
isPlaceholderData,
|
|
7261
|
-
isLoading,
|
|
7262
|
-
isFetching
|
|
7263
|
-
} = useGetListData4(listDataProps, queryKey, enabled);
|
|
7264
|
-
const {
|
|
7265
|
-
columns: columnsGroup,
|
|
7266
|
-
rows: rowsGroup,
|
|
7267
|
-
typeTable: typeTableGroup
|
|
7268
|
-
} = tableController({
|
|
7269
|
-
data: {
|
|
7270
|
-
fields: viewData?.views?.list?.fields,
|
|
7271
|
-
records: dataResponse?.records ?? dataResponse?.groups,
|
|
7272
|
-
dataModel: viewData?.models?.[model],
|
|
7273
|
-
context: env.context,
|
|
7274
|
-
typeTable: dataResponse?.groups ? "group" : "list"
|
|
7275
|
-
}
|
|
7276
|
-
});
|
|
7277
|
-
const leftPadding = level > 1 ? level * 8 + "px" : "0px";
|
|
7278
|
-
useEffect16(() => {
|
|
7279
|
-
if (isShowGroup && selectedTags?.length > 0) {
|
|
7280
|
-
setIsShowGroup(false);
|
|
7255
|
+
// src/widget/basic/binary-field/controller.ts
|
|
7256
|
+
import { useEffect as useEffect16, useId as useId2, useRef as useRef6, useState as useState16 } from "react";
|
|
7257
|
+
import { isBase64Image } from "@fctc/interface-logic";
|
|
7258
|
+
var binaryFieldController = (props) => {
|
|
7259
|
+
const { name, methods, readonly = false, value } = props;
|
|
7260
|
+
const inputId = useId2();
|
|
7261
|
+
const [selectedImage, setSelectedImage] = useState16(null);
|
|
7262
|
+
const [initialImage, setInitialImage] = useState16(value || null);
|
|
7263
|
+
const [isInsideTable, setIsInsideTable] = useState16(false);
|
|
7264
|
+
const { setValue } = methods;
|
|
7265
|
+
const binaryRef = useRef6(null);
|
|
7266
|
+
const convertUrlToBase64 = async (url) => {
|
|
7267
|
+
try {
|
|
7268
|
+
const response = await fetch(url);
|
|
7269
|
+
const blob = await response.blob();
|
|
7270
|
+
return new Promise((resolve, reject) => {
|
|
7271
|
+
const reader = new FileReader();
|
|
7272
|
+
reader.onloadend = () => {
|
|
7273
|
+
resolve(reader.result);
|
|
7274
|
+
};
|
|
7275
|
+
reader.onerror = reject;
|
|
7276
|
+
reader.readAsDataURL(blob);
|
|
7277
|
+
});
|
|
7278
|
+
} catch (error) {
|
|
7279
|
+
console.error("Error converting URL to Base64:", error);
|
|
7280
|
+
throw error;
|
|
7281
7281
|
}
|
|
7282
|
-
}
|
|
7283
|
-
const
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
)?.[1] : row[group_by_field_name];
|
|
7287
|
-
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`]})`;
|
|
7288
|
-
const allIdsNull = selectedRowKeys?.every((item) => item === void 0);
|
|
7289
|
-
const handleExpandChildGroup = () => {
|
|
7290
|
-
if (isLoading || isFetching) return;
|
|
7291
|
-
const toggleShowGroup = () => setIsShowGroup((prev) => !prev);
|
|
7292
|
-
if (allIdsNull || typeTableGroup === "group") {
|
|
7293
|
-
toggleShowGroup();
|
|
7294
|
-
return;
|
|
7282
|
+
};
|
|
7283
|
+
const extractBase64Data = (base64Url) => {
|
|
7284
|
+
if (base64Url.includes("base64,")) {
|
|
7285
|
+
return base64Url.split("base64,")[1];
|
|
7295
7286
|
}
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
const
|
|
7308
|
-
|
|
7287
|
+
return base64Url;
|
|
7288
|
+
};
|
|
7289
|
+
const handleImageChange = async (e, onChange) => {
|
|
7290
|
+
if (readonly) return;
|
|
7291
|
+
const file = e?.target?.files?.[0];
|
|
7292
|
+
if (file) {
|
|
7293
|
+
const imageUrl = URL.createObjectURL(file);
|
|
7294
|
+
setSelectedImage(imageUrl);
|
|
7295
|
+
setInitialImage(null);
|
|
7296
|
+
onChange(file);
|
|
7297
|
+
const compressedBase64 = await convertUrlToBase64(imageUrl);
|
|
7298
|
+
const base64Data = extractBase64Data(compressedBase64);
|
|
7299
|
+
setValue(name, base64Data, {
|
|
7300
|
+
shouldDirty: true
|
|
7301
|
+
});
|
|
7309
7302
|
}
|
|
7310
|
-
|
|
7303
|
+
};
|
|
7304
|
+
const handleRemoveImage = (onChange) => {
|
|
7305
|
+
setSelectedImage(null);
|
|
7306
|
+
setInitialImage(null);
|
|
7307
|
+
onChange(null);
|
|
7308
|
+
};
|
|
7309
|
+
const isBlobUrl = (url) => {
|
|
7310
|
+
return /^blob:/.test(url);
|
|
7311
|
+
};
|
|
7312
|
+
const checkIsImageLink = (url) => {
|
|
7313
|
+
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
7314
|
+
return imageExtensions.test(url) || isBase64Image(url) || isBlobUrl(url);
|
|
7315
|
+
};
|
|
7316
|
+
const getImageBase64WithMimeType = (base64) => {
|
|
7317
|
+
if (typeof base64 !== "string" || base64.length < 10) return null;
|
|
7318
|
+
if (isBase64Image(base64)) return base64;
|
|
7319
|
+
let mimeType = null;
|
|
7320
|
+
if (base64.startsWith("iVBORw0KGgo")) mimeType = "image/png";
|
|
7321
|
+
else if (base64.startsWith("/9j/")) mimeType = "image/jpeg";
|
|
7322
|
+
else if (base64.startsWith("R0lGOD")) mimeType = "image/gif";
|
|
7323
|
+
else if (base64.startsWith("Qk")) mimeType = "image/bmp";
|
|
7324
|
+
else if (base64.startsWith("UklGR")) mimeType = "image/webp";
|
|
7325
|
+
return mimeType ? `data:${mimeType};base64,${base64}` : null;
|
|
7311
7326
|
};
|
|
7312
7327
|
useEffect16(() => {
|
|
7313
|
-
|
|
7314
|
-
|
|
7328
|
+
return () => {
|
|
7329
|
+
if (selectedImage) {
|
|
7330
|
+
URL.revokeObjectURL(selectedImage);
|
|
7331
|
+
}
|
|
7332
|
+
};
|
|
7333
|
+
}, [selectedImage]);
|
|
7334
|
+
useEffect16(() => {
|
|
7335
|
+
if (binaryRef.current) {
|
|
7336
|
+
const isInsideTable2 = !!binaryRef.current.closest("table");
|
|
7337
|
+
setIsInsideTable(isInsideTable2);
|
|
7315
7338
|
}
|
|
7316
|
-
|
|
7317
|
-
setSelectedRowKeys3([...clonedKeys, -1]);
|
|
7318
|
-
setTimeout(() => setSelectedRowKeys3(clonedKeys), 500);
|
|
7319
|
-
}, [isQueryFetched]);
|
|
7339
|
+
}, []);
|
|
7320
7340
|
return {
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
columnsGroup,
|
|
7331
|
-
indexRow,
|
|
7332
|
-
rowsGroup,
|
|
7333
|
-
model,
|
|
7334
|
-
viewData,
|
|
7335
|
-
renderField,
|
|
7336
|
-
level,
|
|
7337
|
-
specification,
|
|
7338
|
-
context,
|
|
7339
|
-
checkedAll,
|
|
7340
|
-
isDisplayCheckbox,
|
|
7341
|
-
isAutoSelect,
|
|
7342
|
-
setIsAutoSelect,
|
|
7343
|
-
selectedRowKeysRef,
|
|
7344
|
-
initVal,
|
|
7345
|
-
dataResponse,
|
|
7346
|
-
pageGroup,
|
|
7347
|
-
setPageGroup
|
|
7341
|
+
inputId,
|
|
7342
|
+
selectedImage,
|
|
7343
|
+
initialImage,
|
|
7344
|
+
isInsideTable,
|
|
7345
|
+
binaryRef,
|
|
7346
|
+
handleImageChange,
|
|
7347
|
+
handleRemoveImage,
|
|
7348
|
+
checkIsImageLink,
|
|
7349
|
+
getImageBase64WithMimeType
|
|
7348
7350
|
};
|
|
7349
7351
|
};
|
|
7350
7352
|
export {
|