Files
twenty/front/src/pages/settings/SettingsWorkspaceMembers.tsx
T
Emilien Chauvet 14caaf298a Feat/add invite link (#603)
* Add UI for invite link

* Use invite link

* Isolate link component

* Improve UX
2023-07-11 13:35:43 -07:00

118 lines
3.5 KiB
TypeScript

import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';
import { Button } from '@/ui/components/buttons/Button';
import { MainSectionTitle } from '@/ui/components/section-titles/MainSectionTitle';
import { SubSectionTitle } from '@/ui/components/section-titles/SubSectionTitle';
import { IconTrash } from '@/ui/icons';
import { NoTopBarContainer } from '@/ui/layout/containers/NoTopBarContainer';
import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink';
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
import {
useGetWorkspaceMembersQuery,
useRemoveWorkspaceMemberMutation,
} from '~/generated/graphql';
const StyledContainer = styled.div`
display: flex;
flex-direction: column;
padding: ${({ theme }) => theme.spacing(8)};
width: 350px;
> * + * {
margin-top: ${({ theme }) => theme.spacing(8)};
}
`;
const ButtonContainer = styled.div`
align-items: center;
display: flex;
flex-direction: row;
margin-left: ${({ theme }) => theme.spacing(3)};
`;
export function SettingsWorkspaceMembers() {
const [currentUser] = useRecoilState(currentUserState);
const workspace = currentUser?.workspaceMember?.workspace;
const theme = useTheme();
const { data } = useGetWorkspaceMembersQuery();
const [removeWorkspaceMember] = useRemoveWorkspaceMemberMutation();
const handleRemoveWorkspaceMember = async (userId: string) => {
await removeWorkspaceMember({
variables: {
where: {
userId,
},
},
optimisticResponse: {
__typename: 'Mutation',
deleteWorkspaceMember: {
__typename: 'WorkspaceMember',
id: userId,
},
},
update: (cache, { data: responseData }) => {
if (!responseData) {
return;
}
const normalizedId = cache.identify({
id: responseData.deleteWorkspaceMember.id,
__typename: 'WorkspaceMember',
});
// Evict object from cache
cache.evict({ id: normalizedId });
// Clean up relation to this object
cache.gc();
},
});
};
return (
<NoTopBarContainer>
<StyledContainer>
<MainSectionTitle>Members</MainSectionTitle>
{workspace?.inviteHash && (
<>
<SubSectionTitle
title="Invite"
description="Send an invitation to use Twenty"
/>
<WorkspaceInviteLink
inviteLink={`${window.location.origin}/auth/invite/${workspace?.inviteHash}`}
/>
</>
)}
<SubSectionTitle
title="Members"
description="Manage the members of your space here"
/>
{data?.workspaceMembers?.map((member) => (
<WorkspaceMemberCard
key={member.user.id}
workspaceMember={{ user: member.user }}
accessory={
currentUser?.id !== member.user.id && (
<ButtonContainer>
<Button
onClick={() => handleRemoveWorkspaceMember(member.user.id)}
variant="tertiary"
size="small"
icon={<IconTrash size={theme.icon.size.md} />}
/>
</ButtonContainer>
)
}
/>
))}
</StyledContainer>
</NoTopBarContainer>
);
}