feat: add new collection button to slider bar (#3369)

This commit is contained in:
JimmFly 2023-07-26 12:32:55 +08:00 committed by GitHub
parent 8334ac031b
commit 2c249781a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 130 additions and 27 deletions

View File

@ -0,0 +1,56 @@
import { IconButton } from '@affine/component';
import {
EditCollectionModel,
useCollectionManager,
} from '@affine/component/page-list';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { PlusIcon } from '@blocksuite/icons';
import type { Workspace } from '@blocksuite/store';
import { uuidv4 } from '@blocksuite/store';
import { useMemo, useState } from 'react';
import { useGetPageInfoById } from '../../../../hooks/use-get-page-info';
type AddCollectionButtonProps = {
workspace: Workspace;
};
export const AddCollectionButton = ({
workspace,
}: AddCollectionButtonProps) => {
const getPageInfo = useGetPageInfoById(workspace);
const setting = useCollectionManager(workspace.id);
const t = useAFFiNEI18N();
const [show, showUpdateCollection] = useState(false);
const defaultCollection = useMemo(
() => ({
id: uuidv4(),
name: '',
pinned: true,
filterList: [],
workspaceId: workspace.id,
}),
[workspace.id]
);
return (
<>
<IconButton
data-testid="slider-bar-add-collection-button"
onClick={() => showUpdateCollection(true)}
size="small"
>
<PlusIcon />
</IconButton>
<EditCollectionModel
propertiesMeta={workspace.meta.properties}
getPageInfo={getPageInfo}
onConfirm={setting.saveCollection}
open={show}
onClose={() => showUpdateCollection(false)}
title={t['Save As New Collection']()}
init={defaultCollection}
/>
</>
);
};

View File

@ -12,6 +12,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { import {
DeleteIcon, DeleteIcon,
FilterIcon, FilterIcon,
InformationIcon,
MoreHorizontalIcon, MoreHorizontalIcon,
UnpinIcon, UnpinIcon,
ViewLayersIcon, ViewLayersIcon,
@ -251,21 +252,34 @@ export const CollectionsList = ({ workspace }: CollectionsListProps) => {
const metas = useBlockSuitePageMeta(workspace); const metas = useBlockSuitePageMeta(workspace);
const { savedCollections } = useSavedCollections(workspace.id); const { savedCollections } = useSavedCollections(workspace.id);
const getPageInfo = useGetPageInfoById(workspace); const getPageInfo = useGetPageInfoById(workspace);
const pinedCollections = useMemo(
() => savedCollections.filter(v => v.pinned),
[savedCollections]
);
if (pinedCollections.length === 0) {
return (
<MenuItem
data-testid="slider-bar-collection-null-description"
icon={<InformationIcon />}
disabled
>
<span>Create a collection</span>
</MenuItem>
);
}
return ( return (
<div data-testid="collections" className={styles.wrapper}> <div data-testid="collections" className={styles.wrapper}>
{savedCollections {pinedCollections.map(view => {
.filter(v => v.pinned) return (
.map(view => { <CollectionRenderer
return ( getPageInfo={getPageInfo}
<CollectionRenderer key={view.id}
getPageInfo={getPageInfo} collection={view}
key={view.id} pages={metas}
collection={view} workspace={workspace}
pages={metas} />
workspace={workspace} );
/> })}
);
})}
</div> </div>
); );
}; };

View File

@ -29,6 +29,7 @@ import { useHistoryAtom } from '../../atoms/history';
import { useAppSetting } from '../../atoms/settings'; import { useAppSetting } from '../../atoms/settings';
import type { AllWorkspace } from '../../shared'; import type { AllWorkspace } from '../../shared';
import { CollectionsList } from '../pure/workspace-slider-bar/collections'; import { CollectionsList } from '../pure/workspace-slider-bar/collections';
import { AddCollectionButton } from '../pure/workspace-slider-bar/collections/add-collection-button';
import FavoriteList from '../pure/workspace-slider-bar/favorite/favorite-list'; import FavoriteList from '../pure/workspace-slider-bar/favorite/favorite-list';
import { WorkspaceSelector } from '../pure/workspace-slider-bar/WorkspaceSelector'; import { WorkspaceSelector } from '../pure/workspace-slider-bar/WorkspaceSelector';
import ImportPage from './import-page'; import ImportPage from './import-page';
@ -190,7 +191,9 @@ export const RootAppSidebar = ({
<SidebarScrollableContainer> <SidebarScrollableContainer>
<CategoryDivider label={t['Favorites']()} /> <CategoryDivider label={t['Favorites']()} />
<FavoriteList workspace={blockSuiteWorkspace} /> <FavoriteList workspace={blockSuiteWorkspace} />
<CategoryDivider label={t['Collections']()} /> <CategoryDivider label={t['Collections']()}>
<AddCollectionButton workspace={blockSuiteWorkspace} />
</CategoryDivider>
<CollectionsList workspace={blockSuiteWorkspace} /> <CollectionsList workspace={blockSuiteWorkspace} />
<CategoryDivider label={t['others']()} /> <CategoryDivider label={t['others']()} />
<RouteMenuLinkItem <RouteMenuLinkItem

View File

@ -2,8 +2,11 @@ import { style } from '@vanilla-extract/css';
export const root = style({ export const root = style({
fontSize: 'var(--affine-font-xs)', fontSize: 'var(--affine-font-xs)',
height: '16px', minHeight: '16px',
userSelect: 'none', userSelect: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
selectors: { selectors: {
'&:not(:first-of-type)': { '&:not(:first-of-type)': {
marginTop: '10px', marginTop: '10px',

View File

@ -21,7 +21,6 @@ export const viewButton = style({
fontSize: 'var(--affine-font-xs)', fontSize: 'var(--affine-font-xs)',
background: 'var(--affine-white)', background: 'var(--affine-white)',
maxWidth: '200px', maxWidth: '200px',
overflow: 'hidden',
color: 'var(--affine-text-secondary-color)', color: 'var(--affine-text-secondary-color)',
border: '1px solid var(--affine-border-color)', border: '1px solid var(--affine-border-color)',
transition: 'margin-left 0.2s ease-in-out', transition: 'margin-left 0.2s ease-in-out',
@ -41,6 +40,8 @@ export const viewButton = style({
}, },
}); });
globalStyle(`${viewButton} > span`, { globalStyle(`${viewButton} > span`, {
display: 'block',
width: '100%',
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
@ -75,6 +76,9 @@ export const filterButton = style({
padding: '4px 8px', padding: '4px 8px',
fontSize: 'var(--affine-font-xs)', fontSize: 'var(--affine-font-xs)',
background: 'var(--affine-white)', background: 'var(--affine-white)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'var(--affine-text-secondary-color)', color: 'var(--affine-text-secondary-color)',
border: '1px solid var(--affine-border-color)', border: '1px solid var(--affine-border-color)',
transition: 'margin-left 0.2s ease-in-out', transition: 'margin-left 0.2s ease-in-out',

View File

@ -243,14 +243,14 @@ export const EditCollection = ({
marginTop: 40, marginTop: 40,
}} }}
> >
<Button className={styles.cancelButton} onClick={onCancel}> <Button size="large" onClick={onCancel}>
{t['Cancel']()} {t['Cancel']()}
</Button> </Button>
<Button <Button
style={{ style={{
marginLeft: 20, marginLeft: 20,
borderRadius: '8px',
}} }}
size="large"
data-testid="save-collection" data-testid="save-collection"
type="primary" type="primary"
onClick={() => { onClick={() => {
@ -276,17 +276,13 @@ export const SaveCollectionButton = ({
return ( return (
<> <>
<Button <Button
className={styles.saveButton}
onClick={() => changeShow(true)} onClick={() => changeShow(true)}
size="large"
data-testid="save-as-collection" data-testid="save-as-collection"
icon={<SaveIcon />}
size="large"
style={{ padding: '7px 8px' }}
> >
<div className={styles.saveButtonContainer}> Save As Collection
<div className={styles.saveIcon}>
<SaveIcon />
</div>
<div className={styles.saveText}>Save As Collection</div>
</div>
</Button> </Button>
<EditCollectionModel <EditCollectionModel
title={t['Save As New Collection']()} title={t['Save As New Collection']()}

View File

@ -67,7 +67,7 @@ export const button = style({
}, },
'&.primary': { '&.primary': {
color: 'var(--affine-white)', color: 'var(--affine-pure-white)',
background: 'var(--affine-primary-color)', background: 'var(--affine-primary-color)',
borderColor: 'var(--affine-black-10)', borderColor: 'var(--affine-black-10)',
boxShadow: 'var(--affine-button-inner-shadow)', boxShadow: 'var(--affine-button-inner-shadow)',

View File

@ -154,3 +154,30 @@ test('create temporary filter by click tag', async ({ page }) => {
await page.getByRole('tooltip').getByText('TODO Tag').click(); await page.getByRole('tooltip').getByText('TODO Tag').click();
expect(await page.getByTestId('title').count()).toBe(2); expect(await page.getByTestId('title').count()).toBe(2);
}); });
test('add collection from sidebar', async ({ page }) => {
await openHomePage(page);
await waitEditorLoad(page);
await newPage(page);
await getBlockSuiteEditorTitle(page).click();
await getBlockSuiteEditorTitle(page).fill('test page');
await page.getByTestId('all-pages').click();
const cell = page.getByRole('cell', {
name: 'test page',
});
await expect(cell).toBeVisible();
const nullCollection = page.getByTestId(
'slider-bar-collection-null-description'
);
await expect(nullCollection).toBeVisible();
await page.getByTestId('slider-bar-add-collection-button').click();
const title = page.getByTestId('input-collection-title');
await title.isVisible();
await title.fill('test collection');
await page.getByTestId('save-collection').click();
await page.waitForTimeout(100);
const collections = page.getByTestId('collections');
const items = collections.getByTestId('collection-item');
expect(await items.count()).toBe(1);
await expect(nullCollection).not.toBeVisible();
});