chore(core): remove snapshot import export feature flag (#8865)

This commit is contained in:
Chen
2024-11-20 15:06:20 +08:00
committed by GitHub
parent 47243247b9
commit b87c3840f3
19 changed files with 120 additions and 331 deletions
@@ -11,11 +11,7 @@ import { useBlockSuiteMetaHelper } from '@affine/core/components/hooks/affine/us
import { useEnableCloud } from '@affine/core/components/hooks/affine/use-enable-cloud';
import { useExportPage } from '@affine/core/components/hooks/affine/use-export-page';
import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta';
import {
Export,
MoveToTrash,
Snapshot,
} from '@affine/core/components/page-list';
import { Export, MoveToTrash } from '@affine/core/components/page-list';
import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
import { useDetailPageHeaderResponsive } from '@affine/core/desktop/pages/workspace/detail-page/use-header-responsive';
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
@@ -44,7 +40,6 @@ import {
TocIcon,
} from '@blocksuite/icons/rc';
import {
FeatureFlagService,
useLiveData,
useService,
useServiceOptional,
@@ -84,10 +79,6 @@ export const PageHeaderMenuButton = ({
const primaryMode = useLiveData(editorService.editor.doc.primaryMode$);
const workbench = useService(WorkbenchService).workbench;
const featureFlagService = useService(FeatureFlagService);
const enableSnapshotImportExport = useLiveData(
featureFlagService.flags.enable_snapshot_import_export.$
);
const openInAppService = useServiceOptional(OpenInAppService);
const { favorite, toggleFavorite } = useFavorite(pageId);
@@ -402,7 +393,6 @@ export const PageHeaderMenuButton = ({
{t['Import']()}
</MenuItem>
<Export exportHandler={exportHandler} pageMode={currentMode} />
{enableSnapshotImportExport && <Snapshot />}
<MenuSeparator />
<MoveToTrash
data-testid="editor-option-menu-delete"
@@ -260,6 +260,23 @@ export function useRegisterBlocksuiteEditorCommands(editor: Editor) {
})
);
unsubs.push(
registerAffineCommand({
id: `editor:${mode}-export-to-snapshot`,
preconditionStrategy,
category: `editor:${mode}`,
icon: mode === 'page' ? <PageIcon /> : <EdgelessIcon />,
label: t['Export to Snapshot'](),
async run() {
track.$.cmdk.editor.export({
type: 'snapshot',
});
exportHandler('snapshot');
},
})
);
unsubs.push(
registerAffineCommand({
id: `editor:${mode}-move-to-trash`,
@@ -6,6 +6,7 @@ import {
ExportToHtmlIcon,
ExportToMarkdownIcon,
ExportToPngIcon,
PageIcon,
PrinterIcon,
} from '@blocksuite/icons/rc';
import type { ReactNode } from 'react';
@@ -22,7 +23,9 @@ interface ExportMenuItemProps<T> {
}
interface ExportProps {
exportHandler: (type: 'pdf' | 'html' | 'png' | 'markdown') => void;
exportHandler: (
type: 'pdf' | 'html' | 'png' | 'markdown' | 'snapshot'
) => void;
pageMode?: 'page' | 'edgeless';
className?: string;
}
@@ -94,6 +97,13 @@ export const ExportMenuItems = ({
icon={<ExportToMarkdownIcon />}
label={t['Export to Markdown']()}
/>
<ExportMenuItem
onSelect={() => exportHandler('snapshot')}
className={className}
type="snapshot"
icon={<PageIcon />}
label={t['Export to Snapshot']()}
/>
</>
);
};
@@ -2,4 +2,3 @@ export * from './disable-public-sharing';
export * from './export';
// export * from './MoveTo';
export * from './move-to-trash';
export * from './snapshot';
@@ -1,223 +0,0 @@
import { MenuItem, MenuSeparator, MenuSub, notify } from '@affine/component';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { useI18n } from '@affine/i18n';
import track from '@affine/track';
import { openFileOrFiles, ZipTransformer } from '@blocksuite/affine/blocks';
import type { Doc } from '@blocksuite/affine/store';
import { ExportIcon, ImportIcon, ToneIcon } from '@blocksuite/icons/rc';
import {
FeatureFlagService,
useService,
WorkspaceService,
} from '@toeverything/infra';
import { type ReactNode, useCallback } from 'react';
import { useExportPage } from '../../hooks/affine/use-export-page';
import { useAsyncCallback } from '../../hooks/affine-async-hooks';
import { transitionStyle } from './index.css';
interface SnapshotMenuItemsProps {
snapshotActionHandler: (action: 'import' | 'export' | 'disable') => void;
className?: string;
}
interface SnapshotMenuItemProps<T> {
onSelect: () => void;
className?: string;
type: T;
icon: ReactNode;
label: string;
}
interface SnapshotProps {
className?: string;
}
export function SnapshotMenuItem<T>({
onSelect,
className,
type,
icon,
label,
}: SnapshotMenuItemProps<T>) {
return (
<MenuItem
className={className}
data-testid={`snapshot-${type}`}
onSelect={onSelect}
block
prefixIcon={icon}
>
{label}
</MenuItem>
);
}
export const DisableSnapshotMenuItems = ({
snapshotActionHandler,
className = transitionStyle,
}: SnapshotMenuItemsProps) => {
const t = useI18n();
return (
<SnapshotMenuItem
onSelect={() => snapshotActionHandler('disable')}
className={className}
type="disable"
icon={<ToneIcon />}
label={t['Disable Snapshot']()}
/>
);
};
export const SnapshotMenuItems = ({
snapshotActionHandler,
className = transitionStyle,
}: SnapshotMenuItemsProps) => {
const t = useI18n();
return (
<>
<SnapshotMenuItem
onSelect={() => snapshotActionHandler('import')}
className={className}
type="import"
icon={<ImportIcon />}
label={t['Import']()}
/>
<SnapshotMenuItem
onSelect={() => snapshotActionHandler('export')}
className={className}
type="export"
icon={<ExportIcon />}
label={t['Export']()}
/>
</>
);
};
export const Snapshot = ({ className }: SnapshotProps) => {
const t = useI18n();
const workspace = useService(WorkspaceService).workspace;
const docCollection = workspace.docCollection;
const workbench = useService(WorkbenchService).workbench;
const exportHandler = useExportPage();
const featureFlagService = useService(FeatureFlagService);
const importSnapshot = useCallback(async () => {
try {
const file = await openFileOrFiles({ acceptType: 'Zip' });
if (!file) return null;
track.$.header.snapshot.import({
type: 'snapshot',
status: 'importing',
});
const importedDocs = (
await ZipTransformer.importDocs(docCollection, file)
).filter(doc => doc !== undefined);
if (importedDocs.length === 0) {
notify.error({
title: 'Import Snapshot Failed',
message: 'No valid documents found in the imported file.',
});
return null;
}
notify.success({
title: 'Imported Snapshot Successfully',
message: `Imported ${importedDocs.length} doc(s)`,
});
track.$.header.snapshot.import({
type: 'snapshot',
status: 'success',
result: {
docCount: importedDocs.length,
},
});
return importedDocs;
} catch (error) {
console.error('Error importing snapshot:', error);
notify.error({
title: 'Import Snapshot Failed',
message: 'Failed to import snapshot. Please try again.',
});
track.$.header.snapshot.import({
type: 'snapshot',
status: 'failed',
error: error instanceof Error ? error.message : undefined,
});
return null;
}
}, [docCollection]);
const openImportedDocs = useCallback(
(importedDocs: Doc[]) => {
if (importedDocs.length > 1) {
workbench.openAll();
} else if (importedDocs[0]?.id) {
workbench.openDoc(importedDocs[0].id);
}
},
[workbench]
);
const handleImportSnapshot = useAsyncCallback(async () => {
const importedDocs = await importSnapshot();
if (importedDocs) {
openImportedDocs(importedDocs);
track.$.header.docOptions.import();
track.$.header.actions.createDoc({
control: 'import',
});
}
}, [importSnapshot, openImportedDocs]);
const disableSnapshotActionOption = useCallback(() => {
featureFlagService.flags.enable_snapshot_import_export.set(false);
}, [featureFlagService]);
const snapshotActionHandler = useCallback(
(action: 'import' | 'export' | 'disable') => {
switch (action) {
case 'import':
return handleImportSnapshot();
case 'export':
track.$.header.snapshot.export({
type: 'snapshot',
});
return exportHandler('snapshot');
case 'disable':
return disableSnapshotActionOption();
}
},
[handleImportSnapshot, exportHandler, disableSnapshotActionOption]
);
const items = (
<>
<SnapshotMenuItems
snapshotActionHandler={snapshotActionHandler}
className={className}
/>
<MenuSeparator />
<DisableSnapshotMenuItems
snapshotActionHandler={snapshotActionHandler}
className={className}
/>
</>
);
return (
<MenuSub
items={items}
triggerOptions={{
className: transitionStyle,
prefixIcon: <ToneIcon />,
'data-testid': 'snapshot-menu',
}}
subOptions={{}}
>
{t['Snapshot']()}
</MenuSub>
);
};