Add confirmation dialog to delete publications.
This commit is contained in:
@@ -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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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}`));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user