mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 12:02:10 +03:00
toggle Field on label between singular and plural based on relation type (#8817)
#7683 ![labelPlural](https://github.com/user-attachments/assets/3e620d7e-dd51-4e4e-a9ba-289f2685ddf3) ![labelSingular](https://github.com/user-attachments/assets/84739ac5-29b4-48c8-8a71-3f8f2816641b) 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:
parent
0527bc296e
commit
2b0f67191a
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user