mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
feat: add tags support (#2988)
Co-authored-by: Alex Yang <himself65@outlook.com>
This commit is contained in:
@@ -71,6 +71,7 @@ AffineAllPageList.args = {
|
||||
icon: <PageIcon />,
|
||||
isPublicPage: true,
|
||||
title: 'Today Page',
|
||||
tags: [],
|
||||
preview: 'this is page preview',
|
||||
createDate: new Date(),
|
||||
updatedDate: new Date(),
|
||||
@@ -87,6 +88,7 @@ AffineAllPageList.args = {
|
||||
isPublicPage: true,
|
||||
title:
|
||||
'1 Example Public Page with long title that will be truncated because it is too too long',
|
||||
tags: [],
|
||||
preview:
|
||||
'this is page preview and it is very long and will be truncated because it is too long and it is very long and will be truncated because it is too long',
|
||||
createDate: new Date('2021-01-01'),
|
||||
@@ -103,6 +105,7 @@ AffineAllPageList.args = {
|
||||
isPublicPage: false,
|
||||
icon: <PageIcon />,
|
||||
title: '2 Favorited Page 2021',
|
||||
tags: [],
|
||||
createDate: new Date('2021-01-02'),
|
||||
updatedDate: new Date('2021-01-01'),
|
||||
bookmarkPage: () => toast('Bookmark page'),
|
||||
@@ -117,6 +120,7 @@ AffineAllPageList.args = {
|
||||
isPublicPage: false,
|
||||
icon: <PageIcon />,
|
||||
title: 'page created in 2023-04-01',
|
||||
tags: [],
|
||||
createDate: new Date('2023-04-01'),
|
||||
updatedDate: new Date('2023-04-01'),
|
||||
bookmarkPage: () => toast('Bookmark page'),
|
||||
|
||||
@@ -110,6 +110,13 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
usePageHelper(blockSuiteWorkspace);
|
||||
const t = useAFFiNEI18N();
|
||||
const getPageInfo = useGetPageInfoById();
|
||||
const tagOptionMap = useMemo(
|
||||
() =>
|
||||
Object.fromEntries(
|
||||
blockSuiteWorkspace.meta.properties.tags.options.map(v => [v.id, v])
|
||||
),
|
||||
[blockSuiteWorkspace.meta.properties.tags.options]
|
||||
);
|
||||
const list = useMemo(
|
||||
() =>
|
||||
pageMetas
|
||||
@@ -180,11 +187,15 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
const pageList: ListData[] = list.map(pageMeta => {
|
||||
const page = blockSuiteWorkspace.getPage(pageMeta.id);
|
||||
const preview = page ? getPagePreviewText(page) : undefined;
|
||||
|
||||
return {
|
||||
icon: isPreferredEdgeless(pageMeta.id) ? <EdgelessIcon /> : <PageIcon />,
|
||||
pageId: pageMeta.id,
|
||||
title: pageMeta.title,
|
||||
preview,
|
||||
tags:
|
||||
page?.meta.tags.map(id => tagOptionMap[id]).filter(v => v != null) ??
|
||||
[],
|
||||
favorite: !!pageMeta.favorite,
|
||||
isPublicPage: !!pageMeta.isPublic,
|
||||
createDate: new Date(pageMeta.createDate),
|
||||
@@ -219,6 +230,7 @@ export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
});
|
||||
return (
|
||||
<PageList
|
||||
propertiesMeta={blockSuiteWorkspace.meta.properties}
|
||||
getPageInfo={getPageInfo}
|
||||
onCreateNewPage={createPage}
|
||||
onCreateNewEdgeless={createEdgeless}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Menu } from '@affine/component';
|
||||
import { MenuItem } from '@affine/component/app-sidebar';
|
||||
import {
|
||||
EditCollectionModel,
|
||||
useAllPageSetting,
|
||||
useCollectionManager,
|
||||
useSavedCollections,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
@@ -49,7 +49,7 @@ const CollectionOperations = ({
|
||||
}: {
|
||||
view: Collection;
|
||||
showUpdateCollection: () => void;
|
||||
setting: ReturnType<typeof useAllPageSetting>;
|
||||
setting: ReturnType<typeof useCollectionManager>;
|
||||
}) => {
|
||||
const actions = useMemo<
|
||||
Array<
|
||||
@@ -128,7 +128,7 @@ const CollectionRenderer = ({
|
||||
getPageInfo: GetPageInfoById;
|
||||
}) => {
|
||||
const [collapsed, setCollapsed] = React.useState(true);
|
||||
const setting = useAllPageSetting();
|
||||
const setting = useCollectionManager();
|
||||
const router = useRouter();
|
||||
const clickCollection = useCallback(() => {
|
||||
router
|
||||
@@ -187,6 +187,7 @@ const CollectionRenderer = ({
|
||||
return (
|
||||
<Collapsible.Root open={!collapsed}>
|
||||
<EditCollectionModel
|
||||
propertiesMeta={workspace.blockSuiteWorkspace.meta.properties}
|
||||
getPageInfo={getPageInfo}
|
||||
init={collection}
|
||||
onConfirm={setting.saveCollection}
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
CollectionList,
|
||||
FilterList,
|
||||
SaveCollectionButton,
|
||||
useAllPageSetting,
|
||||
useCollectionManager,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import type { WorkspaceHeaderProps } from '@affine/env/workspace';
|
||||
@@ -22,7 +22,7 @@ export function WorkspaceHeader({
|
||||
currentWorkspace,
|
||||
currentEntry,
|
||||
}: WorkspaceHeaderProps<WorkspaceFlavour>): ReactElement {
|
||||
const setting = useAllPageSetting();
|
||||
const setting = useCollectionManager();
|
||||
const t = useAFFiNEI18N();
|
||||
const saveToCollection = useCallback(
|
||||
async (collection: Collection) => {
|
||||
@@ -38,6 +38,7 @@ export function WorkspaceHeader({
|
||||
<CollectionList
|
||||
setting={setting}
|
||||
getPageInfo={getPageInfoById}
|
||||
propertiesMeta={currentWorkspace.blockSuiteWorkspace.meta.properties}
|
||||
></CollectionList>
|
||||
);
|
||||
const filterContainer =
|
||||
@@ -45,6 +46,9 @@ export function WorkspaceHeader({
|
||||
<div className={filterContainerStyle}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<FilterList
|
||||
propertiesMeta={
|
||||
currentWorkspace.blockSuiteWorkspace.meta.properties
|
||||
}
|
||||
value={setting.currentCollection.filterList}
|
||||
onChange={filterList => {
|
||||
return setting.updateCollection({
|
||||
@@ -57,6 +61,9 @@ export function WorkspaceHeader({
|
||||
<div>
|
||||
{setting.currentCollection.filterList.length > 0 ? (
|
||||
<SaveCollectionButton
|
||||
propertiesMeta={
|
||||
currentWorkspace.blockSuiteWorkspace.meta.properties
|
||||
}
|
||||
getPageInfo={getPageInfoById}
|
||||
init={{
|
||||
id: uuidv4(),
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
||||
import {
|
||||
createTagFilter,
|
||||
useCollectionManager,
|
||||
} from '@affine/component/page-list';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
|
||||
import type { EditorContainer } from '@blocksuite/editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
@@ -19,29 +24,41 @@ import type { NextPageWithLayout } from '../../../shared';
|
||||
|
||||
const WorkspaceDetail: React.FC = () => {
|
||||
const router = useRouter();
|
||||
const { openPage } = useRouterHelper(router);
|
||||
const { openPage, jumpToSubPath } = useRouterHelper(router);
|
||||
const currentPageId = useAtomValue(rootCurrentPageIdAtom);
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
assertExists(currentWorkspace);
|
||||
assertExists(currentPageId);
|
||||
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
|
||||
const [setting, setSetting] = useAtom(pageSettingFamily(currentPageId));
|
||||
const collectionManager = useCollectionManager();
|
||||
if (!setting) {
|
||||
setSetting({
|
||||
mode: 'page',
|
||||
});
|
||||
}
|
||||
|
||||
const onLoad = useCallback(
|
||||
(page: Page, editor: EditorContainer) => {
|
||||
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => {
|
||||
return openPage(blockSuiteWorkspace.id, pageId);
|
||||
});
|
||||
const disposeTagClick = editor.slots.tagClicked.on(async ({ tagId }) => {
|
||||
await jumpToSubPath(currentWorkspace.id, WorkspaceSubPath.ALL);
|
||||
collectionManager.backToAll();
|
||||
collectionManager.setTemporaryFilter([createTagFilter(tagId)]);
|
||||
});
|
||||
return () => {
|
||||
dispose.dispose();
|
||||
disposeTagClick.dispose();
|
||||
};
|
||||
},
|
||||
[blockSuiteWorkspace.id, openPage]
|
||||
[
|
||||
blockSuiteWorkspace.id,
|
||||
collectionManager,
|
||||
currentWorkspace.id,
|
||||
jumpToSubPath,
|
||||
openPage,
|
||||
]
|
||||
);
|
||||
|
||||
const { PageDetail, Header } = getUIAdapter(currentWorkspace.flavour);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useAllPageSetting } from '@affine/component/page-list';
|
||||
import { useCollectionManager } from '@affine/component/page-list';
|
||||
import { QueryParamError } from '@affine/env/constant';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
@@ -16,7 +16,7 @@ import type { NextPageWithLayout } from '../../../shared';
|
||||
|
||||
const AllPage: NextPageWithLayout = () => {
|
||||
const router = useRouter();
|
||||
const setting = useAllPageSetting();
|
||||
const setting = useCollectionManager();
|
||||
const { jumpToPage } = useRouterHelper(router);
|
||||
const [currentWorkspace] = useCurrentWorkspace();
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
@@ -13,5 +13,6 @@ export const filterPage = (collection: Collection, page: PageMeta) => {
|
||||
'Is Favourited': !!page.favorite,
|
||||
Created: page.createDate,
|
||||
Updated: page.updatedDate ?? page.createDate,
|
||||
Tags: page.tags,
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user