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:
@@ -17,6 +17,7 @@ import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/inte
|
||||
|
||||
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
|
||||
@@ -101,6 +102,17 @@ export class ViewEntity extends SyncableEntity implements Required<ViewEntity> {
|
||||
@Column({ nullable: true, type: 'uuid' })
|
||||
kanbanAggregateOperationFieldMetadataId: string | null;
|
||||
|
||||
@ManyToOne(
|
||||
() => FieldMetadataEntity,
|
||||
(FieldMetadataEntity) => FieldMetadataEntity.kanbanAggregateOperationViews,
|
||||
{
|
||||
onDelete: 'CASCADE',
|
||||
nullable: true,
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: 'kanbanAggregateOperationFieldMetadataId' })
|
||||
kanbanAggregateOperationFieldMetadata: Relation<FieldMetadataEntity>;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: Object.values(ViewCalendarLayout),
|
||||
@@ -112,6 +124,17 @@ export class ViewEntity extends SyncableEntity implements Required<ViewEntity> {
|
||||
@Column({ nullable: true, type: 'uuid' })
|
||||
calendarFieldMetadataId: string | null;
|
||||
|
||||
@ManyToOne(
|
||||
() => FieldMetadataEntity,
|
||||
(fieldMetadata) => fieldMetadata.calendarViews,
|
||||
{
|
||||
onDelete: 'CASCADE',
|
||||
nullable: true,
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: 'calendarFieldMetadataId' })
|
||||
calendarFieldMetadata: Relation<FieldMetadataEntity>;
|
||||
|
||||
@Column({ nullable: false, type: 'uuid' })
|
||||
workspaceId: string;
|
||||
|
||||
|
||||
+39
-13
@@ -31,13 +31,20 @@ export class ViewV2Service {
|
||||
createViewInput: CreateViewInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewDTO> {
|
||||
const { flatObjectMetadataMaps, flatViewMaps: existingFlatViewMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatObjectMetadataMaps', 'flatViewMaps'],
|
||||
},
|
||||
);
|
||||
const {
|
||||
flatObjectMetadataMaps,
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: [
|
||||
'flatObjectMetadataMaps',
|
||||
'flatViewMaps',
|
||||
'flatFieldMetadataMaps',
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
const flatViewFromCreateInput = fromCreateViewInputToFlatViewToCreate({
|
||||
createViewInput,
|
||||
@@ -57,6 +64,7 @@ export class ViewV2Service {
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatObjectMetadataMaps: flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
@@ -93,11 +101,14 @@ export class ViewV2Service {
|
||||
updateViewInput: UpdateViewInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewDTO> {
|
||||
const { flatViewMaps: existingFlatViewMaps } =
|
||||
const {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewMaps'],
|
||||
flatMapsKeys: ['flatViewMaps', 'flatFieldMetadataMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -118,6 +129,9 @@ export class ViewV2Service {
|
||||
flatEntityToUpdate: [flatViewFromUpdateInput],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
@@ -153,11 +167,14 @@ export class ViewV2Service {
|
||||
deleteViewInput: DeleteViewInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewDTO> {
|
||||
const { flatViewMaps: existingFlatViewMaps } =
|
||||
const {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewMaps'],
|
||||
flatMapsKeys: ['flatViewMaps', 'flatFieldMetadataMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -178,6 +195,9 @@ export class ViewV2Service {
|
||||
flatEntityToUpdate: [optimisticallyUpdatedFlatViewWithDeletedAt],
|
||||
}),
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
},
|
||||
buildOptions: {
|
||||
isSystemBuild: false,
|
||||
},
|
||||
@@ -213,11 +233,14 @@ export class ViewV2Service {
|
||||
destroyViewInput: DestroyViewInput;
|
||||
workspaceId: string;
|
||||
}): Promise<ViewDTO> {
|
||||
const { flatViewMaps: existingFlatViewMaps } =
|
||||
const {
|
||||
flatViewMaps: existingFlatViewMaps,
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
} =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatViewMaps'],
|
||||
flatMapsKeys: ['flatViewMaps', 'flatFieldMetadataMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -243,6 +266,9 @@ export class ViewV2Service {
|
||||
view: true,
|
||||
},
|
||||
},
|
||||
dependencyAllFlatEntityMaps: {
|
||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||
},
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user