mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 17:46:18 +08:00
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:
+3
-11
@@ -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>
|
||||
);
|
||||
|
||||
+9
-36
@@ -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 />
|
||||
|
||||
+24
-14
@@ -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 (
|
||||
|
||||
+42
@@ -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.",
|
||||
|
||||
Reference in New Issue
Block a user