From be55442f386e27faeaeee7bb975da67ad185619a Mon Sep 17 00:00:00 2001 From: EYHN Date: Fri, 25 Jul 2025 18:26:55 +0800 Subject: [PATCH] feat(core): remove empty workspace (#13317) ## Summary by CodeRabbit * **New Features** * Added the ability to remove an empty workspace directly from the workspace card when you are the owner. * Workspace cards now display a "Remove" button for eligible workspaces. * **Improvements** * Workspace information now indicates if a workspace is empty, improving clarity for users. * **Bug Fixes** * Enhanced accuracy in displaying workspace status by updating how workspace profile data is handled. --- .../workspace-card/index.tsx | 32 ++++++++++++++++--- .../modules/workspace-engine/impls/cloud.ts | 17 ++++++++++ .../src/modules/workspace/entities/profile.ts | 2 ++ .../modules/workspace/stores/profile-cache.ts | 8 +---- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/packages/frontend/core/src/components/workspace-selector/workspace-card/index.tsx b/packages/frontend/core/src/components/workspace-selector/workspace-card/index.tsx index 9fdd97715d..e58bcaf63a 100644 --- a/packages/frontend/core/src/components/workspace-selector/workspace-card/index.tsx +++ b/packages/frontend/core/src/components/workspace-selector/workspace-card/index.tsx @@ -1,11 +1,12 @@ -import { Button, Skeleton, Tooltip } from '@affine/component'; +import { Button, notify, Skeleton, Tooltip } from '@affine/component'; import { Loading } from '@affine/component/ui/loading'; import { useSystemOnline } from '@affine/core/components/hooks/use-system-online'; import { useWorkspace } from '@affine/core/components/hooks/use-workspace'; import { useWorkspaceInfo } from '@affine/core/components/hooks/use-workspace-info'; -import type { - WorkspaceMetadata, - WorkspaceProfileInfo, +import { + type WorkspaceMetadata, + type WorkspaceProfileInfo, + WorkspacesService, } from '@affine/core/modules/workspace'; import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant'; import { useI18n } from '@affine/i18n'; @@ -21,13 +22,15 @@ import { TeamWorkspaceIcon, UnsyncIcon, } from '@blocksuite/icons/rc'; -import { LiveData, useLiveData } from '@toeverything/infra'; +import { LiveData, useLiveData, useService } from '@toeverything/infra'; import { cssVar } from '@toeverything/theme'; import clsx from 'clsx'; import type { HTMLAttributes } from 'react'; import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react'; +import { useAsyncCallback } from '../../hooks/affine-async-hooks'; import { useCatchEventCallback } from '../../hooks/use-catch-event-hook'; +import { useNavigateHelper } from '../../hooks/use-navigate-helper'; import { WorkspaceAvatar } from '../../workspace-avatar'; import * as styles from './styles.css'; export { PureWorkspaceCard } from './pure-workspace-card'; @@ -284,6 +287,8 @@ export const WorkspaceCard = forwardRef< ) => { const t = useI18n(); const information = useWorkspaceInfo(workspaceMetadata); + const workspacesService = useService(WorkspacesService); + const navigate = useNavigateHelper(); const name = information?.name ?? UNTITLED_WORKSPACE_NAME; @@ -291,10 +296,24 @@ export const WorkspaceCard = forwardRef< onClickEnableCloud?.(workspaceMetadata); }, [onClickEnableCloud, workspaceMetadata]); + const onRemoveWorkspace = useAsyncCallback(async () => { + await workspacesService + .deleteWorkspace(workspaceMetadata) + .then(() => { + notify.success({ title: t['Successfully removed workspace']() }); + navigate.jumpToIndex(); + }) + .catch(() => { + notify.error({ title: t['Failed to remove workspace']() }); + }); + }, [workspacesService, workspaceMetadata, t, navigate]); + const onOpenSettings = useCatchEventCallback(() => { onClickOpenSettings?.(workspaceMetadata); }, [onClickOpenSettings, workspaceMetadata]); + console.log(information); + return (
)}
+ {information?.isEmpty && information.isOwner ? ( + + ) : null}
{onClickEnableCloud && workspaceMetadata.flavour === 'local' ? (