feat: docs rehaul, fix missing context in console, quickstarts (#1212)

* onboarding components, routing, steps

* onboarding component, toc

* fix onboarding mixin

* header

* refactor docs

* fix layout

* cleanup routing

* docs routing

* fix conventions

* de en routing

* docs, guide contents, nav

* rem i18n support

* fix routing from docs

* rollup onwarn changes, preload

* update svelte plugin, update rollup config

* move docs

* revert img style, remove code table

* rem de completely

* rollup optim, template

* angular quickstart, quickstart overview page, update deps

* fix link

* pack, slug

* prefetch binding, hidden links

* export log

* guards route ch

* fix homepage

* angular docs

* docs

* resolve fsh

* overview

* docs

* docs

* packages fix race condition

* nav, home link

* add vue, aspnet

* doc optimizations

* embed status pal

* angular guide

* angular guide

* dotnet, angular guide

* viewbox

* typo

* block onboarding route for non iam writers

* set links from component data

* fix: fetch org context in guard, more main cnt (#1192)

* change get started guide, fix code blockquotes, typos

* flutter guide

* h2 spacing

* highlight strong

* plus

* rm start sublinks

* add proxy quickstart

* regex

* prevent outside click, fix project grant write

Co-authored-by: Florian Forster <florian@caos.ch>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Max Peintner
2021-02-16 16:59:18 +01:00
committed by GitHub
parent 30a06e5bec
commit 27be460c07
168 changed files with 2306 additions and 1652 deletions

View File

@@ -11,6 +11,15 @@ const routes: Routes = [
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
canActivate: [AuthGuard],
},
{
path: 'firststeps',
loadChildren: () => import('./modules/onboarding/onboarding.module')
.then(m => m.OnboardingModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['iam.write'],
}
},
{
path: 'granted-projects',
loadChildren: () => import('./pages/projects/granted-projects/granted-projects.module')

View File

@@ -1,19 +1,25 @@
<ng-container *ngIf="(authService.user | async) || {} as user">
<ng-container *ngIf="((['iam.read$','iam.write$'] | hasRole)) as iamuser$">
<mat-toolbar class="root-header">
<button aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()">
<button *ngIf="authenticationService.authenticated" aria-label="Toggle sidenav" mat-icon-button
(click)="drawer.toggle()">
<i class="icon las la-bars"></i>
</button>
<a *ngIf="(isHandset$ | async) == false" class="title" [routerLink]="['/']">
<a class="title" [routerLink]="['/']">
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
src="../assets/images/zitadel-logo-light.svg" />
src="../assets/images/zitadel-logo-solo-light.svg" />
<ng-template #lighttheme>
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-dark.svg" />
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-solo-dark.svg" />
</ng-template>
</a>
<button (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button [matMenuTriggerFor]="menu"
(menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
<svg class="slash" viewBox="0 0 24 24" width="32" height="32" stroke="currentColor" stroke-width="1"
stroke-linecap="round" stroke-linejoin="round" fill="none" shape-rendering="geometricPrecision">
<path d="M16.88 3.549L7.12 20.451"></path>
</svg>
<button class="org-button" (click)="loadOrgs()" *ngIf="profile?.id && org" mat-button
[matMenuTriggerFor]="menu" (menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
<mat-icon>
arrow_drop_down</mat-icon>
</button>
@@ -37,8 +43,8 @@
</button>
</div>
<button class="show-all" mat-menu-item
[routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' | translate}}</button>
<button class="show-all" mat-menu-item [routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' |
translate}}</button>
<ng-template appHasRole [appHasRole]="['org.create','iam.write']">
<button mat-menu-item [routerLink]="[ '/org/create' ]">
@@ -49,23 +55,29 @@
</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>
<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"
[name]="user.displayName ? user.displayName : (user.firstName + ' '+ user.lastName)" [size]="38">
</app-avatar>
<app-accounts-card @accounts class="a_card mat-elevation-z5" *ngIf="showAccount"
<app-accounts-card @accounts class="a_card mat-elevation-z1" *ngIf="showAccount"
(close)="showAccount = false" [profile]="profile" [iamuser]="iamuser$ | async">
</app-accounts-card>
</div>
</mat-toolbar>
<mat-drawer-container class="main-container">
<mat-drawer #drawer class="sidenav" [mode]="(isHandset$ | async) ? 'over' : 'side'"
[opened]="!(isHandset$ | async)">
[opened]="!(isHandset$ | async) && authenticationService.authenticated">
<div class="side-column">
<div class="list">
<a @navitem class="nav-item" [routerLinkActive]="['active']"
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/']">
<i class="icon las la-home"></i>
<span class="label">{{ 'MENU.DASHBOARD' | translate }}</span>
</a>
<ng-container *ngIf="authenticationService.authenticationChanged | async">
<a @navitem matTooltip="{{'MENU.TOOLTIP.PERSONAL' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
@@ -163,6 +175,14 @@
</ng-container>
<span class="fill-space"></span>
<div class="toc-line">
<a class="toc" href="https://zitadel.ch/pdf/agb.pdf" alt="Terms and Conditions"
target="_blank">{{'MENU.TOC'
| translate}}</a>
<span>&nbsp;&nbsp;&nbsp;</span>
<a class="sp-status" href="//status.zitadel.ch">Status</a>
</div>
</div>
<span class="fill-space"></span>
</div>

View File

@@ -11,9 +11,14 @@
left: 0;
right: 0;
.org-button {
font-weight: bold;
padding-right: .5rem;
}
.logo {
max-height: 50px;
width: 160px;
max-height: 40px;
width: 40px;
}
.title {
@@ -22,7 +27,6 @@
font-size: 1.2rem;
font-weight: 400;
line-height: 1.2rem;
margin-right: 1rem;
}
.context-menu {
@@ -82,7 +86,7 @@
padding-top: 60px;
.sidenav {
width: 300px;
width: 280px;
border-right: none;
.side-column {
@@ -90,6 +94,7 @@
display: flex;
flex-direction: column;
align-items: stretch;
height: calc(100% - 60px);
.list {
width: 100%;
@@ -123,7 +128,6 @@
.label {
margin-bottom: 0;
font-size: 14px;
letter-spacing: .05em;
}
.c_label {
@@ -132,7 +136,6 @@
justify-content: space-between;
align-items: center;
font-size: 14px;
letter-spacing: .03em;
.count {
font-size: 12px;
@@ -140,7 +143,7 @@
}
&:hover {
background-color: #00000010;
// background-color: #00000010;
border-top-right-radius: 1.5rem;
border-bottom-right-radius: 1.5rem;
}
@@ -148,6 +151,7 @@
&.active {
border-top-right-radius: 1.5rem;
border-bottom-right-radius: 1.5rem;
font-weight: bold;
}
}
@@ -160,6 +164,43 @@
flex: 1 1 auto;
}
.toc-line {
margin: 2rem 2rem;
.toc {
font-size: 12px;
color: var(--grey);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
.sp-status {
font-size: 12px;
color: var(--grey);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
.sp-status .sp-status-badge.sp-status-ok {
background: darkgreen;
}
.sp-status .sp-status-badge.sp-status-scheduled {
background: darkblue;
}
.sp-status .sp-status-badge.sp-status-minor {
background: darkorange;
}
.sp-status .sp-status-badge.sp-status-major {
background: darkred;
}
}
.logout-button {
margin-bottom: 1rem;
}

View File

@@ -251,7 +251,7 @@ export class AppComponent implements OnDestroy {
}
private getProjectCount(): void {
this.authService.isAllowed(['project.read$']).subscribe((allowed) => {
this.authService.isAllowed(['project.read']).subscribe((allowed) => {
if (allowed) {
this.mgmtService.SearchProjects(0, 0);

View File

@@ -23,6 +23,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AuthConfig, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc';
import { QuicklinkModule } from 'ngx-quicklink';
import { OnboardingModule } from 'src/app/modules/onboarding/onboarding.module';
import { RegExpPipeModule } from 'src/app/pipes/regexp-pipe/regexp-pipe.module';
import { environment } from '../environments/environment';
@@ -121,6 +122,7 @@ const authConfig: AuthConfig = {
WarnDialogModule,
MatDialogModule,
RegExpPipeModule,
OnboardingModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
],
providers: [

View File

@@ -3,20 +3,23 @@ import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angul
import { Observable } from 'rxjs';
import { AuthenticationService } from '../services/authentication.service';
import { GrpcAuthService } from '../services/grpc-auth.service';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(private auth: AuthenticationService) { }
constructor(private auth: AuthenticationService, private authService: GrpcAuthService) { }
public canActivate(
_: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | Promise<boolean> | boolean {
): Observable<boolean> | Promise<boolean> | Promise<any> | boolean {
if (!this.auth.authenticated) {
return this.auth.authenticate();
return this.auth.authenticate().then(() => {
return this.authService.GetActiveOrg();
});
}
return this.auth.authenticated;
}

View File

@@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { OnboardingComponent } from './onboarding.component';
const routes: Routes = [
{
path: '',
component: OnboardingComponent,
data: { animation: 'AddPage' },
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class OnboardingRoutingModule { }

View File

@@ -0,0 +1,27 @@
<div class="split">
<div class="left">
<p class="firststeps">{{'ONBOARDING.HEADER' | translate}}</p>
<h1>{{'ONBOARDING.TITLE' | translate}}</h1>
</div>
<div class="right">
<p class="desc">{{'ONBOARDING.DESCRIPTION' | translate}}</p>
<h2>{{'ONBOARDING.STEPS_TITLE' | translate}}</h2>
<div class="onboarding-row" *ngFor="let step of steps; index as i">
<div class="prev">{{i + 1}}</div>
<div>
<h3>{{step.titleI18nKey | translate}}</h3>
<p>{{step.descI18nKey | translate}}</p>
</div>
<span class="fill-space"></span>
<div class="action-row">
<a *ngIf="step?.docs" [href]="step.docs" alt="Zitadel Docs" target="_blank"
class="goto docs">{{'ONBOARDING.DOCS' |
translate}}
<i class="las la-external-link-alt"></i>
</a>
<a *ngIf="step.link" class="goto" [routerLink]="step.link">{{'ONBOARDING.START' | translate}}</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,147 @@
@import '~@angular/material/theming';
@mixin onboarding-theme($theme) {
/* stylelint-disable */
$primary: map-get($theme, primary);
$primary-color: mat-color($primary, 500);
$is-dark-theme: map-get($theme, is-dark);
/* stylelint-enable */
.onboarding-row {
box-shadow: inset 0 -1px if($is-dark-theme, #303131, #e3e8ee);
.prev {
background: $primary-color;
}
.goto {
text-decoration: none;
background: white;
border: 1px solid if($is-dark-theme, #303131, #e3e8ee);
&.docs {
background-color: $primary-color;
i {
font-size: 1rem;
margin-left: 3px;
}
}
}
}
}
.split {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
box-sizing: border-box;
border-radius: 0.5rem;
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
@media only screen and (min-width: 1024px) {
flex-direction: row;
.right {
overflow: auto;
}
}
.left {
flex-basis: 300px;
box-sizing: border-box;
padding: 1.5rem;
background: linear-gradient(40deg, rgb(80, 66, 121),rgb(177, 59, 122),rgb(225,53,81), rgb(230,107,86));
box-shadow: inset -2px 1px 15px -9px #000000;
h1 {
color: white;
}
.firststeps {
color: #fad6e3;
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
}
p {
color: #fad6e3;
font-size: 12px;
font-weight: bold;
}
button {
width: 100%;
}
}
.right {
padding: 1.5rem;
flex: 1;
box-sizing: border-box;
.desc {
color: var(--grey);
font-size: 20px;
margin-top: .5rem;
}
.onboarding-row {
display: flex;
padding: 1rem 0;
align-items: center;
.prev {
height: 40px;
width: 40px;
min-width: 40px;
border-radius: .5rem;
display: flex;
align-items: center;
justify-content: center;
margin-right: 2rem;
color: white;
font-size: 1.2rem;
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
}
h3 {
margin-top: 0;
margin-bottom: .5rem;
font-size: 15px;
}
p {
font-size: 12px;
margin: 0;
color: var(--grey);
}
.fill-space {
flex: 1;
}
.action-row {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: flex-end;
.goto {
background-color: white;
padding: 2px 1rem;
color: black;
border-radius: 50vw;
font-size: 12px;
margin: .5rem 0 .5rem 1rem;
white-space: nowrap;
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,16 @@
import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from 'src/app/services/authentication.service';
@Component({
selector: 'cnsl-onboarding',
templateUrl: './onboarding.component.html',
styleUrls: ['./onboarding.component.scss']
})
export class OnboardingComponent {
public steps = [
{ titleI18nKey: 'ONBOARDING.STEPS.1.TITLE', descI18nKey: 'ONBOARDING.STEPS.1.DESC', docs: "https://docs.zitadel.ch/use", link: ['/projects', 'create'] },
{ titleI18nKey: 'ONBOARDING.STEPS.2.TITLE', descI18nKey: 'ONBOARDING.STEPS.2.DESC', docs: "https://docs.zitadel.ch/use", link: ['/projects'] },
{ titleI18nKey: 'ONBOARDING.STEPS.3.TITLE', descI18nKey: 'ONBOARDING.STEPS.3.DESC', link: ['/iam', 'policies'] },
];
constructor() { }
}

View File

@@ -0,0 +1,18 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
import { OnboardingRoutingModule } from './onboarding-routing.module';
import { OnboardingComponent } from './onboarding.component';
@NgModule({
declarations: [OnboardingComponent],
imports: [
CommonModule,
TranslateModule,
OnboardingRoutingModule,
MatButtonModule,
],
})
export class OnboardingModule { }

View File

@@ -16,12 +16,42 @@
</div>
<div class="container">
<ng-template appHasRole [appHasRole]="['iam.write']">
<a matRipple *ngIf="!firstStepsDismissed" class="onboard" [routerLink]="['/firststeps']">
<p class="first-steps">{{'ONBOARDING.HEADER' | translate}}</p>
<h2>{{'ONBOARDING.TITLE' | translate}}</h2>
<p class="desc">{{'ONBOARDING.DESCRIPTION' | translate}}</p>
<button matTooltip="{{'ACTIONS.CLOSE' | translate}}" (click)="dismissFirstSteps($event)" mat-icon-button
class="close">
<i class="las la-times"></i>
</button>
</a>
</ng-template>
<a matRipple *ngIf="!firstStepsDismissed" class="quickstart" target="_blank"
href="https://docs.zitadel.ch/quickstarts">
<p class="first-steps">{{'HOME.QUICKSTARTS.LABEL' | translate}}</p>
<h2>{{'HOME.QUICKSTARTS.TITLE' | translate}}</h2>
<p class="desc">{{'HOME.QUICKSTARTS.DESCRIPTION' | translate}}</p>
<div class="logo-cloud">
<i class="lab la-angular"></i>
<i class="lab la-react"></i>
<i class="lab la-android"></i>
<i class="lab la-app-store-ios"></i>
</div>
<button matTooltip="{{'ACTIONS.CLOSE' | translate}}" (click)="dismissQuickstarts($event)" mat-icon-button
class="close">
<i class="las la-times"></i>
</button>
</a>
<ng-template appHasRole [appHasRole]="['iam.write']">
<app-card class="item">
<div class="top">
<h2>
<i class="icon las la-gem"></i>
{{'HOME.IAM'| translate}}</h2>
{{'HOME.IAM'| translate}}
</h2>
<p>{{'HOME.IAM_DESC'| translate}}</p>
</div>
@@ -30,15 +60,12 @@
class="las la-link"></i></a>
</ng-template>
<ng-template appHasRole [appHasRole]="['iam.policy.read']">
<a class="short-link"
[routerLink]="[ '/iam', 'policy','iam']">{{'HOME.IAM_POLICY_IAM' | translate}}<i
class="las la-link"></i></a>
<a class="short-link"
[routerLink]="[ '/iam', 'policy','complexity']">{{'HOME.IAM_POLICY_COMPLEXITY' | translate}}<i
class="las la-link"></i></a>
<a class="short-link"
[routerLink]="[ '/iam', 'policy','login']">{{'HOME.IAM_POLICY_LOGIN' | translate}}<i
class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/iam', 'policy','iam']">{{'HOME.IAM_POLICY_IAM' |
translate}}<i class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/iam', 'policy','complexity']">{{'HOME.IAM_POLICY_COMPLEXITY'
| translate}}<i class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/iam', 'policy','login']">{{'HOME.IAM_POLICY_LOGIN' |
translate}}<i class="las la-link"></i></a>
</ng-template>
<span class="fill-space"></span>
@@ -59,8 +86,8 @@
<span class="fill-space"></span>
<div class="footer">
<a color="primary" mat-stroked-button
[routerLink]="['/users/me']">{{'HOME.SECURITYANDPRIVACY_BUTTON' | translate}}</a>
<a color="primary" mat-stroked-button [routerLink]="['/users/me']">{{'HOME.SECURITYANDPRIVACY_BUTTON' |
translate}}</a>
</div>
</app-card>
@@ -69,18 +96,18 @@
<div class="top">
<h2>
<i class="icon las la-layer-group"></i>
{{'HOME.PROJECTS'| translate}}</h2>
{{'HOME.PROJECTS'| translate}}
</h2>
<p>{{'HOME.PROJECTS_DESC'| translate}}</p>
<ng-template appHasRole [appHasRole]="['project.create']">
<a class="short-link"
[routerLink]="[ '/projects', 'create']">{{'HOME.PROJECTS_NEW_LINK' | translate}}<i
class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/projects', 'create']">{{'HOME.PROJECTS_NEW_LINK' |
translate}}<i class="las la-link"></i></a>
</ng-template>
</div>
<span class="fill-space"></span>
<div class="footer">
<a color="primary" mat-stroked-button
[routerLink]="['/projects']">{{'HOME.PROJECTS_BUTTON' | translate}}</a>
<a color="primary" mat-stroked-button [routerLink]="['/projects']">{{'HOME.PROJECTS_BUTTON' |
translate}}</a>
</div>
</app-card>
</ng-template>
@@ -92,23 +119,21 @@
{{'HOME.PROTECTION'| translate}}</h2>
<p>{{'HOME.PROTECTION_DESC'| translate}}</p>
<ng-template appHasRole [appHasRole]="['iam.policy.read']">
<a class="short-link"
[routerLink]="[ '/org', 'policy','iam']">{{'HOME.ORG_POLICY_IAM' | translate}}<i
class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/org', 'policy','iam']">{{'HOME.ORG_POLICY_IAM' |
translate}}<i class="las la-link"></i></a>
</ng-template>
<ng-template appHasRole [appHasRole]="['policy.read']">
<a class="short-link"
[routerLink]="[ '/org', 'policy','complexity']">{{'HOME.ORG_POLICY_COMPLEXITY' | translate}}<i
class="las la-link"></i></a>
<a class="short-link"
[routerLink]="[ '/org', 'policy','login']">{{'HOME.ORG_POLICY_LOGIN' | translate}}<i
class="las la-link"></i></a>
[routerLink]="[ '/org', 'policy','complexity']">{{'HOME.ORG_POLICY_COMPLEXITY' |
translate}}<i class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/org', 'policy','login']">{{'HOME.ORG_POLICY_LOGIN' |
translate}}<i class="las la-link"></i></a>
</ng-template>
</div>
<span class="fill-space"></span>
<div class="footer">
<a color="primary" mat-stroked-button
[routerLink]="['/org']">{{'HOME.PROTECTION_BUTTON' | translate}}</a>
<a color="primary" mat-stroked-button [routerLink]="['/org']">{{'HOME.PROTECTION_BUTTON' |
translate}}</a>
</div>
</app-card>
</ng-template>
@@ -118,15 +143,14 @@
<div class="top">
<h2>
<i class="las la-users"></i>
{{'HOME.USERS'| translate}}</h2>
{{'HOME.USERS'| translate}}
</h2>
<p>{{'HOME.USERS_DESC'| translate}}</p>
<ng-template appHasRole [appHasRole]="['user.read(:[0-9]*)?']">
<a class="short-link"
[routerLink]="[ '/users', 'list', 'humans']">{{'HOME.USERS_HUMANS' | translate}}<i
class="las la-link"></i></a>
<a class="short-link"
[routerLink]="[ '/users', 'list', 'machines']">{{'HOME.USERS_MACHINES' | translate}}<i
class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/users', 'list', 'humans']">{{'HOME.USERS_HUMANS' |
translate}}<i class="las la-link"></i></a>
<a class="short-link" [routerLink]="[ '/users', 'list', 'machines']">{{'HOME.USERS_MACHINES' |
translate}}<i class="las la-link"></i></a>
</ng-template>
<ng-template appHasRole [appHasRole]="['user.read']">
<a class="short-link" [routerLink]="[ '/users', 'create']">{{'HOME.USERS_CREATE' | translate}}<i
@@ -135,8 +159,8 @@
</div>
<span class="fill-space"></span>
<div class="footer">
<a color="primary" mat-stroked-button
[routerLink]="['/users/list/humans']">{{'HOME.USERS_BUTTON' | translate}}</a>
<a color="primary" mat-stroked-button [routerLink]="['/users/list/humans']">{{'HOME.USERS_BUTTON' |
translate}}</a>
</div>
</app-card>
</ng-template>

View File

@@ -1,6 +1,7 @@
.wrapper {
padding-bottom: 100px;
position: relative;
.header {
display: flex;
@@ -31,6 +32,78 @@
margin: -1rem;
justify-content: space-evenly;
.onboard,
.quickstart {
text-decoration: none;
cursor: pointer;
box-sizing: border-box;
flex: 1 0 45%;
position: relative;
border-radius: 0.5rem;
margin: 1rem;
padding: 1.5rem;
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
h2 {
color: white;
}
.first-steps {
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
}
.close {
visibility: hidden;
position: absolute;
top: 0;
right: 0;
i {
color: white;
font-size: 1rem;
}
}
&:hover {
.close {
visibility: visible;
}
}
}
.onboard {
background: linear-gradient(40deg, rgb(80, 66, 121),rgb(177, 59, 122),rgb(225,53,81), rgb(230,107,86));
p {
color: #fad6e3;
}
}
.quickstart {
background: linear-gradient(30deg, #2283a6,#6c8f59);
p {
color: #d6f3fa;
}
.logo-cloud {
display: flex;
flex-wrap: wrap;
margin: -0.5rem;
i {
font-size: 40px;
padding: .5rem;
border: 1px solid #ffffff50;
border-radius: .5rem;
margin: 0.5rem;
color: white;
}
}
}
.item {
flex: 1 0 45%;
margin: 0 1rem;

View File

@@ -8,8 +8,26 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
})
export class HomeComponent {
public dark: boolean = true;
public firstStepsDismissed: boolean = false;
public quickstartsDismissed: boolean = false;
constructor(public authService: GrpcAuthService) {
const theme = localStorage.getItem('theme');
this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true;
this.firstStepsDismissed = localStorage.getItem('firstStartDismissed') == 'true' ? true : false;
this.quickstartsDismissed = localStorage.getItem('quickstartsDismissed') == 'true' ? true : false;
}
dismissFirstSteps(event: Event): void {
event.preventDefault();
localStorage.setItem('firstStartDismissed', 'true');
this.firstStepsDismissed = true;
}
dismissQuickstarts(event: Event): void {
event.preventDefault();
localStorage.setItem('quickstartsDismissed', 'true');
this.firstStepsDismissed = true;
}
}

View File

@@ -1,19 +1,20 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatRippleModule } from '@angular/material/core';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
import { CardModule } from 'src/app/modules/card/card.module';
import { OnboardingModule } from 'src/app/modules/onboarding/onboarding.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { HomeRoutingModule } from './home-routing.module';
import { HomeComponent } from './home.component';
@NgModule({
declarations: [HomeComponent],
imports: [
@@ -24,9 +25,12 @@ import { HomeComponent } from './home.component';
MatButtonModule,
TranslateModule,
AvatarModule,
MatTooltipModule,
SharedModule,
MatProgressSpinnerModule,
CardModule,
MatRippleModule,
OnboardingModule,
],
})
export class HomeModule { }

View File

@@ -39,7 +39,7 @@
<h1 class="h1">{{ 'PROJECT.GRANT.DETAIL.MEMBERTITLE' | translate }}</h1>
<p class="desc">{{ 'PROJECT.GRANT.DETAIL.MEMBERDESC' | translate }}</p>
<app-members-table *ngIf="grant" style="width: 100%;" [dataSource]="dataSource"
<app-members-table *ngIf="grant" style="width: 100%;" [dataSource]="dataSource" [canWrite]="['project.grant.member.write','project.grant.member.write:' + grant.id] | hasRole | async"
[memberRoleOptions]="memberRoleOptions" (updateRoles)="updateMemberRoles($event.member, $event.change)"
[factoryLoadFunc]="changePageFactory" (changedSelection)="selection = $event" [refreshTrigger]="changePage">
<button selectactions (click)="removeProjectMemberSelection()"

View File

@@ -7,8 +7,9 @@
</ng-template>
<p>{{'USER.SIGNEDOUT' | translate}}</p>
<button color="primary" mat-raised-button
[routerLink]="[ '/users/me' ]">{{'USER.SIGNEDOUT_BTN' | translate}}</button>
<button matTooltip="{{'ACTIONS.LOGIN' | translate}}" color="primary" mat-raised-button
[routerLink]="[ '/users/me' ]">{{'USER.SIGNEDOUT_BTN' |
translate}} <i class="las la-sign-in-alt"></i></button>
</div>
</div>
</div>

View File

@@ -17,19 +17,24 @@
p {
color: var(--grey);
text-align: center;
font-size: 1rem;
font-size: 14px;
margin: 0;
margin-bottom: 3rem;
}
img {
height: 100px;
max-width: 170px;
margin-bottom: 2rem;
}
button {
display: block;
padding: .5rem 4rem;
i {
margin-left: .5rem;
}
}
}
}

View File

@@ -1,7 +1,6 @@
.head {
display: flex;
align-items: center;
border-bottom: 1px solid #ffffff20;
flex-wrap: wrap;
padding-bottom: .5rem;

View File

@@ -55,6 +55,7 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
titleKey: 'ERRORS.TOKENINVALID.TITLE',
descriptionKey: 'ERRORS.TOKENINVALID.DESCRIPTION',
},
disableClose: true,
width: '400px',
});

View File

@@ -1,5 +1,29 @@
{
"APP_NAME": "ZITADEL",
"ONBOARDING": {
"HEADER":"Erste Schritte",
"TITLE":"Lernen Sie unsere ZITADEL Console kennen.",
"LOGINDESC":"Melden Sie sich an um Zugriff auf Funktionen von Zitadel zu erhalten",
"LOGIN":"Anmelden",
"DESCRIPTION":"Führen Sie die folgenden Schritte aus und passen Sie ZITADEL optimal an Ihre Bedürfnisse an.",
"STEPS_TITLE":"Führen Sie die folgenden Schritte in gewünschter Reihenfolge aus:",
"STEPS": {
"1": {
"TITLE":"Projekt erstellen",
"DESC":"Erstellen Sie Ihr erstes Projekt und legen Sie Zugangsberechtigungen eventueller Mitarbeiter fest."
},
"2": {
"TITLE":"Applikation erstellen",
"DESC":"Erstellen Sie eine Applikation innerhalb Ihres Projektes und legen Sie dessen Eigenschaften fest."
},
"3": {
"TITLE":"Sicherheit verbessern",
"DESC":"Erweitern Sie die Zugangsrichtlinien und erhöhen Sie dadurch die Sicherheit ihrer Benutzer."
}
},
"START":"Start",
"DOCS":"Docs"
},
"HOME": {
"TITLE": "ZITADEL",
"SECURITYANDPRIVACY": "Datenschutz und Personalisierung",
@@ -32,9 +56,15 @@
"WELCOME":"Willkommen",
"WELCOMESENTENCE":"Hier findest Du die empfohlenen Aktionen basierend auf Deinen zuletzt erworbenen Berechtigungen. Beachte bitte, dass Du möglicherweise Deine Organisation in der Kopfzeile wechseln musst.",
"DISCLAIMER":"Du kannst nur die Einstellungen Deiner aktuellen Organisation, die in der Kopfzeile angegeben ist, sehen. ZITADEL behandelt Deine Daten vertraulich und sicher.",
"DISCLAIMERLINK":"Mehr Informationen zur Sicherheit"
"DISCLAIMERLINK":"Mehr Informationen zur Sicherheit",
"QUICKSTARTS": {
"LABEL":"Erste Schritte",
"TITLE":"Quickstarts",
"DESCRIPTION":"Mit ZITADEL schnell durchstarten."
}
},
"MENU": {
"DASHBOARD":"Übersicht",
"PERSONAL_INFO": "Persönliche Informationen",
"DOCUMENTATION":"Dokumentation",
"IAMPOLICIES":"IAM",
@@ -54,6 +84,7 @@
"SHOWORGS":"Alle Organisationen anzeigen",
"GRANTSECTION":"Berechtigungssektion",
"GRANTS":"Berechtigungen",
"TOC":"Datenschutz und AGB",
"TOOLTIP": {
"PERSONAL":"Verwalte deinen persönlichen Account, deine IDPs, Login Methoden, Faktoren und Berechtigungen",
"IAMPOLICIES":"Verwalte ZITADELs globale Zugangsrichtlinien und verwalte ZITADEL Manager",

View File

@@ -1,5 +1,29 @@
{
"APP_NAME": "ZITADEL",
"ONBOARDING": {
"HEADER":"First Steps",
"TITLE":"Learn how to use ZITADEL",
"LOGINDESC":"You need to log in to control your ZITADEL settings.",
"LOGIN":"Login",
"DESCRIPTION":"We at ZITADEL care a lot about security and performance. Carry out the following steps and adapt ZITADEL optimally to your needs.",
"STEPS_TITLE":"Complete the following steps in the order you want:",
"STEPS": {
"1": {
"TITLE":"Projekt erstellen",
"DESC":"Erstellen Sie Ihr erstes Projekt und legen Sie Zugangsberechtigungen eventueller Mitarbeiter fest."
},
"2": {
"TITLE":"Applikation erstellen",
"DESC":"Erstellen Sie eine Applikation innerhalb Ihres Projektes und legen Sie dessen Eigenschaften fest."
},
"3": {
"TITLE":"Sicherheit verbessern",
"DESC":"Erweitern Sie die Zugangsrichtlinien und erhöhen Sie dadurch die Sicherheit ihrer Benutzer."
}
},
"START":"Start",
"DOCS":"Docs"
},
"HOME": {
"TITLE": "ZITADEL",
"SECURITYANDPRIVACY": "Data Protection and Personalisation",
@@ -32,9 +56,15 @@
"WELCOME":"Welcome",
"WELCOMESENTENCE":"Here you can find recommended actions based on your last acquired permissions. Note that you may have to select your organisation in the header above.",
"DISCLAIMER":"You can only see settings of your current organisation specified in the header. ZITADEL treats your data confidentially and securely.",
"DISCLAIMERLINK":"Further information"
"DISCLAIMERLINK":"Further information",
"QUICKSTARTS": {
"LABEL":"First Steps",
"TITLE":"Quickstarts",
"DESCRIPTION":"Get started with ZITADEL quickly."
}
},
"MENU": {
"DASHBOARD":"Overview",
"PERSONAL_INFO": "Personal Information",
"DOCUMENTATION":"Documentation",
"IAMPOLICIES":"IAM",
@@ -54,6 +84,7 @@
"SHOWORGS":"Show All Organisations",
"GRANTSECTION":"Authorization Section",
"GRANTS":"Authorizations",
"TOC":"Privacy Policy and TOC",
"TOOLTIP": {
"PERSONAL":"Show your Personal Account, your IDPs, Login methods, Factors and Authorisations",
"IAMPOLICIES":"Manage ZITADELs global Access policies und elect ZITADEL Managers",

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 467 468" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,0,-492)">
<g id="zitadel-logo-solo-lightdesign" transform="matrix(0.564847,0,0,0.659318,-1282.85,492.925)">
<rect x="2271.15" y="0" width="826.773" height="708.241" style="fill:none;"/>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5923.46,-2258.26)">
<path d="M1493.5,1056.38L1493.5,1037L1496.5,1037L1496.5,1061.62L1426.02,1020.38L1496.5,979.392L1496.5,1004L1493.5,1004L1493.5,984.608L1431.98,1020.39L1493.5,1056.38Z" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(31.0036,0,0,15.0393,-397275,-666.457)">
<g transform="matrix(-0.0429306,-0.282967,0.160219,-0.0758207,12884.5,137.392)">
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear1);"/>
</g>
<g transform="matrix(0.160219,0.0758207,-0.0429306,0.282967,12878.9,10.8747)">
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear2);"/>
</g>
<g transform="matrix(-0.117289,0.207146,-0.117289,-0.207146,12943.8,65.7)">
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear3);"/>
</g>
<g transform="matrix(-0.160219,-0.0758207,0.0429306,-0.282967,12917.4,132.195)">
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear4);"/>
</g>
<g transform="matrix(-0.117289,0.207146,0.117289,0.207146,12897.8,5.87512)">
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear5);"/>
</g>
<g transform="matrix(-0.0429306,-0.282967,-0.160219,0.0758207,12936.8,97.6441)">
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear6);"/>
</g>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5928.43,-2257.12)">
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5884.5,-2116.69)">
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5855.22,-2023.06)">
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-6234.47,-2112.14)">
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5957.71,-2350.75)">
<circle cx="1496" cy="1004" r="7" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5477.99,-831.33)">
<path d="M1499.26,757.787C1499.26,757.787 1497.37,756.489 1497,755.2C1496.71,754.182 1496.57,750.662 1496.54,750C1496.41,747.303 1499.21,745.644 1499.21,745.644L1490.01,745.835C1490.01,745.835 1493.15,745.713 1493.46,750C1493.51,750.661 1493.23,753.476 1493,755.2C1492.91,756.447 1491.2,757.668 1491.2,757.668L1499.26,757.787Z" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
<path d="M1495,760L1495,744" style="fill:none;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
<path d="M1498.27,757.077C1498.27,757.077 1496.71,756.46 1496.65,754.8C1496.65,753.658 1496.64,753.281 1496.65,752.016C1496.62,751.334 1496.59,750.608 1496.65,749.949C1496.78,746.836 1498.5,746.156 1498.5,746.156L1491.46,745.931C1491.46,745.931 1493.37,746.719 1493.65,749.83C1493.71,750.489 1493.69,751.528 1493.65,752.209C1493.64,753.331 1493.64,753.413 1493.65,754.518C1493.68,756.334 1492.58,756.827 1492.58,756.827L1498.27,757.077Z" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
<path d="M1500.86,762.056C1500.86,762.056 1499.86,760.4 1503.09,757.456C1504.91,755.797 1507.33,754.151 1509.98,752.255C1514.82,748.79 1520.68,744.94 1526.52,741.049C1531.45,737.766 1536.38,734.479 1540.82,731.68C1544.52,729.349 1547.85,727.296 1550.54,725.8C1551.07,725.506 1551.6,725.329 1552.05,725.029C1554.73,723.257 1556.85,724.968 1556.85,724.968L1552.23,716.282C1552.23,716.282 1551.99,719.454 1550,720.997C1549.57,721.333 1549.15,721.741 1548.67,722.12C1546.2,724.053 1542.99,726.344 1539.39,728.867C1535.06,731.898 1530.13,735.166 1525.19,738.438C1519.35,742.314 1513.52,746.234 1508.49,749.329C1505.74,751.023 1503.28,752.577 1501.13,753.598C1497.99,755.086 1495.28,753.617 1495.28,753.617L1500.86,762.056Z" style="fill:rgb(35,35,35);"/>
</g>
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
</g>
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
<path d="M1496.1,754.362C1496.1,754.362 1497.2,755.607 1501.13,753.598C1503.25,752.509 1505.74,751.023 1508.49,749.329C1513.52,746.234 1519.35,742.314 1525.19,738.438C1530.13,735.166 1534.94,731.832 1539.27,728.802C1542.87,726.279 1549.36,722.059 1549.81,721.75C1552.75,719.73 1552.18,718.196 1552.18,718.196L1555.28,724.152C1555.28,724.152 1553.77,722.905 1551.37,724.681C1550.93,725.006 1544.52,729.349 1540.82,731.68C1536.38,734.479 1531.45,737.766 1526.52,741.049C1520.68,744.94 1514.82,748.79 1509.98,752.255C1507.33,754.151 1504.89,755.771 1503.09,757.456C1499.47,760.841 1501.26,763.283 1501.26,763.283L1496.1,754.362Z" style="fill:rgb(35,35,35);"/>
</g>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,155.247,-155.247,-41.5984,201.516,76.8392)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(155.247,-41.5984,41.5984,155.247,110.08,195.509)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,-113.649,113.649,-113.649,258.31,215.618)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-155.247,41.5984,-41.5984,-155.247,220.914,144.546)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,113.649,113.649,113.649,206.837,124.661)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,-155.247,-155.247,41.5984,152.054,262.8)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 467 467" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g id="zitadel-logo-solo-darkdesign" transform="matrix(0.564847,0,0,0.659318,-1282.85,0)">
<rect x="2271.15" y="0" width="826.773" height="708.241" style="fill:none;"/>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5923.46,-2258.26)">
<path d="M1493.5,1056.38L1493.5,1037L1496.5,1037L1496.5,1061.62L1426.02,1020.38L1496.5,979.392L1496.5,1004L1493.5,1004L1493.5,984.608L1431.98,1020.39L1493.5,1056.38Z" style="fill:white;"/>
</g>
<g transform="matrix(31.0036,0,0,15.0393,-397275,-666.457)">
<g transform="matrix(-0.0429306,-0.282967,0.160219,-0.0758207,12884.5,137.392)">
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear1);"/>
</g>
<g transform="matrix(0.160219,0.0758207,-0.0429306,0.282967,12878.9,10.8747)">
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear2);"/>
</g>
<g transform="matrix(-0.117289,0.207146,-0.117289,-0.207146,12943.8,65.7)">
<path d="M212.517,110L200.392,110L190,92L179.608,110L167.483,110L190,71L212.517,110Z" style="fill:url(#_Linear3);"/>
</g>
<g transform="matrix(-0.160219,-0.0758207,0.0429306,-0.282967,12917.4,132.195)">
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear4);"/>
</g>
<g transform="matrix(-0.117289,0.207146,0.117289,0.207146,12897.8,5.87512)">
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear5);"/>
</g>
<g transform="matrix(-0.0429306,-0.282967,-0.160219,0.0758207,12936.8,97.6441)">
<path d="M139.622,117L149,142L130.244,142L139.622,117Z" style="fill:url(#_Linear6);"/>
</g>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5928.43,-2257.12)">
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5884.5,-2116.69)">
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5855.22,-2023.06)">
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-6234.47,-2112.14)">
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.331,4.25561,-5957.71,-2350.75)">
<circle cx="1496" cy="1004" r="7" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5477.99,-831.33)">
<path d="M1499.26,757.787C1499.26,757.787 1497.37,756.489 1497,755.2C1496.71,754.182 1496.57,750.662 1496.54,750C1496.41,747.303 1499.21,745.644 1499.21,745.644L1490.01,745.835C1490.01,745.835 1493.15,745.713 1493.46,750C1493.51,750.661 1493.23,753.476 1493,755.2C1492.91,756.447 1491.2,757.668 1491.2,757.668L1499.26,757.787Z" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
<path d="M1495,760L1495,744" style="fill:none;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5404.79,-597.271)">
<path d="M1498.27,757.077C1498.27,757.077 1496.71,756.46 1496.65,754.8C1496.65,753.658 1496.64,753.281 1496.65,752.016C1496.62,751.334 1496.59,750.608 1496.65,749.949C1496.78,746.836 1498.5,746.156 1498.5,746.156L1491.46,745.931C1491.46,745.931 1493.37,746.719 1493.65,749.83C1493.71,750.489 1493.69,751.528 1493.65,752.209C1493.64,753.331 1493.64,753.413 1493.65,754.518C1493.68,756.334 1492.58,756.827 1492.58,756.827L1498.27,757.077Z" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
</g>
<g transform="matrix(4.96737,-1.14029,1.16463,3.72366,-5770.62,-677.495)">
<path d="M1500.86,762.056C1500.86,762.056 1499.86,760.4 1503.09,757.456C1504.91,755.797 1507.33,754.151 1509.98,752.255C1514.82,748.79 1520.68,744.94 1526.52,741.049C1531.45,737.766 1536.38,734.479 1540.82,731.68C1544.52,729.349 1547.85,727.296 1550.54,725.8C1551.07,725.506 1551.6,725.329 1552.05,725.029C1554.73,723.257 1556.85,724.968 1556.85,724.968L1552.23,716.282C1552.23,716.282 1551.99,719.454 1550,720.997C1549.57,721.333 1549.15,721.741 1548.67,722.12C1546.2,724.053 1542.99,726.344 1539.39,728.867C1535.06,731.898 1530.13,735.166 1525.19,738.438C1519.35,742.314 1513.52,746.234 1508.49,749.329C1505.74,751.023 1503.28,752.577 1501.13,753.598C1497.99,755.086 1495.28,753.617 1495.28,753.617L1500.86,762.056Z" style="fill:white;"/>
</g>
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
<path d="M1496.17,759.473L1555.54,720.014" style="fill:none;"/>
</g>
<g transform="matrix(4.96737,-1.14029,-1.16463,-3.72366,-3997,4993.28)">
<path d="M1496.1,754.362C1496.1,754.362 1497.2,755.607 1501.13,753.598C1503.25,752.509 1505.74,751.023 1508.49,749.329C1513.52,746.234 1519.35,742.314 1525.19,738.438C1530.13,735.166 1534.94,731.832 1539.27,728.802C1542.87,726.279 1549.36,722.059 1549.81,721.75C1552.75,719.73 1552.18,718.196 1552.18,718.196L1555.28,724.152C1555.28,724.152 1553.77,722.905 1551.37,724.681C1550.93,725.006 1544.52,729.349 1540.82,731.68C1536.38,734.479 1531.45,737.766 1526.52,741.049C1520.68,744.94 1514.82,748.79 1509.98,752.255C1507.33,754.151 1504.89,755.771 1503.09,757.456C1499.47,760.841 1501.26,763.283 1501.26,763.283L1496.1,754.362Z" style="fill:white;"/>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,155.247,-155.247,-41.5984,201.516,76.8392)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(155.247,-41.5984,41.5984,155.247,110.08,195.509)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,-113.649,113.649,-113.649,258.31,215.618)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-155.247,41.5984,-41.5984,-155.247,220.914,144.546)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-113.649,113.649,113.649,113.649,206.837,124.661)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
<linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-41.5984,-155.247,-155.247,41.5984,152.054,262.8)"><stop offset="0" style="stop-color:rgb(255,143,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(254,0,255);stop-opacity:1"/></linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -15,6 +15,7 @@
@import 'src/app/modules/form-field/form-field.component.scss';
@import 'src/app/modules/label/label.component.scss';
@import 'src/app/modules/meta-layout/meta.scss';
@import 'src/app/modules/onboarding/onboarding.component.scss';
@mixin component-themes($theme) {
@include avatar-theme($theme);
@@ -34,4 +35,5 @@
@include link-theme($theme);
@include meta-theme($theme);
@include info-section-theme($theme);
@include onboarding-theme($theme);
}

View File

@@ -29,6 +29,7 @@
<meta name="twitter:title" content="ZITADEL Console" />
<meta name="twitter:description" content="Management Platform for ZITADEL IAM" />
<meta name="twitter:image" content="https://www.zitadel.ch/zitadel-social-preview25.png">
<script src="https://statuspal.io/js/widget.js"></script>
</head>
<body>

View File

@@ -219,18 +219,21 @@ $custom-typography:
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
background-color: #2d2e30;
border-radius: 8px;
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
background-color: #2d2e30;
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
}
::-webkit-scrollbar-thumb {
background-color: #737c8870;
border-radius: 8px;
cursor: pointer;
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
}
.root-header {

View File

@@ -16,18 +16,23 @@
box-shadow: inset 1px 0 if($is-dark-theme, #303131, #e3e8ee);
}
.sidenav {
box-shadow: inset -1px 0 if($is-dark-theme, #303131, #e3e8ee);
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
}
.nav-item {
color: mat-color($foreground, text) !important;
&:hover {
background-color: $sec-dark;
background-color: if($is-dark-theme, $sec-dark, rgb(84 105 212 / 6%));
border-top-right-radius: 1.5rem;
border-bottom-right-radius: 1.5rem;
}
&.active {
color: $primary-color !important;
background-color: rgba($color: $primary-color, $alpha: .1) !important;
background-color: if($is-dark-theme, rgba($color: $primary-color, $alpha: .1), rgb(84 105 212 / 6%)) !important;
}
.c_label {
@@ -54,7 +59,16 @@
.root-header {
box-shadow: inset 0 -1px #e3e8ee;
background-color: $primary-dark !important;
transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
transition: all .3s cubic-bezier(.645, .045, .355, 1);
.slash {
color: if($is-dark-theme, #525454, #d1d5d9);
}
.org-button {
border: 1px solid if($is-dark-theme, #303131, #e3e8ee);
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
}
}
.admin-line {