mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 23:37:23 +00:00
feat(console): deactivate, reactivate org, fix signedout route (#3834)
* org detail * feat: org deactivate, reactivate * statehandler includes instead of startsWith * fix signout route * Update console/src/assets/i18n/de.json Co-authored-by: Livio Spring <livio.a@gmail.com> * french Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
parent
91771bc49b
commit
190a454140
@ -13,6 +13,10 @@ const routes: Routes = [
|
|||||||
loadChildren: () => import('./pages/home/home.module').then((m) => m.HomeModule),
|
loadChildren: () => import('./pages/home/home.module').then((m) => m.HomeModule),
|
||||||
canActivate: [AuthGuard],
|
canActivate: [AuthGuard],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'signedout',
|
||||||
|
loadChildren: () => import('./pages/signedout/signedout.module').then((m) => m.SignedoutModule),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'orgs',
|
path: 'orgs',
|
||||||
loadChildren: () => import('./pages/org-list/org-list.module').then((m) => m.OrgListModule),
|
loadChildren: () => import('./pages/org-list/org-list.module').then((m) => m.OrgListModule),
|
||||||
@ -38,12 +42,7 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: 'users',
|
path: 'users',
|
||||||
canActivate: [AuthGuard],
|
canActivate: [AuthGuard],
|
||||||
children: [
|
loadChildren: () => import('src/app/pages/users/users.module').then((m) => m.UsersModule),
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
loadChildren: () => import('src/app/pages/users/users.module').then((m) => m.UsersModule),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'instance',
|
path: 'instance',
|
||||||
@ -170,10 +169,6 @@ const routes: Routes = [
|
|||||||
roles: ['policy.read'],
|
roles: ['policy.read'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'signedout',
|
|
||||||
loadChildren: () => import('./pages/signedout/signedout.module').then((m) => m.SignedoutModule),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
redirectTo: '/',
|
redirectTo: '/',
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
<ng-container *ngIf="(authService.user | async) || undefined as user">
|
<div class="main-container">
|
||||||
<ng-container *ngIf="['iam.read$', 'iam.write$'] | hasRole as iamuser$">
|
<ng-container *ngIf="(authService.user | async) || {} as user">
|
||||||
<div class="main-container">
|
<cnsl-header
|
||||||
<cnsl-header
|
*ngIf="user && user !== {}"
|
||||||
*ngIf="user"
|
[org]="org"
|
||||||
[org]="org"
|
[user]="$any(user)"
|
||||||
[user]="user"
|
[isDarkTheme]="componentCssClass === 'dark-theme'"
|
||||||
[isDarkTheme]="componentCssClass === 'dark-theme'"
|
[labelpolicy]="labelpolicy"
|
||||||
[labelpolicy]="labelpolicy"
|
(changedActiveOrg)="changedOrg($event)"
|
||||||
(changedActiveOrg)="changedOrg($event)"
|
></cnsl-header>
|
||||||
></cnsl-header>
|
|
||||||
|
|
||||||
<cnsl-nav
|
<cnsl-nav
|
||||||
id="mainnav"
|
id="mainnav"
|
||||||
class="nav"
|
class="nav"
|
||||||
[ngClass]="{ shadow: yoffset > 60 }"
|
[ngClass]="{ shadow: yoffset > 60 }"
|
||||||
*ngIf="user"
|
*ngIf="user && user !== {}"
|
||||||
[org]="org"
|
[org]="org"
|
||||||
[user]="user"
|
[user]="$any(user)"
|
||||||
[isDarkTheme]="componentCssClass === 'dark-theme'"
|
[isDarkTheme]="componentCssClass === 'dark-theme'"
|
||||||
[labelpolicy]="labelpolicy"
|
[labelpolicy]="labelpolicy"
|
||||||
></cnsl-nav>
|
></cnsl-nav>
|
||||||
<div class="router-container" [@routeAnimations]="prepareRoute(outlet)">
|
|
||||||
<div class="outlet">
|
|
||||||
<router-outlet class="outlet" #outlet="outlet"></router-outlet>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
<cnsl-footer [privateLabelPolicy]="labelpolicy"></cnsl-footer>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
|
||||||
|
<div class="router-container" [@routeAnimations]="prepareRoute(outlet)">
|
||||||
|
<div class="outlet">
|
||||||
|
<router-outlet class="outlet" #outlet="outlet"></router-outlet>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="fill-space"></span>
|
||||||
|
<cnsl-footer [privateLabelPolicy]="labelpolicy"></cnsl-footer>
|
||||||
|
</div>
|
||||||
|
@ -69,6 +69,7 @@ export class AppComponent implements OnDestroy {
|
|||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
) {
|
) {
|
||||||
|
this.themeService.loadPrivateLabelling(true);
|
||||||
console.log(
|
console.log(
|
||||||
'%cWait!',
|
'%cWait!',
|
||||||
'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5469D4; font-size: 50px',
|
'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5469D4; font-size: 50px',
|
||||||
|
@ -26,7 +26,6 @@ import { HeaderModule } from './modules/header/header.module';
|
|||||||
import { KeyboardShortcutsModule } from './modules/keyboard-shortcuts/keyboard-shortcuts.module';
|
import { KeyboardShortcutsModule } from './modules/keyboard-shortcuts/keyboard-shortcuts.module';
|
||||||
import { NavModule } from './modules/nav/nav.module';
|
import { NavModule } from './modules/nav/nav.module';
|
||||||
import { WarnDialogModule } from './modules/warn-dialog/warn-dialog.module';
|
import { WarnDialogModule } from './modules/warn-dialog/warn-dialog.module';
|
||||||
import { SignedoutComponent } from './pages/signedout/signedout.component';
|
|
||||||
import { HasRolePipeModule } from './pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from './pipes/has-role-pipe/has-role-pipe.module';
|
||||||
import { AdminService } from './services/admin.service';
|
import { AdminService } from './services/admin.service';
|
||||||
import { AuthenticationService } from './services/authentication.service';
|
import { AuthenticationService } from './services/authentication.service';
|
||||||
@ -79,7 +78,7 @@ const authConfig: AuthConfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent, SignedoutComponent],
|
declarations: [AppComponent],
|
||||||
imports: [
|
imports: [
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
@ -4,13 +4,12 @@ import { AuthConfig } from 'angular-oauth2-oidc';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import { AuthenticationService } from '../services/authentication.service';
|
import { AuthenticationService } from '../services/authentication.service';
|
||||||
import { GrpcAuthService } from '../services/grpc-auth.service';
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AuthGuard implements CanActivate {
|
export class AuthGuard implements CanActivate {
|
||||||
constructor(private auth: AuthenticationService, private authService: GrpcAuthService) {}
|
constructor(private auth: AuthenticationService) {}
|
||||||
|
|
||||||
public canActivate(
|
public canActivate(
|
||||||
route: ActivatedRouteSnapshot,
|
route: ActivatedRouteSnapshot,
|
||||||
|
@ -196,55 +196,56 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="account-card-wrapper">
|
<ng-container
|
||||||
<button
|
*ngIf="user && (user.human?.profile?.displayName || (user.human?.profile?.firstName && user.human?.profile?.lastName))"
|
||||||
cdkOverlayOrigin
|
|
||||||
#accounttrigger="cdkOverlayOrigin"
|
|
||||||
class="icon-container"
|
|
||||||
(click)="showAccount = !showAccount"
|
|
||||||
[ngClass]="{ 'iam-user': (['iam.write$'] | hasRole | async) }"
|
|
||||||
>
|
|
||||||
<cnsl-avatar
|
|
||||||
id="avatartoggle"
|
|
||||||
*ngIf="
|
|
||||||
user && (user.human?.profile?.displayName || (user.human?.profile?.firstName && user.human?.profile?.lastName))
|
|
||||||
"
|
|
||||||
class="avatar-toggle dontcloseonclick"
|
|
||||||
[active]="showAccount"
|
|
||||||
[avatarUrl]="user.human?.profile?.avatarUrl || ''"
|
|
||||||
[forColor]="user?.preferredLoginName || ''"
|
|
||||||
[name]="
|
|
||||||
user.human?.profile?.displayName
|
|
||||||
? user.human?.profile?.displayName ?? ''
|
|
||||||
: user.human?.profile?.firstName + ' ' + user.human?.profile?.lastName
|
|
||||||
"
|
|
||||||
[size]="38"
|
|
||||||
>
|
|
||||||
</cnsl-avatar>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<ng-template
|
|
||||||
cdkConnectedOverlay
|
|
||||||
[cdkConnectedOverlayOrigin]="accounttrigger"
|
|
||||||
[flexibleDimensions]="true"
|
|
||||||
[lockPosition]="true"
|
|
||||||
[cdkConnectedOverlayOffsetY]="10"
|
|
||||||
[cdkConnectedOverlayHasBackdrop]="true"
|
|
||||||
[cdkConnectedOverlayPositions]="accountCardPositions"
|
|
||||||
cdkConnectedOverlayBackdropClass="transparent-backdrop"
|
|
||||||
[cdkConnectedOverlayOpen]="showAccount"
|
|
||||||
(backdropClick)="showAccount = false"
|
|
||||||
(detach)="showAccount = false"
|
|
||||||
>
|
>
|
||||||
<cnsl-accounts-card
|
<div class="account-card-wrapper">
|
||||||
@accounts
|
<button
|
||||||
class="a_card"
|
cdkOverlayOrigin
|
||||||
*ngIf="showAccount"
|
#accounttrigger="cdkOverlayOrigin"
|
||||||
(closedCard)="showAccount = false"
|
class="icon-container"
|
||||||
[user]="user"
|
(click)="showAccount = !showAccount"
|
||||||
[iamuser]="['iam.write$'] | hasRole | async"
|
[ngClass]="{ 'iam-user': (['iam.write$'] | hasRole | async) }"
|
||||||
|
>
|
||||||
|
<cnsl-avatar
|
||||||
|
id="avatartoggle"
|
||||||
|
class="avatar-toggle dontcloseonclick"
|
||||||
|
[active]="showAccount"
|
||||||
|
[avatarUrl]="user.human?.profile?.avatarUrl || ''"
|
||||||
|
[forColor]="user?.preferredLoginName || ''"
|
||||||
|
[name]="
|
||||||
|
user.human?.profile?.displayName
|
||||||
|
? user.human?.profile?.displayName ?? ''
|
||||||
|
: user.human?.profile?.firstName + ' ' + user.human?.profile?.lastName
|
||||||
|
"
|
||||||
|
[size]="38"
|
||||||
|
>
|
||||||
|
</cnsl-avatar>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ng-template
|
||||||
|
cdkConnectedOverlay
|
||||||
|
[cdkConnectedOverlayOrigin]="accounttrigger"
|
||||||
|
[flexibleDimensions]="true"
|
||||||
|
[lockPosition]="true"
|
||||||
|
[cdkConnectedOverlayOffsetY]="10"
|
||||||
|
[cdkConnectedOverlayHasBackdrop]="true"
|
||||||
|
[cdkConnectedOverlayPositions]="accountCardPositions"
|
||||||
|
cdkConnectedOverlayBackdropClass="transparent-backdrop"
|
||||||
|
[cdkConnectedOverlayOpen]="showAccount"
|
||||||
|
(backdropClick)="showAccount = false"
|
||||||
|
(detach)="showAccount = false"
|
||||||
>
|
>
|
||||||
</cnsl-accounts-card>
|
<cnsl-accounts-card
|
||||||
</ng-template>
|
@accounts
|
||||||
|
class="a_card"
|
||||||
|
*ngIf="showAccount"
|
||||||
|
(closedCard)="showAccount = false"
|
||||||
|
[user]="user"
|
||||||
|
[iamuser]="['iam.write$'] | hasRole | async"
|
||||||
|
>
|
||||||
|
</cnsl-accounts-card>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
@ -5,7 +5,25 @@
|
|||||||
[isInactive]="org?.state === OrgState.ORG_STATE_INACTIVE"
|
[isInactive]="org?.state === OrgState.ORG_STATE_INACTIVE"
|
||||||
[hasContributors]="true"
|
[hasContributors]="true"
|
||||||
stateTooltip="{{ 'ORG.STATE.' + org?.state | translate }}"
|
stateTooltip="{{ 'ORG.STATE.' + org?.state | translate }}"
|
||||||
|
[hasActions]="['org.write:' + org?.id, 'org.write$'] | hasRole | async"
|
||||||
>
|
>
|
||||||
|
<ng-template topActions cnslHasRole [hasRole]="['org.write:' + org?.id, 'org.write$']">
|
||||||
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
*ngIf="org?.state === OrgState.ORG_STATE_ACTIVE"
|
||||||
|
(click)="changeState(OrgState.ORG_STATE_INACTIVE)"
|
||||||
|
>
|
||||||
|
{{ 'ORG.PAGES.DEACTIVATE' | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
*ngIf="org?.state === OrgState.ORG_STATE_INACTIVE"
|
||||||
|
(click)="changeState(OrgState.ORG_STATE_ACTIVE)"
|
||||||
|
>
|
||||||
|
{{ 'ORG.PAGES.REACTIVATE' | translate }}
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
<cnsl-contributors
|
<cnsl-contributors
|
||||||
topContributors
|
topContributors
|
||||||
[totalResult]="totalMemberResult"
|
[totalResult]="totalMemberResult"
|
||||||
|
@ -7,6 +7,7 @@ import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-m
|
|||||||
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
||||||
import { InfoSectionType } from 'src/app/modules/info-section/info-section.component';
|
import { InfoSectionType } from 'src/app/modules/info-section/info-section.component';
|
||||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||||
|
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||||
import { Member } from 'src/app/proto/generated/zitadel/member_pb';
|
import { Member } from 'src/app/proto/generated/zitadel/member_pb';
|
||||||
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
|
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
|
||||||
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
||||||
@ -62,6 +63,56 @@ export class OrgDetailComponent implements OnInit, OnDestroy {
|
|||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public changeState(newState: OrgState): void {
|
||||||
|
if (newState === OrgState.ORG_STATE_ACTIVE) {
|
||||||
|
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||||
|
data: {
|
||||||
|
confirmKey: 'ACTIONS.REACTIVATE',
|
||||||
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
|
titleKey: 'ORG.DIALOG.REACTIVATE.TITLE',
|
||||||
|
descriptionKey: 'ORG.DIALOG.REACTIVATE.DESCRIPTION',
|
||||||
|
},
|
||||||
|
width: '400px',
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().subscribe((resp) => {
|
||||||
|
if (resp) {
|
||||||
|
this.mgmtService
|
||||||
|
.reactivateOrg()
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('ORG.TOAST.REACTIVATED', true);
|
||||||
|
this.org.state = OrgState.ORG_STATE_ACTIVE;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (newState === OrgState.ORG_STATE_INACTIVE) {
|
||||||
|
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||||
|
data: {
|
||||||
|
confirmKey: 'ACTIONS.DEACTIVATE',
|
||||||
|
cancelKey: 'ACTIONS.CANCEL',
|
||||||
|
titleKey: 'ORG.DIALOG.DEACTIVATE.TITLE',
|
||||||
|
descriptionKey: 'ORG.DIALOG.DEACTIVATE.DESCRIPTION',
|
||||||
|
},
|
||||||
|
width: '400px',
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().subscribe((resp) => {
|
||||||
|
if (resp) {
|
||||||
|
this.mgmtService
|
||||||
|
.deactivateOrg()
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('ORG.TOAST.DEACTIVATED', true);
|
||||||
|
this.org.state = OrgState.ORG_STATE_INACTIVE;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async getData(): Promise<void> {
|
private async getData(): Promise<void> {
|
||||||
this.mgmtService
|
this.mgmtService
|
||||||
.getMyOrg()
|
.getMyOrg()
|
||||||
|
@ -4,14 +4,14 @@ import { RouterModule, Routes } from '@angular/router';
|
|||||||
import { SignedoutComponent } from './signedout.component';
|
import { SignedoutComponent } from './signedout.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: SignedoutComponent,
|
component: SignedoutComponent,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forChild(routes)],
|
imports: [RouterModule.forChild(routes)],
|
||||||
exports: [RouterModule],
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class SignedoutRoutingModule { }
|
export class SignedoutRoutingModule {}
|
||||||
|
@ -5,11 +5,18 @@
|
|||||||
<ng-template #lighttheme>
|
<ng-template #lighttheme>
|
||||||
<img alt="zitadel logo" src="../../../assets/images/zitadel-logo-dark.svg" />
|
<img alt="zitadel logo" src="../../../assets/images/zitadel-logo-dark.svg" />
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<p class="cnsl-secondary-text">{{'USER.SIGNEDOUT' | translate}}</p>
|
<p class="cnsl-secondary-text">{{ 'USER.SIGNEDOUT' | translate }}</p>
|
||||||
|
|
||||||
<button matTooltip="{{'ACTIONS.LOGIN' | translate}}" color="primary" mat-raised-button
|
<button
|
||||||
[routerLink]="[ '/users/me' ]">{{'USER.SIGNEDOUT_BTN' |
|
class="cnsl-action-button"
|
||||||
translate}} <i class="las la-sign-in-alt"></i></button>
|
matTooltip="{{ 'ACTIONS.LOGIN' | translate }}"
|
||||||
|
color="primary"
|
||||||
|
mat-raised-button
|
||||||
|
[routerLink]="['/users/me']"
|
||||||
|
>
|
||||||
|
<i class="las la-sign-in-alt"></i>
|
||||||
|
<span>{{ 'USER.SIGNEDOUT_BTN' | translate }}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin-top: 50px;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
@ -24,16 +25,6 @@
|
|||||||
img {
|
img {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
max-width: 170px;
|
max-width: 170px;
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
display: block;
|
|
||||||
padding: 0.5rem 4rem;
|
|
||||||
|
|
||||||
i {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { ThemeService } from 'src/app/services/theme.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cnsl-signedout',
|
selector: 'cnsl-signedout',
|
||||||
@ -8,7 +9,9 @@ import { Component } from '@angular/core';
|
|||||||
export class SignedoutComponent {
|
export class SignedoutComponent {
|
||||||
public dark: boolean = true;
|
public dark: boolean = true;
|
||||||
|
|
||||||
constructor() {
|
constructor(themeService: ThemeService) {
|
||||||
|
themeService.loadPrivateLabelling();
|
||||||
|
|
||||||
const theme = localStorage.getItem('theme');
|
const theme = localStorage.getItem('theme');
|
||||||
this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true;
|
this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
import { SharedModule } from 'src/app/modules/shared/shared.module';
|
||||||
|
|
||||||
import { SignedoutRoutingModule } from './signedout-routing.module';
|
import { SignedoutRoutingModule } from './signedout-routing.module';
|
||||||
|
import { SignedoutComponent } from './signedout.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
declarations: [SignedoutComponent],
|
||||||
imports: [
|
imports: [CommonModule, SignedoutRoutingModule, MatButtonModule, MatTooltipModule, TranslateModule, SharedModule],
|
||||||
CommonModule,
|
|
||||||
SignedoutRoutingModule,
|
|
||||||
SharedModule,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class SignedoutModule { }
|
export class SignedoutModule {}
|
||||||
|
@ -49,10 +49,10 @@ export class StatehandlerServiceImpl implements StatehandlerService, OnDestroy {
|
|||||||
switchMap((url: string) => {
|
switchMap((url: string) => {
|
||||||
if (url.includes('?login_hint=')) {
|
if (url.includes('?login_hint=')) {
|
||||||
const newUrl = this.removeParam('login_hint', url);
|
const newUrl = this.removeParam('login_hint', url);
|
||||||
const urlWithoutBasePath = newUrl.startsWith('/ui/console') ? newUrl.replace('/ui/console', '') : newUrl;
|
const urlWithoutBasePath = newUrl.includes('/ui/console') ? newUrl.replace('/ui/console', '') : newUrl;
|
||||||
return of(this.processor.createState(urlWithoutBasePath));
|
return of(this.processor.createState(urlWithoutBasePath));
|
||||||
} else if (url) {
|
} else if (url) {
|
||||||
const urlWithoutBasePath = url.startsWith('/ui/console') ? url.replace('/ui/console', '') : url;
|
const urlWithoutBasePath = url.includes('/ui/console') ? url.replace('/ui/console', '') : url;
|
||||||
return of(this.processor.createState(urlWithoutBasePath));
|
return of(this.processor.createState(urlWithoutBasePath));
|
||||||
} else {
|
} else {
|
||||||
return of(undefined);
|
return of(undefined);
|
||||||
|
@ -140,70 +140,72 @@ export class ThemeService {
|
|||||||
this.saveTextColor(lightText, false);
|
this.saveTextColor(lightText, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
public loadPrivateLabelling(): void {
|
public loadPrivateLabelling(forceDefault: boolean = false): void {
|
||||||
this.setDefaultColors();
|
if (forceDefault) {
|
||||||
|
this.setDefaultColors();
|
||||||
|
} else {
|
||||||
|
const isDark = (color: string) => this.isDark(color);
|
||||||
|
const isLight = (color: string) => this.isLight(color);
|
||||||
|
|
||||||
const isDark = (color: string) => this.isDark(color);
|
this.authService
|
||||||
const isLight = (color: string) => this.isLight(color);
|
.getMyLabelPolicy()
|
||||||
|
.then((lpresp) => {
|
||||||
|
const labelpolicy = lpresp.policy;
|
||||||
|
|
||||||
this.authService
|
const darkPrimary = labelpolicy?.primaryColorDark || '#bbbafa';
|
||||||
.getMyLabelPolicy()
|
const lightPrimary = labelpolicy?.primaryColor || '#5469d4';
|
||||||
.then((lpresp) => {
|
|
||||||
const labelpolicy = lpresp.policy;
|
|
||||||
|
|
||||||
const darkPrimary = labelpolicy?.primaryColorDark || '#bbbafa';
|
const darkWarn = labelpolicy?.warnColorDark || '#ff3b5b';
|
||||||
const lightPrimary = labelpolicy?.primaryColor || '#5469d4';
|
const lightWarn = labelpolicy?.warnColor || '#cd3d56';
|
||||||
|
|
||||||
const darkWarn = labelpolicy?.warnColorDark || '#ff3b5b';
|
let darkBackground = labelpolicy?.backgroundColorDark;
|
||||||
const lightWarn = labelpolicy?.warnColor || '#cd3d56';
|
let lightBackground = labelpolicy?.backgroundColor;
|
||||||
|
|
||||||
let darkBackground = labelpolicy?.backgroundColorDark;
|
let darkText = labelpolicy?.fontColorDark ?? '#ffffff';
|
||||||
let lightBackground = labelpolicy?.backgroundColor;
|
let lightText = labelpolicy?.fontColor ?? '#000000';
|
||||||
|
|
||||||
let darkText = labelpolicy?.fontColorDark ?? '#ffffff';
|
this.savePrimaryColor(darkPrimary, true);
|
||||||
let lightText = labelpolicy?.fontColor ?? '#000000';
|
this.savePrimaryColor(lightPrimary, false);
|
||||||
|
|
||||||
this.savePrimaryColor(darkPrimary, true);
|
this.saveWarnColor(darkWarn, true);
|
||||||
this.savePrimaryColor(lightPrimary, false);
|
this.saveWarnColor(lightWarn, false);
|
||||||
|
|
||||||
this.saveWarnColor(darkWarn, true);
|
if (darkBackground && !isDark(darkBackground)) {
|
||||||
this.saveWarnColor(lightWarn, false);
|
console.info(
|
||||||
|
`Background (${darkBackground}) is not dark enough for a dark theme. Falling back to zitadel background`,
|
||||||
|
);
|
||||||
|
darkBackground = '#111827';
|
||||||
|
}
|
||||||
|
this.saveBackgroundColor(darkBackground || '#111827', true);
|
||||||
|
|
||||||
if (darkBackground && !isDark(darkBackground)) {
|
if (lightBackground && !isLight(lightBackground)) {
|
||||||
console.info(
|
console.info(
|
||||||
`Background (${darkBackground}) is not dark enough for a dark theme. Falling back to zitadel background`,
|
`Background (${lightBackground}) is not light enough for a light theme. Falling back to zitadel background`,
|
||||||
);
|
);
|
||||||
darkBackground = '#111827';
|
lightBackground = '#fafafa';
|
||||||
}
|
}
|
||||||
this.saveBackgroundColor(darkBackground || '#111827', true);
|
this.saveBackgroundColor(lightBackground || '#fafafa', false);
|
||||||
|
|
||||||
if (lightBackground && !isLight(lightBackground)) {
|
if (darkText && !isLight(darkText)) {
|
||||||
console.info(
|
console.info(
|
||||||
`Background (${lightBackground}) is not light enough for a light theme. Falling back to zitadel background`,
|
`Text color (${darkText}) is not light enough for a dark theme. Falling back to zitadel's text color`,
|
||||||
);
|
);
|
||||||
lightBackground = '#fafafa';
|
darkText = '#ffffff';
|
||||||
}
|
}
|
||||||
this.saveBackgroundColor(lightBackground || '#fafafa', false);
|
this.saveTextColor(darkText || '#ffffff', true);
|
||||||
|
|
||||||
if (darkText && !isLight(darkText)) {
|
if (lightText && !isDark(lightText)) {
|
||||||
console.info(
|
console.info(
|
||||||
`Text color (${darkText}) is not light enough for a dark theme. Falling back to zitadel's text color`,
|
`Text color (${lightText}) is not dark enough for a light theme. Falling back to zitadel's text color`,
|
||||||
);
|
);
|
||||||
darkText = '#ffffff';
|
lightText = '#000000';
|
||||||
}
|
}
|
||||||
this.saveTextColor(darkText || '#ffffff', true);
|
this.saveTextColor(lightText || '#000000', false);
|
||||||
|
})
|
||||||
if (lightText && !isDark(lightText)) {
|
.catch((error) => {
|
||||||
console.info(
|
console.error('could not load private labelling policy!', error);
|
||||||
`Text color (${lightText}) is not dark enough for a light theme. Falling back to zitadel's text color`,
|
this.setDefaultColors();
|
||||||
);
|
});
|
||||||
lightText = '#000000';
|
}
|
||||||
}
|
|
||||||
this.saveTextColor(lightText || '#000000', false);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('could not load private labelling policy!', error);
|
|
||||||
this.setDefaultColors();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -757,6 +757,8 @@
|
|||||||
"LISTDESCRIPTION": "Wähle eine Organisation aus.",
|
"LISTDESCRIPTION": "Wähle eine Organisation aus.",
|
||||||
"ACTIVE": "Aktiv",
|
"ACTIVE": "Aktiv",
|
||||||
"CREATE": "Organisation erstellen",
|
"CREATE": "Organisation erstellen",
|
||||||
|
"DEACTIVATE": "Organisation deaktivieren",
|
||||||
|
"REACTIVATE": "Organisation reaktivieren",
|
||||||
"NOPERMISSION": "Sie haben keine Berechtigung, auf Einstellungen der Organisation zuzugreifen.",
|
"NOPERMISSION": "Sie haben keine Berechtigung, auf Einstellungen der Organisation zuzugreifen.",
|
||||||
"USERSELFACCOUNT": "Verwenden Sie Ihr persönliches Konto als Organisationsinhaber",
|
"USERSELFACCOUNT": "Verwenden Sie Ihr persönliches Konto als Organisationsinhaber",
|
||||||
"ORGDETAIL_TITLE": "Gebe den Namen und die Domain für die neue Organisation ein.",
|
"ORGDETAIL_TITLE": "Gebe den Namen und die Domain für die neue Organisation ein.",
|
||||||
@ -821,6 +823,16 @@
|
|||||||
"MEMBERREMOVED": "Manager entfernt.",
|
"MEMBERREMOVED": "Manager entfernt.",
|
||||||
"MEMBERCHANGED": "Manager geändert.",
|
"MEMBERCHANGED": "Manager geändert.",
|
||||||
"SETPRIMARY": "Primäre Domain gesetzt."
|
"SETPRIMARY": "Primäre Domain gesetzt."
|
||||||
|
},
|
||||||
|
"DIALOG": {
|
||||||
|
"DEACTIVATE": {
|
||||||
|
"TITLE": "Organisation deaktivieren",
|
||||||
|
"DESCRIPTION": "Sie sind im Begriff Ihre Organisation zu deaktivieren. User können Sich danach nicht mehr anmelden? Wollen Sie fortfahren?"
|
||||||
|
},
|
||||||
|
"REACTIVATE": {
|
||||||
|
"TITLE": "Organisation reaktivieren",
|
||||||
|
"DESCRIPTION": "Sie sind im Begriff Ihre Organisation zu reaktivieren. User können Sich danach wieder anmelden? Wollen Sie fortfahren?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SETTINGS": {
|
"SETTINGS": {
|
||||||
|
@ -757,6 +757,8 @@
|
|||||||
"LISTDESCRIPTION": "Choose an organization.",
|
"LISTDESCRIPTION": "Choose an organization.",
|
||||||
"ACTIVE": "Active",
|
"ACTIVE": "Active",
|
||||||
"CREATE": "Create Organization",
|
"CREATE": "Create Organization",
|
||||||
|
"DEACTIVATE": "Deactivate Organization",
|
||||||
|
"REACTIVATE": "Reactivate Organization",
|
||||||
"NOPERMISSION": "You don't have the permission to access organization settings.",
|
"NOPERMISSION": "You don't have the permission to access organization settings.",
|
||||||
"USERSELFACCOUNT": "Use your personal account as organization owner",
|
"USERSELFACCOUNT": "Use your personal account as organization owner",
|
||||||
"ORGDETAIL_TITLE": "Enter the name and domain of your new organization.",
|
"ORGDETAIL_TITLE": "Enter the name and domain of your new organization.",
|
||||||
@ -821,6 +823,16 @@
|
|||||||
"MEMBERREMOVED": "Manager removed.",
|
"MEMBERREMOVED": "Manager removed.",
|
||||||
"MEMBERCHANGED": "Manager changed.",
|
"MEMBERCHANGED": "Manager changed.",
|
||||||
"SETPRIMARY": "Primary domain set."
|
"SETPRIMARY": "Primary domain set."
|
||||||
|
},
|
||||||
|
"DIALOG": {
|
||||||
|
"DEACTIVATE": {
|
||||||
|
"TITLE": "Deactivate organization",
|
||||||
|
"DESCRIPTION": "You are about to deactivate your organization. Users won't be able to login afterwards. Are you sure to proceed?"
|
||||||
|
},
|
||||||
|
"REACTIVATE": {
|
||||||
|
"TITLE": "Reactivate organization",
|
||||||
|
"DESCRIPTION": "You are about to reactivate your organization. Users will be able to login again. Are you sure to proceed?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SETTINGS": {
|
"SETTINGS": {
|
||||||
|
@ -757,6 +757,8 @@
|
|||||||
"LISTDESCRIPTION": "Choisissez une organisation.",
|
"LISTDESCRIPTION": "Choisissez une organisation.",
|
||||||
"ACTIVE": "Actif",
|
"ACTIVE": "Actif",
|
||||||
"CREATE": "Créer une organisation",
|
"CREATE": "Créer une organisation",
|
||||||
|
"DEACTIVATE": "Désactiver l'organisation",
|
||||||
|
"REACTIVATE": "Réactiver l'organisation",
|
||||||
"NOPERMISSION": "Vous n'avez pas la permission d'accéder aux paramètres de l'organisation.",
|
"NOPERMISSION": "Vous n'avez pas la permission d'accéder aux paramètres de l'organisation.",
|
||||||
"USERSELFACCOUNT": "Utilisez votre compte personnel comme propriétaire de l'organisation",
|
"USERSELFACCOUNT": "Utilisez votre compte personnel comme propriétaire de l'organisation",
|
||||||
"ORGDETAIL_TITLE": "Saisissez le nom et le domaine de votre nouvelle organisation.",
|
"ORGDETAIL_TITLE": "Saisissez le nom et le domaine de votre nouvelle organisation.",
|
||||||
@ -821,6 +823,16 @@
|
|||||||
"MEMBERREMOVED": "Gestionnaire supprimé.",
|
"MEMBERREMOVED": "Gestionnaire supprimé.",
|
||||||
"MEMBERCHANGED": "Gestionnaire modifié.",
|
"MEMBERCHANGED": "Gestionnaire modifié.",
|
||||||
"SETPRIMARY": "Domaine primaire défini."
|
"SETPRIMARY": "Domaine primaire défini."
|
||||||
|
},
|
||||||
|
"DIALOG": {
|
||||||
|
"DEACTIVATE": {
|
||||||
|
"TITLE": "Désactiver l'organisation",
|
||||||
|
"DESCRIPTION": "Vous êtes sur le point de désactiver votre organisation. Les utilisateurs ne peuvent plus se connecter ? Voulez-vous continuer ?"
|
||||||
|
},
|
||||||
|
"REACTIVATE": {
|
||||||
|
"TITLE": "Réactiver l'organisation",
|
||||||
|
"DESCRIPTION": "Vous êtes sur le point de réactiver votre organisation. Les utilisateurs peuvent ensuite se reconnecter ? Voulez-vous continuer ?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SETTINGS": {
|
"SETTINGS": {
|
||||||
|
@ -757,6 +757,8 @@
|
|||||||
"LISTDESCRIPTION": "Scegli un'organizzazione.",
|
"LISTDESCRIPTION": "Scegli un'organizzazione.",
|
||||||
"ACTIVE": "Attivo",
|
"ACTIVE": "Attivo",
|
||||||
"CREATE": "Creare un'organizzazione",
|
"CREATE": "Creare un'organizzazione",
|
||||||
|
"DEACTIVATE": "Disattiva organizzazione",
|
||||||
|
"REACTIVATE": "Riattiva organizzazione",
|
||||||
"NOPERMISSION": "Non hai l'autorizzazione per accedere alle impostazioni dell'organizzazione.",
|
"NOPERMISSION": "Non hai l'autorizzazione per accedere alle impostazioni dell'organizzazione.",
|
||||||
"USERSELFACCOUNT": "Usa il tuo account personale come proprietario dell'organizzazione",
|
"USERSELFACCOUNT": "Usa il tuo account personale come proprietario dell'organizzazione",
|
||||||
"ORGDETAIL_TITLE": "Inserisci il nome e il dominio della tua nuova organizzazione.",
|
"ORGDETAIL_TITLE": "Inserisci il nome e il dominio della tua nuova organizzazione.",
|
||||||
@ -821,6 +823,16 @@
|
|||||||
"MEMBERREMOVED": "Manager rimosso con successo",
|
"MEMBERREMOVED": "Manager rimosso con successo",
|
||||||
"MEMBERCHANGED": "Manager cambiato con successo",
|
"MEMBERCHANGED": "Manager cambiato con successo",
|
||||||
"SETPRIMARY": "Dominio primario cambiato con successo"
|
"SETPRIMARY": "Dominio primario cambiato con successo"
|
||||||
|
},
|
||||||
|
"DIALOG": {
|
||||||
|
"DEACTIVATE": {
|
||||||
|
"TITLE": "Disattivare l'organizzazione",
|
||||||
|
"DESCRIPTION": "Stai per disattivate la tua organizzazione. Utenti dell' organizzazione non possono più accedere in seguito. Sei sicuro di procedere?"
|
||||||
|
},
|
||||||
|
"REACTIVATE": {
|
||||||
|
"TITLE": "Riattivare l'organizzazione",
|
||||||
|
"DESCRIPTION": "Stai per riattivare la tua organizzazione. Utenti dell' organizzazione possono accedere nuovamente dopo l'attivazione. Vuoi procedere?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SETTINGS": {
|
"SETTINGS": {
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--zitadel-color-font-500);
|
color: var(--zitadel-color-text-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lgn-logo-watermark {
|
.lgn-logo-watermark {
|
||||||
|
@ -50,17 +50,17 @@
|
|||||||
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
|
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
|
||||||
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
|
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
|
||||||
|
|
||||||
--zitadel-color-font-50: rgb(0, 0, 0);
|
--zitadel-color-text-50: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-100: rgb(0, 0, 0);
|
--zitadel-color-text-100: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-200: rgb(0, 0, 0);
|
--zitadel-color-text-200: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-300: rgb(0, 0, 0);
|
--zitadel-color-text-300: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-400: rgb(0, 0, 0);
|
--zitadel-color-text-400: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-500: rgb(0, 0, 0);
|
--zitadel-color-text-500: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-600: rgb(0, 0, 0);
|
--zitadel-color-text-600: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-700: rgb(0, 0, 0);
|
--zitadel-color-text-700: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-800: rgb(0, 0, 0);
|
--zitadel-color-text-800: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-900: rgb(0, 0, 0);
|
--zitadel-color-text-900: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-contrast: rgb(255, 255, 255);
|
--zitadel-color-text-contrast: rgb(255, 255, 255);
|
||||||
--zitadel-color-label: #0000008a;
|
--zitadel-color-label: #0000008a;
|
||||||
|
|
||||||
--zitadel-color-account-selector-hover: rgba(0, 0, 0, 0.02);
|
--zitadel-color-account-selector-hover: rgba(0, 0, 0, 0.02);
|
||||||
|
@ -44,17 +44,17 @@
|
|||||||
--zitadel-color-input-border-hover: #1a1b1b;
|
--zitadel-color-input-border-hover: #1a1b1b;
|
||||||
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
|
--zitadel-color-input-border-active: var(--zitadel-color-primary-500);
|
||||||
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
|
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
|
||||||
--zitadel-color-font-50: rgb(0, 0, 0);
|
--zitadel-color-text-50: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-100: rgb(0, 0, 0);
|
--zitadel-color-text-100: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-200: rgb(0, 0, 0);
|
--zitadel-color-text-200: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-300: rgb(0, 0, 0);
|
--zitadel-color-text-300: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-400: rgb(0, 0, 0);
|
--zitadel-color-text-400: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-500: rgb(0, 0, 0);
|
--zitadel-color-text-500: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-600: rgb(0, 0, 0);
|
--zitadel-color-text-600: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-700: rgb(0, 0, 0);
|
--zitadel-color-text-700: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-800: rgb(0, 0, 0);
|
--zitadel-color-text-800: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-900: rgb(0, 0, 0);
|
--zitadel-color-text-900: rgb(0, 0, 0);
|
||||||
--zitadel-color-font-contrast: rgb(255, 255, 255);
|
--zitadel-color-text-contrast: rgb(255, 255, 255);
|
||||||
--zitadel-color-label: #0000008a;
|
--zitadel-color-label: #0000008a;
|
||||||
--zitadel-color-account-selector-hover: rgba(0, 0, 0, 0.02);
|
--zitadel-color-account-selector-hover: rgba(0, 0, 0, 0.02);
|
||||||
--zitadel-color-account-selector-active: rgba(0, 0, 0, 0.05);
|
--zitadel-color-account-selector-active: rgba(0, 0, 0, 0.05);
|
||||||
@ -2819,7 +2819,7 @@ footer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
footer a {
|
footer a {
|
||||||
color: var(--zitadel-color-font-500);
|
color: var(--zitadel-color-text-500);
|
||||||
}
|
}
|
||||||
footer .lgn-logo-watermark {
|
footer .lgn-logo-watermark {
|
||||||
background: var(--zitadel-logo-powered-by) no-repeat;
|
background: var(--zitadel-logo-powered-by) no-repeat;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user