diff --git a/packages/frontend/core/src/components/page-list/docs/index.ts b/packages/frontend/core/src/components/page-list/docs/index.ts index a122e4f00..33c65b873 100644 --- a/packages/frontend/core/src/components/page-list/docs/index.ts +++ b/packages/frontend/core/src/components/page-list/docs/index.ts @@ -1,5 +1,2 @@ -export * from './page-list-header'; -export * from './page-list-item'; export * from './page-list-new-page-button'; export * from './page-tags'; -export * from './virtualized-page-list'; diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-header.css.ts b/packages/frontend/core/src/components/page-list/docs/page-list-header.css.ts deleted file mode 100644 index 23981bf08..000000000 --- a/packages/frontend/core/src/components/page-list/docs/page-list-header.css.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { cssVar } from '@toeverything/theme'; -import { style } from '@vanilla-extract/css'; -export const docListHeader = style({ - height: 100, - alignItems: 'center', - padding: '48px 16px 20px 24px', - overflow: 'hidden', - display: 'flex', - justifyContent: 'space-between', - background: cssVar('backgroundPrimaryColor'), -}); -export const docListHeaderTitle = style({ - fontSize: cssVar('fontH5'), - fontWeight: 500, - color: cssVar('textSecondaryColor'), - display: 'flex', - alignItems: 'center', - gap: 8, - height: '28px', - userSelect: 'none', -}); -export const titleIcon = style({ - color: cssVar('iconColor'), - display: 'inline-flex', - alignItems: 'center', -}); -export const titleCollectionName = style({ - color: cssVar('textPrimaryColor'), -}); -export const tagSticky = style({ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - padding: '1px 8px', - color: cssVar('textPrimaryColor'), - fontSize: cssVar('fontXs'), - borderRadius: '10px', - columnGap: '4px', - border: `1px solid ${cssVar('borderColor')}`, - background: cssVar('backgroundPrimaryColor'), - maxWidth: '30vw', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - height: '22px', - lineHeight: '1.67em', - cursor: 'pointer', -}); -export const tagIndicator = style({ - width: '8px', - height: '8px', - borderRadius: '50%', - flexShrink: 0, -}); -export const tagLabel = style({ - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', -}); -export const arrowDownSmallIcon = style({ - color: cssVar('iconColor'), - fontSize: '12px', -}); -export const searchIcon = style({ - color: cssVar('iconColor'), - fontSize: '20px', -}); - -export const tagsEditorRoot = style({ - display: 'flex', - flexDirection: 'column', - width: '100%', - padding: '8px', -}); - -export const tagsMenu = style({ - padding: 0, - width: '296px', - overflow: 'hidden', -}); - -export const tagsEditorSelectedTags = style({ - display: 'flex', - gap: '8px', - flexWrap: 'nowrap', - padding: '6px 12px', - minHeight: 42, - alignItems: 'center', -}); - -export const searchInput = style({ - flexGrow: 1, - padding: '10px 0', - margin: '-10px 0', - border: 'none', - outline: 'none', - fontSize: cssVar('fontSm'), - fontFamily: 'inherit', - color: 'inherit', - backgroundColor: 'transparent', - '::placeholder': { - color: cssVar('placeholderColor'), - }, - overflow: 'hidden', -}); - -export const tagsEditorTagsSelector = style({ - display: 'flex', - flexDirection: 'column', - maxHeight: '400px', - overflow: 'auto', -}); - -export const tagSelectorTagsScrollContainer = style({ - overflowX: 'hidden', - position: 'relative', - maxHeight: '200px', - gap: '8px', -}); - -export const tagSelectorItem = style({ - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - padding: '4px 16px', - height: '32px', - gap: 8, - fontSize: cssVar('fontSm'), - cursor: 'pointer', - borderRadius: '4px', - color: cssVar('textPrimaryColor'), - ':hover': { - backgroundColor: cssVar('hoverColor'), - }, - ':visited': { - color: cssVar('textPrimaryColor'), - }, - selectors: { - '&.disable:hover': { - backgroundColor: 'unset', - cursor: 'auto', - }, - }, -}); - -export const tagIcon = style({ - width: '8px', - height: '8px', - borderRadius: '50%', - flexShrink: 0, -}); - -export const tagSelectorItemText = style({ - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', -}); - -export const rightButtonGroup = style({ - display: 'flex', - gap: '12px', - alignItems: 'center', - justifyContent: 'center', -}); - -export const buttonText = style({ - fontSize: cssVar('fontXs'), - fontWeight: 500, - color: cssVar('textPrimaryColor'), -}); diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx b/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx deleted file mode 100644 index 9eba8c0c3..000000000 --- a/packages/frontend/core/src/components/page-list/docs/page-list-header.tsx +++ /dev/null @@ -1,362 +0,0 @@ -import { - Button, - Divider, - Menu, - RowInput, - Scrollable, - useConfirmModal, -} from '@affine/component'; -import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper'; -import { WorkspaceDialogService } from '@affine/core/modules/dialogs'; -import type { DocRecord } from '@affine/core/modules/doc'; -import type { Tag } from '@affine/core/modules/tag'; -import { TagService } from '@affine/core/modules/tag'; -import { WorkbenchService } from '@affine/core/modules/workbench'; -import { WorkspaceService } from '@affine/core/modules/workspace'; -import { inferOpenMode } from '@affine/core/utils'; -import { useI18n } from '@affine/i18n'; -import { track } from '@affine/track'; -import type { DocMode } from '@blocksuite/affine/model'; -import { - ArrowDownSmallIcon, - SearchIcon, - ViewLayersIcon, -} from '@blocksuite/icons/rc'; -import { useLiveData, useService, useServices } from '@toeverything/infra'; -import clsx from 'clsx'; -import { useCallback, useMemo, useState } from 'react'; -import { Link } from 'react-router-dom'; - -import { usePageHelper } from '../../../blocksuite/block-suite-page-list/utils'; -import { - type Collection, - CollectionService, -} from '../../../modules/collection'; -import { SaveAsCollectionButton } from '../view'; -import * as styles from './page-list-header.css'; -import { PageListNewPageButton } from './page-list-new-page-button'; - -export const PageListHeader = () => { - const t = useI18n(); - const { workspaceService, workspaceDialogService, workbenchService } = - useServices({ - WorkspaceService, - WorkspaceDialogService, - WorkbenchService, - }); - - const workbench = workbenchService.workbench; - const workspace = workspaceService.workspace; - const { createEdgeless, createPage } = usePageHelper(workspace.docCollection); - - const title = useMemo(() => { - return t['com.affine.all-pages.header'](); - }, [t]); - - const handleOpenDocs = useCallback( - (result: { - docIds: string[]; - entryId?: string; - isWorkspaceFile?: boolean; - }) => { - const { docIds, entryId, isWorkspaceFile } = result; - // If the imported file is a workspace file, open the entry page. - if (isWorkspaceFile && entryId) { - workbench.openDoc(entryId); - } else if (!docIds.length) { - return; - } - // Open all the docs when there are multiple docs imported. - if (docIds.length > 1) { - workbench.openAll(); - } else { - // Otherwise, open the only doc. - workbench.openDoc(docIds[0]); - } - }, - [workbench] - ); - - const onImportFile = useCallback(() => { - track.$.header.importModal.open(); - workspaceDialogService.open('import', undefined, payload => { - if (!payload) { - return; - } - handleOpenDocs(payload); - }); - }, [workspaceDialogService, handleOpenDocs]); - - return ( -
-
{title}
- createEdgeless({ at: inferOpenMode(e) })} - onCreatePage={e => - createPage('page' as DocMode, { at: inferOpenMode(e) }) - } - onCreateDoc={e => createPage(undefined, { at: inferOpenMode(e) })} - onImportFile={onImportFile} - > -
{t['New Page']()}
-
-
- ); -}; -/** - * @deprecated - */ -export const CollectionPageListHeader = ({ - collection, - workspaceId, -}: { - collection: Collection; - workspaceId: string; -}) => { - const t = useI18n(); - const { jumpToCollections } = useNavigateHelper(); - const { collectionService, workspaceService, workspaceDialogService } = - useServices({ - CollectionService, - WorkspaceService, - WorkspaceDialogService, - }); - - const handleJumpToCollections = useCallback(() => { - jumpToCollections(workspaceId); - }, [jumpToCollections, workspaceId]); - - const handleEdit = useCallback(() => { - workspaceDialogService.open('collection-editor', { - collectionId: collection.id, - }); - }, [collection, workspaceDialogService]); - - const workspace = workspaceService.workspace; - const { createEdgeless, createPage } = usePageHelper(workspace.docCollection); - const { openConfirmModal } = useConfirmModal(); - const name = useLiveData(collection.name$); - - const createAndAddDocument = useCallback( - (createDocumentFn: () => DocRecord) => { - const newDoc = createDocumentFn(); - collectionService.addDocToCollection(collection.id, newDoc.id); - }, - [collection.id, collectionService] - ); - - const onConfirmAddDocument = useCallback( - (createDocumentFn: () => DocRecord) => { - openConfirmModal({ - title: t['com.affine.collection.add-doc.confirm.title'](), - description: t['com.affine.collection.add-doc.confirm.description'](), - cancelText: t['Cancel'](), - confirmText: t['Confirm'](), - confirmButtonOptions: { - variant: 'primary', - }, - onConfirm: () => createAndAddDocument(createDocumentFn), - }); - }, - [openConfirmModal, t, createAndAddDocument] - ); - - const createPageModeDoc = useCallback( - () => createPage('page' as DocMode), - [createPage] - ); - - const onCreateEdgeless = useCallback( - () => onConfirmAddDocument(createEdgeless), - [createEdgeless, onConfirmAddDocument] - ); - const onCreatePage = useCallback(() => { - onConfirmAddDocument(createPageModeDoc); - }, [createPageModeDoc, onConfirmAddDocument]); - const onCreateDoc = useCallback(() => { - onConfirmAddDocument(createPage); - }, [createPage, onConfirmAddDocument]); - - return ( -
-
-
- {t['com.affine.collections.header']()} / -
-
- -
-
{name}
-
-
- - -
{t['New Page']()}
-
-
-
- ); -}; - -/** - * @deprecated - */ -export const TagPageListHeader = ({ - tag, - workspaceId, -}: { - tag: Tag; - workspaceId: string; -}) => { - const tagColor = useLiveData(tag.color$); - const tagTitle = useLiveData(tag.value$); - - const t = useI18n(); - const { jumpToTags, jumpToCollection } = useNavigateHelper(); - const collectionService = useService(CollectionService); - const [openMenu, setOpenMenu] = useState(false); - - const handleJumpToTags = useCallback(() => { - jumpToTags(workspaceId); - }, [jumpToTags, workspaceId]); - - const saveToCollection = useCallback( - (collectionName: string) => { - const id = collectionService.createCollection({ - name: collectionName, - rules: { - filters: [ - { - type: 'system', - key: 'tags', - method: 'include-all', - value: tag.id, - }, - ], - }, - }); - jumpToCollection(workspaceId, id); - }, - [collectionService, tag.id, jumpToCollection, workspaceId] - ); - - return ( -
-
-
- {t['Tags']()} / -
- } - > -
-
-
{tagTitle}
- -
-
-
- -
- ); -}; - -interface SwitchTagProps { - onClick: (open: boolean) => void; -} - -export const SwitchTag = ({ onClick }: SwitchTagProps) => { - const t = useI18n(); - const [inputValue, setInputValue] = useState(''); - const tagList = useService(TagService).tagList; - const filteredTags = useLiveData( - inputValue ? tagList.filterTagsByName$(inputValue) : tagList.tags$ - ); - - const onInputChange = useCallback((value: string) => { - setInputValue(value); - }, []); - - const handleClick = useCallback(() => { - setInputValue(''); - onClick(false); - }, [onClick]); - - return ( -
-
- - -
- -
- - - {filteredTags.map(tag => { - return ; - })} - {filteredTags.length === 0 ? ( -
- {t['Find 0 result']()} -
- ) : null} -
- -
-
-
- ); -}; - -const TagLink = ({ tag, onClick }: { tag: Tag; onClick: () => void }) => { - const tagColor = useLiveData(tag.color$); - const tagTitle = useLiveData(tag.value$); - return ( - -
-
{tagTitle}
- - ); -}; diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-item.css.ts b/packages/frontend/core/src/components/page-list/docs/page-list-item.css.ts deleted file mode 100644 index b0dfe4e4e..000000000 --- a/packages/frontend/core/src/components/page-list/docs/page-list-item.css.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { cssVar } from '@toeverything/theme'; -import { globalStyle, style } from '@vanilla-extract/css'; -export const root = style({ - display: 'flex', - color: cssVar('textPrimaryColor'), - height: '54px', - // 42 + 12 - flexShrink: 0, - width: '100%', - alignItems: 'stretch', - contain: 'strict', - transition: 'background-color 0.2s, opacity 0.2s', - ':hover': { - backgroundColor: cssVar('hoverColor'), - }, - overflow: 'hidden', - cursor: 'default', - selectors: { - '&[data-clickable=true]': { - cursor: 'pointer', - }, - }, -}); - -export const dragPageItemOverlay = style({ - height: '45px', - borderRadius: '8px', - display: 'flex', - alignItems: 'center', - background: cssVar('hoverColorFilled'), - boxShadow: cssVar('menuShadow'), - maxWidth: '360px', - minWidth: '260px', -}); -export const dndCell = style({ - position: 'relative', - marginLeft: -8, - height: '100%', - outline: 'none', - paddingLeft: 8, -}); -globalStyle(`[data-draggable=true] ${dndCell}:before`, { - content: '""', - position: 'absolute', - top: '50%', - transform: 'translateY(-50%)', - left: 0, - width: 4, - height: 4, - transition: 'height 0.2s, opacity 0.2s', - backgroundColor: cssVar('placeholderColor'), - borderRadius: '2px', - opacity: 0, -}); -globalStyle(`[data-draggable=true] ${dndCell}:hover:before`, { - height: 12, - opacity: 1, -}); -globalStyle(`[data-draggable=true][data-dragging=true] ${dndCell}`, { - opacity: 0.5, -}); -globalStyle(`[data-draggable=true][data-dragging=true] ${dndCell}:before`, { - height: 32, - width: 2, - opacity: 1, -}); - -globalStyle(`${root} > :first-child`, { - paddingLeft: '16px', -}); -globalStyle(`${root} > :last-child`, { - paddingRight: '8px', -}); -export const titleIconsWrapper = style({ - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - gap: '10px', -}); -export const selectionCell = style({ - display: 'flex', - alignItems: 'center', - flexShrink: 0, - fontSize: cssVar('fontH3'), -}); -export const titleCell = style({ - display: 'flex', - flexDirection: 'column', - alignItems: 'flex-start', - padding: '0 16px', - maxWidth: 'calc(100% - 64px)', - flex: 1, - whiteSpace: 'nowrap', - userSelect: 'none', -}); -export const titleCellMain = style({ - overflow: 'hidden', - fontSize: cssVar('fontSm'), - fontWeight: 600, - whiteSpace: 'nowrap', - flex: 1, - textOverflow: 'ellipsis', - alignSelf: 'stretch', -}); -export const titleCellPreview = style({ - overflow: 'hidden', - color: cssVar('textSecondaryColor'), - fontSize: cssVar('fontXs'), - flex: 1, - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - alignSelf: 'stretch', -}); -export const iconCell = style({ - display: 'flex', - alignItems: 'center', - fontSize: cssVar('fontH3'), - color: cssVar('iconColor'), - flexShrink: 0, -}); -export const tagsCell = style({ - display: 'flex', - alignItems: 'center', - fontSize: cssVar('fontXs'), - color: cssVar('textSecondaryColor'), - padding: '0 8px', - height: '60px', - width: '100%', -}); -export const dateCell = style({ - display: 'flex', - alignItems: 'center', - fontSize: cssVar('fontXs'), - color: cssVar('textPrimaryColor'), - flexShrink: 0, - flexWrap: 'nowrap', - padding: '0 8px', - userSelect: 'none', -}); -export const actionsCellWrapper = style({ - display: 'flex', - alignItems: 'center', - justifyContent: 'flex-end', - flexShrink: 0, -}); -export const operationsCell = style({ - display: 'flex', - alignItems: 'center', - justifyContent: 'flex-end', - columnGap: '6px', - flexShrink: 0, -}); diff --git a/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx b/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx deleted file mode 100644 index cbe24a12c..000000000 --- a/packages/frontend/core/src/components/page-list/docs/page-list-item.tsx +++ /dev/null @@ -1,398 +0,0 @@ -import { Checkbox, Tooltip, useDraggable } from '@affine/component'; -import { TagService } from '@affine/core/modules/tag'; -import type { AffineDNDData } from '@affine/core/types/dnd'; -import { stopPropagation } from '@affine/core/utils'; -import { i18nTime } from '@affine/i18n'; -import { useLiveData, useService } from '@toeverything/infra'; -import type { ForwardedRef, PropsWithChildren } from 'react'; -import { forwardRef, useCallback, useEffect, useMemo } from 'react'; - -import { WorkbenchLink } from '../../../modules/workbench/view/workbench-link'; -import { - anchorIndexAtom, - rangeIdsAtom, - selectionStateAtom, - useAtom, -} from '../scoped-atoms'; -import type { PageListItemProps } from '../types'; -import { useAllDocDisplayProperties } from '../use-all-doc-display-properties'; -import { ColWrapper } from '../utils'; -import * as styles from './page-list-item.css'; -import { PageTags } from './page-tags'; - -const ListTitleCell = ({ - title, - preview, -}: Pick) => { - const [displayProperties] = useAllDocDisplayProperties(); - return ( -
-
- {title} -
- {preview && displayProperties.displayProperties.bodyNotes ? ( -
- {preview} -
- ) : null} -
- ); -}; - -const ListIconCell = ({ icon }: Pick) => { - return ( -
- {icon} -
- ); -}; - -const PageSelectionCell = ({ - selectable, - onSelectedChange, - selected, -}: Pick) => { - const onSelectionChange = useCallback( - (_event: React.ChangeEvent) => { - return onSelectedChange?.(); - }, - [onSelectedChange] - ); - if (!selectable) { - return null; - } - return ( -
- -
- ); -}; - -export const PageTagsCell = ({ pageId }: Pick) => { - const tagList = useService(TagService).tagList; - const tags = useLiveData(tagList.tagsByPageId$(pageId)); - - return ( -
- -
- ); -}; - -const PageCreateDateCell = ({ - createDate, -}: Pick) => { - return ( - -
- {i18nTime(createDate, { - relative: true, - })} -
-
- ); -}; - -const PageUpdatedDateCell = ({ - updatedDate, -}: Pick) => { - return ( - -
- {updatedDate - ? i18nTime(updatedDate, { - relative: true, - }) - : '-'} -
-
- ); -}; - -const PageListOperationsCell = ({ - operations, -}: Pick) => { - return operations ? ( -
- {operations} -
- ) : null; -}; - -export const PageListItem = (props: PageListItemProps) => { - const [displayProperties] = useAllDocDisplayProperties(); - const pageTitleElement = useMemo(() => { - return ( -
-
- - -
- -
- ); - }, [ - props.icon, - props.onSelectedChange, - props.preview, - props.selectable, - props.selected, - props.title, - ]); - - const { dragRef, CustomDragPreview, dragging } = useDraggable( - () => ({ - canDrag: props.draggable, - data: { - entity: { - type: 'doc', - id: props.pageId, - }, - from: { - at: 'all-docs:list', - }, - }, - }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [props.draggable, props.pageId, props.selectable] - ); - - return ( - <> - - - -
- - -
- -
- -
- - - {props.operations ? ( - - - - ) : null} -
- - {pageTitleElement} - - - ); -}; - -type PageListWrapperProps = PropsWithChildren< - Pick & { - isDragging: boolean; - pageIds: string[]; - } ->; - -const PageListItemWrapper = forwardRef( - ( - { - to, - isDragging, - pageId, - pageIds, - onClick, - children, - draggable, - }: PageListWrapperProps, - ref: ForwardedRef - ) => { - const [selectionState, setSelectionActive] = useAtom(selectionStateAtom); - const [anchorIndex, setAnchorIndex] = useAtom(anchorIndexAtom); - const [rangeIds, setRangeIds] = useAtom(rangeIdsAtom); - - const handleShiftClick = useCallback( - (currentIndex: number) => { - if (anchorIndex === undefined) { - setAnchorIndex(currentIndex); - onClick?.(); - return; - } - - const lowerIndex = Math.min(anchorIndex, currentIndex); - const upperIndex = Math.max(anchorIndex, currentIndex); - const newRangeIds = pageIds.slice(lowerIndex, upperIndex + 1); - - const currentSelected = selectionState.selectedIds || []; - - // Set operations - const setRange = new Set(rangeIds); - const newSelected = new Set( - currentSelected.filter(id => !setRange.has(id)).concat(newRangeIds) - ); - - selectionState.onSelectedIdsChange?.([...newSelected]); - setRangeIds(newRangeIds); - }, - [ - anchorIndex, - onClick, - pageIds, - selectionState, - setAnchorIndex, - rangeIds, - setRangeIds, - ] - ); - - const handleClick = useCallback( - (e: React.MouseEvent) => { - if (!selectionState.selectable) { - return; - } - e.stopPropagation(); - const currentIndex = pageIds.indexOf(pageId); - - if (e.shiftKey) { - e.preventDefault(); - if (!selectionState.selectionActive) { - setSelectionActive(true); - setAnchorIndex(currentIndex); - onClick?.(); - } else { - handleShiftClick(currentIndex); - } - } else { - setAnchorIndex(undefined); - setRangeIds([]); - onClick?.(); - return; - } - }, - [ - handleShiftClick, - onClick, - pageId, - pageIds, - selectionState.selectable, - selectionState.selectionActive, - setAnchorIndex, - setRangeIds, - setSelectionActive, - ] - ); - - const commonProps = useMemo( - () => ({ - role: 'list-item', - 'data-testid': 'page-list-item', - 'data-page-id': pageId, - 'data-draggable': draggable, - className: styles.root, - 'data-clickable': !!onClick || !!to, - 'data-dragging': isDragging, - onClick: onClick ? handleClick : undefined, - }), - [pageId, draggable, onClick, to, isDragging, handleClick] - ); - - useEffect(() => { - if (selectionState.selectionActive) { - // listen for shift key up - const handleKeyUp = (e: KeyboardEvent) => { - if (e.key === 'Shift') { - setAnchorIndex(undefined); - setRangeIds([]); - } - }; - window.addEventListener('keyup', handleKeyUp); - return () => { - window.removeEventListener('keyup', handleKeyUp); - }; - } - return; - }, [ - selectionState.selectionActive, - setAnchorIndex, - setRangeIds, - setSelectionActive, - ]); - - if (to) { - return ( - - {children} - - ); - } else { - return ( -
- {children} -
- ); - } - } -); -PageListItemWrapper.displayName = 'PageListItemWrapper'; diff --git a/packages/frontend/core/src/components/page-list/docs/page-tags.tsx b/packages/frontend/core/src/components/page-list/docs/page-tags.tsx index 98efd0c93..7d619e527 100644 --- a/packages/frontend/core/src/components/page-list/docs/page-tags.tsx +++ b/packages/frontend/core/src/components/page-list/docs/page-tags.tsx @@ -1,14 +1,6 @@ -import { Menu } from '@affine/component'; import { TagItem as TagItemComponent } from '@affine/core/components/tags'; import type { Tag } from '@affine/core/modules/tag'; -import { stopPropagation } from '@affine/core/utils'; -import { MoreHorizontalIcon } from '@blocksuite/icons/rc'; -import { LiveData, useLiveData } from '@toeverything/infra'; -import { assignInlineVars } from '@vanilla-extract/dynamic'; -import clsx from 'clsx'; -import { useMemo } from 'react'; - -import * as styles from './page-tags.css'; +import { useLiveData } from '@toeverything/infra'; export interface PageTagsProps { tags: Tag[]; @@ -47,90 +39,3 @@ export const TagItem = ({ tag, ...props }: TagItemProps) => { /> ); }; - -const TagItemNormal = ({ - tags, - maxItems, -}: { - tags: Tag[]; - maxItems?: number; -}) => { - const nTags = useMemo(() => { - return maxItems ? tags.slice(0, maxItems) : tags; - }, [maxItems, tags]); - - const tagsOrdered = useLiveData( - useMemo(() => { - return LiveData.computed(get => - [...nTags].sort((a, b) => get(a.value$).length - get(b.value$).length) - ); - }, [nTags]) - ); - - return useMemo( - () => - tagsOrdered.map((tag, idx) => ( - - )), - [tagsOrdered] - ); -}; - -export const PageTags = ({ - tags, - widthOnHover, - maxItems, - hoverExpandDirection, -}: PageTagsProps) => { - const sanitizedWidthOnHover = widthOnHover - ? typeof widthOnHover === 'string' - ? widthOnHover - : `${widthOnHover}px` - : 'auto'; - - const tagsInPopover = useMemo(() => { - const lastTags = tags.slice(maxItems); - return ( -
- {lastTags.map((tag, idx) => ( - - ))} -
- ); - }, [maxItems, tags]); - - return ( -
-
-
-
- -
- {maxItems && tags.length > maxItems ? ( - -
- -
-
- ) : null} -
-
- ); -}; diff --git a/packages/frontend/core/src/components/page-list/docs/use-search.tsx b/packages/frontend/core/src/components/page-list/docs/use-search.tsx deleted file mode 100644 index 74b83db6f..000000000 --- a/packages/frontend/core/src/components/page-list/docs/use-search.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import type { DocMeta } from '@blocksuite/affine/store'; -import { useState } from 'react'; - -export const useSearch = (list: DocMeta[]) => { - const [value, onChange] = useState(''); - return { - searchText: value, - updateSearchText: onChange, - searchedList: value - ? list.filter(v => v.title.toLowerCase().includes(value.toLowerCase())) - : list, - }; -}; diff --git a/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx b/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx deleted file mode 100644 index fe2a7fed9..000000000 --- a/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx +++ /dev/null @@ -1,211 +0,0 @@ -import { toast, useConfirmModal } from '@affine/component'; -import { useBlockSuiteDocMeta } from '@affine/core/components/hooks/use-block-suite-page-meta'; -import { type Collection } from '@affine/core/modules/collection'; -import { DocsService } from '@affine/core/modules/doc'; -import type { Tag } from '@affine/core/modules/tag'; -import { WorkspaceService } from '@affine/core/modules/workspace'; -import { Trans, useI18n } from '@affine/i18n'; -import type { DocMeta } from '@blocksuite/affine/store'; -import { useLiveData, useService } from '@toeverything/infra'; -import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; - -import { ListFloatingToolbar } from '../components/list-floating-toolbar'; -import { usePageItemGroupDefinitions } from '../group-definitions'; -import { usePageHeaderColsDef } from '../header-col-def'; -import { PageOperationCell } from '../operation-cell'; -import { PageListItemRenderer } from '../page-group'; -import { ListTableHeader } from '../page-header'; -import type { ItemListHandle, ListItem } from '../types'; -import { VirtualizedList } from '../virtualized-list'; -import { - CollectionPageListHeader, - PageListHeader, - TagPageListHeader, -} from './page-list-header'; - -const usePageOperationsRenderer = (collection?: Collection) => { - const t = useI18n(); - const removeFromAllowList = useCallback( - (id: string) => { - collection?.removeDoc(id); - toast(t['com.affine.collection.removePage.success']()); - }, - [collection, t] - ); - const pageOperationsRenderer = useCallback( - (page: DocMeta, isInAllowList?: boolean) => { - return ( - removeFromAllowList(page.id)} - /> - ); - }, - [removeFromAllowList] - ); - return pageOperationsRenderer; -}; - -export const VirtualizedPageList = memo(function VirtualizedPageList({ - tag, - collection, - listItem, - setHideHeaderCreateNewPage, - disableMultiDelete, -}: { - tag?: Tag; - collection?: Collection; - listItem?: DocMeta[]; - setHideHeaderCreateNewPage?: (hide: boolean) => void; - disableMultiDelete?: boolean; -}) { - const t = useI18n(); - const listRef = useRef(null); - const [showFloatingToolbar, setShowFloatingToolbar] = useState(false); - const [selectedPageIds, setSelectedPageIds] = useState([]); - const currentWorkspace = useService(WorkspaceService).workspace; - const docsService = useService(DocsService); - const pageMetas = useBlockSuiteDocMeta(currentWorkspace.docCollection); - const pageOperations = usePageOperationsRenderer(collection); - const pageHeaderColsDef = usePageHeaderColsDef(); - - const [filteredPageIds, setFilteredPageIds] = useState([]); - useEffect(() => { - const subscription = collection?.watch().subscribe(docIds => { - setFilteredPageIds(docIds); - }); - return () => subscription?.unsubscribe(); - }, [collection]); - const allowList = useLiveData(collection?.info$.map(info => info.allowList)); - const pageMetasToRender = useMemo(() => { - if (listItem) { - return listItem; - } - if (collection) { - return pageMetas.filter( - page => filteredPageIds.includes(page.id) && !page.trash - ); - } - return pageMetas.filter(page => !page.trash); - }, [collection, filteredPageIds, listItem, pageMetas]); - - const filteredSelectedPageIds = useMemo(() => { - const ids = new Set(pageMetasToRender.map(page => page.id)); - return selectedPageIds.filter(id => ids.has(id)); - }, [pageMetasToRender, selectedPageIds]); - - const hideFloatingToolbar = useCallback(() => { - listRef.current?.toggleSelectable(); - }, []); - - const pageOperationRenderer = useCallback( - (item: ListItem) => { - const page = item as DocMeta; - const isInAllowList = allowList?.includes(page.id); - return pageOperations(page, isInAllowList); - }, - [allowList, pageOperations] - ); - - const pageHeaderRenderer = useCallback(() => { - return ; - }, [pageHeaderColsDef]); - - const pageItemRenderer = useCallback((item: ListItem) => { - return ; - }, []); - - const heading = useMemo(() => { - if (tag) { - return ; - } - if (collection) { - return ( - - ); - } - return ; - }, [collection, currentWorkspace.id, tag]); - - const { openConfirmModal } = useConfirmModal(); - - const handleMultiDelete = useCallback(() => { - if (filteredSelectedPageIds.length === 0) { - return; - } - - openConfirmModal({ - title: t['com.affine.moveToTrash.confirmModal.title.multiple']({ - number: filteredSelectedPageIds.length.toString(), - }), - description: t[ - 'com.affine.moveToTrash.confirmModal.description.multiple' - ]({ - number: filteredSelectedPageIds.length.toString(), - }), - cancelText: t['com.affine.confirmModal.button.cancel'](), - confirmText: t.Delete(), - confirmButtonOptions: { - variant: 'error', - }, - onConfirm: () => { - for (const docId of filteredSelectedPageIds) { - const doc = docsService.list.doc$(docId).value; - doc?.moveToTrash(); - } - }, - }); - hideFloatingToolbar(); - }, [ - docsService.list, - filteredSelectedPageIds, - hideFloatingToolbar, - openConfirmModal, - t, - ]); - - const group = usePageItemGroupDefinitions(); - - return ( - <> - - -
- {{ count: filteredSelectedPageIds.length } as any} -
- selected - - } - /> - - ); -}); diff --git a/packages/frontend/core/src/components/page-list/index.tsx b/packages/frontend/core/src/components/page-list/index.tsx index 9753cd089..c4cddd7e3 100644 --- a/packages/frontend/core/src/components/page-list/index.tsx +++ b/packages/frontend/core/src/components/page-list/index.tsx @@ -4,7 +4,6 @@ export * from './components/floating-toolbar'; export * from './components/new-page-button'; export * from './components/page-display-menu'; export * from './docs'; -export * from './docs/page-list-item'; export * from './docs/page-tags'; export * from './group-definitions'; export * from './header-col-def'; diff --git a/packages/frontend/core/src/components/page-list/list.css.ts b/packages/frontend/core/src/components/page-list/list.css.ts index 4380e8b97..b31d593c8 100644 --- a/packages/frontend/core/src/components/page-list/list.css.ts +++ b/packages/frontend/core/src/components/page-list/list.css.ts @@ -2,7 +2,6 @@ import { cssVar } from '@toeverything/theme'; import { createContainer, style } from '@vanilla-extract/css'; import { root as collectionItemRoot } from './collections/collection-list-item.css'; -import { root as pageItemRoot } from './docs/page-list-item.css'; import { root as tagItemRoot } from './tags/tag-list-item.css'; export const listRootContainer = createContainer('list-root-container'); export const pageListScrollContainer = style({ @@ -50,7 +49,7 @@ export const favoriteCell = style({ flexShrink: 0, opacity: 0, selectors: { - [`&[data-favorite], ${pageItemRoot}:hover &, ${collectionItemRoot}:hover &, ${tagItemRoot}:hover &`]: + [`&[data-favorite], ${collectionItemRoot}:hover &, ${tagItemRoot}:hover &`]: { opacity: 1, }, diff --git a/packages/frontend/core/src/components/page-list/list.tsx b/packages/frontend/core/src/components/page-list/list.tsx index 1bd155d45..cba1612ca 100644 --- a/packages/frontend/core/src/components/page-list/list.tsx +++ b/packages/frontend/core/src/components/page-list/list.tsx @@ -1,47 +1,14 @@ -import { Scrollable, useHasScrollTop } from '@affine/component'; -import clsx from 'clsx'; import type { ForwardedRef, PropsWithChildren } from 'react'; -import { - forwardRef, - memo, - useCallback, - useEffect, - useImperativeHandle, -} from 'react'; +import { memo, useEffect, useImperativeHandle } from 'react'; -import { usePageHeaderColsDef } from './header-col-def'; -import * as styles from './list.css'; -import { ItemGroup } from './page-group'; -import { ListTableHeader } from './page-header'; import { - groupsAtom, listPropsAtom, - ListProvider, selectionStateAtom, useAtom, - useAtomValue, useSetAtom, } from './scoped-atoms'; import type { ItemListHandle, ListItem, ListProps } from './types'; -/** - * Given a list of pages, render a list of pages - */ -export const List = forwardRef>( - function List(props, ref) { - return ( - // push pageListProps to the atom so that downstream components can consume it - // this makes sure pageListPropsAtom is always populated - // @ts-expect-error jotai-scope is not well typed, AnyWritableAtom is should be any rather than unknown - - - - - - ); - } -); - // when pressing ESC or double clicking outside of the page list, close the selection mode // TODO(@Peng): use jotai-effect instead but it seems it does not work with jotai-scope? const useItemSelectionStateEffect = () => { @@ -132,58 +99,3 @@ export const ListInnerWrapper = memo( ); ListInnerWrapper.displayName = 'ListInnerWrapper'; - -const ListInner = (props: ListProps) => { - const groups = useAtomValue(groupsAtom); - const pageHeaderColsDef = usePageHeaderColsDef(); - const hideHeader = props.hideHeader; - return ( -
- {!hideHeader ? : null} -
- {groups.map(group => ( - - ))} -
-
- ); -}; - -interface ListScrollContainerProps { - className?: string; - style?: React.CSSProperties; -} - -export const ListScrollContainer = forwardRef< - HTMLDivElement, - PropsWithChildren ->(({ className, children, style }, ref) => { - const [setContainer, hasScrollTop] = useHasScrollTop(); - - const setNodeRef = useCallback( - (r: HTMLDivElement) => { - if (ref) { - if (typeof ref === 'function') { - ref(r); - } else { - ref.current = r; - } - } - return setContainer(r); - }, - [ref, setContainer] - ); - - return ( - - {children} - - - ); -}); - -ListScrollContainer.displayName = 'ListScrollContainer'; diff --git a/packages/frontend/core/src/components/page-list/page-group.tsx b/packages/frontend/core/src/components/page-list/page-group.tsx index 4379392a5..460d2102d 100644 --- a/packages/frontend/core/src/components/page-list/page-group.tsx +++ b/packages/frontend/core/src/components/page-list/page-group.tsx @@ -1,23 +1,15 @@ import { shallowEqual } from '@affine/component'; import type { CollectionMeta } from '@affine/core/modules/collection'; -import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta'; import { useI18n } from '@affine/i18n'; -import type { DocMeta } from '@blocksuite/affine/store'; import { ToggleRightIcon, ViewLayersIcon } from '@blocksuite/icons/rc'; -import * as Collapsible from '@radix-ui/react-collapsible'; -import { useLiveData, useService } from '@toeverything/infra'; -import clsx from 'clsx'; import { selectAtom } from 'jotai/utils'; import type { MouseEventHandler } from 'react'; -import { memo, useCallback, useMemo, useState } from 'react'; +import { memo, useCallback, useMemo } from 'react'; import { CollectionListItem } from './collections/collection-list-item'; -import { PageListItem } from './docs/page-list-item'; -import { PagePreview } from './page-content-preview'; import * as styles from './page-group.css'; import { groupCollapseStateAtom, - groupsAtom, listPropsAtom, selectionStateAtom, useAtom, @@ -29,7 +21,6 @@ import type { ItemGroupProps, ListItem, ListProps, - PageListItemProps, TagListItemProps, TagMeta, } from './types'; @@ -111,82 +102,6 @@ export const ItemGroupHeader = memo(function ItemGroupHeader< ) : null; }); -export const ItemGroup = ({ - id, - items, - label, -}: ItemGroupProps) => { - const [collapsed, setCollapsed] = useState(false); - const onExpandedClicked: MouseEventHandler = useCallback(e => { - e.stopPropagation(); - e.preventDefault(); - setCollapsed(v => !v); - }, []); - const selectionState = useAtomValue(selectionStateAtom); - const selectedItems = useMemo(() => { - const selectedIds = selectionState.selectedIds ?? []; - return items.filter(item => selectedIds.includes(item.id)); - }, [items, selectionState.selectedIds]); - const onSelectAll = useCallback(() => { - const nonCurrentGroupIds = - selectionState.selectedIds?.filter( - id => !items.map(item => item.id).includes(id) - ) ?? []; - - selectionState.onSelectedIdsChange?.([ - ...nonCurrentGroupIds, - ...items.map(item => item.id), - ]); - }, [items, selectionState]); - const t = useI18n(); - return ( - - {label ? ( -
- - - -
{label}
- {selectionState.selectionActive ? ( -
- {selectedItems.length}/{items.length} -
- ) : null} -
- {selectionState.selectionActive ? ( - - ) : null} -
- ) : null} - -
- {items.map(item => ( - - ))} -
-
- - ); -}; - // TODO(@Peng): optimize how to render page meta list item const requiredPropNames = [ 'docCollection', @@ -214,30 +129,6 @@ const listsPropsAtom = selectAtom( shallowEqual ); -export const PageListItemRenderer = memo(function PageListItemRenderer( - item: ListItem -) { - const props = useAtomValue(listsPropsAtom); - const { selectionActive } = useAtomValue(selectionStateAtom); - const groups = useAtomValue(groupsAtom); - const pageItems = groups.flatMap(group => group.items).map(item => item.id); - - const page = item as DocMeta; - return ( - - ); -}); - export const CollectionListItemRenderer = memo((item: ListItem) => { const props = useAtomValue(listsPropsAtom); const { selectionActive } = useAtomValue(selectionStateAtom); @@ -270,62 +161,6 @@ export const TagListItemRenderer = memo(function TagListItemRenderer( ); }); -const PageTitle = ({ id }: { id: string }) => { - const i18n = useI18n(); - const docDisplayMetaService = useService(DocDisplayMetaService); - const title = useLiveData(docDisplayMetaService.title$(id)); - return i18n.t(title); -}; - -const UnifiedPageIcon = ({ id }: { id: string }) => { - const docDisplayMetaService = useService(DocDisplayMetaService); - const Icon = useLiveData(docDisplayMetaService.icon$(id)); - return ; -}; - -function pageMetaToListItemProp( - item: DocMeta, - props: RequiredProps, - pageIds?: string[] -): PageListItemProps { - const toggleSelection = props.onSelectedIdsChange - ? () => { - if (!props.selectedIds) { - throw new Error('selectedIds is not found'); - } - const prevSelected = props.selectedIds.includes(item.id); - const shouldAdd = !prevSelected; - const shouldRemove = prevSelected; - - if (shouldAdd) { - props.onSelectedIdsChange?.([...props.selectedIds, item.id]); - } else if (shouldRemove) { - props.onSelectedIdsChange?.( - props.selectedIds.filter(id => id !== item.id) - ); - } - } - : undefined; - const itemProps: PageListItemProps = { - pageId: item.id, - pageIds, - title: , - preview: , - createDate: new Date(item.createDate), - updatedDate: item.updatedDate ? new Date(item.updatedDate) : undefined, - to: props.rowAsLink && !props.selectable ? `/${item.id}` : undefined, - onClick: toggleSelection, - icon: , - operations: props.operationsRenderer?.(item), - selectable: props.selectable, - selected: props.selectedIds?.includes(item.id), - onSelectedChange: toggleSelection, - draggable: props.draggable, - isPublicPage: !!item.isPublic, - }; - return itemProps; -} - function collectionMetaToListItemProp( item: CollectionMeta, props: RequiredProps diff --git a/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page-header.tsx b/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page-header.tsx deleted file mode 100644 index 4385063be..000000000 --- a/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page-header.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { usePageHelper } from '@affine/core/blocksuite/block-suite-page-list/utils'; -import { ExplorerNavigation } from '@affine/core/components/explorer/header/navigation'; -import { - PageDisplayMenu, - PageListNewPageButton, -} from '@affine/core/components/page-list'; -import { Header } from '@affine/core/components/pure/header'; -import { WorkspaceDialogService } from '@affine/core/modules/dialogs'; -import { WorkbenchService } from '@affine/core/modules/workbench'; -import { WorkspaceService } from '@affine/core/modules/workspace'; -import { inferOpenMode } from '@affine/core/utils'; -import { track } from '@affine/track'; -import { PlusIcon } from '@blocksuite/icons/rc'; -import { useServices } from '@toeverything/infra'; -import clsx from 'clsx'; -import { useCallback } from 'react'; - -import * as styles from './all-page.css'; - -export const AllPageHeader = ({ - showCreateNew, -}: { - showCreateNew: boolean; -}) => { - const { workspaceService, workspaceDialogService, workbenchService } = - useServices({ - WorkspaceService, - WorkspaceDialogService, - WorkbenchService, - }); - const workbench = workbenchService.workbench; - const workspace = workspaceService.workspace; - const { createEdgeless, createPage } = usePageHelper(workspace.docCollection); - - const handleOpenDocs = useCallback( - (result: { - docIds: string[]; - entryId?: string; - isWorkspaceFile?: boolean; - }) => { - const { docIds, entryId, isWorkspaceFile } = result; - // If the imported file is a workspace file, open the entry page. - if (isWorkspaceFile && entryId) { - workbench.openDoc(entryId); - } else if (!docIds.length) { - return; - } - // Open all the docs when there are multiple docs imported. - if (docIds.length > 1) { - workbench.openAll(); - } else { - // Otherwise, open the only doc. - workbench.openDoc(docIds[0]); - } - }, - [workbench] - ); - - const onImportFile = useCallback(() => { - track.$.header.importModal.open(); - workspaceDialogService.open('import', undefined, payload => { - if (!payload) { - return; - } - handleOpenDocs(payload); - }); - }, [workspaceDialogService, handleOpenDocs]); - - return ( -
} - right={ - <> - createEdgeless({ at: inferOpenMode(e) })} - onCreatePage={e => createPage('page', { at: inferOpenMode(e) })} - onCreateDoc={e => createPage(undefined, { at: inferOpenMode(e) })} - onImportFile={onImportFile} - > - - - - - } - /> - ); -}; diff --git a/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page.css.ts b/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page.css.ts deleted file mode 100644 index e4c9de056..000000000 --- a/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page.css.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { style } from '@vanilla-extract/css'; -export const scrollContainer = style({ - flex: 1, - width: '100%', - paddingBottom: '32px', -}); -export const headerCreateNewButton = style({ - transition: 'opacity 0.1s ease-in-out', - marginRight: 16, -}); - -export const headerCreateNewCollectionIconButton = style({ - padding: '4px 8px', - fontSize: '16px', - width: '32px', - height: '28px', - borderRadius: '8px', -}); -export const headerCreateNewButtonHidden = style({ - opacity: 0, - pointerEvents: 'none', -}); - -export const body = style({ - display: 'flex', - flexDirection: 'column', - flex: 1, - height: '100%', - width: '100%', -}); diff --git a/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page.tsx b/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page.tsx deleted file mode 100644 index 0d6def4c9..000000000 --- a/packages/frontend/core/src/desktop/pages/workspace/all-page-old/all-page.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { useBlockSuiteDocMeta } from '@affine/core/components/hooks/use-block-suite-page-meta'; -import { - PageListHeader, - VirtualizedPageList, -} from '@affine/core/components/page-list'; -import { GlobalContextService } from '@affine/core/modules/global-context'; -import { IntegrationService } from '@affine/core/modules/integration'; -import { WorkspacePermissionService } from '@affine/core/modules/permissions'; -import { WorkspaceService } from '@affine/core/modules/workspace'; -import { useI18n } from '@affine/i18n'; -import { useLiveData, useService } from '@toeverything/infra'; -import { useEffect, useMemo, useState } from 'react'; - -import { - useIsActiveView, - ViewBody, - ViewHeader, - ViewIcon, - ViewTitle, -} from '../../../../modules/workbench'; -import { AllDocSidebarTabs } from '../layouts/all-doc-sidebar-tabs'; -import { EmptyPageList } from '../page-list-empty'; -import * as styles from './all-page.css'; -import { AllPageHeader } from './all-page-header'; - -export const AllPage = () => { - const currentWorkspace = useService(WorkspaceService).workspace; - const globalContext = useService(GlobalContextService).globalContext; - const permissionService = useService(WorkspacePermissionService); - const integrationService = useService(IntegrationService); - const pageMetas = useBlockSuiteDocMeta(currentWorkspace.docCollection); - const [hideHeaderCreateNew, setHideHeaderCreateNew] = useState(true); - const isAdmin = useLiveData(permissionService.permission.isAdmin$); - const isOwner = useLiveData(permissionService.permission.isOwner$); - const importing = useLiveData(integrationService.importing$); - - const filteredPageMetas = useMemo( - () => pageMetas.filter(page => !page.trash), - [pageMetas] - ); - - const isActiveView = useIsActiveView(); - - useEffect(() => { - if (isActiveView) { - globalContext.isAllDocs.set(true); - - return () => { - globalContext.isAllDocs.set(false); - }; - } - return; - }, [globalContext, isActiveView]); - - const t = useI18n(); - - if (importing) { - return null; - } - - return ( - <> - - - - - - -
- {filteredPageMetas.length > 0 ? ( - - ) : ( - } /> - )} -
-
- - - ); -}; - -export const Component = () => { - return ; -}; diff --git a/packages/frontend/core/src/desktop/workbench-router.ts b/packages/frontend/core/src/desktop/workbench-router.ts index 98d823e53..f4f962374 100644 --- a/packages/frontend/core/src/desktop/workbench-router.ts +++ b/packages/frontend/core/src/desktop/workbench-router.ts @@ -5,10 +5,6 @@ export const workbenchRoutes = [ path: '/all', lazy: () => import('./pages/workspace/all-page/all-page'), }, - { - path: '/all-old', - lazy: () => import('./pages/workspace/all-page-old/all-page'), - }, { path: '/collection', lazy: () => import('./pages/workspace/all-collection'),