mirror of https://github.com/abpframework/abp.git
19 changed files with 373 additions and 47 deletions
@ -0,0 +1,21 @@ |
|||||
|
@page |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Pages.Abp.MultiTenancy |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization |
||||
|
@model TenantSwitchModalModel |
||||
|
@inject IHtmlLocalizer<AbpUiMultiTenancyResource> L |
||||
|
@{ |
||||
|
Layout = null; |
||||
|
} |
||||
|
<abp-dynamic-form abp-model="@Model.Input" asp-page="/Abp/MultiTenancy/TenantSwitchModal"> |
||||
|
<abp-modal> |
||||
|
<abp-modal-header title="@L["SwitchTenant"].Value"></abp-modal-header> |
||||
|
<abp-modal-body> |
||||
|
<abp-form-content /> |
||||
|
<p>@L["SwitchTenantHint"]</p> |
||||
|
</abp-modal-body> |
||||
|
@* TODO: A "Submit" would be better than "Save"! *@ |
||||
|
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> |
||||
|
</abp-modal> |
||||
|
</abp-dynamic-form> |
||||
@ -0,0 +1,74 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.MultiTenancy; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace Pages.Abp.MultiTenancy |
||||
|
{ |
||||
|
public class TenantSwitchModalModel : AbpPageModel |
||||
|
{ |
||||
|
[BindProperty] |
||||
|
public TenantInfoModel Input { get; set; } |
||||
|
|
||||
|
protected ITenantStore TenantStore { get; } |
||||
|
protected AspNetCoreMultiTenancyOptions Options { get; } |
||||
|
|
||||
|
public TenantSwitchModalModel( |
||||
|
ITenantStore tenantStore, |
||||
|
IOptions<AspNetCoreMultiTenancyOptions> options) |
||||
|
{ |
||||
|
TenantStore = tenantStore; |
||||
|
Options = options.Value; |
||||
|
LocalizationResourceType = typeof(AbpUiMultiTenancyResource); |
||||
|
} |
||||
|
|
||||
|
public async Task OnGetAsync() |
||||
|
{ |
||||
|
Input = new TenantInfoModel(); |
||||
|
|
||||
|
if (CurrentTenant.IsAvailable) |
||||
|
{ |
||||
|
var tenant = await TenantStore.FindAsync(CurrentTenant.GetId()); |
||||
|
Input.Name = tenant?.Name; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task OnPostAsync() |
||||
|
{ |
||||
|
if (Input.Name.IsNullOrEmpty()) |
||||
|
{ |
||||
|
Response.Cookies.Delete(Options.TenantKey); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var tenant = await TenantStore.FindAsync(Input.Name); |
||||
|
if (tenant == null) |
||||
|
{ |
||||
|
throw new UserFriendlyException(L["GivenTenantIsNotAvailable", Input.Name]); |
||||
|
} |
||||
|
|
||||
|
Response.Cookies.Append( |
||||
|
Options.TenantKey, |
||||
|
tenant.Id.ToString(), |
||||
|
new CookieOptions |
||||
|
{ |
||||
|
Path = "/", |
||||
|
HttpOnly = false, |
||||
|
Expires = DateTimeOffset.Now.AddYears(10) |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class TenantInfoModel |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
||||
|
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
||||
|
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
||||
@ -0,0 +1,16 @@ |
|||||
|
(function($) { |
||||
|
|
||||
|
var tenantSwitchModal = new abp.ModalManager(abp.appPath + 'Abp/MultiTenancy/TenantSwitchModal'); |
||||
|
|
||||
|
$(function() { |
||||
|
$('#TenantSwitchToolbarLink').click(function(e) { |
||||
|
e.preventDefault(); |
||||
|
tenantSwitchModal.open(); |
||||
|
}); |
||||
|
|
||||
|
tenantSwitchModal.onResult(function() { |
||||
|
location.reload(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
})(jQuery); |
||||
@ -0,0 +1,61 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.AspNetCore.MultiTenancy; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Localization; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.VirtualFileSystem; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreMvcUiThemeSharedModule), |
||||
|
typeof(AbpAspNetCoreMultiTenancyModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreMvcUiMultiTenancyModule : AbpModule |
||||
|
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.AddAssemblyResource( |
||||
|
typeof(AbpUiMultiTenancyResource), |
||||
|
typeof(AbpAspNetCoreMvcUiMultiTenancyModule).Assembly |
||||
|
); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<VirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiMultiTenancyModule>(); |
||||
|
}); |
||||
|
|
||||
|
Configure<ToolbarOptions>(options => |
||||
|
{ |
||||
|
options.Contributors.Add(new MultiTenancyToolbarContributor()); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Resources |
||||
|
.Add<AbpUiMultiTenancyResource>("en") |
||||
|
.AddVirtualJson("/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization"); |
||||
|
}); |
||||
|
|
||||
|
Configure<BundlingOptions>(options => |
||||
|
{ |
||||
|
options.ScriptBundles |
||||
|
.Get(StandardBundles.Scripts.Global) |
||||
|
.AddFiles( |
||||
|
"/Pages/Abp/MultiTenancy/tenant-switch.js" |
||||
|
); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch |
||||
|
@model TenantSwitchViewComponent.TenantSwitchViewModel |
||||
|
<li class="nav-item"> |
||||
|
<a id="TenantSwitchToolbarLink" href="#"> |
||||
|
@if (Model.Tenant == null) |
||||
|
{ |
||||
|
<text>@@host</text> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<text>@@@Model.Tenant.Name</text> |
||||
|
} |
||||
|
</a> |
||||
|
</li> |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch |
||||
|
{ |
||||
|
public class TenantSwitchViewComponent : AbpViewComponent |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// -1,000,000
|
||||
|
/// </summary>
|
||||
|
public const int Order = -1_000_000; |
||||
|
|
||||
|
protected ITenantStore TenantStore { get; } |
||||
|
|
||||
|
protected ICurrentTenant CurrentTenant { get; } |
||||
|
|
||||
|
public TenantSwitchViewComponent(ITenantStore tenantStore, ICurrentTenant currentTenant) |
||||
|
{ |
||||
|
TenantStore = tenantStore; |
||||
|
CurrentTenant = currentTenant; |
||||
|
} |
||||
|
|
||||
|
public async Task<IViewComponentResult> InvokeAsync() |
||||
|
{ |
||||
|
var model = new TenantSwitchViewModel(); |
||||
|
|
||||
|
if (CurrentTenant.Id.HasValue) |
||||
|
{ |
||||
|
model.Tenant = await TenantStore.FindAsync(CurrentTenant.GetId()); |
||||
|
} |
||||
|
|
||||
|
return View("~/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml", model); |
||||
|
} |
||||
|
|
||||
|
public class TenantSwitchViewModel |
||||
|
{ |
||||
|
public TenantInfo Tenant { get; set; } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization |
||||
|
{ |
||||
|
[LocalizationResourceName("AbpUiMultiTenancy")] |
||||
|
public class AbpUiMultiTenancyResource |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
{ |
||||
|
"culture": "en", |
||||
|
"texts": { |
||||
|
"GivenTenantIsNotAvailable": "Given tenant is not available: {0}", |
||||
|
"SwitchTenant": "Switch tenant", |
||||
|
"Name": "Name", |
||||
|
"SwitchTenantHint": "Leave the name field blank to switch to the host side." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
{ |
||||
|
"culture": "tr", |
||||
|
"texts": { |
||||
|
"GivenTenantIsNotAvailable": "İstenilen müşteri bulunamadı: {0}", |
||||
|
"SwitchTenant": "Müşteri değiştir", |
||||
|
"Name": "İsim", |
||||
|
"SwitchTenantHint": "Host tarafına geçmek için isim alanını boş bırakın." |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy |
||||
|
{ |
||||
|
public class MultiTenancyToolbarContributor : IToolbarContributor |
||||
|
{ |
||||
|
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) |
||||
|
{ |
||||
|
if (context.Toolbar.Name != StandardToolbars.Main) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
context.Toolbar.Items.Add(new ToolbarItem(typeof(TenantSwitchViewComponent), TenantSwitchViewComponent.Order)); |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,15 +0,0 @@ |
|||||
using Volo.Abp.AspNetCore.MultiTenancy; |
|
||||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.UI.TenantSwitch |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(AbpAspNetCoreMvcUiThemeSharedModule), |
|
||||
typeof(AbpAspNetCoreMultiTenancyModule) |
|
||||
)] |
|
||||
public class AbpAspNetCoreMvcUiTenantSwitchModule : AbpModule |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,20 @@ |
|||||
|
using System; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.MultiTenancy |
||||
|
{ |
||||
|
public static class CurrentTenantExtensions |
||||
|
{ |
||||
|
public static Guid GetId([NotNull] this ICurrentTenant currentTenant) |
||||
|
{ |
||||
|
Check.NotNull(currentTenant, nameof(currentTenant)); |
||||
|
|
||||
|
if (currentTenant.Id == null) |
||||
|
{ |
||||
|
throw new AbpException("Current Tenant Id is not available!"); |
||||
|
} |
||||
|
|
||||
|
return currentTenant.Id.Value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue