@ -1,2 +1,2 @@ |
|||
## abp.op |
|||
## abp.io |
|||
Source code of the official web site: https://abp.io |
|||
|
|||
@ -0,0 +1,174 @@ |
|||
# VoloDocs |
|||
|
|||
## 什么是VoloDocs? |
|||
|
|||
VoloDocs是一个跨平台的应用程序,帮助你简单的创建良好的文档与构建开发人员社区. 它借助Github集成简化了软件文档. 使用Github的强大功能进行版本控制,托管文档,并允许用户编译文档. |
|||
|
|||
## 主要功能 |
|||
|
|||
- 集成Github从仓库提供文档. |
|||
- 支持Markdown/HTML文档格式. |
|||
- 支持版本控制 (集成Github release). |
|||
- 支持多个项目. |
|||
- 允许用户在Github上编辑文档. |
|||
- 跨平台,可部署到Windows/Linux/macOS. |
|||
|
|||
## Github源码仓库 |
|||
|
|||
它是免费并且开源的. 你可以查看VoloDocs源码,我们也欢迎PR: |
|||
|
|||
https://github.com/abpframework/abp/tree/master/modules/docs |
|||
|
|||
## 下载 |
|||
|
|||
你可以在下面的链接下载VoloDocs release版: |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.win-x64.zip - **Windows 64 bit** |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.win-x86.zip - **Windows 32 bit** |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.osx-x64.zip - **MacOS** |
|||
|
|||
http://apps.abp.io/VoloDocs/VoloDocs.linux-x64.zip - **Linux** |
|||
|
|||
上面所有的release都是自包含运行时的部署文件. 包含所有的第三方依赖与.Net Core Runtime,所以你不需要安装任何.Net Core SDK/Runtime. |
|||
|
|||
## 目录结构 |
|||
|
|||
解压 `VoloDocs.*.zip` 文件, 你会得到一个 `Web` 文件夹和 `Migrator` 文件夹. `Web` 文件夹中包含网站文件, `Migrator` 文件夹中包含构建数据库的应用程序. 在发布网站之前需要创建数据库或将现有的数据库更新到最新迁移. 如果这是你第一次安装VoloDocs, `Migrator` 会创建一个新数据库. 如果是升级已有的VoloDocs则会将数据库升级到最新的迁移. 使用 `Migrator` 你需要在 `appsettings.json` 文件中更改 `ConnectionString`. 参阅下一节了解如何配置VoloDocs应用程序. |
|||
|
|||
## 逐步部署 |
|||
|
|||
- ### 数据库迁移 |
|||
|
|||
进入 `Migrator` 目录中创建或更新数据库. |
|||
|
|||
打开 `appsettings.json` 文件设置连接字符串,如果你不清楚如何编写连接字符串,可以查看 https://www.connectionstrings.com/. |
|||
|
|||
设置连接字符串后运行 `Migrate.bat` 如果是Linux或MacOS运行 `DotNet VoloDocs.Migrator.dll` 命令. |
|||
|
|||
- ### 配置网站 |
|||
|
|||
进入 `Web` 目录下的VoloDocs文件夹. 打开 `appsettings.json` 文件设置连接字符串(与 `Migrator` 的 `appsettings.json` 相同). 你也可以为网站设置你想要的 `title`,它会显示在网站的左上角. 做完这些现在可以发布网站了. |
|||
|
|||
- ### 部署网站 |
|||
|
|||
在上一步我们创建/更新了数据库(确保数据库链接字符串正确). |
|||
|
|||
- #### 部署到IIS |
|||
|
|||
- 移动 `Web` 文件夹到你的 `wwwroot ` 文件夹中. |
|||
- 重命名 `Web` 文件夹为 `VoloDocs` (现在我们有了 `C:\inetpub\wwwroot\VoloDocs`). |
|||
- 创建网站 `VoloDocs` 会自动创建相同名称的应用程序池. 打开 **应用程序池** 并双击 `VoloDocs` 应用程序池做以下设置 |
|||
- **.NET CLR 版本**: `无托管代码` |
|||
- **托管管道模式**: `集成` |
|||
|
|||
 |
