Datamodel overview show other fields (#6352)

<img width="638" alt="Bildschirmfoto 2024-07-19 um 23 49 00"
src="https://github.com/user-attachments/assets/57b600c4-d985-4e4c-afc0-e0c6dd5bc9f6">

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
This commit is contained in:
brendanlaschke
2024-07-22 16:13:49 +02:00
committed by GitHub
parent 4545ba2737
commit 01fe3b673e
3 changed files with 72 additions and 13 deletions

View File

@ -1,12 +1,11 @@
import { Handle, Position } from 'reactflow';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Handle, Position } from 'reactflow';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { useIcons } from 'twenty-ui'; import { useIcons } from 'twenty-ui';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { capitalize } from '~/utils/string/capitalize';
type ObjectFieldRowProps = { type ObjectFieldRowProps = {
field: FieldMetadataItem; field: FieldMetadataItem;
@ -41,9 +40,7 @@ export const ObjectFieldRow = ({ field }: ObjectFieldRowProps) => {
return ( return (
<StyledRow> <StyledRow>
{Icon && <Icon size={theme.icon.size.md} />} {Icon && <Icon size={theme.icon.size.md} />}
<StyledFieldName> <StyledFieldName>{relatedObject?.labelPlural ?? ''}</StyledFieldName>
{capitalize(relatedObject?.namePlural ?? '')}
</StyledFieldName>
<Handle <Handle
type={field.toRelationMetadata ? 'source' : 'target'} type={field.toRelationMetadata ? 'source' : 'target'}
position={Position.Right} position={Position.Right}

View File

@ -0,0 +1,38 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useIcons } from 'twenty-ui';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
type ObjectFieldRowWithoutRelationProps = {
field: FieldMetadataItem;
};
const StyledRow = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
position: relative;
width: 100%;
padding: 0 ${({ theme }) => theme.spacing(2)};
`;
const StyledFieldName = styled.div`
color: ${({ theme }) => theme.font.color.primary};
`;
export const ObjectFieldRowWithoutRelation = ({
field,
}: ObjectFieldRowWithoutRelationProps) => {
const { getIcon } = useIcons();
const theme = useTheme();
const Icon = getIcon(field?.icon);
return (
<StyledRow>
{Icon && <Icon size={theme.icon.size.md} />}
<StyledFieldName>{field.label}</StyledFieldName>
</StyledRow>
);
};

View File

@ -1,8 +1,8 @@
import { Link } from 'react-router-dom';
import { NodeProps } from 'reactflow';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconChevronDown, useIcons } from 'twenty-ui'; import { Link } from 'react-router-dom';
import { NodeProps } from 'reactflow';
import { IconChevronDown, IconChevronUp, useIcons } from 'twenty-ui';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug'; import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
@ -13,7 +13,9 @@ import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLab
import { FieldMetadataType } from '~/generated/graphql'; import { FieldMetadataType } from '~/generated/graphql';
import { capitalize } from '~/utils/string/capitalize'; import { capitalize } from '~/utils/string/capitalize';
import { ObjectFieldRowWithoutRelation } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewFieldWithoutRelation';
import '@reactflow/node-resizer/dist/style.css'; import '@reactflow/node-resizer/dist/style.css';
import { useState } from 'react';
type SettingsDataModelOverviewObjectProps = NodeProps<ObjectMetadataItem>; type SettingsDataModelOverviewObjectProps = NodeProps<ObjectMetadataItem>;
@ -66,10 +68,15 @@ const StyledCardRow = styled.div`
const StyledCardRowOther = styled.div` const StyledCardRowOther = styled.div`
align-items: center; align-items: center;
cursor: pointer;
display: flex; display: flex;
height: 24px; height: 24px;
padding: 0 ${({ theme }) => theme.spacing(2)}; padding: 0 ${({ theme }) => theme.spacing(2)};
gap: ${({ theme }) => theme.spacing(2)}; gap: ${({ theme }) => theme.spacing(2)};
&:hover {
background-color: ${({ theme }) => theme.background.tertiary};
}
`; `;
const StyledCardRowText = styled.div``; const StyledCardRowText = styled.div``;
@ -95,6 +102,7 @@ export const SettingsDataModelOverviewObject = ({
}: SettingsDataModelOverviewObjectProps) => { }: SettingsDataModelOverviewObjectProps) => {
const theme = useTheme(); const theme = useTheme();
const { getIcon } = useIcons(); const { getIcon } = useIcons();
const [otherFieldsExpanded, setOtherFieldsExpanded] = useState(false);
const { totalCount } = useFindManyRecords({ const { totalCount } = useFindManyRecords({
objectNameSingular: data.nameSingular, objectNameSingular: data.nameSingular,
@ -128,14 +136,30 @@ export const SettingsDataModelOverviewObject = ({
.filter((x) => x.type === FieldMetadataType.Relation) .filter((x) => x.type === FieldMetadataType.Relation)
.map((field) => ( .map((field) => (
<StyledCardRow> <StyledCardRow>
<ObjectFieldRow field={field}></ObjectFieldRow> <ObjectFieldRow field={field} />
</StyledCardRow> </StyledCardRow>
))} ))}
{countNonRelation > 0 && ( {countNonRelation > 0 && (
<StyledCardRowOther> <>
<IconChevronDown size={theme.icon.size.md} /> <StyledCardRowOther
<StyledCardRowText>{countNonRelation} fields</StyledCardRowText> onClick={() => setOtherFieldsExpanded(!otherFieldsExpanded)}
</StyledCardRowOther> >
{otherFieldsExpanded ? (
<IconChevronUp size={theme.icon.size.md} />
) : (
<IconChevronDown size={theme.icon.size.md} />
)}
<StyledCardRowText>{countNonRelation} fields</StyledCardRowText>
</StyledCardRowOther>
{otherFieldsExpanded &&
fields
.filter((x) => x.type !== FieldMetadataType.Relation)
.map((field) => (
<StyledCardRow>
<ObjectFieldRowWithoutRelation field={field} />
</StyledCardRow>
))}
</>
)} )}
</StyledInnerCard> </StyledInnerCard>
</StyledNode> </StyledNode>