toggle Field on label between singular and plural based on relation type (#8817)
#7683   Hello, I’ve implemented the logic for dynamically toggling the Field on label between singular and plural based on the relation type selected by the user. Here's an overview of the changes: Added a variable selectedRelationType to store the user’s selected relation type. Based on this variable, I determine whether to use labelPlural or labelSingular from the selectedObjectMetadataItem. Please review my changes and let me know if there's anything that needs improvement . --------- Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
import * as Apollo from '@apollo/client';
|
import * as Apollo from '@apollo/client';
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
export type Maybe<T> = T | null;
|
export type Maybe<T> = T | null;
|
||||||
export type InputMaybe<T> = Maybe<T>;
|
export type InputMaybe<T> = Maybe<T>;
|
||||||
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
|
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
|
||||||
|
|||||||
@ -110,7 +110,7 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = {
|
|||||||
label: 'Full Name',
|
label: 'Full Name',
|
||||||
Icon: IllustrationIconUser,
|
Icon: IllustrationIconUser,
|
||||||
exampleValue: { firstName: 'John', lastName: 'Doe' },
|
exampleValue: { firstName: 'John', lastName: 'Doe' },
|
||||||
category: 'Advanced',
|
category: 'Basic',
|
||||||
subFields: ['firstName', 'lastName'],
|
subFields: ['firstName', 'lastName'],
|
||||||
filterableSubFields: ['firstName', 'lastName'],
|
filterableSubFields: ['firstName', 'lastName'],
|
||||||
labelBySubField: {
|
labelBySubField: {
|
||||||
|
|||||||
@ -2,6 +2,6 @@ import { SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/con
|
|||||||
import { SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs';
|
import { SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs';
|
||||||
|
|
||||||
export const SETTINGS_FIELD_TYPE_CONFIGS = {
|
export const SETTINGS_FIELD_TYPE_CONFIGS = {
|
||||||
...SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS,
|
|
||||||
...SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS,
|
...SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS,
|
||||||
|
...SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -120,7 +120,7 @@ export const SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS: SettingsNonCompositeFiel
|
|||||||
label: 'JSON',
|
label: 'JSON',
|
||||||
Icon: IllustrationIconJson,
|
Icon: IllustrationIconJson,
|
||||||
exampleValue: { key: 'value' },
|
exampleValue: { key: 'value' },
|
||||||
category: 'Basic',
|
category: 'Advanced',
|
||||||
} as const satisfies SettingsFieldTypeConfig<FieldJsonValue>,
|
} as const satisfies SettingsFieldTypeConfig<FieldJsonValue>,
|
||||||
[FieldMetadataType.RichText]: {
|
[FieldMetadataType.RichText]: {
|
||||||
label: 'Rich Text',
|
label: 'Rich Text',
|
||||||
@ -131,7 +131,7 @@ export const SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS: SettingsNonCompositeFiel
|
|||||||
[FieldMetadataType.Array]: {
|
[FieldMetadataType.Array]: {
|
||||||
label: 'Array',
|
label: 'Array',
|
||||||
Icon: IllustrationIconArray,
|
Icon: IllustrationIconArray,
|
||||||
category: 'Basic',
|
category: 'Advanced',
|
||||||
exampleValue: ['value1', 'value2'],
|
exampleValue: ['value1', 'value2'],
|
||||||
} as const satisfies SettingsFieldTypeConfig<FieldArrayValue>,
|
} as const satisfies SettingsFieldTypeConfig<FieldArrayValue>,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -107,6 +107,11 @@ export const SettingsDataModelFieldRelationForm = ({
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const selectedRelationType = watchFormValue(
|
||||||
|
'relation.type',
|
||||||
|
initialRelationType,
|
||||||
|
);
|
||||||
|
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -152,7 +157,10 @@ export const SettingsDataModelFieldRelationForm = ({
|
|||||||
/>
|
/>
|
||||||
</StyledSelectsContainer>
|
</StyledSelectsContainer>
|
||||||
<StyledInputsLabel>
|
<StyledInputsLabel>
|
||||||
Field on {selectedObjectMetadataItem?.labelPlural}
|
Field on{' '}
|
||||||
|
{selectedRelationType === RelationDefinitionType.ManyToOne
|
||||||
|
? selectedObjectMetadataItem?.labelSingular
|
||||||
|
: selectedObjectMetadataItem?.labelPlural}
|
||||||
</StyledInputsLabel>
|
</StyledInputsLabel>
|
||||||
<StyledInputsContainer>
|
<StyledInputsContainer>
|
||||||
<Controller
|
<Controller
|
||||||
|
|||||||
@ -15,7 +15,10 @@ import {
|
|||||||
SettingsDataModelFieldPreviewCardProps,
|
SettingsDataModelFieldPreviewCardProps,
|
||||||
} from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewCard';
|
} from '@/settings/data-model/fields/preview/components/SettingsDataModelFieldPreviewCard';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import {
|
||||||
|
FieldMetadataType,
|
||||||
|
RelationDefinitionType,
|
||||||
|
} from '~/generated-metadata/graphql';
|
||||||
type SettingsDataModelFieldRelationSettingsFormCardProps = {
|
type SettingsDataModelFieldRelationSettingsFormCardProps = {
|
||||||
fieldMetadataItem: Pick<FieldMetadataItem, 'icon' | 'label' | 'type'> &
|
fieldMetadataItem: Pick<FieldMetadataItem, 'icon' | 'label' | 'type'> &
|
||||||
Partial<Omit<FieldMetadataItem, 'icon' | 'label' | 'type'>>;
|
Partial<Omit<FieldMetadataItem, 'icon' | 'label' | 'type'>>;
|
||||||
@ -86,6 +89,10 @@ export const SettingsDataModelFieldRelationSettingsFormCard = ({
|
|||||||
shrink
|
shrink
|
||||||
objectMetadataItem={objectMetadataItem}
|
objectMetadataItem={objectMetadataItem}
|
||||||
relationObjectMetadataItem={relationObjectMetadataItem}
|
relationObjectMetadataItem={relationObjectMetadataItem}
|
||||||
|
pluralizeLabel={
|
||||||
|
watchFormValue('relation.type') ===
|
||||||
|
RelationDefinitionType.ManyToOne
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<StyledRelationImage
|
<StyledRelationImage
|
||||||
src={relationTypeConfig.imageSrc}
|
src={relationTypeConfig.imageSrc}
|
||||||
@ -110,6 +117,10 @@ export const SettingsDataModelFieldRelationSettingsFormCard = ({
|
|||||||
shrink
|
shrink
|
||||||
objectMetadataItem={relationObjectMetadataItem}
|
objectMetadataItem={relationObjectMetadataItem}
|
||||||
relationObjectMetadataItem={objectMetadataItem}
|
relationObjectMetadataItem={objectMetadataItem}
|
||||||
|
pluralizeLabel={
|
||||||
|
watchFormValue('relation.type') !==
|
||||||
|
RelationDefinitionType.ManyToOne
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</StyledPreviewContent>
|
</StyledPreviewContent>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { Card, CardContent } from 'twenty-ui';
|
|||||||
export type SettingsDataModelFieldPreviewCardProps =
|
export type SettingsDataModelFieldPreviewCardProps =
|
||||||
SettingsDataModelFieldPreviewProps & {
|
SettingsDataModelFieldPreviewProps & {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
pluralizeLabel?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledCard = styled(Card)`
|
const StyledCard = styled(Card)`
|
||||||
@ -28,17 +29,23 @@ export const SettingsDataModelFieldPreviewCard = ({
|
|||||||
relationObjectMetadataItem,
|
relationObjectMetadataItem,
|
||||||
shrink,
|
shrink,
|
||||||
withFieldLabel = true,
|
withFieldLabel = true,
|
||||||
}: SettingsDataModelFieldPreviewCardProps) => (
|
pluralizeLabel = false,
|
||||||
<StyledCard className={className} fullWidth>
|
}: SettingsDataModelFieldPreviewCardProps) => {
|
||||||
<StyledCardContent>
|
return (
|
||||||
<SettingsDataModelObjectSummary objectMetadataItem={objectMetadataItem} />
|
<StyledCard className={className} fullWidth>
|
||||||
<SettingsDataModelFieldPreview
|
<StyledCardContent>
|
||||||
objectMetadataItem={objectMetadataItem}
|
<SettingsDataModelObjectSummary
|
||||||
fieldMetadataItem={fieldMetadataItem}
|
objectMetadataItem={objectMetadataItem}
|
||||||
relationObjectMetadataItem={relationObjectMetadataItem}
|
pluralizeLabel={pluralizeLabel}
|
||||||
shrink={shrink}
|
/>
|
||||||
withFieldLabel={withFieldLabel}
|
<SettingsDataModelFieldPreview
|
||||||
/>
|
objectMetadataItem={objectMetadataItem}
|
||||||
</StyledCardContent>
|
fieldMetadataItem={fieldMetadataItem}
|
||||||
</StyledCard>
|
relationObjectMetadataItem={relationObjectMetadataItem}
|
||||||
);
|
shrink={shrink}
|
||||||
|
withFieldLabel={withFieldLabel}
|
||||||
|
/>
|
||||||
|
</StyledCardContent>
|
||||||
|
</StyledCard>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLab
|
|||||||
export type SettingsDataModelObjectSummaryProps = {
|
export type SettingsDataModelObjectSummaryProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
|
pluralizeLabel?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledObjectSummary = styled.div`
|
const StyledObjectSummary = styled.div`
|
||||||
@ -30,6 +31,7 @@ const StyledIconContainer = styled.div`
|
|||||||
export const SettingsDataModelObjectSummary = ({
|
export const SettingsDataModelObjectSummary = ({
|
||||||
className,
|
className,
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
|
pluralizeLabel = true,
|
||||||
}: SettingsDataModelObjectSummaryProps) => {
|
}: SettingsDataModelObjectSummaryProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
@ -43,7 +45,13 @@ export const SettingsDataModelObjectSummary = ({
|
|||||||
<StyledIconContainer>
|
<StyledIconContainer>
|
||||||
<ObjectIcon size={theme.icon.size.sm} stroke={theme.icon.stroke.md} />
|
<ObjectIcon size={theme.icon.size.sm} stroke={theme.icon.stroke.md} />
|
||||||
</StyledIconContainer>
|
</StyledIconContainer>
|
||||||
<OverflowingTextWithTooltip text={objectMetadataItem.labelPlural} />
|
<OverflowingTextWithTooltip
|
||||||
|
text={
|
||||||
|
pluralizeLabel
|
||||||
|
? objectMetadataItem.labelPlural
|
||||||
|
: objectMetadataItem.labelSingular
|
||||||
|
}
|
||||||
|
/>
|
||||||
</StyledObjectName>
|
</StyledObjectName>
|
||||||
<SettingsDataModelObjectTypeTag objectTypeLabel={objectTypeLabel} />
|
<SettingsDataModelObjectTypeTag objectTypeLabel={objectTypeLabel} />
|
||||||
</StyledObjectSummary>
|
</StyledObjectSummary>
|
||||||
|
|||||||
Reference in New Issue
Block a user