diff --git a/lang/en.json b/lang/en.json index 443882308873910e684ad3965585abbc687d4fba..57394fa28031c891a6154b74890f62f6bfea2fe8 100755 --- a/lang/en.json +++ b/lang/en.json @@ -650,6 +650,7 @@ "groupsToManage": "Choose the authorized assignment groups", "unlinkGroup": "Unlink group", "emptyGroups": "No groups available to associate", + "errorConvertingDocument": "Error converting document", "emptyGroupUsers": "No users associated with this group", "emptyUsers": "No users available to associate" } diff --git a/lang/fr.json b/lang/fr.json index 5d09b232045322b789fce5d83e17456dc63bd859..e830e51490c9811df7dde828149f116afa2f1a2c 100755 --- a/lang/fr.json +++ b/lang/fr.json @@ -649,6 +649,7 @@ "groupsToManage": "Choisir les groupes d'affectations autorisés", "unlinkGroup": "Dissocier le groupe", "emptyGroups": "Aucun groupe disponible à associer", + "errorConvertingDocument": "Erreur lors de la conversion du document", "emptyGroupUsers": "Aucun utilisateur associé à ce groupe", "emptyUsers": "Aucun utilisateur disponible à associer" } diff --git a/src/frontend/app/document/document.component.html b/src/frontend/app/document/document.component.html index 674e1f790288af2578b8780d2f70ff4aa533c1da..8af9bd6c26e8cc07a626a547ebf7ad0bdb9a73d8 100755 --- a/src/frontend/app/document/document.component.html +++ b/src/frontend/app/document/document.component.html @@ -44,10 +44,20 @@ *ngIf="authService.user.substitute !== null && docList[currentDoc]"> <ion-label style="font-size: 13px;">{{'lang.substitutionInfo' | translate}}</ion-label> </ion-toolbar> -<ion-toolbar class="ion-text-center" color="danger" *ngIf="mainDocument.id !== 0 && mainDocument.status !== 'READY'"> - <ion-label style="font-size: 13px;">{{'lang.convertingDocument' | translate}}</ion-label> +<ion-toolbar class="ion-text-center" color="danger" *ngIf="mainDocument.id !== 0 && mainDocument.status === 'CONVERTING'"> + <div class="loading" style="display:flex;height:100%;"> + <ion-label class="loadingMsg">{{'lang.convertingDocument' | translate}}</ion-label> + <ion-spinner name="dots" color="light" style="padding-top: 6.5%;"></ion-spinner> + </div> +</ion-toolbar> +<ion-toolbar class="ion-text-center" color="danger" *ngIf="mainDocument.id !== 0 && mainDocument.status === 'ERROR'"> + <ion-label style="font-size: 14px; font-weight: bold;">{{'lang.errorConvertingDocument' | translate}}</ion-label> </ion-toolbar> <ion-content *ngIf="!loadingdocument" #mainContent> + <!-- <div *ngIf="mainDocument.status === 'READY'" class="loading" style="display:flex;height:100%;"> + <ion-spinner name="lines" color="primary" style="margin: auto;"></ion-spinner> + <ion-label class="loadingMsg">{{'lang.convertingDocument' | translate}}</ion-label> + </div> --> <ng-container *ngIf="(mainDocument.notes !== undefined && mainDocument.notes !== null) || hasWorkflowNotes"> <ion-fab-button *ngIf="!expandedNote" ngDraggable [bounds]="myBounds" [inBounds]="true" (movingOffset)="signaturesService.dragging=true" (endOffset)="signaturesService.dragging=false" @@ -134,7 +144,7 @@ </ion-content> <ion-footer *ngIf="!loadingImage && currentDoc === 0" class="ion-no-border footer-buttons" [ngStyle]="{'grid-template-columns': actionsList.length === 2 ? 'repeat(2, 1fr)' : 'repeat(3, 1fr)'}"> - <ion-button [disabled]="mainDocument.status === 'CONVERTING'" *ngFor="let action of actionsList" [color]="action.color" shape="round" size="large" fill="outline" (click)="launchEvent(action)" style="width: auto;"> + <ion-button [disabled]="isNotReady()" *ngFor="let action of actionsList" [color]="action.color" shape="round" size="large" fill="outline" (click)="launchEvent(action)" style="width: auto;"> <ion-icon *ngIf="action.logo !== ''" [slot]="'start'" [name]="action.logo"></ion-icon> <ion-label style="font-size: 13px;">{{getLabel(action)}}</ion-label> </ion-button> diff --git a/src/frontend/app/document/document.component.scss b/src/frontend/app/document/document.component.scss index 5719a22075e6f30b415b521a8942d1bbe251ce66..b1fbe6af75fa406123c136ec8de8051d820f3e60 100644 --- a/src/frontend/app/document/document.component.scss +++ b/src/frontend/app/document/document.component.scss @@ -398,7 +398,7 @@ button.disabled { .popover-content{ height: 50%; top: 50px; - } + } } ::ng-deep .custom-popover-class { @@ -407,3 +407,26 @@ button.disabled { top: 50px; } } + +::ng-deep.popover-viewport.sc-ion-popover-md { + overflow: auto; +} + +.loading { + display: flex; + position: absolute; + justify-content: center; + top: 0; + left: 0px; + width: 100%; + height: 100%; + z-index: 2; + overflow: hidden; +} + +.loadingMsg { + padding: 2%; + color: var(--ion-color-light); + font-weight: bold; + margin-right: -5px; +} \ No newline at end of file diff --git a/src/frontend/app/document/document.component.ts b/src/frontend/app/document/document.component.ts index ffbda0c365058190e2c5b137684a86ecd4f63c4b..99d0490b9dc56d5ddebadf88ee7f3833a3cea0de 100755 --- a/src/frontend/app/document/document.component.ts +++ b/src/frontend/app/document/document.component.ts @@ -18,7 +18,7 @@ import { LocalStorageService } from '../service/local-storage.service'; import { ActionSheetController, AlertController, LoadingController, MenuController, ModalController, NavController } from '@ionic/angular'; import { NgxExtendedPdfViewerService } from 'ngx-extended-pdf-viewer'; import { catchError, exhaustMap, tap } from 'rxjs/operators'; -import { of, Subscription } from 'rxjs'; +import { of, Subscription, timer } from 'rxjs'; import { SignatureMethodService } from '../service/signature-method/signature-method.service'; import { FunctionsService } from '../service/functions.service'; import { ActionsService } from '../service/actions.service'; @@ -74,6 +74,7 @@ export class DocumentComponent implements OnInit, OnDestroy { }; subscription: Subscription; + timerSubscription: Subscription; signaturesContent: any = []; docList: any = []; @@ -135,17 +136,15 @@ export class DocumentComponent implements OnInit, OnDestroy { }); } - ngOnDestroy(): void { - this.subscription.unsubscribe(); - } - imageLoaded(ev: any) { this.userMode = this.mainDocument.workflow.find((item: any) => item.current)?.mode; if (this.userMode === 'note') { this.actionsList = this.actionsList.filter((item: any) => item.event !== 'openSignatures'); } this.getImageDimensions(true); - this.load.dismiss(); + if (this.mainDocument.status !== 'CONVERTING') { + this.load.dismiss(); + } this.menu.enable(true, 'right-menu'); this.loadingImage = false; document.getElementsByClassName('drag-scroll-content')[0].scrollTop = 0; @@ -310,6 +309,11 @@ export class DocumentComponent implements OnInit, OnDestroy { }); } + ngOnDestroy(): void { + this.timerSubscription?.unsubscribe(); + this.subscription.unsubscribe(); + } + initDocumentInfos(params: any) { this.http.get('../rest/documents/' + params['id']).pipe( tap((data: any) => { @@ -391,6 +395,29 @@ export class DocumentComponent implements OnInit, OnDestroy { // this.renderPdf(); this.renderImage(); this.loadingdocument = false; + this.load.dismiss(); + + if (this.mainDocument.status === 'CONVERTING') { + // timer(0, 10000) call the function immediately and every 10 seconds + this.timerSubscription = timer(0, 10000).pipe( + tap(() => { + this.http.get('../rest/documents/' + params['id']).pipe( + tap((res: any) => { + this.totalPages = res.document.pages; + if (res.document.status !== 'CONVERTING') { + this.mainDocument.status = res.document.status; + this.timerSubscription?.unsubscribe(); + } + }) + ).subscribe(); + }), + catchError((err: any) => { + this.load.dismiss(); + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe(); + } }), catchError((err: any) => { console.log('error', err); @@ -769,4 +796,8 @@ export class DocumentComponent implements OnInit, OnDestroy { } } } + + isNotReady() { + return ['CONVERTING', 'ERROR'].indexOf(this.mainDocument.status) > -1; + } } diff --git a/src/frontend/app/indexation/indexation.component.ts b/src/frontend/app/indexation/indexation.component.ts index b9623e4795f80cae59591b3cb05dcab0e1683f5b..3273ee61fd0d942b82f4a7d2aa6d732b159e9001 100644 --- a/src/frontend/app/indexation/indexation.component.ts +++ b/src/frontend/app/indexation/indexation.component.ts @@ -301,35 +301,46 @@ export class IndexationComponent implements OnInit { } uploadTrigger(fileInput: any) { - if (fileInput.target.files && fileInput.target.files[0] && this.isExtensionAllowed(fileInput.target.files)) { - for (let index = 0; index < fileInput.target.files.length; index++) { - const filename = fileInput.target.files[index].name; - const file = { - title: filename.substr(0, filename.lastIndexOf('.')), - reference: filename.substr(0, filename.lastIndexOf('.')).substr(0, 53), - mainDocument: true, - content: '' - }; - const reader = new FileReader(); - reader.readAsArrayBuffer(fileInput.target.files[index]); - reader.onload = (value: any) => { - file.mainDocument = this.filesToUpload.length === 0; - file.reference = this.filesToUpload.length === 0 ? file.reference : ''; - file.content = this.getBase64Document(value.target.result); - this.filesToUpload.push(file); - if (this.filesToUpload.length === 1) { - setTimeout(() => { - this.menu.open('right-menu'); - }, 500); + this.loadingController.create({ + message: this.translate.instant('lang.loadingDocument'), + spinner: 'dots' + }).then(async (load: HTMLIonLoadingElement) => { + load.present(); + if (fileInput.target.files && fileInput.target.files[0] && this.isExtensionAllowed(fileInput.target.files)) { + for (let index = 0; index < fileInput.target.files.length; index++) { + const filename = fileInput.target.files[index].name; + const file = { + title: filename.substr(0, filename.lastIndexOf('.')), + reference: filename.substr(0, filename.lastIndexOf('.')).substr(0, 53), + mainDocument: true, + content: '' + }; + const reader = new FileReader(); + reader.readAsArrayBuffer(fileInput.target.files[index]); + reader.onload = (value: any) => { + file.mainDocument = this.filesToUpload.length === 0; + file.reference = this.filesToUpload.length === 0 ? file.reference : ''; + file.content = this.getBase64Document(value.target.result); + this.filesToUpload.push(file); + if (this.filesToUpload.length === 1) { + setTimeout(() => { + this.menu.open('right-menu'); + }, 500); + } + }; + if (index === fileInput.target.files.length - 1) { + load.dismiss(); } - }; + } + this.fileImport.nativeElement.value = ''; + } else { + this.loading = false; + load.dismiss(); } - this.fileImport.nativeElement.value = ''; - } else { - this.loading = false; - } + }); } + isExtensionAllowed(files: any[]) { for (let index = 0; index < files.length; index++) { if (files[index].name.toLowerCase().split('.').pop() !== 'pdf') {