Field deactivation side effect views calendar kanban viewFields (#15180)
# Introduction
Handling both:
- field deactivation side effect on view fields, view filters and views
- field deactivation side effect on view that targets it as
`kanbanAggregateFieldMetadataId`
- field deactivation side effect on view that targets it as
`calendarFieldMetadataId`
## Coverage
added coverage
```ts
PASS test/integration/metadata/suites/field-metadata/kanban-aggregate-field-deactivation-deletes-views.integration-spec.ts (13.132 s)
kanban-aggregate-field-deactivation-nullifies-kanban-properties
✓ should nullify kanban properties when field used as kanbanAggregateOperationFieldMetadataId is deactivated (3923 ms)
✓ should not modify views when field not used as kanbanAggregateOperationFieldMetadataId is deactivated (2958 ms)
✓ should nullify kanban properties on multiple views when they all use the same field as kanbanAggregateOperationFieldMetadataId (2542 ms)
✓ should nullify kanban properties when views have different aggregate operations on same field (3380 ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 13.154 s
```
```ts
PASS test/integration/metadata/suites/field-metadata/view-group-field-deactivation-deletes-views.integration-spec.ts (12.639 s)
view-group-field-deactivation-deletes-views
✓ should delete view when field used in view group is deactivated (3469 ms)
✓ should not delete view when field not used in view group is deactivated (3109 ms)
✓ should delete multiple views when they all use the same field in view groups (2741 ms)
✓ should handle deactivation when view has multiple view groups with different fields (3008 ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 12.664 s
```
```ts
PASS test/integration/metadata/suites/field-metadata/calendar-field-deactivation-deletes-views.integration-spec.ts (14.579 s)
calendar-field-deactivation-deletes-views
✓ should delete view when field used as calendarFieldMetadataId is deactivated (3388 ms)
✓ should not delete view when field not used as calendarFieldMetadataId is deactivated (2438 ms)
✓ should delete multiple views when they all use the same field as calendarFieldMetadataId (2635 ms)
✓ should handle deactivation when views have different calendar layouts on same field (3195 ms)
✓ should delete calendar view but not other view types when calendar field is deactivated (2682 ms)
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 14.601 s, estimated 15 s
```
## View soft deletion
We decided to remove the soft deletion grain on all the views, in this
PR context we've only removed soft deleted validation requirement on any
view entities
## Conclusion
close https://github.com/twentyhq/core-team-issues/issues/1754
This commit is contained in:
+2
@@ -221,6 +221,8 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatObjectMetadataMaps:
|
||||
optimisticAllFlatEntityMaps.flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps:
|
||||
optimisticAllFlatEntityMaps.flatFieldMetadataMaps,
|
||||
},
|
||||
from: fromFlatViewMaps,
|
||||
to: toFlatViewMaps,
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { type AllMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-metadata-name.type';
|
||||
import { type FlatEntityPropertiesToCompare } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-to-compare.type';
|
||||
import { type FlatEntityPropertiesUpdates } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-properties-updates.type';
|
||||
import { type FlatEntityPropertyUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-property-update.type';
|
||||
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/is-property-update.util';
|
||||
|
||||
export const findFlatEntityPropertyUpdate = <
|
||||
T extends AllMetadataName,
|
||||
P extends Extract<
|
||||
FlatEntityPropertiesToCompare<T>,
|
||||
keyof MetadataFlatEntity<T>
|
||||
>,
|
||||
>({
|
||||
property,
|
||||
flatEntityUpdates,
|
||||
}: {
|
||||
flatEntityUpdates: FlatEntityPropertiesUpdates<T>;
|
||||
property: P;
|
||||
}) =>
|
||||
flatEntityUpdates.find((update): update is FlatEntityPropertyUpdate<T, P> =>
|
||||
isPropertyUpdate(update, property),
|
||||
);
|
||||
+97
@@ -57,6 +57,53 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
|
||||
dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
const kanbanFieldMetadata = isDefined(
|
||||
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
|
||||
)
|
||||
? findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId:
|
||||
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
|
||||
flatEntityMaps:
|
||||
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
|
||||
})
|
||||
: undefined;
|
||||
const updatedFlatFieldMetadataMapsWithKanban = isDefined(
|
||||
kanbanFieldMetadata,
|
||||
)
|
||||
? replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: {
|
||||
...kanbanFieldMetadata,
|
||||
kanbanAggregateOperationViewIds: [
|
||||
...kanbanFieldMetadata.kanbanAggregateOperationViewIds,
|
||||
flatViewToValidate.id,
|
||||
],
|
||||
},
|
||||
flatEntityMaps:
|
||||
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
|
||||
})
|
||||
: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
|
||||
|
||||
const calendarFieldMetadata = isDefined(
|
||||
flatViewToValidate.calendarFieldMetadataId,
|
||||
)
|
||||
? findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: flatViewToValidate.calendarFieldMetadataId,
|
||||
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
|
||||
})
|
||||
: undefined;
|
||||
const updatedFlatFieldMetadataMaps = isDefined(calendarFieldMetadata)
|
||||
? replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: {
|
||||
...calendarFieldMetadata,
|
||||
calendarViewIds: [
|
||||
...calendarFieldMetadata.calendarViewIds,
|
||||
flatViewToValidate.id,
|
||||
],
|
||||
},
|
||||
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
|
||||
})
|
||||
: updatedFlatFieldMetadataMapsWithKanban;
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
@@ -64,6 +111,7 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
|
||||
view: flatViewToValidate,
|
||||
},
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
|
||||
},
|
||||
};
|
||||
@@ -107,6 +155,54 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
|
||||
})
|
||||
: dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps;
|
||||
|
||||
const kanbanFieldMetadata = isDefined(
|
||||
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
|
||||
)
|
||||
? findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId:
|
||||
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
|
||||
flatEntityMaps:
|
||||
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const updatedFlatFieldMetadataMapsWithKanban = isDefined(
|
||||
kanbanFieldMetadata,
|
||||
)
|
||||
? replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: {
|
||||
...kanbanFieldMetadata,
|
||||
kanbanAggregateOperationViewIds:
|
||||
kanbanFieldMetadata.kanbanAggregateOperationViewIds.filter(
|
||||
(id) => id !== flatViewToValidate.id,
|
||||
),
|
||||
},
|
||||
flatEntityMaps:
|
||||
dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
|
||||
})
|
||||
: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps;
|
||||
|
||||
const calendarFieldMetadata = isDefined(
|
||||
flatViewToValidate.calendarFieldMetadataId,
|
||||
)
|
||||
? findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: flatViewToValidate.calendarFieldMetadataId,
|
||||
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const updatedFlatFieldMetadataMaps = isDefined(calendarFieldMetadata)
|
||||
? replaceFlatEntityInFlatEntityMapsOrThrow({
|
||||
flatEntity: {
|
||||
...calendarFieldMetadata,
|
||||
calendarViewIds: calendarFieldMetadata.calendarViewIds.filter(
|
||||
(id) => id !== flatViewToValidate.id,
|
||||
),
|
||||
},
|
||||
flatEntityMaps: updatedFlatFieldMetadataMapsWithKanban,
|
||||
})
|
||||
: updatedFlatFieldMetadataMapsWithKanban;
|
||||
|
||||
return {
|
||||
status: 'success',
|
||||
action: {
|
||||
@@ -114,6 +210,7 @@ export class WorkspaceMigrationV2ViewActionsBuilderService extends WorkspaceEnti
|
||||
viewId: flatViewToValidate.id,
|
||||
},
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: updatedFlatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps: updatedFlatObjectMetadataMaps,
|
||||
},
|
||||
};
|
||||
|
||||
+17
@@ -15,6 +15,7 @@ import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/
|
||||
import { validateFlatFieldMetadataNameAvailability } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name-availability.util';
|
||||
import { validateFlatFieldMetadataName } from 'src/engine/metadata-modules/flat-field-metadata/validators/utils/validate-flat-field-metadata-name.util';
|
||||
import { isStandardMetadata } from 'src/engine/metadata-modules/utils/is-standard-metadata.util';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/find-flat-entity-property-update.util';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
|
||||
@@ -89,6 +90,22 @@ export class FlatFieldMetadataValidatorService {
|
||||
message: 'Label identifier field metadata id does not exist',
|
||||
userFriendlyMessage: msg`Object related to updated field does not have a label identifier`,
|
||||
});
|
||||
} else if (
|
||||
flatObjectMetadata.labelIdentifierFieldMetadataId ===
|
||||
flatFieldMetadataToValidate.id &&
|
||||
isDefined(
|
||||
findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates: updates,
|
||||
property: 'isActive',
|
||||
}),
|
||||
) &&
|
||||
flatFieldMetadataToValidate.isActive === false
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: FieldMetadataExceptionCode.LABEL_IDENTIFIER_FIELD_METADATA_ID_NOT_FOUND,
|
||||
message: 'Label identifier field metadata cannot be deactivated',
|
||||
userFriendlyMessage: msg`Label identifier field cannot be deactivated`,
|
||||
});
|
||||
}
|
||||
|
||||
if (isMorphOrRelationFlatFieldMetadata(flatFieldMetadataToValidate)) {
|
||||
|
||||
+35
-8
@@ -118,6 +118,10 @@ export class FlatViewFieldValidatorService {
|
||||
public validateFlatViewFieldDeletion({
|
||||
flatEntityToValidate: { id: viewFieldIdToDelete },
|
||||
optimisticFlatEntityMaps: optimisticFlatViewFieldMaps,
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps,
|
||||
},
|
||||
}: FlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.viewField
|
||||
>): FailedFlatEntityValidation<FlatViewField> {
|
||||
@@ -138,14 +142,37 @@ export class FlatViewFieldValidatorService {
|
||||
message: t`View field to delete not found`,
|
||||
userFriendlyMessage: msg`View field to delete not found`,
|
||||
});
|
||||
} else {
|
||||
if (!isDefined(existingFlatViewField.deletedAt)) {
|
||||
validationResult.errors.push({
|
||||
code: ViewExceptionCode.INVALID_VIEW_DATA,
|
||||
message: t`View field to delete has not been soft deleted`,
|
||||
userFriendlyMessage: msg`View field to delete has not been soft deleted`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: existingFlatViewField.fieldMetadataId,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatFieldMetadata)) {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: flatFieldMetadata.objectMetadataId,
|
||||
flatEntityMaps: flatObjectMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatObjectMetadata)) {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
if (
|
||||
flatObjectMetadata.labelIdentifierFieldMetadataId ===
|
||||
existingFlatViewField.fieldMetadataId
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: ViewExceptionCode.INVALID_VIEW_DATA,
|
||||
message: t`Label identifier view field cannot be deleted`,
|
||||
userFriendlyMessage: msg`Label identifier view field cannot be deleted`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
|
||||
-25
@@ -5,7 +5,6 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
|
||||
import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filter/types/flat-view-filter.type';
|
||||
import { ViewFilterExceptionCode } from 'src/engine/metadata-modules/view-filter/exceptions/view-filter.exception';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
@@ -77,7 +76,6 @@ export class FlatViewFilterValidatorService {
|
||||
validateFlatViewFilterDeletion({
|
||||
flatEntityToValidate: flatViewFilterToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatViewFilterMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
}: FlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.viewFilter
|
||||
>): FailedFlatEntityValidation<FlatViewFilter> {
|
||||
@@ -104,29 +102,6 @@ export class FlatViewFilterValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const flatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: existingViewFilter.fieldMetadataId,
|
||||
flatEntityMaps: dependencyOptimisticFlatEntityMaps.flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(flatFieldMetadata)) {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const shouldValidateDeletion = isEnumFlatFieldMetadata(flatFieldMetadata)
|
||||
? flatFieldMetadata.options.some(
|
||||
(option) => option.value === existingViewFilter.value,
|
||||
)
|
||||
: true;
|
||||
|
||||
if (shouldValidateDeletion && !isDefined(existingViewFilter.deletedAt)) {
|
||||
validationResult.errors.push({
|
||||
code: ViewFilterExceptionCode.INVALID_VIEW_FILTER_DATA,
|
||||
message: t`View filter has to be soft deleted first`,
|
||||
userFriendlyMessage: msg`View filter has to be soft deleted first`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
|
||||
-22
@@ -5,7 +5,6 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { isEnumFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-enum-flat-field-metadata.util';
|
||||
import { FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type';
|
||||
import { ViewExceptionCode } from 'src/engine/metadata-modules/view/exceptions/view.exception';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
@@ -89,7 +88,6 @@ export class FlatViewGroupValidatorService {
|
||||
public validateFlatViewGroupDeletion({
|
||||
flatEntityToValidate: { id: viewGroupIdToDelete },
|
||||
optimisticFlatEntityMaps: optimisticFlatViewGroupMaps,
|
||||
dependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps },
|
||||
}: FlatEntityValidationArgs<
|
||||
typeof ALL_METADATA_NAME.viewGroup
|
||||
>): FailedFlatEntityValidation<FlatViewGroup> {
|
||||
@@ -114,26 +112,6 @@ export class FlatViewGroupValidatorService {
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
const relatedFlatFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: existingFlatViewGroup.fieldMetadataId,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
});
|
||||
|
||||
if (
|
||||
isDefined(relatedFlatFieldMetadata) &&
|
||||
isEnumFlatFieldMetadata(relatedFlatFieldMetadata) &&
|
||||
relatedFlatFieldMetadata.options.some(
|
||||
(option) => option.value === existingFlatViewGroup.fieldValue,
|
||||
) &&
|
||||
!isDefined(existingFlatViewGroup.deletedAt)
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: ViewExceptionCode.INVALID_VIEW_DATA,
|
||||
message: t`View group to delete has not been soft deleted`,
|
||||
userFriendlyMessage: msg`View group to delete has not been soft deleted`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
|
||||
+54
-20
@@ -1,22 +1,23 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { msg, t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
|
||||
import { FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
|
||||
import { type ALL_METADATA_NAME } from 'src/engine/metadata-modules/flat-entity/constant/all-metadata-name.constant';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
|
||||
import { ViewExceptionCode } from 'src/engine/metadata-modules/view/exceptions/view.exception';
|
||||
import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
|
||||
import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/find-flat-entity-property-update.util';
|
||||
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
import { type FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-update-validation-args.type';
|
||||
import { type FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/flat-entity-validation-args.type';
|
||||
|
||||
@Injectable()
|
||||
export class FlatViewValidatorService {
|
||||
constructor() {}
|
||||
|
||||
public validateFlatViewUpdate({
|
||||
flatEntityId,
|
||||
flatEntityUpdates,
|
||||
optimisticFlatEntityMaps: optimisticFlatViewMaps,
|
||||
dependencyOptimisticFlatEntityMaps: { flatFieldMetadataMaps },
|
||||
}: FlatEntityUpdateValidationArgs<
|
||||
typeof ALL_METADATA_NAME.view
|
||||
>): FailedFlatEntityValidation<FlatView> {
|
||||
@@ -38,6 +39,29 @@ export class FlatViewValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
const kanbanAggregateOperationFieldMetadataIdUpdate =
|
||||
findFlatEntityPropertyUpdate({
|
||||
property: 'kanbanAggregateOperationFieldMetadataId',
|
||||
flatEntityUpdates,
|
||||
});
|
||||
|
||||
if (
|
||||
isDefined(kanbanAggregateOperationFieldMetadataIdUpdate) &&
|
||||
kanbanAggregateOperationFieldMetadataIdUpdate.to !== null &&
|
||||
!isDefined(
|
||||
findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: kanbanAggregateOperationFieldMetadataIdUpdate.to,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
}),
|
||||
)
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: ViewExceptionCode.INVALID_VIEW_DATA,
|
||||
message: t`View kanban aggregate field metadata not found`,
|
||||
userFriendlyMessage: msg`View kanban aggregate field metadata not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
@@ -63,14 +87,6 @@ export class FlatViewValidatorService {
|
||||
message: t`View not found`,
|
||||
userFriendlyMessage: msg`View not found`,
|
||||
});
|
||||
} else {
|
||||
if (!isDefined(existingFlatView.deletedAt)) {
|
||||
validationResult.errors.push({
|
||||
code: ViewExceptionCode.INVALID_VIEW_DATA,
|
||||
message: t`View to delete has not been soft deleted`,
|
||||
userFriendlyMessage: msg`View to delete has not been soft deleted`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
@@ -79,7 +95,10 @@ export class FlatViewValidatorService {
|
||||
public async validateFlatViewCreation({
|
||||
flatEntityToValidate: flatViewToValidate,
|
||||
optimisticFlatEntityMaps: optimisticFlatViewMaps,
|
||||
dependencyOptimisticFlatEntityMaps,
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
flatFieldMetadataMaps,
|
||||
flatObjectMetadataMaps,
|
||||
},
|
||||
}: FlatEntityValidationArgs<typeof ALL_METADATA_NAME.view>): Promise<
|
||||
FailedFlatEntityValidation<FlatView>
|
||||
> {
|
||||
@@ -92,9 +111,7 @@ export class FlatViewValidatorService {
|
||||
};
|
||||
|
||||
const optimisticFlatObjectMetadata =
|
||||
dependencyOptimisticFlatEntityMaps.flatObjectMetadataMaps.byId[
|
||||
flatViewToValidate.objectMetadataId
|
||||
];
|
||||
flatObjectMetadataMaps.byId[flatViewToValidate.objectMetadataId];
|
||||
|
||||
if (!isDefined(optimisticFlatObjectMetadata)) {
|
||||
validationResult.errors.push({
|
||||
@@ -112,6 +129,23 @@ export class FlatViewValidatorService {
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
isDefined(flatViewToValidate.kanbanAggregateOperationFieldMetadataId) &&
|
||||
!isDefined(
|
||||
findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId:
|
||||
flatViewToValidate.kanbanAggregateOperationFieldMetadataId,
|
||||
flatEntityMaps: flatFieldMetadataMaps,
|
||||
}),
|
||||
)
|
||||
) {
|
||||
validationResult.errors.push({
|
||||
code: ViewExceptionCode.INVALID_VIEW_DATA,
|
||||
message: t`View kanban aggregate field metadata not found`,
|
||||
userFriendlyMessage: msg`View kanban aggregate field metadata not found`,
|
||||
});
|
||||
}
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,8 +26,8 @@ import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-meta
|
||||
import { fieldMetadataTypeToColumnType } from 'src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util';
|
||||
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
|
||||
import { isMorphOrRelationFieldMetadataType } from 'src/engine/utils/is-morph-or-relation-field-metadata-type.util';
|
||||
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/is-property-update.type';
|
||||
import { PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/property-update.type';
|
||||
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/is-property-update.util';
|
||||
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
|
||||
import { serializeDefaultValueV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/serialize-default-value-v2.util';
|
||||
import {
|
||||
|
||||
+5
-4
@@ -17,7 +17,7 @@ import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-meta
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { WorkspaceSchemaManagerService } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.service';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { isPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/is-property-update.type';
|
||||
import { findFlatEntityPropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/utils/find-flat-entity-property-update.util';
|
||||
import { type UpdateObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/types/workspace-migration-object-action-v2';
|
||||
import { type WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type';
|
||||
import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/from-flat-entity-properties-updates-to-partial-flat-entity';
|
||||
@@ -105,9 +105,10 @@ export class UpdateObjectActionHandlerService extends WorkspaceMigrationRunnerAc
|
||||
flatObjectMetadata: flatObjectMetadata,
|
||||
});
|
||||
|
||||
const nameSingularUpdate = updates.find((update) =>
|
||||
isPropertyUpdate(update, 'nameSingular'),
|
||||
);
|
||||
const nameSingularUpdate = findFlatEntityPropertyUpdate({
|
||||
flatEntityUpdates: updates,
|
||||
property: 'nameSingular',
|
||||
});
|
||||
|
||||
if (isDefined(nameSingularUpdate)) {
|
||||
const updatedObjectMetadata: FlatObjectMetadata = {
|
||||
|
||||
Reference in New Issue
Block a user