Commit 8633f904 authored by Hamza HRAMCHI's avatar Hamza HRAMCHI
Browse files

FEAT #16956 TIME 6 create an OTP user in external visa workflow modal action

parent 52997ddd
......@@ -1202,4 +1202,22 @@ export class ActionsService implements OnDestroy {
})
).subscribe();
}
getUserOtpIcon(id: string): Promise<string> {
return new Promise((resolve) => {
this.http.get(`assets/${id}.png`, { responseType: 'blob' }).pipe(
tap((response: any) => {
const reader = new FileReader();
reader.readAsDataURL(response);
reader.onloadend = () => {
resolve(reader.result as any);
};
}),
catchError(err => {
this.notify.handleErrors(err);
return of(false);
})
).subscribe();
});
}
}
......@@ -138,6 +138,7 @@ import { SignatureBookComponent } from './signature-book.component';
import { VisaWorkflowModalComponent } from './visa/modal/visa-workflow-modal.component';
import { ExternalVisaWorkflowComponent } from './visa/externalVisaWorkflow/external-visa-workflow.component';
import { ProfileContactsGroupsComponent } from './profile/contacts-groups/profile-contacts-groups.component';
import { CreateUserOtpComponent } from './visa/externalVisaWorkflow/createUserOtp/create-user-otp.component';
import { EditorOptionComponent } from './profile/parameters/editorOption/editor-option.component';
import { BasketColorComponent } from './profile/parameters/basketsColor/basket-color.component';
......@@ -293,7 +294,8 @@ export class MyHammerConfig extends HammerGestureConfig {
MySignatureBookComponent,
ProfileHistoryComponent,
ProfileOtherPluginComponent,
AddinOutlookConfigurationModalComponent
AddinOutlookConfigurationModalComponent,
CreateUserOtpComponent
],
exports : [
SharedModule
......
<div class="mat-dialog-content-container">
<h1 mat-dialog-title>{{'lang.addOtpUser' | translate}}</h1>
<div mat-dialog-content>
<div *ngIf="loading" class="loading" style="display:flex;height:100%;">
<mat-spinner style="margin:auto;"></mat-spinner>
</div>
<div *ngIf="!loading" class="userForm">
<mat-form-field>
<mat-label>{{'lang.firstname' | translate}}</mat-label>
<input matInput #firstname type="text" [(ngModel)]="userOTP.firstname" required>
</mat-form-field>
<mat-form-field>
<mat-label>{{'lang.lastname' | translate}}</mat-label>
<input matInput #lastname type="text" [(ngModel)]="userOTP.lastname" required>
</mat-form-field>
<mat-form-field>
<mat-label>{{'lang.phoneNumber' | translate}}</mat-label>
<input matInput #phoneNumber type="text" [(ngModel)]="userOTP.phone" required>
<mat-hint align="start">{{ 'lang.frFormatPhone' | translate }}</mat-hint>
</mat-form-field>
<mat-form-field>
<mat-label>{{'lang.email' | translate}}</mat-label>
<input matInput #email type="email" [(ngModel)]="userOTP.email" required>
</mat-form-field>
<mat-form-field>
<mat-label>{{'lang.role' | translate}}</mat-label>
<mat-select #role [(ngModel)]="userOTP.role" required>
<mat-option *ngFor="let role of sampleRoles" [value]="role.id" >
{{ role.label }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'lang.securityMode' | translate }}</mat-label>
<mat-select #securityMode [(ngModel)]="userOTP.mode" required>
<mat-option *ngFor="let mode of securityModes" [value]="mode.id" >
{{ mode.label }}
</mat-option>
</mat-select>
</mat-form-field>
<span class="divider-modal"></span>
<app-maarch-message *ngIf="userOTP.mode" [mode]="'info'" [content]="'lang.securityModeInfo' | translate : {mode: userOTP.mode}"></app-maarch-message>
</div>
</div>
<span class="divider-modal"></span>
<div mat-dialog-actions class="actions">
<button mat-raised-button mat-button color="primary" [disabled]="loading || !isValidForm()" (click)="addOtpUser()">{{'lang.validate' | translate}}</button>
<button mat-raised-button mat-button [mat-dialog-close]="">{{'lang.cancel' | translate}}</button>
</div>
</div>
.loading {
display: flex;
height: 100%;
}
.userForm {
display: flex;
height: 100%;
flex-direction:column
}
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { NotificationService } from '@service/notification/notification.service';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { FunctionsService } from '@service/functions.service';
import { tap, catchError } from 'rxjs/operators';
import { FormControl } from '@angular/forms';
import { ScanPipe } from 'ngx-pipes';
import { Observable, of } from 'rxjs';
import { MatDialogRef } from '@angular/material/dialog';
@Component({
templateUrl: 'create-user-otp.component.html',
styleUrls: ['create-user-otp.component.scss'],
})
export class CreateUserOtpComponent implements OnInit {
// For TEST
sampleRoles: any[] = [
{
id: 'visa',
label: this.translate.instant('lang.visa')
},
{
id: 'stamp',
label: this.translate.instant('lang.stamp')
}
];
securityModes: any[] = [
{
id: 'sms',
label: this.translate.instant('lang.sms')
},
{
id: 'email',
label: this.translate.instant('lang.email')
}
];
userOTP: any = {
type: 'yousign',
firstname: '',
lastname: '',
email: '',
phone: '',
role: '',
mode: ''
};
constructor(
public translate: TranslateService,
public http: HttpClient,
public functions: FunctionsService,
private dialogRef: MatDialogRef<CreateUserOtpComponent>
) { }
ngOnInit(): void {}
addOtpUser() {
this.dialogRef.close({otp: this.userOTP});
}
isValidForm() {
return Object.values(this.userOTP).every(item => (item !== '')) && this.validFormat();
}
validFormat() {
const phoneRegex = /^((\+)33)[1-9](\d{2}){4}$/g;
const emailReegex = /\S+@\S+\.\S+/;
return (this.userOTP.phone.length > 1 && this.userOTP.phone.trim().match(phoneRegex) !== null) && (this.userOTP.email.length > 1 && this.userOTP.email.trim().match(emailReegex) !== null);
}
}
<mat-list *ngIf="!loading">
<button *ngIf="adminMode" mat-raised-button mat-button color="primary" [title]="'lang.addOtpUser' | translate"
style="margin: 10px; display: flex;" (click)="openCreateUserOtp()">
<mat-icon class="fas fa-user-plus" style="width: auto;height: auto;"></mat-icon>
{{'lang.addOtpUser' | translate}}
</button>
<app-plugin-autocomplete *ngIf="adminMode" [labelPlaceholder]="'lang.addPerson' | translate"
[routeDatas]="['/rest/autocomplete/maarchParapheurUsers']" [targetSearchKey]="'idToDisplay'"
[subInfoKey]="'email'" (triggerEvent)="addItemToWorkflow($event)" appearance="outline">
......
......@@ -9,6 +9,8 @@ import { FormControl } from '@angular/forms';
import { ScanPipe } from 'ngx-pipes';
import { Observable, of } from 'rxjs';
import { MatDialog } from '@angular/material/dialog';
import { CreateUserOtpComponent } from './createUserOtp/create-user-otp.component';
import { ActionsService } from '@appRoot/actions/actions.service';
@Component({
selector: 'app-external-visa-workflow',
......@@ -49,7 +51,8 @@ export class ExternalVisaWorkflowComponent implements OnInit {
public http: HttpClient,
private notify: NotificationService,
public functions: FunctionsService,
public dialog: MatDialog
public dialog: MatDialog,
public actionService: ActionsService
) { }
ngOnInit(): void { }
......@@ -201,7 +204,11 @@ export class ExternalVisaWorkflowComponent implements OnInit {
}
checkExternalSignatoryBook() {
return this.visaWorkflow.items.filter((item: any) => this.functions.empty(item.externalId)).map((item: any) => item.labelToDisplay);
if (this.visaWorkflow.items.find((item: any) => item.hasOwnProperty('externalInformations'))) {
return true;
} else {
return this.visaWorkflow.items.filter((item: any) => this.functions.empty(item.externalId)).map((item: any) => item.labelToDisplay);
}
}
saveVisaWorkflow(resIds: number[] = [this.resId]) {
......@@ -333,4 +340,38 @@ export class ExternalVisaWorkflowComponent implements OnInit {
return true;
}
}
openCreateUserOtp() {
const dialogRef = this.dialog.open(CreateUserOtpComponent, {
panelClass: 'maarch-modal',
disableClose: true,
width: '500px',
});
dialogRef.afterClosed().pipe(
tap(async (data: any) => {
if (data.otp) {
const user = {
'id': null,
'processingUser': null,
'userId': null,
'labelToDisplay': `${data.otp.firstname} ${data.otp.lastname}`,
'requested_signature': true,
'process_date': null,
'picture': await this.actionService.getUserOtpIcon(data.otp.type),
'hasPrivilege': true,
'isValid': true,
'delegatedBy': null,
'role': data.otp.role,
'status': 'OK',
'externalId': {
maarchParapheur: null
},
'externalInformations': data.otp
};
this.visaWorkflow.items.push(user);
}
})
).subscribe();
}
}
......@@ -2505,5 +2505,10 @@
"clientId": "Client ID",
"clientSecret": "Client Secret",
"siteUrl": "Sharepoint Online site URL",
"office365sharepointDesc": "<a href=\"https://www.office.com/\" target=\"_blank\"> Office 365 </a> is the online office suite from Microsoft. The editing is done via Sharepoint Online."
"office365sharepointDesc": "<a href=\"https://www.office.com/\" target=\"_blank\"> Office 365 </a> is the online office suite from Microsoft. The editing is done via Sharepoint Online.",
"addOtpUser": "Add OTP user",
"securityMode": "Mode of sending the security code",
"sms": "SMS",
"securityModeInfo": "The user will be notified by <b> mail </b> and will receive a <b> security code </b> by <b> {{mode}} </b> at the time of his turn in the workflow.",
"frFormatPhone": "Format: +33XXXXXXXXX"
}
......@@ -2496,5 +2496,10 @@
"clientId": "Client ID",
"clientSecret": "Client Secret",
"siteUrl": "URL de l'espace Sharepoint Online",
"office365sharepointDesc": "<a href=\"https://www.office.com/\" target=\"_blank\"> Office 365 </a> est la suite bureautique en ligne de Microsoft. L'édtion se fait via Sharepoint Online."
"office365sharepointDesc": "<a href=\"https://www.office.com/\" target=\"_blank\"> Office 365 </a> est la suite bureautique en ligne de Microsoft. L'édtion se fait via Sharepoint Online.",
"addOtpUser": "Ajouter un utilisateur OTP",
"securityMode": "Mode d'envoi du code de sécurité",
"sms": "SMS",
"securityModeInfo": "L'utilisateur sera notifié par <b>mail</b> et recevra un <b>code de sécurité</b> par <b>{{mode}}</b> au moment de son tour dans le circuit.",
"frFormatPhone": "Format: +33XXXXXXXXX"
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment