From d414a1d7377afa169f9a3371eefd0ce347e0ed9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20=C3=87A=C4=9EDA=C5=9E?= Date: Fri, 16 Jan 2026 10:09:56 +0300 Subject: [PATCH] created MudBlazor theme packages --- ...mponentsServerMudBlazorBasicThemeModule.cs | 45 ++++++++++ .../BlazorMudBlazorBasicThemeBundles.cs | 14 ++++ ...verMudBlazorBasicThemeScriptContributor.cs | 11 +++ ...rverMudBlazorBasicThemeStyleContributor.cs | 11 +++ .../MudBlazorBasicThemeToolbarContributor.cs | 19 +++++ .../Themes/Basic/LanguageSwitch.razor | 83 ++++++++++++++++++ .../Themes/Basic/LoginDisplay.razor | 45 ++++++++++ .../Themes/Basic/_Imports.razor | 4 + ...mponents.Server.MudBlazorBasicTheme.csproj | 19 +++++ ...eComponentsWebMudBlazorBasicThemeModule.cs | 24 ++++++ .../MudBlazorBasicTheme.cs | 34 ++++++++ .../Themes/Basic/Branding.razor | 4 + .../Themes/Basic/LoginDisplay.razor | 27 ++++++ .../Themes/Basic/MainLayout.razor | 52 ++++++++++++ .../Themes/Basic/NavMenu.razor | 33 ++++++++ .../Themes/Basic/NavMenu.razor.cs | 14 ++++ .../Themes/Basic/NavToolbar.razor | 56 +++++++++++++ .../Themes/Basic/NullLayout.razor | 21 +++++ .../Themes/Basic/_Imports.razor | 4 + ....Components.Web.MudBlazorBasicTheme.csproj | 14 ++++ .../wwwroot/themes/basic/main.css | 3 + ...ntsWebAssemblyMudBlazorBasicThemeModule.cs | 40 +++++++++ .../AuthenticationOptions.cs | 8 ++ .../MudBlazorBasicThemeToolbarContributor.cs | 19 +++++ .../Themes/Basic/LanguageSwitch.razor | 84 +++++++++++++++++++ .../Themes/Basic/LoginDisplay.razor | 79 +++++++++++++++++ .../Themes/Basic/_Imports.razor | 4 + ...nts.WebAssembly.MudBlazorBasicTheme.csproj | 17 ++++ 28 files changed, 788 insertions(+) create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/AbpAspNetCoreComponentsServerMudBlazorBasicThemeModule.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorMudBlazorBasicThemeBundles.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeScriptContributor.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeStyleContributor.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/_Imports.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.csproj create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/MudBlazorBasicTheme.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/Branding.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/MainLayout.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavToolbar.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NullLayout.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/_Imports.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.csproj create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/wwwroot/themes/basic/main.css create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebAssemblyMudBlazorBasicThemeModule.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AuthenticationOptions.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/_Imports.razor create mode 100644 modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme.csproj diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/AbpAspNetCoreComponentsServerMudBlazorBasicThemeModule.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/AbpAspNetCoreComponentsServerMudBlazorBasicThemeModule.cs new file mode 100644 index 0000000000..049d10e49d --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/AbpAspNetCoreComponentsServerMudBlazorBasicThemeModule.cs @@ -0,0 +1,45 @@ +using Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.Bundling; +using Volo.Abp.AspNetCore.Components.Server.Theming.MudBlazor; +using Volo.Abp.AspNetCore.Components.Server.Theming.MudBlazor.Bundling; +using Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme; + +[DependsOn( + typeof(AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule), + typeof(AbpAspNetCoreComponentsServerThemingMudBlazorModule) + )] +public class AbpAspNetCoreComponentsServerMudBlazorBasicThemeModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Contributors.Add(new MudBlazorBasicThemeToolbarContributor()); + }); + + Configure(options => + { + options + .StyleBundles + .Add(BlazorMudBlazorBasicThemeBundles.Styles.Global, bundle => + { + bundle + .AddBaseBundles(BlazorServerStandardBundles.Styles.Global) + .AddContributors(typeof(BlazorServerMudBlazorBasicThemeStyleContributor)); + }); + + options + .ScriptBundles + .Add(BlazorMudBlazorBasicThemeBundles.Scripts.Global, bundle => + { + bundle + .AddBaseBundles(BlazorServerStandardBundles.Scripts.Global) + .AddContributors(typeof(BlazorServerMudBlazorBasicThemeScriptContributor)); + }); + }); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorMudBlazorBasicThemeBundles.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorMudBlazorBasicThemeBundles.cs new file mode 100644 index 0000000000..8b1efca7ea --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorMudBlazorBasicThemeBundles.cs @@ -0,0 +1,14 @@ +namespace Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.Bundling; + +public static class BlazorMudBlazorBasicThemeBundles +{ + public static class Styles + { + public static string Global = "Blazor.MudBlazorBasicTheme.Global"; + } + + public static class Scripts + { + public static string Global = "Blazor.MudBlazorBasicTheme.Global"; + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeScriptContributor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeScriptContributor.cs new file mode 100644 index 0000000000..d4aea52413 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeScriptContributor.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.Bundling; + +public class BlazorServerMudBlazorBasicThemeScriptContributor : BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + // Add any theme-specific scripts here if needed + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeStyleContributor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeStyleContributor.cs new file mode 100644 index 0000000000..e717faf75c --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Bundling/BlazorServerMudBlazorBasicThemeStyleContributor.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.Bundling; + +public class BlazorServerMudBlazorBasicThemeStyleContributor : BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/themes/basic/main.css"); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs new file mode 100644 index 0000000000..b9f6447955 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; +using Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.Themes.Basic; + +namespace Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme; + +public class MudBlazorBasicThemeToolbarContributor : IToolbarContributor +{ + public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) + { + if (context.Toolbar.Name == StandardToolbars.Main) + { + context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay))); + } + + return Task.CompletedTask; + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor new file mode 100644 index 0000000000..62d7f8b9c7 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor @@ -0,0 +1,83 @@ +@using Volo.Abp.Localization +@using System.Globalization +@using System.Collections.Immutable +@using MudBlazor +@inject ILanguageProvider LanguageProvider +@inject IJSRuntime JsRuntime +@inject ICookieService CookieService + +@if (_otherLanguages != null && _otherLanguages.Any()) +{ + + @_currentLanguage.DisplayName + + @foreach (var language in _otherLanguages) + { + @language.DisplayName + } + +} + +@code { + private IReadOnlyList? _otherLanguages; + private LanguageInfo? _currentLanguage; + + protected override async Task OnInitializedAsync() + { + var selectedLanguageName = await JsRuntime.InvokeAsync( + "localStorage.getItem", + "Abp.SelectedLanguage" + ); + + var allLanguages = await LanguageProvider.GetLanguagesAsync(); + _otherLanguages = allLanguages; + + if (!_otherLanguages.Any()) + { + return; + } + + if (!selectedLanguageName.IsNullOrWhiteSpace()) + { + _currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName); + } + + if (_currentLanguage == null) + { + _currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name); + } + + if (_currentLanguage == null) + { + _currentLanguage = _otherLanguages.FirstOrDefault(); + } + + _otherLanguages = _otherLanguages.Where(l => l != _currentLanguage).ToImmutableList(); + } + + private async Task ChangeLanguageAsync(LanguageInfo language) + { + await JsRuntime.InvokeVoidAsync( + "localStorage.setItem", + "Abp.SelectedLanguage", + language.UiCultureName + ); + + await JsRuntime.InvokeVoidAsync( + "localStorage.setItem", + "Abp.IsRtl", + CultureInfo.GetCultureInfo(language.UiCultureName).TextInfo.IsRightToLeft + ); + + await CookieService.SetAsync( + ".AspNetCore.Culture", + $"c={language.CultureName}|uic={language.UiCultureName}", + new CookieOptions + { + Path = "/" + } + ); + + await JsRuntime.InvokeVoidAsync("location.reload"); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor new file mode 100644 index 0000000000..6dac37fb5f --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor @@ -0,0 +1,45 @@ +@namespace Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.Themes.Basic +@using Volo.Abp.Users +@using Volo.Abp.MultiTenancy +@using Microsoft.Extensions.Localization +@using global::Localization.Resources.AbpUi +@using MudBlazor +@inject ICurrentUser CurrentUser +@inject ICurrentTenant CurrentTenant +@inject IStringLocalizer L + + + + + @if (Menu != null) + { + @foreach (var menuItem in Menu.Items) + { + @menuItem.DisplayName + } + } + + @L["Logout"] + + + + @L["Login"] + + + +@code { + [Inject] protected NavigationManager Navigation { get; set; } = default!; + [Inject] protected IMenuManager MenuManager { get; set; } = default!; + + protected ApplicationMenu? Menu { get; set; } + + protected override async Task OnInitializedAsync() + { + Menu = await MenuManager.GetAsync(StandardMenus.User); + } + + protected void Logout() + { + Navigation.NavigateTo("/Account/Logout", forceLoad: true); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/_Imports.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/_Imports.razor new file mode 100644 index 0000000000..4e91324cd8 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Themes/Basic/_Imports.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Components.Web +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor +@using MudBlazor +@using Volo.Abp.MudBlazorUI diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.csproj b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.csproj new file mode 100644 index 0000000000..82741a876a --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Server.MudBlazorBasicTheme.csproj @@ -0,0 +1,19 @@ + + + + + + + net10.0 + + + + + + + + + + + + diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule.cs new file mode 100644 index 0000000000..4e841b7075 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule.cs @@ -0,0 +1,24 @@ +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor; +using Volo.Abp.AspNetCore.Components.Web.Theming.Theming; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme; + +[DependsOn( + typeof(AbpAspNetCoreComponentsWebThemingMudBlazorModule) +)] +public class AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Themes.Add(); + + if (options.DefaultThemeName == null) + { + options.DefaultThemeName = MudBlazorBasicTheme.Name; + } + }); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/MudBlazorBasicTheme.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/MudBlazorBasicTheme.cs new file mode 100644 index 0000000000..87692e8525 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/MudBlazorBasicTheme.cs @@ -0,0 +1,34 @@ +using Volo.Abp.AspNetCore.Components.Web.Theming.Theming; + +namespace Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme; + +public class MudBlazorBasicTheme : ITheme +{ + public static string Name = "MudBlazorBasic"; + + public string GetLayout(string name, bool fallbackToDefault = true) + { + switch (name) + { + case StandardLayouts.Application: + return "~/Themes/Basic/MainLayout"; + case StandardLayouts.Account: + return "~/Themes/Basic/MainLayout"; + case StandardLayouts.Empty: + return "~/Themes/Basic/NullLayout"; + default: + return fallbackToDefault ? "~/Themes/Basic/MainLayout" : null; + } + } + + public string GetStyle(string name, bool fallbackToDefault = true) + { + switch (name) + { + case StandardStyles.Global: + return "~/themes/basic/main.css"; + default: + return fallbackToDefault ? "~/themes/basic/main.css" : null; + } + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/Branding.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/Branding.razor new file mode 100644 index 0000000000..9877b84559 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/Branding.razor @@ -0,0 +1,4 @@ +@using Volo.Abp.Ui.Branding +@inject IBrandingProvider BrandingProvider + +@BrandingProvider.AppName diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor new file mode 100644 index 0000000000..7e896d5b1d --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor @@ -0,0 +1,27 @@ +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components +@using Volo.Abp.Users +@inject ICurrentUser CurrentUser + +@if (CurrentUser.IsAuthenticated) +{ + + @L["MyAccount"] + + @L["Logout"] + +} +else +{ + @L["Login"] +} + +@code { + [Inject] protected NavigationManager NavigationManager { get; set; } = default!; + [Inject] protected IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!; + + protected async Task Logout() + { + // TODO: Implement logout logic + NavigationManager.NavigateTo("/Account/Logout", forceLoad: true); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/MainLayout.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/MainLayout.razor new file mode 100644 index 0000000000..0b21ab7bfd --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/MainLayout.razor @@ -0,0 +1,52 @@ +@using Volo.Abp.Ui.LayoutHooks +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components.LayoutHooks +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components +@using Volo.Abp.AspNetCore.Components.Web.Theming.Layout +@inherits LayoutComponentBase + + + + + + + + + + + + + + + + + + + + + + + @Body + + + + + + + + + +@code { + private bool _drawerOpen = true; + + private void ToggleDrawer() + { + _drawerOpen = !_drawerOpen; + } +} + +@implements IDisposable diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor new file mode 100644 index 0000000000..bf11fd1e72 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor @@ -0,0 +1,33 @@ +@using Volo.Abp.UI.Navigation +@inject IMenuManager MenuManager + + + @foreach (var menuItem in MenuItems.Items) + { + @if (menuItem.Items.IsNullOrEmpty()) + { + + @if (!string.IsNullOrEmpty(menuItem.Icon)) + { + + } + @menuItem.DisplayName + + } + else + { + + @foreach (var childItem in menuItem.Items) + { + + @if (!string.IsNullOrEmpty(childItem.Icon)) + { + + } + @childItem.DisplayName + + } + + } + } + diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor.cs new file mode 100644 index 0000000000..ea109684c2 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavMenu.razor.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using Volo.Abp.UI.Navigation; + +namespace Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.Themes.Basic; + +public partial class NavMenu +{ + protected ApplicationMenu MenuItems { get; set; } = new(); + + protected override async Task OnInitializedAsync() + { + MenuItems = await MenuManager.GetMainMenuAsync(); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavToolbar.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavToolbar.razor new file mode 100644 index 0000000000..0b04c22dc7 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NavToolbar.razor @@ -0,0 +1,56 @@ +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars +@using Volo.Abp.AspNetCore.Components.Web.Security +@using System.Collections.Generic +@using System +@using Microsoft.AspNetCore.Components + +@implements IDisposable + +@foreach (var render in ToolbarItemRenders) +{ + @render +} + +@code { + [Inject] + private IToolbarManager ToolbarManager { get; set; } = default!; + + [Inject] + protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; } = default!; + + private List ToolbarItemRenders { get; set; } = new List(); + + protected async override Task OnInitializedAsync() + { + await GetToolbarItemRendersAsync(); + ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged; + } + + private async Task GetToolbarItemRendersAsync() + { + var toolbar = await ToolbarManager.GetAsync(StandardToolbars.Main); + + ToolbarItemRenders.Clear(); + + var sequence = 0; + foreach (var item in toolbar.Items) + { + ToolbarItemRenders.Add(builder => + { + builder.OpenComponent(sequence++, item.ComponentType); + builder.CloseComponent(); + }); + } + } + + private async void ApplicationConfigurationChanged() + { + await GetToolbarItemRendersAsync(); + await InvokeAsync(StateHasChanged); + } + + public void Dispose() + { + ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged; + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NullLayout.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NullLayout.razor new file mode 100644 index 0000000000..6cebcca35a --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/NullLayout.razor @@ -0,0 +1,21 @@ +@using Volo.Abp.Ui.LayoutHooks +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components.LayoutHooks +@using Volo.Abp.AspNetCore.Components.Web.Theming.Layout +@inherits LayoutComponentBase + + + + + + + + + + @Body + + + + + + + diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/_Imports.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/_Imports.razor new file mode 100644 index 0000000000..4e91324cd8 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Themes/Basic/_Imports.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Components.Web +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor +@using MudBlazor +@using Volo.Abp.MudBlazorUI diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.csproj b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.csproj new file mode 100644 index 0000000000..03c8c3477a --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.csproj @@ -0,0 +1,14 @@ + + + + + + + net10.0 + + + + + + + diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/wwwroot/themes/basic/main.css b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/wwwroot/themes/basic/main.css new file mode 100644 index 0000000000..03d1488842 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme/wwwroot/themes/basic/main.css @@ -0,0 +1,3 @@ +/* MudBlazor Basic Theme Styles */ + +/* Add any custom theme-specific styles here */ diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebAssemblyMudBlazorBasicThemeModule.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebAssemblyMudBlazorBasicThemeModule.cs new file mode 100644 index 0000000000..8eb9a14efc --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AbpAspNetCoreComponentsWebAssemblyMudBlazorBasicThemeModule.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Components.Web; +using Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Routing; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; +using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.MudBlazor; +using Volo.Abp.Http.Client.IdentityModel.WebAssembly; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme; + +[DependsOn( + typeof(AbpAspNetCoreComponentsWebMudBlazorBasicThemeModule), + typeof(AbpAspNetCoreComponentsWebAssemblyThemingMudBlazorModule), + typeof(AbpHttpClientIdentityModelWebAssemblyModule) + )] +public class AbpAspNetCoreComponentsWebAssemblyMudBlazorBasicThemeModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AdditionalAssemblies.Add(typeof(AbpAspNetCoreComponentsWebAssemblyMudBlazorBasicThemeModule).Assembly); + }); + + Configure(options => + { + options.Contributors.Add(new MudBlazorBasicThemeToolbarContributor()); + }); + + if (context.Services.ExecutePreConfiguredActions().IsBlazorWebApp) + { + Configure(options => + { + options.LoginUrl = "Account/Login"; + options.LogoutUrl = "Account/Logout"; + }); + } + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AuthenticationOptions.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AuthenticationOptions.cs new file mode 100644 index 0000000000..a8fe2ba00d --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/AuthenticationOptions.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme; + +public class AuthenticationOptions +{ + public string LoginUrl { get; set; } = "Account/Login"; + + public string LogoutUrl { get; set; } = "Account/Logout"; +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs new file mode 100644 index 0000000000..a6394bdb78 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/MudBlazorBasicThemeToolbarContributor.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; +using Volo.Abp.AspNetCore.Components.Web.MudBlazorBasicTheme.Themes.Basic; + +namespace Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme; + +public class MudBlazorBasicThemeToolbarContributor : IToolbarContributor +{ + public Task ConfigureToolbarAsync(IToolbarConfigurationContext context) + { + if (context.Toolbar.Name == StandardToolbars.Main) + { + context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginDisplay))); + } + + return Task.CompletedTask; + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor new file mode 100644 index 0000000000..dda55daa21 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LanguageSwitch.razor @@ -0,0 +1,84 @@ +@using Volo.Abp.Localization +@using System.Globalization +@using System.Collections.Immutable +@using Volo.Abp.AspNetCore.Components.Web +@using MudBlazor +@inject ILanguageProvider LanguageProvider +@inject IJSRuntime JsRuntime +@inject ICookieService CookieService + +@if (_otherLanguages != null && _otherLanguages.Any()) +{ + + @_currentLanguage.DisplayName + + @foreach (var language in _otherLanguages) + { + @language.DisplayName + } + +} + +@code { + private IReadOnlyList? _otherLanguages; + private LanguageInfo? _currentLanguage; + + protected override async Task OnInitializedAsync() + { + var selectedLanguageName = await JsRuntime.InvokeAsync( + "localStorage.getItem", + "Abp.SelectedLanguage" + ); + + var allLanguages = await LanguageProvider.GetLanguagesAsync(); + _otherLanguages = allLanguages; + + if (!_otherLanguages.Any()) + { + return; + } + + if (!selectedLanguageName.IsNullOrWhiteSpace()) + { + _currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName); + } + + if (_currentLanguage == null) + { + _currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name); + } + + if (_currentLanguage == null) + { + _currentLanguage = _otherLanguages.FirstOrDefault(); + } + + _otherLanguages = _otherLanguages.Where(l => l != _currentLanguage).ToImmutableList(); + } + + private async Task ChangeLanguageAsync(LanguageInfo language) + { + await JsRuntime.InvokeVoidAsync( + "localStorage.setItem", + "Abp.SelectedLanguage", + language.UiCultureName + ); + + await JsRuntime.InvokeVoidAsync( + "localStorage.setItem", + "Abp.IsRtl", + CultureInfo.GetCultureInfo(language.UiCultureName).TextInfo.IsRightToLeft + ); + + await CookieService.SetAsync( + ".AspNetCore.Culture", + $"c={language.CultureName}|uic={language.UiCultureName}", + new CookieOptions + { + Path = "/" + } + ); + + await JsRuntime.InvokeVoidAsync("location.reload"); + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor new file mode 100644 index 0000000000..ee3b2f531d --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/LoginDisplay.razor @@ -0,0 +1,79 @@ +@using Microsoft.Extensions.Localization +@using global::Localization.Resources.AbpUi +@using Microsoft.Extensions.Options +@using Volo.Abp.AspNetCore.Components.Web +@using Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme +@using MudBlazor +@inherits AbpComponentBase +@inject IJSRuntime JsRuntime +@inject NavigationManager Navigation +@inject IStringLocalizer UiLocalizer +@inject IOptions AuthenticationOptions +@inject IOptions AbpAspNetCoreComponentsWebOptions + + + + + @if (Menu != null) + { + @foreach (var menuItem in Menu.Items) + { + @menuItem.DisplayName + } + } + + @UiLocalizer["Logout"] + + + + @UiLocalizer["Login"] + + + +@code { + [Inject] protected IMenuManager MenuManager { get; set; } = default!; + [Inject] protected ApplicationConfigurationChangedService ApplicationConfigurationChangedService { get; set; } = default!; + + protected ApplicationMenu? Menu { get; set; } + + protected async override Task OnInitializedAsync() + { + Menu = await MenuManager.GetAsync(StandardMenus.User); + ApplicationConfigurationChangedService.Changed += ApplicationConfigurationChanged; + } + + private async void ApplicationConfigurationChanged() + { + Menu = await MenuManager.GetAsync(StandardMenus.User); + await InvokeAsync(StateHasChanged); + } + + public void Dispose() + { + ApplicationConfigurationChangedService.Changed -= ApplicationConfigurationChanged; + } + + private async Task NavigateToAsync(string? uri, string? target = null) + { + if (target == "_blank") + { + await JsRuntime.InvokeVoidAsync("open", uri, target); + } + else + { + Navigation.NavigateTo(uri); + } + } + + private void BeginSignOut() + { + if (AbpAspNetCoreComponentsWebOptions.Value.IsBlazorWebApp) + { + Navigation.NavigateTo(AuthenticationOptions.Value.LogoutUrl, forceLoad: true); + } + else + { + Navigation.NavigateToLogout(AuthenticationOptions.Value.LogoutUrl); + } + } +} diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/_Imports.razor b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/_Imports.razor new file mode 100644 index 0000000000..4e91324cd8 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Themes/Basic/_Imports.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Components.Web +@using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor +@using MudBlazor +@using Volo.Abp.MudBlazorUI diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme.csproj b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme.csproj new file mode 100644 index 0000000000..d895ce3b32 --- /dev/null +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme/Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme.csproj @@ -0,0 +1,17 @@ + + + + + + + net10.0 + Volo.Abp.AspNetCore.Components.WebAssembly.MudBlazorBasicTheme + + + + + + + + +