diff --git a/src/frontend/app/actions/actions.service.ts b/src/frontend/app/actions/actions.service.ts index af87e163072b042749a7265bbbbe69fa6cca4bc7..f7eec03015300a64ba2e283030d41e459e894521 100644 --- a/src/frontend/app/actions/actions.service.ts +++ b/src/frontend/app/actions/actions.service.ts @@ -21,6 +21,7 @@ import { RedirectActionComponent } from './redirect-action/redirect-action.compo import { SendShippingActionComponent } from './send-shipping-action/send-shipping-action.component'; import { redirectInitiatorEntityActionComponent } from './redirect-initiator-entity-action/redirect-initiator-entity-action.component'; import { Router } from '@angular/router'; +import { SendSignatureBookActionComponent } from './send-signature-book-action/send-signature-book-action.component'; @Injectable() export class ActionsService { @@ -547,6 +548,28 @@ export class ActionsService { ).subscribe(); } + sendSignatureBookAction(options: any = null) { + const dialogRef = this.dialog.open(SendSignatureBookActionComponent, { + 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(); + } + + noConfirmAction(options: any = null) { let dataActionToSend = this.setDatasActionToSend(); if ( dataActionToSend.resIds.length === 0) { diff --git a/src/frontend/app/actions/send-signature-book-action/send-signature-book-action.component.html b/src/frontend/app/actions/send-signature-book-action/send-signature-book-action.component.html new file mode 100644 index 0000000000000000000000000000000000000000..b377fc59812460b9e170bb9ca2552b6bcfb391c1 --- /dev/null +++ b/src/frontend/app/actions/send-signature-book-action/send-signature-book-action.component.html @@ -0,0 +1,41 @@ +<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 *ngIf="resourcesError.length > 0" class="alert-message alert-message-danger mailList" role="alert"> + <p> + {{lang.canNotMakeAction}} : + </p> + <ul> + <li *ngFor="let ressource of resourcesError"> + <b>{{ressource.alt_identifier}}</b> : {{lang[ressource.reason]}} + </li> + </ul> + </div> + <app-visa-workflow *ngIf="data.resIds.length == 1 || (!noResourceToProcess && data.resIds.length > 1)" [adminMode]="true" #appVisaWorkflow [resId]="data.resIds[0]"> + </app-visa-workflow> + <div style="padding-top: 10px;"> + <app-note-editor #noteEditor [resIds]="data.resIds"></app-note-editor> + </div> + </mat-sidenav-content> + <mat-sidenav position='end' *ngIf="data.resIds.length === 1" opened mode="side" style="overflow-x:hidden;" + autoFocus="false" [ngStyle]="{'width': '400px'}"> + <app-attachments-list [resId]="data.resIds[0]" (afterActionAttachment)="checkSignatureBook()"></app-attachments-list> + </mat-sidenav> + </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/send-signature-book-action/send-signature-book-action.component.scss b/src/frontend/app/actions/send-signature-book-action/send-signature-book-action.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..9424211bb4af9027d454165e7417bf86fb23c6eb --- /dev/null +++ b/src/frontend/app/actions/send-signature-book-action/send-signature-book-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/send-signature-book-action/send-signature-book-action.component.ts b/src/frontend/app/actions/send-signature-book-action/send-signature-book-action.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..37c26ade6c3c3152c2654e06ac7990e27d6ddacd --- /dev/null +++ b/src/frontend/app/actions/send-signature-book-action/send-signature-book-action.component.ts @@ -0,0 +1,120 @@ +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'; +import { VisaWorkflowComponent } from '../../visa/visa-workflow.component'; + +@Component({ + templateUrl: "send-signature-book-action.component.html", + styleUrls: ['send-signature-book-action.component.scss'], +}) +export class SendSignatureBookActionComponent implements OnInit { + + lang: any = LANG; + loading: boolean = false; + + resourcesError: any[] = []; + + noResourceToProcess: boolean = false; + + @ViewChild('noteEditor', { static: true }) noteEditor: NoteEditorComponent; + @ViewChild('appVisaWorkflow', { static: false }) appVisaWorkflow: VisaWorkflowComponent; + + constructor( + public http: HttpClient, + private notify: NotificationService, + public dialogRef: MatDialogRef<SendSignatureBookActionComponent>, + @Inject(MAT_DIALOG_DATA) public data: any, + public functions: FunctionsService) { } + + async ngOnInit(): Promise<void> { + this.loading = true; + await this.checkSignatureBook(); + this.loading = false; + } + + checkSignatureBook() { + this.resourcesError = []; + + 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 + '/checkSignatureBook', { resources: this.data.resIds }) + .subscribe((data: any) => { + if (!this.functions.empty(data.resourcesInformations.noAttachment)) { + this.resourcesError = data.resourcesInformations.noAttachment; + } + this.noResourceToProcess = this.data.resIds.length === this.resourcesError.length; + resolve(true); + }, (err: any) => { + this.notify.handleSoftErrors(err); + }); + }); + } + + async onSubmit() { + this.loading = true; + if ( this.data.resIds.length === 0) { + // this.indexDocumentAndExecuteAction(); + } else { + const res = await this.appVisaWorkflow.saveVisaWorkflow(); + + if (res) { + this.executeAction(); + } + } + this.loading = false; + } + + /* indexDocumentAndExecuteAction() { + + this.http.post('../../rest/resources', this.data.resource).pipe( + tap((data: any) => { + this.data.resIds = [data.resId]; + }), + exhaustMap(() => this.http.put(this.data.indexActionRoute, {resource : this.data.resIds[0], note : this.noteEditor.getNoteContent()})), + tap(() => { + this.dialogRef.close('success'); + }), + finalize(() => this.loading = false), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe() + } */ + + executeAction() { + let realResSelected: string[]; + let datas: any; + + realResSelected = this.data.resIds.filter((resId: any) => this.resourcesError.map(resErr => resErr.res_id).indexOf(resId) === -1); + + this.http.put(this.data.processActionRoute, {resources : realResSelected, note : this.noteEditor.getNoteContent()}).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) { + return true; + } else { + return false; + } + } +} diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index 09d63b71a222dcc1bac1d8117ccf0ed9154696fa..c85ff192985c583d6f3a8d22dbae948ee21eeb92 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -53,6 +53,7 @@ import { ViewDocActionComponent } from './actions/view-doc-action/ import { RedirectActionComponent } from './actions/redirect-action/redirect-action.component'; import { SendShippingActionComponent } from './actions/send-shipping-action/send-shipping-action.component'; import { redirectInitiatorEntityActionComponent } from './actions/redirect-initiator-entity-action/redirect-initiator-entity-action.component'; +import { SendSignatureBookActionComponent } from './actions/send-signature-book-action/send-signature-book-action.component'; import { FiltersListComponent } from './list/filters/filters-list.component'; import { FiltersToolComponent } from './list/filters/filters-tool.component'; @@ -141,6 +142,7 @@ import { AddAvisModelModalComponent } from './avis/addAvisModel/add-avis-model-m RedirectActionComponent, SendShippingActionComponent, redirectInitiatorEntityActionComponent, + SendSignatureBookActionComponent, ActionsListComponent, PrintSeparatorComponent, FolderPinnedComponent, @@ -191,6 +193,7 @@ import { AddAvisModelModalComponent } from './avis/addAvisModel/add-avis-model-m RedirectActionComponent, SendShippingActionComponent, redirectInitiatorEntityActionComponent, + SendSignatureBookActionComponent, ViewDocActionComponent, FolderUpdateComponent, AddPrivateIndexingModelModalComponent, diff --git a/src/frontend/app/attachments/attachments-list.component.scss b/src/frontend/app/attachments/attachments-list.component.scss index 1b5b3f5cd4b9caab82092dc03de0becd8cb47bd8..5e7d7be4ebbb43bcc7d5a252a2fdb56166f71693 100644 --- a/src/frontend/app/attachments/attachments-list.component.scss +++ b/src/frontend/app/attachments/attachments-list.component.scss @@ -189,14 +189,16 @@ } .addPjProcess { - position: fixed; + position: sticky; + bottom: 5px; z-index: 2; bottom: 80px; margin-left: 10px; } .addPjPanel { - position: fixed; + position: sticky; + bottom: 5px; z-index: 2; bottom: 10px; margin-left: 10px; diff --git a/src/frontend/app/attachments/attachments-list.component.ts b/src/frontend/app/attachments/attachments-list.component.ts index 38638e1e4d7f488ed9a259b8b25982d49c7da801..25f63bb52be771d2793326c75850522d35144860 100644 --- a/src/frontend/app/attachments/attachments-list.component.ts +++ b/src/frontend/app/attachments/attachments-list.component.ts @@ -58,6 +58,8 @@ export class AttachmentsListComponent implements OnInit { @Input('target') target: string = 'panel'; @Output('reloadBadgeAttachments') reloadBadgeAttachments = new EventEmitter<string>(); + @Output() afterActionAttachment = new EventEmitter<string>(); + constructor( public http: HttpClient, private notify: NotificationService, @@ -135,6 +137,7 @@ export class AttachmentsListComponent implements OnInit { this.http.put("../../rest/attachments/" + attachment.resId + "/inSignatureBook", {}) .subscribe(() => { attachment.inSignatureBook = !attachment.inSignatureBook; + this.afterActionAttachment.emit('setInSignatureBook'); this.notify.success(this.lang.actionDone); }, (err: any) => { this.notify.error(err.error.errors); @@ -145,6 +148,7 @@ export class AttachmentsListComponent implements OnInit { this.http.put("../../rest/attachments/" + attachment.resId + "/inSendAttachment", {}) .subscribe(() => { attachment.inSendAttach = !attachment.inSendAttach; + this.afterActionAttachment.emit('setInSendAttachment'); this.notify.success(this.lang.actionDone); }, (err: any) => { this.notify.error(err.error.errors); diff --git a/src/frontend/app/visa/visa-workflow.component.ts b/src/frontend/app/visa/visa-workflow.component.ts index f5814daff9ce7648f8f62193e468056050307ca7..5a8a02bdd368abfb7beb1922d66ba66b74af93b4 100644 --- a/src/frontend/app/visa/visa-workflow.component.ts +++ b/src/frontend/app/visa/visa-workflow.component.ts @@ -308,6 +308,7 @@ export class VisaWorkflowComponent implements OnInit { ).subscribe(); } else { this.notify.error(this.lang.signUserRequired); + resolve(false); } }); }