@fctc/widget-logic 5.2.8 → 5.2.9
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.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +74 -0
- package/dist/index.mjs +74 -0
- package/dist/widget.d.mts +22 -1
- package/dist/widget.d.ts +22 -1
- package/dist/widget.js +74 -0
- package/dist/widget.mjs +73 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ export { useAddEntity, useButton, useChangeOrderPreparationState, useChangeStatu
|
|
|
2
2
|
export { ActionResultType, AppProvider, CompanyTuple, ContextProfile, CurrentCompany, RecordMenu, UseMenuReturn, ViewResponse, useAppProvider, useCallAction, useCallActionType, useClickOutside, useCompany, useCompanyType, useConfig, useConfigType, useDebounce, useDetail, useGetAction, useGetRowIds, useGetSpecification, useListData, useListDataType, useMenu, useMenuType, useProfile, useUser, useUserType, useViewV2, useViewV2Type } from './hooks.mjs';
|
|
3
3
|
export * from '@fctc/interface-logic/configs';
|
|
4
4
|
export { CheckIcon, ChevronBottomIcon, CloseIcon, EyeIcon, FilterIcon, GroupByIcon, LoadingIcon, SearchIcon } from './icons.mjs';
|
|
5
|
-
export { ISelctionStateProps, ITableHeadProps, ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController } from './widget.mjs';
|
|
5
|
+
export { ISelctionStateProps, ITableHeadProps, ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyBinaryController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController } from './widget.mjs';
|
|
6
6
|
export * from '@fctc/interface-logic/types';
|
|
7
7
|
export { IInputFieldProps, ValuePropsType } from './types.mjs';
|
|
8
8
|
export { STORAGES, combineContexts, convertFieldsToArray, countSum, getDateRange, languages, mergeButtons, setStorageItemAsync, useStorageState } from './utils.mjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { useAddEntity, useButton, useChangeOrderPreparationState, useChangeStatu
|
|
|
2
2
|
export { ActionResultType, AppProvider, CompanyTuple, ContextProfile, CurrentCompany, RecordMenu, UseMenuReturn, ViewResponse, useAppProvider, useCallAction, useCallActionType, useClickOutside, useCompany, useCompanyType, useConfig, useConfigType, useDebounce, useDetail, useGetAction, useGetRowIds, useGetSpecification, useListData, useListDataType, useMenu, useMenuType, useProfile, useUser, useUserType, useViewV2, useViewV2Type } from './hooks.js';
|
|
3
3
|
export * from '@fctc/interface-logic/configs';
|
|
4
4
|
export { CheckIcon, ChevronBottomIcon, CloseIcon, EyeIcon, FilterIcon, GroupByIcon, LoadingIcon, SearchIcon } from './icons.js';
|
|
5
|
-
export { ISelctionStateProps, ITableHeadProps, ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController } from './widget.js';
|
|
5
|
+
export { ISelctionStateProps, ITableHeadProps, ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyBinaryController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController } from './widget.js';
|
|
6
6
|
export * from '@fctc/interface-logic/types';
|
|
7
7
|
export { IInputFieldProps, ValuePropsType } from './types.js';
|
|
8
8
|
export { STORAGES, combineContexts, convertFieldsToArray, countSum, getDateRange, languages, mergeButtons, setStorageItemAsync, useStorageState } from './utils.js';
|
package/dist/index.js
CHANGED
|
@@ -4057,6 +4057,7 @@ __export(index_exports, {
|
|
|
4057
4057
|
durationController: () => durationController,
|
|
4058
4058
|
getDateRange: () => getDateRange,
|
|
4059
4059
|
languages: () => languages,
|
|
4060
|
+
many2manyBinaryController: () => many2manyBinaryController,
|
|
4060
4061
|
many2manyFieldController: () => many2manyFieldController,
|
|
4061
4062
|
many2manyTagsController: () => many2manyTagsController,
|
|
4062
4063
|
many2oneButtonController: () => many2oneButtonController,
|
|
@@ -4257,6 +4258,7 @@ var languages = [
|
|
|
4257
4258
|
{ id: "vi_VN", name: "VIE" },
|
|
4258
4259
|
{ id: "en_US", name: "ENG" }
|
|
4259
4260
|
];
|
|
4261
|
+
var isBlobUrl = (url) => url.startsWith("blob:");
|
|
4260
4262
|
|
|
4261
4263
|
// src/utils/function.ts
|
|
4262
4264
|
var import_react2 = require("react");
|
|
@@ -6344,6 +6346,77 @@ var binaryFieldController = (props) => {
|
|
|
6344
6346
|
|
|
6345
6347
|
// src/widget/basic/many2many-binary-field/controller.tsx
|
|
6346
6348
|
var import_react23 = require("react");
|
|
6349
|
+
var many2manyBinaryController = (props) => {
|
|
6350
|
+
const {
|
|
6351
|
+
name,
|
|
6352
|
+
methods,
|
|
6353
|
+
value,
|
|
6354
|
+
onChange: handleOnchange,
|
|
6355
|
+
service,
|
|
6356
|
+
xNode,
|
|
6357
|
+
path
|
|
6358
|
+
} = props;
|
|
6359
|
+
const inputId = (0, import_react23.useId)();
|
|
6360
|
+
const { useUploadFile: useUploadFile2 } = (0, provider_exports.useService)();
|
|
6361
|
+
const { mutateAsync } = useUploadFile2();
|
|
6362
|
+
const binaryRef = (0, import_react23.useRef)(null);
|
|
6363
|
+
const [initialFiles, setInitialFiles] = (0, import_react23.useState)(
|
|
6364
|
+
Array.isArray(value) ? value : value ? [value] : []
|
|
6365
|
+
);
|
|
6366
|
+
const checkIsImageLink = (url) => {
|
|
6367
|
+
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
6368
|
+
return imageExtensions.test(url) || (0, utils_exports.isBase64Image)(url) || isBlobUrl(url);
|
|
6369
|
+
};
|
|
6370
|
+
const sanitizeForBE = (list) => list.filter((x) => x?.datas && !isBlobUrl(x.datas)).map((x) => ({ name: x.name, datas: x.datas, mimetype: x.mimetype }));
|
|
6371
|
+
const handleFileChange = async (files, e, oldValues) => {
|
|
6372
|
+
try {
|
|
6373
|
+
const uploadedUrls = await Promise.all(
|
|
6374
|
+
files.map(async (f) => {
|
|
6375
|
+
const formData = new FormData();
|
|
6376
|
+
formData.append("file", f);
|
|
6377
|
+
const res = await mutateAsync({ formData, service, xNode, path });
|
|
6378
|
+
return res?.url;
|
|
6379
|
+
})
|
|
6380
|
+
);
|
|
6381
|
+
const uploadedItems = files.map((f, i) => ({
|
|
6382
|
+
name: f.name,
|
|
6383
|
+
datas: uploadedUrls[i] ?? "",
|
|
6384
|
+
mimetype: f.type
|
|
6385
|
+
}));
|
|
6386
|
+
const finalList = [...oldValues, ...uploadedItems];
|
|
6387
|
+
methods?.setValue(name, finalList, { shouldDirty: true });
|
|
6388
|
+
const payloadForBE = sanitizeForBE(finalList);
|
|
6389
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
6390
|
+
} catch (err) {
|
|
6391
|
+
console.error(err);
|
|
6392
|
+
} finally {
|
|
6393
|
+
e.target.value = "";
|
|
6394
|
+
}
|
|
6395
|
+
};
|
|
6396
|
+
const handleRemoveAt = (idx) => {
|
|
6397
|
+
const current = methods?.getValues(name) || [];
|
|
6398
|
+
const next = current.filter((_, i) => i !== idx);
|
|
6399
|
+
setInitialFiles((p) => p.filter((_, i) => i !== idx));
|
|
6400
|
+
methods?.setValue(name, next.length ? next : null, { shouldDirty: true });
|
|
6401
|
+
const payloadForBE = next.length ? sanitizeForBE(next) : null;
|
|
6402
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
6403
|
+
};
|
|
6404
|
+
const handleRemoveAll = () => {
|
|
6405
|
+
setInitialFiles([]);
|
|
6406
|
+
methods?.setValue(name, null, { shouldDirty: true });
|
|
6407
|
+
handleOnchange && handleOnchange(name ?? "", null);
|
|
6408
|
+
};
|
|
6409
|
+
return {
|
|
6410
|
+
inputId,
|
|
6411
|
+
initialFiles,
|
|
6412
|
+
binaryRef,
|
|
6413
|
+
handleFileChange,
|
|
6414
|
+
handleRemoveAt,
|
|
6415
|
+
handleRemoveAll,
|
|
6416
|
+
checkIsImageLink,
|
|
6417
|
+
setInitialFiles
|
|
6418
|
+
};
|
|
6419
|
+
};
|
|
6347
6420
|
|
|
6348
6421
|
// src/widget/advance/table/table-head/controller.ts
|
|
6349
6422
|
var import_react24 = require("react");
|
|
@@ -7005,6 +7078,7 @@ __reExport(index_exports, types_exports, module.exports);
|
|
|
7005
7078
|
durationController,
|
|
7006
7079
|
getDateRange,
|
|
7007
7080
|
languages,
|
|
7081
|
+
many2manyBinaryController,
|
|
7008
7082
|
many2manyFieldController,
|
|
7009
7083
|
many2manyTagsController,
|
|
7010
7084
|
many2oneButtonController,
|
package/dist/index.mjs
CHANGED
|
@@ -4061,6 +4061,7 @@ __export(index_exports, {
|
|
|
4061
4061
|
durationController: () => durationController,
|
|
4062
4062
|
getDateRange: () => getDateRange,
|
|
4063
4063
|
languages: () => languages,
|
|
4064
|
+
many2manyBinaryController: () => many2manyBinaryController,
|
|
4064
4065
|
many2manyFieldController: () => many2manyFieldController,
|
|
4065
4066
|
many2manyTagsController: () => many2manyTagsController,
|
|
4066
4067
|
many2oneButtonController: () => many2oneButtonController,
|
|
@@ -4346,6 +4347,7 @@ var languages = [
|
|
|
4346
4347
|
{ id: "vi_VN", name: "VIE" },
|
|
4347
4348
|
{ id: "en_US", name: "ENG" }
|
|
4348
4349
|
];
|
|
4350
|
+
var isBlobUrl = (url) => url.startsWith("blob:");
|
|
4349
4351
|
|
|
4350
4352
|
// src/utils/function.ts
|
|
4351
4353
|
import { useCallback as useCallback2, useEffect, useReducer } from "react";
|
|
@@ -6439,6 +6441,77 @@ var binaryFieldController = (props) => {
|
|
|
6439
6441
|
|
|
6440
6442
|
// src/widget/basic/many2many-binary-field/controller.tsx
|
|
6441
6443
|
import { useId as useId2, useRef as useRef4, useState as useState13 } from "react";
|
|
6444
|
+
var many2manyBinaryController = (props) => {
|
|
6445
|
+
const {
|
|
6446
|
+
name,
|
|
6447
|
+
methods,
|
|
6448
|
+
value,
|
|
6449
|
+
onChange: handleOnchange,
|
|
6450
|
+
service,
|
|
6451
|
+
xNode,
|
|
6452
|
+
path
|
|
6453
|
+
} = props;
|
|
6454
|
+
const inputId = useId2();
|
|
6455
|
+
const { useUploadFile: useUploadFile2 } = (0, provider_exports.useService)();
|
|
6456
|
+
const { mutateAsync } = useUploadFile2();
|
|
6457
|
+
const binaryRef = useRef4(null);
|
|
6458
|
+
const [initialFiles, setInitialFiles] = useState13(
|
|
6459
|
+
Array.isArray(value) ? value : value ? [value] : []
|
|
6460
|
+
);
|
|
6461
|
+
const checkIsImageLink = (url) => {
|
|
6462
|
+
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
6463
|
+
return imageExtensions.test(url) || (0, utils_exports.isBase64Image)(url) || isBlobUrl(url);
|
|
6464
|
+
};
|
|
6465
|
+
const sanitizeForBE = (list) => list.filter((x) => x?.datas && !isBlobUrl(x.datas)).map((x) => ({ name: x.name, datas: x.datas, mimetype: x.mimetype }));
|
|
6466
|
+
const handleFileChange = async (files, e, oldValues) => {
|
|
6467
|
+
try {
|
|
6468
|
+
const uploadedUrls = await Promise.all(
|
|
6469
|
+
files.map(async (f) => {
|
|
6470
|
+
const formData = new FormData();
|
|
6471
|
+
formData.append("file", f);
|
|
6472
|
+
const res = await mutateAsync({ formData, service, xNode, path });
|
|
6473
|
+
return res?.url;
|
|
6474
|
+
})
|
|
6475
|
+
);
|
|
6476
|
+
const uploadedItems = files.map((f, i) => ({
|
|
6477
|
+
name: f.name,
|
|
6478
|
+
datas: uploadedUrls[i] ?? "",
|
|
6479
|
+
mimetype: f.type
|
|
6480
|
+
}));
|
|
6481
|
+
const finalList = [...oldValues, ...uploadedItems];
|
|
6482
|
+
methods?.setValue(name, finalList, { shouldDirty: true });
|
|
6483
|
+
const payloadForBE = sanitizeForBE(finalList);
|
|
6484
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
6485
|
+
} catch (err) {
|
|
6486
|
+
console.error(err);
|
|
6487
|
+
} finally {
|
|
6488
|
+
e.target.value = "";
|
|
6489
|
+
}
|
|
6490
|
+
};
|
|
6491
|
+
const handleRemoveAt = (idx) => {
|
|
6492
|
+
const current = methods?.getValues(name) || [];
|
|
6493
|
+
const next = current.filter((_, i) => i !== idx);
|
|
6494
|
+
setInitialFiles((p) => p.filter((_, i) => i !== idx));
|
|
6495
|
+
methods?.setValue(name, next.length ? next : null, { shouldDirty: true });
|
|
6496
|
+
const payloadForBE = next.length ? sanitizeForBE(next) : null;
|
|
6497
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
6498
|
+
};
|
|
6499
|
+
const handleRemoveAll = () => {
|
|
6500
|
+
setInitialFiles([]);
|
|
6501
|
+
methods?.setValue(name, null, { shouldDirty: true });
|
|
6502
|
+
handleOnchange && handleOnchange(name ?? "", null);
|
|
6503
|
+
};
|
|
6504
|
+
return {
|
|
6505
|
+
inputId,
|
|
6506
|
+
initialFiles,
|
|
6507
|
+
binaryRef,
|
|
6508
|
+
handleFileChange,
|
|
6509
|
+
handleRemoveAt,
|
|
6510
|
+
handleRemoveAll,
|
|
6511
|
+
checkIsImageLink,
|
|
6512
|
+
setInitialFiles
|
|
6513
|
+
};
|
|
6514
|
+
};
|
|
6442
6515
|
|
|
6443
6516
|
// src/widget/advance/table/table-head/controller.ts
|
|
6444
6517
|
import { useMemo as useMemo10, useRef as useRef5 } from "react";
|
|
@@ -7104,6 +7177,7 @@ export {
|
|
|
7104
7177
|
durationController,
|
|
7105
7178
|
getDateRange,
|
|
7106
7179
|
languages,
|
|
7180
|
+
many2manyBinaryController,
|
|
7107
7181
|
many2manyFieldController,
|
|
7108
7182
|
many2manyTagsController,
|
|
7109
7183
|
many2oneButtonController,
|
package/dist/widget.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
+
import { ChangeEvent } from 'react';
|
|
2
3
|
import { IInputFieldProps } from './types.mjs';
|
|
3
4
|
import moment from 'moment';
|
|
4
5
|
import '@fctc/interface-logic/types';
|
|
@@ -232,6 +233,26 @@ declare const binaryFieldController: (props: IBinaryFieldProps) => {
|
|
|
232
233
|
url: any;
|
|
233
234
|
};
|
|
234
235
|
|
|
236
|
+
type UploadDeps = {
|
|
237
|
+
service?: any;
|
|
238
|
+
xNode?: any;
|
|
239
|
+
path?: any;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
declare const many2manyBinaryController: (props: IInputFieldProps & UploadDeps & {
|
|
243
|
+
rootField?: any;
|
|
244
|
+
index?: number;
|
|
245
|
+
}) => {
|
|
246
|
+
inputId: string;
|
|
247
|
+
initialFiles: any[];
|
|
248
|
+
binaryRef: react.RefObject<HTMLDivElement>;
|
|
249
|
+
handleFileChange: (files: any, e: ChangeEvent<HTMLInputElement>, oldValues: any) => Promise<void>;
|
|
250
|
+
handleRemoveAt: (idx: number) => void;
|
|
251
|
+
handleRemoveAll: () => void;
|
|
252
|
+
checkIsImageLink: (url: string) => boolean;
|
|
253
|
+
setInitialFiles: react.Dispatch<react.SetStateAction<any[]>>;
|
|
254
|
+
};
|
|
255
|
+
|
|
235
256
|
declare const tableHeadController: (props: any) => {
|
|
236
257
|
handleCheckBoxAll: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
237
258
|
checkedAll: any;
|
|
@@ -319,4 +340,4 @@ declare const searchController: ({ viewData, model, domain, context, fieldsList,
|
|
|
319
340
|
hoveredIndexSearchList: number | null;
|
|
320
341
|
};
|
|
321
342
|
|
|
322
|
-
export { type ISelctionStateProps, type ITableHeadProps, type ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController };
|
|
343
|
+
export { type ISelctionStateProps, type ITableHeadProps, type ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyBinaryController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController };
|
package/dist/widget.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
+
import { ChangeEvent } from 'react';
|
|
2
3
|
import { IInputFieldProps } from './types.js';
|
|
3
4
|
import moment from 'moment';
|
|
4
5
|
import '@fctc/interface-logic/types';
|
|
@@ -232,6 +233,26 @@ declare const binaryFieldController: (props: IBinaryFieldProps) => {
|
|
|
232
233
|
url: any;
|
|
233
234
|
};
|
|
234
235
|
|
|
236
|
+
type UploadDeps = {
|
|
237
|
+
service?: any;
|
|
238
|
+
xNode?: any;
|
|
239
|
+
path?: any;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
declare const many2manyBinaryController: (props: IInputFieldProps & UploadDeps & {
|
|
243
|
+
rootField?: any;
|
|
244
|
+
index?: number;
|
|
245
|
+
}) => {
|
|
246
|
+
inputId: string;
|
|
247
|
+
initialFiles: any[];
|
|
248
|
+
binaryRef: react.RefObject<HTMLDivElement>;
|
|
249
|
+
handleFileChange: (files: any, e: ChangeEvent<HTMLInputElement>, oldValues: any) => Promise<void>;
|
|
250
|
+
handleRemoveAt: (idx: number) => void;
|
|
251
|
+
handleRemoveAll: () => void;
|
|
252
|
+
checkIsImageLink: (url: string) => boolean;
|
|
253
|
+
setInitialFiles: react.Dispatch<react.SetStateAction<any[]>>;
|
|
254
|
+
};
|
|
255
|
+
|
|
235
256
|
declare const tableHeadController: (props: any) => {
|
|
236
257
|
handleCheckBoxAll: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
237
258
|
checkedAll: any;
|
|
@@ -319,4 +340,4 @@ declare const searchController: ({ viewData, model, domain, context, fieldsList,
|
|
|
319
340
|
hoveredIndexSearchList: number | null;
|
|
320
341
|
};
|
|
321
342
|
|
|
322
|
-
export { type ISelctionStateProps, type ITableHeadProps, type ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController };
|
|
343
|
+
export { type ISelctionStateProps, type ITableHeadProps, type ITableProps, binaryFieldController, colorFieldController, copyLinkButtonController, dateFieldController, downLoadBinaryController, downloadFileController, durationController, many2manyBinaryController, many2manyFieldController, many2manyTagsController, many2oneButtonController, many2oneFieldController, priorityFieldController, searchController, statusDropdownController, tableController, tableGroupController, tableHeadController };
|
package/dist/widget.js
CHANGED
|
@@ -4042,6 +4042,7 @@ __export(widget_exports, {
|
|
|
4042
4042
|
downLoadBinaryController: () => downLoadBinaryController,
|
|
4043
4043
|
downloadFileController: () => downloadFileController,
|
|
4044
4044
|
durationController: () => durationController,
|
|
4045
|
+
many2manyBinaryController: () => many2manyBinaryController,
|
|
4045
4046
|
many2manyFieldController: () => many2manyFieldController,
|
|
4046
4047
|
many2manyTagsController: () => many2manyTagsController,
|
|
4047
4048
|
many2oneButtonController: () => many2oneButtonController,
|
|
@@ -4147,6 +4148,7 @@ var languages = [
|
|
|
4147
4148
|
{ id: "vi_VN", name: "VIE" },
|
|
4148
4149
|
{ id: "en_US", name: "ENG" }
|
|
4149
4150
|
];
|
|
4151
|
+
var isBlobUrl = (url) => url.startsWith("blob:");
|
|
4150
4152
|
|
|
4151
4153
|
// src/utils/function.ts
|
|
4152
4154
|
var import_react3 = require("react");
|
|
@@ -5582,6 +5584,77 @@ var binaryFieldController = (props) => {
|
|
|
5582
5584
|
|
|
5583
5585
|
// src/widget/basic/many2many-binary-field/controller.tsx
|
|
5584
5586
|
var import_react23 = require("react");
|
|
5587
|
+
var many2manyBinaryController = (props) => {
|
|
5588
|
+
const {
|
|
5589
|
+
name,
|
|
5590
|
+
methods,
|
|
5591
|
+
value,
|
|
5592
|
+
onChange: handleOnchange,
|
|
5593
|
+
service,
|
|
5594
|
+
xNode,
|
|
5595
|
+
path
|
|
5596
|
+
} = props;
|
|
5597
|
+
const inputId = (0, import_react23.useId)();
|
|
5598
|
+
const { useUploadFile: useUploadFile2 } = (0, provider_exports.useService)();
|
|
5599
|
+
const { mutateAsync } = useUploadFile2();
|
|
5600
|
+
const binaryRef = (0, import_react23.useRef)(null);
|
|
5601
|
+
const [initialFiles, setInitialFiles] = (0, import_react23.useState)(
|
|
5602
|
+
Array.isArray(value) ? value : value ? [value] : []
|
|
5603
|
+
);
|
|
5604
|
+
const checkIsImageLink = (url) => {
|
|
5605
|
+
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
5606
|
+
return imageExtensions.test(url) || (0, utils_exports.isBase64Image)(url) || isBlobUrl(url);
|
|
5607
|
+
};
|
|
5608
|
+
const sanitizeForBE = (list) => list.filter((x) => x?.datas && !isBlobUrl(x.datas)).map((x) => ({ name: x.name, datas: x.datas, mimetype: x.mimetype }));
|
|
5609
|
+
const handleFileChange = async (files, e, oldValues) => {
|
|
5610
|
+
try {
|
|
5611
|
+
const uploadedUrls = await Promise.all(
|
|
5612
|
+
files.map(async (f) => {
|
|
5613
|
+
const formData = new FormData();
|
|
5614
|
+
formData.append("file", f);
|
|
5615
|
+
const res = await mutateAsync({ formData, service, xNode, path });
|
|
5616
|
+
return res?.url;
|
|
5617
|
+
})
|
|
5618
|
+
);
|
|
5619
|
+
const uploadedItems = files.map((f, i) => ({
|
|
5620
|
+
name: f.name,
|
|
5621
|
+
datas: uploadedUrls[i] ?? "",
|
|
5622
|
+
mimetype: f.type
|
|
5623
|
+
}));
|
|
5624
|
+
const finalList = [...oldValues, ...uploadedItems];
|
|
5625
|
+
methods?.setValue(name, finalList, { shouldDirty: true });
|
|
5626
|
+
const payloadForBE = sanitizeForBE(finalList);
|
|
5627
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
5628
|
+
} catch (err) {
|
|
5629
|
+
console.error(err);
|
|
5630
|
+
} finally {
|
|
5631
|
+
e.target.value = "";
|
|
5632
|
+
}
|
|
5633
|
+
};
|
|
5634
|
+
const handleRemoveAt = (idx) => {
|
|
5635
|
+
const current = methods?.getValues(name) || [];
|
|
5636
|
+
const next = current.filter((_, i) => i !== idx);
|
|
5637
|
+
setInitialFiles((p) => p.filter((_, i) => i !== idx));
|
|
5638
|
+
methods?.setValue(name, next.length ? next : null, { shouldDirty: true });
|
|
5639
|
+
const payloadForBE = next.length ? sanitizeForBE(next) : null;
|
|
5640
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
5641
|
+
};
|
|
5642
|
+
const handleRemoveAll = () => {
|
|
5643
|
+
setInitialFiles([]);
|
|
5644
|
+
methods?.setValue(name, null, { shouldDirty: true });
|
|
5645
|
+
handleOnchange && handleOnchange(name ?? "", null);
|
|
5646
|
+
};
|
|
5647
|
+
return {
|
|
5648
|
+
inputId,
|
|
5649
|
+
initialFiles,
|
|
5650
|
+
binaryRef,
|
|
5651
|
+
handleFileChange,
|
|
5652
|
+
handleRemoveAt,
|
|
5653
|
+
handleRemoveAll,
|
|
5654
|
+
checkIsImageLink,
|
|
5655
|
+
setInitialFiles
|
|
5656
|
+
};
|
|
5657
|
+
};
|
|
5585
5658
|
|
|
5586
5659
|
// src/widget/advance/table/table-head/controller.ts
|
|
5587
5660
|
var import_react24 = require("react");
|
|
@@ -6195,6 +6268,7 @@ var searchController = ({
|
|
|
6195
6268
|
downLoadBinaryController,
|
|
6196
6269
|
downloadFileController,
|
|
6197
6270
|
durationController,
|
|
6271
|
+
many2manyBinaryController,
|
|
6198
6272
|
many2manyFieldController,
|
|
6199
6273
|
many2manyTagsController,
|
|
6200
6274
|
many2oneButtonController,
|
package/dist/widget.mjs
CHANGED
|
@@ -4214,6 +4214,7 @@ var languages = [
|
|
|
4214
4214
|
{ id: "vi_VN", name: "VIE" },
|
|
4215
4215
|
{ id: "en_US", name: "ENG" }
|
|
4216
4216
|
];
|
|
4217
|
+
var isBlobUrl = (url) => url.startsWith("blob:");
|
|
4217
4218
|
|
|
4218
4219
|
// src/utils/function.ts
|
|
4219
4220
|
import { useCallback as useCallback2, useEffect as useEffect2, useReducer } from "react";
|
|
@@ -5654,6 +5655,77 @@ var binaryFieldController = (props) => {
|
|
|
5654
5655
|
|
|
5655
5656
|
// src/widget/basic/many2many-binary-field/controller.tsx
|
|
5656
5657
|
import { useId as useId2, useRef as useRef4, useState as useState13 } from "react";
|
|
5658
|
+
var many2manyBinaryController = (props) => {
|
|
5659
|
+
const {
|
|
5660
|
+
name,
|
|
5661
|
+
methods,
|
|
5662
|
+
value,
|
|
5663
|
+
onChange: handleOnchange,
|
|
5664
|
+
service,
|
|
5665
|
+
xNode,
|
|
5666
|
+
path
|
|
5667
|
+
} = props;
|
|
5668
|
+
const inputId = useId2();
|
|
5669
|
+
const { useUploadFile: useUploadFile2 } = (0, provider_exports.useService)();
|
|
5670
|
+
const { mutateAsync } = useUploadFile2();
|
|
5671
|
+
const binaryRef = useRef4(null);
|
|
5672
|
+
const [initialFiles, setInitialFiles] = useState13(
|
|
5673
|
+
Array.isArray(value) ? value : value ? [value] : []
|
|
5674
|
+
);
|
|
5675
|
+
const checkIsImageLink = (url) => {
|
|
5676
|
+
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|ico)$/i;
|
|
5677
|
+
return imageExtensions.test(url) || (0, utils_exports.isBase64Image)(url) || isBlobUrl(url);
|
|
5678
|
+
};
|
|
5679
|
+
const sanitizeForBE = (list) => list.filter((x) => x?.datas && !isBlobUrl(x.datas)).map((x) => ({ name: x.name, datas: x.datas, mimetype: x.mimetype }));
|
|
5680
|
+
const handleFileChange = async (files, e, oldValues) => {
|
|
5681
|
+
try {
|
|
5682
|
+
const uploadedUrls = await Promise.all(
|
|
5683
|
+
files.map(async (f) => {
|
|
5684
|
+
const formData = new FormData();
|
|
5685
|
+
formData.append("file", f);
|
|
5686
|
+
const res = await mutateAsync({ formData, service, xNode, path });
|
|
5687
|
+
return res?.url;
|
|
5688
|
+
})
|
|
5689
|
+
);
|
|
5690
|
+
const uploadedItems = files.map((f, i) => ({
|
|
5691
|
+
name: f.name,
|
|
5692
|
+
datas: uploadedUrls[i] ?? "",
|
|
5693
|
+
mimetype: f.type
|
|
5694
|
+
}));
|
|
5695
|
+
const finalList = [...oldValues, ...uploadedItems];
|
|
5696
|
+
methods?.setValue(name, finalList, { shouldDirty: true });
|
|
5697
|
+
const payloadForBE = sanitizeForBE(finalList);
|
|
5698
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
5699
|
+
} catch (err) {
|
|
5700
|
+
console.error(err);
|
|
5701
|
+
} finally {
|
|
5702
|
+
e.target.value = "";
|
|
5703
|
+
}
|
|
5704
|
+
};
|
|
5705
|
+
const handleRemoveAt = (idx) => {
|
|
5706
|
+
const current = methods?.getValues(name) || [];
|
|
5707
|
+
const next = current.filter((_, i) => i !== idx);
|
|
5708
|
+
setInitialFiles((p) => p.filter((_, i) => i !== idx));
|
|
5709
|
+
methods?.setValue(name, next.length ? next : null, { shouldDirty: true });
|
|
5710
|
+
const payloadForBE = next.length ? sanitizeForBE(next) : null;
|
|
5711
|
+
handleOnchange && handleOnchange(name ?? "", payloadForBE);
|
|
5712
|
+
};
|
|
5713
|
+
const handleRemoveAll = () => {
|
|
5714
|
+
setInitialFiles([]);
|
|
5715
|
+
methods?.setValue(name, null, { shouldDirty: true });
|
|
5716
|
+
handleOnchange && handleOnchange(name ?? "", null);
|
|
5717
|
+
};
|
|
5718
|
+
return {
|
|
5719
|
+
inputId,
|
|
5720
|
+
initialFiles,
|
|
5721
|
+
binaryRef,
|
|
5722
|
+
handleFileChange,
|
|
5723
|
+
handleRemoveAt,
|
|
5724
|
+
handleRemoveAll,
|
|
5725
|
+
checkIsImageLink,
|
|
5726
|
+
setInitialFiles
|
|
5727
|
+
};
|
|
5728
|
+
};
|
|
5657
5729
|
|
|
5658
5730
|
// src/widget/advance/table/table-head/controller.ts
|
|
5659
5731
|
import { useMemo as useMemo10, useRef as useRef5 } from "react";
|
|
@@ -6267,6 +6339,7 @@ export {
|
|
|
6267
6339
|
downLoadBinaryController,
|
|
6268
6340
|
downloadFileController,
|
|
6269
6341
|
durationController,
|
|
6342
|
+
many2manyBinaryController,
|
|
6270
6343
|
many2manyFieldController,
|
|
6271
6344
|
many2manyTagsController,
|
|
6272
6345
|
many2oneButtonController,
|