Browse Source

Auto add styles/scripts of a used widget in the page #297

pull/1520/head
Halil İbrahim Kalkan 7 years ago
parent
commit
49bb6646a6
  1. 3
      docs/en/AspNetCore/Dashboards.md
  2. 84
      docs/en/AspNetCore/Widgets.md
  3. BIN
      docs/en/images/widget-basic-files.png
  4. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorCollectionExtensions.cs
  5. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
  6. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml
  7. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml
  8. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs
  9. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj
  10. 7
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo.Abp.AspNetCore.Mvc.UI.Widgets.csproj
  11. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs
  12. 9
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetResourcesViewModel.cs
  13. 21
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetScripts/Default.cshtml
  14. 31
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetScripts/WidgetScriptsViewComponent.cs
  15. 21
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetStyles/Default.cshtml
  16. 30
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetStyles/WidgetStylesViewComponent.cs
  17. 3
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/_ViewImports.cshtml
  18. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/IPageWidgetManager.cs
  19. 48
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/PageWidgetManager.cs
  20. 66
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/WidgetDefinition.cs
  21. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/WidgetRenderer.cs
  22. 24
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/WidgetResourceItem.cs

3
docs/en/AspNetCore/Dashboards.md

@ -0,0 +1,3 @@
# Dashboards
TODO

84
docs/en/AspNetCore/Widgets.md

@ -0,0 +1,84 @@
# Widgets
ABP provides a model and infrastructure to create **reusable widgets**. It relies on [ASP.NET Core's ViewComponent](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components) system, so any view component can be used as a widget. Widget system is especially useful when you want to;
* Define widgets in reusable **[modules](../Module-Development-Basics.md)**.
* Have **scripts & styles** for your widget.
* Create **[dashboards](Dashboards.md)** with widgets used in (widgets you've built yourself or defined by modules you are using).
* Co-operate widgets with **[authorization](../Authorization.md)** and **[bundling](Bundling-Minification.md)** systems.
## Basic Widget Definition
### Create a View Component
As the first step, create a regular ASP.NET Core View Component:
![widget-basic-files](../images/widget-basic-files.png)
**MySimpleWidgetViewComponent.cs**:
````csharp
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace DashboardDemo.Web.Pages.Components.MySimpleWidget
{
public class MySimpleWidgetViewComponent : AbpViewComponent
{
public IViewComponentResult Invoke()
{
return View();
}
}
}
````
**Default.cshtml**:
```xml
<div class="my-simple-widget">
<h2>My Simple Widget</h2>
<p>This is a simple widget!</p>
</div>
```
### Define the Widget
Second step is to define a widget using the `WidgetOptions` (in the `ConfigureServices` method of your Web module):
````csharp
Configure<WidgetOptions>(options =>
{
options.Widgets.Add(
new WidgetDefinition(
"MySimpleWidget", //Unique Widget name
typeof(MySimpleWidgetViewComponent) //Type of the ViewComponent
)
);
});
````
Widget name should be unique in the application.
*TODO: This is in development and will probably change!*
### Render the Widget
Whenever you want to render a widget, you can inject the `IWidgetRenderer` and use the `RenderAsync` method with the unique widget name.
````xml
@inject IWidgetRenderer WidgetRenderer
@await WidgetRenderer.RenderAsync(Component, "MySimpleWidget")
````
You could do the same with standard `Component.InvokeAsync` method. The main difference is that `IWidgetRenderer` uses the widget name defined before. The essential benefit of the `WidgetRenderer` comes when your widget has additional resources, like script and style files.
## Style & Script Dependencies
There are some challenges when your widget has script and style files;
* Any page uses the widget should also include the **its script & styles** files into the page.
* The page should also care about **depended libraries/files** of the widget.
ABP solves all these issues when you properly relate the resources with the widget. You don't care about dependencies of the widget.

BIN
docs/en/images/widget-basic-files.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorListExtensions.cs → framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleContributorCollectionExtensions.cs

@ -1,6 +1,6 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public static class BundleContributorListExtensions
public static class BundleContributorCollectionExtensions
{
public static void AddFiles(this BundleContributorCollection contributors, params string[] files)
{

8
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml

@ -9,6 +9,8 @@
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
@using Volo.Abp.MultiTenancy
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@ -39,6 +41,8 @@
@await RenderSectionAsync("styles", false)
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Account)
</head>
<body class="abp-account-layout">
@ -50,7 +54,7 @@
<abp-row>
<abp-column size-md="_4" offset-md="_4">
@if (MultiTenancyOptions.Value.IsEnabled &&
(TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true))
(TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true))
{
<div class="tenant-switch-box" style="background-color: #eee; margin-bottom: 20px; color: #000; padding: 10px; text-align: center;">
<span style="color: #666;">@MultiTenancyStringLocalizer["Tenant"]: </span>
@ -80,6 +84,8 @@
@await RenderSectionAsync("scripts", false)
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account)
</body>
</html>

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml

@ -6,6 +6,8 @@
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@ -41,6 +43,8 @@
<abp-style-bundle name="@BasicThemeBundles.Styles.Global" />
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
@await RenderSectionAsync("styles", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Application)
@ -63,6 +67,8 @@
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
@await RenderSectionAsync("scripts", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Application)

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml

@ -5,6 +5,8 @@
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@ -40,6 +42,8 @@
<abp-style-bundle name="@BasicThemeBundles.Styles.Global" />
@await Component.InvokeAsync(typeof(WidgetStylesViewComponent))
@await RenderSectionAsync("styles", false)
@await Component.InvokeLayoutHookAsync(LayoutHooks.Head.Last, StandardLayouts.Empty)
@ -59,6 +63,8 @@
@await RenderSectionAsync("scripts", false)
@await Component.InvokeAsync(typeof(WidgetScriptsViewComponent))
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Empty)
</body>
</html>

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs

@ -2,6 +2,7 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@ -9,7 +10,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared
{
[DependsOn(
typeof(AbpAspNetCoreMvcUiBootstrapModule),
typeof(AbpAspNetCoreMvcUiPackagesModule)
typeof(AbpAspNetCoreMvcUiPackagesModule),
typeof(AbpAspNetCoreMvcUiWidgetsModule)
)]
public class AbpAspNetCoreMvcUiThemeSharedModule : AbpModule
{

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj

@ -39,6 +39,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Packages\Volo.Abp.AspNetCore.Mvc.UI.Packages.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Widgets\Volo.Abp.AspNetCore.Mvc.UI.Widgets.csproj" />
</ItemGroup>
</Project>

7
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo.Abp.AspNetCore.Mvc.UI.Widgets.csproj

@ -10,7 +10,12 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bundling\Volo.Abp.AspNetCore.Mvc.UI.Bundling.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\UI\Widgets\Components\**\*.cshtml" />
<Content Remove="Volo\Abp\AspNetCore\Mvc\UI\Widgets\Components\**\*.cshtml" />
</ItemGroup>
</Project>

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/AbpAspNetCoreMvcUiWidgetsModule.cs

@ -1,13 +1,22 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets
{
[DependsOn(
typeof(AbpAspNetCoreMvcUiBootstrapModule)
)]
typeof(AbpAspNetCoreMvcUiBootstrapModule),
typeof(AbpAspNetCoreMvcUiBundlingModule)
)]
public class AbpAspNetCoreMvcUiWidgetsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<VirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiWidgetsModule>();
});
}
}
}

