diff --git a/src/frontend/app/administration/administration.module.ts b/src/frontend/app/administration/administration.module.ts index 5c21f8e1dbca662e51398e693a3944eb0411c4cd..e33cedfb06b56cbac47ff2bc42cc05a9bbe5c31d 100755 --- a/src/frontend/app/administration/administration.module.ts +++ b/src/frontend/app/administration/administration.module.ts @@ -10,6 +10,7 @@ import { AdministrationRoutingModule } from './administration-routing.m import { AdministrationComponent } from './administration.component'; import { UsersAdministrationComponent, UsersAdministrationRedirectModalComponent } from './user/users-administration.component'; +import { AccountLinkComponent } from './user/account-link/account-link.component'; import { GroupsAdministrationComponent, GroupsAdministrationRedirectModalComponent } from './group/groups-administration.component'; import { UserAdministrationComponent, UserAdministrationRedirectModalComponent } from './user/user-administration.component'; import { GroupAdministrationComponent } from './group/group-administration.component'; @@ -103,7 +104,8 @@ import { ShippingAdministrationComponent } from './shipping/shippin ListAdministrationComponent, TemplateAdministrationCheckEntitiesModalComponent, ShippingsAdministrationComponent, - ShippingAdministrationComponent + ShippingAdministrationComponent, + AccountLinkComponent ], entryComponents: [ UsersAdministrationRedirectModalComponent, @@ -116,7 +118,8 @@ import { ShippingAdministrationComponent } from './shipping/shippin TechnicalAdministrationComponent, ListAdministrationComponent, ListAdministrationComponent, - TemplateAdministrationCheckEntitiesModalComponent + TemplateAdministrationCheckEntitiesModalComponent, + AccountLinkComponent ], }) export class AdministrationModule {} \ No newline at end of file diff --git a/src/frontend/app/administration/user/account-link/account-link.component.html b/src/frontend/app/administration/user/account-link/account-link.component.html new file mode 100644 index 0000000000000000000000000000000000000000..3f5a61d2d01c6f0bf34428dd6d057d2d0b72421f --- /dev/null +++ b/src/frontend/app/administration/user/account-link/account-link.component.html @@ -0,0 +1,31 @@ +<h1 mat-dialog-title>{{lang.linkAccount}}</h1> +<mat-dialog-content class="modal-container"> + <mat-form-field appearance="outline" floatLabel="never" [style.fontSize.px]="10"> + <input id="availableUsers" type="text" matInput placeholder="{{lang.searchUserInMaarchParapheur}}" + [matAutocomplete]="auto" [formControl]="userCtrl"> + <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selectUser($event)" isOpen="true"> + <mat-option *ngFor="let user of filteredUsers | async" [value]="user"> + {{user.idToDisplay}} + </mat-option> + </mat-autocomplete> + </mat-form-field> + <mat-list *ngIf="externalUser.inMaarchParapheur"> + <mat-list-item > + <mat-icon class="avatarAccount" color="primary" mat-list-icon + [style.background-image]="'url('+externalUser.picture+')'"></mat-icon> + <h4 mat-line>{{externalUser.firstname}} {{externalUser.lastname}}</h4> + <p mat-line style="color:#666">{{externalUser.email}}</p> + <button mat-icon-button color="warn" [title]="lang.unlinkAccount" (click)="unlinkMaarchParapheurAccount()"> + <mat-icon class="fas fa-unlink"></mat-icon> + </button> + </mat-list-item> + </mat-list> + <mat-form-field *ngIf="!externalUser.inMaarchParapheur"> + <input type="text" matInput placeholder="{{lang.newLoginInMaarchParapheur}}" [(ngModel)]="externalUser.login"> + </mat-form-field> + <div *ngIf="!externalUser.inMaarchParapheur" class="alert-message alert-message-danger" role="alert" style="margin-top: 30px;" [innerHTML]="lang.maarchParapheurAccountMsg + ' <b>' + externalUser.login + '</b> ' + lang.maarchParapheurAccountMsg2"></div> +</mat-dialog-content> +<mat-dialog-actions> + <button color="primary" mat-raised-button (click)="this.dialogRef.close(externalUser);">{{lang.validate}}</button> + <button mat-raised-button (click)="this.dialogRef.close('');">{{lang.cancel}}</button> +</mat-dialog-actions> \ No newline at end of file diff --git a/src/frontend/app/administration/user/account-link/account-link.component.scss b/src/frontend/app/administration/user/account-link/account-link.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..f8b37d5023b443875931c6410075e5228bb8978d --- /dev/null +++ b/src/frontend/app/administration/user/account-link/account-link.component.scss @@ -0,0 +1,21 @@ +@import '../../../../css/vars.scss'; + +.mat-dialog-title { + padding: 10px; +} +.avatarAccount { + border: solid 3px #F99830; + height: 45px !important; + width: 45px !important; + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.modal-container{ + height: auto; +} + +.modal-body{ + min-height: auto; +} diff --git a/src/frontend/app/administration/user/account-link/account-link.component.ts b/src/frontend/app/administration/user/account-link/account-link.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b4befe9831ef70d14aa2ab6cf0c8c6cc80ab944 --- /dev/null +++ b/src/frontend/app/administration/user/account-link/account-link.component.ts @@ -0,0 +1,72 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { LANG } from '../../../translate.component'; +import { AutoCompletePlugin } from '../../../../plugins/autocomplete.plugin'; +import { HttpClient } from '@angular/common/http'; +import { NotificationService } from '../../../notification.service'; + +declare function $j(selector: any): any; + +@Component({ + templateUrl: 'account-link.component.html', + styleUrls: ['account-link.component.scss'], + providers: [NotificationService] +}) +export class AccountLinkComponent extends AutoCompletePlugin { + lang: any = LANG; + externalUser: any = { + inMaarchParapheur: false, + login: '', + firstname: '', + lastname: '', + email: '', + picture: '' + }; + + constructor(public http: HttpClient, @Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: MatDialogRef<AccountLinkComponent>, private notify: NotificationService) { + super(http, ['signatureBookUsersNotLinked']); + } + + ngOnInit(): void { + this.http.get(this.coreUrl + 'rest/autocomplete/maarchParapheurUsers', { params: { "search": this.data.user.lastname, "exludeAlreadyConnected": 'true' } }) + .subscribe((dataUsers: any) => { + if ( dataUsers.length > 0) { + this.externalUser = dataUsers[0]; + this.externalUser.inMaarchParapheur = true; + this.http.get("../../rest/maarchParapheur/user/" + this.externalUser.id + "/picture") + .subscribe((data: any) => { + this.externalUser.picture = data.picture; + }, (err) => { + this.notify.handleErrors(err); + }); + } else { + this.externalUser.inMaarchParapheur = false; + this.externalUser = this.data.user; + this.externalUser.login = this.data.user.user_id; + this.externalUser.email = this.data.user.mail; + } + }, (err: any) => { + this.notify.handleErrors(err); + }); + + } + + selectUser(event: any) { + $j('#availableUsers').blur(); + this.userCtrl.setValue(''); + this.externalUser = event.option.value; + this.externalUser.inMaarchParapheur = true; + this.http.get("../../rest/maarchParapheur/user/" + this.externalUser.id + "/picture") + .subscribe((data: any) => { + this.externalUser.picture = data.picture; + }, (err) => { + this.notify.handleErrors(err); + }); + } + + unlinkMaarchParapheurAccount() { + this.externalUser.inMaarchParapheur = false; + this.externalUser = this.data.user; + this.externalUser.email = this.data.user.mail; + } +} diff --git a/src/frontend/app/administration/user/user-administration.component.css b/src/frontend/app/administration/user/user-administration.component.css deleted file mode 100755 index d648c4f452adf4efb251dbb056a4f08af7b359cb..0000000000000000000000000000000000000000 --- a/src/frontend/app/administration/user/user-administration.component.css +++ /dev/null @@ -1,18 +0,0 @@ -.avatar { - text-decoration:none; - background:#135f7f; - color:white; - width:100px; - height:100px; - border-radius:5px; - display:block; - overflow:hidden; - margin: 5px; -} -.form-group{ - margin:0px; -} - -.vertical-divider{ - height: 80%; -} \ No newline at end of file diff --git a/src/frontend/app/administration/user/user-administration.component.html b/src/frontend/app/administration/user/user-administration.component.html index d7c684ab300f65639f0d6911a243f74224e77d4d..cdc1df34c4dc21d6aba4d1567c352fda7ddd54e6 100755 --- a/src/frontend/app/administration/user/user-administration.component.html +++ b/src/frontend/app/administration/user/user-administration.component.html @@ -30,22 +30,29 @@ {{lang.changePassword}} </p> </a> - <a mat-list-item *ngIf="user.canCreateMaarchParapheurUser" (click)="sendToMaarchParapheur()" + <a mat-list-item *ngIf="user.canCreateMaarchParapheurUser" (click)="linkMaarchParapheurAccount()" title="{{lang.createUserInMaarchParapheur}}"> - <mat-icon color="primary" mat-list-icon class="fa fa-user"></mat-icon> + <mat-icon color="primary" mat-list-icon class="fa fa-link"></mat-icon> <p mat-line> - {{lang.createUserInMaarchParapheur}} - </p> - </a> - <a style="opacity:0.7" mat-list-item *ngIf="user.external_id.maarchParapheur" disabled - title="{{lang.userCreatedInMaarchParapheur}}"> - <mat-icon color="primary" mat-list-icon class="fa fa-user"></mat-icon> - <p mat-line> - {{lang.userCreatedInMaarchParapheur}} + {{lang.linkAccount}} </p> </a> </mat-nav-list> <mat-divider></mat-divider> + <mat-list *ngIf="maarchParapheurLink.login !== ''"> + <h3 mat-subheader>Compte Maarch Parapheur</h3> + <mat-list-item> + <mat-icon class="avatarAccount" color="primary" mat-list-icon [style.background-image]="'url('+maarchParapheurLink.picture+')'"></mat-icon> + <p mat-line class="accountInfo"> + <span> + {{maarchParapheurLink.login}} + </span> + <button mat-icon-button color="warn" (click)="unlinkMaarchParapheurAccount()" title="{{lang.unlinkAccount}}"> + <mat-icon class="fas fa-unlink"></mat-icon> + </button> + </p> + </mat-list-item> + </mat-list> </mat-sidenav> <mat-sidenav-content> <div *ngIf="loading" style="display:flex;height:100%;"> diff --git a/src/frontend/app/administration/user/user-administration.component.scss b/src/frontend/app/administration/user/user-administration.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..efc374c61b8bafdade6fdfafbb66fe75e0a35bd4 --- /dev/null +++ b/src/frontend/app/administration/user/user-administration.component.scss @@ -0,0 +1,38 @@ +.avatar { + text-decoration:none; + background:#135f7f; + color:white; + width:100px; + height:100px; + border-radius:5px; + display:block; + overflow:hidden; + margin: 5px; +} +.form-group{ + margin:0px; +} + +.vertical-divider{ + height: 80%; +} + +.avatarAccount { + border: solid 3px #F99830; + height: 45px !important; + width: 45px !important; + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.accountInfo { + margin-left: 20px !important; + display: flex !important; + + span { + flex: 1; + align-items: center; + display: flex; + } +} \ No newline at end of file diff --git a/src/frontend/app/administration/user/user-administration.component.ts b/src/frontend/app/administration/user/user-administration.component.ts index d7ffcf6b157b47e12c16f77adb1232b6f2ba65e5..3bcaf764935a325a601561a57e7b035239b9d0a2 100755 --- a/src/frontend/app/administration/user/user-administration.component.ts +++ b/src/frontend/app/administration/user/user-administration.component.ts @@ -6,10 +6,11 @@ import { LANG } from '../../translate.component'; import { MatSidenav, MatPaginator, MatTableDataSource, MatSort, MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { FormControl, FormGroup, Validators, AbstractControl, ValidationErrors, ValidatorFn, FormBuilder } from '@angular/forms'; import { NotificationService } from '../../notification.service'; -import { HeaderService } from '../../../service/header.service'; +import { HeaderService } from '../../../service/header.service'; import { AutoCompletePlugin } from '../../../plugins/autocomplete.plugin'; import { SelectionModel } from '@angular/cdk/collections'; +import { AccountLinkComponent } from './account-link/account-link.component'; declare function $j(selector: any): any; declare const angularGlobals: any; @@ -17,30 +18,30 @@ declare const angularGlobals: any; @Component({ templateUrl: "user-administration.component.html", - styleUrls: ['user-administration.component.css'], + styleUrls: ['user-administration.component.scss'], providers: [NotificationService] }) export class UserAdministrationComponent extends AutoCompletePlugin implements OnInit { - @ViewChild('snav') public sidenavLeft : MatSidenav; - @ViewChild('snav2') public sidenavRight : MatSidenav; - - - private _mobileQueryListener : () => void; - mobileQuery : MediaQueryList; - - coreUrl : string; - lang : any = LANG; - loading : boolean = false; - dialogRef : MatDialogRef<any>; - config : any = {}; - serialId : number; - userId : string; - mode : string = ''; - user : any = {}; - _search : string = ''; - creationMode : boolean; - - signatureModel : any = { + @ViewChild('snav') public sidenavLeft: MatSidenav; + @ViewChild('snav2') public sidenavRight: MatSidenav; + + + private _mobileQueryListener: () => void; + mobileQuery: MediaQueryList; + + coreUrl: string; + lang: any = LANG; + loading: boolean = false; + dialogRef: MatDialogRef<any>; + config: any = {}; + serialId: number; + userId: string; + mode: string = ''; + user: any = {}; + _search: string = ''; + creationMode: boolean; + + signatureModel: any = { base64: "", base64ForJs: "", name: "", @@ -48,38 +49,42 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O size: 0, label: "", }; - userAbsenceModel : any[] = []; - userList : any[] = []; - selectedSignature : number = -1; - selectedSignatureLabel : string = ""; - loadingSign : boolean = false; - data : any[] = []; - CurrentYear : number = new Date().getFullYear(); - currentMonth : number = new Date().getMonth() + 1; - minDate : Date = new Date(); - firstFormGroup : FormGroup; - ruleText : string = ''; - otherRuleText : string; - validPassword : boolean = false; - showPassword : boolean = false; - hidePassword : boolean = true; - passwordModel : any = { - currentPassword : "", - newPassword : "", - reNewPassword : "" + userAbsenceModel: any[] = []; + userList: any[] = []; + maarchParapheurLink: any = { + login: '', + picture: '' + } + selectedSignature: number = -1; + selectedSignatureLabel: string = ""; + loadingSign: boolean = false; + data: any[] = []; + CurrentYear: number = new Date().getFullYear(); + currentMonth: number = new Date().getMonth() + 1; + minDate: Date = new Date(); + firstFormGroup: FormGroup; + ruleText: string = ''; + otherRuleText: string; + validPassword: boolean = false; + showPassword: boolean = false; + hidePassword: boolean = true; + passwordModel: any = { + currentPassword: "", + newPassword: "", + reNewPassword: "" }; - passwordRules : any = { - minLength : { enabled: false, value: 0 }, - complexityUpper : { enabled: false, value: 0 }, - complexityNumber : { enabled: false, value: 0 }, - complexitySpecial : { enabled: false, value: 0 }, - renewal : { enabled: false, value: 0 }, - historyLastUse : { enabled: false, value: 0 } + passwordRules: any = { + minLength: { enabled: false, value: 0 }, + complexityUpper: { enabled: false, value: 0 }, + complexityNumber: { enabled: false, value: 0 }, + complexitySpecial: { enabled: false, value: 0 }, + renewal: { enabled: false, value: 0 }, + historyLastUse: { enabled: false, value: 0 } }; - displayedColumns = ['event_date', 'event_type', 'info', 'remote_ip']; - dataSource = new MatTableDataSource(this.data); - selectedTabIndex : number = 0; + displayedColumns = ['event_date', 'event_type', 'info', 'remote_ip']; + dataSource = new MatTableDataSource(this.data); + selectedTabIndex: number = 0; @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -92,11 +97,11 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O //Redirect Baskets selectionBaskets = new SelectionModel<Element>(true, []); masterToggleBaskets(event: any) { - if (event.checked) { + if (event.checked) { this.user.baskets.forEach((basket: any) => { if (!basket.userToDisplay) { - this.selectionBaskets.select(basket); - } + this.selectionBaskets.select(basket); + } }); } else { this.selectionBaskets.clear(); @@ -142,11 +147,16 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O this.http.get(this.coreUrl + "rest/users/" + this.serialId + "/details") .subscribe((data: any) => { this.user = data; - + this.data = data.history; this.userId = data.user_id; this.minDate = new Date(this.CurrentYear + '-' + this.currentMonth + '-01'); this.headerService.setHeader(this.lang.userModification, data.firstname + " " + data.lastname); + + if (this.user.external_id.maarchParapheur !== undefined) { + this.checkInfoMaarchParapheurAccount(); + } + this.loading = false; setTimeout(() => { this.dataSource = new MatTableDataSource(this.data); @@ -160,6 +170,84 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O }); } + checkInfoMaarchParapheurAccount() { + this.http.get("../../rest/users/" + this.serialId + "/statusInMaarchParapheur") + .subscribe((data: any) => { + this.maarchParapheurLink.login = data.link; + this.loading = false; + if (this.maarchParapheurLink.login !== '') { + this.loadAvatarMaarchParapheur(this.user.external_id.maarchParapheur); + } + + }, (err) => { + this.notify.handleErrors(err); + }); + } + + linkMaarchParapheurAccount() { + const dialogRef = this.dialog.open(AccountLinkComponent, { autoFocus: false, data: { user: this.user } }); + dialogRef.afterClosed().subscribe(result => { + if (result) { + if (result.inMaarchParapheur) { + this.linkAccountToMaarchParahpeur(result.id); + } else { + this.createAccountToMaarchParahpeur(result.id, result.login); + } + + } + }); + } + + linkAccountToMaarchParahpeur(externalId: number) { + this.http.put(this.coreUrl + "rest/users/" + this.serialId + "/linkToMaarchParapheur", { maarchParapheurUserId: externalId }) + .subscribe(() => { + this.user.canCreateMaarchParapheurUser = false; + this.user.external_id['maarchParapheur'] = externalId; + this.checkInfoMaarchParapheurAccount(); + this.notify.success(this.lang.accountLinked); + }, (err) => { + this.notify.error(err.error.errors); + }); + } + + createAccountToMaarchParahpeur(id: number, login: string) { + this.http.put(this.coreUrl + "rest/users/" + id + "/createInMaarchParapheur", { login: login }) + .subscribe((data: any) => { + this.user.canCreateMaarchParapheurUser = false; + this.user.external_id['maarchParapheur'] = data.externalId; + this.checkInfoMaarchParapheurAccount(); + this.notify.success(this.lang.accountAdded); + }, (err) => { + this.notify.error(err.error.errors); + }); + } + + loadAvatarMaarchParapheur(externalId: number) { + this.http.get("../../rest/maarchParapheur/user/" + externalId + "/picture") + .subscribe((data: any) => { + this.maarchParapheurLink.picture = data.picture; + + }, (err) => { + this.notify.handleErrors(err); + }); + } + + unlinkMaarchParapheurAccount() { + let r = confirm(this.lang.confirmAction + ' ' + this.lang.unlinkAccount); + + if (r) { + this.http.put(this.coreUrl + "rest/users/" + this.serialId + "/unlinkToMaarchParapheur", {}) + .subscribe(() => { + this.user.canCreateMaarchParapheurUser = true; + this.maarchParapheurLink.login = ''; + this.maarchParapheurLink.picture = ''; + this.notify.success(this.lang.accountUnlinked); + }, (err) => { + this.notify.error(err.error.errors); + }); + } + } + toogleRedirect(basket: any) { $j('#redirectUser_' + basket.group_id + '_' + basket.basket_id).toggle(); @@ -192,7 +280,7 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O .on('select_node.jstree', (e: any, data: any) => { if (this.mode == '') { this.addEntity(data.node.id); - } + } }).on('deselect_node.jstree', (e: any, data: any) => { this.deleteEntity(data.node.id); }) @@ -309,8 +397,8 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O addEntity(entiyId: any) { let entity = { - "entityId" : entiyId, - "role" : '' + "entityId": entiyId, + "role": '' }; this.http.post(this.coreUrl + "rest/users/" + this.serialId + "/entities", entity) @@ -357,28 +445,28 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O this.notify.error(err.error.errors); }); } else { - this.config = { data: { hasConfidentialityInstances:data['hasConfidentialityInstances'], hasListTemplates:data['hasListTemplates'] } }; + this.config = { data: { hasConfidentialityInstances: data['hasConfidentialityInstances'], hasListTemplates: data['hasListTemplates'] } }; this.dialogRef = this.dialog.open(UserAdministrationRedirectModalComponent, this.config); this.dialogRef.afterClosed().subscribe((result: any) => { this.mode = 'delete'; if (result) { this.mode = result.processMode; - this.http.request('DELETE', this.coreUrl + "rest/users/" + this.serialId + "/entities/" + entityId, {body : {"mode":this.mode,"newUser":result.newUser}}) - .subscribe((data: any) => { - this.user.entities = data.entities; - this.user.allEntities = data.allEntities; - this.notify.success(this.lang.entityDeleted); - }, (err) => { - this.notify.error(err.error.errors); - }); + this.http.request('DELETE', this.coreUrl + "rest/users/" + this.serialId + "/entities/" + entityId, { body: { "mode": this.mode, "newUser": result.newUser } }) + .subscribe((data: any) => { + this.user.entities = data.entities; + this.user.allEntities = data.allEntities; + this.notify.success(this.lang.entityDeleted); + }, (err) => { + this.notify.error(err.error.errors); + }); } else { $j('#jstree').jstree('select_node', entityId); this.mode = ''; } - this.dialogRef = null; + this.dialogRef = null; }); } - + }, (err) => { this.notify.error(err.error.errors); }); @@ -429,7 +517,7 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O } } - test(event:any) { + test(event: any) { if (event.mouseEvent.dataTransfer.files && event.mouseEvent.dataTransfer.files[0]) { var reader = new FileReader(); @@ -449,15 +537,15 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O } } - addBasketRedirection(newUser:any) { - let basketsRedirect:any[] = []; - + addBasketRedirection(newUser: any) { + let basketsRedirect: any[] = []; + this.selectionBaskets.selected.forEach((elem: any) => { basketsRedirect.push( { actual_user_id: newUser.serialId, - basket_id:elem.basket_id, - group_id:elem.groupSerialId, + basket_id: elem.basket_id, + group_id: elem.groupSerialId, originalOwner: null } ) @@ -479,16 +567,16 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O } } - reassignBasketRedirection(newUser:any, basket: any, i: number) { + reassignBasketRedirection(newUser: any, basket: any, i: number) { let r = confirm(this.lang.confirmAction + ' ' + this.lang.redirectBasket); if (r) { this.http.post(this.coreUrl + "rest/users/" + this.serialId + "/redirectedBaskets", [ { - "actual_user_id": newUser.serialId, - "basket_id": basket.basket_id, + "actual_user_id": newUser.serialId, + "basket_id": basket.basket_id, "group_id": basket.group_id, - "originalOwner": basket.owner_user_id, + "originalOwner": basket.owner_user_id, } ]) .subscribe((data: any) => { @@ -534,24 +622,24 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O } } - toggleBasket(state:boolean) { - let basketsDisable:any = []; + toggleBasket(state: boolean) { + let basketsDisable: any = []; this.user.baskets.forEach((elem: any) => { this.selectionBaskets.selected.forEach((selected: any) => { if (elem.basket_id == selected.basket_id && elem.group_id == selected.group_id && elem.allowed != state) { elem.allowed = state; - basketsDisable.push({"basketId" : elem.basket_id, "groupSerialId":elem.groupSerialId, "allowed":state}); + basketsDisable.push({ "basketId": elem.basket_id, "groupSerialId": elem.groupSerialId, "allowed": state }); } }); }); if (basketsDisable.length > 0) { - this.http.put(this.coreUrl + "rest/users/" + this.serialId + "/baskets", {"baskets" :basketsDisable}) - .subscribe((data: any) => { - this.selectionBaskets.clear(); - this.notify.success(this.lang.basketsUpdated); - }, (err: any) => { - this.notify.error(err.error.errors); - }); + this.http.put(this.coreUrl + "rest/users/" + this.serialId + "/baskets", { "baskets": basketsDisable }) + .subscribe((data: any) => { + this.selectionBaskets.clear(); + this.notify.success(this.lang.basketsUpdated); + }, (err: any) => { + this.notify.error(err.error.errors); + }); } } @@ -578,7 +666,7 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O getErrorMessage() { if (this.firstFormGroup.controls['newPasswordCtrl'].value != this.firstFormGroup.controls['retypePasswordCtrl'].value) { - this.firstFormGroup.controls['retypePasswordCtrl'].setErrors({'mismatch': true}); + this.firstFormGroup.controls['retypePasswordCtrl'].setErrors({ 'mismatch': true }); } else { this.firstFormGroup.controls['retypePasswordCtrl'].setErrors(null); } @@ -608,8 +696,8 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O if (group.controls['newPasswordCtrl'].value == group.controls['retypePasswordCtrl'].value) { return false; } else { - group.controls['retypePasswordCtrl'].setErrors({'mismatch': true}); - return {'mismatch': true}; + group.controls['retypePasswordCtrl'].setErrors({ 'mismatch': true }); + return { 'mismatch': true }; } } @@ -626,7 +714,7 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O changePasswd() { this.http.get(this.coreUrl + 'rest/passwordRules') .subscribe((data: any) => { - let valArr : ValidatorFn[] = []; + let valArr: ValidatorFn[] = []; let ruleTextArr: String[] = []; let otherRuleTextArr: String[] = []; @@ -671,13 +759,13 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O this.passwordRules.renewal.enabled = rule.enabled; this.passwordRules.renewal.value = rule.value; if (rule.enabled) { - otherRuleTextArr.push(this.lang['password' + rule.label] + ' <b>' + rule.value + ' ' + this.lang.days + '</b>. ' + this.lang['password2' + rule.label]+'.'); + otherRuleTextArr.push(this.lang['password' + rule.label] + ' <b>' + rule.value + ' ' + this.lang.days + '</b>. ' + this.lang['password2' + rule.label] + '.'); } } else if (rule.label == 'historyLastUse') { this.passwordRules.historyLastUse.enabled = rule.enabled; this.passwordRules.historyLastUse.value = rule.value; if (rule.enabled) { - otherRuleTextArr.push(this.lang['passwordhistoryLastUseDesc'] + ' <b>' + rule.value + '</b> ' + this.lang['passwordhistoryLastUseDesc2']+'.'); + otherRuleTextArr.push(this.lang['passwordhistoryLastUseDesc'] + ' <b>' + rule.value + '</b> ' + this.lang['passwordhistoryLastUseDesc2'] + '.'); } } @@ -702,8 +790,8 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O Validators.compose([Validators.required]) ] }, { - validator: this.matchValidator - }); + validator: this.matchValidator + }); this.validPassword = false; this.firstFormGroup.controls['currentPasswordCtrl'].setErrors(null); @@ -767,7 +855,7 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O } } - setUserModeLogin(event:any) { + setUserModeLogin(event: any) { if (event.checked) { this.user.loginmode = "restMode"; } else { @@ -775,7 +863,7 @@ export class UserAdministrationComponent extends AutoCompletePlugin implements O } } - sendToMaarchParapheur(){ + sendToMaarchParapheur() { let r = confirm(this.lang.confirmAction + ' ' + this.lang.createUserInMaarchParapheur); if (r) { diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index 72ab32868d2746aff002d0c3b6de1a3bea209240..e02c5108928155c00644438cb455e70162fc1f89 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -1009,4 +1009,12 @@ export const LANG_EN = { "visaWorkflowWillBeSend" : "Visa workflow will be send to Maarch Parapheur", "usersNotExistedInMaarchParapheur" : "Some users does not exist in Maarch Parapheur", "usersMissingInSignatureBook" : "missing in Maarch Parapheur", + "unlinkAccount" : "Unlink account", + "accountLinked" : "Account linked", + "accountUnlinked" : "Account unlinked", + "linkAccount" : "Link Maarch Parapheur account", + "maarchParapheurAccountMsg" : "A <b>new</b> account with login", + "maarchParapheurAccountMsg2" : " will be created in Maarch Parapheur.", + "searchUserInMaarchParapheur" : "Search an user in Maarch Parapheur", + "newLoginInMaarchParapheur" : "New Maarch Parapheur Login", }; diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index 8edd504b5d929ff7bba1fb0216a05fcda315fd9c..ef66ace40b45fe0419eab8a8b8d555db2bca34af 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -1042,4 +1042,12 @@ export const LANG_FR = { "visaWorkflowWillBeSend" : "Le circuit visa des courriers sera envoyé à Maarch Parapheur", "usersNotExistedInMaarchParapheur" : "Certains utilisateurs n'existent pas dans Maarch Parapheur", "usersMissingInSignatureBook" : "non présent dans Maarch Parapheur", + "unlinkAccount" : "Dissocier le compte", + "accountLinked" : "Compte associé", + "accountUnlinked" : "Compte dissocié", + "linkAccount" : "Lier un compte Maarch Parapheur", + "maarchParapheurAccountMsg" : "Un <b>nouveau</b> compte avec l'identifiant", + "maarchParapheurAccountMsg2" : "sera créé dans Maarch Parapheur.", + "searchUserInMaarchParapheur" : "Recherche un utilisateur dans Maarch Parapheur", + "newLoginInMaarchParapheur" : "Nouvel identifiant Maarch Parapheur", }; \ No newline at end of file diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index 9fca72d95813ac6c185ba70218757e031ab8424e..56454e4ef3c3c203c6f915023236ebcdd69448bf 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -1036,4 +1036,11 @@ export const LANG_NL = { "visaWorkflowWillBeSend" : "Visa workflow will be send to Maarch Parapheur", //_TO_TRANSLATE "usersNotExistedInMaarchParapheur" : "Some users does not exist in Maarch Parapheur", //_TO_TRANSLATE "usersMissingInSignatureBook" : "missing in Maarch Parapheur", //_TO_TRANSLATE + "unlinkAccount" : "Unlink account", //_TO_TRANSLATE + "accountLinked" : "Account linked", //_TO_TRANSLATE + "accountUnlinked" : "Account unlinked", //_TO_TRANSLATE + "maarchParapheurAccountMsg" : "A <b>new</b> account with login", //_TO_TRANSLATE + "maarchParapheurAccountMsg2" : " will be created in Maarch Parapheur.", //_TO_TRANSLATE + "searchUserInMaarchParapheur" : "Search unlinked an user in Maarch Parapheur", //_TO_TRANSLATE + "newLoginInMaarchParapheur" : "New Maarch Parapheur Login", //_TO_TRANSLATE }; diff --git a/src/frontend/plugins/autocomplete.plugin.ts b/src/frontend/plugins/autocomplete.plugin.ts index 2be17c1db33b5288bb46791cc2fc7c6810cb22f8..3faedd86cbb9437d201065bcda43597f7c4159bb 100755 --- a/src/frontend/plugins/autocomplete.plugin.ts +++ b/src/frontend/plugins/autocomplete.plugin.ts @@ -72,6 +72,22 @@ export class AutoCompletePlugin { }); } + if (target.indexOf('signatureBookUsersNotLinked') != -1) { + this.userCtrl = new FormControl(); + this.userCtrl.valueChanges.pipe( + debounceTime(300), + filter(value => value ? value.length > 2 : false), + distinctUntilChanged(), + switchMap(data => this.http.get(this.coreUrl + 'rest/autocomplete/maarchParapheurUsers', { params: { "search": data, "exludeAlreadyConnected": 'true' } })) + ).subscribe((response: any) => { + this.filteredUsers = this.userCtrl.valueChanges + .pipe( + startWith(''), + map(user => user ? this.autocompleteFilterUser(user) : response.slice()) + ); + }); + } + if (target.indexOf('statuses') != -1) { this.statusCtrl = new FormControl(); this.http.get(this.coreUrl + 'rest/autocomplete/statuses')