feat(core): adjust empty collection style (#5239)

<img width="270" alt="image" src="https://github.com/toeverything/AFFiNE/assets/102217452/18ac2de8-51c0-447e-9c81-787f579eab4e">
This commit is contained in:
JimmFly
2023-12-11 06:30:09 +00:00
parent cfd200528f
commit e7a7796ef3
7 changed files with 114 additions and 65 deletions
@@ -87,17 +87,9 @@ const CloudShareMenu = (props: ShareMenuProps) => {
}}
>
<Button data-testid="cloud-share-menu-button" type="primary">
<div
style={{
color: isSharedPage
? 'var(--affine-link-color)'
: 'var(--affine-text-primary-color)',
}}
>
{isSharedPage
? t['com.affine.share-menu.sharedButton']()
: t['com.affine.share-menu.shareButton']()}
</div>
{isSharedPage
? t['com.affine.share-menu.sharedButton']()
: t['com.affine.share-menu.shareButton']()}
</Button>
</Menu>
);
@@ -1,46 +1,19 @@
import {
createEmptyCollection,
useCollectionManager,
useEditCollectionName,
} from '@affine/component/page-list';
import { IconButton } from '@affine/component/ui/button';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { PlusIcon } from '@blocksuite/icons';
import { nanoid } from 'nanoid';
import { useCallback } from 'react';
import type { ReactElement } from 'react';
import { collectionsCRUDAtom } from '../../../../atoms/collections';
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
import { useNavigateHelper } from '../../../../hooks/use-navigate-helper';
export const AddCollectionButton = () => {
const setting = useCollectionManager(collectionsCRUDAtom);
const t = useAFFiNEI18N();
const { node, open } = useEditCollectionName({
title: t['com.affine.editCollection.createCollection'](),
showTips: true,
});
const navigateHelper = useNavigateHelper();
const [workspace] = useCurrentWorkspace();
const handleClick = useCallback(() => {
open('')
.then(name => {
const id = nanoid();
return setting
.createCollection(createEmptyCollection(id, { name }))
.then(() => {
navigateHelper.jumpToCollection(workspace.id, id);
});
})
.catch(err => {
console.error(err);
});
}, [navigateHelper, open, setting, workspace.id]);
export const AddCollectionButton = ({
node,
onClick,
}: {
node: ReactElement | null;
onClick: () => void;
}) => {
return (
<>
<IconButton
data-testid="slider-bar-add-collection-button"
onClick={handleClick}
onClick={onClick}
size="small"
>
<PlusIcon />
@@ -1,8 +1,5 @@
import { AnimatedCollectionsIcon, toast } from '@affine/component';
import {
MenuItem as SidebarMenuItem,
MenuLinkItem as SidebarMenuLinkItem,
} from '@affine/component/app-sidebar';
import { MenuLinkItem as SidebarMenuLinkItem } from '@affine/component/app-sidebar';
import {
CollectionOperations,
filterPage,
@@ -10,10 +7,10 @@ import {
useCollectionManager,
useSavedCollections,
} from '@affine/component/page-list';
import { IconButton } from '@affine/component/ui/button';
import { Button, IconButton } from '@affine/component/ui/button';
import type { Collection, DeleteCollectionInfo } from '@affine/env/filter';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { InformationIcon, MoreHorizontalIcon } from '@blocksuite/icons';
import { MoreHorizontalIcon, ViewLayersIcon } from '@blocksuite/icons';
import type { PageMeta, Workspace } from '@blocksuite/store';
import type { DragEndEvent } from '@dnd-kit/core';
import { useDroppable } from '@dnd-kit/core';
@@ -155,19 +152,32 @@ const CollectionRenderer = ({
</Collapsible.Root>
);
};
export const CollectionsList = ({ workspace, info }: CollectionsListProps) => {
export const CollectionsList = ({
workspace,
info,
onCreate,
}: CollectionsListProps) => {
const metas = useBlockSuitePageMeta(workspace);
const { collections } = useSavedCollections(collectionsCRUDAtom);
const t = useAFFiNEI18N();
if (collections.length === 0) {
return (
<SidebarMenuItem
data-testid="slider-bar-collection-null-description"
icon={<InformationIcon />}
disabled
>
<span>{t['Create a collection']()}</span>
</SidebarMenuItem>
<div className={styles.emptyCollectionWrapper}>
<div className={styles.emptyCollectionContent}>
<div className={styles.emptyCollectionIconWrapper}>
<ViewLayersIcon className={styles.emptyCollectionIcon} />
</div>
<div
data-testid="slider-bar-collection-null-description"
className={styles.emptyCollectionMessage}
>
{t['com.affine.collections.empty.message']()}
</div>
</div>
<Button className={styles.emptyCollectionNewButton} onClick={onCreate}>
{t['com.affine.collections.empty.new-collection-button']()}
</Button>
</div>
);
}
return (
@@ -87,3 +87,45 @@ export const collapsibleContent = style({
},
},
});
export const emptyCollectionWrapper = style({
padding: '9px 0',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 8,
});
export const emptyCollectionContent = style({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 6,
});
export const emptyCollectionIconWrapper = style({
width: 36,
height: 36,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
backgroundColor: 'var(--affine-background-secondary-color)',
});
export const emptyCollectionIcon = style({
fontSize: 20,
color: 'var(--affine-icon-secondary)',
});
export const emptyCollectionMessage = style({
fontSize: 'var(--affine-font-sm)',
textAlign: 'center',
color: 'var(--affine-text-secondary-color)',
});
export const emptyCollectionNewButton = style({
padding: '0 8px',
height: '30px',
fontSize: 'var(--affine-font-sm)',
});
@@ -8,4 +8,5 @@ export type FavoriteListProps = {
export type CollectionsListProps = {
workspace: Workspace;
info: DeleteCollectionInfo;
onCreate?: () => void;
};
@@ -12,15 +12,22 @@ import {
SidebarContainer,
SidebarScrollableContainer,
} from '@affine/component/app-sidebar';
import { MoveToTrash } from '@affine/component/page-list';
import {
createEmptyCollection,
MoveToTrash,
useCollectionManager,
useEditCollectionName,
} from '@affine/component/page-list';
import { Menu } from '@affine/component/ui/menu';
import { collectionsCRUDAtom } from '@affine/core/atoms/collections';
import { WorkspaceSubPath } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { FolderIcon, SettingsIcon } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store';
import { type Page } from '@blocksuite/store';
import { useDroppable } from '@dnd-kit/core';
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
import { useAtom, useAtomValue } from 'jotai';
import { nanoid } from 'nanoid';
import type { HTMLAttributes, ReactElement } from 'react';
import { forwardRef, useCallback, useEffect, useMemo } from 'react';
@@ -171,6 +178,24 @@ export const RootAppSidebar = ({
}, [setOpenUserWorkspaceList]);
useRegisterBrowserHistoryCommands(router.back, router.forward);
const userInfo = useDeleteCollectionInfo();
const setting = useCollectionManager(collectionsCRUDAtom);
const { node, open } = useEditCollectionName({
title: t['com.affine.editCollection.createCollection'](),
showTips: true,
});
const handleCreateCollection = useCallback(() => {
open('')
.then(async name => {
const id = nanoid();
await setting.createCollection(createEmptyCollection(id, { name }));
navigateHelper.jumpToCollection(blockSuiteWorkspace.id, id);
})
.catch(err => {
console.error(err);
});
}, [blockSuiteWorkspace.id, navigateHelper, open, setting]);
return (
<AppSidebar
router={router}
@@ -245,9 +270,13 @@ export const RootAppSidebar = ({
</CategoryDivider>
<FavoriteList workspace={blockSuiteWorkspace} />
<CategoryDivider label={t['com.affine.rootAppSidebar.collections']()}>
<AddCollectionButton />
<AddCollectionButton node={node} onClick={handleCreateCollection} />
</CategoryDivider>
<CollectionsList workspace={blockSuiteWorkspace} info={userInfo} />
<CollectionsList
workspace={blockSuiteWorkspace}
info={userInfo}
onCreate={handleCreateCollection}
/>
<CategoryDivider label={t['com.affine.rootAppSidebar.others']()} />
{/* fixme: remove the following spacer */}
<div style={{ height: '4px' }} />
@@ -553,6 +553,8 @@
"com.affine.collection.menu.rename": "Rename",
"com.affine.collectionBar.backToAll": "Back to all",
"com.affine.collections.header": "Collections",
"com.affine.collections.empty.message": "No collections",
"com.affine.collections.empty.new-collection-button": "New collection",
"com.affine.confirmModal.button.cancel": "Cancel",
"com.affine.currentYear": "Current Year",
"com.affine.deleteLeaveWorkspace.description": "Delete workspace from this device and optionally delete all data.",