Files
zitadel/console/src/app/modules/info-row/info-row.component.html
T
6aeaa89c25 feat: Display Authentication Method Name on Application Page (#9639)
# Which Problems Are Solved

The Authentication Method name is currently not displayed on the
Application Page, this screenshot is taken from the linked issue:

<img width="946" alt="417991175-a6c8497f-9c4f-4042-8ffa-c5f995ab5039"
src="https://github.com/user-attachments/assets/aea0e956-27e3-4e32-bcb1-0a7456480084"
/>


I can also add other fields if necessary, but the layout may need to be
redesigned to keep a good looking UI since there are already a lot of
fields.

# How the Problems Are Solved

Display the Authentication Method name between the `Status` and the `ID`
fields from either the `oidcConfig` or the `apiConfig` objects.

Here are some screenshots of the result:

None:


![image](https://github.com/user-attachments/assets/776dc3db-5196-413e-bff4-38f1a149f5c5)

Private JWT:


![image](https://github.com/user-attachments/assets/e9279143-1c92-4932-a271-c0865393384c)

Post:


![image](https://github.com/user-attachments/assets/486ca69b-715d-4681-8b5b-5db47ff2cbf1)

API Basic:


![image](https://github.com/user-attachments/assets/3ad923f1-642b-400b-a38a-818c1ce3534e)

# Additional Changes

None

# Additional Context

- Closes #9435

---------

Co-authored-by: Ramon <[email protected]>
2025-06-04 13:31:54 +02:00

343 lines
12 KiB
HTML

<div class="info-row" *ngIf="user">
<div class="info-wrapper">
<p class="info-row-title">{{ 'USER.PAGES.STATE' | translate }}</p>
<p
*ngIf="user?.state"
class="state"
[ngClass]="{
active: user.state === UserState.USER_STATE_ACTIVE,
inactive: user.state === UserState.USER_STATE_INACTIVE,
}"
>
{{ (isV2(user) ? 'USER.STATEV2.' : 'USER.STATE.') + user.state | translate }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'USER.ID' | translate }}</p>
<p *ngIf="userId" class="info-row-desc">{{ userId }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'USER.DETAILS.DATECREATED' | translate }}</p>
<p *ngIf="creationDate" class="info-row-desc">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'USER.DETAILS.DATECHANGED' | translate }}</p>
<p *ngIf="changeDate" class="info-row-desc">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper width">
<p class="info-row-title">{{ 'USER.PAGES.LOGINMETHODS' | translate }}</p>
<div class="copy-row" *ngFor="let login of loginMethods">
<button
[disabled]="copied === login"
[matTooltip]="(copied !== login ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="login"
(copiedValue)="copied = $event"
data-e2e="copy-loginname"
>
{{ login }}
</button>
</div>
</div>
</div>
<div class="info-row" *ngIf="instance">
<div class="info-wrapper">
<p class="info-row-title">{{ 'IAM.PAGES.STATE' | translate }}</p>
<p
*ngIf="instance?.state"
class="state"
[ngClass]="{
active: instance.state === State.INSTANCE_STATE_RUNNING,
inactive: instance.state === State.INSTANCE_STATE_STOPPED || instance.state === State.INSTANCE_STATE_STOPPING,
}"
>
{{ 'IAM.STATE.' + instance.state | translate }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="instance?.id" class="info-row-desc">{{ instance.id }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'NAME' | translate }}</p>
<p *ngIf="instance?.name" class="info-row-desc">{{ instance.name }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'VERSION' | translate }}</p>
<p *ngIf="instance?.version" class="info-row-desc">{{ instance.version }}</p>
</div>
<div class="info-wrapper width">
<p class="info-row-title">{{ 'IAM.PAGES.DOMAINLIST' | translate }}</p>
<div class="copy-row" *ngFor="let domain of instance?.domainsList">
<button
[disabled]="copied === domain.domain"
[matTooltip]="(copied !== domain.domain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="domain.domain"
(copiedValue)="copied = $event"
>
{{ domain.domain }}
</button>
</div>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
<p *ngIf="instance?.details?.creationDate as creationDate" class="info-row-desc">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
<p *ngIf="instance?.details?.changeDate as changeDate" class="info-row-desc">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
</div>
<div class="info-row" *ngIf="org">
<div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.STATE' | translate }}</p>
<p
*ngIf="org?.state"
class="state"
[ngClass]="{ active: org.state === OrgState.ORG_STATE_ACTIVE, inactive: org.state === OrgState.ORG_STATE_INACTIVE }"
>
{{ 'ORG.STATE.' + org.state | translate }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="org?.id" class="info-row-desc">{{ org.id }}</p>
</div>
<div class="info-wrapper width">
<p class="info-row-title">{{ 'ORG.PAGES.PRIMARYDOMAIN' | translate }}</p>
<div class="copy-row" *ngIf="org.primaryDomain">
<button
[disabled]="copied === org.primaryDomain"
[matTooltip]="(copied !== org.primaryDomain ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="org.primaryDomain"
(copiedValue)="copied = $event"
>
{{ org.primaryDomain }}
</button>
</div>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.CREATIONDATE' | translate }}</p>
<p *ngIf="org?.details?.creationDate as creationDate" class="info-row-desc">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'ORG.PAGES.DATECHANGED' | translate }}</p>
<p *ngIf="org?.details?.changeDate as changeDate" class="info-row-desc">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
</div>
<div class="info-row" *ngIf="project">
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
<p
*ngIf="project?.state"
class="state"
[ngClass]="{
active: project.state === ProjectState.PROJECT_STATE_ACTIVE,
inactive: project.state === ProjectState.PROJECT_STATE_INACTIVE,
}"
>
{{ 'PROJECT.STATE.' + project.state | translate }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="project?.id" class="info-row-desc">{{ project.id }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
<p *ngIf="project?.details?.creationDate as creationDate" class="info-row-desc">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
<p *ngIf="project?.details?.changeDate as changeDate" class="info-row-desc">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
</div>
<div class="info-row" *ngIf="grantedProject">
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.STATE.TITLE' | translate }}</p>
<p
*ngIf="grantedProject?.state"
class="state"
[ngClass]="{
active: grantedProject.state === ProjectGrantState.PROJECT_GRANT_STATE_ACTIVE,
inactive: grantedProject.state === ProjectGrantState.PROJECT_GRANT_STATE_INACTIVE,
}"
>
{{ 'PROJECT.STATE.' + grantedProject.state | translate }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'RESOURCEID' | translate }}</p>
<p *ngIf="grantedProject?.projectId" class="info-row-desc">{{ grantedProject.projectId }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.GRANT.GRANTID' | translate }}</p>
<p *ngIf="grantedProject?.grantId" class="info-row-desc">{{ grantedProject.grantId }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.CREATEDON' | translate }}</p>
<p *ngIf="grantedProject?.details?.creationDate as creationDate" class="info-row-desc">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'PROJECT.PAGES.LASTMODIFIED' | translate }}</p>
<p *ngIf="grantedProject?.details?.changeDate as changeDate" class="info-row-desc">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
</div>
<ng-container *ngIf="app">
<div class="info-row">
<div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.STATE' | translate }}</p>
<p
*ngIf="app?.state"
class="state"
[ngClass]="{ active: app.state === AppState.APP_STATE_ACTIVE, inactive: app.state === AppState.APP_STATE_INACTIVE }"
>
{{ 'APP.PAGES.DETAIL.STATE.' + app.state | translate }}
</p>
</div>
<div class="info-wrapper" *ngIf="app?.apiConfig?.authMethodType as authMethodType">
<p class="info-row-title">{{ 'APP.AUTHMETHOD' | translate }}</p>
<p class="info-row-desc">
{{ 'APP.API.AUTHMETHOD.' + authMethodType | translate }}
</p>
</div>
<div class="info-wrapper" *ngIf="app?.oidcConfig?.authMethodType as authMethodType">
<p class="info-row-title">{{ 'APP.AUTHMETHOD' | translate }}</p>
<p class="info-row-desc">
{{ 'APP.OIDC.AUTHMETHOD.' + authMethodType | translate }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.ID' | translate }}</p>
<p *ngIf="app?.id" class="info-row-desc">{{ app.id }}</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.DATECREATED' | translate }}</p>
<p *ngIf="app?.details?.creationDate as creationDate" class="info-row-desc">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'APP.PAGES.DATECHANGED' | translate }}</p>
<p *ngIf="app?.details?.changeDate as changeDate" class="info-row-desc">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper" *ngIf="app">
<p class="info-row-title">{{ 'APP.OIDC.INFO.CLIENTID' | translate }}</p>
<div class="copy-row" *ngIf="app.oidcConfig?.clientId">
<button
*ngIf="app.oidcConfig?.clientId as clientId"
[disabled]="copied === clientId"
[matTooltip]="(copied !== clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="clientId"
(copiedValue)="copied = $event"
>
{{ clientId }}
</button>
</div>
<div class="copy-row" *ngIf="app.apiConfig?.clientId">
<button
*ngIf="app.apiConfig?.clientId as clientId"
[disabled]="copied === clientId"
[matTooltip]="(copied !== clientId ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"
cnslCopyToClipboard
[valueToCopy]="clientId"
(copiedValue)="copied = $event"
>
{{ clientId }}
</button>
</div>
</div>
</div>
</ng-container>
<div class="info-row" *ngIf="idp">
<div class="info-wrapper width">
<p class="info-row-title">{{ 'IDP.ID' | translate }}</p>
<p class="info-row-desc">
{{ idp.id }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'IDP.DETAIL.DATECREATED' | translate }}</p>
<p class="info-row-desc" *ngIf="idp?.details?.creationDate as creationDate">
{{ creationDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'IDP.DETAIL.DATECHANGED' | translate }}</p>
<p class="info-row-desc" *ngIf="idp?.details?.changeDate as changeDate">
{{ changeDate | timestampToDate | localizedDate: 'dd. MMMM YYYY, HH:mm' }}
</p>
</div>
<div class="info-wrapper">
<p class="info-row-title">{{ 'IDP.STATE' | translate }}</p>
<p
*ngIf="idp?.state"
class="state"
[ngClass]="{ active: idp.state === IDPState.IDP_STATE_ACTIVE, inactive: idp.state === IDPState.IDP_STATE_INACTIVE }"
>
{{ 'IDP.STATES.' + idp.state | translate }}
</p>
</div>
</div>