Fix breadcrumbs to display friendly object names instead of API names… (#13573)

Fixes #13250

This PR fixes the breadcrumb display issue where API names were shown
instead of friendly object names when navigating to related objects in
the detail view.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
aaron
2025-08-03 12:18:32 -07:00
committed by GitHub
parent 253a9221db
commit b8a26dfe8c
27 changed files with 211 additions and 109 deletions
@@ -5,16 +5,16 @@ import { WorkflowDeleteRecordAction } from '@/workflow/types/Workflow';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useEffect, useState } from 'react';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useTheme } from '@emotion/react';
import { isDefined } from 'twenty-shared/utils';
import { HorizontalSeparator, useIcons } from 'twenty-ui/display';
import { SelectOption } from 'twenty-ui/input';
import { JsonValue } from 'type-fest';
import { useDebouncedCallback } from 'use-debounce';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useTheme } from '@emotion/react';
type WorkflowEditActionDeleteRecordProps = {
action: WorkflowDeleteRecordAction;
@@ -29,7 +29,7 @@ type WorkflowEditActionDeleteRecordProps = {
};
type DeleteRecordFormData = {
objectName: string;
objectNameSingular: string;
objectRecordId: string;
};
@@ -52,7 +52,7 @@ export const WorkflowEditActionDeleteRecord = ({
}));
const [formData, setFormData] = useState<DeleteRecordFormData>({
objectName: action.settings.input.objectName,
objectNameSingular: action.settings.input.objectName,
objectRecordId: action.settings.input.objectRecordId,
});
const isFormDisabled = actionOptions.readonly;
@@ -72,7 +72,7 @@ export const WorkflowEditActionDeleteRecord = ({
};
const objectNameSingular = activeNonSystemObjectMetadataItems.find(
(item) => item.nameSingular === formData.objectName,
(item) => item.nameSingular === formData.objectNameSingular,
)?.nameSingular;
const saveAction = useDebouncedCallback(
@@ -82,7 +82,7 @@ export const WorkflowEditActionDeleteRecord = ({
}
const {
objectName: updatedObjectName,
objectNameSingular: updatedObjectName,
objectRecordId: updatedObjectRecordId,
} = formData;
@@ -137,12 +137,12 @@ export const WorkflowEditActionDeleteRecord = ({
label="Object"
fullWidth
disabled={isFormDisabled}
value={formData.objectName}
value={formData.objectNameSingular}
emptyOption={{ label: 'Select an option', value: '' }}
options={availableMetadata}
onChange={(objectName) => {
onChange={(objectNameSingular) => {
const newFormData: DeleteRecordFormData = {
objectName,
objectNameSingular,
objectRecordId: '',
};
@@ -35,7 +35,7 @@ type WorkflowEditActionUpdateRecordProps = {
};
type UpdateRecordFormData = {
objectName: string;
objectNameSingular: string;
objectRecordId: string;
fieldsToUpdate: string[];
[field: string]: unknown;
@@ -60,7 +60,7 @@ export const WorkflowEditActionUpdateRecord = ({
}));
const [formData, setFormData] = useState<UpdateRecordFormData>({
objectName: action.settings.input.objectName,
objectNameSingular: action.settings.input.objectName,
objectRecordId: action.settings.input.objectRecordId,
fieldsToUpdate: action.settings.input.fieldsToUpdate ?? [],
...action.settings.input.objectRecord,
@@ -83,7 +83,7 @@ export const WorkflowEditActionUpdateRecord = ({
};
const selectedObjectMetadataItem = activeNonSystemObjectMetadataItems.find(
(item) => item.nameSingular === formData.objectName,
(item) => item.nameSingular === formData.objectNameSingular,
);
const objectNameSingular = selectedObjectMetadataItem?.nameSingular;
@@ -114,7 +114,7 @@ export const WorkflowEditActionUpdateRecord = ({
}
const {
objectName: updatedObjectName,
objectNameSingular: updatedObjectName,
objectRecordId: updatedObjectRecordId,
fieldsToUpdate: updatedFieldsToUpdate,
...updatedOtherFields
@@ -174,12 +174,12 @@ export const WorkflowEditActionUpdateRecord = ({
label="Object"
fullWidth
disabled={isFormDisabled}
value={formData.objectName}
value={formData.objectNameSingular}
emptyOption={{ label: 'Select an option', value: '' }}
options={availableMetadata}
onChange={(updatedObjectName) => {
const newFormData: UpdateRecordFormData = {
objectName: updatedObjectName,
objectNameSingular: updatedObjectName,
objectRecordId: '',
fieldsToUpdate: [],
};
@@ -36,7 +36,7 @@ type WorkflowEditActionFindRecordsProps = {
};
type FindRecordsFormData = {
objectName: string;
objectNameSingular: string;
filter?: FindRecordsActionFilter;
limit?: number;
};
@@ -65,14 +65,14 @@ export const WorkflowEditActionFindRecords = ({
}));
const [formData, setFormData] = useState<FindRecordsFormData>({
objectName: action.settings.input.objectName,
objectNameSingular: action.settings.input.objectName,
limit: action.settings.input.limit,
filter: action.settings.input.filter as FindRecordsActionFilter,
});
const isFormDisabled = actionOptions.readonly;
const selectedObjectMetadataItem = activeNonSystemObjectMetadataItems.find(
(item) => item.nameSingular === formData.objectName,
(item) => item.nameSingular === formData.objectNameSingular,
);
const selectedObjectMetadataItemNameSingular =
@@ -87,7 +87,7 @@ export const WorkflowEditActionFindRecords = ({
}
const {
objectName: updatedObjectName,
objectNameSingular: updatedObjectName,
limit: updatedLimit,
filter: updatedFilter,
} = formData;
@@ -118,7 +118,7 @@ export const WorkflowEditActionFindRecords = ({
action,
defaultTitle: 'Search Records',
});
const instanceId = `workflow-edit-action-record-find-records-${action.id}-${formData.objectName}`;
const instanceId = `workflow-edit-action-record-find-records-${action.id}-${formData.objectNameSingular}`;
return (
<>
@@ -148,9 +148,9 @@ export const WorkflowEditActionFindRecords = ({
value={selectedObjectMetadataItemNameSingular}
emptyOption={{ label: 'Select an option', value: '' }}
options={availableMetadata}
onChange={(objectName) => {
onChange={(objectNameSingular) => {
const newFormData: FindRecordsFormData = {
objectName,
objectNameSingular,
limit: 1,
};