mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-13 03:24:26 +00:00
fix(console): policy reset for custom, header org filter, idp add dialog (#865)
* remove reset button if not default, rem load * dirty focus fix * use idptype in dialog * remove logs * lint * revert idp add changes * log error * lint
This commit is contained in:
parent
ef3b7482cd
commit
40b8d3ffa4
@ -20,17 +20,17 @@
|
|||||||
|
|
||||||
<mat-menu class="menu" #menu="matMenu">
|
<mat-menu class="menu" #menu="matMenu">
|
||||||
<div class="spinner-w">
|
<div class="spinner-w">
|
||||||
<mat-spinner diameter="20" *ngIf="orgLoading" color="accent">
|
<mat-spinner diameter="20" *ngIf="orgLoading$ | async" color="accent">
|
||||||
</mat-spinner>
|
</mat-spinner>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-form-field class="filter-form" appearance="fill">
|
<mat-form-field class="filter-form" appearance="fill">
|
||||||
<input autocomplete="off" matInput (click)="$event.stopPropagation()" (keyup)="applyFilter($event)"
|
<input matInput [formControl]="filterControl" autocomplete="off" (click)="$event.stopPropagation()"
|
||||||
placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}" #input>
|
placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}" #input>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
||||||
*ngFor="let temporg of orgs" mat-menu-item (click)="setActiveOrg(temporg)">
|
*ngFor="let temporg of orgs$ | async" mat-menu-item (click)="setActiveOrg(temporg)">
|
||||||
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@ -2,13 +2,14 @@ import { BreakpointObserver } from '@angular/cdk/layout';
|
|||||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
import { DOCUMENT, ViewportScroller } from '@angular/common';
|
import { DOCUMENT, ViewportScroller } from '@angular/common';
|
||||||
import { Component, ElementRef, HostBinding, Inject, OnDestroy, ViewChild } from '@angular/core';
|
import { Component, ElementRef, HostBinding, Inject, OnDestroy, ViewChild } from '@angular/core';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
import { MatIconRegistry } from '@angular/material/icon';
|
import { MatIconRegistry } from '@angular/material/icon';
|
||||||
import { MatDrawer } from '@angular/material/sidenav';
|
import { MatDrawer } from '@angular/material/sidenav';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { Router, RouterOutlet } from '@angular/router';
|
import { Router, RouterOutlet } from '@angular/router';
|
||||||
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
||||||
import { Observable, of, Subscription } from 'rxjs';
|
import { BehaviorSubject, from, Observable, of, Subscription } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { catchError, debounceTime, finalize, map, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { accountCard, navAnimations, routeAnimations, toolbarAnimation } from './animations';
|
import { accountCard, navAnimations, routeAnimations, toolbarAnimation } from './animations';
|
||||||
import {
|
import {
|
||||||
@ -48,17 +49,18 @@ export class AppComponent implements OnDestroy {
|
|||||||
|
|
||||||
public showAccount: boolean = false;
|
public showAccount: boolean = false;
|
||||||
public org!: Org.AsObject;
|
public org!: Org.AsObject;
|
||||||
public orgs: Org.AsObject[] = [];
|
public orgs$: Observable<Org.AsObject[]> = of([]);
|
||||||
public profile!: UserProfileView.AsObject;
|
public profile!: UserProfileView.AsObject;
|
||||||
public isDarkTheme: Observable<boolean> = of(true);
|
public isDarkTheme: Observable<boolean> = of(true);
|
||||||
|
|
||||||
public orgLoading: boolean = false;
|
public orgLoading$: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||||
|
|
||||||
public showProjectSection: boolean = false;
|
public showProjectSection: boolean = false;
|
||||||
|
|
||||||
public grantedProjectsCount: number = 0;
|
public grantedProjectsCount: number = 0;
|
||||||
public ownedProjectsCount: number = 0;
|
public ownedProjectsCount: number = 0;
|
||||||
|
|
||||||
|
public filterControl: FormControl = new FormControl('');
|
||||||
private authSub: Subscription = new Subscription();
|
private authSub: Subscription = new Subscription();
|
||||||
private orgSub: Subscription = new Subscription();
|
private orgSub: Subscription = new Subscription();
|
||||||
|
|
||||||
@ -148,7 +150,6 @@ export class AppComponent implements OnDestroy {
|
|||||||
|
|
||||||
this.orgSub = this.authService.activeOrgChanged.subscribe(org => {
|
this.orgSub = this.authService.activeOrgChanged.subscribe(org => {
|
||||||
this.org = org;
|
this.org = org;
|
||||||
|
|
||||||
this.getProjectCount();
|
this.getProjectCount();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -172,6 +173,12 @@ export class AppComponent implements OnDestroy {
|
|||||||
this.translate.onLangChange.subscribe((language: LangChangeEvent) => {
|
this.translate.onLangChange.subscribe((language: LangChangeEvent) => {
|
||||||
this.document.documentElement.lang = language.lang;
|
this.document.documentElement.lang = language.lang;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.filterControl.valueChanges.pipe(debounceTime(300)).subscribe(value => {
|
||||||
|
this.loadOrgs(
|
||||||
|
value.trim().toLowerCase(),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy(): void {
|
public ngOnDestroy(): void {
|
||||||
@ -188,14 +195,17 @@ export class AppComponent implements OnDestroy {
|
|||||||
query.setValue(filter);
|
query.setValue(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.orgLoading = true;
|
this.orgLoading$.next(true);
|
||||||
this.authService.SearchMyProjectOrgs(10, 0, query ? [query] : undefined).then(res => {
|
this.orgs$ = from(this.authService.SearchMyProjectOrgs(10, 0, query ? [query] : undefined)).pipe(
|
||||||
this.orgs = res.toObject().resultList;
|
map(resp => {
|
||||||
this.orgLoading = false;
|
return resp.toObject().resultList;
|
||||||
}).catch(error => {
|
}),
|
||||||
this.toast.showError(error);
|
catchError(() => of([])),
|
||||||
this.orgLoading = false;
|
finalize(() => {
|
||||||
});
|
this.orgLoading$.next(false);
|
||||||
|
this.focusFilter();
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareRoute(outlet: RouterOutlet): boolean {
|
public prepareRoute(outlet: RouterOutlet): boolean {
|
||||||
@ -231,7 +241,9 @@ export class AppComponent implements OnDestroy {
|
|||||||
public setActiveOrg(org: Org.AsObject): void {
|
public setActiveOrg(org: Org.AsObject): void {
|
||||||
this.org = org;
|
this.org = org;
|
||||||
this.authService.setActiveOrg(org);
|
this.authService.setActiveOrg(org);
|
||||||
this.router.navigate(['/']);
|
this.authService.zitadelPermissionsChanged.pipe(take(1)).subscribe(() => {
|
||||||
|
this.router.navigate(['/']);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getProjectCount(): void {
|
private getProjectCount(): void {
|
||||||
@ -248,13 +260,6 @@ export class AppComponent implements OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyFilter(event: Event): void {
|
|
||||||
const filterValue = (event.target as HTMLInputElement).value;
|
|
||||||
this.loadOrgs(
|
|
||||||
filterValue.trim().toLowerCase(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
focusFilter(): void {
|
focusFilter(): void {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.input.nativeElement.focus();
|
this.input.nativeElement.focus();
|
||||||
|
@ -3,6 +3,7 @@ import { CommonModule, registerLocaleData } from '@angular/common';
|
|||||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||||
import localeDe from '@angular/common/locales/de';
|
import localeDe from '@angular/common/locales/de';
|
||||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatNativeDateModule } from '@angular/material/core';
|
import { MatNativeDateModule } from '@angular/material/core';
|
||||||
@ -115,6 +116,7 @@ const authConfig: AuthConfig = {
|
|||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
AvatarModule,
|
AvatarModule,
|
||||||
|
@ -165,6 +165,8 @@ export class LoginPolicyComponent implements OnDestroy {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
}).catch(error => {
|
||||||
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -183,10 +185,20 @@ export class LoginPolicyComponent implements OnDestroy {
|
|||||||
public removeIdp(idp: AdminIdpProviderView.AsObject | MgmtIdpProviderView.AsObject): void {
|
public removeIdp(idp: AdminIdpProviderView.AsObject | MgmtIdpProviderView.AsObject): void {
|
||||||
switch (this.serviceType) {
|
switch (this.serviceType) {
|
||||||
case PolicyComponentServiceType.MGMT:
|
case PolicyComponentServiceType.MGMT:
|
||||||
(this.service as ManagementService).RemoveIdpProviderFromLoginPolicy(idp.idpConfigId);
|
(this.service as ManagementService).RemoveIdpProviderFromLoginPolicy(idp.idpConfigId).then(() => {
|
||||||
|
const index = this.idps.findIndex(temp => temp === idp);
|
||||||
|
if (index > -1) {
|
||||||
|
this.idps.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case PolicyComponentServiceType.ADMIN:
|
case PolicyComponentServiceType.ADMIN:
|
||||||
(this.service as AdminService).RemoveIdpProviderFromDefaultLoginPolicy(idp.idpConfigId);
|
(this.service as AdminService).RemoveIdpProviderFromDefaultLoginPolicy(idp.idpConfigId).then(() => {
|
||||||
|
const index = this.idps.findIndex(temp => temp === idp);
|
||||||
|
if (index > -1) {
|
||||||
|
this.idps.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<p class="default" *ngIf="isDefault"> {{'ORG.POLICY.DEFAULTLABEL' | translate}}</p>
|
<p class="default" *ngIf="isDefault"> {{'ORG.POLICY.DEFAULTLABEL' | translate}}</p>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['iam.policy.delete']">
|
<ng-template appHasRole [appHasRole]="['iam.policy.delete']">
|
||||||
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT" matTooltip="{{'ORG.POLICY.RESET' | translate}}"
|
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||||
color="warn" (click)="removePolicy()" mat-stroked-button>
|
matTooltip="{{'ORG.POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||||
{{'ORG.POLICY.RESET' | translate}}
|
{{'ORG.POLICY.RESET' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
<app-detail-layout [backRouterLink]="[ serviceType === PolicyComponentServiceType.ADMIN ? '/iam' : '/org']"
|
||||||
[title]="'ORG.POLICY.PWD_AGE.TITLE' | translate" [description]="'ORG.POLICY.PWD_AGE.DESCRIPTION' | translate">
|
[title]="'ORG.POLICY.PWD_AGE.TITLE' | translate" [description]="'ORG.POLICY.PWD_AGE.DESCRIPTION' | translate">
|
||||||
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
||||||
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT" matTooltip="{{'ORG.POLICY.RESET' | translate}}"
|
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||||
color="warn" (click)="removePolicy()" mat-stroked-button>
|
matTooltip="{{'ORG.POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||||
{{'ORG.POLICY.RESET' | translate}}
|
{{'ORG.POLICY.RESET' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -112,7 +112,6 @@ export class PasswordAgePolicyComponent implements OnDestroy {
|
|||||||
this.ageData.expireWarnDays,
|
this.ageData.expireWarnDays,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
||||||
this.getData();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
@ -122,7 +121,6 @@ export class PasswordAgePolicyComponent implements OnDestroy {
|
|||||||
this.ageData.expireWarnDays,
|
this.ageData.expireWarnDays,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
||||||
this.getData();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
@ -134,12 +132,18 @@ export class PasswordAgePolicyComponent implements OnDestroy {
|
|||||||
this.ageData.expireWarnDays,
|
this.ageData.expireWarnDays,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
||||||
this.getData();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isDefault(): boolean {
|
||||||
|
if (this.ageData && this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||||
|
return (this.ageData as PasswordAgePolicyView.AsObject).pb_default;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<p class="default" *ngIf="isDefault"> {{'ORG.POLICY.DEFAULTLABEL' | translate}}</p>
|
<p class="default" *ngIf="isDefault"> {{'ORG.POLICY.DEFAULTLABEL' | translate}}</p>
|
||||||
|
|
||||||
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
||||||
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT" matTooltip="{{'ORG.POLICY.RESET' | translate}}"
|
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||||
color="warn" (click)="removePolicy()" mat-stroked-button>
|
matTooltip="{{'ORG.POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||||
{{'ORG.POLICY.RESET' | translate}}
|
{{'ORG.POLICY.RESET' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -45,11 +45,7 @@ export class PasswordLockoutPolicyComponent implements OnDestroy {
|
|||||||
|
|
||||||
return this.route.params;
|
return this.route.params;
|
||||||
})).subscribe(() => {
|
})).subscribe(() => {
|
||||||
this.getData().then(data => {
|
this.fetchData();
|
||||||
if (data) {
|
|
||||||
this.lockoutData = data.toObject() as PasswordLockoutPolicyView.AsObject;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +53,14 @@ export class PasswordLockoutPolicyComponent implements OnDestroy {
|
|||||||
this.sub.unsubscribe();
|
this.sub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fetchData(): void {
|
||||||
|
this.getData().then(data => {
|
||||||
|
if (data) {
|
||||||
|
this.lockoutData = data.toObject() as PasswordLockoutPolicyView.AsObject;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private getData(): Promise<PasswordLockoutPolicyView | DefaultPasswordLockoutPolicyView> {
|
private getData(): Promise<PasswordLockoutPolicyView | DefaultPasswordLockoutPolicyView> {
|
||||||
switch (this.serviceType) {
|
switch (this.serviceType) {
|
||||||
case PolicyComponentServiceType.MGMT:
|
case PolicyComponentServiceType.MGMT:
|
||||||
@ -70,9 +74,7 @@ export class PasswordLockoutPolicyComponent implements OnDestroy {
|
|||||||
if (this.service instanceof ManagementService) {
|
if (this.service instanceof ManagementService) {
|
||||||
this.service.RemovePasswordLockoutPolicy().then(() => {
|
this.service.RemovePasswordLockoutPolicy().then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.RESETSUCCESS', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.RESETSUCCESS', true);
|
||||||
setTimeout(() => {
|
this.fetchData();
|
||||||
this.getData();
|
|
||||||
}, 1000);
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
@ -99,7 +101,6 @@ export class PasswordLockoutPolicyComponent implements OnDestroy {
|
|||||||
this.lockoutData.showLockoutFailure,
|
this.lockoutData.showLockoutFailure,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
||||||
this.getData();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
@ -110,7 +111,6 @@ export class PasswordLockoutPolicyComponent implements OnDestroy {
|
|||||||
this.lockoutData.showLockoutFailure,
|
this.lockoutData.showLockoutFailure,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
||||||
this.getData();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
@ -120,7 +120,6 @@ export class PasswordLockoutPolicyComponent implements OnDestroy {
|
|||||||
this.lockoutData.showLockoutFailure,
|
this.lockoutData.showLockoutFailure,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
this.toast.showInfo('ORG.POLICY.TOAST.SET', true);
|
||||||
this.getData();
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user