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

Is it possible to have one running application that has

  • both the admin and public functionality in one place (not backend/frontend application)?

Something like:

  • Tenants would control the CMS (when logged in) (www.tenant.domain.com)
    • Not logged in users would see the result (blog/pages/menus/etc)
  • Host admin have CMS for the host domain ((www.domain.com)
    • plush would be that the host could create menu items that would apply for all tenants

Tenant could create a Blog page like this

and view it like this on the same application, not having to have another application instance (public web)?

It is cheaper and easier to have it all in one solution.

p.s I tried this in Blazor Server.. is that maybe not supported? And if so are there any other restrictions or limitations for Blazor?

e.s I tried this also with MVC and had some different strangeness https://support.abp.io/QA/Questions/6711/Bugs--Issues-v81x#answer-3a115a09-806f-bf69-6f41-319509df51ef

Abp.io Blazor Server 8.0.5

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
Showing 21 to 30 of 210 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13