9
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetResourcesViewModel.cs

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components
{
public class WidgetResourcesViewModel
{
public IReadOnlyList<WidgetDefinition> Widgets { get; set; }
}
}

21
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetScripts/Default.cshtml

@ -0,0 +1,21 @@
@model Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetResourcesViewModel
@if (Model.Widgets.Any())
{
var resourceItems = Model.Widgets.SelectMany(w => w.Scripts).ToArray();
if (resourceItems.Any())
{
<abp-script-bundle>
@foreach (var resourceItem in resourceItems)
{
if (resourceItem.Src != null)
{
<abp-script src="@resourceItem.Src" />
}
else
{
<abp-script type="@resourceItem.Type" />
}
}
</abp-script-bundle>
}
}

31
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetScripts/WidgetScriptsViewComponent.cs

@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
{
public class WidgetScriptsViewComponent : AbpViewComponent
{
protected IPageWidgetManager PageWidgetManager { get; }
protected WidgetOptions Options { get; }
public WidgetScriptsViewComponent(
IPageWidgetManager pageWidgetManager,
IOptions<WidgetOptions> options)
{
PageWidgetManager = pageWidgetManager;
Options = options.Value;
}
public virtual IViewComponentResult Invoke()
{
return View(
"~/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetScripts/Default.cshtml",
new WidgetResourcesViewModel
{
Widgets = PageWidgetManager.GetAll()
}
);
}
}
}

21
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetStyles/Default.cshtml

@ -0,0 +1,21 @@
@model Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetResourcesViewModel
@if (Model.Widgets.Any())
{
var resourceItems = Model.Widgets.SelectMany(w => w.Styles).ToArray();
if (resourceItems.Any())
{
<abp-style-bundle>
@foreach (var resourceItem in resourceItems)
{
if (resourceItem.Src != null)
{
<abp-style src="@resourceItem.Src" />
}
else
{
<abp-style type="@resourceItem.Type" />
}
}
</abp-style-bundle>
}
}

30
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetStyles/WidgetStylesViewComponent.cs

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
{
public class WidgetStylesViewComponent : AbpViewComponent
{
protected IPageWidgetManager PageWidgetManager { get; }
protected WidgetOptions Options { get; }
public WidgetStylesViewComponent(
IPageWidgetManager pageWidgetManager,
IOptions<WidgetOptions> options)
{
PageWidgetManager = pageWidgetManager;
Options = options.Value;
}
public virtual IViewComponentResult Invoke()
{
return View(
"~/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/WidgetStyles/Default.cshtml",
new WidgetResourcesViewModel
{
Widgets = PageWidgetManager.GetAll()
}
);
}
}
}

3
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/Components/_ViewImports.cshtml

@ -0,0 +1,3 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling

