refactor: remove unused code (#2484)

This commit is contained in:
Himself65
2023-05-22 17:11:18 +08:00
committed by himself65
parent 2c0f799bc7
commit 0e3d80940e
31 changed files with 44 additions and 1505 deletions
@@ -1,2 +0,0 @@
export * from './pinboard-menu';
export * from './pinboard-render/';
@@ -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;
@@ -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>
</>
);
};
@@ -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>
);
};
@@ -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;
@@ -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;
@@ -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>
);
};
@@ -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',
},
};
});