From 0152172dd1ad7ce3a5d8fbf3af3eee78aa6a883a Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Wed, 11 Jan 2023 21:23:41 +0800 Subject: [PATCH] feat: connect with datacenter invite function --- .../workspace-setting/MembersPage.tsx | 214 ------------------ .../workspace-setting/general/style.ts | 8 - .../src/components/workspace-setting/index.ts | 2 +- .../member/InviteMemberModal.tsx} | 57 ++--- .../workspace-setting/member/MembersPage.tsx | 189 ++++++++++++++++ .../workspace-setting/member/index.ts | 1 + .../workspace-setting/member/style.ts | 107 +++++++++ .../src/components/workspace-setting/style.ts | 93 -------- packages/app/src/hooks/use-members.ts | 51 +++++ .../app/src/hooks/use-workspace-helper.ts | 6 - .../providers/app-state-provider/Provider.tsx | 2 - packages/data-center/src/index.ts | 2 +- 12 files changed, 364 insertions(+), 368 deletions(-) delete mode 100644 packages/app/src/components/workspace-setting/MembersPage.tsx rename packages/app/src/components/{invite-members/index.tsx => workspace-setting/member/InviteMemberModal.tsx} (77%) create mode 100644 packages/app/src/components/workspace-setting/member/MembersPage.tsx create mode 100644 packages/app/src/components/workspace-setting/member/index.ts create mode 100644 packages/app/src/components/workspace-setting/member/style.ts create mode 100644 packages/app/src/hooks/use-members.ts diff --git a/packages/app/src/components/workspace-setting/MembersPage.tsx b/packages/app/src/components/workspace-setting/MembersPage.tsx deleted file mode 100644 index e2a9beeae0..0000000000 --- a/packages/app/src/components/workspace-setting/MembersPage.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import { - StyledMemberAvatar, - StyledMemberButtonContainer, - StyledMemberEmail, - StyledMemberInfo, - StyledMemberListContainer, - StyledMemberListItem, - StyledMemberName, - StyledMemberNameContainer, - StyledMemberRoleContainer, - StyledMemberTitleContainer, - StyledMoreVerticalButton, - StyledPublishExplanation, -} 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 { Menu, MenuItem } from '@/ui/menu'; -import { Empty } from '@/ui/empty'; -// import { -// deleteMember, -// getMembers, -// User, -// Workspace, -// } from '@/hooks/mock-data/mock'; -import { WorkspaceUnit } from '@affine/datacenter'; -import { useTemporaryHelper } from '@/providers/temporary-helper-provider'; -import { StyledMemberWarp } from './general/style'; -import { useConfirm } from '@/providers/ConfirmProvider'; -// import { useAppState } from '@/providers/app-state-provider'; - -// import { useAppState } from '@/providers/app-state-provider'; -export const MembersPage = ({ workspace }: { workspace: WorkspaceUnit }) => { - const [isInviteModalShow, setIsInviteModalShow] = useState(false); - - const [members, setMembers] = useState<[{ name: string; email: string }?]>( - [] - ); - - // const getMembers = async () =>{ - // const members = await dataCenter. - // } - - console.log('setMembers: ', setMembers); - const { user, login, updateWorkspaceMeta } = useTemporaryHelper(); - const { confirm } = useConfirm(); - // const refreshMembers = useCallback(() => { - // getDataCenter() - // .then(dc => - // dc.apis.getWorkspaceMembers({ - // id: workspace.id, - // }) - // ) - // .then(data => { - // setMembers(data); - // }) - // .catch(err => { - // console.log(err); - // }); - // }, [workspace.id]); - const setMembersList = () => { - // setMembers([]); - // const members = getMembers(workspace.id); - // members && setMembers(members); - }; - useEffect(() => { - setMembersList(); - // refreshMembers(); - }); - - return ( -
- {workspace.provider === 'affine' ? ( - <> - - - Users({members.length}) - - Access level - - - {members.length ? ( - members.map((member, index) => { - return ( - - - - - - - - {member?.name} - - {member?.email} - - - - {/* {member.accepted - ? member.type !== 99 - ? 'Member' - : 'Workspace Owner' - : 'Pending'} */} - Pending - - - - { - // 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={} - > - Delete - - - } - placement="bottom-end" - disablePortal={true} - > - - - - - - - ); - }) - ) : ( - - )} - - - - { - setIsInviteModalShow(false); - }} - onInviteSuccess={() => { - setMembersList(); - setIsInviteModalShow(false); - // refreshMembers(); - }} - workspaceId={workspace.id} - open={isInviteModalShow} - > - - - ) : ( - - <>Collaborating with other members requires AFFiNE Cloud service. - - - - - )} -
- ); -}; diff --git a/packages/app/src/components/workspace-setting/general/style.ts b/packages/app/src/components/workspace-setting/general/style.ts index 4a82017e96..739ec24aec 100644 --- a/packages/app/src/components/workspace-setting/general/style.ts +++ b/packages/app/src/components/workspace-setting/general/style.ts @@ -26,11 +26,3 @@ export const StyledSettingAvatarContent = styled('div')(() => { export const StyledSettingAvatar = styled(MuiAvatar)(() => { return { height: '72px', width: '72px', marginRight: '24px' }; }); - -export const StyledMemberWarp = styled('div')(() => { - return { - display: 'flex', - flexDirection: 'column', - padding: '40px 0', - }; -}); diff --git a/packages/app/src/components/workspace-setting/index.ts b/packages/app/src/components/workspace-setting/index.ts index c0eea1cfb0..0468074d2f 100644 --- a/packages/app/src/components/workspace-setting/index.ts +++ b/packages/app/src/components/workspace-setting/index.ts @@ -1,5 +1,5 @@ export * from './general'; export * from './ExportPage'; -export * from './MembersPage'; +export * from './member'; export * from './SyncPage'; export * from './PublishPage'; diff --git a/packages/app/src/components/invite-members/index.tsx b/packages/app/src/components/workspace-setting/member/InviteMemberModal.tsx similarity index 77% rename from packages/app/src/components/invite-members/index.tsx rename to packages/app/src/components/workspace-setting/member/InviteMemberModal.tsx index 6fb020fc52..c066908ed0 100644 --- a/packages/app/src/components/invite-members/index.tsx +++ b/packages/app/src/components/workspace-setting/member/InviteMemberModal.tsx @@ -4,9 +4,9 @@ import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; import { useState } from 'react'; -// import { getDataCenter } from '@affine/datacenter'; import { Avatar } from '@mui/material'; -import { setMember } from '@/hooks/mock-data/mock'; +import useMembers from '@/hooks/use-members'; +import { User } from '@affine/datacenter'; interface LoginModalProps { open: boolean; onClose: () => void; @@ -43,46 +43,27 @@ export const debounce = any>( }; const gmailReg = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@gmail\.com$/; -export const InviteMembers = ({ +export const InviteMemberModal = ({ open, onClose, - workspaceId, onInviteSuccess, }: LoginModalProps) => { const [email, setEmail] = useState(''); const [showMember, setShowMember] = useState(false); const [showTip, setShowTip] = useState(false); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const [userData, setUserData] = useState({}); + const [userData, setUserData] = useState(null); + const { inviteMember, getUserByEmail } = useMembers(); const inputChange = (value: string) => { setShowMember(true); if (gmailReg.test(value)) { setEmail(value); setShowTip(false); - setUserData({ - name: 'wxl', - avatar: 'https://avatars.githubusercontent.com/u/20501502?v=4', - email: value, + getUserByEmail(value).then(data => { + if (data?.name) { + setUserData(data); + setShowTip(false); + } }); - // debounce( - // () => { - // getDataCenter() - // .then(dc => - // dc.apis.getUserByEmail({ - // email: value, - // workspace_id: workspaceId, - // }) - // ) - // .then(data => { - // if (data?.name) { - // setUserData(data); - // setShowTip(false); - // } - // }); - // }, - // 300, - // true - // )(); } else { setShowTip(true); } @@ -118,8 +99,8 @@ export const InviteMembers = ({ Non-Gmail is not supported ) : ( - {userData?.avatar_url ? ( - + {userData?.avatar ? ( + ) : ( @@ -139,19 +120,9 @@ export const InviteMembers = ({ + { + setIsInviteModalShow(false); + }} + onInviteSuccess={() => { + setIsInviteModalShow(false); + // refreshMembers(); + }} + workspaceId={workspace.id} + open={isInviteModalShow} + > + + + ); + } + + return ( + + <>Collaborating with other members requires AFFiNE Cloud service. + + + + + ); +}; diff --git a/packages/app/src/components/workspace-setting/member/index.ts b/packages/app/src/components/workspace-setting/member/index.ts new file mode 100644 index 0000000000..aced79efe5 --- /dev/null +++ b/packages/app/src/components/workspace-setting/member/index.ts @@ -0,0 +1 @@ +export * from './MembersPage'; diff --git a/packages/app/src/components/workspace-setting/member/style.ts b/packages/app/src/components/workspace-setting/member/style.ts new file mode 100644 index 0000000000..a5bf612f9a --- /dev/null +++ b/packages/app/src/components/workspace-setting/member/style.ts @@ -0,0 +1,107 @@ +import { styled } from '@/styles'; +import MuiAvatar from '@mui/material/Avatar'; +import { Button } from '@/ui/button'; + +export const StyledMemberTitleContainer = styled('div')(() => { + return { + display: 'flex', + marginTop: '60px', + fontWeight: '500', + flex: 1, + }; +}); + +export const StyledMemberAvatar = styled(MuiAvatar)(() => { + return { height: '40px', width: '40px' }; +}); + +export const StyledMemberNameContainer = styled('div')(() => { + return { + display: 'flex', + alignItems: 'center', + width: '402px', + }; +}); + +export const StyledMemberRoleContainer = styled('div')(() => { + return { + display: 'flex', + alignItems: 'center', + width: '222px', + }; +}); + +export const StyledMemberListContainer = styled('ul')(() => { + return { + marginTop: '15px', + overflowY: 'scroll', + }; +}); + +export const StyledMemberListItem = styled('li')(() => { + return { + display: 'flex', + alignItems: 'center', + height: '72px', + }; +}); + +export const StyledMemberInfo = styled('div')(() => { + return { + paddingLeft: '12px', + }; +}); + +export const StyledMemberName = styled('div')(({ theme }) => { + return { + fontWeight: '400', + fontSize: '18px', + lineHeight: '16px', + color: theme.colors.textColor, + }; +}); + +export const StyledMemberEmail = styled('div')(({ theme }) => { + return { + fontWeight: '400', + fontSize: '16px', + lineHeight: '22px', + color: theme.colors.iconColor, + }; +}); + +export const StyledMemberButtonContainer = styled('div')(() => { + return { + marginTop: '14px', + }; +}); + +export const StyledMoreVerticalButton = styled('button')(() => { + return { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + width: '24px', + height: '24px', + cursor: 'pointer', + }; +}); + +export const StyledPublishExplanation = styled('div')(() => { + return { + paddingRight: '48px', + fontWeight: '500', + fontSize: '18px', + lineHeight: '26px', + flex: 1, + marginTop: '60px', + }; +}); + +export const StyledMemberWarp = styled('div')(() => { + return { + display: 'flex', + flexDirection: 'column', + padding: '40px 0', + }; +}); diff --git a/packages/app/src/components/workspace-setting/style.ts b/packages/app/src/components/workspace-setting/style.ts index f750ef8598..1809ed4280 100644 --- a/packages/app/src/components/workspace-setting/style.ts +++ b/packages/app/src/components/workspace-setting/style.ts @@ -96,99 +96,6 @@ export const StyledSettingH2 = styled('h2')<{ marginTop?: number }>( } ); -export const StyledAvatarUploadBtn = styled(Button)(({ theme }) => { - return { - backgroundColor: theme.colors.hoverBackground, - color: theme.colors.primaryColor, - margin: '0 12px 0 24px', - }; -}); - -export const StyledMemberTitleContainer = styled('div')(() => { - return { - display: 'flex', - marginTop: '60px', - fontWeight: '500', - flex: 1, - }; -}); - -export const StyledMemberAvatar = styled(MuiAvatar)(() => { - return { height: '40px', width: '40px' }; -}); - -export const StyledMemberNameContainer = styled('div')(() => { - return { - display: 'flex', - alignItems: 'center', - width: '402px', - }; -}); - -export const StyledMemberRoleContainer = styled('div')(() => { - return { - display: 'flex', - alignItems: 'center', - width: '222px', - }; -}); - -export const StyledMemberListContainer = styled('ul')(() => { - return { - marginTop: '15px', - overflowY: 'scroll', - }; -}); - -export const StyledMemberListItem = styled('li')(() => { - return { - display: 'flex', - alignItems: 'center', - height: '72px', - }; -}); - -export const StyledMemberInfo = styled('div')(() => { - return { - paddingLeft: '12px', - }; -}); - -export const StyledMemberName = styled('div')(({ theme }) => { - return { - fontWeight: '400', - fontSize: '18px', - lineHeight: '16px', - color: theme.colors.textColor, - }; -}); - -export const StyledMemberEmail = styled('div')(({ theme }) => { - return { - fontWeight: '400', - fontSize: '16px', - lineHeight: '22px', - color: theme.colors.iconColor, - }; -}); - -export const StyledMemberButtonContainer = styled('div')(() => { - return { - marginTop: '14px', - }; -}); - -export const StyledMoreVerticalButton = styled('button')(() => { - return { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - width: '24px', - height: '24px', - cursor: 'pointer', - }; -}); - export const StyledPublishExplanation = styled('div')(() => { return { paddingRight: '48px', diff --git a/packages/app/src/hooks/use-members.ts b/packages/app/src/hooks/use-members.ts new file mode 100644 index 0000000000..3011c94f83 --- /dev/null +++ b/packages/app/src/hooks/use-members.ts @@ -0,0 +1,51 @@ +import { useCallback, useEffect, useState } from 'react'; +import { Member } from '@affine/datacenter'; +import { useAppState } from '@/providers/app-state-provider'; +export const useMembers = () => { + const { dataCenter, currentWorkspace } = useAppState(); + const [members, setMembers] = useState([]); + const [loaded, setLoaded] = useState(false); + const refreshMembers = useCallback(async () => { + if (!currentWorkspace || !dataCenter) return; + const members = await dataCenter.getMembers(currentWorkspace.id); + setMembers(members); + }, [dataCenter, currentWorkspace]); + + useEffect(() => { + const init = async () => { + await refreshMembers(); + setLoaded(true); + }; + init(); + }, [refreshMembers]); + + const inviteMember = async (email: string) => { + currentWorkspace && + dataCenter && + (await dataCenter.inviteMember(currentWorkspace?.id, email)); + }; + + const removeMember = async (permissionId: number) => { + if (!currentWorkspace || !dataCenter) { + return; + } + setLoaded(false); + await dataCenter.removeMember(currentWorkspace.id, permissionId); + await refreshMembers(); + setLoaded(true); + }; + + const getUserByEmail = async (email: string) => { + if (!currentWorkspace) return null; + return dataCenter?.getUserByEmail(currentWorkspace.id, email); + }; + return { + members, + removeMember, + inviteMember, + getUserByEmail, + loaded, + }; +}; + +export default useMembers; diff --git a/packages/app/src/hooks/use-workspace-helper.ts b/packages/app/src/hooks/use-workspace-helper.ts index f67a3b152f..397371e52f 100644 --- a/packages/app/src/hooks/use-workspace-helper.ts +++ b/packages/app/src/hooks/use-workspace-helper.ts @@ -56,16 +56,10 @@ export const useWorkspaceHelper = () => { }); }; - const inviteMember = async (email: string) => { - currentWorkspace && - (await dataCenter.inviteMember(currentWorkspace?.id, email)); - }; - return { createWorkspace, publishWorkspace, updateWorkspace, enableWorkspace, - inviteMember, }; }; diff --git a/packages/app/src/providers/app-state-provider/Provider.tsx b/packages/app/src/providers/app-state-provider/Provider.tsx index 710bf81853..ef6c594b0b 100644 --- a/packages/app/src/providers/app-state-provider/Provider.tsx +++ b/packages/app/src/providers/app-state-provider/Provider.tsx @@ -20,11 +20,9 @@ export const AppStateProvider = ({ children, }: PropsWithChildren) => { const [appState, setAppState] = useState({} as AppStateValue); - useEffect(() => { const initState = async () => { const dataCenter = await getDataCenter(); - // Ensure datacenter has at least one workspace if (dataCenter.workspaces.length === 0) { await createDefaultWorkspace(dataCenter); diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index fd199935fc..591a83b14a 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -26,7 +26,7 @@ const _initializeDataCenter = () => { export const getDataCenter = _initializeDataCenter(); export type { DataCenter }; -export type { AccessTokenMessage } from './provider/affine/apis'; +export * from './provider/affine/apis'; export { WorkspaceUnit } from './workspace-unit'; export { getLogger } from './logger'; export * from './message';