Add destroy for core view resolvers (#13745)

Add destroy for core view resolvers

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Raphaël Bosi
2025-08-09 00:44:17 +02:00
committed by GitHub
parent 12709481cf
commit 983c40485b
36 changed files with 624 additions and 0 deletions
@@ -87,4 +87,6 @@ export class ViewFieldController {
return { success: isDefined(deletedViewField) };
}
// TODO: the destroy endpoint will be implemented when we settle on a strategy
}
@@ -89,4 +89,6 @@ export class ViewFilterGroupController {
return { success: isDefined(deletedViewFilterGroup) };
}
// TODO: the destroy endpoint will be implemented when we settle on a strategy
}
@@ -87,4 +87,6 @@ export class ViewFilterController {
return { success: isDefined(deletedViewFilter) };
}
// TODO: the destroy endpoint will be implemented when we settle on a strategy
}
@@ -87,4 +87,6 @@ export class ViewGroupController {
return { success: isDefined(deletedViewGroup) };
}
// TODO: the destroy endpoint will be implemented when we settle on a strategy
}
@@ -84,4 +84,6 @@ export class ViewSortController {
return { success: isDefined(deletedViewSort) };
}
// TODO: the destroy endpoint will be implemented when we settle on a strategy
}
@@ -84,4 +84,6 @@ export class ViewController {
return { success: isDefined(deletedView) };
}
// TODO: the destroy endpoint will be implemented when we settle on a strategy
}
@@ -67,4 +67,17 @@ export class ViewFieldResolver {
return isDefined(deletedViewField);
}
@Mutation(() => Boolean)
async destroyCoreViewField(
@Args('id', { type: () => String }) id: string,
@AuthWorkspace() workspace: Workspace,
): Promise<boolean> {
const deletedViewField = await this.viewFieldService.destroy(
id,
workspace.id,
);
return isDefined(deletedViewField);
}
}
@@ -73,4 +73,17 @@ export class ViewFilterGroupResolver {
return isDefined(deletedViewFilterGroup);
}
@Mutation(() => Boolean)
async destroyCoreViewFilterGroup(
@Args('id', { type: () => String }) id: string,
@AuthWorkspace() workspace: Workspace,
): Promise<boolean> {
const deletedViewFilterGroup = await this.viewFilterGroupService.destroy(
id,
workspace.id,
);
return isDefined(deletedViewFilterGroup);
}
}
@@ -71,4 +71,17 @@ export class ViewFilterResolver {
return isDefined(deletedViewFilter);
}
@Mutation(() => Boolean)
async destroyCoreViewFilter(
@Args('id', { type: () => String }) id: string,
@AuthWorkspace() workspace: Workspace,
): Promise<boolean> {
const deletedViewFilter = await this.viewFilterService.destroy(
id,
workspace.id,
);
return isDefined(deletedViewFilter);
}
}
@@ -71,4 +71,17 @@ export class ViewGroupResolver {
return isDefined(deletedViewGroup);
}
@Mutation(() => Boolean)
async destroyCoreViewGroup(
@Args('id', { type: () => String }) id: string,
@AuthWorkspace() workspace: Workspace,
): Promise<boolean> {
const deletedViewGroup = await this.viewGroupService.destroy(
id,
workspace.id,
);
return isDefined(deletedViewGroup);
}
}
@@ -68,4 +68,17 @@ export class ViewSortResolver {
return isDefined(deletedViewSort);
}
@Mutation(() => Boolean)
async destroyCoreViewSort(
@Args('id', { type: () => String }) id: string,
@AuthWorkspace() workspace: Workspace,
): Promise<boolean> {
const deletedViewSort = await this.viewSortService.destroy(
id,
workspace.id,
);
return isDefined(deletedViewSort);
}
}
@@ -71,4 +71,14 @@ export class ViewResolver {
return isDefined(deletedView);
}
@Mutation(() => Boolean)
async destroyCoreView(
@Args('id', { type: () => String }) id: string,
@AuthWorkspace() workspace: Workspace,
): Promise<boolean> {
const deletedView = await this.viewService.destroy(id, workspace.id);
return isDefined(deletedView);
}
}
@@ -294,4 +294,20 @@ describe('ViewFieldService', () => {
);
});
});
describe('destroy', () => {
it('should destroy a view field successfully', async () => {
const id = 'view-field-id';
const workspaceId = 'workspace-id';
jest.spyOn(viewFieldService, 'findById').mockResolvedValue(mockViewField);
jest.spyOn(viewFieldRepository, 'delete').mockResolvedValue({} as any);
const result = await viewFieldService.destroy(id, workspaceId);
expect(viewFieldService.findById).toHaveBeenCalledWith(id, workspaceId);
expect(viewFieldRepository.delete).toHaveBeenCalledWith(id);
expect(result).toEqual(true);
});
});
});
@@ -41,6 +41,7 @@ describe('ViewFilterGroupService', () => {
create: jest.fn(),
save: jest.fn(),
softDelete: jest.fn(),
delete: jest.fn(),
},
},
],
@@ -329,4 +330,27 @@ describe('ViewFilterGroupService', () => {
);
});
});
describe('destroy', () => {
it('should destroy a view filter group successfully', async () => {
const id = 'view-filter-group-id';
const workspaceId = 'workspace-id';
jest
.spyOn(viewFilterGroupService, 'findById')
.mockResolvedValue(mockViewFilterGroup);
jest
.spyOn(viewFilterGroupRepository, 'delete')
.mockResolvedValue({} as any);
const result = await viewFilterGroupService.destroy(id, workspaceId);
expect(viewFilterGroupService.findById).toHaveBeenCalledWith(
id,
workspaceId,
);
expect(viewFilterGroupRepository.delete).toHaveBeenCalledWith(id);
expect(result).toEqual(true);
});
});
});
@@ -43,6 +43,7 @@ describe('ViewFilterService', () => {
create: jest.fn(),
save: jest.fn(),
softDelete: jest.fn(),
delete: jest.fn(),
},
},
],
@@ -310,4 +311,22 @@ describe('ViewFilterService', () => {
);
});
});
describe('destroy', () => {
it('should destroy a view filter successfully', async () => {
const id = 'view-filter-id';
const workspaceId = 'workspace-id';
jest
.spyOn(viewFilterService, 'findById')
.mockResolvedValue(mockViewFilter);
jest.spyOn(viewFilterRepository, 'delete').mockResolvedValue({} as any);
const result = await viewFilterService.destroy(id, workspaceId);
expect(viewFilterService.findById).toHaveBeenCalledWith(id, workspaceId);
expect(viewFilterRepository.delete).toHaveBeenCalledWith(id);
expect(result).toEqual(true);
});
});
});
@@ -42,6 +42,7 @@ describe('ViewGroupService', () => {
create: jest.fn(),
save: jest.fn(),
softDelete: jest.fn(),
delete: jest.fn(),
},
},
],
@@ -294,4 +295,20 @@ describe('ViewGroupService', () => {
);
});
});
describe('destroy', () => {
it('should destroy a view group successfully', async () => {
const id = 'view-group-id';
const workspaceId = 'workspace-id';
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(mockViewGroup);
jest.spyOn(viewGroupRepository, 'delete').mockResolvedValue({} as any);
const result = await viewGroupService.destroy(id, workspaceId);
expect(viewGroupService.findById).toHaveBeenCalledWith(id, workspaceId);
expect(viewGroupRepository.delete).toHaveBeenCalledWith(id);
expect(result).toEqual(true);
});
});
});
@@ -41,6 +41,7 @@ describe('ViewSortService', () => {
create: jest.fn(),
save: jest.fn(),
softDelete: jest.fn(),
delete: jest.fn(),
},
},
],
@@ -281,4 +282,20 @@ describe('ViewSortService', () => {
);
});
});
describe('destroy', () => {
it('should destroy a view sort successfully', async () => {
const id = 'view-sort-id';
const workspaceId = 'workspace-id';
jest.spyOn(viewSortService, 'findById').mockResolvedValue(mockViewSort);
jest.spyOn(viewSortRepository, 'delete').mockResolvedValue({} as any);
const result = await viewSortService.destroy(id, workspaceId);
expect(viewSortService.findById).toHaveBeenCalledWith(id, workspaceId);
expect(viewSortRepository.delete).toHaveBeenCalledWith(id);
expect(result).toEqual(true);
});
});
});
@@ -50,6 +50,7 @@ describe('ViewService', () => {
create: jest.fn(),
save: jest.fn(),
softDelete: jest.fn(),
delete: jest.fn(),
},
},
],
@@ -295,4 +296,20 @@ describe('ViewService', () => {
);
});
});
describe('destroy', () => {
it('should destroy a view successfully', async () => {
const id = 'view-id';
const workspaceId = 'workspace-id';
jest.spyOn(viewService, 'findById').mockResolvedValue(mockView);
jest.spyOn(viewRepository, 'delete').mockResolvedValue({} as any);
const result = await viewService.destroy(id, workspaceId);
expect(viewService.findById).toHaveBeenCalledWith(id, workspaceId);
expect(viewRepository.delete).toHaveBeenCalledWith(id);
expect(result).toEqual(true);
});
});
});
@@ -149,4 +149,22 @@ export class ViewFieldService {
return viewField;
}
async destroy(id: string, workspaceId: string): Promise<boolean> {
const viewField = await this.findById(id, workspaceId);
if (!isDefined(viewField)) {
throw new ViewFieldException(
generateViewFieldExceptionMessage(
ViewFieldExceptionMessageKey.VIEW_FIELD_NOT_FOUND,
id,
),
ViewFieldExceptionCode.VIEW_FIELD_NOT_FOUND,
);
}
await this.viewFieldRepository.delete(id);
return true;
}
}
@@ -161,4 +161,22 @@ export class ViewFilterGroupService {
return viewFilterGroup;
}
async destroy(id: string, workspaceId: string): Promise<boolean> {
const viewFilterGroup = await this.findById(id, workspaceId);
if (!isDefined(viewFilterGroup)) {
throw new ViewFilterGroupException(
generateViewFilterGroupExceptionMessage(
ViewFilterGroupExceptionMessageKey.VIEW_FILTER_GROUP_NOT_FOUND,
id,
),
ViewFilterGroupExceptionCode.VIEW_FILTER_GROUP_NOT_FOUND,
);
}
await this.viewFilterGroupRepository.delete(id);
return true;
}
}
@@ -149,4 +149,22 @@ export class ViewFilterService {
return viewFilter;
}
async destroy(id: string, workspaceId: string): Promise<boolean> {
const viewFilter = await this.findById(id, workspaceId);
if (!isDefined(viewFilter)) {
throw new ViewFilterException(
generateViewFilterExceptionMessage(
ViewFilterExceptionMessageKey.VIEW_FILTER_NOT_FOUND,
id,
),
ViewFilterExceptionCode.VIEW_FILTER_NOT_FOUND,
);
}
await this.viewFilterRepository.delete(id);
return true;
}
}
@@ -149,4 +149,22 @@ export class ViewGroupService {
return viewGroup;
}
async destroy(id: string, workspaceId: string): Promise<boolean> {
const viewGroup = await this.findById(id, workspaceId);
if (!isDefined(viewGroup)) {
throw new ViewGroupException(
generateViewGroupExceptionMessage(
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
id,
),
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
);
}
await this.viewGroupRepository.delete(id);
return true;
}
}
@@ -144,4 +144,22 @@ export class ViewSortService {
return viewSort;
}
async destroy(id: string, workspaceId: string): Promise<boolean> {
const viewSort = await this.findById(id, workspaceId);
if (!isDefined(viewSort)) {
throw new ViewSortException(
generateViewSortExceptionMessage(
ViewSortExceptionMessageKey.VIEW_SORT_NOT_FOUND,
id,
),
ViewSortExceptionCode.VIEW_SORT_NOT_FOUND,
);
}
await this.viewSortRepository.delete(id);
return true;
}
}
@@ -156,4 +156,22 @@ export class ViewService {
return view;
}
async destroy(id: string, workspaceId: string): Promise<boolean> {
const view = await this.findById(id, workspaceId);
if (!isDefined(view)) {
throw new ViewException(
generateViewExceptionMessage(
ViewExceptionMessageKey.VIEW_NOT_FOUND,
id,
),
ViewExceptionCode.VIEW_NOT_FOUND,
);
}
await this.viewRepository.delete(id);
return true;
}
}