Add confirmation dialog to delete publications.

This commit is contained in:
Florian THIERRY
2024-09-18 09:05:18 +02:00
parent 500952d4d4
commit f5e1e10ebd
7 changed files with 132 additions and 35 deletions

View File

@@ -0,0 +1,10 @@
<h1>{{title}}</h1>
<h2>{{description}}</h2>
<footer>
<button type="button" class="secondary" (click)="closeDialog()">
No
</button>
<button type="button" (click)="closeAndValidate()">
Yes
</button>
</footer>

View File

@@ -0,0 +1,39 @@
:host {
display: flex;
flex-direction: column;
text-align: center;
padding: 1em;
footer {
display: flex;
flex-direction: row;
justify-content: space-between;
button {
padding: .8em 1.2em;
border-radius: 10em;
border: none;
background-color: #3f51b5;
color: white;
transition: background-color .2s ease-in-out;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
&:hover {
background-color: #5b6ed8;
}
&.secondary {
color: #3f51b5;
background-color: white;
&:hover {
background-color: #f2f4ff;
cursor: pointer;
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
import { Component, inject, Input } from "@angular/core";
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
export interface ConfirmationDialogData {
title: string;
description: string;
}
@Component({
selector: 'app-confirmation-dialog',
standalone: true,
templateUrl: './confirmation-dialog.component.html',
styleUrl: './confirmation-dialog.component.scss',
imports: []
})
export class ConfirmationDialog {
private readonly dialogRef = inject(MatDialogRef<ConfirmationDialog>);
data: ConfirmationDialogData = inject(MAT_DIALOG_DATA);
get title(): string {
return this.data.title;
}
get description(): string {
return this.data.description;
}
closeAndValidate(): void {
this.dialogRef.close(true);
}
closeDialog(): void {
this.dialogRef.close(false);
}
}

View File

@@ -1,14 +1,14 @@
import { inject, Injectable, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { PublicationRestService } from "../../core/rest-services/publications/publication.rest-service";
import { MatSnackBar } from "@angular/material/snack-bar";
import { MatDialog } from "@angular/material/dialog";
import { BehaviorSubject, Observable, Subscription } from "rxjs";
import { copy } from "../../core/utils/ObjectUtils";
import { Publication } from "../../core/rest-services/publications/model/publication";
import { Location } from "@angular/common"; import { Location } from "@angular/common";
import { PictureSelectionDialog } from "./picture-selection-dialog/picture-selection-dialog.component"; import { inject, Injectable, OnDestroy } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { MatSnackBar } from "@angular/material/snack-bar";
import { ActivatedRoute } from "@angular/router";
import { BehaviorSubject, Observable, Subscription } from "rxjs";
import { Publication } from "../../core/rest-services/publications/model/publication";
import { PublicationRestService } from "../../core/rest-services/publications/publication.rest-service";
import { copy } from "../../core/utils/ObjectUtils";
import { CodeBlockDialog } from "./code-block-dialog/code-block-dialog.component"; import { CodeBlockDialog } from "./code-block-dialog/code-block-dialog.component";
import { PictureSelectionDialog } from "./picture-selection-dialog/picture-selection-dialog.component";
declare let Prism: any; declare let Prism: any;
@@ -58,7 +58,6 @@ export class PublicationEditionService implements OnDestroy {
private readonly activatedRoute = inject(ActivatedRoute); private readonly activatedRoute = inject(ActivatedRoute);
private readonly publicationRestService = inject(PublicationRestService); private readonly publicationRestService = inject(PublicationRestService);
private readonly location = inject(Location); private readonly location = inject(Location);
private readonly router = inject(Router);
private readonly snackBar = inject(MatSnackBar); private readonly snackBar = inject(MatSnackBar);
private readonly dialog = inject(MatDialog); private readonly dialog = inject(MatDialog);
@@ -265,23 +264,6 @@ export class PublicationEditionService implements OnDestroy {
this._save(state); this._save(state);
} }
save(): void {
const state = this._state;
this.isSavingSubject.next(true);
this.publicationRestService.update(state.publication)
.then(() => {
this.snackBar.open('Publication updated succesfully!', 'Close', { duration: 5000 });
this.router.navigate(['/home']);
})
.catch(error => {
const errorMessage = 'An error occured while saving publication modifications.';
console.error(errorMessage, error);
this.snackBar.open(errorMessage, 'Close', { duration: 5000 });
})
.finally(() => this.isSavingSubject.next(false));
}
loadPreview(): void { loadPreview(): void {
const state = this._state; const state = this._state;

View File

@@ -1,6 +1,6 @@
import { HttpClient, HttpParams } from '@angular/common/http'; import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable, inject } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { lastValueFrom } from 'rxjs'; import { last, lastValueFrom } from 'rxjs';
import { Publication } from './model/publication'; import { Publication } from './model/publication';
@Injectable({ @Injectable({
@@ -35,4 +35,8 @@ export class PublicationRestService {
const request = { text: publicationText }; const request = { text: publicationText };
return lastValueFrom(this.httpClient.post<string>('/api/publications/preview', request)); return lastValueFrom(this.httpClient.post<string>('/api/publications/preview', request));
} }
delete(publicationId: string): Promise<void> {
return lastValueFrom(this.httpClient.delete<void>(`/api/publications/${publicationId}`));
}
} }

View File

@@ -25,7 +25,7 @@
</div> </div>
</div> </div>
@if (isAuthorAndUserEquals) { @if (isAuthorAndUserEquals) {
<button type="button" matTooltip="Click to delete the publication" matTooltipPosition="left"> <button type="button" (click)="deletePublication()" matTooltip="Click to delete the publication" matTooltipPosition="left">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
Delete Delete
</button> </button>

View File

@@ -1,14 +1,16 @@
import { Component, OnDestroy, OnInit, inject } from '@angular/core'; import { Component, OnDestroy, OnInit, inject } from '@angular/core';
import { PublicationRestService } from '../../core/rest-services/publications/publication.rest-service'; import { PublicationRestService } from '../../core/rest-services/publications/publication.rest-service';
import { ActivatedRoute, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { Publication } from '../../core/rest-services/publications/model/publication'; import { Publication } from '../../core/rest-services/publications/model/publication';
import { MatSnackBar } from '@angular/material/snack-bar'; import { MatSnackBar } from '@angular/material/snack-bar';
import { CommonModule } from '@angular/common'; import { CommonModule, Location } from '@angular/common';
import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { MatProgressSpinner } from '@angular/material/progress-spinner';
import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip'; import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
import { MatIcon } from '@angular/material/icon'; import { MatIcon } from '@angular/material/icon';
import { AuthenticationService } from '../../core/service/authentication.service'; import { AuthenticationService } from '../../core/service/authentication.service';
import { MatDialog } from '@angular/material/dialog';
import { ConfirmationDialog } from '../../components/confirmation-dialog/confirmation-dialog.component';
declare let Prism: any; declare let Prism: any;
@@ -20,11 +22,14 @@ declare let Prism: any;
styleUrl: './publication.component.scss' styleUrl: './publication.component.scss'
}) })
export class PublicationComponent implements OnInit, OnDestroy { export class PublicationComponent implements OnInit, OnDestroy {
private activatedRoute = inject(ActivatedRoute); private readonly activatedRoute = inject(ActivatedRoute);
private authenticationService = inject(AuthenticationService); private readonly authenticationService = inject(AuthenticationService);
private publicationRestService = inject(PublicationRestService); private readonly dialog = inject(MatDialog);
private readonly publicationRestService = inject(PublicationRestService);
private readonly location = inject(Location);
private readonly snackBar = inject(MatSnackBar);
private paramMapSubscription?: Subscription; private paramMapSubscription?: Subscription;
private snackBar = inject(MatSnackBar); private afterDialogCloseSubscription?: Subscription;
isLoading: boolean = false; isLoading: boolean = false;
isAuthorAndUserEquals: boolean = false; isAuthorAndUserEquals: boolean = false;
publication?: Publication; publication?: Publication;
@@ -57,5 +62,27 @@ export class PublicationComponent implements OnInit, OnDestroy {
ngOnDestroy(): void { ngOnDestroy(): void {
this.paramMapSubscription?.unsubscribe(); this.paramMapSubscription?.unsubscribe();
this.afterDialogCloseSubscription?.unsubscribe();
}
deletePublication(): void {
const dialogRef = this.dialog.open(
ConfirmationDialog,
{
data: {
title: 'Publication deletion',
description: 'Are you sure you want to delete this publication?'
}
}
);
this.afterDialogCloseSubscription = dialogRef.afterClosed()
.subscribe(response => {
if (response && this.publication?.id) {
this.publicationRestService.delete(this.publication.id);
this.snackBar.open('Publication deleted', 'Close', { duration: 5000 });
this.location.back();
}
});
} }
} }