mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
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]>
113 lines
3.7 KiB
TypeScript
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;
|
|
}
|
|
}
|