mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
web: Improve user display in modals by falling back to username (#18243)
* web: Improve user display in modals by falling back to username Fixes UX issues in user-related modals where users without a display name would show empty text. Previously: * "Are you sure you want to update User ""?" (empty display name) * "Successfully updated User undefined" Now: * "Are you sure you want to update User john_doe?" (falls back to username) * "Successfully updated User john_doe" Topics of discussion: * Wether the object label should be lowercased to keep the sentence flowing (In this case, lowercasing User) * oops it did have quotes actually * pls
This commit is contained in:
@@ -3,18 +3,20 @@ import "#elements/buttons/SpinnerButton/index";
|
||||
import { parseAPIResponseError, pluckErrorDetail } from "#common/errors/network";
|
||||
import { MessageLevel } from "#common/messages";
|
||||
|
||||
import { DeleteForm } from "#elements/forms/DeleteForm";
|
||||
import { showMessage } from "#elements/messages/MessageContainer";
|
||||
import { UserDeleteForm } from "#elements/user/utils";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { html, TemplateResult } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
|
||||
@customElement("ak-user-active-form")
|
||||
export class UserActiveForm extends DeleteForm {
|
||||
export class UserActiveForm extends UserDeleteForm {
|
||||
onSuccess(): void {
|
||||
showMessage({
|
||||
message: msg(str`Successfully updated ${this.objectLabel} ${this.obj?.name}`),
|
||||
message: msg(
|
||||
str`Successfully updated ${this.objectLabel} ${this.getObjectDisplayName()}`,
|
||||
),
|
||||
level: MessageLevel.success,
|
||||
});
|
||||
}
|
||||
@@ -30,7 +32,8 @@ export class UserActiveForm extends DeleteForm {
|
||||
});
|
||||
}
|
||||
|
||||
renderModalInner(): TemplateResult {
|
||||
override renderModalInner(): TemplateResult {
|
||||
const objName = this.getFormattedObjectName();
|
||||
return html`<section class="pf-c-modal-box__header pf-c-page__main-section pf-m-light">
|
||||
<div class="pf-c-content">
|
||||
<h1 class="pf-c-title pf-m-2xl">${msg(str`Update ${this.objectLabel}`)}</h1>
|
||||
@@ -39,9 +42,7 @@ export class UserActiveForm extends DeleteForm {
|
||||
<section class="pf-c-modal-box__body pf-m-light">
|
||||
<form class="pf-c-form pf-m-horizontal">
|
||||
<p>
|
||||
${msg(
|
||||
str`Are you sure you want to update ${this.objectLabel} "${this.obj?.name}"?`,
|
||||
)}
|
||||
${msg(str`Are you sure you want to update ${this.objectLabel}${objName}?`)}
|
||||
</p>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
@@ -32,6 +32,22 @@ export class DeleteForm extends ModalButton {
|
||||
@property({ attribute: false })
|
||||
delete!: () => Promise<unknown>;
|
||||
|
||||
/**
|
||||
* Get the display name for the object being deleted/updated.
|
||||
*/
|
||||
protected getObjectDisplayName(): string | undefined {
|
||||
return this.obj?.name as string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted object name for display in messages.
|
||||
* Returns ` "displayName"` with quotes if display name exists, empty string otherwise.
|
||||
*/
|
||||
protected getFormattedObjectName(): string {
|
||||
const displayName = this.getObjectDisplayName();
|
||||
return displayName ? ` "${displayName}"` : "";
|
||||
}
|
||||
|
||||
confirm(): Promise<void> {
|
||||
return this.delete()
|
||||
.then(() => {
|
||||
@@ -54,7 +70,9 @@ export class DeleteForm extends ModalButton {
|
||||
|
||||
onSuccess(): void {
|
||||
showMessage({
|
||||
message: msg(str`Successfully deleted ${this.objectLabel} ${this.obj?.name}`),
|
||||
message: msg(
|
||||
str`Successfully deleted ${this.objectLabel} ${this.getObjectDisplayName()}`,
|
||||
),
|
||||
level: MessageLevel.success,
|
||||
});
|
||||
}
|
||||
@@ -71,12 +89,7 @@ export class DeleteForm extends ModalButton {
|
||||
}
|
||||
|
||||
renderModalInner(): TemplateResult {
|
||||
let objName = this.obj?.name;
|
||||
if (objName) {
|
||||
objName = ` "${objName}"`;
|
||||
} else {
|
||||
objName = "";
|
||||
}
|
||||
const objName = this.getFormattedObjectName();
|
||||
return html`<section class="pf-c-modal-box__header pf-c-page__main-section pf-m-light">
|
||||
<div class="pf-c-content">
|
||||
<h1 class="pf-c-title pf-m-2xl">${msg(str`Delete ${this.objectLabel}`)}</h1>
|
||||
@@ -85,7 +98,7 @@ export class DeleteForm extends ModalButton {
|
||||
<section class="pf-c-modal-box__body pf-m-light">
|
||||
<form class="pf-c-form pf-m-horizontal">
|
||||
<p>
|
||||
${msg(str`Are you sure you want to delete ${this.objectLabel} ${objName}?`)}
|
||||
${msg(str`Are you sure you want to delete ${this.objectLabel}${objName}?`)}
|
||||
</p>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DeleteForm } from "#elements/forms/DeleteForm";
|
||||
|
||||
import { User } from "@goauthentik/api";
|
||||
|
||||
export function UserOption(user: User): string {
|
||||
@@ -17,3 +19,24 @@ export function UserOption(user: User): string {
|
||||
}
|
||||
return finalString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a display-friendly name for a user object.
|
||||
* Falls back to username if no display name (name field) is set.
|
||||
*
|
||||
* @param user - The user object
|
||||
* @returns The user's display name or username
|
||||
*/
|
||||
export function getUserDisplayName(user: User): string {
|
||||
return user.name || user.username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for delete/update forms that work with User objects.
|
||||
* Automatically uses username as fallback when user has no display name.
|
||||
*/
|
||||
export class UserDeleteForm extends DeleteForm {
|
||||
protected override getObjectDisplayName(): string | undefined {
|
||||
return this.obj ? getUserDisplayName(this.obj as unknown as User) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user