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,6 +1,6 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ComponentProps, ReactNode } from 'react';
import { ReactNode } from 'react';
import { useRecoilValue } from 'recoil';
import {
IconChevronDown,
@ -18,7 +18,7 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
export const PAGE_BAR_MIN_HEIGHT = 40;
const StyledTopBarContainer = styled.div`
const StyledTopBarContainer = styled.div<{ width?: number }>`
align-items: center;
background: ${({ theme }) => theme.background.noisy};
color: ${({ theme }) => theme.font.color.primary};
@ -31,6 +31,7 @@ const StyledTopBarContainer = styled.div`
padding-left: 0;
padding-right: ${({ theme }) => theme.spacing(3)};
z-index: 20;
width: ${({ width }) => width + 'px' || '100%'};
@media (max-width: ${MOBILE_VIEWPORT}px) {
padding-left: ${({ theme }) => theme.spacing(3)};
@ -76,8 +77,8 @@ const StyledTopBarButtonContainer = styled.div`
margin-right: ${({ theme }) => theme.spacing(1)};
`;
type PageHeaderProps = ComponentProps<'div'> & {
title: string;
type PageHeaderProps = {
title: ReactNode;
hasClosePageButton?: boolean;
onClosePage?: () => void;
hasPaginationButtons?: boolean;
@ -87,6 +88,7 @@ type PageHeaderProps = ComponentProps<'div'> & {
navigateToNextRecord?: () => void;
Icon: IconComponent;
children?: ReactNode;
width?: number;
};
export const PageHeader = ({
@ -100,13 +102,14 @@ export const PageHeader = ({
navigateToNextRecord,
Icon,
children,
width,
}: PageHeaderProps) => {
const isMobile = useIsMobile();
const theme = useTheme();
const isNavigationDrawerOpen = useRecoilValue(isNavigationDrawerOpenState);
return (
<StyledTopBarContainer>
<StyledTopBarContainer width={width}>
<StyledLeftContainer>
{!isMobile && !isNavigationDrawerOpen && (
<StyledTopBarButtonContainer>
@ -143,7 +146,11 @@ export const PageHeader = ({
)}
{Icon && <Icon size={theme.icon.size.md} />}
<StyledTitleContainer data-testid="top-bar-title">
<OverflowingTextWithTooltip text={title} />
{typeof title === 'string' ? (
<OverflowingTextWithTooltip text={title} />
) : (
title
)}
</StyledTitleContainer>
</StyledTopBarIconStyledTitleContainer>
</StyledLeftContainer>

View File

@ -1,15 +1,21 @@
import React from 'react';
import styled from '@emotion/styled';
import React from 'react';
const StyledPanel = styled.div`
background: ${({ theme }) => theme.background.primary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.md};
height: 100%;
overflow: auto;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
`;
export const PagePanel = ({ children }: { children: React.ReactNode }) => (
type PagePanelProps = {
children: React.ReactNode;
hasInformationBar?: boolean;
};
export const PagePanel = ({ children }: PagePanelProps) => (
<StyledPanel>{children}</StyledPanel>
);

View File

@ -1,16 +1,18 @@
import styled from '@emotion/styled';
import { JSX } from 'react';
import { JSX, ReactNode } from 'react';
import { IconComponent } from 'twenty-ui';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { InformationBannerWrapper } from '@/information-banner/components/InformationBannerWrapper';
import { OBJECT_SETTINGS_WIDTH } from '@/settings/data-model/constants/ObjectSettings';
import { PageBody } from './PageBody';
import { PageHeader } from './PageHeader';
type SubMenuTopBarContainerProps = {
children: JSX.Element | JSX.Element[];
title: string;
title: string | ReactNode;
actionButton?: ReactNode;
Icon: IconComponent;
className?: string;
};
@ -25,6 +27,7 @@ const StyledContainer = styled.div<{ isMobile: boolean }>`
export const SubMenuTopBarContainer = ({
children,
title,
actionButton,
Icon,
className,
}: SubMenuTopBarContainerProps) => {
@ -32,7 +35,13 @@ export const SubMenuTopBarContainer = ({
return (
<StyledContainer isMobile={isMobile} className={className}>
{isMobile && <PageHeader title={title} Icon={Icon} />}
<PageHeader
title={title}
Icon={Icon}
width={OBJECT_SETTINGS_WIDTH + 4 * 8}
>
{actionButton}
</PageHeader>
<PageBody>
<InformationBannerWrapper />
{children}