@astral/ui 4.18.6 → 4.19.0

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.
Files changed (43) hide show
  1. package/components/fileUploading/FileUploader/FIleList/FileList.d.ts +6 -2
  2. package/components/fileUploading/FileUploader/FIleList/FileList.js +1 -1
  3. package/components/fileUploading/FileUploaderFile/Actions/Actions.js +3 -3
  4. package/components/fileUploading/FileUploaderFile/Actions/useLogic/useLogic.d.ts +6 -1
  5. package/components/fileUploading/FileUploaderFile/Actions/useLogic/useLogic.js +2 -1
  6. package/components/fileUploading/FileUploaderFile/FileUploaderFile.d.ts +4 -0
  7. package/components/fileUploading/PreviewFileUploader/FileList/FileList.d.ts +6 -2
  8. package/components/fileUploading/PreviewFileUploader/FileList/FileList.js +1 -1
  9. package/components/fileUploading/PreviewFileUploaderFile/FilePreview/FilePreview.d.ts +4 -0
  10. package/components/fileUploading/PreviewFileUploaderFile/FilePreview/FilePreview.js +2 -2
  11. package/components/fileUploading/PreviewFileUploaderFile/PreviewFileUploaderFile.d.ts +4 -0
  12. package/components/fileUploading/PreviewFileUploaderFile/PreviewFileUploaderFile.js +2 -2
  13. package/components/fileUploading/hooks/useFileUploader/useFileUploader.d.ts +2 -1
  14. package/components/fileUploading/hooks/useFileUploader/useFileUploader.js +17 -5
  15. package/components/fileUploading/hooks/usePreviewFileUploader/usePreviewFileUploader.d.ts +10 -2
  16. package/components/fileUploading/hooks/usePreviewFileUploader/usePreviewFileUploader.js +14 -4
  17. package/components/fileUploading/types.d.ts +7 -0
  18. package/node/components/fileUploading/FileUploader/FIleList/FileList.d.ts +6 -2
  19. package/node/components/fileUploading/FileUploader/FIleList/FileList.js +1 -1
  20. package/node/components/fileUploading/FileUploaderFile/Actions/Actions.js +3 -3
  21. package/node/components/fileUploading/FileUploaderFile/Actions/useLogic/useLogic.d.ts +6 -1
  22. package/node/components/fileUploading/FileUploaderFile/Actions/useLogic/useLogic.js +2 -1
  23. package/node/components/fileUploading/FileUploaderFile/FileUploaderFile.d.ts +4 -0
  24. package/node/components/fileUploading/PreviewFileUploader/FileList/FileList.d.ts +6 -2
  25. package/node/components/fileUploading/PreviewFileUploader/FileList/FileList.js +1 -1
  26. package/node/components/fileUploading/PreviewFileUploaderFile/FilePreview/FilePreview.d.ts +4 -0
  27. package/node/components/fileUploading/PreviewFileUploaderFile/FilePreview/FilePreview.js +2 -2
  28. package/node/components/fileUploading/PreviewFileUploaderFile/PreviewFileUploaderFile.d.ts +4 -0
  29. package/node/components/fileUploading/PreviewFileUploaderFile/PreviewFileUploaderFile.js +2 -2
  30. package/node/components/fileUploading/hooks/useFileUploader/useFileUploader.d.ts +2 -1
  31. package/node/components/fileUploading/hooks/useFileUploader/useFileUploader.js +16 -4
  32. package/node/components/fileUploading/hooks/usePreviewFileUploader/usePreviewFileUploader.d.ts +10 -2
  33. package/node/components/fileUploading/hooks/usePreviewFileUploader/usePreviewFileUploader.js +13 -3
  34. package/node/components/fileUploading/types.d.ts +7 -0
  35. package/package.json +1 -1
  36. package/hook-form/FormFileUploader/faker.d.ts +0 -2
  37. package/hook-form/FormFileUploader/faker.js +0 -37
  38. package/hook-form/FormPreviewFileUploader/faker.d.ts +0 -2
  39. package/hook-form/FormPreviewFileUploader/faker.js +0 -37
  40. package/node/hook-form/FormFileUploader/faker.d.ts +0 -2
  41. package/node/hook-form/FormFileUploader/faker.js +0 -44
  42. package/node/hook-form/FormPreviewFileUploader/faker.d.ts +0 -2
  43. package/node/hook-form/FormPreviewFileUploader/faker.js +0 -44
@@ -1,5 +1,5 @@
1
1
  import { type FileUploaderFileProps } from '../../FileUploaderFile';
2
- import { type UploadFile } from '../../types';
2
+ import { type FileId, type UploadFile } from '../../types';
3
3
  export type FileListProps = {
4
4
  isMultiple?: boolean;
5
5
  /**
@@ -7,5 +7,9 @@ export type FileListProps = {
7
7
  */
8
8
  files?: UploadFile[];
9
9
  className?: string;
10
+ /**
11
+ * Идентификатор файла, для которого выполняется удаление
12
+ */
13
+ deletingFileId?: FileId | null;
10
14
  } & Pick<FileUploaderFileProps, 'onDelete' | 'onRetry' | 'onView' | 'generateDownloadLink' | 'selfFiles' | 'setErrorStatusFile'>;
