From 6f3db280b3031cbc8761c75d5a560a47f7a16c4a Mon Sep 17 00:00:00 2001 From: Alex ORLUC <alex.orluc@maarch.org> Date: Fri, 17 Jan 2020 15:47:52 +0100 Subject: [PATCH] FEAT #10633 TIME 1:20 add give avis parallel + fix msg --- src/frontend/app/actions/actions.service.ts | 23 ++++ ...ontinue-avis-circuit-action.component.html | 7 +- .../continue-avis-circuit-action.component.ts | 36 +++-- .../give-avis-parallel-action.component.html | 50 +++++++ .../give-avis-parallel-action.component.scss | 128 ++++++++++++++++++ .../give-avis-parallel-action.component.ts | 102 ++++++++++++++ .../send-avis-parallel-action.component.ts | 2 +- .../send-avis-workflow-action.component.ts | 2 +- src/frontend/app/app.module.ts | 3 + .../app/avis/avis-workflow.component.ts | 8 +- src/frontend/lang/lang-en.ts | 8 ++ src/frontend/lang/lang-fr.ts | 8 ++ src/frontend/lang/lang-nl.ts | 8 ++ 13 files changed, 366 insertions(+), 19 deletions(-) create mode 100644 src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.html create mode 100644 src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.scss create mode 100644 src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.ts diff --git a/src/frontend/app/actions/actions.service.ts b/src/frontend/app/actions/actions.service.ts index 6533b97c3f8..4ef2814ce01 100644 --- a/src/frontend/app/actions/actions.service.ts +++ b/src/frontend/app/actions/actions.service.ts @@ -30,6 +30,7 @@ import { ContinueVisaCircuitActionComponent } from './visa-continue-circuit-acti import { SendAvisWorkflowComponent } from './avis-workflow-send-action/send-avis-workflow-action.component'; import { ContinueAvisCircuitActionComponent } from './avis-continue-circuit-action/continue-avis-circuit-action.component'; import { SendAvisParallelComponent } from './avis-parallel-send-action/send-avis-parallel-action.component'; +import { GiveAvisParallelActionComponent } from './avis-give-parallel-action/give-avis-parallel-action.component'; @Injectable() export class ActionsService { @@ -798,5 +799,27 @@ export class ActionsService { ).subscribe(); } + giveOpinionParallelAction(options: any = null) { + const dialogRef = this.dialog.open(GiveAvisParallelActionComponent, { + autoFocus: false, + disableClose: true, + data: this.setDatasActionToSend() + }); + dialogRef.afterClosed().pipe( + tap((data: any) => { + this.unlockResourceAfterActionModal(data); + }), + filter((data: string) => data === 'success'), + tap((result: any) => { + this.endAction(result); + }), + finalize(() => this.loading = false), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + } diff --git a/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.html b/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.html index a53d4a66038..6a7400832c5 100644 --- a/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.html +++ b/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.html @@ -12,6 +12,11 @@ <b *ngIf="data.resIds.length > 1" color="primary" class="highlight">{{data.resIds.length}} {{lang.elements}}</b> ? </div> + <div class="alert-message alert-message-info" + *ngIf="data.resIds.length == 1 && !noResourceToProcess" + role="alert" style="margin-top: 30px;" + [innerHTML]="'<b>' + ownerOpinion + '</b> '+ lang.askOpinionUser + ' :<br/><br/>' + opinionContent"> + </div> <div class="alert-message alert-message-info" *ngIf="data.resIds.length == 1 && appAvisWorkflow !== undefined && appAvisWorkflow.getNextAvisUser() !== ''" role="alert" style="margin-top: 30px;" @@ -39,7 +44,7 @@ </li> </ul> </div> - <app-note-editor #noteEditor [resIds]="data.resIds"></app-note-editor> + <app-note-editor #noteEditor [title]="lang.addOpinion" [resIds]="data.resIds"></app-note-editor> <app-avis-workflow *ngIf="data.resIds.length == 1" [adminMode]="false" [resId]="data.resIds[0]" #appAvisWorkflow> </app-avis-workflow> diff --git a/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.ts b/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.ts index 2eae3dd7b16..3dd4d2ad304 100644 --- a/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.ts +++ b/src/frontend/app/actions/avis-continue-circuit-action/continue-avis-circuit-action.component.ts @@ -21,6 +21,9 @@ export class ContinueAvisCircuitActionComponent implements OnInit { resourcesWarnings: any[] = []; resourcesErrors: any[] = []; + ownerOpinion: string = ''; + opinionContent: string = ''; + noResourceToProcess: boolean = null; @ViewChild('noteEditor', { static: true }) noteEditor: NoteEditorComponent; @@ -33,35 +36,40 @@ export class ContinueAvisCircuitActionComponent implements OnInit { @Inject(MAT_DIALOG_DATA) public data: any, public functions: FunctionsService) { } - async ngOnInit(): Promise<void> { - this.loading = true; - await this.checkAvisCircuit(); - this.loading = false; + ngOnInit() { + this.checkAvisCircuit(); } checkAvisCircuit() { + this.loading = true; this.resourcesErrors = []; this.resourcesWarnings = []; - - return new Promise((resolve, reject) => { - this.http.post('../../rest/resourcesList/users/' + this.data.userId + '/groups/' + this.data.groupId + '/baskets/' + this.data.basketId + '/actions/' + this.data.action.id + '/checkContinueOpinionCircuit', { resources: this.data.resIds }) - .subscribe((data: any) => { + this.http.post('../../rest/resourcesList/users/' + this.data.userId + '/groups/' + this.data.groupId + '/baskets/' + this.data.basketId + '/actions/' + this.data.action.id + '/checkContinueOpinionCircuit', { resources: this.data.resIds }).pipe( + tap((data: any) => { if (!this.functions.empty(data.resourcesInformations.warning)) { this.resourcesWarnings = data.resourcesInformations.warning; } - if(!this.functions.empty(data.resourcesInformations.error)) { + if (!this.functions.empty(data.resourcesInformations.error)) { this.resourcesErrors = data.resourcesInformations.error; this.noResourceToProcess = this.resourcesErrors.length === this.data.resIds.length; } - resolve(true); - }, (err: any) => { + + if (!this.noResourceToProcess) { + this.ownerOpinion = data.resourcesInformations.success[0].avisUserAsk; + this.opinionContent = data.resourcesInformations.success[0].note; + } + }), + finalize(() => this.loading = false), + catchError((err: any) => { this.notify.handleSoftErrors(err); - }); - }); + this.dialogRef.close(); + return of(false); + }) + ).subscribe(); } - async onSubmit() { + onSubmit() { const realResSelected: number[] = this.data.resIds.filter((resId: any) => this.resourcesErrors.map(resErr => resErr.res_id).indexOf(resId) === -1); this.executeAction(realResSelected); } diff --git a/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.html b/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.html new file mode 100644 index 00000000000..6d9816f405e --- /dev/null +++ b/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.html @@ -0,0 +1,50 @@ +<h1 mat-dialog-title>{{data.action.label}}</h1> +<div mat-dialog-content> + <div *ngIf="loading" class="loading" style="display:flex;height:100%;"> + <mat-spinner style="margin:auto;"></mat-spinner> + </div> + <mat-sidenav-container autosize style="height:100%;"> + <mat-sidenav-content style="background: white;padding:10px;"> + <div> + {{lang.makeActionOn}} + <b *ngIf="data.resIds.length === 0" color="primary" class="highlight">{{lang.currentIndexingMail}}</b> + <b *ngIf="data.resIds.length == 1" color="primary" class="highlight">{{data.resource.chrono}}</b> + <b *ngIf="data.resIds.length > 1" color="primary" class="highlight">{{data.resIds.length}} + {{lang.elements}}</b> ? + </div> + <div class="alert-message alert-message-info" + *ngIf="data.resIds.length == 1 && !noResourceToProcess" + role="alert" style="margin-top: 30px;" + [innerHTML]="'<b>' + ownerOpinion + '</b> '+ lang.askOpinionUser + ' :<br/><br/>' + opinionContent"> + </div> + + <div class="alert-message alert-message-info" + *ngIf="data.resIds.length > 1 && !noResourceToProcess" + role="alert" style="margin-top: 30px;" [innerHTML]="lang.askOpinion"></div> + + <div *ngIf="resourcesErrors.length > 0" class="alert-message alert-message-danger mailList" role="alert"> + <p> + {{lang.canNotMakeAction}} : + </p> + <ul> + <li *ngFor="let ressource of resourcesErrors"> + <b>{{ressource.alt_identifier}}</b> : {{lang[ressource.reason]}} + </li> + </ul> + </div> + <div *ngIf="resourcesWarnings.length > 0" class="alert-message alert-message-info mailList" role="alert"> + <ul style="margin: 0;padding-bottom: 0px;"> + <li *ngFor="let ressource of resourcesWarnings"> + <b>{{ressource.alt_identifier}}</b> : {{lang[ressource.reason]}} + </li> + </ul> + </div> + <app-note-editor #noteEditor [title]="lang.addOpinion" [resIds]="data.resIds"></app-note-editor> + </mat-sidenav-content> + </mat-sidenav-container> +</div> +<div mat-dialog-actions class="actions"> + <button mat-raised-button mat-button color="primary" [disabled]="loading || !isValidAction()" + (click)="onSubmit()">{{lang.validate}}</button> + <button mat-raised-button mat-button [disabled]="loading" [mat-dialog-close]="">{{lang.cancel}}</button> +</div> \ No newline at end of file diff --git a/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.scss b/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.scss new file mode 100644 index 00000000000..9424211bb4a --- /dev/null +++ b/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.scss @@ -0,0 +1,128 @@ +@import '../../../css/vars.scss'; + +.fullHeight { + height: 70vh; +} + +.fullWidth { + width: 70vw; +} + +.highlight { + font-size: 110%; +} + +.loading { + display: flex; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #ffffffb3; + z-index: 2; + overflow: hidden; +} + +.mailList { + ul { + font-size: 12px; + max-height: 100px; + overflow: auto; + padding-left: 25px; + padding-right: 5px; + padding-bottom: 10px; + margin-top: 10px; + } + + p { + //font-size: 18px; + margin: 0; + text-decoration: underline; + } + + b { + font-size: 120%; + } +} + +.formType { + align-items: center; + display: flex; + margin: 10px; + border-radius: 4px; + border: solid 1px #ccc; + position: relative; + padding: 10px; + + &-title { + white-space: pre; + overflow: hidden; + max-width: 85%; + text-overflow: ellipsis; + z-index: 1; + font-size: 10px; + font-weight: bold; + background: white; + position: absolute; + top: -7px; + left: 10px; + padding: 0px; + margin: 0px; + color: #135f7f; + } + + ::ng-deep.mat-form-field-suffix { + color: $secondary; + font-size: 15px; + top: 0; + } + + ::ng-deep.mat-form-field-wrapper { + padding: 0; + } +} + +.priceContent { + display: flex; + align-items: center; + justify-content: flex-end; + width: 100%; + + &-label { + text-align: right; + color: $primary; + flex: 1; + justify-content: flex-end; + display: flex; + padding-right: 10px; + } + + .mat-form-field { + width: 90px !important; + + input { + font-weight: bold; + user-select: none; + } + } +} + +.priceInfo { + padding-right: 20px; + font-size: 10px; + opacity: 0.5; + width: 100%; +} + +.pjList { + display: flex; + width: 100%; + overflow: auto; + flex-direction: column; + background: #666; + + img { + margin: 10px; + } +} \ No newline at end of file diff --git a/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.ts b/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.ts new file mode 100644 index 00000000000..f449a05576d --- /dev/null +++ b/src/frontend/app/actions/avis-give-parallel-action/give-avis-parallel-action.component.ts @@ -0,0 +1,102 @@ +import { Component, OnInit, Inject, ViewChild } from '@angular/core'; +import { LANG } from '../../translate.component'; +import { NotificationService } from '../../notification.service'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { HttpClient } from '@angular/common/http'; +import { NoteEditorComponent } from '../../notes/note-editor.component'; +import { tap, finalize, catchError } from 'rxjs/operators'; +import { of } from 'rxjs'; +import { FunctionsService } from '../../../service/functions.service'; + +@Component({ + templateUrl: "give-avis-parallel-action.component.html", + styleUrls: ['give-avis-parallel-action.component.scss'], +}) +export class GiveAvisParallelActionComponent implements OnInit { + + lang: any = LANG; + loading: boolean = false; + + resourcesWarnings: any[] = []; + resourcesErrors: any[] = []; + + noResourceToProcess: boolean = null; + + ownerOpinion: string = ''; + opinionContent: string = ''; + + @ViewChild('noteEditor', { static: true }) noteEditor: NoteEditorComponent; + + constructor( + public http: HttpClient, + private notify: NotificationService, + public dialogRef: MatDialogRef<GiveAvisParallelActionComponent>, + @Inject(MAT_DIALOG_DATA) public data: any, + public functions: FunctionsService) { } + + ngOnInit() { + this.checkAvisParallel(); + } + + checkAvisParallel() { + this.loading = true; + this.resourcesErrors = []; + this.resourcesWarnings = []; + + this.http.post('../../rest/resourcesList/users/' + this.data.userId + '/groups/' + this.data.groupId + '/baskets/' + this.data.basketId + '/actions/' + this.data.action.id + '/checkGiveParallelOpinion', { resources: this.data.resIds }).pipe( + tap((data: any) => { + if (!this.functions.empty(data.resourcesInformations.warning)) { + this.resourcesWarnings = data.resourcesInformations.warning; + } + + if (!this.functions.empty(data.resourcesInformations.error)) { + this.resourcesErrors = data.resourcesInformations.error; + this.noResourceToProcess = this.resourcesErrors.length === this.data.resIds.length; + } + + if (!this.noResourceToProcess) { + this.ownerOpinion = data.resourcesInformations.success[0].avisUserAsk; + this.opinionContent = data.resourcesInformations.success[0].note; + } + }), + finalize(() => this.loading = false), + catchError((err: any) => { + this.notify.handleSoftErrors(err); + this.dialogRef.close(); + return of(false); + }) + ).subscribe(); + } + + onSubmit() { + const realResSelected: number[] = this.data.resIds.filter((resId: any) => this.resourcesErrors.map(resErr => resErr.res_id).indexOf(resId) === -1); + this.executeAction(realResSelected); + } + + executeAction(realResSelected: number[]) { + const noteContent: string = `[${this.lang.avisUserState}] ${this.noteEditor.getNoteContent()}`; + this.http.put(this.data.processActionRoute, { resources: realResSelected, note: noteContent }).pipe( + tap((data: any) => { + if (!data) { + this.dialogRef.close('success'); + } + if (data && data.errors != null) { + this.notify.error(data.errors); + } + }), + finalize(() => this.loading = false), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + isValidAction() { + if (!this.noResourceToProcess && !this.functions.empty(this.noteEditor.getNoteContent())) { + return true; + } else { + return false; + } + } +} diff --git a/src/frontend/app/actions/avis-parallel-send-action/send-avis-parallel-action.component.ts b/src/frontend/app/actions/avis-parallel-send-action/send-avis-parallel-action.component.ts index d57ec93da64..978f9514b75 100644 --- a/src/frontend/app/actions/avis-parallel-send-action/send-avis-parallel-action.component.ts +++ b/src/frontend/app/actions/avis-parallel-send-action/send-avis-parallel-action.component.ts @@ -86,7 +86,7 @@ export class SendAvisParallelComponent implements AfterViewInit { } executeAction(realResSelected: number[]) { - const noteContent: string = `[POUR AVIS] ${this.noteEditor.getNoteContent()}`; + const noteContent: string = `[${this.lang.avisUserAsk.toUpperCase()}] ${this.noteEditor.getNoteContent()}`; this.http.put(this.data.processActionRoute, { resources: realResSelected, note: noteContent, data: { opinionLimitDate: this.functions.formatDateObjectToFrenchDateString(this.opinionLimitDate, true), opinionCircuit : this.appAvisWorkflow.getWorkflow() } }).pipe( tap((data: any) => { if (!data) { diff --git a/src/frontend/app/actions/avis-workflow-send-action/send-avis-workflow-action.component.ts b/src/frontend/app/actions/avis-workflow-send-action/send-avis-workflow-action.component.ts index f85e842d252..695a9af27ec 100644 --- a/src/frontend/app/actions/avis-workflow-send-action/send-avis-workflow-action.component.ts +++ b/src/frontend/app/actions/avis-workflow-send-action/send-avis-workflow-action.component.ts @@ -84,7 +84,7 @@ export class SendAvisWorkflowComponent implements AfterViewInit { } executeAction(realResSelected: number[]) { - const noteContent: string = `[POUR AVIS] ${this.noteEditor.getNoteContent()}`; + const noteContent: string = `[${this.lang.avisUserAsk.toUpperCase()}] ${this.noteEditor.getNoteContent()}`; this.http.put(this.data.processActionRoute, { resources: realResSelected, note: noteContent, data: { opinionLimitDate: this.functions.formatDateObjectToFrenchDateString(this.opinionLimitDate, true) } }).pipe( tap((data: any) => { if (!data) { diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index 6b40043d2e0..d36e56761c2 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -62,6 +62,7 @@ import { ContinueVisaCircuitActionComponent } from './actions/visa import { ContinueAvisCircuitActionComponent } from './actions/avis-continue-circuit-action/continue-avis-circuit-action.component'; import { SendAvisWorkflowComponent } from './actions/avis-workflow-send-action/send-avis-workflow-action.component'; import { SendAvisParallelComponent } from './actions/avis-parallel-send-action/send-avis-parallel-action.component'; +import { GiveAvisParallelActionComponent } from './actions/avis-give-parallel-action/give-avis-parallel-action.component'; import { FiltersListComponent } from './list/filters/filters-list.component'; import { FiltersToolComponent } from './list/filters/filters-tool.component'; @@ -159,6 +160,7 @@ import { AddAvisModelModalComponent } from './avis/addAvisModel/add-avis-model-m ContinueAvisCircuitActionComponent, SendAvisWorkflowComponent, SendAvisParallelComponent, + GiveAvisParallelActionComponent, ActionsListComponent, PrintSeparatorComponent, FolderPinnedComponent, @@ -212,6 +214,7 @@ import { AddAvisModelModalComponent } from './avis/addAvisModel/add-avis-model-m SendExternalNoteBookActionComponent, ContinueVisaCircuitActionComponent, ContinueAvisCircuitActionComponent, + GiveAvisParallelActionComponent, ProcessActionComponent, RedirectActionComponent, SendShippingActionComponent, diff --git a/src/frontend/app/avis/avis-workflow.component.ts b/src/frontend/app/avis/avis-workflow.component.ts index 16e0a9d928f..2238e47b7e2 100644 --- a/src/frontend/app/avis/avis-workflow.component.ts +++ b/src/frontend/app/avis/avis-workflow.component.ts @@ -62,12 +62,16 @@ export class AvisWorkflowComponent implements OnInit { ) { } ngOnInit(): void { - if (this.mode === 'parallel') { + if (this.mode === 'parallel' && this.adminMode) { this.loadAvisRoles(); } if (this.resId !== null) { - this.loadWorkflow(this.resId); + if (this.mode === 'circuit') { + this.loadWorkflow(this.resId); + } else { + this.loadParallelWorkflow(this.resId); + } } } diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index e9e39cd12ba..3db903c5fa3 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -1423,4 +1423,12 @@ export const LANG_EN = { "interrupted": "Interrupted", "addOpinionReason": "Please fill the opinion reason", "opinionLimitDate": "Opinion limit date", + "addOpinion": "Give your opinion", + "askOpinion": "Several users ask your opinion", + "askOpinionUser": "ask your opinion", + "avisUserAsk": "for opinion", + "avisUserState": "opinion", + "userNotInDiffusionList": "You are not in opinion diffusion list", + "noOpinionLimiteDate": "The opinion limit date is not defined", + "noOpinionNote": "The reason is not defined", }; diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index 78ddb665033..5ba65656d73 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -1463,4 +1463,12 @@ export const LANG_FR = { "interrupted": "Interrompu", "addOpinionReason": "Veuillez renseigner le motif de l'avis", "opinionLimitDate": "Date limite de l'avis", + "addOpinion": "Donner votre avis", + "askOpinion": "Des personnes vous demande votre avis", + "askOpinionUser": "vous demande votre avis", + "avisUserAsk": "pour avis", + "avisUserState": "avis", + "userNotInDiffusionList": "Vous n'êtes pas dans la liste de diffusion des avis", + "noOpinionLimiteDate": "La date limite de l'avis n'est pas défini", + "noOpinionNote": "Aucun motif défini", }; diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index c6e7540e2d3..b59104669e6 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -1448,4 +1448,12 @@ export const LANG_NL = { "opinionLimitDate": "Opinion limit date", //_TO_TRANSLATE "visaWorkflowInterrupted" : "Interrupted workflow",//_TO_TRANSLATE "hasInterruptedWorkflow" : "Has interrupted the workflow",//_TO_TRANSLATE + "addOpinion": "Give your opinion", //_TO_TRANSLATE + "askOpinion": "Several users ask your opinion", //_TO_TRANSLATE + "askOpinionUser": "ask your opinion", //_TO_TRANSLATE + "avisUserAsk": "for opinion", //_TO_TRANSLATE + "avisUserState": "opinion", //_TO_TRANSLATE + "userNotInDiffusionList": "You are not in opinion diffusion list", //_TO_TRANSLATE + "noOpinionLimiteDate": "The opinion limit date is not defined", //_TO_TRANSLATE + "noOpinionNote": "The reason is not defined", //_TO_TRANSLATE }; -- GitLab