feat: soft delete (#6576)

Implement soft delete on standards and custom objects.
This is a temporary solution, when we drop `pg_graphql` we should rely
on the `softDelete` functions of TypeORM.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Jérémy M
2024-08-16 21:20:02 +02:00
committed by GitHub
parent 20d84755bb
commit db54469c8a
118 changed files with 1675 additions and 492 deletions

View File

@ -1,7 +1,7 @@
import { useNavigate } from 'react-router-dom';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconDotsVertical, IconTrash } from 'twenty-ui';
import { useNavigate } from 'react-router-dom';
import { useRecoilState, useRecoilValue } from 'recoil';
import { IconDotsVertical, IconRestore, IconTrash } from 'twenty-ui';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
@ -11,6 +11,9 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useDestroyManyRecords } from '@/object-record/hooks/useDestroyManyRecords';
import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { Dropdown } from '../../dropdown/components/Dropdown';
import { DropdownMenu } from '../../dropdown/components/DropdownMenu';
@ -32,6 +35,12 @@ export const ShowPageMoreButton = ({
const { deleteOneRecord } = useDeleteOneRecord({
objectNameSingular,
});
const { destroyManyRecords } = useDestroyManyRecords({
objectNameSingular,
});
const { restoreManyRecords } = useRestoreManyRecords({
objectNameSingular,
});
const handleDelete = () => {
deleteOneRecord(recordId);
@ -39,6 +48,21 @@ export const ShowPageMoreButton = ({
navigate(navigationMemorizedUrl, { replace: true });
};
const handleDestroy = () => {
destroyManyRecords([recordId]);
closeDropdown();
navigate(navigationMemorizedUrl, { replace: true });
};
const handleRestore = () => {
restoreManyRecords([recordId]);
closeDropdown();
};
const [recordFromStore] = useRecoilState<any>(
recordStoreFamilyState(recordId),
);
return (
<StyledContainer>
<Dropdown
@ -56,12 +80,29 @@ export const ShowPageMoreButton = ({
dropdownComponents={
<DropdownMenu>
<DropdownMenuItemsContainer>
<MenuItem
onClick={handleDelete}
accent="danger"
LeftIcon={IconTrash}
text="Delete"
/>
{recordFromStore && !recordFromStore.deletedAt && (
<MenuItem
onClick={handleDelete}
accent="danger"
LeftIcon={IconTrash}
text="Delete"
/>
)}
{recordFromStore && recordFromStore.deletedAt && (
<>
<MenuItem
onClick={handleDestroy}
accent="danger"
LeftIcon={IconTrash}
text="Destroy"
/>
<MenuItem
onClick={handleRestore}
LeftIcon={IconRestore}
text="Restore"
/>
</>
)}
</DropdownMenuItemsContainer>
</DropdownMenu>
}