Files
twenty/packages/twenty-front/src/pages/settings/SettingsWorkspaceMembers.tsx
Thaïs 014f11fb6f perf: apply record optimistic effects with cache.modify on mutation (#3540)
* perf: apply record optimistic effects with cache.modify on mutation

Closes #3509

* refactor: return early when created records do not match filter

* fix: fix id generation on record creation

* fix: comment filtering behavior on record creation

* Fixed typing error

* refactor: review - use ??

* refactor: review - add variables in readFieldValueToSort

* docs: review - add comments for variables.first in triggerUpdateRecordOptimisticEffect

* refactor: review - add intermediary variable for 'not' filter in useMultiObjectSearchMatchesSearchFilterAndToSelectQuery

* refactor: review - add filter utils

* fix: fix tests

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2024-01-23 18:13:00 +01:00

115 lines
4.4 KiB
TypeScript

import { useState } from 'react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { IconSettings, IconTrash } from '@/ui/display/icon';
import { H1Title } from '@/ui/display/typography/components/H1Title';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { IconButton } from '@/ui/input/button/components/IconButton';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section';
import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink';
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
const StyledH1Title = styled(H1Title)`
margin-bottom: 0;
`;
const StyledButtonContainer = styled.div`
align-items: center;
display: flex;
flex-direction: row;
margin-left: ${({ theme }) => theme.spacing(3)};
`;
export const SettingsWorkspaceMembers = () => {
const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false);
const [workspaceMemberToDelete, setWorkspaceMemberToDelete] = useState<
string | undefined
>();
const { records: workspaceMembers } = useFindManyRecords<WorkspaceMember>({
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
});
const { deleteOneRecord: deleteOneWorkspaceMember } = useDeleteOneRecord({
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
});
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const handleRemoveWorkspaceMember = async (workspaceMemberId: string) => {
await deleteOneWorkspaceMember?.(workspaceMemberId);
setIsConfirmationModalOpen(false);
};
return (
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
<StyledH1Title title="Members" />
{currentWorkspace?.inviteHash && (
<Section>
<H2Title
title="Invite"
description="Send an invitation to use Twenty"
/>
<WorkspaceInviteLink
inviteLink={`${window.location.origin}/invite/${currentWorkspace?.inviteHash}`}
/>
</Section>
)}
<Section>
<H2Title
title="Members"
description="Manage the members of your space here"
/>
{workspaceMembers?.map((member) => (
<WorkspaceMemberCard
key={member.id}
workspaceMember={member as WorkspaceMember}
accessory={
currentWorkspaceMember?.id !== member.id && (
<StyledButtonContainer>
<IconButton
onClick={() => {
setIsConfirmationModalOpen(true);
setWorkspaceMemberToDelete(member.id);
}}
variant="tertiary"
size="medium"
Icon={IconTrash}
/>
</StyledButtonContainer>
)
}
/>
))}
</Section>
</SettingsPageContainer>
<ConfirmationModal
isOpen={isConfirmationModalOpen}
setIsOpen={setIsConfirmationModalOpen}
title="Account Deletion"
subtitle={
<>
This action cannot be undone. This will permanently delete this user
and remove them from all their assignements.
</>
}
onConfirmClick={() =>
workspaceMemberToDelete &&
handleRemoveWorkspaceMember(workspaceMemberToDelete)
}
deleteButtonText="Delete account"
/>
</SubMenuTopBarContainer>
);
};