- ABP Framework version: v8.0.4
- UI Type: Blazor Server
- Database System: EF Core (SQL Server)
Is it possible to bypass the "My Account" page with the linked account module and instead return directly to the previously opened page?
9 Answer(s)
-
0
Hi,
We considered this issue, but it would cause problems if the linked account did not have permissions, so we gave up
-
0
Is there any way we can streamline it or reduce the number of clicks? Any suggestions on how we can improve the user experience?
Basically can you think of any recommendations that we could apply in a reasonable fashion?
-
0
Hi,
Sorry, maybe I misunderstand.
Do you mean to open the linked account modal directly instead of redirecting to my account first? Right?
-
0
Yes that would be helpful.
Basically the goal is to reduce the number of clicks that a user has to do to change accounts across tenants.
So imagine a scenario where the user is on an invoices page and they want to enter invoices for one tenant and then quickly switch to another tenant and add invoices there as well.
The current navigation is kind of clicky and involves multiple steps to switch tenants.
The goal would be something that is a little bit more like say Gmail for example where you can switch back and forth with ease and few clicks.
And I understand that there are some technical challenges and limitations from what I initially asked.
Therefore with the goals that we have in mind are there any easy wins that we can implement as an alternative?
-
0
Hi,
You can make it yourself
You can add a user menu:
https://docs.abp.io/en/abp/latest/UI/Blazor/Navigation-Menu#standard-menus
The user menu can be a Blazor component, for example:
context.Menu.Items.Add( new ApplicationMenuItem("LinkedAccounts", "Linked Accounts", "#") .UseComponent(typeof(LinkedAccountComponent)));
Then you can inject the
IIdentityLinkUserAppService
service to get the account list. -
0
I implemented this as I understood you guys. I think it would be rather easy to add the users into the dropdown so you would only need one click to switch.
This modal has a button to switch
@using Volo.Abp.Account @using Volo.Abp.Data @using Volo.Abp.Domain.Repositories @using Volo.Abp.Identity @using Volo.Abp.MultiTenancy @using Volo.Abp.Users @inject ICurrentTenant CurrentTenant @inject ICurrentUser CurrentUser @inject NavigationManager NavigationManager @inject IIdentityLinkUserAppService IdentityLinkUserAppService @inject IJSRuntime JsRuntime <form method="post" action="Account/LinkLogin" id="LinkLoginForm" hidden> <input type="hidden" name="SourceLinkUserId" value="@CurrentUser.Id"> <input type="hidden" name="SourceLinkTenantId" value="@CurrentTenant.Id"> <input type="hidden" id="SourceLinkToken" name="SourceLinkToken"> <input type="hidden" id="TargetLinkUserId" name="TargetLinkUserId"> <input type="hidden" id="TargetLinkTenantId" name="TargetLinkTenantId"> <input type="hidden" name="ReturnUrl"> </form> @if (linkedAccounts != null) { <li class="outer-menu-item" id="MenuItem_LinkedAccounts" @onclick="@ShowModal" style="cursor:pointer;"> <a class="lpx-menu-item-link"> <span class="lpx-menu-item-icon"> <i class="lpx-icon fa fa-exchange-alt" aria-hidden="true"></i> </span> <span class="lpx-menu-item-text">Switch Account</span> </a> </li> } <Modal @ref="modalRef"> <ModalContent> <ModalHeader> <ModalTitle>Switch Account</ModalTitle> <CloseButton Clicked="@HideModal" /> </ModalHeader> <ModalBody> @if (linkedAccounts == null) { <Text> Loading... </Text> } else { foreach (var account in linkedAccounts) { <Button Color="Color.Light" Size="Size.ExtraSmall" Clicked="() => SwitchToAccount(account)"> Switch to Tenant: @account.TargetTenantName (user: @account.TargetUserName) </Button> } } </ModalBody> <ModalFooter> <Button Color="Color.Secondary" Clicked="@HideModal">Close</Button> </ModalFooter> </ModalContent> </Modal> @code { private List<LinkUserDto> linkedAccounts = new(); public LinkedAccountComponent(IRepository<IdentityUser, Guid> userRepository) { this.userRepository = userRepository; } private readonly IRepository<IdentityUser, Guid> userRepository; private Modal modalRef = new(); protected override async Task OnInitializedAsync() { linkedAccounts = (await IdentityLinkUserAppService.GetAllListAsync()).Items.ToList(); } public async Task SwitchToAccount(LinkUserDto linkedAccount) { // Generating SourceLinkToken var sourceLinkToken = await IdentityLinkUserAppService.GenerateLinkLoginTokenAsync(); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('SourceLinkToken').value = '" + sourceLinkToken + "'"); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('TargetLinkUserId').value = '" + linkedAccount.TargetUserId + "'"); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('TargetLinkTenantId').value = '" + linkedAccount.TargetTenantId + "'"); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('LinkLoginForm').submit()"); await HideModal(); } private Task ShowModal() { return modalRef.Show(); } private Task HideModal() { return modalRef.Hide(); } }
and
ConfigureMenuAsync
in theIMenuContributor
public async Task ConfigureMenuAsync(MenuConfigurationContext context) { if (context.Menu.Name == StandardMenus.Main) { await ConfigureMainMenuAsync(context); } else if (context.Menu.Name == StandardMenus.User) { await ConfigureUserMenuAsync(context); } } private async Task ConfigureUserMenuAsync(MenuConfigurationContext context) { context.Menu.Items.Add( new ApplicationMenuItem("LinkedAccounts", "Linked Accounts", "#") .UseComponent(typeof(LinkedAccountComponent))); await Task.CompletedTask.ConfigureAwait(false); }
Is this code valid @liangshiwei AND how should you do the actual switching?
-
0
You can try:
<form method="post" action="Account/LinkLogin" id="LinkLoginForm" hidden> <input type="hidden" name="SourceLinkUserId" value="@CurrentUser.Id"> <input type="hidden" name="SourceLinkTenantId" value="@CurrentTenant.Id"> <input type="hidden" id="SourceLinkToken" name="SourceLinkToken"> <input type="hidden" id="TargetLinkUserId" name="TargetLinkUserId"> <input type="hidden" id="TargetLinkTenantId" name="TargetLinkTenantId"> <input type="hidden" name="ReturnUrl"> </form> ....................... public async Task SwitchToAccount(LinkedAccount linkedAccount) { // Generating SourceLinkToken var sourceLinkToken = await IdentityLinkUserAppService.GenerateLinkLoginTokenAsync(); // HERE TENANTID AND TARGETENANTID ARE NULL await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('SourceLinkToken').value = '" + sourceLinkToken + "'"); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('TargetLinkUserId').value = '" + linkedAccount.TargetUserId + "'"); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('TargetLinkTenantId').value = '" + linkedAccount.TargetTenantId + "'"); await JsRuntime.InvokeVoidAsync("eval", "document.getElementById('LinkLoginForm').submit()"); }
-
0
-
0
should be
await IdentityLinkUserAppService.GenerateLinkLoginTokenAsync();
not
await IdentityLinkUserAppService.GenerateLinkTokenAsync()