From 2ec5f6fb60fea52c0d22db96404b2a3879d57feb Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Wed, 8 Feb 2023 18:11:27 +0800 Subject: [PATCH] feat: setting page with new design --- .../enable-workspace/EnableWorkspaceModal.tsx | 5 +- .../src/components/enable-workspace/index.tsx | 2 +- packages/app/src/components/header/styles.ts | 2 +- .../workspace-avatar/WorkspaceUnitAvatar.tsx | 6 +- .../workspace-setting/ExportPage.tsx | 32 ++-- .../workspace-setting/PublishPage.tsx | 139 ++++++-------- .../components/workspace-setting/SyncPage.tsx | 173 +++++++++--------- .../workspace-setting/general/General.tsx | 161 ++++++++-------- .../workspace-setting/general/style.ts | 52 +----- .../workspace-setting/member/MembersPage.tsx | 18 +- .../workspace-setting/member/style.ts | 21 --- .../src/components/workspace-setting/style.ts | 128 +++++-------- packages/app/src/pages/affine.tsx | 5 +- .../pages/workspace/[workspaceId]/setting.tsx | 9 +- packages/app/src/styles/theme.ts | 8 +- packages/app/src/ui/button/interface.ts | 2 +- packages/app/src/ui/button/styles.ts | 2 +- packages/app/src/ui/button/utils.ts | 13 ++ packages/app/src/ui/layout/Wrapper.tsx | 56 +++++- packages/i18n/src/resources/en.json | 10 +- packages/i18n/src/resources/zh-Hans.json | 10 +- 21 files changed, 404 insertions(+), 450 deletions(-) diff --git a/packages/app/src/components/enable-workspace/EnableWorkspaceModal.tsx b/packages/app/src/components/enable-workspace/EnableWorkspaceModal.tsx index fff76d86d8..95da09511e 100644 --- a/packages/app/src/components/enable-workspace/EnableWorkspaceModal.tsx +++ b/packages/app/src/components/enable-workspace/EnableWorkspaceModal.tsx @@ -89,7 +89,6 @@ const ContentTitle = styled('h1')({ lineHeight: '28px', fontWeight: 600, textAlign: 'center', - paddingBottom: '16px', }); const StyleTips = styled('div')(() => { @@ -97,8 +96,8 @@ const StyleTips = styled('div')(() => { userSelect: 'none', width: '400px', margin: 'auto', - marginBottom: '24px', - marginTop: '16px', + marginBottom: '32px', + marginTop: '12px', }; }); diff --git a/packages/app/src/components/enable-workspace/index.tsx b/packages/app/src/components/enable-workspace/index.tsx index ec63f21d9a..cd4d558ff8 100644 --- a/packages/app/src/components/enable-workspace/index.tsx +++ b/packages/app/src/components/enable-workspace/index.tsx @@ -9,7 +9,7 @@ export const EnableWorkspaceButton = () => { return ( <> + ); }; diff --git a/packages/app/src/components/workspace-setting/PublishPage.tsx b/packages/app/src/components/workspace-setting/PublishPage.tsx index a21c5b7d85..c2a1b258a2 100644 --- a/packages/app/src/components/workspace-setting/PublishPage.tsx +++ b/packages/app/src/components/workspace-setting/PublishPage.tsx @@ -1,11 +1,3 @@ -import { - StyledButtonContainer, - StyledPublishContent, - StyledPublishCopyContainer, - StyledPublishExplanation, - StyledSettingH2, - StyledStopPublishContainer, -} from './style'; import { useState } from 'react'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; @@ -14,6 +6,7 @@ import { WorkspaceUnit } from '@affine/datacenter'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; import { useTranslation } from '@affine/i18n'; import { EnableWorkspaceButton } from '../enable-workspace'; +import { Wrapper, Content, FlexWrapper } from '@/ui/layout'; export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const shareUrl = window.location.host + '/public-workspace/' + workspace.id; const { publishWorkspace } = useWorkspaceHelper(); @@ -33,82 +26,64 @@ export const PublishPage = ({ workspace }: { workspace: WorkspaceUnit }) => { toast(t('Copied link to clipboard')); }; + if (workspace.provider === 'affine') { + if (workspace.published) { + return ( + <> + {t('Published Description')} + + + {t('Share with link')} + + + + + + + + ); + } + + return ( + <> + {t('Publishing Description')} + + + ); + } + return ( <> - {workspace.provider === 'affine' ? ( -
- - {workspace.published ? ( - <> - - {t('Published Description')} - - - - - {t('Share with link')} - - - - - - - - ) : ( - - {t('Publishing Description')} -
- -
-
- )} -
- - {workspace.published ? ( - - - - ) : ( - <> - )} -
- ) : ( - - <> - - {t('Publishing')} - - -
- -
- -
- )} + {t('Publishing')} + ); }; diff --git a/packages/app/src/components/workspace-setting/SyncPage.tsx b/packages/app/src/components/workspace-setting/SyncPage.tsx index c90398153a..c98b06da46 100644 --- a/packages/app/src/components/workspace-setting/SyncPage.tsx +++ b/packages/app/src/components/workspace-setting/SyncPage.tsx @@ -1,97 +1,106 @@ import { - StyledButtonContainer, - StyledPublishContent, - StyledPublishExplanation, StyledWorkspaceName, StyledEmail, + // StyledDownloadCard, + // StyledDownloadCardDes, } from './style'; -// import { DownloadIcon } from '@blocksuite/icons'; -// import { Button } from '@/ui/button'; -// import { Menu, MenuItem } from '@/ui/menu'; import { WorkspaceUnit } from '@affine/datacenter'; import { useTranslation, Trans } from '@affine/i18n'; import { WorkspaceUnitAvatar } from '@/components/workspace-avatar'; import { EnableWorkspaceButton } from '../enable-workspace'; import { useAppState } from '@/providers/app-state-provider'; +import { FlexWrapper, Content, Wrapper } from '@/ui/layout'; + +// // FIXME: Temporary solution, since the @blocksuite/icons is broken +// const ActiveIcon = () => { +// return ( +// +// +// +// +// ); +// }; + export const SyncPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const { t } = useTranslation(); const { user } = useAppState(); + if (workspace.provider === 'local') { + return ( + <> + + + {workspace.name}  + {t('is a Local Workspace')} + +

{t('Local Workspace Description')}

+ + + + + ); + } return ( -
- - {workspace.provider === 'local' ? ( - <> - - - {workspace.name}  - {t('is a Local Workspace')} - -
{t('Local Workspace Description')}
- - - - - ) : ( - <> - - - {workspace.name}  - {t('is a Cloud Workspace')} - -
- - All data will be synchronised and saved to the AFFiNE account - - {{ - email: '{' + user?.email + '}.', - }} - - -
- {/* TODO: will finish the feature next version */} - {/* - - { - // deleteMember(workspace.id, 0); - }} - icon={} - > - {t('Download data', { CoreOrAll: t('core') })} - - { - // deleteMember(workspace.id, 0); - }} - icon={} - > - {t('Download data', { CoreOrAll: t('all') })} - - - } - placement="bottom-end" - disablePortal={true} - > - - - */} - - )} -
-
+ <> + + + {workspace.name}  + {t('is a Cloud Workspace')} + + + All data will be synchronised and saved to the AFFiNE account + + {{ + email: '{' + user?.email + '}.', + }} + + + + {/**/} + {/* {t('Data sync mode')}*/} + {/**/} + {/**/} + {/* */} + {/* */} + {/* {t('Download all data')}*/} + {/* */} + {/* {t('It takes up more space on your device.')}*/} + {/* */} + {/* */} + + {/* */} + {/* */} + {/* {t('Download core data')}*/} + {/* */} + {/* {t('It takes up little space on your device.')}*/} + {/* */} + {/* */} + {/**/} + ); }; diff --git a/packages/app/src/components/workspace-setting/general/General.tsx b/packages/app/src/components/workspace-setting/general/General.tsx index ca2cf197b7..241c97f060 100644 --- a/packages/app/src/components/workspace-setting/general/General.tsx +++ b/packages/app/src/components/workspace-setting/general/General.tsx @@ -1,23 +1,13 @@ -import { - StyledDeleteButtonContainer, - // StyledSettingAvatar, - StyledSettingAvatarContent, - StyledSettingInputContainer, - StyledDoneButtonContainer, - StyledInput, - StyledProviderInfo, - StyleGeneral, - StyledAvatar, -} from './style'; -import { StyledSettingH2 } from '../style'; +import { StyledInput, StyledProviderInfo, StyledAvatar } from './style'; +import { StyledSettingKey, StyledRow } from '../style'; +import { FlexWrapper, Content } from '@/ui/layout'; import { useState } from 'react'; import { Button } from '@/ui/button'; import { useAppState } from '@/providers/app-state-provider'; import { WorkspaceDelete } from './delete'; import { WorkspaceLeave } from './leave'; -import { DoneIcon, UsersIcon } from '@blocksuite/icons'; -// import { Upload } from '@/components/file-upload'; +import { UsersIcon } from '@blocksuite/icons'; import { WorkspaceUnitAvatar } from '@/components/workspace-avatar'; import { WorkspaceUnit } from '@affine/datacenter'; import { useWorkspaceHelper } from '@/hooks/use-workspace-helper'; @@ -33,9 +23,6 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => { const { updateWorkspace } = useWorkspaceHelper(); const { t } = useTranslation(); - const handleChangeWorkSpaceName = (newName: string) => { - setWorkspaceName(newName); - }; const handleUpdateWorkspaceName = () => { currentWorkspace && updateWorkspace({ name: workspaceName }, currentWorkspace); @@ -47,72 +34,93 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => { (await updateWorkspace({ avatarBlob: blob }, currentWorkspace)); }; - return workspace ? ( - -
- {t('Workspace Avatar')} - - - - <> -
- -
- - -
-
- {/* TODO: Wait for image sync to complete */} - {/* - - */} - {/* TODO: add upload logic */} -
- {t('Workspace Name')} - + if (!workspace) { + return null; + } + + return ( + <> + + {t('Workspace Avatar')} + + + <> +
+ +
+ + +
+
+
+ + + {t('Workspace Name')} + { + setWorkspaceName(newName); + }} > - {isOwner ? ( - { - handleUpdateWorkspaceName(); - }} - > - - - ) : null} -
- {t('Workspace Type')} - + {isOwner && ( + <> + + + + )} + + + + + {t('Workspace Type')} + {isOwner ? ( currentWorkspace?.provider === 'local' ? ( - + - {t('Local Workspace')} - + + {t('Local Workspace')} + + ) : ( - + - {t('Available Offline')} - + + {t('Available Offline')} + + ) ) : ( @@ -120,10 +128,11 @@ export const GeneralPage = ({ workspace }: { workspace: WorkspaceUnit }) => { {t('Joined Workspace')} )} - -
+ + - + + {t('Delete Workspace')} {isOwner ? ( <> + - diff --git a/packages/app/src/pages/workspace/[workspaceId]/setting.tsx b/packages/app/src/pages/workspace/[workspaceId]/setting.tsx index ffab84524c..8754e52a7e 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/setting.tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/setting.tsx @@ -11,6 +11,7 @@ import { MembersPage, PublishPage, SyncPage, + ExportPage, } from '@/components/workspace-setting'; import { SettingsIcon } from '@blocksuite/icons'; import { useAppState } from '@/providers/app-state-provider'; @@ -43,10 +44,10 @@ const useTabMap = () => { panelRender: workspace => , }, // TODO: next version will finish this feature - // { - // name: t('Export'), - // panelRender: workspace => , - // }, + { + name: t('Export'), + panelRender: workspace => , + }, ]; const [activeTab, setActiveTab] = useState(tabMap[0].name); const handleTabChange = (tab: string) => { diff --git a/packages/app/src/styles/theme.ts b/packages/app/src/styles/theme.ts index cde3ac6961..58e05d0800 100644 --- a/packages/app/src/styles/theme.ts +++ b/packages/app/src/styles/theme.ts @@ -15,7 +15,7 @@ export const getLightTheme = ( primaryColor: '#6880FF', pageBackground: '#fff', - hoverBackground: '#F1F1F4', + hoverBackground: '#F1F3FF', innerHoverBackground: '#E9E9EC', popoverBackground: '#fff', tooltipBackground: '#6880FF', @@ -38,9 +38,9 @@ export const getLightTheme = ( tooltipColor: '#fff', codeColor: '#517ea6', quoteColor: '#4C6275', - placeHolderColor: '#555770', + placeHolderColor: '#888A9E', selectedColor: 'rgba(104, 128, 255, 0.1)', - borderColor: '#555770', + borderColor: '#E3E2E4', disableColor: '#555770', warningColor: '#906616', errorColor: '#EB4335', @@ -56,7 +56,7 @@ export const getLightTheme = ( h6: '18px', base: '16px', xs: '14px', - sm: '14px', + sm: '12px', family: `Avenir Next, Poppins, ${basicFontFamily}`, numberFamily: `Roboto Mono, ${basicFontFamily}`, diff --git a/packages/app/src/ui/button/interface.ts b/packages/app/src/ui/button/interface.ts index 150afa648b..d198db55dd 100644 --- a/packages/app/src/ui/button/interface.ts +++ b/packages/app/src/ui/button/interface.ts @@ -19,7 +19,7 @@ export type ButtonProps = PropsWithChildren & icon?: ReactElement; iconPosition?: 'start' | 'end'; shape?: 'default' | 'round' | 'circle'; - type?: 'primary' | 'warning' | 'danger' | 'default'; + type?: 'primary' | 'light' | 'warning' | 'danger' | 'default'; bold?: boolean; loading?: boolean; noBorder?: boolean; diff --git a/packages/app/src/ui/button/styles.ts b/packages/app/src/ui/button/styles.ts index 74f6092402..860762c710 100644 --- a/packages/app/src/ui/button/styles.ts +++ b/packages/app/src/ui/button/styles.ts @@ -213,7 +213,7 @@ export const StyledButton = styled('button', { }, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - ...getButtonColors(theme, type, { + ...getButtonColors(theme, type, disabled, { hoverBackground, hoverColor, hoverStyle, diff --git a/packages/app/src/ui/button/utils.ts b/packages/app/src/ui/button/utils.ts index fddfa5df6e..b883cf0fce 100644 --- a/packages/app/src/ui/button/utils.ts +++ b/packages/app/src/ui/button/utils.ts @@ -40,6 +40,7 @@ export const getSize = ( export const getButtonColors = ( theme: AffineTheme, type: ButtonProps['type'], + disabled: boolean, extend?: { hoverBackground: ButtonProps['hoverBackground']; hoverColor: ButtonProps['hoverColor']; @@ -56,6 +57,18 @@ export const getButtonColors = ( color: '#fff', }, }; + case 'light': + return { + background: theme.colors.hoverBackground, + color: disabled ? theme.colors.disableColor : theme.colors.primaryColor, + borderColor: theme.colors.hoverBackground, + '.affine-button-icon': { + borderColor: theme.colors.primaryColor, + }, + ':hover': { + borderColor: theme.colors.primaryColor, + }, + }; case 'warning': return { background: theme.colors.warningBackground, diff --git a/packages/app/src/ui/layout/Wrapper.tsx b/packages/app/src/ui/layout/Wrapper.tsx index a463312abf..2f5d9d46e7 100644 --- a/packages/app/src/ui/layout/Wrapper.tsx +++ b/packages/app/src/ui/layout/Wrapper.tsx @@ -6,7 +6,15 @@ export type WrapperProps = { width?: CSSProperties['width']; height?: CSSProperties['height']; padding?: CSSProperties['padding']; + paddingTop?: CSSProperties['paddingTop']; + paddingRight?: CSSProperties['paddingRight']; + paddingLeft?: CSSProperties['paddingLeft']; + paddingBottom?: CSSProperties['paddingBottom']; margin?: CSSProperties['margin']; + marginTop?: CSSProperties['marginTop']; + marginLeft?: CSSProperties['marginLeft']; + marginRight?: CSSProperties['marginRight']; + marginBottom?: CSSProperties['marginBottom']; }; export type FlexWrapperProps = { @@ -22,17 +30,55 @@ export type FlexWrapperProps = { // Sometimes we just want to wrap a component with a div to set flex or other styles, but we don't want to create a new component for it. export const Wrapper = styled('div', { shouldForwardProp: prop => { - return !['display', 'width', 'height', 'padding', 'margin'].includes(prop); + return ![ + 'display', + 'width', + 'height', + 'padding', + 'margin', + 'paddingTop', + 'paddingRight', + 'paddingLeft', + 'paddingBottom', + 'marginTop', + 'marginLeft', + 'marginRight', + 'marginBottom', + ].includes(prop); }, -})(({ display, width, height, padding, margin }) => { - return { +})( + ({ display, width, height, padding, margin, - }; -}); + paddingTop, + paddingRight, + paddingLeft, + paddingBottom, + marginTop, + marginLeft, + marginRight, + marginBottom, + }) => { + return { + display, + width, + height, + padding, + margin, + paddingTop, + paddingRight, + paddingLeft, + paddingBottom, + marginTop, + marginLeft, + marginRight, + marginBottom, + }; + } +); export const FlexWrapper = styled(Wrapper, { shouldForwardProp: prop => { diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json index 448a19db5c..c195c9bafe 100644 --- a/packages/i18n/src/resources/en.json +++ b/packages/i18n/src/resources/en.json @@ -35,6 +35,7 @@ "Permanently deleted": "Permanently deleted", "restored": "{{title}} restored", "Cancel": "Cancel", + "Confirm": "Confirm", "Keyboard Shortcuts": "Keyboard Shortcuts", "Contact Us": "Contact Us", "Official Website": "Official Website", @@ -133,6 +134,7 @@ "Share with link": "Share with link", "Copy Link": "Copy Link", "Publishing Description": "After publishing to the web, everyone can view the content of this workspace through the link.", + "Export Description": "You can export the entire Workspace data for backup, and the exported data can be re-impored.", "Stop publishing": "Stop publishing", "Publish to web": "Publish to web", "Download data": "Download {{CoreOrAll}} data", @@ -174,5 +176,11 @@ "Cloud Workspace Description": "All data will be synchronized and saved to the AFFiNE account <1>{{email}}", "Download data Description1": "It takes up more space on your device.", "Download data Description2": "It takes up little space on your device.", - "Enabled success": "Enabled success" + "Enabled success": "Enabled success", + "Export AFFINE backup file (coming soon)": "Export AFFINE backup file (coming soon)", + "Data sync mode": "Data sync mode", + "Download all data": "Download all data", + "It takes up more space on your device.": "It takes up more space on your device.", + "Download core data": "Download core data", + "It takes up little space on your device.": "It takes up little space on your device." } diff --git a/packages/i18n/src/resources/zh-Hans.json b/packages/i18n/src/resources/zh-Hans.json index 93f4a2e351..6ed058b3a3 100644 --- a/packages/i18n/src/resources/zh-Hans.json +++ b/packages/i18n/src/resources/zh-Hans.json @@ -39,6 +39,7 @@ "Permanently deleted": "已永久删除", "restored": "{{title}} 已恢复", "Cancel": "取消", + "Confirm": "确定", "Keyboard Shortcuts": "键盘快捷键", "Contact Us": "联系我们", "Official Website": "官网", @@ -133,6 +134,7 @@ "Share with link": "通过链接分享", "Copy Link": "复制链接", "Publishing Description": "发布到web后,所有人都可以通过链接查看此工作区的内容。", + "Export Description": "您可以导出整个Workspace数据进行备份,并且可以重新导入导出的数据。", "Stop publishing": "中止发布", "Publish to web": "发布到web", "Sync Description": "{{workspaceName}}是本地工作区,所有数据都存储在当前设备上。您可以为此工作区启用AFFiNE Cloud,以使数据与云端保持同步。", @@ -145,5 +147,11 @@ "Workspace Settings": "工作区设置", "core": "核心", "all": "全部", - "A workspace is your virtual space to capture, create and plan as just one person or together as a team.": "工作空间是一个人或一个团队创建和计划的虚拟空间。" + "A workspace is your virtual space to capture, create and plan as just one person or together as a team.": "工作空间是一个人或一个团队创建和计划的虚拟空间。", + "Export AFFINE backup file (coming soon)": "导出 AFFiNE 备份文件(即将上线)", + "Data sync mode": "数据同步模式", + "Download all data": "下载全部数据", + "It takes up more space on your device.": "占用设备更多空间。", + "Download core data": "下载核心数据", + "It takes up little space on your device.": "占用设备较少空间。" }