|||
|
|||
|
|||
|
|||
- 如果发生发生发现错误,表示未在服务器安装托管捆绑包. 请参阅文档 [this document](https://docs.microsoft.com/aspnet/core/host-and-deploy/iis/#install-the-net-core-hosting-bundle) 了解如何安装或[下载托管捆绑包](https://www.microsoft.com/net/permalink/dotnetcore-current-windows-runtime-bundle-installer). |
|||
|
|||
``` |
|||
Handler "aspNetCore" has a bad module "AspNetCoreModuleV2" in its module list using IIS |
|||
``` |
|||
|
|||
- 关于托管VoloDocs的更多信息,请参阅 [在IIS上托管ASP.NET Core应用程序的微软官方文档](https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis). |
|||
|
|||
- #### 部署到Azure |
|||
|
|||
微软有一篇关于将ASP.NET Core应用程序部署到Azure App Service的文档. 我们建议你此[文档](https://docs.microsoft.com/en-us/azure/app-service/app-service-web-get-started-dotnet). |
|||
|
|||
- #### 使用命令行运行应用程序 |
|||
|
|||
你可以从命令行运行应用程序,进入 `VoloDocs\Web` 文件夹并运行 `VoloDocs.Web.exe`,如果是Linux或MacOS运行 `DotNet VoloDocs.Web.dll` 命令. |
|||
|
|||
- ### 首次运行 |
|||
|
|||
打开浏览器导航到你的网址. |
|||
|
|||
首次运行网站,我们需要创建一个项目. |
|||
|
|||
#### 创建项目 |
|||
|
|||
跳转到以下网址创建项目 |
|||
|
|||
- `http://<yourwebsite>/Account/Login?returnUrl=/Docs/Admin/Projects` |
|||
|
|||
##### 默认凭据 |
|||
|
|||
使用管理员身份登陆到管理后台,用户名密码如下: |
|||
|
|||
* **用户名**: `admin` |
|||
|
|||
* **密码**: `1q2w3E*` |
|||
|
|||
##### 示例项目的定义 |
|||
|
|||
以下是一个使用了Github源的示例项目信息. |
|||
|
|||
配置VoloDocs展示存储在Github仓库中ABP Framework的文档. |
|||
|
|||
这是ABP Framework文档在Github的链接: |
|||
|
|||
https://github.com/abpframework/abp/tree/master/docs/zh-Hans |
|||
|
|||
|
|||
|
|||
* **名称**: `ABP Framework` |
|||
|
|||
* **简称**: `abp` |
|||
|
|||
* **格式**: `markdown` |
|||
|
|||
* **默认文档名称**: `Index` |
|||
|
|||
* **文档导航名称**: `docs-nav.json` ([参见示例](https://github.com/abpframework/abp/blob/master/docs/zh-Hans/docs-nav.json)) |
|||
|
|||
* **最小版本**: *留空* *(隐藏之前的版本)* |
|||
|
|||
* **主网站网址**: `/` |
|||
|
|||
* **最新版本分支名称**: 留空 |
|||
|
|||
* **GitHub链接**: `https://github.com/abpframework/abp/tree/{version}/docs/zh-Hans/` |
|||
|
|||
* **GitHub访问令牌**: [参见如何创建Github访问令牌](#retrieving-github-access-token) |
|||
|
|||
* **GitHub用户名称**: [参见如何找到自己的Github用户名称](#learn-your-github-username) |
|||
|
|||
 |
|||
|
|||
##### 创建访问令牌 |
|||
|
|||
在Github页右上角找到 `Settings`,然后在左侧导航中点击 `Developer Settings`,在这里选择 `Personal access tokens`. 点击创建新token,输入名称与描述并勾选repo复选框. 如果已有访问令牌但已经忘记,可以选择[重新生成](https://github.com/settings/tokens/new). |
|||
|
|||
###### 创建仅授权访问公共仓库的token |
|||
|
|||
想要仅授权访问公共仓库,仅勾选 `public_repo` 就可以了,然后点击页面底部的 `Generate Token` 按钮完成操作. |
|||
|
|||
 |
|||
|
|||
###### 创建可访问私有仓库的token |
|||
|
|||
想要授权访问私有仓库,勾选 `repo` 下的所有选项. 然后点击页面底部的 `Generate Token` 按钮完成操作. |
|||
|
|||
 |
|||
|
|||
###### 查看你的Github用户名称 |
|||
|
|||
在Github页面右上角点击头像图片,"Signed in as ..." 后面就是你的用户名称 |
|||
|
|||
 |
|||
|
|||
|
|||
|
|||
保存项目后转到网站根地址,你会看到文档已经正常显示. |
|||
|
|||
`http://<yourwebsite>/documents` |
|||
|
|||
### 发现问题? |
|||
|
|||
如果你在安装,使用时遇到问题或者发现bug,请发起issues与我们联系: |
|||
|
|||
https://github.com/abpframework/abp/issues/new |
|||
@ -0,0 +1,33 @@ |
|||
# 领取驱动设计 |
|||
|
|||
## 什么是DDD? |
|||
|
|||
ABP框架提供了**基础设施**使基础**DDD**的开发更易实现. DDD在[维基百科中的定义](https://zh.wikipedia.org/wiki/%E5%9F%9F%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91)如下: |
|||
|
|||
> **领域驱动设计(DDD)** 是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法. 领域驱动设计的前提是: |
|||
> |
|||
> - 把项目的主要重点放在核心领域和领域逻辑上 |
|||
> - 把复杂的设计放在领域模型上 |
|||
> - 发起技术专家和领域专家之间的创造性协作,以迭代方式完善解决特定领域问题的概念模型 |
|||
|
|||
### 分层 |
|||
|
|||
ABP框架遵循DDD原则和模式去实现分层应用程序模型,该模型由四个基本层组成: |
|||
|
|||
- **表示层**: 为用户提供接口. 使用*应用层*实现与用户交互. |
|||
- **应用层**: 表示层与领域层的中介,编排业务对象执行特定的应用程序任务. 使用应用程序逻辑实现用例. |
|||
- **领域层**: 包含业务对象以及业务规则. 是应用程序的核心. |
|||
- **基础设施层**: 提供通用的技术功能,支持更高的层,主要使用第三方类库. |
|||
|
|||
## 内容 |
|||
|
|||
* **领域层** |
|||
* [实体与聚合根](Entities.md) |
|||
* 值对象 |
|||
* [仓储](Repositories.md) |
|||
* 领域服务 |
|||
* 规约 |
|||
* **应用层** |
|||
* [应用服务](Application-Services.md) |
|||
* [数据传输对象(DTO)](Data-Transfer-Objects.md) |
|||
* 工作单元 |
|||
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 153 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
@ -0,0 +1,25 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
|
|||
namespace Microsoft.AspNetCore.Builder |
|||
{ |
|||
public static class ApplicationBuilderAbpJwtTokenMiddlewareExtension |
|||
{ |
|||
public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app, string schema = JwtBearerDefaults.AuthenticationScheme) |
|||
{ |
|||
return app.Use(async (ctx, next) => |
|||
{ |
|||
if (ctx.User.Identity?.IsAuthenticated != true) |
|||
{ |
|||
var result = await ctx.AuthenticateAsync(schema); |
|||
if (result.Succeeded && result.Principal != null) |
|||
{ |
|||
ctx.User = result.Principal; |
|||
} |
|||
} |
|||
|
|||
await next(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.AspNetCore.Authentication.JwtBearer</AssemblyName> |
|||
<PackageId>Volo.Abp.AspNetCore.Authentication.JwtBearer</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Security; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Authentication.JwtBearer |
|||
{ |
|||
[DependsOn(typeof(AbpSecurityModule))] |
|||
public class AbpAspNetCoreAuthenticationJwtBearerModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Property)] |
|||
public class DynamicFormIgnore : Attribute |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:57333/", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Volo.Abp.AspNetCore.Mvc.UI.Dashboards": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "http://localhost:57343/" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Dashboards</AssemblyName> |
|||
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Dashboards</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<IsPackable>true</IsPackable> |
|||
<OutputType>Library</OutputType> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\UI\Dashboards\Components\**\*.cshtml" /> |
|||
<Content Remove="Volo\Abp\AspNetCore\Mvc\UI\Dashboards\Components\**\*.cshtml" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Content Remove="Volo\Abp\AspNetCore\Mvc\UI\Dashboards\_ViewImports.cshtml" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\UI\Dashboards\_ViewImports.cshtml" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Widgets\Volo.Abp.AspNetCore.Mvc.UI.Widgets.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bundling\Volo.Abp.AspNetCore.Mvc.UI.Bundling.csproj" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1,20 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcUiWidgetsModule) |
|||
)] |
|||
public class AbpAspNetCoreMvcUiDashboardsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<VirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiDashboardsModule>(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class AbpBasicDashboardScriptContributor : BundleContributor |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class AbpBasicDashboardStyleContributor : BundleContributor |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards.Components.Dashboard |
|||
{ |
|||
public class DashboardViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly DashboardOptions _dashboardOptions; |
|||
private readonly WidgetOptions _widgetOptions; |
|||
|
|||
public DashboardViewComponent(IOptions<DashboardOptions> dashboardOptions, IOptions<WidgetOptions> widgetOptions) |
|||
{ |
|||
_dashboardOptions = dashboardOptions.Value; |
|||
_widgetOptions = widgetOptions.Value; |
|||
} |
|||
|
|||
public IViewComponentResult Invoke(string dashboardName) |
|||
{ |
|||
var dashboard = _dashboardOptions.Dashboards.Single(d => d.Name.Equals(dashboardName)); |
|||
|
|||
var model = new DashboardViewModel(dashboard, _widgetOptions.Widgets); |
|||
|
|||
return View("~/Volo/Abp/AspNetCore/Mvc/UI/Dashboards/Components/Dashboard/Default.cshtml", model); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards.Components.Dashboard |
|||
{ |
|||
public class DashboardViewModel |
|||
{ |
|||
public DashboardDefinition Dashboard { get; set; } |
|||
|
|||
public List<WidgetDefinition> Widgets { get; set; } |
|||
|
|||
public DashboardViewModel(DashboardDefinition dashboard, List<WidgetDefinition> widgets) |
|||
{ |
|||
Dashboard = dashboard; |
|||
Widgets = widgets; |
|||
} |
|||
|
|||
public WidgetDefinition GetWidget(string name) |
|||
{ |
|||
return Widgets.Single(d => d.Name.Equals(name)); |
|||
} |
|||
|
|||
public async Task<bool> CheckPermissionsAsync(IAuthorizationService authorizationService, WidgetDefinition widget) |
|||
{ |
|||
foreach (var permission in widget.RequiredPermissions) |
|||
{ |
|||
if (!await authorizationService.IsGrantedAsync(permission)) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
@using Microsoft.AspNetCore.Authorization |
|||
@using Microsoft.Extensions.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
@inject IAuthorizationService AuthorizationService |
|||
@inject IWidgetRenderer WidgetRenderer |
|||
@inject IStringLocalizerFactory localizer |
|||
@model Volo.Abp.AspNetCore.Mvc.UI.Dashboards.Components.Dashboard.DashboardViewModel |
|||
@{ |
|||
} |
|||
|
|||
<abp-row> |
|||
@foreach (var widgetConfiguration in Model.Dashboard.AvailableWidgets) |
|||
{ |
|||
var widgetDefinition = Model.GetWidget(widgetConfiguration.WidgetName); |
|||
if (await Model.CheckPermissionsAsync(AuthorizationService, widgetDefinition)) |
|||
{ |
|||
widgetDefinition.DefaultDimensions = widgetConfiguration.Dimensions ?? widgetDefinition.DefaultDimensions ?? new WidgetDimensions(6, 4); |
|||
|
|||
<abp-column class="col-@(widgetDefinition.DefaultDimensions.Width) p-2" |
|||
style="height: @(widgetDefinition.DefaultDimensions.Height * 100)px"> |
|||
|
|||
@await WidgetRenderer.RenderAsync(Component, widgetDefinition.Name) |
|||
</abp-column> |
|||
} |
|||
} |
|||
</abp-row> |
|||
@ -0,0 +1,49 @@ |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class DashboardDefinition |
|||
{ |
|||
/// <summary>
|
|||
/// Unique name of the dashboard.
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public string Name { get; } |
|||
|
|||
/// <summary>
|
|||
/// A list of Widgets available for this dashboard.
|
|||
/// </summary>
|
|||
public List<DashboardWidgetConfiguration> AvailableWidgets { get; } |
|||
|
|||
/// <summary>
|
|||
/// Display name of the widget.
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public ILocalizableString DisplayName |
|||
{ |
|||
get => _displayName; |
|||
set => _displayName = Check.NotNull(value, nameof(value)); |
|||
} |
|||
private ILocalizableString _displayName; |
|||
|
|||
public DashboardDefinition( |
|||
[NotNull] string name, |
|||
[CanBeNull] ILocalizableString displayName) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
DisplayName = displayName ?? new FixedLocalizableString(name); |
|||
|
|||
AvailableWidgets = new List<DashboardWidgetConfiguration>(); |
|||
} |
|||
|
|||
public DashboardDefinition WithWidget(string widgetName, WidgetLocation location = null, WidgetDimensions dimensions = null) |
|||
{ |
|||
AvailableWidgets.Add( new DashboardWidgetConfiguration(widgetName, dimensions, location)); |
|||
|
|||
return this; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class DashboardOptions |
|||
{ |
|||
public List<DashboardDefinition> Dashboards { get; } |
|||
|
|||
public DashboardOptions() |
|||
{ |
|||
Dashboards = new List<DashboardDefinition>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Html; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Dashboards.Components.Dashboard; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class DashboardRenderer : IDashboardRenderer |
|||
{ |
|||
public async Task<IHtmlContent> RenderAsync(IViewComponentHelper componentHelper, object args = null) |
|||
{ |
|||
return await componentHelper.InvokeAsync(typeof(DashboardViewComponent), args ?? new object()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class DashboardWidgetConfiguration |
|||
{ |
|||
[NotNull] |
|||
public string WidgetName { get; } |
|||
|
|||
[CanBeNull] |
|||
public WidgetDimensions Dimensions { get; set; } |
|||
|
|||
[CanBeNull] |
|||
public WidgetLocation Location { get; set; } |
|||
|
|||
public DashboardWidgetConfiguration( |
|||
[NotNull] string widgetName, |
|||
[CanBeNull] WidgetDimensions dimensions = null, |
|||
[CanBeNull] WidgetLocation location = null |
|||
) |
|||
{ |
|||
WidgetName = Check.NotNullOrWhiteSpace(widgetName, nameof(widgetName)); |
|||
Dimensions = dimensions; |
|||
Location = location; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Html; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public interface IDashboardRenderer : ITransientDependency |
|||
{ |
|||
Task<IHtmlContent> RenderAsync(IViewComponentHelper componentHelper, object args = null); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Dashboards |
|||
{ |
|||
public class WidgetLocation |
|||
{ |
|||
public int X { get; set; } |
|||
|
|||
public int Y { get; set; } |
|||
|
|||
public WidgetLocation(int x, int y) |
|||
{ |
|||
X = x; |
|||
Y = y; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.AspNetCore.Mvc.UI.Widgets</AssemblyName> |
|||
<PackageId>Volo.Abp.AspNetCore.Mvc.UI.Widgets</PackageId> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap\Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcUiBootstrapModule) |
|||
)] |
|||
public class AbpAspNetCoreMvcUiWidgetsModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Html; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
{ |
|||
public interface IWidgetRenderer : ITransientDependency |
|||
{ |
|||
Task<IHtmlContent> RenderAsync(IViewComponentHelper componentHelper, string widgetName, object args = null); |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
{ |
|||
public class WidgetDefinition |
|||
{ |
|||
/// <summary>
|
|||
/// Unique name of the widget.
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public string Name { get; } |
|||
|
|||
/// <summary>
|
|||
/// Display name of the widget.
|
|||
/// </summary>
|
|||
[NotNull] |
|||
public ILocalizableString DisplayName |
|||
{ |
|||
get => _displayName; |
|||
set => _displayName = Check.NotNull(value, nameof(value)); |
|||
} |
|||
private ILocalizableString _displayName; |
|||
|
|||
[NotNull] |
|||
public Type ViewComponentType { get; } |
|||
|
|||
[CanBeNull] |
|||
public WidgetDimensions DefaultDimensions { get; set; } |
|||
|
|||
public List<string> RequiredPermissions { get; set; } |
|||
|
|||
public WidgetDefinition( |
|||
[NotNull] string name, |
|||
[CanBeNull] ILocalizableString displayName, |
|||
[NotNull] Type viewComponentType) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
ViewComponentType = Check.NotNull(viewComponentType, nameof(viewComponentType)); |
|||
DisplayName = displayName ?? new FixedLocalizableString(name); |
|||
RequiredPermissions = new List<string>(); |
|||
} |
|||
|
|||
public WidgetDefinition AddRequiredPermission(string permissionName) |
|||
{ |
|||
RequiredPermissions.Add(permissionName); |
|||
return this; |
|||
} |
|||
|
|||
public WidgetDefinition SetDefaultDimension(int width, int height) |
|||
{ |
|||
DefaultDimensions = new WidgetDimensions(width, height); |
|||
return this; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
{ |
|||
public class WidgetDimensions |
|||
{ |
|||
public int Width { get; } |
|||
|
|||
public int Height { get; } |
|||
|
|||
public WidgetDimensions(int width, int height) |
|||
{ |
|||
Width = width; |
|||
Height = height; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
{ |
|||
public class WidgetOptions |
|||
{ |
|||
public List<WidgetDefinition> Widgets { get; } |
|||
|
|||
public WidgetOptions() |
|||
{ |
|||
Widgets = new List<WidgetDefinition>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Html; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Options; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Widgets |
|||
{ |
|||
public class WidgetRenderer : IWidgetRenderer |
|||
{ |
|||
private readonly WidgetOptions _widgetOptions; |
|||
|
|||
public WidgetRenderer(IOptions<WidgetOptions> widgetOptions) |
|||
{ |
|||
_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)); |
|||
|
|||
return await componentHelper.InvokeAsync(widget.ViewComponentType, args ?? new object()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.ApplicationModels; |
|||
using Microsoft.AspNetCore.Mvc.Versioning; |
|||
using Volo.Abp.ApiVersioning; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.Conventions; |
|||
using Volo.Abp.AspNetCore.Mvc.Versioning; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class AbpApiVersioningExtensions |
|||
{ |
|||
public static IServiceCollection AddAbpApiVersioning(this IServiceCollection services, Action<ApiVersioningOptions> setupAction) |
|||
{ |
|||
services.AddTransient<IRequestedApiVersion, HttpContextRequestedApiVersion>(); |
|||
services.AddTransient<IApiControllerSpecification, AbpConventionalApiControllerSpecification>(); |
|||
|
|||
services.AddApiVersioning(setupAction); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static void ConfigureAbp(this ApiVersioningOptions options, AbpAspNetCoreMvcOptions mvcOptions) |
|||
{ |
|||
foreach (var setting in mvcOptions.ConventionalControllers.ConventionalControllerSettings) |
|||
{ |
|||
if (setting.ApiVersionConfigurer == null) |
|||
{ |
|||
ConfigureApiVersionsByConvention(options, setting); |
|||
} |
|||
else |
|||
{ |
|||
setting.ApiVersionConfigurer.Invoke(options); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void ConfigureApiVersionsByConvention(ApiVersioningOptions options, ConventionalControllerSetting setting) |
|||
{ |
|||
foreach (var controllerType in setting.ControllerTypes) |
|||
{ |
|||
var controllerBuilder = options.Conventions.Controller(controllerType); |
|||
|
|||
if (setting.ApiVersions.Any()) |
|||
{ |
|||
foreach (var apiVersion in setting.ApiVersions) |
|||
{ |
|||
controllerBuilder.HasApiVersion(apiVersion); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (!controllerType.IsDefined(typeof(ApiVersionAttribute), true)) |
|||
{ |
|||
controllerBuilder.IsApiVersionNeutral(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,61 +0,0 @@ |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Versioning; |
|||
using Volo.Abp.ApiVersioning; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.Conventions; |
|||
using Volo.Abp.AspNetCore.Mvc.Versioning; |
|||
|
|||
namespace Microsoft.Extensions.DependencyInjection |
|||
{ |
|||
public static class AbpApiVersioningOptionsExtensions |
|||
{ |
|||
public static void ConfigureAbp(this ApiVersioningOptions options, IServiceCollection services) |
|||
{ |
|||
//TODO: Use new builder will be released with Api Versioning 2.1 instead of reflection!
|
|||
|
|||
services.AddTransient<IRequestedApiVersion, HttpContextRequestedApiVersion>(); |
|||
|
|||
services.Configure<AbpAspNetCoreMvcOptions>(op => |
|||
{ |
|||
//TODO: Configuring api version should be done directly inside ConfigureAbp,
|
|||
//TODO: not in a callback that will be called by MVC later! For that, we immediately need to controllerAssemblySettings
|
|||
|
|||
foreach (var setting in op.ConventionalControllers.ConventionalControllerSettings) |
|||
{ |
|||
if (setting.ApiVersionConfigurer == null) |
|||
{ |
|||
ConfigureApiVersionsByConvention(options, setting); |
|||
} |
|||
else |
|||
{ |
|||
setting.ApiVersionConfigurer.Invoke(options); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
private static void ConfigureApiVersionsByConvention(ApiVersioningOptions options, ConventionalControllerSetting setting) |
|||
{ |
|||
foreach (var controllerType in setting.ControllerTypes) |
|||
{ |
|||
var controllerBuilder = options.Conventions.Controller(controllerType); |
|||
|
|||
if (setting.ApiVersions.Any()) |
|||
{ |
|||
foreach (var apiVersion in setting.ApiVersions) |
|||
{ |
|||
controllerBuilder.HasApiVersion(apiVersion); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (!controllerType.IsDefined(typeof(ApiVersionAttribute), true)) |
|||
{ |
|||
controllerBuilder.IsApiVersionNeutral(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Microsoft.AspNetCore.Mvc.ApplicationModels; |
|||
using Microsoft.Extensions.Options; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Conventions |
|||
{ |
|||
public class AbpConventionalApiControllerSpecification : IApiControllerSpecification |
|||
{ |
|||
private readonly AbpAspNetCoreMvcOptions _options; |
|||
|
|||
public AbpConventionalApiControllerSpecification(IOptions<AbpAspNetCoreMvcOptions> options) |
|||
{ |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public bool IsSatisfiedBy(ControllerModel controller) |
|||
{ |
|||
var configuration = _options |
|||
.ConventionalControllers |
|||
.ConventionalControllerSettings |
|||
.GetSettingOrNull(controller.ControllerType.AsType()); |
|||
|
|||
return configuration != null; |
|||
} |
|||
} |
|||
} |
|||