fix(console): user create loading state and i18n, improved app create stepper, invalid token dialog, cleanup, new home (#509)

* fix iam member model

* fix org member model

* fix auth user loading

* copytoclipboard directive

* directive logs, load bar on init, create user

* typo

* welcome section, contributor spinner

* fix home link

* fix stepper flow

* show dialog on invalid token

* fix app table refresh, pin icons light theme

* cleanup contributor

* Update console/src/assets/i18n/en.json

Co-authored-by: Florian Forster <florian@caos.ch>

* Update console/src/assets/i18n/de.json

Co-authored-by: Florian Forster <florian@caos.ch>

* Update console/src/assets/i18n/de.json

Co-authored-by: Florian Forster <florian@caos.ch>

* Update console/src/assets/i18n/de.json

Co-authored-by: Florian Forster <florian@caos.ch>

Co-authored-by: Florian Forster <florian@caos.ch>
This commit is contained in:
Max Peintner
2020-07-24 09:48:58 +02:00
committed by GitHub
parent c105bf483b
commit af60b88997
73 changed files with 581 additions and 487 deletions

View File

@@ -13,6 +13,8 @@
<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">

View File

@@ -39,6 +39,7 @@ export class UserCreateComponent implements OnDestroy {
private sub: Subscription = new Subscription();
public userLoginMustBeDomain: boolean = false;
public loading: boolean = false;
constructor(
private router: Router,
@@ -47,12 +48,15 @@ export class UserCreateComponent implements OnDestroy {
private fb: FormBuilder,
private orgService: OrgService,
) {
this.loading = true;
this.orgService.GetMyOrgIamPolicy().then((iampolicy) => {
this.userLoginMustBeDomain = iampolicy.toObject().userLoginMustBeDomain;
this.initForm();
this.loading = false;
}).catch(error => {
console.error(error);
this.initForm();
this.loading = false;
});
}
@@ -83,13 +87,16 @@ export class UserCreateComponent implements OnDestroy {
public createUser(): void {
this.user = this.userForm.value;
this.loading = true;
this.userService
.CreateUser(this.user)
.then((data: User) => {
this.loading = false;
this.toast.showInfo('USER.TOAST.CREATED', true);
this.router.navigate(['users', data.getId()]);
})
.catch(error => {
this.loading = false;
this.toast.showError(error);
});
}

View File

@@ -6,6 +6,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatTooltipModule } from '@angular/material/tooltip';
@@ -29,6 +30,7 @@ import { UserCreateComponent } from './user-create.component';
MatButtonModule,
MatIconModule,
MatProgressSpinnerModule,
MatProgressBarModule,
MatCheckboxModule,
MatTooltipModule,
TranslateModule,

View File

@@ -13,7 +13,7 @@
<span>{{login}}</span>
<button color="primary" [disabled]="copied == login"
[matTooltip]="(copied != login ? 'USER.PAGES.COPY' : 'USER.PAGES.COPIED' ) | translate"
(click)="copytoclipboard(login)" mat-icon-button>
appCopyToClipboard [valueToCopy]="login" (copiedValue)="copied = $event" mat-icon-button>
<i *ngIf="copied != login" class="las la-clipboard"></i>
<i *ngIf="copied == login" class="las la-clipboard-check"></i>
</button>

View File

@@ -39,9 +39,11 @@ export class AuthUserDetailComponent implements OnDestroy {
private dialog: MatDialog,
) {
this.loading = true;
this.getData().then(() => {
this.userService.GetMyUser().then(user => {
this.user = user.toObject();
this.loading = false;
}).catch(error => {
this.toast.showError(error);
this.loading = false;
});
}
@@ -149,30 +151,4 @@ export class AuthUserDetailComponent implements OnDestroy {
this.phoneEditState = false;
});
}
private async getData(): Promise<void> {
this.userService.GetMyUser().then(user => {
this.user = user.toObject();
}).catch(error => {
this.toast.showError(error);
});
}
public copytoclipboard(value: string): void {
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = value;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
this.copied = value;
setTimeout(() => {
this.copied = '';
}, 3000);
}
}

View File

@@ -60,7 +60,6 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy {
public getOTP(): void {
this.service.GetMyMfas().then(mfas => {
console.log(mfas.toObject().mfasList);
this.dataSource = new MatTableDataSource(mfas.toObject().mfasList);
this.dataSource.sort = this.sort;

View File

@@ -0,0 +1,11 @@
@import '~@angular/material/theming';
@mixin theme-card($theme) {
$primary: map-get($theme, primary);
$primary-dark: mat-color($primary, A800);
.theme-conent, .theme-app , .crescent {
background-color: $primary-dark;
transition: background-color .4s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}

View File

@@ -1,4 +1,5 @@
$dark-background: #2d2e30;
$light-background: #fafafa;
:root {
transition: none;
@@ -21,6 +22,7 @@ $dark-background: #2d2e30;
height: 6rem;
background: linear-gradient(40deg, #FF0080,#FF8C00 70%);
margin: auto;
box-shadow: 0 30px 60px rgba(0,0,0,0.12);
}
.crescent {
@@ -29,10 +31,10 @@ $dark-background: #2d2e30;
right: 0;
width: 4rem;
height: 4rem;
background: #fafafa;
background: $light-background;
transform: scale(0);
transform-origin: top right;
transition: transform .6s cubic-bezier(0.645, 0.045, 0.355, 1);
transition: transform .4s cubic-bezier(0.645, 0.045, 0.355, 1);
}
p {
@@ -66,7 +68,7 @@ label {
.toggle {
position: absolute;
background-color: #fafafa;
background-color: $light-background;
box-shadow: 0 2px 15px rgba(0,0,0,.15);
}
@@ -101,7 +103,7 @@ label {
[type="checkbox"]:checked + .theme-app{
background-color: $dark-background;
color: #fafafa;
color: $light-background;
}
[type="checkbox"]:checked + .theme-app .crescent{

View File

@@ -13,6 +13,7 @@ import { MatTableModule } from '@angular/material/table';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { QRCodeModule } from 'angularx-qrcode';
import { CopyToClipboardModule } from 'src/app/directives/copy-to-clipboard/copy-to-clipboard.module';
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';
@@ -70,6 +71,7 @@ import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component';
MatPaginatorModule,
SharedModule,
RefreshTableModule,
CopyToClipboardModule,
],
})
export class UserDetailModule { }

View File

@@ -25,12 +25,13 @@
<app-card title="{{ 'USER.PAGES.LOGINNAMES' | translate }}"
description="{{ 'USER.PAGES.LOGINNAMESDESC' | translate }}" *ngIf="user">
<div class="login-name-row" *ngFor="let login of user?.loginNamesList">
<span>{{login}}</span>
<span>{{login}} </span>
<button color="primary" [disabled]="copied == login"
[matTooltip]="(copied != login ? 'USER.PAGES.COPY' : 'USER.PAGES.COPIED' ) | translate"
(click)="copytoclipboard(login)" mat-icon-button>
appCopyToClipboard [valueToCopy]="login" (copiedValue)="copied = $event" mat-icon-button>
<i *ngIf="copied != login" class="las la-clipboard"></i>
<i *ngIf="copied == login" class="las la-clipboard-check"></i>
</button>
</div>
</app-card>

View File

@@ -1,6 +1,6 @@
import { Location } from '@angular/common';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs';
import { ChangeType } from 'src/app/modules/changes/changes.component';
@@ -27,7 +27,6 @@ export class UserDetailComponent implements OnInit, OnDestroy {
public genders: Gender[] = [Gender.GENDER_MALE, Gender.GENDER_FEMALE, Gender.GENDER_DIVERSE];
public languages: string[] = ['de', 'en'];
public isMgmt: boolean = false;
private subscription: Subscription = new Subscription();
public emailEditState: boolean = false;
public phoneEditState: boolean = false;
@@ -49,11 +48,11 @@ export class UserDetailComponent implements OnInit, OnDestroy {
public ngOnInit(): void {
this.subscription = this.route.params.subscribe(params => {
this.loading = true;
this.getData(params).then(() => {
this.loading = false;
}).catch(error => {
this.loading = false;
const { id } = params;
this.mgmtUserService.GetUserByID(id).then(user => {
this.user = user.toObject();
}).catch(err => {
console.error(err);
});
});
}
@@ -157,15 +156,6 @@ export class UserDetailComponent implements OnInit, OnDestroy {
this._location.back();
}
private async getData({ id }: Params): Promise<void> {
this.isMgmt = true;
this.mgmtUserService.GetUserByID(id).then(user => {
this.user = user.toObject();
}).catch(err => {
console.error(err);
});
}
public sendSetPasswordNotification(): void {
this.mgmtUserService.SendSetPasswordNotification(this.user.id, NotificationType.NOTIFICATIONTYPE_EMAIL)
.then(() => {
@@ -174,22 +164,4 @@ export class UserDetailComponent implements OnInit, OnDestroy {
this.toast.showError(error);
});
}
public copytoclipboard(value: string): void {
const selBox = document.createElement('textarea');
selBox.style.position = 'fixed';
selBox.style.left = '0';
selBox.style.top = '0';
selBox.style.opacity = '0';
selBox.value = value;
document.body.appendChild(selBox);
selBox.focus();
selBox.select();
document.execCommand('copy');
document.body.removeChild(selBox);
this.copied = value;
setTimeout(() => {
this.copied = '';
}, 3000);
}
}