Hi,
It seems like ABP breaks when you are using longer usernames like "reallylongusername"
there also seems to be inconsistencies between UIs, above is angular UI, below is the same page in My Account for API (which I think is MVC)
One displays name, the other one displays username.
<br> Why is different UIs showing different things (username vs firstname and lastname) for same page?
How can we modify/change this so that a truncated username is not shown and also which properties are shown (username, firstname, lastname etc)
Thanks.
7 Answer(s)
-
0
What you see is expected: they are different UIs backed by different implementations.
- Angular UI reads the header dropdown from the client-side
currentUserinfo and typically displaysuserName. - The other screen (the โMy Account for APIโ, MVC/Razor profile management page) uses server-side rendering and typically displays the full name (Name + Surname) and falls back to username if those are empty.
- Also note: before ABP v4.3 the โMy Accountโ link in Angular used to redirect to the MVC profile page; since v4.3, if you add the Angular Account Module, โMy Accountโ is an Angular page instead. So mixing of pages/UIs can happen depending on which modules you use and which link you click.
- Angular UI reads the header dropdown from the client-side
Fixing the long username UI break / truncation (Angular):
- Change what is shown in the header user area (recommended): show full name (or whatever you want) instead of
userName.- In your Angular layout/header template, locate the part similar to:
- Change what is shown in the header user area (recommended): show full name (or whatever you want) instead of
<strong>{{ (currentUser$ | async)?.userName }}</strong>- Replace it with name/surname (with fallback), e.g.:<strong> {{ ((currentUser$ | async)?.name || '') + ' ' + ((currentUser$ | async)?.surname || '') || (currentUser$ | async)?.userName }} </strong>- If your template doesnโt have `name`/`surname` available in the `currentUser` object, you can still solve the UI break with CSS (next step) or extend what you load into `currentUser` (project-specific).- Prevent layout break via CSS (works even if you keep username):
- Apply ellipsis truncation on the element that contains the username, for example:
.my-user-display-name { max-width: 180px; /* adjust */ display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }And wrap the displayed text:<strong class="my-user-display-name">{{ (currentUser$ | async)?.userName }}</strong>- Changing which properties are shown in My Account / Manage Profile:
- Angular My Account page (Account Module) is customizable by replacing/patching the relevant tab/component (so you can show
userName,name,surname, etc. in a consistent way). - MVC/Razor profile management page is a separate UI and must be customized on the MVC side (different mechanism).
- Angular My Account page (Account Module) is customizable by replacing/patching the relevant tab/component (so you can show
Sources:
- https://abp.io/docs/latest/framework/ui/angular/account-module
This response was generated by AI. If it didnโt solve your problem, feel free to post a new answer โ our support team will jump in to help you soon.
-
0
Ai instructions seems wrong here, referring to non existent files etc
-
0
This seem to be related
https://abp.io/support/questions/5889/Use-user-first-name-and-last-name-on-the-menu-profile--instead-of-user-name-in-ABPUSer-table
but seems complicated and will probably break if LeptonX theme is updated.
We would ideally just want to his the username below the profile picture, and then have all UIs show Firstname Lastname when you go into the user accont menu (like with the MVC UI)
-
0
-
0
hi
We will adjust Angular to display
nameandsurnamein the next patch version.Also, how could we disable/hide everything but the logout button in this absurdly complicated user menu that make it seem like you are logged in as an admin even though it is a normal user?
Our Angular team will guide you in removing the menu items.
For MVC:
You can add a new
MyUserMenuContributorto remove them.PostConfigure<AbpNavigationOptions>(options => { options.MenuContributors.Add(new MyUserMenuContributor()); }); public class MyUserMenuContributor : IMenuContributor { public virtual Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name != StandardMenus.User) { return Task.CompletedTask; } context.Menu.TryRemoveMenuItem("Account.LinkedAccounts"); context.Menu.TryRemoveMenuItem("Account.AuthorityDelegation"); context.Menu.TryRemoveMenuItem("Account.ExternalLogins"); return Task.CompletedTask; } }Thanks.
-
0
Hello,
The recommended way to customize the related toolbar is to follow the approach described here: https://abp.io/support/questions/5889/Use-user-first-name-and-last-name-on-the-menu-profile--instead-of-user-name-in-ABPUSer-table
First, create a custom toolbar component like the example below:
import { Component, ViewEncapsulation } from '@angular/core'; import { AsyncPipe, NgTemplateOutlet } from '@angular/common'; import { LpxAvatarModule } from '@volo/ngx-lepton-x.core'; import { ToolbarComponent, LpxToolbarModule } from '@volosoft/ngx-lepton-x/layouts'; @Component({ selector: 'lpx-toolbar', template: ` <div class="lpx-toolbar"> @if (userProfileService.user$ | async; as user) { <ng-content></ng-content> <nav class="lpx-toolbar"> <ul class="lpx-nav-menu"> @if (authService.isUserExists$ | async) { <li #profileLink class="outer-menu-item lpx-user-menu" (click)="profileClick.emit()"> <a class="lpx-menu-item-link"> <lpx-avatar [avatar]="user.avatar"></lpx-avatar> <!--UPDATE HERE--> <span class="lpx-menu-item-text">{{ user.fullName || user.userName }}</span> <!--UPDATE HERE--> </a> </li> } @else { <li class="outer-menu-item lpx-user-menu text-center"> <a class="lpx-menu-item-link" (click)="navigateToLogin()"> <i class="bi bi-box-arrow-right"></i> </a> </li> } </ul> <ng-container *ngTemplateOutlet=" itemsTmp || defaultItemsTmp; context: { $implicit: toolbarService.items$ | async } " ></ng-container> </nav> } <ng-template #defaultItemsTmp let-items> <lpx-toolbar-items [items]="items"></lpx-toolbar-items> </ng-template> </div> `, imports: [AsyncPipe, NgTemplateOutlet, LpxAvatarModule, LpxToolbarModule], encapsulation: ViewEncapsulation.None, }) export class MyToolbarComponent extends ToolbarComponent {}Next, create a toolbar container component:
import { Component } from '@angular/core'; import { AsyncPipe } from '@angular/common'; import { observeOn } from 'rxjs/operators'; import { asyncScheduler } from 'rxjs'; import { LpxCoreModule, LpxNavbarModule, LpxAvatarModule, LpxClickOutsideModule, } from '@volo/ngx-lepton-x.core'; import { LpxContextMenuModule } from '@volosoft/ngx-lepton-x'; import { ToolbarContainerComponent } from '@volosoft/ngx-lepton-x/layouts'; import { MyToolbarComponent } from '../my-toolbar/my-toolbar.component'; @Component({ selector: 'app-toolbar-container', template: ` <lpx-toolbar [profileRef]="profileRef$" (profileClick)="toggleCtxMenu()"> @if ( { user: userProfileService.user$ | async, profileRef: profileRefForMenu$ | async, }; as data ) { @if (data.profileRef) { <lpx-context-menu #menu="lpx-context-menu" (lpxClickOutside)="menu.close()" [exceptedRefs]="[data.profileRef]" > <lpx-context-menu-header> <div class="lpx-user-ctx-header"> <div class="lpx-user-ctx-img"> <lpx-avatar [avatar]="data.user?.avatar"></lpx-avatar> </div> <div class="lpx-user-ctx-info"> <span class="lpx-context-menu-user-name">{{ data.user?.fullName || data.user?.userName }}</span> @if (data.user?.tenant?.name; as tenantName) { <span class="lpx-context-menu-user-tenant">{{ tenantName }}</span> } <span class="lpx-context-menu-user-email">{{ data.user?.email }}</span> </div> </div> </lpx-context-menu-header> @for (actions of data.user?.userActionGroups; track actions.id) { <lpx-context-menu-action-group> <lpx-navbar-routes [navbarItems]="actions" [routerItem]="false"></lpx-navbar-routes> </lpx-context-menu-action-group> } </lpx-context-menu> } } </lpx-toolbar> `, imports: [ AsyncPipe, LpxAvatarModule, LpxClickOutsideModule, LpxContextMenuModule, LpxCoreModule, LpxNavbarModule, MyToolbarComponent, ], }) export class MyToolbarContainerComponent extends ToolbarContainerComponent { /** Deferred so NG0100 is avoided when profileRef$ emits after the same CD cycle. */ protected profileRefForMenu$ = this.profileRef$.pipe(observeOn(asyncScheduler)); }Finally, replace the default toolbar component in your root app component:
import { eThemeLeptonXComponents } from '@volosoft/abp.ng.theme.lepton-x'; import { MyToolbarContainerComponent } from './my-toolbar-container/my-toolbar-container.component'; @Component({ selector: 'app-root', template: ` <abp-loader-bar /> <abp-dynamic-layout /> <abp-gdpr-cookie-consent /> `, imports: [LoaderBarComponent, DynamicLayoutComponent, GdprCookieConsentComponent], }) export class AppComponent { protected readonly replaceableService = inject(ReplaceableComponentsService); constructor() { this.replaceableService.add({ key: eThemeLeptonXComponents.Toolbar, component: MyToolbarContainerComponent, }); } }You mentioned that this approach seems complicated and might break if the LeptonX theme is updated.
Thereโs no need for concer since we do not frequently introduce breaking changes that would affect this structure, it should remain stable.
Thank you for your cooperation.
-
0
[maliming] said: hi
We will adjust Angular to display
nameandsurnamein the next patch version.Also, how could we disable/hide everything but the logout button in this absurdly complicated user menu that make it seem like you are logged in as an admin even though it is a normal user?
Our Angular team will guide you in removing the menu items.
For MVC:
You can add a new
MyUserMenuContributorto remove them.PostConfigure<AbpNavigationOptions>(options => { options.MenuContributors.Add(new MyUserMenuContributor()); }); public class MyUserMenuContributor : IMenuContributor { public virtual Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name != StandardMenus.User) { return Task.CompletedTask; } context.Menu.TryRemoveMenuItem("Account.LinkedAccounts"); context.Menu.TryRemoveMenuItem("Account.AuthorityDelegation"); context.Menu.TryRemoveMenuItem("Account.ExternalLogins"); return Task.CompletedTask; } }Thanks.
Thanks you.
Please consider refunding this ticket as it seems it identified a problem.


