Merge branch 'feat/filesystem_and_search' of github.com:toeverything/AFFiNE into feat/filesystem_and_search

This commit is contained in:
DiamondThree
2022-12-19 17:50:52 +08:00
27 changed files with 3857 additions and 1284 deletions
+44 -3
View File
@@ -13,6 +13,9 @@ import {
ExportToHtmlIcon,
ExportToMarkdownIcon,
MoreVerticalIcon,
FavouritesIcon,
FavouritedIcon,
TrashIcon,
} from '@blocksuite/icons';
import { useEditor } from '@/providers/editor-provider';
import ThemeModeSwitch from '@/components/theme-mode-switch';
@@ -22,15 +25,37 @@ import { getWarningMessage, shouldShowWarning } from './utils';
import { Menu, MenuItem } from '@/ui/menu';
import { useRouter } from 'next/router';
import { useConfirm } from '@/providers/confirm-provider';
import { useModal } from '@/providers/global-modal-provider';
import { useAppState } from '@/providers/app-state-provider';
import { SyncIcon } from './sync-icon';
import { toast } from '@/components/toast';
const PopoverContent = () => {
const { editor, mode, setMode } = useEditor();
const {
editor,
mode,
setMode,
getPageMeta,
page,
toggleFavoritePage,
toggleDeletePage,
} = useEditor();
const { confirm } = useConfirm();
const { id, favorite, title } = getPageMeta(page?.id) ?? {
id: '',
favorite: false,
title: '',
};
return (
<>
<MenuItem
onClick={() => {
toggleFavoritePage(id);
}}
icon={favorite ? <FavouritedIcon /> : <FavouritesIcon />}
>
{favorite ? 'Remove' : 'Add'} to favourites
</MenuItem>
<MenuItem
icon={mode === 'page' ? <EdgelessIcon /> : <PaperIcon />}
onClick={() => {
@@ -66,6 +91,22 @@ const PopoverContent = () => {
Export
</MenuItem>
</Menu>
<MenuItem
onClick={() => {
confirm({
title: 'Delete page?',
content: `${title || 'Untitled'} will be moved to Trash`,
confirmText: 'Delete',
confirmType: 'danger',
}).then(confirm => {
confirm && toggleDeletePage(id);
toast('Moved to Trash');
});
}}
icon={<TrashIcon />}
>
Delete
</MenuItem>
</>
);
};
@@ -11,8 +11,9 @@ export const QuickSearchButton = ({
const { triggerQuickSearchModal } = useModal();
return (
<Tooltip content="Search and quickly jump to a page" placement="bottom">
<Tooltip content="Switch to" placement="bottom">
<IconButton
data-testid="header-quickSearchButton"
{...props}
onClick={e => {
onClick?.(e);
+39 -17
View File
@@ -6,7 +6,6 @@ import {
EdgelessIcon,
} from '@blocksuite/icons';
import {
StyledFavoriteButton,
StyledTableContainer,
StyledTableRow,
StyledTitleLink,
@@ -18,19 +17,31 @@ import Empty from './empty';
import { Content } from '@/ui/layout';
import React from 'react';
import DateCell from '@/components/page-list/date-cell';
const FavoriteTag = ({ pageMeta }: { pageMeta: PageMeta }) => {
import { IconButton } from '@/ui/button';
import { Tooltip } from '@/ui/tooltip';
import { router } from 'next/client';
const FavoriteTag = ({
pageMeta: { favorite, id },
}: {
pageMeta: PageMeta;
}) => {
const { toggleFavoritePage } = useEditor();
return (
<StyledFavoriteButton
className="favorite-button"
favorite={pageMeta.favorite}
onClick={() => {
toggleFavoritePage(pageMeta.id);
}}
<Tooltip
content={favorite ? 'Favourited' : 'Favourite'}
placement="top-start"
>
{pageMeta.favorite ? <FavouritedIcon /> : <FavouritesIcon />}
</StyledFavoriteButton>
<IconButton
darker={true}
iconSize={[20, 20]}
onClick={e => {
e.stopPropagation();
toggleFavoritePage(id);
}}
>
{favorite ? <FavouritedIcon /> : <FavouritesIcon />}
</IconButton>
</Tooltip>
);
};
@@ -52,7 +63,7 @@ export const PageList = ({
<Table>
<TableHead>
<TableRow>
<TableCell proportion={0.5}>Documents</TableCell>
<TableCell proportion={0.5}>Title</TableCell>
<TableCell proportion={0.2}>Created</TableCell>
<TableCell proportion={0.2}>
{isTrash ? 'Moved to Trash' : 'Updated'}
@@ -63,12 +74,18 @@ export const PageList = ({
<TableBody>
{pageList.map((pageMeta, index) => {
return (
<StyledTableRow key={`${pageMeta.id}-${index}`}>
<StyledTableRow
key={`${pageMeta.id}-${index}`}
onClick={() => {
router.push({
pathname: '/',
query: { pageId: pageMeta.id },
});
}}
>
<TableCell>
<StyledTitleWrapper>
<StyledTitleLink
href={{ pathname: '/', query: { pageId: pageMeta.id } }}
>
<StyledTitleLink>
{pageMeta.mode === 'edgeless' ? (
<EdgelessIcon />
) : (
@@ -87,7 +104,12 @@ export const PageList = ({
dateKey={isTrash ? 'trashDate' : 'updatedDate'}
backupKey={isTrash ? 'trashDate' : 'createDate'}
/>
<TableCell style={{ padding: 0 }}>
<TableCell
style={{ padding: 0 }}
onClick={e => {
e.stopPropagation();
}}
>
{isTrash ? (
<TrashOperationCell pageMeta={pageMeta} />
) : (
@@ -12,7 +12,7 @@ import {
OpenInNewIcon,
TrashIcon,
} from '@blocksuite/icons';
import React from 'react';
import { toast } from '@/components/toast';
export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
const { id, favorite } = pageMeta;
@@ -41,11 +41,12 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
onClick={() => {
confirm({
title: 'Delete page?',
content: `${pageMeta.title} will be moved to Trash`,
content: `${pageMeta.title || 'Untitled'} will be moved to Trash`,
confirmText: 'Delete',
confirmType: 'danger',
}).then(confirm => {
confirm && toggleDeletePage(id);
toast('Moved to Trash');
});
}}
icon={<TrashIcon />}
@@ -57,7 +58,7 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
return (
<Wrapper alignItems="center" justifyContent="center">
<Menu content={OperationMenu} placement="bottom-end" disablePortal={true}>
<IconButton hoverBackground="#E0E6FF">
<IconButton darker={true}>
<MoreVerticalIcon />
</IconButton>
</Menu>
@@ -67,31 +68,34 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
export const TrashOperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
const { id } = pageMeta;
const { permanentlyDeletePage, toggleDeletePage } = useEditor();
const { permanentlyDeletePage, toggleDeletePage, openPage, getPageMeta } =
useEditor();
const { confirm } = useConfirm();
return (
<Wrapper>
<IconButton
hoverBackground="#E0E6FF"
darker={true}
style={{ marginRight: '12px' }}
onClick={() => {
toggleDeletePage(id);
toast(`${getPageMeta(id)?.title || 'Untitled'} restored`);
openPage(id);
}}
>
<RestoreIcon />
</IconButton>
<IconButton
hoverBackground="#E0E6FF"
darker={true}
onClick={() => {
confirm({
title: 'Permanently delete',
content:
"Once deleted, you can't undo this action. Do you confirm?",
title: 'Delete permanently?',
content: "Once deleted, you can't undo this action.",
confirmText: 'Delete',
confirmType: 'danger',
}).then(confirm => {
confirm && permanentlyDeletePage(id);
toast('Permanently deleted');
});
}}
>
@@ -23,7 +23,7 @@ export const StyledTitleWrapper = styled.div(({ theme }) => {
},
};
});
export const StyledTitleLink = styled(Link)(({ theme }) => {
export const StyledTitleLink = styled.div(({ theme }) => {
return {
maxWidth: '80%',
marginRight: '18px',
@@ -34,31 +34,12 @@ export const StyledTitleLink = styled(Link)(({ theme }) => {
marginRight: '12px',
color: theme.colors.iconColor,
},
':hover': {
color: theme.colors.textColor,
'>svg': {
color: theme.colors.primaryColor,
},
},
};
});
export const StyledFavoriteButton = styled.button<{ favorite: boolean }>(
({ theme, favorite }) => {
return {
width: '32px',
height: '32px',
justifyContent: 'center',
alignItems: 'center',
display: 'none',
color: favorite ? theme.colors.primaryColor : theme.colors.iconColor,
'&:hover': {
color: theme.colors.primaryColor,
},
};
}
);
export const StyledTableRow = styled(TableRow)(({ theme }) => {
return {
cursor: 'pointer',
'&:hover': {
'.favorite-button': {
display: 'flex',
@@ -12,6 +12,7 @@ export const Footer = (props: { query: string }) => {
return (
<Command.Item
data-testid="quickSearch-addNewPage"
onSelect={async () => {
const page = await createPage({ title: query });
openPage(page.id);
@@ -48,7 +48,12 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
}, [open, triggerQuickSearchModal]);
return (
<Modal open={open} onClose={onClose} wrapperPosition={['top', 'center']}>
<Modal
open={open}
onClose={onClose}
wrapperPosition={['top', 'center']}
data-testid="quickSearch"
>
<ModalWrapper
width={620}
style={{
@@ -70,7 +70,7 @@ export const Results = (props: {
</StyledNotFound>
)
) : (
<Command.Group heading="Jump to">
<Command.Group heading="Switch to">
{List.map(link => {
return (
<Command.Item
@@ -37,10 +37,10 @@ export const StyledJumpTo = styled('div')(({ theme }) => {
});
export const StyledNotFound = styled('div')(({ theme }) => {
return {
width: '620px',
width: '612px',
...displayFlex('center', 'center'),
flexDirection: 'column',
padding: '10px 16px',
padding: '5px 16px',
fontSize: theme.font.sm,
span: {
width: '100%',
@@ -1,3 +1,4 @@
import { useRouter } from 'next/router';
import { styled } from '@/styles';
import {
WorkspaceItemAvatar,
@@ -13,9 +14,15 @@ interface WorkspaceItemProps {
icon: string;
}
export const WorkspaceItem = ({ name, icon }: WorkspaceItemProps) => {
export const WorkspaceItem = ({ id, name, icon }: WorkspaceItemProps) => {
const router = useRouter();
return (
<StyledWrapper>
<StyledWrapper
onClick={() => {
router.push(`/workspace/${id}`);
}}
>
<WorkspaceItemAvatar alt={name} src={icon}>
{name.charAt(0)}
</WorkspaceItemAvatar>
@@ -8,6 +8,7 @@ export const WorkspaceSelector = () => {
content={<SelectorPopperContent />}
zIndex={1000}
placement="bottom-start"
trigger="hover"
>
<SelectorWrapper>
<Avatar alt="Affine" />
@@ -19,6 +19,7 @@ import {
ImportIcon,
TrashIcon,
AddIcon,
FavouritedIcon,
} from '@blocksuite/icons';
import Link from 'next/link';
import { Tooltip } from '@/ui/tooltip';
@@ -74,15 +75,14 @@ export const WorkSpaceSliderBar = () => {
<StyledListItemForWorkspace>
<WorkspaceSelector />
</StyledListItemForWorkspace>
<Tooltip content="Search and quickly jump to a page" placement="right">
<StyledListItem
onClick={() => {
triggerQuickSearchModal();
}}
>
<SearchIcon /> Quick search
</StyledListItem>
</Tooltip>
<StyledListItem
data-testid="sliderBar-quickSearchButton"
onClick={() => {
triggerQuickSearchModal();
}}
>
<SearchIcon /> Quick search
</StyledListItem>
<Link href={{ pathname: '/page-list/all' }}>
<StyledListItem active={router.pathname === '/page-list/all'}>
<AllPagesIcon /> <span>All pages</span>
@@ -94,7 +94,7 @@ export const WorkSpaceSliderBar = () => {
Favourites
</StyledLink>
<IconButton
hoverBackground="#E0E6FF"
darker={true}
onClick={() => {
setShowSubFavorite(!showSubFavorite);
}}
@@ -108,13 +108,16 @@ export const WorkSpaceSliderBar = () => {
</StyledListItem>
<FavoriteList showList={showSubFavorite} />
<StyledListItem
onClick={() => {
triggerImportModal();
}}
>
<ImportIcon /> Import
</StyledListItem>
<Tooltip content="Coming soon" placement="right-start" zIndex={9999}>
<StyledListItem
disabled={true}
onClick={() => {
// triggerImportModal();
}}
>
<ImportIcon /> Import
</StyledListItem>
</Tooltip>
<Link href={{ pathname: '/page-list/trash' }}>
<StyledListItem active={router.pathname === '/page-list/trash'}>
@@ -136,6 +139,7 @@ export const WorkSpaceSliderBar = () => {
visible={showTip}
>
<StyledArrowButton
data-testid="sliderBar-arrowButton"
isShow={show}
onClick={() => {
setShow(!show);
@@ -43,29 +43,33 @@ export const StyledArrowButton = styled.button<{ isShow: boolean }>(
}
);
export const StyledListItem = styled.button<{ active?: boolean }>(
({ theme, active }) => {
return {
width: '296px',
height: '32px',
marginTop: '12px',
fontSize: theme.font.sm,
color: active ? theme.colors.primaryColor : theme.colors.popoverColor,
backgroundColor: active ? theme.colors.hoverBackground : 'unset',
paddingLeft: '12px',
borderRadius: '5px',
...displayFlex('flex-start', 'center'),
'>svg': {
fontSize: '20px',
marginRight: '12px',
},
':hover': {
color: theme.colors.primaryColor,
backgroundColor: theme.colors.hoverBackground,
},
};
}
);
export const StyledListItem = styled.button<{
active?: boolean;
disabled?: boolean;
}>(({ theme, active, disabled }) => {
return {
width: '296px',
height: '32px',
marginTop: '12px',
fontSize: theme.font.sm,
color: active ? theme.colors.primaryColor : theme.colors.popoverColor,
paddingLeft: '12px',
borderRadius: '5px',
...displayFlex('flex-start', 'center'),
...(disabled
? { cursor: 'not-allowed', color: theme.colors.borderColor }
: {}),
'>svg': {
fontSize: '20px',
marginRight: '12px',
},
':hover:not([disabled])': {
color: theme.colors.primaryColor,
backgroundColor: theme.colors.hoverBackground,
},
};
});
export const StyledListItemForWorkspace = styled(StyledListItem)({
height: '52px',