Skip to content

Commit

Permalink
feat: add delete of release candidates
Browse files Browse the repository at this point in the history
  • Loading branch information
thielpa committed Feb 14, 2025
1 parent 6117085 commit 6389e4b
Show file tree
Hide file tree
Showing 17 changed files with 125 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,3 @@
</p-accordion-panel>
}
</p-accordion>

<p-confirmDialog></p-confirmDialog>
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { injectMutation, injectQuery, QueryClient } from '@tanstack/angular-quer
import { IconsModule } from 'icons.module';
import { ConfirmationService } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { InputTextModule } from 'primeng/inputtext';
import { TagModule } from 'primeng/tag';
import { EnvironmentDeploymentInfoComponent } from '../deployment-info/environment-deployment-info.component';
Expand Down Expand Up @@ -49,7 +48,6 @@ import { EnvironmentStatusTagComponent } from '../environment-status-tag/environ
EnvironmentStatusInfoComponent,
LockTimeComponent,
AvatarModule,
ConfirmDialogModule,
CommonModule,
TimeAgoPipe,
UserAvatarComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import type {
GetGroupsWithWorkflowsData,
GetAllRepositoriesData,
GetRepositoryByIdData,
DeleteReleaseCandidateByNameData,
DeleteReleaseCandidateByNameResponse,
GetReleaseCandidateByNameData,
GetCommitsSinceLastReleaseCandidateData,
GetAllPullRequestsData,
Expand Down Expand Up @@ -74,6 +76,7 @@ import {
getGroupsWithWorkflows,
getAllRepositories,
getRepositoryById,
deleteReleaseCandidateByName,
getReleaseCandidateByName,
getCommitsSinceLastReleaseCandidate,
getAllPullRequests,
Expand Down Expand Up @@ -560,6 +563,20 @@ export const getRepositoryByIdOptions = (options: Options<GetRepositoryByIdData>
});
};

export const deleteReleaseCandidateByNameMutation = (options?: Partial<Options<DeleteReleaseCandidateByNameData>>) => {
const mutationOptions: MutationOptions<DeleteReleaseCandidateByNameResponse, DefaultError, Options<DeleteReleaseCandidateByNameData>> = {
mutationFn: async localOptions => {
const { data } = await deleteReleaseCandidateByName({
...options,
...localOptions,
throwOnError: true,
});
return data;
},
};
return mutationOptions;
};

export const getReleaseCandidateByNameQueryKey = (options: Options<GetReleaseCandidateByNameData>) => [createQueryKey('getReleaseCandidateByName', options)];

export const getReleaseCandidateByNameOptions = (options: Options<GetReleaseCandidateByNameData>) => {
Expand Down
9 changes: 9 additions & 0 deletions client/src/app/core/modules/openapi/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import type {
GetAllRepositoriesResponse,
GetRepositoryByIdData,
GetRepositoryByIdResponse,
DeleteReleaseCandidateByNameData,
DeleteReleaseCandidateByNameResponse,
GetReleaseCandidateByNameData,
GetReleaseCandidateByNameResponse,
GetCommitsSinceLastReleaseCandidateData,
Expand Down Expand Up @@ -278,6 +280,13 @@ export const getRepositoryById = <ThrowOnError extends boolean = false>(options:
});
};

export const deleteReleaseCandidateByName = <ThrowOnError extends boolean = false>(options: Options<DeleteReleaseCandidateByNameData, ThrowOnError>) => {
return (options?.client ?? client).delete<DeleteReleaseCandidateByNameResponse, unknown, ThrowOnError>({
...options,
url: '/api/release-candidate/{name}',
});
};

