From 46d000f14c6d7e1ef8fd30b0f1e711a338666b7d Mon Sep 17 00:00:00 2001 From: "florian.azizian" <florian.azizian@maarch.org> Date: Thu, 19 Nov 2020 18:58:45 +0100 Subject: [PATCH] FIX #11169 TIME 1:20 Display groups in user administration --- lang/en.json | 1 + lang/fr.json | 1 + src/app/user/controllers/UserController.php | 2 +- .../administration/user/user.component.html | 169 +++++++++++------- .../administration/user/user.component.scss | 15 ++ .../app/administration/user/user.component.ts | 5 + 6 files changed, 124 insertions(+), 69 deletions(-) diff --git a/lang/en.json b/lang/en.json index 37174027fe..2330d42364 100755 --- a/lang/en.json +++ b/lang/en.json @@ -308,6 +308,7 @@ "passwordValid": "Password is valid", "wrongCurrentPassword": "Wrong current password", "alreadyUsedPassword": "The password has already been used", + "noAssociatedGroup": "The user does not belong to any group", "homePage": "Home page" } } diff --git a/lang/fr.json b/lang/fr.json index cb404a2165..73fec3d706 100755 --- a/lang/fr.json +++ b/lang/fr.json @@ -324,6 +324,7 @@ "inca_card": "Carte agent", "eidas": "Eidas", "rgs_2stars": "Rgs**", + "noAssociatedGroup": "L'utilisateur appartient à aucun groupe", "docToSign": "Document à signer", "attachDocToSign": "Annexe attaché au(x) document(s) à signer", "titleSearch": "Sujet du document à signer", diff --git a/src/app/user/controllers/UserController.php b/src/app/user/controllers/UserController.php index 795463b38d..486322ef94 100755 --- a/src/app/user/controllers/UserController.php +++ b/src/app/user/controllers/UserController.php @@ -86,7 +86,7 @@ class UserController $user['groups'] = []; $userGroups = UserGroupModel::get(['select' => ['group_id'], 'where' => ['user_id = ?'], 'data' => [$args['id']]]); - $groupsIds = array_column($userGroups, 'group_id'); + $groupsIds = array_column($userGroups, 'group_id'); if (!empty($groupsIds)) { $groups = GroupModel::get(['select' => ['label'], 'where' => ['id in (?)'], 'data' => [$groupsIds]]); $user['groups'] = $groups; diff --git a/src/frontend/app/administration/user/user.component.html b/src/frontend/app/administration/user/user.component.html index 01eb0d3387..044c3defd9 100644 --- a/src/frontend/app/administration/user/user.component.html +++ b/src/frontend/app/administration/user/user.component.html @@ -9,74 +9,107 @@ </ion-avatar> </ion-toolbar> </ion-header> -<form style="display: contents;" id="adminForm" (ngSubmit)="onSubmit()" #adminForm="ngForm"> + +<ion-header> + <ion-toolbar> + <ion-segment [value]="currentTool" (ionChange)="initTab($event.detail.value)"> + <ion-segment-button value="info"> + <ion-label>{{'lang.informations' | translate}}</ion-label> + <ion-icon name="information-circle"></ion-icon> + </ion-segment-button> + <ion-segment-button value="groups"> + <ion-label>{{'lang.manage_groups' | translate}}</ion-label> + <ion-icon name="people-sharp"></ion-icon> + </ion-segment-button> + </ion-segment> + </ion-toolbar> +</ion-header> + +<ng-container *ngIf="currentTool === 'info'"> + <form style="display: contents;" id="adminForm" (ngSubmit)="onSubmit()" #adminForm="ngForm"> + <ion-content> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.login' | translate}} *</ion-label> + <ion-input name="login" [readonly]="!creationMode" [(ngModel)]="user.login" required pattern="^[\w.@-]*$"> + </ion-input> + </ion-item> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.firstname' | translate}} *</ion-label> + <ion-input name="firstname" [(ngModel)]="user.firstname" required></ion-input> + </ion-item> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.lastname' | translate}} *</ion-label> + <ion-input name="lastname" [(ngModel)]="user.lastname" required></ion-input> + </ion-item> + <ion-item> + <ion-label color="secondary" position="floating">{{'lang.email' | translate}} *</ion-label> + <ion-input type="email" name="email" [(ngModel)]="user.email" required + pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"></ion-input> + </ion-item> + <ion-item> + <ion-label>{{'lang.restUser' | translate}}</ion-label> + <ion-toggle slot="start" color="primary" [disabled]="!creationMode" name="isRest" [(ngModel)]="user.isRest" + [checked]="user.isRest" (ionChange)="getPassRules($event)"></ion-toggle> + </ion-item> + <ion-list> + <ion-list-header> + <ion-label color="secondary">{{'lang.signatureModes' | translate}}</ion-label> + </ion-list-header> + <ng-container *ngFor="let signMode of authService.signatureRoles"> + <ion-item *ngIf="signMode.id !=='visa'"> + <ion-label [style.color]="signMode.color">{{'lang.' + signMode.id | translate}}</ion-label> + <ion-checkbox slot="start" [checked]="user.signatureModes.indexOf(signMode.id) > -1" (ionChange)="toggleSignMode(signMode, $event.detail.checked)" [disabled]="signMode.id === 'stamp'"></ion-checkbox> + </ion-item> + </ng-container> + </ion-list> + <ion-item style="align-items: center;" *ngIf="user.isRest"> + <ion-button slot="end" fill="clear" color="primary" (click)="hideNewPassword = !hideNewPassword"> + <ion-icon color="primary" [name]="hideNewPassword ? 'eye-outline' : 'eye-off-outline'"> + </ion-icon> + </ion-button> + <ion-label color="secondary" position="floating">{{'lang.newPassword' | translate}}</ion-label> + <ion-input [type]="hideNewPassword ? 'password' : 'text'" name="newPasswordRest" + [(ngModel)]="passwordRest.newPassword" (ionChange)="checkPasswordValidity(passwordRest.newPassword)"> + </ion-input> + </ion-item> + <ion-item style="align-items: center;" *ngIf="user.isRest"> + <ion-button slot="end" fill="clear" color="primary" + (click)="hideNewPasswordConfirm = !hideNewPasswordConfirm"> + <ion-icon color="primary" [name]="hideNewPasswordConfirm ? 'eye-outline' : 'eye-off-outline'"> + </ion-icon> + </ion-button> + <ion-label color="secondary" position="floating">{{'lang.passwordConfirmation' | translate}}</ion-label> + <ion-input [type]="hideNewPasswordConfirm ? 'password' : 'text'" name="passwordConfirmation" + [(ngModel)]="passwordRest.passwordConfirmation"></ion-input> + <ion-note color="danger" *ngIf="passwordRest.passwordConfirmation !== passwordRest.newPassword"> + {{'lang.passwordNotMatch' | translate}}</ion-note> + <ion-note color="success" + *ngIf="passwordRest.passwordConfirmation === passwordRest.newPassword && passwordRest.newPassword.length > 0 && passwordRest.passwordConfirmation.length> 0"> + {{'lang.samePassword' | translate}}</ion-note> + </ion-item> + <ion-item text-center lines="none" style="position: sticky;bottom:0px;z-index:1;"> + <div style="display: flex;align-items: center;justify-content: center;width: 100%;background: white;"> + <ion-button type="submit" shape="round" size="large" fill="outline" color="primary" + [disabled]="!adminForm.form.valid || !canValidate()"> + <ion-label style="font-size: 13px;">{{'lang.validate' | translate}}</ion-label> + </ion-button> + </div> + </ion-item> + </ion-content> + </form> +</ng-container> + +<ng-container *ngIf="currentTool === 'groups'"> <ion-content> - <ion-item> - <ion-label color="secondary" position="floating">{{'lang.login' | translate}} *</ion-label> - <ion-input name="login" [readonly]="!creationMode" [(ngModel)]="user.login" required pattern="^[\w.@-]*$"> - </ion-input> - </ion-item> - <ion-item> - <ion-label color="secondary" position="floating">{{'lang.firstname' | translate}} *</ion-label> - <ion-input name="firstname" [(ngModel)]="user.firstname" required></ion-input> - </ion-item> - <ion-item> - <ion-label color="secondary" position="floating">{{'lang.lastname' | translate}} *</ion-label> - <ion-input name="lastname" [(ngModel)]="user.lastname" required></ion-input> - </ion-item> - <ion-item> - <ion-label color="secondary" position="floating">{{'lang.email' | translate}} *</ion-label> - <ion-input type="email" name="email" [(ngModel)]="user.email" required - pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"></ion-input> - </ion-item> - <ion-item> - <ion-label>{{'lang.restUser' | translate}}</ion-label> - <ion-toggle slot="start" color="primary" [disabled]="!creationMode" name="isRest" [(ngModel)]="user.isRest" - [checked]="user.isRest" (ionChange)="getPassRules($event)"></ion-toggle> - </ion-item> - <ion-list> - <ion-list-header> - <ion-label color="secondary">{{'lang.signatureModes' | translate}}</ion-label> - </ion-list-header> - <ng-container *ngFor="let signMode of authService.signatureRoles"> - <ion-item *ngIf="signMode.id !=='visa'"> - <ion-label [style.color]="signMode.color">{{'lang.' + signMode.id | translate}}</ion-label> - <ion-checkbox slot="start" [checked]="user.signatureModes.indexOf(signMode.id) > -1" (ionChange)="toggleSignMode(signMode, $event.detail.checked)" [disabled]="signMode.id === 'stamp'"></ion-checkbox> - </ion-item> - </ng-container> + <ion-list *ngIf="user.groups.length > 0"> + <ion-item *ngFor="let group of user.groups"> + <ion-label>{{group.label}}</ion-label> + </ion-item> + </ion-list> + <ion-list class="no-result" *ngIf="user.groups.length === 0"> + <ion-item lines="none"> + <ion-label class="no-result-label" color="medium">{{'lang.noAssociatedGroup' | translate}}</ion-label> + </ion-item> </ion-list> - <ion-item style="align-items: center;" *ngIf="user.isRest"> - <ion-button slot="end" fill="clear" color="primary" (click)="hideNewPassword = !hideNewPassword"> - <ion-icon color="primary" [name]="hideNewPassword ? 'eye-outline' : 'eye-off-outline'"> - </ion-icon> - </ion-button> - <ion-label color="secondary" position="floating">{{'lang.newPassword' | translate}}</ion-label> - <ion-input [type]="hideNewPassword ? 'password' : 'text'" name="newPasswordRest" - [(ngModel)]="passwordRest.newPassword" (ionChange)="checkPasswordValidity(passwordRest.newPassword)"> - </ion-input> - </ion-item> - <ion-item style="align-items: center;" *ngIf="user.isRest"> - <ion-button slot="end" fill="clear" color="primary" - (click)="hideNewPasswordConfirm = !hideNewPasswordConfirm"> - <ion-icon color="primary" [name]="hideNewPasswordConfirm ? 'eye-outline' : 'eye-off-outline'"> - </ion-icon> - </ion-button> - <ion-label color="secondary" position="floating">{{'lang.passwordConfirmation' | translate}}</ion-label> - <ion-input [type]="hideNewPasswordConfirm ? 'password' : 'text'" name="passwordConfirmation" - [(ngModel)]="passwordRest.passwordConfirmation"></ion-input> - <ion-note color="danger" *ngIf="passwordRest.passwordConfirmation !== passwordRest.newPassword"> - {{'lang.passwordNotMatch' | translate}}</ion-note> - <ion-note color="success" - *ngIf="passwordRest.passwordConfirmation === passwordRest.newPassword && passwordRest.newPassword.length > 0 && passwordRest.passwordConfirmation.length> 0"> - {{'lang.samePassword' | translate}}</ion-note> - </ion-item> - <ion-item text-center lines="none" style="position: sticky;bottom:0px;z-index:1;"> - <div style="display: flex;align-items: center;justify-content: center;width: 100%;background: white;"> - <ion-button type="submit" shape="round" size="large" fill="outline" color="primary" - [disabled]="!adminForm.form.valid || !canValidate()"> - <ion-label style="font-size: 13px;">{{'lang.validate' | translate}}</ion-label> - </ion-button> - </div> - </ion-item> </ion-content> -</form> \ No newline at end of file +</ng-container> diff --git a/src/frontend/app/administration/user/user.component.scss b/src/frontend/app/administration/user/user.component.scss index e18ad0d5c7..c655824dc5 100644 --- a/src/frontend/app/administration/user/user.component.scss +++ b/src/frontend/app/administration/user/user.component.scss @@ -11,3 +11,18 @@ transition: all 0.2s; } +.no-result { + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.no-result .item { + width: 100%; + text-align: center; +} + +.no-result-label { + font-size: 30px; +} \ No newline at end of file diff --git a/src/frontend/app/administration/user/user.component.ts b/src/frontend/app/administration/user/user.component.ts index 2f288d5d04..f593ecd840 100644 --- a/src/frontend/app/administration/user/user.component.ts +++ b/src/frontend/app/administration/user/user.component.ts @@ -46,6 +46,7 @@ export class UserComponent implements OnInit { hideCurrentPassword: Boolean = true; hideNewPassword: Boolean = true; hideNewPasswordConfirm: Boolean = true; + currentTool = 'info'; // HANDLE PASSWORD passwordRules: any = { @@ -305,4 +306,8 @@ export class UserComponent implements OnInit { this.user.signatureModes = this.user.signatureModes.filter((item: any) => item !== signMode.id); } } + + initTab(val: any) { + this.currentTool = val; + } } -- GitLab