Activities of "Sturla"

Please add comments to your nuget packages (interfaces if missing). Its super easy https://stackoverflow.com/a/57731750

Currently there are none but I don´t doubt that you have comments on the methods them selfs but having them on the interfaces is also must for better self service

It is almost working but something is off..

I updated my code example with yours.

Am I pulling the correct values? I have connected gg and ss..

Can you check if is there a console error? It seems like it's a text input in your case.

I checked and its not working in Blazor but is working in MVC

The auto only kicks in if I enter the first letter of the blogs name.

p.s Can we do something about the css of the dropdown? It cramped and hard to view...

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 the IMenuContributor

    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?

Please add some help information (?) bubbles to settings. E.g. the OpenId settings where I don´t know what things do... What is "Consent Type" etc?

It would be great to have a short text like "Consent type does....". Having a link to abp.io documentation would be super nice (this would also give abp.io valuable inbound SEO links)

Host and teant CMS strangness

If I create a page (test) CMS as the Host I can see it if I log out, if I create a page (xxx) under a tenant (Rambo) and log out I will not see the first page (test)

F5 does nothing to refresh...

Expected behaviour when no user is logged in

  • test page would always bee shown (on root domain (https://www.root.com) and subdomain (https://rambo.root.com)) since this is host CMS. Update: I´m doubting this.. it should probably also just be visible on root domain.
  • xxx page only shown on subdomain (https://rambo.root.com)

In my local test there is currently no subdomain setup so I ask if this is a normal behavior?

I´m btw trying to see if I can have one application with host and tenant specific CMS (https://support.abp.io/QA/Questions/6885/One-application-Admin-and-public-in-one-CMS-setup)

This was btw tested with abp.io 8.0.5 MVC

I´m not quite sure if this should be called a bug or not BUT if you don´t know the awailable blogs you will have to go back and type them in to get it in the dropdown.

I would have some wait period (2 sek) after you put the cursor to the input and it will automatically show the blogs availabel.

At least offer an error text telling the user what is the issue..

Can you add information about the template used to create the solution and maybe a "Create another" dropdown option so I don´t have to wonder about this every time I create a new solution.

I use this when I do version updates. What I will do is to create another "compare" solution and then use BeyoundCompare to compare all the files and see if there are some other changes or best practises I want to move over also.

Can you make it easy to find permissions for e.g UI elements? If I had all the commercial source code it would be easy..

Currently I have logic like this that disables functionality based on permissions. Every new version of abp.io I need to add to this because some new functionality pops up and usually in the CMS module.

And every time I have issues trying to locate the new permissions for that UI element... last time I had to track down CmsKit.PageFeedback to remove that from the public website and to do it I had to debug through the menu creation method but that time I was lucky it was there but not in some module I can´t go through!

Can we get a list of these permissions somewhere?

They can´t be viewed through the Feature window

or the Permissions window

  • It would be enough if there was an information bubble (ℹ️) next to the permission showing CmsKit.PageFeedback text on hover

@alper

First of all there is a difference in 0 or 1 results when going to docs from commercial or open docks. I misspelled tired and got this result https://docs.abp.io/en/abp/latest and https://docs.abp.io/en/commercial/latest/

Then if I search for tiered I get this with the commercial one showing me 1 item but 45 "entries" (shouldn´t that be pages?)

you should look into OpenAI if you havent already https://openai.com/blog/introducing-chatgpt-and-whisper-apis

Showing 61 to 70 of 218 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on October 30, 2025, 06:33