Files
twenty/packages/twenty-front/src/pages/settings/data-model/SettingsObjectDetailPageContent.tsx
Jérémy M db54469c8a 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>
2024-08-16 21:20:02 +02:00

104 lines
3.8 KiB
TypeScript

import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getDisabledFieldMetadataItems } from '@/object-metadata/utils/getDisabledFieldMetadataItems';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsObjectSummaryCard } from '@/settings/data-model/object-details/components/SettingsObjectSummaryCard';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { Button } from '@/ui/input/button/components/Button';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
import styled from '@emotion/styled';
import { isNonEmptyArray } from '@sniptt/guards';
import { useNavigate } from 'react-router-dom';
import { H2Title, IconHierarchy2, IconPlus } from 'twenty-ui';
import { SettingsObjectFieldTable } from '~/pages/settings/data-model/SettingsObjectFieldTable';
const StyledDiv = styled.div`
display: flex;
justify-content: flex-end;
padding-top: ${({ theme }) => theme.spacing(2)};
`;
export type SettingsObjectDetailPageContentProps = {
objectMetadataItem: ObjectMetadataItem;
};
export const SettingsObjectDetailPageContent = ({
objectMetadataItem,
}: SettingsObjectDetailPageContentProps) => {
const navigate = useNavigate();
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
const handleDisableObject = async () => {
await updateOneObjectMetadataItem({
idToUpdate: objectMetadataItem.id,
updatePayload: { isActive: false },
});
navigate(getSettingsPagePath(SettingsPath.Objects));
};
const disabledFieldMetadataItems =
getDisabledFieldMetadataItems(objectMetadataItem);
const shouldDisplayAddFieldButton = !objectMetadataItem.isRemote;
return (
<SubMenuTopBarContainer
Icon={IconHierarchy2}
title={
<Breadcrumb
links={[
{ children: 'Objects', href: '/settings/objects' },
{ children: objectMetadataItem.labelPlural },
]}
/>
}
>
<SettingsPageContainer>
<Section>
<H2Title title="About" description="Manage your object" />
<SettingsObjectSummaryCard
iconKey={objectMetadataItem.icon ?? undefined}
name={objectMetadataItem.labelPlural || ''}
objectMetadataItem={objectMetadataItem}
onDeactivate={handleDisableObject}
onEdit={() => navigate('./edit')}
/>
</Section>
<Section>
<H2Title
title="Fields"
description={`Customise the fields available in the ${objectMetadataItem.labelSingular} views and their display order in the ${objectMetadataItem.labelSingular} detail view and menus.`}
/>
<SettingsObjectFieldTable
objectMetadataItem={objectMetadataItem}
mode="view"
/>
{shouldDisplayAddFieldButton && (
<StyledDiv>
<UndecoratedLink
to={
isNonEmptyArray(disabledFieldMetadataItems)
? './new-field/step-1'
: './new-field/step-2'
}
>
<Button
Icon={IconPlus}
title="Add Field"
size="small"
variant="secondary"
/>
</UndecoratedLink>
</StyledDiv>
)}
</Section>
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
};