refactor: remove unused code (#2484)

This commit is contained in:
Himself65 2023-05-22 17:11:18 +08:00 committed by GitHub
parent 281a068cfb
commit f01997f8ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 44 additions and 1505 deletions

View File

@ -81,7 +81,7 @@ export const LocalPlugin: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
Provider: ({ children }) => {
return <>{children}</>;
},
PageDetail: ({ currentWorkspace, currentPageId }) => {
PageDetail: ({ currentWorkspace, currentPageId, onLoadEditor }) => {
const page = currentWorkspace.blockSuiteWorkspace.getPage(currentPageId);
if (!page) {
throw new PageNotFoundError(
@ -94,6 +94,7 @@ export const LocalPlugin: WorkspaceAdapter<WorkspaceFlavour.LOCAL> = {
<PageDetailEditor
pageId={currentPageId}
onInit={initPage}
onLoad={onLoadEditor}
workspace={currentWorkspace}
/>
</>

View File

@ -36,6 +36,7 @@ const Editor: React.FC<{
globalThis.page = page;
// @ts-ignore
globalThis.editor = editor;
return () => void 0;
}, []);
if (!page) {

View File

@ -1,2 +0,0 @@
export * from './pinboard-menu';
export * from './pinboard-render/';

View File

@ -1,133 +0,0 @@
import type { PureMenuProps } from '@affine/component';
import { Input, PureMenu, TreeView } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { RemoveIcon, SearchIcon } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store';
import React, { useCallback, useMemo, useState } from 'react';
import { useReferenceLinkHelper } from '../../../../hooks/affine/use-reference-link-helper';
import { usePinboardData } from '../../../../hooks/use-pinboard-data';
import { usePinboardHandler } from '../../../../hooks/use-pinboard-handler';
import type { BlockSuiteWorkspace } from '../../../../shared';
import { toast } from '../../../../utils';
import { PinboardRender } from '../pinboard-render/';
import {
StyledMenuContent,
StyledMenuFooter,
StyledMenuSubTitle,
StyledPinboard,
StyledSearchContainer,
} from '../styles';
import { SearchContent } from './search-content';
export interface PinboardMenuProps extends PureMenuProps {
metas: PageMeta[];
currentMeta: PageMeta;
blockSuiteWorkspace: BlockSuiteWorkspace;
showRemovePinboard?: boolean;
onPinboardClick?: (p: { dragId: string; dropId: string }) => void;
}
export const PinboardMenu = ({
metas: propsMetas,
currentMeta,
blockSuiteWorkspace,
showRemovePinboard = false,
onPinboardClick,
...pureMenuProps
}: PinboardMenuProps) => {
const metas = useMemo(
() => propsMetas.filter(m => m.id !== currentMeta.id),
[currentMeta.id, propsMetas]
);
const t = useAFFiNEI18N();
const [query, setQuery] = useState('');
const isSearching = query.length > 0;
const searchResult = metas.filter(
meta => !meta.trash && meta.title.includes(query)
);
const { removeReferenceLink } = useReferenceLinkHelper(blockSuiteWorkspace);
const { dropPin } = usePinboardHandler({
blockSuiteWorkspace,
metas,
});
const handleClick = useCallback(
(dropId: string) => {
const targetTitle = metas.find(m => m.id === dropId)?.title;
dropPin(currentMeta.id, dropId, {
bottomLine: false,
topLine: false,
internal: true,
});
onPinboardClick?.({ dragId: currentMeta.id, dropId });
toast(`Moved "${currentMeta.title}" to "${targetTitle}"`);
},
[currentMeta.id, currentMeta.title, dropPin, metas, onPinboardClick]
);
const { data } = usePinboardData({
metas,
pinboardRender: PinboardRender,
blockSuiteWorkspace,
onClick: (e, node) => {
handleClick(node.id);
},
});
return (
<PureMenu
width={320}
height={480}
{...pureMenuProps}
data-testid="pinboard-menu"
>
<StyledSearchContainer>
<label>
<SearchIcon />
</label>
<Input
value={query}
onChange={setQuery}
placeholder={t['Move page to']()}
height={32}
noBorder={true}
onClick={e => e.stopPropagation()}
data-testid="pinboard-menu-search"
/>
</StyledSearchContainer>
<StyledMenuContent>
{isSearching && (
<SearchContent results={searchResult} onClick={handleClick} />
)}
{!isSearching && (
<>
<StyledMenuSubTitle>Suggested</StyledMenuSubTitle>
<TreeView data={data} indent={16} enableDnd={false} />
</>
)}
</StyledMenuContent>
{showRemovePinboard && (
<StyledMenuFooter>
<StyledPinboard
data-testid={'remove-from-pinboard-button'}
onClick={() => {
removeReferenceLink(currentMeta.id);
}}
>
<RemoveIcon />
{t['Remove from Pivots']()}
</StyledPinboard>
<p>{t['RFP']()}</p>
</StyledMenuFooter>
)}
</PureMenu>
);
};
export default PinboardMenu;

View File

@ -1,63 +0,0 @@
import { FlexWrapper } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store';
import { useAtomValue } from 'jotai';
import Image from 'next/legacy/image';
import React from 'react';
import { workspacePreferredModeAtom } from '../../../../atoms';
import { StyledMenuSubTitle, StyledPinboard } from '../styles';
export const SearchContent = ({
results,
onClick,
}: {
results: PageMeta[];
onClick?: (dropId: string) => void;
}) => {
const t = useAFFiNEI18N();
const record = useAtomValue(workspacePreferredModeAtom);
if (results.length) {
return (
<>
<StyledMenuSubTitle>
{t['Find results']({ number: `${results.length}` })}
</StyledMenuSubTitle>
{results.map(meta => {
return (
<StyledPinboard
key={meta.id}
onClick={() => {
onClick?.(meta.id);
}}
data-testid="pinboard-search-result"
>
{record[meta.id] === 'edgeless' ? <EdgelessIcon /> : <PageIcon />}
{meta.title}
</StyledPinboard>
);
})}
</>
);
}
return (
<>
<StyledMenuSubTitle>{t['Find 0 result']()}</StyledMenuSubTitle>
<FlexWrapper
alignItems="center"
justifyContent="center"
style={{ marginTop: 20 }}
>
<Image
src="/imgs/no-result.svg"
alt="no result"
width={150}
height={150}
/>
</FlexWrapper>
</>
);
};

View File

@ -1,22 +0,0 @@
import { PlusIcon } from '@blocksuite/icons';
import { StyledOperationButton } from '../styles';
import type { OperationButtonProps } from './operation-button';
export const AddButton = ({
onAdd,
visible,
}: Pick<OperationButtonProps, 'onAdd' | 'visible'>) => {
return (
<StyledOperationButton
visible={visible}
size="small"
onClick={e => {
e.stopPropagation();
onAdd();
}}
>
<PlusIcon />
</StyledOperationButton>
);
};

View File

@ -1,14 +0,0 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { StyledPinboard } from '../styles';
export const EmptyItem = () => {
const t = useAFFiNEI18N();
return (
<StyledPinboard disable={true} textWrap={true}>
{t['Organize pages to build knowledge']()}
</StyledPinboard>
);
};
export default EmptyItem;

View File

@ -1,137 +0,0 @@
import { Input } from '@affine/component';
import {
ArrowDownSmallIcon,
EdgelessIcon,
LevelIcon,
PageIcon,
PinboardIcon,
} from '@blocksuite/icons';
import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta';
import { useAtomValue } from 'jotai';
import { useRouter } from 'next/router';
import { useMemo, useState } from 'react';
import { workspacePreferredModeAtom } from '../../../../atoms';
import type { PinboardNode } from '../../../../hooks/use-pinboard-data';
import { StyledCollapsedButton, StyledPinboard } from '../styles';
import { AddButton } from './add-button';
import EmptyItem from './empty-item';
import { OperationButton } from './operation-button';
const getIcon = (type: 'root' | 'edgeless' | 'page') => {
switch (type) {
case 'root':
return <PinboardIcon className="mode-icon" />;
case 'edgeless':
return <EdgelessIcon className="mode-icon" />;
default:
return <PageIcon className="mode-icon" />;
}
};
export const PinboardRender: PinboardNode['render'] = (
node,
{
isOver,
onAdd,
onDelete,
collapsed,
setCollapsed,
isSelected,
disableCollapse,
},
renderProps
) => {
const {
onClick,
showOperationButton = false,
currentMeta,
metas = [],
blockSuiteWorkspace,
asPath,
} = renderProps!;
const record = useAtomValue(workspacePreferredModeAtom);
const { setPageTitle } = usePageMetaHelper(blockSuiteWorkspace);
const router = useRouter();
const [isHover, setIsHover] = useState(false);
const [showRename, setShowRename] = useState(false);
const active = router.query.pageId === node.id;
const isRoot = !!currentMeta.isRootPinboard;
return (
<>
<StyledPinboard
data-testid={`pinboard-${node.id}`}
onClick={e => {
onClick?.(e, node);
}}
onMouseEnter={() => setIsHover(true)}
onMouseLeave={() => setIsHover(false)}
isOver={isOver || isSelected}
active={active}
disableCollapse={!!disableCollapse}
>
{!disableCollapse && (
<StyledCollapsedButton
collapse={collapsed}
show={!!node.children?.length}
onClick={e => {
e.stopPropagation();
setCollapsed(node.id, !collapsed);
}}
>
<ArrowDownSmallIcon />
</StyledCollapsedButton>
)}
{asPath && !isRoot ? <LevelIcon className="path-icon" /> : null}
{getIcon(isRoot ? 'root' : record[node.id])}
{showRename ? (
<Input
data-testid={`pinboard-input-${node.id}`}
value={currentMeta.title || ''}
placeholder="Untitled"
onClick={e => e.stopPropagation()}
height={32}
onBlur={() => {
setShowRename(false);
}}
onChange={value => {
// FIXME: setPageTitle would make input blur, and can't input the Chinese character
setPageTitle(node.id, value);
}}
/>
) : (
<span>{isRoot ? 'Pinboard' : currentMeta.title || 'Untitled'}</span>
)}
{showOperationButton && <AddButton onAdd={onAdd} visible={isHover} />}
{showOperationButton && (
<OperationButton
isRoot={isRoot}
onAdd={onAdd}
onDelete={onDelete}
metas={metas}
currentMeta={currentMeta!}
blockSuiteWorkspace={blockSuiteWorkspace!}
visible={isHover}
onMenuClose={() => setIsHover(false)}
onRename={() => {
setShowRename(true);
setIsHover(false);
}}
/>
)}
</StyledPinboard>
{useMemo(
() =>
isRoot &&
!metas.find(m => (currentMeta.subpageIds ?? []).includes(m.id)),
[currentMeta.subpageIds, isRoot, metas]
) && <EmptyItem />}
</>
);
};
export default PinboardRender;

View File

@ -1,170 +0,0 @@
import { MenuItem, MuiClickAwayListener, PureMenu } from '@affine/component';
import { CopyLink, MoveToTrash } from '@affine/component/page-list';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
MoreVerticalIcon,
MoveToIcon,
PenIcon,
PlusIcon,
} from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store';
import { baseTheme } from '@toeverything/theme';
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 { PinboardMenu } from '../pinboard-menu/';
import { StyledOperationButton } from '../styles';
export type OperationButtonProps = {
isRoot: boolean;
onAdd: () => void;
onDelete: () => void;
metas: PageMeta[];
currentMeta: PageMeta;
blockSuiteWorkspace: BlockSuiteWorkspace;
visible: boolean;
onRename?: () => void;
onMenuClose?: () => void;
};
export const OperationButton = ({
isRoot,
onAdd,
onDelete,
metas,
currentMeta,
blockSuiteWorkspace,
visible,
onMenuClose,
onRename,
}: OperationButtonProps) => {
const t = useAFFiNEI18N();
const timer = useRef<ReturnType<typeof setTimeout>>();
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [operationMenuOpen, setOperationMenuOpen] = useState(false);
const [pinboardMenuOpen, setPinboardMenuOpen] = useState(false);
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
const menuIndex = useMemo(() => parseInt(baseTheme.zIndexModal) + 1, []);
const { removeToTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace);
return (
<MuiClickAwayListener
onClickAway={() => {
setOperationMenuOpen(false);
setPinboardMenuOpen(false);
}}
>
<div
style={{ display: 'flex' }}
onClick={e => {
e.stopPropagation();
}}
onMouseLeave={() => {
timer.current = setTimeout(() => {
setOperationMenuOpen(false);
setPinboardMenuOpen(false);
}, 150);
}}
onMouseEnter={() => {
clearTimeout(timer.current);
}}
>
<StyledOperationButton
data-testid="pinboard-operation-button"
ref={ref => setAnchorEl(ref)}
size="small"
onClick={() => {
setOperationMenuOpen(!operationMenuOpen);
}}
visible={visible}
>
<MoreVerticalIcon />
</StyledOperationButton>
<PureMenu
data-testid="pinboard-operation-menu"
width={256}
anchorEl={anchorEl}
open={operationMenuOpen}
placement="bottom"
zIndex={menuIndex}
>
<MenuItem
data-testid="pinboard-operation-add"
onClick={() => {
onAdd();
setOperationMenuOpen(false);
onMenuClose?.();
}}
icon={<PlusIcon />}
>
{t['Add a subpage inside']()}
</MenuItem>
{!isRoot && (
<MenuItem
data-testid="pinboard-operation-move-to"
onClick={() => {
setOperationMenuOpen(false);
setPinboardMenuOpen(true);
}}
icon={<MoveToIcon />}
>
{t['Move to']()}
</MenuItem>
)}
{!isRoot && (
<MenuItem
data-testid="pinboard-operation-rename"
onClick={() => {
onRename?.();
setOperationMenuOpen(false);
onMenuClose?.();
}}
icon={<PenIcon />}
>
{t['Rename']()}
</MenuItem>
)}
{!isRoot && (
<MoveToTrash
testId="pinboard-operation-move-to-trash"
onItemClick={() => {
setOperationMenuOpen(false);
setConfirmModalOpen(true);
onMenuClose?.();
}}
/>
)}
<CopyLink />
</PureMenu>
<PinboardMenu
anchorEl={anchorEl}
open={pinboardMenuOpen}
placement="bottom"
zIndex={menuIndex}
metas={metas}
currentMeta={currentMeta}
blockSuiteWorkspace={blockSuiteWorkspace}
showRemovePinboard={true}
/>
<MoveToTrash.ConfirmModal
open={confirmModalOpen}
title={currentMeta.title}
onConfirm={() => {
toast(t['Moved to Trash']());
removeToTrash(currentMeta.id);
onDelete();
}}
onCancel={() => {
setConfirmModalOpen(false);
}}
confirmButtonTestId="move-to-trash-confirm"
cancelButtonTestId="move-to-trash-cancel"
/>
</div>
</MuiClickAwayListener>
);
};

View File

@ -1,148 +0,0 @@
import {
displayFlex,
IconButton,
styled,
textEllipsis,
} from '@affine/component';
export const StyledCollapsedButton = styled('button')<{
collapse: boolean;
show?: boolean;
}>(({ collapse, show = true }) => {
return {
width: '16px',
height: '100%',
...displayFlex('center', 'center'),
fontSize: '16px',
position: 'absolute',
left: '0',
top: '0',
bottom: '0',
margin: 'auto',
color: 'var(--affine-icon-color)',
opacity: '.6',
transition: 'opacity .15s ease-in-out',
display: show ? 'flex' : 'none',
svg: {
transform: `rotate(${collapse ? '-90' : '0'}deg)`,
},
':hover': {
opacity: '1',
},
};
});
export const StyledPinboard = styled('div')<{
disable?: boolean;
active?: boolean;
isOver?: boolean;
disableCollapse?: boolean;
textWrap?: boolean;
}>(
({
disableCollapse,
disable = false,
active = false,
isOver,
textWrap = false,
}) => {
return {
width: '100%',
lineHeight: '1.5',
minHeight: '32px',
borderRadius: '8px',
...displayFlex('flex-start', 'center'),
padding: disableCollapse ? '0 5px' : '0 2px 0 16px',
position: 'relative',
color: disable
? 'var(--affine-text-disable-color)'
: active
? 'var(--affine-primary-color)'
: 'var(--affine-text-primary-color)',
cursor: disable ? 'not-allowed' : 'pointer',
background: isOver ? 'rgba(118, 95, 254, 0.06)' : '',
fontSize: 'var(--affine-font-base)',
userSelect: 'none',
...(textWrap
? {
wordBreak: 'break-word',
whiteSpace: 'pre-wrap',
}
: {}),
span: {
flexGrow: '1',
textAlign: 'left',
...textEllipsis(1),
},
'.path-icon': {
fontSize: '16px',
transform: 'translateY(-4px)',
},
'.mode-icon': {
fontSize: '20px',
marginRight: '8px',
flexShrink: '0',
color: active
? 'var(--affine-primary-color)'
: 'var(--affine-icon-color)',
},
':hover': {
backgroundColor: disable ? '' : 'var(--affine-hover-color)',
},
};
}
);
export const StyledOperationButton = styled(IconButton, {
shouldForwardProp: prop => {
return !['visible'].includes(prop as string);
},
})<{ visible: boolean }>(({ visible }) => {
return {
visibility: visible ? 'visible' : 'hidden',
};
});
export const StyledSearchContainer = styled('div')(() => {
return {
width: 'calc(100% - 24px)',
margin: '0 auto',
...displayFlex('flex-start', 'center'),
borderBottom: '1px solid var(--affine-border-color)',
label: {
color: 'var(--affine-icon-color)',
fontSize: '20px',
height: '20px',
},
};
});
export const StyledMenuContent = styled('div')(() => {
return {
height: '266px',
overflow: 'auto',
};
});
export const StyledMenuSubTitle = styled('div')(() => {
return {
color: 'var(--affine-text-secondary-color)',
lineHeight: '36px',
padding: '0 12px',
};
});
export const StyledMenuFooter = styled('div')(() => {
return {
width: 'calc(100% - 24px)',
margin: '0 auto',
borderTop: '1px solid var(--affine-border-color)',
padding: '6px 0',
p: {
paddingLeft: '44px',
color: 'var(--affine-text-secondary-color)',
fontSize: '14px',
},
};
});

View File

@ -108,14 +108,12 @@ const PageMenu = () => {
{mode === 'page' ? t['Edgeless']() : t['Page']()}
</MenuItem>
<Export />
{!pageMeta.isRootPinboard && (
<MoveToTrash
testId="editor-option-menu-delete"
onItemClick={() => {
setOpenConfirm(true);
}}
/>
)}
<MoveToTrash
testId="editor-option-menu-delete"
onItemClick={() => {
setOpenConfirm(true);
}}
/>
<div className={styles.horizontalDividerContainer}>
<div className={styles.horizontalDivider} />
</div>

View File

@ -21,7 +21,7 @@ export type PageDetailEditorProps = {
workspace: AffineOfficialWorkspace;
pageId: string;
onInit: (page: Page, editor: Readonly<EditorContainer>) => void;
onLoad?: (page: Page, editor: EditorContainer) => void;
onLoad?: (page: Page, editor: EditorContainer) => () => void;
header?: React.ReactNode;
};
@ -85,7 +85,10 @@ export const PageDetailEditor: React.FC<PageDetailEditorProps> = ({
updatedDate: Date.now(),
});
localStorage.setItem('last_page_id', page.id);
onLoad?.(page, editor);
if (onLoad) {
return onLoad(page, editor);
}
return () => {};
},
[onLoad, setEditor]
)}

View File

@ -1,166 +0,0 @@
import { IconButton, Tooltip, TreeView } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
ArrowRightSmallIcon,
CollapseIcon,
ExpandIcon,
MoreHorizontalIcon,
} from '@blocksuite/icons';
import type { PageMeta } from '@blocksuite/store';
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
import { useRouter } from 'next/router';
import type { MouseEvent } from 'react';
import { Fragment, useCallback, useMemo, useState } from 'react';
import type { PinboardNode } from '../../../../hooks/use-pinboard-data';
import { usePinboardData } from '../../../../hooks/use-pinboard-data';
import { useRouterHelper } from '../../../../hooks/use-router-helper';
import type { BlockSuiteWorkspace } from '../../../../shared';
import { PinboardRender } from '../../../affine/pinboard';
import {
StyledNavigationPathContainer,
StyledNavPathExtendContainer,
StyledNavPathLink,
} from './styles';
import { calcHowManyPathShouldBeShown, findPath } from './utils';
export const NavigationPath = ({
blockSuiteWorkspace,
pageId: propsPageId,
onJumpToPage,
}: {
blockSuiteWorkspace: BlockSuiteWorkspace;
pageId?: string;
onJumpToPage?: (pageId: string) => void;
}) => {
const metas = useBlockSuitePageMeta(blockSuiteWorkspace);
const router = useRouter();
const t = useAFFiNEI18N();
const [openExtend, setOpenExtend] = useState(false);
const pageId = propsPageId ?? router.query.pageId;
const { jumpToPage } = useRouterHelper(router);
const pathData = useMemo(() => {
const meta = metas.find(m => m.id === pageId);
const path = meta ? findPath(metas, meta) : [];
const actualPath = calcHowManyPathShouldBeShown(path);
return {
hasEllipsis: path.length !== actualPath.length,
path: actualPath,
};
}, [metas, pageId]);
if (pathData.path.length < 2) {
// Means there is no parent page
return null;
}
return (
<>
<StyledNavigationPathContainer data-testid="navigation-path">
{openExtend ? (
<span>{t['Navigation Path']()}</span>
) : (
pathData.path.map((meta, index) => {
const isLast = index === pathData.path.length - 1;
const showEllipsis = pathData.hasEllipsis && index === 1;
return (
<Fragment key={meta.id}>
{showEllipsis && (
<>
<IconButton
size="small"
onClick={() => setOpenExtend(true)}
>
<MoreHorizontalIcon />
</IconButton>
<ArrowRightSmallIcon className="path-arrow" />
</>
)}
<StyledNavPathLink
data-testid="navigation-path-link"
active={isLast}
onClick={() => {
if (isLast) return;
jumpToPage(blockSuiteWorkspace.id, meta.id);
onJumpToPage?.(meta.id);
}}
title={meta.title}
>
{meta.title}
</StyledNavPathLink>
{!isLast && <ArrowRightSmallIcon className="path-arrow" />}
</Fragment>
);
})
)}
<Tooltip
content={
openExtend
? t['Back to Quick Search']()
: t['View Navigation Path']()
}
placement="top"
disablePortal={true}
>
<IconButton
data-testid="navigation-path-expand-btn"
size="small"
className="collapse-btn"
onClick={() => {
setOpenExtend(!openExtend);
}}
>
{openExtend ? <CollapseIcon /> : <ExpandIcon />}
</IconButton>
</Tooltip>
</StyledNavigationPathContainer>
<NavigationPathExtendPanel
open={openExtend}
blockSuiteWorkspace={blockSuiteWorkspace}
metas={metas}
onJumpToPage={onJumpToPage}
/>
</>
);
};
const NavigationPathExtendPanel = ({
open,
metas,
blockSuiteWorkspace,
onJumpToPage,
}: {
open: boolean;
metas: PageMeta[];
blockSuiteWorkspace: BlockSuiteWorkspace;
onJumpToPage?: (pageId: string) => void;
}) => {
const router = useRouter();
const { jumpToPage } = useRouterHelper(router);
const handlePinboardClick = useCallback(
(e: MouseEvent<HTMLDivElement>, node: PinboardNode) => {
jumpToPage(blockSuiteWorkspace.id, node.id);
onJumpToPage?.(node.id);
},
[blockSuiteWorkspace.id, jumpToPage, onJumpToPage]
);
const { data } = usePinboardData({
metas,
pinboardRender: PinboardRender,
blockSuiteWorkspace: blockSuiteWorkspace,
onClick: handlePinboardClick,
asPath: true,
});
return (
<StyledNavPathExtendContainer
show={open}
data-testid="navigation-path-expand-panel"
>
<TreeView data={data} indent={10} disableCollapse={true} />
</StyledNavPathExtendContainer>
);
};

View File

@ -1,63 +0,0 @@
import { displayFlex, styled, textEllipsis } from '@affine/component';
export const StyledNavigationPathContainer = styled('div')(() => {
return {
height: '46px',
...displayFlex('flex-start', 'center'),
background: 'var(--affine-background-secondary-color)',
padding: '0 40px 0 20px',
position: 'relative',
fontSize: 'var(--affine-font-sm)',
zIndex: 2,
'.collapse-btn': {
position: 'absolute',
right: '12px',
top: 0,
bottom: 0,
margin: 'auto',
},
'.path-arrow': {
fontSize: '16px',
color: 'var(--affine-icon-color)',
},
};
});
export const StyledNavPathLink = styled('div')<{ active?: boolean }>(
({ active }) => {
return {
color: active
? 'var(--affine-text-primary-color)'
: 'var(--affine-text-secondary-color)',
cursor: active ? 'auto' : 'pointer',
maxWidth: '160px',
...textEllipsis(1),
padding: '0 4px',
transition: 'background .15s',
':hover': active
? {}
: {
background: 'var(--affine-hover-color)',
borderRadius: '4px',
},
};
}
);
export const StyledNavPathExtendContainer = styled('div')<{ show: boolean }>(
({ show }) => {
return {
position: 'absolute',
left: '0',
top: show ? '0' : '-100%',
zIndex: '1',
height: '100%',
width: '100%',
background: 'var(--affine-background-secondary-color)',
transition: 'top .15s',
fontSize: 'var(--affine-font-sm)',
color: 'var(--affine-text-secondary-color)',
padding: '46px 12px 0 15px',
};
}
);

View File

@ -1,60 +0,0 @@
import type { PageMeta } from '@blocksuite/store';
export function findPath(metas: PageMeta[], meta: PageMeta): PageMeta[] {
function helper(group: PageMeta[]): PageMeta[] {
const last = group[group.length - 1];
const parent = metas.find(m => (m.subpageIds ?? []).includes(last.id));
if (parent) {
return helper([...group, parent]);
}
return group;
}
return helper([meta]).reverse();
}
function getPathItemWidth(content: string) {
// padding is 8px, arrow is 16px, and each char is 10px
// the max width is 160px
const charWidth = 10;
const w = content.length * charWidth + 8 + 16;
return w > 160 ? 160 : w;
}
// XXX: this is a static way to calculate the path width, not get the real width
export function calcHowManyPathShouldBeShown(path: PageMeta[]): PageMeta[] {
if (path.length === 0) {
return [];
}
const first = path[0];
const last = path[path.length - 1];
// 20 is the ellipsis icon width
const maxWidth = 550 - 20;
if (first.id === last.id) {
return [first];
}
function getMiddlePath(restWidth: number, restPath: PageMeta[]): PageMeta[] {
if (restPath.length === 0) {
return [];
}
const last = restPath[restPath.length - 1];
const w = getPathItemWidth(last.title);
if (restWidth - w > 80) {
return [
...getMiddlePath(restWidth - w, restPath.slice(0, restPath.length - 1)),
last,
];
}
return [];
}
return [
first,
...getMiddlePath(
maxWidth - getPathItemWidth(first.title),
path.slice(1, -1)
),
last,
];
}

View File

@ -1,25 +1,5 @@
import type { Page } from '@blocksuite/store';
import type { AllWorkspace } from '../../../shared';
export type FavoriteListProps = {
currentWorkspace: AllWorkspace;
};
export type WorkSpaceSliderBarProps = {
isPublicWorkspace: boolean;
onOpenQuickSearchModal: () => void;
onOpenWorkspaceListModal: () => void;
currentWorkspace: AllWorkspace | null;
currentPageId: string | null;
openPage: (pageId: string) => void;
createPage: () => Page;
currentPath: string;
paths: {
all: (workspaceId: string) => string;
favorite: (workspaceId: string) => string;
trash: (workspaceId: string) => string;
setting: (workspaceId: string) => string;
shared: (workspaceId: string) => string;
};
};

View File

@ -1,64 +0,0 @@
import { TreeView } from '@affine/component';
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
import type { MouseEvent } from 'react';
import { useCallback } from 'react';
import type { PinboardNode } from '../../../hooks/use-pinboard-data';
import { usePinboardData } from '../../../hooks/use-pinboard-data';
import { usePinboardHandler } from '../../../hooks/use-pinboard-handler';
import type { BlockSuiteWorkspace } from '../../../shared';
import { PinboardRender } from '../../affine/pinboard';
export type PinboardProps = {
blockSuiteWorkspace: BlockSuiteWorkspace;
openPage: (pageId: string) => void;
};
/**
* @deprecated
*/
export const Pinboard = ({ blockSuiteWorkspace, openPage }: PinboardProps) => {
const allMetas = useBlockSuitePageMeta(blockSuiteWorkspace);
const handlePinboardClick = useCallback(
(e: MouseEvent<HTMLDivElement>, node: PinboardNode) => {
openPage(node.id);
},
[openPage]
);
const onAdd = useCallback(
(id: string) => {
openPage(id);
},
[openPage]
);
const { data } = usePinboardData({
metas: allMetas,
pinboardRender: PinboardRender,
blockSuiteWorkspace: blockSuiteWorkspace,
onClick: handlePinboardClick,
showOperationButton: true,
});
const { addPin, deletePin, dropPin } = usePinboardHandler({
blockSuiteWorkspace: blockSuiteWorkspace,
metas: allMetas,
onAdd,
});
if (!data.length) {
return null;
}
return (
<div data-testid="sidebar-pinboard-container">
<TreeView
data={data}
onAdd={addPin}
onDelete={deletePin}
onDrop={dropPin}
indent={16}
/>
</div>
);
};
export default Pinboard;

View File

@ -1,42 +0,0 @@
import { useAtomValue } from 'jotai';
import { useEffect } from 'react';
import { currentEditorAtom } from '../../atoms';
export function useReferenceLinkEffect(props?: {
pageLinkClicked?: (params: { pageId: string }) => void;
subpageLinked?: (params: { pageId: string }) => void;
subpageUnlinked?: (params: { pageId: string }) => void;
}) {
const { pageLinkClicked, subpageLinked, subpageUnlinked } = props ?? {};
const editor = useAtomValue(currentEditorAtom);
useEffect(() => {
if (!editor) {
return;
}
const linkClickedDisposable = editor.slots.pageLinkClicked.on(
({ pageId }) => {
pageLinkClicked?.({ pageId });
}
);
// const subpageLinkedDisposable = editor.slots.subpageLinked.on(
// ({ pageId }) => {
// subpageLinked?.({ pageId });
// }
// );
// const subpageUnlinkedDisposable = editor.slots.subpageUnlinked.on(
// ({ pageId }) => {
// subpageUnlinked?.({ pageId });
// }
// );
return () => {
linkClickedDisposable.dispose();
// subpageLinkedDisposable.dispose();
// subpageUnlinkedDisposable.dispose();
};
}, [editor, pageLinkClicked, subpageLinked, subpageUnlinked]);
}

View File

@ -1,92 +0,0 @@
import type { Node } from '@affine/component';
import type { PageMeta } from '@blocksuite/store';
import type { MouseEvent } from 'react';
import { useMemo } from 'react';
import type { BlockSuiteWorkspace } from '../shared';
export type RenderProps = {
blockSuiteWorkspace: BlockSuiteWorkspace;
onClick?: (e: MouseEvent<HTMLDivElement>, node: PinboardNode) => void;
showOperationButton?: boolean;
// If true, the node will be rendered with path icon at start
asPath?: boolean;
};
export type NodeRenderProps = RenderProps & {
metas: PageMeta[];
currentMeta: PageMeta;
};
export type PinboardNode = Node<NodeRenderProps>;
function flattenToTree(
metas: PageMeta[],
pinboardRender: PinboardNode['render'],
renderProps: RenderProps
): PinboardNode[] {
const rootMeta = metas.find(meta => meta.isRootPinboard);
const helper = (internalMetas: PageMeta[]): PinboardNode[] => {
return internalMetas.reduce<PinboardNode[]>(
(returnedMetas, internalMeta) => {
const { subpageIds = [] } = internalMeta;
const childrenMetas = subpageIds
.map(id => metas.find(m => m.id === id)!)
.filter(m => m);
// @ts-ignore
const returnedMeta: PinboardNode = {
...internalMeta,
children: helper(childrenMetas),
render: (node, props) =>
pinboardRender(node, props, {
...renderProps,
currentMeta: internalMeta,
metas,
}),
};
returnedMetas.push(returnedMeta);
return returnedMetas;
},
[]
);
};
// Unreachable code, we have removed the root pinboard
// @ts-expect-error
return helper(rootMeta ? [{ ...rootMeta, renderTopLine: false }] : []);
}
export function usePinboardData({
metas,
pinboardRender,
blockSuiteWorkspace,
onClick,
showOperationButton,
asPath,
}: {
metas: PageMeta[];
pinboardRender: PinboardNode['render'];
} & RenderProps) {
const data = useMemo(
() =>
flattenToTree(metas, pinboardRender, {
blockSuiteWorkspace,
onClick,
showOperationButton,
asPath,
}),
[
asPath,
blockSuiteWorkspace,
metas,
onClick,
pinboardRender,
showOperationButton,
]
);
return {
data,
};
}
export default usePinboardData;

View File

@ -1,138 +0,0 @@
import type { TreeViewProps } from '@affine/component';
import { DebugLogger } from '@affine/debug';
import type { PageMeta } from '@blocksuite/store';
import { nanoid } from '@blocksuite/store';
import { usePageMetaHelper } from '@toeverything/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspaceHelper } from '@toeverything/hooks/use-block-suite-workspace-helper';
import { useCallback, useMemo } from 'react';
import type { BlockSuiteWorkspace } from '../shared';
import { useBlockSuiteMetaHelper } from './affine/use-block-suite-meta-helper';
import { useReferenceLinkHelper } from './affine/use-reference-link-helper';
import type { NodeRenderProps } from './use-pinboard-data';
const logger = new DebugLogger('pinboard');
function findRootIds(metas: PageMeta[], id: string): string[] {
const parentMeta = metas.find(m => m.subpageIds?.includes(id));
if (!parentMeta) {
return [id];
}
return [parentMeta.id, ...findRootIds(metas, parentMeta.id)];
}
export function usePinboardHandler({
blockSuiteWorkspace,
metas: propsMetas,
onAdd,
onDelete,
onDrop,
}: {
blockSuiteWorkspace: BlockSuiteWorkspace;
metas?: PageMeta[];
onAdd?: (addedId: string, parentId: string) => void;
onDelete?: TreeViewProps<NodeRenderProps>['onDelete'];
onDrop?: TreeViewProps<NodeRenderProps>['onDrop'];
}) {
const metas = useMemo(
() => propsMetas || blockSuiteWorkspace.meta.pageMetas || [],
[blockSuiteWorkspace.meta.pageMetas, propsMetas]
);
const { createPage } = useBlockSuiteWorkspaceHelper(blockSuiteWorkspace);
const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
const { removeToTrash: removeToTrashHelper } =
useBlockSuiteMetaHelper(blockSuiteWorkspace);
const { addReferenceLink, removeReferenceLink } =
useReferenceLinkHelper(blockSuiteWorkspace);
const addPin = useCallback(
(parentId: string) => {
const id = nanoid();
createPage(id);
onAdd?.(id, parentId);
addReferenceLink(parentId, id);
},
[addReferenceLink, createPage, onAdd]
);
const deletePin = useCallback(
(deleteId: string) => {
removeToTrashHelper(deleteId);
onDelete?.(deleteId);
},
[removeToTrashHelper, onDelete]
);
const dropPin = useCallback(
(
dragId: string,
dropId: string,
position: {
topLine: boolean;
bottomLine: boolean;
internal: boolean;
}
) => {
if (dragId === dropId) {
return;
}
const dropRootIds = findRootIds(metas, dropId);
if (dropRootIds.includes(dragId)) {
return;
}
logger.info('handleDrop', {
dragId,
dropId,
position,
metas,
});
const { topLine, bottomLine } = position;
const dragParentMeta = metas.find(meta =>
meta.subpageIds?.includes(dragId)
);
if (bottomLine || topLine) {
const insertOffset = bottomLine ? 1 : 0;
const dropParentMeta = metas.find(m => m.subpageIds?.includes(dropId));
if (dropParentMeta?.id === dragParentMeta?.id) {
// same parent, resort node
const newSubpageIds = [...(dragParentMeta?.subpageIds ?? [])];
const deleteIndex = newSubpageIds.findIndex(id => id === dragId);
newSubpageIds.splice(deleteIndex, 1);
const insertIndex =
newSubpageIds.findIndex(id => id === dropId) + insertOffset;
newSubpageIds.splice(insertIndex, 0, dragId);
dragParentMeta &&
setPageMeta(dragParentMeta.id, {
subpageIds: newSubpageIds,
});
return onDrop?.(dragId, dropId, position);
}
// Old parent will delete drag node, new parent will be added
removeReferenceLink(dragId);
dropParentMeta && addReferenceLink(dropParentMeta.id, dragId);
return onDrop?.(dragId, dropId, position);
}
// drop into the node
if (dragParentMeta && dragParentMeta.id === dropId) {
return;
}
if (dragParentMeta) {
removeReferenceLink(dragId);
}
const dropMeta = metas.find(meta => meta.id === dropId)!;
addReferenceLink(dropMeta.id, dragId);
},
[addReferenceLink, metas, onDrop, removeReferenceLink, setPageMeta]
);
return {
dropPin,
addPin,
deletePin,
};
}
export default usePinboardHandler;

View File

@ -287,11 +287,6 @@ export const WorkspaceLayoutInner: FC<PropsWithChildren> = ({ children }) => {
void jumpToPage(currentWorkspace.id, pageId);
}
}
// fixme: pinboard has been removed,
// the related code should be removed in the future.
// no matter the workspace is empty, ensure the root pinboard exists
// ensureRootPinboard(currentWorkspace.blockSuiteWorkspace);
//#endregion
useEffect(() => {

View File

@ -9,7 +9,7 @@ import { useAtom, useAtomValue } from 'jotai';
import Link from 'next/link';
import { useRouter } from 'next/router';
import type { ReactElement } from 'react';
import { Suspense, useCallback, useEffect } from 'react';
import { Suspense, useEffect } from 'react';
import {
publicPageBlockSuiteAtom,
@ -19,7 +19,6 @@ import {
import { PageDetailEditor } from '../../../components/page-detail-editor';
import { WorkspaceAvatar } from '../../../components/pure/footer';
import { PageLoading } from '../../../components/pure/loading';
import { useReferenceLinkEffect } from '../../../hooks/affine/use-reference-link-effect';
import { useRouterHelper } from '../../../hooks/use-router-helper';
import {
PublicQuickSearch,
@ -64,14 +63,6 @@ const PublicWorkspaceDetailPageInner = (): ReactElement => {
}
const router = useRouter();
const { openPage } = useRouterHelper(router);
useReferenceLinkEffect({
pageLinkClicked: useCallback(
({ pageId }: { pageId: string }) => {
return openPage(blockSuiteWorkspace.id, pageId);
},
[blockSuiteWorkspace.id, openPage]
),
});
const t = useAFFiNEI18N();
const [name] = useBlockSuiteWorkspaceName(blockSuiteWorkspace);
const [avatar] = useBlockSuiteWorkspaceAvatarUrl(blockSuiteWorkspace);
@ -86,6 +77,12 @@ const PublicWorkspaceDetailPageInner = (): ReactElement => {
onLoad={(_, editor) => {
const { page } = editor;
page.awarenessStore.setReadonly(page, true);
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => {
return openPage(blockSuiteWorkspace.id, pageId);
});
return () => {
dispose.dispose();
};
}}
onInit={initPage}
header={

View File

@ -4,11 +4,9 @@ import { config } from '@affine/env';
import { Unreachable } from '@affine/env/constant';
import { rootCurrentPageIdAtom } from '@affine/workspace/atom';
import { WorkspaceFlavour } from '@affine/workspace/type';
import type { EditorContainer } from '@blocksuite/editor';
import type { Page } from '@blocksuite/store';
import { assertExists } from '@blocksuite/store';
import {
useBlockSuitePageMeta,
usePageMetaHelper,
} from '@toeverything/hooks/use-block-suite-page-meta';
import { useBlockSuiteWorkspacePage } from '@toeverything/hooks/use-block-suite-workspace-page';
import { useAtomValue } from 'jotai';
import { useRouter } from 'next/router';
@ -17,9 +15,7 @@ import { useCallback, useEffect } from 'react';
import { WorkspaceAdapters } from '../../../adapters/workspace';
import { rootCurrentWorkspaceAtom } from '../../../atoms/root';
import { useReferenceLinkEffect } from '../../../hooks/affine/use-reference-link-effect';
import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace';
import { usePinboardHandler } from '../../../hooks/use-pinboard-handler';
import { useSyncRecentViewsWithRouter } from '../../../hooks/use-recent-views';
import { useRouterHelper } from '../../../hooks/use-router-helper';
import { WorkspaceLayout } from '../../../layouts/workspace-layout';
@ -42,41 +38,19 @@ const WorkspaceDetail: React.FC = () => {
assertExists(currentWorkspace);
assertExists(currentPageId);
const blockSuiteWorkspace = currentWorkspace.blockSuiteWorkspace;
const { setPageMeta, getPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
const { deletePin } = usePinboardHandler({
blockSuiteWorkspace,
metas: useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace),
});
useSyncRecentViewsWithRouter(router, blockSuiteWorkspace);
useReferenceLinkEffect({
pageLinkClicked: useCallback(
({ pageId }: { pageId: string }) => {
assertExists(currentWorkspace);
return openPage(currentWorkspace.id, pageId);
},
[currentWorkspace, openPage]
),
subpageUnlinked: useCallback(
({ pageId }: { pageId: string }) => {
deletePin(pageId);
},
[deletePin]
),
subpageLinked: useCallback(
({ pageId }: { pageId: string }) => {
const meta = currentPageId && getPageMeta(currentPageId);
if (!meta || meta.subpageIds?.includes(pageId)) {
return;
}
setPageMeta(currentPageId, {
subpageIds: [...(meta.subpageIds ?? []), pageId],
});
},
[currentPageId, getPageMeta, setPageMeta]
),
});
const onLoad = useCallback(
(page: Page, editor: EditorContainer) => {
const dispose = editor.slots.pageLinkClicked.on(({ pageId }) => {
return openPage(blockSuiteWorkspace.id, pageId);
});
return () => {
dispose.dispose();
};
},
[blockSuiteWorkspace.id, openPage]
);
useEffect(() => {
if (currentWorkspace) {
@ -90,6 +64,7 @@ const WorkspaceDetail: React.FC = () => {
<PageDetail
currentWorkspace={currentWorkspace}
currentPageId={currentPageId}
onLoadEditor={onLoad}
/>
);
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
@ -99,6 +74,7 @@ const WorkspaceDetail: React.FC = () => {
<PageDetail
currentWorkspace={currentWorkspace}
currentPageId={currentPageId}
onLoadEditor={onLoad}
/>
);
}

View File

@ -21,7 +21,7 @@ export type EditorProps = {
page: Page;
mode: 'page' | 'edgeless';
onInit: (page: Page, editor: Readonly<EditorContainer>) => void;
onLoad?: (page: Page, editor: EditorContainer) => void;
onLoad?: (page: Page, editor: EditorContainer) => () => void;
style?: CSSProperties;
};
@ -67,7 +67,7 @@ const BlockSuiteEditorImpl = (props: EditorProps): ReactElement => {
if (page.root === null) {
props.onInit(page, editor);
}
props.onLoad?.(page, editor);
return props.onLoad?.(page, editor);
}
}, [props.page, props.onInit, props.onLoad, editor, props, page]);

View File

@ -103,9 +103,6 @@ export const toast = (
easing: 'cubic-bezier(0.21, 1.02, 0.73, 1)',
fill: 'forwards' as const,
}; // satisfies KeyframeAnimationOptions;
// FIXME: Vitest not support element.animate,
// can try it in `apps/web/src/components/__tests__/PinBoard.spec.tsx` `delete pivot`
typeof element.animate === 'function' && element.animate(fadeIn, options);
setTimeout(async () => {
if (typeof element.animate !== 'function') return;

View File

@ -1,8 +1,7 @@
import { DebugLogger } from '@affine/debug';
import markdown from '@affine/templates/AFFiNE-beta-0.5.4.md';
import { ContentParser } from '@blocksuite/blocks/content-parser';
import type { Page, Workspace } from '@blocksuite/store';
import { nanoid } from '@blocksuite/store';
import type { Page } from '@blocksuite/store';
declare global {
interface Window {
@ -57,25 +56,3 @@ export function _initPageWithDemoMarkdown(page: Page): void {
contentParser.importMarkdown(demoText, frameId);
page.workspace.setPageMeta(page.id, { title: demoTitle });
}
export function ensureRootPinboard(blockSuiteWorkspace: Workspace) {
const metas = blockSuiteWorkspace.meta.pageMetas;
const rootMeta = metas.find(m => m.isRootPinboard);
if (rootMeta) {
return rootMeta.id;
}
const rootPinboardPage = blockSuiteWorkspace.createPage(nanoid());
const title = `${blockSuiteWorkspace.meta.name}'s Pinboard`;
_initEmptyPage(rootPinboardPage, title);
blockSuiteWorkspace.meta.setPageMeta(rootPinboardPage.id, {
isRootPinboard: true,
title,
});
return rootPinboardPage.id;
}

View File

@ -20,7 +20,6 @@ declare module '@blocksuite/store' {
init?: boolean;
// todo: support `number` in the future
isPublic?: boolean;
isRootPinboard?: boolean;
}
}

View File

@ -1,6 +1,8 @@
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference path='../../../apps/electron/layers/preload/preload.d.ts' />
import type { Workspace as RemoteWorkspace } from '@affine/workspace/affine/api';
import type { EditorContainer } from '@blocksuite/editor';
import type { Page } from '@blocksuite/store';
import type { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
import type { createStore } from 'jotai';
import type { FC, PropsWithChildren } from 'react';
@ -183,6 +185,7 @@ type SettingProps<Flavour extends keyof WorkspaceRegistry> =
type PageDetailProps<Flavour extends keyof WorkspaceRegistry> =
UIBaseProps<Flavour> & {
currentPageId: string;
onLoadEditor: (page: Page, editor: EditorContainer) => () => void;
};
type PageListProps<_Flavour extends keyof WorkspaceRegistry> = {

View File

@ -1,15 +1,7 @@
import type { Page } from '@playwright/test';
import { getMetas } from './utils';
export const webUrl = 'http://localhost:8080';
export async function openHomePage(page: Page) {
await page.goto(webUrl);
}
export async function initHomePageWithPinboard(page: Page) {
await openHomePage(page);
await page.waitForSelector('[data-testid="sidebar-pinboard-container"]');
return (await getMetas(page)).find(m => m.isRootPinboard);
}

View File

@ -47,24 +47,3 @@ export async function clickPageMoreActions(page: Page) {
.getByTestId('editor-option-menu')
.click();
}
/**
* @deprecated
*/
export async function createPinboardPage(
page: Page,
parentId: string,
title: string
) {
await newPage(page);
await page.focus('.affine-default-page-block-title');
await page.type('.affine-default-page-block-title', title, {
delay: 100,
});
await clickPageMoreActions(page);
await page.getByTestId('move-to-menu-item').click();
await page
.getByTestId('pinboard-menu')
.getByTestId(`pinboard-${parentId}`)
.click();
}

View File

@ -2,12 +2,8 @@ import { test } from '@affine-test/kit/playwright';
import { expect, type Page } from '@playwright/test';
import { withCtrlOrMeta } from '../libs/keyboard';
import { initHomePageWithPinboard, openHomePage } from '../libs/load-page';
import {
createPinboardPage,
newPage,
waitMarkdownImported,
} from '../libs/page-logic';
import { openHomePage } from '../libs/load-page';
import { newPage, waitMarkdownImported } from '../libs/page-logic';
const openQuickSearchByShortcut = async (page: Page) =>
await withCtrlOrMeta(page, () => page.keyboard.press('k', { delay: 50 }));
@ -171,12 +167,6 @@ test('Focus title after creating a new page', async ({ page }) => {
await titleIsFocused(page);
});
test.skip('Show navigation path if page is a subpage', async ({ page }) => {
const rootPinboardMeta = await initHomePageWithPinboard(page);
await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
await openQuickSearchByShortcut(page);
expect(await page.getByTestId('navigation-path').count()).toBe(1);
});
test('Not show navigation path if page is not a subpage or current page is not in editor', async ({
page,
}) => {
@ -185,38 +175,3 @@ test('Not show navigation path if page is not a subpage or current page is not i
await openQuickSearchByShortcut(page);
expect(await page.getByTestId('navigation-path').count()).toBe(0);
});
test.skip('Navigation path item click will jump to page, but not current active item', async ({
page,
}) => {
const rootPinboardMeta = await initHomePageWithPinboard(page);
await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
await openQuickSearchByShortcut(page);
const oldUrl = page.url();
expect(
await page.locator('[data-testid="navigation-path-link"]').count()
).toBe(2);
await page.locator('[data-testid="navigation-path-link"]').nth(1).click();
expect(page.url()).toBe(oldUrl);
await page.locator('[data-testid="navigation-path-link"]').nth(0).click();
expect(page.url()).not.toBe(oldUrl);
});
test.skip('Navigation path expand', async ({ page }) => {
//
const rootPinboardMeta = await initHomePageWithPinboard(page);
await createPinboardPage(page, rootPinboardMeta?.id ?? '', 'test1');
await openQuickSearchByShortcut(page);
const top = await page
.getByTestId('navigation-path-expand-panel')
.evaluate(el => {
return window.getComputedStyle(el).getPropertyValue('top');
});
expect(parseInt(top)).toBeLessThan(0);
await page.getByTestId('navigation-path-expand-btn').click();
await page.waitForTimeout(500);
const expandTop = await page
.getByTestId('navigation-path-expand-panel')
.evaluate(el => {
return window.getComputedStyle(el).getPropertyValue('top');
});
expect(expandTop).toBe('0px');
});