mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
refactor: clean all pages component (#2176)
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
import { MenuItem } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CopyIcon } from '@blocksuite/icons';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
//
|
||||
import { toast } from '../../../utils';
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
|
||||
export const CopyLink = ({ onItemClick, onSelect }: CommonMenuItemProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const copyUrl = useCallback(() => {
|
||||
navigator.clipboard.writeText(window.location.href);
|
||||
toast(t['Copied link to clipboard']());
|
||||
}, [t]);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
data-testid="copy-link"
|
||||
onClick={() => {
|
||||
copyUrl();
|
||||
onItemClick?.();
|
||||
onSelect?.();
|
||||
}}
|
||||
icon={<CopyIcon />}
|
||||
>
|
||||
{t['Copy Link']()}
|
||||
</MenuItem>
|
||||
);
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
import { MenuItem, styled } from '@affine/component';
|
||||
import type { PublicLinkDisableProps } from '@affine/component/share-menu';
|
||||
import { PublicLinkDisableModal } from '@affine/component/share-menu';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ShareIcon } from '@blocksuite/icons';
|
||||
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
|
||||
const StyledMenuItem = styled(MenuItem)(({ theme }) => {
|
||||
return {
|
||||
div: {
|
||||
color: theme.palette.error.main,
|
||||
svg: {
|
||||
color: theme.palette.error.main,
|
||||
},
|
||||
},
|
||||
':hover': {
|
||||
div: {
|
||||
color: theme.palette.error.main,
|
||||
svg: {
|
||||
color: theme.palette.error.main,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
export const DisablePublicSharing = ({
|
||||
onSelect,
|
||||
onItemClick,
|
||||
testId,
|
||||
}: CommonMenuItemProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<>
|
||||
<StyledMenuItem
|
||||
data-testid={testId}
|
||||
onClick={() => {
|
||||
onItemClick?.();
|
||||
onSelect?.();
|
||||
}}
|
||||
style={{ color: 'red' }}
|
||||
icon={<ShareIcon />}
|
||||
>
|
||||
{t['Disable Public Sharing']()}
|
||||
</StyledMenuItem>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const DisablePublicSharingModal = ({
|
||||
page,
|
||||
open,
|
||||
onClose,
|
||||
}: PublicLinkDisableProps) => {
|
||||
return <PublicLinkDisableModal page={page} open={open} onClose={onClose} />;
|
||||
};
|
||||
|
||||
DisablePublicSharing.DisablePublicSharingModal = DisablePublicSharingModal;
|
||||
@@ -1,73 +0,0 @@
|
||||
import { Menu, MenuItem } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ContentParser } from '@blocksuite/blocks/content-parser';
|
||||
import {
|
||||
ArrowRightSmallIcon,
|
||||
ExportIcon,
|
||||
ExportToHtmlIcon,
|
||||
ExportToMarkdownIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import { useRef } from 'react';
|
||||
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
|
||||
export const Export = ({
|
||||
onSelect,
|
||||
onItemClick,
|
||||
}: CommonMenuItemProps<{ type: 'markdown' | 'html' }>) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const contentParserRef = useRef<ContentParser>();
|
||||
return (
|
||||
<Menu
|
||||
width={248}
|
||||
placement="left"
|
||||
trigger="click"
|
||||
content={
|
||||
<>
|
||||
<MenuItem
|
||||
data-testid="export-to-html"
|
||||
onClick={() => {
|
||||
if (!contentParserRef.current) {
|
||||
contentParserRef.current = new ContentParser(
|
||||
globalThis.currentEditor!.page
|
||||
);
|
||||
}
|
||||
contentParserRef.current.onExportHtml();
|
||||
onSelect?.({ type: 'html' });
|
||||
}}
|
||||
icon={<ExportToHtmlIcon />}
|
||||
>
|
||||
{t['Export to HTML']()}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
data-testid="export-to-markdown"
|
||||
onClick={() => {
|
||||
if (!contentParserRef.current) {
|
||||
contentParserRef.current = new ContentParser(
|
||||
globalThis.currentEditor!.page
|
||||
);
|
||||
}
|
||||
contentParserRef.current.onExportMarkdown();
|
||||
onSelect?.({ type: 'markdown' });
|
||||
}}
|
||||
icon={<ExportToMarkdownIcon />}
|
||||
>
|
||||
{t['Export to Markdown']()}
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<MenuItem
|
||||
data-testid="export-menu"
|
||||
icon={<ExportIcon />}
|
||||
endIcon={<ArrowRightSmallIcon />}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onItemClick?.();
|
||||
}}
|
||||
>
|
||||
{t.Export()}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
import { MenuItem } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ArrowRightSmallIcon, MoveToIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import type { BlockSuiteWorkspace } from '../../../shared';
|
||||
import { PinboardMenu } from '../pinboard';
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
|
||||
export type MoveToProps = CommonMenuItemProps<{
|
||||
dragId: string;
|
||||
dropId: string;
|
||||
}> & {
|
||||
metas: PageMeta[];
|
||||
currentMeta: PageMeta;
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const MoveTo = ({
|
||||
metas,
|
||||
currentMeta,
|
||||
blockSuiteWorkspace,
|
||||
onSelect,
|
||||
onItemClick,
|
||||
}: MoveToProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
const open = anchorEl !== null;
|
||||
return (
|
||||
<>
|
||||
<MenuItem
|
||||
ref={ref}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
setAnchorEl(ref.current);
|
||||
onItemClick?.();
|
||||
}}
|
||||
icon={<MoveToIcon />}
|
||||
endIcon={<ArrowRightSmallIcon />}
|
||||
data-testid="move-to-menu-item"
|
||||
>
|
||||
{t['Move to']()}
|
||||
</MenuItem>
|
||||
<PinboardMenu
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
placement="left"
|
||||
metas={metas}
|
||||
currentMeta={currentMeta}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onPinboardClick={onSelect}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
import type { ConfirmProps } from '@affine/component';
|
||||
import { Confirm, MenuItem } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { DeleteTemporarilyIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
|
||||
import type { CommonMenuItemProps } from './types';
|
||||
|
||||
export const MoveToTrash = ({
|
||||
onSelect,
|
||||
onItemClick,
|
||||
testId,
|
||||
}: CommonMenuItemProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem
|
||||
data-testid={testId}
|
||||
onClick={() => {
|
||||
onItemClick?.();
|
||||
onSelect?.();
|
||||
}}
|
||||
icon={<DeleteTemporarilyIcon />}
|
||||
>
|
||||
{t['Move to Trash']()}
|
||||
</MenuItem>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ConfirmModal = ({
|
||||
meta,
|
||||
...confirmModalProps
|
||||
}: {
|
||||
meta: PageMeta;
|
||||
} & ConfirmProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<Confirm
|
||||
title={t['Delete page?']()}
|
||||
content={t['will be moved to Trash']({
|
||||
title: meta.title || 'Untitled',
|
||||
})}
|
||||
confirmText={t.Delete()}
|
||||
confirmType="danger"
|
||||
{...confirmModalProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
MoveToTrash.ConfirmModal = ConfirmModal;
|
||||
@@ -1,5 +0,0 @@
|
||||
export * from './CopyLink';
|
||||
export * from './DisablePublicSharing';
|
||||
export * from './Export';
|
||||
export * from './MoveTo';
|
||||
export * from './MoveToTrash';
|
||||
@@ -1,7 +0,0 @@
|
||||
export type CommonMenuItemProps<SelectParams = undefined> = {
|
||||
// onItemClick is triggered when the item is clicked, sometimes after item click, it still has some internal logic to run(like popover a new menu), so we need to have a separate callback for that
|
||||
onItemClick?: () => void;
|
||||
// onSelect is triggered when the item is selected, it's the final callback for the item click
|
||||
onSelect?: (params?: SelectParams) => void;
|
||||
testId?: string;
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import { MenuItem, MuiClickAwayListener, PureMenu } from '@affine/component';
|
||||
import { CopyLink, MoveToTrash } from '@affine/component/page-list';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
MoreVerticalIcon,
|
||||
@@ -13,7 +14,6 @@ import { useMemo, useRef, useState } from 'react';
|
||||
import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper';
|
||||
import type { BlockSuiteWorkspace } from '../../../../shared';
|
||||
import { toast } from '../../../../utils';
|
||||
import { CopyLink, MoveToTrash } from '../../operation-menu-items';
|
||||
import { PinboardMenu } from '../pinboard-menu/';
|
||||
import { StyledOperationButton } from '../styles';
|
||||
|
||||
@@ -152,7 +152,7 @@ export const OperationButton = ({
|
||||
/>
|
||||
<MoveToTrash.ConfirmModal
|
||||
open={confirmModalOpen}
|
||||
meta={currentMeta}
|
||||
title={currentMeta.title}
|
||||
onConfirm={() => {
|
||||
toast(t['Moved to Trash']());
|
||||
removeToTrash(currentMeta.id);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const pageListEmptyStyle = style({
|
||||
height: 'calc(100% - 52px)',
|
||||
});
|
||||
@@ -1,35 +1,172 @@
|
||||
import { Empty } from '@affine/component';
|
||||
import type { ListData, TrashListData } from '@affine/component/page-list';
|
||||
import { PageList, PageListTrashView } from '@affine/component/page-list';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import dayjs from 'dayjs';
|
||||
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type React from 'react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { workspacePreferredModeAtom } from '../../../atoms';
|
||||
import { useBlockSuiteMetaHelper } from '../../../hooks/affine/use-block-suite-meta-helper';
|
||||
import type { BlockSuiteWorkspace } from '../../../shared';
|
||||
import PageList from './page-list';
|
||||
import { toast } from '../../../utils';
|
||||
import { pageListEmptyStyle } from './index.css';
|
||||
|
||||
export type BlockSuitePageListProps = {
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
listType: 'all' | 'trash' | 'favorite' | 'shared' | 'public';
|
||||
isPublic?: true;
|
||||
onOpenPage: (pageId: string, newTab?: boolean) => void;
|
||||
};
|
||||
|
||||
const filter = {
|
||||
all: (pageMeta: PageMeta) => !pageMeta.trash,
|
||||
public: (pageMeta: PageMeta) => !pageMeta.trash,
|
||||
trash: (pageMeta: PageMeta, allMetas: PageMeta[]) => {
|
||||
const parentMeta = allMetas.find(m => m.subpageIds?.includes(pageMeta.id));
|
||||
return !parentMeta?.trash && pageMeta.trash;
|
||||
},
|
||||
favorite: (pageMeta: PageMeta) => pageMeta.favorite && !pageMeta.trash,
|
||||
shared: (pageMeta: PageMeta) => pageMeta.isPublic && !pageMeta.trash,
|
||||
};
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
const formatDate = (date?: number | unknown) => {
|
||||
const dateStr =
|
||||
typeof date === 'number' ? dayjs(date).format('YYYY-MM-DD HH:mm') : '--';
|
||||
return dateStr;
|
||||
};
|
||||
|
||||
const PageListEmpty = (props: {
|
||||
listType: BlockSuitePageListProps['listType'];
|
||||
}) => {
|
||||
const { listType } = props;
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const getEmptyDescription = () => {
|
||||
if (listType === 'all') {
|
||||
return t['emptyAllPages']();
|
||||
}
|
||||
if (listType === 'favorite') {
|
||||
return t['emptyFavorite']();
|
||||
}
|
||||
if (listType === 'trash') {
|
||||
return t['emptyTrash']();
|
||||
}
|
||||
if (listType === 'shared') {
|
||||
return t['emptySharedPages']();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={pageListEmptyStyle}>
|
||||
<Empty description={getEmptyDescription()} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const BlockSuitePageList: React.FC<BlockSuitePageListProps> = ({
|
||||
blockSuiteWorkspace,
|
||||
onOpenPage,
|
||||
listType,
|
||||
isPublic = false,
|
||||
}) => {
|
||||
return (
|
||||
<PageList
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onClickPage={onOpenPage}
|
||||
listType="all"
|
||||
/>
|
||||
const pageMetas = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||
const {
|
||||
toggleFavorite,
|
||||
removeToTrash,
|
||||
restoreFromTrash,
|
||||
permanentlyDeletePage,
|
||||
cancelPublicPage,
|
||||
} = useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
||||
const t = useAFFiNEI18N();
|
||||
const list = useMemo(
|
||||
() => pageMetas.filter(pageMeta => filter[listType](pageMeta, pageMetas)),
|
||||
[pageMetas, listType]
|
||||
);
|
||||
};
|
||||
const record = useAtomValue(workspacePreferredModeAtom);
|
||||
if (list.length === 0) {
|
||||
return <PageListEmpty listType={listType} />;
|
||||
}
|
||||
|
||||
if (listType === 'trash') {
|
||||
const pageList: TrashListData[] = list.map(pageMeta => {
|
||||
return {
|
||||
icon:
|
||||
record[pageMeta.id] === 'edgeless' ? <EdgelessIcon /> : <PageIcon />,
|
||||
pageId: pageMeta.id,
|
||||
title: pageMeta.title,
|
||||
favorite: !!pageMeta.favorite,
|
||||
createDate: formatDate(pageMeta.createDate),
|
||||
updatedDate: formatDate(pageMeta.updatedDate),
|
||||
onClickPage: () => onOpenPage(pageMeta.id),
|
||||
onClickRestore: () => {
|
||||
restoreFromTrash(pageMeta.id);
|
||||
},
|
||||
onRestorePage: () => {
|
||||
restoreFromTrash(pageMeta.id);
|
||||
toast(t['restored']({ title: pageMeta.title || 'Untitled' }));
|
||||
},
|
||||
onPermanentlyDeletePage: () => {
|
||||
permanentlyDeletePage(pageMeta.id);
|
||||
toast(t['Permanently deleted']());
|
||||
},
|
||||
};
|
||||
});
|
||||
return <PageListTrashView list={pageList} />;
|
||||
}
|
||||
|
||||
const pageList: ListData[] = list.map(pageMeta => {
|
||||
return {
|
||||
icon:
|
||||
record[pageMeta.id] === 'edgeless' ? <EdgelessIcon /> : <PageIcon />,
|
||||
pageId: pageMeta.id,
|
||||
title: pageMeta.title,
|
||||
favorite: !!pageMeta.favorite,
|
||||
isPublicPage: !!pageMeta.isPublic,
|
||||
createDate: formatDate(pageMeta.createDate),
|
||||
updatedDate: formatDate(pageMeta.updatedDate),
|
||||
onClickPage: () => onOpenPage(pageMeta.id),
|
||||
onOpenPageInNewTab: () => onOpenPage(pageMeta.id, true),
|
||||
onClickRestore: () => {
|
||||
restoreFromTrash(pageMeta.id);
|
||||
},
|
||||
removeToTrash: () => {
|
||||
removeToTrash(pageMeta.id);
|
||||
toast(t['Successfully deleted']());
|
||||
},
|
||||
onRestorePage: () => {
|
||||
restoreFromTrash(pageMeta.id);
|
||||
toast(t['restored']({ title: pageMeta.title || 'Untitled' }));
|
||||
},
|
||||
bookmarkPage: () => {
|
||||
toggleFavorite(pageMeta.id);
|
||||
toast(
|
||||
pageMeta.favorite
|
||||
? t['Removed from Favorites']()
|
||||
: t['Added to Favorites']()
|
||||
);
|
||||
},
|
||||
onDisablePublicSharing: () => {
|
||||
cancelPublicPage(pageMeta.id);
|
||||
toast('Successfully disabled', {
|
||||
portal: document.body,
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const BlockSuitePublicPageList: React.FC<BlockSuitePageListProps> = ({
|
||||
blockSuiteWorkspace,
|
||||
onOpenPage,
|
||||
}) => {
|
||||
return (
|
||||
<PageList
|
||||
isPublic={true}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onClickPage={onOpenPage}
|
||||
isPublicWorkspace={isPublic}
|
||||
list={pageList}
|
||||
listType={listType}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import type { TableCellProps } from '@affine/component';
|
||||
import { TableCell } from '@affine/component';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import dayjs from 'dayjs';
|
||||
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
||||
import React from 'react';
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
|
||||
export const DateCell = ({
|
||||
pageMeta,
|
||||
dateKey,
|
||||
backupKey = 'updatedDate',
|
||||
...props
|
||||
}: {
|
||||
pageMeta: PageMeta;
|
||||
dateKey: keyof PageMeta;
|
||||
backupKey?: keyof PageMeta;
|
||||
} & Omit<TableCellProps, 'children'>) => {
|
||||
const value = pageMeta[dateKey] ?? pageMeta[backupKey];
|
||||
return (
|
||||
<TableCell ellipsis={true} {...props}>
|
||||
{typeof value === 'number'
|
||||
? dayjs(value).format('YYYY-MM-DD HH:mm')
|
||||
: '--'}
|
||||
</TableCell>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateCell;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { Empty } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import React from 'react';
|
||||
export const PageListEmpty = (props: { listType?: string }) => {
|
||||
const { listType } = props;
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const getEmptyDescription = () => {
|
||||
if (listType === 'all') {
|
||||
return t['emptyAllPages']();
|
||||
}
|
||||
if (listType === 'favorite') {
|
||||
return t['emptyFavorite']();
|
||||
}
|
||||
if (listType === 'trash') {
|
||||
return t['emptyTrash']();
|
||||
}
|
||||
if (listType === 'shared') {
|
||||
return t['emptySharedPages']();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ height: 'calc(100% - 52px)' }}>
|
||||
<Empty description={getEmptyDescription()} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageListEmpty;
|
||||
@@ -1,198 +0,0 @@
|
||||
import {
|
||||
Confirm,
|
||||
FlexWrapper,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Tooltip,
|
||||
} from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
DeletePermanentlyIcon,
|
||||
FavoritedIcon,
|
||||
FavoriteIcon,
|
||||
MoreVerticalIcon,
|
||||
OpenInNewIcon,
|
||||
ResetIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { assertExists } from '@blocksuite/store';
|
||||
import type React from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import type { BlockSuiteWorkspace } from '../../../../shared';
|
||||
import { toast } from '../../../../utils';
|
||||
import {
|
||||
DisablePublicSharing,
|
||||
MoveToTrash,
|
||||
} from '../../../affine/operation-menu-items';
|
||||
|
||||
export type OperationCellProps = {
|
||||
pageMeta: PageMeta;
|
||||
metas: PageMeta[];
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
onOpenPageInNewTab: (pageId: string) => void;
|
||||
onToggleFavoritePage: (pageId: string) => void;
|
||||
onToggleTrashPage: (pageId: string, isTrash: boolean) => void;
|
||||
};
|
||||
|
||||
export const OperationCell: React.FC<OperationCellProps> = ({
|
||||
pageMeta,
|
||||
blockSuiteWorkspace,
|
||||
onOpenPageInNewTab,
|
||||
onToggleFavoritePage,
|
||||
onToggleTrashPage,
|
||||
}) => {
|
||||
const { id, favorite, isPublic } = pageMeta;
|
||||
const t = useAFFiNEI18N();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [openDisableShared, setOpenDisableShared] = useState(false);
|
||||
|
||||
const page = blockSuiteWorkspace.getPage(id);
|
||||
assertExists(page);
|
||||
|
||||
const OperationMenu = (
|
||||
<>
|
||||
{isPublic && (
|
||||
<DisablePublicSharing
|
||||
testId="disable-public-sharing"
|
||||
onItemClick={() => {
|
||||
setOpenDisableShared(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onToggleFavoritePage(id);
|
||||
toast(
|
||||
favorite ? t['Removed from Favorites']() : t['Added to Favorites']()
|
||||
);
|
||||
}}
|
||||
icon={
|
||||
favorite ? (
|
||||
<FavoritedIcon style={{ color: 'var(--affine-primary-color)' }} />
|
||||
) : (
|
||||
<FavoriteIcon />
|
||||
)
|
||||
}
|
||||
>
|
||||
{favorite ? t['Remove from favorites']() : t['Add to Favorites']()}
|
||||
</MenuItem>
|
||||
{!environment.isDesktop && (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onOpenPageInNewTab(id);
|
||||
}}
|
||||
icon={<OpenInNewIcon />}
|
||||
>
|
||||
{t['Open in new tab']()}
|
||||
</MenuItem>
|
||||
)}
|
||||
{!pageMeta.isRootPinboard && (
|
||||
<MoveToTrash
|
||||
testId="move-to-trash"
|
||||
onItemClick={() => {
|
||||
setOpen(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<FlexWrapper alignItems="center" justifyContent="center">
|
||||
<Menu
|
||||
content={OperationMenu}
|
||||
placement="bottom"
|
||||
disablePortal={true}
|
||||
trigger="click"
|
||||
>
|
||||
<IconButton data-testid="page-list-operation-button">
|
||||
<MoreVerticalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
</FlexWrapper>
|
||||
<MoveToTrash.ConfirmModal
|
||||
open={open}
|
||||
meta={pageMeta}
|
||||
onConfirm={() => {
|
||||
onToggleTrashPage(id, true);
|
||||
toast(t['Moved to Trash']());
|
||||
setOpen(false);
|
||||
}}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
onCancel={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
/>
|
||||
<DisablePublicSharing.DisablePublicSharingModal
|
||||
page={page}
|
||||
open={openDisableShared}
|
||||
onClose={() => {
|
||||
setOpenDisableShared(false);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export type TrashOperationCellProps = {
|
||||
pageMeta: PageMeta;
|
||||
onPermanentlyDeletePage: (pageId: string) => void;
|
||||
onRestorePage: (pageId: string) => void;
|
||||
onOpenPage: (pageId: string) => void;
|
||||
};
|
||||
|
||||
export const TrashOperationCell: React.FC<TrashOperationCellProps> = ({
|
||||
pageMeta,
|
||||
onPermanentlyDeletePage,
|
||||
onRestorePage,
|
||||
}) => {
|
||||
const { id, title } = pageMeta;
|
||||
const t = useAFFiNEI18N();
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<FlexWrapper>
|
||||
<Tooltip content={t['Restore it']()} placement="top-start">
|
||||
<IconButton
|
||||
style={{ marginRight: '12px' }}
|
||||
onClick={() => {
|
||||
onRestorePage(id);
|
||||
toast(t['restored']({ title: title || 'Untitled' }));
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip content={t['Delete permanently']()} placement="top-start">
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setOpen(true);
|
||||
}}
|
||||
>
|
||||
<DeletePermanentlyIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Confirm
|
||||
title={t['Delete permanently?']()}
|
||||
content={t['TrashButtonGroupDescription']()}
|
||||
confirmText={t['Delete']()}
|
||||
confirmType="danger"
|
||||
open={open}
|
||||
onConfirm={() => {
|
||||
onPermanentlyDeletePage(id);
|
||||
toast(t['Permanently deleted']());
|
||||
setOpen(false);
|
||||
}}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
onCancel={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
/>
|
||||
</FlexWrapper>
|
||||
);
|
||||
};
|
||||
@@ -1,252 +0,0 @@
|
||||
import {
|
||||
Content,
|
||||
IconButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Tooltip,
|
||||
} from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
EdgelessIcon,
|
||||
FavoritedIcon,
|
||||
FavoriteIcon,
|
||||
PageIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import type { PageMeta } from '@blocksuite/store';
|
||||
import { useMediaQuery, useTheme } from '@mui/material';
|
||||
import {
|
||||
useBlockSuitePageMeta,
|
||||
usePageMetaHelper,
|
||||
} from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type React from 'react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { workspacePreferredModeAtom } from '../../../../atoms';
|
||||
import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper';
|
||||
import type { BlockSuiteWorkspace } from '../../../../shared';
|
||||
import { toast } from '../../../../utils';
|
||||
import DateCell from './DateCell';
|
||||
import Empty from './Empty';
|
||||
import { OperationCell, TrashOperationCell } from './OperationCell';
|
||||
import {
|
||||
StyledTableContainer,
|
||||
StyledTableRow,
|
||||
StyledTitleLink,
|
||||
StyledTitleWrapper,
|
||||
} from './styles';
|
||||
|
||||
export type FavoriteTagProps = {
|
||||
pageMeta: PageMeta;
|
||||
onClick: () => void;
|
||||
};
|
||||
const FavoriteTag: React.FC<FavoriteTagProps> = ({
|
||||
pageMeta: { favorite },
|
||||
onClick,
|
||||
}) => {
|
||||
const t = useAFFiNEI18N();
|
||||
return (
|
||||
<Tooltip
|
||||
content={favorite ? t['Favorited']() : t['Favorite']()}
|
||||
placement="top-start"
|
||||
>
|
||||
<IconButton
|
||||
iconSize={[20, 20]}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onClick();
|
||||
toast(
|
||||
favorite ? t['Removed from Favorites']() : t['Added to Favorites']()
|
||||
);
|
||||
}}
|
||||
style={{
|
||||
color: favorite
|
||||
? 'var(--affine-primary-color)'
|
||||
: 'var(--affine-icon-color)',
|
||||
}}
|
||||
className={favorite ? '' : 'favorite-button'}
|
||||
>
|
||||
{favorite ? (
|
||||
<FavoritedIcon data-testid="favorited-icon" />
|
||||
) : (
|
||||
<FavoriteIcon />
|
||||
)}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
type PageListProps = {
|
||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||
isPublic?: boolean;
|
||||
listType?: 'all' | 'trash' | 'favorite' | 'shared';
|
||||
onClickPage: (pageId: string, newTab?: boolean) => void;
|
||||
};
|
||||
|
||||
const filter = {
|
||||
all: (pageMeta: PageMeta) => !pageMeta.trash,
|
||||
trash: (pageMeta: PageMeta, allMetas: PageMeta[]) => {
|
||||
const parentMeta = allMetas.find(m => m.subpageIds?.includes(pageMeta.id));
|
||||
return !parentMeta?.trash && pageMeta.trash;
|
||||
},
|
||||
favorite: (pageMeta: PageMeta) => pageMeta.favorite && !pageMeta.trash,
|
||||
shared: (pageMeta: PageMeta) => pageMeta.isPublic && !pageMeta.trash,
|
||||
};
|
||||
|
||||
export const PageList: React.FC<PageListProps> = ({
|
||||
blockSuiteWorkspace,
|
||||
isPublic = false,
|
||||
listType,
|
||||
onClickPage,
|
||||
}) => {
|
||||
const pageList = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||
const helper = usePageMetaHelper(blockSuiteWorkspace);
|
||||
const { removeToTrash, restoreFromTrash } =
|
||||
useBlockSuiteMetaHelper(blockSuiteWorkspace);
|
||||
const t = useAFFiNEI18N();
|
||||
const theme = useTheme();
|
||||
const matches = useMediaQuery(theme.breakpoints.up('sm'));
|
||||
const isTrash = listType === 'trash';
|
||||
const isShared = listType === 'shared';
|
||||
const record = useAtomValue(workspacePreferredModeAtom);
|
||||
const list = useMemo(
|
||||
() =>
|
||||
pageList.filter(pageMeta =>
|
||||
filter[listType ?? 'all'](pageMeta, pageList)
|
||||
),
|
||||
[pageList, listType]
|
||||
);
|
||||
if (list.length === 0) {
|
||||
return <Empty listType={listType} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledTableContainer>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{matches && (
|
||||
<>
|
||||
<TableCell proportion={0.5}>{t['Title']()}</TableCell>
|
||||
<TableCell proportion={0.2}>{t['Created']()}</TableCell>
|
||||
<TableCell proportion={0.2}>
|
||||
{isTrash
|
||||
? t['Moved to Trash']()
|
||||
: isShared
|
||||
? 'Shared'
|
||||
: t['Updated']()}
|
||||
</TableCell>
|
||||
<TableCell proportion={0.1}></TableCell>
|
||||
</>
|
||||
)}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{list.map((pageMeta, index) => {
|
||||
return (
|
||||
<StyledTableRow
|
||||
data-testid={`page-list-item-${pageMeta.id}`}
|
||||
key={`${pageMeta.id}-${index}`}
|
||||
>
|
||||
<TableCell
|
||||
onClick={() => {
|
||||
onClickPage(pageMeta.id);
|
||||
}}
|
||||
>
|
||||
<StyledTitleWrapper>
|
||||
<StyledTitleLink>
|
||||
{record[pageMeta.id] === 'edgeless' ? (
|
||||
<EdgelessIcon />
|
||||
) : (
|
||||
<PageIcon />
|
||||
)}
|
||||
<Content ellipsis={true} color="inherit">
|
||||
{pageMeta.title || t['Untitled']()}
|
||||
</Content>
|
||||
</StyledTitleLink>
|
||||
{listType && !isTrash && (
|
||||
<FavoriteTag
|
||||
onClick={() => {
|
||||
helper.setPageMeta(pageMeta.id, {
|
||||
favorite: !pageMeta.favorite,
|
||||
});
|
||||
}}
|
||||
pageMeta={pageMeta}
|
||||
/>
|
||||
)}
|
||||
</StyledTitleWrapper>
|
||||
</TableCell>
|
||||
{matches && (
|
||||
<>
|
||||
<DateCell
|
||||
pageMeta={pageMeta}
|
||||
dateKey="createDate"
|
||||
onClick={() => {
|
||||
onClickPage(pageMeta.id);
|
||||
}}
|
||||
/>
|
||||
<DateCell
|
||||
pageMeta={pageMeta}
|
||||
dateKey={isTrash ? 'trashDate' : 'updatedDate'}
|
||||
backupKey={isTrash ? 'trashDate' : 'createDate'}
|
||||
onClick={() => {
|
||||
onClickPage(pageMeta.id);
|
||||
}}
|
||||
/>
|
||||
{!isPublic && (
|
||||
<TableCell
|
||||
style={{ padding: 0 }}
|
||||
data-testid={`more-actions-${pageMeta.id}`}
|
||||
>
|
||||
{isTrash ? (
|
||||
<TrashOperationCell
|
||||
pageMeta={pageMeta}
|
||||
onPermanentlyDeletePage={pageId => {
|
||||
blockSuiteWorkspace.removePage(pageId);
|
||||
}}
|
||||
onRestorePage={() => {
|
||||
restoreFromTrash(pageMeta.id);
|
||||
}}
|
||||
onOpenPage={pageId => {
|
||||
onClickPage(pageId, false);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<OperationCell
|
||||
pageMeta={pageMeta}
|
||||
metas={pageList}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onOpenPageInNewTab={pageId => {
|
||||
onClickPage(pageId, true);
|
||||
}}
|
||||
onToggleFavoritePage={(pageId: string) => {
|
||||
helper.setPageMeta(pageId, {
|
||||
favorite: !pageMeta.favorite,
|
||||
});
|
||||
}}
|
||||
onToggleTrashPage={(pageId, isTrash) => {
|
||||
if (isTrash) {
|
||||
removeToTrash(pageId);
|
||||
} else {
|
||||
restoreFromTrash(pageId);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</TableCell>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</StyledTableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</StyledTableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageList;
|
||||
@@ -1,55 +0,0 @@
|
||||
import { displayFlex, styled } from '@affine/component';
|
||||
import { TableRow } from '@affine/component';
|
||||
|
||||
export const StyledTableContainer = styled('div')(({ theme }) => {
|
||||
return {
|
||||
height: 'calc(100vh - 52px)',
|
||||
padding: '78px 72px',
|
||||
maxWidth: '100%',
|
||||
overflowY: 'auto',
|
||||
[theme.breakpoints.down('md')]: {
|
||||
padding: '12px 24px',
|
||||
},
|
||||
};
|
||||
});
|
||||
export const StyledTitleWrapper = styled('div')(() => {
|
||||
return {
|
||||
...displayFlex('flex-start', 'center'),
|
||||
a: {
|
||||
color: 'inherit',
|
||||
},
|
||||
'a:visited': {
|
||||
color: 'unset',
|
||||
},
|
||||
'a:hover': {
|
||||
color: 'var(--affine-primary-color)',
|
||||
},
|
||||
};
|
||||
});
|
||||
export const StyledTitleLink = styled('div')(() => {
|
||||
return {
|
||||
maxWidth: '80%',
|
||||
marginRight: '18px',
|
||||
...displayFlex('flex-start', 'center'),
|
||||
color: 'var(--affine-text-primary-color)',
|
||||
'>svg': {
|
||||
fontSize: '24px',
|
||||
marginRight: '12px',
|
||||
color: 'var(--affine-icon-color)',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledTableRow = styled(TableRow)(() => {
|
||||
return {
|
||||
cursor: 'pointer',
|
||||
'.favorite-button': {
|
||||
display: 'none',
|
||||
},
|
||||
'&:hover': {
|
||||
'.favorite-button': {
|
||||
display: 'flex',
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
// fixme(himself65): refactor this file
|
||||
import { FlexWrapper, IconButton, Menu, MenuItem } from '@affine/component';
|
||||
import { Export, MoveToTrash } from '@affine/component/page-list';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import {
|
||||
EdgelessIcon,
|
||||
@@ -22,7 +23,6 @@ import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suit
|
||||
import { useCurrentPageId } from '../../../../hooks/current/use-current-page-id';
|
||||
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
|
||||
import { toast } from '../../../../utils';
|
||||
import { Export, MoveToTrash } from '../../../affine/operation-menu-items';
|
||||
import { MenuThemeModeSwitch } from '../header-right-items/theme-mode-switch';
|
||||
import {
|
||||
StyledHorizontalDivider,
|
||||
@@ -152,7 +152,7 @@ const PageMenu = () => {
|
||||
</Menu>
|
||||
<MoveToTrash.ConfirmModal
|
||||
open={openConfirm}
|
||||
meta={pageMeta}
|
||||
title={pageMeta.title}
|
||||
onConfirm={() => {
|
||||
removeToTrash(pageMeta.id);
|
||||
toast(t['Moved to Trash']());
|
||||
|
||||
@@ -15,6 +15,32 @@ export function useBlockSuiteMetaHelper(
|
||||
useReferenceLinkHelper(blockSuiteWorkspace);
|
||||
const metas = useBlockSuitePageMeta(blockSuiteWorkspace);
|
||||
|
||||
const addToFavorite = useCallback(
|
||||
(pageId: string) => {
|
||||
setPageMeta(pageId, {
|
||||
favorite: true,
|
||||
});
|
||||
},
|
||||
[setPageMeta]
|
||||
);
|
||||
const removeFromFavorite = useCallback(
|
||||
(pageId: string) => {
|
||||
setPageMeta(pageId, {
|
||||
favorite: false,
|
||||
});
|
||||
},
|
||||
[setPageMeta]
|
||||
);
|
||||
const toggleFavorite = useCallback(
|
||||
(pageId: string) => {
|
||||
const { favorite } = getPageMeta(pageId) ?? {};
|
||||
setPageMeta(pageId, {
|
||||
favorite: !favorite,
|
||||
});
|
||||
},
|
||||
[getPageMeta, setPageMeta]
|
||||
);
|
||||
|
||||
const removeToTrash = useCallback(
|
||||
(pageId: string, isRoot = true) => {
|
||||
const parentMeta = metas.find(m => m.subpageIds?.includes(pageId));
|
||||
@@ -58,8 +84,47 @@ export function useBlockSuiteMetaHelper(
|
||||
[addReferenceLink, getPageMeta, setPageMeta]
|
||||
);
|
||||
|
||||
const permanentlyDeletePage = useCallback(
|
||||
(pageId: string) => {
|
||||
blockSuiteWorkspace.removePage(pageId);
|
||||
},
|
||||
[blockSuiteWorkspace]
|
||||
);
|
||||
|
||||
/**
|
||||
* see {@link useBlockSuiteWorkspacePageIsPublic}
|
||||
*/
|
||||
const publicPage = useCallback(
|
||||
(pageId: string) => {
|
||||
setPageMeta(pageId, {
|
||||
isPublic: true,
|
||||
});
|
||||
},
|
||||
[setPageMeta]
|
||||
);
|
||||
|
||||
/**
|
||||
* see {@link useBlockSuiteWorkspacePageIsPublic}
|
||||
*/
|
||||
const cancelPublicPage = useCallback(
|
||||
(pageId: string) => {
|
||||
setPageMeta(pageId, {
|
||||
isPublic: false,
|
||||
});
|
||||
},
|
||||
[setPageMeta]
|
||||
);
|
||||
|
||||
return {
|
||||
publicPage,
|
||||
cancelPublicPage,
|
||||
|
||||
addToFavorite,
|
||||
removeFromFavorite,
|
||||
toggleFavorite,
|
||||
|
||||
removeToTrash,
|
||||
restoreFromTrash,
|
||||
permanentlyDeletePage,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Typography } from '@mui/material';
|
||||
import type React from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import PageList from '../../components/blocksuite/block-suite-page-list/page-list';
|
||||
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
||||
import { StyledPage, StyledWrapper } from '../../layouts/styles';
|
||||
import { toast } from '../../utils';
|
||||
|
||||
@@ -57,9 +57,10 @@ const BroadcastPage: React.FC = () => {
|
||||
>
|
||||
Create Page
|
||||
</Button>
|
||||
<PageList
|
||||
<BlockSuitePageList
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onClickPage={() => {
|
||||
listType="all"
|
||||
onOpenPage={() => {
|
||||
toast('do nothing');
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Breadcrumbs, IconButton, ListSkeleton } from '@affine/component';
|
||||
import { StyledTableContainer } from '@affine/component/page-list';
|
||||
import { SearchIcon } from '@blocksuite/icons';
|
||||
import { useBlockSuiteWorkspaceAvatarUrl } from '@toeverything/hooks/use-block-suite-workspace-avatar-url';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
publicWorkspaceIdAtom,
|
||||
} from '../../atoms/public-workspace';
|
||||
import { QueryParamError } from '../../components/affine/affine-error-eoundary';
|
||||
import { StyledTableContainer } from '../../components/blocksuite/block-suite-page-list/page-list/styles';
|
||||
import { WorkspaceAvatar } from '../../components/pure/footer';
|
||||
import { PageLoading } from '../../components/pure/loading';
|
||||
import {
|
||||
@@ -23,9 +23,9 @@ import {
|
||||
import type { NextPageWithLayout } from '../../shared';
|
||||
import { NavContainer, StyledBreadcrumbs } from './[workspaceId]/[pageId]';
|
||||
|
||||
const BlockSuitePublicPageList = lazy(() =>
|
||||
const BlockSuitePageList = lazy(() =>
|
||||
import('../../components/blocksuite/block-suite-page-list').then(module => ({
|
||||
default: module.BlockSuitePublicPageList,
|
||||
default: module.BlockSuitePageList,
|
||||
}))
|
||||
);
|
||||
|
||||
@@ -79,7 +79,9 @@ const ListPageInner: React.FC<{
|
||||
</StyledTableContainer>
|
||||
}
|
||||
>
|
||||
<BlockSuitePublicPageList
|
||||
<BlockSuitePageList
|
||||
listType="public"
|
||||
isPublic={true}
|
||||
onOpenPage={handleClickPage}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
|
||||
@@ -5,7 +5,7 @@ import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import PageList from '../../../components/blocksuite/block-suite-page-list/page-list';
|
||||
import { BlockSuitePageList } from '../../../components/blocksuite/block-suite-page-list';
|
||||
import { PageLoading } from '../../../components/pure/loading';
|
||||
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||
@@ -50,9 +50,9 @@ const FavouritePage: NextPageWithLayout = () => {
|
||||
>
|
||||
{t['Favorites']()}
|
||||
</WorkspaceTitle>
|
||||
<PageList
|
||||
<BlockSuitePageList
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onClickPage={onClickPage}
|
||||
onOpenPage={onClickPage}
|
||||
listType="favorite"
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -5,7 +5,7 @@ import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import PageList from '../../../components/blocksuite/block-suite-page-list/page-list';
|
||||
import { BlockSuitePageList } from '../../../components/blocksuite/block-suite-page-list';
|
||||
import { PageLoading } from '../../../components/pure/loading';
|
||||
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||
@@ -50,9 +50,9 @@ const SharedPages: NextPageWithLayout = () => {
|
||||
>
|
||||
{t['Shared Pages']()}
|
||||
</WorkspaceTitle>
|
||||
<PageList
|
||||
<BlockSuitePageList
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onClickPage={onClickPage}
|
||||
onOpenPage={onClickPage}
|
||||
listType="shared"
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -5,7 +5,7 @@ import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import PageList from '../../../components/blocksuite/block-suite-page-list/page-list';
|
||||
import { BlockSuitePageList } from '../../../components/blocksuite/block-suite-page-list';
|
||||
import { PageLoading } from '../../../components/pure/loading';
|
||||
import { WorkspaceTitle } from '../../../components/pure/workspace-title';
|
||||
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
|
||||
@@ -53,9 +53,9 @@ const TrashPage: NextPageWithLayout = () => {
|
||||
>
|
||||
{t['Trash']()}
|
||||
</WorkspaceTitle>
|
||||
<PageList
|
||||
<BlockSuitePageList
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onClickPage={onClickPage}
|
||||
onOpenPage={onClickPage}
|
||||
listType="trash"
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -304,6 +304,7 @@ export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
|
||||
PageList: ({ blockSuiteWorkspace, onOpenPage }) => {
|
||||
return (
|
||||
<BlockSuitePageList
|
||||
listType="all"
|
||||
onOpenPage={onOpenPage}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
|
||||
@@ -78,6 +78,7 @@ export const LocalPlugin: WorkspacePlugin<WorkspaceFlavour.LOCAL> = {
|
||||
PageList: ({ blockSuiteWorkspace, onOpenPage }) => {
|
||||
return (
|
||||
<BlockSuitePageList
|
||||
listType="all"
|
||||
onOpenPage={onOpenPage}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user