Code cleaning about publication edition component.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
<button type="button" class="close" (click)="closeDialog()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
<header>
|
||||
<h1>Select an illustration:</h1>
|
||||
</header>
|
||||
<div class="picture-container">
|
||||
@if (isLoading) {
|
||||
<h2>Pictures loading...</h2>
|
||||
<mat-spinner></mat-spinner>
|
||||
} @else {
|
||||
@if (pictures.length) {
|
||||
@for(picture of pictures; track picture) {
|
||||
<img src="/api/pictures/{{picture.id}}" (click)="selectPicture(picture)" matTooltip="Choose this illustration"/>
|
||||
}
|
||||
} @else {
|
||||
<h2>There is no any picture.</h2>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<footer>
|
||||
<button type="button" class="secondary" matRipple (click)="closeDialog()">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="button" (click)="fileUpload.click()" matRipple>
|
||||
<mat-icon>upload_file</mat-icon>
|
||||
Add new picture
|
||||
</button>
|
||||
<input type="file" (change)="uploadPicture($event)" #fileUpload/>
|
||||
</footer>
|
||||
@@ -0,0 +1,97 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1em;
|
||||
gap: 1em;
|
||||
position: relative;
|
||||
max-height: 90vh;
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
border-radius: 10em;
|
||||
border: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
header {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.picture-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
max-height: 30em;
|
||||
overflow-y: auto;
|
||||
min-height: 10em;
|
||||
padding: .5em 0;
|
||||
|
||||
img {
|
||||
width: 15em;
|
||||
height: 10em;
|
||||
object-fit: cover;
|
||||
border-radius: 1em;
|
||||
opacity: .9;
|
||||
box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
|
||||
transition: opacity .2s ease-in-out, box-shadow .2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
box-shadow: 0 2px 5px 0 rgba(0,0,0,.32),0 2px 10px 0 rgba(0,0,0,.24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { Component, inject, OnInit } from "@angular/core";
|
||||
import { Picture } from "../../../core/rest-services/picture/model/picture";
|
||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||
import { PictureRestService } from "../../../core/rest-services/picture/picture.rest-service";
|
||||
import { MatIcon } from "@angular/material/icon";
|
||||
import { MatDialogRef } from "@angular/material/dialog";
|
||||
import {MatRippleModule} from '@angular/material/core';
|
||||
import { MatTooltip } from "@angular/material/tooltip";
|
||||
|
||||
@Component({
|
||||
selector: 'app-picture-selection',
|
||||
standalone: true,
|
||||
imports: [MatProgressSpinnerModule, MatIcon, MatRippleModule, MatTooltip],
|
||||
templateUrl: './picture-selection-dialog.component.html',
|
||||
styleUrl: './picture-selection-dialog.component.scss',
|
||||
})
|
||||
export class PictureSelectionDialog implements OnInit {
|
||||
private readonly pictureRestService = inject(PictureRestService);
|
||||
private readonly snackBar = inject(MatSnackBar);
|
||||
private readonly dialogRef = inject(MatDialogRef<PictureSelectionDialog>);
|
||||
|
||||
isLoading: boolean = false;
|
||||
isLoaded: boolean = false;
|
||||
pictures: Picture[] = [];
|
||||
|
||||
ngOnInit(): void {
|
||||
this.isLoading = true;
|
||||
this.pictureRestService.getAllOfCurrentUser()
|
||||
.then(pictures => {
|
||||
this.pictures = pictures;
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.status === 401) {
|
||||
this.dialogRef.close();
|
||||
} else {
|
||||
const errorMessage = 'An error occured while loading pictures.';
|
||||
console.error(errorMessage, error);
|
||||
this.snackBar.open(errorMessage, 'Close', { duration: 5000 });
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false;
|
||||
this.isLoaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
selectPicture(picture: Picture): void {
|
||||
this.dialogRef.close(picture.id);
|
||||
}
|
||||
|
||||
closeDialog(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
uploadPicture(fileSelectionEvent: any): void {
|
||||
const pictureFile = fileSelectionEvent.target.files[0];
|
||||
if (pictureFile) {
|
||||
this.pictureRestService.uploadPicture(pictureFile)
|
||||
.then(pictureId => {
|
||||
this.dialogRef.close(pictureId);
|
||||
})
|
||||
.catch(error => {
|
||||
const errorMessage = 'A technical error occured while uploading your picture.';
|
||||
console.error(errorMessage, error);
|
||||
this.snackBar.open(errorMessage, 'Close', { duration: 5000 });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { inject, Injectable } from "@angular/core";
|
||||
import { PictureRestService } from "../../../core/rest-services/picture/picture.rest-service";
|
||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||
import { MatDialogRef } from "@angular/material/dialog";
|
||||
import { PictureSelectionDialog } from "./picture-selection-dialog.component";
|
||||
|
||||
@Injectable()
|
||||
export class PictureSelectionDialogService {
|
||||
private pictureRestService = inject(PictureRestService);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private readonly dialogRef = inject(MatDialogRef<PictureSelectionDialog>);
|
||||
|
||||
uploadPicture(pictureFile: File): void {
|
||||
this.pictureRestService.uploadPicture(pictureFile)
|
||||
.then(pictureId => {
|
||||
this.dialogRef.close(pictureId);
|
||||
})
|
||||
.catch(error => {
|
||||
const errorMessage = 'An error occured while uploading a picture...';
|
||||
console.error(errorMessage, error);
|
||||
this.snackBar.open(errorMessage, 'Close', { duration: 5000 });
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user