feat(core): add new doc button to collection page (#6423)

close TOV-64

You can add this document to the collection while creating a new document on the collection page.

<img width="790" alt="image" src="https://github.com/toeverything/AFFiNE/assets/102217452/828f80af-a1a5-47c2-98c2-a574cf79052c">
This commit is contained in:
JimmFly 2024-04-01 08:05:23 +00:00
parent 9c6eba8971
commit 2631b41e6d
No known key found for this signature in database
GPG Key ID: 14A6F56854E1BED7
12 changed files with 123 additions and 52 deletions

View File

@ -22,7 +22,7 @@ export const newCollectionButton = style({
padding: '6px 10px',
borderRadius: '8px',
background: cssVar('backgroundPrimaryColor'),
fontSize: cssVar('fontSm'),
fontWeight: 600,
height: '32px',
fontSize: cssVar('fontXs'),
fontWeight: 500,
height: '28px',
});

View File

@ -10,7 +10,7 @@ import { menuContent } from './new-page-button.css';
type NewPageButtonProps = {
createNewPage: () => void;
createNewEdgeless: () => void;
importFile: () => void;
importFile?: () => void;
size?: 'small' | 'default';
};
@ -43,13 +43,15 @@ export const CreateNewPagePopup = ({
onClick={createNewEdgeless}
data-testid="new-edgeless-button-in-all-page"
/>
<BlockCard
title={t['com.affine.new_import']()}
desc={t['com.affine.import_file']()}
right={<ImportIcon width={20} height={20} />}
onClick={importFile}
data-testid="import-button-in-all-page"
/>
{importFile ? (
<BlockCard
title={t['com.affine.new_import']()}
desc={t['com.affine.import_file']()}
right={<ImportIcon width={20} height={20} />}
onClick={importFile}
data-testid="import-button-in-all-page"
/>
) : null}
{/* TODO Import */}
</div>
);
@ -63,22 +65,29 @@ export const NewPageButton = ({
children,
}: PropsWithChildren<NewPageButtonProps>) => {
const [open, setOpen] = useState(false);
const handleCreateNewPage = useCallback(() => {
createNewPage();
setOpen(false);
}, [createNewPage]);
const handleCreateNewEdgeless = useCallback(() => {
createNewEdgeless();
setOpen(false);
}, [createNewEdgeless]);
const handleImportFile = useCallback(() => {
importFile?.();
setOpen(false);
}, [importFile]);
return (
<Menu
items={
<CreateNewPagePopup
createNewPage={useCallback(() => {
createNewPage();
setOpen(false);
}, [createNewPage])}
createNewEdgeless={useCallback(() => {
createNewEdgeless();
setOpen(false);
}, [createNewEdgeless])}
importFile={useCallback(() => {
importFile();
setOpen(false);
}, [importFile])}
createNewPage={handleCreateNewPage}
createNewEdgeless={handleCreateNewEdgeless}
importFile={importFile ? handleImportFile : undefined}
/>
}
rootOptions={{

View File

@ -31,9 +31,9 @@ export const addPageButton = style({
padding: '6px 10px',
borderRadius: '8px',
background: cssVar('backgroundPrimaryColor'),
fontSize: cssVar('fontSm'),
fontWeight: 600,
height: '32px',
fontSize: cssVar('fontXs'),
fontWeight: 500,
height: '28px',
});
export const tagSticky = style({
display: 'flex',
@ -162,3 +162,16 @@ export const tagSelectorItemText = style({
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
});
export const rightButtonGroup = style({
display: 'flex',
gap: '12px',
alignItems: 'center',
justifyContent: 'center',
});
export const buttonText = style({
fontSize: cssVar('fontXs'),
fontWeight: 500,
color: cssVar('textPrimaryColor'),
});

View File

@ -10,13 +10,14 @@ import {
SearchIcon,
ViewLayersIcon,
} from '@blocksuite/icons';
import { useLiveData, useService } from '@toeverything/infra';
import { useLiveData, useService, Workspace } from '@toeverything/infra';
import clsx from 'clsx';
import { nanoid } from 'nanoid';
import { useCallback, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { CollectionService } from '../../../modules/collection';
import { usePageHelper } from '../../blocksuite/block-suite-page-list/utils';
import { createTagFilter } from '../filter/utils';
import { createEmptyCollection } from '../use-collection-manager';
import type { AllPageListConfig } from '../view/edit-collection/edit-collection';
@ -29,6 +30,10 @@ import { PageListNewPageButton } from './page-list-new-page-button';
export const PageListHeader = () => {
const t = useAFFiNEI18N();
const workspace = useService(Workspace);
const { importFile, createEdgeless, createPage } = usePageHelper(
workspace.docCollection
);
const title = useMemo(() => {
return t['com.affine.all-pages.header']();
@ -37,8 +42,14 @@ export const PageListHeader = () => {
return (
<div className={styles.docListHeader}>
<div className={styles.docListHeaderTitle}>{title}</div>
<PageListNewPageButton testId="new-page-button-trigger">
{t['New Page']()}
<PageListNewPageButton
size="small"
testId="new-page-button-trigger"
onCreateEdgeless={createEdgeless}
onCreatePage={createPage}
onImportFile={importFile}
>
<div className={styles.buttonText}>{t['New Page']()}</div>
</PageListNewPageButton>
</div>
);
@ -62,11 +73,23 @@ export const CollectionPageListHeader = ({
const collectionService = useService(CollectionService);
const { node, open } = useEditCollection(config);
const handleAddPage = useAsyncCallback(async () => {
const handleEdit = useAsyncCallback(async () => {
const ret = await open({ ...collection }, 'page');
collectionService.updateCollection(collection.id, () => ret);
}, [collection, collectionService, open]);
const workspace = useService(Workspace);
const { createEdgeless, createPage } = usePageHelper(workspace.docCollection);
const handleCreateEdgeless = useCallback(() => {
const newDoc = createEdgeless();
collectionService.addPageToCollection(collection.id, newDoc.id);
}, [collection.id, collectionService, createEdgeless]);
const handleCreatePage = useCallback(() => {
const newDoc = createPage();
collectionService.addPageToCollection(collection.id, newDoc.id);
}, [collection.id, collectionService, createPage]);
return (
<>
{node}
@ -80,9 +103,19 @@ export const CollectionPageListHeader = ({
</div>
<div className={styles.titleCollectionName}>{collection.name}</div>
</div>
<Button className={styles.addPageButton} onClick={handleAddPage}>
{t['com.affine.collection.addPages']()}
</Button>
<div className={styles.rightButtonGroup}>
<Button className={styles.addPageButton} onClick={handleEdit}>
{t['Edit']()}
</Button>
<PageListNewPageButton
size="small"
testId="new-page-button-trigger"
onCreateEdgeless={handleCreateEdgeless}
onCreatePage={handleCreatePage}
>
<div className={styles.buttonText}>{t['New Page']()}</div>
</PageListNewPageButton>
</div>
</div>
</>
);

View File

@ -133,7 +133,7 @@ export const dateCell = style({
display: 'flex',
alignItems: 'center',
fontSize: cssVar('fontXs'),
color: cssVar('textSecondaryColor'),
color: cssVar('textPrimaryColor'),
flexShrink: 0,
flexWrap: 'nowrap',
padding: '0 8px',

View File

@ -1,7 +1,5 @@
import { useService, Workspace } from '@toeverything/infra';
import type { PropsWithChildren } from 'react';
import { usePageHelper } from '../../blocksuite/block-suite-page-list/utils';
import { NewPageButton } from '../components/new-page-button';
import * as styles from './page-list-new-page-button.css';
@ -10,22 +8,24 @@ export const PageListNewPageButton = ({
children,
size,
testId,
onCreatePage,
onCreateEdgeless,
onImportFile,
}: PropsWithChildren<{
className?: string;
size?: 'small' | 'default';
testId?: string;
onCreatePage: () => void;
onCreateEdgeless: () => void;
onImportFile?: () => void;
}>) => {
const currentWorkspace = useService(Workspace);
const { importFile, createEdgeless, createPage } = usePageHelper(
currentWorkspace.docCollection
);
return (
<div className={className} data-testid={testId}>
<NewPageButton
size={size}
importFile={importFile}
createNewEdgeless={createEdgeless}
createNewPage={createPage}
importFile={onImportFile}
createNewEdgeless={onCreateEdgeless}
createNewPage={onCreatePage}
>
<div className={styles.newPageButtonLabel}>{children}</div>
</NewPageButton>

View File

@ -22,7 +22,7 @@ export const newTagButton = style({
padding: '6px 10px',
borderRadius: '8px',
background: cssVar('backgroundPrimaryColor'),
fontSize: cssVar('fontSm'),
fontWeight: 600,
height: '32px',
fontSize: cssVar('fontXs'),
fontWeight: 500,
height: '28px',
});

View File

@ -0,0 +1,10 @@
import { cssVar } from '@toeverything/theme';
import { style } from '@vanilla-extract/css';
export const button = style({
padding: '6px 10px',
borderRadius: '8px',
background: cssVar('backgroundPrimaryColor'),
fontSize: cssVar('fontXs'),
fontWeight: 500,
height: '28px',
});

View File

@ -6,6 +6,7 @@ import { nanoid } from 'nanoid';
import { useCallback } from 'react';
import { createEmptyCollection } from '../use-collection-manager';
import * as styles from './save-as-collection-button.css';
import { useEditCollectionName } from './use-edit-collection';
interface SaveAsCollectionButtonProps {
@ -35,8 +36,7 @@ export const SaveAsCollectionButton = ({
onClick={handleClick}
data-testid="save-as-collection"
icon={<SaveIcon />}
size="large"
style={{ padding: '7px 8px' }}
className={styles.button}
>
{t['com.affine.editCollection.saveCollection']()}
</Button>

View File

@ -147,6 +147,6 @@ export const emptyCollectionMessage = style({
});
export const emptyCollectionNewButton = style({
padding: '0 8px',
height: '30px',
fontSize: cssVar('fontSm'),
height: '28px',
fontSize: cssVar('fontXs'),
});

View File

@ -1,3 +1,4 @@
import { usePageHelper } from '@affine/core/components/blocksuite/block-suite-page-list/utils';
import {
AllPageListOperationsMenu,
PageDisplayMenu,
@ -22,7 +23,9 @@ export const AllPageHeader = ({
onChangeFilters: (filters: Filter[]) => void;
}) => {
const workspace = useService(Workspace);
const { importFile, createEdgeless, createPage } = usePageHelper(
workspace.docCollection
);
return (
<Header
left={
@ -40,6 +43,9 @@ export const AllPageHeader = ({
styles.headerCreateNewButton,
!showCreateNew && styles.headerCreateNewButtonHidden
)}
onCreateEdgeless={createEdgeless}
onCreatePage={createPage}
onImportFile={importFile}
>
<PlusIcon />
</PageListNewPageButton>

View File

@ -892,7 +892,7 @@
"com.affine.payment.member-limit.pro.confirm": "知道了",
"com.affine.payment.member-limit.pro.description": "每个 {{planName}} 用户最多可以邀请 {{quota}} 个成员加入他们的工作区。 如果您想继续添加协作成员,可以创建新的工作区。",
"com.affine.payment.member-limit.title": "成员数量已达到极限",
"com.affine.payment.member.description": "在此处管理成员。{{planName}} 用户可以邀请最多 {{memberLimit}} 人",
"com.affine.payment.member.description": "在此处管理成员。{{planName}} 用户可以邀请最多 {{memberLimit}} 人",
"com.affine.payment.member.description.go-upgrade": "前往升级",
"com.affine.payment.modal.change.cancel": "取消",
"com.affine.payment.modal.change.confirm": "更改",