mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-18 23:07:02 +08:00
Merge branch 'master' of github.com:toeverything/AFFiNE into fix/downhill-bugs
This commit is contained in:
@@ -7,6 +7,21 @@ if (process.env.NODE_ENV === 'development' || process.env.COVERAGE === 'true') {
|
||||
plugins.push('istanbul');
|
||||
}
|
||||
|
||||
plugins.push([
|
||||
'@emotion',
|
||||
{
|
||||
// See https://emotion.sh/docs/@emotion/babel-plugin
|
||||
importMap: {
|
||||
'@/styles': {
|
||||
styled: {
|
||||
canonicalImport: ['@emotion/styled', 'default'],
|
||||
styledBaseImport: ['@/styles', 'styled'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
module.exports = {
|
||||
presets: ['next/babel'],
|
||||
plugins,
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
"dependencies": {
|
||||
"@affine/datacenter": "workspace:*",
|
||||
"@affine/i18n": "workspace:*",
|
||||
"@blocksuite/blocks": "0.4.0-20230203030233-b22bea7",
|
||||
"@blocksuite/editor": "0.4.0-20230203030233-b22bea7",
|
||||
"@blocksuite/blocks": "0.4.0-alpha.2",
|
||||
"@blocksuite/editor": "0.4.0-alpha.2",
|
||||
"@blocksuite/icons": "^2.0.2",
|
||||
"@blocksuite/store": "0.4.0-20230203030233-b22bea7",
|
||||
"@blocksuite/store": "0.4.0-alpha.2",
|
||||
"@emotion/css": "^11.10.0",
|
||||
"@emotion/react": "^11.10.4",
|
||||
"@emotion/server": "^11.10.0",
|
||||
@@ -28,7 +28,7 @@
|
||||
"cmdk": "^0.1.20",
|
||||
"css-spring": "^4.1.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"lit": "^2.3.1",
|
||||
"lit": "^2.6.1",
|
||||
"next": "13.1.0",
|
||||
"next-debug-local": "^0.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
@@ -36,9 +36,10 @@
|
||||
"quill-cursors": "^4.0.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"yjs": "^13.5.44"
|
||||
"yjs": "^13.5.45"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@emotion/babel-plugin": "^11.10.5",
|
||||
"@types/node": "18.7.18",
|
||||
"@types/react": "18.0.20",
|
||||
"@types/react-dom": "18.0.6",
|
||||
@@ -50,7 +51,7 @@
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"next-pwa": "^5.6.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"typescript": "4.8.3"
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
||||
@@ -7,7 +7,7 @@ export const NotfoundPage = () => {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<PageContainer>
|
||||
<NotFoundTitle>
|
||||
<NotFoundTitle data-testid="notFound">
|
||||
{t('404 - Page Not Found')}
|
||||
<p>
|
||||
<Button
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { PropsWithChildren, ReactNode } from 'react';
|
||||
import Header from './Header';
|
||||
import QuickSearchButton from './QuickSearchButton';
|
||||
import { StyledPageListTittleWrapper } from './styles';
|
||||
// import QuickSearchButton from './QuickSearchButton';
|
||||
|
||||
@@ -12,7 +13,7 @@ export const PageListHeader = ({ icon, children }: PageListHeaderProps) => {
|
||||
<StyledPageListTittleWrapper>
|
||||
{icon}
|
||||
{children}
|
||||
{/* <QuickSearchButton style={{ marginLeft: '5px' }} /> */}
|
||||
<QuickSearchButton />
|
||||
</StyledPageListTittleWrapper>
|
||||
</Header>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,6 @@ export const PageListEmpty = (props: { listType?: string }) => {
|
||||
{listType === 'all' && <p>{t('emptyAllPages')}</p>}
|
||||
{listType === 'favorite' && <p>{t('emptyFavourite')}</p>}
|
||||
{listType === 'trash' && <p>{t('emptyTrash')}</p>}
|
||||
<p>{t('still designed')}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
import React from 'react';
|
||||
import { AddIcon } from '@blocksuite/icons';
|
||||
import { StyledModalFooterContent } from './style';
|
||||
import { useModal } from '@/providers/GlobalModalProvider';
|
||||
import { Command } from 'cmdk';
|
||||
import { usePageHelper } from '@/hooks/use-page-helper';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
export const Footer = (props: { query: string }) => {
|
||||
const { triggerQuickSearchModal } = useModal();
|
||||
export const Footer = (props: { query: string; onClose: () => void }) => {
|
||||
const { openPage, createPage } = usePageHelper();
|
||||
const { t } = useTranslation();
|
||||
const query = props.query;
|
||||
const { query, onClose } = props;
|
||||
|
||||
return (
|
||||
<Command.Item
|
||||
data-testid="quickSearch-addNewPage"
|
||||
onSelect={async () => {
|
||||
onClose();
|
||||
const pageId = await createPage({ title: query });
|
||||
if (pageId) {
|
||||
openPage(pageId);
|
||||
}
|
||||
|
||||
triggerQuickSearchModal();
|
||||
}}
|
||||
>
|
||||
<StyledModalFooterContent>
|
||||
|
||||
@@ -28,12 +28,9 @@ export const Input = (props: {
|
||||
},
|
||||
true
|
||||
);
|
||||
setInputValue(props.query);
|
||||
return inputRef.current?.focus();
|
||||
}, [inputRef]);
|
||||
useEffect(() => {
|
||||
return setInputValue(props.query);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [inputRef, props.query]);
|
||||
return (
|
||||
<StyledInputContent>
|
||||
<StyledLabel htmlFor=":r5:">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Command } from 'cmdk';
|
||||
import { StyledListItem, StyledNotFound } from './style';
|
||||
import { useModal } from '@/providers/GlobalModalProvider';
|
||||
import { PaperIcon, EdgelessIcon } from '@blocksuite/icons';
|
||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||
import { useAppState } from '@/providers/app-state-provider';
|
||||
@@ -12,14 +11,11 @@ import usePageHelper from '@/hooks/use-page-helper';
|
||||
export const Results = (props: {
|
||||
query: string;
|
||||
loading: boolean;
|
||||
onClose: () => void;
|
||||
setLoading: Dispatch<SetStateAction<boolean>>;
|
||||
setShowCreatePage: Dispatch<SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const query = props.query;
|
||||
const loading = props.loading;
|
||||
const setLoading = props.setLoading;
|
||||
const setShowCreatePage = props.setShowCreatePage;
|
||||
const { triggerQuickSearchModal } = useModal();
|
||||
const { query, loading, setLoading, setShowCreatePage, onClose } = props;
|
||||
const { openPage } = usePageHelper();
|
||||
const router = useRouter();
|
||||
const { currentWorkspace, pageList } = useAppState();
|
||||
@@ -55,8 +51,8 @@ export const Results = (props: {
|
||||
<Command.Item
|
||||
key={result.id}
|
||||
onSelect={() => {
|
||||
onClose();
|
||||
openPage(result.id);
|
||||
triggerQuickSearchModal();
|
||||
}}
|
||||
value={result.id}
|
||||
>
|
||||
@@ -86,8 +82,8 @@ export const Results = (props: {
|
||||
key={link.title}
|
||||
value={link.title}
|
||||
onSelect={() => {
|
||||
onClose();
|
||||
router.push(link.href);
|
||||
triggerQuickSearchModal();
|
||||
}}
|
||||
>
|
||||
<StyledListItem>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { FC, SVGProps } from 'react';
|
||||
import { AllPagesIcon, FavouritesIcon, TrashIcon } from '@blocksuite/icons';
|
||||
import {
|
||||
AllPagesIcon,
|
||||
FavouritesIcon,
|
||||
TrashIcon,
|
||||
SettingsIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import { useTranslation } from '@affine/i18n';
|
||||
|
||||
export const useSwitchToConfig = (
|
||||
@@ -23,6 +28,13 @@ export const useSwitchToConfig = (
|
||||
: '',
|
||||
icon: FavouritesIcon,
|
||||
},
|
||||
{
|
||||
title: t('Settings'),
|
||||
href: currentWorkspaceId
|
||||
? `/workspace/${currentWorkspaceId}/setting`
|
||||
: '',
|
||||
icon: SettingsIcon,
|
||||
},
|
||||
{
|
||||
title: t('Trash'),
|
||||
href: currentWorkspaceId ? `/workspace/${currentWorkspaceId}/trash` : '',
|
||||
|
||||
@@ -31,11 +31,16 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
const [showCreatePage, setShowCreatePage] = useState(true);
|
||||
const { triggerQuickSearchModal } = useModal();
|
||||
|
||||
const handleClose = () => {
|
||||
setQuery('');
|
||||
onClose();
|
||||
};
|
||||
// Add ‘⌘+K’ shortcut keys as switches
|
||||
useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if ((e.key === 'k' && e.metaKey) || (e.key === 'k' && e.ctrlKey)) {
|
||||
const selection = window.getSelection();
|
||||
setQuery('');
|
||||
if (selection?.toString()) {
|
||||
triggerQuickSearchModal(false);
|
||||
return;
|
||||
@@ -45,9 +50,6 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!open) {
|
||||
setQuery('');
|
||||
}
|
||||
document.addEventListener('keydown', down, { capture: true });
|
||||
return () =>
|
||||
document.removeEventListener('keydown', down, { capture: true });
|
||||
@@ -64,7 +66,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
onClose={handleClose}
|
||||
wrapperPosition={['top', 'center']}
|
||||
data-testid="quickSearch"
|
||||
>
|
||||
@@ -108,6 +110,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
query={query}
|
||||
loading={loading}
|
||||
setLoading={setLoading}
|
||||
onClose={handleClose}
|
||||
setShowCreatePage={setShowCreatePage}
|
||||
/>
|
||||
) : (
|
||||
@@ -115,7 +118,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
query={query}
|
||||
loading={loading}
|
||||
setLoading={setLoading}
|
||||
onClose={onClose}
|
||||
onClose={handleClose}
|
||||
setPublishWorkspaceName={setPublishWorkspaceName}
|
||||
/>
|
||||
)}
|
||||
@@ -125,7 +128,7 @@ export const QuickSearch = ({ open, onClose }: TransitionsModalProps) => {
|
||||
<>
|
||||
<StyledModalDivider />
|
||||
<StyledModalFooter>
|
||||
<Footer query={query} />
|
||||
<Footer query={query} onClose={handleClose} />
|
||||
</StyledModalFooter>
|
||||
</>
|
||||
) : null
|
||||
|
||||
@@ -23,6 +23,7 @@ export const WorkspaceCard = ({
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<StyledCard
|
||||
data-testid="workspace-card"
|
||||
onClick={() => {
|
||||
onClick(workspaceData);
|
||||
}}
|
||||
|
||||
@@ -32,7 +32,6 @@ import { EnableWorkspaceButton } from '@/components/enable-workspace';
|
||||
export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||
const [isInviteModalShow, setIsInviteModalShow] = useState(false);
|
||||
const { members, removeMember, loaded } = useMembers();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { confirm } = useConfirm();
|
||||
|
||||
@@ -94,41 +93,45 @@ export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||
: t('Pending')}
|
||||
</StyledMemberRoleContainer>
|
||||
<StyledMoreVerticalButton>
|
||||
<Menu
|
||||
content={
|
||||
<>
|
||||
<MenuItem
|
||||
onClick={async () => {
|
||||
const confirmRemove = await confirm({
|
||||
title: t('Delete Member?'),
|
||||
content: t('will delete member'),
|
||||
confirmText: t('Delete'),
|
||||
confirmType: 'danger',
|
||||
});
|
||||
{member.type === 99 ? (
|
||||
<></>
|
||||
) : (
|
||||
<Menu
|
||||
content={
|
||||
<>
|
||||
<MenuItem
|
||||
onClick={async () => {
|
||||
const confirmRemove = await confirm({
|
||||
title: t('Delete Member?'),
|
||||
content: t('will delete member'),
|
||||
confirmText: t('Delete'),
|
||||
confirmType: 'danger',
|
||||
});
|
||||
|
||||
if (!confirmRemove) {
|
||||
return;
|
||||
}
|
||||
await removeMember(member.id);
|
||||
toast(
|
||||
t('Member has been removed', {
|
||||
name: user.name,
|
||||
})
|
||||
);
|
||||
}}
|
||||
icon={<TrashIcon />}
|
||||
>
|
||||
{t('Delete')}
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
placement="bottom-end"
|
||||
disablePortal={true}
|
||||
>
|
||||
<IconButton>
|
||||
<MoreVerticalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
if (!confirmRemove) {
|
||||
return;
|
||||
}
|
||||
await removeMember(member.id);
|
||||
toast(
|
||||
t('Member has been removed', {
|
||||
name: user.name,
|
||||
})
|
||||
);
|
||||
}}
|
||||
icon={<TrashIcon />}
|
||||
>
|
||||
{t('Delete')}
|
||||
</MenuItem>
|
||||
</>
|
||||
}
|
||||
placement="bottom-end"
|
||||
disablePortal={true}
|
||||
>
|
||||
<IconButton>
|
||||
<MoreVerticalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
)}
|
||||
</StyledMoreVerticalButton>
|
||||
</StyledMemberListItem>
|
||||
);
|
||||
|
||||
@@ -32,13 +32,13 @@ export const WorkspaceSelector = () => {
|
||||
>
|
||||
<WorkspaceUnitAvatar
|
||||
size={28}
|
||||
name={currentWorkspace?.name ?? 'AFFiNE'}
|
||||
name={currentWorkspace?.name ?? 'AFFiNE Test'}
|
||||
workspaceUnit={currentWorkspace}
|
||||
/>
|
||||
</div>
|
||||
</Avatar>
|
||||
<WorkspaceName data-testid="workspace-name">
|
||||
{currentWorkspace?.name ?? 'AFFiNE'}
|
||||
{currentWorkspace?.name ?? 'AFFiNE Test'}
|
||||
</WorkspaceName>
|
||||
</SelectorWrapper>
|
||||
<WorkspaceModal
|
||||
|
||||
@@ -67,8 +67,8 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => {
|
||||
};
|
||||
|
||||
const AppDefender = ({ children }: PropsWithChildren) => {
|
||||
const { synced } = useAppState();
|
||||
const router = useRouter();
|
||||
const { synced } = useAppState();
|
||||
|
||||
useEffect(() => {
|
||||
if (router.asPath === '/') {
|
||||
@@ -76,6 +76,11 @@ const AppDefender = ({ children }: PropsWithChildren) => {
|
||||
}
|
||||
}, [router]);
|
||||
|
||||
// if you visit /404, you will see the children directly
|
||||
if (router.route === '/404') {
|
||||
return <div>{children}</div>;
|
||||
}
|
||||
|
||||
return <div>{synced ? children : <PageLoading />}</div>;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DataCenter } from '@affine/datacenter';
|
||||
|
||||
const DEFAULT_WORKSPACE_NAME = 'AFFINE Test';
|
||||
const DEFAULT_WORKSPACE_NAME = 'AFFiNE Test';
|
||||
|
||||
export const createDefaultWorkspace = async (dataCenter: DataCenter) => {
|
||||
return dataCenter.createWorkspace({
|
||||
|
||||
Reference in New Issue
Block a user