11
- export declare const FileList: ({ isMultiple, files, className, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
15
+ export declare const FileList: ({ isMultiple, files, className, deletingFileId, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { FileUploaderFile, } from '../../FileUploaderFile';
3
3
  import { Wrapper } from './styles';
4
- export const FileList = ({ isMultiple, files, className, ...restProps }) => (_jsx(Wrapper, { "$isMultiple": isMultiple, className: className, children: files?.map((file) => (_jsx("li", { children: _jsx(FileUploaderFile, { ...file, ...restProps }) }, file.id))) }));
4
+ export const FileList = ({ isMultiple, files, className, deletingFileId, ...restProps }) => (_jsx(Wrapper, { "$isMultiple": isMultiple, className: className, children: files?.map((file) => (_jsx("li", { children: _jsx(FileUploaderFile, { ...file, ...restProps, isDeletingFile: deletingFileId === file.id }) }, file.id))) }));
@@ -9,13 +9,13 @@ import { Tooltip } from '../../../Tooltip';
9
9
  import { Wrapper } from './styles';
10
10
  import { useLogic } from './useLogic';
11
11
  export const Actions = (props) => {
12
- const { downloadButtonProps, viewButtonProps, isVisibleAbortButton, isVisibleRetryButton, handleAbort, handleDelete, handleRetry, isLoading, isError, fileName, } = useLogic(props);
12
+ const { downloadButtonProps, viewButtonProps, isVisibleAbortButton, isVisibleRetryButton, handleAbort, handleDelete, handleRetry, isLoading, isError, isDeletingFile, fileName, } = useLogic(props);
13
13
  if (isLoading) {
14
14
  return (_jsx(Wrapper, { children: isVisibleAbortButton && (_jsx(Tooltip, { title: "\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", children: _jsx(IconButton, { variant: "text", onClick: handleAbort, children: _jsx(CrossOutlineMd, {}) }) })) }));
15
15
  }
16
16
  if (isError) {
17
- return (_jsxs(Wrapper, { children: [isVisibleRetryButton && (_jsx(Tooltip, { title: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", children: _jsx(IconButton, { variant: "text", onClick: handleRetry, children: _jsx(RetryOutlineMd, {}) }) })), _jsx(Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: _jsx(IconButton, { variant: "text", onClick: handleDelete, children: _jsx(CrossOutlineMd, {}) }) })] }));
17
+ return (_jsxs(Wrapper, { children: [isVisibleRetryButton && (_jsx(Tooltip, { title: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", children: _jsx(IconButton, { variant: "text", onClick: handleRetry, children: _jsx(RetryOutlineMd, {}) }) })), _jsx(Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: _jsx(IconButton, { variant: "text", onClick: handleDelete, loading: isDeletingFile, children: _jsx(CrossOutlineMd, {}) }) })] }));
18
18
  }
19
19
  const { isShowViewButton, ...restViewButtonProps } = viewButtonProps;
20
- return (_jsxs(Wrapper, { children: [isShowViewButton && (_jsx(Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", children: _jsx(IconButton, { variant: "text", ...restViewButtonProps, children: _jsx(EyeOutlineMd, {}) }) })), _jsx(Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", children: _jsx(IconButton, { component: "a", variant: "text", download: fileName, ...downloadButtonProps, children: _jsx(DownloadOutlineMd, {}) }) }), _jsx(Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: _jsx(IconButton, { variant: "text", onClick: handleDelete, children: _jsx(BinOutlineMd, {}) }) })] }));
20
+ return (_jsxs(Wrapper, { children: [isShowViewButton && (_jsx(Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", children: _jsx(IconButton, { variant: "text", ...restViewButtonProps, children: _jsx(EyeOutlineMd, {}) }) })), _jsx(Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", children: _jsx(IconButton, { component: "a", variant: "text", download: fileName, ...downloadButtonProps, children: _jsx(DownloadOutlineMd, {}) }) }), _jsx(Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: _jsx(IconButton, { variant: "text", onClick: handleDelete, loading: isDeletingFile, children: _jsx(BinOutlineMd, {}) }) })] }));
21
21
  };
@@ -45,9 +45,13 @@ export type UseLogicParams = {
45
45
  * Функция, вызываемая при удалении файла
46
46
  */
47
47
  onDelete: (fileId: FileId) => void;
48
+ /**
49
+ * Флаг загрузки при удалении файла
50
+ */
51
+ isDeletingFile?: boolean;
48
52
  abortController?: AbortController;
49
53
  } & Pick<SelfFileApi, 'selfFiles' | 'setErrorStatusFile'>;
50
- export declare const useLogic: ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, fileName, }: UseLogicParams) => {
54
+ export declare const useLogic: ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, isDeletingFile, fileName, }: UseLogicParams) => {
51
55
  downloadButtonProps: {
52
56
  href: string;
53
57
  };
@@ -69,5 +73,6 @@ export declare const useLogic: ({ fileId, file, fileUrl, isUploadError, generate
69
73
  handleRetry: () => void | undefined;
70
74
  isLoading: boolean | undefined;
71
75
  isError: boolean | undefined;
76
+ isDeletingFile: boolean | undefined;
72
77
  fileName: string;
73
78
  };
@@ -4,7 +4,7 @@ import { ConfigContext } from '../../../../ConfigProvider';
4
4
  import { ABORT_ERROR_MESSAGE, EXTENSIONS_IN_NEW_TAB, VIEW_NEW_TAB_ERROR_MESSAGE, } from '../../../constants';
5
5
  import { useGenerateLocalFileURL } from '../../../hooks/useGenerateLocalFileURL';
6
6
  import { generateAttrLinkNewTab } from '../../../utils/generateAttrLinkNewTab';
7
- export const useLogic = ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, fileName, }) => {
7
+ export const useLogic = ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, isDeletingFile, fileName, }) => {
8
8
  const { captureException } = useContext(ConfigContext);
9
9
  const { generateUrl } = useGenerateLocalFileURL();
10
10
  const { controller } = selfFiles[fileId] || {};
@@ -71,6 +71,7 @@ export const useLogic = ({ fileId, file, fileUrl, isUploadError, generateDownloa
71
71
  handleRetry,
72
72
  isLoading,
73
73
  isError,
74
+ isDeletingFile,
74
75
  fileName,
75
76
  };
76
77
  };
@@ -17,5 +17,9 @@ export type FileUploaderFileProps = UploadFile & {
17
17
  * Функция, вызываемая при удалении файла
18
18
  */
19
19
  onDelete: (fileId: FileId) => void;
20
+ /**
21
+ * Флаг загрузки при удалении файла
22
+ */
23
+ isDeletingFile?: boolean;
20
24
  } & Pick<ActionsProps, 'selfFiles' | 'setErrorStatusFile'>;
21
25
  export declare const FileUploaderFile: (props: FileUploaderFileProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,10 @@
1
1
  import { type PreviewFileUploaderFileProps } from '../../PreviewFileUploaderFile';
2
- import { type UploadFile } from '../../types';
2
+ import type { FileId, UploadFile } from '../../types';
3
3
  export type FileListProps = {
4
4
  files: UploadFile[];
5
+ /**
6
+ * Идентификатор файла, для которого выполняется удаление
7
+ */
8
+ deletingFileId?: FileId | null;
5
9
  } & Pick<PreviewFileUploaderFileProps, 'onDelete' | 'onRetry' | 'onView' | 'generateDownloadLink' | 'selfFiles' | 'setErrorStatusFile'>;
6
- export declare const FileList: ({ files, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
10
+ export declare const FileList: ({ files, deletingFileId, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,3 +1,3 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { PreviewFileUploaderFile, } from '../../PreviewFileUploaderFile';
3
- export const FileList = ({ files, ...restProps }) => (_jsx(_Fragment, { children: files?.map((file) => (_jsx(PreviewFileUploaderFile, { ...file, ...restProps }, file.id))) }));
3
+ export const FileList = ({ files, deletingFileId, ...restProps }) => (_jsx(_Fragment, { children: files?.map((file) => (_jsx(PreviewFileUploaderFile, { ...file, ...restProps, isDeletingFile: deletingFileId === file.id }, file.id))) }));
@@ -42,6 +42,10 @@ export type FilePreviewProps = {
42
42
  * Скрытие персональных данных от инструментов мониторинга
43
43
  */
44
44
  isHidePersonalData?: boolean;
45
+ /**
46
+ * Флаг загрузки при удалении файла
47
+ */
48
+ isDeletingFile?: boolean;
45
49
  /**
46
50
  * Компонент для отображения превью pdf-файлов
47
51
  */
@@ -13,7 +13,7 @@ import { Actions, Details, StyledFileInfo, Wrapper } from './styles';
13
13
  import { useLogic } from './useLogic';
14
14
  export const FilePreview = (props) => {
15
15
  const { viewButtonProps, downloadButtonProps, deleteButtonProps, isImageFile, isPdfFile, isOtherFile, } = useLogic(props);
16
- const { file, fileName, fileSize, fileUrl, generateDownloadLink, isHidePersonalData, PdfViewer, } = props;
16
+ const { file, fileName, fileSize, fileUrl, generateDownloadLink, isHidePersonalData, PdfViewer, isDeletingFile, } = props;
17
17
  const { isMobile } = useViewportType();
18
- return (_jsxs(Wrapper, { children: [_jsx(Preview, { isImageFile: isImageFile, isPdfFile: isPdfFile, file: file, fileUrl: fileUrl, generateDownloadLink: generateDownloadLink, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer }), _jsxs(Details, { className: previewFileUploaderClassnames.details, "$isOtherFile": isOtherFile, children: [isOtherFile && _jsx(Typography, { variant: "h6", children: "\u0424\u0430\u0439\u043B \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D" }), _jsx(StyledFileInfo, { "$isOtherFile": isOtherFile, fileName: fileName, fileSize: fileSize }), _jsx(Actions, { children: isMobile && isOtherFile ? (_jsx(Button, { variant: "light", color: "grey", ...deleteButtonProps, children: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C" })) : (_jsxs(_Fragment, { children: [!isOtherFile && (_jsx(Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", disableInteractive: true, children: _jsx(IconButton, { variant: "light", color: "grey", ...viewButtonProps, children: _jsx(EyeOutlineMd, {}) }) })), _jsx(Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", disableInteractive: true, children: _jsx(IconButton, { component: "a", variant: "light", color: "grey", download: fileName, ...downloadButtonProps, children: _jsx(DownloadOutlineMd, {}) }) }), _jsx(Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", disableInteractive: true, children: _jsx(IconButton, { variant: "light", color: "grey", ...deleteButtonProps, children: _jsx(BinOutlineMd, {}) }) })] })) })] })] }));
18
+ return (_jsxs(Wrapper, { children: [_jsx(Preview, { isImageFile: isImageFile, isPdfFile: isPdfFile, file: file, fileUrl: fileUrl, generateDownloadLink: generateDownloadLink, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer }), _jsxs(Details, { className: previewFileUploaderClassnames.details, "$isOtherFile": isOtherFile, children: [isOtherFile && _jsx(Typography, { variant: "h6", children: "\u0424\u0430\u0439\u043B \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D" }), _jsx(StyledFileInfo, { "$isOtherFile": isOtherFile, fileName: fileName, fileSize: fileSize }), _jsx(Actions, { children: isMobile && isOtherFile ? (_jsx(Button, { variant: "light", color: "grey", loading: isDeletingFile, ...deleteButtonProps, children: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C" })) : (_jsxs(_Fragment, { children: [!isOtherFile && (_jsx(Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", disableInteractive: true, children: _jsx(IconButton, { variant: "light", color: "grey", ...viewButtonProps, children: _jsx(EyeOutlineMd, {}) }) })), _jsx(Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", disableInteractive: true, children: _jsx(IconButton, { component: "a", variant: "light", color: "grey", download: fileName, ...downloadButtonProps, children: _jsx(DownloadOutlineMd, {}) }) }), _jsx(Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", disableInteractive: true, children: _jsx(IconButton, { variant: "light", color: "grey", loading: isDeletingFile, ...deleteButtonProps, children: _jsx(BinOutlineMd, {}) }) })] })) })] })] }));
19
19
  };
@@ -23,6 +23,10 @@ export type PreviewFileUploaderFileProps = UploadFile & {
23
23
  * Скрытие персональных данных от инструментов мониторинга
24
24
  */
25
25
  isHidePersonalData?: boolean;
26
+ /**
27
+ * Флаг загрузки при удалении файла
28
+ */
29
+ isDeletingFile?: boolean;
26
30
  /**
27
31
  * Компонент для отображения превью pdf-файлов
28
32
  */
@@ -5,8 +5,8 @@ import { FileLoading } from './FileLoading';
5
5
  import { FilePreview } from './FilePreview';
6
6
  import { Wrapper } from './styles';
7
7
  export const PreviewFileUploaderFile = (props) => {
8
- const { id, name, type, file, url, size, status, generateDownloadLink, onRetry, onDelete, onView, selfFiles, setErrorStatusFile, isHidePersonalData, PdfViewer, } = props;
8
+ const { id, name, type, file, url, size, status, generateDownloadLink, onRetry, onDelete, onView, selfFiles, setErrorStatusFile, isHidePersonalData, PdfViewer, isDeletingFile, } = props;
9
9
  const { isLoading, isUploadError, isRestrictionError, errorMsg, progress } = status || {};
10
10
  const isError = isUploadError || isRestrictionError;
11
- return (_jsx(Fade, { in: true, children: _jsxs(Wrapper, { "$isLoading": isLoading, "$isError": isError, children: [!isLoading && !isError && (_jsx(FilePreview, { fileId: id, fileName: name, fileType: type, file: file, fileUrl: url, fileSize: size, generateDownloadLink: generateDownloadLink, onView: onView, onDelete: onDelete, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer })), isLoading && (_jsx(FileLoading, { selfFiles: selfFiles, setErrorStatusFile: setErrorStatusFile, fileId: id, fileName: name, fileSize: size, progress: progress })), isError && (_jsx(FileError, { fileId: id, fileName: name, file: file, fileSize: size, errorMsg: errorMsg, isUploadError: isUploadError, onRetry: onRetry, onDelete: onDelete }))] }) }));
11
+ return (_jsx(Fade, { in: true, children: _jsxs(Wrapper, { "$isLoading": isLoading, "$isError": isError, children: [!isLoading && !isError && (_jsx(FilePreview, { fileId: id, fileName: name, fileType: type, file: file, fileUrl: url, fileSize: size, generateDownloadLink: generateDownloadLink, onView: onView, onDelete: onDelete, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer, isDeletingFile: isDeletingFile })), isLoading && (_jsx(FileLoading, { selfFiles: selfFiles, setErrorStatusFile: setErrorStatusFile, fileId: id, fileName: name, fileSize: size, progress: progress })), isError && (_jsx(FileError, { fileId: id, fileName: name, file: file, fileSize: size, errorMsg: errorMsg, isUploadError: isUploadError, onRetry: onRetry, onDelete: onDelete }))] }) }));
12
12
  };
@@ -1,7 +1,7 @@
1
1
  import { type ChangeEvent } from 'react';
2
2
  import type { FileId, FileUploaderProps, UploadFile } from '../../types';
3
3
  export type UseFileUploaderParams = FileUploaderProps;
4
- export declare const useFileUploader: ({ value, isDisabled, isMultiple, accept, restrictions, maxFileSize, maxFileCount, inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }: UseFileUploaderParams) => {
4
+ export declare const useFileUploader: ({ value, isDisabled, isMultiple, accept, restrictions, maxFileSize, maxFileCount, inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }: UseFileUploaderParams) => {
5
5
  dropZoneProps: {
6
6
  isLimitMaxFileCount: boolean;
7
7
  maxFileCount: number;
@@ -53,5 +53,6 @@ export declare const useFileUploader: ({ value, isDisabled, isMultiple, accept,
53
53
  selfFiles: Record<string, UploadFile & import("../../types").SpecificSelfFileParams>;
54
54
  setErrorStatusFile: (fileId: string, errorMsg: string) => void;
55
55
  getErrorMessage: ((fileId: string, error: Error) => string) | undefined;
56
+ deletingFileId: string | null;
56
57
  };
57
58
  };
@@ -1,6 +1,6 @@
1
1
  import { declensionOfWords } from '@astral/utils/declension/declensionOfWords';
2
2
  import { formatFileSizeToView } from '@astral/utils/file/formatFileSizeToView';
3
- import { useMemo } from 'react';
3
+ import { useMemo, useState } from 'react';
4
4
  import { useGenerateLocalId } from '../../../useGenerateLocalId';
5
5
  import { useId } from '../../../useId';
6
6
  import { DEFAULT_FILE_STATUS, fileUploaderClassnames } from '../../constants';
@@ -11,8 +11,9 @@ import { toArray } from '../../utils/toArray';
11
11
  import { useDnD } from '../useDnD';
12
12
  import { useUploadFiles } from '../useUploadFiles';
13
13
  export const useFileUploader = ({ value, isDisabled, isMultiple, accept, restrictions = [], maxFileSize, maxFileCount = 1, // для случая, когда isMultiple=false
14
- inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }) => {
14
+ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }) => {
15
15
  const inputId = useId();
16
+ const [deletingFileId, setDeletingFileId] = useState(null);
16
17
  const { generateId } = useGenerateLocalId();
17
18
  // Преобразуем value к массиву
18
19
  const files = useMemo(() => toArray(value), [value]);
@@ -94,10 +95,20 @@ inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloa
94
95
  },
95
96
  });
96
97
  const handleDelete = (fileId) => {
97
- if (isMultiple) {
98
- return onChange(files?.filter(({ id }) => id !== fileId));
98
+ const deleteFile = () => {
99
+ if (isMultiple) {
100
+ return onChange(files?.filter(({ id }) => id !== fileId));
101
+ }
102
+ return onChange(null);
103
+ };
104
+ if (!onDeleteFile) {
105
+ return deleteFile();
99
106
  }
100
- return onChange(null);
107
+ setDeletingFileId(fileId);
108
+ onDeleteFile(fileId)
109
+ .then(deleteFile)
110
+ .catch(() => notify.error('Ошибка удаления файла'))
111
+ .finally(() => setDeletingFileId(null));
101
112
  };
102
113
  const getHandlerOnRetry = () => {
103
114
  if (onUploadFile) {
@@ -155,6 +166,7 @@ inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloa
155
166
  selfFiles,
156
167
  setErrorStatusFile,
157
168
  getErrorMessage,
169
+ deletingFileId,
158
170
  },
159
171
  };
160
172
  };
@@ -117,6 +117,13 @@ export type UsePreviewFileUploaderParams = {
117
117
  * - При обновлении информации о файле после успешной загрузки
118
118
  */
119
119
  onChange: (value: UploadFile | null) => void;
120
+ /**
121
+ * Функция, вызываемая при удалении файла.
122
+ * Используется для сбора идентификаторов файлов, помеченных на удаление.
123
+ * Фактическое удаление файлов с сервера должно выполняться только при подтверждении формы,
124
+ * чтобы избежать потери данных при отмене действия или перезагрузке страницы.
125
+ */
126
+ onDeleteFile?: (fileId: FileId) => Promise<void>;
120
127
  /**
121
128
  * Скрытие персональных данных от инструментов мониторинга
122
129
  */
@@ -126,7 +133,7 @@ export type UsePreviewFileUploaderParams = {
126
133
  */
127
134
  PdfViewer?: ((props: PdfViewerProps) => ReactElement) | LazyExoticComponent<(props: PdfViewerProps) => ReactElement>;
128
135
  };
129
- export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restrictions, maxFileSize, inputRef, notify, onChange, onUploadFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }: UsePreviewFileUploaderParams) => {
136
+ export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restrictions, maxFileSize, inputRef, notify, onChange, onUploadFile, onDeleteFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }: UsePreviewFileUploaderParams) => {
130
137
  dropZoneProps: {
131
138
  isVisibleAddFile: boolean;
132
139
  isVisibleFileList: boolean;
@@ -165,7 +172,7 @@ export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restr
165
172
  isError: boolean | undefined;
166
173
  };
167
174
  fileListProps: {
168
- onDelete: () => void;
175
+ onDelete: (fileId: FileId) => void;
169
176
  onRetry: ((fileId: FileId, file: File) => void) | undefined;
170
177
  setErrorStatusFile: (fileId: string, errorMsg: string) => void;
171
178
  selfFiles: Record<string, UploadFile & import("../../types").SpecificSelfFileParams>;
@@ -174,5 +181,6 @@ export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restr
174
181
  files: UploadFile[];
175
182
  isHidePersonalData: boolean | undefined;
176
183
  PdfViewer: LazyExoticComponent<(props: PdfViewerProps) => ReactElement> | ((props: PdfViewerProps) => ReactElement) | undefined;
184
+ deletingFileId: string | null;
177
185
  };
178
186
  };
@@ -1,6 +1,6 @@
1
1
  import { declensionOfWords } from '@astral/utils/declension/declensionOfWords';
2
2
  import { formatFileSizeToView } from '@astral/utils/file/formatFileSizeToView';
3
- import { useMemo, } from 'react';
3
+ import { useMemo, useState, } from 'react';
4
4
  import { useGenerateLocalId } from '../../../useGenerateLocalId';
5
5
  import { useId } from '../../../useId';
6
6
  import { DEFAULT_FILE_STATUS, previewFileUploaderClassnames, } from '../../constants';
@@ -10,8 +10,9 @@ import { rulePipe } from '../../utils/rulePipe';
10
10
  import { toArray } from '../../utils/toArray';
11
11
  import { useDnD } from '../useDnD';
12
12
  import { useUploadFiles } from '../useUploadFiles';
13
- export const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions = [], maxFileSize, inputRef, notify, onChange, onUploadFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }) => {
13
+ export const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions = [], maxFileSize, inputRef, notify, onChange, onUploadFile, onDeleteFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }) => {
14
14
  const inputId = useId();
15
+ const [deletingFileId, setDeletingFileId] = useState(null);
15
16
  const { generateId } = useGenerateLocalId();
16
17
  // Преобразуем value к массиву
17
18
  const files = useMemo(() => toArray(value), [value]);
@@ -80,8 +81,16 @@ export const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions
80
81
  });
81
82
  },
82
83
  });
83
- const handleDelete = () => {
84
- return onChange(null);
84
+ const handleDelete = (fileId) => {
85
+ const deleteFile = () => onChange(null);
86
+ if (!onDeleteFile) {
87
+ return deleteFile();
88
+ }
89
+ setDeletingFileId(fileId);
90
+ onDeleteFile(fileId)
91
+ .then(deleteFile)
92
+ .catch(() => notify.error('Ошибка удаления файла'))
93
+ .finally(() => setDeletingFileId(null));
85
94
  };
86
95
  const getHandlerOnRetry = () => {
87
96
  if (onUploadFile) {
@@ -135,6 +144,7 @@ export const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions
135
144
  files,
136
145
  isHidePersonalData,
137
146
  PdfViewer,
147
+ deletingFileId,
138
148
  },
139
149
  };
140
150
  };
@@ -188,6 +188,13 @@ type BaseFileUploaderProps = {
188
188
  signal: AbortSignal;
189
189
  setProgress: (progressFileId: FileId, progressEvent: ProgressEvent) => void;
190
190
  }) => Promise<UploadedFileData>;
