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 {
DeleteIcon,
FilterIcon,
InformationIcon,
MoreHorizontalIcon,
UnpinIcon,
ViewLayersIcon,
@ -251,21 +252,34 @@ export const CollectionsList = ({ workspace }: CollectionsListProps) => {
const metas = useBlockSuitePageMeta(workspace);
const { savedCollections } = useSavedCollections(workspace.id);
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 (
<div data-testid="collections" className={styles.wrapper}>
{savedCollections
.filter(v => v.pinned)
.map(view => {
return (
<CollectionRenderer
getPageInfo={getPageInfo}
key={view.id}
collection={view}
pages={metas}
workspace={workspace}
/>
);
})}
{pinedCollections.map(view => {
return (
<CollectionRenderer
getPageInfo={getPageInfo}
key={view.id}
collection={view}
pages={metas}
workspace={workspace}
/>
);
})}
</div>
);
};

View File

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

View File

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

View File

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

View File

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

View File

@ -67,7 +67,7 @@ export const button = style({
},
'&.primary': {
color: 'var(--affine-white)',
color: 'var(--affine-pure-white)',
background: 'var(--affine-primary-color)',
borderColor: 'var(--affine-black-10)',
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();
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();
});