feat: improve Relation field type tag (#2606)

* feat: improve Relation field type tag

Closes #2359

* refactor: code review - rename dataTypes to settingsFieldMetadataTypes

* refactor: code review - style Icon with styled
This commit is contained in:
Thaïs
2023-11-21 16:23:35 +01:00
committed by GitHub
parent f97d25d986
commit 0f4796bd1a
9 changed files with 82 additions and 30 deletions

View File

@ -19,7 +19,7 @@ export const useRelationMetadata = ({
relationMetadata?.relationType === RelationMetadataType.OneToMany &&
fieldMetadataItem?.toRelationMetadata
? 'MANY_TO_ONE'
: (relationMetadata?.relationType as RelationType);
: (relationMetadata?.relationType as RelationType | undefined);
const relationObjectMetadataId =
relationMetadata && 'toObjectMetadata' in relationMetadata

View File

@ -10,7 +10,7 @@ import { Field } from '~/generated/graphql';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { SettingsObjectFieldPreviewValueEffect } from '../components/SettingsObjectFieldPreviewValueEffect';
import { dataTypes } from '../constants/dataTypes';
import { settingsFieldMetadataTypes } from '../constants/settingsFieldMetadataTypes';
import { useFieldPreview } from '../hooks/useFieldPreview';
import { useRelationFieldPreview } from '../hooks/useRelationFieldPreview';
@ -99,7 +99,7 @@ export const SettingsObjectFieldPreview = ({
const defaultValue =
fieldMetadata.type === FieldMetadataType.Relation
? relationDefaultValue
: dataTypes[fieldMetadata.type].defaultValue;
: settingsFieldMetadataTypes[fieldMetadata.type].defaultValue;
return (
<StyledContainer className={className}>

View File

@ -5,8 +5,8 @@ import { Select } from '@/ui/input/components/Select';
import { Section } from '@/ui/layout/section/components/Section';
import { Field, FieldMetadataType } from '~/generated-metadata/graphql';
import { dataTypes } from '../constants/dataTypes';
import { relationTypes } from '../constants/relationTypes';
import { settingsFieldMetadataTypes } from '../constants/settingsFieldMetadataTypes';
import {
SettingsObjectFieldPreview,
@ -55,11 +55,11 @@ export const SettingsObjectFieldTypeSelectSection = ({
}: SettingsObjectFieldTypeSelectSectionProps) => {
const relationFormConfig = values?.relation;
const fieldTypeOptions = Object.entries(dataTypes)
const fieldTypeOptions = Object.entries(settingsFieldMetadataTypes)
.filter(([key]) => !excludedFieldTypes?.includes(key as FieldMetadataType))
.map(([key, dataType]) => ({
.map(([key, dataTypeConfig]) => ({
value: key as FieldMetadataType,
...dataType,
...dataTypeConfig,
}));
return (

View File

@ -18,7 +18,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
const defaultDateValue = new Date();
defaultDateValue.setFullYear(defaultDateValue.getFullYear() + 2);
export const dataTypes: Record<
export const settingsFieldMetadataTypes: Record<
FieldMetadataType,
{ label: string; Icon: IconComponent; defaultValue?: unknown }
> = {

View File

@ -1,9 +1,17 @@
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { dataTypes } from '../../constants/dataTypes';
import { settingsFieldMetadataTypes } from '../../constants/settingsFieldMetadataTypes';
type SettingsObjectFieldDataTypeProps = {
onClick?: () => void;
Icon?: IconComponent;
label?: string;
value: FieldMetadataType;
};
const StyledDataType = styled.div<{ value: FieldMetadataType }>`
align-items: center;
@ -13,8 +21,16 @@ const StyledDataType = styled.div<{ value: FieldMetadataType }>`
font-size: ${({ theme }) => theme.font.size.sm};
gap: ${({ theme }) => theme.spacing(1)};
height: 20px;
overflow: hidden;
padding: 0 ${({ theme }) => theme.spacing(2)};
${({ onClick }) =>
onClick
? css`
cursor: pointer;
`
: ''}
${({ theme, value }) =>
value === FieldMetadataType.Relation
? css`
@ -24,21 +40,28 @@ const StyledDataType = styled.div<{ value: FieldMetadataType }>`
: ''}
`;
type SettingsObjectFieldDataTypeProps = {
value: FieldMetadataType;
};
const StyledLabelContainer = styled.div`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
export const SettingsObjectFieldDataType = ({
onClick,
value,
Icon = settingsFieldMetadataTypes[value].Icon,
label = settingsFieldMetadataTypes[value].label,
}: SettingsObjectFieldDataTypeProps) => {
const theme = useTheme();
const { label, Icon } = dataTypes?.[value];
const StyledIcon = styled(Icon)`
flex: 1 0 auto;
`;
return (
<StyledDataType value={value}>
<Icon size={theme.icon.size.sm} />
{label}
<StyledDataType onClick={onClick} value={value}>
<StyledIcon size={theme.icon.size.sm} />
<StyledLabelContainer>{label}</StyledLabelContainer>
</StyledDataType>
);
};

View File

@ -1,19 +1,23 @@
import { ReactNode } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { dataTypes } from '../../constants/dataTypes';
import { relationTypes } from '../../constants/relationTypes';
import { settingsFieldMetadataTypes } from '../../constants/settingsFieldMetadataTypes';
import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType';
type SettingsObjectFieldItemTableRowProps = {
ActionIcon: ReactNode;
fieldItem: FieldMetadataItem;
fieldMetadataItem: FieldMetadataItem;
};
export const StyledObjectFieldTableRow = styled(TableRow)`
@ -32,27 +36,51 @@ const StyledIconTableCell = styled(TableCell)`
export const SettingsObjectFieldItemTableRow = ({
ActionIcon,
fieldItem,
fieldMetadataItem: fieldMetadataItem,
}: SettingsObjectFieldItemTableRowProps) => {
const theme = useTheme();
const { Icon } = useLazyLoadIcon(fieldItem.icon ?? '');
const { Icon } = useLazyLoadIcon(fieldMetadataItem.icon ?? '');
const navigate = useNavigate();
// TODO: parse with zod and merge types with FieldType (create a subset of FieldType for example)
const fieldDataTypeIsSupported = Object.keys(dataTypes).includes(
fieldItem.type,
);
const fieldDataTypeIsSupported =
fieldMetadataItem.type in settingsFieldMetadataTypes;
const { relationObjectMetadataItem, relationType } = useRelationMetadata({
fieldMetadataItem,
});
if (!fieldDataTypeIsSupported) return null;
const RelationIcon = relationType
? relationTypes[relationType].Icon
: undefined;
return (
<StyledObjectFieldTableRow>
<StyledNameTableCell>
{!!Icon && <Icon size={theme.icon.size.md} />}
{fieldItem.label}
{fieldMetadataItem.label}
</StyledNameTableCell>
<TableCell>{fieldItem.isCustom ? 'Custom' : 'Standard'}</TableCell>
<TableCell>
<SettingsObjectFieldDataType value={fieldItem.type} />
{fieldMetadataItem.isCustom ? 'Custom' : 'Standard'}
</TableCell>
<TableCell>
<SettingsObjectFieldDataType
Icon={RelationIcon}
label={relationObjectMetadataItem?.labelPlural}
onClick={
relationObjectMetadataItem?.namePlural
? () =>
navigate(
`/settings/objects/${getObjectSlug(
relationObjectMetadataItem,
)}`,
)
: undefined
}
value={fieldMetadataItem.type}
/>
</TableCell>
<StyledIconTableCell>{ActionIcon}</StyledIconTableCell>
</StyledObjectFieldTableRow>

View File

@ -1,6 +1,7 @@
import { FunctionComponent } from 'react';
export type IconComponent = FunctionComponent<{
className?: string;
color?: string;
size?: number;
stroke?: number;

View File

@ -94,7 +94,7 @@ export const SettingsObjectDetail = () => {
{activeMetadataFields.map((activeMetadataField) => (
<SettingsObjectFieldItemTableRow
key={activeMetadataField.id}
fieldItem={activeMetadataField}
fieldMetadataItem={activeMetadataField}
ActionIcon={
<SettingsObjectFieldActiveActionDropdown
isCustomField={activeMetadataField.isCustom}
@ -116,7 +116,7 @@ export const SettingsObjectDetail = () => {
{disabledMetadataFields.map((disabledMetadataField) => (
<SettingsObjectFieldItemTableRow
key={disabledMetadataField.id}
fieldItem={disabledMetadataField}
fieldMetadataItem={disabledMetadataField}
ActionIcon={
<SettingsObjectFieldDisabledActionDropdown
isCustomField={disabledMetadataField.isCustom}

View File

@ -136,7 +136,7 @@ export const SettingsObjectNewFieldStep1 = () => {
{activeMetadataFields.map((field) => (
<SettingsObjectFieldItemTableRow
key={field.id}
fieldItem={field}
fieldMetadataItem={field}
ActionIcon={
<LightIconButton
Icon={IconMinus}
@ -153,7 +153,7 @@ export const SettingsObjectNewFieldStep1 = () => {
{disabledMetadataFields.map((field) => (
<SettingsObjectFieldItemTableRow
key={field.name}
fieldItem={field}
fieldMetadataItem={field}
ActionIcon={
<LightIconButton
Icon={IconPlus}