mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-11 07:06:28 +08:00
refactor(editor): split openFileOrFiles into openSingleFileWith and openFilesWith (#12523)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved file selection dialogs for attachments, imports, and uploads, allowing for more consistent and streamlined file picking across the app. - **Bug Fixes** - Resolved inconsistencies when selecting single or multiple files, ensuring a smoother user experience during file import and upload. - **Refactor** - Unified and simplified file selection logic throughout the app for better reliability and maintainability. - Standardized import functions to uniformly handle arrays of files, enhancing consistency in file processing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
||||
import { openSingleFileWith } from '@blocksuite/affine-shared/utils';
|
||||
import { type SlashMenuConfig } from '@blocksuite/affine-widget-slash-menu';
|
||||
import { ExportToPdfIcon, FileIcon } from '@blocksuite/icons/lit';
|
||||
|
||||
@@ -21,7 +21,7 @@ export const attachmentSlashMenuConfig: SlashMenuConfig = {
|
||||
model.store.schema.flavourSchemaMap.has('affine:attachment'),
|
||||
action: ({ std, model }) => {
|
||||
(async () => {
|
||||
const file = await openFileOrFiles();
|
||||
const file = await openSingleFileWith();
|
||||
if (!file) return;
|
||||
|
||||
await addSiblingAttachmentBlocks(std, [file], model);
|
||||
@@ -44,7 +44,7 @@ export const attachmentSlashMenuConfig: SlashMenuConfig = {
|
||||
model.store.schema.flavourSchemaMap.has('affine:attachment'),
|
||||
action: ({ std, model }) => {
|
||||
(async () => {
|
||||
const file = await openFileOrFiles();
|
||||
const file = await openSingleFileWith();
|
||||
if (!file) return;
|
||||
|
||||
await addSiblingAttachmentBlocks(std, [file], model);
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
FeatureFlagService,
|
||||
TelemetryProvider,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
||||
import { openSingleFileWith } from '@blocksuite/affine-shared/utils';
|
||||
import { Bound, type IVec } from '@blocksuite/global/gfx';
|
||||
import type { BlockComponent } from '@blocksuite/std';
|
||||
import type { TemplateResult } from 'lit';
|
||||
@@ -158,7 +158,7 @@ export const textRender: DraggableTool['render'] = async (bound, edgeless) => {
|
||||
export const mediaRender: DraggableTool['render'] = async (bound, edgeless) => {
|
||||
let file: File | null = null;
|
||||
try {
|
||||
file = await openFileOrFiles();
|
||||
file = await openSingleFileWith();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
||||
import { openSingleFileWith } from '@blocksuite/affine-shared/utils';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import type { Bound } from '@blocksuite/global/gfx';
|
||||
import c from 'simple-xml-to-json';
|
||||
@@ -12,9 +12,7 @@ type MindMapNode = {
|
||||
};
|
||||
|
||||
export async function importMindmap(bound: Bound): Promise<MindMapNode> {
|
||||
const file = await openFileOrFiles({
|
||||
acceptType: 'MindMap',
|
||||
});
|
||||
const file = await openSingleFileWith('MindMap');
|
||||
|
||||
if (!file) {
|
||||
throw new BlockSuiteError(ErrorCode.UserAbortError, 'Aborted by user');
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
getImageFilesFromLocal,
|
||||
openFileOrFiles,
|
||||
openSingleFileWith,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { AttachmentIcon, ImageIcon, LinkIcon } from '@blocksuite/icons/lit';
|
||||
@@ -139,7 +139,7 @@ export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
.activeMode=${'background'}
|
||||
.tooltip=${'File'}
|
||||
@click=${async () => {
|
||||
const file = await openFileOrFiles();
|
||||
const file = await openSingleFileWith();
|
||||
if (!file) return;
|
||||
await addAttachments(this.edgeless.std, [file]);
|
||||
this.gfx.tool.setTool(DefaultTool);
|
||||
|
||||
@@ -112,21 +112,11 @@ type AcceptTypes =
|
||||
| 'Html'
|
||||
| 'Zip'
|
||||
| 'MindMap';
|
||||
export function openFileOrFiles(options?: {
|
||||
acceptType?: AcceptTypes;
|
||||
}): Promise<File | null>;
|
||||
export function openFileOrFiles(options: {
|
||||
acceptType?: AcceptTypes;
|
||||
multiple: false;
|
||||
}): Promise<File | null>;
|
||||
export function openFileOrFiles(options: {
|
||||
acceptType?: AcceptTypes;
|
||||
multiple: true;
|
||||
}): Promise<File[] | null>;
|
||||
export async function openFileOrFiles({
|
||||
acceptType = 'Any',
|
||||
multiple = false,
|
||||
} = {}) {
|
||||
|
||||
export async function openFilesWith(
|
||||
acceptType: AcceptTypes = 'Any',
|
||||
multiple: boolean = true
|
||||
): Promise<File[] | null> {
|
||||
// Feature detection. The API needs to be supported
|
||||
// and the app not run in an iframe.
|
||||
const supportsFileSystemAccess =
|
||||
@@ -138,6 +128,7 @@ export async function openFileOrFiles({
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
// If the File System Access API is supported…
|
||||
if (supportsFileSystemAccess && window.showOpenFilePicker) {
|
||||
try {
|
||||
@@ -153,30 +144,14 @@ export async function openFileOrFiles({
|
||||
} satisfies OpenFilePickerOptions;
|
||||
// Show the file picker, optionally allowing multiple files.
|
||||
const handles = await window.showOpenFilePicker(pickerOpts);
|
||||
// Only one file is requested.
|
||||
if (!multiple) {
|
||||
// Add the `FileSystemFileHandle` as `.handle`.
|
||||
const file = await handles[0].getFile();
|
||||
// Add the `FileSystemFileHandle` as `.handle`.
|
||||
// file.handle = handles[0];
|
||||
return file;
|
||||
} else {
|
||||
const files = await Promise.all(
|
||||
handles.map(async handle => {
|
||||
const file = await handle.getFile();
|
||||
// Add the `FileSystemFileHandle` as `.handle`.
|
||||
// file.handle = handles[0];
|
||||
return file;
|
||||
})
|
||||
);
|
||||
return files;
|
||||
}
|
||||
|
||||
return await Promise.all(handles.map(handle => handle.getFile()));
|
||||
} catch (err) {
|
||||
console.error('Error opening file');
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback if the File System Access API is not supported.
|
||||
return new Promise(resolve => {
|
||||
// Append a new `<input type="file" multiple? />` and hide it.
|
||||
@@ -184,9 +159,8 @@ export async function openFileOrFiles({
|
||||
input.classList.add('affine-upload-input');
|
||||
input.style.display = 'none';
|
||||
input.type = 'file';
|
||||
if (multiple) {
|
||||
input.multiple = true;
|
||||
}
|
||||
input.multiple = multiple;
|
||||
|
||||
if (acceptType !== 'Any') {
|
||||
// For example, `accept="image/*"` or `accept="video/*,audio/*"`.
|
||||
input.accept = Object.keys(
|
||||
@@ -198,17 +172,8 @@ export async function openFileOrFiles({
|
||||
input.addEventListener('change', () => {
|
||||
// Remove the `<input type="file" multiple? />` again from the DOM.
|
||||
input.remove();
|
||||
// If no files were selected, return.
|
||||
if (!input.files) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
// Return all files or just one file.
|
||||
if (multiple) {
|
||||
resolve(Array.from(input.files));
|
||||
return;
|
||||
}
|
||||
resolve(input.files[0]);
|
||||
|
||||
resolve(input.files ? Array.from(input.files) : null);
|
||||
});
|
||||
// The `cancel` event fires when the user cancels the dialog.
|
||||
input.addEventListener('cancel', () => {
|
||||
@@ -223,11 +188,14 @@ export async function openFileOrFiles({
|
||||
});
|
||||
}
|
||||
|
||||
export function openSingleFileWith(
|
||||
acceptType?: AcceptTypes
|
||||
): Promise<File | null> {
|
||||
return openFilesWith(acceptType, false).then(files => files?.at(0) ?? null);
|
||||
}
|
||||
|
||||
export async function getImageFilesFromLocal() {
|
||||
const imageFiles = await openFileOrFiles({
|
||||
acceptType: 'Images',
|
||||
multiple: true,
|
||||
});
|
||||
const imageFiles = await openFilesWith('Images');
|
||||
if (!imageFiles) return [];
|
||||
return imageFiles;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||
import {
|
||||
createDefaultDoc,
|
||||
openFileOrFiles,
|
||||
openSingleFileWith,
|
||||
type Signal,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import type { AffineLinkedDocWidget } from '@blocksuite/affine-widget-linked-doc';
|
||||
@@ -418,7 +418,7 @@ const contentMediaToolGroup: KeyboardToolPanelGroup = {
|
||||
const model = selectedModels?.[0];
|
||||
if (!model) return;
|
||||
|
||||
const file = await openFileOrFiles();
|
||||
const file = await openSingleFileWith();
|
||||
if (!file) return;
|
||||
|
||||
await addSiblingAttachmentBlocks(std, [file], model);
|
||||
@@ -1040,7 +1040,7 @@ export const defaultKeyboardToolbarConfig: KeyboardToolbarConfig = {
|
||||
const model = selectedModels?.[0];
|
||||
if (!model) return;
|
||||
|
||||
const file = await openFileOrFiles();
|
||||
const file = await openSingleFileWith();
|
||||
if (!file) return;
|
||||
|
||||
await addSiblingAttachmentBlocks(std, [file], model);
|
||||
|
||||
@@ -6,7 +6,10 @@ import {
|
||||
NewIcon,
|
||||
NotionIcon,
|
||||
} from '@blocksuite/affine-components/icons';
|
||||
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
||||
import {
|
||||
openFilesWith,
|
||||
openSingleFileWith,
|
||||
} from '@blocksuite/affine-shared/utils';
|
||||
import { WithDisposable } from '@blocksuite/global/lit';
|
||||
import type { ExtensionType, Schema, Workspace } from '@blocksuite/store';
|
||||
import { html, LitElement, type PropertyValues } from 'lit';
|
||||
@@ -50,7 +53,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
||||
}
|
||||
|
||||
private async _importHtml() {
|
||||
const files = await openFileOrFiles({ acceptType: 'Html', multiple: true });
|
||||
const files = await openFilesWith('Html');
|
||||
if (!files) return;
|
||||
const pageIds: string[] = [];
|
||||
for (const file of files) {
|
||||
@@ -79,10 +82,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
||||
}
|
||||
|
||||
private async _importMarkDown() {
|
||||
const files = await openFileOrFiles({
|
||||
acceptType: 'Markdown',
|
||||
multiple: true,
|
||||
});
|
||||
const files = await openFilesWith('Markdown');
|
||||
if (!files) return;
|
||||
const pageIds: string[] = [];
|
||||
for (const file of files) {
|
||||
@@ -111,7 +111,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
||||
}
|
||||
|
||||
private async _importNotion() {
|
||||
const file = await openFileOrFiles({ acceptType: 'Zip' });
|
||||
const file = await openSingleFileWith('Zip');
|
||||
if (!file) return;
|
||||
const needLoading = file.size > SHOW_LOADING_SIZE;
|
||||
if (needLoading) {
|
||||
|
||||
@@ -41,7 +41,11 @@ import {
|
||||
SizeVariables,
|
||||
StyleVariables,
|
||||
} from '@blocksuite/affine/shared/theme';
|
||||
import { openFileOrFiles, printToPdf } from '@blocksuite/affine/shared/utils';
|
||||
import {
|
||||
openFilesWith,
|
||||
openSingleFileWith,
|
||||
printToPdf,
|
||||
} from '@blocksuite/affine/shared/utils';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { GfxControllerIdentifier } from '@blocksuite/affine/std/gfx';
|
||||
import {
|
||||
@@ -339,10 +343,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
||||
|
||||
private async _importHTML() {
|
||||
try {
|
||||
const files = await openFileOrFiles({
|
||||
acceptType: 'Html',
|
||||
multiple: true,
|
||||
});
|
||||
const files = await openFilesWith('Html');
|
||||
|
||||
if (!files) return;
|
||||
|
||||
@@ -373,7 +374,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
||||
|
||||
private async _importHTMLZip() {
|
||||
try {
|
||||
const file = await openFileOrFiles({ acceptType: 'Zip' });
|
||||
const file = await openSingleFileWith('Zip');
|
||||
if (!file) return;
|
||||
const result = await HtmlTransformer.importHTMLZip({
|
||||
collection: this.collection,
|
||||
@@ -393,10 +394,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
||||
|
||||
private async _importMarkdown() {
|
||||
try {
|
||||
const files = await openFileOrFiles({
|
||||
acceptType: 'Markdown',
|
||||
multiple: true,
|
||||
});
|
||||
const files = await openFilesWith('Markdown');
|
||||
|
||||
if (!files) return;
|
||||
|
||||
@@ -427,7 +425,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
||||
|
||||
private async _importMarkdownZip() {
|
||||
try {
|
||||
const file = await openFileOrFiles({ acceptType: 'Zip' });
|
||||
const file = await openSingleFileWith('Zip');
|
||||
if (!file) return;
|
||||
const result = await MarkdownTransformer.importMarkdownZip({
|
||||
collection: this.collection,
|
||||
@@ -447,10 +445,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
||||
|
||||
private async _importNotionHTML() {
|
||||
try {
|
||||
const file = await openFileOrFiles({
|
||||
acceptType: 'Html',
|
||||
multiple: false,
|
||||
});
|
||||
const file = await openSingleFileWith('Html');
|
||||
if (!file) return;
|
||||
const doc = this.editor.doc;
|
||||
const job = doc.getTransformer([defaultImageProxyMiddleware]);
|
||||
@@ -467,7 +462,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
||||
|
||||
private async _importNotionHTMLZip() {
|
||||
try {
|
||||
const file = await openFileOrFiles({ acceptType: 'Zip' });
|
||||
const file = await openSingleFileWith('Zip');
|
||||
if (!file) return;
|
||||
const result = await NotionHtmlTransformer.importNotionZip({
|
||||
collection: this.collection,
|
||||
|
||||
@@ -5,7 +5,7 @@ import track from '@affine/track';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { openFileOrFiles } from '@blocksuite/affine/shared/utils';
|
||||
import { openFilesWith } from '@blocksuite/affine/shared/utils';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { DocMeta } from '@blocksuite/affine/store';
|
||||
import {
|
||||
@@ -159,9 +159,7 @@ export class ChatPanelAddPopover extends SignalWatcher(
|
||||
};
|
||||
|
||||
private readonly _addFileChip = async () => {
|
||||
const files = await openFileOrFiles({
|
||||
multiple: true,
|
||||
});
|
||||
const files = await openFilesWith();
|
||||
if (!files || files.length === 0) return;
|
||||
|
||||
const images = files.filter(file => file.type.startsWith('image/'));
|
||||
|
||||
@@ -3,7 +3,7 @@ import { stopPropagation } from '@affine/core/utils';
|
||||
import type { CopilotSessionType } from '@affine/graphql';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { openFileOrFiles } from '@blocksuite/affine/shared/utils';
|
||||
import { openFilesWith } from '@blocksuite/affine/shared/utils';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import {
|
||||
CloseIcon,
|
||||
@@ -533,10 +533,7 @@ export class AIChatInput extends SignalWatcher(WithDisposable(LitElement)) {
|
||||
private readonly _uploadImageFiles = async (_e: MouseEvent) => {
|
||||
if (this._isImageUploadDisabled) return;
|
||||
|
||||
const images = await openFileOrFiles({
|
||||
acceptType: 'Images',
|
||||
multiple: true,
|
||||
});
|
||||
const images = await openFilesWith('Images');
|
||||
if (!images) return;
|
||||
if (this.chatContextValue.images.length + images.length > MAX_IMAGE_COUNT) {
|
||||
toast(`You can only upload up to ${MAX_IMAGE_COUNT} images`);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type DataViewCellLifeCycle,
|
||||
EditorHostKey,
|
||||
} from '@blocksuite/affine/blocks/database';
|
||||
import { openFileOrFiles } from '@blocksuite/affine/shared/utils';
|
||||
import { openFilesWith } from '@blocksuite/affine/shared/utils';
|
||||
import type { BlobEngine } from '@blocksuite/affine/sync';
|
||||
import {
|
||||
DeleteIcon,
|
||||
@@ -402,7 +402,7 @@ const FileCellComponent: ForwardRefRenderFunction<
|
||||
>
|
||||
<Button
|
||||
onClick={() => {
|
||||
openFileOrFiles({ multiple: true })
|
||||
openFilesWith()
|
||||
.then(files => {
|
||||
files?.forEach(file => {
|
||||
manager.uploadFile(file);
|
||||
@@ -447,7 +447,7 @@ const FileCellComponent: ForwardRefRenderFunction<
|
||||
<div className={styles.uploadContainer}>
|
||||
<div
|
||||
onClick={() => {
|
||||
openFileOrFiles({ multiple: true })
|
||||
openFilesWith()
|
||||
.then(files => {
|
||||
files?.forEach(file => {
|
||||
manager.uploadFile(file);
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import track from '@affine/track';
|
||||
import { openFileOrFiles } from '@blocksuite/affine/shared/utils';
|
||||
import { openFilesWith } from '@blocksuite/affine/shared/utils';
|
||||
import type { Workspace } from '@blocksuite/affine/store';
|
||||
import {
|
||||
HtmlTransformer,
|
||||
@@ -56,7 +56,7 @@ type ImportConfig = {
|
||||
fileOptions: { acceptType: AcceptType; multiple: boolean };
|
||||
importFunction: (
|
||||
docCollection: Workspace,
|
||||
file: File | File[]
|
||||
files: File[]
|
||||
) => Promise<ImportResult>;
|
||||
};
|
||||
|
||||
@@ -134,9 +134,6 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
||||
markdown: {
|
||||
fileOptions: { acceptType: 'Markdown', multiple: true },
|
||||
importFunction: async (docCollection, files) => {
|
||||
if (!Array.isArray(files)) {
|
||||
throw new Error('Expected an array of files for markdown files import');
|
||||
}
|
||||
const docIds: string[] = [];
|
||||
for (const file of files) {
|
||||
const text = await file.text();
|
||||
@@ -157,8 +154,9 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
||||
},
|
||||
markdownZip: {
|
||||
fileOptions: { acceptType: 'Zip', multiple: false },
|
||||
importFunction: async (docCollection, file) => {
|
||||
if (Array.isArray(file)) {
|
||||
importFunction: async (docCollection, files) => {
|
||||
const file = files.length === 1 ? files[0] : null;
|
||||
if (!file) {
|
||||
throw new Error('Expected a single zip file for markdownZip import');
|
||||
}
|
||||
const docIds = await MarkdownTransformer.importMarkdownZip({
|
||||
@@ -175,9 +173,6 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
||||
html: {
|
||||
fileOptions: { acceptType: 'Html', multiple: true },
|
||||
importFunction: async (docCollection, files) => {
|
||||
if (!Array.isArray(files)) {
|
||||
throw new Error('Expected an array of files for html files import');
|
||||
}
|
||||
const docIds: string[] = [];
|
||||
for (const file of files) {
|
||||
const text = await file.text();
|
||||
@@ -198,8 +193,9 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
||||
},
|
||||
notion: {
|
||||
fileOptions: { acceptType: 'Zip', multiple: false },
|
||||
importFunction: async (docCollection, file) => {
|
||||
if (Array.isArray(file)) {
|
||||
importFunction: async (docCollection, files) => {
|
||||
const file = files.length === 1 ? files[0] : null;
|
||||
if (!file) {
|
||||
throw new Error('Expected a single zip file for notion import');
|
||||
}
|
||||
const { entryId, pageIds, isWorkspaceFile } =
|
||||
@@ -218,8 +214,9 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
||||
},
|
||||
snapshot: {
|
||||
fileOptions: { acceptType: 'Zip', multiple: false },
|
||||
importFunction: async (docCollection, file) => {
|
||||
if (Array.isArray(file)) {
|
||||
importFunction: async (docCollection, files) => {
|
||||
const file = files.length === 1 ? files[0] : null;
|
||||
if (!file) {
|
||||
throw new Error('Expected a single zip file for snapshot import');
|
||||
}
|
||||
const docIds = (
|
||||
@@ -412,9 +409,10 @@ export const ImportDialog = ({
|
||||
setImportError(null);
|
||||
try {
|
||||
const importConfig = importConfigs[type];
|
||||
const file = await openFileOrFiles(importConfig.fileOptions);
|
||||
const { acceptType, multiple } = importConfig.fileOptions;
|
||||
const files = await openFilesWith(acceptType, multiple);
|
||||
|
||||
if (!file || (Array.isArray(file) && file.length === 0)) {
|
||||
if (!files || files.length === 0) {
|
||||
throw new Error(
|
||||
t['com.affine.import.status.failed.message.no-file-selected']()
|
||||
);
|
||||
@@ -427,7 +425,7 @@ export const ImportDialog = ({
|
||||
});
|
||||
|
||||
const { docIds, entryId, isWorkspaceFile } =
|
||||
await importConfig.importFunction(docCollection, file);
|
||||
await importConfig.importFunction(docCollection, files);
|
||||
|
||||
setImportResult({ docIds, entryId, isWorkspaceFile });
|
||||
setStatus('success');
|
||||
|
||||
Reference in New Issue
Block a user