fix issue (#7152 : Improve relation empty states on record page) (#7157)

- "No xxx" removed for empty relations
- All(0) removed

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
This commit is contained in:
Falgun Patel
2024-09-24 20:32:58 +05:30
committed by GitHub
parent 2fedf0d2fc
commit fd6740fa88
4 changed files with 24 additions and 87 deletions

View File

@ -1,35 +0,0 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useIcons } from 'twenty-ui';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
type RecordDetailRelationRecordsListEmptyStateProps = {
relationObjectMetadataItem: ObjectMetadataItem;
};
const StyledRelationRecordsListEmptyState = styled.div`
color: ${({ theme }) => theme.font.color.light};
align-items: center;
justify-content: center;
gap: ${({ theme }) => theme.spacing(2)};
display: flex;
height: ${({ theme }) => theme.spacing(10)};
text-transform: capitalize;
`;
export const RecordDetailRelationRecordsListEmptyState = ({
relationObjectMetadataItem,
}: RecordDetailRelationRecordsListEmptyStateProps) => {
const theme = useTheme();
const { getIcon } = useIcons();
const Icon = getIcon(relationObjectMetadataItem.icon);
return (
<StyledRelationRecordsListEmptyState>
<Icon size={theme.icon.size.sm} />
<div>No {relationObjectMetadataItem.labelSingular}</div>
</StyledRelationRecordsListEmptyState>
);
};

View File

@ -13,8 +13,6 @@ import { RelationFromManyFieldInputMultiRecordsEffect } from '@/object-record/re
import { useUpdateRelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/hooks/useUpdateRelationFromManyFieldInput'; import { useUpdateRelationFromManyFieldInput } from '@/object-record/record-field/meta-types/input/hooks/useUpdateRelationFromManyFieldInput';
import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { FieldRelationMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { RecordDetailRelationRecordsList } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsList'; import { RecordDetailRelationRecordsList } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsList';
import { RecordDetailRelationRecordsListEmptyState } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationRecordsListEmptyState';
import { RecordDetailRelationSectionSkeletonLoader } from '@/object-record/record-show/record-detail-section/components/RecordDetailRelationSectionSkeletonLoader';
import { RecordDetailSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailSection'; import { RecordDetailSection } from '@/object-record/record-show/record-detail-section/components/RecordDetailSection';
import { RecordDetailSectionHeader } from '@/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader'; import { RecordDetailSectionHeader } from '@/object-record/record-show/record-detail-section/components/RecordDetailSectionHeader';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
@ -133,20 +131,10 @@ export const RecordDetailRelationSection = ({
}?${qs.stringify(filterQueryParams)}`; }?${qs.stringify(filterQueryParams)}`;
const showContent = () => { const showContent = () => {
if (loading) { return (
return ( relationRecords.length > 0 && (
<RecordDetailRelationSectionSkeletonLoader <RecordDetailRelationRecordsList relationRecords={relationRecords} />
numSkeletons={fieldName === 'people' ? 2 : 1} )
/>
);
}
return relationRecords.length ? (
<RecordDetailRelationRecordsList relationRecords={relationRecords} />
) : (
<RecordDetailRelationRecordsListEmptyState
relationObjectMetadataItem={relationObjectMetadataItem}
/>
); );
}; };
@ -158,6 +146,8 @@ export const RecordDetailRelationSection = ({
recordId, recordId,
}); });
if (loading) return null;
return ( return (
<RecordDetailSection> <RecordDetailSection>
<RecordDetailSectionHeader <RecordDetailSectionHeader
@ -166,11 +156,15 @@ export const RecordDetailRelationSection = ({
isToManyObjects isToManyObjects
? { ? {
to: filterLinkHref, to: filterLinkHref,
label: `All (${relationRecords.length})`, label:
relationRecords.length > 0
? `All (${relationRecords.length})`
: '',
} }
: undefined : undefined
} }
hideRightAdornmentOnMouseLeave={!isDropdownOpen && !isMobile} hideRightAdornmentOnMouseLeave={!isDropdownOpen && !isMobile}
areRecordsAvailable={relationRecords.length > 0}
rightAdornment={ rightAdornment={
<DropdownScope dropdownScopeId={dropdownId}> <DropdownScope dropdownScopeId={dropdownId}>
<StyledAddDropdown <StyledAddDropdown

View File

@ -1,31 +0,0 @@
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
const StyledSkeletonDiv = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(4)};
height: 40px;
`;
export const RecordDetailRelationSectionSkeletonLoader = ({
numSkeletons = 1,
}: {
numSkeletons?: number;
}) => {
const theme = useTheme();
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
highlightColor={theme.background.transparent.lighter}
borderRadius={4}
>
<StyledSkeletonDiv>
{Array.from({ length: numSkeletons }).map((_, index) => (
<Skeleton key={index} width={129} height={16} />
))}
</StyledSkeletonDiv>
</SkeletonTheme>
);
};

View File

@ -1,12 +1,16 @@
import styled from '@emotion/styled';
import { useState } from 'react'; import { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from '@emotion/styled';
const StyledHeader = styled.header<{ isDropdownOpen?: boolean }>` const StyledHeader = styled.header<{
isDropdownOpen?: boolean;
areRecordsAvailable?: boolean;
}>`
align-items: center; align-items: center;
display: flex; display: flex;
height: 24px; height: 24px;
margin-bottom: ${({ theme }) => theme.spacing(2)}; margin-bottom: ${({ theme, areRecordsAvailable }) =>
areRecordsAvailable && theme.spacing(2)};
`; `;
const StyledTitle = styled.div` const StyledTitle = styled.div`
@ -34,6 +38,7 @@ type RecordDetailSectionHeaderProps = {
link?: { to: string; label: string }; link?: { to: string; label: string };
rightAdornment?: React.ReactNode; rightAdornment?: React.ReactNode;
hideRightAdornmentOnMouseLeave?: boolean; hideRightAdornmentOnMouseLeave?: boolean;
areRecordsAvailable?: boolean;
}; };
export const RecordDetailSectionHeader = ({ export const RecordDetailSectionHeader = ({
@ -41,11 +46,13 @@ export const RecordDetailSectionHeader = ({
link, link,
rightAdornment, rightAdornment,
hideRightAdornmentOnMouseLeave = true, hideRightAdornmentOnMouseLeave = true,
areRecordsAvailable = false,
}: RecordDetailSectionHeaderProps) => { }: RecordDetailSectionHeaderProps) => {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
return ( return (
<StyledHeader <StyledHeader
areRecordsAvailable={areRecordsAvailable}
onMouseEnter={() => setIsHovered(true)} onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)} onMouseLeave={() => setIsHovered(false)}
> >
@ -53,7 +60,9 @@ export const RecordDetailSectionHeader = ({
<StyledTitleLabel>{title}</StyledTitleLabel> <StyledTitleLabel>{title}</StyledTitleLabel>
{link && <StyledLink to={link.to}>{link.label}</StyledLink>} {link && <StyledLink to={link.to}>{link.label}</StyledLink>}
</StyledTitle> </StyledTitle>
{hideRightAdornmentOnMouseLeave && !isHovered ? null : rightAdornment} {hideRightAdornmentOnMouseLeave && !isHovered && areRecordsAvailable
? null
: rightAdornment}
</StyledHeader> </StyledHeader>
); );
}; };