From 4bf9ceba488a7e1c0e83849d9fe5a026f061753c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20=C3=87A=C4=9EDA=C5=9E?= Date: Sat, 17 Jan 2026 16:54:43 +0300 Subject: [PATCH] fixed build problem in several modules for MudBlazor --- ...etCore.Components.Web.Theming.MudBlazor.md | 271 ++++++++++++++++++ ...CoreComponentsWebThemingMudBlazorModule.cs | 15 +- .../AbpDynamicLayoutComponentOptions.cs | 19 ++ .../Bundling/AbpScripts.razor | 61 ++++ .../Bundling/AbpStyles.razor | 75 +++++ .../Bundling/IComponentBundleManager.cs | 11 + .../Components/DynamicLayoutComponent.razor | 7 + .../DynamicLayoutComponent.razor.cs | 10 + .../Components/LayoutHooks/LayoutHook.razor | 7 + .../LayoutHooks/LayoutHook.razor.cs | 43 +++ .../Components/PageHeader.razor | 65 ----- .../Components/PageHeader.razor.cs | 127 -------- .../Layout/PageHeader.razor | 65 +++++ .../Layout/PageHeader.razor.cs | 199 +++++++++++++ .../Layout/PageHeaderOptions.cs | 8 + .../Layout/PageLayout.cs | 54 ++++ .../Layout/StandardLayouts.cs | 9 + .../PageToolbars/IPageToolbarContributor.cs | 8 + .../PageToolbars/IPageToolbarManager.cs | 8 + .../MudBlazorPageToolbarExtensions.cs | 34 --- .../PageToolbars/MudPageToolbarButton.razor | 13 - .../MudPageToolbarButton.razor.cs | 33 --- .../PageToolbars/PageToolbar.cs | 11 + .../PageToolbarContributionContext.cs | 20 ++ .../PageToolbars/PageToolbarContributor.cs | 8 + .../PageToolbarContributorList.cs | 7 + .../PageToolbars/PageToolbarDictionary.cs | 8 + .../PageToolbars/PageToolbarExtensions.cs | 69 +++++ .../PageToolbars/PageToolbarItem.cs | 25 ++ .../PageToolbars/PageToolbarItemList.cs | 8 + .../PageToolbars/PageToolbarManager.cs | 38 +++ .../SimplePageToolbarContributor.cs | 58 ++++ .../Routing/AbpRouterOptions.cs | 15 + .../Routing/RouterAssemblyList.cs | 9 + .../Theming/AbpThemingOptions.cs | 13 + .../Theming/DefaultThemeManager.cs | 34 +++ .../Theming/DefaultThemeSelector.cs | 36 +++ .../Theming/ITheme.cs | 8 + .../Theming/IThemeManager.cs | 6 + .../Theming/IThemeSelector.cs | 6 + .../Theming/ThemeDictionary.cs | 23 ++ .../Theming/ThemeExtensions.cs | 27 ++ .../Theming/ThemeInfo.cs | 24 ++ .../Theming/ThemeNameAttribute.cs | 23 ++ .../Toolbars/AbpToolbarOptions.cs | 15 + .../Toolbars/IToolbarConfigurationContext.cs | 27 ++ .../Toolbars/IToolbarContributor.cs | 8 + .../Toolbars/IToolbarManager.cs | 8 + .../Toolbars/StandardToolbars.cs | 6 + .../Toolbars/Toolbar.cs | 17 ++ .../Toolbars/ToolbarConfigurationContext.cs | 51 ++++ .../Toolbars/ToolbarItem.cs | 21 ++ .../Toolbars/ToolbarManager.cs | 38 +++ ...re.Components.Web.Theming.MudBlazor.csproj | 11 +- .../_Imports.razor | 6 - .../Volo.Abp.MudBlazorUI/BreadcrumbItem.cs | 17 ++ .../AbpMudExtensibleDataGrid.razor.cs | 24 +- .../Volo.Abp.FeatureManagement.slnx | 3 + .../Components/FeatureManagementModal.razor | 9 +- .../FeatureSettingManagementComponent.razor | 3 +- .../Volo.Abp.SettingManagement.slnx | 3 + ...pSettingManagementBlazorMudBlazorModule.cs | 3 +- .../EmailSettingGroupViewComponent.razor.cs | 16 +- .../SettingManagement.razor.cs | 4 +- .../Volo.Abp.TenantManagement.slnx | 3 + ...bpTenantManagementBlazorMudBlazorModule.cs | 3 +- .../TenantManagement.razor.cs | 9 +- 67 files changed, 1609 insertions(+), 314 deletions(-) create mode 100644 docs/en/Migration-Plan-Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.md create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpDynamicLayoutComponentOptions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpScripts.razor create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpStyles.razor create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/IComponentBundleManager.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeaderOptions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageLayout.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/StandardLayouts.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarContributor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarManager.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudBlazorPageToolbarExtensions.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbar.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributionContext.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributorList.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarDictionary.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarExtensions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItem.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItemList.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarManager.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/SimplePageToolbarContributor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/AbpRouterOptions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/RouterAssemblyList.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/AbpThemingOptions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeManager.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeSelector.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ITheme.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeManager.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeSelector.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeDictionary.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeExtensions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeInfo.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeNameAttribute.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/AbpToolbarOptions.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarConfigurationContext.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarContributor.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarManager.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/StandardToolbars.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/Toolbar.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarConfigurationContext.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarItem.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarManager.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/_Imports.razor create mode 100644 framework/src/Volo.Abp.MudBlazorUI/BreadcrumbItem.cs diff --git a/docs/en/Migration-Plan-Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.md b/docs/en/Migration-Plan-Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.md new file mode 100644 index 0000000000..4efbc379c4 --- /dev/null +++ b/docs/en/Migration-Plan-Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.md @@ -0,0 +1,271 @@ +# Implementation Plan: Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor + +## Overview +This document outlines the plan to implement all missing features from `Volo.Abp.AspNetCore.Components.Web.Theming` (Blazorise version) into `Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor` (MudBlazor version). + +## Current Status + +### ✅ Already Implemented +1. **PageHeader Component** (`Components/PageHeader.razor` + `.razor.cs`) +2. **MudPageToolbarButton** (`PageToolbars/MudPageToolbarButton.razor` + `.razor.cs`) +3. **MudBlazorPageToolbarExtensions** (`PageToolbars/MudBlazorPageToolbarExtensions.cs`) - Contains `AddMudButton` method +4. **Module Registration** (`AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs`) + +### ❌ Missing Features + +## Implementation Plan + +### Phase 1: Core Components (High Priority) + +#### 1.1 DynamicLayoutComponent +**Location:** `Components/DynamicLayoutComponent.razor` + `.razor.cs` + +**Description:** Renders dynamic components configured in `AbpDynamicLayoutComponentOptions`. + +**Implementation:** +- Copy `DynamicLayoutComponent.razor` from Blazorise version (no UI-specific code, should work as-is) +- Copy `DynamicLayoutComponent.razor.cs` from Blazorise version (no UI-specific code, should work as-is) +- These components are UI-agnostic and can be directly copied + +**Files to Create:** +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor` +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor.cs` + +**Dependencies:** None (uses base `AbpAspNetCoreComponentsWebThemingModule`) + +--- + +#### 1.2 LayoutHook Component +**Location:** `Components/LayoutHooks/LayoutHook.razor` + `.razor.cs` + +**Description:** Renders layout hooks that allow injecting components at specific points in layouts. + +**Implementation:** +- Copy `LayoutHook.razor` from Blazorise version (no UI-specific code, should work as-is) +- Copy `LayoutHook.razor.cs` from Blazorise version (no UI-specific code, should work as-is) +- These components are UI-agnostic and can be directly copied + +**Files to Create:** +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor` +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor.cs` + +**Dependencies:** None (uses base `AbpAspNetCoreComponentsWeb.Theming` infrastructure) + +--- + +### Phase 2: Bundling Components (High Priority) + +#### 2.1 AbpStyles Component +**Location:** `Bundling/AbpStyles.razor` + +**Description:** Renders CSS stylesheets with support for prerendering and WebAssembly. + +**Implementation:** +- Copy `AbpStyles.razor` from Blazorise version +- This component is UI-agnostic and can be directly copied +- Handles: + - Prerendering support + - WebAssembly style file handling + - Bundle management via `IComponentBundleManager` + +**Files to Create:** +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpStyles.razor` + +**Dependencies:** +- `IComponentBundleManager` (from base `Volo.Abp.AspNetCore.Components.Web.Theming`) + +--- + +#### 2.2 AbpScripts Component +**Location:** `Bundling/AbpScripts.razor` + +**Description:** Renders JavaScript files with support for prerendering and WebAssembly. + +**Implementation:** +- Copy `AbpScripts.razor` from Blazorise version +- This component is UI-agnostic and can be directly copied +- Handles: + - Prerendering support + - WebAssembly script file handling + - Bundle management via `IComponentBundleManager` + +**Files to Create:** +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpScripts.razor` + +**Dependencies:** +- `IComponentBundleManager` (from base `Volo.Abp.AspNetCore.Components.Web.Theming`) + +--- + +### Phase 3: PageToolbar Extensions (Medium Priority) + +#### 3.1 AddComponent Extension Methods +**Location:** `PageToolbars/MudBlazorPageToolbarExtensions.cs` + +**Description:** Add `AddComponent` extension methods to `PageToolbar` for adding custom components to toolbars. + +**Current State:** Only `AddMudButton` exists. + +**Implementation:** +- Add `AddComponent` generic method +- Add `AddComponent(Type componentType, ...)` non-generic method +- These methods should use `SimplePageToolbarContributor` (from base project) +- Follow the same pattern as Blazorise version but without UI-specific code + +**Files to Update:** +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudBlazorPageToolbarExtensions.cs` + +**Example Implementation:** +```csharp +public static PageToolbar AddComponent( + this PageToolbar toolbar, + Dictionary? arguments = null, + int order = 0, + string? requiredPolicyName = null) +{ + return toolbar.AddComponent( + typeof(TComponent), + arguments, + order, + requiredPolicyName + ); +} + +public static PageToolbar AddComponent( + this PageToolbar toolbar, + Type componentType, + Dictionary? arguments = null, + int order = 0, + string? requiredPolicyName = null) +{ + toolbar.Contributors.Add( + new SimplePageToolbarContributor( + componentType, + arguments, + order, + requiredPolicyName + ) + ); + + return toolbar; +} +``` + +**Dependencies:** +- `SimplePageToolbarContributor` (from base `Volo.Abp.AspNetCore.Components.Web.Theming`) + +--- + +### Phase 4: Module Configuration (Low Priority - Optional) + +#### 4.1 Module Service Configuration +**Location:** `AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs` + +**Description:** Configure any MudBlazor-specific services or options. + +**Current State:** Module is empty (only depends on base modules). + +**Implementation:** +- Review if any MudBlazor-specific configuration is needed +- Currently, the base `AbpAspNetCoreComponentsWebThemingModule` handles `AbpDynamicLayoutComponentOptions` +- May need to add MudBlazor-specific component registrations if required + +**Files to Update:** +- `framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs` + +**Note:** This may not be necessary if all configuration is handled in the base module or in theme-specific packages. + +--- + +## Implementation Notes + +### UI-Agnostic Components +The following components are **UI-agnostic** and can be copied directly from the Blazorise version: +- `DynamicLayoutComponent` +- `LayoutHook` +- `AbpStyles` +- `AbpScripts` + +These components don't use any Blazorise-specific UI components and rely only on: +- Base Blazor components (`ComponentBase`, `DynamicComponent`) +- ABP infrastructure (options, services) +- Standard .NET types + +### Infrastructure Already Available +The following infrastructure is already available in the base `Volo.Abp.AspNetCore.Components.Web.Theming` project and doesn't need to be reimplemented: +- `PageToolbar`, `PageToolbarManager`, `IPageToolbarManager` +- `PageToolbarContributor`, `SimplePageToolbarContributor` +- `PageToolbarItem`, `PageToolbarItemList` +- `PageLayout`, `PageHeaderOptions` +- `StandardLayouts` +- `AbpRouterOptions`, `RouterAssemblyList` +- `IThemeManager`, `ITheme`, theme infrastructure +- `ToolbarManager`, `Toolbar`, toolbar infrastructure +- `AbpDynamicLayoutComponentOptions` +- `IComponentBundleManager` + +### Testing Checklist +After implementing each phase, verify: +1. ✅ Components compile without errors +2. ✅ Components can be used in MudBlazor layouts +3. ✅ Bundling components work with prerendering +4. ✅ Layout hooks render correctly +5. ✅ Dynamic layout components render correctly +6. ✅ PageToolbar extensions work with MudBlazor components + +--- + +## Implementation Order + +1. **Phase 1** - Core Components (DynamicLayoutComponent, LayoutHook) + - These are foundational and used by layouts + - UI-agnostic, easy to implement + +2. **Phase 2** - Bundling Components (AbpStyles, AbpScripts) + - Required for proper asset loading + - UI-agnostic, easy to implement + +3. **Phase 3** - PageToolbar Extensions + - Enhances toolbar functionality + - Straightforward implementation + +4. **Phase 4** - Module Configuration + - Optional, only if needed + +--- + +## Files Summary + +### Files to Create (7 files) +1. `Components/DynamicLayoutComponent.razor` +2. `Components/DynamicLayoutComponent.razor.cs` +3. `Components/LayoutHooks/LayoutHook.razor` +4. `Components/LayoutHooks/LayoutHook.razor.cs` +5. `Bundling/AbpStyles.razor` +6. `Bundling/AbpScripts.razor` +7. (Optional) Update `PageToolbars/MudBlazorPageToolbarExtensions.cs` + +### Files to Update (1 file) +1. `PageToolbars/MudBlazorPageToolbarExtensions.cs` - Add `AddComponent` methods + +--- + +## Estimated Effort + +- **Phase 1:** ~30 minutes (copy files, verify) +- **Phase 2:** ~30 minutes (copy files, verify) +- **Phase 3:** ~20 minutes (add extension methods) +- **Phase 4:** ~10 minutes (if needed) + +**Total:** ~1.5 hours + +--- + +## Dependencies + +All required dependencies are already available: +- Base `Volo.Abp.AspNetCore.Components.Web.Theming` project +- `Volo.Abp.MudBlazorUI` project +- Standard Blazor infrastructure + +No new NuGet packages or project references are required. diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs index a273b69314..67ff2d3f87 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpAspNetCoreComponentsWebThemingMudBlazorModule.cs @@ -1,12 +1,21 @@ -using Volo.Abp.AspNetCore.Components.Web.Theming; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; using Volo.Abp.Modularity; using Volo.Abp.MudBlazorUI; +using Volo.Abp.UI.Navigation; namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor; [DependsOn( - typeof(AbpAspNetCoreComponentsWebThemingModule), - typeof(AbpMudBlazorUIModule) + typeof(AbpAspNetCoreComponentsWebModule), + typeof(AbpMudBlazorUIModule), + typeof(AbpUiNavigationModule), + typeof(AbpDddApplicationContractsModule), + typeof(AbpAuthorizationModule), + typeof(AbpGlobalFeaturesModule), + typeof(AbpFeaturesModule) )] public class AbpAspNetCoreComponentsWebThemingMudBlazorModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpDynamicLayoutComponentOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpDynamicLayoutComponentOptions.cs new file mode 100644 index 0000000000..ab6b516004 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/AbpDynamicLayoutComponentOptions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor; + +public class AbpDynamicLayoutComponentOptions +{ + /// + /// Used to define components that renders in the layout + /// + [NotNull] + public Dictionary?> Components { get; set; } + + public AbpDynamicLayoutComponentOptions() + { + Components = new Dictionary?>(); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpScripts.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpScripts.razor new file mode 100644 index 0000000000..436a22fc0e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpScripts.razor @@ -0,0 +1,61 @@ +@implements IDisposable +@inject IComponentBundleManager BundleManager +@inject PersistentComponentState ApplicationState +@if (ScriptFiles != null) +{ + foreach (var file in ScriptFiles) + { + var src = file; + if (!AppBasePath.IsNullOrWhiteSpace()) + { + src = AppBasePath.EnsureEndsWith('/') + file.RemovePreFix("/"); + } + + } +} + +@code { + + private const string PrerenderedKey = "abp_script_prerendered"; + + [Parameter] + public List? WebAssemblyScriptFiles { get; set; } + + [Parameter] + public string? BundleName { get; set; } + + [Parameter] + public string? AppBasePath { get; set; } + + private List? ScriptFiles { get; set; } + + private PersistingComponentStateSubscription _persistingSubscription; + + protected override async Task OnInitializedAsync() + { + _persistingSubscription = ApplicationState.RegisterOnPersisting(Callback); + if (!ApplicationState.TryTakeFromJson(PrerenderedKey, out _)) + { + // We are in prerendering mode + if (!BundleName.IsNullOrWhiteSpace()) + { + ScriptFiles = (await BundleManager.GetScriptBundleFilesAsync(BundleName!)).ToList(); + } + } + else + { + if (OperatingSystem.IsBrowser() && WebAssemblyScriptFiles != null) + { + ScriptFiles = WebAssemblyScriptFiles; + } + } + } + + private Task Callback() + { + ApplicationState.PersistAsJson(PrerenderedKey, PrerenderedKey); + return Task.CompletedTask; + } + + public void Dispose() => _persistingSubscription.Dispose(); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpStyles.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpStyles.razor new file mode 100644 index 0000000000..1c2ede488f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/AbpStyles.razor @@ -0,0 +1,75 @@ +@implements IDisposable +@inject IComponentBundleManager BundleManager +@inject PersistentComponentState ApplicationState +@if (StyleFiles != null) +{ + foreach (var file in StyleFiles) + { + var href = file; + if (!AppBasePath.IsNullOrWhiteSpace()) + { + href = AppBasePath.EnsureEndsWith('/') + file.RemovePreFix("/"); + } + + } +} + +@code { + + private const string PrerenderedKey = "abp_style_prerendered"; + + [Parameter] + public List? WebAssemblyStyleFiles { get; set; } + + [Parameter] + public string? BundleName { get; set; } + + [Parameter] + public string? AppBasePath { get; set; } + + private List? StyleFiles { get; set; } + + private PersistingComponentStateSubscription _persistingSubscription; + + protected override async Task OnInitializedAsync() + { + _persistingSubscription = ApplicationState.RegisterOnPersisting(Callback); + if (!ApplicationState.TryTakeFromJson>(PrerenderedKey, out var scriptFiles)) + { + // We are in prerendering mode + if (!BundleName.IsNullOrWhiteSpace()) + { + StyleFiles = (await BundleManager.GetStyleBundleFilesAsync(BundleName!)).ToList(); + } + } + else + { + StyleFiles = scriptFiles; + if (OperatingSystem.IsBrowser() && StyleFiles != null && WebAssemblyStyleFiles != null) + { + StyleFiles.AddIfNotContains(WebAssemblyStyleFiles); + } + } + } + + private bool _hasRemoveServerStyle = false; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (!_hasRemoveServerStyle && OperatingSystem.IsBrowser() && WebAssemblyStyleFiles != null) + { + _hasRemoveServerStyle = true; + await Task.Delay(3000); + StyleFiles = WebAssemblyStyleFiles; + StateHasChanged(); + } + } + + private Task Callback() + { + ApplicationState.PersistAsJson(PrerenderedKey, StyleFiles); + return Task.CompletedTask; + } + + public void Dispose() => _persistingSubscription.Dispose(); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/IComponentBundleManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/IComponentBundleManager.cs new file mode 100644 index 0000000000..8fe8aa710f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Bundling/IComponentBundleManager.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Bundling; + +public interface IComponentBundleManager +{ + Task> GetStyleBundleFilesAsync(string bundleName); + + Task> GetScriptBundleFilesAsync(string bundleName); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor new file mode 100644 index 0000000000..7119f6a54c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor @@ -0,0 +1,7 @@ +@if (AbpDynamicLayoutComponentOptions.Value.Components.Any()) +{ + foreach (var (componentType, parameters) in AbpDynamicLayoutComponentOptions.Value.Components) + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor.cs new file mode 100644 index 0000000000..5b9ba2bb66 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/DynamicLayoutComponent.razor.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components; + +public partial class DynamicLayoutComponent : ComponentBase +{ + [Inject] + protected IOptions AbpDynamicLayoutComponentOptions { get; set; } = default!; +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor new file mode 100644 index 0000000000..d7c5718d7b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor @@ -0,0 +1,7 @@ +@if (LayoutHookViewModel.Hooks.Any()) +{ + foreach (var hook in LayoutHookViewModel.Hooks) + { + + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor.cs new file mode 100644 index 0000000000..3cf75df16f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/LayoutHooks/LayoutHook.razor.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Options; +using Volo.Abp.Ui.LayoutHooks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components.LayoutHooks; + +public partial class LayoutHook : ComponentBase +{ + [Parameter] + public string Name { get; set; } = default!; + + [Parameter] + public string? Layout { get; set; } + + [Inject] + protected IOptions LayoutHookOptions { get; set; } = default!; + + protected LayoutHookViewModel LayoutHookViewModel { get; private set; } = default!; + + protected override Task OnInitializedAsync() + { + if (LayoutHookOptions.Value.Hooks.TryGetValue(Name, out var layoutHooks)) + { + layoutHooks = layoutHooks + .Where(x => IsComponentBase(x) && (string.IsNullOrWhiteSpace(x.Layout) || x.Layout == Layout)) + .ToList(); + } + + layoutHooks ??= new List(); + + LayoutHookViewModel = new LayoutHookViewModel(layoutHooks.ToArray(), Layout); + + return Task.CompletedTask; + } + + protected virtual bool IsComponentBase(LayoutHookInfo layoutHook) + { + return typeof(ComponentBase).IsAssignableFrom(layoutHook.ComponentType); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor deleted file mode 100644 index ff769fdfc7..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor +++ /dev/null @@ -1,65 +0,0 @@ -@using Microsoft.AspNetCore.Components.Web -@using Volo.Abp.Ui.Branding -@inject IBrandingProvider BrandingProvider -@using global::MudBlazor - - - @if (PageLayout.Title.IsNullOrEmpty()) - { - @BrandingProvider.AppName - } - else - { - @PageLayout.Title | @BrandingProvider.AppName - } - - @if (Options.Value.RenderPageTitle) - { - - - @PageLayout.Title - - - } - - @if (Options.Value.RenderBreadcrumbs && PageLayout.BreadcrumbItems.Any()) - { - - - @if (BreadcrumbShowHome) - { - - - - } - @foreach (var item in PageLayout.BreadcrumbItems) - { - - @item.Text - - } - - - } - - @if (Options.Value.RenderToolbar) - { - - - @if (Toolbar == null) - { - @ChildContent - } - - @foreach (var toolbarItemRender in ToolbarItemRenders) - { - - @toolbarItemRender - - } - - - } - - - diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor.cs deleted file mode 100644 index 379adc958c..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Components/PageHeader.razor.cs +++ /dev/null @@ -1,127 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Volo.Abp.AspNetCore.Components.Web.Theming.Layout; -using Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars; -using Volo.Abp.BlazoriseUI; - -namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Components; - -public partial class PageHeader : ComponentBase, IDisposable -{ - protected List ToolbarItemRenders { get; set; } - - [Inject] - public IPageToolbarManager PageToolbarManager { get; set; } = default!; - - [Inject] - public PageLayout PageLayout { get; private set; } = default!; - - [Inject] - public IOptions Options { get; set; } = default!; - - [Parameter] - public string? Title { get => PageLayout.Title; set => PageLayout.Title = value; } - - [Parameter] - public bool BreadcrumbShowHome { get; set; } = true; - - [Parameter] - public bool BreadcrumbShowCurrent { get; set; } = true; - - [Parameter] - public RenderFragment ChildContent { get; set; } = default!; - - [Parameter] - public List BreadcrumbItems - { - get => PageLayout.BreadcrumbItems.ToList(); - set - { - PageLayout.BreadcrumbItems.Clear(); - if (value != null) - { - foreach (var item in value) - { - PageLayout.BreadcrumbItems.Add(item); - } - } - } - } - - [Parameter] - public PageToolbar? Toolbar { get; set; } - - public PageHeader() - { - ToolbarItemRenders = new List(); - } - - protected async override Task OnParametersSetAsync() - { - await base.OnParametersSetAsync(); - if (Toolbar != null) - { - var toolbarItems = await PageToolbarManager.GetItemsAsync(Toolbar); - - if (!ShouldRenderToolbarItems(toolbarItems)) - { - return; - } - - ToolbarItemRenders.Clear(); - - if (!Options.Value.RenderToolbar) - { - PageLayout.ToolbarItems.Clear(); - foreach (var item in toolbarItems) - { - PageLayout.ToolbarItems.Add(item); - } - return; - } - - foreach (var item in toolbarItems) - { - var sequence = 0; - ToolbarItemRenders.Add(builder => - { - builder.OpenComponent(sequence, item.ComponentType); - if (item.Arguments != null) - { - foreach (var argument in item.Arguments) - { - sequence++; - builder.AddAttribute(sequence, argument.Key, argument.Value); - } - } - builder.CloseComponent(); - }); - } - } - } - - protected virtual bool ShouldRenderToolbarItems(PageToolbarItem[] items) - { - if (items.Length != PageLayout.ToolbarItems.Count) - { - return true; - } - - return items.Where((t, i) => t.ComponentType != PageLayout.ToolbarItems[i].ComponentType).Any(); - } - - protected async override Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - } - - public void Dispose() - { - PageLayout.Reset(); - ToolbarItemRenders.Clear(); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor new file mode 100644 index 0000000000..64149f6869 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor @@ -0,0 +1,65 @@ +@using global::MudBlazor +@using Microsoft.Extensions.Options +@using Microsoft.AspNetCore.Components.Web +@using Volo.Abp.Ui.Branding + +@inject IOptions Options +@inject IBrandingProvider BrandingProvider + + + + @if (PageLayout.Title.IsNullOrEmpty()) + { + @BrandingProvider.AppName + } + else + { + @PageLayout.Title | @BrandingProvider.AppName + } + + @if(Options.Value.RenderPageTitle) + { + + @PageLayout.Title + + } + + @if (Options.Value.RenderBreadcrumbs && PageLayout.BreadcrumbItems.Any()) + { + + + + + @if (!string.IsNullOrEmpty(item.Icon)) + { + + } + @item.Text + + + + + + + + } + + @if(Options.Value.RenderToolbar) + { + + + @if (Toolbar == null) + { + @ChildContent + } + + @foreach (var toolbarItemRender in ToolbarItemRenders) + { + + @toolbarItemRender + + } + + + } + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor.cs new file mode 100644 index 0000000000..dbaa1eebde --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeader.razor.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using MudBlazor; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Layout; + +public partial class PageHeader : ComponentBase, IDisposable +{ + protected List ToolbarItemRenders { get; set; } + + private List _breadcrumbItems = new(); + + public IPageToolbarManager PageToolbarManager { get; set; } = default!; + + [Inject] + public PageLayout PageLayout { get; private set; } = default!; + + [Parameter] // TODO: Consider removing this property in future and use only PageLayout. + public string? Title { get => PageLayout.Title; set => PageLayout.Title = value; } + + [Parameter] + public bool BreadcrumbShowHome { get; set; } = true; + + [Parameter] + public bool BreadcrumbShowCurrent { get; set; } = true; + + [Parameter] + public RenderFragment ChildContent { get; set; } = default!; + + [Parameter] // TODO: Consider removing this property in future and use only PageLayout. + public List BreadcrumbItems { + get => PageLayout.BreadcrumbItems.ToList(); + set + { + PageLayout.BreadcrumbItems.Clear(); + foreach (var item in value) + { + PageLayout.BreadcrumbItems.Add(item); + } + } + } + + [Parameter] + public PageToolbar? Toolbar { get; set; } + + public PageHeader() + { + ToolbarItemRenders = new List(); + } + + protected override async Task OnParametersSetAsync() + { + await base.OnParametersSetAsync(); + + // Build MudBlazor breadcrumb items + BuildBreadcrumbItems(); + + if (Toolbar != null) + { + var toolbarItems = await PageToolbarManager.GetItemsAsync(Toolbar); + + if (!ShouldRenderToolbarItems(toolbarItems)) + { + return; + } + + ToolbarItemRenders.Clear(); + + if (!Options.Value.RenderToolbar) + { + PageLayout.ToolbarItems.Clear(); + foreach (var item in toolbarItems) + { + PageLayout.ToolbarItems.Add(item); + } + return; + } + + foreach (var item in toolbarItems) + { + var sequence = 0; + ToolbarItemRenders.Add(builder => + { + builder.OpenComponent(sequence, item.ComponentType); + if (item.Arguments != null) + { + foreach (var argument in item.Arguments) + { + sequence++; + builder.AddAttribute(sequence, argument.Key, argument.Value); + } + } + builder.CloseComponent(); + }); + } + } + } + + private void BuildBreadcrumbItems() + { + _breadcrumbItems.Clear(); + + if (BreadcrumbShowHome) + { + _breadcrumbItems.Add(new BreadcrumbItem(string.Empty, href: "/", icon: Icons.Material.Filled.Home)); + } + + var pageItems = PageLayout.BreadcrumbItems.ToList(); + for (var i = 0; i < pageItems.Count; i++) + { + var item = pageItems[i]; + var isLast = i == pageItems.Count - 1; + + // Convert Blazorise icon to MudBlazor icon if needed + var mudIcon = ConvertToMudIcon(item.Icon); + + // If BreadcrumbShowCurrent is false, skip the last item or make it non-clickable + if (isLast && !BreadcrumbShowCurrent) + { + continue; + } + + _breadcrumbItems.Add(new BreadcrumbItem( + item.Text, + href: isLast ? null : item.Href, + disabled: isLast, + icon: mudIcon)); + } + } + + /// + /// Converts Blazorise icon to MudBlazor icon. + /// You may need to expand this mapping based on the icons used in your application. + /// + private static string? ConvertToMudIcon(object? blazoriseIcon) + { + if (blazoriseIcon == null) + { + return null; + } + + // If it's already a string (MudBlazor icon format), return as-is + if (blazoriseIcon is string iconString) + { + return iconString; + } + + // Map common Blazorise icons to MudBlazor icons + // Add more mappings as needed for your application + var iconName = blazoriseIcon.ToString(); + + return iconName switch + { + "Home" => Icons.Material.Filled.Home, + "Edit" => Icons.Material.Filled.Edit, + "Delete" => Icons.Material.Filled.Delete, + "Add" => Icons.Material.Filled.Add, + "Search" => Icons.Material.Filled.Search, + "Settings" => Icons.Material.Filled.Settings, + "User" => Icons.Material.Filled.Person, + "Users" => Icons.Material.Filled.People, + "File" => Icons.Material.Filled.InsertDriveFile, + "Folder" => Icons.Material.Filled.Folder, + "Dashboard" => Icons.Material.Filled.Dashboard, + "List" => Icons.Material.Filled.List, + "Check" => Icons.Material.Filled.Check, + "Times" => Icons.Material.Filled.Close, + "Warning" => Icons.Material.Filled.Warning, + "Info" => Icons.Material.Filled.Info, + "Question" => Icons.Material.Filled.Help, + _ => null // Return null for unmapped icons + }; + } + + protected virtual bool ShouldRenderToolbarItems(PageToolbarItem[] items) + { + if (items.Length != PageLayout.ToolbarItems.Count) + { + return true; + } + + return items.Where((t, i) => t.ComponentType != PageLayout.ToolbarItems[i].ComponentType).Any(); + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + } + + public void Dispose() + { + PageLayout.Reset(); + ToolbarItemRenders.Clear(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeaderOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeaderOptions.cs new file mode 100644 index 0000000000..68492898d5 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageHeaderOptions.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Layout; + +public class PageHeaderOptions +{ + public bool RenderPageTitle { get; set; } = true; + public bool RenderBreadcrumbs { get; set; } = true; + public bool RenderToolbar { get; set; } = true; +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageLayout.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageLayout.cs new file mode 100644 index 0000000000..de1ba5e35b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/PageLayout.cs @@ -0,0 +1,54 @@ +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using MudBlazor; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Layout; + +public class PageLayout : IScopedDependency, INotifyPropertyChanged +{ + private string? title; + + // TODO: Consider using this property for setting Page Title too. + public virtual string? Title { + get => title; + set { + title = value; + OnPropertyChanged(); + } + } + + private string? menuItemName; + + public string? MenuItemName { + get => menuItemName; + set + { + menuItemName = value; + OnPropertyChanged(); + } + } + + public bool ShowToolbar { get; set; } = true; + + public virtual ObservableCollection BreadcrumbItems { get; } = new(); + + public virtual ObservableCollection ToolbarItems { get; } = new(); + + public event PropertyChangedEventHandler? PropertyChanged; + + protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + public void Reset() + { + Title = string.Empty; + MenuItemName = string.Empty; + BreadcrumbItems.Clear(); + ToolbarItems.Clear(); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/StandardLayouts.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/StandardLayouts.cs new file mode 100644 index 0000000000..bc25f503bd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Layout/StandardLayouts.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Layout; + +public static class StandardLayouts +{ + public const string Application = "Application"; + public const string Account = "Account"; + public const string Public = "Public"; + public const string Empty = "Empty"; +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarContributor.cs new file mode 100644 index 0000000000..f1f5b230f4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarContributor.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public interface IPageToolbarContributor +{ + Task ContributeAsync(PageToolbarContributionContext context); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarManager.cs new file mode 100644 index 0000000000..58f5833249 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/IPageToolbarManager.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public interface IPageToolbarManager +{ + Task GetItemsAsync(PageToolbar toolbar); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudBlazorPageToolbarExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudBlazorPageToolbarExtensions.cs deleted file mode 100644 index 54327dd60a..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudBlazorPageToolbarExtensions.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars; - -namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; - -public static class MudBlazorPageToolbarExtensions -{ - public static PageToolbar AddMudButton( - this PageToolbar toolbar, - string text, - Func clicked, - object? icon = null, - int order = 0, - string? requiredPolicyName = null) - { - toolbar.AddComponent( - typeof(MudPageToolbarButton), - new Dictionary - { - { nameof(MudPageToolbarButton.Text), text }, - { nameof(MudPageToolbarButton.Disabled), false }, - { nameof(MudPageToolbarButton.Icon), icon }, - { nameof(MudPageToolbarButton.Clicked), clicked } - }, - order, - requiredPolicyName - ); - - return toolbar; - } -} - diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor deleted file mode 100644 index c882121561..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor +++ /dev/null @@ -1,13 +0,0 @@ -@using global::MudBlazor - - - @if (Icon is string iconString && !string.IsNullOrWhiteSpace(iconString)) - { - - } - @Text - - diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor.cs deleted file mode 100644 index 47ec248ae4..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/MudPageToolbarButton.razor.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; -using global::MudBlazor; - -namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; - -public partial class MudPageToolbarButton : ComponentBase -{ - [Parameter] - public string Text { get; set; } = string.Empty; - - [Parameter] - public bool Disabled { get; set; } - - [Parameter] - public object? Icon { get; set; } - - [Parameter] - public Func? Clicked { get; set; } - - private EventCallback OnClickCallback => EventCallback.Factory.Create(this, OnClickAsync); - - private async Task OnClickAsync(MouseEventArgs args) - { - if (Clicked != null && !Disabled) - { - await Clicked.Invoke(); - } - await Task.CompletedTask; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbar.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbar.cs new file mode 100644 index 0000000000..1f808816ab --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbar.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbar +{ + public PageToolbarContributorList Contributors { get; set; } + + public PageToolbar() + { + Contributors = new PageToolbarContributorList(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributionContext.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributionContext.cs new file mode 100644 index 0000000000..37f7677cf9 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributionContext.cs @@ -0,0 +1,20 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbarContributionContext +{ + [NotNull] + public IServiceProvider ServiceProvider { get; } + + [NotNull] + public PageToolbarItemList Items { get; } + + public PageToolbarContributionContext( + [NotNull] IServiceProvider serviceProvider) + { + ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); + Items = new PageToolbarItemList(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributor.cs new file mode 100644 index 0000000000..92fb22838e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributor.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public abstract class PageToolbarContributor : IPageToolbarContributor +{ + public abstract Task ContributeAsync(PageToolbarContributionContext context); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributorList.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributorList.cs new file mode 100644 index 0000000000..0723bbe571 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarContributorList.cs @@ -0,0 +1,7 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbarContributorList : List +{ +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarDictionary.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarDictionary.cs new file mode 100644 index 0000000000..2016008a5e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarDictionary.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbarDictionary : Dictionary +{ + +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarExtensions.cs new file mode 100644 index 0000000000..c96cfad11c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarExtensions.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using MudBlazor; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public static class PageToolbarExtensions +{ + public static PageToolbar AddComponent( + this PageToolbar toolbar, + Dictionary? arguments = null, + int order = 0, + string? requiredPolicyName = null) + { + return toolbar.AddComponent( + typeof(TComponent), + arguments, + order, + requiredPolicyName + ); + } + + public static PageToolbar AddComponent( + this PageToolbar toolbar, + Type componentType, + Dictionary? arguments = null, + int order = 0, + string? requiredPolicyName = null) + { + toolbar.Contributors.Add( + new SimplePageToolbarContributor( + componentType, + arguments, + order, + requiredPolicyName + ) + ); + + return toolbar; + } + + public static PageToolbar AddButton( + this PageToolbar toolbar, + string text, + Func clicked, + object? icon = null, + Color? color = null, + bool disabled = false, + int order = 0, + string? requiredPolicyName = null) + { + // TODO@MudBlazor: Implement ToolbarButton contributor + // toolbar.AddComponent( + // new Dictionary + // { + // { nameof(ToolbarButton.Color), color ?? Color.Primary}, + // { nameof(ToolbarButton.Text), text}, + // { nameof(ToolbarButton.Disabled), disabled}, + // { nameof(ToolbarButton.Icon), icon}, + // { nameof(ToolbarButton.Clicked),clicked}, + // }, + // order, + // requiredPolicyName + // ); + + return toolbar; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItem.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItem.cs new file mode 100644 index 0000000000..f5820599d4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItem.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbarItem +{ + [NotNull] + public Type ComponentType { get; } + + public Dictionary? Arguments { get; set; } + + public int Order { get; set; } + + public PageToolbarItem( + [NotNull] Type componentType, + Dictionary? arguments = null, + int order = 0) + { + ComponentType = Check.NotNull(componentType, nameof(componentType)); + Arguments = arguments; + Order = order; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItemList.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItemList.cs new file mode 100644 index 0000000000..761efa01ed --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarItemList.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbarItemList : List +{ + +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarManager.cs new file mode 100644 index 0000000000..24efd89e1b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/PageToolbarManager.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class PageToolbarManager : IPageToolbarManager, ITransientDependency +{ + protected IServiceScopeFactory ServiceScopeFactory { get; } + + public PageToolbarManager( + IServiceScopeFactory serviceScopeFactory) + { + ServiceScopeFactory = serviceScopeFactory; + } + + public virtual async Task GetItemsAsync(PageToolbar toolbar) + { + if (toolbar == null || !toolbar.Contributors.Any()) + { + return Array.Empty(); + } + + using (var scope = ServiceScopeFactory.CreateScope()) + { + var context = new PageToolbarContributionContext(scope.ServiceProvider); + + foreach (var contributor in toolbar.Contributors) + { + await contributor.ContributeAsync(context); + } + + return context.Items.OrderBy(i => i.Order).ToArray(); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/SimplePageToolbarContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/SimplePageToolbarContributor.cs new file mode 100644 index 0000000000..4b333e2b90 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/PageToolbars/SimplePageToolbarContributor.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.PageToolbars; + +public class SimplePageToolbarContributor : IPageToolbarContributor +{ + public Type ComponentType { get; } + + public Dictionary? Arguments { get; set; } + + public int Order { get; } + + public string? RequiredPolicyName { get; } + + private bool? _shouldAddComponent; + + public SimplePageToolbarContributor( + Type componentType, + Dictionary? arguments = null, + int order = 0, + string? requiredPolicyName = null) + { + ComponentType = componentType; + Arguments = arguments; + Order = order; + RequiredPolicyName = requiredPolicyName; + } + + public async Task ContributeAsync(PageToolbarContributionContext context) + { + if (await ShouldAddComponentAsync(context)) + { + context.Items.Add(new PageToolbarItem(ComponentType, Arguments, Order)); + } + } + + protected virtual async Task ShouldAddComponentAsync(PageToolbarContributionContext context) + { + if (_shouldAddComponent.HasValue) + { + return _shouldAddComponent.Value; + } + + if (RequiredPolicyName == null) + { + _shouldAddComponent = true; + return _shouldAddComponent.Value; + } + + var authorizationService = context.ServiceProvider.GetRequiredService(); + _shouldAddComponent = await authorizationService.IsGrantedAsync(RequiredPolicyName); + return _shouldAddComponent.Value; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/AbpRouterOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/AbpRouterOptions.cs new file mode 100644 index 0000000000..d0f8bb98b1 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/AbpRouterOptions.cs @@ -0,0 +1,15 @@ +using System.Reflection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Routing; + +public class AbpRouterOptions +{ + public Assembly AppAssembly { get; set; } = default!; + + public RouterAssemblyList AdditionalAssemblies { get; } + + public AbpRouterOptions() + { + AdditionalAssemblies = new RouterAssemblyList(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/RouterAssemblyList.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/RouterAssemblyList.cs new file mode 100644 index 0000000000..4d2dfa8be5 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Routing/RouterAssemblyList.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using System.Reflection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Routing; + +public class RouterAssemblyList : List +{ + +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/AbpThemingOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/AbpThemingOptions.cs new file mode 100644 index 0000000000..4fd7d8958c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/AbpThemingOptions.cs @@ -0,0 +1,13 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public class AbpThemingOptions +{ + public ThemeDictionary Themes { get; } + + public string? DefaultThemeName { get; set; } + + public AbpThemingOptions() + { + Themes = new ThemeDictionary(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeManager.cs new file mode 100644 index 0000000000..30bf198a9f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeManager.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public class DefaultThemeManager : IThemeManager, IScopedDependency, IServiceProviderAccessor +{ + public IServiceProvider ServiceProvider { get; } + public ITheme CurrentTheme => GetCurrentTheme(); + + private ITheme? _currentTheme; + + protected IThemeSelector ThemeSelector { get; } + + public DefaultThemeManager( + IServiceProvider serviceProvider, + IThemeSelector themeSelector) + { + ServiceProvider = serviceProvider; + ThemeSelector = themeSelector; + } + + protected virtual ITheme GetCurrentTheme() + { + if (_currentTheme != null) + { + return _currentTheme; + } + + _currentTheme = (ITheme)ServiceProvider.GetRequiredService(ThemeSelector.GetCurrentThemeInfo().ThemeType); + return _currentTheme; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeSelector.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeSelector.cs new file mode 100644 index 0000000000..18fa99744c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/DefaultThemeSelector.cs @@ -0,0 +1,36 @@ +using System.Linq; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public class DefaultThemeSelector : IThemeSelector, ITransientDependency +{ + protected AbpThemingOptions Options { get; } + + public DefaultThemeSelector(IOptions options) + { + Options = options.Value; + } + + public virtual ThemeInfo GetCurrentThemeInfo() + { + if (!Options.Themes.Any()) + { + throw new AbpException($"No theme registered! Use {nameof(AbpThemingOptions)} to register themes."); + } + + if (Options.DefaultThemeName == null) + { + return Options.Themes.Values.First(); + } + + var themeInfo = Options.Themes.Values.FirstOrDefault(t => t.Name == Options.DefaultThemeName); + if (themeInfo == null) + { + throw new AbpException("Default theme is configured but it's not found in the registered themes: " + Options.DefaultThemeName); + } + + return themeInfo; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ITheme.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ITheme.cs new file mode 100644 index 0000000000..270ff2c427 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ITheme.cs @@ -0,0 +1,8 @@ +using System; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public interface ITheme +{ + Type GetLayout(string name, bool fallbackToDefault = true); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeManager.cs new file mode 100644 index 0000000000..663ce4716c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeManager.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public interface IThemeManager +{ + ITheme CurrentTheme { get; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeSelector.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeSelector.cs new file mode 100644 index 0000000000..51809a6f54 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/IThemeSelector.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public interface IThemeSelector +{ + ThemeInfo GetCurrentThemeInfo(); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeDictionary.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeDictionary.cs new file mode 100644 index 0000000000..e2361c2c6a --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeDictionary.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public class ThemeDictionary : Dictionary +{ + public ThemeInfo Add() + where TTheme : ITheme + { + return Add(typeof(TTheme)); + } + + public ThemeInfo Add(Type themeType) + { + if (ContainsKey(themeType)) + { + throw new AbpException("This theme is already added before: " + themeType.AssemblyQualifiedName); + } + + return this[themeType] = new ThemeInfo(themeType); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeExtensions.cs new file mode 100644 index 0000000000..09798cecea --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeExtensions.cs @@ -0,0 +1,27 @@ +using System; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Layout; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public static class ThemeExtensions +{ + public static Type GetApplicationLayout(this ITheme theme, bool fallbackToDefault = true) + { + return theme.GetLayout(StandardLayouts.Application, fallbackToDefault); + } + + public static Type GetAccountLayout(this ITheme theme, bool fallbackToDefault = true) + { + return theme.GetLayout(StandardLayouts.Account, fallbackToDefault); + } + + public static Type GetPublicLayout(this ITheme theme, bool fallbackToDefault = true) + { + return theme.GetLayout(StandardLayouts.Public, fallbackToDefault); + } + + public static Type GetEmptyLayout(this ITheme theme, bool fallbackToDefault = true) + { + return theme.GetLayout(StandardLayouts.Empty, fallbackToDefault); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeInfo.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeInfo.cs new file mode 100644 index 0000000000..d9525cd758 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeInfo.cs @@ -0,0 +1,24 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +public class ThemeInfo +{ + public Type ThemeType { get; } + + public string Name { get; } + + public ThemeInfo([NotNull] Type themeType) + { + Check.NotNull(themeType, nameof(themeType)); + + if (!typeof(ITheme).IsAssignableFrom(themeType)) + { + throw new AbpException($"Given {nameof(themeType)} ({themeType.AssemblyQualifiedName}) should be type of {typeof(ITheme).AssemblyQualifiedName}"); + } + + ThemeType = themeType; + Name = ThemeNameAttribute.GetName(themeType); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeNameAttribute.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeNameAttribute.cs new file mode 100644 index 0000000000..fc85e1e5cd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Theming/ThemeNameAttribute.cs @@ -0,0 +1,23 @@ +using System; +using System.Linq; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Theming; + +[AttributeUsage(AttributeTargets.Class)] +public class ThemeNameAttribute : Attribute +{ + public string Name { get; set; } + + public ThemeNameAttribute(string name) + { + Name = name; + } + + public static string GetName(Type themeType) + { + return themeType + .GetCustomAttributes(true) + .OfType() + .FirstOrDefault()?.Name ?? themeType.Name; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/AbpToolbarOptions.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/AbpToolbarOptions.cs new file mode 100644 index 0000000000..e096cebbc2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/AbpToolbarOptions.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public class AbpToolbarOptions +{ + [NotNull] + public List Contributors { get; } + + public AbpToolbarOptions() + { + Contributors = new List(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarConfigurationContext.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarConfigurationContext.cs new file mode 100644 index 0000000000..b019b269d8 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarConfigurationContext.cs @@ -0,0 +1,27 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Localization; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public interface IToolbarConfigurationContext : IServiceProviderAccessor +{ + Toolbar Toolbar { get; } + + IAuthorizationService AuthorizationService { get; } + + IStringLocalizerFactory StringLocalizerFactory { get; } + + Task IsGrantedAsync(string policyName); + + IStringLocalizer? GetDefaultLocalizer(); + + [NotNull] + public IStringLocalizer GetLocalizer(); + + [NotNull] + public IStringLocalizer GetLocalizer(Type resourceType); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarContributor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarContributor.cs new file mode 100644 index 0000000000..973509464c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarContributor.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public interface IToolbarContributor +{ + Task ConfigureToolbarAsync(IToolbarConfigurationContext context); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarManager.cs new file mode 100644 index 0000000000..cb483092d9 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/IToolbarManager.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public interface IToolbarManager +{ + Task GetAsync(string name); +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/StandardToolbars.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/StandardToolbars.cs new file mode 100644 index 0000000000..c3443f7efd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/StandardToolbars.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public static class StandardToolbars +{ + public const string Main = "Main"; +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/Toolbar.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/Toolbar.cs new file mode 100644 index 0000000000..5a0d829124 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/Toolbar.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public class Toolbar +{ + public string Name { get; } + + public List Items { get; } + + public Toolbar([NotNull] string name) + { + Name = Check.NotNull(name, nameof(name)); + Items = new List(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarConfigurationContext.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarConfigurationContext.cs new file mode 100644 index 0000000000..1fdff594b0 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarConfigurationContext.cs @@ -0,0 +1,51 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public class ToolbarConfigurationContext : IToolbarConfigurationContext +{ + public IServiceProvider ServiceProvider { get; } + + private readonly IAbpLazyServiceProvider _lazyServiceProvider; + + public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService(); + + public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService(); + + public Toolbar Toolbar { get; } + + public ToolbarConfigurationContext(Toolbar toolbar, IServiceProvider serviceProvider) + { + Toolbar = toolbar; + ServiceProvider = serviceProvider; + _lazyServiceProvider = ServiceProvider.GetRequiredService(); + } + + public Task IsGrantedAsync(string policyName) + { + return AuthorizationService.IsGrantedAsync(policyName); + } + + public IStringLocalizer? GetDefaultLocalizer() + { + return StringLocalizerFactory.CreateDefaultOrNull(); + } + + [NotNull] + public IStringLocalizer GetLocalizer() + { + return StringLocalizerFactory.Create(); + } + + [NotNull] + public IStringLocalizer GetLocalizer(Type resourceType) + { + return StringLocalizerFactory.Create(resourceType); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarItem.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarItem.cs new file mode 100644 index 0000000000..31b2839cc6 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarItem.cs @@ -0,0 +1,21 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public class ToolbarItem +{ + public Type ComponentType { + get => _componentType; + set => _componentType = Check.NotNull(value, nameof(value)); + } + private Type _componentType = default!; + + public int Order { get; set; } + + public ToolbarItem([NotNull] Type componentType, int order = 0) + { + Order = order; + ComponentType = Check.NotNull(componentType, nameof(componentType)); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarManager.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarManager.cs new file mode 100644 index 0000000000..cfdfcfd1e7 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Toolbars/ToolbarManager.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Toolbars; + +public class ToolbarManager : IToolbarManager, ITransientDependency +{ + protected AbpToolbarOptions Options { get; } + protected IServiceProvider ServiceProvider { get; } + + public ToolbarManager( + IOptions options, + IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Options = options.Value; + } + + public async Task GetAsync(string name) + { + var toolbar = new Toolbar(name); + + using (var scope = ServiceProvider.CreateScope()) + { + var context = new ToolbarConfigurationContext(toolbar, scope.ServiceProvider); + + foreach (var contributor in Options.Contributors) + { + await contributor.ConfigureToolbarAsync(context); + } + } + + return toolbar; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.csproj b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.csproj index b934d1fcc5..77a85c612a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.csproj @@ -10,8 +10,17 @@ - + + + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/_Imports.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/_Imports.razor deleted file mode 100644 index 747f485d94..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor/_Imports.razor +++ /dev/null @@ -1,6 +0,0 @@ -@using MudBlazor -@using Volo.Abp.AspNetCore.Components.Web.Theming -@using Volo.Abp.AspNetCore.Components.Web.Theming.Layout -@using Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars -@using Volo.Abp.BlazoriseUI - diff --git a/framework/src/Volo.Abp.MudBlazorUI/BreadcrumbItem.cs b/framework/src/Volo.Abp.MudBlazorUI/BreadcrumbItem.cs new file mode 100644 index 0000000000..b6fa0d219c --- /dev/null +++ b/framework/src/Volo.Abp.MudBlazorUI/BreadcrumbItem.cs @@ -0,0 +1,17 @@ +namespace Volo.Abp.MudBlazorUI; + +public class BreadcrumbItem +{ + public string Text { get; set; } + + public object? Icon { get; set; } + + public string? Url { get; set; } + + public BreadcrumbItem(string text, string? url = null, object? icon = null) + { + Text = text; + Url = url; + Icon = icon; + } +} diff --git a/framework/src/Volo.Abp.MudBlazorUI/Components/AbpMudExtensibleDataGrid.razor.cs b/framework/src/Volo.Abp.MudBlazorUI/Components/AbpMudExtensibleDataGrid.razor.cs index 15afdfc47c..24f31436a5 100644 --- a/framework/src/Volo.Abp.MudBlazorUI/Components/AbpMudExtensibleDataGrid.razor.cs +++ b/framework/src/Volo.Abp.MudBlazorUI/Components/AbpMudExtensibleDataGrid.razor.cs @@ -71,30 +71,20 @@ public partial class AbpMudExtensibleDataGrid : ComponentBase return convertedValue; } - protected virtual object? GetPropertyValue(TItem? item, string propertyPath) + protected virtual object GetPropertyValue(TItem item, string propertyPath) { - if (item == null) - { - return null; - } + ArgumentNullException.ThrowIfNull(item); var properties = propertyPath.Split('.'); - object? value = item; + object value = item; foreach (var prop in properties) { - if (value == null) - { - return null; - } - - var propertyInfo = value.GetType().GetProperty(prop, BindingFlags.Public | BindingFlags.Instance); - if (propertyInfo == null) - { - return null; - } + var propertyInfo = value.GetType().GetProperty(prop, BindingFlags.Public | BindingFlags.Instance) + ?? throw new ArgumentException($"Property '{prop}' not found on type '{value.GetType().Name}'", nameof(propertyPath)); - value = propertyInfo.GetValue(value); + value = propertyInfo.GetValue(value) + ?? throw new InvalidOperationException($"Property '{prop}' returned null"); } return value; diff --git a/modules/feature-management/Volo.Abp.FeatureManagement.slnx b/modules/feature-management/Volo.Abp.FeatureManagement.slnx index f246fb78b0..8b504d625b 100644 --- a/modules/feature-management/Volo.Abp.FeatureManagement.slnx +++ b/modules/feature-management/Volo.Abp.FeatureManagement.slnx @@ -2,6 +2,9 @@ + + + diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureManagementModal.razor b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureManagementModal.razor index f76e8a9630..37cfea2e87 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureManagementModal.razor +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureManagementModal.razor @@ -1,3 +1,5 @@ +@using global::MudBlazor +@using JetBrains.Annotations @using Volo.Abp.Validation.StringValues @using Microsoft.Extensions.Localization @using MudBlazor @@ -33,7 +35,7 @@ @if (feature.Description != null) { @@ -66,9 +68,8 @@ @if (feature.ValueType is ToggleStringValueType) { - @if (feature.Description != null) { diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureSettingGroup/FeatureSettingManagementComponent.razor b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureSettingGroup/FeatureSettingManagementComponent.razor index 2c763e9660..bbc906af93 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureSettingGroup/FeatureSettingManagementComponent.razor +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor.MudBlazor/Components/FeatureSettingGroup/FeatureSettingManagementComponent.razor @@ -1,5 +1,4 @@ -@using MudBlazor -@using Volo.Abp.FeatureManagement.Localization +@using global::MudBlazor @inherits Volo.Abp.AspNetCore.Components.AbpComponentBase @if (Settings != null && Settings.HasManageHostFeaturesPermission) diff --git a/modules/setting-management/Volo.Abp.SettingManagement.slnx b/modules/setting-management/Volo.Abp.SettingManagement.slnx index f44b64c8e0..5b73c332f0 100644 --- a/modules/setting-management/Volo.Abp.SettingManagement.slnx +++ b/modules/setting-management/Volo.Abp.SettingManagement.slnx @@ -5,6 +5,9 @@ + + + diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/AbpSettingManagementBlazorMudBlazorModule.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/AbpSettingManagementBlazorMudBlazorModule.cs index ed57edea53..2e5f322047 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/AbpSettingManagementBlazorMudBlazorModule.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/AbpSettingManagementBlazorMudBlazorModule.cs @@ -1,13 +1,12 @@ using Localization.Resources.AbpUi; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor; -using Volo.Abp.AspNetCore.Components.Web.Theming.Routing; using Volo.Abp.Localization; using Volo.Abp.Mapperly; using Volo.Abp.Modularity; using Volo.Abp.SettingManagement.Blazor.MudBlazor.Menus; using Volo.Abp.SettingManagement.Blazor.MudBlazor.Settings; -using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Routing; using Volo.Abp.SettingManagement.Localization; using Volo.Abp.UI.Navigation; diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor.cs index 7bb2d548f6..9e15fad338 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/EmailSettingGroup/EmailSettingGroupViewComponent.razor.cs @@ -63,7 +63,13 @@ public partial class EmailSettingGroupViewComponent { try { - if (_emailFormRef != null && !await _emailFormRef.Validate()) + if (_emailFormRef == null) + { + return; + } + + await _emailFormRef.Validate(); + if (!_emailFormRef.IsValid) { return; } @@ -121,7 +127,13 @@ public partial class EmailSettingGroupViewComponent { try { - if (_testEmailFormRef != null && !await _testEmailFormRef.Validate()) + if (_testEmailFormRef == null) + { + return; + } + + await _testEmailFormRef.Validate(); + if (!_testEmailFormRef.IsValid) { return; } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/SettingManagement.razor.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/SettingManagement.razor.cs index a85d2433fe..6596709716 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/SettingManagement.razor.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.MudBlazor/Pages/SettingManagement/SettingManagement.razor.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; -using Volo.Abp.BlazoriseUI; +using Volo.Abp.MudBlazorUI; using Volo.Abp.SettingManagement.Localization; namespace Volo.Abp.SettingManagement.Blazor.MudBlazor.Pages.SettingManagement; @@ -28,7 +28,7 @@ public partial class SettingManagement protected List SettingItemRenders { get; set; } = new List(); protected string? SelectedGroup; - protected List BreadcrumbItems = new List(); + protected List BreadcrumbItems = new(); protected int _activeTabIndex = 0; diff --git a/modules/tenant-management/Volo.Abp.TenantManagement.slnx b/modules/tenant-management/Volo.Abp.TenantManagement.slnx index ee9677787f..e44ab4110a 100644 --- a/modules/tenant-management/Volo.Abp.TenantManagement.slnx +++ b/modules/tenant-management/Volo.Abp.TenantManagement.slnx @@ -2,6 +2,9 @@ + + + diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/AbpTenantManagementBlazorMudBlazorModule.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/AbpTenantManagementBlazorMudBlazorModule.cs index 2427eb0083..dfee56fd12 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/AbpTenantManagementBlazorMudBlazorModule.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/AbpTenantManagementBlazorMudBlazorModule.cs @@ -1,6 +1,5 @@ using Localization.Resources.AbpUi; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.AspNetCore.Components.Web.Theming.Routing; using Volo.Abp.Mapperly; using Volo.Abp.FeatureManagement.Blazor.MudBlazor; using Volo.Abp.FeatureManagement.Localization; @@ -9,7 +8,7 @@ using Volo.Abp.Modularity; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending.Modularity; using Volo.Abp.TenantManagement.Blazor.MudBlazor.Navigation; -using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Routing; using Volo.Abp.TenantManagement.Localization; using Volo.Abp.Threading; using Volo.Abp.UI.Navigation; diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/Pages/TenantManagement/TenantManagement.razor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/Pages/TenantManagement/TenantManagement.razor.cs index eafa1c2af1..1f164617d0 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/Pages/TenantManagement/TenantManagement.razor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor.MudBlazor/Pages/TenantManagement/TenantManagement.razor.cs @@ -143,10 +143,17 @@ public partial class TenantManagement protected override async Task CreateEntityAsync() { - if (_createFormRef != null && !await _createFormRef.Validate()) + if (_createFormRef == null) { return; } + + await _createFormRef.Validate(); + if (!_createFormRef.IsValid) + { + return; + } + await base.CreateEntityAsync(); }