export const getReleaseCandidateByName = <ThrowOnError extends boolean = false>(options: Options<GetReleaseCandidateByNameData, ThrowOnError>) => {
return (options?.client ?? client).get<GetReleaseCandidateByNameResponse, unknown, ThrowOnError>({
...options,
Expand Down
18 changes: 18 additions & 0 deletions client/src/app/core/modules/openapi/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,24 @@ export type GetRepositoryByIdResponses = {

export type GetRepositoryByIdResponse = GetRepositoryByIdResponses[keyof GetRepositoryByIdResponses];

export type DeleteReleaseCandidateByNameData = {
body?: never;
path: {
name: string;
};
query?: never;
url: '/api/release-candidate/{name}';
};

export type DeleteReleaseCandidateByNameResponses = {
/**
* OK
*/
200: ReleaseCandidateInfoDto;
};

export type DeleteReleaseCandidateByNameResponse = DeleteReleaseCandidateByNameResponses[keyof DeleteReleaseCandidateByNameResponses];

export type GetReleaseCandidateByNameData = {
body?: never;
path: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@
</div>
</div>
<p-toast></p-toast>
<p-confirmdialog />
</div>
</main>
2 changes: 2 additions & 0 deletions client/src/app/pages/main-layout/main-layout.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ToastModule } from 'primeng/toast';
import { TooltipModule } from 'primeng/tooltip';
import { HeliosIconComponent } from '../../components/helios-icon/helios-icon.component';
import { UserLockInfoComponent } from '@app/components/user-lock-info/user-lock-info.component';
import { ConfirmDialogModule } from 'primeng/confirmdialog';

@Component({
selector: 'app-main-layout',
Expand All @@ -31,6 +32,7 @@ import { UserLockInfoComponent } from '@app/components/user-lock-info/user-lock-
HeliosIconComponent,
DividerModule,
AvatarModule,
ConfirmDialogModule,
CardModule,
ProfileNavSectionComponent,
UserLockInfoComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,4 @@ <h3 class="text-xl mb-2">Workflows</h3>
</div>
</div>
</p-dialog>

<p-confirmDialog></p-confirmDialog>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { InputTextModule } from 'primeng/inputtext';
import { IconsModule } from 'icons.module';
import { DragDropModule } from 'primeng/dragdrop';
import { ConfirmationService } from 'primeng/api';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { DividerModule } from 'primeng/divider';

import {
Expand All @@ -33,7 +32,6 @@ import { LockingThresholdsComponent } from '@app/components/locking-thresholds/l

@Component({
selector: 'app-project-settings',
standalone: true,
imports: [
FormsModule,
TableModule,
Expand All @@ -47,7 +45,6 @@ import { LockingThresholdsComponent } from '@app/components/locking-thresholds/l
InputTextModule,
IconsModule,
DragDropModule,
ConfirmDialogModule,
DividerModule,
],
templateUrl: './project-settings.component.html',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ <h2 class="text-2xl">
<i-tabler name="git-commit" class="!size-4" />
{{ releaseCandidate.commit.sha | slice: 0 : 7 }}
</p-tag>
@if (permissionService.isAtLeastMaintainer()) {
<p-button text (onClick)="deleteReleaseCandidate(releaseCandidate)">
<i-tabler name="trash" class="!size-5 text-red-500 hover:text-red-700" />
</p-button>
}
</h2>
<div class="flex gap-1 items-center text-sm">
<div>created by</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Component, inject, input } from '@angular/core';
import { evaluateMutation, getReleaseCandidateByNameOptions, getReleaseCandidateByNameQueryKey } from '@app/core/modules/openapi/@tanstack/angular-query-experimental.gen';
import {
deleteReleaseCandidateByNameMutation,
evaluateMutation,
getReleaseCandidateByNameOptions,
getReleaseCandidateByNameQueryKey,
} from '@app/core/modules/openapi/@tanstack/angular-query-experimental.gen';
import { injectMutation, injectQuery, QueryClient } from '@tanstack/angular-query-experimental';
import { ButtonModule } from 'primeng/button';
import { ButtonGroupModule } from 'primeng/buttongroup';
Expand All @@ -11,9 +16,11 @@ import { TimeAgoPipe } from '@app/pipes/time-ago.pipe';
import { TooltipModule } from 'primeng/tooltip';
import { SlicePipe } from '@angular/common';
import { TagModule } from 'primeng/tag';
import { MessageService } from 'primeng/api';
import { ConfirmationService, MessageService } from 'primeng/api';
import { KeycloakService } from '@app/core/services/keycloak/keycloak.service';
import { PermissionService } from '@app/core/services/permission.service';
import { ReleaseCandidateDetailsDto } from '@app/core/modules/openapi';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
selector: 'app-release-candidate-details',
Expand All @@ -24,7 +31,10 @@ export class ReleaseCandidateDetailsComponent {
private messageService = inject(MessageService);
private keycloakService = inject(KeycloakService);
permissionService = inject(PermissionService);
private confirmationService = inject(ConfirmationService);
private queryClient = inject(QueryClient);
private router = inject(Router);
private route = inject(ActivatedRoute);

name = input.required<string>();
releaseCandidateQuery = injectQuery(() => getReleaseCandidateByNameOptions({ path: { name: this.name() } }));
Expand All @@ -37,10 +47,28 @@ export class ReleaseCandidateDetailsComponent {
},
}));

deleteReleaseCandidateMutation = injectMutation(() => ({
...deleteReleaseCandidateByNameMutation(),
onSuccess: () => {
this.messageService.add({ severity: 'success', summary: 'Release Candidate Deletion', detail: 'Release candidate has been deleted successfully' });
this.router.navigate(['..'], { relativeTo: this.route });
},
}));

evaluateReleaseCandidate = (isWorking: boolean) => {
this.evaluateReleaseCandidateMutation.mutate({ path: { name: this.name(), isWorking } });
};

deleteReleaseCandidate = (rc: ReleaseCandidateDetailsDto) => {
this.confirmationService.confirm({
header: 'Delete Release Candidate',
message: `Are you sure you want to delete release candidate ${rc.name}? This cannot be undone.`,
accept: () => {
this.deleteReleaseCandidateMutation.mutate({ path: { name: rc.name } });
},
});
};

hasUserEvaluatedTo(isWorking: boolean) {
const evaluations = this.releaseCandidateQuery.data()?.evaluations;
if (!evaluations) return false;
Expand Down
2 changes: 2 additions & 0 deletions client/src/icons.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import {
IconCircle,
IconClock,
IconTag,
IconTrash,
IconX,
} from 'angular-tabler-icons/icons';

Expand Down Expand Up @@ -111,6 +112,7 @@ const icons = {
IconCircle,
IconClock,
IconTag,
IconTrash,
IconX,
};

Expand Down
17 changes: 17 additions & 0 deletions server/application-server/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,23 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ReleaseCandidateDetailsDto"
delete:
tags:
- release-candidate-controller
operationId: deleteReleaseCandidateByName
parameters:
- name: name
in: path
required: true
schema:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/ReleaseCandidateInfoDto"
/api/release-candidate/newcommits:
get:
tags:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class ReleaseCandidate {

@Id private String name;

@OneToOne(optional = false, cascade = CascadeType.ALL)
@OneToOne(optional = false)
private Commit commit;

@ManyToOne(fetch = FetchType.LAZY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -48,4 +49,10 @@ public ResponseEntity<Void> evaluate(@PathVariable String name, @PathVariable bo
releaseCandidateService.evaluateReleaseCandidate(name, isWorking);
return ResponseEntity.ok().build();
}

@DeleteMapping("/{name}")
public ResponseEntity<ReleaseCandidateInfoDto> deleteReleaseCandidateByName(
@PathVariable String name) {
return ResponseEntity.ok(releaseCandidateService.deleteReleaseCandidateByName(name));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ Optional<ReleaseCandidate> findByRepositoryRepositoryIdAndCommitSha(
Long repositoryId, String commitSha);

boolean existsByRepositoryRepositoryIdAndName(Long repositoryId, String name);

Optional<ReleaseCandidate> deleteByRepositoryRepositoryIdAndName(Long repositoryId, String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,18 @@ public void evaluateReleaseCandidate(String name, boolean isWorking) {
evaluation.setWorking(isWorking);
releaseCandidateEvaluationRepository.save(evaluation);
}

public ReleaseCandidateInfoDto deleteReleaseCandidateByName(String name) {
final Long repositoryId = RepositoryContext.getRepositoryId();

ReleaseCandidateInfoDto rc = releaseCandidateRepository
.findByRepositoryRepositoryIdAndName(repositoryId, name)
.map(ReleaseCandidateInfoDto::fromReleaseCandidate)
.orElseThrow(() -> new ReleaseCandidateException("ReleaseCandidate could not be found."));

releaseCandidateRepository
.deleteByRepositoryRepositoryIdAndName(repositoryId, name);

return rc;
}
}

0 comments on commit 6389e4b

Please sign in to comment.