mirror of https://github.com/abpframework/eventhub
34 changed files with 992 additions and 6 deletions
@ -0,0 +1,15 @@ |
|||
namespace EventHub.Web.Theme.Bundling |
|||
{ |
|||
public static class EventHubThemeBundles |
|||
{ |
|||
public static class Styles |
|||
{ |
|||
public const string Global = "EventHub.Global"; |
|||
} |
|||
|
|||
public static class Scripts |
|||
{ |
|||
public const string Global = "EventHub.Global"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace EventHub.Web.Theme.Bundling |
|||
{ |
|||
public class EventHubThemeGlobalScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.Add("/themes/eventhub/layout.js"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace EventHub.Web.Theme.Bundling |
|||
{ |
|||
public class EventHubThemeGlobalStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.Add("/themes/eventhub/layout.css"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<AddRazorSupportForMvc>true</AddRazorSupportForMvc> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<IsPackable>true</IsPackable> |
|||
<OutputType>Library</OutputType> |
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="wwwroot\**\*.*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Content Remove="wwwroot\**\*.*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy" Version="4.2.1" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared" Version="4.2.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="5.0.*" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,26 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theming; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace EventHub.Web.Theme |
|||
{ |
|||
[ThemeName(Name)] |
|||
public class EventHubTheme : ITheme, ITransientDependency |
|||
{ |
|||
public const string Name = "EventHub"; |
|||
|
|||
public virtual string GetLayout(string name, bool fallbackToDefault = true) |
|||
{ |
|||
switch (name) |
|||
{ |
|||
case StandardLayouts.Application: |
|||
return "~/Themes/EventHub/Layouts/Application.cshtml"; |
|||
case StandardLayouts.Account: |
|||
return "~/Themes/EventHub/Layouts/Account.cshtml"; |
|||
case StandardLayouts.Empty: |
|||
return "~/Themes/EventHub/Layouts/Empty.cshtml"; |
|||
default: |
|||
return fallbackToDefault ? "~/Themes/EventHub/Layouts/Application.cshtml" : null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
using EventHub.Web.Theme.Bundling; |
|||
using EventHub.Web.Theme.Toolbars; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; |
|||
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.AspNetCore.Mvc.UI.Theming; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace EventHub.Web.Theme |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcUiThemeSharedModule), |
|||
typeof(AbpAspNetCoreMvcUiMultiTenancyModule) |
|||
)] |
|||
public class EventHubWebThemeModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(EventHubWebThemeModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpThemingOptions>(options => |
|||
{ |
|||
options.Themes.Add<EventHubTheme>(); |
|||
options.DefaultThemeName = EventHubTheme.Name; |
|||
}); |
|||
|
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<EventHubWebThemeModule>(); |
|||
}); |
|||
|
|||
Configure<AbpToolbarOptions>(options => |
|||
{ |
|||
options.Contributors.Add(new EventHubThemeMainTopToolbarContributor()); |
|||
}); |
|||
|
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
options |
|||
.StyleBundles |
|||
.Add(EventHubThemeBundles.Styles.Global, bundle => |
|||
{ |
|||
bundle |
|||
.AddBaseBundles(StandardBundles.Styles.Global) |
|||
.AddContributors(typeof(EventHubThemeGlobalStyleContributor)); |
|||
}); |
|||
|
|||
options |
|||
.ScriptBundles |
|||
.Add(EventHubThemeBundles.Scripts.Global, bundle => |
|||
{ |
|||
bundle |
|||
.AddBaseBundles(StandardBundles.Scripts.Global) |
|||
.AddContributors(typeof(EventHubThemeGlobalScriptContributor)); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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,9 @@ |
|||
@using Volo.Abp.Ui.Branding |
|||
@inject IBrandingProvider BrandingProvider |
|||
<a class="navbar-brand" href="~/"> |
|||
@if (!BrandingProvider.LogoUrl.IsNullOrWhiteSpace()) |
|||
{ |
|||
<img src="@BrandingProvider.LogoUrl" alt="@BrandingProvider.AppName" > |
|||
} |
|||
@BrandingProvider.AppName |
|||
</a> |
|||
@ -0,0 +1,13 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.Brand |
|||
{ |
|||
public class MainNavbarBrandViewComponent : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Themes/EventHub/Components/Brand/Default.cshtml"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.Brand |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.Menu |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.Toolbar |
|||
<nav class="navbar navbar-expand-md navbar-dark bg-dark shadow-sm flex-column flex-md-row mb-4" id="main-navbar" style="min-height: 4rem;"> |
|||
<div class="container"> |
|||
@(await Component.InvokeAsync<MainNavbarBrandViewComponent>()) |
|||
<button class="navbar-toggler" type="button" data-toggle="collapse" |
|||
data-target="#main-navbar-collapse" aria-controls="main-navbar-collapse" |
|||
aria-expanded="false" aria-label="Toggle navigation"> |
|||
<span class="navbar-toggler-icon"></span> |
|||
</button> |
|||
<div class="collapse navbar-collapse" id="main-navbar-collapse"> |
|||
<ul class="navbar-nav mx-auto"> |
|||
@(await Component.InvokeAsync<MainNavbarMenuViewComponent>()) |
|||
</ul> |
|||
<ul class="navbar-nav"> |
|||
@(await Component.InvokeAsync<MainNavbarToolbarViewComponent>()) |
|||
</ul> |
|||
</div> |
|||
</div> |
|||
</nav> |
|||
@ -0,0 +1,13 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.MainNavbar |
|||
{ |
|||
public class MainNavbarViewComponent : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Themes/EventHub/Components/MainNavbar/Default.cshtml"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
@using Volo.Abp.UI.Navigation |
|||
@model ApplicationMenu |
|||
@foreach (var menuItem in Model.Items) |
|||
{ |
|||
var elementId = string.IsNullOrEmpty(menuItem.ElementId) ? string.Empty : $"id=\"{menuItem.ElementId}\""; |
|||
var cssClass = string.IsNullOrEmpty(menuItem.CssClass) ? string.Empty : menuItem.CssClass; |
|||
var disabled = menuItem.IsDisabled ? "disabled" : string.Empty; |
|||
var url = string.IsNullOrEmpty(menuItem.Url) ? "#" : Url.Content(menuItem.Url); |
|||
if (menuItem.IsLeaf) |
|||
{ |
|||
if (menuItem.Url != null) |
|||
{ |
|||
<li class="nav-item @cssClass @disabled" @elementId> |
|||
<a class="nav-link" href="@url" target="@menuItem.Target"> |
|||
@if (menuItem.Icon != null) |
|||
{ |
|||
if (menuItem.Icon.StartsWith("fa")) |
|||
{ |
|||
<i class="@menuItem.Icon"></i> |
|||
} |
|||
} |
|||
@menuItem.DisplayName |
|||
</a> |
|||
</li> |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
<li class="nav-item"> |
|||
<div class="dropdown"> |
|||
<a class="nav-link dropdown-toggle" href="#" id="Menu_@(menuItem.Name)" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
|||
@if (menuItem.Icon != null) |
|||
{ |
|||
if (menuItem.Icon.StartsWith("fa")) |
|||
{ |
|||
<i class="@menuItem.Icon"></i> |
|||
} |
|||
} |
|||
@menuItem.DisplayName |
|||
</a> |
|||
<div class="dropdown-menu border-0 shadow-sm" aria-labelledby="Menu_@(menuItem.Name)"> |
|||
@foreach (var childMenuItem in menuItem.Items) |
|||
{ |
|||
@await Html.PartialAsync("~/Themes/EventHub/Components/Menu/_MenuItem.cshtml", childMenuItem) |
|||
} |
|||
</div> |
|||
</div> |
|||
</li> |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.Menu |
|||
{ |
|||
public class MainNavbarMenuViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IMenuManager _menuManager; |
|||
|
|||
public MainNavbarMenuViewComponent(IMenuManager menuManager) |
|||
{ |
|||
_menuManager = menuManager; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
var menu = await _menuManager.GetAsync(StandardMenus.Main); |
|||
return View("~/Themes/EventHub/Components/Menu/Default.cshtml", menu); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
@using Volo.Abp.UI.Navigation |
|||
@model ApplicationMenuItem |
|||
@{ |
|||
var elementId = string.IsNullOrEmpty(Model.ElementId) ? string.Empty : $"id=\"{Model.ElementId}\""; |
|||
var cssClass = string.IsNullOrEmpty(Model.CssClass) ? string.Empty : Model.CssClass; |
|||
var disabled = Model.IsDisabled ? "disabled" : string.Empty; |
|||
var url = string.IsNullOrEmpty(Model.Url) ? "#" : Url.Content(Model.Url); |
|||
} |
|||
@if (Model.IsLeaf) |
|||
{ |
|||
if (Model.Url != null) |
|||
{ |
|||
<a class="dropdown-item @cssClass @disabled" href="@url" target="@Model.Target" @Html.Raw(elementId)> |
|||
@if (Model.Icon != null) |
|||
{ |
|||
if (Model.Icon.StartsWith("fa")) |
|||
{ |
|||
<i class="@Model.Icon"></i> |
|||
} |
|||
} |
|||
@Model.DisplayName |
|||
</a> |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
<div class="dropdown-submenu"> |
|||
<a role="button" class="btn dropdown-toggle" data-toggle="dropdown" |
|||
aria-haspopup="true" aria-expanded="false"> |
|||
<span class="lp-icon"> |
|||
<i class="@(Model.Icon ?? "")"></i> |
|||
</span> |
|||
<span class="lp-text"> |
|||
@Model.DisplayName |
|||
</span> |
|||
</a> |
|||
<div class="dropdown-menu border-0 shadow-sm"> |
|||
@foreach (var childMenuItem in Model.Items) |
|||
{ |
|||
@await Html.PartialAsync("~/Themes/EventHub/Components/Menu/_MenuItem.cshtml", childMenuItem) |
|||
} |
|||
</div> |
|||
</div> |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
@model Volo.Abp.AspNetCore.Mvc.UI.Alerts.AlertList |
|||
@if (Model.Any()) |
|||
{ |
|||
<div id="AbpPageAlerts"> |
|||
@foreach (var alertMessage in Model) |
|||
{ |
|||
<abp-alert alert-type="@(alertMessage.Type)" dismissible="@alertMessage.Dismissible"> |
|||
@if (alertMessage.Title != null) |
|||
{ |
|||
<h4>@alertMessage.Title</h4> |
|||
} |
|||
@alertMessage.Text |
|||
</abp-alert> |
|||
} |
|||
</div> |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Alerts; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.PageAlerts |
|||
{ |
|||
public class PageAlertsViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IAlertManager _alertManager; |
|||
|
|||
public PageAlertsViewComponent(IAlertManager alertManager) |
|||
{ |
|||
_alertManager = alertManager; |
|||
} |
|||
|
|||
public IViewComponentResult Invoke(string name) |
|||
{ |
|||
return View("~/Themes/EventHub/Components/PageAlerts/Default.cshtml", _alertManager.Alerts); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars |
|||
@model Toolbar |
|||
@foreach (var toolbarItem in Model.Items.OrderBy(i => i.Order)) |
|||
{ |
|||
<li class="nav-item">@(await Component.InvokeAsync(toolbarItem.ComponentType))</li> |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
@using System.Linq |
|||
@using Microsoft.AspNetCore.Http.Extensions |
|||
@model EventHub.Web.Theme.Themes.EventHub.Components.Toolbar.LanguageSwitch.LanguageSwitchViewComponentModel |
|||
@if (Model.OtherLanguages.Any()) |
|||
{ |
|||
<div class="dropdown"> |
|||
<a class="nav-link dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
|||
@Model.CurrentLanguage.DisplayName |
|||
</a> |
|||
|
|||
<div class="dropdown-menu dropdown-menu-right border-0 shadow-sm" aria-labelledby="dropdownMenuLink"> |
|||
@foreach (var language in Model.OtherLanguages) |
|||
{ |
|||
<a class="dropdown-item" href="~/Abp/Languages/Switch?culture=@(language.CultureName)&uiCulture=@(language.UiCultureName)&returnUrl=@(System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery()))">@language.DisplayName</a> |
|||
} |
|||
</div> |
|||
</div> |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.RequestLocalization; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.Toolbar.LanguageSwitch |
|||
{ |
|||
public class LanguageSwitchViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly ILanguageProvider _languageProvider; |
|||
|
|||
public LanguageSwitchViewComponent(ILanguageProvider languageProvider) |
|||
{ |
|||
_languageProvider = languageProvider; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
var languages = await _languageProvider.GetLanguagesAsync(); |
|||
var currentLanguage = languages.FindByCulture( |
|||
CultureInfo.CurrentCulture.Name, |
|||
CultureInfo.CurrentUICulture.Name |
|||
); |
|||
|
|||
if (currentLanguage == null) |
|||
{ |
|||
var abpRequestLocalizationOptionsProvider = HttpContext.RequestServices.GetRequiredService<IAbpRequestLocalizationOptionsProvider>(); |
|||
var localizationOptions = await abpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync(); |
|||
if (localizationOptions.DefaultRequestCulture != null) |
|||
{ |
|||
currentLanguage = new LanguageInfo( |
|||
localizationOptions.DefaultRequestCulture.Culture.Name, |
|||
localizationOptions.DefaultRequestCulture.UICulture.Name, |
|||
localizationOptions.DefaultRequestCulture.UICulture.DisplayName); |
|||
} |
|||
else |
|||
{ |
|||
currentLanguage = new LanguageInfo( |
|||
CultureInfo.CurrentCulture.Name, |
|||
CultureInfo.CurrentUICulture.Name, |
|||
CultureInfo.CurrentUICulture.DisplayName); |
|||
} |
|||
} |
|||
|
|||
var model = new LanguageSwitchViewComponentModel |
|||
{ |
|||
CurrentLanguage = currentLanguage, |
|||
OtherLanguages = languages.Where(l => l != currentLanguage).ToList() |
|||
}; |
|||
|
|||
return View("~/Themes/EventHub/Components/Toolbar/LanguageSwitch/Default.cshtml", model); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.Toolbar.LanguageSwitch |
|||
{ |
|||
public class LanguageSwitchViewComponentModel |
|||
{ |
|||
public LanguageInfo CurrentLanguage { get; set; } |
|||
|
|||
public List<LanguageInfo> OtherLanguages { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.Toolbar |
|||
{ |
|||
public class MainNavbarToolbarViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IToolbarManager _toolbarManager; |
|||
|
|||
public MainNavbarToolbarViewComponent(IToolbarManager toolbarManager) |
|||
{ |
|||
_toolbarManager = toolbarManager; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
var toolbar = await _toolbarManager.GetAsync(StandardToolbars.Main); |
|||
return View("~/Themes/EventHub/Components/Toolbar/Default.cshtml", toolbar); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
@using Localization.Resources.AbpUi |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.MultiTenancy |
|||
@using Volo.Abp.UI.Navigation |
|||
@using Volo.Abp.Users |
|||
@inject ICurrentUser CurrentUser |
|||
@inject ICurrentTenant CurrentTenant |
|||
@inject IHtmlLocalizer<AbpUiResource> L |
|||
@model ApplicationMenu |
|||
<div class="dropdown"> |
|||
<a class="nav-link dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
|||
@if (CurrentUser.TenantId != null) |
|||
{ |
|||
<small><i>@CurrentTenant.Name</i>\</small>@CurrentUser.UserName |
|||
} |
|||
else |
|||
{ |
|||
@CurrentUser.UserName |
|||
} |
|||
</a> |
|||
|
|||
@if (Model.Items.Any()) |
|||
{ |
|||
<div class="dropdown-menu dropdown-menu-right border-0 shadow-sm" aria-labelledby="dropdownMenuLink"> |
|||
@foreach (var menuItem in Model.Items) |
|||
{ |
|||
var elementId = string.IsNullOrEmpty(menuItem.ElementId) ? string.Empty : $"id=\"{menuItem.ElementId}\""; |
|||
var cssClass = string.IsNullOrEmpty(menuItem.CssClass) ? string.Empty : menuItem.CssClass; |
|||
var disabled = menuItem.IsDisabled ? "disabled" : string.Empty; |
|||
var url = string.IsNullOrEmpty(menuItem.Url) ? "#" : Url.Content(menuItem.Url); |
|||
|
|||
<a class="dropdown-item @cssClass @disabled" href="@url" target="@menuItem.Target" @Html.Raw(elementId)> |
|||
@if (menuItem.Icon != null) |
|||
{ |
|||
if (menuItem.Icon.StartsWith("fa")) |
|||
{ |
|||
<i class="@menuItem.Icon"></i> |
|||
} |
|||
} |
|||
@menuItem.DisplayName |
|||
</a> |
|||
} |
|||
</div> |
|||
} |
|||
</div> |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace EventHub.Web.Theme.Themes.EventHub.Components.Toolbar.UserMenu |
|||
{ |
|||
public class UserMenuViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IMenuManager _menuManager; |
|||
|
|||
public UserMenuViewComponent(IMenuManager menuManager) |
|||
{ |
|||
_menuManager = menuManager; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
var menu = await _menuManager.GetAsync(StandardMenus.User); |
|||
return View("~/Themes/EventHub/Components/Toolbar/UserMenu/Default.cshtml", menu); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
@using Microsoft.Extensions.Localization |
|||
@using Microsoft.Extensions.Options |
|||
@using Volo.Abp.AspNetCore.MultiTenancy |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Theming |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles |
|||
@using Volo.Abp.MultiTenancy |
|||
@using Volo.Abp.Localization |
|||
@using Volo.Abp.Ui.Branding |
|||
@using EventHub.Web.Theme.Bundling |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.MainNavbar |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.PageAlerts |
|||
@inject IBrandingProvider BrandingProvider |
|||
@inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions |
|||
@inject ICurrentTenant CurrentTenant |
|||
@inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer |
|||
@inject ITenantResolveResultAccessor TenantResolveResultAccessor |
|||
|
|||
@{ |
|||
Layout = null; |
|||
var containerClass = ViewBag.FluidLayout == true ? "container-fluid" : "container"; //TODO: Better and type-safe options |
|||
var rtl = CultureHelper.IsRtl ? "rtl" : string.Empty; |
|||
} |
|||
|
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="@CultureInfo.CurrentCulture.Name" dir="@rtl"> |
|||
<head> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Account) |
|||
|
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
|
|||
<title>@(ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title)</title> |
|||
|
|||
@if (ViewBag.Description != null) |
|||
{ |
|||
<meta name="description" content="@(ViewBag.Description as string)" /> |
|||
} |
|||
<abp-style-bundle name="@EventHubThemeBundles.Styles.Global" /> |
|||
|
|||
@await RenderSectionAsync("styles", false) |
|||
|
|||
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent)) |
|||
|
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account) |
|||
</head> |
|||
<body class="abp-account-layout bg-light @rtl"> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Account) |
|||
|
|||
@(await Component.InvokeAsync<MainNavbarViewComponent>()) |
|||
|
|||
<div class="@containerClass"> |
|||
<abp-row> |
|||
<abp-column class="col mx-auto" style="max-width: 440px"> |
|||
@if (MultiTenancyOptions.Value.IsEnabled && |
|||
(TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true)) |
|||
{ |
|||
<div class="card shadow-sm rounded mb-3"> |
|||
<div class="card-body px-5"> |
|||
<div class="row"> |
|||
<div class="col"> |
|||
<span style="font-size: .8em;" class="text-uppercase text-muted">@MultiTenancyStringLocalizer["Tenant"]</span><br /> |
|||
<h6 class="m-0 d-inline-block"> |
|||
@if (CurrentTenant.Id == null) |
|||
{ |
|||
<span> |
|||
@MultiTenancyStringLocalizer["NotSelected"] |
|||
</span> |
|||
} |
|||
else |
|||
{ |
|||
<strong>@(CurrentTenant.Name ?? CurrentTenant.Id.Value.ToString())</strong> |
|||
} |
|||
</h6> |
|||
</div> |
|||
<div class="col-auto"> |
|||
<a id="AbpTenantSwitchLink" href="javascript:;" class="btn btn-sm mt-3 btn-outline-primary">@MultiTenancyStringLocalizer["Switch"]</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
} |
|||
@(await Component.InvokeAsync<PageAlertsViewComponent>()) |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Account) |
|||
@RenderBody() |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Account) |
|||
</abp-column> |
|||
</abp-row> |
|||
</div> |
|||
|
|||
<abp-script-bundle name="@EventHubThemeBundles.Scripts.Global" /> |
|||
|
|||
<script src="~/Abp/ApplicationConfigurationScript"></script> |
|||
<script src="~/Abp/ServiceProxyScript"></script> |
|||
|
|||
@await RenderSectionAsync("scripts", false) |
|||
|
|||
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent)) |
|||
|
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account) |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,80 @@ |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Layout |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Theming |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles |
|||
@using Volo.Abp.Localization |
|||
@using Volo.Abp.Ui.Branding |
|||
@using EventHub.Web.Theme.Bundling |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.MainNavbar |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.PageAlerts |
|||
@inject IBrandingProvider BrandingProvider |
|||
@inject IPageLayout PageLayout |
|||
@{ |
|||
Layout = null; |
|||
var containerClass = ViewBag.FluidLayout == true ? "container-fluid" : "container"; //TODO: Better and type-safe options |
|||
|
|||
var pageTitle = ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title; //TODO: Discard to get from Title |
|||
|
|||
if (PageLayout.Content.Title != null) |
|||
{ |
|||
if (!string.IsNullOrWhiteSpace(pageTitle)) |
|||
{ |
|||
pageTitle = " | " + pageTitle; |
|||
} |
|||
|
|||
pageTitle = PageLayout.Content.Title + pageTitle; |
|||
} |
|||
|
|||
var rtl = CultureHelper.IsRtl ? "rtl" : string.Empty; |
|||
} |
|||
|
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="@CultureInfo.CurrentCulture.Name" dir="@rtl"> |
|||
<head> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Application) |
|||
|
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
|
|||
<title>@pageTitle</title> |
|||
|
|||
<abp-style-bundle name="@EventHubThemeBundles.Styles.Global" /> |
|||
|
|||
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent)) |
|||
|
|||
@await RenderSectionAsync("styles", false) |
|||
|
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Application) |
|||
</head> |
|||
<body class="abp-application-layout bg-light @rtl"> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Application) |
|||
|
|||
@(await Component.InvokeAsync<MainNavbarViewComponent>()) |
|||
|
|||
<div class="@containerClass"> |
|||
@(await Component.InvokeAsync<PageAlertsViewComponent>()) |
|||
<div id="AbpContentToolbar"> |
|||
<div class="text-right mb-2"> |
|||
@RenderSection("content_toolbar", false) |
|||
</div> |
|||
</div> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Application) |
|||
@RenderBody() |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Application) |
|||
</div> |
|||
|
|||
<abp-script-bundle name="@EventHubThemeBundles.Scripts.Global" /> |
|||
|
|||
<script src="~/Abp/ApplicationConfigurationScript"></script> |
|||
<script src="~/Abp/ServiceProxyScript"></script> |
|||
|
|||
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent)) |
|||
|
|||
@await RenderSectionAsync("scripts", false) |
|||
|
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Application) |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,75 @@ |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Layout |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Theming |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles |
|||
@using Volo.Abp.Localization |
|||
@using Volo.Abp.Ui.Branding |
|||
@using EventHub.Web.Theme.Bundling |
|||
@using EventHub.Web.Theme.Themes.EventHub.Components.PageAlerts |
|||
@inject IBrandingProvider BrandingProvider |
|||
@inject IPageLayout PageLayout |
|||
@{ |
|||
Layout = null; |
|||
var containerClass = ViewBag.FluidLayout == true ? "container-fluid" : "container"; //TODO: Better and type-safe options |
|||
|
|||
var pageTitle = ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title; //TODO: Discard to get from Title |
|||
|
|||
if (PageLayout.Content.Title != null) |
|||
{ |
|||
if (!string.IsNullOrWhiteSpace(pageTitle)) |
|||
{ |
|||
pageTitle = " | " + pageTitle; |
|||
} |
|||
|
|||
pageTitle = PageLayout.Content.Title + pageTitle; |
|||
} |
|||
|
|||
var rtl = CultureHelper.IsRtl ? "rtl" : string.Empty; |
|||
} |
|||
|
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="@CultureInfo.CurrentCulture.Name" dir="@rtl"> |
|||
<head> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.First, StandardLayouts.Empty) |
|||
|
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
|
|||
<title>@pageTitle</title> |
|||
@if (ViewBag.Description != null) |
|||
{ |
|||
<meta name="description" content="@ViewBag.Description" /> |
|||
} |
|||
<abp-style-bundle name="@EventHubThemeBundles.Styles.Global" /> |
|||
|
|||
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent)) |
|||
|
|||
@await RenderSectionAsync("styles", false) |
|||
|
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Empty) |
|||
</head> |
|||
<body class="abp-empty-layout @rtl"> |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.First, StandardLayouts.Empty) |
|||
|
|||
<div class="@containerClass"> |
|||
@(await Component.InvokeAsync<PageAlertsViewComponent>()) |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Empty) |
|||
@RenderBody() |
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Empty) |
|||
</div> |
|||
|
|||
<abp-script-bundle name="@EventHubThemeBundles.Scripts.Global" /> |
|||
|
|||
<script src="~/Abp/ApplicationConfigurationScript"></script> |
|||
<script src="~/Abp/ServiceProxyScript"></script> |
|||
|
|||
@await RenderSectionAsync("scripts", false) |
|||
|
|||
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent)) |
|||
|
|||
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Empty) |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,4 @@ |
|||
@using System.Globalization |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@ -0,0 +1,39 @@ |
|||
using System.Threading.Tasks; |
|||
using EventHub.Web.Theme.Themes.EventHub.Components.Toolbar.LanguageSwitch; |
|||
using EventHub.Web.Theme.Themes.EventHub.Components.Toolbar.UserMenu; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace EventHub.Web.Theme.Toolbars |
|||
{ |
|||
public class EventHubThemeMainTopToolbarContributor : IToolbarContributor |
|||
{ |
|||
public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context) |
|||
{ |
|||
if (context.Toolbar.Name != StandardToolbars.Main) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (!(context.Theme is EventHubTheme)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var languageProvider = context.ServiceProvider.GetRequiredService<ILanguageProvider>(); |
|||
|
|||
var languages = await languageProvider.GetLanguagesAsync(); |
|||
if (languages.Count > 1) |
|||
{ |
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitchViewComponent))); |
|||
} |
|||
|
|||
if (context.ServiceProvider.GetRequiredService<ICurrentUser>().IsAuthenticated) |
|||
{ |
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(UserMenuViewComponent))); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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,90 @@ |
|||
|
|||
#main-navbar-tools a.dropdown-toggle { |
|||
text-decoration: none; |
|||
color: #fff; |
|||
} |
|||
|
|||
.navbar .dropdown-submenu { |
|||
position: relative; |
|||
} |
|||
.navbar .dropdown-menu { |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
.navbar .dropdown-menu a { |
|||
font-size: .9em; |
|||
padding: 10px 15px; |
|||
display: block; |
|||
min-width: 210px; |
|||
text-align: left; |
|||
border-radius: 0.25rem; |
|||
min-height: 44px; |
|||
} |
|||
.navbar .dropdown-submenu a::after { |
|||
transform: rotate(-90deg); |
|||
position: absolute; |
|||
right: 16px; |
|||
top: 18px; |
|||
} |
|||
.navbar .dropdown-submenu .dropdown-menu { |
|||
top: 0; |
|||
left: 100%; |
|||
} |
|||
|
|||
.card-header .btn { |
|||
padding: 2px 6px; |
|||
} |
|||
.card-header h5 { |
|||
margin: 0; |
|||
} |
|||
.container > .card { |
|||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; |
|||
} |
|||
|
|||
@media screen and (min-width: 768px) { |
|||
.navbar .dropdown:hover > .dropdown-menu { |
|||
display: block; |
|||
} |
|||
|
|||
.navbar .dropdown-submenu:hover > .dropdown-menu { |
|||
display: block; |
|||
} |
|||
} |
|||
.input-validation-error { |
|||
border-color: #dc3545; |
|||
} |
|||
.field-validation-error { |
|||
font-size: 0.8em; |
|||
} |
|||
|
|||
.dataTables_scrollBody { |
|||
min-height: 248px; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_info { |
|||
padding-top: 11px; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
div.dataTables_wrapper div.dataTables_length label { |
|||
padding-top: 10px; |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
.rtl .dropdown-menu-right { |
|||
right: auto; |
|||
left: 0; |
|||
} |
|||
|
|||
.rtl .dropdown-menu-right a { |
|||
text-align: right; |
|||
} |
|||
|
|||
.rtl .navbar .dropdown-menu a { |
|||
text-align: right; |
|||
} |
|||
.rtl .navbar .dropdown-submenu .dropdown-menu { |
|||
top: 0; |
|||
left: auto; |
|||
right: 100%; |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
$(function () { |
|||
$('.dropdown-menu a.dropdown-toggle').on('click', function (e) { |
|||
if (!$(this).next().hasClass('show')) { |
|||
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show"); |
|||
} |
|||
|
|||
var $subMenu = $(this).next(".dropdown-menu"); |
|||
$subMenu.toggleClass('show'); |
|||
|
|||
$(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function (e) { |
|||
$('.dropdown-submenu .show').removeClass("show"); |
|||
}); |
|||
|
|||
return false; |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue