chore(core): remove snapshot import export feature flag (#8865)
This commit is contained in:
@@ -206,16 +206,6 @@ export const AFFINE_FLAGS = {
|
|||||||
configurable: false,
|
configurable: false,
|
||||||
defaultState: isMobile,
|
defaultState: isMobile,
|
||||||
},
|
},
|
||||||
enable_snapshot_import_export: {
|
|
||||||
category: 'affine',
|
|
||||||
displayName:
|
|
||||||
'com.affine.settings.workspace.experimental-features.enable-snapshot-import-export.name',
|
|
||||||
description:
|
|
||||||
'com.affine.settings.workspace.experimental-features.enable-snapshot-import-export.description',
|
|
||||||
hide: true,
|
|
||||||
configurable: true,
|
|
||||||
defaultState: false,
|
|
||||||
},
|
|
||||||
} satisfies { [key in string]: FlagInfo };
|
} satisfies { [key in string]: FlagInfo };
|
||||||
|
|
||||||
export type AFFINE_FLAGS = typeof AFFINE_FLAGS;
|
export type AFFINE_FLAGS = typeof AFFINE_FLAGS;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@blocksuite/affine": "0.17.32",
|
"@blocksuite/affine": "0.17.32",
|
||||||
"@blocksuite/icons": "^2.1.69",
|
"@blocksuite/icons": "^2.1.70",
|
||||||
"@capacitor/android": "^6.1.2",
|
"@capacitor/android": "^6.1.2",
|
||||||
"@capacitor/core": "^6.1.2",
|
"@capacitor/core": "^6.1.2",
|
||||||
"@sentry/react": "^8.0.0",
|
"@sentry/react": "^8.0.0",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@blocksuite/affine": "0.17.32",
|
"@blocksuite/affine": "0.17.32",
|
||||||
"@blocksuite/icons": "^2.1.69",
|
"@blocksuite/icons": "^2.1.70",
|
||||||
"@capacitor/app": "^6.0.1",
|
"@capacitor/app": "^6.0.1",
|
||||||
"@capacitor/browser": "^6.0.3",
|
"@capacitor/browser": "^6.0.3",
|
||||||
"@capacitor/core": "^6.1.2",
|
"@capacitor/core": "^6.1.2",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"@affine/core": "workspace:*",
|
"@affine/core": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@blocksuite/affine": "0.17.32",
|
"@blocksuite/affine": "0.17.32",
|
||||||
"@blocksuite/icons": "^2.1.69",
|
"@blocksuite/icons": "^2.1.70",
|
||||||
"@sentry/react": "^8.0.0",
|
"@sentry/react": "^8.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@blocksuite/affine": "*",
|
"@blocksuite/affine": "*",
|
||||||
"@blocksuite/icons": "2.1.67"
|
"@blocksuite/icons": "2.1.68"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@affine/cli": "workspace:*",
|
"@affine/cli": "workspace:*",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@atlaskit/pragmatic-drag-and-drop": "^1.2.1",
|
"@atlaskit/pragmatic-drag-and-drop": "^1.2.1",
|
||||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
||||||
"@blocksuite/icons": "2.1.69",
|
"@blocksuite/icons": "2.1.70",
|
||||||
"@emotion/react": "^11.11.4",
|
"@emotion/react": "^11.11.4",
|
||||||
"@emotion/styled": "^11.11.5",
|
"@emotion/styled": "^11.11.5",
|
||||||
"@radix-ui/react-avatar": "^1.0.4",
|
"@radix-ui/react-avatar": "^1.0.4",
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@blocksuite/affine": "0.17.32",
|
"@blocksuite/affine": "0.17.32",
|
||||||
"@blocksuite/icons": "2.1.69",
|
"@blocksuite/icons": "2.1.70",
|
||||||
"@chromatic-com/storybook": "^3.0.0",
|
"@chromatic-com/storybook": "^3.0.0",
|
||||||
"@storybook/addon-essentials": "^8.2.9",
|
"@storybook/addon-essentials": "^8.2.9",
|
||||||
"@storybook/addon-interactions": "^8.2.9",
|
"@storybook/addon-interactions": "^8.2.9",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"@affine/templates": "workspace:*",
|
"@affine/templates": "workspace:*",
|
||||||
"@affine/track": "workspace:*",
|
"@affine/track": "workspace:*",
|
||||||
"@blocksuite/affine": "0.17.32",
|
"@blocksuite/affine": "0.17.32",
|
||||||
"@blocksuite/icons": "2.1.69",
|
"@blocksuite/icons": "2.1.70",
|
||||||
"@capacitor/app": "^6.0.1",
|
"@capacitor/app": "^6.0.1",
|
||||||
"@capacitor/browser": "^6.0.3",
|
"@capacitor/browser": "^6.0.3",
|
||||||
"@dnd-kit/core": "^6.1.0",
|
"@dnd-kit/core": "^6.1.0",
|
||||||
|
|||||||
@@ -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 { useEnableCloud } from '@affine/core/components/hooks/affine/use-enable-cloud';
|
||||||
import { useExportPage } from '@affine/core/components/hooks/affine/use-export-page';
|
import { useExportPage } from '@affine/core/components/hooks/affine/use-export-page';
|
||||||
import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta';
|
import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta';
|
||||||
import {
|
import { Export, MoveToTrash } from '@affine/core/components/page-list';
|
||||||
Export,
|
|
||||||
MoveToTrash,
|
|
||||||
Snapshot,
|
|
||||||
} from '@affine/core/components/page-list';
|
|
||||||
import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
|
import { IsFavoriteIcon } from '@affine/core/components/pure/icons';
|
||||||
import { useDetailPageHeaderResponsive } from '@affine/core/desktop/pages/workspace/detail-page/use-header-responsive';
|
import { useDetailPageHeaderResponsive } from '@affine/core/desktop/pages/workspace/detail-page/use-header-responsive';
|
||||||
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||||
@@ -44,7 +40,6 @@ import {
|
|||||||
TocIcon,
|
TocIcon,
|
||||||
} from '@blocksuite/icons/rc';
|
} from '@blocksuite/icons/rc';
|
||||||
import {
|
import {
|
||||||
FeatureFlagService,
|
|
||||||
useLiveData,
|
useLiveData,
|
||||||
useService,
|
useService,
|
||||||
useServiceOptional,
|
useServiceOptional,
|
||||||
@@ -84,10 +79,6 @@ export const PageHeaderMenuButton = ({
|
|||||||
const primaryMode = useLiveData(editorService.editor.doc.primaryMode$);
|
const primaryMode = useLiveData(editorService.editor.doc.primaryMode$);
|
||||||
|
|
||||||
const workbench = useService(WorkbenchService).workbench;
|
const workbench = useService(WorkbenchService).workbench;
|
||||||
const featureFlagService = useService(FeatureFlagService);
|
|
||||||
const enableSnapshotImportExport = useLiveData(
|
|
||||||
featureFlagService.flags.enable_snapshot_import_export.$
|
|
||||||
);
|
|
||||||
const openInAppService = useServiceOptional(OpenInAppService);
|
const openInAppService = useServiceOptional(OpenInAppService);
|
||||||
|
|
||||||
const { favorite, toggleFavorite } = useFavorite(pageId);
|
const { favorite, toggleFavorite } = useFavorite(pageId);
|
||||||
@@ -402,7 +393,6 @@ export const PageHeaderMenuButton = ({
|
|||||||
{t['Import']()}
|
{t['Import']()}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Export exportHandler={exportHandler} pageMode={currentMode} />
|
<Export exportHandler={exportHandler} pageMode={currentMode} />
|
||||||
{enableSnapshotImportExport && <Snapshot />}
|
|
||||||
<MenuSeparator />
|
<MenuSeparator />
|
||||||
<MoveToTrash
|
<MoveToTrash
|
||||||
data-testid="editor-option-menu-delete"
|
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(
|
unsubs.push(
|
||||||
registerAffineCommand({
|
registerAffineCommand({
|
||||||
id: `editor:${mode}-move-to-trash`,
|
id: `editor:${mode}-move-to-trash`,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
ExportToHtmlIcon,
|
ExportToHtmlIcon,
|
||||||
ExportToMarkdownIcon,
|
ExportToMarkdownIcon,
|
||||||
ExportToPngIcon,
|
ExportToPngIcon,
|
||||||
|
PageIcon,
|
||||||
PrinterIcon,
|
PrinterIcon,
|
||||||
} from '@blocksuite/icons/rc';
|
} from '@blocksuite/icons/rc';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
@@ -22,7 +23,9 @@ interface ExportMenuItemProps<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ExportProps {
|
interface ExportProps {
|
||||||
exportHandler: (type: 'pdf' | 'html' | 'png' | 'markdown') => void;
|
exportHandler: (
|
||||||
|
type: 'pdf' | 'html' | 'png' | 'markdown' | 'snapshot'
|
||||||
|
) => void;
|
||||||
pageMode?: 'page' | 'edgeless';
|
pageMode?: 'page' | 'edgeless';
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
@@ -94,6 +97,13 @@ export const ExportMenuItems = ({
|
|||||||
icon={<ExportToMarkdownIcon />}
|
icon={<ExportToMarkdownIcon />}
|
||||||
label={t['Export to Markdown']()}
|
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 './export';
|
||||||
// export * from './MoveTo';
|
// export * from './MoveTo';
|
||||||
export * from './move-to-trash';
|
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>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -8,6 +8,7 @@ import { UrlService } from '@affine/core/modules/url';
|
|||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import track from '@affine/track';
|
import track from '@affine/track';
|
||||||
import {
|
import {
|
||||||
|
HtmlTransformer,
|
||||||
MarkdownTransformer,
|
MarkdownTransformer,
|
||||||
NotionHtmlTransformer,
|
NotionHtmlTransformer,
|
||||||
openFileOrFiles,
|
openFileOrFiles,
|
||||||
@@ -15,24 +16,22 @@ import {
|
|||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
import type { DocCollection } from '@blocksuite/affine/store';
|
import type { DocCollection } from '@blocksuite/affine/store';
|
||||||
import {
|
import {
|
||||||
|
ExportToHtmlIcon,
|
||||||
ExportToMarkdownIcon,
|
ExportToMarkdownIcon,
|
||||||
HelpIcon,
|
HelpIcon,
|
||||||
NotionIcon,
|
NotionIcon,
|
||||||
|
PageIcon,
|
||||||
|
ZipIcon,
|
||||||
} from '@blocksuite/icons/rc';
|
} from '@blocksuite/icons/rc';
|
||||||
import {
|
import { useService, WorkspaceService } from '@toeverything/infra';
|
||||||
FeatureFlagService,
|
|
||||||
useLiveData,
|
|
||||||
useService,
|
|
||||||
WorkspaceService,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
import { cssVar } from '@toeverything/theme';
|
import { cssVar } from '@toeverything/theme';
|
||||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||||
import { type ReactElement, useCallback, useState } from 'react';
|
import { type ReactElement, useCallback, useState } from 'react';
|
||||||
|
|
||||||
import * as style from './styles.css';
|
import * as style from './styles.css';
|
||||||
|
|
||||||
type ImportType = 'markdown' | 'markdownZip' | 'notion' | 'snapshot';
|
type ImportType = 'markdown' | 'markdownZip' | 'notion' | 'snapshot' | 'html';
|
||||||
type AcceptType = 'Markdown' | 'Zip';
|
type AcceptType = 'Markdown' | 'Zip' | 'Html';
|
||||||
type Status = 'idle' | 'importing' | 'success' | 'error';
|
type Status = 'idle' | 'importing' | 'success' | 'error';
|
||||||
type ImportResult = {
|
type ImportResult = {
|
||||||
docIds: string[];
|
docIds: string[];
|
||||||
@@ -68,14 +67,31 @@ const importOptions = [
|
|||||||
key: 'markdownZip',
|
key: 'markdownZip',
|
||||||
label: 'com.affine.import.markdown-with-media-files',
|
label: 'com.affine.import.markdown-with-media-files',
|
||||||
prefixIcon: (
|
prefixIcon: (
|
||||||
<ExportToMarkdownIcon
|
<ZipIcon color={cssVarV2('icon/primary')} width={20} height={20} />
|
||||||
|
),
|
||||||
|
suffixIcon: (
|
||||||
|
<HelpIcon color={cssVarV2('icon/primary')} width={20} height={20} />
|
||||||
|
),
|
||||||
|
suffixTooltip: 'com.affine.import.markdown-with-media-files.tooltip',
|
||||||
|
testId: 'editor-option-menu-import-markdown-with-media',
|
||||||
|
type: 'markdownZip' as ImportType,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'html',
|
||||||
|
label: 'com.affine.import.html-files',
|
||||||
|
prefixIcon: (
|
||||||
|
<ExportToHtmlIcon
|
||||||
color={cssVarV2('icon/primary')}
|
color={cssVarV2('icon/primary')}
|
||||||
width={20}
|
width={20}
|
||||||
height={20}
|
height={20}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
testId: 'editor-option-menu-import-markdown-with-media',
|
suffixIcon: (
|
||||||
type: 'markdownZip' as ImportType,
|
<HelpIcon color={cssVarV2('icon/primary')} width={20} height={20} />
|
||||||
|
),
|
||||||
|
suffixTooltip: 'com.affine.import.html-files.tooltip',
|
||||||
|
testId: 'editor-option-menu-import-html',
|
||||||
|
type: 'html' as ImportType,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'notion',
|
key: 'notion',
|
||||||
@@ -88,6 +104,15 @@ const importOptions = [
|
|||||||
testId: 'editor-option-menu-import-notion',
|
testId: 'editor-option-menu-import-notion',
|
||||||
type: 'notion' as ImportType,
|
type: 'notion' as ImportType,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'snapshot',
|
||||||
|
label: 'com.affine.import.snapshot',
|
||||||
|
prefixIcon: (
|
||||||
|
<PageIcon color={cssVarV2('icon/primary')} width={20} height={20} />
|
||||||
|
),
|
||||||
|
testId: 'editor-option-menu-import-snapshot',
|
||||||
|
type: 'snapshot' as ImportType,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const importConfigs: Record<ImportType, ImportConfig> = {
|
const importConfigs: Record<ImportType, ImportConfig> = {
|
||||||
@@ -128,6 +153,28 @@ 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();
|
||||||
|
const fileName = file.name.split('.').slice(0, -1).join('.');
|
||||||
|
const docId = await HtmlTransformer.importHTMLToDoc({
|
||||||
|
collection: docCollection,
|
||||||
|
html: text,
|
||||||
|
fileName,
|
||||||
|
});
|
||||||
|
if (docId) docIds.push(docId);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
docIds,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
notion: {
|
notion: {
|
||||||
fileOptions: { acceptType: 'Zip', multiple: false },
|
fileOptions: { acceptType: 'Zip', multiple: false },
|
||||||
importFunction: async (docCollection, file) => {
|
importFunction: async (docCollection, file) => {
|
||||||
@@ -200,10 +247,6 @@ const ImportOptions = ({
|
|||||||
onImport: (type: ImportType) => void;
|
onImport: (type: ImportType) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const featureFlagService = useService(FeatureFlagService);
|
|
||||||
const enableSnapshotImportExport = useLiveData(
|
|
||||||
featureFlagService.flags.enable_snapshot_import_export.$
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -232,14 +275,6 @@ const ImportOptions = ({
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{enableSnapshotImportExport && (
|
|
||||||
<div className={style.importModalTip}>
|
|
||||||
{t['Import']()}{' '}
|
|
||||||
<span className={style.link} onClick={() => onImport('snapshot')}>
|
|
||||||
{t['Snapshot']()}.
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className={style.importModalTip}>
|
<div className={style.importModalTip}>
|
||||||
{t['com.affine.import.modal.tip']()}{' '}
|
{t['com.affine.import.modal.tip']()}{' '}
|
||||||
<a
|
<a
|
||||||
@@ -373,6 +408,9 @@ export const ImportDialog = ({
|
|||||||
docCount: docIds.length,
|
docCount: docIds.length,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
track.$.importModal.$.createDoc({
|
||||||
|
control: 'import',
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage =
|
const errorMessage =
|
||||||
error instanceof Error ? error.message : 'Unknown error occurred';
|
error instanceof Error ? error.message : 'Unknown error occurred';
|
||||||
|
|||||||
@@ -10,11 +10,7 @@ import { appIconMap, appNames } from '@affine/core/utils/channel';
|
|||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { mixpanel } from '@affine/track';
|
import { mixpanel } from '@affine/track';
|
||||||
import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons/rc';
|
import { ArrowRightSmallIcon, OpenInNewIcon } from '@blocksuite/icons/rc';
|
||||||
import {
|
import { useServices } from '@toeverything/infra';
|
||||||
FeatureFlagService,
|
|
||||||
useLiveData,
|
|
||||||
useServices,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { useAppSettingHelper } from '../../../../../components/hooks/affine/use-app-setting-helper';
|
import { useAppSettingHelper } from '../../../../../components/hooks/affine/use-app-setting-helper';
|
||||||
@@ -29,13 +25,9 @@ export const AboutAffine = () => {
|
|||||||
const channel = BUILD_CONFIG.appBuildType;
|
const channel = BUILD_CONFIG.appBuildType;
|
||||||
const appIcon = appIconMap[channel];
|
const appIcon = appIconMap[channel];
|
||||||
const appName = appNames[channel];
|
const appName = appNames[channel];
|
||||||
const { urlService, featureFlagService } = useServices({
|
const { urlService } = useServices({
|
||||||
UrlService,
|
UrlService,
|
||||||
FeatureFlagService,
|
|
||||||
});
|
});
|
||||||
const enableSnapshotImportExport = useLiveData(
|
|
||||||
featureFlagService.flags.enable_snapshot_import_export.$
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSwitchAutoCheck = useCallback(
|
const onSwitchAutoCheck = useCallback(
|
||||||
(checked: boolean) => {
|
(checked: boolean) => {
|
||||||
@@ -65,13 +57,6 @@ export const AboutAffine = () => {
|
|||||||
[updateSettings]
|
[updateSettings]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSwitchSnapshotImportExport = useCallback(
|
|
||||||
(checked: boolean) => {
|
|
||||||
featureFlagService.flags.enable_snapshot_import_export.set(checked);
|
|
||||||
},
|
|
||||||
[featureFlagService]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SettingHeader
|
<SettingHeader
|
||||||
@@ -155,16 +140,6 @@ export const AboutAffine = () => {
|
|||||||
{t['com.affine.aboutAFFiNE.contact.community']()}
|
{t['com.affine.aboutAFFiNE.contact.community']()}
|
||||||
<OpenInNewIcon className="icon" />
|
<OpenInNewIcon className="icon" />
|
||||||
</a>
|
</a>
|
||||||
<SettingRow
|
|
||||||
name={t['com.affine.snapshot.import-export.enable']()}
|
|
||||||
desc={t['com.affine.snapshot.import-export.enable.desc']()}
|
|
||||||
className={styles.snapshotImportExportRow}
|
|
||||||
>
|
|
||||||
<Switch
|
|
||||||
checked={enableSnapshotImportExport}
|
|
||||||
onChange={onSwitchSnapshotImportExport}
|
|
||||||
/>
|
|
||||||
</SettingRow>
|
|
||||||
</SettingWrapper>
|
</SettingWrapper>
|
||||||
<SettingWrapper title={t['com.affine.aboutAFFiNE.community.title']()}>
|
<SettingWrapper title={t['com.affine.aboutAFFiNE.community.title']()}>
|
||||||
<div className={styles.communityWrapper}>
|
<div className={styles.communityWrapper}>
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"ar": 76,
|
"ar": 75,
|
||||||
"ca": 5,
|
"ca": 5,
|
||||||
"da": 6,
|
"da": 6,
|
||||||
"de": 28,
|
"de": 28,
|
||||||
"el-GR": 0,
|
"el-GR": 0,
|
||||||
"en": 100,
|
"en": 100,
|
||||||
"es-AR": 14,
|
"es-AR": 14,
|
||||||
"es-CL": 16,
|
"es-CL": 15,
|
||||||
"es": 14,
|
"es": 14,
|
||||||
"fr": 67,
|
"fr": 67,
|
||||||
"hi": 2,
|
"hi": 2,
|
||||||
"it-IT": 1,
|
"it-IT": 1,
|
||||||
"it": 1,
|
"it": 1,
|
||||||
"ja": 100,
|
"ja": 100,
|
||||||
"ko": 80,
|
"ko": 79,
|
||||||
"pl": 0,
|
"pl": 0,
|
||||||
"pt-BR": 87,
|
"pt-BR": 86,
|
||||||
"ru": 74,
|
"ru": 74,
|
||||||
"sv-SE": 4,
|
"sv-SE": 4,
|
||||||
"ur": 3,
|
"ur": 3,
|
||||||
|
|||||||
@@ -526,8 +526,11 @@
|
|||||||
"com.affine.import-template.dialog.errorLoad": "Failed to load template, please try again.",
|
"com.affine.import-template.dialog.errorLoad": "Failed to load template, please try again.",
|
||||||
"com.affine.import_file": "Support Markdown/Notion",
|
"com.affine.import_file": "Support Markdown/Notion",
|
||||||
"com.affine.import.affine-workspace-data": "AFFiNE workspace data",
|
"com.affine.import.affine-workspace-data": "AFFiNE workspace data",
|
||||||
|
"com.affine.import.html-files": "HTML",
|
||||||
|
"com.affine.import.html-files.tooltip": "This is an experimental feature that is not perfect and may cause your data to be missing after import.",
|
||||||
"com.affine.import.markdown-files": "Markdown files (.md)",
|
"com.affine.import.markdown-files": "Markdown files (.md)",
|
||||||
"com.affine.import.markdown-with-media-files": "Markdown with media files (.zip)",
|
"com.affine.import.markdown-with-media-files": "Markdown with media files (.zip)",
|
||||||
|
"com.affine.import.markdown-with-media-files.tooltip": "Please upload a markdown zip file with attachments, experimental function, there may be data loss.",
|
||||||
"com.affine.import.modal.tip": "If you'd like to request support for additional file types, feel free to let us know on",
|
"com.affine.import.modal.tip": "If you'd like to request support for additional file types, feel free to let us know on",
|
||||||
"com.affine.import.notion": "Notion",
|
"com.affine.import.notion": "Notion",
|
||||||
"com.affine.import.notion.tooltip": "Import your Notion data. Supported import formats: HTML with subpages.",
|
"com.affine.import.notion.tooltip": "Import your Notion data. Supported import formats: HTML with subpages.",
|
||||||
|
|||||||
@@ -526,8 +526,11 @@
|
|||||||
"com.affine.import-template.dialog.errorLoad": "读取模版失败,请重试。",
|
"com.affine.import-template.dialog.errorLoad": "读取模版失败,请重试。",
|
||||||
"com.affine.import_file": "支持 Markdown/Notion",
|
"com.affine.import_file": "支持 Markdown/Notion",
|
||||||
"com.affine.import.affine-workspace-data": "AFFiNE 工作区数据",
|
"com.affine.import.affine-workspace-data": "AFFiNE 工作区数据",
|
||||||
|
"com.affine.import.html-files": "HTML",
|
||||||
|
"com.affine.import.html-files.tooltip": "这是一个实验性功能,可能不完全完美,导入后可能会导致数据丢失。",
|
||||||
"com.affine.import.markdown-files": "Markdown 文件 (.md)",
|
"com.affine.import.markdown-files": "Markdown 文件 (.md)",
|
||||||
"com.affine.import.markdown-with-media-files": "Markdown 文件(带媒体文件) (.zip)",
|
"com.affine.import.markdown-with-media-files": "Markdown 文件(带媒体文件) (.zip)",
|
||||||
|
"com.affine.import.markdown-with-media-files.tooltip": "请上传带有附件的 Markdown 压缩包,这是一个实验性功能,可能不完全完美,导入后可能会导致数据丢失。",
|
||||||
"com.affine.import.modal.tip": "如果您希望请求支持其他文件类型,请随时告诉我们",
|
"com.affine.import.modal.tip": "如果您希望请求支持其他文件类型,请随时告诉我们",
|
||||||
"com.affine.import.notion": "Notion",
|
"com.affine.import.notion": "Notion",
|
||||||
"com.affine.import.notion.tooltip": "导入您的 Notion 数据。支持导入格式:HTML 带子页面。",
|
"com.affine.import.notion.tooltip": "导入您的 Notion 数据。支持导入格式:HTML 带子页面。",
|
||||||
|
|||||||
@@ -526,8 +526,11 @@
|
|||||||
"com.affine.import-template.dialog.errorLoad": "加載模板失敗,請重試。",
|
"com.affine.import-template.dialog.errorLoad": "加載模板失敗,請重試。",
|
||||||
"com.affine.import_file": "支援 Markdown/Notion",
|
"com.affine.import_file": "支援 Markdown/Notion",
|
||||||
"com.affine.import.affine-workspace-data": "AFFiNE 工作區數據",
|
"com.affine.import.affine-workspace-data": "AFFiNE 工作區數據",
|
||||||
|
"com.affine.import.html-files": "HTML",
|
||||||
|
"com.affine.import.html-files.tooltip": "這是一個實驗性功能,可能不完全完美,導入後可能會導致數據丟失。",
|
||||||
"com.affine.import.markdown-files": "Markdown 文件 (.md)",
|
"com.affine.import.markdown-files": "Markdown 文件 (.md)",
|
||||||
"com.affine.import.markdown-with-media-files": "Markdown 文件(帶媒體文件) (.zip)",
|
"com.affine.import.markdown-with-media-files": "Markdown 文件(帶媒體文件) (.zip)",
|
||||||
|
"com.affine.import.markdown-with-media-files.tooltip": "請上傳帶有附件的 Markdown 壓縮包,這是一個實驗性功能,可能不完全完美,導入後可能會導致數據丟失。",
|
||||||
"com.affine.import.modal.tip": "如果您希望請求支持其他文件類型,請隨時告訴我們",
|
"com.affine.import.modal.tip": "如果您希望請求支持其他文件類型,請隨時告訴我們",
|
||||||
"com.affine.import.notion": "Notion",
|
"com.affine.import.notion": "Notion",
|
||||||
"com.affine.import.notion.tooltip": "導入您的 Notion 數據。支持導入格式:HTML 帶子頁面。",
|
"com.affine.import.notion.tooltip": "導入您的 Notion 數據。支持導入格式:HTML 帶子頁面。",
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ const PageEvents = {
|
|||||||
$: ['open', 'close', 'switchPageMode', 'viewPlans'],
|
$: ['open', 'close', 'switchPageMode', 'viewPlans'],
|
||||||
},
|
},
|
||||||
importModal: {
|
importModal: {
|
||||||
$: ['open', 'import'],
|
$: ['open', 'import', 'createDoc'],
|
||||||
},
|
},
|
||||||
paywall: {
|
paywall: {
|
||||||
storage: ['viewPlans'],
|
storage: ['viewPlans'],
|
||||||
|
|||||||
30
yarn.lock
30
yarn.lock
@@ -223,7 +223,7 @@ __metadata:
|
|||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@blocksuite/affine": "npm:0.17.32"
|
"@blocksuite/affine": "npm:0.17.32"
|
||||||
"@blocksuite/icons": "npm:^2.1.69"
|
"@blocksuite/icons": "npm:^2.1.70"
|
||||||
"@capacitor/android": "npm:^6.1.2"
|
"@capacitor/android": "npm:^6.1.2"
|
||||||
"@capacitor/cli": "npm:^6.1.2"
|
"@capacitor/cli": "npm:^6.1.2"
|
||||||
"@capacitor/core": "npm:^6.1.2"
|
"@capacitor/core": "npm:^6.1.2"
|
||||||
@@ -327,7 +327,7 @@ __metadata:
|
|||||||
"@atlaskit/pragmatic-drag-and-drop": "npm:^1.2.1"
|
"@atlaskit/pragmatic-drag-and-drop": "npm:^1.2.1"
|
||||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "npm:^1.0.3"
|
"@atlaskit/pragmatic-drag-and-drop-hitbox": "npm:^1.0.3"
|
||||||
"@blocksuite/affine": "npm:0.17.32"
|
"@blocksuite/affine": "npm:0.17.32"
|
||||||
"@blocksuite/icons": "npm:2.1.69"
|
"@blocksuite/icons": "npm:2.1.70"
|
||||||
"@chromatic-com/storybook": "npm:^3.0.0"
|
"@chromatic-com/storybook": "npm:^3.0.0"
|
||||||
"@emotion/react": "npm:^11.11.4"
|
"@emotion/react": "npm:^11.11.4"
|
||||||
"@emotion/styled": "npm:^11.11.5"
|
"@emotion/styled": "npm:^11.11.5"
|
||||||
@@ -382,7 +382,7 @@ __metadata:
|
|||||||
zod: "npm:^3.22.4"
|
zod: "npm:^3.22.4"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@blocksuite/affine": "*"
|
"@blocksuite/affine": "*"
|
||||||
"@blocksuite/icons": 2.1.67
|
"@blocksuite/icons": 2.1.68
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@@ -410,7 +410,7 @@ __metadata:
|
|||||||
"@affine/templates": "workspace:*"
|
"@affine/templates": "workspace:*"
|
||||||
"@affine/track": "workspace:*"
|
"@affine/track": "workspace:*"
|
||||||
"@blocksuite/affine": "npm:0.17.32"
|
"@blocksuite/affine": "npm:0.17.32"
|
||||||
"@blocksuite/icons": "npm:2.1.69"
|
"@blocksuite/icons": "npm:2.1.70"
|
||||||
"@capacitor/app": "npm:^6.0.1"
|
"@capacitor/app": "npm:^6.0.1"
|
||||||
"@capacitor/browser": "npm:^6.0.3"
|
"@capacitor/browser": "npm:^6.0.3"
|
||||||
"@dnd-kit/core": "npm:^6.1.0"
|
"@dnd-kit/core": "npm:^6.1.0"
|
||||||
@@ -622,7 +622,7 @@ __metadata:
|
|||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@blocksuite/affine": "npm:0.17.32"
|
"@blocksuite/affine": "npm:0.17.32"
|
||||||
"@blocksuite/icons": "npm:^2.1.69"
|
"@blocksuite/icons": "npm:^2.1.70"
|
||||||
"@capacitor/app": "npm:^6.0.1"
|
"@capacitor/app": "npm:^6.0.1"
|
||||||
"@capacitor/browser": "npm:^6.0.3"
|
"@capacitor/browser": "npm:^6.0.3"
|
||||||
"@capacitor/cli": "npm:^6.1.2"
|
"@capacitor/cli": "npm:^6.1.2"
|
||||||
@@ -648,7 +648,7 @@ __metadata:
|
|||||||
"@affine/core": "workspace:*"
|
"@affine/core": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@blocksuite/affine": "npm:0.17.32"
|
"@blocksuite/affine": "npm:0.17.32"
|
||||||
"@blocksuite/icons": "npm:^2.1.69"
|
"@blocksuite/icons": "npm:^2.1.70"
|
||||||
"@sentry/react": "npm:^8.0.0"
|
"@sentry/react": "npm:^8.0.0"
|
||||||
"@types/react": "npm:^18.2.75"
|
"@types/react": "npm:^18.2.75"
|
||||||
"@types/react-dom": "npm:^18.2.24"
|
"@types/react-dom": "npm:^18.2.24"
|
||||||
@@ -2815,23 +2815,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@blocksuite/icons@npm:2.1.69":
|
"@blocksuite/icons@npm:2.1.70, @blocksuite/icons@npm:^2.1.68, @blocksuite/icons@npm:^2.1.70":
|
||||||
version: 2.1.69
|
|
||||||
resolution: "@blocksuite/icons@npm:2.1.69"
|
|
||||||
peerDependencies:
|
|
||||||
"@types/react": ^18.0.25
|
|
||||||
lit: ^3.1.1
|
|
||||||
react: ^18.2.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
lit:
|
|
||||||
optional: true
|
|
||||||
react:
|
|
||||||
optional: true
|
|
||||||
checksum: 10/c2d8e7d72bb950fbaa6de8fd6c67d354932c32c72932c9c6f1132fbde6f2fb865a767ab17035ee3c83fe779b05b09a0d71506c623b17e5f7d1eb7c4bce61df02
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@blocksuite/icons@npm:^2.1.68, @blocksuite/icons@npm:^2.1.69":
|
|
||||||
version: 2.1.70
|
version: 2.1.70
|
||||||
resolution: "@blocksuite/icons@npm:2.1.70"
|
resolution: "@blocksuite/icons@npm:2.1.70"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user