191
+ /**
192
+ * Функция, вызываемая при удалении файла.
193
+ * Используется для сбора идентификаторов файлов, помеченных на удаление.
194
+ * Фактическое удаление файлов с сервера должно выполняться только при подтверждении формы,
195
+ * чтобы избежать потери данных при отмене действия или перезагрузке страницы.
196
+ */
197
+ onDeleteFile?: (fileId: FileId) => Promise<void>;
191
198
  /**
192
199
  * Обработчик просмотра файла
193
200
  * @param fileId - Идентификатор файла
@@ -1,5 +1,5 @@
1
1
  import { type FileUploaderFileProps } from '../../FileUploaderFile';
2
- import { type UploadFile } from '../../types';
2
+ import { type FileId, type UploadFile } from '../../types';
3
3
  export type FileListProps = {
4
4
  isMultiple?: boolean;
5
5
  /**
@@ -7,5 +7,9 @@ export type FileListProps = {
7
7
  */
8
8
  files?: UploadFile[];
9
9
  className?: string;
10
+ /**
11
+ * Идентификатор файла, для которого выполняется удаление
12
+ */
13
+ deletingFileId?: FileId | null;
10
14
  } & Pick<FileUploaderFileProps, 'onDelete' | 'onRetry' | 'onView' | 'generateDownloadLink' | 'selfFiles' | 'setErrorStatusFile'>;
