Merge pull request #4169 from tsiegleauq/gender-client
Add gender field to users
This commit is contained in:
commit
c48148fc01
@ -2,6 +2,11 @@ import { Searchable } from '../base/searchable';
|
||||
import { SearchRepresentation } from '../../../core/services/search.service';
|
||||
import { BaseModel } from '../base/base-model';
|
||||
|
||||
/**
|
||||
* Iterable pre selection of genders (sexes)
|
||||
*/
|
||||
export const genders = ['Female', 'Male', 'Diverse'];
|
||||
|
||||
/**
|
||||
* Representation of a user in contrast to the operator.
|
||||
* @ignore
|
||||
@ -14,6 +19,7 @@ export class User extends BaseModel<User> implements Searchable {
|
||||
public title: string;
|
||||
public first_name: string;
|
||||
public last_name: string;
|
||||
public gender: string;
|
||||
public structure_level: string;
|
||||
public number: string;
|
||||
public about_me: string;
|
||||
|
@ -4,9 +4,7 @@
|
||||
<h2><span translate>List of speakers</span></h2>
|
||||
</div>
|
||||
<div class="menu-slot" *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||
<button type="button" mat-icon-button [matMenuTriggerFor]="speakerMenu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<button type="button" mat-icon-button [matMenuTriggerFor]="speakerMenu"><mat-icon>more_vert</mat-icon></button>
|
||||
</div>
|
||||
</os-head-bar>
|
||||
|
||||
@ -68,6 +66,7 @@
|
||||
<span *ngIf="hasSpokenCount(item)" class="red-warning-text speaker-warning">
|
||||
{{ hasSpokenCount(item) + 1 }}. <span translate>contribution</span>
|
||||
</span>
|
||||
<span *ngIf="item.gender">({{ item.gender | translate }})</span>
|
||||
</span>
|
||||
<mat-button-toggle-group *osPerms="'agenda.can_manage_list_of_speakers'">
|
||||
<mat-button-toggle matTooltip="{{ 'Begin speech' | translate }}" (click)="onStartButton(item)">
|
||||
@ -117,7 +116,6 @@
|
||||
</mat-card>
|
||||
|
||||
<mat-menu #speakerMenu="matMenu">
|
||||
|
||||
<button mat-menu-item *ngIf="closedList" (click)="openSpeakerList()">
|
||||
<mat-icon>mic</mat-icon>
|
||||
<span translate>Open list of speakers</span>
|
||||
|
@ -46,6 +46,10 @@ export class ViewSpeaker extends BaseViewModel implements Selectable {
|
||||
return this.user.full_name || this.user.username;
|
||||
}
|
||||
|
||||
public get gender(): string {
|
||||
return this.user.gender || '';
|
||||
}
|
||||
|
||||
public constructor(speaker?: Speaker, user?: User) {
|
||||
super();
|
||||
this._speaker = speaker;
|
||||
|
@ -9,8 +9,7 @@
|
||||
<!-- Title -->
|
||||
<div class="title-slot">
|
||||
<h2>
|
||||
<span *ngIf="newUser" translate>New participant</span>
|
||||
<span *ngIf="!newUser">{{ user.full_name }}</span>
|
||||
<span *ngIf="newUser" translate>New participant</span> <span *ngIf="!newUser">{{ user.full_name }}</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@ -39,61 +38,74 @@
|
||||
[formGroup]="personalInfoForm"
|
||||
(ngSubmit)="saveUser()"
|
||||
*ngIf="user"
|
||||
(keydown)="onKeyDown($event)">
|
||||
(keydown)="onKeyDown($event)"
|
||||
>
|
||||
<!-- <h3 translate>Personal Data</h3> -->
|
||||
<div *ngIf="isAllowed('seeName')">
|
||||
<!-- Title -->
|
||||
<mat-form-field
|
||||
class="form16 distance force-min-with"
|
||||
*ngIf="user.title || (editUser && isAllowed('manage'))">
|
||||
*ngIf="user.title || (editUser && isAllowed('manage'))"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
osAutofocus
|
||||
placeholder="{{ 'Title' | translate }}"
|
||||
formControlName="title"
|
||||
[value]="user.title"/>
|
||||
[value]="user.title"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- First name -->
|
||||
<mat-form-field
|
||||
class="form37 distance force-min-with"
|
||||
*ngIf="user.first_name || (editUser && isAllowed('manage'))">
|
||||
*ngIf="user.first_name || (editUser && isAllowed('manage'))"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="{{ 'Given name' | translate }}"
|
||||
formControlName="first_name"
|
||||
[value]="user.first_name"/>
|
||||
[value]="user.first_name"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Last name -->
|
||||
<mat-form-field
|
||||
class="form37 force-min-with"
|
||||
*ngIf="user.last_name || (editUser && isAllowed('manage'))">
|
||||
<mat-form-field class="form37 force-min-with" *ngIf="user.last_name || (editUser && isAllowed('manage'))">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="{{ 'Surname' | translate }}"
|
||||
formControlName="last_name"
|
||||
[value]="user.last_name"/>
|
||||
[value]="user.last_name"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="isAllowed('seePersonal')">
|
||||
<!-- E-Mail -->
|
||||
<mat-form-field *ngIf="user.email || editUser">
|
||||
<mat-form-field class="form70 distance" *ngIf="user.email || editUser">
|
||||
<input
|
||||
type="email"
|
||||
matInput
|
||||
placeholder="{{ 'Email' | translate }}"
|
||||
name="email"
|
||||
formControlName="email"
|
||||
[value]="user.email"/>
|
||||
[value]="user.email"
|
||||
/>
|
||||
<mat-error *ngIf="personalInfoForm.get('email').hasError('email')" translate>
|
||||
Please enter a valid email address
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Gender -->
|
||||
<mat-form-field class="form25 force-min-with" *ngIf="user.gender || editUser">
|
||||
<mat-select placeholder="{{ 'Gender' | translate }}" formControlName="gender">
|
||||
<mat-option>-</mat-option>
|
||||
<mat-option *ngFor="let gender of genderList" [value]="gender">{{ gender | translate }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@ -104,19 +116,22 @@
|
||||
matInput
|
||||
placeholder="{{ 'Structure level' | translate }}"
|
||||
formControlName="structure_level"
|
||||
[value]="user.structure_level"/>
|
||||
[value]="user.structure_level"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Participant Number -->
|
||||
<mat-form-field
|
||||
class="form25 force-min-with"
|
||||
*ngIf="user.participant_number || (editUser && isAllowed('manage'))">
|
||||
*ngIf="user.participant_number || (editUser && isAllowed('manage'))"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="{{ 'Participant number' | translate }}"
|
||||
formControlName="number"
|
||||
[value]="user.participant_number"/>
|
||||
[value]="user.participant_number"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
@ -136,7 +151,8 @@
|
||||
matInput
|
||||
placeholder="{{ 'Initial password' | translate }}"
|
||||
formControlName="default_password"
|
||||
[value]="user.default_password"/>
|
||||
[value]="user.default_password"
|
||||
/>
|
||||
<mat-hint align="end">Generate</mat-hint>
|
||||
<button
|
||||
type="button"
|
||||
@ -144,7 +160,8 @@
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
[disabled]="!newUser"
|
||||
(click)="generatePassword()">
|
||||
(click)="generatePassword()"
|
||||
>
|
||||
<mat-icon>sync_problem</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
@ -166,7 +183,8 @@
|
||||
matInput
|
||||
placeholder="{{ 'Username' | translate }}"
|
||||
formControlName="username"
|
||||
[value]="user.username"/>
|
||||
[value]="user.username"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
@ -177,7 +195,8 @@
|
||||
matInput
|
||||
placeholder="{{ 'Comment' | translate }}"
|
||||
formControlName="comment"
|
||||
[value]="user.comment"/>
|
||||
[value]="user.comment"
|
||||
/>
|
||||
<mat-hint translate>Only for internal notes.</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@ -187,7 +206,8 @@
|
||||
<mat-checkbox
|
||||
formControlName="is_present"
|
||||
matTooltip="{{ 'Designates whether this user is in the room.' | translate }}"
|
||||
[value]="user.is_present">
|
||||
[value]="user.is_present"
|
||||
>
|
||||
<span translate>Is present</span>
|
||||
</mat-checkbox>
|
||||
|
||||
@ -199,7 +219,8 @@
|
||||
matTooltip="{{
|
||||
'Designates whether this user should be treated as active. Unselect this instead of deleting the account.'
|
||||
| translate
|
||||
}}">
|
||||
}}"
|
||||
>
|
||||
<span translate>Is active</span>
|
||||
</mat-checkbox>
|
||||
|
||||
@ -207,7 +228,8 @@
|
||||
<mat-checkbox
|
||||
formControlName="is_committee"
|
||||
[value]="user.is_committee"
|
||||
matTooltip="{{ 'Designates whether this user should be treated as a committee.' | translate }}">
|
||||
matTooltip="{{ 'Designates whether this user should be treated as a committee.' | translate }}"
|
||||
>
|
||||
<span translate>Is a committee</span>
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
@ -1,16 +1,18 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { genders } from 'app/shared/models/users/user';
|
||||
import { ViewUser } from '../../models/view-user';
|
||||
import { UserRepositoryService } from '../../services/user-repository.service';
|
||||
import { Group } from '../../../../shared/models/users/group';
|
||||
import { DataStoreService } from '../../../../core/services/data-store.service';
|
||||
import { OperatorService } from '../../../../core/services/operator.service';
|
||||
import { BaseViewComponent } from '../../../base/base-view';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { PromptService } from '../../../../core/services/prompt.service';
|
||||
|
||||
/**
|
||||
@ -62,6 +64,11 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
*/
|
||||
public groups: Group[];
|
||||
|
||||
/**
|
||||
* Hold the list of genders (sexes) publicly to dynamically iterate in the view
|
||||
*/
|
||||
public genderList = genders;
|
||||
|
||||
/**
|
||||
* Constructor for user
|
||||
*
|
||||
@ -114,6 +121,7 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* Checks, if the given user id matches with the operator ones.
|
||||
*
|
||||
* @param userId The id to check, if it's the operator
|
||||
* @returns If the user is the operator
|
||||
*/
|
||||
@ -178,6 +186,7 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
title: [''],
|
||||
first_name: [''],
|
||||
last_name: [''],
|
||||
gender: [''],
|
||||
structure_level: [''],
|
||||
number: [''],
|
||||
about_me: [''],
|
||||
@ -226,6 +235,7 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
this.personalInfoForm.get('first_name'),
|
||||
this.personalInfoForm.get('last_name'),
|
||||
this.personalInfoForm.get('email'),
|
||||
this.personalInfoForm.get('gender'),
|
||||
this.personalInfoForm.get('structure_level'),
|
||||
this.personalInfoForm.get('number'),
|
||||
this.personalInfoForm.get('groups_id'),
|
||||
@ -241,6 +251,7 @@ export class UserDetailComponent extends BaseViewComponent implements OnInit {
|
||||
allowedFormFields.push(
|
||||
this.personalInfoForm.get('username'),
|
||||
this.personalInfoForm.get('email'),
|
||||
this.personalInfoForm.get('gender'),
|
||||
this.personalInfoForm.get('about_me')
|
||||
);
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ export class ViewUser extends BaseProjectableModel {
|
||||
return this.user ? this.user.email : null;
|
||||
}
|
||||
|
||||
public get gender(): string {
|
||||
return this.user ? this.user.gender : null;
|
||||
}
|
||||
|
||||
public get structure_level(): string {
|
||||
return this.user ? this.user.structure_level : null;
|
||||
}
|
||||
|
@ -64,6 +64,12 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User> {
|
||||
updateUser.username = viewUser.username;
|
||||
}
|
||||
|
||||
// if the update user does not have a gender-field, send gender as empty string.
|
||||
// This allow to delete a previously selected gender
|
||||
if (!updateUser.gender) {
|
||||
updateUser.gender = '';
|
||||
}
|
||||
|
||||
return await this.dataSend.updateModel(updateUser);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user