mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 06:16:59 +08:00
Merge branch 'feat/poc' into feat/datacenter
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
|||||||
StyledCloseButton,
|
StyledCloseButton,
|
||||||
} from './styles';
|
} from './styles';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import { getWarningMessage, shouldShowWarning } from './utils';
|
import { useWarningMessage, shouldShowWarning } from './utils';
|
||||||
import EditorOptionMenu from './header-right-items/EditorOptionMenu';
|
import EditorOptionMenu from './header-right-items/EditorOptionMenu';
|
||||||
import TrashButtonGroup from './header-right-items/TrashButtonGroup';
|
import TrashButtonGroup from './header-right-items/TrashButtonGroup';
|
||||||
import ThemeModeSwitch from './header-right-items/theme-mode-switch';
|
import ThemeModeSwitch from './header-right-items/theme-mode-switch';
|
||||||
@@ -22,7 +22,7 @@ const BrowserWarning = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<StyledBrowserWarning show={show}>
|
<StyledBrowserWarning show={show}>
|
||||||
{getWarningMessage()}
|
{useWarningMessage()}
|
||||||
<StyledCloseButton onClick={onClose}>
|
<StyledCloseButton onClick={onClose}>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</StyledCloseButton>
|
</StyledCloseButton>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const QuickSearchButton = ({
|
|||||||
const { triggerQuickSearchModal } = useModal();
|
const { triggerQuickSearchModal } = useModal();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Tooltip content={t('Switch to')} placement="bottom">
|
<Tooltip content={t('Jump to')} placement="bottom">
|
||||||
<StyledIconButtonWithAnimate
|
<StyledIconButtonWithAnimate
|
||||||
data-testid="header-quickSearchButton"
|
data-testid="header-quickSearchButton"
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import getIsMobile from '@/utils/get-is-mobile';
|
import getIsMobile from '@/utils/get-is-mobile';
|
||||||
|
import { Trans, useTranslation } from '@affine/i18n';
|
||||||
// Inspire by https://stackoverflow.com/a/4900484/8415727
|
// Inspire by https://stackoverflow.com/a/4900484/8415727
|
||||||
const getChromeVersion = () => {
|
const getChromeVersion = () => {
|
||||||
const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||||
@@ -19,20 +20,20 @@ export const shouldShowWarning = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getWarningMessage = () => {
|
export const useWarningMessage = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
if (!getIsChrome()) {
|
if (!getIsChrome()) {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
We recommend the <strong>Chrome</strong> browser for optimal experience.
|
<Trans i18nKey="recommendBrowser">
|
||||||
|
We recommend the <strong>Chrome</strong> browser for optimal
|
||||||
|
experience.
|
||||||
|
</Trans>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (getChromeVersion() < minimumChromeVersion) {
|
if (getChromeVersion() < minimumChromeVersion) {
|
||||||
return (
|
return <span>{t('upgradeBrowser')}</span>;
|
||||||
<span>
|
|
||||||
Please upgrade to the latest version of Chrome for the best experience.
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { styled } from '@/styles';
|
import { styled } from '@/styles';
|
||||||
import Loading from './Loading';
|
import Loading from './Loading';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
|
||||||
// Used for the full page loading
|
// Used for the full page loading
|
||||||
const StyledLoadingContainer = styled('div')(() => {
|
const StyledLoadingContainer = styled('div')(() => {
|
||||||
@@ -17,12 +18,13 @@ const StyledLoadingContainer = styled('div')(() => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PageLoading = ({ text = 'Loading...' }: { text?: string }) => {
|
export const PageLoading = ({ text }: { text?: string }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<StyledLoadingContainer>
|
<StyledLoadingContainer>
|
||||||
<div className="wrapper">
|
<div className="wrapper">
|
||||||
<Loading />
|
<Loading />
|
||||||
<h1>{text}</h1>
|
<h1>{text ? text : t('Loading')}</h1>
|
||||||
</div>
|
</div>
|
||||||
</StyledLoadingContainer>
|
</StyledLoadingContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import { styled } from '@/styles';
|
|||||||
import { Button } from '@/ui/button';
|
import { Button } from '@/ui/button';
|
||||||
// import { useModal } from '@/providers/GlobalModalProvider';
|
// import { useModal } from '@/providers/GlobalModalProvider';
|
||||||
import { GoogleIcon, StayLogOutIcon } from './Icons';
|
import { GoogleIcon, StayLogOutIcon } from './Icons';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
export const GoogleLoginButton = () => {
|
export const GoogleLoginButton = () => {
|
||||||
// const { triggerLoginModal } = useModal();
|
// const { triggerLoginModal } = useModal();
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<StyledGoogleButton
|
<StyledGoogleButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -24,8 +25,10 @@ export const GoogleLoginButton = () => {
|
|||||||
<GoogleIcon />
|
<GoogleIcon />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
<TextWrapper>
|
<TextWrapper>
|
||||||
<Title>Continue with Google</Title>
|
<Title>{t('Continue with Google')}</Title>
|
||||||
<Description>Set up an AFFiNE account to sync data</Description>
|
<Description>
|
||||||
|
{t('Set up an AFFiNE account to sync data')}
|
||||||
|
</Description>
|
||||||
</TextWrapper>
|
</TextWrapper>
|
||||||
</ButtonWrapper>
|
</ButtonWrapper>
|
||||||
</StyledGoogleButton>
|
</StyledGoogleButton>
|
||||||
@@ -33,6 +36,7 @@ export const GoogleLoginButton = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const StayLogOutButton = () => {
|
export const StayLogOutButton = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<StyledStayLogOutButton>
|
<StyledStayLogOutButton>
|
||||||
<ButtonWrapper>
|
<ButtonWrapper>
|
||||||
@@ -40,8 +44,8 @@ export const StayLogOutButton = () => {
|
|||||||
<StayLogOutIcon />
|
<StayLogOutIcon />
|
||||||
</IconWrapper>
|
</IconWrapper>
|
||||||
<TextWrapper>
|
<TextWrapper>
|
||||||
<Title>Stay logged out</Title>
|
<Title>{t('Stay logged out')}</Title>
|
||||||
<Description>All changes are saved locally</Description>
|
<Description>{t('All changes are saved locally')}</Description>
|
||||||
</TextWrapper>
|
</TextWrapper>
|
||||||
</ButtonWrapper>
|
</ButtonWrapper>
|
||||||
</StyledStayLogOutButton>
|
</StyledStayLogOutButton>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import { styled } from '@/styles';
|
|||||||
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
|
import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal';
|
||||||
import { TextButton } from '@/ui/button';
|
import { TextButton } from '@/ui/button';
|
||||||
import { GoogleLoginButton, StayLogOutButton } from './LoginOptionButton';
|
import { GoogleLoginButton, StayLogOutButton } from './LoginOptionButton';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
interface LoginModalProps {
|
interface LoginModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LoginModal = ({ open, onClose }: LoginModalProps) => {
|
export const LoginModal = ({ open, onClose }: LoginModalProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Modal open={open} onClose={onClose} data-testid="login-modal">
|
<Modal open={open} onClose={onClose} data-testid="login-modal">
|
||||||
<ModalWrapper width={620} height={334}>
|
<ModalWrapper width={620} height={334}>
|
||||||
@@ -23,12 +24,12 @@ export const LoginModal = ({ open, onClose }: LoginModalProps) => {
|
|||||||
/>
|
/>
|
||||||
</Header>
|
</Header>
|
||||||
<Content>
|
<Content>
|
||||||
<ContentTitle>Currently not logged in</ContentTitle>
|
<ContentTitle>{t('NotLoggedIn')}</ContentTitle>
|
||||||
<GoogleLoginButton />
|
<GoogleLoginButton />
|
||||||
<StayLogOutButton />
|
<StayLogOutButton />
|
||||||
</Content>
|
</Content>
|
||||||
<Footer>
|
<Footer>
|
||||||
<TextButton icon={<StyledResetIcon />}>Clear local data</TextButton>
|
<TextButton icon={<StyledResetIcon />}>{t('ClearData')}</TextButton>
|
||||||
</Footer>
|
</Footer>
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import Modal, { ModalCloseButton, ModalWrapper } from '@/ui/modal';
|
|||||||
import getIsMobile from '@/utils/get-is-mobile';
|
import getIsMobile from '@/utils/get-is-mobile';
|
||||||
import { StyledButton, StyledContent, StyledTitle } from './styles';
|
import { StyledButton, StyledContent, StyledTitle } from './styles';
|
||||||
import bg from './bg.png';
|
import bg from './bg.png';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
export const MobileModal = () => {
|
export const MobileModal = () => {
|
||||||
const [showModal, setShowModal] = useState(getIsMobile());
|
const [showModal, setShowModal] = useState(getIsMobile());
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={showModal}
|
open={showModal}
|
||||||
@@ -25,20 +27,17 @@ export const MobileModal = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StyledTitle>Ooops!</StyledTitle>
|
<StyledTitle>{t('Ooops!')}</StyledTitle>
|
||||||
<StyledContent>
|
<StyledContent>
|
||||||
<p>Looks like you are browsing on a mobile device.</p>
|
<p>{t('mobile device')}</p>
|
||||||
<p>
|
<p>{t('mobile device description')}</p>
|
||||||
We are still working on mobile support and recommend you use a
|
|
||||||
desktop device.
|
|
||||||
</p>
|
|
||||||
</StyledContent>
|
</StyledContent>
|
||||||
<StyledButton
|
<StyledButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Got it
|
{t('Got it')}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Empty } from '@/ui/empty';
|
import { Empty } from '@/ui/empty';
|
||||||
export const PageListEmpty = () => {
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
export const PageListEmpty = (props: { listType?: string }) => {
|
||||||
|
const { listType } = props;
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'center' }}>
|
||||||
<Empty
|
<Empty
|
||||||
@@ -8,8 +11,10 @@ export const PageListEmpty = () => {
|
|||||||
height={300}
|
height={300}
|
||||||
sx={{ marginTop: '100px', marginBottom: '30px' }}
|
sx={{ marginTop: '100px', marginBottom: '30px' }}
|
||||||
/>
|
/>
|
||||||
<p>Tips: Click Add to Favourites/Trash and the page will appear here.</p>
|
{listType === 'all' && <p>{t('emptyAllPages')}</p>}
|
||||||
<p>(Designer is grappling with designing)</p>
|
{listType === 'favorite' && <p>{t('emptyFavourite')}</p>}
|
||||||
|
{listType === 'trash' && <p>{t('emptyTrash')}</p>}
|
||||||
|
<p>{t('still designed')}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -68,17 +68,19 @@ export const PageList = ({
|
|||||||
showFavoriteTag = false,
|
showFavoriteTag = false,
|
||||||
isTrash = false,
|
isTrash = false,
|
||||||
isPublic = false,
|
isPublic = false,
|
||||||
|
listType,
|
||||||
}: {
|
}: {
|
||||||
pageList: PageMeta[];
|
pageList: PageMeta[];
|
||||||
showFavoriteTag?: boolean;
|
showFavoriteTag?: boolean;
|
||||||
isTrash?: boolean;
|
isTrash?: boolean;
|
||||||
isPublic?: boolean;
|
isPublic?: boolean;
|
||||||
|
listType?: 'all' | 'trash' | 'favorite';
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { currentWorkspace } = useAppState();
|
const { currentWorkspace } = useAppState();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
if (pageList.length === 0) {
|
if (pageList.length === 0) {
|
||||||
return <Empty />;
|
return <Empty listType={listType} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { SearchIcon } from '@blocksuite/icons';
|
|||||||
import { StyledInputContent, StyledLabel } from './style';
|
import { StyledInputContent, StyledLabel } from './style';
|
||||||
import { Command } from 'cmdk';
|
import { Command } from 'cmdk';
|
||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useAppState } from '@/providers/app-state-provider';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
export const Input = (props: {
|
export const Input = (props: {
|
||||||
query: string;
|
query: string;
|
||||||
setQuery: Dispatch<SetStateAction<string>>;
|
setQuery: Dispatch<SetStateAction<string>>;
|
||||||
@@ -18,7 +19,7 @@ export const Input = (props: {
|
|||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const { currentWorkspace } = useAppState();
|
const { currentWorkspace } = useAppState();
|
||||||
|
const { t } = useTranslation();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
inputRef.current?.addEventListener(
|
inputRef.current?.addEventListener(
|
||||||
'blur',
|
'blur',
|
||||||
@@ -78,8 +79,10 @@ export const Input = (props: {
|
|||||||
}}
|
}}
|
||||||
placeholder={
|
placeholder={
|
||||||
currentWorkspace?.isPublish
|
currentWorkspace?.isPublish
|
||||||
? `Search in ${currentWorkspace?.blocksuiteWorkspace?.meta.name}`
|
? t('Quick search placeholder2', {
|
||||||
: 'Quick Search...'
|
workspace: currentWorkspace?.blocksuiteWorkspace?.meta.name,
|
||||||
|
})
|
||||||
|
: t('Quick search placeholder')
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</StyledInputContent>
|
</StyledInputContent>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export const Results = (props: {
|
|||||||
</StyledNotFound>
|
</StyledNotFound>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Command.Group heading={t('Switch to')}>
|
<Command.Group heading={t('Jump to')}>
|
||||||
{List.map(link => {
|
{List.map(link => {
|
||||||
return (
|
return (
|
||||||
<Command.Item
|
<Command.Item
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { WorkspaceAvatar } from '@/components/workspace-avatar';
|
|||||||
import { useAppState } from '@/providers/app-state-provider';
|
import { useAppState } from '@/providers/app-state-provider';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useConfirm } from '@/providers/ConfirmProvider';
|
import { useConfirm } from '@/providers/ConfirmProvider';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
|
||||||
interface WorkspaceModalProps {
|
interface WorkspaceModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -26,6 +27,7 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
|
|||||||
const { workspaceList, currentWorkspace, login, user, logout } =
|
const { workspaceList, currentWorkspace, login, user, logout } =
|
||||||
useAppState();
|
useAppState();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Modal open={open} onClose={onClose}>
|
<Modal open={open} onClose={onClose}>
|
||||||
@@ -34,7 +36,7 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
|
|||||||
style={{ padding: '10px', display: 'flex', flexDirection: 'column' }}
|
style={{ padding: '10px', display: 'flex', flexDirection: 'column' }}
|
||||||
>
|
>
|
||||||
<Header>
|
<Header>
|
||||||
<ContentTitle>My Workspaces</ContentTitle>
|
<ContentTitle>{t('My Workspaces')}</ContentTitle>
|
||||||
{/* <LanguageMenu /> */}
|
{/* <LanguageMenu /> */}
|
||||||
<ModalCloseButton
|
<ModalCloseButton
|
||||||
top={6}
|
top={6}
|
||||||
@@ -123,13 +125,13 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
|
|||||||
marginRight: '10px',
|
marginRight: '10px',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
Create Or Import
|
{t('Create Or Import')}
|
||||||
</Button>
|
</Button>
|
||||||
</li>
|
</li>
|
||||||
</WorkspaceList>
|
</WorkspaceList>
|
||||||
<p style={{ fontSize: '14px', color: '#ccc', margin: '12px 0' }}>
|
<p style={{ fontSize: '14px', color: '#ccc', margin: '12px 0' }}>
|
||||||
Tips:Workspace is your virtual space to capture, create and plan
|
{t('Tips')}
|
||||||
as just one person or together as a team.
|
{t('Workspace description')}
|
||||||
</p>
|
</p>
|
||||||
</Content>
|
</Content>
|
||||||
<Footer>
|
<Footer>
|
||||||
@@ -137,10 +139,10 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
|
|||||||
<Button
|
<Button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await login();
|
await login();
|
||||||
toast('Login success');
|
toast(t('login success'));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Sign in AFFiNE Cloud
|
{t('Sign in')}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
@@ -161,7 +163,7 @@ export const WorkspaceModal = ({ open, onClose }: WorkspaceModalProps) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Sign out of AFFiNE Cloud
|
{t('Sign out')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Footer>
|
</Footer>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { styled } from '@/styles';
|
import { styled } from '@/styles';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
|
import { Trans } from '@affine/i18n';
|
||||||
export const ExportPageTitleContainer = styled('div')(() => {
|
export const ExportPageTitleContainer = styled('div')(() => {
|
||||||
return {
|
return {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -12,8 +12,13 @@ export const ExportPageTitleContainer = styled('div')(() => {
|
|||||||
export const ExportPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
export const ExportPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||||
return (
|
return (
|
||||||
<ExportPageTitleContainer>
|
<ExportPageTitleContainer>
|
||||||
Export Workspace{' '}
|
<Trans i18nKey="Export Workspace">
|
||||||
<code style={{ margin: '0 10px' }}>{workspace.name}</code> Is Comming
|
Export Workspace
|
||||||
|
<code style={{ margin: '0 10px' }}>
|
||||||
|
{{ workspace: workspace.name }}
|
||||||
|
</code>
|
||||||
|
Is Comming
|
||||||
|
</Trans>
|
||||||
</ExportPageTitleContainer>
|
</ExportPageTitleContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import { toast } from '@/ui/toast';
|
|||||||
// import { useAppState } from '@/providers/app-state-provider3';
|
// import { useAppState } from '@/providers/app-state-provider3';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
|
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||||
const shareUrl = window.location.host + '/public-workspace/' + workspace.id;
|
const shareUrl = window.location.host + '/public-workspace/' + workspace.id;
|
||||||
const { publishWorkspace, enableWorkspace } = useWorkspaceHelper();
|
const { publishWorkspace, enableWorkspace } = useWorkspaceHelper();
|
||||||
|
const { t } = useTranslation();
|
||||||
const togglePublic = async (flag: boolean) => {
|
const togglePublic = async (flag: boolean) => {
|
||||||
await publishWorkspace(workspace.id.toString(), flag);
|
await publishWorkspace(workspace.id.toString(), flag);
|
||||||
};
|
};
|
||||||
@@ -37,22 +37,21 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
{workspace?.published ? (
|
{workspace?.published ? (
|
||||||
<>
|
<>
|
||||||
<StyledPublishExplanation>
|
<StyledPublishExplanation>
|
||||||
Publishing to web requires AFFiNE Cloud service .
|
{t('Publishing')}
|
||||||
</StyledPublishExplanation>
|
</StyledPublishExplanation>
|
||||||
<StyledSettingH2>Share with link</StyledSettingH2>
|
<StyledSettingH2>{t('Share with link')}</StyledSettingH2>
|
||||||
<StyledPublishCopyContainer>
|
<StyledPublishCopyContainer>
|
||||||
<Input width={500} value={shareUrl} disabled={true}></Input>
|
<Input width={500} value={shareUrl} disabled={true}></Input>
|
||||||
<StyledCopyButtonContainer>
|
<StyledCopyButtonContainer>
|
||||||
<Button onClick={copyUrl} type="primary" shape="circle">
|
<Button onClick={copyUrl} type="primary" shape="circle">
|
||||||
Copy Link
|
{t('Copy Link')}
|
||||||
</Button>
|
</Button>
|
||||||
</StyledCopyButtonContainer>
|
</StyledCopyButtonContainer>
|
||||||
</StyledPublishCopyContainer>
|
</StyledPublishCopyContainer>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<StyledPublishExplanation>
|
<StyledPublishExplanation>
|
||||||
After publishing to the web, everyone can view the content of
|
{'Publishing Description'}
|
||||||
this workspace through the link.
|
|
||||||
</StyledPublishExplanation>
|
</StyledPublishExplanation>
|
||||||
)}
|
)}
|
||||||
</StyledPublishContent>
|
</StyledPublishContent>
|
||||||
@@ -64,7 +63,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
>
|
>
|
||||||
Stop publishing
|
{t('Stop publishing')}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
@@ -74,7 +73,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
>
|
>
|
||||||
Publish to web
|
{t('Publish to web')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -82,7 +81,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
<StyledPublishContent>
|
<StyledPublishContent>
|
||||||
<>
|
<>
|
||||||
<StyledPublishExplanation>
|
<StyledPublishExplanation>
|
||||||
Publishing to web requires AFFiNE Cloud service.
|
{t('Publishing')}
|
||||||
</StyledPublishExplanation>
|
</StyledPublishExplanation>
|
||||||
|
|
||||||
<StyledPublishCopyContainer>
|
<StyledPublishCopyContainer>
|
||||||
@@ -93,7 +92,7 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
>
|
>
|
||||||
Enable AFFiNE Cloud
|
{t('Enable AFFiNE Cloud')}
|
||||||
</Button>
|
</Button>
|
||||||
</StyledPublishCopyContainer>
|
</StyledPublishCopyContainer>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -8,17 +8,19 @@ import { Button } from '@/ui/button';
|
|||||||
import { Menu, MenuItem } from '@/ui/menu';
|
import { Menu, MenuItem } from '@/ui/menu';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
|
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
|
||||||
|
import { Trans, useTranslation } from '@affine/i18n';
|
||||||
export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||||
const { enableWorkspace } = useWorkspaceHelper();
|
const { enableWorkspace } = useWorkspaceHelper();
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<StyledPublishContent>
|
<StyledPublishContent>
|
||||||
{workspace?.provider === 'local' ? (
|
{workspace?.provider === 'local' ? (
|
||||||
<>
|
<>
|
||||||
<StyledPublishExplanation>
|
<StyledPublishExplanation>
|
||||||
{workspace.name ?? 'Affine'} is Local Workspace. All data is
|
{t('Sync Description', {
|
||||||
stored on the current device. You can enable AFFiNE Cloud for this
|
workspaceName: workspace.name ?? 'Affine',
|
||||||
workspace to keep data in sync with the cloud.
|
})}
|
||||||
</StyledPublishExplanation>
|
</StyledPublishExplanation>
|
||||||
|
|
||||||
<StyledPublishCopyContainer>
|
<StyledPublishCopyContainer>
|
||||||
@@ -29,15 +31,18 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
type="primary"
|
type="primary"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
>
|
>
|
||||||
Enable AFFiNE Cloud
|
{t('Enable AFFiNE Cloud')}
|
||||||
</Button>
|
</Button>
|
||||||
</StyledPublishCopyContainer>
|
</StyledPublishCopyContainer>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<StyledPublishExplanation>
|
<StyledPublishExplanation>
|
||||||
<code>{workspace.name ?? 'Affine'}</code> is Cloud Workspace. All
|
<Trans i18nKey="Sync Description2">
|
||||||
data will be synchronized and saved to the AFFiNE
|
<code>{{ workspaceName: workspace.name ?? 'Affine' }}</code>
|
||||||
|
is Cloud Workspace. All data will be synchronised and saved to
|
||||||
|
the AFFiNE
|
||||||
|
</Trans>
|
||||||
</StyledPublishExplanation>
|
</StyledPublishExplanation>
|
||||||
<StyledPublishCopyContainer>
|
<StyledPublishCopyContainer>
|
||||||
<Menu
|
<Menu
|
||||||
@@ -49,7 +54,7 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
}}
|
}}
|
||||||
icon={<DownloadIcon />}
|
icon={<DownloadIcon />}
|
||||||
>
|
>
|
||||||
Download core data to device
|
{t('Download data to device', { CoreOrAll: 'core' })}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -57,14 +62,16 @@ export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
}}
|
}}
|
||||||
icon={<DownloadIcon />}
|
icon={<DownloadIcon />}
|
||||||
>
|
>
|
||||||
Download all data to device
|
{t('Download data to device', { CoreOrAll: 'all' })}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
disablePortal={true}
|
disablePortal={true}
|
||||||
>
|
>
|
||||||
<Button>Download all data to device</Button>
|
<Button>
|
||||||
|
{t('Download data to device', { CoreOrAll: 'all' })}
|
||||||
|
</Button>
|
||||||
</Menu>
|
</Menu>
|
||||||
</StyledPublishCopyContainer>
|
</StyledPublishCopyContainer>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { Upload } from '@/components/file-upload';
|
|||||||
import { WorkspaceAvatar } from '@/components/workspace-avatar';
|
import { WorkspaceAvatar } from '@/components/workspace-avatar';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
|
import { useWorkspaceHelper } from '@/hooks/use-workspace-helper';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
||||||
const [showDelete, setShowDelete] = useState<boolean>(false);
|
const [showDelete, setShowDelete] = useState<boolean>(false);
|
||||||
const [showLeave, setShowLeave] = useState<boolean>(false);
|
const [showLeave, setShowLeave] = useState<boolean>(false);
|
||||||
@@ -23,6 +24,8 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
const [workspaceName, setWorkspaceName] = useState<string>(workspace.name);
|
const [workspaceName, setWorkspaceName] = useState<string>(workspace.name);
|
||||||
const { currentWorkspace } = useAppState();
|
const { currentWorkspace } = useAppState();
|
||||||
const { updateWorkspace } = useWorkspaceHelper();
|
const { updateWorkspace } = useWorkspaceHelper();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const isOwner = true;
|
const isOwner = true;
|
||||||
const handleChangeWorkSpaceName = (newName: string) => {
|
const handleChangeWorkSpaceName = (newName: string) => {
|
||||||
setWorkspaceName(newName);
|
setWorkspaceName(newName);
|
||||||
@@ -56,7 +59,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
|
|
||||||
return workspace ? (
|
return workspace ? (
|
||||||
<div>
|
<div>
|
||||||
<StyledSettingH2 marginTop={56}>Workspace Icon</StyledSettingH2>
|
<StyledSettingH2 marginTop={56}>{t('Workspace Icon')}</StyledSettingH2>
|
||||||
<StyledSettingAvatarContent>
|
<StyledSettingAvatarContent>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -74,16 +77,16 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"
|
accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"
|
||||||
fileChange={fileChange}
|
fileChange={fileChange}
|
||||||
>
|
>
|
||||||
<Button loading={uploading}>Upload</Button>
|
<Button loading={uploading}>{t('Upload')}</Button>
|
||||||
</Upload>
|
</Upload>
|
||||||
{/* TODO: add upload logic */}
|
{/* TODO: add upload logic */}
|
||||||
</StyledSettingAvatarContent>
|
</StyledSettingAvatarContent>
|
||||||
<StyledSettingH2 marginTop={20}>Workspace Name</StyledSettingH2>
|
<StyledSettingH2 marginTop={20}>{t('Workspace Name')}</StyledSettingH2>
|
||||||
<StyledSettingInputContainer>
|
<StyledSettingInputContainer>
|
||||||
<Input
|
<Input
|
||||||
width={327}
|
width={327}
|
||||||
value={workspaceName}
|
value={workspaceName}
|
||||||
placeholder="Workspace Name"
|
placeholder={t('Workspace Name')}
|
||||||
maxLength={14}
|
maxLength={14}
|
||||||
minLength={1}
|
minLength={1}
|
||||||
onChange={handleChangeWorkSpaceName}
|
onChange={handleChangeWorkSpaceName}
|
||||||
@@ -97,7 +100,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
✔️
|
✔️
|
||||||
</TextButton>
|
</TextButton>
|
||||||
</StyledSettingInputContainer>
|
</StyledSettingInputContainer>
|
||||||
<StyledSettingH2 marginTop={20}>Workspace Type</StyledSettingH2>
|
<StyledSettingH2 marginTop={20}>{t('Workspace Type')}</StyledSettingH2>
|
||||||
<StyledSettingInputContainer>
|
<StyledSettingInputContainer>
|
||||||
<code>{workspace.provider} </code>
|
<code>{workspace.provider} </code>
|
||||||
</StyledSettingInputContainer>
|
</StyledSettingInputContainer>
|
||||||
@@ -105,7 +108,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
{isOwner ? (
|
{isOwner ? (
|
||||||
<>
|
<>
|
||||||
<Button type="danger" shape="circle" onClick={handleClickDelete}>
|
<Button type="danger" shape="circle" onClick={handleClickDelete}>
|
||||||
Delete Workspace
|
{t('Delete Workspace')}
|
||||||
</Button>
|
</Button>
|
||||||
<WorkspaceDelete
|
<WorkspaceDelete
|
||||||
open={showDelete}
|
open={showDelete}
|
||||||
@@ -116,7 +119,7 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Button type="danger" shape="circle" onClick={handleClickLeave}>
|
<Button type="danger" shape="circle" onClick={handleClickLeave}>
|
||||||
Leave Workspace
|
{t('Leave Workspace')}
|
||||||
</Button>
|
</Button>
|
||||||
<WorkspaceLeave
|
<WorkspaceLeave
|
||||||
open={showLeave}
|
open={showLeave}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
// Workspace,
|
// Workspace,
|
||||||
} from '@/hooks/mock-data/mock';
|
} from '@/hooks/mock-data/mock';
|
||||||
import { WorkspaceUnit } from '@affine/datacenter';
|
import { WorkspaceUnit } from '@affine/datacenter';
|
||||||
|
import { Trans, useTranslation } from '@affine/i18n';
|
||||||
interface WorkspaceDeleteProps {
|
interface WorkspaceDeleteProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -31,6 +31,7 @@ export const WorkspaceDelete = ({
|
|||||||
workspace,
|
workspace,
|
||||||
}: WorkspaceDeleteProps) => {
|
}: WorkspaceDeleteProps) => {
|
||||||
const [deleteStr, setDeleteStr] = useState<string>('');
|
const [deleteStr, setDeleteStr] = useState<string>('');
|
||||||
|
const { t } = useTranslation();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const handlerInputChange = (workspaceName: string) => {
|
const handlerInputChange = (workspaceName: string) => {
|
||||||
@@ -55,31 +56,40 @@ export const WorkspaceDelete = ({
|
|||||||
<Modal open={open} onClose={onClose}>
|
<Modal open={open} onClose={onClose}>
|
||||||
<StyledModalWrapper>
|
<StyledModalWrapper>
|
||||||
<ModalCloseButton onClick={onClose} />
|
<ModalCloseButton onClick={onClose} />
|
||||||
<StyledModalHeader>Delete Workspace</StyledModalHeader>
|
<StyledModalHeader>{t('Delete Workspace')}</StyledModalHeader>
|
||||||
{workspace.provider === 'local' ? (
|
{workspace.provider === 'local' ? (
|
||||||
<StyledTextContent>
|
<StyledTextContent>
|
||||||
Deleting (
|
<Trans i18nKey="Delete Workspace Description">
|
||||||
<StyledWorkspaceName>{workspace.name}</StyledWorkspaceName>) cannot
|
Deleting (
|
||||||
be undone, please proceed with caution. along with all its content.
|
<StyledWorkspaceName>
|
||||||
|
{{ workspace: workspace.name }}
|
||||||
|
</StyledWorkspaceName>
|
||||||
|
) cannot be undone, please proceed with caution. along with all
|
||||||
|
its content.
|
||||||
|
</Trans>
|
||||||
</StyledTextContent>
|
</StyledTextContent>
|
||||||
) : (
|
) : (
|
||||||
<StyledTextContent>
|
<StyledTextContent>
|
||||||
Deleting (
|
<Trans i18nKey="Delete Workspace Description2">
|
||||||
<StyledWorkspaceName>{workspace.name}</StyledWorkspaceName>) will
|
Deleting (
|
||||||
delete both local and cloud data, this operation cannot be undone,
|
<StyledWorkspaceName>
|
||||||
please proceed with caution.
|
{{ workspace: workspace.name }}
|
||||||
|
</StyledWorkspaceName>
|
||||||
|
) will delete both local and cloud data, this operation cannot be
|
||||||
|
undone, please proceed with caution.
|
||||||
|
</Trans>
|
||||||
</StyledTextContent>
|
</StyledTextContent>
|
||||||
)}
|
)}
|
||||||
<StyledInputContent>
|
<StyledInputContent>
|
||||||
<Input
|
<Input
|
||||||
onChange={handlerInputChange}
|
onChange={handlerInputChange}
|
||||||
placeholder="Please type “Delete” to confirm"
|
placeholder={t('Delete Workspace placeholder')}
|
||||||
value={deleteStr}
|
value={deleteStr}
|
||||||
></Input>
|
></Input>
|
||||||
</StyledInputContent>
|
</StyledInputContent>
|
||||||
<StyledButtonContent>
|
<StyledButtonContent>
|
||||||
<Button shape="circle" onClick={onClose}>
|
<Button shape="circle" onClick={onClose}>
|
||||||
Cancel
|
{t('Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
disabled={deleteStr.toLowerCase() !== 'delete'}
|
disabled={deleteStr.toLowerCase() !== 'delete'}
|
||||||
@@ -88,7 +98,7 @@ export const WorkspaceDelete = ({
|
|||||||
shape="circle"
|
shape="circle"
|
||||||
style={{ marginLeft: '24px' }}
|
style={{ marginLeft: '24px' }}
|
||||||
>
|
>
|
||||||
Delete
|
{t('Delete')}
|
||||||
</Button>
|
</Button>
|
||||||
</StyledButtonContent>
|
</StyledButtonContent>
|
||||||
</StyledModalWrapper>
|
</StyledModalWrapper>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
} from './style';
|
} from './style';
|
||||||
import { ModalCloseButton } from '@/ui/modal';
|
import { ModalCloseButton } from '@/ui/modal';
|
||||||
import { Button } from '@/ui/button';
|
import { Button } from '@/ui/button';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
// import { getDataCenter } from '@affine/datacenter';
|
// import { getDataCenter } from '@affine/datacenter';
|
||||||
// import { useAppState } from '@/providers/app-state-provider';
|
// import { useAppState } from '@/providers/app-state-provider';
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ export const WorkspaceLeave = ({
|
|||||||
onClose,
|
onClose,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
}: WorkspaceDeleteProps) => {
|
}: WorkspaceDeleteProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
console.log('workspaceId: ', workspaceId);
|
console.log('workspaceId: ', workspaceId);
|
||||||
// const router = useRouter();
|
// const router = useRouter();
|
||||||
// const { refreshWorkspacesMeta } = useAppState();
|
// const { refreshWorkspacesMeta } = useAppState();
|
||||||
@@ -37,14 +39,13 @@ export const WorkspaceLeave = ({
|
|||||||
<Modal open={open} onClose={onClose}>
|
<Modal open={open} onClose={onClose}>
|
||||||
<StyledModalWrapper>
|
<StyledModalWrapper>
|
||||||
<ModalCloseButton onClick={onClose} />
|
<ModalCloseButton onClick={onClose} />
|
||||||
<StyledModalHeader>Leave Workspace</StyledModalHeader>
|
<StyledModalHeader>{t('Leave Workspace')}</StyledModalHeader>
|
||||||
<StyledTextContent>
|
<StyledTextContent>
|
||||||
After you leave, you will not be able to access all the contents of
|
{t('Leave Workspace Description')}
|
||||||
this workspace.
|
|
||||||
</StyledTextContent>
|
</StyledTextContent>
|
||||||
<StyledButtonContent>
|
<StyledButtonContent>
|
||||||
<Button shape="circle" onClick={onClose}>
|
<Button shape="circle" onClick={onClose}>
|
||||||
Cancel
|
{t('Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleLeave}
|
onClick={handleLeave}
|
||||||
@@ -52,7 +53,7 @@ export const WorkspaceLeave = ({
|
|||||||
shape="circle"
|
shape="circle"
|
||||||
style={{ marginLeft: '24px' }}
|
style={{ marginLeft: '24px' }}
|
||||||
>
|
>
|
||||||
Leave
|
{t('Leave')}
|
||||||
</Button>
|
</Button>
|
||||||
</StyledButtonContent>
|
</StyledButtonContent>
|
||||||
</StyledModalWrapper>
|
</StyledModalWrapper>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useState } from 'react';
|
|||||||
import { Avatar } from '@mui/material';
|
import { Avatar } from '@mui/material';
|
||||||
import useMembers from '@/hooks/use-members';
|
import useMembers from '@/hooks/use-members';
|
||||||
import { User } from '@affine/datacenter';
|
import { User } from '@affine/datacenter';
|
||||||
|
import { useTranslation } from '@affine/i18n';
|
||||||
interface LoginModalProps {
|
interface LoginModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -53,6 +54,7 @@ export const InviteMemberModal = ({
|
|||||||
const [showTip, setShowTip] = useState<boolean>(false);
|
const [showTip, setShowTip] = useState<boolean>(false);
|
||||||
const [userData, setUserData] = useState<User | null>(null);
|
const [userData, setUserData] = useState<User | null>(null);
|
||||||
const { inviteMember, getUserByEmail } = useMembers();
|
const { inviteMember, getUserByEmail } = useMembers();
|
||||||
|
const { t } = useTranslation();
|
||||||
const inputChange = (value: string) => {
|
const inputChange = (value: string) => {
|
||||||
setShowMember(true);
|
setShowMember(true);
|
||||||
if (gmailReg.test(value)) {
|
if (gmailReg.test(value)) {
|
||||||
@@ -82,7 +84,7 @@ export const InviteMemberModal = ({
|
|||||||
/>
|
/>
|
||||||
</Header>
|
</Header>
|
||||||
<Content>
|
<Content>
|
||||||
<ContentTitle>Invite members</ContentTitle>
|
<ContentTitle>{t('Invite Members')}</ContentTitle>
|
||||||
<InviteBox>
|
<InviteBox>
|
||||||
<Input
|
<Input
|
||||||
width={360}
|
width={360}
|
||||||
@@ -91,12 +93,12 @@ export const InviteMemberModal = ({
|
|||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
setShowMember(false);
|
setShowMember(false);
|
||||||
}}
|
}}
|
||||||
placeholder="Search mail (Gmail support only)"
|
placeholder={t('Invite placeholder')}
|
||||||
></Input>
|
></Input>
|
||||||
{showMember ? (
|
{showMember ? (
|
||||||
<Members>
|
<Members>
|
||||||
{showTip ? (
|
{showTip ? (
|
||||||
<NoFind>Non-Gmail is not supported</NoFind>
|
<NoFind>{t('Non-Gmail')}</NoFind>
|
||||||
) : (
|
) : (
|
||||||
<Member>
|
<Member>
|
||||||
{userData?.avatar ? (
|
{userData?.avatar ? (
|
||||||
@@ -125,7 +127,7 @@ export const InviteMemberModal = ({
|
|||||||
onInviteSuccess();
|
onInviteSuccess();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Invite
|
{t('Invite')}
|
||||||
</Button>
|
</Button>
|
||||||
</Footer>
|
</Footer>
|
||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export const WorkSpaceSliderBar = () => {
|
|||||||
<StyledListItem active={router.asPath === paths.setting}>
|
<StyledListItem active={router.asPath === paths.setting}>
|
||||||
<StyledLink href={{ pathname: paths.setting }}>
|
<StyledLink href={{ pathname: paths.setting }}>
|
||||||
<SettingsIcon />
|
<SettingsIcon />
|
||||||
Settings
|
{t('Settings')}
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
</StyledListItem>
|
</StyledListItem>
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const All = () => {
|
|||||||
<PageList
|
<PageList
|
||||||
pageList={pageList.filter(p => !p.trash)}
|
pageList={pageList.filter(p => !p.trash)}
|
||||||
showFavoriteTag={true}
|
showFavoriteTag={true}
|
||||||
|
listType="all"
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ export const Favorite = () => {
|
|||||||
<PageListHeader icon={<FavouritesIcon />}>
|
<PageListHeader icon={<FavouritesIcon />}>
|
||||||
{t('Favourites')}
|
{t('Favourites')}
|
||||||
</PageListHeader>
|
</PageListHeader>
|
||||||
<PageList pageList={pageList.filter(p => p.favorite && !p.trash)} />
|
<PageList
|
||||||
|
pageList={pageList.filter(p => p.favorite && !p.trash)}
|
||||||
|
listType="favorite"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,11 @@ export const Trash = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageListHeader icon={<TrashIcon />}>{t('Trash')}</PageListHeader>
|
<PageListHeader icon={<TrashIcon />}>{t('Trash')}</PageListHeader>
|
||||||
<PageList pageList={pageList.filter(p => p.trash)} isTrash={true} />
|
<PageList
|
||||||
|
pageList={pageList.filter(p => p.trash)}
|
||||||
|
isTrash={true}
|
||||||
|
listType="trash"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ declare module 'react-i18next' {
|
|||||||
// custom namespace type if you changed it
|
// custom namespace type if you changed it
|
||||||
// defaultNS: 'ns1';
|
// defaultNS: 'ns1';
|
||||||
// custom resources type
|
// custom resources type
|
||||||
|
allowObjectInHTMLChildren: true;
|
||||||
resources: {
|
resources: {
|
||||||
en: typeof en_US;
|
en: typeof en_US;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
{
|
{
|
||||||
"Quick search": "Quick search",
|
"Quick search": "Quick search",
|
||||||
"Quick search placeholder": "Quick Search...",
|
|
||||||
"Quick search placeholder2": "Search in {{workspace}}",
|
|
||||||
"All pages": "All pages",
|
"All pages": "All pages",
|
||||||
"Favourites": "Favourites",
|
"Favourites": "Favourites",
|
||||||
"No item": "No item",
|
"No item": "No item",
|
||||||
"Settings": "Settings",
|
|
||||||
"Import": "Import",
|
"Import": "Import",
|
||||||
"Trash": "Trash",
|
"Trash": "Trash",
|
||||||
"New Page": "New Page",
|
"New Page": "New Page",
|
||||||
@@ -14,13 +11,11 @@
|
|||||||
"Find results": "Find {{number}} results",
|
"Find results": "Find {{number}} results",
|
||||||
"Collapse sidebar": "Collapse sidebar",
|
"Collapse sidebar": "Collapse sidebar",
|
||||||
"Expand sidebar": "Expand sidebar",
|
"Expand sidebar": "Expand sidebar",
|
||||||
"Removed from Favourites": "Removed from Favourites",
|
|
||||||
"Remove from favourites": "Remove from favourites",
|
|
||||||
"Added to Favourites": "Added to Favourites",
|
"Added to Favourites": "Added to Favourites",
|
||||||
"Add to favourites": "Add to favourites",
|
"Add to favourites": "Add to favourites",
|
||||||
"Paper": "Paper",
|
"Paper": "Paper",
|
||||||
"Edgeless": "Edgeless",
|
"Edgeless": "Edgeless",
|
||||||
"Switch to": "Switch to",
|
"Jump to": "Jump to",
|
||||||
"Convert to ": "Convert to ",
|
"Convert to ": "Convert to ",
|
||||||
"Page": "Page",
|
"Page": "Page",
|
||||||
"Export": "Export",
|
"Export": "Export",
|
||||||
@@ -37,7 +32,6 @@
|
|||||||
"Delete page?": "Delete page?",
|
"Delete page?": "Delete page?",
|
||||||
"Delete permanently?": "Delete permanently?",
|
"Delete permanently?": "Delete permanently?",
|
||||||
"will be moved to Trash": "{{title}} will be moved to Trash",
|
"will be moved to Trash": "{{title}} will be moved to Trash",
|
||||||
"Once deleted, you can't undo this action.": "Once deleted, you can't undo this action.",
|
|
||||||
"Moved to Trash": "Moved to Trash",
|
"Moved to Trash": "Moved to Trash",
|
||||||
"Permanently deleted": "Permanently deleted",
|
"Permanently deleted": "Permanently deleted",
|
||||||
"restored": "{{title}} restored",
|
"restored": "{{title}} restored",
|
||||||
@@ -57,7 +51,6 @@
|
|||||||
"Strikethrough": "Strikethrough",
|
"Strikethrough": "Strikethrough",
|
||||||
"Inline code": "Inline code",
|
"Inline code": "Inline code",
|
||||||
"Code block": "Code block",
|
"Code block": "Code block",
|
||||||
"Link": "Hyperlink (with selected text)",
|
|
||||||
"Body text": "Body text",
|
"Body text": "Body text",
|
||||||
"Heading": "Heading {{number}}",
|
"Heading": "Heading {{number}}",
|
||||||
"Increase indent": "Increase indent",
|
"Increase indent": "Increase indent",
|
||||||
@@ -65,6 +58,11 @@
|
|||||||
"Markdown Syntax": "Markdown Syntax",
|
"Markdown Syntax": "Markdown Syntax",
|
||||||
"Divider": "Divider",
|
"Divider": "Divider",
|
||||||
"404 - Page Not Found": "404 - Page Not Found",
|
"404 - Page Not Found": "404 - Page Not Found",
|
||||||
|
"Once deleted, you can't undo this action": {
|
||||||
|
"": "Once deleted, you can't undo this action."
|
||||||
|
},
|
||||||
|
"Remove from favourites": "Remove from favourites",
|
||||||
|
"Removed from Favourites": "Removed from Favourites",
|
||||||
"New Workspace": "New Workspace",
|
"New Workspace": "New Workspace",
|
||||||
"Workspace description": "Workspace is your virtual space to capture, create and plan as just one person or together as a team.",
|
"Workspace description": "Workspace is your virtual space to capture, create and plan as just one person or together as a team.",
|
||||||
"Create": "Create",
|
"Create": "Create",
|
||||||
@@ -79,6 +77,10 @@
|
|||||||
"TrashButtonGroupTitle": "Permanently delete",
|
"TrashButtonGroupTitle": "Permanently delete",
|
||||||
"TrashButtonGroupDescription": "Once deleted, you can't undo this action. Do you confirm?",
|
"TrashButtonGroupDescription": "Once deleted, you can't undo this action. Do you confirm?",
|
||||||
"Delete permanently": "Delete permanently",
|
"Delete permanently": "Delete permanently",
|
||||||
|
"Link": "Hyperlink (with selected text)",
|
||||||
|
"Quick search placeholder": "Quick Search...",
|
||||||
|
"Quick search placeholder2": "Search in {{workspace}}",
|
||||||
|
"Settings": "Settings",
|
||||||
"recommendBrowser": " We recommend the <1>Chrome</1> browser for optimal experience.",
|
"recommendBrowser": " We recommend the <1>Chrome</1> browser for optimal experience.",
|
||||||
"upgradeBrowser": "Please upgrade to the latest version of Chrome for the best experience.",
|
"upgradeBrowser": "Please upgrade to the latest version of Chrome for the best experience.",
|
||||||
"Invite Members": "Invite Members",
|
"Invite Members": "Invite Members",
|
||||||
@@ -104,19 +106,15 @@
|
|||||||
"Create Or Import": "Create Or Import",
|
"Create Or Import": "Create Or Import",
|
||||||
"Tips": "Tips: ",
|
"Tips": "Tips: ",
|
||||||
"login success": "Login success",
|
"login success": "Login success",
|
||||||
"Sign in": "Sign in AFFiNE Cloud",
|
|
||||||
"Sign out": "Sign out of AFFiNE Cloud",
|
"Sign out": "Sign out of AFFiNE Cloud",
|
||||||
"Delete Workspace": "Delete Workspace",
|
"Delete Workspace": "Delete Workspace",
|
||||||
"Delete Workspace Description": "Deleting (<1>{{workspace}}</1>) cannot be undone, please proceed with caution. along with all its content.",
|
|
||||||
"Delete Workspace Description2": "Deleting (<1>{{workspace}}</1>) will delete both local and cloud data, this operation cannot be undone, please proceed with caution.",
|
"Delete Workspace Description2": "Deleting (<1>{{workspace}}</1>) will delete both local and cloud data, this operation cannot be undone, please proceed with caution.",
|
||||||
"Delete Workspace placeholder": "Please type “Delete” to confirm",
|
"Delete Workspace placeholder": "Please type “Delete” to confirm",
|
||||||
"Leave Workspace": "Leave Workspace",
|
"Leave Workspace": "Leave Workspace",
|
||||||
"Leave Workspace Description": "After you leave, you will not be able to access all the contents of this workspace.",
|
|
||||||
"Leave": "Leave",
|
"Leave": "Leave",
|
||||||
"Workspace Icon": "Workspace Icon",
|
"Workspace Icon": "Workspace Icon",
|
||||||
"Workspace Name": "Workspace Name",
|
"Workspace Name": "Workspace Name",
|
||||||
"Workspace Type": "Workspace Type",
|
"Workspace Type": "Workspace Type",
|
||||||
"Export Workspace": "Export Workspace <1>{{workspace}}</1> Is Coming",
|
|
||||||
"Users": "Users",
|
"Users": "Users",
|
||||||
"Access level": "Access level",
|
"Access level": "Access level",
|
||||||
"Pending": "Pending",
|
"Pending": "Pending",
|
||||||
@@ -132,12 +130,16 @@
|
|||||||
"Publishing Description": "After publishing to the web, everyone can view the content of this workspace through the link.",
|
"Publishing Description": "After publishing to the web, everyone can view the content of this workspace through the link.",
|
||||||
"Stop publishing": "Stop publishing",
|
"Stop publishing": "Stop publishing",
|
||||||
"Publish to web": "Publish to web",
|
"Publish to web": "Publish to web",
|
||||||
"Sync Description": "{{workspaceName}} is Local Workspace. All data is stored on the current device. You can enable AFFiNE Cloud for this workspace to keep data in sync with the cloud.",
|
|
||||||
"Sync Description2": "<1>{{workspaceName}}</1> is Cloud Workspace. All data will be synchronized and saved to the AFFiNE",
|
|
||||||
"Download data to device": "Download {{CoreOrAll}} data to device",
|
"Download data to device": "Download {{CoreOrAll}} data to device",
|
||||||
"General": "General",
|
"General": "General",
|
||||||
"Sync": "Sync",
|
"Sync": "Sync",
|
||||||
"Collaboration": "Collaboration",
|
"Collaboration": "Collaboration",
|
||||||
"Publish": "Publish",
|
"Publish": "Publish",
|
||||||
"Workspace Settings": "Workspace Settings"
|
"Workspace Settings": "Workspace Settings",
|
||||||
|
"Export Workspace": "Export Workspace <1>{{workspace}}</1> is coming soon",
|
||||||
|
"Leave Workspace Description": "After you leave, you will no longer be able to access the contents of this workspace.",
|
||||||
|
"Sign in": "Sign in to AFFiNE Cloud",
|
||||||
|
"Sync Description": "{{workspaceName}} is a Local Workspace. All data is stored on the current device. You can enable AFFiNE Cloud for this workspace to keep data in sync with the cloud.",
|
||||||
|
"Sync Description2": "<1>{{workspaceName}}</1> is a Cloud Workspace. All data will be synchronised and saved to AFFiNE Cloud.",
|
||||||
|
"Delete Workspace Description": "Deleting (<1>{{workspace}}</1>) cannot be undone, please proceed with caution. All contents will be lost."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1,16 +1,11 @@
|
|||||||
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
// Run `pnpm run download-resources` to regenerate.
|
// Run `pnpm run download-resources` to regenerate.
|
||||||
// To overwrite this, please overwrite download.ts
|
// To overwrite this, please overwrite download.ts script.
|
||||||
import en from './en.json';
|
import en from './en.json';
|
||||||
import zh_Hans from './zh-Hans.json';
|
|
||||||
import zh_Hant from './zh-Hant.json';
|
|
||||||
import sr from './sr.json';
|
|
||||||
import fr from './fr.json';
|
|
||||||
import bn from './bn.json';
|
|
||||||
|
|
||||||
export const LOCALES = [
|
export const LOCALES = [
|
||||||
{
|
{
|
||||||
id: 1000016008,
|
id: 1000040001,
|
||||||
name: 'English',
|
name: 'English',
|
||||||
tag: 'en',
|
tag: 'en',
|
||||||
originalName: 'English',
|
originalName: 'English',
|
||||||
@@ -19,54 +14,4 @@ export const LOCALES = [
|
|||||||
completeRate: 1,
|
completeRate: 1,
|
||||||
res: en,
|
res: en,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 1000016009,
|
|
||||||
name: 'Simplified Chinese',
|
|
||||||
tag: 'zh-Hans',
|
|
||||||
originalName: '简体中文',
|
|
||||||
flagEmoji: '🇨🇳',
|
|
||||||
base: false,
|
|
||||||
completeRate: 1,
|
|
||||||
res: zh_Hans,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1000016012,
|
|
||||||
name: 'Traditional Chinese',
|
|
||||||
tag: 'zh-Hant',
|
|
||||||
originalName: '繁體中文',
|
|
||||||
flagEmoji: '🇭🇰',
|
|
||||||
base: false,
|
|
||||||
completeRate: 1,
|
|
||||||
res: zh_Hant,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1000034005,
|
|
||||||
name: 'Serbian',
|
|
||||||
tag: 'sr',
|
|
||||||
originalName: 'српски',
|
|
||||||
flagEmoji: '🇷🇸',
|
|
||||||
base: false,
|
|
||||||
completeRate: 0.9166666666666666,
|
|
||||||
res: sr,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1000034008,
|
|
||||||
name: 'French',
|
|
||||||
tag: 'fr',
|
|
||||||
originalName: 'français',
|
|
||||||
flagEmoji: '🇫🇷',
|
|
||||||
base: false,
|
|
||||||
completeRate: 1,
|
|
||||||
res: fr,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1000034010,
|
|
||||||
name: 'Bangla',
|
|
||||||
tag: 'bn',
|
|
||||||
originalName: 'বাংলা',
|
|
||||||
flagEmoji: '🇧🇩',
|
|
||||||
base: false,
|
|
||||||
completeRate: 0.7083333333333334,
|
|
||||||
res: bn,
|
|
||||||
},
|
|
||||||
] as const;
|
] as const;
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
Reference in New Issue
Block a user