11
- export declare const FileList: ({ isMultiple, files, className, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
15
+ export declare const FileList: ({ isMultiple, files, className, deletingFileId, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
@@ -4,5 +4,5 @@ exports.FileList = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const FileUploaderFile_1 = require("../../FileUploaderFile");
6
6
  const styles_1 = require("./styles");
7
- const FileList = ({ isMultiple, files, className, ...restProps }) => ((0, jsx_runtime_1.jsx)(styles_1.Wrapper, { "$isMultiple": isMultiple, className: className, children: files?.map((file) => ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)(FileUploaderFile_1.FileUploaderFile, { ...file, ...restProps }) }, file.id))) }));
7
+ const FileList = ({ isMultiple, files, className, deletingFileId, ...restProps }) => ((0, jsx_runtime_1.jsx)(styles_1.Wrapper, { "$isMultiple": isMultiple, className: className, children: files?.map((file) => ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)(FileUploaderFile_1.FileUploaderFile, { ...file, ...restProps, isDeletingFile: deletingFileId === file.id }) }, file.id))) }));
8
8
  exports.FileList = FileList;
@@ -12,14 +12,14 @@ const Tooltip_1 = require("../../../Tooltip");
12
12
  const styles_1 = require("./styles");
13
13
  const useLogic_1 = require("./useLogic");
