From 84b36c1d354398d06617c1a4ff25e106d561bb76 Mon Sep 17 00:00:00 2001 From: Whitewater Date: Thu, 4 May 2023 20:59:16 -0700 Subject: [PATCH] refactor: clean all pages component (#2176) Co-authored-by: himself65 --- .../affine/operation-menu-items/MoveTo.tsx | 60 --- .../pinboard-render/OperationButton.tsx | 4 +- .../block-suite-page-list/index.css.ts | 5 + .../block-suite-page-list/index.tsx | 165 +++++++- .../page-list/DateCell.tsx | 30 -- .../block-suite-page-list/page-list/Empty.tsx | 30 -- .../block-suite-page-list/page-list/index.tsx | 252 ------------- .../header-right-items/EditorOptionMenu.tsx | 4 +- .../affine/use-block-suite-meta-helper.ts | 65 ++++ apps/web/src/pages/_debug/broadcast.dev.tsx | 7 +- .../pages/public-workspace/[workspaceId].tsx | 10 +- .../workspace/[workspaceId]/favorite.tsx | 6 +- .../pages/workspace/[workspaceId]/shared.tsx | 6 +- .../pages/workspace/[workspaceId]/trash.tsx | 6 +- apps/web/src/plugins/affine/index.tsx | 1 + apps/web/src/plugins/local/index.tsx | 1 + .../src/components/page-list/all-page.tsx | 356 ++++++++++++++++++ .../src/components/page-list/index.tsx | 4 + .../components/page-list/operation-cell.tsx | 84 ++--- .../operation-menu-items/CopyLink.tsx | 4 +- .../DisablePublicSharing.tsx | 11 +- .../operation-menu-items/Export.tsx | 0 .../operation-menu-items/MoveToTrash.tsx | 7 +- .../page-list}/operation-menu-items/index.ts | 2 +- .../page-list}/operation-menu-items/types.ts | 0 .../src/components}/page-list/styles.ts | 4 +- .../src/components/share-menu/SharePage.tsx | 8 +- .../share-menu/disable-public-link/index.tsx | 22 +- .../src/stories/ChangeLog.stories.tsx | 2 +- .../src/stories/PageList.stories.tsx | 89 +++++ .../src/stories/ShareMenu.stories.tsx | 28 +- .../component/src/stories/Switch.stories.tsx | 3 - 32 files changed, 772 insertions(+), 504 deletions(-) delete mode 100644 apps/web/src/components/affine/operation-menu-items/MoveTo.tsx create mode 100644 apps/web/src/components/blocksuite/block-suite-page-list/index.css.ts delete mode 100644 apps/web/src/components/blocksuite/block-suite-page-list/page-list/Empty.tsx delete mode 100644 apps/web/src/components/blocksuite/block-suite-page-list/page-list/index.tsx create mode 100644 packages/component/src/components/page-list/all-page.tsx create mode 100644 packages/component/src/components/page-list/index.tsx rename apps/web/src/components/blocksuite/block-suite-page-list/page-list/OperationCell.tsx => packages/component/src/components/page-list/operation-cell.tsx (65%) rename {apps/web/src/components/affine => packages/component/src/components/page-list}/operation-menu-items/CopyLink.tsx (88%) rename {apps/web/src/components/affine => packages/component/src/components/page-list}/operation-menu-items/DisablePublicSharing.tsx (76%) rename {apps/web/src/components/affine => packages/component/src/components/page-list}/operation-menu-items/Export.tsx (100%) rename {apps/web/src/components/affine => packages/component/src/components/page-list}/operation-menu-items/MoveToTrash.tsx (89%) rename {apps/web/src/components/affine => packages/component/src/components/page-list}/operation-menu-items/index.ts (81%) rename {apps/web/src/components/affine => packages/component/src/components/page-list}/operation-menu-items/types.ts (100%) rename {apps/web/src/components/blocksuite/block-suite-page-list => packages/component/src/components}/page-list/styles.ts (95%) create mode 100644 packages/component/src/stories/PageList.stories.tsx diff --git a/apps/web/src/components/affine/operation-menu-items/MoveTo.tsx b/apps/web/src/components/affine/operation-menu-items/MoveTo.tsx deleted file mode 100644 index 318ec4364a..0000000000 --- a/apps/web/src/components/affine/operation-menu-items/MoveTo.tsx +++ /dev/null @@ -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(null); - const [anchorEl, setAnchorEl] = useState(null); - const open = anchorEl !== null; - return ( - <> - { - e.stopPropagation(); - setAnchorEl(ref.current); - onItemClick?.(); - }} - icon={} - endIcon={} - data-testid="move-to-menu-item" - > - {t['Move to']()} - - - - ); -}; diff --git a/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx b/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx index 40c496cb6b..0fbe534008 100644 --- a/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx +++ b/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx @@ -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 = ({ /> { toast(t['Moved to Trash']()); removeToTrash(currentMeta.id); diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/index.css.ts b/apps/web/src/components/blocksuite/block-suite-page-list/index.css.ts new file mode 100644 index 0000000000..c1dd7ea1c2 --- /dev/null +++ b/apps/web/src/components/blocksuite/block-suite-page-list/index.css.ts @@ -0,0 +1,5 @@ +import { style } from '@vanilla-extract/css'; + +export const pageListEmptyStyle = style({ + height: 'calc(100% - 52px)', +}); diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/index.tsx b/apps/web/src/components/blocksuite/block-suite-page-list/index.tsx index 500741c0b4..f2241678b4 100644 --- a/apps/web/src/components/blocksuite/block-suite-page-list/index.tsx +++ b/apps/web/src/components/blocksuite/block-suite-page-list/index.tsx @@ -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 ( +
+ +
+ ); +}; + export const BlockSuitePageList: React.FC = ({ blockSuiteWorkspace, onOpenPage, + listType, + isPublic = false, }) => { - return ( - + 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 ; + } + + if (listType === 'trash') { + const pageList: TrashListData[] = list.map(pageMeta => { + return { + icon: + record[pageMeta.id] === 'edgeless' ? : , + 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 ; + } + + const pageList: ListData[] = list.map(pageMeta => { + return { + icon: + record[pageMeta.id] === 'edgeless' ? : , + 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 = ({ - blockSuiteWorkspace, - onOpenPage, -}) => { return ( ); }; diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/DateCell.tsx b/apps/web/src/components/blocksuite/block-suite-page-list/page-list/DateCell.tsx index 2c769f4511..e69de29bb2 100644 --- a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/DateCell.tsx +++ b/apps/web/src/components/blocksuite/block-suite-page-list/page-list/DateCell.tsx @@ -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) => { - const value = pageMeta[dateKey] ?? pageMeta[backupKey]; - return ( - - {typeof value === 'number' - ? dayjs(value).format('YYYY-MM-DD HH:mm') - : '--'} - - ); -}; - -export default DateCell; diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/Empty.tsx b/apps/web/src/components/blocksuite/block-suite-page-list/page-list/Empty.tsx deleted file mode 100644 index 7c2af5aaed..0000000000 --- a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/Empty.tsx +++ /dev/null @@ -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 ( -
- -
- ); -}; - -export default PageListEmpty; diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/index.tsx b/apps/web/src/components/blocksuite/block-suite-page-list/page-list/index.tsx deleted file mode 100644 index 9c9aa0265e..0000000000 --- a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/index.tsx +++ /dev/null @@ -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 = ({ - pageMeta: { favorite }, - onClick, -}) => { - const t = useAFFiNEI18N(); - return ( - - { - 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 ? ( - - ) : ( - - )} - - - ); -}; - -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 = ({ - 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 ; - } - - return ( - - - - - {matches && ( - <> - {t['Title']()} - {t['Created']()} - - {isTrash - ? t['Moved to Trash']() - : isShared - ? 'Shared' - : t['Updated']()} - - - - )} - - - - {list.map((pageMeta, index) => { - return ( - - { - onClickPage(pageMeta.id); - }} - > - - - {record[pageMeta.id] === 'edgeless' ? ( - - ) : ( - - )} - - {pageMeta.title || t['Untitled']()} - - - {listType && !isTrash && ( - { - helper.setPageMeta(pageMeta.id, { - favorite: !pageMeta.favorite, - }); - }} - pageMeta={pageMeta} - /> - )} - - - {matches && ( - <> - { - onClickPage(pageMeta.id); - }} - /> - { - onClickPage(pageMeta.id); - }} - /> - {!isPublic && ( - - {isTrash ? ( - { - blockSuiteWorkspace.removePage(pageId); - }} - onRestorePage={() => { - restoreFromTrash(pageMeta.id); - }} - onOpenPage={pageId => { - onClickPage(pageId, false); - }} - /> - ) : ( - { - onClickPage(pageId, true); - }} - onToggleFavoritePage={(pageId: string) => { - helper.setPageMeta(pageId, { - favorite: !pageMeta.favorite, - }); - }} - onToggleTrashPage={(pageId, isTrash) => { - if (isTrash) { - removeToTrash(pageId); - } else { - restoreFromTrash(pageId); - } - }} - /> - )} - - )} - - )} - - ); - })} - -
-
- ); -}; - -export default PageList; diff --git a/apps/web/src/components/blocksuite/workspace-header/header-right-items/EditorOptionMenu.tsx b/apps/web/src/components/blocksuite/workspace-header/header-right-items/EditorOptionMenu.tsx index d30745b67e..1e9d6f6f3f 100644 --- a/apps/web/src/components/blocksuite/workspace-header/header-right-items/EditorOptionMenu.tsx +++ b/apps/web/src/components/blocksuite/workspace-header/header-right-items/EditorOptionMenu.tsx @@ -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 = () => { { removeToTrash(pageMeta.id); toast(t['Moved to Trash']()); diff --git a/apps/web/src/hooks/affine/use-block-suite-meta-helper.ts b/apps/web/src/hooks/affine/use-block-suite-meta-helper.ts index 38dd829803..69568df54a 100644 --- a/apps/web/src/hooks/affine/use-block-suite-meta-helper.ts +++ b/apps/web/src/hooks/affine/use-block-suite-meta-helper.ts @@ -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, }; } diff --git a/apps/web/src/pages/_debug/broadcast.dev.tsx b/apps/web/src/pages/_debug/broadcast.dev.tsx index 6c57f2027b..f895f4ce56 100644 --- a/apps/web/src/pages/_debug/broadcast.dev.tsx +++ b/apps/web/src/pages/_debug/broadcast.dev.tsx @@ -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 - { + listType="all" + onOpenPage={() => { toast('do nothing'); }} /> diff --git a/apps/web/src/pages/public-workspace/[workspaceId].tsx b/apps/web/src/pages/public-workspace/[workspaceId].tsx index ff040605d3..0fb24bb798 100644 --- a/apps/web/src/pages/public-workspace/[workspaceId].tsx +++ b/apps/web/src/pages/public-workspace/[workspaceId].tsx @@ -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<{ } > - diff --git a/apps/web/src/pages/workspace/[workspaceId]/favorite.tsx b/apps/web/src/pages/workspace/[workspaceId]/favorite.tsx index 2349d4dfd3..cf26f1746a 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/favorite.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/favorite.tsx @@ -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']()} - diff --git a/apps/web/src/pages/workspace/[workspaceId]/shared.tsx b/apps/web/src/pages/workspace/[workspaceId]/shared.tsx index c8bb1f8d9c..8a6bd3a3db 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/shared.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/shared.tsx @@ -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']()} - diff --git a/apps/web/src/pages/workspace/[workspaceId]/trash.tsx b/apps/web/src/pages/workspace/[workspaceId]/trash.tsx index 0054d21a0a..5e2a3a487c 100644 --- a/apps/web/src/pages/workspace/[workspaceId]/trash.tsx +++ b/apps/web/src/pages/workspace/[workspaceId]/trash.tsx @@ -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']()} - diff --git a/apps/web/src/plugins/affine/index.tsx b/apps/web/src/plugins/affine/index.tsx index c04a12b2f9..5ccae83c45 100644 --- a/apps/web/src/plugins/affine/index.tsx +++ b/apps/web/src/plugins/affine/index.tsx @@ -304,6 +304,7 @@ export const AffinePlugin: WorkspacePlugin = { PageList: ({ blockSuiteWorkspace, onOpenPage }) => { return ( diff --git a/apps/web/src/plugins/local/index.tsx b/apps/web/src/plugins/local/index.tsx index 48928c664f..97b88ad085 100644 --- a/apps/web/src/plugins/local/index.tsx +++ b/apps/web/src/plugins/local/index.tsx @@ -78,6 +78,7 @@ export const LocalPlugin: WorkspacePlugin = { PageList: ({ blockSuiteWorkspace, onOpenPage }) => { return ( diff --git a/packages/component/src/components/page-list/all-page.tsx b/packages/component/src/components/page-list/all-page.tsx new file mode 100644 index 0000000000..457cdd72f8 --- /dev/null +++ b/packages/component/src/components/page-list/all-page.tsx @@ -0,0 +1,356 @@ +import type { IconButtonProps, TableCellProps } from '@affine/component'; +import { + Content, + IconButton, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Tooltip, +} from '@affine/component'; +import { OperationCell, TrashOperationCell } from '@affine/component/page-list'; +import { useAFFiNEI18N } from '@affine/i18n/hooks'; +import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons'; +import { useMediaQuery, useTheme } from '@mui/material'; +import { forwardRef } from 'react'; + +import { + StyledTableContainer, + StyledTableRow, + StyledTitleLink, + StyledTitleWrapper, +} from './styles'; + +export type FavoriteTagProps = { + active: boolean; +}; + +// eslint-disable-next-line react/display-name +const FavoriteTag = forwardRef< + HTMLButtonElement, + FavoriteTagProps & Omit +>(({ active, onClick, ...props }, ref) => { + const t = useAFFiNEI18N(); + return ( + + { + e.stopPropagation(); + onClick?.(e); + }} + {...props} + > + {active ? ( + + ) : ( + + )} + + + ); +}); + +export type PageListProps = { + isPublicWorkspace?: boolean; + list: ListData[]; + listType: 'all' | 'favorite' | 'shared' | 'public'; + onClickPage: (pageId: string, newTab?: boolean) => void; +}; + +const TitleCell = ({ + icon, + text, + suffix, + ...props +}: { + icon: JSX.Element; + text: string; + suffix?: JSX.Element; +} & TableCellProps) => { + return ( + + + + {icon} + + {text} + + + {suffix} + + + ); +}; + +export type ListData = { + pageId: string; + icon: JSX.Element; + title: string; + favorite: boolean; + createDate: string; + updatedDate?: string; + trashDate?: string; + isPublicPage: boolean; + onClickPage: () => void; + onOpenPageInNewTab: () => void; + bookmarkPage: () => void; + removeToTrash: () => void; + onDisablePublicSharing: () => void; +}; + +export const PageList: React.FC = ({ + isPublicWorkspace = false, + list, + listType, +}) => { + const t = useAFFiNEI18N(); + + const isShared = listType === 'shared'; + + const theme = useTheme(); + const isSmallDevices = useMediaQuery(theme.breakpoints.down('sm')); + if (isSmallDevices) { + return ; + } + + const ListHead = () => { + const t = useAFFiNEI18N(); + return ( + + + {t['Title']()} + {t['Created']()} + + {isShared + ? // TODO add i18n + 'Shared' + : t['Updated']()} + + + + + ); + }; + + const ListItems = list.map( + ( + { + pageId, + title, + icon, + isPublicPage, + favorite, + createDate, + updatedDate, + onClickPage, + bookmarkPage, + onOpenPageInNewTab, + removeToTrash, + onDisablePublicSharing, + }, + index + ) => { + return ( + + + } + onClick={onClickPage} + /> + + {createDate} + + + {updatedDate ?? createDate} + + {!isPublicWorkspace && ( + + + + )} + + ); + } + ); + + return ( + + + + {ListItems} +
+
+ ); +}; + +const TrashListHead = () => { + const t = useAFFiNEI18N(); + return ( + + + {t['Title']()} + {t['Created']()} + {t['Moved to Trash']()} + + + + ); +}; + +export type TrashListData = { + pageId: string; + icon: JSX.Element; + title: string; + favorite: boolean; + createDate: string; + updatedDate?: string; + trashDate?: string; + // isPublic: boolean; + onClickPage: () => void; + onRestorePage: () => void; + onPermanentlyDeletePage: () => void; +}; + +export const PageListTrashView: React.FC<{ + list: TrashListData[]; +}> = ({ list }) => { + const t = useAFFiNEI18N(); + + const theme = useTheme(); + const isSmallDevices = useMediaQuery(theme.breakpoints.down('sm')); + if (isSmallDevices) { + const mobileList = list.map(({ pageId, icon, title, onClickPage }) => ({ + title, + icon, + pageId, + onClickPage, + })); + return ; + } + const ListItems = list.map( + ( + { + pageId, + title, + icon, + createDate, + trashDate, + onClickPage, + onPermanentlyDeletePage, + onRestorePage, + }, + index + ) => { + return ( + + + + {createDate} + + + {trashDate} + + + + + + ); + } + ); + + return ( + + + + {ListItems} +
+
+ ); +}; + +const PageListMobileView: React.FC<{ + list: { + pageId: string; + title: string; + icon: JSX.Element; + onClickPage: () => void; + }[]; +}> = ({ list }) => { + const t = useAFFiNEI18N(); + + const ListItems = list.map(({ pageId, title, icon, onClickPage }, index) => { + return ( + + + + + {icon} + + {title || t['Untitled']()} + + + + + + ); + }); + + return ( + + + {ListItems} +
+
+ ); +}; + +export default PageList; diff --git a/packages/component/src/components/page-list/index.tsx b/packages/component/src/components/page-list/index.tsx new file mode 100644 index 0000000000..9c84cce828 --- /dev/null +++ b/packages/component/src/components/page-list/index.tsx @@ -0,0 +1,4 @@ +export * from './all-page'; +export * from './operation-cell'; +export * from './operation-menu-items'; +export * from './styles'; diff --git a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/OperationCell.tsx b/packages/component/src/components/page-list/operation-cell.tsx similarity index 65% rename from apps/web/src/components/blocksuite/block-suite-page-list/page-list/OperationCell.tsx rename to packages/component/src/components/page-list/operation-cell.tsx index 8bcbbb8d66..7f27675d8e 100644 --- a/apps/web/src/components/blocksuite/block-suite-page-list/page-list/OperationCell.tsx +++ b/packages/component/src/components/page-list/operation-cell.tsx @@ -15,42 +15,34 @@ import { 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'; +import { DisablePublicSharing, MoveToTrash } from './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; + title: string; + favorite: boolean; + isPublic: boolean; + onOpenPageInNewTab: () => void; + onToggleFavoritePage: () => void; + onRemoveToTrash: () => void; + onDisablePublicSharing: () => void; }; export const OperationCell: React.FC = ({ - pageMeta, - blockSuiteWorkspace, + title, + favorite, + isPublic, onOpenPageInNewTab, onToggleFavoritePage, - onToggleTrashPage, + onRemoveToTrash, + onDisablePublicSharing, }) => { - 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 && ( @@ -62,12 +54,7 @@ export const OperationCell: React.FC = ({ /> )} { - onToggleFavoritePage(id); - toast( - favorite ? t['Removed from Favorites']() : t['Added to Favorites']() - ); - }} + onClick={onToggleFavoritePage} icon={ favorite ? ( @@ -79,23 +66,16 @@ export const OperationCell: React.FC = ({ {favorite ? t['Remove from favorites']() : t['Add to Favorites']()} {!environment.isDesktop && ( - { - onOpenPageInNewTab(id); - }} - icon={} - > + }> {t['Open in new tab']()} )} - {!pageMeta.isRootPinboard && ( - { - setOpen(true); - }} - /> - )} + { + setOpen(true); + }} + /> ); return ( @@ -114,10 +94,9 @@ export const OperationCell: React.FC = ({ { - onToggleTrashPage(id, true); - toast(t['Moved to Trash']()); + onRemoveToTrash(); setOpen(false); }} onClose={() => { @@ -128,7 +107,7 @@ export const OperationCell: React.FC = ({ }} /> { setOpenDisableShared(false); @@ -139,18 +118,15 @@ export const OperationCell: React.FC = ({ }; export type TrashOperationCellProps = { - pageMeta: PageMeta; - onPermanentlyDeletePage: (pageId: string) => void; - onRestorePage: (pageId: string) => void; - onOpenPage: (pageId: string) => void; + onPermanentlyDeletePage: () => void; + onRestorePage: () => void; + onOpenPage: () => void; }; export const TrashOperationCell: React.FC = ({ - pageMeta, onPermanentlyDeletePage, onRestorePage, }) => { - const { id, title } = pageMeta; const t = useAFFiNEI18N(); const [open, setOpen] = useState(false); return ( @@ -159,8 +135,7 @@ export const TrashOperationCell: React.FC = ({ { - onRestorePage(id); - toast(t['restored']({ title: title || 'Untitled' })); + onRestorePage(); }} > @@ -182,8 +157,7 @@ export const TrashOperationCell: React.FC = ({ confirmType="danger" open={open} onConfirm={() => { - onPermanentlyDeletePage(id); - toast(t['Permanently deleted']()); + onPermanentlyDeletePage(); setOpen(false); }} onClose={() => { diff --git a/apps/web/src/components/affine/operation-menu-items/CopyLink.tsx b/packages/component/src/components/page-list/operation-menu-items/CopyLink.tsx similarity index 88% rename from apps/web/src/components/affine/operation-menu-items/CopyLink.tsx rename to packages/component/src/components/page-list/operation-menu-items/CopyLink.tsx index 58203e1cfa..8a22e38f2e 100644 --- a/apps/web/src/components/affine/operation-menu-items/CopyLink.tsx +++ b/packages/component/src/components/page-list/operation-menu-items/CopyLink.tsx @@ -1,10 +1,8 @@ -import { MenuItem } from '@affine/component'; +import { MenuItem, toast } 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) => { diff --git a/apps/web/src/components/affine/operation-menu-items/DisablePublicSharing.tsx b/packages/component/src/components/page-list/operation-menu-items/DisablePublicSharing.tsx similarity index 76% rename from apps/web/src/components/affine/operation-menu-items/DisablePublicSharing.tsx rename to packages/component/src/components/page-list/operation-menu-items/DisablePublicSharing.tsx index 50deb4d81e..aa9d0573fc 100644 --- a/apps/web/src/components/affine/operation-menu-items/DisablePublicSharing.tsx +++ b/packages/component/src/components/page-list/operation-menu-items/DisablePublicSharing.tsx @@ -1,5 +1,4 @@ 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'; @@ -47,12 +46,4 @@ export const DisablePublicSharing = ({ ); }; -const DisablePublicSharingModal = ({ - page, - open, - onClose, -}: PublicLinkDisableProps) => { - return ; -}; - -DisablePublicSharing.DisablePublicSharingModal = DisablePublicSharingModal; +DisablePublicSharing.DisablePublicSharingModal = PublicLinkDisableModal; diff --git a/apps/web/src/components/affine/operation-menu-items/Export.tsx b/packages/component/src/components/page-list/operation-menu-items/Export.tsx similarity index 100% rename from apps/web/src/components/affine/operation-menu-items/Export.tsx rename to packages/component/src/components/page-list/operation-menu-items/Export.tsx diff --git a/apps/web/src/components/affine/operation-menu-items/MoveToTrash.tsx b/packages/component/src/components/page-list/operation-menu-items/MoveToTrash.tsx similarity index 89% rename from apps/web/src/components/affine/operation-menu-items/MoveToTrash.tsx rename to packages/component/src/components/page-list/operation-menu-items/MoveToTrash.tsx index d4a388babc..82d472578a 100644 --- a/apps/web/src/components/affine/operation-menu-items/MoveToTrash.tsx +++ b/packages/component/src/components/page-list/operation-menu-items/MoveToTrash.tsx @@ -2,7 +2,6 @@ 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'; @@ -30,10 +29,10 @@ export const MoveToTrash = ({ }; const ConfirmModal = ({ - meta, + title, ...confirmModalProps }: { - meta: PageMeta; + title: string; } & ConfirmProps) => { const t = useAFFiNEI18N(); @@ -41,7 +40,7 @@ const ConfirmModal = ({ { return { cursor: 'pointer', '.favorite-button': { - display: 'none', + visibility: 'hidden', }, '&:hover': { '.favorite-button': { - display: 'flex', + visibility: 'visible', }, }, }; diff --git a/packages/component/src/components/share-menu/SharePage.tsx b/packages/component/src/components/share-menu/SharePage.tsx index c448b99d0a..72522ee6be 100644 --- a/packages/component/src/components/share-menu/SharePage.tsx +++ b/packages/component/src/components/share-menu/SharePage.tsx @@ -56,6 +56,12 @@ export const AffineSharePage: FC = props => { navigator.clipboard.writeText(sharingUrl); toast(t['Copied link to clipboard']()); }, [sharingUrl, t]); + const onDisablePublic = useCallback(() => { + setIsPublic(false); + toast('Successfully disabled', { + portal: document.body, + }); + }, [setIsPublic]); return (
@@ -104,8 +110,8 @@ export const AffineSharePage: FC = props => { {t['Disable Public Link']()} { setShowDisable(false); }} diff --git a/packages/component/src/components/share-menu/disable-public-link/index.tsx b/packages/component/src/components/share-menu/disable-public-link/index.tsx index 19d10bf911..6765a8a839 100644 --- a/packages/component/src/components/share-menu/disable-public-link/index.tsx +++ b/packages/component/src/components/share-menu/disable-public-link/index.tsx @@ -1,9 +1,6 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks'; -import type { Page } from '@blocksuite/store'; -import { useBlockSuiteWorkspacePageIsPublic } from '@toeverything/hooks/use-block-suite-workspace-page-is-public'; -import { useCallback } from 'react'; -import { Modal, ModalCloseButton, toast } from '../../..'; +import { Modal, ModalCloseButton } from '../../..'; import { StyledButton, StyledButtonContent, @@ -14,25 +11,17 @@ import { } from './style'; export type PublicLinkDisableProps = { - page: Page; open: boolean; + onConfirmDisable: () => void; onClose: () => void; }; export const PublicLinkDisableModal = ({ - page, open, + onConfirmDisable, onClose, }: PublicLinkDisableProps) => { const t = useAFFiNEI18N(); - const [, setIsPublic] = useBlockSuiteWorkspacePageIsPublic(page); - const handleDisable = useCallback(() => { - setIsPublic(false); - toast('Successfully disabled', { - portal: document.body, - }); - onClose(); - }, [onClose, setIsPublic]); return ( @@ -47,7 +36,10 @@ export const PublicLinkDisableModal = ({ {t['Cancel']()} { + onConfirmDisable(); + onClose(); + }} style={{ marginLeft: '24px' }} > {t['Disable']()} diff --git a/packages/component/src/stories/ChangeLog.stories.tsx b/packages/component/src/stories/ChangeLog.stories.tsx index 2234e1ea5d..5117bd0e62 100644 --- a/packages/component/src/stories/ChangeLog.stories.tsx +++ b/packages/component/src/stories/ChangeLog.stories.tsx @@ -44,5 +44,5 @@ export const Close: StoryFn = () => { Close.play = async ({ canvasElement }) => { const element = within(canvasElement); await new Promise(resolve => setTimeout(resolve, 2000)); - await element.getByTestId('change-log-close-button').click(); + element.getByTestId('change-log-close-button').click(); }; diff --git a/packages/component/src/stories/PageList.stories.tsx b/packages/component/src/stories/PageList.stories.tsx new file mode 100644 index 0000000000..f3c1ca5326 --- /dev/null +++ b/packages/component/src/stories/PageList.stories.tsx @@ -0,0 +1,89 @@ +import { PageIcon } from '@blocksuite/icons'; +import type { StoryFn } from '@storybook/react'; + +import { AffineLoading } from '../components/affine-loading'; +import type { + PageListProps, + TrashListData, +} from '../components/page-list/all-page'; +import { PageListTrashView } from '../components/page-list/all-page'; +import PageList from '../components/page-list/all-page'; +import type { OperationCellProps } from '../components/page-list/operation-cell'; +import { OperationCell } from '../components/page-list/operation-cell'; +import { toast } from '../ui/toast'; + +export default { + title: 'AFFiNE/PageList', + component: AffineLoading, +}; + +export const AffineOperationCell: StoryFn = ({ + ...props +}) => ( +
+ +
+); + +AffineOperationCell.args = { + title: 'Example Page', + favorite: false, + isPublic: true, + onToggleFavoritePage: () => toast('Toggle favorite page'), + onDisablePublicSharing: () => toast('Disable public sharing'), + onOpenPageInNewTab: () => toast('Open page in new tab'), + onRemoveToTrash: () => toast('Remove to trash'), +}; + +export const AffineAllPageList: StoryFn = ({ ...props }) => ( +
+ +
+); + +AffineAllPageList.args = { + isPublicWorkspace: false, + listType: 'all', + list: [ + { + pageId: '1', + favorite: false, + icon: , + isPublicPage: true, + title: 'Example Page', + updatedDate: '2021-01-01', + createDate: '2021-01-01', + trashDate: '2021-01-01', + bookmarkPage: () => toast('Bookmark page'), + onClickPage: () => toast('Click page'), + onDisablePublicSharing: () => toast('Disable public sharing'), + onOpenPageInNewTab: () => toast('Open page in new tab'), + removeToTrash: () => toast('Remove to trash'), + }, + ], +}; + +export const AffineTrashPageList: StoryFn<{ + list: TrashListData[]; +}> = ({ ...props }) => ( +
+ +
+); + +AffineTrashPageList.args = { + list: [ + { + pageId: '1', + favorite: false, + icon: , + title: 'Example Page', + updatedDate: '2021-01-01', + createDate: '2021-01-01', + trashDate: '2021-01-01', + onClickPage: () => toast('Click page'), + onPermanentlyDeletePage: () => toast('Permanently delete page'), + onRestorePage: () => toast('Restore page'), + }, + ], +}; diff --git a/packages/component/src/stories/ShareMenu.stories.tsx b/packages/component/src/stories/ShareMenu.stories.tsx index b2c7aeae3a..cfafd9750f 100644 --- a/packages/component/src/stories/ShareMenu.stories.tsx +++ b/packages/component/src/stories/ShareMenu.stories.tsx @@ -5,8 +5,11 @@ import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils'; import type { Page } from '@blocksuite/store'; import { expect } from '@storybook/jest'; import type { StoryFn } from '@storybook/react'; +import { useState } from 'react'; +import { PublicLinkDisableModal } from '../components/share-menu/disable-public-link'; import { ShareMenu } from '../components/share-menu/ShareMenu'; +import { StyledDisableButton } from '../components/share-menu/styles'; import toast from '../ui/toast/toast'; export default { @@ -36,9 +39,9 @@ const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace( WorkspaceFlavour.LOCAL ); -initPage(blockSuiteWorkspace.createPage('page0')); -initPage(blockSuiteWorkspace.createPage('page1')); -initPage(blockSuiteWorkspace.createPage('page2')); +initPage(blockSuiteWorkspace.createPage({ id: 'page0' })); +initPage(blockSuiteWorkspace.createPage({ id: 'page1' })); +initPage(blockSuiteWorkspace.createPage({ id: 'page2' })); const localWorkspace: LocalWorkspace = { id: 'test-workspace', @@ -103,3 +106,22 @@ export const AffineBasic: StoryFn = () => { /> ); }; + +export const DisableModal: StoryFn = () => { + const [open, setOpen] = useState(false); + return ( + <> + setOpen(!open)}> + Disable Public Link + + { + toast('Disabled'); + setOpen(false); + }} + onClose={() => setOpen(false)} + /> + + ); +}; diff --git a/packages/component/src/stories/Switch.stories.tsx b/packages/component/src/stories/Switch.stories.tsx index cef366da6f..da4ab05496 100644 --- a/packages/component/src/stories/Switch.stories.tsx +++ b/packages/component/src/stories/Switch.stories.tsx @@ -11,6 +11,3 @@ export default { export const Basic: StoryFn = () => { return ; }; -Basic.args = { - logoSrc: '/imgs/affine-text-logo.png', -};