@emailmaker/filemanager 0.10.65 → 0.10.67
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/FileContent/FileContent.d.ts +7 -19
- package/components/FileContent/FileContentHeader.d.ts +32 -0
- package/components/FileContent/FileSelectionCheckbox.d.ts +14 -0
- package/components/FileContent/SelectableTableRow.d.ts +12 -0
- package/components/FileContent/presentation/FileGridItem.d.ts +32 -0
- package/components/FileContent/presentation/FileItemActionsDropdown.d.ts +24 -0
- package/components/FileContent/presentation/FileItemDate.d.ts +11 -0
- package/components/FileContent/presentation/FileItemName.d.ts +13 -0
- package/components/FileContent/presentation/FileItemPreview.d.ts +22 -0
- package/components/FileContent/presentation/types.d.ts +1 -0
- package/components/FileContent/renderers/FileGridView.d.ts +34 -0
- package/components/FileContent/renderers/FileTableView.d.ts +26 -0
- package/components/PixieEditor/PixieEditor.d.ts +3 -2
- package/file-manager.css +11 -2
- package/file-manager.d.ts +6 -2
- package/file-manager.esm.js +9 -9
- package/file-manager.esm.js.map +1 -1
- package/file-manager.js +1 -1
- package/hooks/core/files/index.d.ts +1 -0
- package/hooks/core/files/useFileSelectionStore.d.ts +32 -0
- package/hooks/core/types.d.ts +0 -3
- package/hooks/useFileActions.d.ts +2 -9
- package/hooks/usePixieEditor.d.ts +4 -4
- package/my-files.json +1 -0
- package/package.json +1 -1
- package/presentation/file-list/FileListAdapter.d.ts +10 -0
- package/presentation/file-list/types.d.ts +20 -0
- package/presentation/file-list/useFileListEngine.d.ts +26 -0
- package/presentation/list-core/ListItemAdapter.d.ts +9 -0
- package/presentation/list-core/RowModelCache.d.ts +13 -0
- package/presentation/list-core/ViewportController.d.ts +10 -0
- package/presentation/list-core/types.d.ts +31 -0
- package/presentation/list-core/useListPresentationEngine.d.ts +20 -0
- package/presentation/list-core/useViewportRenderController.d.ts +24 -0
- package/presentation/list-core/viewportMetrics.d.ts +3 -0
- package/types.d.ts +19 -0
- package/utils/fileFormatUtils.d.ts +1 -1
- package/utils/imageCompression.d.ts +5 -2
- package/utils/jsonDataProvider.d.ts +1 -0
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { UseFileUploadReturn } from '../../hooks/useFileUpload';
|
|
3
2
|
import { SortByType, SortOptionType, SortOrderType } from '../../hooks/core/types';
|
|
4
|
-
import { File as AppFile, PaginationState,
|
|
3
|
+
import { File as AppFile, PaginationState, ThumbnailFile } from '../../types';
|
|
5
4
|
interface FileContentProps {
|
|
6
5
|
searchTerm: string;
|
|
7
|
-
sortField: string;
|
|
8
|
-
setSortField: (field: string) => void;
|
|
9
|
-
pathHistory: PathItem[];
|
|
10
|
-
handleBreadcrumbClick: (index: number) => void;
|
|
11
6
|
handleAddFile: () => void;
|
|
12
|
-
setIsUrlModalVisible: (visible: boolean) => void;
|
|
13
7
|
files: AppFile[];
|
|
14
8
|
handleSearch: (searchTerm: string) => void;
|
|
15
|
-
handleSort: (sortBy: SortByType, sortOrder: SortOrderType) => void;
|
|
16
9
|
sortBy: SortByType;
|
|
17
10
|
sortOrder: SortOrderType;
|
|
18
11
|
handleSortOptionChange: (option: SortOptionType) => void;
|
|
@@ -20,22 +13,17 @@ interface FileContentProps {
|
|
|
20
13
|
setPagination: (pagination: Partial<PaginationState>) => void;
|
|
21
14
|
loading: boolean;
|
|
22
15
|
handleItemClick: (record: AppFile) => void;
|
|
23
|
-
handleDeleteFile: (fileId: string) => void;
|
|
24
|
-
selectedFiles: Set<string>;
|
|
25
|
-
toggleFileSelection: (fileId: string, opts?: {
|
|
26
|
-
metaKey?: boolean;
|
|
27
|
-
ctrlKey?: boolean;
|
|
28
|
-
shiftKey?: boolean;
|
|
29
|
-
forceToggle?: boolean;
|
|
30
|
-
}) => void;
|
|
31
|
-
handleDroppedFiles: (droppedFiles: globalThis.File[]) => Promise<void>;
|
|
32
|
-
fileUpload: UseFileUploadReturn;
|
|
33
16
|
onClearSelection: () => void;
|
|
34
17
|
onRename: (selectedFileId?: string) => void;
|
|
35
18
|
onDelete: (file?: AppFile) => void;
|
|
36
19
|
onCopy: () => void;
|
|
37
20
|
onMove: () => void;
|
|
21
|
+
showRenameModal: (fileId: string) => void;
|
|
22
|
+
showDeleteConfirm?: () => void;
|
|
23
|
+
showCopyModal: () => void;
|
|
24
|
+
showMoveModal: () => void;
|
|
38
25
|
onEdit: (file?: AppFile | ThumbnailFile) => void;
|
|
26
|
+
getFileData: (fileId: string, silent?: boolean) => Promise<Blob | undefined>;
|
|
39
27
|
}
|
|
40
|
-
export declare const FileContent: React.
|
|
28
|
+
export declare const FileContent: React.NamedExoticComponent<FileContentProps>;
|
|
41
29
|
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TFunction } from 'i18next';
|
|
3
|
+
import { SortOptionType } from '../../hooks/core/types';
|
|
4
|
+
import { File as AppFile, ThumbnailFile } from '../../types';
|
|
5
|
+
interface FileContentHeaderProps {
|
|
6
|
+
files: AppFile[];
|
|
7
|
+
filesById: Map<string, AppFile>;
|
|
8
|
+
currentSortOption: SortOptionType;
|
|
9
|
+
isSmallScreen: boolean;
|
|
10
|
+
iconStrokeWidth?: number;
|
|
11
|
+
features: Record<string, boolean | undefined>;
|
|
12
|
+
viewMode: 'grid' | 'table';
|
|
13
|
+
setViewMode: (value: 'grid' | 'table') => void;
|
|
14
|
+
handleSearch: (searchTerm: string) => void;
|
|
15
|
+
handleSortOptionChange: (option: SortOptionType) => void;
|
|
16
|
+
onClearSelection: () => void;
|
|
17
|
+
onRename: (selectedFileId?: string) => void;
|
|
18
|
+
onDelete: (file?: AppFile) => void;
|
|
19
|
+
onCopy: () => void;
|
|
20
|
+
onMove: () => void;
|
|
21
|
+
onEdit: (file?: AppFile | ThumbnailFile) => void;
|
|
22
|
+
t: TFunction;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Selection-toolbar живёт отдельно от корня `FileContent`.
|
|
26
|
+
*
|
|
27
|
+
* Это важно для производительности: selection меняется часто, и если держать
|
|
28
|
+
* подписку на `selectedFiles` в корне списка, каждый клик по checkbox будет
|
|
29
|
+
* заново прогонять весь `FileContent`, даже когда сама таблица уже стабилизирована.
|
|
30
|
+
*/
|
|
31
|
+
export declare const FileContentHeader: React.NamedExoticComponent<FileContentHeaderProps>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface FileSelectionCheckboxProps {
|
|
3
|
+
fileId: string;
|
|
4
|
+
style?: React.CSSProperties;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Узкий checkbox выбора файла.
|
|
8
|
+
*
|
|
9
|
+
* Компонент подписывается только на булево состояние конкретного `fileId`.
|
|
10
|
+
* Благодаря этому при смене selection не нужно заново перерисовывать весь список:
|
|
11
|
+
* обновится только тот checkbox, у которого реально поменялось состояние.
|
|
12
|
+
*/
|
|
13
|
+
export declare const FileSelectionCheckbox: React.NamedExoticComponent<FileSelectionCheckboxProps>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type SelectableTableRowProps = React.HTMLAttributes<HTMLTableRowElement> & {
|
|
3
|
+
'data-row-key'?: string | number;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Кастомная строка таблицы, которая сама знает, выбран ли её `rowKey`.
|
|
7
|
+
*
|
|
8
|
+
* Это позволяет не прокидывать `selectedFiles` в `rowClassName` из родителя и
|
|
9
|
+
* не заставлять всю таблицу зависеть от каждого изменения selection.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SelectableTableRow: React.NamedExoticComponent<SelectableTableRowProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FileItemViewModel } from './types';
|
|
3
|
+
import type { File as AppFile } from '../../../types';
|
|
4
|
+
import type { TFunction } from 'i18next';
|
|
5
|
+
interface FileGridItemProps {
|
|
6
|
+
item: FileItemViewModel;
|
|
7
|
+
t: TFunction;
|
|
8
|
+
iconStrokeWidth?: number;
|
|
9
|
+
FolderIcon: React.ComponentType<{
|
|
10
|
+
className?: string;
|
|
11
|
+
style?: React.CSSProperties;
|
|
12
|
+
}>;
|
|
13
|
+
handleSingleClick: (callback: () => void) => void;
|
|
14
|
+
handleDoubleClick: (callback: () => void) => void;
|
|
15
|
+
handleItemClick: (record: AppFile) => void;
|
|
16
|
+
setCurrentMenuFile?: (file: string) => void;
|
|
17
|
+
showMoveModal: () => void;
|
|
18
|
+
showCopyModal: () => void;
|
|
19
|
+
showRenameModal: (fileId: string) => void;
|
|
20
|
+
showDeleteConfirm?: () => void;
|
|
21
|
+
onEdit: (file?: AppFile) => void;
|
|
22
|
+
onEditorOk?: (file: AppFile) => void;
|
|
23
|
+
getFileData: (fileId: string, silent?: boolean) => Promise<Blob | undefined>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Карточка grid-режима на основе общего view-model.
|
|
27
|
+
*
|
|
28
|
+
* Grid и table используют один и тот же подготовленный `item`, поэтому
|
|
29
|
+
* визуальные режимы отличаются только отрисовкой, а не повторным derive данных.
|
|
30
|
+
*/
|
|
31
|
+
export declare const FileGridItem: React.NamedExoticComponent<FileGridItemProps>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TFunction } from 'i18next';
|
|
3
|
+
import type { File as AppFile } from '../../../types';
|
|
4
|
+
import type { FileItemViewModel } from './types';
|
|
5
|
+
interface FileItemActionsDropdownProps {
|
|
6
|
+
item: FileItemViewModel;
|
|
7
|
+
variant?: 'table' | 'grid';
|
|
8
|
+
t: TFunction;
|
|
9
|
+
iconStrokeWidth?: number;
|
|
10
|
+
setCurrentMenuFile?: (file: string) => void;
|
|
11
|
+
showMoveModal: () => void;
|
|
12
|
+
showCopyModal: () => void;
|
|
13
|
+
showRenameModal: (fileId: string) => void;
|
|
14
|
+
showDeleteConfirm?: () => void;
|
|
15
|
+
onEdit: (file?: AppFile) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Общий dropdown для table и grid.
|
|
19
|
+
*
|
|
20
|
+
* Меню строится по готовым флагам из view-model, поэтому при rerender контейнера
|
|
21
|
+
* здесь не нужно заново вычислять доступность действий из исходного файла.
|
|
22
|
+
*/
|
|
23
|
+
export declare const FileItemActionsDropdown: React.NamedExoticComponent<FileItemActionsDropdownProps>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FileItemViewModel } from './types';
|
|
3
|
+
interface FileItemDateProps {
|
|
4
|
+
item: FileItemViewModel;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Дата вынесена отдельно, чтобы tooltip и форматированный текст были изолированы
|
|
8
|
+
* от остального содержимого строки.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FileItemDate: React.NamedExoticComponent<FileItemDateProps>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FileItemViewModel } from './types';
|
|
3
|
+
interface FileItemNameProps {
|
|
4
|
+
item: FileItemViewModel;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Имя и вторичный текст для папки.
|
|
8
|
+
*
|
|
9
|
+
* Это leaf-компонент, поэтому при rerender таблицы он может быстро bailout-иться,
|
|
10
|
+
* если сам `item` не изменился.
|
|
11
|
+
*/
|
|
12
|
+
export declare const FileItemName: React.NamedExoticComponent<FileItemNameProps>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FileItemViewModel } from './types';
|
|
3
|
+
interface FileItemPreviewProps {
|
|
4
|
+
item: FileItemViewModel;
|
|
5
|
+
variant?: 'table' | 'grid';
|
|
6
|
+
FolderIcon: React.ComponentType<{
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
}>;
|
|
10
|
+
getFileData: (fileId: string, silent?: boolean) => Promise<Blob | undefined>;
|
|
11
|
+
className?: string;
|
|
12
|
+
width?: number;
|
|
13
|
+
height?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Отдельный leaf-компонент превью.
|
|
17
|
+
*
|
|
18
|
+
* Его задача простая: не вычислять ничего на лету, а только отрисовать уже
|
|
19
|
+
* подготовленный view-model. Тогда rerender таблицы не тянет повторную derive-логику.
|
|
20
|
+
*/
|
|
21
|
+
export declare const FileItemPreview: React.NamedExoticComponent<FileItemPreviewProps>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { FileListRowModel as FileItemViewModel } from '../../../presentation/file-list/types';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TFunction } from 'i18next';
|
|
3
|
+
import type { FileListRowModel } from '../../../presentation/file-list/types';
|
|
4
|
+
import type { File as AppFile } from '../../../types';
|
|
5
|
+
interface FileGridViewProps {
|
|
6
|
+
rows: FileListRowModel[];
|
|
7
|
+
topOffset?: number;
|
|
8
|
+
bottomOffset?: number;
|
|
9
|
+
t: TFunction;
|
|
10
|
+
iconStrokeWidth?: number;
|
|
11
|
+
FolderIcon: React.ComponentType<{
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
}>;
|
|
15
|
+
handleSingleClick: (callback: () => void) => void;
|
|
16
|
+
handleDoubleClick: (callback: () => void) => void;
|
|
17
|
+
handleItemClick: (record: AppFile) => void;
|
|
18
|
+
setCurrentMenuFile?: (file: string) => void;
|
|
19
|
+
showMoveModal: () => void;
|
|
20
|
+
showCopyModal: () => void;
|
|
21
|
+
showRenameModal: (fileId: string) => void;
|
|
22
|
+
showDeleteConfirm?: () => void;
|
|
23
|
+
onEdit: (file?: AppFile) => void;
|
|
24
|
+
onEditorOk?: (file: AppFile) => void;
|
|
25
|
+
getFileData: (fileId: string, silent?: boolean) => Promise<Blob | undefined>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Изолированный renderer grid-режима.
|
|
29
|
+
*
|
|
30
|
+
* Здесь остаётся только раскладка и composition карточек, а orchestration
|
|
31
|
+
* живёт в `FileContent`, чтобы случайные правки UI не ломали memo-цепочку.
|
|
32
|
+
*/
|
|
33
|
+
export declare const FileGridView: React.NamedExoticComponent<FileGridViewProps>;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ColumnsType } from 'antd/es/table';
|
|
3
|
+
import type { FileListRowModel } from '../../../presentation/file-list/types';
|
|
4
|
+
interface FileTableViewProps {
|
|
5
|
+
rows: FileListRowModel[];
|
|
6
|
+
columns: ColumnsType<FileListRowModel>;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
topOffset?: number;
|
|
9
|
+
bottomOffset?: number;
|
|
10
|
+
onRow: (record: FileListRowModel) => React.HTMLAttributes<HTMLElement>;
|
|
11
|
+
components: {
|
|
12
|
+
body: {
|
|
13
|
+
row: React.ComponentType<React.HTMLAttributes<HTMLTableRowElement> & {
|
|
14
|
+
'data-row-key'?: string | number;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Изолированный renderer table-режима.
|
|
21
|
+
*
|
|
22
|
+
* Важно, что `loading` живёт снаружи таблицы, а не внутри `Table`,
|
|
23
|
+
* поэтому сам table tree не пересобирается только из-за spinner state.
|
|
24
|
+
*/
|
|
25
|
+
export declare const FileTableView: React.NamedExoticComponent<FileTableViewProps>;
|
|
26
|
+
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { PixieSavePayload } from '../../types';
|
|
2
3
|
import { File as AppFile, ThumbnailFile } from '../../types';
|
|
3
4
|
interface PixieEditorProps {
|
|
4
5
|
visible: boolean;
|
|
5
6
|
onClose?: () => void;
|
|
6
7
|
file: AppFile | ThumbnailFile | string | null;
|
|
7
|
-
onSave: (updatedFile: AppFile) => Promise<AppFile | undefined>;
|
|
8
|
-
onSaveCopy: (updatedFile: AppFile) => Promise<AppFile | undefined>;
|
|
8
|
+
onSave: (updatedFile: AppFile, payload: PixieSavePayload) => Promise<AppFile | undefined>;
|
|
9
|
+
onSaveCopy: (updatedFile: AppFile, payload: PixieSavePayload) => Promise<AppFile | undefined>;
|
|
9
10
|
}
|
|
10
11
|
export declare const PixieEditor: React.FC<PixieEditorProps>;
|
|
11
12
|
export {};
|
package/file-manager.css
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
display: flex;
|
|
33
33
|
flex-direction: column;
|
|
34
34
|
height: 100%;
|
|
35
|
+
min-height: 0;
|
|
35
36
|
padding: 36px 16px;
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
.em-filemanager .filesContainer {
|
|
52
53
|
position: relative;
|
|
53
54
|
flex: 1;
|
|
55
|
+
min-height: 0;
|
|
54
56
|
overflow-y: auto;
|
|
55
57
|
display: flex;
|
|
56
58
|
flex-direction: column;
|
|
@@ -115,12 +117,19 @@
|
|
|
115
117
|
|
|
116
118
|
.em-filemanager .tableContainer {
|
|
117
119
|
flex: 1;
|
|
118
|
-
|
|
120
|
+
min-height: 0;
|
|
121
|
+
overflow: hidden;
|
|
119
122
|
width: 100%;
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-direction: column;
|
|
120
125
|
position: relative;
|
|
121
126
|
z-index: 0;
|
|
122
127
|
}
|
|
123
128
|
|
|
129
|
+
.em-filemanager .tableLoadingWrapper {
|
|
130
|
+
width: 100%;
|
|
131
|
+
}
|
|
132
|
+
|
|
124
133
|
.em-filemanager .imagePreview {
|
|
125
134
|
max-width: 100%;
|
|
126
135
|
display: block;
|
|
@@ -559,7 +568,7 @@
|
|
|
559
568
|
font-style: normal;
|
|
560
569
|
font-weight: 400;
|
|
561
570
|
line-height: normal;
|
|
562
|
-
color: #
|
|
571
|
+
color: #8c8c8c;
|
|
563
572
|
}
|
|
564
573
|
@charset "UTF-8";
|
|
565
574
|
.em-filemanager .folderTree .emptyFolderContainer {
|
package/file-manager.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Config, CustomIcons, File, FileManagerDataProviders, NotifyListener, Notify, NotifyEvent, ThumbnailFile } from './types';
|
|
2
|
+
import type { Config, CustomIcons, File, FileManagerDataProviders, PixieSavePayload, NotifyListener, Notify, NotifyEvent, ThumbnailFile } from './types';
|
|
3
3
|
import './styles/index.scss';
|
|
4
4
|
export declare const FileManagerAppWithContext: (props: FileManagerAppProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
export interface Options {
|
|
@@ -74,12 +74,16 @@ export interface InitPixieEditorOptions {
|
|
|
74
74
|
type?: string;
|
|
75
75
|
extension?: string;
|
|
76
76
|
dataProviders?: FileManagerDataProviders;
|
|
77
|
-
onSave?: (updatedFile: File) => Promise<void> | void;
|
|
77
|
+
onSave?: (updatedFile: File, payload?: PixieSavePayload) => Promise<void> | void;
|
|
78
78
|
onClose?: () => void;
|
|
79
79
|
theme?: Config['theme'];
|
|
80
80
|
locale?: string;
|
|
81
81
|
baseUrl?: string;
|
|
82
82
|
assetsUrl?: string;
|
|
83
|
+
compressMaxSize?: Config['compressMaxSize'];
|
|
84
|
+
compressMaxWidthOrHeight?: Config['compressMaxWidthOrHeight'];
|
|
85
|
+
compessorUrl?: string;
|
|
86
|
+
compressorUrl?: string;
|
|
83
87
|
showNotifications?: boolean;
|
|
84
88
|
handleFileProxy?: Config['handleFileProxy'];
|
|
85
89
|
handleNotify?: NotifyListener<NotifyEvent>;
|