fix(console): hide granted project navigation if none, cache zitadel permissions, emit refresh on org change, cleanup contributors, styling (#511)

* 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

* inherit parent color, animations

* use localized date pipe everywhere

* cmp styles refactor, dont show granted p if none

* fix navitem desc, fixed header

* change permissions, caching

* roles on org emit, use prom instead of hot obs

* dont calc 100vh
This commit is contained in:
Max Peintner
2020-07-28 09:09:18 +02:00
committed by GitHub
parent 2d8f934a07
commit 531060ab67
37 changed files with 442 additions and 296 deletions
@@ -15,9 +15,5 @@
box-sizing: border-box;
outline: none;
color: white;
// &.active:hover {
// border: 2px solid #8795a1;
// }
}
}
+51
View File
@@ -0,0 +1,51 @@
@import '~@angular/material/theming';
@mixin card-theme($theme) {
$primary: map-get($theme, primary);
$primary-color: mat-color($primary, 500);
$primary-dark: mat-color($primary, A800);
$border-color: mat-color($primary, A700);
$border-selected-color: mat-color($primary, A600);
.card {
background-color: $primary-dark;
transition: background-color .4s ease-in-out;
border: 1px solid rgba($border-color, .2);
box-sizing: border-box;
border-radius: .5rem;
outline: none;
.selection-icon {
opacity: 0;
position: absolute;
top: -12px;
left: -12px;
color: $border-color;
}
&.selected {
background-color: #ffffff25;
border: 1px solid $border-selected-color;
.text-part {
.icons {
opacity: 1;
}
}
.selection-icon {
color: $border-selected-color;
opacity: 1;
}
}
.iamuser {
color: $primary-color;
}
.edit-button {
&:hover {
color: $border-selected-color;
}
}
}
}
@@ -1,7 +1,8 @@
<span class="header">{{ 'CHANGES.LISTTITLE' | translate }}</span>
<div class="scroll-container" appScrollable (scrollPosition)="scrollHandler($event)">
<li class="item change-item-back" *ngFor="let event of data | async">
<div class="scroll-container" appScrollable (scrollPosition)="scrollHandler($event)"
[@cardAnimation]="data && (data | async)?.length">
<li class="item change-item-back" *ngFor="let event of data | async" @animate>
<span class="seq">
{{event.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}
</span>
@@ -1,3 +1,6 @@
@import '~@angular/material/theming';
.header {
display: block;
margin-bottom: 1rem;
@@ -5,42 +8,53 @@
margin-top: 1rem;
}
.scroll-container {
max-height: 60vh;
overflow-y: scroll;
@mixin changes-theme($theme) {
.item {
box-sizing: border-box;
padding: .5rem;
margin: .25rem 0;
border-radius: .5rem;
display: flex;
flex-direction: column;
.editor {
color: #8795a1;
.scroll-container {
max-height: 60vh;
overflow-y: scroll;
.item {
box-sizing: border-box;
padding: .5rem;
margin: .25rem 0;
border-radius: .5rem;
display: flex;
flex-direction: column;
.editor {
color: #8795a1;
font-size: 12px;
align-self: flex-end;
}
.seq {
color: #8795a1;
font-size: 12px;
align-self: flex-end;
}
.desc {
overflow-x: auto;
font-size: 14px;
}
$primary: map-get($theme, primary);
$primary-dark: mat-color($primary, A800);
&.change-item-back {
background-color: rgba($primary-dark, 0.93);
transition: background-color .4s ease-in-out;
}
}
.sp-wrapper {
padding: .5rem;
display: flex;
justify-content: center;
}
.end-container {
font-size: 12px;
align-self: flex-end;
}
.seq {
color: #8795a1;
font-size: 12px;
align-self: flex-end;
}
.desc {
overflow-x: auto;
font-size: 14px;
}
}
.sp-wrapper {
padding: .5rem;
display: flex;
justify-content: center;
}
.end-container {
font-size: 12px;
color: #8795a1;
}
}
}
@@ -1,3 +1,4 @@
import { animate, animateChild, keyframes, query, stagger, style, transition, trigger } from '@angular/animations';
import { Component, Input, OnInit } from '@angular/core';
import { BehaviorSubject, from, Observable, of } from 'rxjs';
import { catchError, scan, take, tap } from 'rxjs/operators';
@@ -16,6 +17,22 @@ export enum ChangeType {
selector: 'app-changes',
templateUrl: './changes.component.html',
styleUrls: ['./changes.component.scss'],
animations: [
trigger('cardAnimation', [
transition('* => *', [
query('@animate', stagger('50ms', animateChild()), { optional: true }),
]),
]),
trigger('animate', [
transition(':enter', [
animate('.2s ease-in', keyframes([
style({ opacity: 0 }),
style({ opacity: .5, transform: 'scale(1.02)' }),
style({ opacity: 1, transform: 'scale(1)' }),
])),
]),
]),
],
})
export class ChangesComponent implements OnInit {
@Input() public changeType: ChangeType = ChangeType.USER;
@@ -2,12 +2,12 @@
<span class="header">{{ title }}</span>
<span class="sub-header">{{ description }}</span>
<div class="people">
<div class="img-list">
<div class="img-list" [@cardAnimation]="totalResult">
<mat-spinner diameter="20" *ngIf="loading"></mat-spinner>
<ng-container *ngIf="totalResult < 10; else compact">
<ng-container *ngFor="let member of membersSubject | async; index as i">
<div (click)="emitShowDetail()" class="avatar-circle"
<div @animate (click)="emitShowDetail()" class="avatar-circle"
matTooltip="{{ member.email }} | {{member.rolesList?.join(' ')}}"
[ngStyle]="{'z-index': 100 - i}">
<app-avatar *ngIf="member && (member.displayName || (member.firstName && member.lastName))"
@@ -1,4 +1,4 @@
import { animate, animateChild, query, stagger, style, transition, trigger } from '@angular/animations';
import { animate, animateChild, keyframes, query, stagger, style, transition, trigger } from '@angular/animations';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@@ -7,17 +7,18 @@ import { BehaviorSubject } from 'rxjs';
templateUrl: './contributors.component.html',
styleUrls: ['./contributors.component.scss'],
animations: [
trigger('list', [
transition(':enter', [
query('@animate',
stagger(80, animateChild()),
),
trigger('cardAnimation', [
transition('* => *', [
query('@animate', stagger('40ms', animateChild()), { optional: true }),
]),
]),
trigger('animate', [
transition(':enter', [
style({ opacity: 0, transform: 'translateX(100%)' }),
animate('100ms', style({ opacity: 1, transform: 'translateX(0)' })),
animate('.2s ease-in', keyframes([
style({ opacity: 0, offset: 0 }),
style({ opacity: .5, transform: 'scale(1.05)', offset: 0.3 }),
style({ opacity: 1, transform: 'scale(1)', offset: 1 }),
])),
]),
]),
],
@@ -51,7 +51,7 @@
<ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.ROLE.CREATIONDATE' | translate }} </th>
<td (click)="openDetailDialog(role)" mat-cell *matCellDef="let role">
<span>{{role.creationDate | timestampToDate | date: 'dd. MMM, HH:mm' }}</span>
<span>{{role.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }}</span>
</td>
</ng-container>
@@ -16,6 +16,7 @@ import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { RefreshTableModule } from '../refresh-table/refresh-table.module';
@@ -46,6 +47,7 @@ import { ProjectRolesComponent } from './project-roles.component';
MatMenuModule,
TimestampToDatePipeModule,
RefreshTableModule,
LocalizedDatePipeModule,
],
exports: [
ProjectRolesComponent,
@@ -51,13 +51,13 @@
<ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.CREATIONDATE' | translate }} </th>
<td class="pointer" mat-cell *matCellDef="let grant">
{{grant.creationDate | timestampToDate | date: 'dd. MMM, HH:mm' }} </td>
{{grant.creationDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} </td>
</ng-container>
<ng-container matColumnDef="changeDate">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.GRANT.CHANGEDATE' | translate }} </th>
<td class="pointer" mat-cell *matCellDef="let grant">
{{grant.changeDate | timestampToDate | date: 'dd. MMM, HH:mm' }} </td>
{{grant.changeDate | timestampToDate | localizedDate: 'dd. MMM, HH:mm' }} </td>
</ng-container>
<ng-container matColumnDef="roleNamesList">
@@ -14,6 +14,7 @@ import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe.module';
import { AvatarModule } from '../avatar/avatar.module';
@@ -43,6 +44,7 @@ import { UserGrantsComponent } from './user-grants.component';
HasRolePipeModule,
TimestampToDatePipeModule,
RefreshTableModule,
LocalizedDatePipeModule,
],
exports: [
UserGrantsComponent,