14
14
  const Actions = (props) => {
15
- const { downloadButtonProps, viewButtonProps, isVisibleAbortButton, isVisibleRetryButton, handleAbort, handleDelete, handleRetry, isLoading, isError, fileName, } = (0, useLogic_1.useLogic)(props);
15
+ const { downloadButtonProps, viewButtonProps, isVisibleAbortButton, isVisibleRetryButton, handleAbort, handleDelete, handleRetry, isLoading, isError, isDeletingFile, fileName, } = (0, useLogic_1.useLogic)(props);
16
16
  if (isLoading) {
17
17
  return ((0, jsx_runtime_1.jsx)(styles_1.Wrapper, { children: isVisibleAbortButton && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleAbort, children: (0, jsx_runtime_1.jsx)(CrossOutlineMd_1.CrossOutlineMd, {}) }) })) }));
18
18
  }
19
19
  if (isError) {
20
- return ((0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { children: [isVisibleRetryButton && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleRetry, children: (0, jsx_runtime_1.jsx)(RetryOutlineMd_1.RetryOutlineMd, {}) }) })), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleDelete, children: (0, jsx_runtime_1.jsx)(CrossOutlineMd_1.CrossOutlineMd, {}) }) })] }));
20
+ return ((0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { children: [isVisibleRetryButton && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0443", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleRetry, children: (0, jsx_runtime_1.jsx)(RetryOutlineMd_1.RetryOutlineMd, {}) }) })), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleDelete, loading: isDeletingFile, children: (0, jsx_runtime_1.jsx)(CrossOutlineMd_1.CrossOutlineMd, {}) }) })] }));
21
21
  }
22
22
  const { isShowViewButton, ...restViewButtonProps } = viewButtonProps;
23
- return ((0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { children: [isShowViewButton && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", ...restViewButtonProps, children: (0, jsx_runtime_1.jsx)(EyeOutlineMd_1.EyeOutlineMd, {}) }) })), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { component: "a", variant: "text", download: fileName, ...downloadButtonProps, children: (0, jsx_runtime_1.jsx)(DownloadOutlineMd_1.DownloadOutlineMd, {}) }) }), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleDelete, children: (0, jsx_runtime_1.jsx)(BinOutlineMd_1.BinOutlineMd, {}) }) })] }));
23
+ return ((0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { children: [isShowViewButton && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", ...restViewButtonProps, children: (0, jsx_runtime_1.jsx)(EyeOutlineMd_1.EyeOutlineMd, {}) }) })), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { component: "a", variant: "text", download: fileName, ...downloadButtonProps, children: (0, jsx_runtime_1.jsx)(DownloadOutlineMd_1.DownloadOutlineMd, {}) }) }), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "text", onClick: handleDelete, loading: isDeletingFile, children: (0, jsx_runtime_1.jsx)(BinOutlineMd_1.BinOutlineMd, {}) }) })] }));
24
24
  };
25
25
  exports.Actions = Actions;
@@ -45,9 +45,13 @@ export type UseLogicParams = {
45
45
  * Функция, вызываемая при удалении файла
46
46
  */
47
47
  onDelete: (fileId: FileId) => void;
48
+ /**
49
+ * Флаг загрузки при удалении файла
50
+ */
51
+ isDeletingFile?: boolean;
48
52
  abortController?: AbortController;
49
53
  } & Pick<SelfFileApi, 'selfFiles' | 'setErrorStatusFile'>;
50
- export declare const useLogic: ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, fileName, }: UseLogicParams) => {
54
+ export declare const useLogic: ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, isDeletingFile, fileName, }: UseLogicParams) => {
51
55
  downloadButtonProps: {
52
56
  href: string;
53
57
  };
@@ -69,5 +73,6 @@ export declare const useLogic: ({ fileId, file, fileUrl, isUploadError, generate
69
73
  handleRetry: () => void | undefined;
70
74
  isLoading: boolean | undefined;
71
75
  isError: boolean | undefined;
76
+ isDeletingFile: boolean | undefined;
72
77
  fileName: string;
73
78
  };
@@ -7,7 +7,7 @@ const ConfigProvider_1 = require("../../../../ConfigProvider");
7
7
  const constants_1 = require("../../../constants");
8
8
  const useGenerateLocalFileURL_1 = require("../../../hooks/useGenerateLocalFileURL");
9
9
  const generateAttrLinkNewTab_1 = require("../../../utils/generateAttrLinkNewTab");
10
- const useLogic = ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, fileName, }) => {
10
+ const useLogic = ({ fileId, file, fileUrl, isUploadError, generateDownloadLink, onDelete, onRetry, onView, setErrorStatusFile, selfFiles, isLoading, isError, isDeletingFile, fileName, }) => {
11
11
  const { captureException } = (0, react_1.useContext)(ConfigProvider_1.ConfigContext);
12
12
  const { generateUrl } = (0, useGenerateLocalFileURL_1.useGenerateLocalFileURL)();
13
13
  const { controller } = selfFiles[fileId] || {};
@@ -74,6 +74,7 @@ const useLogic = ({ fileId, file, fileUrl, isUploadError, generateDownloadLink,
74
74
  handleRetry,
75
75
  isLoading,
76
76
  isError,
77
+ isDeletingFile,
77
78
  fileName,
78
79
  };
79
80
  };
@@ -17,5 +17,9 @@ export type FileUploaderFileProps = UploadFile & {
17
17
  * Функция, вызываемая при удалении файла
18
18
  */
19
19
  onDelete: (fileId: FileId) => void;
20
+ /**
21
+ * Флаг загрузки при удалении файла
22
+ */
23
+ isDeletingFile?: boolean;
20
24
  } & Pick<ActionsProps, 'selfFiles' | 'setErrorStatusFile'>;
21
25
  export declare const FileUploaderFile: (props: FileUploaderFileProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,10 @@
1
1
  import { type PreviewFileUploaderFileProps } from '../../PreviewFileUploaderFile';
2
- import { type UploadFile } from '../../types';
2
+ import type { FileId, UploadFile } from '../../types';
3
3
  export type FileListProps = {
4
4
  files: UploadFile[];
5
+ /**
6
+ * Идентификатор файла, для которого выполняется удаление
7
+ */
8
+ deletingFileId?: FileId | null;
5
9
  } & Pick<PreviewFileUploaderFileProps, 'onDelete' | 'onRetry' | 'onView' | 'generateDownloadLink' | 'selfFiles' | 'setErrorStatusFile'>;
6
- export declare const FileList: ({ files, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
10
+ export declare const FileList: ({ files, deletingFileId, ...restProps }: FileListProps) => import("react/jsx-runtime").JSX.Element;
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FileList = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const PreviewFileUploaderFile_1 = require("../../PreviewFileUploaderFile");
6
- const FileList = ({ files, ...restProps }) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: files?.map((file) => ((0, jsx_runtime_1.jsx)(PreviewFileUploaderFile_1.PreviewFileUploaderFile, { ...file, ...restProps }, file.id))) }));
6
+ const FileList = ({ files, deletingFileId, ...restProps }) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: files?.map((file) => ((0, jsx_runtime_1.jsx)(PreviewFileUploaderFile_1.PreviewFileUploaderFile, { ...file, ...restProps, isDeletingFile: deletingFileId === file.id }, file.id))) }));
7
7
  exports.FileList = FileList;
@@ -42,6 +42,10 @@ export type FilePreviewProps = {
42
42
  * Скрытие персональных данных от инструментов мониторинга
43
43
  */
44
44
  isHidePersonalData?: boolean;
45
+ /**
46
+ * Флаг загрузки при удалении файла
47
+ */
48
+ isDeletingFile?: boolean;
45
49
  /**
46
50
  * Компонент для отображения превью pdf-файлов
47
51
  */
@@ -16,8 +16,8 @@ const styles_1 = require("./styles");
16
16
  const useLogic_1 = require("./useLogic");
17
17
  const FilePreview = (props) => {
18
18
  const { viewButtonProps, downloadButtonProps, deleteButtonProps, isImageFile, isPdfFile, isOtherFile, } = (0, useLogic_1.useLogic)(props);
19
- const { file, fileName, fileSize, fileUrl, generateDownloadLink, isHidePersonalData, PdfViewer, } = props;
19
+ const { file, fileName, fileSize, fileUrl, generateDownloadLink, isHidePersonalData, PdfViewer, isDeletingFile, } = props;
20
20
  const { isMobile } = (0, useViewportType_1.useViewportType)();
21
- return ((0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { children: [(0, jsx_runtime_1.jsx)(Preview_1.Preview, { isImageFile: isImageFile, isPdfFile: isPdfFile, file: file, fileUrl: fileUrl, generateDownloadLink: generateDownloadLink, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer }), (0, jsx_runtime_1.jsxs)(styles_1.Details, { className: constants_1.previewFileUploaderClassnames.details, "$isOtherFile": isOtherFile, children: [isOtherFile && (0, jsx_runtime_1.jsx)(Typography_1.Typography, { variant: "h6", children: "\u0424\u0430\u0439\u043B \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D" }), (0, jsx_runtime_1.jsx)(styles_1.StyledFileInfo, { "$isOtherFile": isOtherFile, fileName: fileName, fileSize: fileSize }), (0, jsx_runtime_1.jsx)(styles_1.Actions, { children: isMobile && isOtherFile ? ((0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "light", color: "grey", ...deleteButtonProps, children: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C" })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!isOtherFile && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", disableInteractive: true, children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "light", color: "grey", ...viewButtonProps, children: (0, jsx_runtime_1.jsx)(EyeOutlineMd_1.EyeOutlineMd, {}) }) })), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", disableInteractive: true, children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { component: "a", variant: "light", color: "grey", download: fileName, ...downloadButtonProps, children: (0, jsx_runtime_1.jsx)(DownloadOutlineMd_1.DownloadOutlineMd, {}) }) }), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", disableInteractive: true, children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "light", color: "grey", ...deleteButtonProps, children: (0, jsx_runtime_1.jsx)(BinOutlineMd_1.BinOutlineMd, {}) }) })] })) })] })] }));
21
+ return ((0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { children: [(0, jsx_runtime_1.jsx)(Preview_1.Preview, { isImageFile: isImageFile, isPdfFile: isPdfFile, file: file, fileUrl: fileUrl, generateDownloadLink: generateDownloadLink, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer }), (0, jsx_runtime_1.jsxs)(styles_1.Details, { className: constants_1.previewFileUploaderClassnames.details, "$isOtherFile": isOtherFile, children: [isOtherFile && (0, jsx_runtime_1.jsx)(Typography_1.Typography, { variant: "h6", children: "\u0424\u0430\u0439\u043B \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D" }), (0, jsx_runtime_1.jsx)(styles_1.StyledFileInfo, { "$isOtherFile": isOtherFile, fileName: fileName, fileSize: fileSize }), (0, jsx_runtime_1.jsx)(styles_1.Actions, { children: isMobile && isOtherFile ? ((0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "light", color: "grey", loading: isDeletingFile, ...deleteButtonProps, children: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C" })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!isOtherFile && ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u041F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C", disableInteractive: true, children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "light", color: "grey", ...viewButtonProps, children: (0, jsx_runtime_1.jsx)(EyeOutlineMd_1.EyeOutlineMd, {}) }) })), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0421\u043A\u0430\u0447\u0430\u0442\u044C", disableInteractive: true, children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { component: "a", variant: "light", color: "grey", download: fileName, ...downloadButtonProps, children: (0, jsx_runtime_1.jsx)(DownloadOutlineMd_1.DownloadOutlineMd, {}) }) }), (0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, { title: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C", disableInteractive: true, children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, { variant: "light", color: "grey", loading: isDeletingFile, ...deleteButtonProps, children: (0, jsx_runtime_1.jsx)(BinOutlineMd_1.BinOutlineMd, {}) }) })] })) })] })] }));
22
22
  };
