mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 01:56:27 +08:00
Merge branch 'develop' into feat/quick-search
This commit is contained in:
@@ -75,16 +75,18 @@ const toolbarList2 = [
|
||||
const UndoRedo = () => {
|
||||
const [canUndo, setCanUndo] = useState(false);
|
||||
const [canRedo, setCanRedo] = useState(false);
|
||||
const { editor } = useEditor();
|
||||
const { currentPage } = useEditor();
|
||||
useEffect(() => {
|
||||
if (!editor) return;
|
||||
const { space } = editor;
|
||||
if (!currentPage) return;
|
||||
|
||||
space.signals.historyUpdated.on(() => {
|
||||
setCanUndo(space.canUndo);
|
||||
setCanRedo(space.canRedo);
|
||||
currentPage.signals.historyUpdated.on(() => {
|
||||
setCanUndo(currentPage.canUndo);
|
||||
setCanRedo(currentPage.canRedo);
|
||||
});
|
||||
}, [editor]);
|
||||
return () => {
|
||||
currentPage.signals.historyUpdated.dispose();
|
||||
};
|
||||
}, [currentPage]);
|
||||
|
||||
return (
|
||||
<StyledToolbarWrapper>
|
||||
@@ -92,7 +94,7 @@ const UndoRedo = () => {
|
||||
<StyledToolbarItem
|
||||
disable={!canUndo}
|
||||
onClick={() => {
|
||||
editor?.space?.undo();
|
||||
currentPage?.undo();
|
||||
}}
|
||||
>
|
||||
<UndoIcon />
|
||||
@@ -102,7 +104,7 @@ const UndoRedo = () => {
|
||||
<StyledToolbarItem
|
||||
disable={!canRedo}
|
||||
onClick={() => {
|
||||
editor?.space?.redo();
|
||||
currentPage?.redo();
|
||||
}}
|
||||
>
|
||||
<RedoIcon />
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './header';
|
||||
export * from './page-header';
|
||||
export { StyledTitle as HeaderWrapper } from './styles';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
|
||||
import { StyledButtonWrapper, StyledTitle } from './styles';
|
||||
import { Button } from '@/ui/button';
|
||||
import { Wrapper } from '@/ui/layout';
|
||||
import { Wrapper, Content } from '@/ui/layout';
|
||||
import { Loading } from '@/components/loading';
|
||||
import { useEffect, useState } from 'react';
|
||||
type ImportModalProps = {
|
||||
@@ -9,21 +9,19 @@ type ImportModalProps = {
|
||||
onClose: () => void;
|
||||
};
|
||||
export const ImportModal = ({ open, onClose }: ImportModalProps) => {
|
||||
const [status, setStatus] = useState<'unImported' | 'importing'>(
|
||||
'unImported'
|
||||
);
|
||||
const [status, setStatus] = useState<'unImported' | 'importing'>('importing');
|
||||
|
||||
useEffect(() => {
|
||||
if (status === 'importing') {
|
||||
setTimeout(() => {
|
||||
setStatus('unImported');
|
||||
}, 3000);
|
||||
}, 1500);
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={onClose}>
|
||||
<ModalWrapper width={460} height={240}>
|
||||
<ModalWrapper width={460} minHeight={240}>
|
||||
<ModalCloseButton onClick={onClose} />
|
||||
<StyledTitle>Import</StyledTitle>
|
||||
|
||||
@@ -47,8 +45,16 @@ export const ImportModal = ({ open, onClose }: ImportModalProps) => {
|
||||
)}
|
||||
|
||||
{status === 'importing' && (
|
||||
<Wrapper justifyContent="center" style={{ marginTop: 22 }}>
|
||||
<Wrapper
|
||||
wrap={true}
|
||||
justifyContent="center"
|
||||
style={{ marginTop: 22, paddingBottom: '32px' }}
|
||||
>
|
||||
<Loading size={25}></Loading>
|
||||
<Content align="center" weight="500">
|
||||
OOOOPS! Sorry forgot to remind you that we are working on the
|
||||
import function
|
||||
</Content>
|
||||
</Wrapper>
|
||||
)}
|
||||
</ModalWrapper>
|
||||
|
||||
@@ -23,8 +23,3 @@ export const StyledButtonWrapper = styled.div(() => {
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledLoadingWrapper = styled.div(() => {
|
||||
return {
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
||||
import dayjs from 'dayjs';
|
||||
import { PageMeta } from '@/providers/editor-provider';
|
||||
import { TableCell } from '@/ui/table';
|
||||
import React from 'react';
|
||||
|
||||
dayjs.extend(localizedFormat);
|
||||
|
||||
export const DateCell = ({
|
||||
pageMeta,
|
||||
dateKey,
|
||||
}: {
|
||||
pageMeta: PageMeta;
|
||||
dateKey: keyof PageMeta;
|
||||
}) => {
|
||||
// dayjs().format('L LT');
|
||||
return (
|
||||
<TableCell ellipsis={true}>
|
||||
{dayjs(pageMeta[dateKey] as string).format('YYYY-MM-DD HH:MM')}
|
||||
</TableCell>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateCell;
|
||||
@@ -12,6 +12,7 @@ import { OperationCell, TrashOperationCell } from './operation-cell';
|
||||
import Empty from './empty';
|
||||
import Link from 'next/link';
|
||||
import React from 'react';
|
||||
import DateCell from '@/components/page-list/date-cell';
|
||||
const FavoriteTag = ({ pageMeta }: { pageMeta: PageMeta }) => {
|
||||
const { toggleFavoritePage } = useEditor();
|
||||
|
||||
@@ -40,6 +41,7 @@ export const PageList = ({
|
||||
if (pageList.length === 0) {
|
||||
return <Empty />;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledTableContainer>
|
||||
<Table>
|
||||
@@ -48,7 +50,7 @@ export const PageList = ({
|
||||
<TableCell proportion={0.5}>Documents</TableCell>
|
||||
<TableCell proportion={0.2}>Created</TableCell>
|
||||
<TableCell proportion={0.2}>
|
||||
{isTrash ? 'Uploaded' : 'Moved to Trash'}
|
||||
{isTrash ? 'Moved to Trash' : 'Uploaded'}
|
||||
</TableCell>
|
||||
<TableCell proportion={0.1}></TableCell>
|
||||
</TableRow>
|
||||
@@ -69,9 +71,12 @@ export const PageList = ({
|
||||
{showFavoriteTag && <FavoriteTag pageMeta={pageMeta} />}
|
||||
</StyledTitleWrapper>
|
||||
</TableCell>
|
||||
<TableCell ellipsis={true}>{pageMeta.createDate}</TableCell>
|
||||
<TableCell ellipsis={true}>{pageMeta.createDate}</TableCell>
|
||||
<TableCell>
|
||||
<DateCell pageMeta={pageMeta} dateKey="createDate" />
|
||||
<DateCell
|
||||
pageMeta={pageMeta}
|
||||
dateKey={isTrash ? 'trashDate' : 'createDate'}
|
||||
/>
|
||||
<TableCell style={{ padding: 0 }}>
|
||||
{isTrash ? (
|
||||
<TrashOperationCell pageMeta={pageMeta} />
|
||||
) : (
|
||||
|
||||
@@ -3,7 +3,15 @@ import { useConfirm } from '@/providers/confirm-provider';
|
||||
import { Menu, MenuItem } from '@/ui/menu';
|
||||
import { Wrapper } from '@/ui/layout';
|
||||
import { IconButton } from '@/ui/button';
|
||||
import { MoreVerticalIcon, RestoreIcon, DeleteIcon } from '@blocksuite/icons';
|
||||
import {
|
||||
MoreVerticalIcon,
|
||||
RestoreIcon,
|
||||
DeleteIcon,
|
||||
FavouritesIcon,
|
||||
FavouritedIcon,
|
||||
OpenInNewIcon,
|
||||
TrashIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import React from 'react';
|
||||
|
||||
export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
|
||||
@@ -17,6 +25,7 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
|
||||
onClick={() => {
|
||||
toggleFavoritePage(id);
|
||||
}}
|
||||
icon={favorite ? <FavouritedIcon /> : <FavouritesIcon />}
|
||||
>
|
||||
{favorite ? 'Remove' : 'Add'} to favourites
|
||||
</MenuItem>
|
||||
@@ -24,6 +33,7 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
|
||||
onClick={() => {
|
||||
openPage(id);
|
||||
}}
|
||||
icon={<OpenInNewIcon />}
|
||||
>
|
||||
Open in new tab
|
||||
</MenuItem>
|
||||
@@ -39,6 +49,7 @@ export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
|
||||
confirm && toggleDeletePage(id);
|
||||
});
|
||||
}}
|
||||
icon={<TrashIcon />}
|
||||
>
|
||||
Delete
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Command, useCommandState } from 'cmdk';
|
||||
|
||||
const NoResult = (props: { query: string }) => {
|
||||
const NoResult = () => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
|
||||
const search = useCommandState(state => state.search);
|
||||
// eslint-disable-next-line react/no-unescaped-entities
|
||||
return <Command.Empty>No results found for "{search}".</Command.Empty>;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ const isMac = () => {
|
||||
export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
const [query, setQuery] = useState('');
|
||||
const { triggerQuickSearchModal } = useModal();
|
||||
|
||||
useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if (e.key === 'k' && e.metaKey) {
|
||||
@@ -38,7 +37,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
};
|
||||
document.addEventListener('keydown', down);
|
||||
return () => document.removeEventListener('keydown', down);
|
||||
}, [open]);
|
||||
}, [open, triggerQuickSearchModal]);
|
||||
return (
|
||||
<Modal open={open} onClose={onClose} wrapperPosition={['top', 'center']}>
|
||||
<ModalWrapper
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import {
|
||||
StyledArrowButton,
|
||||
StyledLink,
|
||||
StyledListItem,
|
||||
StyledNewPageButton,
|
||||
StyledSliderBar,
|
||||
@@ -9,7 +10,15 @@ import {
|
||||
} from './style';
|
||||
import { Arrow } from './icons';
|
||||
import Collapse from '@mui/material/Collapse';
|
||||
import { ArrowDownIcon } from '@blocksuite/icons';
|
||||
import {
|
||||
ArrowDownIcon,
|
||||
SearchIcon,
|
||||
AllPagesIcon,
|
||||
FavouritesIcon,
|
||||
ImportIcon,
|
||||
TrashIcon,
|
||||
AddIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import Link from 'next/link';
|
||||
import { useEditor } from '@/providers/editor-provider';
|
||||
import { useModal } from '@/providers/global-modal-provider';
|
||||
@@ -20,7 +29,7 @@ const FavoriteList = ({ showList }: { showList: boolean }) => {
|
||||
const { pageList, openPage } = useEditor();
|
||||
const router = useRouter();
|
||||
|
||||
const favoriteList = pageList.filter(p => p.favorite);
|
||||
const favoriteList = pageList.filter(p => p.favorite && !p.trash);
|
||||
return (
|
||||
<Collapse in={showList}>
|
||||
{favoriteList.map((pageMeta, index) => {
|
||||
@@ -61,20 +70,18 @@ export const WorkSpaceSliderBar = () => {
|
||||
triggerQuickSearchModal();
|
||||
}}
|
||||
>
|
||||
Quick search
|
||||
<SearchIcon /> Quick search
|
||||
</StyledListItem>
|
||||
<Link href={{ pathname: '/page-list/all' }}>
|
||||
<StyledListItem active={router.pathname === '/page-list/all'}>
|
||||
All pages
|
||||
<AllPagesIcon /> All pages
|
||||
</StyledListItem>
|
||||
</Link>
|
||||
<StyledListItem active={router.pathname === '/page-list/favorite'}>
|
||||
<Link
|
||||
href={{ pathname: '/page-list/favorite' }}
|
||||
style={{ flexGrow: 1, textAlign: 'left', color: 'inherit' }}
|
||||
>
|
||||
<StyledLink href={{ pathname: '/page-list/favorite' }}>
|
||||
<FavouritesIcon />
|
||||
Favourites
|
||||
</Link>
|
||||
</StyledLink>
|
||||
<IconButton
|
||||
hoverBackground="#E0E6FF"
|
||||
onClick={() => {
|
||||
@@ -95,12 +102,12 @@ export const WorkSpaceSliderBar = () => {
|
||||
triggerImportModal();
|
||||
}}
|
||||
>
|
||||
Import
|
||||
<ImportIcon /> Import
|
||||
</StyledListItem>
|
||||
|
||||
<Link href={{ pathname: '/page-list/trash' }}>
|
||||
<StyledListItem active={router.pathname === '/page-list/trash'}>
|
||||
Trash
|
||||
<TrashIcon /> Trash
|
||||
</StyledListItem>
|
||||
</Link>
|
||||
<StyledNewPageButton
|
||||
@@ -110,7 +117,7 @@ export const WorkSpaceSliderBar = () => {
|
||||
pageMeta && openPage(pageMeta.id);
|
||||
}}
|
||||
>
|
||||
New Page
|
||||
<AddIcon /> New Page
|
||||
</StyledNewPageButton>
|
||||
</StyledSliderBar>
|
||||
<StyledArrowButton
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { displayFlex, styled, textEllipsis } from '@/styles';
|
||||
import Link from 'next/link';
|
||||
|
||||
export const StyledSliderBar = styled.div<{ show: boolean }>(
|
||||
({ theme, show }) => {
|
||||
@@ -54,6 +55,10 @@ export const StyledListItem = styled.button<{ active?: boolean }>(
|
||||
paddingLeft: '12px',
|
||||
borderRadius: '5px',
|
||||
...displayFlex('flex-start', 'center'),
|
||||
'>svg': {
|
||||
fontSize: '20px',
|
||||
marginRight: '12px',
|
||||
},
|
||||
':hover': {
|
||||
color: theme.colors.primaryColor,
|
||||
backgroundColor: theme.colors.hoverBackground,
|
||||
@@ -62,6 +67,21 @@ export const StyledListItem = styled.button<{ active?: boolean }>(
|
||||
}
|
||||
);
|
||||
|
||||
export const StyledLink = styled(Link)(({ theme }) => {
|
||||
return {
|
||||
flexGrow: 1,
|
||||
textAlign: 'left',
|
||||
color: 'inherit',
|
||||
...displayFlex('flex-start', 'center'),
|
||||
':visited': {
|
||||
color: 'inherit',
|
||||
},
|
||||
'>svg': {
|
||||
fontSize: '20px',
|
||||
marginRight: '12px',
|
||||
},
|
||||
};
|
||||
});
|
||||
export const StyledNewPageButton = styled(StyledListItem)(({ theme }) => {
|
||||
return {
|
||||
position: 'absolute',
|
||||
|
||||
Reference in New Issue
Block a user