**### Problem**
When creating a custom Data Model object, the auto-generated Note and
Task relations had incorrect labels ("Note Targets", "Task Targets") and
a wrong hardcoded icon (IconBuildingSkyscraper).
Expected behavior is to use user-friendly labels ("Notes", "Tasks") and
proper icons, consistent with standard objects like Company and Person.
**Root causes:**
* `icon` in `createFieldInput` was hardcoded to
`'IconBuildingSkyscraper'`
* `label` was derived from `targetFlatObjectMetadata.labelPlural`, which
returns system labels (e.g., "Note Targets") instead of display labels
---
**Fix**
* Added `sourceFieldOverridesByRelationObjectNameSingular` map to define
correct labels and icons for all default relation types
* Ensures consistency with standard objects
Mappings:
* noteTarget: "Note Targets" → "Notes", IconBuildingSkyscraper →
IconNotes
* taskTarget: "Task Targets" → "Tasks", IconBuildingSkyscraper →
IconCheckbox
* attachment: "Attachments" → "Attachments", IconBuildingSkyscraper →
IconFileImport
* timelineActivity: "Timeline Activities" → "Timeline Activities",
IconBuildingSkyscraper → IconTimelineEvent
* favorite: "Favorites" → "Favorites", IconBuildingSkyscraper →
IconHeart
* Added type safety using:
`satisfies Record<(typeof
DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS)[number], ...>`
This ensures new default relations must be explicitly defined
* Renamed variable:
`icon` → `targetFieldIcon`
for better clarity (it is only used for the target field)
---
**Limitations**
* Applies only to newly created custom objects
* Existing objects will keep incorrect labels/icons
* Requires a separate data migration to fix existing data
---
**Testing**
1. Go to Settings → Data Model
2. Create a new custom object
3. Verify:
* Labels show "Notes" and "Tasks" (not "Note Targets"/"Task Targets")
* Icons match those used in standard objects (e.g., Company, Person)
---
## Update (reworked while merging main)
The original approach was reworked:
- The label/icon mapping now lives in a shared
`STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT` constant
(`msg`-based, so labels stay translatable), used as the single source of
truth. Dropped the unused `favorite` entry.
- Standard objects now reference that same constant explicitly at each
call site (uniformization) instead of duplicating the values. Objects
that intentionally differ keep their explicit overrides: note/task →
`Relations`, person/workspaceMember → `Events`, workflow attachments →
`IconFileUpload`.
- Fixed an unrelated typo found along the way: Company's
`timelineActivities` icon was `IconIconTimelineEvent`.
- For the history (supersedes the "Limitations" above): added a `2.9.0`
workspace upgrade command
`upgrade:2-9:fix-standard-relation-field-labels-icons` that re-syncs
**standard** objects' default relation labels/icons against the source
of truth. It deliberately leaves **custom** objects untouched — their
relation fields are user-editable and must not be overwritten by an
upgrade.
## Testing / Verification
Verified locally end-to-end:
**New custom objects**
- Created a custom object via the Data Model UI and via the metadata API
— its note/task/attachment/timeline relations now show `Notes` / `Tasks`
/ `Attachments` / `Timeline Activities` with the correct icons instead
of `Note Targets` + `IconBuildingSkyscraper`.
**Standard uniformization (value-preserving)**
- Re-seeded a workspace on this branch and inspected all 25
default-relation field definitions across the 10 standard objects: every
canonical value is unchanged, every intentional variant (Relations /
Events / IconFileUpload) is preserved, and the only diff vs `main` is
the Company `IconIconTimelineEvent` → `IconTimelineEvent` fix.
**Upgrade command (existing workspaces)**
- Simulated a real upgrade: seeded a workspace on `main` (Company icon
typo present), created a custom object via the metadata API (it came out
with the old buggy labels, as expected on `main`), then switched to this
branch and ran the command.
- Confirmed via both the metadata API and direct DB inspection:
Company's standard `timelineActivities` icon healed to
`IconTimelineEvent`, while the custom object's relations were left
untouched.
- Idempotent: re-running reports "already up to date".
**CI**: typecheck, lint, server unit tests, and all server
integration-test shards green.
---------
Co-authored-by: Manish Kumar <manishkumar@Mac.lan>
Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module';
|
||||
import { FixStandardRelationFieldLabelsIconsCommand } from 'src/database/commands/upgrade-version-command/2-14/2-14-workspace-command-1799000040000-fix-standard-relation-field-labels-icons.command';
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ApplicationModule,
|
||||
WorkspaceCacheModule,
|
||||
WorkspaceIteratorModule,
|
||||
WorkspaceMigrationModule,
|
||||
],
|
||||
providers: [FixStandardRelationFieldLabelsIconsCommand],
|
||||
})
|
||||
export class V2_14_UpgradeVersionCommandModule {}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
import { Command } from 'nest-commander';
|
||||
import {
|
||||
DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS,
|
||||
STANDARD_OBJECTS,
|
||||
} from 'twenty-shared/metadata';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ActiveOrSuspendedWorkspaceCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspace.command-runner';
|
||||
import { WorkspaceIteratorService } from 'src/database/commands/command-runners/workspace-iterator.service';
|
||||
import { type RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspace.command-runner';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { RegisteredWorkspaceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-workspace-command.decorator';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import { computeTwentyStandardApplicationAllFlatEntityMaps } from 'src/engine/workspace-manager/twenty-standard-application/utils/twenty-standard-application-all-flat-entity-maps.constant';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
// The default relation fields every object gets point to one of the default
|
||||
// relation objects (note/task/attachment/timeline). On standard objects their
|
||||
// labels/icons are system-owned, so we re-sync any drift against the
|
||||
// source-of-truth definition (e.g. the Company timelineActivities
|
||||
// IconIconTimelineEvent typo). Custom objects are left untouched on purpose:
|
||||
// their relation fields are user-editable.
|
||||
const DEFAULT_RELATION_TARGET_UNIVERSAL_IDENTIFIERS = new Set<string>(
|
||||
DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS.map(
|
||||
(objectName) => STANDARD_OBJECTS[objectName].universalIdentifier,
|
||||
),
|
||||
);
|
||||
|
||||
@RegisteredWorkspaceCommand('2.14.0', 1799000040000)
|
||||
@Command({
|
||||
name: 'upgrade:2-14:fix-standard-relation-field-labels-icons',
|
||||
description:
|
||||
"Re-sync standard objects' default relation field labels/icons (note/task/attachment/timeline) against the source of truth, healing drift such as the Company timelineActivities IconIconTimelineEvent typo.",
|
||||
})
|
||||
export class FixStandardRelationFieldLabelsIconsCommand extends ActiveOrSuspendedWorkspaceCommandRunner {
|
||||
constructor(
|
||||
protected readonly workspaceIteratorService: WorkspaceIteratorService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
) {
|
||||
super(workspaceIteratorService);
|
||||
}
|
||||
|
||||
override async runOnWorkspace({
|
||||
workspaceId,
|
||||
options,
|
||||
}: RunOnWorkspaceArgs): Promise<void> {
|
||||
const isDryRun = options.dryRun ?? false;
|
||||
|
||||
const { twentyStandardFlatApplication } =
|
||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{ workspaceId },
|
||||
);
|
||||
|
||||
const { flatFieldMetadataMaps: existingFlatFieldMetadataMaps } =
|
||||
await this.workspaceCacheService.getOrRecompute(workspaceId, [
|
||||
'flatFieldMetadataMaps',
|
||||
]);
|
||||
|
||||
const now = new Date().toISOString();
|
||||
|
||||
const { allFlatEntityMaps: standardAllFlatEntityMaps } =
|
||||
computeTwentyStandardApplicationAllFlatEntityMaps({
|
||||
now,
|
||||
workspaceId,
|
||||
twentyStandardApplicationId: twentyStandardFlatApplication.id,
|
||||
});
|
||||
|
||||
const fieldsToUpdate = Object.values(
|
||||
standardAllFlatEntityMaps.flatFieldMetadataMaps.byUniversalIdentifier,
|
||||
)
|
||||
.filter(isDefined)
|
||||
.filter(
|
||||
(standardField) =>
|
||||
isDefined(
|
||||
standardField.relationTargetObjectMetadataUniversalIdentifier,
|
||||
) &&
|
||||
DEFAULT_RELATION_TARGET_UNIVERSAL_IDENTIFIERS.has(
|
||||
standardField.relationTargetObjectMetadataUniversalIdentifier,
|
||||
),
|
||||
)
|
||||
.map((standardField) => {
|
||||
const existingField =
|
||||
existingFlatFieldMetadataMaps.byUniversalIdentifier[
|
||||
standardField.universalIdentifier
|
||||
];
|
||||
|
||||
if (
|
||||
!isDefined(existingField) ||
|
||||
(existingField.label === standardField.label &&
|
||||
existingField.icon === standardField.icon)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...existingField,
|
||||
label: standardField.label,
|
||||
icon: standardField.icon,
|
||||
updatedAt: now,
|
||||
};
|
||||
})
|
||||
.filter(isDefined);
|
||||
|
||||
if (fieldsToUpdate.length === 0) {
|
||||
this.logger.log(
|
||||
`Standard relation field labels/icons already up to date for workspace ${workspaceId}`,
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`${isDryRun ? '[DRY RUN] ' : ''}Workspace ${workspaceId}: ${fieldsToUpdate.length} standard relation field(s) to heal`,
|
||||
);
|
||||
|
||||
if (isDryRun) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result =
|
||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
allFlatEntityOperationByMetadataName: {
|
||||
fieldMetadata: {
|
||||
flatEntityToCreate: [],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: fieldsToUpdate,
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier:
|
||||
twentyStandardFlatApplication.universalIdentifier,
|
||||
},
|
||||
);
|
||||
|
||||
if (result.status === 'fail') {
|
||||
throw new Error(
|
||||
`Migration failed for workspace ${workspaceId} while healing standard relation field labels/icons`,
|
||||
);
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`Healed ${fieldsToUpdate.length} standard relation field(s) for workspace ${workspaceId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
@@ -14,6 +14,7 @@ import { V2_8_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-
|
||||
import { V2_9_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-9/2-9-upgrade-version-command.module';
|
||||
import { V2_10_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-10/2-10-upgrade-version-command.module';
|
||||
import { V2_13_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-13/2-13-upgrade-version-command.module';
|
||||
import { V2_14_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/2-14/2-14-upgrade-version-command.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -31,6 +32,7 @@ import { V2_13_UpgradeVersionCommandModule } from 'src/database/commands/upgrade
|
||||
V2_9_UpgradeVersionCommandModule,
|
||||
V2_10_UpgradeVersionCommandModule,
|
||||
V2_13_UpgradeVersionCommandModule,
|
||||
V2_14_UpgradeVersionCommandModule,
|
||||
],
|
||||
})
|
||||
export class WorkspaceCommandProviderModule {}
|
||||
|
||||
+1
-1
@@ -441,7 +441,7 @@ export const COMPANY_FLAT_FIELDS_MOCK = {
|
||||
label: 'Timeline Activities',
|
||||
defaultValue: null,
|
||||
description: 'Timeline Activities linked to the company',
|
||||
icon: 'IconIconTimelineEvent',
|
||||
icon: 'IconTimelineEvent',
|
||||
standardOverrides: null,
|
||||
options: null,
|
||||
settings: { relationType: RelationType.ONE_TO_MANY },
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
|
||||
import { DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS } from 'twenty-shared/metadata';
|
||||
|
||||
export const STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT = {
|
||||
noteTarget: { label: msg`Notes`, icon: 'IconNotes' },
|
||||
taskTarget: { label: msg`Tasks`, icon: 'IconCheckbox' },
|
||||
attachment: { label: msg`Attachments`, icon: 'IconFileImport' },
|
||||
timelineActivity: {
|
||||
label: msg`Timeline Activities`,
|
||||
icon: 'IconTimelineEvent',
|
||||
},
|
||||
} satisfies Record<
|
||||
(typeof DEFAULT_RELATIONS_OBJECTS_STANDARD_IDS)[number],
|
||||
{ label: MessageDescriptor; icon: string }
|
||||
>;
|
||||
+11
-4
@@ -5,7 +5,9 @@ import {
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { computeMorphOrRelationFieldJoinColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-morph-or-relation-field-join-column-name.util';
|
||||
import { i18nLabel } from 'src/engine/workspace-manager/twenty-standard-application/utils/i18n-label.util';
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
@@ -94,11 +96,16 @@ export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({
|
||||
flatEntityId: targetFlatObjectMetadataId,
|
||||
});
|
||||
|
||||
const icon =
|
||||
const targetFieldIcon =
|
||||
STANDARD_OBJECT_ICONS[
|
||||
targetFlatObjectMetadata.nameSingular as keyof typeof STANDARD_OBJECT_ICONS
|
||||
] || 'IconBuildingSkyscraper';
|
||||
|
||||
const standardFieldProperties =
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT[
|
||||
objectMetadataNameSingular
|
||||
];
|
||||
|
||||
const morphFieldName = `target${capitalize(sourceFlatObjectMetadata.nameSingular)}`;
|
||||
const fieldName = isObjectMigratedToMorphRelations
|
||||
? morphFieldName
|
||||
@@ -122,10 +129,10 @@ export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({
|
||||
morphId,
|
||||
targetFieldName: fieldName,
|
||||
createFieldInput: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
icon: standardFieldProperties.icon,
|
||||
type: FieldMetadataType.RELATION,
|
||||
name: targetFlatObjectMetadata.namePlural,
|
||||
label: capitalize(targetFlatObjectMetadata.labelPlural),
|
||||
label: i18nLabel(standardFieldProperties.label),
|
||||
isSystem: false,
|
||||
relationCreationPayload: {
|
||||
type: RelationType.ONE_TO_MANY,
|
||||
@@ -133,7 +140,7 @@ export const buildDefaultRelationFlatFieldMetadatasForCustomObject = ({
|
||||
targetFieldLabel: capitalize(
|
||||
sourceFlatObjectMetadata.nameSingular,
|
||||
),
|
||||
targetFieldIcon: icon,
|
||||
targetFieldIcon: targetFieldIcon,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
+22
-8
@@ -7,6 +7,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -347,9 +348,12 @@ export const buildCompanyStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'taskTargets',
|
||||
label: i18nLabel(msg`Tasks`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.taskTarget.label,
|
||||
),
|
||||
description: i18nLabel(msg`Tasks tied to the company`),
|
||||
icon: 'IconCheckbox',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.taskTarget
|
||||
.icon,
|
||||
isUIEditable: false,
|
||||
isNullable: true,
|
||||
targetObjectName: 'taskTarget',
|
||||
@@ -370,9 +374,12 @@ export const buildCompanyStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'noteTargets',
|
||||
label: i18nLabel(msg`Notes`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.noteTarget.label,
|
||||
),
|
||||
description: i18nLabel(msg`Notes tied to the company`),
|
||||
icon: 'IconNotes',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.noteTarget
|
||||
.icon,
|
||||
isUIEditable: false,
|
||||
isNullable: true,
|
||||
targetObjectName: 'noteTarget',
|
||||
@@ -415,9 +422,12 @@ export const buildCompanyStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'attachments',
|
||||
label: i18nLabel(msg`Attachments`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment.label,
|
||||
),
|
||||
description: i18nLabel(msg`Attachments linked to the company`),
|
||||
icon: 'IconFileImport',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment
|
||||
.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'attachment',
|
||||
targetFieldName: 'targetCompany',
|
||||
@@ -437,9 +447,13 @@ export const buildCompanyStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline Activities linked to the company`),
|
||||
icon: 'IconIconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'timelineActivity',
|
||||
targetFieldName: 'targetCompany',
|
||||
|
||||
+12
-4
@@ -6,6 +6,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -239,9 +240,13 @@ export const buildDashboardStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline activities linked to the dashboard`),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'timelineActivity',
|
||||
targetFieldName: 'targetDashboard',
|
||||
@@ -261,9 +266,12 @@ export const buildDashboardStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'attachments',
|
||||
label: i18nLabel(msg`Attachments`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment.label,
|
||||
),
|
||||
description: i18nLabel(msg`Attachments linked to the dashboard`),
|
||||
icon: 'IconFileImport',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment
|
||||
.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'attachment',
|
||||
targetFieldName: 'targetDashboard',
|
||||
|
||||
+12
-4
@@ -6,6 +6,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -266,9 +267,12 @@ export const buildNoteStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'attachments',
|
||||
label: i18nLabel(msg`Attachments`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment.label,
|
||||
),
|
||||
description: i18nLabel(msg`Note attachments`),
|
||||
icon: 'IconFileImport',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment
|
||||
.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'attachment',
|
||||
targetFieldName: 'targetNote',
|
||||
@@ -288,9 +292,13 @@ export const buildNoteStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline Activities linked to the note.`),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'timelineActivity',
|
||||
targetFieldName: 'targetNote',
|
||||
|
||||
+22
-8
@@ -7,6 +7,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -363,9 +364,12 @@ export const buildOpportunityStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'taskTargets',
|
||||
label: i18nLabel(msg`Tasks`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.taskTarget.label,
|
||||
),
|
||||
description: i18nLabel(msg`Tasks tied to the opportunity`),
|
||||
icon: 'IconCheckbox',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.taskTarget
|
||||
.icon,
|
||||
isUIEditable: false,
|
||||
isNullable: true,
|
||||
targetObjectName: 'taskTarget',
|
||||
@@ -386,9 +390,12 @@ export const buildOpportunityStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'noteTargets',
|
||||
label: i18nLabel(msg`Notes`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.noteTarget.label,
|
||||
),
|
||||
description: i18nLabel(msg`Notes tied to the opportunity`),
|
||||
icon: 'IconNotes',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.noteTarget
|
||||
.icon,
|
||||
isUIEditable: false,
|
||||
isNullable: true,
|
||||
targetObjectName: 'noteTarget',
|
||||
@@ -409,9 +416,12 @@ export const buildOpportunityStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'attachments',
|
||||
label: i18nLabel(msg`Attachments`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment.label,
|
||||
),
|
||||
description: i18nLabel(msg`Attachments linked to the opportunity`),
|
||||
icon: 'IconFileImport',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment
|
||||
.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'attachment',
|
||||
targetFieldName: 'targetOpportunity',
|
||||
@@ -431,11 +441,15 @@ export const buildOpportunityStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(
|
||||
msg`Timeline Activities linked to the opportunity.`,
|
||||
),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'timelineActivity',
|
||||
targetFieldName: 'targetOpportunity',
|
||||
|
||||
+16
-6
@@ -9,6 +9,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -365,9 +366,12 @@ export const buildPersonStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'taskTargets',
|
||||
label: i18nLabel(msg`Tasks`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.taskTarget.label,
|
||||
),
|
||||
description: i18nLabel(msg`Tasks tied to the contact`),
|
||||
icon: 'IconCheckbox',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.taskTarget
|
||||
.icon,
|
||||
isUIEditable: false,
|
||||
isNullable: true,
|
||||
targetObjectName: 'taskTarget',
|
||||
@@ -388,9 +392,12 @@ export const buildPersonStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'noteTargets',
|
||||
label: i18nLabel(msg`Notes`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.noteTarget.label,
|
||||
),
|
||||
description: i18nLabel(msg`Notes tied to the contact`),
|
||||
icon: 'IconNotes',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.noteTarget
|
||||
.icon,
|
||||
isUIEditable: false,
|
||||
isNullable: true,
|
||||
targetObjectName: 'noteTarget',
|
||||
@@ -411,9 +418,12 @@ export const buildPersonStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'attachments',
|
||||
label: i18nLabel(msg`Attachments`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment.label,
|
||||
),
|
||||
description: i18nLabel(msg`Attachments linked to the contact.`),
|
||||
icon: 'IconFileImport',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment
|
||||
.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'attachment',
|
||||
targetFieldName: 'targetPerson',
|
||||
|
||||
+12
-4
@@ -7,6 +7,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -323,9 +324,12 @@ export const buildTaskStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'attachments',
|
||||
label: i18nLabel(msg`Attachments`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment.label,
|
||||
),
|
||||
description: i18nLabel(msg`Task attachments`),
|
||||
icon: 'IconFileImport',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.attachment
|
||||
.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'attachment',
|
||||
targetFieldName: 'targetTask',
|
||||
@@ -369,9 +373,13 @@ export const buildTaskStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline Activities linked to the task.`),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: true,
|
||||
targetObjectName: 'timelineActivity',
|
||||
targetFieldName: 'targetTask',
|
||||
|
||||
+7
-2
@@ -7,6 +7,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -428,9 +429,13 @@ export const buildWorkflowRunStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline activities linked to the run`),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: false,
|
||||
isUIEditable: false,
|
||||
targetObjectName: 'timelineActivity',
|
||||
|
||||
+7
-2
@@ -6,6 +6,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -347,9 +348,13 @@ export const buildWorkflowStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline activities linked to the workflow`),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: false,
|
||||
targetObjectName: 'timelineActivity',
|
||||
targetFieldName: 'targetWorkflow',
|
||||
|
||||
+7
-2
@@ -7,6 +7,7 @@ import {
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT } from 'src/engine/metadata-modules/object-metadata/constants/standard-relation-field-properties.constant';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
|
||||
import {
|
||||
@@ -354,9 +355,13 @@ export const buildWorkflowVersionStandardFlatFieldMetadatas = ({
|
||||
type: FieldMetadataType.RELATION,
|
||||
morphId: null,
|
||||
fieldName: 'timelineActivities',
|
||||
label: i18nLabel(msg`Timeline Activities`),
|
||||
label: i18nLabel(
|
||||
STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT.timelineActivity
|
||||
.label,
|
||||
),
|
||||
description: i18nLabel(msg`Timeline activities linked to the version`),
|
||||
icon: 'IconTimelineEvent',
|
||||
icon: STANDARD_RELATION_FIELD_PROPERTIES_BY_RELATION_OBJECT
|
||||
.timelineActivity.icon,
|
||||
isNullable: false,
|
||||
isUIEditable: false,
|
||||
targetObjectName: 'timelineActivity',
|
||||
|
||||
Reference in New Issue
Block a user