23
23
  exports.FilePreview = FilePreview;
@@ -23,6 +23,10 @@ export type PreviewFileUploaderFileProps = UploadFile & {
23
23
  * Скрытие персональных данных от инструментов мониторинга
24
24
  */
25
25
  isHidePersonalData?: boolean;
26
+ /**
27
+ * Флаг загрузки при удалении файла
28
+ */
29
+ isDeletingFile?: boolean;
26
30
  /**
27
31
  * Компонент для отображения превью pdf-файлов
28
32
  */
@@ -8,9 +8,9 @@ const FileLoading_1 = require("./FileLoading");
8
8
  const FilePreview_1 = require("./FilePreview");
9
9
  const styles_1 = require("./styles");
10
10
  const PreviewFileUploaderFile = (props) => {
11
- const { id, name, type, file, url, size, status, generateDownloadLink, onRetry, onDelete, onView, selfFiles, setErrorStatusFile, isHidePersonalData, PdfViewer, } = props;
11
+ const { id, name, type, file, url, size, status, generateDownloadLink, onRetry, onDelete, onView, selfFiles, setErrorStatusFile, isHidePersonalData, PdfViewer, isDeletingFile, } = props;
12
12
  const { isLoading, isUploadError, isRestrictionError, errorMsg, progress } = status || {};
13
13
  const isError = isUploadError || isRestrictionError;
14
- return ((0, jsx_runtime_1.jsx)(Fade_1.Fade, { in: true, children: (0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { "$isLoading": isLoading, "$isError": isError, children: [!isLoading && !isError && ((0, jsx_runtime_1.jsx)(FilePreview_1.FilePreview, { fileId: id, fileName: name, fileType: type, file: file, fileUrl: url, fileSize: size, generateDownloadLink: generateDownloadLink, onView: onView, onDelete: onDelete, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer })), isLoading && ((0, jsx_runtime_1.jsx)(FileLoading_1.FileLoading, { selfFiles: selfFiles, setErrorStatusFile: setErrorStatusFile, fileId: id, fileName: name, fileSize: size, progress: progress })), isError && ((0, jsx_runtime_1.jsx)(FileError_1.FileError, { fileId: id, fileName: name, file: file, fileSize: size, errorMsg: errorMsg, isUploadError: isUploadError, onRetry: onRetry, onDelete: onDelete }))] }) }));
14
+ return ((0, jsx_runtime_1.jsx)(Fade_1.Fade, { in: true, children: (0, jsx_runtime_1.jsxs)(styles_1.Wrapper, { "$isLoading": isLoading, "$isError": isError, children: [!isLoading && !isError && ((0, jsx_runtime_1.jsx)(FilePreview_1.FilePreview, { fileId: id, fileName: name, fileType: type, file: file, fileUrl: url, fileSize: size, generateDownloadLink: generateDownloadLink, onView: onView, onDelete: onDelete, isHidePersonalData: isHidePersonalData, PdfViewer: PdfViewer, isDeletingFile: isDeletingFile })), isLoading && ((0, jsx_runtime_1.jsx)(FileLoading_1.FileLoading, { selfFiles: selfFiles, setErrorStatusFile: setErrorStatusFile, fileId: id, fileName: name, fileSize: size, progress: progress })), isError && ((0, jsx_runtime_1.jsx)(FileError_1.FileError, { fileId: id, fileName: name, file: file, fileSize: size, errorMsg: errorMsg, isUploadError: isUploadError, onRetry: onRetry, onDelete: onDelete }))] }) }));
15
15
  };
16
16
  exports.PreviewFileUploaderFile = PreviewFileUploaderFile;
@@ -1,7 +1,7 @@
1
1
  import { type ChangeEvent } from 'react';
2
2
  import type { FileId, FileUploaderProps, UploadFile } from '../../types';
3
3
  export type UseFileUploaderParams = FileUploaderProps;
4
- export declare const useFileUploader: ({ value, isDisabled, isMultiple, accept, restrictions, maxFileSize, maxFileCount, inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }: UseFileUploaderParams) => {
4
+ export declare const useFileUploader: ({ value, isDisabled, isMultiple, accept, restrictions, maxFileSize, maxFileCount, inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }: UseFileUploaderParams) => {
5
5
  dropZoneProps: {
6
6
  isLimitMaxFileCount: boolean;
7
7
  maxFileCount: number;
@@ -53,5 +53,6 @@ export declare const useFileUploader: ({ value, isDisabled, isMultiple, accept,
53
53
  selfFiles: Record<string, UploadFile & import("../../types").SpecificSelfFileParams>;
54
54
  setErrorStatusFile: (fileId: string, errorMsg: string) => void;
55
55
  getErrorMessage: ((fileId: string, error: Error) => string) | undefined;
56
+ deletingFileId: string | null;
56
57
  };
57
58
  };
@@ -14,8 +14,9 @@ const toArray_1 = require("../../utils/toArray");
14
14
  const useDnD_1 = require("../useDnD");
15
15
  const useUploadFiles_1 = require("../useUploadFiles");
16
16
  const useFileUploader = ({ value, isDisabled, isMultiple, accept, restrictions = [], maxFileSize, maxFileCount = 1, // для случая, когда isMultiple=false
17
- inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }) => {
17
+ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, generateDownloadLink, placeholder, helperText, label, className, getErrorMessage, }) => {
18
18
  const inputId = (0, useId_1.useId)();
19
+ const [deletingFileId, setDeletingFileId] = (0, react_1.useState)(null);
19
20
  const { generateId } = (0, useGenerateLocalId_1.useGenerateLocalId)();
20
21
  // Преобразуем value к массиву
21
22
  const files = (0, react_1.useMemo)(() => (0, toArray_1.toArray)(value), [value]);
@@ -97,10 +98,20 @@ inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloa
97
98
  },
98
99
  });
99
100
  const handleDelete = (fileId) => {
100
- if (isMultiple) {
101
- return onChange(files?.filter(({ id }) => id !== fileId));
101
+ const deleteFile = () => {
102
+ if (isMultiple) {
103
+ return onChange(files?.filter(({ id }) => id !== fileId));
104
+ }
105
+ return onChange(null);
106
+ };
107
+ if (!onDeleteFile) {
108
+ return deleteFile();
102
109
  }
103
- return onChange(null);
110
+ setDeletingFileId(fileId);
111
+ onDeleteFile(fileId)
112
+ .then(deleteFile)
113
+ .catch(() => notify.error('Ошибка удаления файла'))
114
+ .finally(() => setDeletingFileId(null));
104
115
  };
105
116
  const getHandlerOnRetry = () => {
106
117
  if (onUploadFile) {
@@ -158,6 +169,7 @@ inputRef, notify, onChange, onUploadFile, name, isError, onView, generateDownloa
158
169
  selfFiles,
159
170
  setErrorStatusFile,
160
171
  getErrorMessage,
172
+ deletingFileId,
161
173
  },
162
174
  };
163
175
  };
@@ -117,6 +117,13 @@ export type UsePreviewFileUploaderParams = {
117
117
  * - При обновлении информации о файле после успешной загрузки
118
118
  */
119
119
  onChange: (value: UploadFile | null) => void;
120
+ /**
121
+ * Функция, вызываемая при удалении файла.
122
+ * Используется для сбора идентификаторов файлов, помеченных на удаление.
123
+ * Фактическое удаление файлов с сервера должно выполняться только при подтверждении формы,
124
+ * чтобы избежать потери данных при отмене действия или перезагрузке страницы.
125
+ */
126
+ onDeleteFile?: (fileId: FileId) => Promise<void>;
120
127
  /**
121
128
  * Скрытие персональных данных от инструментов мониторинга
122
129
  */
@@ -126,7 +133,7 @@ export type UsePreviewFileUploaderParams = {
126
133
  */
127
134
  PdfViewer?: ((props: PdfViewerProps) => ReactElement) | LazyExoticComponent<(props: PdfViewerProps) => ReactElement>;
128
135
  };
129
- export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restrictions, maxFileSize, inputRef, notify, onChange, onUploadFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }: UsePreviewFileUploaderParams) => {
136
+ export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restrictions, maxFileSize, inputRef, notify, onChange, onUploadFile, onDeleteFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }: UsePreviewFileUploaderParams) => {
130
137
  dropZoneProps: {
131
138
  isVisibleAddFile: boolean;
132
139
  isVisibleFileList: boolean;
@@ -165,7 +172,7 @@ export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restr
165
172
  isError: boolean | undefined;
166
173
  };
167
174
  fileListProps: {
168
- onDelete: () => void;
175
+ onDelete: (fileId: FileId) => void;
169
176
  onRetry: ((fileId: FileId, file: File) => void) | undefined;
170
177
  setErrorStatusFile: (fileId: string, errorMsg: string) => void;
171
178
  selfFiles: Record<string, UploadFile & import("../../types").SpecificSelfFileParams>;
@@ -174,5 +181,6 @@ export declare const usePreviewFileUploader: ({ value, isDisabled, accept, restr
174
181
  files: UploadFile[];
175
182
  isHidePersonalData: boolean | undefined;
176
183
  PdfViewer: LazyExoticComponent<(props: PdfViewerProps) => ReactElement> | ((props: PdfViewerProps) => ReactElement) | undefined;
184
+ deletingFileId: string | null;
177
185
  };
178
186
  };
@@ -13,8 +13,9 @@ const rulePipe_1 = require("../../utils/rulePipe");
13
13
  const toArray_1 = require("../../utils/toArray");
14
14
  const useDnD_1 = require("../useDnD");
15
15
  const useUploadFiles_1 = require("../useUploadFiles");
16
- const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions = [], maxFileSize, inputRef, notify, onChange, onUploadFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }) => {
16
+ const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions = [], maxFileSize, inputRef, notify, onChange, onUploadFile, onDeleteFile, label, isError, generateDownloadLink, onView, name, helperText, className, placeholder, placeholderImgSrc, isHidePersonalData, PdfViewer, }) => {
17
17
  const inputId = (0, useId_1.useId)();
18
+ const [deletingFileId, setDeletingFileId] = (0, react_1.useState)(null);
18
19
  const { generateId } = (0, useGenerateLocalId_1.useGenerateLocalId)();
19
20
  // Преобразуем value к массиву
20
21
  const files = (0, react_1.useMemo)(() => (0, toArray_1.toArray)(value), [value]);
@@ -83,8 +84,16 @@ const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions = [],
83
84
  });
