mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
feat: replace modal with new design (#4324)
Co-authored-by: Peng Xiao <pengxiao@outlook.com>
This commit is contained in:
@@ -1,14 +1,9 @@
|
||||
import {
|
||||
Input,
|
||||
Modal,
|
||||
ModalCloseButton,
|
||||
ModalWrapper,
|
||||
toast,
|
||||
} from '@affine/component';
|
||||
import { Input, toast } from '@affine/component';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { HelpIcon } from '@blocksuite/icons';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
import { Modal } from '@toeverything/components/modal';
|
||||
import { Tooltip } from '@toeverything/components/tooltip';
|
||||
import type {
|
||||
LoadDBFileResult,
|
||||
@@ -386,16 +381,28 @@ export const CreateWorkspaceModal = ({
|
||||
/>
|
||||
) : null;
|
||||
|
||||
const onOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
if (!open) {
|
||||
onClose();
|
||||
}
|
||||
},
|
||||
[onClose]
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal open={mode !== false && !!step} onClose={onClose}>
|
||||
<ModalWrapper width={560} style={{ padding: '10px' }}>
|
||||
<div className={style.header}>
|
||||
<ModalCloseButton top={6} right={6} onClick={onClose} />
|
||||
</div>
|
||||
{nameWorkspaceNode}
|
||||
{setDBLocationNode}
|
||||
{setSyncingModeNode}
|
||||
</ModalWrapper>
|
||||
<Modal
|
||||
open={mode !== false && !!step}
|
||||
width={560}
|
||||
onOpenChange={onOpenChange}
|
||||
contentOptions={{
|
||||
style: { padding: '10px' },
|
||||
}}
|
||||
>
|
||||
<div className={style.header}></div>
|
||||
{nameWorkspaceNode}
|
||||
{setDBLocationNode}
|
||||
{setSyncingModeNode}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,33 +1,26 @@
|
||||
import { Modal, ModalWrapper } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon } from '@blocksuite/icons';
|
||||
import { Button, IconButton } from '@toeverything/components/button';
|
||||
import {
|
||||
ConfirmModal,
|
||||
type ConfirmModalProps,
|
||||
} from '@toeverything/components/modal';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { authAtom } from '../../../atoms';
|
||||
import { setOnceSignedInEventAtom } from '../../../atoms/event';
|
||||
import { useCurrentLoginStatus } from '../../../hooks/affine/use-current-login-status';
|
||||
import { ButtonContainer, Content, Header, StyleTips, Title } from './style';
|
||||
|
||||
interface EnableAffineCloudModalProps {
|
||||
open: boolean;
|
||||
onConfirm: () => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const EnableAffineCloudModal = ({
|
||||
onConfirm: propsOnConfirm,
|
||||
open,
|
||||
onClose,
|
||||
}: EnableAffineCloudModalProps) => {
|
||||
...props
|
||||
}: ConfirmModalProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const loginStatus = useCurrentLoginStatus();
|
||||
const setAuthAtom = useSetAtom(authAtom);
|
||||
const setOnceSignedInEvent = useSetAtom(setOnceSignedInEventAtom);
|
||||
|
||||
const confirm = useCallback(async () => {
|
||||
return propsOnConfirm();
|
||||
return propsOnConfirm?.();
|
||||
}, [propsOnConfirm]);
|
||||
|
||||
const onConfirm = useCallback(() => {
|
||||
@@ -39,42 +32,29 @@ export const EnableAffineCloudModal = ({
|
||||
setOnceSignedInEvent(confirm);
|
||||
}
|
||||
if (loginStatus === 'authenticated') {
|
||||
return propsOnConfirm();
|
||||
return propsOnConfirm?.();
|
||||
}
|
||||
}, [confirm, loginStatus, propsOnConfirm, setAuthAtom, setOnceSignedInEvent]);
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={onClose} data-testid="logout-modal">
|
||||
<ModalWrapper width={480}>
|
||||
<Header>
|
||||
<Title>{t['Enable AFFiNE Cloud']()}</Title>
|
||||
<IconButton onClick={onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Content>
|
||||
<StyleTips>{t['Enable AFFiNE Cloud Description']()}</StyleTips>
|
||||
<ButtonContainer>
|
||||
<div>
|
||||
<Button onClick={onClose} block>
|
||||
{t['com.affine.enableAffineCloudModal.button.cancel']()}
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
data-testid="confirm-enable-affine-cloud-button"
|
||||
type="primary"
|
||||
block
|
||||
onClick={onConfirm}
|
||||
>
|
||||
{loginStatus === 'authenticated'
|
||||
? t['Enable']()
|
||||
: t['Sign in and Enable']()}
|
||||
</Button>
|
||||
</div>
|
||||
</ButtonContainer>
|
||||
</Content>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
<ConfirmModal
|
||||
width={480}
|
||||
title={t['Enable AFFiNE Cloud']()}
|
||||
description={t['Enable AFFiNE Cloud Description']()}
|
||||
cancelText={t['com.affine.enableAffineCloudModal.button.cancel']()}
|
||||
onConfirm={onConfirm}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
['data-testid' as string]: 'confirm-enable-affine-cloud-button',
|
||||
children:
|
||||
loginStatus === 'authenticated'
|
||||
? t['Enable']()
|
||||
: t['Sign in and Enable'](),
|
||||
}}
|
||||
contentOptions={{
|
||||
['data-testid' as string]: 'enable-cloud-modal',
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { styled } from '@affine/component';
|
||||
|
||||
export const Header = styled('div')({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
paddingRight: '20px',
|
||||
paddingTop: '20px',
|
||||
paddingLeft: '24px',
|
||||
alignItems: 'center',
|
||||
});
|
||||
|
||||
export const Content = styled('div')({
|
||||
padding: '12px 24px 20px 24px',
|
||||
});
|
||||
|
||||
export const Title = styled('div')({
|
||||
fontSize: 'var(--affine-font-h6)',
|
||||
lineHeight: '26px',
|
||||
fontWeight: 600,
|
||||
});
|
||||
|
||||
export const StyleTips = styled('div')(() => {
|
||||
return {
|
||||
userSelect: 'none',
|
||||
marginBottom: '20px',
|
||||
};
|
||||
});
|
||||
export const ButtonContainer = styled('div')(() => {
|
||||
return {
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
gap: '20px',
|
||||
paddingTop: '20px',
|
||||
};
|
||||
});
|
||||
@@ -1,33 +1,24 @@
|
||||
import { Input, Modal, ModalCloseButton } from '@affine/component';
|
||||
import { Input } from '@affine/component';
|
||||
import type { AffineOfficialWorkspace } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
import {
|
||||
ConfirmModal,
|
||||
type ConfirmModalProps,
|
||||
} from '@toeverything/components/modal';
|
||||
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
|
||||
import { useState } from 'react';
|
||||
|
||||
import {
|
||||
StyledButtonContent,
|
||||
StyledInputContent,
|
||||
StyledModalHeader,
|
||||
StyledModalWrapper,
|
||||
StyledTextContent,
|
||||
StyledWorkspaceName,
|
||||
} from './style';
|
||||
import { StyledInputContent, StyledWorkspaceName } from './style';
|
||||
|
||||
interface WorkspaceDeleteProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
interface WorkspaceDeleteProps extends ConfirmModalProps {
|
||||
workspace: AffineOfficialWorkspace;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
export const WorkspaceDeleteModal = ({
|
||||
open,
|
||||
onClose,
|
||||
onConfirm,
|
||||
workspace,
|
||||
...props
|
||||
}: WorkspaceDeleteProps) => {
|
||||
const [workspaceName] = useBlockSuiteWorkspaceName(
|
||||
workspace.blockSuiteWorkspace
|
||||
@@ -37,65 +28,50 @@ export const WorkspaceDeleteModal = ({
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={onClose}>
|
||||
<StyledModalWrapper>
|
||||
<ModalCloseButton onClick={onClose} />
|
||||
<StyledModalHeader>
|
||||
{t['com.affine.workspaceDelete.title']()}?
|
||||
</StyledModalHeader>
|
||||
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<StyledTextContent>
|
||||
<Trans i18nKey="com.affine.workspaceDelete.description">
|
||||
Deleting (
|
||||
<StyledWorkspaceName>
|
||||
{{ workspace: workspaceName } as any}
|
||||
</StyledWorkspaceName>
|
||||
) cannot be undone, please proceed with caution. All contents will
|
||||
be lost.
|
||||
</Trans>
|
||||
</StyledTextContent>
|
||||
) : (
|
||||
<StyledTextContent>
|
||||
<Trans i18nKey="com.affine.workspaceDelete.description2">
|
||||
Deleting (
|
||||
<StyledWorkspaceName>
|
||||
{{ workspace: workspaceName } as any}
|
||||
</StyledWorkspaceName>
|
||||
) will delete both local and cloud data, this operation cannot be
|
||||
undone, please proceed with caution.
|
||||
</Trans>
|
||||
</StyledTextContent>
|
||||
)}
|
||||
<StyledInputContent>
|
||||
<Input
|
||||
ref={ref => {
|
||||
if (ref) {
|
||||
window.setTimeout(() => ref.focus(), 0);
|
||||
}
|
||||
}}
|
||||
onChange={setDeleteStr}
|
||||
data-testid="delete-workspace-input"
|
||||
placeholder={t['com.affine.workspaceDelete.placeholder']()}
|
||||
width={315}
|
||||
height={42}
|
||||
/>
|
||||
</StyledInputContent>
|
||||
<StyledButtonContent>
|
||||
<Button onClick={onClose} size="large">
|
||||
{t['com.affine.workspaceDelete.button.cancel']()}
|
||||
</Button>
|
||||
<Button
|
||||
data-testid="delete-workspace-confirm-button"
|
||||
disabled={!allowDelete}
|
||||
onClick={onConfirm}
|
||||
size="large"
|
||||
type="error"
|
||||
style={{ marginLeft: '24px' }}
|
||||
>
|
||||
{t['com.affine.workspaceDelete.button.delete']()}
|
||||
</Button>
|
||||
</StyledButtonContent>
|
||||
</StyledModalWrapper>
|
||||
</Modal>
|
||||
<ConfirmModal
|
||||
title={`${t['com.affine.workspaceDelete.title']()}?`}
|
||||
cancelText={t['com.affine.workspaceDelete.button.cancel']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'error',
|
||||
disabled: !allowDelete,
|
||||
['data-testid' as string]: 'delete-workspace-confirm-button',
|
||||
children: t['com.affine.workspaceDelete.button.delete'](),
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<Trans i18nKey="com.affine.workspaceDelete.description">
|
||||
Deleting (
|
||||
<StyledWorkspaceName>
|
||||
{{ workspace: workspaceName } as any}
|
||||
</StyledWorkspaceName>
|
||||
) cannot be undone, please proceed with caution. All contents will be
|
||||
lost.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans i18nKey="com.affine.workspaceDelete.description2">
|
||||
Deleting (
|
||||
<StyledWorkspaceName>
|
||||
{{ workspace: workspaceName } as any}
|
||||
</StyledWorkspaceName>
|
||||
) will delete both local and cloud data, this operation cannot be
|
||||
undone, please proceed with caution.
|
||||
</Trans>
|
||||
)}
|
||||
<StyledInputContent>
|
||||
<Input
|
||||
ref={ref => {
|
||||
if (ref) {
|
||||
window.setTimeout(() => ref.focus(), 0);
|
||||
}
|
||||
}}
|
||||
onChange={setDeleteStr}
|
||||
data-testid="delete-workspace-input"
|
||||
placeholder={t['com.affine.workspaceDelete.placeholder']()}
|
||||
width={315}
|
||||
height={42}
|
||||
/>
|
||||
</StyledInputContent>
|
||||
</ConfirmModal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,20 +21,6 @@ export const StyledModalHeader = styled('div')(() => {
|
||||
};
|
||||
});
|
||||
|
||||
// export const StyledModalContent = styled('div')(({ theme }) => {});
|
||||
|
||||
export const StyledTextContent = styled('div')(() => {
|
||||
return {
|
||||
margin: 'auto',
|
||||
width: '425px',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: '400',
|
||||
fontSize: '18px',
|
||||
lineHeight: '26px',
|
||||
textAlign: 'left',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledInputContent = styled('div')(() => {
|
||||
return {
|
||||
display: 'flex',
|
||||
@@ -45,31 +31,8 @@ export const StyledInputContent = styled('div')(() => {
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledButtonContent = styled('div')(() => {
|
||||
return {
|
||||
marginBottom: '42px',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledWorkspaceName = styled('span')(() => {
|
||||
return {
|
||||
fontWeight: '600',
|
||||
};
|
||||
});
|
||||
|
||||
// export const StyledCancelButton = styled(Button)(({ theme }) => {
|
||||
// return {
|
||||
// width: '100px',
|
||||
// justifyContent: 'center',
|
||||
// };
|
||||
// });
|
||||
|
||||
// export const StyledDeleteButton = styled(Button)(({ theme }) => {
|
||||
// return {
|
||||
// width: '100px',
|
||||
// justifyContent: 'center',
|
||||
// };
|
||||
// });
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ConfirmModal } from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import type { AffineOfficialWorkspace } from '@affine/env/workspace';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ArrowRightSmallIcon } from '@blocksuite/icons';
|
||||
import { ConfirmModal } from '@toeverything/components/modal';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import type { WorkspaceSettingDetailProps } from '../types';
|
||||
@@ -33,10 +33,6 @@ export const DeleteLeaveWorkspace = ({
|
||||
}
|
||||
}, [isOwner]);
|
||||
|
||||
const onCloseLeaveModal = useCallback(() => {
|
||||
setShowLeave(false);
|
||||
}, []);
|
||||
|
||||
const onLeaveConfirm = useCallback(() => {
|
||||
return onLeaveWorkspace();
|
||||
}, [onLeaveWorkspace]);
|
||||
@@ -71,21 +67,21 @@ export const DeleteLeaveWorkspace = ({
|
||||
<WorkspaceDeleteModal
|
||||
onConfirm={onDeleteConfirm}
|
||||
open={showDelete}
|
||||
onClose={() => {
|
||||
setShowDelete(false);
|
||||
}}
|
||||
onOpenChange={setShowDelete}
|
||||
workspace={workspace}
|
||||
/>
|
||||
) : (
|
||||
<ConfirmModal
|
||||
open={showLeave}
|
||||
cancelText={t['com.affine.confirmModal.button.cancel']()}
|
||||
onConfirm={onLeaveConfirm}
|
||||
onCancel={onCloseLeaveModal}
|
||||
onClose={onCloseLeaveModal}
|
||||
onOpenChange={setShowLeave}
|
||||
title={`${t['com.affine.deleteLeaveWorkspace.leave']()}?`}
|
||||
content={t['com.affine.deleteLeaveWorkspace.leaveDescription']()}
|
||||
confirmType="warning"
|
||||
confirmText={t['Leave']()}
|
||||
description={t['com.affine.deleteLeaveWorkspace.leaveDescription']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'warning',
|
||||
children: t['Leave'](),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -142,9 +142,7 @@ const PublishPanelLocal = ({
|
||||
{runtimeConfig.enableCloud ? (
|
||||
<EnableAffineCloudModal
|
||||
open={open}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
onOpenChange={setOpen}
|
||||
onConfirm={() => {
|
||||
onTransferWorkspace(
|
||||
WorkspaceFlavour.LOCAL,
|
||||
@@ -155,12 +153,7 @@ const PublishPanelLocal = ({
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<TmpDisableAffineCloudModal
|
||||
open={open}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
/>
|
||||
<TmpDisableAffineCloudModal open={open} onOpenChange={setOpen} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -8,12 +8,16 @@ import { guideOnboardingAtom } from '../../atoms/guide';
|
||||
export const OnboardingModal = memo(function OnboardingModal() {
|
||||
const [open, setOpen] = useAtom(openOnboardingModalAtom);
|
||||
const [guideOpen, setShowOnboarding] = useAtom(guideOnboardingAtom);
|
||||
const onCloseTourModal = useCallback(() => {
|
||||
setShowOnboarding(false);
|
||||
setOpen(false);
|
||||
}, [setOpen, setShowOnboarding]);
|
||||
const onOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
if (open) return;
|
||||
setShowOnboarding(false);
|
||||
setOpen(false);
|
||||
},
|
||||
[setOpen, setShowOnboarding]
|
||||
);
|
||||
|
||||
return (
|
||||
<TourModal open={!open ? guideOpen : open} onClose={onCloseTourModal} />
|
||||
<TourModal open={!open ? guideOpen : open} onOpenChange={onOpenChange} />
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import {
|
||||
SettingModal as SettingModalBase,
|
||||
type SettingModalProps as SettingModalBaseProps,
|
||||
WorkspaceDetailSkeleton,
|
||||
} from '@affine/component/setting-components';
|
||||
import { WorkspaceDetailSkeleton } from '@affine/component/setting-components';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { ContactWithUsIcon } from '@blocksuite/icons';
|
||||
import { Modal, type ModalProps } from '@toeverything/components/modal';
|
||||
import { Suspense, useCallback } from 'react';
|
||||
|
||||
import { useCurrentLoginStatus } from '../../../hooks/affine/use-current-login-status';
|
||||
@@ -20,7 +17,7 @@ import { WorkspaceSetting } from './workspace-setting';
|
||||
|
||||
type ActiveTab = GeneralSettingKeys | 'workspace' | 'account';
|
||||
|
||||
export interface SettingProps {
|
||||
export interface SettingProps extends ModalProps {
|
||||
activeTab: ActiveTab;
|
||||
workspaceId: string | null;
|
||||
onSettingClick: (params: {
|
||||
@@ -29,15 +26,12 @@ export interface SettingProps {
|
||||
}) => void;
|
||||
}
|
||||
|
||||
type SettingModalProps = SettingModalBaseProps & SettingProps;
|
||||
|
||||
export const SettingModal = ({
|
||||
open,
|
||||
setOpen,
|
||||
activeTab = 'appearance',
|
||||
workspaceId = null,
|
||||
onSettingClick,
|
||||
}: SettingModalProps) => {
|
||||
...modalProps
|
||||
}: SettingProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
const loginStatus = useCurrentLoginStatus();
|
||||
|
||||
@@ -66,7 +60,21 @@ export const SettingModal = ({
|
||||
}, [onSettingClick]);
|
||||
|
||||
return (
|
||||
<SettingModalBase open={open} setOpen={setOpen}>
|
||||
<Modal
|
||||
width={1080}
|
||||
height={760}
|
||||
contentOptions={{
|
||||
['data-testid' as string]: 'setting-modal',
|
||||
style: {
|
||||
maxHeight: '85vh',
|
||||
maxWidth: '70vw',
|
||||
padding: 0,
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
},
|
||||
}}
|
||||
{...modalProps}
|
||||
>
|
||||
<SettingSidebar
|
||||
generalSettingList={generalSettingList}
|
||||
onGeneralSettingClick={onGeneralSettingClick}
|
||||
@@ -105,6 +113,6 @@ export const SettingModal = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SettingModalBase>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -30,9 +30,7 @@ export const SharePageModal = ({ workspace, page }: SharePageModalProps) => {
|
||||
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||
<EnableAffineCloudModal
|
||||
open={open}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
onOpenChange={setOpen}
|
||||
onConfirm={() => {
|
||||
onTransformWorkspace(
|
||||
WorkspaceFlavour.LOCAL,
|
||||
|
||||
@@ -1,79 +1,61 @@
|
||||
import { Empty, Modal, ModalWrapper } from '@affine/component';
|
||||
import { Empty } from '@affine/component';
|
||||
import { Trans } from '@affine/i18n';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon } from '@blocksuite/icons';
|
||||
import { IconButton } from '@toeverything/components/button';
|
||||
import { Modal, type ModalProps } from '@toeverything/components/modal';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import {
|
||||
Content,
|
||||
ContentTitle,
|
||||
Header,
|
||||
StyleButton,
|
||||
StyleButtonContainer,
|
||||
StyleImage,
|
||||
StyleTips,
|
||||
} from './style';
|
||||
|
||||
interface TmpDisableAffineCloudModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const TmpDisableAffineCloudModal = ({
|
||||
open,
|
||||
onClose,
|
||||
}: TmpDisableAffineCloudModalProps) => {
|
||||
export const TmpDisableAffineCloudModal = (props: ModalProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
props.onOpenChange?.(false);
|
||||
}, [props]);
|
||||
return (
|
||||
<Modal
|
||||
data-testid="disable-affine-cloud-modal"
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
title={t['com.affine.cloudTempDisable.title']()}
|
||||
contentOptions={{
|
||||
['data-testid' as string]: 'disable-affine-cloud-modal',
|
||||
}}
|
||||
width={480}
|
||||
{...props}
|
||||
>
|
||||
<ModalWrapper width={480}>
|
||||
<Header>
|
||||
<IconButton onClick={onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentTitle>
|
||||
{t['com.affine.cloudTempDisable.title']()}
|
||||
</ContentTitle>
|
||||
<StyleTips>
|
||||
<Trans i18nKey="com.affine.cloudTempDisable.description">
|
||||
We are upgrading the AFFiNE Cloud service and it is temporarily
|
||||
unavailable on the client side. If you wish to stay updated on the
|
||||
progress and be notified on availability, you can fill out the
|
||||
<a
|
||||
href="https://6dxre9ihosp.typeform.com/to/B8IHwuyy"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
style={{
|
||||
color: 'var(--affine-link-color)',
|
||||
}}
|
||||
>
|
||||
AFFiNE Cloud Signup
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</StyleTips>
|
||||
<StyleImage>
|
||||
<Empty
|
||||
containerStyle={{
|
||||
width: '200px',
|
||||
height: '112px',
|
||||
}}
|
||||
/>
|
||||
</StyleImage>
|
||||
<StyleButtonContainer>
|
||||
<StyleButton type="primary" onClick={onClose}>
|
||||
{t['Got it']()}
|
||||
</StyleButton>
|
||||
</StyleButtonContainer>
|
||||
</Content>
|
||||
</ModalWrapper>
|
||||
<StyleTips>
|
||||
<Trans i18nKey="com.affine.cloudTempDisable.description">
|
||||
We are upgrading the AFFiNE Cloud service and it is temporarily
|
||||
unavailable on the client side. If you wish to stay updated on the
|
||||
progress and be notified on availability, you can fill out the
|
||||
<a
|
||||
href="https://6dxre9ihosp.typeform.com/to/B8IHwuyy"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
style={{
|
||||
color: 'var(--affine-link-color)',
|
||||
}}
|
||||
>
|
||||
AFFiNE Cloud Signup
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</StyleTips>
|
||||
<StyleImage>
|
||||
<Empty
|
||||
containerStyle={{
|
||||
width: '200px',
|
||||
height: '112px',
|
||||
}}
|
||||
/>
|
||||
</StyleImage>
|
||||
<StyleButtonContainer>
|
||||
<StyleButton type="primary" onClick={onClose}>
|
||||
{t['Got it']()}
|
||||
</StyleButton>
|
||||
</StyleButtonContainer>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,6 +16,7 @@ export const Content = styled('div')({
|
||||
|
||||
export const ContentTitle = styled('h1')(() => {
|
||||
return {
|
||||
marginTop: 44,
|
||||
fontSize: 'var(--affine-font-h6)',
|
||||
lineHeight: '28px',
|
||||
fontWeight: 600,
|
||||
@@ -24,8 +25,7 @@ export const ContentTitle = styled('h1')(() => {
|
||||
|
||||
export const StyleTips = styled('div')(() => {
|
||||
return {
|
||||
userSelect: 'none',
|
||||
margin: '20px 0',
|
||||
margin: '0 0 20px 0',
|
||||
a: {
|
||||
color: 'var(--affine-primary-color)',
|
||||
},
|
||||
@@ -35,7 +35,6 @@ export const StyleTips = styled('div')(() => {
|
||||
export const StyleButton = styled(Button)(() => {
|
||||
return {
|
||||
textAlign: 'center',
|
||||
margin: '20px 0',
|
||||
borderRadius: '8px',
|
||||
backgroundColor: 'var(--affine-primary-color)',
|
||||
span: {
|
||||
@@ -46,11 +45,12 @@ export const StyleButton = styled(Button)(() => {
|
||||
export const StyleButtonContainer = styled('div')(() => {
|
||||
return {
|
||||
width: '100%',
|
||||
marginTop: 20,
|
||||
...displayFlex('flex-end', 'center'),
|
||||
};
|
||||
});
|
||||
export const StyleImage = styled('div')(() => {
|
||||
return {
|
||||
width: '100%',
|
||||
...displayFlex('center', 'center'),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { Modal, ModalWrapper } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon } from '@blocksuite/icons';
|
||||
import { IconButton } from '@toeverything/components/button';
|
||||
|
||||
import { Content, ContentTitle, Header, StyleButton, StyleTips } from './style';
|
||||
|
||||
export interface TransformWorkspaceToAffineModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onConform: () => void;
|
||||
}
|
||||
|
||||
export const TransformWorkspaceToAffineModal = ({
|
||||
open,
|
||||
onClose,
|
||||
onConform,
|
||||
}: TransformWorkspaceToAffineModalProps) => {
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
data-testid="enable-affine-cloud-modal"
|
||||
>
|
||||
<ModalWrapper width={560} height={292}>
|
||||
<Header>
|
||||
<IconButton onClick={onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Content>
|
||||
<ContentTitle>{t['Enable AFFiNE Cloud']()}?</ContentTitle>
|
||||
<StyleTips>{t['Enable AFFiNE Cloud Description']()}</StyleTips>
|
||||
{/* <StyleTips>{t('Retain cached cloud data')}</StyleTips> */}
|
||||
<div>
|
||||
<StyleButton
|
||||
data-testid="confirm-enable-cloud-button"
|
||||
type="primary"
|
||||
onClick={onConform}
|
||||
>
|
||||
{t['Sign in and Enable']()}
|
||||
</StyleButton>
|
||||
<StyleButton
|
||||
shape="round"
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{t['Not now']()}
|
||||
</StyleButton>
|
||||
</div>
|
||||
</Content>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
import { styled } from '@affine/component';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
|
||||
export const Header = styled('div')({
|
||||
height: '44px',
|
||||
display: 'flex',
|
||||
flexDirection: 'row-reverse',
|
||||
paddingRight: '10px',
|
||||
paddingTop: '10px',
|
||||
flexShrink: 0,
|
||||
});
|
||||
|
||||
export const Content = styled('div')({
|
||||
textAlign: 'center',
|
||||
});
|
||||
|
||||
export const ContentTitle = styled('h1')({
|
||||
fontSize: '20px',
|
||||
lineHeight: '28px',
|
||||
fontWeight: 600,
|
||||
textAlign: 'center',
|
||||
});
|
||||
|
||||
export const StyleTips = styled('div')(() => {
|
||||
return {
|
||||
userSelect: 'none',
|
||||
width: '400px',
|
||||
margin: 'auto',
|
||||
marginBottom: '32px',
|
||||
marginTop: '12px',
|
||||
};
|
||||
});
|
||||
|
||||
export const StyleButton = styled(Button)(() => {
|
||||
return {
|
||||
width: '284px',
|
||||
display: 'block',
|
||||
margin: 'auto',
|
||||
marginTop: '16px',
|
||||
};
|
||||
});
|
||||
@@ -225,9 +225,7 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
|
||||
open={openConfirm}
|
||||
title={pageMeta.title}
|
||||
onConfirm={handleOnConfirm}
|
||||
onCancel={() => {
|
||||
setOpenConfirm(false);
|
||||
}}
|
||||
onOpenChange={setOpenConfirm}
|
||||
/>
|
||||
</FlexWrapper>
|
||||
</>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Modal, ModalWrapper } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { Modal } from '@toeverything/components/modal';
|
||||
import { Command } from 'cmdk';
|
||||
import { startTransition, Suspense } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
@@ -75,93 +75,86 @@ export const QuickSearchModal = ({
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
wrapperPosition={['top', 'center']}
|
||||
data-testid="quickSearch"
|
||||
>
|
||||
<ModalWrapper
|
||||
width={608}
|
||||
style={{
|
||||
onOpenChange={setOpen}
|
||||
width={608}
|
||||
contentOptions={{
|
||||
['data-testid' as string]: 'quickSearch',
|
||||
style: {
|
||||
maxHeight: '80vh',
|
||||
minHeight: '412px',
|
||||
top: '80px',
|
||||
overflow: 'hidden',
|
||||
transform: 'translateX(-50%)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Command
|
||||
shouldFilter={false}
|
||||
//Handle KeyboardEvent conflicts with blocksuite
|
||||
onKeyDown={(e: React.KeyboardEvent) => {
|
||||
if (
|
||||
e.key === 'ArrowDown' ||
|
||||
e.key === 'ArrowUp' ||
|
||||
e.key === 'ArrowLeft' ||
|
||||
e.key === 'ArrowRight'
|
||||
) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* <NavigationPath
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
onJumpToPage={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
/> */}
|
||||
<Command
|
||||
shouldFilter={false}
|
||||
//Handle KeyboardEvent conflicts with blocksuite
|
||||
onKeyDown={(e: React.KeyboardEvent) => {
|
||||
if (
|
||||
e.key === 'ArrowDown' ||
|
||||
e.key === 'ArrowUp' ||
|
||||
e.key === 'ArrowLeft' ||
|
||||
e.key === 'ArrowRight'
|
||||
) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<StyledModalHeader>
|
||||
<SearchInput
|
||||
ref={inputRef}
|
||||
onValueChange={value => {
|
||||
setQuery(value);
|
||||
}}
|
||||
onKeyDown={e => {
|
||||
// Avoid triggering the cmdk onSelect event when the input method is in use
|
||||
if (e.nativeEvent.isComposing) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
}}
|
||||
placeholder={t['Quick search placeholder']()}
|
||||
/>
|
||||
<StyledShortcut>
|
||||
{environment.isBrowser && environment.isMacOs
|
||||
? '⌘ + K'
|
||||
: 'Ctrl + K'}
|
||||
</StyledShortcut>
|
||||
</StyledModalHeader>
|
||||
<StyledModalDivider />
|
||||
<Command.List>
|
||||
<StyledContent>
|
||||
<Suspense
|
||||
fallback={
|
||||
<StyledNotFound>
|
||||
<span>{t['com.affine.loading']()}</span>
|
||||
</StyledNotFound>
|
||||
}
|
||||
>
|
||||
<Results
|
||||
<StyledModalHeader>
|
||||
<SearchInput
|
||||
ref={inputRef}
|
||||
onValueChange={value => {
|
||||
setQuery(value);
|
||||
}}
|
||||
onKeyDown={e => {
|
||||
// Avoid triggering the cmdk onSelect event when the input method is in use
|
||||
if (e.nativeEvent.isComposing) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
}}
|
||||
placeholder={t['Quick search placeholder']()}
|
||||
/>
|
||||
<StyledShortcut>
|
||||
{environment.isBrowser && environment.isMacOs
|
||||
? '⌘ + K'
|
||||
: 'Ctrl + K'}
|
||||
</StyledShortcut>
|
||||
</StyledModalHeader>
|
||||
<StyledModalDivider />
|
||||
<Command.List>
|
||||
<StyledContent>
|
||||
<Suspense
|
||||
fallback={
|
||||
<StyledNotFound>
|
||||
<span>{t['com.affine.loading']()}</span>
|
||||
</StyledNotFound>
|
||||
}
|
||||
>
|
||||
<Results
|
||||
query={query}
|
||||
onClose={handleClose}
|
||||
workspace={workspace}
|
||||
setShowCreatePage={setShowCreatePage}
|
||||
/>
|
||||
</Suspense>
|
||||
</StyledContent>
|
||||
{showCreatePage ? (
|
||||
<>
|
||||
<StyledModalDivider />
|
||||
<StyledModalFooter>
|
||||
<Footer
|
||||
query={query}
|
||||
onClose={handleClose}
|
||||
workspace={workspace}
|
||||
setShowCreatePage={setShowCreatePage}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
</Suspense>
|
||||
</StyledContent>
|
||||
{showCreatePage ? (
|
||||
<>
|
||||
<StyledModalDivider />
|
||||
<StyledModalFooter>
|
||||
<Footer
|
||||
query={query}
|
||||
onClose={handleClose}
|
||||
blockSuiteWorkspace={blockSuiteWorkspace}
|
||||
/>
|
||||
</StyledModalFooter>
|
||||
</>
|
||||
) : null}
|
||||
</Command.List>
|
||||
</Command>
|
||||
</ModalWrapper>
|
||||
</StyledModalFooter>
|
||||
</>
|
||||
) : null}
|
||||
</Command.List>
|
||||
</Command>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import {
|
||||
ModalCloseButton,
|
||||
MuiClickAwayListener,
|
||||
MuiSlide,
|
||||
} from '@affine/component';
|
||||
import { MuiClickAwayListener, MuiSlide } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { CloseIcon } from '@blocksuite/icons';
|
||||
import { IconButton } from '@toeverything/components/button';
|
||||
|
||||
import {
|
||||
type ShortcutsInfo,
|
||||
@@ -14,13 +12,7 @@ import {
|
||||
} from '../../../hooks/affine/use-shortcuts';
|
||||
import { KeyboardIcon } from './icons';
|
||||
import * as styles from './style.css';
|
||||
// import {
|
||||
// StyledListItem,
|
||||
// StyledModalHeader,
|
||||
// StyledShortcutsModal,
|
||||
// StyledSubTitle,
|
||||
// StyledTitle,
|
||||
// } from './style';
|
||||
|
||||
type ModalProps = {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
@@ -81,12 +73,16 @@ export const ShortcutsModal = ({ open, onClose }: ModalProps) => {
|
||||
{t['Shortcuts']()}
|
||||
</div>
|
||||
|
||||
<ModalCloseButton
|
||||
top={6}
|
||||
right={6}
|
||||
<IconButton
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 6,
|
||||
top: 6,
|
||||
}}
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
icon={<CloseIcon />}
|
||||
/>
|
||||
</div>
|
||||
<ShortcutsPanel shortcutsInfo={generalShortcutsInfo} />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Confirm } from '@affine/component';
|
||||
import { WorkspaceSubPath } from '@affine/env/workspace';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { Button } from '@toeverything/components/button';
|
||||
import { ConfirmModal } from '@toeverything/components/modal';
|
||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||
import { currentPageIdAtom } from '@toeverything/infra/atom';
|
||||
import { useAtomValue } from 'jotai';
|
||||
@@ -61,23 +61,21 @@ export const TrashButtonGroup = () => {
|
||||
{t['com.affine.trashOperation.deletePermanently']()}
|
||||
</Button>
|
||||
</div>
|
||||
<Confirm
|
||||
<ConfirmModal
|
||||
title={t['com.affine.trashOperation.delete.title']()}
|
||||
content={t['com.affine.trashOperation.delete.description']()}
|
||||
confirmText={t['com.affine.trashOperation.delete']()}
|
||||
confirmType="error"
|
||||
cancelText={t['com.affine.confirmModal.button.cancel']()}
|
||||
description={t['com.affine.trashOperation.delete.description']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'error',
|
||||
children: t['com.affine.trashOperation.delete'](),
|
||||
}}
|
||||
open={open}
|
||||
onConfirm={useCallback(() => {
|
||||
jumpToSubPath(workspace.id, WorkspaceSubPath.ALL);
|
||||
blockSuiteWorkspace.removePage(pageId);
|
||||
toast(t['com.affine.toastMessage.permanentlyDeleted']());
|
||||
}, [blockSuiteWorkspace, jumpToSubPath, pageId, workspace.id, t])}
|
||||
onCancel={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
onOpenChange={setOpen}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -177,6 +177,7 @@ export const WorkspaceListModal = ({
|
||||
const localWorkspaces = workspaces.filter(
|
||||
({ flavour }) => flavour === WorkspaceFlavour.LOCAL
|
||||
) as (AffineCloudWorkspace | LocalWorkspace)[];
|
||||
// FIXME: replace mui popover
|
||||
return (
|
||||
<Popover
|
||||
sx={{
|
||||
@@ -209,6 +210,7 @@ export const WorkspaceListModal = ({
|
||||
openModal: true,
|
||||
}));
|
||||
}
|
||||
onClose();
|
||||
}}
|
||||
data-testid="cloud-signin-button"
|
||||
>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
EditCollectionModel,
|
||||
EditCollectionModal,
|
||||
useCollectionManager,
|
||||
} from '@affine/component/page-list';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
@@ -46,12 +46,12 @@ export const AddCollectionButton = ({
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
|
||||
<EditCollectionModel
|
||||
<EditCollectionModal
|
||||
propertiesMeta={workspace.meta.properties}
|
||||
getPageInfo={getPageInfo}
|
||||
onConfirm={setting.saveCollection}
|
||||
open={show}
|
||||
onClose={() => showUpdateCollection(false)}
|
||||
onOpenChange={showUpdateCollection}
|
||||
title={t['com.affine.editCollection.saveCollection']()}
|
||||
init={defaultCollection}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MenuItem as CollectionItem } from '@affine/component/app-sidebar';
|
||||
import {
|
||||
EditCollectionModel,
|
||||
EditCollectionModal,
|
||||
useCollectionManager,
|
||||
useSavedCollections,
|
||||
} from '@affine/component/page-list';
|
||||
@@ -203,13 +203,13 @@ const CollectionRenderer = ({
|
||||
|
||||
return (
|
||||
<Collapsible.Root open={!collapsed}>
|
||||
<EditCollectionModel
|
||||
<EditCollectionModal
|
||||
propertiesMeta={workspace.meta.properties}
|
||||
getPageInfo={getPageInfo}
|
||||
init={collection}
|
||||
onConfirm={setting.saveCollection}
|
||||
open={show}
|
||||
onClose={() => showUpdateCollection(false)}
|
||||
onOpenChange={showUpdateCollection}
|
||||
/>
|
||||
<CollectionItem
|
||||
data-testid="collection-item"
|
||||
|
||||
@@ -53,14 +53,14 @@ export type RootAppSidebarProps = {
|
||||
};
|
||||
|
||||
const RouteMenuLinkItem = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
HTMLDivElement,
|
||||
{
|
||||
currentPath: string; // todo: pass through useRouter?
|
||||
path: string;
|
||||
icon: ReactElement;
|
||||
children?: ReactElement;
|
||||
isDraggedOver?: boolean;
|
||||
} & React.HTMLAttributes<HTMLButtonElement>
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ currentPath, path, icon, children, isDraggedOver, ...props }, ref) => {
|
||||
// Force active style when a page is dragged over
|
||||
const active = isDraggedOver || currentPath === path;
|
||||
|
||||
Reference in New Issue
Block a user