-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add snapshot import export config (#8584)
- Loading branch information
1 parent
0f9d11f
commit ba3aa7f
Showing
12 changed files
with
279 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
203 changes: 203 additions & 0 deletions
203
packages/frontend/core/src/components/page-list/operation-menu-items/snapshot.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
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; | ||
|
||
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)`, | ||
}); | ||
return importedDocs; | ||
} catch (error) { | ||
console.error('Error importing snapshot:', error); | ||
notify.error({ | ||
title: 'Import Snapshot Failed', | ||
message: 'Failed to import snapshot. Please try again.', | ||
}); | ||
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': | ||
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' as string]: 'snapshot-menu', | ||
}} | ||
subOptions={{}} | ||
> | ||
{t['Snapshot']()} | ||
</MenuSub> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ | |
"ja": 100, | ||
"ko": 89, | ||
"pl": 0, | ||
"pt-BR": 97, | ||
"pt-BR": 96, | ||
"ru": 82, | ||
"sv-SE": 5, | ||
"ur": 3, | ||
|
Oops, something went wrong.