11
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/IPageWidgetManager.cs

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets
{
public interface IPageWidgetManager
{
bool TryAdd(WidgetDefinition widget);
IReadOnlyList<WidgetDefinition> GetAll();
}
}

48
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/PageWidgetManager.cs

@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.AspNetCore.Http;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets
{
public class PageWidgetManager : IPageWidgetManager, IScopedDependency
{
public const string HttpContextItemName = "__AbpCurrentWidgets";
private readonly IHttpContextAccessor _httpContextAccessor;
public PageWidgetManager(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public bool TryAdd(WidgetDefinition widget)
{
return GetWidgetList()
.AddIfNotContains(widget);
}
private List<WidgetDefinition> GetWidgetList()
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
{
throw new AbpException($"{typeof(PageWidgetManager).AssemblyQualifiedName} should be used in a web request! Can not get IHttpContextAccessor.HttpContext.");
}
var widgets = httpContext.Items[HttpContextItemName] as List<WidgetDefinition>;
if (widgets == null)
{
widgets = new List<WidgetDefinition>();
httpContext.Items[HttpContextItemName] = widgets;
}
return widgets;
}
public IReadOnlyList<WidgetDefinition> GetAll()
{
return GetWidgetList().ToImmutableArray();
}
}
}

66
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/WidgetDefinition.cs

@ -32,27 +32,85 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets
public List<string> RequiredPermissions { get; set; }
public List<WidgetResourceItem> Styles { get; }
public List<WidgetResourceItem> Scripts { get; }
public WidgetDefinition(
[NotNull] string name,
[CanBeNull] ILocalizableString displayName,
[NotNull] Type viewComponentType)
[NotNull] Type viewComponentType,
[CanBeNull] ILocalizableString displayName = null)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name));
ViewComponentType = Check.NotNull(viewComponentType, nameof(viewComponentType));
DisplayName = displayName ?? new FixedLocalizableString(name);
RequiredPermissions = new List<string>();
Styles = new List<WidgetResourceItem>();
Scripts = new List<WidgetResourceItem>();
}
public WidgetDefinition AddRequiredPermission(string permissionName)
public WidgetDefinition WithPermission([NotNull] string permissionName)
{
Check.NotNullOrWhiteSpace(permissionName, nameof(permissionName));
RequiredPermissions.Add(permissionName);
return this;
}
public WidgetDefinition SetDefaultDimension(int width, int height)
public WidgetDefinition WithDefaultDimensions(int width, int height)
{
DefaultDimensions = new WidgetDimensions(width, height);
return this;
}
public WidgetDefinition WithStyles(params string[] files)
{
return WithResources(Styles, files);
}
public WidgetDefinition WithStyles(params Type[] bundleContributorTypes)
{
return WithResources(Styles, bundleContributorTypes);
}
public WidgetDefinition WithScripts(params string[] files)
{
return WithResources(Scripts, files);
}
public WidgetDefinition WithScripts(params Type[] bundleContributorTypes)
{
return WithResources(Scripts, bundleContributorTypes);
}
private WidgetDefinition WithResources(List<WidgetResourceItem> resourceItems, Type[] bundleContributorTypes)
{
if (bundleContributorTypes.IsNullOrEmpty())
{
return this;
}
foreach (var bundleContributorType in bundleContributorTypes)
{
resourceItems.Add(new WidgetResourceItem(bundleContributorType));
}
return this;
}
private WidgetDefinition WithResources(List<WidgetResourceItem> resourceItems, string[] files)
{
if (files.IsNullOrEmpty())
{
return this;
}
foreach (var file in files)
{
resourceItems.Add(new WidgetResourceItem(file));
}
return this;
}
}
}

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/WidgetRenderer.cs

@ -9,16 +9,18 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets
public class WidgetRenderer : IWidgetRenderer
{
private readonly WidgetOptions _widgetOptions;
private readonly IPageWidgetManager _pageWidgetManager;
public WidgetRenderer(IOptions<WidgetOptions> widgetOptions)
public WidgetRenderer(IOptions<WidgetOptions> widgetOptions, IPageWidgetManager pageWidgetManager)
{
_pageWidgetManager = pageWidgetManager;
_widgetOptions = widgetOptions.Value;
}
public async Task<IHtmlContent> RenderAsync(IViewComponentHelper componentHelper, string widgetName, object args = null)
{
var widget = _widgetOptions.Widgets.Single(w=>w.Name.Equals(widgetName));
_pageWidgetManager.TryAdd(widget);
return await componentHelper.InvokeAsync(widget.ViewComponentType, args ?? new object());
}
}

24
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Widgets/Volo/Abp/AspNetCore/Mvc/UI/Widgets/WidgetResourceItem.cs

@ -0,0 +1,24 @@
using System;
using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets
{
public class WidgetResourceItem
{
[CanBeNull]
public string Src { get; }
[CanBeNull]
public Type Type { get; }
public WidgetResourceItem([NotNull] string src)
{
Src = Check.NotNullOrWhiteSpace(src, nameof(src));
}
public WidgetResourceItem([NotNull] Type type)
{
Type = Check.NotNull(type, nameof(type));
}
}
}
Loading…
Cancel
Save