@astral/ui 4.77.0 → 4.78.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.
- package/components/Avatar/styles.js +5 -1
- package/components/fileUploading/FileUploader/public.d.ts +1 -1
- package/components/fileUploading/hooks/useFileUploader/useFileUploader.js +9 -6
- package/components/fileUploading/hooks/useSyncFiles/useSyncFiles.d.ts +9 -1
- package/components/fileUploading/hooks/useSyncFiles/useSyncFiles.js +3 -3
- package/components/fileUploading/hooks/useUploadFiles/useUploadFiles.d.ts +5 -2
- package/components/fileUploading/hooks/useUploadFiles/useUploadFiles.js +13 -3
- package/components/fileUploading/types.d.ts +10 -2
- package/hook-form/FormFileUploader/FormFileUploader.d.ts +5 -2
- package/hook-form/FormFileUploader/FormFileUploader.js +8 -3
- package/hook-form/FormPageLayoutBase/styles.js +6 -2
- package/hook-form/FormPreviewFileUploader/FormPreviewFileUploader.d.ts +10 -3
- package/hook-form/FormPreviewFileUploader/FormPreviewFileUploader.js +7 -3
- package/node/components/Avatar/styles.js +27 -3
- package/node/components/fileUploading/FileUploader/public.d.ts +1 -1
- package/node/components/fileUploading/hooks/useFileUploader/useFileUploader.js +9 -6
- package/node/components/fileUploading/hooks/useSyncFiles/useSyncFiles.d.ts +9 -1
- package/node/components/fileUploading/hooks/useSyncFiles/useSyncFiles.js +3 -3
- package/node/components/fileUploading/hooks/useUploadFiles/useUploadFiles.d.ts +5 -2
- package/node/components/fileUploading/hooks/useUploadFiles/useUploadFiles.js +12 -2
- package/node/components/fileUploading/types.d.ts +10 -2
- package/node/hook-form/FormFileUploader/FormFileUploader.d.ts +5 -2
- package/node/hook-form/FormFileUploader/FormFileUploader.js +8 -3
- package/node/hook-form/FormPageLayoutBase/styles.js +6 -2
- package/node/hook-form/FormPreviewFileUploader/FormPreviewFileUploader.d.ts +10 -3
- package/node/hook-form/FormPreviewFileUploader/FormPreviewFileUploader.js +7 -3
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import Avatar from '@mui/material/Avatar';
|
|
1
|
+
import Avatar, { avatarClasses } from '@mui/material/Avatar';
|
|
2
2
|
import { styled } from '../styled/styled';
|
|
3
3
|
const getFont = (size) => {
|
|
4
4
|
if (size === 'sm') {
|
|
@@ -14,4 +14,8 @@ export const StyledAvatar = styled(Avatar, {
|
|
|
14
14
|
}) `
|
|
15
15
|
font-size: ${({ theme, $size }) => theme.typography[getFont($size)].fontSize};
|
|
16
16
|
font-weight: ${({ theme, $size }) => theme.typography[getFont($size)].fontWeight};
|
|
17
|
+
|
|
18
|
+
& .${avatarClasses.img} {
|
|
19
|
+
background-color: ${({ theme }) => theme.palette.grey[200]};
|
|
20
|
+
}
|
|
17
21
|
`;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { fileUploaderClassnames } from '../constants';
|
|
2
|
-
export type { FileId, FileUploaderNotify, FileUploaderProps, RestrictionFn, RestrictionFnResult, UploadedFileData, UploadFile, } from '../types';
|
|
2
|
+
export type { FileId, FileUploaderMetaInfo, FileUploaderNotify, FileUploaderProps, RestrictionFn, RestrictionFnResult, UploadedFileData, UploadFile, } from '../types';
|
|
3
3
|
export { FileUploader } from './FileUploader';
|
|
@@ -57,7 +57,7 @@ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, g
|
|
|
57
57
|
onUploadFile,
|
|
58
58
|
getErrorMessage,
|
|
59
59
|
});
|
|
60
|
-
const handleChange = (event) => {
|
|
60
|
+
const handleChange = (event, metaInfo) => {
|
|
61
61
|
// Преобразуем к массиву и удаляем дубликаты
|
|
62
62
|
const droppedFiles = Array.from(event.target.files || []).filter((droppedFile) => !files.find((file) => compareFile(droppedFile, file)));
|
|
63
63
|
const addedFiles = droppedFiles
|
|
@@ -78,22 +78,25 @@ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, g
|
|
|
78
78
|
];
|
|
79
79
|
}, []);
|
|
80
80
|
if (isMultiple) {
|
|
81
|
-
onChange([...files, ...addedFiles]);
|
|
81
|
+
onChange([...files, ...addedFiles], metaInfo);
|
|
82
82
|
}
|
|
83
83
|
else if (addedFiles.length) {
|
|
84
|
-
onChange(addedFiles[0]);
|
|
84
|
+
onChange(addedFiles[0], metaInfo);
|
|
85
85
|
}
|
|
86
86
|
if (addedFiles.length < droppedFiles.length) {
|
|
87
87
|
notifyWarning(addedFiles.length, droppedFiles.length);
|
|
88
88
|
}
|
|
89
|
-
enqueueFiles(addedFiles);
|
|
89
|
+
enqueueFiles(addedFiles, metaInfo);
|
|
90
|
+
};
|
|
91
|
+
const handleFileInputChange = (event) => {
|
|
92
|
+
handleChange(event, { inputSourceType: 'fileInput' });
|
|
90
93
|
};
|
|
91
94
|
const { isDragActive, ...dropZoneActions } = useDnD({
|
|
92
95
|
isDisabled,
|
|
93
96
|
onChange: (droppedFiles) => {
|
|
94
97
|
handleChange({
|
|
95
98
|
target: { files: droppedFiles },
|
|
96
|
-
});
|
|
99
|
+
}, { inputSourceType: 'dragAndDrop' });
|
|
97
100
|
},
|
|
98
101
|
});
|
|
99
102
|
const handleDelete = (fileId) => {
|
|
@@ -142,7 +145,7 @@ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, g
|
|
|
142
145
|
accept: accept.join(),
|
|
143
146
|
ref: inputRef,
|
|
144
147
|
value: '',
|
|
145
|
-
onChange:
|
|
148
|
+
onChange: handleFileInputChange,
|
|
146
149
|
name,
|
|
147
150
|
isMultiple,
|
|
148
151
|
isDisabled,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
1
2
|
import type { FileId, SpecificSelfFileParams, UploadFile } from '../../types';
|
|
3
|
+
type ChangeMetaInfo = {
|
|
4
|
+
inputSourceType?: 'fileInput' | 'dragAndDrop';
|
|
5
|
+
};
|
|
2
6
|
type UseSyncFilesParams<TMultiple extends boolean = false> = {
|
|
3
7
|
/**
|
|
4
8
|
* Список файлов, которые приходят как value в компонент
|
|
@@ -15,7 +19,11 @@ type UseSyncFilesParams<TMultiple extends boolean = false> = {
|
|
|
15
19
|
/**
|
|
16
20
|
* Функция, вызываемая при изменении списка файлов
|
|
17
21
|
*/
|
|
18
|
-
onChange: TMultiple extends true ? (value: UploadFile[]) => void : (value: UploadFile | null) => void;
|
|
22
|
+
onChange: TMultiple extends true ? (value: UploadFile[], metaInfo?: ChangeMetaInfo) => void : (value: UploadFile | null, metaInfo?: ChangeMetaInfo) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Ref с metaInfo последнего пользовательского действия
|
|
25
|
+
*/
|
|
26
|
+
metaInfoRef: RefObject<ChangeMetaInfo | undefined>;
|
|
19
27
|
};
|
|
20
28
|
export declare const useSyncFiles: <TMultiple extends boolean>(props: UseSyncFilesParams<TMultiple>) => void;
|
|
21
29
|
export {};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { isEmpty } from '../../../utils/isEmpty';
|
|
3
3
|
export const useSyncFiles = (props) => {
|
|
4
|
-
const { isMultiple, files, selfFiles } = props;
|
|
4
|
+
const { isMultiple, files, selfFiles, metaInfoRef } = props;
|
|
5
5
|
const handleSingleFileChange = (updatedFiles) => {
|
|
6
6
|
const { onChange } = props;
|
|
7
|
-
onChange(updatedFiles.length > 0 ? updatedFiles[0] : null);
|
|
7
|
+
onChange(updatedFiles.length > 0 ? updatedFiles[0] : null, metaInfoRef.current);
|
|
8
8
|
};
|
|
9
9
|
const handleMultipleFileChange = (updatedFiles) => {
|
|
10
10
|
const { onChange } = props;
|
|
11
|
-
onChange(updatedFiles);
|
|
11
|
+
onChange(updatedFiles, metaInfoRef.current);
|
|
12
12
|
};
|
|
13
13
|
useEffect(() => {
|
|
14
14
|
if (isEmpty(selfFiles)) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { FileId, UploadedFileData, UploadFile } from '../../types';
|
|
2
|
+
type ChangeMetaInfo = {
|
|
3
|
+
inputSourceType?: 'fileInput' | 'dragAndDrop';
|
|
4
|
+
};
|
|
2
5
|
type UseUploadFilesParams = {
|
|
3
6
|
/**
|
|
4
7
|
* Список файлов, которые приходят как value в компонент
|
|
@@ -11,7 +14,7 @@ type UseUploadFilesParams = {
|
|
|
11
14
|
/**
|
|
12
15
|
* Функция, вызываемая при изменении списка файлов
|
|
13
16
|
*/
|
|
14
|
-
onChange: ((value: UploadFile[]) => void) | ((value: UploadFile | null) => void);
|
|
17
|
+
onChange: ((value: UploadFile[], metaInfo?: ChangeMetaInfo) => void) | ((value: UploadFile | null, metaInfo?: ChangeMetaInfo) => void);
|
|
15
18
|
/**
|
|
16
19
|
* Функция загрузки файлов на сервер
|
|
17
20
|
* @param fileId - Идентификатор файла
|
|
@@ -31,7 +34,7 @@ type UseUploadFilesParams = {
|
|
|
31
34
|
getErrorMessage?: (fileId: FileId, error: Error) => string;
|
|
32
35
|
};
|
|
33
36
|
export declare const useUploadFiles: ({ isMultiple, files: externalFiles, onChange, onUploadFile, getErrorMessage, }: UseUploadFilesParams) => {
|
|
34
|
-
enqueueFiles: (files: UploadFile[]) => void;
|
|
37
|
+
enqueueFiles: (files: UploadFile[], metaInfo?: ChangeMetaInfo) => void;
|
|
35
38
|
refetchFile: (fileToSend: UploadFile) => void;
|
|
36
39
|
selfFiles: Record<string, UploadFile & import("../../types").SpecificSelfFileParams>;
|
|
37
40
|
setErrorStatusFile: (fileId: string, errorMsg: string) => void;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { ABORT_ERROR_CODE, UPLOAD_ERROR_MESSAGE } from '../../constants';
|
|
3
3
|
import { useSelfFiles } from '../useSelfFiles';
|
|
4
4
|
import { useSyncFiles } from '../useSyncFiles';
|
|
5
5
|
export const useUploadFiles = ({ isMultiple, files: externalFiles, onChange, onUploadFile, getErrorMessage, }) => {
|
|
6
6
|
const [fileQueue, setFileQueue] = useState([]);
|
|
7
|
+
// Хранит metaInfo последнего пользовательского действия,
|
|
8
|
+
// чтобы передавать его в onChange при синхронизации статусов загрузки
|
|
9
|
+
const metaInfoRef = useRef(undefined);
|
|
7
10
|
const { selfFiles, setLoadingStatusFile, setSuccessStatusFile, setErrorStatusFile, updateFileInfo, } = useSelfFiles();
|
|
8
11
|
// При изменении статусов обновляем внешнее состояние
|
|
9
|
-
useSyncFiles({
|
|
10
|
-
|
|
12
|
+
useSyncFiles({
|
|
13
|
+
isMultiple,
|
|
14
|
+
files: externalFiles,
|
|
15
|
+
selfFiles,
|
|
16
|
+
onChange,
|
|
17
|
+
metaInfoRef,
|
|
18
|
+
});
|
|
19
|
+
const enqueueFiles = (files, metaInfo) => {
|
|
20
|
+
metaInfoRef.current = metaInfo;
|
|
11
21
|
const acceptedFiles = files.filter(({ status }) => !status?.isRestrictionError);
|
|
12
22
|
setFileQueue(acceptedFiles);
|
|
13
23
|
};
|
|
@@ -6,6 +6,12 @@ export type RestrictionFnResult = {
|
|
|
6
6
|
};
|
|
7
7
|
export type RestrictionFn = (value: File) => RestrictionFnResult | undefined;
|
|
8
8
|
export type FileId = string;
|
|
9
|
+
export type FileUploaderMetaInfo = {
|
|
10
|
+
/**
|
|
11
|
+
* Способ загрузки файла (fileInput или dragAndDrop)
|
|
12
|
+
*/
|
|
13
|
+
inputSourceType?: 'fileInput' | 'dragAndDrop';
|
|
14
|
+
};
|
|
9
15
|
/**
|
|
10
16
|
* Расширенная информация о переданном accept
|
|
11
17
|
*/
|
|
@@ -231,6 +237,7 @@ type SingleFileUploaderProps = {
|
|
|
231
237
|
/**
|
|
232
238
|
* Функция, вызываемая при изменении списка файлов (добавление/удаление)
|
|
233
239
|
* @param value - Объект загруженного файла или null при удалении
|
|
240
|
+
* @param metaInfo.inputSourceType - Способ загрузки файла (fileInput или dragAndDrop)
|
|
234
241
|
* @remarks
|
|
235
242
|
* Вызывается в следующих случаях:
|
|
236
243
|
* - При добавлении нового файла через диалог выбора или drag-n-drop
|
|
@@ -238,7 +245,7 @@ type SingleFileUploaderProps = {
|
|
|
238
245
|
* - При изменении статуса загрузки файла (loading/success/error)
|
|
239
246
|
* - При обновлении информации о файле после успешной загрузки
|
|
240
247
|
*/
|
|
241
|
-
onChange: (value: UploadFile | null) => void;
|
|
248
|
+
onChange: (value: UploadFile | null, metaInfo?: FileUploaderMetaInfo) => void;
|
|
242
249
|
} & BaseFileUploaderProps;
|
|
243
250
|
type MultipleFileUploaderProps = {
|
|
244
251
|
value: UploadFile[];
|
|
@@ -253,6 +260,7 @@ type MultipleFileUploaderProps = {
|
|
|
253
260
|
/**
|
|
254
261
|
* Функция, вызываемая при изменении списка файлов (добавление/удаление)
|
|
255
262
|
* @param value - Массив объектов загруженных файлов
|
|
263
|
+
* @param metaInfo.inputSourceType - Способ загрузки файла (fileInput или dragAndDrop)
|
|
256
264
|
* @remarks
|
|
257
265
|
* Вызывается в следующих случаях:
|
|
258
266
|
* - При добавлении новых файлов через диалог выбора или drag-n-drop
|
|
@@ -260,7 +268,7 @@ type MultipleFileUploaderProps = {
|
|
|
260
268
|
* - При изменении статуса загрузки файла (loading/success/error)
|
|
261
269
|
* - При обновлении информации о файле после успешной загрузки
|
|
262
270
|
*/
|
|
263
|
-
onChange: (value: UploadFile[]) => void;
|
|
271
|
+
onChange: (value: UploadFile[], metaInfo?: FileUploaderMetaInfo) => void;
|
|
264
272
|
} & BaseFileUploaderProps;
|
|
265
273
|
export type FileUploaderProps = MultipleFileUploaderProps | SingleFileUploaderProps;
|
|
266
274
|
export type SpecificSelfFileParams = {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { type FileUploaderNotify, type FileUploaderProps, type UploadFile } from '../../components/fileUploading/FileUploader';
|
|
2
|
+
import { type FileUploaderMetaInfo, type FileUploaderNotify, type FileUploaderProps, type UploadFile } from '../../components/fileUploading/FileUploader';
|
|
3
3
|
import { type WithFormFieldProps } from '../types';
|
|
4
|
-
type
|
|
4
|
+
export type FormFileUploaderMetaInfo = FileUploaderMetaInfo;
|
|
5
|
+
type BaseFileUploaderProps = Omit<FileUploaderProps, 'value' | 'isMultiple' | 'maxFileCount' | 'notify' | 'onChange'> & {
|
|
6
|
+
onChange?: (value: FormFileUploaderValue | FormFileUploaderValue[], metaInfo?: FormFileUploaderMetaInfo) => void;
|
|
7
|
+
};
|
|
5
8
|
type SingleFileUploaderProps = {
|
|
6
9
|
isMultiple?: false;
|
|
7
10
|
maxFileCount?: never;
|
|
@@ -5,11 +5,16 @@ import { useFormFieldProps } from '../useFormFieldProps';
|
|
|
5
5
|
/**
|
|
6
6
|
* FileUploader для формы
|
|
7
7
|
*/
|
|
8
|
-
const FormFileUploaderInner = (props, ref) => {
|
|
9
|
-
const { error, ...fieldProps } = useFormFieldProps(props);
|
|
8
|
+
const FormFileUploaderInner = ({ onChange: propsOnChange, ...props }, ref) => {
|
|
9
|
+
const { error, onChange, ...fieldProps } = useFormFieldProps(props);
|
|
10
|
+
const handleChange = (value, metaInfo) => {
|
|
11
|
+
onChange(value);
|
|
12
|
+
propsOnChange?.(value, metaInfo);
|
|
13
|
+
};
|
|
14
|
+
return (
|
|
10
15
|
// biome-ignore lint/suspicious/noTsIgnore: Ошибка типизации при пробросе пропсов: isMultiple
|
|
11
16
|
// @ts-ignore
|
|
12
17
|
// TODO https://track.astral.ru/soft/browse/UIKIT-1926
|
|
13
|
-
|
|
18
|
+
_jsx(FileUploader, { isError: error, onChange: handleChange, ...fieldProps, ref: ref }));
|
|
14
19
|
};
|
|
15
20
|
export const FormFileUploader = forwardRefWithGeneric(FormFileUploaderInner);
|
|
@@ -25,12 +25,16 @@ export const StyledPageContent = styled(PageContent) `
|
|
|
25
25
|
|
|
26
26
|
border-top: 1px solid ${({ theme }) => theme.palette.grey[300]};
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
${({ theme }) => theme.breakpoints.up('sm')} {
|
|
29
|
+
.${pageContentClassnames.content} {
|
|
30
30
|
overflow: unset;
|
|
31
31
|
|
|
32
32
|
height: auto;
|
|
33
33
|
padding: 0;
|
|
34
|
+
|
|
35
|
+
&.${pageContentClassnames.contentHasHeader}, &.${pageContentClassnames.hasAside} {
|
|
36
|
+
padding: 0;
|
|
37
|
+
}
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { ForwardedRef } from 'react';
|
|
2
2
|
import { type PreviewFileUploaderProps } from '../../components/fileUploading/PreviewFileUploader';
|
|
3
|
+
import { type FileUploaderMetaInfo, type UploadFile } from '../../components/fileUploading/types';
|
|
3
4
|
import { type WithFormFieldProps } from '../types';
|
|
4
|
-
export type
|
|
5
|
+
export type FormPreviewFileUploaderValue = UploadFile;
|
|
6
|
+
export type FormPreviewFileUploaderMetaInfo = FileUploaderMetaInfo;
|
|
7
|
+
export type FormPreviewFileUploaderProps<TFieldValues extends object> = WithFormFieldProps<Omit<PreviewFileUploaderProps, 'value' | 'onChange'>, TFieldValues> & {
|
|
8
|
+
onChange?: (value: FormPreviewFileUploaderValue | null, metaInfo?: FormPreviewFileUploaderMetaInfo) => void;
|
|
9
|
+
};
|
|
5
10
|
/**
|
|
6
11
|
* PreviewFileUploader для формы
|
|
7
12
|
*/
|
|
8
|
-
export declare const FormPreviewFileUploaderInner: <TFieldValues extends object>(props: FormPreviewFileUploaderProps<TFieldValues>, ref: ForwardedRef<HTMLDivElement>) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
-
export declare const FormPreviewFileUploader: <TFieldValues extends object>(props: Omit<Omit<import("../..").UsePreviewFileUploaderParams, "onChange" | "value">, "error" | "name"> & Omit<import("react-hook-form").UseControllerProps<TFieldValues>, "rules"> &
|
|
13
|
+
export declare const FormPreviewFileUploaderInner: <TFieldValues extends object>({ onChange: propsOnChange, ...props }: FormPreviewFileUploaderProps<TFieldValues>, ref: ForwardedRef<HTMLDivElement>) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare const FormPreviewFileUploader: <TFieldValues extends object>(props: Omit<Omit<import("../..").UsePreviewFileUploaderParams, "onChange" | "value">, "error" | "name"> & Omit<import("react-hook-form").UseControllerProps<TFieldValues>, "rules"> & {
|
|
15
|
+
onChange?: ((value: FormPreviewFileUploaderValue | null, metaInfo?: FormPreviewFileUploaderMetaInfo) => void) | undefined;
|
|
16
|
+
} & import("react").RefAttributes<HTMLDivElement>) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
|
|
@@ -5,8 +5,12 @@ import { useFormFieldProps } from '../useFormFieldProps';
|
|
|
5
5
|
/**
|
|
6
6
|
* PreviewFileUploader для формы
|
|
7
7
|
*/
|
|
8
|
-
export const FormPreviewFileUploaderInner = (props, ref) => {
|
|
9
|
-
const { error, ...fieldProps } = useFormFieldProps(props);
|
|
10
|
-
|
|
8
|
+
export const FormPreviewFileUploaderInner = ({ onChange: propsOnChange, ...props }, ref) => {
|
|
9
|
+
const { error, onChange, ...fieldProps } = useFormFieldProps(props);
|
|
10
|
+
const handleChange = (value, metaInfo) => {
|
|
11
|
+
onChange(value);
|
|
12
|
+
propsOnChange?.(value, metaInfo);
|
|
13
|
+
};
|
|
14
|
+
return (_jsx(PreviewFileUploader, { isError: error, onChange: handleChange, ...fieldProps, ref: ref }));
|
|
11
15
|
};
|
|
12
16
|
export const FormPreviewFileUploader = forwardRefWithGeneric(FormPreviewFileUploaderInner);
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
4
24
|
};
|
|
5
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
26
|
exports.StyledAvatar = void 0;
|
|
7
|
-
const Avatar_1 =
|
|
27
|
+
const Avatar_1 = __importStar(require("@mui/material/Avatar"));
|
|
8
28
|
const styled_1 = require("../styled/styled");
|
|
9
29
|
const getFont = (size) => {
|
|
10
30
|
if (size === 'sm') {
|
|
@@ -20,4 +40,8 @@ exports.StyledAvatar = (0, styled_1.styled)(Avatar_1.default, {
|
|
|
20
40
|
}) `
|
|
21
41
|
font-size: ${({ theme, $size }) => theme.typography[getFont($size)].fontSize};
|
|
22
42
|
font-weight: ${({ theme, $size }) => theme.typography[getFont($size)].fontWeight};
|
|
43
|
+
|
|
44
|
+
& .${Avatar_1.avatarClasses.img} {
|
|
45
|
+
background-color: ${({ theme }) => theme.palette.grey[200]};
|
|
46
|
+
}
|
|
23
47
|
`;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { fileUploaderClassnames } from '../constants';
|
|
2
|
-
export type { FileId, FileUploaderNotify, FileUploaderProps, RestrictionFn, RestrictionFnResult, UploadedFileData, UploadFile, } from '../types';
|
|
2
|
+
export type { FileId, FileUploaderMetaInfo, FileUploaderNotify, FileUploaderProps, RestrictionFn, RestrictionFnResult, UploadedFileData, UploadFile, } from '../types';
|
|
3
3
|
export { FileUploader } from './FileUploader';
|
|
@@ -60,7 +60,7 @@ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, g
|
|
|
60
60
|
onUploadFile,
|
|
61
61
|
getErrorMessage,
|
|
62
62
|
});
|
|
63
|
-
const handleChange = (event) => {
|
|
63
|
+
const handleChange = (event, metaInfo) => {
|
|
64
64
|
// Преобразуем к массиву и удаляем дубликаты
|
|
65
65
|
const droppedFiles = Array.from(event.target.files || []).filter((droppedFile) => !files.find((file) => (0, compareFile_1.compareFile)(droppedFile, file)));
|
|
66
66
|
const addedFiles = droppedFiles
|
|
@@ -81,22 +81,25 @@ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, g
|
|
|
81
81
|
];
|
|
82
82
|
}, []);
|
|
83
83
|
if (isMultiple) {
|
|
84
|
-
onChange([...files, ...addedFiles]);
|
|
84
|
+
onChange([...files, ...addedFiles], metaInfo);
|
|
85
85
|
}
|
|
86
86
|
else if (addedFiles.length) {
|
|
87
|
-
onChange(addedFiles[0]);
|
|
87
|
+
onChange(addedFiles[0], metaInfo);
|
|
88
88
|
}
|
|
89
89
|
if (addedFiles.length < droppedFiles.length) {
|
|
90
90
|
notifyWarning(addedFiles.length, droppedFiles.length);
|
|
91
91
|
}
|
|
92
|
-
enqueueFiles(addedFiles);
|
|
92
|
+
enqueueFiles(addedFiles, metaInfo);
|
|
93
|
+
};
|
|
94
|
+
const handleFileInputChange = (event) => {
|
|
95
|
+
handleChange(event, { inputSourceType: 'fileInput' });
|
|
93
96
|
};
|
|
94
97
|
const { isDragActive, ...dropZoneActions } = (0, useDnD_1.useDnD)({
|
|
95
98
|
isDisabled,
|
|
96
99
|
onChange: (droppedFiles) => {
|
|
97
100
|
handleChange({
|
|
98
101
|
target: { files: droppedFiles },
|
|
99
|
-
});
|
|
102
|
+
}, { inputSourceType: 'dragAndDrop' });
|
|
100
103
|
},
|
|
101
104
|
});
|
|
102
105
|
const handleDelete = (fileId) => {
|
|
@@ -145,7 +148,7 @@ inputRef, notify, onChange, onUploadFile, onDeleteFile, name, isError, onView, g
|
|
|
145
148
|
accept: accept.join(),
|
|
146
149
|
ref: inputRef,
|
|
147
150
|
value: '',
|
|
148
|
-
onChange:
|
|
151
|
+
onChange: handleFileInputChange,
|
|
149
152
|
name,
|
|
150
153
|
isMultiple,
|
|
151
154
|
isDisabled,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
1
2
|
import type { FileId, SpecificSelfFileParams, UploadFile } from '../../types';
|
|
3
|
+
type ChangeMetaInfo = {
|
|
4
|
+
inputSourceType?: 'fileInput' | 'dragAndDrop';
|
|
5
|
+
};
|
|
2
6
|
type UseSyncFilesParams<TMultiple extends boolean = false> = {
|
|
3
7
|
/**
|
|
4
8
|
* Список файлов, которые приходят как value в компонент
|
|
@@ -15,7 +19,11 @@ type UseSyncFilesParams<TMultiple extends boolean = false> = {
|
|
|
15
19
|
/**
|
|
16
20
|
* Функция, вызываемая при изменении списка файлов
|
|
17
21
|
*/
|
|
18
|
-
onChange: TMultiple extends true ? (value: UploadFile[]) => void : (value: UploadFile | null) => void;
|
|
22
|
+
onChange: TMultiple extends true ? (value: UploadFile[], metaInfo?: ChangeMetaInfo) => void : (value: UploadFile | null, metaInfo?: ChangeMetaInfo) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Ref с metaInfo последнего пользовательского действия
|
|
25
|
+
*/
|
|
26
|
+
metaInfoRef: RefObject<ChangeMetaInfo | undefined>;
|
|
19
27
|
};
|
|
20
28
|
export declare const useSyncFiles: <TMultiple extends boolean>(props: UseSyncFilesParams<TMultiple>) => void;
|
|
21
29
|
export {};
|
|
@@ -4,14 +4,14 @@ exports.useSyncFiles = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const isEmpty_1 = require("../../../utils/isEmpty");
|
|
6
6
|
const useSyncFiles = (props) => {
|
|
7
|
-
const { isMultiple, files, selfFiles } = props;
|
|
7
|
+
const { isMultiple, files, selfFiles, metaInfoRef } = props;
|
|
8
8
|
const handleSingleFileChange = (updatedFiles) => {
|
|
9
9
|
const { onChange } = props;
|
|
10
|
-
onChange(updatedFiles.length > 0 ? updatedFiles[0] : null);
|
|
10
|
+
onChange(updatedFiles.length > 0 ? updatedFiles[0] : null, metaInfoRef.current);
|
|
11
11
|
};
|
|
12
12
|
const handleMultipleFileChange = (updatedFiles) => {
|
|
13
13
|
const { onChange } = props;
|
|
14
|
-
onChange(updatedFiles);
|
|
14
|
+
onChange(updatedFiles, metaInfoRef.current);
|
|
15
15
|
};
|
|
16
16
|
(0, react_1.useEffect)(() => {
|
|
17
17
|
if ((0, isEmpty_1.isEmpty)(selfFiles)) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { FileId, UploadedFileData, UploadFile } from '../../types';
|
|
2
|
+
type ChangeMetaInfo = {
|
|
3
|
+
inputSourceType?: 'fileInput' | 'dragAndDrop';
|
|
4
|
+
};
|
|
2
5
|
type UseUploadFilesParams = {
|
|
3
6
|
/**
|
|
4
7
|
* Список файлов, которые приходят как value в компонент
|
|
@@ -11,7 +14,7 @@ type UseUploadFilesParams = {
|
|
|
11
14
|
/**
|
|
12
15
|
* Функция, вызываемая при изменении списка файлов
|
|
13
16
|
*/
|
|
14
|
-
onChange: ((value: UploadFile[]) => void) | ((value: UploadFile | null) => void);
|
|
17
|
+
onChange: ((value: UploadFile[], metaInfo?: ChangeMetaInfo) => void) | ((value: UploadFile | null, metaInfo?: ChangeMetaInfo) => void);
|
|
15
18
|
/**
|
|
16
19
|
* Функция загрузки файлов на сервер
|
|
17
20
|
* @param fileId - Идентификатор файла
|
|
@@ -31,7 +34,7 @@ type UseUploadFilesParams = {
|
|
|
31
34
|
getErrorMessage?: (fileId: FileId, error: Error) => string;
|
|
32
35
|
};
|
|
33
36
|
export declare const useUploadFiles: ({ isMultiple, files: externalFiles, onChange, onUploadFile, getErrorMessage, }: UseUploadFilesParams) => {
|
|
34
|
-
enqueueFiles: (files: UploadFile[]) => void;
|
|
37
|
+
enqueueFiles: (files: UploadFile[], metaInfo?: ChangeMetaInfo) => void;
|
|
35
38
|
refetchFile: (fileToSend: UploadFile) => void;
|
|
36
39
|
selfFiles: Record<string, UploadFile & import("../../types").SpecificSelfFileParams>;
|
|
37
40
|
setErrorStatusFile: (fileId: string, errorMsg: string) => void;
|
|
@@ -7,10 +7,20 @@ const useSelfFiles_1 = require("../useSelfFiles");
|
|
|
7
7
|
const useSyncFiles_1 = require("../useSyncFiles");
|
|
8
8
|
const useUploadFiles = ({ isMultiple, files: externalFiles, onChange, onUploadFile, getErrorMessage, }) => {
|
|
9
9
|
const [fileQueue, setFileQueue] = (0, react_1.useState)([]);
|
|
10
|
+
// Хранит metaInfo последнего пользовательского действия,
|
|
11
|
+
// чтобы передавать его в onChange при синхронизации статусов загрузки
|
|
12
|
+
const metaInfoRef = (0, react_1.useRef)(undefined);
|
|
10
13
|
const { selfFiles, setLoadingStatusFile, setSuccessStatusFile, setErrorStatusFile, updateFileInfo, } = (0, useSelfFiles_1.useSelfFiles)();
|
|
11
14
|
// При изменении статусов обновляем внешнее состояние
|
|
12
|
-
(0, useSyncFiles_1.useSyncFiles)({
|
|
13
|
-
|
|
15
|
+
(0, useSyncFiles_1.useSyncFiles)({
|
|
16
|
+
isMultiple,
|
|
17
|
+
files: externalFiles,
|
|
18
|
+
selfFiles,
|
|
19
|
+
onChange,
|
|
20
|
+
metaInfoRef,
|
|
21
|
+
});
|
|
22
|
+
const enqueueFiles = (files, metaInfo) => {
|
|
23
|
+
metaInfoRef.current = metaInfo;
|
|
14
24
|
const acceptedFiles = files.filter(({ status }) => !status?.isRestrictionError);
|
|
15
25
|
setFileQueue(acceptedFiles);
|
|
16
26
|
};
|
|
@@ -6,6 +6,12 @@ export type RestrictionFnResult = {
|
|
|
6
6
|
};
|
|
7
7
|
export type RestrictionFn = (value: File) => RestrictionFnResult | undefined;
|
|
8
8
|
export type FileId = string;
|
|
9
|
+
export type FileUploaderMetaInfo = {
|
|
10
|
+
/**
|
|
11
|
+
* Способ загрузки файла (fileInput или dragAndDrop)
|
|
12
|
+
*/
|
|
13
|
+
inputSourceType?: 'fileInput' | 'dragAndDrop';
|
|
14
|
+
};
|
|
9
15
|
/**
|
|
10
16
|
* Расширенная информация о переданном accept
|
|
11
17
|
*/
|
|
@@ -231,6 +237,7 @@ type SingleFileUploaderProps = {
|
|
|
231
237
|
/**
|
|
232
238
|
* Функция, вызываемая при изменении списка файлов (добавление/удаление)
|
|
233
239
|
* @param value - Объект загруженного файла или null при удалении
|
|
240
|
+
* @param metaInfo.inputSourceType - Способ загрузки файла (fileInput или dragAndDrop)
|
|
234
241
|
* @remarks
|
|
235
242
|
* Вызывается в следующих случаях:
|
|
236
243
|
* - При добавлении нового файла через диалог выбора или drag-n-drop
|
|
@@ -238,7 +245,7 @@ type SingleFileUploaderProps = {
|
|
|
238
245
|
* - При изменении статуса загрузки файла (loading/success/error)
|
|
239
246
|
* - При обновлении информации о файле после успешной загрузки
|
|
240
247
|
*/
|
|
241
|
-
onChange: (value: UploadFile | null) => void;
|
|
248
|
+
onChange: (value: UploadFile | null, metaInfo?: FileUploaderMetaInfo) => void;
|
|
242
249
|
} & BaseFileUploaderProps;
|
|
243
250
|
type MultipleFileUploaderProps = {
|
|
244
251
|
value: UploadFile[];
|
|
@@ -253,6 +260,7 @@ type MultipleFileUploaderProps = {
|
|
|
253
260
|
/**
|
|
254
261
|
* Функция, вызываемая при изменении списка файлов (добавление/удаление)
|
|
255
262
|
* @param value - Массив объектов загруженных файлов
|
|
263
|
+
* @param metaInfo.inputSourceType - Способ загрузки файла (fileInput или dragAndDrop)
|
|
256
264
|
* @remarks
|
|
257
265
|
* Вызывается в следующих случаях:
|
|
258
266
|
* - При добавлении новых файлов через диалог выбора или drag-n-drop
|
|
@@ -260,7 +268,7 @@ type MultipleFileUploaderProps = {
|
|
|
260
268
|
* - При изменении статуса загрузки файла (loading/success/error)
|
|
261
269
|
* - При обновлении информации о файле после успешной загрузки
|
|
262
270
|
*/
|
|
263
|
-
onChange: (value: UploadFile[]) => void;
|
|
271
|
+
onChange: (value: UploadFile[], metaInfo?: FileUploaderMetaInfo) => void;
|
|
264
272
|
} & BaseFileUploaderProps;
|
|
265
273
|
export type FileUploaderProps = MultipleFileUploaderProps | SingleFileUploaderProps;
|
|
266
274
|
export type SpecificSelfFileParams = {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { type FileUploaderNotify, type FileUploaderProps, type UploadFile } from '../../components/fileUploading/FileUploader';
|
|
2
|
+
import { type FileUploaderMetaInfo, type FileUploaderNotify, type FileUploaderProps, type UploadFile } from '../../components/fileUploading/FileUploader';
|
|
3
3
|
import { type WithFormFieldProps } from '../types';
|
|
4
|
-
type
|
|
4
|
+
export type FormFileUploaderMetaInfo = FileUploaderMetaInfo;
|
|
5
|
+
type BaseFileUploaderProps = Omit<FileUploaderProps, 'value' | 'isMultiple' | 'maxFileCount' | 'notify' | 'onChange'> & {
|
|
6
|
+
onChange?: (value: FormFileUploaderValue | FormFileUploaderValue[], metaInfo?: FormFileUploaderMetaInfo) => void;
|
|
7
|
+
};
|
|
5
8
|
type SingleFileUploaderProps = {
|
|
6
9
|
isMultiple?: false;
|
|
7
10
|
maxFileCount?: never;
|
|
@@ -8,11 +8,16 @@ const useFormFieldProps_1 = require("../useFormFieldProps");
|
|
|
8
8
|
/**
|
|
9
9
|
* FileUploader для формы
|
|
10
10
|
*/
|
|
11
|
-
const FormFileUploaderInner = (props, ref) => {
|
|
12
|
-
const { error, ...fieldProps } = (0, useFormFieldProps_1.useFormFieldProps)(props);
|
|
11
|
+
const FormFileUploaderInner = ({ onChange: propsOnChange, ...props }, ref) => {
|
|
12
|
+
const { error, onChange, ...fieldProps } = (0, useFormFieldProps_1.useFormFieldProps)(props);
|
|
13
|
+
const handleChange = (value, metaInfo) => {
|
|
14
|
+
onChange(value);
|
|
15
|
+
propsOnChange?.(value, metaInfo);
|
|
16
|
+
};
|
|
17
|
+
return (
|
|
13
18
|
// biome-ignore lint/suspicious/noTsIgnore: Ошибка типизации при пробросе пропсов: isMultiple
|
|
14
19
|
// @ts-ignore
|
|
15
20
|
// TODO https://track.astral.ru/soft/browse/UIKIT-1926
|
|
16
|
-
|
|
21
|
+
(0, jsx_runtime_1.jsx)(FileUploader_1.FileUploader, { isError: error, onChange: handleChange, ...fieldProps, ref: ref }));
|
|
17
22
|
};
|
|
18
23
|
exports.FormFileUploader = (0, forwardRefWithGeneric_1.forwardRefWithGeneric)(FormFileUploaderInner);
|
|
@@ -28,12 +28,16 @@ exports.StyledPageContent = (0, styled_1.styled)(PageContent_1.PageContent) `
|
|
|
28
28
|
|
|
29
29
|
border-top: 1px solid ${({ theme }) => theme.palette.grey[300]};
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
${({ theme }) => theme.breakpoints.up('sm')} {
|
|
32
|
+
.${PageContent_1.pageContentClassnames.content} {
|
|
33
33
|
overflow: unset;
|
|
34
34
|
|
|
35
35
|
height: auto;
|
|
36
36
|
padding: 0;
|
|
37
|
+
|
|
38
|
+
&.${PageContent_1.pageContentClassnames.contentHasHeader}, &.${PageContent_1.pageContentClassnames.hasAside} {
|
|
39
|
+
padding: 0;
|
|
40
|
+
}
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
43
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { ForwardedRef } from 'react';
|
|
2
2
|
import { type PreviewFileUploaderProps } from '../../components/fileUploading/PreviewFileUploader';
|
|
3
|
+
import { type FileUploaderMetaInfo, type UploadFile } from '../../components/fileUploading/types';
|
|
3
4
|
import { type WithFormFieldProps } from '../types';
|
|
4
|
-
export type
|
|
5
|
+
export type FormPreviewFileUploaderValue = UploadFile;
|
|
6
|
+
export type FormPreviewFileUploaderMetaInfo = FileUploaderMetaInfo;
|
|
7
|
+
export type FormPreviewFileUploaderProps<TFieldValues extends object> = WithFormFieldProps<Omit<PreviewFileUploaderProps, 'value' | 'onChange'>, TFieldValues> & {
|
|
8
|
+
onChange?: (value: FormPreviewFileUploaderValue | null, metaInfo?: FormPreviewFileUploaderMetaInfo) => void;
|
|
9
|
+
};
|
|
5
10
|
/**
|
|
6
11
|
* PreviewFileUploader для формы
|
|
7
12
|
*/
|
|
8
|
-
export declare const FormPreviewFileUploaderInner: <TFieldValues extends object>(props: FormPreviewFileUploaderProps<TFieldValues>, ref: ForwardedRef<HTMLDivElement>) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
-
export declare const FormPreviewFileUploader: <TFieldValues extends object>(props: Omit<Omit<import("../..").UsePreviewFileUploaderParams, "onChange" | "value">, "error" | "name"> & Omit<import("react-hook-form").UseControllerProps<TFieldValues>, "rules"> &
|
|
13
|
+
export declare const FormPreviewFileUploaderInner: <TFieldValues extends object>({ onChange: propsOnChange, ...props }: FormPreviewFileUploaderProps<TFieldValues>, ref: ForwardedRef<HTMLDivElement>) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare const FormPreviewFileUploader: <TFieldValues extends object>(props: Omit<Omit<import("../..").UsePreviewFileUploaderParams, "onChange" | "value">, "error" | "name"> & Omit<import("react-hook-form").UseControllerProps<TFieldValues>, "rules"> & {
|
|
15
|
+
onChange?: ((value: FormPreviewFileUploaderValue | null, metaInfo?: FormPreviewFileUploaderMetaInfo) => void) | undefined;
|
|
16
|
+
} & import("react").RefAttributes<HTMLDivElement>) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
|
|
@@ -8,9 +8,13 @@ const useFormFieldProps_1 = require("../useFormFieldProps");
|
|
|
8
8
|
/**
|
|
9
9
|
* PreviewFileUploader для формы
|
|
10
10
|
*/
|
|
11
|
-
const FormPreviewFileUploaderInner = (props, ref) => {
|
|
12
|
-
const { error, ...fieldProps } = (0, useFormFieldProps_1.useFormFieldProps)(props);
|
|
13
|
-
|
|
11
|
+
const FormPreviewFileUploaderInner = ({ onChange: propsOnChange, ...props }, ref) => {
|
|
12
|
+
const { error, onChange, ...fieldProps } = (0, useFormFieldProps_1.useFormFieldProps)(props);
|
|
13
|
+
const handleChange = (value, metaInfo) => {
|
|
14
|
+
onChange(value);
|
|
15
|
+
propsOnChange?.(value, metaInfo);
|
|
16
|
+
};
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(PreviewFileUploader_1.PreviewFileUploader, { isError: error, onChange: handleChange, ...fieldProps, ref: ref }));
|
|
14
18
|
};
|
|
15
19
|
exports.FormPreviewFileUploaderInner = FormPreviewFileUploaderInner;
|
|
16
20
|
exports.FormPreviewFileUploader = (0, forwardRefWithGeneric_1.forwardRefWithGeneric)(exports.FormPreviewFileUploaderInner);
|