mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 17:22:18 +03:00
feat: add new collection button to slider bar (#3369)
This commit is contained in:
parent
8334ac031b
commit
2c249781a2
@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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']()}
|
||||
|
@ -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)',
|
||||
|
@ -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();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user