fix(console): sidenav ordering and naming, split eventstore to its own view, documentation link in header (#1021)

* reorg, headers

* reorg sidenav, seperate eventstore comp, i18n

* lint

* lighter project count design

* black default

* small changes

* titles

* naming
This commit is contained in:
Max Peintner 2020-11-27 11:11:30 +01:00 committed by GitHub
parent ae26999834
commit 2cd6da361a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 138 additions and 69 deletions

View File

@ -49,6 +49,8 @@
</mat-menu>
<span class="fill-space"></span>
<a class="doc-link" href="https://docs.zitadel.ch" mat-stroked-button
target="_blank">{{'MENU.DOCUMENTATION' | translate}}</a>
<div (clickOutside)="closeAccountCard()" class="icon-container">
<app-avatar *ngIf="user && (user.displayName || (user.firstName && user.lastName))"
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
@ -73,44 +75,31 @@
</a>
</ng-container>
<ng-container *ngIf="iamuser$ | async">
<div @navitem class="divider">
<div class="line"></div>
<span>{{'MENU.ADMINSECTION' | translate}}</span>
<div class="hiddenline"></div>
</div>
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAM' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/iam']">
<i class="icon las la-gem"></i>
<span class="label">{{'MENU.IAM' | translate}}</span>
</a>
</ng-container>
<div *ngIf="org" [@navAnimation]="org">
<ng-template appHasRole [appHasRole]="['org.read']">
<ng-template appHasRole
[appHasRole]="['org.read', 'project.read(:[0-9]*)?', 'user.read(:[0-9]*)?', 'user.grant.read(:[0-9]*)?']">
<div @navitem class="divider">
<div class="line"></div>
<span>{{'MENU.ORGSECTION' | translate}}</span>
<span>{{org?.name ? org.name : ('MENU.ORGSECTION' | translate)}}</span>
<div class="hiddenline"></div>
</div>
</ng-template>
<ng-template appHasRole [appHasRole]="['org.read']">
<a @navitem matTooltip="{{'MENU.TOOLTIP.ORG' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/org']">
<i class="icon las la-archway"></i>
<span
class="label">{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}</span>
<span class="label">{{'MENU.ORGANIZATION' | translate}}</span>
</a>
</ng-template>
<ng-template appHasRole [appHasRole]="['project.read(:[0-9]*)?']">
<a @navitem matTooltip="{{'MENU.TOOLTIP.SELFPROJECTS' | translate}}"
class="nav-item indented" [routerLinkActive]="['active']"
[routerLink]="[ '/projects']">
<a @navitem matTooltip="{{'MENU.TOOLTIP.SELFPROJECTS' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/projects']">
<i class="icon las la-layer-group"></i>
<div class="c_label">
<span>{{org?.name ? org.name : 'MENU.ORGANIZATION' | translate}}
{{'MENU.PROJECT' | translate}} </span>
<span> {{'MENU.PROJECT' | translate}} </span>
<span *ngIf="(mgmtService?.ownedProjectsCount | async)"
class="count">{{mgmtService?.ownedProjectsCount | async}}</span>
</div>
@ -118,7 +107,7 @@
<a @navitem matTooltip="{{'MENU.TOOLTIP.GRANTEDPROJECTS' | translate}}"
*ngIf="mgmtService?.grantedProjectsCount && (mgmtService?.grantedProjectsCount | async)"
class="nav-item indented" [routerLinkActive]="['active']"
class="nav-item" [routerLinkActive]="['active']"
[routerLink]="[ '/granted-projects']">
<i class="icon las la-layer-group"></i>
<div class="c_label">
@ -129,16 +118,15 @@
</ng-template>
<ng-template appHasRole [appHasRole]="['user.read(:[0-9]*)?']">
<a @navitem matTooltip="{{'MENU.TOOLTIP.HUMANUSERS' | translate}}"
class="nav-item indented" [routerLinkActive]="['active']"
[routerLink]="[ '/users/list/humans']" [routerLinkActiveOptions]="{ exact: true }">
<a @navitem matTooltip="{{'MENU.TOOLTIP.HUMANUSERS' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/users/list/humans']"
[routerLinkActiveOptions]="{ exact: true }">
<i class="icon las la-user-friends"></i>
<span class="label">{{ 'MENU.HUMANUSERS' | translate }}</span>
</a>
<a @navitem matTooltip="{{'MENU.TOOLTIP.MACHINEUSERS' | translate}}"
class="nav-item indented" [routerLinkActive]="['active']"
[routerLink]="[ '/users/list/machines']"
<a @navitem matTooltip="{{'MENU.TOOLTIP.MACHINEUSERS' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/users/list/machines']"
[routerLinkActiveOptions]="{ exact: true }">
<i class="icon las la-users-cog"></i>
<span class="label">{{ 'MENU.MACHINEUSERS' | translate }}</span>
@ -146,21 +134,33 @@
</ng-template>
<ng-template appHasRole [appHasRole]="['user.grant.read(:[0-9]*)?']">
<!-- <div @navitem class="divider">
<div class="line"></div>
<span class="label">
{{ 'MENU.GRANTSECTION' | translate }}</span>
<div class="hiddenline"></div>
</div> -->
<a @navitem class="nav-item indented" [routerLinkActive]="['active']"
[routerLink]="[ '/grants']" [routerLinkActiveOptions]="{ exact: true }">
<a @navitem class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/grants']"
[routerLinkActiveOptions]="{ exact: true }">
<i class="icon las la-shield-alt"></i>
<span class="label">{{ 'MENU.GRANTS' | translate }}</span>
</a>
</ng-template>
</div>
<ng-container *ngIf="iamuser$ | async">
<div @navitem class="divider">
<div class="line"></div>
<span>{{'MENU.ADMINSECTION' | translate}}</span>
<div class="hiddenline"></div>
</div>
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMPOLICIES' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/iam','policies']">
<i class="icon las la-gem"></i>
<span class="label">{{'MENU.IAMPOLICIES' | translate}}</span>
</a>
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMEVENTSTORE' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/iam', 'eventstore']">
<i class="icon las la-gem"></i>
<span class="label">{{'MENU.IAMEVENTSTORE' | translate}}</span>
</a>
</ng-container>
<span class="fill-space"></span>
</div>
<span class="fill-space"></span>

