Browse Source

Merge branch 'rel-4.0' into dev

pull/6287/head
Halil İbrahim Kalkan 6 years ago
parent
commit
d9ed2643b6
  1. 4
      docs/en/Localization.md
  2. 2
      docs/en/Migration-Guides/Abp-4_0.md
  3. 2
      docs/en/UI/AspNetCore/Branding.md
  4. 2
      docs/en/UI/AspNetCore/Customization-User-Interface.md
  5. 12
      docs/en/UI/AspNetCore/Navigation-Menu.md
  6. 57
      docs/en/UI/Blazor/Basic-Theme.md
  7. 37
      docs/en/UI/Blazor/Branding.md
  8. 87
      docs/en/UI/Blazor/Customization-Overriding-Components.md
  9. 77
      docs/en/UI/Blazor/Localization.md
  10. 206
      docs/en/UI/Blazor/Navigation-Menu.md
  11. 3
      docs/en/UI/Blazor/Page-Alerts.md
  12. 62
      docs/en/UI/Blazor/Settings.md
  13. 206
      docs/en/UI/Blazor/Theming.md
  14. 74
      docs/en/UI/Blazor/Toolbars.md
  15. 16
      docs/en/docs-nav.json
  16. BIN
      docs/en/images/basic-theme-application-layout-blazor.png
  17. BIN
      docs/en/images/blazor-notification-bell-component.png
  18. BIN
      docs/en/images/bookstore-branding-blazor.png
  19. BIN
      docs/en/images/bookstore-logo-blazor.png
  20. 3
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/Branding.razor
  21. 4
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor
  22. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBrandingProvider.cs
  23. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameComponentBase.cs
  24. 2
      templates/module/angular/projects/dev-app/src/environments/environment.ts
  25. 6
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/EntityFrameworkCore/MyProjectNameHttpApiHostMigrationsDbContext.cs
  26. 382
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20201019021119_Initial.Designer.cs
  27. 212
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20201019021119_Initial.cs
  28. 380
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/MyProjectNameHttpApiHostMigrationsDbContextModelSnapshot.cs

4
docs/en/Localization.md

