Merge branches 'feat/poc' and 'feat/poc' of github.com:toeverything/AFFiNE into feat/poc

This commit is contained in:
JimmFly
2023-01-06 15:04:16 +08:00
10 changed files with 462 additions and 393 deletions

View File

@@ -9,7 +9,6 @@ import {
setActiveWorkspace,
Login,
User,
getUserInfo,
SignOut,
updateWorkspaceMeta,
} from '@/hooks/mock-data/mock';
@@ -23,6 +22,7 @@ import {
import { useConfirm } from '@/providers/confirm-provider';
import { toast } from '@/ui/toast';
import { WorkspaceAvatar } from '@/components/workspace-avatar';
import useTemporaryHelper from '@/hooks/use-temporary-helper';
interface LoginModalProps {
open: boolean;
onClose: () => void;
@@ -30,23 +30,17 @@ interface LoginModalProps {
export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
const [workspaceList, setWorkspaceList] = useState<Workspace[]>([]);
const [user, setUser] = useState<User | null>();
const [createWorkspaceOpen, setCreateWorkspaceOpen] = useState(false);
const { confirm } = useConfirm();
const { user, login } = useTemporaryHelper();
useEffect(() => {
setList();
setUserInfo();
}, []);
const setList = () => {
const data = getWorkspaces();
console.log('data: ', data);
setWorkspaceList(data);
};
const setUserInfo = () => {
const data = getUserInfo();
setUser(data);
};
return (
<div>
@@ -153,9 +147,8 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
{!user ? (
<Button
onClick={() => {
Login();
login();
toast('login success');
setUserInfo();
}}
>
Sign in AFFiNE Cloud
@@ -164,7 +157,6 @@ export const WorkspaceModal = ({ open, onClose }: LoginModalProps) => {
<Button
onClick={() => {
SignOut();
setUserInfo();
}}
>
Sign out of AFFiNE Cloud

View File

@@ -0,0 +1,198 @@
import {
StyledMemberAvatar,
StyledMemberButtonContainer,
StyledMemberEmail,
StyledMemberInfo,
StyledMemberListContainer,
StyledMemberListItem,
StyledMemberName,
StyledMemberNameContainer,
StyledMemberRoleContainer,
StyledMemberTitleContainer,
StyledMoreVerticalButton,
} from './style';
import { MoreVerticalIcon, EmailIcon, TrashIcon } from '@blocksuite/icons';
import { useEffect, useState } from 'react';
import { Button, IconButton } from '@/ui/button';
import { InviteMembers } from '../invite-members/index';
// import { Member, getDataCenter } from '@affine/datacenter';
// import { Avatar } from '@mui/material';
import { Menu, MenuItem } from '@/ui/menu';
import { Empty } from '@/ui/empty';
import {
deleteMember,
getMembers,
getUserInfo,
Login,
User,
Workspace,
} from '@/hooks/mock-data/mock';
// import { useAppState } from '@/providers/app-state-provider';
export const MembersPage = ({ workspace }: { workspace: Workspace }) => {
const [isInviteModalShow, setIsInviteModalShow] = useState(false);
const [members, setMembers] = useState<User[]>([]);
const [userInfo, setUserInfo] = useState<User>();
// const refreshMembers = useCallback(() => {
// getDataCenter()
// .then(dc =>
// dc.apis.getWorkspaceMembers({
// id: workspace.id,
// })
// )
// .then(data => {
// setMembers(data);
// })
// .catch(err => {
// console.log(err);
// });
// }, [workspace.id]);
useEffect(() => {
setUser();
setMembersList();
// refreshMembers();
}, []);
const setUser = () => {
const user = getUserInfo();
user && setUserInfo(user);
};
const setMembersList = () => {
const members = getMembers(workspace.id);
members && setMembers(members);
};
return (
<div>
{userInfo ? (
<>
<StyledMemberTitleContainer>
<StyledMemberNameContainer>
Users({members.length})
</StyledMemberNameContainer>
<StyledMemberRoleContainer>Access level</StyledMemberRoleContainer>
</StyledMemberTitleContainer>
<StyledMemberListContainer>
{members.length === 0 && (
<Empty
width={648}
sx={{ marginTop: '60px' }}
height={300}
></Empty>
)}
{members.length ? (
members.map((member, index) => {
return (
<StyledMemberListItem key={index}>
<StyledMemberNameContainer>
<StyledMemberAvatar alt="member avatar">
<EmailIcon></EmailIcon>
</StyledMemberAvatar>
<StyledMemberInfo>
<StyledMemberName>{member.name}</StyledMemberName>
<StyledMemberEmail>{member.email}</StyledMemberEmail>
</StyledMemberInfo>
</StyledMemberNameContainer>
<StyledMemberRoleContainer>
{/* {member.accepted
? member.type !== 99
? 'Member'
: 'Workspace Owner'
: 'Pending'} */}
Pending
</StyledMemberRoleContainer>
<StyledMoreVerticalButton>
<Menu
content={
<>
<MenuItem
onClick={() => {
deleteMember(workspace.id, 0);
setMembersList();
// confirm({
// title: 'Delete Member?',
// content: `will delete member`,
// confirmText: 'Delete',
// confirmType: 'danger',
// }).then(confirm => {
// getDataCenter()
// .then(dc =>
// dc.apis.removeMember({
// permissionId: member.id,
// })
// )
// .then(() => {
// // console.log('data: ', data);
// toast('Moved to Trash');
// // refreshMembers();
// });
// });
}}
icon={<TrashIcon />}
>
Delete
</MenuItem>
</>
}
placement="bottom-end"
disablePortal={true}
>
<IconButton>
<MoreVerticalIcon />
</IconButton>
</Menu>
</StyledMoreVerticalButton>
</StyledMemberListItem>
);
})
) : (
<></>
)}
</StyledMemberListContainer>
<StyledMemberButtonContainer>
<Button
onClick={() => {
setIsInviteModalShow(true);
}}
type="primary"
shape="circle"
>
Invite Members
</Button>
<InviteMembers
onClose={() => {
setIsInviteModalShow(false);
}}
onInviteSuccess={() => {
setMembersList();
setIsInviteModalShow(false);
// refreshMembers();
}}
workspaceId={workspace.id}
open={isInviteModalShow}
></InviteMembers>
</StyledMemberButtonContainer>
</>
) : (
<>
<div>
Collaborating with other members requires AFFiNE Cloud service.
</div>
<div>
<Button
onClick={() => {
Login();
setUser();
}}
>
Enable AFFiNE Cloud
</Button>
</div>
</>
)}
</div>
);
};

View File

@@ -0,0 +1,122 @@
import {
StyledCopyButtonContainer,
StyledPublishContent,
StyledPublishCopyContainer,
StyledPublishExplanation,
StyledSettingH2,
} from './style';
import { Button } from '@/ui/button';
import Input from '@/ui/input';
import { toast } from '@/ui/toast';
import { Workspace } from '@/hooks/mock-data/mock';
import useTemporaryHelper from '@/hooks/use-temporary-helper';
import { useConfirm } from '@/providers/confirm-provider';
export const PublishPage = ({ workspace }: { workspace: Workspace }) => {
const shareUrl =
window.location.host + '/workspace/' + workspace.id + '?share=true';
const { login, updateWorkspaceMeta, user, currentWorkspace } =
useTemporaryHelper();
const { confirm } = useConfirm();
const togglePublic = (flag: boolean) => {
updateWorkspaceMeta(currentWorkspace.id, { isPublish: flag });
};
const copyUrl = () => {
navigator.clipboard.writeText(shareUrl);
toast('Copied url to clipboard');
};
const enableAffineCloud = () => {
confirm({
title: 'Enable AFFiNE Cloud?',
content: `If enabled, the data in this workspace will be backed up and synchronized via AFFiNE Cloud.`,
confirmText: user ? 'Enable' : 'Sign in and Enable',
cancelText: 'Skip',
}).then(confirm => {
if (user) {
updateWorkspaceMeta(currentWorkspace.id, { isPublish: true });
} else {
confirm && login();
updateWorkspaceMeta(currentWorkspace.id, { isPublish: true });
}
});
};
return (
<>
{currentWorkspace.type === 'cloud' ? (
<div>
<StyledPublishContent>
{currentWorkspace?.isPublish ? (
<>
<StyledPublishExplanation>
Publishing to web requires AFFiNE Cloud service .
</StyledPublishExplanation>
<StyledSettingH2 marginTop={48}>
Share with link
</StyledSettingH2>
<StyledPublishCopyContainer>
<Input width={500} value={shareUrl} disabled={true}></Input>
<StyledCopyButtonContainer>
<Button onClick={copyUrl} type="primary" shape="circle">
Copy Link
</Button>
</StyledCopyButtonContainer>
</StyledPublishCopyContainer>
</>
) : (
<StyledPublishExplanation>
After publishing to the web, everyone can view the content of
this workspace through the link.
</StyledPublishExplanation>
)}
</StyledPublishContent>
{!currentWorkspace?.isPublish ? (
<Button
onClick={() => {
togglePublic(true);
}}
type="primary"
shape="circle"
>
Publish to web
</Button>
) : (
<Button
onClick={() => {
togglePublic(false);
}}
type="primary"
shape="circle"
>
Stop publishing
</Button>
)}
</div>
) : (
<StyledPublishContent>
<>
<StyledPublishExplanation>
Publishing to web requires AFFiNE Cloud service.
</StyledPublishExplanation>
<StyledPublishCopyContainer>
<Button
onClick={() => {
enableAffineCloud();
}}
type="primary"
shape="circle"
>
Enable AFFiNE Cloud
</Button>
</StyledPublishCopyContainer>
</>
</StyledPublishContent>
)}
</>
);
};

View File

@@ -0,0 +1,91 @@
import {
StyledPublishContent,
StyledPublishCopyContainer,
StyledPublishExplanation,
} from './style';
import { DownloadIcon } from '@blocksuite/icons';
import { useEffect, useState } from 'react';
import { Button } from '@/ui/button';
import { Menu, MenuItem } from '@/ui/menu';
import {
deleteMember,
getActiveWorkspace,
updateWorkspaceMeta,
Workspace,
} from '@/hooks/mock-data/mock';
export const SyncPage = ({ workspace }: { workspace: Workspace }) => {
const [workspaceType, setWorkspaceType] = useState('local');
useEffect(() => {
setType();
});
const setType = () => {
const ACTIVEworkspace = getActiveWorkspace();
ACTIVEworkspace && setWorkspaceType(ACTIVEworkspace.type);
};
return (
<div>
<StyledPublishContent>
{workspaceType === 'local' ? (
<>
<StyledPublishExplanation>
{workspace.name} 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.
</StyledPublishExplanation>
<StyledPublishCopyContainer>
<Button
onClick={() => {
updateWorkspaceMeta(workspace.id, {
type: 'cloud',
});
setType();
}}
type="primary"
shape="circle"
>
Enable AFFiNE Cloud
</Button>
</StyledPublishCopyContainer>
</>
) : (
<>
<StyledPublishExplanation>
<code>{workspace.name}</code> is Cloud Workspace. All data will be
synchronized and saved to the AFFiNE
</StyledPublishExplanation>
<StyledPublishCopyContainer>
<Menu
content={
<>
<MenuItem
onClick={() => {
deleteMember(workspace.id, 0);
}}
icon={<DownloadIcon />}
>
Download core data to device
</MenuItem>
<MenuItem
onClick={() => {
deleteMember(workspace.id, 0);
}}
icon={<DownloadIcon />}
>
Download all data to device
</MenuItem>
</>
}
placement="bottom-end"
disablePortal={true}
>
<Button>Download all data to device</Button>
</Menu>
</StyledPublishCopyContainer>
</>
)}
</StyledPublishContent>
</div>
);
};

View File

@@ -14,20 +14,22 @@ import { Button } from '@/ui/button';
import { getDataCenter } from '@affine/datacenter';
import { useRouter } from 'next/router';
import { useAppState } from '@/providers/app-state-provider';
import { deleteWorkspace, getWorkspaces } from '@/hooks/mock-data/mock';
import {
deleteWorkspace,
getWorkspaces,
Workspace,
} from '@/hooks/mock-data/mock';
interface WorkspaceDeleteProps {
open: boolean;
onClose: () => void;
workspaceName: string;
workspaceId: string;
workspace: Workspace;
}
export const WorkspaceDelete = ({
open,
onClose,
workspaceId,
workspaceName,
workspace,
}: WorkspaceDeleteProps) => {
const [deleteStr, setDeleteStr] = useState<string>('');
const router = useRouter();
@@ -40,7 +42,7 @@ export const WorkspaceDelete = ({
// const dc = await getDataCenter();
// await dc.apis.deleteWorkspace({ id: workspaceId });
// router.push(`/workspace/${nextWorkSpaceId}`);
deleteWorkspace(workspaceId);
deleteWorkspace(workspace.id);
const workspaceList = getWorkspaces();
if (workspaceList.length) {
router.push(`/workspace/${workspaceList[0].id}`);
@@ -55,11 +57,20 @@ export const WorkspaceDelete = ({
<StyledModalWrapper>
<ModalCloseButton onClick={onClose} />
<StyledModalHeader>Delete Workspace</StyledModalHeader>
<StyledTextContent>
This action cannot be undone. This will permanently delete (
<StyledWorkspaceName>{workspaceName}</StyledWorkspaceName>) along with
all its content.
</StyledTextContent>
{workspace.type === 'local' ? (
<StyledTextContent>
Deleting (
<StyledWorkspaceName>{workspace.name}</StyledWorkspaceName>) cannot
be undone, please proceed with caution. along with all its content.
</StyledTextContent>
) : (
<StyledTextContent>
Deleting (
<StyledWorkspaceName>{workspace.name}</StyledWorkspaceName>) will
delete both local and cloud data, this operation cannot be undone,
please proceed with caution.
</StyledTextContent>
)}
<StyledInputContent>
<Input
onChange={handlerInputChange}

View File

@@ -16,7 +16,8 @@ export const StyledModalHeader = styled('div')(({ theme }) => {
width: '460px',
fontWeight: '600',
fontSize: '20px;',
textAlign: 'center',
textAlign: 'left',
paddingLeft: '20px',
color: theme.colors.popoverColor,
};
});
@@ -32,7 +33,7 @@ export const StyledTextContent = styled('div')(() => {
fontWeight: '400',
fontSize: '18px',
lineHeight: '26px',
textAlign: 'center',
textAlign: 'left',
};
});
@@ -41,7 +42,7 @@ export const StyledInputContent = styled('div')(() => {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
margin: '40px 0 24px 0',
margin: '20px 0 24px 0',
};
});

View File

@@ -77,11 +77,8 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
return workspace ? (
<div>
<StyledSettingH2 marginTop={56}>Workspace Avatar</StyledSettingH2>
<StyledSettingH2 marginTop={56}>Workspace Icon</StyledSettingH2>
<StyledSettingAvatarContent>
{/* <StyledSettingAvatar alt="workspace avatar" src={''}>
AFFiNE
</StyledSettingAvatar> */}
<div
style={{
float: 'left',
@@ -98,10 +95,6 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
<Button loading={uploading}>Upload</Button>
</Upload>
{/* TODO: add upload logic */}
{/* {isOwner ? (
<StyledAvatarUploadBtn shape="round">upload</StyledAvatarUploadBtn>
) : null} */}
{/* <Button shape="round">remove</Button> */}
</StyledSettingAvatarContent>
<StyledSettingH2 marginTop={20}>Workspace Name</StyledSettingH2>
<StyledSettingInputContainer>
@@ -122,7 +115,7 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
</TextButton>
</StyledSettingInputContainer>
{userInfo ? (
{/* {userInfo ? (
<div>
<StyledSettingH2 marginTop={20}>Workspace Owner</StyledSettingH2>
<StyledSettingInputContainer>
@@ -136,7 +129,7 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
</div>
) : (
''
)}
)} */}
<StyledSettingH2 marginTop={20}>Workspace Type</StyledSettingH2>
<StyledSettingInputContainer>
@@ -151,8 +144,7 @@ export const GeneralPage = ({ workspace }: { workspace: Workspace }) => {
<WorkspaceDelete
open={showDelete}
onClose={handleCloseDelete}
workspaceName={workspaceName}
workspaceId={workspace.id}
workspace={workspace}
/>
</>
) : (

View File

@@ -199,11 +199,12 @@ export const StyledMoreVerticalButton = styled('button')(() => {
export const StyledPublishExplanation = styled('div')(() => {
return {
marginTop: '56px',
paddingRight: '48px',
fontWeight: '500',
fontSize: '18px',
lineHeight: '26px',
flex: 1,
marginTop: '60px',
};
});
@@ -213,7 +214,9 @@ export const StyledPublishCopyContainer = styled('div')(() => {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
height: '38px',
paddingTop: '20px',
};
});
@@ -226,5 +229,7 @@ export const StyledCopyButtonContainer = styled('div')(() => {
export const StyledPublishContent = styled('div')(() => {
return {
height: '494px',
display: 'flex',
flexDirection: 'column',
};
});

View File

@@ -1,23 +1,7 @@
import Modal, { ModalCloseButton } from '@/ui/modal';
import {
StyledCopyButtonContainer,
StyledMemberAvatar,
StyledMemberButtonContainer,
StyledMemberEmail,
StyledMemberInfo,
StyledMemberListContainer,
StyledMemberListItem,
StyledMemberName,
StyledMemberNameContainer,
StyledMemberRoleContainer,
StyledMemberTitleContainer,
StyledMoreVerticalButton,
StyledPublishContent,
StyledPublishCopyContainer,
StyledPublishExplanation,
StyledSettingContainer,
StyledSettingContent,
StyledSettingH2,
StyledSettingSidebar,
StyledSettingSidebarHeader,
StyledSettingTabContainer,
@@ -28,34 +12,14 @@ import {
EditIcon,
UsersIcon,
PublishIcon,
MoreVerticalIcon,
EmailIcon,
TrashIcon,
DownloadIcon,
CloudInsyncIcon,
} from '@blocksuite/icons';
import { useEffect, useState } from 'react';
import { Button, IconButton } from '@/ui/button';
import Input from '@/ui/input';
import { InviteMembers } from '../invite-members/index';
// import { Member, getDataCenter } from '@affine/datacenter';
// import { Avatar } from '@mui/material';
import { Menu, MenuItem } from '@/ui/menu';
import { toast } from '@/ui/toast';
import { Empty } from '@/ui/empty';
// import { useAppState } from '@/providers/app-state-provider';
import { GeneralPage } from './general';
import {
deleteMember,
getActiveWorkspace,
getMembers,
getUserInfo,
Login,
setWorkspacePublish,
updateWorkspaceMeta,
User,
Workspace,
} from '@/hooks/mock-data/mock';
import { getActiveWorkspace } from '@/hooks/mock-data/mock';
import MembersPage from './MembersPage';
import PublishPage from './PublishPage';
import SyncPage from './SyncPage';
enum ActiveTab {
'general' = 'general',
@@ -192,313 +156,3 @@ export const WorkspaceSetting = ({
</Modal>
);
};
const MembersPage = ({ workspace }: { workspace: Workspace }) => {
const [isInviteModalShow, setIsInviteModalShow] = useState(false);
const [members, setMembers] = useState<User[]>([]);
const [userInfo, setUserInfo] = useState<User>();
// const refreshMembers = useCallback(() => {
// getDataCenter()
// .then(dc =>
// dc.apis.getWorkspaceMembers({
// id: workspace.id,
// })
// )
// .then(data => {
// setMembers(data);
// })
// .catch(err => {
// console.log(err);
// });
// }, [workspace.id]);
useEffect(() => {
setUser();
setMembersList();
// refreshMembers();
}, []);
const setUser = () => {
const user = getUserInfo();
user && setUserInfo(user);
};
const setMembersList = () => {
const members = getMembers(workspace.id);
members && setMembers(members);
};
return (
<div>
{userInfo ? (
<>
<StyledMemberTitleContainer>
<StyledMemberNameContainer>
Users({members.length})
</StyledMemberNameContainer>
<StyledMemberRoleContainer>Access level</StyledMemberRoleContainer>
</StyledMemberTitleContainer>
<StyledMemberListContainer>
{members.length === 0 && (
<Empty
width={648}
sx={{ marginTop: '60px' }}
height={300}
></Empty>
)}
{members.length ? (
members.map((member, index) => {
return (
<StyledMemberListItem key={index}>
<StyledMemberNameContainer>
<StyledMemberAvatar alt="member avatar">
<EmailIcon></EmailIcon>
</StyledMemberAvatar>
<StyledMemberInfo>
<StyledMemberName>{member.name}</StyledMemberName>
<StyledMemberEmail>{member.email}</StyledMemberEmail>
</StyledMemberInfo>
</StyledMemberNameContainer>
<StyledMemberRoleContainer>
{/* {member.accepted
? member.type !== 99
? 'Member'
: 'Workspace Owner'
: 'Pending'} */}
Pending
</StyledMemberRoleContainer>
<StyledMoreVerticalButton>
<Menu
content={
<>
<MenuItem
onClick={() => {
deleteMember(workspace.id, 0);
setMembersList();
// confirm({
// title: 'Delete Member?',
// content: `will delete member`,
// confirmText: 'Delete',
// confirmType: 'danger',
// }).then(confirm => {
// getDataCenter()
// .then(dc =>
// dc.apis.removeMember({
// permissionId: member.id,
// })
// )
// .then(() => {
// // console.log('data: ', data);
// toast('Moved to Trash');
// // refreshMembers();
// });
// });
}}
icon={<TrashIcon />}
>
Delete
</MenuItem>
</>
}
placement="bottom-end"
disablePortal={true}
>
<IconButton>
<MoreVerticalIcon />
</IconButton>
</Menu>
</StyledMoreVerticalButton>
</StyledMemberListItem>
);
})
) : (
<></>
)}
</StyledMemberListContainer>
<StyledMemberButtonContainer>
<Button
onClick={() => {
setIsInviteModalShow(true);
}}
type="primary"
shape="circle"
>
Invite Members
</Button>
<InviteMembers
onClose={() => {
setIsInviteModalShow(false);
}}
onInviteSuccess={() => {
setMembersList();
setIsInviteModalShow(false);
// refreshMembers();
}}
workspaceId={workspace.id}
open={isInviteModalShow}
></InviteMembers>
</StyledMemberButtonContainer>
</>
) : (
<>
<div>
Collaborating with other members requires AFFiNE Cloud service.
</div>
<div>
<Button
onClick={() => {
Login();
setUser();
}}
>
Enable AFFiNE Cloud
</Button>
</div>
</>
)}
</div>
);
};
const PublishPage = ({ workspace }: { workspace: Workspace }) => {
const shareUrl =
window.location.host + '/workspace/' + workspace.id + '?share=true';
const [publicStatus, setPublicStatus] = useState<boolean | null>(
workspace.isPublish ?? false
);
const togglePublic = (flag: boolean) => {
const isPublic = setWorkspacePublish(workspace.id, flag);
setPublicStatus(isPublic);
};
const copyUrl = () => {
navigator.clipboard.writeText(shareUrl);
toast('Copied url to clipboard');
};
return (
<div>
<StyledPublishContent>
{publicStatus ? (
<>
<StyledPublishExplanation>
The current workspace has been published to the web, everyone can
view the contents of this workspace through the link.
</StyledPublishExplanation>
<StyledSettingH2 marginTop={48}>Share with link</StyledSettingH2>
<StyledPublishCopyContainer>
<Input width={500} value={shareUrl} disabled={true}></Input>
<StyledCopyButtonContainer>
<Button onClick={copyUrl} type="primary" shape="circle">
Copy Link
</Button>
</StyledCopyButtonContainer>
</StyledPublishCopyContainer>
</>
) : (
<StyledPublishExplanation>
After publishing to the web, everyone can view the content of this
workspace through the link.
</StyledPublishExplanation>
)}
</StyledPublishContent>
{!publicStatus ? (
<Button
onClick={() => {
togglePublic(true);
}}
type="primary"
shape="circle"
>
Publish to web
</Button>
) : (
<Button
onClick={() => {
togglePublic(false);
}}
type="primary"
shape="circle"
>
Stop publishing
</Button>
)}
</div>
);
};
const SyncPage = ({ workspace }: { workspace: Workspace }) => {
const [workspaceType, setWorkspaceType] = useState('local');
useEffect(() => {
setType();
});
const setType = () => {
const ACTIVEworkspace = getActiveWorkspace();
console.log('ACTIVEworkspace: ', ACTIVEworkspace);
ACTIVEworkspace && setWorkspaceType(ACTIVEworkspace.type);
};
return (
<div>
<StyledPublishContent>
{workspaceType === 'local' ? (
<>
<StyledPublishExplanation>
{workspace.name} 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.
</StyledPublishExplanation>
<StyledPublishCopyContainer>
<StyledCopyButtonContainer>
<Button
onClick={() => {
updateWorkspaceMeta(workspace.id, {
type: 'cloud',
});
setType();
}}
type="primary"
shape="circle"
>
Enable AFFiNE Cloud
</Button>
</StyledCopyButtonContainer>
</StyledPublishCopyContainer>
</>
) : (
<StyledPublishExplanation>
<code>{workspace.name}</code> is Cloud Workspace. All data will be
synchronized and saved to the AFFiNE account
<div>
<Menu
content={
<>
<MenuItem
onClick={() => {
deleteMember(workspace.id, 0);
}}
icon={<DownloadIcon />}
>
Download core data to device
</MenuItem>
<MenuItem
onClick={() => {
deleteMember(workspace.id, 0);
}}
icon={<DownloadIcon />}
>
Download all data to device
</MenuItem>
</>
}
placement="bottom-end"
disablePortal={true}
>
<Button>Download all data to device</Button>
</Menu>
</div>
</StyledPublishExplanation>
)}
</StyledPublishContent>
</div>
);
};

View File

@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { getWorkspaces, Workspace, User } from './mock-data/mock';
export function getActiveWorkspace(): Workspace {
@@ -12,16 +12,19 @@ export const useTemporaryHelper = () => {
const [currentWorkspace, setCurrentWorkspace] = useState<Workspace>(
JSON.parse(localStorage.getItem('affine-active-workspace') ?? '{}')
);
const [user, setUser] = useState<User | null>(null);
const [user, setUser] = useState<User | null>();
return {
updateWorkspaceMeta: (workspaceId: string, workspaceData: Workspace) => {
updateWorkspaceMeta: (
workspaceId: string,
workspaceData: { name?: string; avatar?: string; isPublish?: boolean }
) => {
const workspacesMeta = getWorkspaces();
const newWorkspacesMeta = workspacesMeta.map((workspace: Workspace) => {
if (workspace.id === workspaceId) {
workspaceData.name && (workspace.name = workspaceData.name);
workspaceData.avatar && (workspace.avatar = workspaceData.avatar);
return workspaceData;
return workspace;
}
return workspace;
});
@@ -94,7 +97,7 @@ export const useTemporaryHelper = () => {
avatar: 'string',
};
localStorage.setItem('affine-user', JSON.stringify(userInfo));
console.log('login');
setUser(userInfo);
},
getUserInfo: () => {