Files
zitadel/console/src/app/modules/info-row/info-row.component.ts
T
f963ea9f86 feat(console): rehauled navigation for instances including breadcrumb (#10283)
This PR significantly improves user navigation by introducing a new
instance-level navigation bar. This new bar, positioned above the
existing organization navigation, provides quick access to key sections:
Home, Organizations, Actions, and Settings.

Additionally, the breadcrumb component has been refined for more
consistent behavior, reintroducing intuitive breadcrumb buttons to
easily navigate up the hierarchy. These changes also include design
improvements for a cleaner and more streamlined appearance across the
interface.

<img width="423" height="138" alt="Screenshot 2025-07-17 at 14 55 46"
src="https://github.com/user-attachments/assets/ba9e40a1-1077-4cb6-8735-ac7ab637abe7"
/>
<img width="562" height="132" alt="Screenshot 2025-07-17 at 14 56 41"
src="https://github.com/user-attachments/assets/d85dc673-0df8-4677-9d2b-dc031dde42c3"
/>
<img width="545" height="254" alt="Screenshot 2025-07-17 at 14 56 10"
src="https://github.com/user-attachments/assets/eaf10117-079e-4181-8dbb-60c89b24556a"
/>
<img width="689" height="261" alt="Screenshot 2025-07-17 at 14 56 20"
src="https://github.com/user-attachments/assets/510ad550-1d9a-4c6a-8af1-66cb0b23619c"
/>

---------

Co-authored-by: conblem <[email protected]>
Co-authored-by: Stefan Benz <[email protected]>
Co-authored-by: Florian Forster <[email protected]>
2025-08-28 11:23:14 +02:00

113 lines
3.7 KiB
TypeScript

import { Component, Input } from '@angular/core';
import { App, AppState } from 'src/app/proto/generated/zitadel/app_pb';
import { IDP, IDPState } from 'src/app/proto/generated/zitadel/idp_pb';
import { InstanceDetail, State } from 'src/app/proto/generated/zitadel/instance_pb';
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
import { LoginPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
import { GrantedProject, Project, ProjectGrantState, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
import { User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
import { User as UserV1 } from '@zitadel/proto/zitadel/user_pb';
import { User as UserV2 } from '@zitadel/proto/zitadel/user/v2/user_pb';
import { LoginPolicy as LoginPolicyV2 } from '@zitadel/proto/zitadel/policy_pb';
import { Organization as OrgV2 } from '@zitadel/proto/zitadel/org/v2/org_pb';
@Component({
selector: 'cnsl-info-row',
templateUrl: './info-row.component.html',
styleUrls: ['./info-row.component.scss'],
})
export class InfoRowComponent {
@Input() public user?: User.AsObject | UserV2 | UserV1;
@Input() public org!: Org.AsObject | OrgV2;
@Input() public instance!: InstanceDetail.AsObject;
@Input() public app!: App.AsObject;
@Input() public idp!: IDP.AsObject;
@Input() public project!: Project.AsObject;
@Input() public grantedProject!: GrantedProject.AsObject;
@Input() public loginPolicy?: LoginPolicy.AsObject | LoginPolicyV2;
public UserState = UserState;
public State = State;
public OrgState = OrgState;
public AppState = AppState;
public IDPState = IDPState;
public ProjectState = ProjectState;
public ProjectGrantState = ProjectGrantState;
public copied: string = '';
constructor() {}
public get loginMethods(): Set<string> {
if (!this.user) {
return new Set();
}
const methods = '$typeName' in this.user ? this.user.loginNames : this.user.loginNamesList;
const loginPolicy = this.loginPolicy;
if (!loginPolicy) {
return new Set([...methods]);
}
let email = !loginPolicy.disableLoginWithEmail ? this.getEmail(this.user) : '';
let phone = !loginPolicy.disableLoginWithPhone ? this.getPhone(this.user) : '';
return new Set([email, phone, ...methods].filter(Boolean));
}
public get userId() {
if (!this.user) {
return undefined;
}
if ('$typeName' in this.user && this.user.$typeName === 'zitadel.user.v2.User') {
return this.user.userId;
}
return this.user.id;
}
public get changeDate() {
return this.user?.details?.changeDate;
}
public get creationDate() {
return this.user?.details?.creationDate;
}
private getEmail(user: User.AsObject | UserV2 | UserV1) {
const human = this.human(user);
if (!human) {
return '';
}
if ('$typeName' in human && human.$typeName === 'zitadel.user.v2.HumanUser') {
return human.email?.isVerified ? human.email.email : '';
}
return human.email?.isEmailVerified ? human.email.email : '';
}
private getPhone(user: User.AsObject | UserV2 | UserV1) {
const human = this.human(user);
if (!human) {
return '';
}
if ('$typeName' in human && human.$typeName === 'zitadel.user.v2.HumanUser') {
return human.phone?.isVerified ? human.phone.phone : '';
}
return human.phone?.isPhoneVerified ? human.phone.phone : '';
}
public human(user: User.AsObject | UserV2 | UserV1) {
if (!('$typeName' in user)) {
return user.human;
}
return user.type.case === 'human' ? user.type.value : undefined;
}
public isV2(user: User.AsObject | UserV2 | UserV1) {
if ('$typeName' in user) {
return user.$typeName === 'zitadel.user.v2.User';
}
return false;
}
}