@ -162,8 +162,8 @@ Getting the localized text is pretty standard.
Just inject the `IStringLocalizer<TResource>` service and use it like shown below:
````C#
public class MyService
````csharp
public class MyService : ITransientDependency
{
private readonly IStringLocalizer<TestResource> _localizer;

2
docs/en/Migration-Guides/Abp-4_0.md

@ -2,7 +2,7 @@
This document introduces the breaking changes done in the ABP Framework 4.0 and explains how to fix your 3.x based solutions while upgrading to the ABP Framework 4.0.
> See this blog post (TODO: LINK) to learn what's new with the ABP Framework 4.0. This document only focuses on the breaking changes.
> See [the blog post](https://blog.abp.io/abp/ABP.IO-Platform-v4.0-RC-Has-Been-Released-based-on-.NET-5.0) to learn what's new with the ABP Framework 4.0. This document only focuses on the breaking changes.
## Overall

2
docs/en/UI/AspNetCore/Branding.md

@ -11,7 +11,7 @@ The screenshot below shows *MyProject* as the application name:
You can implement the `IBrandingProvider` interface or inherit from the `DefaultBrandingProvider` to set the application name:
````csharp
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace MyProject.Web

2
docs/en/UI/AspNetCore/Customization-User-Interface.md

@ -1,6 +1,6 @@
# ASP.NET Core (MVC / Razor Pages) User Interface Customization Guide
This document explains how to override the user interface of a depended [application module](../../Modules/Index.md) for ASP.NET Core MVC / Razor Page applications.
This document explains how to override the user interface of a depended [application module](../../Modules/Index.md) or [theme](Theming.md) for ASP.NET Core MVC / Razor Page applications.
## Overriding a Page

12
docs/en/UI/AspNetCore/Navigation-Menu.md

@ -13,6 +13,8 @@ So, ABP Framework **provides a menu infrastructure** where;
In order to add menu items (or manipulate the existing items) you need to create a class implementing the `IMenuContributor` interface.
> The [application startup template](../../Startup-Templates/Application.md) already contains an implementation of the `IMenuContributor`. So, you can add items inside that class instead of creating a new one.
**Example: Add a *CRM* menu item with *Customers* and *Orders* sub menu items**
```csharp
@ -66,6 +68,16 @@ Configure<AbpNavigationOptions>(options =>
});
````
This example uses some localization keys as display names those should be defined in the localization file:
````json
"Menu:CRM": "CRM",
"Menu:Orders": "Orders",
"Menu:Customers": "Customers"
````
See the [localization document](../../Localization.md) to learn more about the localization.
When you run the application, you will see the menu items added to the main menu:
![nav-main-menu](../../images/nav-main-menu.png)

57
docs/en/UI/Blazor/Basic-Theme.md

@ -0,0 +1,57 @@
# Blazor UI: Basic Theme
The Basic Theme is a theme implementation for the Blazor UI. It is a minimalist theme that doesn't add any styling on top of the plain [Bootstrap](https://getbootstrap.com/). You can take the Basic Theme as the **base theme** and build your own theme or styling on top of it. See the *Customization* section.
> If you are looking for a professional, enterprise ready theme, you can check the [Lepton Theme](https://commercial.abp.io/themes), which is a part of the [ABP Commercial](https://commercial.abp.io/).
> See the [Theming document](Theming.md) to learn about themes.
## Installation
**This theme is already installed** when you create a new solution using the [startup templates](../../Startup-Templates/Index.md). If you need to manually install it, follow the steps below:
* Install the [Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme) NuGet package to your web project.
* Add `AbpAspNetCoreComponentsWebAssemblyBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../Module-Development-Basics.md) in the your Blazor UI project.
* Use `Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic.App` as the root component of your application in the `ConfigureServices` method of your module:
````csharp
var builder = context.Services.GetSingletonInstance<WebAssemblyHostBuilder>();
builder.RootComponents.Add<App>("#ApplicationContainer");
````
`#ApplicationContainer` is a selector (like `<div id="ApplicationContainer">Loading...</div>`) in the `index.html`.
## The Layout
![basic-theme-application-layout](../../images/basic-theme-application-layout.png)
Application Layout implements the following parts, in addition to the common parts mentioned above;
* [Branding](Branding.md) Area
* Main [Menu](Navigation-Menu.md)
* Main [Toolbar](Toolbars.md) with Language Selection & User Menu
* [Page Alerts](Page-Alerts.md)
## Customization
You have two options two customize this theme:
### Overriding Styles / Components
In this approach, you continue to use the the theme as NuGet and NPM packages and customize the parts you need to. There are several ways to customize it;
#### Override the Styles
You can simply override the styles in the Global Styles file of your application.
#### Override the Components
See the [Customization / Overriding Components](Customization-Overriding-Components.md) to learn how you can replace components, customize and extend the user interface.
### Copy & Customize
You can download the [source code](https://github.com/abpframework/abp/tree/dev/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme) of the Basic Theme, copy the project content into your solution, re-arrange the package/module dependencies (see the Installation section above to understand how it was installed to the project) and freely customize the theme based on your application requirements.
## See Also
* [Theming](Theming.md)

37
docs/en/UI/Blazor/Branding.md

@ -0,0 +1,37 @@
# Blazor UI: Branding
## IBrandingProvider
`IBrandingProvider` is a simple interface that is used to show the application name and logo on the layout.
The screenshot below shows *MyProject* as the application name:
![branding-nobrand](../../images/branding-nobrand.png)
You can implement the `IBrandingProvider` interface or inherit from the `DefaultBrandingProvider` to set the application name:
````csharp
using Volo.Abp.DependencyInjection;
using Volo.Abp.Ui.Branding;
namespace MyCompanyName.MyProjectName.Blazor
{
[Dependency(ReplaceServices = true)]
public class MyProjectNameBrandingProvider : DefaultBrandingProvider
{
public override string AppName => "Book Store";
}
}
````
The result will be like shown below:
![branding-appname](../../images/branding-appname.png)
`IBrandingProvider` has the following properties:
* `AppName`: The application name.
* `LogoUrl`: A URL to show the application logo.
* `LogoReverseUrl`: A URL to show the application logo on a reverse color theme (dark, for example).
> **Tip**: `IBrandingProvider` is used in every page refresh. For a multi-tenant application, you can return a tenant specific application name to customize it per tenant.

87
docs/en/UI/Blazor/Customization-Overriding-Components.md

@ -1,3 +1,88 @@
# Blazor UI: Customization / Overriding Components
TODO
This document explains how to override the user interface of a depended [application module](../../Modules/Index.md) or [theme](Theming.md) for Blazor applications.
## Overriding a Razor Component
The ABP Framework, pre-built themes and modules define some **re-usable razor components and pages**. These pages and components can be replaced by your application or module.
> Since pages are just the razor components, the same principle is valid for pages too.
### Example: Replacing the Branding Area
The screenshot below was taken from the [Basic Theme](Basic-Theme.md) comes with the application startup template.
![bookstore-brand-area-highlighted](../../images/bookstore-brand-area-highlighted.png)
The [Basic Theme](Basic-Theme.md) defines some razor components for the layout. For example, the highlighted area with the red rectangle above is called *Branding* component. You probably want to customize this component by adding your **own application logo**. Let's see how to do it.
First, create your logo and place under a folder in your web application. We used `wwwroot/bookstore-logo.png` path:
![bookstore-logo-blazor](../../images/bookstore-logo-blazor.png)
The next step is to create a razor component, like `MyBlazor.razor`, in your application:
![bookstore-logo-blazor](../../images/bookstore-branding-blazor.png)
The content of the `MyBlazor.razor` is shown below:
````html
@using Volo.Abp.DependencyInjection
@using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
@inherits Branding
@attribute [ExposeServices(typeof(Branding))]
@attribute [Dependency(ReplaceServices = true)]
<a href="/">
<img src="bookstore-logo.png" width="250" height="60"/>
</a>
````
Let's explain the code:
* `@inherits Branding` line inherits the Branding component defined by the [Basic Theme](Basic-Theme.md) (in the `Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic` namespace).
* `@attribute [ExposeServices(typeof(Branding))]` registers this service (component) to [dependency injection](../../Dependency-Injection.md) for the `Branding` service (component).
* `@attribute [Dependency(ReplaceServices = true)]` replaces the `Branding` class (component) with this new `MyBranding` class (component).
* The rest of the code is related the content and styling of the component.
Now, you can run the application to see the result:
![bookstore-added-logo](D:/Github/abp/docs/en/images/bookstore-added-logo.png)
> Since the component inherits from the component it is replacing, you can use all the non-private fields/properties/methods of the base component in the derived component.
### Example: Replacing with the Code Behind File
If you prefer to use code-behind file for the C# code of your component, you can use the attributes in the C# side.
**MyBlazor.razor**
````html
@using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic
@inherits Branding
<a href="/">
<img src="bookstore-logo.png" width="250" height="60"/>
</a>
````
**MyBlazor.razor.cs**
````csharp
using Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic;
using Volo.Abp.DependencyInjection;
namespace MyProject.Blazor.Components
{
[ExposeServices(typeof(Branding))]
[Dependency(ReplaceServices = true)]
public partial class MyBranding
{
}
}
````
## Theming
The [Theming](Theming.md) system allows you to build your own theme. You can create your theme from scratch or get the [Basic Theme](Basic-Theme.md) and change however you like.
## Manipulating the Bundles

77
docs/en/UI/Blazor/Localization.md

@ -1,3 +1,78 @@
# Blazor UI: Localization
Blazor applications can reuse the same `IStringLocalizer<T>` service that is explained in the [localization document](../../Localization.md). All the localization resources and texts available in the server side are usable in the Blazor application.
Blazor applications can reuse the same `IStringLocalizer<T>` service that is explained in the [localization document](../../Localization.md).
All the localization resources and texts available in the server side are usable in the Blazor application.
## IStringLocalizer
`IStringLocalizer<T>` (`T` is the localization resource class) can be injected in any service or component to use the localization service.
### Razor Components
Use `@inject IStringLocalizer<MyProjectNameResource>` to use the localization in a razor component.
**Example: Localization in a Razor Component**
````csharp
@page "/"
@using MyCompanyName.MyProjectName.Localization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<MyProjectNameResource> L
<h1>
@L["LongWelcomeMessage"]
</h1>
````
> `L` is a name that we love and use as the name of a `IStringLocalizer` instance, while you can give any name.
#### The AbpComponentBase
`AbpComponentBase` is a useful base class that you can derive the components from. It has some useful properties/methods you typically need in a component.
The `AbpComponentBase` already defines a base `L` property (of type `IStringLocalizer`). It only requires to set the resource type (in the constructor of the derived class). If you created your application from the ABP's application startup template, then you should have a *YourProjectComponentBase* class in the Blazor project. Inherit components from this class to have the localizer pre-injected.
**Example: Derive from the base component class**
````csharp
@page "/"
@inherits MyProjectNameComponentBase
<h1>
@L["LongWelcomeMessage"]
</h1>
````
### Other Services
`IStringLocalizer<T>` can be injected into any service.
**Example**
````csharp
public class MyService : ITransientDependency
{
private readonly IStringLocalizer<TestResource> _localizer;
public MyService(IStringLocalizer<TestResource> localizer)
{
_localizer = localizer;
}
public void Foo()
{
var str = _localizer["HelloWorld"];
}
}
````
### Format Arguments
Format arguments can be passed after the localization key. If your message is `Hello {0}, welcome!`, then you can pass the `{0}` argument to the localizer like `_localizer["HelloMessage", "John"]`.
> Refer to the [Microsoft's localization documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) for details about using the localization.
## See Also
* [Localization](../../Localization.md)

206
docs/en/UI/Blazor/Navigation-Menu.md

@ -1,3 +1,207 @@
# Blazor UI: Navigation / Menu
TODO
Every application has a main menu to allow users to navigate to pages/screens of the application. Some applications may contain more than one menu in different sections of the UI.
ABP Framework is a [modular](../../Module-Development-Basics.md) application development framework. **Every module may need to add items to the menu**.
So, ABP Framework **provides a menu infrastructure** where;
* The application or the modules can add items to a menu, without knowing how the menu is rendered.
* The [theme](Theming.md) properly renders the menu.
## Adding Menu Items
In order to add menu items (or manipulate the existing items) you need to create a class implementing the `IMenuContributor` interface.
> The [application startup template](../../Startup-Templates/Application.md) already contains an implementation of the `IMenuContributor`. So, you can add items inside that class instead of creating a new one.
**Example: Add a *CRM* menu item with *Customers* and *Orders* sub menu items**
```csharp
using System.Threading.Tasks;
using MyProject.Localization;
using Volo.Abp.UI.Navigation;
namespace MyProject.Web.Menus
{
public class MyProjectMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
var l = context.GetLocalizer<MyProjectResource>();
context.Menu.AddItem(
new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"])
.AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Customers",
displayName: l["Menu:Customers"],
url: "/crm/customers")
).AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Orders",
displayName: l["Menu:Orders"],
url: "/crm/orders")
)
);
}
}
}
```
* This example adds items only to the main menu (`StandardMenus.Main`: see the *Standard Menus* section below).
* It gets a `IStringLocalizer` from `context` to [localize](../../Localization.md) the display names of the menu items.
* Adds the Customers and Orders as children of the CRM menu.
Once you create a menu contributor, you need to add it to the `AbpNavigationOptions` in the `ConfigureServices` method of your module:
````csharp
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new MyProjectMenuContributor());
});
````
This example uses some localization keys as display names those should be defined in the localization file:
````json
"Menu:CRM": "CRM",
"Menu:Orders": "Orders",
"Menu:Customers": "Customers"
````
See the [localization document](../../Localization.md) to learn more about the localization.
When you run the application, you will see the menu items added to the main menu:
![nav-main-menu](../../images/nav-main-menu.png)
> The menu is rendered by the current UI [theme](Theming.md). So, the look of the main menu can be completely different based on your theme.
Here, a few notes on the menu contributors;
* ABP Framework calls the `ConfigureMenuAsync` method **whenever need to render** the menu.
* Every menu item can have **children**. So, you can add menu items with **unlimited depth** (however, your UI theme may not support unlimited depth).
* Only leaf menu items have `url`s normally. When you click to a parent menu, its sub menu is opened or closed, you don't navigate the `url` of a parent menu item.
* If a menu item has no children and has no `url` defined, then it is not rendered on the UI. This simplifies to authorize the menu items: You only authorize the child items (see the next section). If none of the children are authorized, then the parent automatically disappears.
### Menu Item Properties
There are more options of a menu item (the constructor of the `ApplicationMenuItem` class). Here, the list of all available options;
* `name` (`string`, required): The **unique name** of the menu item.
* `displayName` (`string`, required): Display name/text of the menu item. You can [localize](../../Localization.md) this as shown before.
* `url` (`string`): The URL of the menu item.
* `icon` (`string`): An icon name. Free [Font Awesome](https://fontawesome.com/) icon classes are supported out of the box. Example: `fa fa-book`. You can use any CSS font icon class as long as you include the necessary CSS files to your application.
* `order` (`int`): The order of the menu item. Default value is `1000`. Items are sorted by the adding order unless you specify an order value.
* `customData` (`object`): A custom object that you can associate to the menu item and use it while rendering the menu item.
* `target` (`string`): Target of the menu item. Can be `null` (default), "\_*blank*", "\_*self*", "\_*parent*", "\_*top*" or a frame name for web applications.
* `elementId` (`string`): Can be used to render the element with a specific HTML `id` attribute.
* `cssClass` (`string`): Additional string classes for the menu item.
### Authorization
As seen above, a menu contributor contributes to the menu dynamically. So, you can perform any custom logic or get menu items from any source.
One use case is the [authorization](Authorization.md). You typically want to add menu items by checking a permission.
**Example: Check if the current user has a permission**
````csharp
if (await context.IsGrantedAsync("MyPermissionName"))
{
//...add menu items
}
````
> You can use `context.AuthorizationService` to directly access to the `IAuthorizationService`.
### Resolving Dependencies
`context.ServiceProvider` can be used to resolve any service dependency.
**Example: Get a service**
````csharp
var myService = context.ServiceProvider.GetRequiredService<IMyService>();
//...use the service
````
> You don't need to care about releasing/disposing services. ABP Framework handles it.
### The Administration Menu
There is a special menu item in the menu menu that is added by the ABP Framework: The *Administration* menu. It is typically used by the pre-built admin [application modules](../../Modules/Index.md):
![nav-main-menu-administration](../../images/nav-main-menu-administration.png)
If you want to add menu items under the *Administration* menu item, you can use the `context.Menu.GetAdministration()` extension method:
````csharp
context.Menu.GetAdministration().AddItem(...)
````
### Manipulating the Existing Menu Items
ABP Framework executes the menu contributors by the [module dependency order](../../Module-Development-Basics.md). So, you can manipulate the menu items that your application or module (directly or indirectly) depends on.
**Example: Set an icon for the `Users` menu item added by the [Identity Module](../../Modules/Identity.md)**
````csharp
var userMenu = context.Menu.FindMenuItem(IdentityMenuNames.Users);
userMenu.Icon = "fa fa-users";
````
> `context.Menu` gives you ability to access to all the menu items those have been added by the previous menu contributors.
## Standard Menus
A menu is a **named** component. An application may contain more than one menus with different, unique names. There are two pre-defined standard menus:
* `Main`: The main menu of the application. Contains links to the page of the application. Defined as a constant: `Volo.Abp.UI.Navigation.StandardMenus.Main`.
* `User`: User profile menu. Defined as a constant: `Volo.Abp.UI.Navigation.StandardMenus.User`.
The `Main` menu already covered above. The `User` menu is available when a user has logged in:
![user-menu](../../images/user-menu.png)
You can add items to the `User` menu by checking the `context.Menu.Name` as shown below:
```csharp
if (context.Menu.Name == StandardMenus.User)
{
//...add items
}
```
## IMenuManager
`IMenuManager` is generally used by the UI [theme](Theming.md) to render the menu items on the UI. So, **you generally don't need to directly use** the `IMenuManager`.
**Example: Get the Main Menu to render in a razor component**
```csharp
// Code behind file of a razor component
public partial class NavMenu
{
private readonly IMenuManager _menuManager;
public NavMenu(IMenuManager menuManager)
{
_menuManager = menuManager;
}
protected override async Task OnInitializedAsync()
{
var menu = await _menuManager.GetAsync(StandardMenus.Main);
//...
}
}
```

3
docs/en/UI/Blazor/Page-Alerts.md

@ -0,0 +1,3 @@
# Blazor UI: Page Alerts
TODO

62
docs/en/UI/Blazor/Settings.md

@ -1,3 +1,63 @@
# Blazor UI: Settings
Blazor applications can reuse the same `ISettingProvider` service that is explained in the [settings document](../../Settings.md).
Blazor applications can reuse the same `ISettingProvider` service that is explained in the [settings document](../../Settings.md).
## ISettingProvider
`ISettingProvider` is used to get the value of a setting or get the values of all the settings.
**Example usages in a simple service**
````csharp
public class MyService : ITransientDependency
{
private readonly ISettingProvider _settingProvider;
//Inject ISettingProvider in the constructor
public MyService(ISettingProvider settingProvider)
{
_settingProvider = settingProvider;
}
public async Task FooAsync()
{
//Get a value as string.
string setting1 = await _settingProvider.GetOrNullAsync("MySettingName");
//Get a bool value and fallback to the default value (false) if not set.
bool setting2 = await _settingProvider.GetAsync<bool>("MyBoolSettingName");
//Get a bool value and fallback to the provided default value (true) if not set.
bool setting3 = await _settingProvider.GetAsync<bool>(
"MyBoolSettingName", defaultValue: true);
//Get a bool value with the IsTrueAsync shortcut extension method
bool setting4 = await _settingProvider.IsTrueAsync("MyBoolSettingName");
//Get an int value or the default value (0) if not set
int setting5 = (await _settingProvider.GetAsync<int>("MyIntegerSettingName"));
//Get an int value or null if not provided
int? setting6 = (await _settingProvider
.GetOrNullAsync("MyIntegerSettingName"))?.To<int>();
}
}
````
**Example usage in a Razor Component**
````csharp
@page "/"
@using Volo.Abp.Settings
@inject ISettingProvider SettingProvider
@code {
protected override async Task OnInitializedAsync()
{
bool settingValue = await SettingProvider.GetAsync<bool>("MyBoolSettingName");
}
}
````
## See Also
* [Settings](../../Settings.md)

206
docs/en/UI/Blazor/Theming.md

@ -1,3 +1,207 @@
# Blazor UI: Theming
TODO
## Introduction
ABP Framework provides a complete **UI Theming** system with the following goals:
* Reusable [application modules](../../Modules/Index.md) are developed **theme-independent**, so they can work with any UI theme.
* UI theme is **decided by the final application**.
* The theme is distributed via a NuGet package, so it is **easily upgradable**.
* The final application can **customize** the selected theme.
In order to accomplish these goals, ABP Framework;
* Determines a set of **base libraries** used and adapted by all the themes. So, module and application developers can depend on and use these libraries without depending on a particular theme.
* Provides a system that consists of layout parts (like [navigation menus](Navigation-Menu.md) and [toolbars](Toolbars.md)) that is implemented by all the themes. So, the modules and the application to contribute to the layout to compose a consistent application UI.
### Current Themes
Currently, two themes are **officially provided**:
* The [Basic Theme](Basic-Theme.md) is the minimalist theme with the plain Bootstrap style. It is **open source and free**.
* The [Lepton Theme](https://commercial.abp.io/themes) is a **commercial** theme developed by the core ABP team and is a part of the [ABP Commercial](https://commercial.abp.io/) license.
## Overall
### The Base Libraries
All the themes must depend on the [Volo.Abp.AspNetCore.Components.WebAssembly.Theming](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Components.WebAssembly.Theming) NuGet package, so they are indirectly depending on the following libraries:
* [Twitter Bootstrap](https://getbootstrap.com/) as the fundamental HTML/CSS framework.
* [Blazorise](https://github.com/stsrki/Blazorise) as a component library that supports the Bootstrap and adds extra components like Data Grid and Tree.
* [FontAwesome](https://fontawesome.com/) as the fundamental CSS font library.
* [Flag Icon](https://github.com/lipis/flag-icon-css) as a library to show flags of countries.
These libraries are selected as the base libraries and available to the applications and modules.
> Bootstrap's JavaScript part is not used since the Blazorise library already provides the necessary functionalities to the Bootstrap components in a native way.
### The Layout
All themes must define a layout for the application. The following image shows the user management page in the [Basic Theme](Basic-Theme.md) application layout:
![basic-theme-application-layout-blazor](../../images/basic-theme-application-layout-blazor.png)
And the same page is shown below with the [Lepton Theme](https://commercial.abp.io/themes) application layout:
![lepton-theme-application-layout](../../images/lepton-theme-application-layout.png)
As you can see, the page is the same, but the look is completely different in the themes above.
The application layout typically includes the following parts;
* A [main menu](Navigation-Menu.md)
* Main [Toolbar](Toolbars.md) with the following components;
* User menu
* Language switch dropdown
* [Page alerts](Page-Alerts.md)
* The page content (aka `@Body`)
## Implementing a Theme
A theme is simply a Razor Class Library.
### The Easy Way
The easiest way to create a new theme is to copy the [Basic Theme Source Code](https://github.com/abpframework/abp/tree/dev/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme) and customize it. Once you get a copy of the theme in your solution, remove the `Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic` NuGet package and reference to the local project.
### Global Styles / Scripts
A theme generally needs to add a global style to the page. ABP provides a system to manage the [Global Styles and Scripts](Global-Scripts-Styles.md). A theme can implement the `IBundleContributer` to add global style or script files to the page.
**Example: Adding a style to the page**
````csharp
using Volo.Abp.Bundling;
namespace MyTheme
{
public class MyThemeBundleContributer : IBundleContributer
{
public void AddScripts(BundleContext context)
{
}
public void AddStyles(BundleContext context)
{
context.Add("_content/MyTheme/styles.css");
}
}
}
````
`styles.css` file should be added into the `wwwroot` folder of the theme project for this example. When you use the `abp bundle` command, this class is automatically discovered and executed to add the style to the page.
See the [Global Styles and Scripts](Global-Scripts-Styles.md) document for more.
### Layout Parts
A typical Layout consists of several parts. The theme should include the necessary parts in each layout.
**Example: The Basic Theme has the following parts for the Application Layout**
![basic-theme-application-layout-parts](../../images/basic-theme-application-layout-parts.png)
The application code and the modules can only show contents in the Page Content part. If they need to change the other parts (to add a menu item, to add a toolbar item, to change the application name in the branding area...) they should use the ABP Framework APIs.
The following sections explain the fundamental parts pre-defined by the ABP Framework and can be implemented by the themes.
> It is a good practice to split the layout into components/partials, so the final application can override them partially for customization purpose.
#### Branding
`IBrandingProvider` service should be used to get the name and the logo URL of the application to render in the Branding part.
The [Application Startup Template](../../Startup-Templates/Application.md) has an implementation of this interface to set the values by the application developer.
#### Main Menu
`IMenuManager` service is used to get the main menu items and render on the layout.
**Example: Get the Main Menu to render in a razor component**
```csharp
// Code behind file of a razor component
public partial class NavMenu
{
private readonly IMenuManager _menuManager;
public NavMenu(IMenuManager menuManager)
{
_menuManager = menuManager;
}
protected override async Task OnInitializedAsync()
{
var menu = await _menuManager.GetAsync(StandardMenus.Main);
//...
}
}
```
See the [Navigation / Menus](Navigation-Menu.md) document to learn more about the navigation system.
#### Main Toolbar
`IToolbarManager` service is used to get the Main Toolbar items and render on the layout. Each item of this toolbar is a Razor Component, so it may include any type of UI elements. Inject the `IToolbarManager` and use the `GetAsync` to get the toolbar items:
````csharp
var toolbar = await _toolbarManager.GetAsync(StandardToolbars.Main);
````
> See the [Toolbars](Toolbars.md) document to learn more on the toolbar system.
The theme has a responsibility to add two pre-defined items to the main toolbar: Language Selection and User Menu. To do that, create a class implementing the `IToolbarContributor` interface and add it to the `AbpToolbarOptions` as shown below:
```csharp
Configure<AbpToolbarOptions>(options =>
{
options.Contributors.Add(new BasicThemeMainTopToolbarContributor());
});
```
##### Language Selection
Language Selection toolbar item is generally a dropdown that is used to switch between languages. `ILanguageProvider` is used to get the list of available languages and `CultureInfo.CurrentUICulture` is used to learn the current language.
Local Storage is used to get and set the current language with the `Abp.SelectedLanguage` key.
**Example: Get the currently selected language**
````csharp
var selectedLanguageName = await JsRuntime.InvokeAsync<string>(
"localStorage.getItem",
"Abp.SelectedLanguage"
);
````
**Example: Set the selected language**
````csharp
await JsRuntime.InvokeVoidAsync(
"localStorage.setItem",
"Abp.SelectedLanguage",
"en-US"
);
````
The theme should reload the page after changing the language:
````csharp
await JsRuntime.InvokeVoidAsync("location.reload");
````
##### User Menu
User menu includes links related to the user account. `IMenuManager` is used just like the Main Menu, but this time with `StandardMenus.User` parameter like shown below:
````csharp
var menu = await _menuManager.GetAsync(StandardMenus.User);
````
[ICurrentUser](../../CurrentUser.md) and [ICurrentTenant](../../Multi-Tenancy.md) services can be used to obtain the current user and tenant names.
#### Page Alerts
`IAlertManager` service is used to get the current page alerts to render on the layout. See the [Page Alerts](Page-Alerts.md) document to learn more.

74
docs/en/UI/Blazor/Toolbars.md

@ -1,3 +1,75 @@
# Blazor UI: Toolbars
TODO
The Toolbar system is used to define **toolbars** on the user interface. Modules (or your application) can add **items** to a toolbar, then the [theme](Theming.md) renders the toolbar on the **layout**.
There is only one **standard toolbar** named "Main" (defined as a constant: `StandardToolbars.Main`). The [Basic Theme](Basic-Theme) renders the main toolbar as shown below:
![bookstore-toolbar-highlighted](../../images/bookstore-toolbar-highlighted.png)
In the screenshot above, there are two items added to the main toolbar: Language switch component & user menu. You can add your own items here.
## Example: Add a Notification Icon
In this example, we will add a **notification (bell) icon** to the left of the language switch item. A item in the toolbar should be a **Razor Component**. So, first, create a new razor component in your project (the location of the component doesn't matter):
![bookstore-notification-view-component](../../images/blazor-notification-bell-component.png)
The content of the `Notification.razor` is shown below:
````html
@inherits Volo.Abp.AspNetCore.Components.AbpComponentBase
<div style="color: white; margin: 8px;">
<i class="far fa-bell" @onclick="ShowNotifications"></i>
</div>
@code {
private async Task ShowNotifications()
{
await Message.Info("TODO: Show notifications");
}
}
````
This sample simply shows a message. In real life, you probably want to call an HTTP API to get notifications and show on the UI.
Now, we can create a class implementing the `IToolbarContributor` interface:
````csharp
using System.Threading.Tasks;
using MyCompanyName.MyProjectName.Blazor.Components;
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Toolbars;
namespace MyCompanyName.MyProjectName.Blazor
{
public class MyToolbarContributor : IToolbarContributor
{
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
{
if (context.Toolbar.Name == StandardToolbars.Main)
{
context.Toolbar.Items.Insert(0, new ToolbarItem(typeof(Notification)));
}
return Task.CompletedTask;
}
}
}
````
This class adds the `NotificationViewComponent` as the first item in the `Main` toolbar.
Finally, you need to add this contributor to the `AbpToolbarOptions`, in the `ConfigureServices` of your [module](../../Module-Development-Basics.md):
````csharp
Configure<AbpToolbarOptions>(options =>
{
options.Contributors.Add(new MyToolbarContributor());
});
````
That's all, you will see the notification icon on the toolbar when you run the application:
![bookstore-notification-icon-on-toolbar](../../images/bookstore-notification-icon-on-toolbar.png)
## IToolbarManager
`IToolbarManager` is used to render the toolbar. It returns the toolbar items by a toolbar name. This is generally used by the [themes](Theming.md) to render the toolbar on the layout.

16
docs/en/docs-nav.json

@ -588,12 +588,26 @@
},
{
"text": "Theming",
"path": "UI/Blazor/Theming.md"
"path": "UI/Blazor/Theming.md",
"items": [
{
"text": "The Basic Theme",
"path": "UI/Blazor/Basic-Theme.md"
}
]
},
{
"text": "Toolbars",
"path": "UI/Blazor/Toolbars.md"
},
{
"text": "Page Alerts",
"path": "UI/Blazor/Page-Alerts.md"
},
{
"text": "Branding",
"path": "UI/Blazor/Branding.md"
},
{
"text": "Customization / Overriding Components",
"path": "UI/Blazor/Customization-Overriding-Components.md"

BIN
docs/en/images/basic-theme-application-layout-blazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
docs/en/images/blazor-notification-bell-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/en/images/bookstore-branding-blazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/en/images/bookstore-logo-blazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

3
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/Branding.razor

@ -0,0 +1,3 @@
@using Volo.Abp.Ui.Branding
@inject IBrandingProvider BrandingProvider
<a class="navbar-brand" href="/">@BrandingProvider.AppName</a>

4
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor

@ -1,9 +1,7 @@
@inherits LayoutComponentBase
@using Volo.Abp.Ui.Branding
@inject IBrandingProvider BrandingProvider
<nav class="navbar navbar-expand-md navbar-dark bg-dark shadow-sm flex-column flex-md-row mb-4" id="main-navbar" style="min-height: 4rem;">
<div class="container">
<a class="navbar-brand" href="/">@BrandingProvider.AppName</a>
<Branding />
<button @onclick="ToggleCollapse" class="navbar-toggler" type="button" data-toggle="collapse"
data-target="#main-navbar-collapse" aria-controls="main-navbar-collapse"
aria-expanded="false" aria-label="Toggle navigation">

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBrandingProvider.cs

@ -1,7 +1,9 @@
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Ui.Branding;
namespace MyCompanyName.MyProjectName.Blazor
{
[Dependency(ReplaceServices = true)]
public class MyProjectNameBrandingProvider : DefaultBrandingProvider
{
public override string AppName => "MyProjectName";

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameComponentBase.cs

@ -3,9 +3,9 @@ using Volo.Abp.AspNetCore.Components;
namespace MyCompanyName.MyProjectName.Blazor
{
public class MyProjectNameComponentBase : AbpComponentBase
public abstract class MyProjectNameComponentBase : AbpComponentBase
{
public MyProjectNameComponentBase()
protected MyProjectNameComponentBase()
{
LocalizationResource = typeof(MyProjectNameResource);
}

2
templates/module/angular/projects/dev-app/src/environments/environment.ts

@ -14,7 +14,7 @@ export const environment = {
redirectUri: baseUrl,
clientId: 'MyProjectName_App',
responseType: 'code',
scope: 'offline_access MyProjectName',
scope: 'offline_access MyProjectName role email openid profile',
},
apis: {
default: {

6
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/EntityFrameworkCore/MyProjectNameHttpApiHostMigrationsDbContext.cs

@ -1,8 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.EntityFrameworkCore
{
@ -19,9 +16,6 @@ namespace MyCompanyName.MyProjectName.EntityFrameworkCore
base.OnModelCreating(modelBuilder);
modelBuilder.ConfigureMyProjectName();
modelBuilder.ConfigureAuditLogging();
modelBuilder.ConfigurePermissionManagement();
modelBuilder.ConfigureSettingManagement();
}
}
}

382
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20201019021119_Initial.Designer.cs

@ -1,382 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyCompanyName.MyProjectName.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
[DbContext(typeof(MyProjectNameHttpApiHostMigrationsDbContext))]
[Migration("20201019021119_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.UseIdentityColumns()
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.0-rc.2.20475.6");
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ApplicationName")
.HasMaxLength(96)
.HasColumnType("nvarchar(96)")
.HasColumnName("ApplicationName");
b.Property<string>("BrowserInfo")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)")
.HasColumnName("BrowserInfo");
b.Property<string>("ClientId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("ClientId");
b.Property<string>("ClientIpAddress")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("ClientIpAddress");
b.Property<string>("ClientName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("ClientName");
b.Property<string>("Comments")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("Comments");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("CorrelationId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("CorrelationId");
b.Property<string>("Exceptions")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)")
.HasColumnName("Exceptions");
b.Property<int>("ExecutionDuration")
.HasColumnType("int")
.HasColumnName("ExecutionDuration");
b.Property<DateTime>("ExecutionTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("HttpMethod")
.HasMaxLength(16)
.HasColumnType("nvarchar(16)")
.HasColumnName("HttpMethod");
b.Property<int?>("HttpStatusCode")
.HasColumnType("int")
.HasColumnName("HttpStatusCode");
b.Property<Guid?>("ImpersonatorTenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("ImpersonatorTenantId");
b.Property<Guid?>("ImpersonatorUserId")
.HasColumnType("uniqueidentifier")
.HasColumnName("ImpersonatorUserId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(max)");
b.Property<string>("Url")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("Url");
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier")
.HasColumnName("UserId");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("UserName");
b.HasKey("Id");
b.HasIndex("TenantId", "ExecutionTime");
b.HasIndex("TenantId", "UserId", "ExecutionTime");
b.ToTable("AbpAuditLogs");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid>("AuditLogId")
.HasColumnType("uniqueidentifier")
.HasColumnName("AuditLogId");
b.Property<int>("ExecutionDuration")
.HasColumnType("int")
.HasColumnName("ExecutionDuration");
b.Property<DateTime>("ExecutionTime")
.HasColumnType("datetime2")
.HasColumnName("ExecutionTime");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("MethodName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("MethodName");
b.Property<string>("Parameters")
.HasMaxLength(2000)
.HasColumnType("nvarchar(2000)")
.HasColumnName("Parameters");
b.Property<string>("ServiceName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("ServiceName");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("AuditLogId");
b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime");
b.ToTable("AbpAuditLogActions");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid>("AuditLogId")
.HasColumnType("uniqueidentifier")
.HasColumnName("AuditLogId");
b.Property<DateTime>("ChangeTime")
.HasColumnType("datetime2")
.HasColumnName("ChangeTime");
b.Property<byte>("ChangeType")
.HasColumnType("tinyint")
.HasColumnName("ChangeType");
b.Property<string>("EntityId")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("EntityId");
b.Property<Guid?>("EntityTenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("EntityTypeFullName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("EntityTypeFullName");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("AuditLogId");
b.HasIndex("TenantId", "EntityTypeFullName", "EntityId");
b.ToTable("AbpEntityChanges");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid>("EntityChangeId")
.HasColumnType("uniqueidentifier");
b.Property<string>("NewValue")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)")
.HasColumnName("NewValue");
b.Property<string>("OriginalValue")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)")
.HasColumnName("OriginalValue");
b.Property<string>("PropertyName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("PropertyName");
b.Property<string>("PropertyTypeFullName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("PropertyTypeFullName");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityChangeId");
b.ToTable("AbpEntityPropertyChanges");
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpPermissionGrants");
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)
.WithMany("Actions")
.HasForeignKey("AuditLogId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)
.WithMany("EntityChanges")
.HasForeignKey("AuditLogId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
{
b.HasOne("Volo.Abp.AuditLogging.EntityChange", null)
.WithMany("PropertyChanges")
.HasForeignKey("EntityChangeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Navigation("Actions");
b.Navigation("EntityChanges");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
{
b.Navigation("PropertyChanges");
});
#pragma warning restore 612, 618
}
}
}

212
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20201019021119_Initial.cs

@ -1,212 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MyCompanyName.MyProjectName.Migrations
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AbpAuditLogs",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
ApplicationName = table.Column<string>(type: "nvarchar(96)", maxLength: 96, nullable: true),
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
TenantName = table.Column<string>(type: "nvarchar(max)", nullable: true),
ImpersonatorUserId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
ImpersonatorTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
ExecutionTime = table.Column<DateTime>(type: "datetime2", nullable: false),
ExecutionDuration = table.Column<int>(type: "int", nullable: false),
ClientIpAddress = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
ClientName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
ClientId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
CorrelationId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
BrowserInfo = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
HttpMethod = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: true),
Url = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
Exceptions = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
Comments = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
HttpStatusCode = table.Column<int>(type: "int", nullable: true),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true),
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuditLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpPermissionGrants",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
ProviderName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false),
ProviderKey = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpPermissionGrants", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSettings",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Value = table.Column<string>(type: "nvarchar(2048)", maxLength: 2048, nullable: false),
ProviderName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
ProviderKey = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpSettings", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpAuditLogActions",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
AuditLogId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
ServiceName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
MethodName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
Parameters = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
ExecutionTime = table.Column<DateTime>(type: "datetime2", nullable: false),
ExecutionDuration = table.Column<int>(type: "int", nullable: false),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuditLogActions", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuditLogActions_AbpAuditLogs_AuditLogId",
column: x => x.AuditLogId,
principalTable: "AbpAuditLogs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AbpEntityChanges",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
AuditLogId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
ChangeTime = table.Column<DateTime>(type: "datetime2", nullable: false),
ChangeType = table.Column<byte>(type: "tinyint", nullable: false),
EntityTenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
EntityId = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
EntityTypeFullName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpEntityChanges", x => x.Id);
table.ForeignKey(
name: "FK_AbpEntityChanges_AbpAuditLogs_AuditLogId",
column: x => x.AuditLogId,
principalTable: "AbpAuditLogs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AbpEntityPropertyChanges",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
EntityChangeId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
NewValue = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
OriginalValue = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
PropertyName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
PropertyTypeFullName = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpEntityPropertyChanges", x => x.Id);
table.ForeignKey(
name: "FK_AbpEntityPropertyChanges_AbpEntityChanges_EntityChangeId",
column: x => x.EntityChangeId,
principalTable: "AbpEntityChanges",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AbpAuditLogActions_AuditLogId",
table: "AbpAuditLogActions",
column: "AuditLogId");
migrationBuilder.CreateIndex(
name: "IX_AbpAuditLogActions_TenantId_ServiceName_MethodName_ExecutionTime",
table: "AbpAuditLogActions",
columns: new[] { "TenantId", "ServiceName", "MethodName", "ExecutionTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpAuditLogs_TenantId_ExecutionTime",
table: "AbpAuditLogs",
columns: new[] { "TenantId", "ExecutionTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpAuditLogs_TenantId_UserId_ExecutionTime",
table: "AbpAuditLogs",
columns: new[] { "TenantId", "UserId", "ExecutionTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpEntityChanges_AuditLogId",
table: "AbpEntityChanges",
column: "AuditLogId");
migrationBuilder.CreateIndex(
name: "IX_AbpEntityChanges_TenantId_EntityTypeFullName_EntityId",
table: "AbpEntityChanges",
columns: new[] { "TenantId", "EntityTypeFullName", "EntityId" });
migrationBuilder.CreateIndex(
name: "IX_AbpEntityPropertyChanges_EntityChangeId",
table: "AbpEntityPropertyChanges",
column: "EntityChangeId");
migrationBuilder.CreateIndex(
name: "IX_AbpPermissionGrants_Name_ProviderName_ProviderKey",
table: "AbpPermissionGrants",
columns: new[] { "Name", "ProviderName", "ProviderKey" });
migrationBuilder.CreateIndex(
name: "IX_AbpSettings_Name_ProviderName_ProviderKey",
table: "AbpSettings",
columns: new[] { "Name", "ProviderName", "ProviderKey" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpAuditLogActions");
migrationBuilder.DropTable(
name: "AbpEntityPropertyChanges");
migrationBuilder.DropTable(
name: "AbpPermissionGrants");
migrationBuilder.DropTable(
name: "AbpSettings");
migrationBuilder.DropTable(
name: "AbpEntityChanges");
migrationBuilder.DropTable(
name: "AbpAuditLogs");
}
}
}

380
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/MyProjectNameHttpApiHostMigrationsDbContextModelSnapshot.cs

@ -1,380 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyCompanyName.MyProjectName.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
[DbContext(typeof(MyProjectNameHttpApiHostMigrationsDbContext))]
partial class MyProjectNameHttpApiHostMigrationsDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.UseIdentityColumns()
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.0-rc.2.20475.6");
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ApplicationName")
.HasMaxLength(96)
.HasColumnType("nvarchar(96)")
.HasColumnName("ApplicationName");
b.Property<string>("BrowserInfo")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)")
.HasColumnName("BrowserInfo");
b.Property<string>("ClientId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("ClientId");
b.Property<string>("ClientIpAddress")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("ClientIpAddress");
b.Property<string>("ClientName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("ClientName");
b.Property<string>("Comments")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("Comments");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("CorrelationId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("CorrelationId");
b.Property<string>("Exceptions")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)")
.HasColumnName("Exceptions");
b.Property<int>("ExecutionDuration")
.HasColumnType("int")
.HasColumnName("ExecutionDuration");
b.Property<DateTime>("ExecutionTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("HttpMethod")
.HasMaxLength(16)
.HasColumnType("nvarchar(16)")
.HasColumnName("HttpMethod");
b.Property<int?>("HttpStatusCode")
.HasColumnType("int")
.HasColumnName("HttpStatusCode");
b.Property<Guid?>("ImpersonatorTenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("ImpersonatorTenantId");
b.Property<Guid?>("ImpersonatorUserId")
.HasColumnType("uniqueidentifier")
.HasColumnName("ImpersonatorUserId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(max)");
b.Property<string>("Url")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("Url");
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier")
.HasColumnName("UserId");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("UserName");
b.HasKey("Id");
b.HasIndex("TenantId", "ExecutionTime");
b.HasIndex("TenantId", "UserId", "ExecutionTime");
b.ToTable("AbpAuditLogs");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid>("AuditLogId")
.HasColumnType("uniqueidentifier")
.HasColumnName("AuditLogId");
b.Property<int>("ExecutionDuration")
.HasColumnType("int")
.HasColumnName("ExecutionDuration");
b.Property<DateTime>("ExecutionTime")
.HasColumnType("datetime2")
.HasColumnName("ExecutionTime");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("MethodName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("MethodName");
b.Property<string>("Parameters")
.HasMaxLength(2000)
.HasColumnType("nvarchar(2000)")
.HasColumnName("Parameters");
b.Property<string>("ServiceName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("ServiceName");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("AuditLogId");
b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime");
b.ToTable("AbpAuditLogActions");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid>("AuditLogId")
.HasColumnType("uniqueidentifier")
.HasColumnName("AuditLogId");
b.Property<DateTime>("ChangeTime")
.HasColumnType("datetime2")
.HasColumnName("ChangeTime");
b.Property<byte>("ChangeType")
.HasColumnType("tinyint")
.HasColumnName("ChangeType");
b.Property<string>("EntityId")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("EntityId");
b.Property<Guid?>("EntityTenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("EntityTypeFullName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("EntityTypeFullName");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("AuditLogId");
b.HasIndex("TenantId", "EntityTypeFullName", "EntityId");
b.ToTable("AbpEntityChanges");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid>("EntityChangeId")
.HasColumnType("uniqueidentifier");
b.Property<string>("NewValue")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)")
.HasColumnName("NewValue");
b.Property<string>("OriginalValue")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)")
.HasColumnName("OriginalValue");
b.Property<string>("PropertyName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("PropertyName");
b.Property<string>("PropertyTypeFullName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("PropertyTypeFullName");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityChangeId");
b.ToTable("AbpEntityPropertyChanges");
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpPermissionGrants");
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)
.WithMany("Actions")
.HasForeignKey("AuditLogId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)
.WithMany("EntityChanges")
.HasForeignKey("AuditLogId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
{
b.HasOne("Volo.Abp.AuditLogging.EntityChange", null)
.WithMany("PropertyChanges")
.HasForeignKey("EntityChangeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Navigation("Actions");
b.Navigation("EntityChanges");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
{
b.Navigation("PropertyChanges");
});
#pragma warning restore 612, 618
}
}
}
Loading…
Cancel
Save