mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-12 00:55:12 +00:00
feat(console): add stylelint scss, app redirecturi validation, user grant api change (#531)
* add custom validator for redirect inputs * change http pattern, i18n * throw out deprecated usergrant functions * remove deprecation service * show docs in app detail * reorder data promises * show redirect desc in app detail * custom validator * grant search filters * rm animations * add validation to app detail * user grant udpate * rm grantid from update req * fix project member guard * fix hasrole directive * show validation errors, i18n * fix router link from org members * navitem padding * mobile layout * policy grid mobile layout * rm unused background * lint * add stylelinter add to pipeline * update stylelint rules * lint unknown rule * disable enable rules * lint * table style lint * table classes * fix stylelinter rule, lint * overflow fix member detail * common detail page * user create, password, project grant detail clnup * move meta styles * lint * password policy indicator * lint * fix org create * common component for complexity view * lint * user grant filter * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster <[email protected]> * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster <[email protected]> * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster <[email protected]> * Update console/src/assets/i18n/de.json Co-authored-by: Florian Forster <[email protected]> * Update console/src/assets/i18n/en.json Co-authored-by: Florian Forster <[email protected]> Co-authored-by: Florian Forster <[email protected]>
This commit is contained in:
co-authored by
Florian Forster
parent
8d1725a81d
commit
22ba33c2ef
@@ -1,103 +1,87 @@
|
||||
<div class="max-width-container">
|
||||
<div class="container">
|
||||
<div class="left">
|
||||
<a [routerLink]="[ '/users']" mat-icon-button>
|
||||
<mat-icon class="icon">arrow_back</mat-icon>
|
||||
</a>
|
||||
<app-detail-layout [backRouterLink]="[ '/users/all']" title="{{ 'USER.CREATE.TITLE' | translate }}"
|
||||
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
|
||||
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar>
|
||||
|
||||
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
|
||||
<div class="content">
|
||||
<p class="section">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.EMAIL' | translate }}</mat-label>
|
||||
<input matInput formControlName="email" required />
|
||||
<mat-error *ngIf="email?.invalid && email?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.USERNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="userName" required />
|
||||
<mat-error *ngIf="userName?.invalid && userName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="userName?.invalid && userName?.errors?.noEmailValidator">
|
||||
{{ 'USER.VALIDATION.NOEMAIL' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="firstName" required />
|
||||
<mat-error *ngIf="firstName?.invalid && firstName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="lastName" required />
|
||||
<mat-error *ngIf="lastName?.invalid && lastName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="nickName" />
|
||||
<mat-error *ngIf="nickName?.invalid && nickName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
|
||||
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.GENDER' | translate }}</mat-label>
|
||||
<mat-select formControlName="gender">
|
||||
<mat-option *ngFor="let gender of genders" [value]="gender">
|
||||
{{ 'GENDERS.'+gender | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="gender?.invalid && gender?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</mat-label>
|
||||
<mat-select formControlName="preferredLanguage">
|
||||
<mat-option *ngFor="let language of languages" [value]="language">
|
||||
{{ 'LANGUAGES.'+language | translate }}
|
||||
</mat-option>
|
||||
<mat-error *ngIf="preferredLanguage?.invalid && preferredLanguage?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.ADDRESSANDPHONESECTION' | translate }}</p>
|
||||
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.PHONE' | translate }}</mat-label>
|
||||
<input matInput formControlName="phone" />
|
||||
<mat-error *ngIf="phone?.invalid && phone?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="head">
|
||||
|
||||
<h1>{{ 'USER.CREATE.TITLE' | translate }}</h1>
|
||||
|
||||
<p class="desc">{{ 'USER.CREATE.DESCRIPTION' | translate }}</p>
|
||||
</div>
|
||||
|
||||
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar>
|
||||
|
||||
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
|
||||
<!-- <h2>{{ 'USER.PAGES.CREATE' | translate}}</h2> -->
|
||||
<div class="content">
|
||||
<p class="section">{{ 'USER.CREATE.NAMEANDEMAILSECTION' | translate }}</p>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.EMAIL' | translate }}</mat-label>
|
||||
<input matInput formControlName="email" required />
|
||||
<mat-error *ngIf="email?.invalid && email?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.USERNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="userName" required />
|
||||
<mat-error *ngIf="userName?.invalid && userName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="userName?.invalid && userName?.errors?.noEmailValidator">
|
||||
{{ 'USER.VALIDATION.NOEMAIL' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.FIRSTNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="firstName" required />
|
||||
<mat-error *ngIf="firstName?.invalid && firstName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.LASTNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="lastName" required />
|
||||
<mat-error *ngIf="lastName?.invalid && lastName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.NICKNAME' | translate }}</mat-label>
|
||||
<input matInput formControlName="nickName" />
|
||||
<mat-error *ngIf="nickName?.invalid && nickName?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.GENDERLANGSECTION' | translate }}</p>
|
||||
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.GENDER' | translate }}</mat-label>
|
||||
<mat-select formControlName="gender">
|
||||
<mat-option *ngFor="let gender of genders" [value]="gender">
|
||||
{{ 'GENDERS.'+gender | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="gender?.invalid && gender?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.PREFERRED_LANGUAGE' | translate }}</mat-label>
|
||||
<mat-select formControlName="preferredLanguage">
|
||||
<mat-option *ngFor="let language of languages" [value]="language">
|
||||
{{ 'LANGUAGES.'+language | translate }}
|
||||
</mat-option>
|
||||
<mat-error *ngIf="preferredLanguage?.invalid && preferredLanguage?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<p class="section">{{ 'USER.CREATE.ADDRESSANDPHONESECTION' | translate }}</p>
|
||||
|
||||
<mat-form-field class="formfield">
|
||||
<mat-label>{{ 'USER.PROFILE.PHONE' | translate }}</mat-label>
|
||||
<input matInput formControlName="phone" />
|
||||
<mat-error *ngIf="phone?.invalid && phone?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button color="primary" [disabled]="userForm.invalid" type="submit"
|
||||
mat-raised-button>{{ 'ACTIONS.CREATE' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="btn-container">
|
||||
<button color="primary" [disabled]="userForm.invalid" type="submit"
|
||||
mat-raised-button>{{ 'ACTIONS.CREATE' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</app-detail-layout>
|
||||
@@ -1,82 +1,33 @@
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
padding-bottom: 3rem;
|
||||
.form {
|
||||
width: 100%;
|
||||
padding-top: 1rem;
|
||||
|
||||
.left {
|
||||
width: 100px;
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
justify-content: center;
|
||||
|
||||
a {
|
||||
margin-top: .2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
.head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
flex-wrap: wrap;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
width: 100%;
|
||||
display: block;
|
||||
font-size: .9rem;
|
||||
color: #8795a1;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
padding-top: 1rem;
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
button {
|
||||
margin-top: 3rem;
|
||||
display: block;
|
||||
padding: 0.5rem 4rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
.section {
|
||||
padding: .5rem;
|
||||
flex-basis: 100%;
|
||||
color: #8795a1;
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
&.nowrap{
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
flex: 1 0 33%;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
.btn-container {
|
||||
button {
|
||||
margin-top: 3rem;
|
||||
display: block;
|
||||
padding: .5rem 4rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
display: flex wrap;
|
||||
flex-direction: row;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
.section {
|
||||
padding: .5rem;
|
||||
flex-basis: 100%;
|
||||
color: #8795a1;
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
.formfield {
|
||||
flex: 1 0 33%;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||
|
||||
import { UserCreateRoutingModule } from './user-create-routing.module';
|
||||
import { UserCreateComponent } from './user-create.component';
|
||||
@@ -34,6 +35,7 @@ import { UserCreateComponent } from './user-create.component';
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule,
|
||||
TranslateModule,
|
||||
DetailLayoutModule,
|
||||
],
|
||||
})
|
||||
export class UserCreateModule { }
|
||||
|
||||
+15
-13
@@ -1,6 +1,6 @@
|
||||
<app-meta-layout>
|
||||
<div class="max-width-container">
|
||||
<h1>{{ 'USER.TITLE' | translate }}</h1>
|
||||
<h1 class="h1">{{ 'USER.TITLE' | translate }}</h1>
|
||||
<p class="sub">{{'USER.DESCRIPTION' | translate}}</p>
|
||||
|
||||
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar>
|
||||
@@ -21,13 +21,13 @@
|
||||
</app-card>
|
||||
|
||||
<div class="col" *ngIf="user">
|
||||
<app-card title="{{ 'USER.PROFILE.TITLE' | translate }}">
|
||||
<app-card class="app-card" title="{{ 'USER.PROFILE.TITLE' | translate }}">
|
||||
<app-detail-form [genders]="genders" [languages]="languages" [profile]="user"
|
||||
(changedLanguage)="changedLanguage($event)" (submitData)="saveProfile($event)">
|
||||
</app-detail-form>
|
||||
</app-card>
|
||||
|
||||
<app-card title="Theme" class="theme-card">
|
||||
<app-card title="Theme" class="app-card theme-card">
|
||||
<app-theme-setting></app-theme-setting>
|
||||
</app-card>
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@
|
||||
<span>*********</span>
|
||||
<div class="actions">
|
||||
<a [routerLink]="['password']" mat-icon-button>
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
<mat-icon class="icon">chevron_right</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,11 +52,12 @@
|
||||
<ng-container *ngIf="!emailEditState; else emailEdit">
|
||||
<div class="actions">
|
||||
<span class="name">{{user?.email}}</span>
|
||||
<mat-icon *ngIf="user?.isEmailVerified" color="primary" aria-hidden="false"
|
||||
<mat-icon class="icon" *ngIf="user?.isEmailVerified" color="primary" aria-hidden="false"
|
||||
aria-label="verified icon">
|
||||
check_circle_outline</mat-icon>
|
||||
<ng-container *ngIf="user?.email && !user?.isEmailVerified">
|
||||
<mat-icon color="warn" aria-hidden="false" aria-label="not verified icon">highlight_off
|
||||
<mat-icon class="icon" color="warn" aria-hidden="false" aria-label="not verified icon">
|
||||
highlight_off
|
||||
</mat-icon>
|
||||
<a class="verify" matTooltip="{{'USER.LOGINMETHODS.EMAIL.RESEND' | translate}}"
|
||||
(click)="resendVerification()">{{'USER.LOGINMETHODS.RESENDCODE' | translate}}</a>
|
||||
@@ -65,7 +66,7 @@
|
||||
|
||||
<div class="actions">
|
||||
<button (click)="emailEditState = true" mat-icon-button>
|
||||
<mat-icon>edit</mat-icon>
|
||||
<mat-icon class="icon">edit</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
@@ -75,7 +76,7 @@
|
||||
<input matInput [(ngModel)]="user.email" />
|
||||
</mat-form-field>
|
||||
<button (click)="emailEditState = false" mat-icon-button>
|
||||
<mat-icon>close</mat-icon>
|
||||
<mat-icon class="icon">close</mat-icon>
|
||||
</button>
|
||||
<button [disabled]="!user.email" class="submit-button" type="button" color="primary"
|
||||
(click)="saveEmail()" mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
@@ -88,11 +89,12 @@
|
||||
<ng-container *ngIf="!phoneEditState; else phoneEdit">
|
||||
<div class="actions">
|
||||
<span class="name">{{user?.phone}}</span>
|
||||
<mat-icon *ngIf="user?.isPhoneVerified" color="primary" aria-hidden="false"
|
||||
<mat-icon class="icon" *ngIf="user?.isPhoneVerified" color="primary" aria-hidden="false"
|
||||
aria-label="verified icon">
|
||||
check_circle_outline</mat-icon>
|
||||
<ng-container *ngIf="user?.phone && !user?.isPhoneVerified">
|
||||
<mat-icon color="warn" aria-hidden="false" aria-label="not verified icon">highlight_off
|
||||
<mat-icon class="icon" color="warn" aria-hidden="false" aria-label="not verified icon">
|
||||
highlight_off
|
||||
</mat-icon>
|
||||
<a class="verify" matTooltip="{{'USER.LOGINMETHODS.ENTERCODE_DESC' | translate}}"
|
||||
(click)="enterCode()">{{'USER.LOGINMETHODS.ENTERCODE' | translate}}</a>
|
||||
@@ -103,7 +105,7 @@
|
||||
|
||||
<div class="actions">
|
||||
<button (click)="phoneEditState = true" mat-icon-button>
|
||||
<mat-icon>edit</mat-icon>
|
||||
<mat-icon class="icon">edit</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
@@ -114,7 +116,7 @@
|
||||
<input matInput [(ngModel)]="user.phone" />
|
||||
</mat-form-field>
|
||||
<button (click)="phoneEditState = false" mat-icon-button>
|
||||
<mat-icon>close</mat-icon>
|
||||
<mat-icon class="icon">close</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="user.phone" color="warn" (click)="deletePhone()" mat-icon-button>
|
||||
<i class="las la-trash"></i>
|
||||
@@ -137,6 +139,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-changes [changeType]="ChangeType.MYUSER" [id]="user.id"></app-changes>
|
||||
<app-changes class="changes" [changeType]="ChangeType.MYUSER" [id]="user.id"></app-changes>
|
||||
</div>
|
||||
</app-meta-layout>
|
||||
+124
-256
@@ -1,286 +1,154 @@
|
||||
h1 {
|
||||
.h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.avatar-section {
|
||||
.sub {
|
||||
color: #8795a1;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.login-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
color: #8795a1;
|
||||
text-transform: uppercase;
|
||||
margin-right: 3rem;
|
||||
font-size: .9rem;
|
||||
button {
|
||||
transition: opacity .15s ease-in-out;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
||||
&[disabled] {
|
||||
visibility: visible;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
img {
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 50%;
|
||||
margin: .5rem;
|
||||
border: 2px solid #8795a1;
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sub {
|
||||
color: #8795a1;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.login-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
transition: opacity .15s ease-in-out;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
||||
&[disabled] {
|
||||
visibility: visible;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
&.nowrap{
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
flex: 1;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.method-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: -.5rem;
|
||||
|
||||
.method-row {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
button {
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
padding: .5rem;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.label,
|
||||
.name {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.actions {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1;
|
||||
font-size: .9rem;
|
||||
color: #8795a1;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
border-radius: .5rem;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
|
||||
.verify {
|
||||
text-decoration: none;
|
||||
font-size: .8rem;
|
||||
color: #8795a1;
|
||||
border-radius: .5rem;
|
||||
cursor: pointer;
|
||||
word-wrap: none;
|
||||
white-space: nowrap;
|
||||
margin-right: 1rem;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.method-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: -.5rem;
|
||||
|
||||
.method-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
padding: .5rem;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.label, .name {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.actions {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1;
|
||||
font-size: .9rem;
|
||||
color: #8795a1;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.verify {
|
||||
text-decoration: none;
|
||||
font-size: .8rem;
|
||||
color: #8795a1;
|
||||
border-radius: .5rem;
|
||||
cursor: pointer;
|
||||
word-wrap: none;
|
||||
white-space: nowrap;
|
||||
margin-right: 1rem;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.col {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
margin: -.5rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
margin: -1.5rem -.5rem;
|
||||
|
||||
app-card {
|
||||
flex: 1;
|
||||
margin: .5rem
|
||||
}
|
||||
.app-card {
|
||||
flex: 1;
|
||||
margin: .5rem;
|
||||
}
|
||||
|
||||
.theme-card {
|
||||
max-width: 300px;
|
||||
}
|
||||
.theme-card {
|
||||
max-width: 300px;
|
||||
|
||||
.pwd-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #8795a1;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
@media only screen and (max-width: 450px) {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side {
|
||||
.details {
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #81868a40;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
margin-bottom: 0.5rem;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
display: inline-block;
|
||||
visibility: visible;
|
||||
mat-icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.first {
|
||||
flex: 1;
|
||||
font-size: 0.8rem;
|
||||
margin-right: 0.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.second {
|
||||
font-size: 0.8rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-left: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
.details {
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #81868a40;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
margin-bottom: .5rem;
|
||||
align-items: center;
|
||||
|
||||
.side-section {
|
||||
color: #8795a1;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #81868a40;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
margin-bottom: 0.5rem;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
display: inline-block;
|
||||
visibility: visible;
|
||||
mat-icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.first {
|
||||
flex: 1;
|
||||
font-size: 0.8rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.second {
|
||||
font-size: 0.8rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side-section {
|
||||
color: #8795a1;
|
||||
}
|
||||
}
|
||||
|
||||
app-changes {
|
||||
.first {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
font-size: .8rem;
|
||||
margin-right: .5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.second {
|
||||
font-size: .8rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-left: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.changes {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
<app-card title="{{'USER.MFA.TITLE' | translate}}" description="{{'USER.MFA.DESCRIPTION' | translate}}">
|
||||
<app-refresh-table [loading]="loading$ | async" (refreshed)="getOTP()" [dataSize]="dataSource?.data?.length">
|
||||
<table class="background-style" mat-table [dataSource]="dataSource">
|
||||
<table class="table background-style" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.MFA.TABLETYPE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa"> {{'USER.MFA.TYPE.'+ mfa.type | translate}} </td>
|
||||
@@ -33,9 +33,9 @@
|
||||
</table>
|
||||
</app-refresh-table>
|
||||
<div class="add-row">
|
||||
<button *ngIf="otpAvailable" (click)="addOTP()" mat-stroked-button color="primary"
|
||||
<button class="button" *ngIf="otpAvailable" (click)="addOTP()" mat-stroked-button color="primary"
|
||||
matTooltip="{{'ACTIONS.NEW' | translate}}">
|
||||
<mat-icon svgIcon="mdi_radar"></mat-icon>{{'USER.MFA.OTP' | translate}}
|
||||
<mat-icon class="icon" svgIcon="mdi_radar"></mat-icon>{{'USER.MFA.OTP' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
|
||||
+37
-36
@@ -1,40 +1,41 @@
|
||||
|
||||
.add-row {
|
||||
display: flex;
|
||||
margin: -.5rem;
|
||||
.add-row {
|
||||
display: flex;
|
||||
margin: -.5rem;
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
margin: .5rem;
|
||||
margin-top: 1rem;
|
||||
.button {
|
||||
border-radius: .5rem;
|
||||
margin: .5rem;
|
||||
margin-top: 1rem;
|
||||
|
||||
mat-icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
margin-left: 1rem;
|
||||
color: #5282c1;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
td, th {
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
.icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
margin-left: 1rem;
|
||||
color: #5282c1;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
|
||||
td,
|
||||
th {
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -1,16 +1,16 @@
|
||||
.formfield {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.ok-button {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.ok-button {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<qrcode *ngIf="data" class="qrcode" [qrdata]="data" [width]="150" [errorCorrectionLevel]="'M'"></qrcode>
|
||||
</div>
|
||||
|
||||
<mat-form-field label="Access Code" required="true">
|
||||
<mat-form-field class="form-field" label="Access Code" required="true">
|
||||
<mat-label>Code</mat-label>
|
||||
<input matInput [(ngModel)]="code" />
|
||||
</mat-form-field>
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
.form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action {
|
||||
|
||||
+9
-6
@@ -1,11 +1,14 @@
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
@mixin theme-card($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-dark: mat-color($primary, A800);
|
||||
/* stylelint-disable */
|
||||
$primary: map-get($theme, primary);
|
||||
$primary-dark: mat-color($primary, A800);
|
||||
/* stylelint-enable */
|
||||
|
||||
.theme-conent, .crescent {
|
||||
background-color: $primary-dark;
|
||||
transition: background-color .4s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
.theme-conent,
|
||||
.crescent {
|
||||
background-color: $primary-dark;
|
||||
transition: background-color .4s cubic-bezier(.645, .045, .355, 1);
|
||||
}
|
||||
}
|
||||
|
||||
+23
-22
@@ -2,11 +2,11 @@ $dark-background: #2d2e30;
|
||||
$light-background: #fafafa;
|
||||
|
||||
:root {
|
||||
transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.theme-app {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.theme-content {
|
||||
@@ -20,9 +20,9 @@ $light-background: #fafafa;
|
||||
border-radius: 100%;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
background: linear-gradient(40deg, #FF0080,#FF8C00 70%);
|
||||
background: linear-gradient(40deg, #ff0080, #ff8c00 70%);
|
||||
margin: auto;
|
||||
box-shadow: 0 30px 60px rgba(0,0,0,0.12);
|
||||
box-shadow: 0 30px 60px rgba(0, 0, 0, .12);
|
||||
}
|
||||
|
||||
.crescent {
|
||||
@@ -34,10 +34,10 @@ $light-background: #fafafa;
|
||||
background: $light-background;
|
||||
transform: scale(0);
|
||||
transform-origin: top right;
|
||||
transition: transform .4s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
transition: transform .4s cubic-bezier(.645, .045, .355, 1);
|
||||
}
|
||||
|
||||
p {
|
||||
p {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
@@ -48,28 +48,29 @@ p {
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
color: #8795a1;
|
||||
font-size: 14px;
|
||||
color: #8795a1;
|
||||
}
|
||||
|
||||
label, .toggle {
|
||||
label,
|
||||
.toggle {
|
||||
height: 2.8rem;
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
label {
|
||||
width: 100%;
|
||||
background-color: rgba(0,0,0,.1);
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
border-radius: 100px;
|
||||
position: relative;
|
||||
margin: 1rem 0 1rem 0;
|
||||
margin: 1rem 0 1rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
position: absolute;
|
||||
background-color: $light-background;
|
||||
box-shadow: 0 2px 15px rgba(0,0,0,.15);
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
.names {
|
||||
@@ -88,33 +89,33 @@ label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app .toggle{
|
||||
[type="checkbox"]:checked + .theme-app .toggle {
|
||||
transform: translateX(100%);
|
||||
background-color: $dark-background;
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app .dark{
|
||||
[type="checkbox"]:checked + .theme-app .dark {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app .light{
|
||||
[type="checkbox"]:checked + .theme-app .light {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app{
|
||||
[type="checkbox"]:checked + .theme-app {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app .crescent{
|
||||
[type="checkbox"]:checked + .theme-app .crescent {
|
||||
transform: scale(1);
|
||||
background: $dark-background;
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app .circle{
|
||||
background: linear-gradient(40deg, #8983F7, #A3DAFB 70%);
|
||||
[type="checkbox"]:checked + .theme-app .circle {
|
||||
background: linear-gradient(40deg, #8983f7, #a3dafb 70%);
|
||||
}
|
||||
|
||||
[type="checkbox"]:checked + .theme-app .main-circle{
|
||||
background: linear-gradient(40deg, #8983F7, #A3DAFB 70%);
|
||||
}
|
||||
[type="checkbox"]:checked + .theme-app .main-circle {
|
||||
background: linear-gradient(40deg, #8983f7, #a3dafb 70%);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button type="submit" color="primary" mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
<button class="submit-button" type="submit" color="primary"
|
||||
mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,25 +1,21 @@
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
&.nowrap{
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
flex: 1 1 33%;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
.formfield {
|
||||
flex: 1 1 33%;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.submit-button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,151 +1,76 @@
|
||||
<div class="max-width-container">
|
||||
<div class="container">
|
||||
<div class="left">
|
||||
<a *ngIf="userId" [routerLink]="[ '/user',userId]" mat-icon-button>
|
||||
<mat-icon class="icon">arrow_back</mat-icon>
|
||||
</a>
|
||||
<a *ngIf="!userId" [routerLink]="[ '/users/me']" mat-icon-button>
|
||||
<mat-icon class="icon">arrow_back</mat-icon>
|
||||
</a>
|
||||
<app-detail-layout [backRouterLink]="userId ? [ '/users',userId] : [ '/users/me']"
|
||||
title="{{ 'USER.PASSWORD.TITLE' | translate }}" description="{{ 'USER.PASSWORD.DESCRIPTION' | translate }}">
|
||||
|
||||
<ng-container *ngIf="userId; else authUser">
|
||||
<div class="validation" *ngIf="this.policy">
|
||||
<app-password-complexity-view [policy]="this.policy" [password]="password">
|
||||
</app-password-complexity-view>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="head">
|
||||
<h1>{{ 'USER.PASSWORD.TITLE' | translate }}</h1>
|
||||
<p class="desc">{{ 'USER.PASSWORD.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<form *ngIf="passwordForm" autocomplete="new-password" [formGroup]="passwordForm"
|
||||
(ngSubmit)="setInitialPassword(userId)">
|
||||
<div class="content center">
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="password" matInput formControlName="password" type="password" />
|
||||
|
||||
<mat-error *ngIf="password?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="passwordRepeat" matInput formControlName="confirmPassword"
|
||||
type="password" />
|
||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button
|
||||
color="primary">{{ 'USER.PASSWORD.SET' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="userId; else authUser">
|
||||
<form *ngIf="passwordForm" autocomplete="new-password" [formGroup]="passwordForm"
|
||||
(ngSubmit)="setInitialPassword(userId)">
|
||||
<div class="content center">
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="password" matInput formControlName="password"
|
||||
type="password" />
|
||||
<ng-template #authUser>
|
||||
<form *ngIf="passwordForm" [formGroup]="passwordForm" (ngSubmit)="setPassword()">
|
||||
<div class="content">
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.OLD' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="password" type="password" matInput
|
||||
formControlName="currentPassword" />
|
||||
<mat-error *ngIf="currentPassword?.errors?.required">
|
||||
{{ 'USER.PASSWORD.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-error *ngIf="password?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="password?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:password?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="passwordRepeat" matInput formControlName="confirmPassword"
|
||||
type="password" />
|
||||
<div class="validation between" *ngIf="this.policy">
|
||||
<app-password-complexity-view [policy]="this.policy" [password]="newPassword">
|
||||
</app-password-complexity-view>
|
||||
</div>
|
||||
|
||||
<mat-error *ngIf="confirmPassword?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:confirmPassword?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="btn-container">
|
||||
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button
|
||||
color="primary">{{ 'USER.PASSWORD.SET' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</ng-container>
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="new password" type="password" matInput
|
||||
formControlName="newPassword" />
|
||||
|
||||
<ng-template #authUser>
|
||||
<form *ngIf="passwordForm" [formGroup]="passwordForm" (ngSubmit)="setPassword()">
|
||||
<div class="content">
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.OLD' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="password" type="password" matInput
|
||||
formControlName="currentPassword" />
|
||||
<mat-error *ngIf="currentPassword?.errors?.required">
|
||||
{{ 'USER.PASSWORD.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.NEW' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="new password" type="password" matInput
|
||||
formControlName="newPassword" />
|
||||
|
||||
<mat-error *ngIf="newPassword?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="newPassword?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="newPassword?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="newPassword?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="newPassword?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="newPassword?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:newPassword?.errors?.minlength }}
|
||||
</mat-error>
|
||||
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="password repeating" type="password" matInput
|
||||
formControlName="confirmPassword" />
|
||||
|
||||
<mat-error *ngIf="confirmPassword?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.symbolValidator">
|
||||
{{ 'USER.VALIDATION.SYMBOLERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.numberValidator">
|
||||
{{ 'USER.VALIDATION.NUMBERERROR' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.upperCaseValidator">
|
||||
{{ 'USER.VALIDATION.UPPERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.lowerCaseValidator">
|
||||
{{ 'USER.VALIDATION.LOWERCASEMISSING' | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="confirmPassword?.errors?.minlength">
|
||||
{{ 'USER.VALIDATION.MINLENGTH' | translate:confirmPassword?.errors?.minlength }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button
|
||||
color="primary">{{ 'USER.PASSWORD.RESET' | translate }}</button>
|
||||
</form>
|
||||
</ng-template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<mat-error *ngIf="newPassword?.errors?.required">
|
||||
{{ 'USER.VALIDATION.REQUIRED' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="formfield" appearance="outline">
|
||||
<mat-label>{{ 'USER.PASSWORD.CONFIRM' | translate }}</mat-label>
|
||||
<input autocomplete="off" name="password repeating" type="password" matInput
|
||||
formControlName="confirmPassword" />
|
||||
<mat-error *ngIf="confirmPassword?.errors?.notequal">
|
||||
{{ 'USER.PASSWORD.NOTEQUAL' | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<button class="submit-button" [disabled]="passwordForm.invalid" mat-raised-button
|
||||
color="primary">{{ 'USER.PASSWORD.RESET' | translate }}</button>
|
||||
</form>
|
||||
</ng-template>
|
||||
</app-detail-layout>
|
||||
@@ -1,66 +1,34 @@
|
||||
.container {
|
||||
display: flex;
|
||||
padding-bottom: 3rem;
|
||||
|
||||
.left {
|
||||
width: 100px;
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
justify-content: center;
|
||||
|
||||
a {
|
||||
margin-top: .2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
padding-top: 1rem;
|
||||
|
||||
.head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
margin-bottom: 2rem;
|
||||
flex-wrap: wrap;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin-top: 0.2rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
width: 100%;
|
||||
display: block;
|
||||
font-size: .9rem;
|
||||
color: #8795a1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
mat-form-field {
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
|
||||
&.center {
|
||||
align-items: center;
|
||||
}
|
||||
.formfield {
|
||||
margin: 0 .5rem;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
&.center {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.validation {
|
||||
&.between {
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
margin-top: 100px;
|
||||
display: block;
|
||||
padding: 0.5rem 4rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
margin-top: 100px;
|
||||
display: block;
|
||||
padding: .5rem 4rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.mat-error {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { lowerCaseValidator, numberValidator, symbolValidator, upperCaseValidator } from 'src/app/pages/validators';
|
||||
import { PasswordComplexityPolicy } from 'src/app/proto/generated/auth_pb';
|
||||
import { AuthUserService } from 'src/app/services/auth-user.service';
|
||||
@@ -27,12 +28,14 @@ function passwordConfirmValidator(c: AbstractControl): any {
|
||||
templateUrl: './password.component.html',
|
||||
styleUrls: ['./password.component.scss'],
|
||||
})
|
||||
export class PasswordComponent implements OnInit {
|
||||
export class PasswordComponent implements OnDestroy {
|
||||
userId: string = '';
|
||||
|
||||
public policy!: PasswordComplexityPolicy.AsObject;
|
||||
public passwordForm!: FormGroup;
|
||||
|
||||
private formSub: Subscription = new Subscription();
|
||||
|
||||
constructor(
|
||||
activatedRoute: ActivatedRoute,
|
||||
private fb: FormBuilder,
|
||||
@@ -73,7 +76,8 @@ export class PasswordComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
public ngOnDestroy(): void {
|
||||
this.formSub.unsubscribe();
|
||||
}
|
||||
|
||||
setupForm(validators: Validators[]): void {
|
||||
|
||||
@@ -20,11 +20,15 @@ const routes: Routes = [
|
||||
path: 'me',
|
||||
component: AuthUserDetailComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
animation: 'HomePage',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'me/password',
|
||||
component: PasswordComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: { animation: 'AddPage' },
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
@@ -32,6 +36,7 @@ const routes: Routes = [
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['user.read'],
|
||||
animation: 'HomePage',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -40,6 +45,7 @@ const routes: Routes = [
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['user.write'],
|
||||
animation: 'AddPage',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -17,7 +17,9 @@ import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { ChangesModule } from 'src/app/modules/changes/changes.module';
|
||||
import { DetailLayoutModule } from 'src/app/modules/detail-layout/detail-layout.module';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { PasswordComplexityViewModule } from 'src/app/modules/password-complexity-view/password-complexity-view.module';
|
||||
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
|
||||
@@ -72,6 +74,8 @@ import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component';
|
||||
SharedModule,
|
||||
RefreshTableModule,
|
||||
CopyToClipboardModule,
|
||||
DetailLayoutModule,
|
||||
PasswordComplexityViewModule,
|
||||
],
|
||||
})
|
||||
export class UserDetailModule { }
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
color="primary"
|
||||
*ngIf="user.state === UserState.USERSTATE_INITIAL">{{ 'USER.PASSWORD.RESENDNOTIFICATION' | translate }}</button>
|
||||
<a [routerLink]="['password']" mat-icon-button>
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
<mat-icon class="icon">chevron_right</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -66,11 +66,12 @@
|
||||
<ng-container *ngIf="!emailEditState; else emailEdit">
|
||||
<div class="actions">
|
||||
<span class="name">{{user?.email}}</span>
|
||||
<mat-icon *ngIf="user?.isEmailVerified" color="primary" aria-hidden="false"
|
||||
<mat-icon class="icon" *ngIf="user?.isEmailVerified" color="primary" aria-hidden="false"
|
||||
aria-label="verified icon">
|
||||
check_circle_outline</mat-icon>
|
||||
<ng-container *ngIf="user?.email && !user?.isEmailVerified">
|
||||
<mat-icon color="warn" aria-hidden="false" aria-label="not verified icon">highlight_off
|
||||
<mat-icon class="icon" color="warn" aria-hidden="false" aria-label="not verified icon">
|
||||
highlight_off
|
||||
</mat-icon>
|
||||
<a class="verify" matTooltip="{{'USER.LOGINMETHODS.EMAIL.RESEND' | translate}}"
|
||||
(click)="resendVerification()">{{'USER.LOGINMETHODS.RESENDCODE' | translate}}</a>
|
||||
@@ -79,7 +80,7 @@
|
||||
|
||||
<div class="actions">
|
||||
<button (click)="emailEditState = true" mat-icon-button>
|
||||
<mat-icon>edit</mat-icon>
|
||||
<mat-icon class="icon">edit</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
@@ -89,7 +90,7 @@
|
||||
<input matInput [(ngModel)]="user.email" />
|
||||
</mat-form-field>
|
||||
<button (click)="emailEditState = false" mat-icon-button>
|
||||
<mat-icon>close</mat-icon>
|
||||
<mat-icon class="icon">close</mat-icon>
|
||||
</button>
|
||||
<button [disabled]="!user.email" class="submit-button" type="button" color="primary"
|
||||
(click)="saveEmail()" mat-raised-button>{{ 'ACTIONS.SAVE' | translate }}</button>
|
||||
@@ -102,11 +103,12 @@
|
||||
<ng-container *ngIf="!phoneEditState; else phoneEdit">
|
||||
<div class="actions">
|
||||
<span class="name">{{user?.phone}}</span>
|
||||
<mat-icon *ngIf="user?.isPhoneVerified" color="primary" aria-hidden="false"
|
||||
<mat-icon class="icon" *ngIf="user?.isPhoneVerified" color="primary" aria-hidden="false"
|
||||
aria-label="verified icon">
|
||||
check_circle_outline</mat-icon>
|
||||
<ng-container *ngIf="user?.phone && !user?.isPhoneVerified">
|
||||
<mat-icon color="warn" aria-hidden="false" aria-label="not verified icon">highlight_off
|
||||
<mat-icon class="icon" color="warn" aria-hidden="false" aria-label="not verified icon">
|
||||
highlight_off
|
||||
</mat-icon>
|
||||
<a class="verify" matTooltip="{{'USER.LOGINMETHODS.PHONE.RESEND' | translate}}"
|
||||
(click)="resendPhoneVerification()">{{'USER.LOGINMETHODS.RESENDCODE' | translate}}</a>
|
||||
@@ -115,7 +117,7 @@
|
||||
|
||||
<div class="actions">
|
||||
<button (click)="phoneEditState = true" mat-icon-button>
|
||||
<mat-icon>edit</mat-icon>
|
||||
<mat-icon class="icon">edit</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
@@ -126,7 +128,7 @@
|
||||
<input matInput [(ngModel)]="user.phone" />
|
||||
</mat-form-field>
|
||||
<button (click)="phoneEditState = false" mat-icon-button>
|
||||
<mat-icon>close</mat-icon>
|
||||
<mat-icon class="icon">close</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="user.phone" color="warn" (click)="deletePhone()" mat-icon-button>
|
||||
<i class="las la-trash"></i>
|
||||
@@ -156,6 +158,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-changes [changeType]="ChangeType.USER" [id]="user.id"></app-changes>
|
||||
<app-changes class="changes" [changeType]="ChangeType.USER" [id]="user.id"></app-changes>
|
||||
</div>
|
||||
</app-meta-layout>
|
||||
@@ -6,121 +6,91 @@
|
||||
padding-bottom: .5rem;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
margin-right: 2rem;
|
||||
display: block;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
margin-right: 1rem;
|
||||
font-size: 2rem;
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.state-button {
|
||||
border-radius: .5rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
&.nowrap{
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
&.center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
flex: 1 1 33%;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 0 -.5rem;
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
margin: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.method-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: -.5rem;
|
||||
|
||||
.method-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
padding: .5rem;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.label, .name {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.actions {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: -.5rem;
|
||||
|
||||
.notify-change-pwd {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1;
|
||||
font-size: .9rem;
|
||||
color: #818a8a;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.verify {
|
||||
text-decoration: none;
|
||||
font-size: .8rem;
|
||||
color: #8795a1;
|
||||
border-radius: .5rem;
|
||||
cursor: pointer;
|
||||
word-wrap: none;
|
||||
white-space: nowrap;
|
||||
margin-right: 1rem;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
.method-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
padding: .5rem;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.label,
|
||||
.name {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.actions {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.notify-change-pwd {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1;
|
||||
font-size: .9rem;
|
||||
color: #818a8a;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.verify {
|
||||
text-decoration: none;
|
||||
font-size: .8rem;
|
||||
color: #8795a1;
|
||||
border-radius: .5rem;
|
||||
cursor: pointer;
|
||||
word-wrap: none;
|
||||
white-space: nowrap;
|
||||
margin-right: 1rem;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-phone-email {
|
||||
@@ -128,120 +98,35 @@
|
||||
}
|
||||
|
||||
.side {
|
||||
.details {
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #81868a40;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
margin-bottom: 0.5rem;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
display: inline-block;
|
||||
visibility: visible;
|
||||
mat-icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.first {
|
||||
flex: 1;
|
||||
font-size: 0.8rem;
|
||||
margin-right: 0.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.second {
|
||||
font-size: 0.8rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-left: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
.details {
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #81868a40;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
margin-bottom: .5rem;
|
||||
align-items: center;
|
||||
|
||||
.side-section {
|
||||
color: #8795a1;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #81868a40;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
margin-bottom: 0.5rem;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
display: inline-block;
|
||||
visibility: visible;
|
||||
mat-icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.first {
|
||||
flex: 1;
|
||||
font-size: 0.8rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.second {
|
||||
font-size: 0.8rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side-section {
|
||||
color: #8795a1;
|
||||
}
|
||||
}
|
||||
|
||||
app-changes {
|
||||
.first {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
font-size: .8rem;
|
||||
margin-right: .5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.second {
|
||||
font-size: .8rem;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin-left: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.changes {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<app-card title="{{'USER.MFA.TITLE' | translate}}" description="{{'USER.MFA.DESCRIPTION' | translate}}">
|
||||
<app-refresh-table [loading]="loading$ | async" (refreshed)="getOTP()" [dataSize]="dataSource?.data?.length">
|
||||
<table class="background-style" mat-table [dataSource]="dataSource">
|
||||
<table class="table background-style" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.MFA.TABLETYPE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa"> {{'USER.MFA.TYPE.'+ mfa.type | translate}} </td>
|
||||
|
||||
+31
-30
@@ -1,43 +1,44 @@
|
||||
|
||||
.col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
margin-bottom: 1rem;
|
||||
justify-content: space-between;
|
||||
padding: .5rem 0;
|
||||
align-items: center;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: .5rem 0;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
}
|
||||
span {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
margin-left: 1rem;
|
||||
color: #5282c1;
|
||||
}
|
||||
i {
|
||||
margin-left: 1rem;
|
||||
color: #5282c1;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
.table {
|
||||
width: 100%;
|
||||
|
||||
td, th {
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</ng-template>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table class="background-style" mat-table [dataSource]="dataSource">
|
||||
<table class="table background-style" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"
|
||||
@@ -66,8 +66,8 @@
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<mat-paginator #paginator class="background-style" [length]="userResult?.totalResult || 0" [pageSize]="10"
|
||||
[pageSizeOptions]="[5, 10, 20]" (page)="changePage($event)"></mat-paginator>
|
||||
<mat-paginator #paginator class="paginator background-style" [length]="userResult?.totalResult || 0"
|
||||
[pageSize]="10" [pageSizeOptions]="[5, 10, 20]" (page)="changePage($event)"></mat-paginator>
|
||||
</div>
|
||||
</app-refresh-table>
|
||||
</div>
|
||||
@@ -1,44 +1,47 @@
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.sub {
|
||||
color: #8795a1;
|
||||
margin-bottom: 2rem;
|
||||
color: #8795a1;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.add-button {
|
||||
border-radius: .5rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
overflow: auto;
|
||||
overflow: auto;
|
||||
|
||||
table, mat-paginator {
|
||||
width: 100%;
|
||||
.table,
|
||||
.paginator {
|
||||
width: 100%;
|
||||
|
||||
td, th {
|
||||
padding: 0 1rem;
|
||||
td,
|
||||
th {
|
||||
padding: 0 1rem;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.data-row {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #ffffff05;
|
||||
}
|
||||
}
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.data-row {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #ffffff05;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
outline: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user