@groupeactual/ui-kit 1.7.1 → 1.7.2
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/cjs/index.js +1 -1
- package/dist/es/index.d.ts +5 -2
- package/dist/es/index.js +1 -1
- package/dist/es/src/components/UploadDocument/FileUploader.d.ts +4 -2
- package/dist/es/src/components/UploadDocument/fileuploader.interface.d.ts +1 -0
- package/package.json +4 -4
- package/src/components/Datatable/use-pagination-props.hook.ts +0 -1
- package/src/components/UploadDocument/FileUploader.tsx +60 -75
- package/src/components/UploadDocument/fileuploader.interface.ts +1 -0
|
@@ -11,6 +11,8 @@ interface Props {
|
|
|
11
11
|
accept?: string[];
|
|
12
12
|
acceptText?: AcceptTextType;
|
|
13
13
|
orText?: string;
|
|
14
|
+
fromLocalText?: string;
|
|
15
|
+
fromGoogleDriveText?: string;
|
|
14
16
|
disabled?: boolean;
|
|
15
17
|
error?: string;
|
|
16
18
|
enableGoogleDrive?: boolean;
|
|
@@ -19,7 +21,7 @@ interface Props {
|
|
|
19
21
|
_isDroppingFile?: boolean;
|
|
20
22
|
validateFile?: (_size: number, _type: string, _accept: string[], _setUploadFileError: React.Dispatch<React.SetStateAction<boolean | string>>) => boolean;
|
|
21
23
|
onTouched?: () => void;
|
|
22
|
-
onFilesDataChange?: (_fileData: FileDataType[] | undefined
|
|
24
|
+
onFilesDataChange?: (_fileData: FileDataType[] | undefined) => void;
|
|
23
25
|
}
|
|
24
|
-
declare const FileUploader: ({ title, subTitle, titleAddButton, helperText, titleTooltip, files, isMulti, accept, acceptText, orText, disabled, error, enableGoogleDrive, googleAuthClientId, googleApiKey, _isDroppingFile, validateFile, onTouched, onFilesDataChange, }: Props) => React.JSX.Element;
|
|
26
|
+
declare const FileUploader: ({ title, subTitle, titleAddButton, helperText, titleTooltip, files, isMulti, accept, acceptText, orText, fromLocalText, fromGoogleDriveText, disabled, error, enableGoogleDrive, googleAuthClientId, googleApiKey, _isDroppingFile, validateFile, onTouched, onFilesDataChange, }: Props) => React.JSX.Element;
|
|
25
27
|
export default FileUploader;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@groupeactual/ui-kit",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A simple template for a custom React component library",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"@types/google.picker": "^0.0.46",
|
|
15
15
|
"@types/styled-components": "^5.1.34",
|
|
16
16
|
"framer-motion": "^11.12.0",
|
|
17
|
-
"eslint": "^9.
|
|
17
|
+
"eslint": "^9.16.0",
|
|
18
18
|
"eslint-config-prettier": "^9.1.0",
|
|
19
19
|
"eslint-plugin-import": "^2.31.0",
|
|
20
20
|
"eslint-plugin-jest": "^28.9.0",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"@mui/x-date-pickers": "7.15.0",
|
|
34
34
|
"@mui/x-date-pickers-pro": "7.15.0",
|
|
35
35
|
"styled-components": "^6.1.13",
|
|
36
|
-
"@groupeactual/design-tokens": "1.7.
|
|
36
|
+
"@groupeactual/design-tokens": "1.7.2"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "rollup -c",
|
|
40
40
|
"build:watch": "rollup --bundleConfigAsCjs -c -w",
|
|
41
41
|
"dev": "npm run build:watch",
|
|
42
|
-
"eslint": "eslint --config \"eslint.config.js\" --color \".\"",
|
|
42
|
+
"eslint": "eslint --config \"eslint.config.js\" --color \".\" --max-warnings=0",
|
|
43
43
|
"lint": "npm run eslint"
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
} from '@fortawesome/pro-solid-svg-icons';
|
|
23
23
|
import { Box, IconButton } from '@mui/material';
|
|
24
24
|
import Menu from '@mui/material/Menu';
|
|
25
|
-
import { set } from 'lodash';
|
|
26
25
|
|
|
27
26
|
import Button from '@/components/Button';
|
|
28
27
|
import IconProvider from '@/components/IconProvider';
|
|
@@ -48,6 +47,8 @@ interface Props {
|
|
|
48
47
|
accept?: string[];
|
|
49
48
|
acceptText?: AcceptTextType;
|
|
50
49
|
orText?: string;
|
|
50
|
+
fromLocalText?: string;
|
|
51
|
+
fromGoogleDriveText?: string;
|
|
51
52
|
disabled?: boolean;
|
|
52
53
|
error?: string;
|
|
53
54
|
enableGoogleDrive?: boolean;
|
|
@@ -61,10 +62,7 @@ interface Props {
|
|
|
61
62
|
_setUploadFileError: React.Dispatch<React.SetStateAction<boolean | string>>,
|
|
62
63
|
) => boolean;
|
|
63
64
|
onTouched?: () => void;
|
|
64
|
-
onFilesDataChange?: (
|
|
65
|
-
_fileData: FileDataType[] | undefined,
|
|
66
|
-
_filesInput?: File[],
|
|
67
|
-
) => void;
|
|
65
|
+
onFilesDataChange?: (_fileData: FileDataType[] | undefined) => void;
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
const FileUploader = ({
|
|
@@ -78,6 +76,8 @@ const FileUploader = ({
|
|
|
78
76
|
accept = [],
|
|
79
77
|
acceptText = { fileFormat: '', maxSize: '', subText: '' },
|
|
80
78
|
orText = 'ou',
|
|
79
|
+
fromLocalText = 'Depuis votre PC',
|
|
80
|
+
fromGoogleDriveText = 'Depuis Google Drive',
|
|
81
81
|
disabled = false,
|
|
82
82
|
error,
|
|
83
83
|
enableGoogleDrive = false,
|
|
@@ -94,8 +94,6 @@ const FileUploader = ({
|
|
|
94
94
|
|
|
95
95
|
// * States
|
|
96
96
|
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
|
97
|
-
// * currentFiles is used only to revoke the object URL when the component is unmounted for performance reasons
|
|
98
|
-
const [currentFiles, setCurrentFiles] = useState<File[]>([]);
|
|
99
97
|
// * filesData is used to display the files in the component
|
|
100
98
|
const [filesData, setFilesData] = useState<FileDataType[] | undefined>([]);
|
|
101
99
|
const [isDroppingFile, setIsDroppingFile] =
|
|
@@ -192,12 +190,34 @@ const FileUploader = ({
|
|
|
192
190
|
handleClose();
|
|
193
191
|
onTouched?.();
|
|
194
192
|
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
if (token && data && data.docs && data.docs.length > 0) {
|
|
194
|
+
// * Google Drive
|
|
195
|
+
const validDocs = data.docs.filter((doc) =>
|
|
196
|
+
validateFile
|
|
197
|
+
? validateFile(
|
|
198
|
+
doc.sizeBytes,
|
|
199
|
+
doc.mimeType,
|
|
200
|
+
accept,
|
|
201
|
+
setUploadFileError,
|
|
202
|
+
)
|
|
203
|
+
: true,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const googleFileData = validDocs.map((doc) => ({
|
|
207
|
+
name: doc.name,
|
|
208
|
+
size: Math.round(doc.sizeBytes / 1024), // * Convert size to KB
|
|
209
|
+
type: doc.mimeType,
|
|
210
|
+
url: `https://drive.google.com/file/d/${doc.id}/view?usp=drive_we`,
|
|
211
|
+
driveFileId: doc.id,
|
|
212
|
+
driveAccessToken: token,
|
|
213
|
+
}));
|
|
214
|
+
|
|
215
|
+
setFilesData([...(filesData || []), ...googleFileData]);
|
|
216
|
+
} else if (
|
|
197
217
|
fileInputRef.current?.files &&
|
|
198
218
|
fileInputRef.current?.files?.length > 0
|
|
199
219
|
) {
|
|
200
|
-
|
|
220
|
+
// * Local Files
|
|
201
221
|
const fileList = Array.from(fileInputRef.current?.files);
|
|
202
222
|
|
|
203
223
|
const newFileData: FileDataType[] = fileList
|
|
@@ -210,54 +230,27 @@ const FileUploader = ({
|
|
|
210
230
|
return null;
|
|
211
231
|
}
|
|
212
232
|
|
|
213
|
-
validInputFiles.push(file);
|
|
214
|
-
|
|
215
233
|
return {
|
|
216
234
|
name: file?.name ?? '',
|
|
217
235
|
size: Math.round(file.size / 1024),
|
|
218
236
|
type: file.type,
|
|
219
237
|
url: URL.createObjectURL(file),
|
|
238
|
+
file: file,
|
|
220
239
|
};
|
|
221
240
|
})
|
|
222
|
-
.filter((file)
|
|
241
|
+
.filter((file) => file !== null);
|
|
223
242
|
|
|
224
243
|
if (newFileData && newFileData?.length > 0) {
|
|
225
|
-
setCurrentFiles([...(currentFiles || []), ...validInputFiles]);
|
|
226
244
|
setFilesData([...(filesData || []), ...newFileData]);
|
|
227
245
|
}
|
|
228
|
-
} else if (token && data && data.docs && data.docs.length > 0) {
|
|
229
|
-
// * Google Drive
|
|
230
|
-
const validDocs = data.docs.filter((doc) =>
|
|
231
|
-
validateFile
|
|
232
|
-
? validateFile(
|
|
233
|
-
doc.sizeBytes,
|
|
234
|
-
doc.mimeType,
|
|
235
|
-
accept,
|
|
236
|
-
setUploadFileError,
|
|
237
|
-
)
|
|
238
|
-
: true,
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
const googleFileData = validDocs.map((doc) => ({
|
|
242
|
-
name: doc.name,
|
|
243
|
-
size: Math.round(doc.sizeBytes / 1024), // * Convert size to KB
|
|
244
|
-
type: doc.mimeType,
|
|
245
|
-
url: `https://drive.google.com/file/d/${doc.id}/view?usp=drive_we`,
|
|
246
|
-
driveFileId: doc.id,
|
|
247
|
-
driveAccessToken: token,
|
|
248
|
-
}));
|
|
249
|
-
|
|
250
|
-
setFilesData([...(filesData || []), ...googleFileData]);
|
|
251
246
|
}
|
|
252
247
|
|
|
253
248
|
setIsDroppingFile(false);
|
|
254
249
|
},
|
|
255
250
|
[
|
|
256
251
|
fileInputRef,
|
|
257
|
-
currentFiles,
|
|
258
252
|
filesData,
|
|
259
253
|
setIsDroppingFile,
|
|
260
|
-
setCurrentFiles,
|
|
261
254
|
setFilesData,
|
|
262
255
|
validateFile,
|
|
263
256
|
onTouched,
|
|
@@ -268,8 +261,8 @@ const FileUploader = ({
|
|
|
268
261
|
const handleDelete = useCallback(
|
|
269
262
|
(fileIndex: number) => {
|
|
270
263
|
//* Remove the file from the currentFiles array
|
|
271
|
-
if (
|
|
272
|
-
const fileToDelete =
|
|
264
|
+
if (filesData && filesData.length > 0) {
|
|
265
|
+
const fileToDelete = filesData[fileIndex]?.file;
|
|
273
266
|
if (fileToDelete) {
|
|
274
267
|
// * Revoke the object URL to free up memory, use try and catch to avoid errors on the other files not imported with the file input
|
|
275
268
|
try {
|
|
@@ -279,14 +272,6 @@ const FileUploader = ({
|
|
|
279
272
|
// * Do nothing
|
|
280
273
|
}
|
|
281
274
|
}
|
|
282
|
-
|
|
283
|
-
if (currentFiles.length === 1) {
|
|
284
|
-
setCurrentFiles([]);
|
|
285
|
-
} else {
|
|
286
|
-
setCurrentFiles(
|
|
287
|
-
currentFiles.filter((_, index) => index !== fileIndex),
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
275
|
}
|
|
291
276
|
|
|
292
277
|
//* Remove the file from the filesData array
|
|
@@ -302,7 +287,7 @@ const FileUploader = ({
|
|
|
302
287
|
|
|
303
288
|
setIsDroppingFile(false);
|
|
304
289
|
},
|
|
305
|
-
[
|
|
290
|
+
[filesData, setIsDroppingFile, setFilesData],
|
|
306
291
|
);
|
|
307
292
|
|
|
308
293
|
// * Utils
|
|
@@ -318,54 +303,54 @@ const FileUploader = ({
|
|
|
318
303
|
// * Initialize the component with the files passed as props
|
|
319
304
|
useEffect(() => {
|
|
320
305
|
if (!isInitialized && files.length > 0) {
|
|
321
|
-
const FilesDataDto: FileDataType[] = files.map((file) => ({
|
|
322
|
-
name: file.name,
|
|
323
|
-
size: Math.round(file.size / 1024), // Convert size to KB
|
|
324
|
-
type: file.type,
|
|
325
|
-
url: file.url,
|
|
326
|
-
}));
|
|
327
|
-
|
|
328
306
|
const initializeFiles = async () => {
|
|
329
307
|
const initialFiles = await Promise.all(
|
|
330
|
-
|
|
331
|
-
const response = await fetch(
|
|
308
|
+
files.map(async (file) => {
|
|
309
|
+
const response = await fetch(file.url);
|
|
332
310
|
const blob = await response.blob();
|
|
333
311
|
|
|
334
|
-
return
|
|
335
|
-
|
|
336
|
-
|
|
312
|
+
return {
|
|
313
|
+
name: file.name,
|
|
314
|
+
size: Math.round(file.size / 1024), // Convert size to KB
|
|
315
|
+
type: file.type,
|
|
316
|
+
url: file.url,
|
|
317
|
+
file: new File([blob], file.name, {
|
|
318
|
+
type: file.type,
|
|
319
|
+
}),
|
|
320
|
+
};
|
|
337
321
|
}),
|
|
338
322
|
);
|
|
339
323
|
|
|
340
|
-
|
|
324
|
+
setFilesData(initialFiles);
|
|
341
325
|
};
|
|
342
326
|
|
|
343
327
|
initializeFiles();
|
|
344
|
-
setFilesData(FilesDataDto);
|
|
345
328
|
setIsInitialized(true);
|
|
346
329
|
}
|
|
347
330
|
}, [files]);
|
|
348
331
|
|
|
349
332
|
useEffect(() => {
|
|
350
333
|
// * Notify parent component
|
|
351
|
-
onFilesDataChange?.(filesData
|
|
352
|
-
}, [filesData
|
|
334
|
+
onFilesDataChange?.(filesData);
|
|
335
|
+
}, [filesData]);
|
|
353
336
|
|
|
354
337
|
useEffect(() => {
|
|
355
338
|
return () => {
|
|
356
|
-
if (!
|
|
339
|
+
if (!filesData?.length) return;
|
|
357
340
|
|
|
358
341
|
try {
|
|
359
342
|
// * Only for file imported with the file input, use try and catch to avoid errors on the other files
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
343
|
+
filesData.forEach((_fileData) => {
|
|
344
|
+
if (_fileData?.file) {
|
|
345
|
+
const fileURL = URL.createObjectURL(_fileData?.file);
|
|
346
|
+
URL.revokeObjectURL(fileURL);
|
|
347
|
+
}
|
|
363
348
|
});
|
|
364
349
|
} catch {
|
|
365
350
|
// * Do nothing
|
|
366
351
|
}
|
|
367
352
|
};
|
|
368
|
-
}, [
|
|
353
|
+
}, [filesData]);
|
|
369
354
|
|
|
370
355
|
return (
|
|
371
356
|
<Box
|
|
@@ -517,9 +502,9 @@ const FileUploader = ({
|
|
|
517
502
|
testId="pc-add"
|
|
518
503
|
onClick={() => handleFileChange(null, null, null, [], true)}
|
|
519
504
|
>
|
|
520
|
-
<Box gap={1} display="flex">
|
|
505
|
+
<Box gap={1} display="inline-flex" alignItems="center">
|
|
521
506
|
<IconProvider size="sm" icon={faFolderOpen} />
|
|
522
|
-
<Text variant="body2">
|
|
507
|
+
<Text variant="body2">{fromLocalText}</Text>
|
|
523
508
|
</Box>
|
|
524
509
|
</MenuItem>
|
|
525
510
|
<GooglePickerWrapper
|
|
@@ -534,9 +519,9 @@ const FileUploader = ({
|
|
|
534
519
|
viewId="FOLDERS"
|
|
535
520
|
>
|
|
536
521
|
<MenuItem testId="drive-add" onClick={handleClose}>
|
|
537
|
-
<Box gap={1} display="flex">
|
|
522
|
+
<Box gap={1} display="inline-flex" alignItems="center">
|
|
538
523
|
<IconProvider size="sm" icon={faGoogleDrive} />
|
|
539
|
-
<Text variant="body2">
|
|
524
|
+
<Text variant="body2">{fromGoogleDriveText}</Text>
|
|
540
525
|
</Box>
|
|
541
526
|
</MenuItem>
|
|
542
527
|
</GooglePickerWrapper>
|