mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-19 19:16:29 +08:00
refactor: workspace manager (#5060)
This commit is contained in:
@@ -4,16 +4,17 @@ import {
|
||||
FavoriteTag,
|
||||
} from '@affine/component/page-list';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { waitForCurrentWorkspaceAtom } from '@affine/workspace/atom';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { usePageHelper } from '../../components/blocksuite/block-suite-page-list/utils';
|
||||
import { useCurrentWorkspace } from '../current/use-current-workspace';
|
||||
import { useBlockSuiteMetaHelper } from './use-block-suite-meta-helper';
|
||||
|
||||
export const useAllPageListConfig = () => {
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const currentWorkspace = useAtomValue(waitForCurrentWorkspaceAtom);
|
||||
const workspace = currentWorkspace.blockSuiteWorkspace;
|
||||
const pageMetas = useBlockSuitePageMeta(workspace);
|
||||
const { isPreferredEdgeless } = usePageHelper(workspace);
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { getIsOwnerQuery } from '@affine/graphql';
|
||||
import { useQueryImmutable } from '@affine/workspace/affine/gql';
|
||||
import type { WorkspaceMetadata } from '@affine/workspace/metadata';
|
||||
|
||||
export function useIsWorkspaceOwner(workspaceId: string) {
|
||||
const { data } = useQueryImmutable({
|
||||
query: getIsOwnerQuery,
|
||||
variables: {
|
||||
workspaceId,
|
||||
},
|
||||
});
|
||||
export function useIsWorkspaceOwner(workspaceMetadata: WorkspaceMetadata) {
|
||||
const { data } = useQueryImmutable(
|
||||
workspaceMetadata.flavour !== WorkspaceFlavour.LOCAL
|
||||
? {
|
||||
query: getIsOwnerQuery,
|
||||
variables: {
|
||||
workspaceId: workspaceMetadata.id,
|
||||
},
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
|
||||
if (workspaceMetadata.flavour === WorkspaceFlavour.LOCAL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return data.isOwner;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { leaveWorkspaceMutation } from '@affine/graphql';
|
||||
import { useMutation } from '@affine/workspace/affine/gql';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useAppHelper } from '../use-workspaces';
|
||||
|
||||
export function useLeaveWorkspace() {
|
||||
const { deleteWorkspaceMeta } = useAppHelper();
|
||||
|
||||
const { trigger: leaveWorkspace } = useMutation({
|
||||
mutation: leaveWorkspaceMutation,
|
||||
});
|
||||
|
||||
return useCallback(
|
||||
async (workspaceId: string, workspaceName: string) => {
|
||||
deleteWorkspaceMeta(workspaceId);
|
||||
|
||||
await leaveWorkspace({
|
||||
workspaceId,
|
||||
workspaceName,
|
||||
sendLeaveMail: true,
|
||||
});
|
||||
},
|
||||
[deleteWorkspaceMeta, leaveWorkspace]
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { toast } from '@affine/component';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { waitForCurrentWorkspaceAtom } from '@affine/workspace/atom';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { EdgelessIcon, HistoryIcon, PageIcon } from '@blocksuite/icons';
|
||||
import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
@@ -8,11 +9,10 @@ import {
|
||||
PreconditionStrategy,
|
||||
registerAffineCommand,
|
||||
} from '@toeverything/infra/command';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
import { pageHistoryModalAtom } from '../../atoms/page-history';
|
||||
import { useCurrentWorkspace } from '../current/use-current-workspace';
|
||||
import { useBlockSuiteMetaHelper } from './use-block-suite-meta-helper';
|
||||
import { useExportPage } from './use-export-page';
|
||||
import { useTrashModalHelper } from './use-trash-modal-helper';
|
||||
@@ -22,7 +22,7 @@ export function useRegisterBlocksuiteEditorCommands(
|
||||
mode: 'page' | 'edgeless'
|
||||
) {
|
||||
const t = useAFFiNEI18N();
|
||||
const [workspace] = useCurrentWorkspace();
|
||||
const workspace = useAtomValue(waitForCurrentWorkspaceAtom);
|
||||
const blockSuiteWorkspace = workspace.blockSuiteWorkspace;
|
||||
const { getPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
|
||||
const currentPage = blockSuiteWorkspace.getPage(pageId);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { toast } from '@affine/component';
|
||||
import type { DraggableTitleCellData } from '@affine/component/page-list';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { waitForCurrentWorkspaceAtom } from '@affine/workspace/atom';
|
||||
import type { DragEndEvent, UniqueIdentifier } from '@dnd-kit/core';
|
||||
import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useCurrentWorkspace } from '../current/use-current-workspace';
|
||||
import { useBlockSuiteMetaHelper } from './use-block-suite-meta-helper';
|
||||
import { useTrashModalHelper } from './use-trash-modal-helper';
|
||||
|
||||
@@ -68,7 +69,7 @@ export function getDragItemId(
|
||||
|
||||
export const useSidebarDrag = () => {
|
||||
const t = useAFFiNEI18N();
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const currentWorkspace = useAtomValue(waitForCurrentWorkspaceAtom);
|
||||
const workspace = currentWorkspace.blockSuiteWorkspace;
|
||||
const { setTrashModal } = useTrashModalHelper(workspace);
|
||||
const { addToFavorite, removeFromFavorite } =
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceAtom,
|
||||
} from '@toeverything/infra/atom';
|
||||
import { waitForCurrentWorkspaceAtom } from '@affine/workspace/atom';
|
||||
import { useBlockSuiteWorkspacePage } from '@toeverything/hooks/use-block-suite-workspace-page';
|
||||
import { currentPageIdAtom } from '@toeverything/infra/atom';
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
export const useCurrentPage = () => {
|
||||
const currentPageId = useAtomValue(currentPageIdAtom);
|
||||
const currentWorkspace = useAtomValue(currentWorkspaceAtom);
|
||||
const currentWorkspace = useAtomValue(waitForCurrentWorkspaceAtom);
|
||||
|
||||
return currentPageId ? currentWorkspace.getPage(currentPageId) : null;
|
||||
return useBlockSuiteWorkspacePage(
|
||||
currentWorkspace?.blockSuiteWorkspace,
|
||||
currentPageId
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import type { SyncEngine, SyncEngineStatus } from '@affine/workspace/providers';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useCurrentWorkspace } from './use-current-workspace';
|
||||
|
||||
export function useCurrentSyncEngine(): SyncEngine | undefined {
|
||||
const [workspace] = useCurrentWorkspace();
|
||||
// FIXME: This is a hack to get the sync engine, we need refactor this in the future.
|
||||
const syncEngine = (
|
||||
workspace.blockSuiteWorkspace.providers[0] as { engine?: SyncEngine }
|
||||
)?.engine;
|
||||
|
||||
return syncEngine;
|
||||
}
|
||||
|
||||
export function useCurrentSyncEngineStatus(): SyncEngineStatus | undefined {
|
||||
const syncEngine = useCurrentSyncEngine();
|
||||
const [status, setStatus] = useState<SyncEngineStatus>();
|
||||
|
||||
useEffect(() => {
|
||||
if (syncEngine) {
|
||||
setStatus(syncEngine.status);
|
||||
return syncEngine.onStatusChange.on(status => {
|
||||
setStatus(status);
|
||||
}).dispose;
|
||||
} else {
|
||||
setStatus(undefined);
|
||||
}
|
||||
return;
|
||||
}, [syncEngine]);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import {
|
||||
currentPageIdAtom,
|
||||
currentWorkspaceIdAtom,
|
||||
} from '@toeverything/infra/atom';
|
||||
import { useAtom, useSetAtom } from 'jotai';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
|
||||
import type { AllWorkspace } from '../../shared';
|
||||
import { useWorkspace, useWorkspaceEffect } from '../use-workspace';
|
||||
|
||||
declare global {
|
||||
/**
|
||||
* @internal debug only
|
||||
*/
|
||||
// eslint-disable-next-line no-var
|
||||
var currentWorkspace: AllWorkspace | undefined;
|
||||
interface WindowEventMap {
|
||||
'affine:workspace:change': CustomEvent<{ id: string }>;
|
||||
}
|
||||
}
|
||||
|
||||
export function useCurrentWorkspace(): [
|
||||
AllWorkspace,
|
||||
(id: string | null) => void,
|
||||
] {
|
||||
const [id, setId] = useAtom(currentWorkspaceIdAtom);
|
||||
assertExists(id);
|
||||
const currentWorkspace = useWorkspace(id);
|
||||
// when you call current workspace, effect is always called
|
||||
useWorkspaceEffect(currentWorkspace.id);
|
||||
useEffect(() => {
|
||||
globalThis.currentWorkspace = currentWorkspace;
|
||||
globalThis.dispatchEvent(
|
||||
new CustomEvent('affine:workspace:change', {
|
||||
detail: { id: currentWorkspace.id },
|
||||
})
|
||||
);
|
||||
}, [currentWorkspace]);
|
||||
const setPageId = useSetAtom(currentPageIdAtom);
|
||||
return [
|
||||
currentWorkspace,
|
||||
useCallback(
|
||||
(id: string | null) => {
|
||||
if (environment.isBrowser && id) {
|
||||
localStorage.setItem('last_workspace_id', id);
|
||||
}
|
||||
setPageId(null);
|
||||
setId(id);
|
||||
},
|
||||
[setId, setPageId]
|
||||
),
|
||||
];
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
import { pushNotificationAtom } from '@affine/component/notification-center';
|
||||
import type { WorkspaceRegistry } from '@affine/env/workspace';
|
||||
import type { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
rootWorkspacesMetadataAtom,
|
||||
workspaceAdaptersAtom,
|
||||
} from '@affine/workspace/atom';
|
||||
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
|
||||
import { currentPageIdAtom } from '@toeverything/infra/atom';
|
||||
import { WorkspaceVersion } from '@toeverything/infra/blocksuite';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
|
||||
import { openSettingModalAtom } from '../../atoms';
|
||||
import { useNavigateHelper } from '../use-navigate-helper';
|
||||
|
||||
export function useOnTransformWorkspace() {
|
||||
const t = useAFFiNEI18N();
|
||||
const setSettingModal = useSetAtom(openSettingModalAtom);
|
||||
const WorkspaceAdapters = useAtomValue(workspaceAdaptersAtom);
|
||||
const setMetadata = useSetAtom(rootWorkspacesMetadataAtom);
|
||||
const { openPage } = useNavigateHelper();
|
||||
const currentPageId = useAtomValue(currentPageIdAtom);
|
||||
const pushNotification = useSetAtom(pushNotificationAtom);
|
||||
|
||||
return useAsyncCallback(
|
||||
async <From extends WorkspaceFlavour, To extends WorkspaceFlavour>(
|
||||
from: From,
|
||||
to: To,
|
||||
workspace: WorkspaceRegistry[From]
|
||||
): Promise<void> => {
|
||||
// create first, then delete, in case of failure
|
||||
const newId = await WorkspaceAdapters[to].CRUD.create(
|
||||
workspace.blockSuiteWorkspace
|
||||
);
|
||||
await WorkspaceAdapters[from].CRUD.delete(workspace.blockSuiteWorkspace);
|
||||
setMetadata(workspaces => {
|
||||
const idx = workspaces.findIndex(ws => ws.id === workspace.id);
|
||||
workspaces.splice(idx, 1, {
|
||||
id: newId,
|
||||
flavour: to,
|
||||
version: WorkspaceVersion.SubDoc,
|
||||
});
|
||||
return [...workspaces];
|
||||
}, newId);
|
||||
// fixme(himself65): setting modal could still open and open the non-exist workspace
|
||||
setSettingModal(settings => ({
|
||||
...settings,
|
||||
open: false,
|
||||
}));
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('affine-workspace:transform', {
|
||||
detail: {
|
||||
from,
|
||||
to,
|
||||
oldId: workspace.id,
|
||||
newId: newId,
|
||||
},
|
||||
})
|
||||
);
|
||||
openPage(newId, currentPageId ?? WorkspaceSubPath.ALL);
|
||||
pushNotification({
|
||||
title: t['Successfully enabled AFFiNE Cloud'](),
|
||||
type: 'success',
|
||||
});
|
||||
},
|
||||
[
|
||||
WorkspaceAdapters,
|
||||
setMetadata,
|
||||
setSettingModal,
|
||||
openPage,
|
||||
currentPageId,
|
||||
pushNotification,
|
||||
t,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
declare global {
|
||||
// global Events
|
||||
interface WindowEventMap {
|
||||
'affine-workspace:transform': CustomEvent<{
|
||||
from: WorkspaceFlavour;
|
||||
to: WorkspaceFlavour;
|
||||
oldId: string;
|
||||
newId: string;
|
||||
}>;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useAtom, useStore } from 'jotai';
|
||||
import { waitForCurrentWorkspaceAtom } from '@affine/workspace/atom';
|
||||
import { useAtom, useAtomValue, useStore } from 'jotai';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@@ -14,14 +15,13 @@ import {
|
||||
} from '../commands';
|
||||
import { usePageHelper } from '../components/blocksuite/block-suite-page-list/utils';
|
||||
import { useLanguageHelper } from './affine/use-language-helper';
|
||||
import { useCurrentWorkspace } from './current/use-current-workspace';
|
||||
import { useNavigateHelper } from './use-navigate-helper';
|
||||
|
||||
export function useRegisterWorkspaceCommands() {
|
||||
const store = useStore();
|
||||
const t = useAFFiNEI18N();
|
||||
const theme = useTheme();
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const currentWorkspace = useAtomValue(waitForCurrentWorkspaceAtom);
|
||||
const languageHelper = useLanguageHelper();
|
||||
const pageHelper = usePageHelper(currentWorkspace.blockSuiteWorkspace);
|
||||
const navigationHelper = useNavigateHelper();
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import type { BlobManager } from '@blocksuite/store';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import type { BlockSuiteWorkspace } from '../shared';
|
||||
|
||||
const logger = new DebugLogger('useWorkspaceBlob');
|
||||
|
||||
export function useWorkspaceBlob(
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace
|
||||
): BlobManager {
|
||||
return useMemo(() => blockSuiteWorkspace.blob, [blockSuiteWorkspace.blob]);
|
||||
}
|
||||
|
||||
export function useWorkspaceBlobImage(
|
||||
key: string | null,
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace
|
||||
) {
|
||||
const blobManager = useWorkspaceBlob(blockSuiteWorkspace);
|
||||
const [blob, setBlob] = useState<Blob | null>(null);
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
if (key === null) {
|
||||
setBlob(null);
|
||||
return;
|
||||
}
|
||||
blobManager
|
||||
?.get(key)
|
||||
.then(blob => {
|
||||
if (controller.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
if (blob) {
|
||||
setBlob(blob);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error('Failed to get blob', err);
|
||||
});
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
}, [blobManager, key]);
|
||||
const [url, setUrl] = useState<string | null>(null);
|
||||
const ref = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
URL.revokeObjectURL(ref.current);
|
||||
}
|
||||
if (blob) {
|
||||
const url = URL.createObjectURL(blob);
|
||||
setUrl(url);
|
||||
ref.current = url;
|
||||
}
|
||||
}, [blob]);
|
||||
return url;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import {
|
||||
type AffineOfficialWorkspace,
|
||||
WorkspaceFlavour,
|
||||
} from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
import { getBlockSuiteWorkspaceAtom } from '@toeverything/infra/__internal__/workspace';
|
||||
import type { Atom } from 'jotai';
|
||||
import { atom, useAtomValue } from 'jotai';
|
||||
|
||||
const workspaceWeakMap = new WeakMap<
|
||||
Workspace,
|
||||
Atom<Promise<AffineOfficialWorkspace>>
|
||||
>();
|
||||
|
||||
// workspace effect is the side effect like connect to the server/indexeddb,
|
||||
// this will save the workspace updates permanently.
|
||||
export function useWorkspaceEffect(workspaceId: string): void {
|
||||
const [, effectAtom] = getBlockSuiteWorkspaceAtom(workspaceId);
|
||||
useAtomValue(effectAtom);
|
||||
}
|
||||
|
||||
// todo(himself65): remove this hook
|
||||
export function useWorkspace(workspaceId: string): AffineOfficialWorkspace {
|
||||
const [workspaceAtom] = getBlockSuiteWorkspaceAtom(workspaceId);
|
||||
const workspace = useAtomValue(workspaceAtom);
|
||||
if (!workspaceWeakMap.has(workspace)) {
|
||||
const baseAtom = atom(async get => {
|
||||
const metadataList = await get(rootWorkspacesMetadataAtom);
|
||||
const flavour = metadataList.find(({ id }) => id === workspaceId)
|
||||
?.flavour;
|
||||
|
||||
if (!flavour) {
|
||||
// when last workspace is removed, we may encounter this warning. it should be fine
|
||||
console.warn(
|
||||
'workspace not found in rootWorkspacesMetadataAtom, maybe it is removed',
|
||||
workspaceId
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
id: workspaceId,
|
||||
flavour: flavour ?? WorkspaceFlavour.LOCAL,
|
||||
blockSuiteWorkspace: workspace,
|
||||
};
|
||||
});
|
||||
workspaceWeakMap.set(workspace, baseAtom);
|
||||
}
|
||||
|
||||
return useAtomValue(
|
||||
workspaceWeakMap.get(workspace) as Atom<Promise<AffineOfficialWorkspace>>
|
||||
);
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||
import { saveWorkspaceToLocalStorage } from '@affine/workspace/local/crud';
|
||||
import { getOrCreateWorkspace } from '@affine/workspace/manager';
|
||||
import { getWorkspace } from '@toeverything/infra/__internal__/workspace';
|
||||
import { getCurrentStore } from '@toeverything/infra/atom';
|
||||
import {
|
||||
buildShowcaseWorkspace,
|
||||
WorkspaceVersion,
|
||||
} from '@toeverything/infra/blocksuite';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { LocalAdapter } from '../adapters/local';
|
||||
import { WorkspaceAdapters } from '../adapters/workspace';
|
||||
import { setPageModeAtom } from '../atoms';
|
||||
|
||||
const logger = new DebugLogger('use-workspaces');
|
||||
|
||||
/**
|
||||
* This hook has the permission to all workspaces. Be careful when using it.
|
||||
*/
|
||||
export function useAppHelper() {
|
||||
const jotaiWorkspaces = useAtomValue(rootWorkspacesMetadataAtom);
|
||||
const set = useSetAtom(rootWorkspacesMetadataAtom);
|
||||
return {
|
||||
addLocalWorkspace: useCallback(
|
||||
async (workspaceId: string): Promise<string> => {
|
||||
getOrCreateWorkspace(workspaceId, WorkspaceFlavour.LOCAL);
|
||||
saveWorkspaceToLocalStorage(workspaceId);
|
||||
set(workspaces => [
|
||||
...workspaces,
|
||||
{
|
||||
id: workspaceId,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
version: WorkspaceVersion.DatabaseV3,
|
||||
},
|
||||
]);
|
||||
logger.debug('imported local workspace', workspaceId);
|
||||
return workspaceId;
|
||||
},
|
||||
[set]
|
||||
),
|
||||
addCloudWorkspace: useCallback(
|
||||
(workspaceId: string) => {
|
||||
getOrCreateWorkspace(workspaceId, WorkspaceFlavour.AFFINE_CLOUD);
|
||||
set(workspaces => [
|
||||
...workspaces,
|
||||
{
|
||||
id: workspaceId,
|
||||
flavour: WorkspaceFlavour.AFFINE_CLOUD,
|
||||
version: WorkspaceVersion.DatabaseV3,
|
||||
},
|
||||
]);
|
||||
logger.debug('imported cloud workspace', workspaceId);
|
||||
},
|
||||
[set]
|
||||
),
|
||||
createLocalWorkspace: useCallback(
|
||||
async (name: string): Promise<string> => {
|
||||
const blockSuiteWorkspace = getOrCreateWorkspace(
|
||||
nanoid(),
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
blockSuiteWorkspace.meta.setName(name);
|
||||
const id = await LocalAdapter.CRUD.create(blockSuiteWorkspace);
|
||||
{
|
||||
// this is hack, because CRUD doesn't return the workspace
|
||||
const blockSuiteWorkspace = getOrCreateWorkspace(
|
||||
id,
|
||||
WorkspaceFlavour.LOCAL
|
||||
);
|
||||
await buildShowcaseWorkspace(blockSuiteWorkspace, {
|
||||
store: getCurrentStore(),
|
||||
atoms: {
|
||||
pageMode: setPageModeAtom,
|
||||
},
|
||||
});
|
||||
}
|
||||
set(workspaces => [
|
||||
...workspaces,
|
||||
{
|
||||
id,
|
||||
flavour: WorkspaceFlavour.LOCAL,
|
||||
version: WorkspaceVersion.DatabaseV3,
|
||||
},
|
||||
]);
|
||||
logger.debug('created local workspace', id);
|
||||
return id;
|
||||
},
|
||||
[set]
|
||||
),
|
||||
deleteWorkspace: useCallback(
|
||||
async (workspaceId: string) => {
|
||||
const targetJotaiWorkspace = jotaiWorkspaces.find(
|
||||
ws => ws.id === workspaceId
|
||||
);
|
||||
if (!targetJotaiWorkspace) {
|
||||
throw new Error('page cannot be found');
|
||||
}
|
||||
|
||||
const targetWorkspace = getWorkspace(targetJotaiWorkspace.id);
|
||||
|
||||
// delete workspace from plugin
|
||||
await WorkspaceAdapters[targetJotaiWorkspace.flavour].CRUD.delete(
|
||||
targetWorkspace
|
||||
);
|
||||
// delete workspace from jotai storage
|
||||
set(workspaces => workspaces.filter(ws => ws.id !== workspaceId));
|
||||
},
|
||||
[jotaiWorkspaces, set]
|
||||
),
|
||||
deleteWorkspaceMeta: useCallback(
|
||||
(workspaceId: string) => {
|
||||
set(workspaces => workspaces.filter(ws => ws.id !== workspaceId));
|
||||
},
|
||||
[set]
|
||||
),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user