fix: prohibit delete last workspace (#2212)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { atomWithSyncStorage } from '@affine/jotai';
|
import { atomWithSyncStorage } from '@affine/jotai';
|
||||||
|
import { rootWorkspacesMetadataAtom } from '@affine/workspace/atom';
|
||||||
import type { SettingPanel } from '@affine/workspace/type';
|
import type { SettingPanel } from '@affine/workspace/type';
|
||||||
import {
|
import {
|
||||||
settingPanel,
|
settingPanel,
|
||||||
@@ -8,7 +9,7 @@ import {
|
|||||||
} from '@affine/workspace/type';
|
} from '@affine/workspace/type';
|
||||||
import { SettingsIcon } from '@blocksuite/icons';
|
import { SettingsIcon } from '@blocksuite/icons';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom, useAtomValue } from 'jotai';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
@@ -23,6 +24,7 @@ import { useAppHelper } from '../../../hooks/use-workspaces';
|
|||||||
import { WorkspaceLayout } from '../../../layouts/workspace-layout';
|
import { WorkspaceLayout } from '../../../layouts/workspace-layout';
|
||||||
import { WorkspacePlugins } from '../../../plugins';
|
import { WorkspacePlugins } from '../../../plugins';
|
||||||
import type { NextPageWithLayout } from '../../../shared';
|
import type { NextPageWithLayout } from '../../../shared';
|
||||||
|
import { toast } from '../../../utils';
|
||||||
|
|
||||||
const settingPanelAtom = atomWithSyncStorage<SettingPanel>(
|
const settingPanelAtom = atomWithSyncStorage<SettingPanel>(
|
||||||
'workspaceId',
|
'workspaceId',
|
||||||
@@ -31,6 +33,7 @@ const settingPanelAtom = atomWithSyncStorage<SettingPanel>(
|
|||||||
|
|
||||||
const SettingPage: NextPageWithLayout = () => {
|
const SettingPage: NextPageWithLayout = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const workspaceIds = useAtomValue(rootWorkspacesMetadataAtom);
|
||||||
const [currentWorkspace] = useCurrentWorkspace();
|
const [currentWorkspace] = useCurrentWorkspace();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
useSyncRouterWithCurrentWorkspaceId(router);
|
useSyncRouterWithCurrentWorkspaceId(router);
|
||||||
@@ -97,8 +100,12 @@ const SettingPage: NextPageWithLayout = () => {
|
|||||||
const onDeleteWorkspace = useCallback(() => {
|
const onDeleteWorkspace = useCallback(() => {
|
||||||
assertExists(currentWorkspace);
|
assertExists(currentWorkspace);
|
||||||
const workspaceId = currentWorkspace.id;
|
const workspaceId = currentWorkspace.id;
|
||||||
|
if (workspaceIds.length === 1 && workspaceId === workspaceIds[0].id) {
|
||||||
|
toast(t('You cannot delete the last workspace'));
|
||||||
|
throw new Error('You cannot delete the last workspace');
|
||||||
|
}
|
||||||
return helper.deleteWorkspace(workspaceId);
|
return helper.deleteWorkspace(workspaceId);
|
||||||
}, [currentWorkspace, helper]);
|
}, [currentWorkspace, helper, t, workspaceIds]);
|
||||||
const onTransformWorkspace = useOnTransformWorkspace();
|
const onTransformWorkspace = useOnTransformWorkspace();
|
||||||
if (!router.isReady) {
|
if (!router.isReady) {
|
||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
|
|||||||
@@ -227,5 +227,6 @@
|
|||||||
"Finding Current Workspace": "Finding Current Workspace",
|
"Finding Current Workspace": "Finding Current Workspace",
|
||||||
"Page is Loading": "Page is Loading",
|
"Page is Loading": "Page is Loading",
|
||||||
"Loading All Workspaces": "Loading All Workspaces",
|
"Loading All Workspaces": "Loading All Workspaces",
|
||||||
"Loading Page": "Loading Page"
|
"Loading Page": "Loading Page",
|
||||||
|
"You cannot delete the last workspace": "You cannot delete the last workspace"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,5 +189,6 @@
|
|||||||
"is a Local Workspace": "是本地工作区",
|
"is a Local Workspace": "是本地工作区",
|
||||||
"Sign out description": "登出会导致未同步的内容丢失",
|
"Sign out description": "登出会导致未同步的内容丢失",
|
||||||
"Not now": "稍后再说",
|
"Not now": "稍后再说",
|
||||||
"Saved then enable AFFiNE Cloud": "所有改动已保存在本地,点击启用 AFFiNE 云服务"
|
"Saved then enable AFFiNE Cloud": "所有改动已保存在本地,点击启用 AFFiNE 云服务",
|
||||||
|
"You cannot delete the last workspace": "你不能删除最后一个工作区"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,50 @@ import { expect } from '@playwright/test';
|
|||||||
|
|
||||||
import { openHomePage } from '../libs/load-page';
|
import { openHomePage } from '../libs/load-page';
|
||||||
import { waitMarkdownImported } from '../libs/page-logic';
|
import { waitMarkdownImported } from '../libs/page-logic';
|
||||||
import { clickSideBarSettingButton } from '../libs/sidebar';
|
import {
|
||||||
|
clickSideBarCurrentWorkspaceBanner,
|
||||||
|
clickSideBarSettingButton,
|
||||||
|
} from '../libs/sidebar';
|
||||||
import { assertCurrentWorkspaceFlavour } from '../libs/workspace';
|
import { assertCurrentWorkspaceFlavour } from '../libs/workspace';
|
||||||
|
|
||||||
test('New a workspace , then delete it in all workspaces, permanently delete it', async ({
|
test('Create new workspace, then delete it', async ({ page }) => {
|
||||||
page,
|
await openHomePage(page);
|
||||||
}) => {
|
await waitMarkdownImported(page);
|
||||||
|
await clickSideBarCurrentWorkspaceBanner(page);
|
||||||
|
await page.getByTestId('new-workspace').click();
|
||||||
|
await page
|
||||||
|
.getByTestId('create-workspace-input')
|
||||||
|
.type('Test Workspace', { delay: 50 });
|
||||||
|
await page.getByTestId('create-workspace-button').click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
await page.waitForSelector('[data-testid="workspace-name"]');
|
||||||
|
expect(await page.getByTestId('workspace-name').textContent()).toBe(
|
||||||
|
'Test Workspace'
|
||||||
|
);
|
||||||
|
await clickSideBarSettingButton(page);
|
||||||
|
await page.getByTestId('delete-workspace-button').click();
|
||||||
|
const workspaceNameDom = await page.getByTestId('workspace-name');
|
||||||
|
const currentWorkspaceName = await workspaceNameDom.evaluate(
|
||||||
|
node => node.textContent
|
||||||
|
);
|
||||||
|
await page
|
||||||
|
.getByTestId('delete-workspace-input')
|
||||||
|
.type(currentWorkspaceName as string);
|
||||||
|
const promise = page
|
||||||
|
.getByTestId('affine-toast')
|
||||||
|
.waitFor({ state: 'attached' });
|
||||||
|
await page.getByTestId('delete-workspace-confirm-button').click();
|
||||||
|
await promise;
|
||||||
|
await page.reload();
|
||||||
|
await page.waitForSelector('[data-testid="workspace-name"]');
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
expect(await page.getByTestId('workspace-name').textContent()).toBe(
|
||||||
|
'Demo Workspace'
|
||||||
|
);
|
||||||
|
await assertCurrentWorkspaceFlavour('local', page);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should not delete the last one workspace', async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitMarkdownImported(page);
|
await waitMarkdownImported(page);
|
||||||
await clickSideBarSettingButton(page);
|
await clickSideBarSettingButton(page);
|
||||||
@@ -20,10 +58,15 @@ test('New a workspace , then delete it in all workspaces, permanently delete it'
|
|||||||
await page
|
await page
|
||||||
.getByTestId('delete-workspace-input')
|
.getByTestId('delete-workspace-input')
|
||||||
.type(currentWorkspaceName as string);
|
.type(currentWorkspaceName as string);
|
||||||
|
const promise = page
|
||||||
|
.getByTestId('affine-toast')
|
||||||
|
.waitFor({ state: 'attached' });
|
||||||
await page.getByTestId('delete-workspace-confirm-button').click();
|
await page.getByTestId('delete-workspace-confirm-button').click();
|
||||||
await page.getByTestId('affine-toast').waitFor({ state: 'attached' });
|
await promise;
|
||||||
expect(await page.getByTestId('workspace-card').count()).toBe(0);
|
await page.reload();
|
||||||
await page.mouse.click(1, 1);
|
await page.waitForSelector('[data-testid="workspace-name"]');
|
||||||
expect(await page.getByTestId('workspace-card').count()).toBe(0);
|
expect(await page.getByTestId('workspace-name').textContent()).toBe(
|
||||||
|
'Demo Workspace'
|
||||||
|
);
|
||||||
await assertCurrentWorkspaceFlavour('local', page);
|
await assertCurrentWorkspaceFlavour('local', page);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user