From a1fa0141abdd33171dfe432a51a601e0d0afd3b6 Mon Sep 17 00:00:00 2001
From: mhg <73169169+Marcel-Haag@users.noreply.github.com>
Date: Sat, 29 Jan 2022 03:09:02 +0100
Subject: [PATCH] feat: added delete project option and generic confirm dialog
---
security-c4po-angular/src/app/app.module.ts | 2 +
.../project-overview.component.html | 4 +-
.../project-overview.component.scss | 8 +++
.../project-overview.component.ts | 29 ++++++++--
.../src/assets/@theme/styles/_dialog.scss | 18 ++++++
.../src/assets/@theme/styles/pace.theme.scss | 6 --
.../src/assets/i18n/de-DE.json | 11 +++-
.../src/assets/i18n/en-US.json | 11 +++-
.../confirm-dialog.component.html | 21 +++++++
.../confirm-dialog.component.scss | 1 +
.../confirm-dialog.component.spec.ts | 56 +++++++++++++++++++
.../confirm-dialog.component.ts | 28 ++++++++++
.../confirm-dialog/confirm-dialog.module.ts | 23 ++++++++
.../project-dialog.component.html | 6 +-
.../project-dialog.component.scss | 2 +
.../services/dialog-service/dialog-message.ts | 6 ++
.../dialog-service/dialog.service.mock.ts | 5 ++
.../services/dialog-service/dialog.service.ts | 17 ++++++
.../shared/services/project.service.mock.ts | 8 ++-
.../shared/services/project.service.spec.ts | 31 +++++++++-
.../src/shared/services/project.service.ts | 11 ++++
21 files changed, 283 insertions(+), 21 deletions(-)
create mode 100644 security-c4po-angular/src/assets/@theme/styles/_dialog.scss
create mode 100644 security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.html
create mode 100644 security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.scss
create mode 100644 security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.spec.ts
create mode 100644 security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.ts
create mode 100644 security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.module.ts
create mode 100644 security-c4po-angular/src/shared/services/dialog-service/dialog-message.ts
diff --git a/security-c4po-angular/src/app/app.module.ts b/security-c4po-angular/src/app/app.module.ts
index 19e02b6..1d4594a 100644
--- a/security-c4po-angular/src/app/app.module.ts
+++ b/security-c4po-angular/src/app/app.module.ts
@@ -27,6 +27,7 @@ import {KeycloakService} from 'keycloak-angular';
import {httpInterceptorProviders} from '@shared/interceptors';
import {FlexLayoutModule} from '@angular/flex-layout';
import {DialogService} from '@shared/services/dialog-service/dialog.service';
+import {ConfirmDialogModule} from '@shared/modules/confirm-dialog/confirm-dialog.module';
@NgModule({
declarations: [
@@ -45,6 +46,7 @@ import {DialogService} from '@shared/services/dialog-service/dialog.service';
NbIconModule,
NbButtonModule,
NbEvaIconsModule,
+ ConfirmDialogModule,
NgxsModule.forRoot([SessionState], {developmentMode: !environment.production}),
HttpClientModule,
TranslateModule.forRoot({
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.component.html b/security-c4po-angular/src/app/project-overview/project-overview.component.html
index 41cb515..2582c21 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.component.html
+++ b/security-c4po-angular/src/app/project-overview/project-overview.component.html
@@ -1,6 +1,6 @@
-
+
+ (click)="onClickDeleteProject(project)">
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.component.scss b/security-c4po-angular/src/app/project-overview/project-overview.component.scss
index c411834..20f6bb7 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.component.scss
+++ b/security-c4po-angular/src/app/project-overview/project-overview.component.scss
@@ -1,3 +1,5 @@
+@import '../../assets/@theme/styles/themes';
+
.project-card {
max-width: 22rem;
width: 22rem;
@@ -33,6 +35,12 @@
}
}
+.project-card:hover {
+ background-color: nb-theme(color-info-transparent-default);
+ margin-top: +0.625rem;
+ transform: scale(1.025)
+}
+
.project-link:hover {
cursor: pointer !important;
}
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.component.ts b/security-c4po-angular/src/app/project-overview/project-overview.component.ts
index 75704e7..200a6ae 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.component.ts
+++ b/security-c4po-angular/src/app/project-overview/project-overview.component.ts
@@ -5,10 +5,9 @@ import {BehaviorSubject, Observable} from 'rxjs';
import {untilDestroyed} from 'ngx-take-until-destroy';
import {ProjectService} from '@shared/services/project.service';
import {NotificationService, PopupType} from '@shared/services/notification.service';
-import {filter, mergeMap, tap} from 'rxjs/operators';
+import {catchError, filter, mergeMap, switchMap, tap} from 'rxjs/operators';
import {DialogService} from '@shared/services/dialog-service/dialog.service';
import {ProjectDialogComponent} from '@shared/modules/project-dialog/project-dialog.component';
-import {NB_DIALOG_CONFIG} from '@nebular/theme/components/dialog/dialog-config';
@Component({
selector: 'app-project-overview',
@@ -80,8 +79,30 @@ export class ProjectOverviewComponent implements OnInit, OnDestroy {
console.log('to be implemented...');
}
- onClickDeleteProject(): void {
- console.log('to be implemented...');
+ onClickDeleteProject(project: Project): void {
+ const message = {
+ title: 'project.delete.title',
+ key: 'project.delete.key',
+ data: {name: project.title},
+ };
+ this.dialogService.openConfirmDialog(
+ message
+ ).onClose.pipe(
+ filter((confirm) => !!confirm),
+ switchMap(() => this.projectService.deleteProjectById(project.id)),
+ catchError(() => {
+ this.notificationService.showPopup('project.popup.delete.failed', PopupType.FAILURE);
+ return [];
+ }),
+ untilDestroyed(this)
+ ).subscribe({
+ next: () => {
+ this.loadProjects();
+ this.notificationService.showPopup('project.popup.delete.success', PopupType.SUCCESS);
+ }, error: error => {
+ console.error(error);
+ }
+ });
}
isLoading(): Observable
{
diff --git a/security-c4po-angular/src/assets/@theme/styles/_dialog.scss b/security-c4po-angular/src/assets/@theme/styles/_dialog.scss
new file mode 100644
index 0000000..0e35a53
--- /dev/null
+++ b/security-c4po-angular/src/assets/@theme/styles/_dialog.scss
@@ -0,0 +1,18 @@
+.dialog-header {
+ height: 6.75vh;
+ font-size: 1.5rem;
+
+ .dialog-headline {
+ margin-top: 2rem;
+ }
+}
+
+.dialog-body {
+ font-size: 1.15rem;
+}
+
+.dialog-button {
+ width: 4.5rem;
+ height: 2.5rem;
+ font-size: 1.5rem;
+}
diff --git a/security-c4po-angular/src/assets/@theme/styles/pace.theme.scss b/security-c4po-angular/src/assets/@theme/styles/pace.theme.scss
index c14f331..8343514 100644
--- a/security-c4po-angular/src/assets/@theme/styles/pace.theme.scss
+++ b/security-c4po-angular/src/assets/@theme/styles/pace.theme.scss
@@ -1,9 +1,3 @@
-/**
- * @license
- * Copyright Akveo. All Rights Reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- */
-
@mixin ngx-pace-theme() {
.pace .pace-progress {
diff --git a/security-c4po-angular/src/assets/i18n/de-DE.json b/security-c4po-angular/src/assets/i18n/de-DE.json
index 1fbf84b..c81a822 100644
--- a/security-c4po-angular/src/assets/i18n/de-DE.json
+++ b/security-c4po-angular/src/assets/i18n/de-DE.json
@@ -3,7 +3,10 @@
"action.login": "Einloggen",
"action.retry": "Erneut Versuchen",
"action.save": "Speichern",
+ "action.confirm": "Bestätigen",
"action.cancel": "Abbrechen",
+ "action.yes": "Ja",
+ "action.no": "Nein",
"username": "Nutzername",
"password": "Passwort"
},
@@ -33,10 +36,16 @@
"create": {
"header": "Neues Projekt erstellen"
},
+ "delete": {
+ "title": "Projekt löschen",
+ "key": "Möchten Sie das Projekt \"{{name}}\" unwiderruflich löschen?"
+ },
"popup": {
"not.found": "Keine Projekte gefunden",
"save.success": "Projekt erfolgreich gespeichert",
- "save.failed": "Projekt konnte nicht gespeichert werden"
+ "save.failed": "Projekt konnte nicht gespeichert werden",
+ "delete.success": "Projekt erfolgreich gelöscht",
+ "delete.failed": "Projekt konnte nicht gelöscht werden"
},
"title.label": "Projekt Titel",
"client.label": "Name des Auftraggebers",
diff --git a/security-c4po-angular/src/assets/i18n/en-US.json b/security-c4po-angular/src/assets/i18n/en-US.json
index b7c1f4e..a1cb888 100644
--- a/security-c4po-angular/src/assets/i18n/en-US.json
+++ b/security-c4po-angular/src/assets/i18n/en-US.json
@@ -2,8 +2,11 @@
"global": {
"action.login": "Login",
"action.retry": "Try again",
+ "action.confirm": "Confirm",
"action.save": "Save",
"action.cancel": "Cancel",
+ "action.yes": "Yes",
+ "action.no": "No",
"username": "Username",
"password": "Password"
},
@@ -33,10 +36,16 @@
"create": {
"header": "Create New Project"
},
+ "delete": {
+ "title": "Delete Project",
+ "key": "Do you want to permanently delete the project \"{{name}}\"?"
+ },
"popup": {
"not.found": "No projects found",
"save.success": "Project saved successfully",
- "save.failed": "Project could not be saved"
+ "save.failed": "Project could not be saved",
+ "delete.success": "Project deleted successfully",
+ "delete.failed": "Project could not be deleted"
},
"title.label": "Project Title",
"client.label": "Name of Client",
diff --git a/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.html b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.html
new file mode 100644
index 0000000..72597bc
--- /dev/null
+++ b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.html
@@ -0,0 +1,21 @@
+
+
+
+ {{ data?.key | translate: data?.data }}
+
+
+
+
+
+
diff --git a/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.scss b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.scss
new file mode 100644
index 0000000..0878515
--- /dev/null
+++ b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.scss
@@ -0,0 +1 @@
+@import "../../../assets/@theme/styles/_dialog.scss";
diff --git a/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.spec.ts b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.spec.ts
new file mode 100644
index 0000000..747788c
--- /dev/null
+++ b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.spec.ts
@@ -0,0 +1,56 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ConfirmDialogComponent } from './confirm-dialog.component';
+import {DialogService} from '@shared/services/dialog-service/dialog.service';
+import {DialogServiceMock} from '@shared/services/dialog-service/dialog.service.mock';
+import {NbButtonModule, NbCardModule, NbDialogRef, NbLayoutModule} from '@nebular/theme';
+import {CommonModule} from '@angular/common';
+import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
+import {HttpLoaderFactory} from '../../../app/common-app.module';
+import {HttpClient, HttpClientModule} from '@angular/common/http';
+import {HttpClientTestingModule} from '@angular/common/http/testing';
+import {FlexLayoutModule} from '@angular/flex-layout';
+
+describe('ConfirmDialogComponent', () => {
+ let component: ConfirmDialogComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [
+ ConfirmDialogComponent
+ ],
+ imports: [
+ CommonModule,
+ NbLayoutModule,
+ NbCardModule,
+ NbButtonModule,
+ FlexLayoutModule,
+ TranslateModule.forRoot({
+ loader: {
+ provide: TranslateLoader,
+ useFactory: HttpLoaderFactory,
+ deps: [HttpClient]
+ }
+ }),
+ HttpClientModule,
+ HttpClientTestingModule
+ ],
+ providers: [
+ {provide: DialogService, useClass: DialogServiceMock},
+ {provide: NbDialogRef, useValue: {}}
+ ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfirmDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.ts b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.ts
new file mode 100644
index 0000000..a5de5b6
--- /dev/null
+++ b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.component.ts
@@ -0,0 +1,28 @@
+import {Component, Input} from '@angular/core';
+import {NbDialogRef} from '@nebular/theme';
+
+@Component({
+ selector: 'app-confirm-dialog',
+ templateUrl: './confirm-dialog.component.html',
+ styleUrls: ['./confirm-dialog.component.scss']
+})
+export class ConfirmDialogComponent {
+ /**
+ * @param data contains all relevant information the dialog needs
+ * @param data.title The translation key for the dialog title
+ * @param data.key The translation key for the shown message
+ * @param data.data The data that may be used in the message translation key
+ */
+ @Input() data: any;
+
+ constructor(protected dialogRef: NbDialogRef) {
+ }
+
+ onClickConfirm(): void {
+ this.dialogRef.close({confirm: true});
+ }
+
+ onClickClose(): void {
+ this.dialogRef.close();
+ }
+}
diff --git a/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.module.ts b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.module.ts
new file mode 100644
index 0000000..cddddb6
--- /dev/null
+++ b/security-c4po-angular/src/shared/modules/confirm-dialog/confirm-dialog.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import {ConfirmDialogComponent} from '@shared/modules/confirm-dialog/confirm-dialog.component';
+import {NbButtonModule, NbCardModule} from '@nebular/theme';
+import {FlexLayoutModule} from '@angular/flex-layout';
+import {TranslateModule} from '@ngx-translate/core';
+
+@NgModule({
+ declarations: [
+ ConfirmDialogComponent
+ ],
+ imports: [
+ CommonModule,
+ NbCardModule,
+ NbButtonModule,
+ FlexLayoutModule,
+ TranslateModule
+ ],
+ entryComponents: [
+ ConfirmDialogComponent
+ ]
+})
+export class ConfirmDialogModule { }
diff --git a/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html b/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html
index a4f6b5a..0b84d7b 100644
--- a/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html
+++ b/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html
@@ -1,5 +1,5 @@
-