mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
refactor: remove legacy cloud (#2987)
This commit is contained in:
@@ -15,7 +15,6 @@ import type { PropsWithChildren, ReactElement } from 'react';
|
||||
import React, { lazy, Suspense, useEffect } from 'react';
|
||||
|
||||
import { AffineErrorBoundary } from '../components/affine/affine-error-eoundary';
|
||||
import { MessageCenter } from '../components/pure/message-center';
|
||||
import type { NextPageWithLayout } from '../shared';
|
||||
import createEmotionCache from '../utils/create-emotion-cache';
|
||||
|
||||
@@ -61,7 +60,6 @@ const App = function App({
|
||||
return (
|
||||
<CacheProvider value={emotionCache}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<MessageCenter />
|
||||
<AffineErrorBoundary router={useRouter()}>
|
||||
<AffineContext>
|
||||
<Head>
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
import { Button } from '@affine/component';
|
||||
import { MainContainer } from '@affine/component/workspace';
|
||||
import { currentAffineUserAtom } from '@affine/workspace/affine/atom';
|
||||
import {
|
||||
clearLoginStorage,
|
||||
createAffineAuth,
|
||||
getLoginStorage,
|
||||
isExpired,
|
||||
parseIdToken,
|
||||
setLoginStorage,
|
||||
SignMethod,
|
||||
} from '@affine/workspace/affine/login';
|
||||
import { useAtom } from 'jotai';
|
||||
import type { NextPage } from 'next';
|
||||
import { lazy, Suspense, useMemo } from 'react';
|
||||
|
||||
import { AppContainer } from '../../components/affine/app-container';
|
||||
import { toast } from '../../utils';
|
||||
|
||||
const Viewer = lazy(() =>
|
||||
import('@rich-data/viewer').then(m => ({ default: m.JsonViewer }))
|
||||
);
|
||||
|
||||
import { useTheme } from 'next-themes';
|
||||
|
||||
const LoginDevPage: NextPage = () => {
|
||||
const [user, setUser] = useAtom(currentAffineUserAtom);
|
||||
const auth = useMemo(() => createAffineAuth(), []);
|
||||
return (
|
||||
<AppContainer>
|
||||
<MainContainer>
|
||||
<h1>LoginDevPage</h1>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const storage = getLoginStorage();
|
||||
if (storage) {
|
||||
const user = parseIdToken(storage.token);
|
||||
if (isExpired(user)) {
|
||||
await auth.refreshToken(storage);
|
||||
}
|
||||
}
|
||||
const response = await auth.generateToken(SignMethod.Google);
|
||||
if (response) {
|
||||
setLoginStorage(response);
|
||||
const user = parseIdToken(response.token);
|
||||
setUser(user);
|
||||
} else {
|
||||
toast('Login failed');
|
||||
}
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const storage = getLoginStorage();
|
||||
if (!storage) {
|
||||
throw new Error('No storage');
|
||||
}
|
||||
const response = await auth.refreshToken(storage);
|
||||
if (response) {
|
||||
setLoginStorage(response);
|
||||
const user = parseIdToken(response.token);
|
||||
setUser(user);
|
||||
} else {
|
||||
toast('Login failed');
|
||||
}
|
||||
}}
|
||||
>
|
||||
Refresh Token
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
clearLoginStorage();
|
||||
setUser(null);
|
||||
}}
|
||||
>
|
||||
Reset Storage
|
||||
</Button>
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const status = await fetch('/api/workspace', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache',
|
||||
Authorization: getLoginStorage()?.token ?? '',
|
||||
},
|
||||
}).then(r => r.status);
|
||||
toast(`Response Status: ${status}`);
|
||||
}}
|
||||
>
|
||||
Check Permission
|
||||
</Button>
|
||||
<Suspense>
|
||||
<Viewer
|
||||
theme={useTheme().resolvedTheme === 'light' ? 'light' : 'dark'}
|
||||
value={user}
|
||||
/>
|
||||
</Suspense>
|
||||
</MainContainer>
|
||||
</AppContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginDevPage;
|
||||
@@ -1,112 +0,0 @@
|
||||
import { displayFlex, styled } from '@affine/component';
|
||||
import { Button } from '@affine/component';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import type { Permission } from '@affine/env/workspace/legacy-cloud';
|
||||
import {
|
||||
SucessfulDuotoneIcon,
|
||||
UnsucessfulDuotoneIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import { NoSsr } from '@mui/material';
|
||||
import Image from 'next/legacy/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Suspense } from 'react';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { QueryKey } from '../../adapters/affine/fetcher';
|
||||
import { PageLoading } from '../../components/pure/loading';
|
||||
import { RouteLogic, useRouterHelper } from '../../hooks/use-router-helper';
|
||||
import type { NextPageWithLayout } from '../../shared';
|
||||
|
||||
const InvitePage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const { jumpToSubPath } = useRouterHelper(router);
|
||||
const { data: inviteData } = useSWR<Permission>(
|
||||
typeof router.query.invite_code === 'string'
|
||||
? [QueryKey.acceptInvite, router.query.invite_code]
|
||||
: null
|
||||
);
|
||||
|
||||
if (inviteData?.accepted) {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<Image
|
||||
src="/imgs/invite-success.svg"
|
||||
alt=""
|
||||
layout="fill"
|
||||
width={300}
|
||||
height={300}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
shape="round"
|
||||
onClick={() => {
|
||||
jumpToSubPath(
|
||||
inviteData.workspace_id,
|
||||
WorkspaceSubPath.ALL,
|
||||
RouteLogic.REPLACE
|
||||
).catch(err => console.error(err));
|
||||
}}
|
||||
>
|
||||
Go to Workspace
|
||||
</Button>
|
||||
<p>
|
||||
<SucessfulDuotoneIcon />
|
||||
Successfully joined
|
||||
</p>
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (inviteData?.accepted === false) {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<Image src="/imgs/invite-error.svg" alt="" />
|
||||
<Button
|
||||
shape="round"
|
||||
onClick={() => {
|
||||
router.replace(`/`).catch(err => console.error(err));
|
||||
}}
|
||||
>
|
||||
Back to Home
|
||||
</Button>
|
||||
<p>
|
||||
<UnsucessfulDuotoneIcon />
|
||||
The link has expired
|
||||
</p>
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
throw new Error('Invalid invite code');
|
||||
};
|
||||
|
||||
export default InvitePage;
|
||||
|
||||
InvitePage.getLayout = page => {
|
||||
return (
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
<NoSsr>{page}</NoSsr>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
const StyledContainer = styled('div')(() => {
|
||||
return {
|
||||
height: '100vh',
|
||||
...displayFlex('center', 'center'),
|
||||
flexDirection: 'column',
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
img: {
|
||||
width: '300px',
|
||||
height: '300px',
|
||||
},
|
||||
p: {
|
||||
...displayFlex('center', 'center'),
|
||||
marginTop: '24px',
|
||||
svg: {
|
||||
color: 'var(--affine-primary-color)',
|
||||
fontSize: '24px',
|
||||
marginRight: '12px',
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -1,134 +0,0 @@
|
||||
import { Breadcrumbs, IconButton, ListSkeleton } from '@affine/component';
|
||||
import { StyledTableContainer } from '@affine/component/page-list';
|
||||
import { QueryParamError } from '@affine/env/constant';
|
||||
import { rootCurrentWorkspaceIdAtom } from '@affine/workspace/atom';
|
||||
import { SearchIcon } from '@blocksuite/icons';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { useRouter } from 'next/router';
|
||||
import type React from 'react';
|
||||
import { lazy, Suspense, useCallback, useEffect } from 'react';
|
||||
|
||||
import { openQuickSearchModalAtom } from '../../atoms';
|
||||
import {
|
||||
publicWorkspaceAtom,
|
||||
publicWorkspaceIdAtom,
|
||||
} from '../../atoms/public-workspace';
|
||||
import { WorkspaceAvatar } from '../../components/pure/footer';
|
||||
import { PageLoading } from '../../components/pure/loading';
|
||||
import {
|
||||
PublicQuickSearch,
|
||||
PublicWorkspaceLayout,
|
||||
} from '../../layouts/public-workspace-layout';
|
||||
import type { NextPageWithLayout } from '../../shared';
|
||||
import { NavContainer, StyledBreadcrumbs } from './[workspaceId]/[pageId]';
|
||||
|
||||
const BlockSuitePageList = lazy(() =>
|
||||
import('../../components/blocksuite/block-suite-page-list').then(module => ({
|
||||
default: module.BlockSuitePageList,
|
||||
}))
|
||||
);
|
||||
|
||||
const ListPageInner: React.FC<{
|
||||
workspaceId: string;
|
||||
}> = ({ workspaceId }) => {
|
||||
const router = useRouter();
|
||||
const publicWorkspace = useAtomValue(publicWorkspaceAtom);
|
||||
const blockSuiteWorkspace = publicWorkspace.blockSuiteWorkspace;
|
||||
const handleClickPage = useCallback(
|
||||
(pageId: string) => {
|
||||
return router.push({
|
||||
pathname: `/public-workspace/[workspaceId]/[pageId]`,
|
||||
query: {
|
||||
workspaceId,
|
||||
pageId,
|
||||
},
|
||||
});
|
||||
},
|
||||
[router, workspaceId]
|
||||
);
|
||||
const [name] = useBlockSuiteWorkspaceName(blockSuiteWorkspace);
|
||||
const [avatar] = useBlockSuiteWorkspaceAvatarUrl(blockSuiteWorkspace);
|
||||
const setSearchModalOpen = useSetAtom(openQuickSearchModalAtom);
|
||||
const handleOpen = useCallback(() => {
|
||||
setSearchModalOpen(true);
|
||||
}, [setSearchModalOpen]);
|
||||
if (!blockSuiteWorkspace) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<PublicQuickSearch workspace={publicWorkspace} />
|
||||
<NavContainer sx={{ px: '20px' }}>
|
||||
<Breadcrumbs>
|
||||
<StyledBreadcrumbs
|
||||
href={`/public-workspace/${blockSuiteWorkspace.id}`}
|
||||
>
|
||||
<WorkspaceAvatar size={24} name={name} avatar={avatar} />
|
||||
<span>{name}</span>
|
||||
</StyledBreadcrumbs>
|
||||
</Breadcrumbs>
|
||||
<IconButton onClick={handleOpen}>
|
||||
<SearchIcon />
|
||||
</IconButton>
|
||||
</NavContainer>
|
||||
<Suspense
|
||||
fallback={
|
||||
<StyledTableContainer>
|
||||
<ListSkeleton />
|
||||
</StyledTableContainer>
|
||||
}
|
||||
>
|
||||
<BlockSuitePageList
|
||||
listType="public"
|
||||
isPublic={true}
|
||||
onOpenPage={handleClickPage}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// This is affine only page, so we don't need to dynamic use WorkspacePlugin
|
||||
const ListPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const workspaceId = router.query.workspaceId;
|
||||
const setWorkspaceId = useSetAtom(publicWorkspaceIdAtom);
|
||||
// todo: remove this atom usage here
|
||||
const setCurrentWorkspaceId = useSetAtom(rootCurrentWorkspaceIdAtom);
|
||||
useEffect(() => {
|
||||
if (!router.isReady) {
|
||||
return;
|
||||
}
|
||||
if (typeof workspaceId === 'string') {
|
||||
setWorkspaceId(workspaceId);
|
||||
setCurrentWorkspaceId(workspaceId);
|
||||
}
|
||||
}, [router.isReady, setCurrentWorkspaceId, setWorkspaceId, workspaceId]);
|
||||
const value = useAtomValue(publicWorkspaceIdAtom);
|
||||
if (!router.isReady || !value) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
if (typeof workspaceId !== 'string') {
|
||||
throw new QueryParamError('workspaceId', workspaceId);
|
||||
}
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
<StyledTableContainer>
|
||||
<ListSkeleton />
|
||||
</StyledTableContainer>
|
||||
}
|
||||
>
|
||||
<ListPageInner workspaceId={workspaceId} />
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListPage;
|
||||
|
||||
ListPage.getLayout = page => {
|
||||
return <PublicWorkspaceLayout>{page}</PublicWorkspaceLayout>;
|
||||
};
|
||||
@@ -1,158 +0,0 @@
|
||||
import { Breadcrumbs, displayFlex, styled } from '@affine/component';
|
||||
import { initEmptyPage } from '@affine/env/blocksuite';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { PageIcon } from '@blocksuite/icons';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { ReactElement } from 'react';
|
||||
import { Suspense, useCallback, useEffect } from 'react';
|
||||
|
||||
import {
|
||||
publicPageBlockSuiteAtom,
|
||||
publicWorkspaceIdAtom,
|
||||
publicWorkspacePageIdAtom,
|
||||
} from '../../../atoms/public-workspace';
|
||||
import { BlockSuiteEditorHeader } from '../../../components/blocksuite/workspace-header';
|
||||
import {
|
||||
PageDetailEditor,
|
||||
type PageDetailEditorProps,
|
||||
} from '../../../components/page-detail-editor';
|
||||
import { WorkspaceAvatar } from '../../../components/pure/footer';
|
||||
import { PageLoading } from '../../../components/pure/loading';
|
||||
import { useRouterHelper } from '../../../hooks/use-router-helper';
|
||||
import {
|
||||
PublicQuickSearch,
|
||||
PublicWorkspaceLayout,
|
||||
} from '../../../layouts/public-workspace-layout';
|
||||
import type { NextPageWithLayout } from '../../../shared';
|
||||
|
||||
export const NavContainer = styled('div')(() => {
|
||||
return {
|
||||
width: '100vw',
|
||||
height: '52px',
|
||||
...displayFlex('space-between', 'center'),
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledBreadcrumbs = styled(Link)(() => {
|
||||
return {
|
||||
flex: 1,
|
||||
...displayFlex('center', 'center'),
|
||||
paddingLeft: '12px',
|
||||
span: {
|
||||
padding: '0 12px',
|
||||
fontSize: 'var(--affine-font-base)',
|
||||
lineHeight: 'var(--affine-line-height)',
|
||||
},
|
||||
':hover': { color: 'var(--affine-primary-color)' },
|
||||
transition: 'all .15s',
|
||||
':visited': {
|
||||
':hover': { color: 'var(--affine-primary-color)' },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const PublicWorkspaceDetailPageInner = (): ReactElement => {
|
||||
const pageId = useAtomValue(publicWorkspacePageIdAtom);
|
||||
assertExists(pageId, 'pageId is null');
|
||||
const publicWorkspace = useAtomValue(publicPageBlockSuiteAtom);
|
||||
const blockSuiteWorkspace = publicWorkspace.blockSuiteWorkspace;
|
||||
if (!blockSuiteWorkspace) {
|
||||
throw new Error('cannot find workspace');
|
||||
}
|
||||
const router = useRouter();
|
||||
const { openPage } = useRouterHelper(router);
|
||||
const t = useAFFiNEI18N();
|
||||
const [name] = useBlockSuiteWorkspaceName(blockSuiteWorkspace);
|
||||
const [avatar] = useBlockSuiteWorkspaceAvatarUrl(blockSuiteWorkspace);
|
||||
const pageTitle = blockSuiteWorkspace.meta.getPageMeta(pageId)?.title;
|
||||
const onLoad = useCallback<NonNullable<PageDetailEditorProps['onLoad']>>(
|
||||
(_, editor) => {
|
||||
const { page } = editor;
|
||||
page.awarenessStore.setReadonly(page, true);
|
||||
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => {
|
||||
return openPage(blockSuiteWorkspace.id, pageId);
|
||||
});
|
||||
return () => {
|
||||
dispose.dispose();
|
||||
};
|
||||
},
|
||||
[blockSuiteWorkspace.id, openPage]
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<PublicQuickSearch workspace={publicWorkspace} />
|
||||
<BlockSuiteEditorHeader
|
||||
isPublic={true}
|
||||
workspace={publicWorkspace}
|
||||
currentPage={blockSuiteWorkspace.getPage(pageId)}
|
||||
>
|
||||
<NavContainer>
|
||||
<Breadcrumbs>
|
||||
<StyledBreadcrumbs
|
||||
href={`/public-workspace/${blockSuiteWorkspace.id}`}
|
||||
>
|
||||
<WorkspaceAvatar size={24} name={name} avatar={avatar} />
|
||||
<span>{name}</span>
|
||||
</StyledBreadcrumbs>
|
||||
<StyledBreadcrumbs
|
||||
href={`/public-workspace/${blockSuiteWorkspace.id}/${pageId}`}
|
||||
>
|
||||
<PageIcon fontSize={24} />
|
||||
<span>{pageTitle ? pageTitle : t['Untitled']()}</span>
|
||||
</StyledBreadcrumbs>
|
||||
</Breadcrumbs>
|
||||
</NavContainer>
|
||||
</BlockSuiteEditorHeader>
|
||||
<PageDetailEditor
|
||||
isPublic={true}
|
||||
pageId={pageId}
|
||||
workspace={publicWorkspace}
|
||||
onLoad={onLoad}
|
||||
onInit={initEmptyPage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const PublicWorkspaceDetailPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const [workspaceId, setWorkspaceId] = useAtom(publicWorkspaceIdAtom);
|
||||
const [pageId, setPageId] = useAtom(publicWorkspacePageIdAtom);
|
||||
useEffect(() => {
|
||||
if (!router.isReady) {
|
||||
return;
|
||||
}
|
||||
if (typeof router.query.workspaceId === 'string') {
|
||||
setWorkspaceId(router.query.workspaceId);
|
||||
}
|
||||
if (typeof router.query.pageId === 'string') {
|
||||
setPageId(router.query.pageId);
|
||||
}
|
||||
}, [
|
||||
router.isReady,
|
||||
router.query.pageId,
|
||||
router.query.workspaceId,
|
||||
setPageId,
|
||||
setWorkspaceId,
|
||||
]);
|
||||
if (!router.isReady || !workspaceId || !pageId) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
return (
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
<PublicWorkspaceDetailPageInner />
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default PublicWorkspaceDetailPage;
|
||||
|
||||
PublicWorkspaceDetailPage.getLayout = page => {
|
||||
return <PublicWorkspaceLayout>{page}</PublicWorkspaceLayout>;
|
||||
};
|
||||
@@ -1,136 +0,0 @@
|
||||
import type { SettingPanel } from '@affine/env/workspace';
|
||||
import {
|
||||
settingPanel,
|
||||
settingPanelValues,
|
||||
WorkspaceSubPath,
|
||||
} from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import { useAtom } from 'jotai';
|
||||
import { atomWithStorage } from 'jotai/utils';
|
||||
import Head from 'next/head';
|
||||
import type { NextRouter } from 'next/router';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { getUIAdapter } from '../../../adapters/workspace';
|
||||
import { PageLoading } from '../../../components/pure/loading';
|
||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||
import { useOnTransformWorkspace } from '../../../hooks/root/use-on-transform-workspace';
|
||||
import { useAppHelper } from '../../../hooks/use-workspaces';
|
||||
import { WorkspaceLayout } from '../../../layouts/workspace-layout';
|
||||
import type { NextPageWithLayout } from '../../../shared';
|
||||
|
||||
const settingPanelAtom = atomWithStorage<SettingPanel>(
|
||||
'workspaceId',
|
||||
settingPanel.General
|
||||
);
|
||||
|
||||
function useTabRouterSync(
|
||||
router: NextRouter,
|
||||
currentTab: SettingPanel,
|
||||
setCurrentTab: (tab: SettingPanel) => void
|
||||
): void {
|
||||
if (!router.isReady) {
|
||||
return;
|
||||
}
|
||||
const queryCurrentTab =
|
||||
typeof router.query.currentTab === 'string'
|
||||
? router.query.currentTab
|
||||
: null;
|
||||
if (
|
||||
(queryCurrentTab !== null &&
|
||||
settingPanelValues.indexOf(queryCurrentTab as SettingPanel) === -1) ||
|
||||
settingPanelValues.indexOf(currentTab as SettingPanel) === -1
|
||||
) {
|
||||
setCurrentTab(settingPanel.General);
|
||||
router
|
||||
.replace({
|
||||
pathname: router.pathname,
|
||||
query: {
|
||||
...router.query,
|
||||
currentTab: settingPanel.General,
|
||||
},
|
||||
})
|
||||
.catch(console.error);
|
||||
} else if (queryCurrentTab !== currentTab) {
|
||||
router
|
||||
.replace({
|
||||
pathname: router.pathname,
|
||||
query: {
|
||||
...router.query,
|
||||
currentTab: currentTab,
|
||||
},
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
const SettingPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const t = useAFFiNEI18N();
|
||||
const [currentTab, setCurrentTab] = useAtom(settingPanelAtom);
|
||||
const onChangeTab = useCallback(
|
||||
(tab: SettingPanel) => {
|
||||
setCurrentTab(tab as SettingPanel);
|
||||
router
|
||||
.push({
|
||||
pathname: router.pathname,
|
||||
query: {
|
||||
...router.query,
|
||||
currentTab: tab,
|
||||
},
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
[router, setCurrentTab]
|
||||
);
|
||||
|
||||
useTabRouterSync(router, currentTab, setCurrentTab);
|
||||
|
||||
const helper = useAppHelper();
|
||||
|
||||
const onDeleteWorkspace = useCallback(async () => {
|
||||
assertExists(currentWorkspace);
|
||||
const workspaceId = currentWorkspace.id;
|
||||
return helper.deleteWorkspace(workspaceId);
|
||||
}, [currentWorkspace, helper]);
|
||||
const onTransformWorkspace = useOnTransformWorkspace();
|
||||
if (
|
||||
!router.isReady ||
|
||||
currentWorkspace === null ||
|
||||
settingPanelValues.indexOf(currentTab as SettingPanel) === -1
|
||||
) {
|
||||
return <PageLoading />;
|
||||
}
|
||||
const { SettingsDetail, Header } = getUIAdapter(currentWorkspace.flavour);
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t['Settings']()} - AFFiNE</title>
|
||||
</Head>
|
||||
<Header
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentEntry={{
|
||||
subPath: WorkspaceSubPath.SETTING,
|
||||
}}
|
||||
/>
|
||||
<SettingsDetail
|
||||
onTransformWorkspace={onTransformWorkspace}
|
||||
onDeleteWorkspace={onDeleteWorkspace}
|
||||
currentWorkspace={currentWorkspace}
|
||||
currentTab={currentTab as SettingPanel}
|
||||
onChangeTab={onChangeTab}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingPage;
|
||||
|
||||
SettingPage.getLayout = page => {
|
||||
return <WorkspaceLayout>{page}</WorkspaceLayout>;
|
||||
};
|
||||
Reference in New Issue
Block a user