diff --git a/lang/fr.json b/lang/fr.json index 3a8424aa276145ae09738cc8d94930a18c251c9e..172d2c6c36305c5111203b541a7e4eaa63940feb 100755 --- a/lang/fr.json +++ b/lang/fr.json @@ -473,6 +473,12 @@ "mailServerOffline": "Le serveur de messagerie est indisponible pour le moment, veuillez ré-essayer ultérieurement", "mailServerOfflineMsg": "Le serveur de messagerie doit être <b>testé</b> et <b>opérationnel</b> pour : <b>{{action}}</b>", "testAndValidate": "Tester et valider", - "receiveActivationNotification": "Recevoir le courriel d'activation" + "receiveActivationNotification": "Recevoir le courriel d'activation", + "newOtp": "Ajouter un OTP", + "otpUser": "Utilisateur OTP", + "notifyUserBy": "Notifier l'utilisateur par", + "phoneAlt": "Mobile", + "sms": "Sms", + "source": "Source" } } diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index 661f4cfa05324ca8431f8b51819aa8a7bcb6e505..011bd10f7a37278c15584a1b669cf8395648d735 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -53,13 +53,14 @@ import { MainDocumentDetailComponent } from './document/main-document-detail/mai import { AssociatedDocumentsComponent } from './document/associated-documents/associated-documents.component'; import { UpdatePasswordComponent } from './login/updatePassword/updatePassword.component'; import { PasswordModificationComponent } from './login/passwordModification/password-modification.component'; -import { VisaWorkflowModelsComponent } from './document/visa-workflow/models/visa-workflow-models.component'; import { SearchComponent } from './search/search.component'; import { SignaturePositionComponent } from './indexation/signature-position/signature-position.component'; import { DevToolComponent } from './service/debug/dev-tool.component'; import { DevLangComponent } from './service/debug/dev-lang.component'; import { DocumentDateListComponent } from './documentDateList/document-date-list.component'; import { DateOptionModalComponent } from './documentDateList/dateOption/date-option-modal.component'; +import { OtpCreateComponent } from './document/visa-workflow/otps/otp-create.component'; +import { OtpYousignComponent } from './document/visa-workflow/otps/yousign/otp-yousign.component'; // ADMINISTRATION @@ -140,7 +141,6 @@ registerLocaleData(localeFr, 'fr-FR'); CheckConnectionComponent, CheckEmailConnectionComponent, IndexationComponent, - VisaWorkflowModelsComponent, SearchComponent, SignaturePositionComponent, DevToolComponent, @@ -148,7 +148,9 @@ registerLocaleData(localeFr, 'fr-FR'); SignatureMethodModalComponent, HistoryListComponent, DocumentDateListComponent, - DateOptionModalComponent + DateOptionModalComponent, + OtpCreateComponent, + OtpYousignComponent ], imports: [ FormsModule, diff --git a/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.html b/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.html deleted file mode 100644 index 43a4eac100611b873504242d01407b5b894c373b..0000000000000000000000000000000000000000 --- a/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.html +++ /dev/null @@ -1,17 +0,0 @@ -<ion-list lines="none"> - <ion-list-header> - <ion-label color="secondary">{{'lang.circuitModels' | translate}}</ion-label> - </ion-list-header> - <ion-item button *ngFor="let model of visaWorkflowModels" (click)="loadVisaWorkflow(model)"> - <ion-label>{{model.title}}</ion-label> - <ion-buttons slot="end"> - <ion-button fill="clear" slot="icon-only" shape="round" color="danger" (click)="$event.stopPropagation();removeModel(model)"> - <ion-icon slot="icon-only" name="trash-outline"></ion-icon> - </ion-button> - </ion-buttons> - </ion-item> - <ion-item button (click)="createModel()" [disabled]="currentWorkflow.length === 0"> - <ion-icon color="primary" slot="start" name="add-circle-outline"></ion-icon> - <ion-label color="primary">{{'lang.newTemplate' | translate}}</ion-label> - </ion-item> -</ion-list> \ No newline at end of file diff --git a/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.scss b/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.scss deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.ts b/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.ts deleted file mode 100644 index 991ec474d654e408bb360ea8b265c671f69c3f2e..0000000000000000000000000000000000000000 --- a/src/frontend/app/document/visa-workflow/models/visa-workflow-models.component.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { AlertController, PopoverController } from '@ionic/angular'; -import { NotificationService } from '../../../service/notification.service'; -import { catchError, tap } from 'rxjs/operators'; -import { of } from 'rxjs'; -import { AuthService } from '../../../service/auth.service'; -import { TranslateService } from '@ngx-translate/core'; - -@Component({ - selector: 'app-visa-workflow-models', - templateUrl: 'visa-workflow-models.component.html', - styleUrls: ['visa-workflow-models.component.scss'], -}) -export class VisaWorkflowModelsComponent implements OnInit { - - @Input() currentWorkflow: any[] = []; - - visaWorkflowModels: any[] = []; - - constructor( - public http: HttpClient, - private translate: TranslateService, - public popoverController: PopoverController, - public alertController: AlertController, - public notificationService: NotificationService, - public authService: AuthService - ) { } - - ngOnInit(): void { - this.getVisaUserModels(); - } - - async createModel() { - const alert = await this.alertController.create({ - header: this.translate.instant('lang.newTemplate'), - message: this.translate.instant('lang.newTemplateDesc'), - inputs: [ - { - name: 'title', - type: 'text', - placeholder: this.translate.instant('lang.label') + ' *', - }, - ], - buttons: [ - { - text: this.translate.instant('lang.cancel'), - role: 'cancel', - handler: () => { } - }, { - text: this.translate.instant('lang.validate'), - handler: (data: any) => { - if (data.title !== '') { - this.saveModel(data.title); - return true; - } else { - this.notificationService.error(this.translate.instant('lang.label') + ' ' + this.translate.instant('lang.mandatory')); - return false; - } - } - } - ] - }); - - await alert.present(); - } - - saveModel(title: string) { - const objToSend: any = { - title: title, - items: this.currentWorkflow.map((item: any) => ({ - userId: item.userId, - mode: this.authService.getWorkflowMode(item.role), - signatureMode: this.authService.getSignatureMode(item.role) - })) - }; - this.http.post('../rest/workflowTemplates', objToSend).pipe( - tap((res: any) => { - this.notificationService.success('lang.modelCreated'); - this.visaWorkflowModels.push({ id: res.id, title: title }); - }), - catchError(err => { - this.notificationService.handleErrors(err); - return of(false); - }) - ).subscribe(); - } - - async removeModel(model: any) { - const alert = await this.alertController.create({ - header: this.translate.instant('lang.delete'), - message: this.translate.instant('lang.deleteTemplate'), - buttons: [ - { - text: this.translate.instant('lang.no'), - role: 'cancel', - handler: () => { } - }, { - text: this.translate.instant('lang.yes'), - handler: () => { - this.http.delete(`../rest/workflowTemplates/${model.id}`).pipe( - tap(() => { - this.visaWorkflowModels = this.visaWorkflowModels.filter((item: any) => item.id !== model.id); - this.notificationService.success(`Modèle ${model.title} supprimé`); - }), - catchError(err => { - this.notificationService.handleErrors(err); - return of(false); - }) - ).subscribe(); - } - } - ] - }); - - await alert.present(); - } - - getVisaUserModels() { - this.http.get('../rest/workflowTemplates').pipe( - tap((data: any) => { - this.visaWorkflowModels = data.workflowTemplates; - }), - catchError(err => { - this.notificationService.handleErrors(err); - return of(false); - }) - ).subscribe(); - } - - loadVisaWorkflow(model: any) { - this.http.get(`../rest/workflowTemplates/${model.id}`).pipe( - tap((data: any) => { - const workflows: any[] = data.workflowTemplate.items.map((item: any) => { - const obj: any = { - 'userId': item.userId, - 'userDisplay': item.userLabel, - 'role': item.mode === 'visa' ? 'visa' : item.signatureMode, - 'processDate': null, - 'current': false, - 'modes': ['visa'].concat(item.userSignatureModes) - }; - return obj; - }); - this.popoverController.dismiss(workflows); - }), - catchError(err => { - this.notificationService.handleErrors(err); - return of(false); - }) - ).subscribe(); - } -} diff --git a/src/frontend/app/document/visa-workflow/otps/otp-create.component.html b/src/frontend/app/document/visa-workflow/otps/otp-create.component.html new file mode 100644 index 0000000000000000000000000000000000000000..66d8c5cf5afc403e1a9ad987a635701fd2b02a5f --- /dev/null +++ b/src/frontend/app/document/visa-workflow/otps/otp-create.component.html @@ -0,0 +1,31 @@ +<ion-header [translucent]="true"> + <ion-toolbar color="primary"> + <ion-title>{{'lang.otpUser' | translate}}</ion-title> + <ion-buttons slot="end"> + <ion-button (click)="dismissModal()"> + <ion-icon slot="icon-only" name="close-outline"></ion-icon> + </ion-button> + </ion-buttons> + </ion-toolbar> +</ion-header> +<ion-content> + <ion-card> + <ion-item> + <ion-label color="secondary">{{'lang.source' | translate}}</ion-label> + <ion-select [value]="currentSource.id" cancelText="{{'lang.cancel' | translate}}"> + <ion-select-option *ngFor="let source of sources" [value]="source.id"> + {{source.label | translate}}</ion-select-option> + </ion-select> + </ion-item> + </ion-card> + <app-otp-yousign #appOtpYousign *ngIf="currentSource.type === 'yousign'"></app-otp-yousign> +</ion-content> +<ion-footer class="ion-no-border"> + <ion-toolbar> + <ion-buttons class="ion-justify-content-center"> + <ion-button type="submit" color="primary" (click)="onSubmit()" [disabled]="!isValid()"> + <ion-label>{{'lang.save' | translate}}</ion-label> + </ion-button> + </ion-buttons> + </ion-toolbar> +</ion-footer> \ No newline at end of file diff --git a/src/frontend/app/document/visa-workflow/otps/otp-create.component.scss b/src/frontend/app/document/visa-workflow/otps/otp-create.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..b6dd7ffb77756d3f8efc0b8dc80a2791f1c9ea5d --- /dev/null +++ b/src/frontend/app/document/visa-workflow/otps/otp-create.component.scss @@ -0,0 +1,3 @@ +.my-custom-class { + --min-width: 400px; + } \ No newline at end of file diff --git a/src/frontend/app/document/visa-workflow/otps/otp-create.component.ts b/src/frontend/app/document/visa-workflow/otps/otp-create.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..a6c96a48967d9cd09a5df6a5dda35bb24c92a8a7 --- /dev/null +++ b/src/frontend/app/document/visa-workflow/otps/otp-create.component.ts @@ -0,0 +1,66 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { NotificationService } from '../../../service/notification.service'; +import { AuthService } from '../../../service/auth.service'; +import { TranslateService } from '@ngx-translate/core'; +import { ModalController } from '@ionic/angular'; +import { OtpYousignComponent } from './yousign/otp-yousign.component'; + +@Component({ + selector: 'app-otp-create', + templateUrl: 'otp-create.component.html', + styleUrls: ['otp-create.component.scss'], +}) +export class OtpCreateComponent implements OnInit { + + @ViewChild('appOtpYousign', { static: false }) appOtpYousign: OtpYousignComponent; + + sources: any[] = []; + + currentSource: any = null; + + constructor( + public http: HttpClient, + private translate: TranslateService, + public notificationService: NotificationService, + public authService: AuthService, + public modalController: ModalController + ) { } + + ngOnInit(): void { + this.getConfig(); + } + + getConfig() { + // FOR TEST + this.sources = [ + { + id: 1, + label: 'yousign', + type: 'yousign' + } + ]; + this.currentSource = this.sources[0]; + /* this.http.get(`../rest/???`).pipe( + tap((data: any) => { + + }), + catchError(err => { + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe();*/ + } + + onSubmit() { + this.modalController.dismiss(this.appOtpYousign.getData()); + } + + dismissModal() { + this.modalController.dismiss('cancel'); + } + + isValid() { + return this.appOtpYousign?.isValid(); + } +} diff --git a/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.html b/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.html new file mode 100644 index 0000000000000000000000000000000000000000..8d37833affd6f940051d86b4d0923aa29d29a15e --- /dev/null +++ b/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.html @@ -0,0 +1,57 @@ +<form style="display: contents;" #otpForm="ngForm"> + <ion-list lines="full" class="ion-no-margin"> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.firstname' | translate}} *</ion-label> + <ion-input name="firstname" [maxlength]="128" [(ngModel)]="otp.firstname" placeholder="Alain" required> + </ion-input> + </ion-item> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.lastname' | translate}} *</ion-label> + <ion-input name="lastname" [maxlength]="128" [(ngModel)]="otp.lastname" placeholder="Dupont" required> + </ion-input> + </ion-item> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.phoneAlt' | translate}} <ng-container + *ngIf="otp.mode === 'sms'">*</ng-container> + </ion-label> + <ion-input name="phone" pattern="^\+?[1-9]\d{1,14}$" [(ngModel)]="otp.phone" placeholder="+33646342143" + [required]="otp.mode === 'sms'"></ion-input> + </ion-item> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.email' | translate}} <ng-container + *ngIf="otp.mode === 'email'">*</ng-container> + </ion-label> + <ion-input name="email" pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" + placeholder="alain.dupont@gmail.com" [(ngModel)]="otp.email" [required]="otp.mode === 'email'"> + </ion-input> + </ion-item> + </ion-list> + <ion-list> + <ion-radio-group [(ngModel)]="otp.role" [value]="otp.role"> + <ion-list-header> + <ion-label color="secondary">{{'lang.role' | translate}}</ion-label> + </ion-list-header> + <div style="display:flex;"> + <ion-item *ngFor="let role of roles" style="flex:1;"> + <ion-label>{{'lang.' + role | translate}}</ion-label> + <ion-radio slot="start" [value]="role"></ion-radio> + </ion-item> + </div> + </ion-radio-group> + <!--<ion-label color="secondary" position="floating">{{'lang.role' | translate}}</ion-label> + <ion-select name="mode" [(ngModel)]="otp.role" [value]="otp.role" cancelText="{{'lang.cancel' | translate}}"> + <ion-select-option *ngFor="let role of roles" [value]="role"> + {{'lang.' + role | translate}}</ion-select-option> + </ion-select>--> + </ion-list> + <ion-list> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.notifyUserBy' | translate}}</ion-label> + <ion-select name="mode" [(ngModel)]="otp.notify" [value]="otp.notify" + cancelText="{{'lang.cancel' | translate}}" [disabled]="notificationModes.length === 1"> + <ion-select-option *ngFor="let mode of notificationModes" [value]="mode"> + {{'lang.' + mode | translate}}</ion-select-option> + </ion-select> + </ion-item> + </ion-list> +</form> \ No newline at end of file diff --git a/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.scss b/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..3c297bb5fad493de5144d0b0141601b065ee74f0 --- /dev/null +++ b/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.scss @@ -0,0 +1,9 @@ +.item-interactive-disabled.sc-ion-label-md-h:not(.item-multiple-inputs), .item-interactive-disabled:not(.item-multiple-inputs) .sc-ion-label-md-h { + opacity: initial !important; +} + +.error { + font-size: 10px; + padding: 5px; + color: var(--ion-color-danger); +} \ No newline at end of file diff --git a/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.ts b/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..48f33845f23e23cc8bd77fbe78eeeca79d7307cd --- /dev/null +++ b/src/frontend/app/document/visa-workflow/otps/yousign/otp-yousign.component.ts @@ -0,0 +1,66 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { NotificationService } from '../../../../service/notification.service'; +import { TranslateService } from '@ngx-translate/core'; +import { NgForm } from '@angular/forms'; + +@Component({ + selector: 'app-otp-yousign', + templateUrl: 'otp-yousign.component.html', + styleUrls: ['otp-yousign.component.scss'], +}) +export class OtpYousignComponent implements OnInit { + @ViewChild('otpForm', { static: false }) otpForm: NgForm; + + notificationModes: any[] = []; + + roles: any[] = [ + 'otp_visa_yousign', + 'otp_sign_yousign' + ]; + + otp: any = { + firstname: '', + lastname: '', + email: '', + phone: '', + notify: 'sms', + role: 'otp_sign_yousign' + }; + + constructor( + public http: HttpClient, + private translate: TranslateService, + public notificationService: NotificationService, + ) { } + + ngOnInit(): void { + this.getConfig(); + } + + getConfig() { + // FOR TEST + this.notificationModes = [ + 'sms', + 'email' + ]; + this.otp.mode = this.notificationModes[0]; + /* this.http.get(`../rest/???`).pipe( + tap((data: any) => { + + }), + catchError(err => { + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe();*/ + } + + getData() { + return this.otp; + } + + isValid() { + return this.otpForm.valid; + } +} diff --git a/src/frontend/app/document/visa-workflow/visa-workflow.component.html b/src/frontend/app/document/visa-workflow/visa-workflow.component.html index 7865a96ae57ea65c58177da8e0b543da78efe20b..b3f01cf772cdfaee3b13b0b42b3ac386055838c4 100644 --- a/src/frontend/app/document/visa-workflow/visa-workflow.component.html +++ b/src/frontend/app/document/visa-workflow/visa-workflow.component.html @@ -14,11 +14,33 @@ <ion-searchbar #searchInput [(ngModel)]="visaUsersSearchVal" [placeholder]="'lang.searchUser' | translate" (ionChange)="getVisaUsers($event)" (ionFocus)="visaUsersSearchVal=''"></ion-searchbar> <ion-buttons slot="end"> - <ion-button fill="clear" slot="icon-only" shape="round" color="primary" - (click)="openVisaWorkflowModels($event)" [title]="'lang.circuitModels' | translate"> + <ion-button fill="clear" slot="icon-only" shape="round" color="primary" [matMenuTriggerFor]="menu" + [title]="'lang.circuitModels' | translate"> <ion-icon slot="icon-only" name="albums-outline"></ion-icon> </ion-button> </ion-buttons> + <mat-menu #menu="matMenu"> + <ion-item button (click)="openOtpModal()" lines="none"> + <ion-icon name="person-circle-outline" slot="start" color="primary"></ion-icon> + <ion-label>{{'lang.newOtp' | translate}}</ion-label> + </ion-item> + <button mat-menu-item [matMenuTriggerFor]="model" + (menuOpened)="getVisaUserModels()">{{'lang.circuitModels' | translate}}</button> + </mat-menu> + <mat-menu #model="matMenu"> + <ion-item button lines="none" *ngFor="let model of visaWorkflowModels" (click)="loadVisaWorkflow(model)"> + <ion-label>{{model.title}}</ion-label> + <ion-buttons slot="end"> + <ion-button fill="clear" slot="icon-only" shape="round" color="danger" + (click)="$event.stopPropagation();removeModel(model)"> + <ion-icon slot="icon-only" name="trash-outline"></ion-icon> + </ion-button> + </ion-buttons> + </ion-item> + <ion-item button (click)="createModel()" [disabled]="visaWorkflow.length === 0"> + <ion-label>{{'lang.newTemplate' | translate}}</ion-label> + </ion-item> + </mat-menu> </ion-item> <ion-list *ngIf="visaUsersList.length > 0" style="position: absolute;z-index: 2;width: 100%;box-shadow: 0 4px 2px -2px gray;"> @@ -41,8 +63,7 @@ <ion-reorder slot="start"> <ion-icon [title]="'lang.reorder' | translate" name="reorder-three" style="font-size: 30px;"></ion-icon> </ion-reorder> - <ion-avatar slot="start" class="avatar-user" style="cursor: grab;" - (click)="$event.stopPropagation();"> + <ion-avatar slot="start" class="avatar-user" style="cursor: grab;" (click)="$event.stopPropagation();"> <img [src]="diffusion.userPicture"> </ion-avatar> <ion-label> @@ -56,7 +77,8 @@ interface="popover" [interfaceOptions]="customPopoverOptions" [style.color]="getRole(diffusion.role)?.color" [disabled]="!editMode" style="width: auto;max-width: 100%;padding-left:0px;"> - <ion-select-option [value]="mode" *ngFor="let mode of diffusion.modes" [disabled]="!isValidRole(i,mode, diffusion.role)"> + <ion-select-option [value]="mode" *ngFor="let mode of diffusion.modes" + [disabled]="!isValidRole(i,mode, diffusion.role)"> {{'lang.' + mode + 'User' | translate}} </ion-select-option> </ion-select> diff --git a/src/frontend/app/document/visa-workflow/visa-workflow.component.ts b/src/frontend/app/document/visa-workflow/visa-workflow.component.ts index 04181496b66beb7f6ca3df9b494628d17e68a57a..a99c7ec7d41a8bd44eb5d97598711b85c3c92bdf 100644 --- a/src/frontend/app/document/visa-workflow/visa-workflow.component.ts +++ b/src/frontend/app/document/visa-workflow/visa-workflow.component.ts @@ -5,9 +5,10 @@ import { AuthService } from '../../service/auth.service'; import { catchError, tap } from 'rxjs/operators'; import { of } from 'rxjs'; import { NotificationService } from '../../service/notification.service'; -import { IonReorderGroup, PopoverController } from '@ionic/angular'; -import { VisaWorkflowModelsComponent } from './models/visa-workflow-models.component'; +import { AlertController, IonReorderGroup, ModalController, PopoverController } from '@ionic/angular'; import { ItemReorderEventDetail } from '@ionic/core'; +import { TranslateService } from '@ngx-translate/core'; +import { OtpCreateComponent } from './otps/otp-create.component'; @Component({ selector: 'app-visa-workflow', @@ -29,13 +30,16 @@ export class VisaWorkflowComponent implements OnInit { header: 'Roles' }; roles: any[] = []; + visaWorkflowModels: any[] = []; constructor( public http: HttpClient, + private translate: TranslateService, + public alertController: AlertController, public signaturesService: SignaturesContentService, public authService: AuthService, public notificationService: NotificationService, - public popoverController: PopoverController + public modalController: ModalController, ) { } ngOnInit(): void { @@ -143,21 +147,26 @@ export class VisaWorkflowComponent implements OnInit { this.visaUsersList = []; } - async openVisaWorkflowModels(ev: any) { - const popover = await this.popoverController.create({ - component: VisaWorkflowModelsComponent, - componentProps: { currentWorkflow: this.visaWorkflow }, - event: ev, + async openOtpModal(ev: any) { + const modal = await this.modalController.create({ + cssClass: 'my-custom-class', + component: OtpCreateComponent, + backdropDismiss: false, }); - await popover.present(); + await modal.present(); - popover.onDidDismiss() + modal.onDidDismiss() .then((result: any) => { - if (result.role !== 'backdrop') { - this.visaWorkflow = this.visaWorkflow.concat(result.data); - this.visaWorkflow.forEach((element: any, index: number) => { - this.getAvatarUser(index); - }); + if (typeof result.data === 'object') { + const obj: any = { + 'userId': null, + 'userDisplay': `${result.data.firstname} ${result.data.lastname}`, + 'role': result.data.role, + 'processDate': null, + 'current': false, + 'modes': [result.data.role] + }; + this.visaWorkflow.push(obj); } }); } @@ -188,4 +197,127 @@ export class VisaWorkflowComponent implements OnInit { return true; } } + + async createModel() { + const alert = await this.alertController.create({ + header: this.translate.instant('lang.newTemplate'), + message: this.translate.instant('lang.newTemplateDesc'), + inputs: [ + { + name: 'title', + type: 'text', + placeholder: this.translate.instant('lang.label') + ' *', + }, + ], + buttons: [ + { + text: this.translate.instant('lang.cancel'), + role: 'cancel', + handler: () => { } + }, { + text: this.translate.instant('lang.validate'), + handler: (data: any) => { + if (data.title !== '') { + this.saveModel(data.title); + return true; + } else { + this.notificationService.error(this.translate.instant('lang.label') + ' ' + this.translate.instant('lang.mandatory')); + return false; + } + } + } + ] + }); + + await alert.present(); + } + + saveModel(title: string) { + const objToSend: any = { + title: title, + items: this.visaWorkflow.map((item: any) => ({ + userId: item.userId, + mode: this.authService.getWorkflowMode(item.role), + signatureMode: this.authService.getSignatureMode(item.role) + })) + }; + this.http.post('../rest/workflowTemplates', objToSend).pipe( + tap((res: any) => { + this.notificationService.success('lang.modelCreated'); + this.visaWorkflowModels.push({ id: res.id, title: title }); + }), + catchError(err => { + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + async removeModel(model: any) { + const alert = await this.alertController.create({ + header: this.translate.instant('lang.delete'), + message: this.translate.instant('lang.deleteTemplate'), + buttons: [ + { + text: this.translate.instant('lang.no'), + role: 'cancel', + handler: () => { } + }, { + text: this.translate.instant('lang.yes'), + handler: () => { + this.http.delete(`../rest/workflowTemplates/${model.id}`).pipe( + tap(() => { + this.visaWorkflowModels = this.visaWorkflowModels.filter((item: any) => item.id !== model.id); + this.notificationService.success(`Modèle ${model.title} supprimé`); + }), + catchError(err => { + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + } + ] + }); + + await alert.present(); + } + + loadVisaWorkflow(model: any) { + this.http.get(`../rest/workflowTemplates/${model.id}`).pipe( + tap((data: any) => { + const workflows: any[] = data.workflowTemplate.items.map((item: any) => { + const obj: any = { + 'userId': item.userId, + 'userDisplay': item.userLabel, + 'role': item.mode === 'visa' ? 'visa' : item.signatureMode, + 'processDate': null, + 'current': false, + 'modes': ['visa'].concat(item.userSignatureModes) + }; + return obj; + }); + this.visaWorkflow = this.visaWorkflow.concat(workflows); + this.visaWorkflow.forEach((element: any, index: number) => { + this.getAvatarUser(index); + }); + }), + catchError(err => { + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + getVisaUserModels() { + this.http.get('../rest/workflowTemplates').pipe( + tap((data: any) => { + this.visaWorkflowModels = data.workflowTemplates; + }), + catchError(err => { + this.notificationService.handleErrors(err); + return of(false); + }) + ).subscribe(); + } }