84
85
  },
85
86
  });
86
- const handleDelete = () => {
87
- return onChange(null);
87
+ const handleDelete = (fileId) => {
88
+ const deleteFile = () => onChange(null);
89
+ if (!onDeleteFile) {
90
+ return deleteFile();
91
+ }
92
+ setDeletingFileId(fileId);
93
+ onDeleteFile(fileId)
94
+ .then(deleteFile)
95
+ .catch(() => notify.error('Ошибка удаления файла'))
96
+ .finally(() => setDeletingFileId(null));
88
97
  };
89
98
  const getHandlerOnRetry = () => {
90
99
  if (onUploadFile) {
@@ -138,6 +147,7 @@ const usePreviewFileUploader = ({ value, isDisabled, accept, restrictions = [],
138
147
  files,
139
148
  isHidePersonalData,
140
149
  PdfViewer,
150
+ deletingFileId,
141
151
  },
142
152
  };
143
153
  };
@@ -188,6 +188,13 @@ type BaseFileUploaderProps = {
188
188
  signal: AbortSignal;
189
189
  setProgress: (progressFileId: FileId, progressEvent: ProgressEvent) => void;
190
190
  }) => Promise<UploadedFileData>;
191
+ /**
192
+ * Функция, вызываемая при удалении файла.
193
+ * Используется для сбора идентификаторов файлов, помеченных на удаление.
194
+ * Фактическое удаление файлов с сервера должно выполняться только при подтверждении формы,
195
+ * чтобы избежать потери данных при отмене действия или перезагрузке страницы.
196
+ */
197
+ onDeleteFile?: (fileId: FileId) => Promise<void>;
191
198
  /**
192
199
  * Обработчик просмотра файла
193
200
  * @param fileId - Идентификатор файла
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astral/ui",
3
- "version": "4.18.6",
3
+ "version": "4.19.0",
4
4
  "browser": "./index.js",
5
5
  "main": "./node/index.js",
6
6
  "dependencies": {
@@ -1,2 +0,0 @@
1
- import { type AxiosRequestConfig } from 'axios';
2
- export declare const fakeFileUploadQuery: (formData: FormData, options?: AxiosRequestConfig) => Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -1,37 +0,0 @@
1
- import axios from 'axios';
2
- import AxiosMockAdapter from 'axios-mock-adapter';
3
- let globalId = 0;
4
- const generateId = () => {
5
- globalId += 1;
6
- return globalId;
7
- };
8
- const progressSteps = Array.from({ length: 10 }, (_, i) => (i + 1) / 10);
9
- const getRandomDelay = () => Math.random() * 300 + 200; // 200-500ms
10
- const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
11
- const mock = new AxiosMockAdapter(axios);
12
- mock.onPost('/api/upload').reply(async (config) => {
13
- const response = {
14
- id: `upl-${generateId()}`,
15
- };
16
- const formData = config.data;
17
- const file = formData.get('file');
18
- const total = file.size;
19
- for (const progress of progressSteps) {
20
- await sleep(getRandomDelay());
21
- if (config.onUploadProgress) {
22
- config.onUploadProgress({
23
- loaded: Math.floor(total * progress),
24
- total,
25
- lengthComputable: true,
26
- bytes: Math.floor(total * progress),
27
- });
28
- }
29
- }
30
- return [200, response];
31
- });
32
- export const fakeFileUploadQuery = (formData, options) => axios.post('/api/upload', formData, {
33
- headers: {
34
- 'Content-Type': 'multipart/form-data',
35
- },
36
- ...(options || {}),
37
- });
@@ -1,2 +0,0 @@
1
- import { type AxiosRequestConfig } from 'axios';
2
- export declare const fakePreviewFileUploadQuery: (formData: FormData, options?: AxiosRequestConfig) => Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -1,37 +0,0 @@
1
- import axios from 'axios';
2
- import AxiosMockAdapter from 'axios-mock-adapter';
3
- let globalId = 0;
4
- const generateId = () => {
5
- globalId += 1;
6
- return globalId;
7
- };
8
- const progressSteps = Array.from({ length: 10 }, (_, i) => (i + 1) / 10);
9
- const getRandomDelay = () => Math.random() * 300 + 200; // 200-500ms
10
- const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
11
- const mock = new AxiosMockAdapter(axios);
12
- mock.onPost('/api/upload').reply(async (config) => {
13
- const response = {
14
- id: `upl-${generateId()}`,
15
- };
16
- const formData = config.data;
17
- const file = formData.get('file');
18
- const total = file.size;
19
- for (const progress of progressSteps) {
20
- await sleep(getRandomDelay());
21
- if (config.onUploadProgress) {
22
- config.onUploadProgress({
23
- loaded: Math.floor(total * progress),
24
- total,
25
- lengthComputable: true,
26
- bytes: Math.floor(total * progress),
27
- });
28
- }
29
- }
30
- return [200, response];
31
- });
32
- export const fakePreviewFileUploadQuery = (formData, options) => axios.post('/api/upload', formData, {
33
- headers: {
34
- 'Content-Type': 'multipart/form-data',
35
- },
36
- ...(options || {}),
37
- });
@@ -1,2 +0,0 @@
1
- import { type AxiosRequestConfig } from 'axios';
2
- export declare const fakeFileUploadQuery: (formData: FormData, options?: AxiosRequestConfig) => Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -1,44 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.fakeFileUploadQuery = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
9
- let globalId = 0;
10
- const generateId = () => {
11
- globalId += 1;
12
- return globalId;
13
- };
14
- const progressSteps = Array.from({ length: 10 }, (_, i) => (i + 1) / 10);
15
- const getRandomDelay = () => Math.random() * 300 + 200; // 200-500ms
16
- const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
17
- const mock = new axios_mock_adapter_1.default(axios_1.default);
18
- mock.onPost('/api/upload').reply(async (config) => {
19
- const response = {
20
- id: `upl-${generateId()}`,
21
- };
22
- const formData = config.data;
23
- const file = formData.get('file');
24
- const total = file.size;
25
- for (const progress of progressSteps) {
26
- await sleep(getRandomDelay());
27
- if (config.onUploadProgress) {
28
- config.onUploadProgress({
29
- loaded: Math.floor(total * progress),
30
- total,
31
- lengthComputable: true,
32
- bytes: Math.floor(total * progress),
33
- });
34
- }
35
- }
36
- return [200, response];
37
- });
38
- const fakeFileUploadQuery = (formData, options) => axios_1.default.post('/api/upload', formData, {
39
- headers: {
40
- 'Content-Type': 'multipart/form-data',
41
- },
42
- ...(options || {}),
43
- });
44
- exports.fakeFileUploadQuery = fakeFileUploadQuery;
@@ -1,2 +0,0 @@
1
- import { type AxiosRequestConfig } from 'axios';
2
- export declare const fakePreviewFileUploadQuery: (formData: FormData, options?: AxiosRequestConfig) => Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -1,44 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.fakePreviewFileUploadQuery = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
9
- let globalId = 0;
10
- const generateId = () => {
11
- globalId += 1;
12
- return globalId;
13
- };
14
- const progressSteps = Array.from({ length: 10 }, (_, i) => (i + 1) / 10);
15
- const getRandomDelay = () => Math.random() * 300 + 200; // 200-500ms
16
- const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
17
- const mock = new axios_mock_adapter_1.default(axios_1.default);
18
- mock.onPost('/api/upload').reply(async (config) => {
19
- const response = {
20
- id: `upl-${generateId()}`,
21
- };
22
- const formData = config.data;
23
- const file = formData.get('file');
24
- const total = file.size;
25
- for (const progress of progressSteps) {
26
- await sleep(getRandomDelay());
27
- if (config.onUploadProgress) {
28
- config.onUploadProgress({
29
- loaded: Math.floor(total * progress),
30
- total,
31
- lengthComputable: true,
32
- bytes: Math.floor(total * progress),
33
- });
34
- }
35
- }
36
- return [200, response];
37
- });
38
- const fakePreviewFileUploadQuery = (formData, options) => axios_1.default.post('/api/upload', formData, {
39
- headers: {
40
- 'Content-Type': 'multipart/form-data',
41
- },
42
- ...(options || {}),
43
- });
44
- exports.fakePreviewFileUploadQuery = fakePreviewFileUploadQuery;