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:
@ -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}
|
||||||
|
|||||||
@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user