Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6bb8fa8559 | |||
| a771216f6e | |||
| fe371eb4c4 | |||
| 1db92ce662 | |||
| 6bb0212a70 | |||
| 4a543a0e0a |
+13
-9
@@ -13,7 +13,8 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { pascalCase } from '~/utils/string/pascalCase';
|
||||
|
||||
export const RelationFromManyFieldDisplay = () => {
|
||||
const { fieldValue, fieldDefinition } = useRelationFromManyFieldDisplay();
|
||||
const { fieldValue, fieldDefinition, generateRecordChipData } =
|
||||
useRelationFromManyFieldDisplay();
|
||||
const { isFocused } = useFieldFocus();
|
||||
const { disableChipClick } = useContext(FieldContext);
|
||||
|
||||
@@ -99,14 +100,17 @@ export const RelationFromManyFieldDisplay = () => {
|
||||
} else {
|
||||
return (
|
||||
<ExpandableList isChipCountDisplayed={isFocused}>
|
||||
{fieldValue.filter(isDefined).map((record) => (
|
||||
<RecordChip
|
||||
key={record.id}
|
||||
objectNameSingular={objectNameSingular}
|
||||
record={record}
|
||||
forceDisableClick={disableChipClick}
|
||||
/>
|
||||
))}
|
||||
{fieldValue.filter(isDefined).map((record) => {
|
||||
const recordChipData = generateRecordChipData(record);
|
||||
return (
|
||||
<RecordChip
|
||||
key={recordChipData.recordId}
|
||||
objectNameSingular={recordChipData.objectNameSingular}
|
||||
record={record}
|
||||
forceDisableClick={disableChipClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ExpandableList>
|
||||
);
|
||||
}
|
||||
|
||||
+1
-2
@@ -60,9 +60,8 @@ export const useRelationFromManyFieldDisplay = () => {
|
||||
: (record: ObjectRecord) =>
|
||||
generateDefaultRecordChipData({
|
||||
record,
|
||||
// @ts-expect-error Above assertions does not infer that fieldDefinition.metadata.objectMetadataNameSingular always defined
|
||||
objectNameSingular:
|
||||
fieldDefinition.metadata.objectMetadataNameSingular,
|
||||
fieldDefinition.metadata.relationObjectMetadataNameSingular,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
+1
-2
@@ -60,9 +60,8 @@ export const useRelationToOneFieldDisplay = () => {
|
||||
: (record: ObjectRecord) =>
|
||||
generateDefaultRecordChipData({
|
||||
record,
|
||||
// @ts-expect-error Above assertions does not infer that fieldDefinition.metadata.objectMetadataNameSingular always defined
|
||||
objectNameSingular:
|
||||
fieldDefinition.metadata.objectMetadataNameSingular,
|
||||
fieldDefinition.metadata.relationObjectMetadataNameSingular,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
+5
-1
@@ -9,6 +9,7 @@ import { useCurrencySettingsFormInitialValues } from '@/settings/data-model/fiel
|
||||
import { Select } from '@/ui/input/components/Select';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconCurrencyDollar } from 'twenty-ui/display';
|
||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||
|
||||
export const settingsDataModelFieldCurrencyFormSchema = z.object({
|
||||
defaultValue: currencyFieldDefaultValueSchema,
|
||||
@@ -58,7 +59,10 @@ export const SettingsDataModelFieldCurrencyForm = ({
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
dropdownId="object-field-default-value-select-currency"
|
||||
options={CURRENCIES}
|
||||
options={CURRENCIES.map(({ value, ...rest }) => ({
|
||||
...rest,
|
||||
value: applySimpleQuotesToString(value),
|
||||
}))}
|
||||
selectSizeVariant="small"
|
||||
withSearchInput={true}
|
||||
/>
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ export const SettingsDataModelFieldPreview = ({
|
||||
fieldMetadataItem.name || `${fieldMetadataItem.type}-new-field`;
|
||||
const recordId =
|
||||
previewRecord?.id ??
|
||||
`${objectMetadataItem.nameSingular}-${fieldName}-${fieldMetadataItem.relationDefinition?.direction}-preview`;
|
||||
`${objectMetadataItem.nameSingular}-${fieldName}-${fieldMetadataItem.relationDefinition?.direction}-${relationObjectMetadataItem?.nameSingular}-preview`;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'nest-commander';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { In, Like, Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveOrSuspendedWorkspacesMigrationCommandRunner,
|
||||
RunOnWorkspaceArgs,
|
||||
} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
|
||||
@Command({
|
||||
name: 'upgrade:0-53:remove-relation-foreign-key-field-metadata',
|
||||
description: 'Remove relation foreign key from field metadata',
|
||||
})
|
||||
export class RemoveRelationForeignKeyFieldMetadataCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
protected readonly workspaceRepository: Repository<Workspace>,
|
||||
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
override async runOnWorkspace({
|
||||
index,
|
||||
total,
|
||||
workspaceId,
|
||||
options,
|
||||
}: RunOnWorkspaceArgs): Promise<void> {
|
||||
this.logger.log(
|
||||
`Running command for workspace ${workspaceId} ${index + 1}/${total}`,
|
||||
);
|
||||
|
||||
const fieldMetadataCollection = await this.fieldMetadataRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
type: In([FieldMetadataType.UUID]),
|
||||
label: Like('%(foreign key)%'),
|
||||
},
|
||||
});
|
||||
|
||||
if (!fieldMetadataCollection.length) {
|
||||
this.logger.log(
|
||||
chalk.yellow(
|
||||
`No relation field metadata found for workspace ${workspaceId}.`,
|
||||
),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.dryRun) {
|
||||
this.logger.log(
|
||||
chalk.yellow(
|
||||
`Dry run, would delete ${fieldMetadataCollection.length} relation field metadata for workspace ${workspaceId}.`,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
await this.fieldMetadataRepository.delete({
|
||||
id: In(
|
||||
fieldMetadataCollection.map((fieldMetadata) => fieldMetadata.id),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
chalk.green(`Command completed for workspace ${workspaceId}.`),
|
||||
);
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -1,16 +1,28 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { BackfillWorkflowNextStepIdsCommand } from 'src/database/commands/upgrade-version-command/0-52/0-52-backfill-workflow-next-step-ids.command';
|
||||
import { MigrateWorkflowEventListenersToAutomatedTriggersCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-migrate-workflow-event-listeners-to-automated-triggers.command';
|
||||
import { RemoveRelationForeignKeyFieldMetadataCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-remove-relation-foreign-key-field-metadata.command';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Workspace], 'core'),
|
||||
TypeOrmModule.forFeature([FieldMetadataEntity], 'metadata'),
|
||||
WorkspaceDataSourceModule,
|
||||
],
|
||||
providers: [MigrateWorkflowEventListenersToAutomatedTriggersCommand],
|
||||
exports: [MigrateWorkflowEventListenersToAutomatedTriggersCommand],
|
||||
providers: [
|
||||
MigrateWorkflowEventListenersToAutomatedTriggersCommand,
|
||||
BackfillWorkflowNextStepIdsCommand,
|
||||
RemoveRelationForeignKeyFieldMetadataCommand,
|
||||
],
|
||||
exports: [
|
||||
MigrateWorkflowEventListenersToAutomatedTriggersCommand,
|
||||
RemoveRelationForeignKeyFieldMetadataCommand,
|
||||
BackfillWorkflowNextStepIdsCommand,
|
||||
],
|
||||
})
|
||||
export class V0_53_UpgradeVersionCommandModule {}
|
||||
|
||||
+3
-3
@@ -19,11 +19,11 @@ import { UpdateViewAggregateOperationsCommand } from 'src/database/commands/upgr
|
||||
import { UpgradeCreatedByEnumCommand } from 'src/database/commands/upgrade-version-command/0-51/0-51-update-workflow-trigger-type-enum.command';
|
||||
import { MigrateRelationsToFieldMetadataCommand } from 'src/database/commands/upgrade-version-command/0-52/0-52-migrate-relations-to-field-metadata.command';
|
||||
import { UpgradeDateAndDateTimeFieldsSettingsJsonCommand } from 'src/database/commands/upgrade-version-command/0-52/0-52-upgrade-settings-field';
|
||||
import { MigrateWorkflowEventListenersToAutomatedTriggersCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-migrate-workflow-event-listeners-to-automated-triggers.command';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
|
||||
import { MigrateWorkflowEventListenersToAutomatedTriggersCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-migrate-workflow-event-listeners-to-automated-triggers.command';
|
||||
|
||||
type VersionCommands = {
|
||||
beforeSyncMetadata: ActiveOrSuspendedWorkspacesMigrationCommandRunner[];
|
||||
@@ -34,7 +34,7 @@ type VersionCommands = {
|
||||
description: 'Upgrade workspaces to the latest version',
|
||||
})
|
||||
export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
fromWorkspaceVersion = new SemVer('0.50.0');
|
||||
fromWorkspaceVersion = new SemVer('0.51.0');
|
||||
private commands: VersionCommands;
|
||||
|
||||
constructor(
|
||||
@@ -117,7 +117,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
],
|
||||
};
|
||||
|
||||
this.commands = commands_053;
|
||||
this.commands = _commands_052;
|
||||
}
|
||||
|
||||
override async runBeforeSyncMetadata(args: RunOnWorkspaceArgs) {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ export async function determineSchemaRelationDetails(
|
||||
objectMetadataMaps.byId[fieldMetadata.relationTargetObjectMetadataId];
|
||||
|
||||
if (!sourceObjectMetadata || !targetObjectMetadata) {
|
||||
throw new Error('Object metadata not found');
|
||||
throw new Error(`Object metadata not found for field ${fieldMetadata.id}`);
|
||||
}
|
||||
|
||||
if (!fieldMetadata.relationTargetFieldMetadataId) {
|
||||
|
||||
+60
-43
@@ -18,7 +18,6 @@ import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
import { FieldMetadataUpdate } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory';
|
||||
import { camelCase } from 'src/utils/camel-case';
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationFieldRelationFactory {
|
||||
constructor(
|
||||
@@ -101,6 +100,24 @@ export class WorkspaceMigrationFieldRelationFactory {
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
sourceFieldMetadata.settings.relationType !== RelationType.MANY_TO_ONE
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings.joinColumnName) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.id} has no join column name in settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.relationTargetObjectMetadataId} not found`,
|
||||
@@ -137,29 +154,27 @@ export class WorkspaceMigrationFieldRelationFactory {
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(targetObjectMetadata),
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY,
|
||||
columnName: `${camelCase(targetFieldMetadata.name)}Id`,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(targetObjectMetadata),
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
columnName: `${camelCase(targetFieldMetadata.name)}Id`,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
referencedTableName:
|
||||
computeObjectTargetTable(sourceObjectMetadata),
|
||||
computeObjectTargetTable(targetObjectMetadata),
|
||||
referencedTableColumnName: 'id',
|
||||
isUnique:
|
||||
targetFieldMetadata.settings.relationType ===
|
||||
RelationType.ONE_TO_ONE,
|
||||
onDelete: targetFieldMetadata.settings.onDelete,
|
||||
isUnique: false,
|
||||
onDelete: sourceFieldMetadata.settings.onDelete,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -192,22 +207,27 @@ export class WorkspaceMigrationFieldRelationFactory {
|
||||
sourceFieldMetadata.relationTargetObjectMetadataId
|
||||
];
|
||||
|
||||
if (!sourceObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.objectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
// We're creating it from `ONE_TO_MANY` with the join column so we don't need to create a migration for `MANY_TO_ONE`
|
||||
if (
|
||||
sourceFieldMetadata.settings.relationType === RelationType.MANY_TO_ONE
|
||||
sourceFieldMetadata.settings.relationType !== RelationType.MANY_TO_ONE
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sourceObjectMetadata) {
|
||||
if (!sourceFieldMetadata.settings.joinColumnName) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.objectMetadataId} not found`,
|
||||
`FieldMetadata with id ${sourceFieldMetadata.id} has no join column name in settings`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -239,43 +259,29 @@ export class WorkspaceMigrationFieldRelationFactory {
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetFieldMetadata.settings.joinColumnName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(targetObjectMetadata),
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
...this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
targetFieldMetadata,
|
||||
sourceFieldMetadata,
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(targetObjectMetadata),
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
columnName:
|
||||
targetFieldMetadata.settings.joinColumnName ??
|
||||
`${camelCase(targetFieldMetadata.name)}Id`,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
referencedTableName:
|
||||
computeObjectTargetTable(sourceObjectMetadata),
|
||||
computeObjectTargetTable(targetObjectMetadata),
|
||||
referencedTableColumnName: 'id',
|
||||
isUnique:
|
||||
targetFieldMetadata.settings.relationType ===
|
||||
RelationType.ONE_TO_ONE,
|
||||
onDelete: targetFieldMetadata.settings.onDelete,
|
||||
isUnique: false,
|
||||
onDelete: sourceFieldMetadata.settings.onDelete,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -314,6 +320,19 @@ export class WorkspaceMigrationFieldRelationFactory {
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
sourceFieldMetadata.settings.relationType !== RelationType.MANY_TO_ONE
|
||||
) {
|
||||
// Only MANY_TO_ONE relations deletion have consequences on the database schema
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.relationTargetObjectMetadataId} not found`,
|
||||
@@ -342,32 +361,30 @@ export class WorkspaceMigrationFieldRelationFactory {
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetFieldMetadata.settings) {
|
||||
if (!sourceFieldMetadata.settings.joinColumnName) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no join column name, it should not generate a workspace migration`,
|
||||
);
|
||||
}
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(targetObjectMetadata),
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY,
|
||||
columnName: `${camelCase(targetFieldMetadata.name)}Id`,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(targetObjectMetadata),
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP,
|
||||
columnName:
|
||||
targetFieldMetadata.settings.joinColumnName ??
|
||||
`${camelCase(targetFieldMetadata.name)}Id`,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
+6
-6
@@ -130,10 +130,6 @@ export class WorkspaceFieldRelationComparator {
|
||||
throw new Error(`Field ${fieldId} not found in originalObjectMetadata`);
|
||||
}
|
||||
|
||||
if (!standardFieldMetadata) {
|
||||
throw new Error(`Field ${fieldId} not found in standardObjectMetadata`);
|
||||
}
|
||||
|
||||
for (const difference of differences) {
|
||||
const property = difference.path[difference.path.length - 1];
|
||||
|
||||
@@ -175,11 +171,11 @@ export class WorkspaceFieldRelationComparator {
|
||||
(fieldPropertiesToStringify as readonly string[]).includes(property)
|
||||
) {
|
||||
const newValue = this.parseJSONOrString(difference.value);
|
||||
const oldValue = this.parseJSONOrString(difference.oldValue);
|
||||
|
||||
if (property === 'settings' && difference.oldValue) {
|
||||
const newSettings = newValue as FieldMetadataRelationSettings;
|
||||
const oldSettings =
|
||||
difference.oldValue as FieldMetadataRelationSettings;
|
||||
const oldSettings = oldValue as FieldMetadataRelationSettings;
|
||||
|
||||
// Check if the relation type has changed
|
||||
if (oldSettings.relationType !== newSettings.relationType) {
|
||||
@@ -193,6 +189,10 @@ export class WorkspaceFieldRelationComparator {
|
||||
}
|
||||
}
|
||||
|
||||
if (!standardFieldMetadata) {
|
||||
throw new Error(`Field ${fieldId} not found in standardObjectMetadata`);
|
||||
}
|
||||
|
||||
if (relationTypeChange) {
|
||||
result.push({
|
||||
action: ComparatorAction.DELETE,
|
||||
|
||||
+15
-11
@@ -221,8 +221,6 @@ export class WorkspaceMetadataUpdaterService {
|
||||
[];
|
||||
let updatedFieldRelationMetadataCollection: FieldMetadataUpdate<FieldMetadataType.RELATION>[] =
|
||||
[];
|
||||
let deletedFieldRelationMetadataCollection: FieldMetadataUpdate<FieldMetadataType.RELATION>[] =
|
||||
[];
|
||||
|
||||
/**
|
||||
* Create field relation metadata
|
||||
@@ -253,20 +251,26 @@ export class WorkspaceMetadataUpdaterService {
|
||||
}
|
||||
|
||||
if (!options || options.actions.includes('delete')) {
|
||||
deletedFieldRelationMetadataCollection = await this.updateEntities<
|
||||
FieldMetadataEntity<FieldMetadataType.RELATION>
|
||||
>(
|
||||
manager,
|
||||
FieldMetadataEntity,
|
||||
storage.fieldRelationMetadataDeleteCollection,
|
||||
['objectMetadataId', 'workspaceId'],
|
||||
);
|
||||
const fieldMetadataRepository =
|
||||
manager.getRepository(FieldMetadataEntity);
|
||||
|
||||
if (storage.fieldRelationMetadataDeleteCollection.length > 0) {
|
||||
await fieldMetadataRepository.delete(
|
||||
storage.fieldRelationMetadataDeleteCollection.map(
|
||||
(field) => field.id,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
createdFieldRelationMetadataCollection,
|
||||
updatedFieldRelationMetadataCollection,
|
||||
deletedFieldRelationMetadataCollection,
|
||||
deletedFieldRelationMetadataCollection:
|
||||
storage.fieldRelationMetadataDeleteCollection.map((field) => ({
|
||||
current: field,
|
||||
altered: field,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+33
-13
@@ -62,19 +62,39 @@ export class MessagingMessageService {
|
||||
});
|
||||
|
||||
if (existingMessage) {
|
||||
await messageChannelMessageAssociationRepository.upsert(
|
||||
{
|
||||
messageChannelId,
|
||||
messageId: existingMessage.id,
|
||||
messageExternalId: message.externalId,
|
||||
messageThreadExternalId: message.messageThreadExternalId,
|
||||
},
|
||||
{
|
||||
conflictPaths: ['messageChannelId', 'messageId'],
|
||||
indexPredicate: '"deletedAt" IS NULL',
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
const existingAssociation =
|
||||
await messageChannelMessageAssociationRepository.findOne(
|
||||
{
|
||||
where: {
|
||||
messageChannelId,
|
||||
messageId: existingMessage.id,
|
||||
},
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
if (existingAssociation) {
|
||||
await messageChannelMessageAssociationRepository.update(
|
||||
{
|
||||
id: existingAssociation.id,
|
||||
},
|
||||
{
|
||||
messageExternalId: message.externalId,
|
||||
messageThreadExternalId: message.messageThreadExternalId,
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
} else {
|
||||
await messageChannelMessageAssociationRepository.insert(
|
||||
{
|
||||
messageChannelId,
|
||||
messageId: existingMessage.id,
|
||||
messageExternalId: message.externalId,
|
||||
messageThreadExternalId: message.messageThreadExternalId,
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user