mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-14 09:55:12 +00:00
# Which Problems Are Solved The new breadcrumbs were causing problems with some more advanced Zitadel setups. This pr removes the new breadcrumbs to revert to the old navigation behaviour. # How the Problems Are Solved Most of the changes could be kept but those specific to the navigation where mostly reverted. # Additional Changes Updated some dependencies. # Additional Context - Closes #10863
This commit is contained in:
@@ -5,9 +5,7 @@ import { OrgTableModule } from 'src/app/modules/org-table/org-table.module';
|
||||
|
||||
import { ActionsRoutingModule } from './actions-routing.module';
|
||||
import { ActionsComponent } from './actions.component';
|
||||
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
|
||||
import { SidenavModule } from 'src/app/modules/sidenav/sidenav.module';
|
||||
import { ActionsTwoActionsComponent } from 'src/app/modules/actions-two/actions-two-actions/actions-two-actions.component';
|
||||
import ActionsTwoModule from 'src/app/modules/actions-two/actions-two.module';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, effect } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
@@ -27,8 +27,6 @@ export class HomeComponent {
|
||||
|
||||
protected readonly PolicyComponentServiceType = PolicyComponentServiceType;
|
||||
|
||||
private readonly permissions = this.newAuthService.listMyZitadelPermissionsQuery();
|
||||
|
||||
constructor(
|
||||
public authService: GrpcAuthService,
|
||||
private readonly newAuthService: NewAuthService,
|
||||
@@ -37,24 +35,13 @@ export class HomeComponent {
|
||||
private readonly router: Router,
|
||||
) {
|
||||
const bread: Breadcrumb = {
|
||||
type: BreadcrumbType.INSTANCE,
|
||||
routerLink: ['/'],
|
||||
type: BreadcrumbType.ORG,
|
||||
routerLink: ['/org'],
|
||||
};
|
||||
|
||||
breadcrumbService.setBreadcrumb([bread]);
|
||||
|
||||
const theme = localStorage.getItem('theme');
|
||||
this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true;
|
||||
|
||||
effect(() => {
|
||||
const permission = this.permissions.data();
|
||||
if (!permission) {
|
||||
return;
|
||||
}
|
||||
if (permission.includes('iam.read')) {
|
||||
return;
|
||||
}
|
||||
this.router.navigate(['/org']).then();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Component, DestroyRef } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { BehaviorSubject, defer, from, Observable, of, shareReplay, TimeoutError } from 'rxjs';
|
||||
import { catchError, finalize, map, timeout } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BehaviorSubject, from, Observable, of } from 'rxjs';
|
||||
import { catchError, finalize, map } from 'rxjs/operators';
|
||||
import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component';
|
||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||
import { InstanceDetail, State } from 'src/app/proto/generated/zitadel/instance_pb';
|
||||
@@ -34,10 +34,11 @@ import {
|
||||
FAILEDEVENTS,
|
||||
EVENTS,
|
||||
FEATURESETTINGS,
|
||||
ACTIONS,
|
||||
ACTIONS_TARGETS,
|
||||
} from 'src/app/modules/settings-list/settings';
|
||||
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { EnvironmentService } from 'src/app/services/environment.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
@Component({
|
||||
selector: 'cnsl-instance',
|
||||
@@ -77,6 +78,9 @@ export class InstanceComponent {
|
||||
VIEWS,
|
||||
EVENTS,
|
||||
FAILEDEVENTS,
|
||||
//actions
|
||||
ACTIONS,
|
||||
ACTIONS_TARGETS,
|
||||
// others
|
||||
PRIVACYPOLICY,
|
||||
LANGUAGES,
|
||||
|
||||
@@ -3,18 +3,26 @@
|
||||
*ngIf="['org.write:' + org.id, 'org.write$'] | hasRole as hasWrite$"
|
||||
[hasBackButton]="false"
|
||||
title="{{ org.name }}"
|
||||
[isActive]="org.state === OrganizationState.ACTIVE"
|
||||
[isInactive]="org.state === OrganizationState.INACTIVE"
|
||||
[isActive]="$any(org.state) === OrganizationState.ACTIVE"
|
||||
[isInactive]="$any(org.state) === OrganizationState.INACTIVE"
|
||||
[hasContributors]="true"
|
||||
stateTooltip="{{ 'ORG.STATE.' + org.state | translate }}"
|
||||
[hasActions]="hasWrite$ | async"
|
||||
>
|
||||
<ng-container topActions *ngIf="hasWrite$ | async">
|
||||
<button mat-menu-item *ngIf="org.state === OrganizationState.ACTIVE" (click)="changeState(OrganizationState.INACTIVE)">
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="$any(org.state) === OrganizationState.ACTIVE"
|
||||
(click)="changeState(OrganizationState.INACTIVE)"
|
||||
>
|
||||
{{ 'ORG.PAGES.DEACTIVATE' | translate }}
|
||||
</button>
|
||||
|
||||
<button mat-menu-item *ngIf="org.state === OrganizationState.INACTIVE" (click)="changeState(OrganizationState.ACTIVE)">
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="$any(org.state) === OrganizationState.INACTIVE"
|
||||
(click)="changeState(OrganizationState.ACTIVE)"
|
||||
>
|
||||
{{ 'ORG.PAGES.REACTIVATE' | translate }}
|
||||
</button>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectorRef, Component, effect, OnInit, signal } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, OnInit, signal } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { BehaviorSubject, from, lastValueFrom, Observable, of } from 'rxjs';
|
||||
@@ -19,7 +19,9 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
import { NewOrganizationService } from '../../../services/new-organization.service';
|
||||
import { injectMutation } from '@tanstack/angular-query-experimental';
|
||||
import { Organization, OrganizationState } from '@zitadel/proto/zitadel/org/v2/org_pb';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { GrpcAuthService } from '../../../services/grpc-auth.service';
|
||||
import { Org } from '@zitadel/proto/zitadel/org_pb';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-org-detail',
|
||||
@@ -53,6 +55,7 @@ export class OrgDetailComponent implements OnInit {
|
||||
protected reloadChanges = signal(true);
|
||||
|
||||
constructor(
|
||||
private readonly authService: GrpcAuthService,
|
||||
private readonly dialog: MatDialog,
|
||||
private readonly mgmtService: ManagementService,
|
||||
private readonly toast: ToastService,
|
||||
@@ -67,17 +70,14 @@ export class OrgDetailComponent implements OnInit {
|
||||
};
|
||||
breadcrumbService.setBreadcrumb([bread]);
|
||||
|
||||
effect(() => {
|
||||
const orgId = this.newOrganizationService.orgId();
|
||||
if (!orgId) {
|
||||
authService.activeOrgChanged.pipe(takeUntilDestroyed()).subscribe((org) => {
|
||||
if (!org) {
|
||||
return;
|
||||
}
|
||||
this.loadMembers();
|
||||
this.loadMetadata();
|
||||
});
|
||||
|
||||
// force rerender changes because it is not reactive to orgId changes
|
||||
toObservable(this.newOrganizationService.orgId).subscribe(() => {
|
||||
// force rerender changes because it is not reactive to orgId changes
|
||||
this.reloadChanges.set(false);
|
||||
cdr.detectChanges();
|
||||
this.reloadChanges.set(true);
|
||||
@@ -137,7 +137,7 @@ export class OrgDetailComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteOrg(org: Organization) {
|
||||
public async deleteOrg(org: Organization | Org) {
|
||||
const mgmtUserData = {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
@@ -265,7 +265,7 @@ export class OrgDetailComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
public async renameOrg(org: Organization): Promise<void> {
|
||||
public async renameOrg(org: Organization | Org): Promise<void> {
|
||||
const dialogRef = this.dialog.open(NameDialogComponent, {
|
||||
data: {
|
||||
name: org.name,
|
||||
@@ -286,7 +286,7 @@ export class OrgDetailComponent implements OnInit {
|
||||
this.toast.showInfo('ORG.TOAST.UPDATED', true);
|
||||
const resp = await this.mgmtService.getMyOrg();
|
||||
if (resp.org) {
|
||||
await this.newOrganizationService.setOrgId(resp.org.id);
|
||||
await this.authService.getActiveOrg(resp.org.id);
|
||||
}
|
||||
} catch (error) {
|
||||
this.toast.showError(error);
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';
|
||||
import { BehaviorSubject, Observable, Subject, takeUntil } from 'rxjs';
|
||||
import { ProjectType } from 'src/app/modules/project-members/project-members-datasource';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||
import { GrantedProject, Project, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { StorageKey, StorageLocation, StorageService } from 'src/app/services/storage.service';
|
||||
|
||||
@@ -56,7 +56,6 @@ export class UserCreateV2Component implements OnInit {
|
||||
private readonly passwordComplexityPolicy$: Observable<PasswordComplexityPolicy>;
|
||||
protected readonly authenticationFactor$: Observable<AuthenticationFactor>;
|
||||
private readonly useLoginV2$: Observable<LoginV2FeatureFlag | undefined>;
|
||||
private orgId = this.organizationService.getOrgId();
|
||||
|
||||
constructor(
|
||||
private readonly router: Router,
|
||||
@@ -70,7 +69,6 @@ export class UserCreateV2Component implements OnInit {
|
||||
private readonly route: ActivatedRoute,
|
||||
protected readonly location: Location,
|
||||
private readonly authService: GrpcAuthService,
|
||||
private readonly organizationService: NewOrganizationService,
|
||||
) {
|
||||
this.userForm = this.buildUserForm();
|
||||
|
||||
@@ -186,11 +184,11 @@ export class UserCreateV2Component implements OnInit {
|
||||
private async createUserV2Try(authenticationFactor: AuthenticationFactor) {
|
||||
this.loading.set(true);
|
||||
|
||||
this.organizationService.getOrgId();
|
||||
const activeOrg = await this.authService.getActiveOrg();
|
||||
const userValues = this.userForm.getRawValue();
|
||||
|
||||
const humanReq: MessageInitShape<typeof AddHumanUserRequestSchema> = {
|
||||
organization: { org: { case: 'orgId', value: this.orgId() } },
|
||||
organization: { org: { case: 'orgId', value: activeOrg.id } },
|
||||
username: userValues.username,
|
||||
profile: {
|
||||
givenName: userValues.givenName,
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
delay,
|
||||
distinctUntilChanged,
|
||||
EMPTY,
|
||||
from,
|
||||
Observable,
|
||||
of,
|
||||
ReplaySubject,
|
||||
@@ -35,7 +36,7 @@ import { PaginatorComponent } from 'src/app/modules/paginator/paginator.componen
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { UserService } from 'src/app/services/user.service';
|
||||
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
|
||||
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
||||
import { SearchQuery as UserSearchQuery } from 'src/app/proto/generated/zitadel/user_pb';
|
||||
import { Type, UserFieldName } from '@zitadel/proto/zitadel/user/v2/query_pb';
|
||||
import { UserState, User } from '@zitadel/proto/zitadel/user/v2/user_pb';
|
||||
@@ -43,6 +44,8 @@ import { MessageInitShape } from '@bufbuild/protobuf';
|
||||
import { ListUsersRequestSchema, ListUsersResponse } from '@zitadel/proto/zitadel/user/v2/user_service_pb';
|
||||
import { UserState as UserStateV1 } from 'src/app/proto/generated/zitadel/user_pb';
|
||||
import { NewOrganizationService } from 'src/app/services/new-organization.service';
|
||||
import { AuthenticationService } from 'src/app/services/authentication.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
|
||||
type ListUsersRequest = MessageInitShape<typeof ListUsersRequestSchema>;
|
||||
type QueriesArray = NonNullable<ListUsersRequest['queries']>;
|
||||
@@ -124,6 +127,8 @@ export class UserTableComponent implements OnInit {
|
||||
private readonly route: ActivatedRoute,
|
||||
private readonly destroyRef: DestroyRef,
|
||||
private readonly newOrganizationService: NewOrganizationService,
|
||||
private readonly authenticationService: AuthenticationService,
|
||||
private readonly authService: GrpcAuthService,
|
||||
) {
|
||||
this.type$ = this.getType$().pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
this.users$ = this.getUsers(this.type$).pipe(shareReplay({ refCount: true, bufferSize: 1 }));
|
||||
@@ -229,7 +234,7 @@ export class UserTableComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getQueries(type$: Observable<Type>): Observable<Query[]> {
|
||||
const orgId$ = toObservable(this.newOrganizationService.orgId).pipe(filter(Boolean));
|
||||
const orgId$ = this.getActiveOrgId().pipe(filter(Boolean));
|
||||
return this.searchQueries$.pipe(
|
||||
startWith([]),
|
||||
combineLatestWith(type$, orgId$),
|
||||
@@ -474,4 +479,20 @@ export class UserTableComponent implements OnInit {
|
||||
const selected = this.selection.selected;
|
||||
return selected ? selected.findIndex((user) => user.state !== UserState.INACTIVE) > -1 : false;
|
||||
}
|
||||
|
||||
private getActiveOrgId() {
|
||||
return this.authenticationService.authenticationChanged.pipe(
|
||||
startWith(true),
|
||||
filter(Boolean),
|
||||
switchMap(() =>
|
||||
from(this.authService.getActiveOrg()).pipe(
|
||||
catchError((err) => {
|
||||
this.toast.showError(err);
|
||||
return of(undefined);
|
||||
}),
|
||||
),
|
||||
),
|
||||
map((org) => org?.id),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user