View File

@ -34,6 +34,10 @@
flex: 1;
}
.doc-link {
margin-right: 1rem;
}
.icon-container {
display: flex;
justify-content: space-between;
@ -105,10 +109,8 @@
cursor: pointer;
padding: 0 1rem;
margin-right: .5rem;
&.indented {
padding-left: 2rem;
}
border-top-right-radius: 1.5rem;
border-bottom-right-radius: 1.5rem;
.icon {
margin: .5rem 1rem;
@ -219,6 +221,7 @@
height: 1px;
margin: .5rem 0;
flex: 1;
min-width: 10px;
}
.hiddenline {

View File

@ -0,0 +1,12 @@
<div class="max-width-container">
<h1>{{ 'IAM.EVENTSTORE.TITLE' | translate }}</h1>
<p class="desc">{{'IAM.EVENTSTORE.DESCRIPTION' | translate }}</p>
<app-card title="{{ 'IAM.VIEWS.TITLE' | translate }}" description="{{ 'IAM.VIEWS.DESCRIPTION' | translate }}">
<app-iam-views></app-iam-views>
</app-card>
<app-card title="{{ 'IAM.FAILEDEVENTS.TITLE' | translate }}"
description="{{ 'IAM.FAILEDEVENTS.DESCRIPTION' | translate }}">
<app-iam-failed-events></app-iam-failed-events>
</app-card>
</div>

View File

@ -0,0 +1,8 @@
h1 {
margin-top: 0;
}
.desc {
color: var(--grey);
margin-bottom: 2rem;
}

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { EventstoreComponent } from './eventstore.component';
describe('EventstoreComponent', () => {
let component: EventstoreComponent;
let fixture: ComponentFixture<EventstoreComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [EventstoreComponent],
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(EventstoreComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,8 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-eventstore',
templateUrl: './eventstore.component.html',
styleUrls: ['./eventstore.component.scss'],
})
export class EventstoreComponent { }

View File

@ -4,17 +4,26 @@ import { AuthGuard } from 'src/app/guards/auth.guard';
import { RoleGuard } from 'src/app/guards/role.guard';
import { PolicyComponentServiceType, PolicyComponentType } from 'src/app/modules/policies/policy-component-types.enum';
import { EventstoreComponent } from './eventstore/eventstore.component';
import { IamComponent } from './iam.component';
const routes: Routes = [
{
path: '',
path: 'policies',
component: IamComponent,
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.read'],
},
},
{
path: 'eventstore',
component: EventstoreComponent,
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.read'],
},
},
{
path: 'members',
loadChildren: () => import('./iam-members/iam-members.module').then(m => m.IamMembersModule),

View File

@ -1,18 +1,9 @@
<app-meta-layout>
<div class="enlarged-container">
<h1 class="h1">{{'IAM.DETAIL.TITLE' | translate}}</h1>
<p class="sub">{{'IAM.DETAIL.DESCRIPTION' | translate}} </p>
<h1 class="h1">{{'IAM.POLICIES.TITLE' | translate}}</h1>
<p class="sub">{{'IAM.POLICIES.DESCRIPTION' | translate}} </p>
<app-policy-grid [type]="PolicyGridType.IAM"></app-policy-grid>
<app-card title="{{ 'IAM.VIEWS.TITLE' | translate }}" description="{{ 'IAM.VIEWS.DESCRIPTION' | translate }}">
<app-iam-views></app-iam-views>
</app-card>
<app-card title="{{ 'IAM.FAILEDEVENTS.TITLE' | translate }}"
description="{{ 'IAM.FAILEDEVENTS.DESCRIPTION' | translate }}">
<app-iam-failed-events></app-iam-failed-events>
</app-card>
</div>
<div class="side" metainfo>

View File

@ -26,13 +26,14 @@ import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.mod
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
import { EventstoreComponent } from './eventstore/eventstore.component';
import { FailedEventsComponent } from './failed-events/failed-events.component';
import { IamRoutingModule } from './iam-routing.module';
import { IamViewsComponent } from './iam-views/iam-views.component';
import { IamComponent } from './iam.component';
@NgModule({
declarations: [IamComponent, IamViewsComponent, FailedEventsComponent],
declarations: [IamComponent, EventstoreComponent, IamViewsComponent, FailedEventsComponent],
imports: [
CommonModule,
IamRoutingModule,

View File

@ -36,7 +36,9 @@
},
"MENU": {
"PERSONAL_INFO": "Persönliche Informationen",
"IAM":"Administration",
"DOCUMENTATION":"Dokumentation",
"IAMPOLICIES":"IAM",
"IAMEVENTSTORE":"Speicher",
"ORGANIZATION": "Organisation",
"ADMINSECTION":"ZITADEL Administration",
"ORGSECTION":"Organisation",
@ -54,7 +56,8 @@
"GRANTS":"Berechtigungen",
"TOOLTIP": {
"PERSONAL":"Verwalte deinen persönlichen Account, deine IDPs, Login Methoden, Faktoren und Berechtigungen",
"IAM":"Verwalte ZITADELs globale Zugangsrichtlinien, bereinige views und fehlerhafte events",
"IAMPOLICIES":"Verwalte ZITADELs globale Zugangsrichtlinien und verwalte ZITADEL Manager",
"IAMEVENTSTORE":"Bereinige views und fehlerhafte Events",
"ORG":"Verwalte die Zugangsrichtlinien und Domains deiner Organisation ",
"SELFPROJECTS":"Verwalte die Projekte deiner Organisation",
"GRANTEDPROJECTS":"Verwalte die berechtigten Projekte von anderen Organisationen",
@ -370,9 +373,13 @@
}
},
"IAM": {
"DETAIL": {
"TITLE":"Administration Identity- und Access-Management Administration",
"DESCRIPTION":"Verwalte die Einstellungen von ZITADEL."
"POLICIES": {
"TITLE":"IAM Administration",
"DESCRIPTION":"Verwalte Richtlinen und Zugangseinstellungen von ZITADEL."
},
"EVENTSTORE": {
"TITLE":"IAM Speicher Administration",
"DESCRIPTION":"Verwalte Speicher Einstellungen von ZITADEL."
},
"MEMBER": {
"TITLE":"Manager",

View File

@ -36,7 +36,9 @@
},
"MENU": {
"PERSONAL_INFO": "Personal Information",
"IAM":"Administration",
"DOCUMENTATION":"Documentation",
"IAMPOLICIES":"IAM",
"IAMEVENTSTORE":"Storage",
"ORGANIZATION": "Organisation",
"ADMINSECTION":"ZITADEL Administration",
"ORGSECTION":"Organisation",
@ -54,7 +56,8 @@
"GRANTS":"Authorizations",
"TOOLTIP": {
"PERSONAL":"Show your Personal Account, your IDPs, Login methods, Factors and Authorisations",
"IAM":"Show ZITADELs global access policies, clear views and failed events",
"IAMPOLICIES":"Manage ZITADELs global Access policies und elect ZITADEL Managers",
"IAMEVENTSTORE":"Clear views and failed events",
"ORG":"Show your organisations access policies, and manage your domain names",
"SELFPROJECTS":"Show your organisations own projects",
"GRANTEDPROJECTS":"Show projects your organisation was granted access",
@ -370,9 +373,13 @@
}
},
"IAM": {
"DETAIL": {
"TITLE":"Identity and Access Management Administration",
"DESCRIPTION":"Manage the ZITADEL settings."
"POLICIES": {
"TITLE":"IAM Policies and Access Settings",
"DESCRIPTION":"Manage your ZITADEL Policies and Management Access Settings."
},
"EVENTSTORE": {
"TITLE":"IAM Storage Administration",
"DESCRIPTION":"Manage your ZITADEL views and failed events."
},
"MEMBER": {
"TITLE":"Managers",

View File

@ -274,7 +274,7 @@ h2 {
.max-width-container {
max-width: 1350px;
padding: 0 1.5rem;
padding-top: 4rem;
padding-top: 2rem;
padding-left: 4rem;
@media only screen and (min-width: 1024px) {
@ -293,7 +293,7 @@ h2 {
.enlarged-container {
padding: 0 1.5rem;
padding-top: 4rem;
padding-top: 2rem;
padding-left: 4rem;
@media only screen and (max-width: 500px) {

View File

@ -32,10 +32,8 @@
.c_label {
.count {
background-color: $primary-color;
padding: 3px 6px;
border-radius: 50vw;
color: white;
}
}
}