Browse Source

Add Blazor variant to modular CRM docs and migrations

Add Blazor WebApp variants to the Modular CRM tutorial: insert doc-params and UI conditionals across parts 01-08, add multiple Blazor-specific screenshots, and include Blazor code samples/placeholders for catalog and ordering pages and menu contributor. Also add EF Core migration (20260227074745_ABP10_2) and update the DbContext model snapshot, plus small updates to migrator and web app settings/packages to accommodate the changes.
pull/24987/head
SALİH ÖZKARA 1 month ago
parent
commit
468c2805a4
  1. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png
  2. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3-blazor-webapp.png
  3. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-catalog-module-expanded-in-solution-explorer-blazor-webapp.png
  4. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies-v2-blazor-webapp.png
  5. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-blazor-webapp.png
  6. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering-v2-blazor-webapp.png
  7. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module-blazor-webapp.png
  8. BIN
      docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog-for-catalog-blazor-webapp.png
  9. BIN
      docs/en/tutorials/modular-crm/images/catalog-module-vs-code-blazor-webapp.png
  10. 7
      docs/en/tutorials/modular-crm/index.md
  11. 15
      docs/en/tutorials/modular-crm/part-01.md
  12. 15
      docs/en/tutorials/modular-crm/part-02.md
  13. 58
      docs/en/tutorials/modular-crm/part-03.md
  14. 23
      docs/en/tutorials/modular-crm/part-04.md
  15. 96
      docs/en/tutorials/modular-crm/part-05.md
  16. 55
      docs/en/tutorials/modular-crm/part-06.md
  17. 15
      docs/en/tutorials/modular-crm/part-07.md
  18. 7
      docs/en/tutorials/modular-crm/part-08.md
  19. 1538
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.Designer.cs
  20. 160
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.cs
  21. 138
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs
  22. 2
      modules/docs/app/VoloDocs.Migrator/appsettings.json
  23. 3
      modules/docs/app/VoloDocs.Web/VoloDocs.Web.abppkg
  24. 2
      modules/docs/app/VoloDocs.Web/appsettings.json

BIN
docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-catalog-module-expanded-in-solution-explorer-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-imports-and-dependencies-v2-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering-v2-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
docs/en/tutorials/modular-crm/images/abp-studio-module-installation-dialog-for-catalog-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/en/tutorials/modular-crm/images/catalog-module-vs-code-blazor-webapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

7
docs/en/tutorials/modular-crm/index.md

@ -7,6 +7,13 @@
# Modular Monolith Application Development Tutorial
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{

15
docs/en/tutorials/modular-crm/part-01.md

@ -7,6 +7,13 @@
# Creating the Initial Solution
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -28,7 +35,7 @@ In this first part of this tutorial, we will create a new ABP solution with modu
Follow the *[Get Started](../../get-started/single-layer-web-application.md)* guide to create a single layer web application with the following configuration:
* **Solution name**: `ModularCrm`
* **UI Framework**: ASP.NET Core MVC / Razor Pages
* **UI Framework**: {{if UI == "MVC"}}ASP.NET Core MVC / Razor Pages{{else if UI == "BlazorWebApp"}}Blazor WebApp{{end}}
* **Database Provider**: Entity Framework Core
You can select the other options based on your preference but at the **Modularity** step, check the _Setup as a modular solution_ option and add a new **Standard Module** named `ModularCrm.Catalog`:
@ -62,12 +69,16 @@ Initially, you see a `ModularCrm` solution with two solution folders:
If you expand it, you can see the .NET projects (ABP Studio Packages) of the `ModularCrm.Catalog` module:
{{if UI == "MVC"}}
![abp-studio-catalog-module-expanded-in-solution-explorer](images/abp-studio-catalog-module-expanded-in-solution-explorer.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-catalog-module-expanded-in-solution-explorer](images/abp-studio-catalog-module-expanded-in-solution-explorer-blazor-webapp.png)
{{end}}
- `ModularCrm.Catalog`: The main module project that contains your [entities](../../framework/architecture/domain-driven-design/entities.md), [application service](../../framework/architecture/domain-driven-design/application-services.md) implementations and other business objects
- `ModularCrm.Catalog.Contracts`: Basically contains [application service](../../framework/architecture/domain-driven-design/application-services.md) interfaces and [DTOs](../../framework/architecture/domain-driven-design/data-transfer-objects.md). These interfaces then can be used by client modules for integration purposes or by the user interface to perform use cases related to that module
- `ModularCrm.Catalog.Tests`: Unit and integration tests (if you selected the _Include Tests_ option) for that module
- `ModularCrm.Catalog.UI`: Contains user interface pages and components for the module
- {{if UI == "MVC"}}`ModularCrm.Catalog.UI`: Contains user interface pages and components for the module{{else if UI == "BlazorWebApp"}}`ModularCrm.Catalog.Blazor`: Contains Blazor WebApp user interface pages and components for the module{{end}}
## Summary

15
docs/en/tutorials/modular-crm/part-02.md

@ -7,6 +7,13 @@
# Setting Up the Catalog Module
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -25,7 +32,7 @@ In this part, you will install the `ModularCrm.Catalog` module to the main appli
## Installing the Catalog Module to the Main Application
A module does not contain an executable application inside. The `ModularCrm.Catalog.UI` project is just a class library project, not an executable web application. A module should be installed in an executable application to run it.
A module does not contain an executable application inside. The {{if UI == "MVC"}}`ModularCrm.Catalog.UI`{{else if UI == "BlazorWebApp"}}`ModularCrm.Catalog.Blazor`{{end}} project is just a class library project, not an executable web application. A module should be installed in an executable application to run it.
> **Ensure that the web application is not running in [Solution Runner](../../studio/running-applications.md) or in your IDE. Installing a module to a running application will produce errors.**
@ -41,9 +48,13 @@ Select the `ModularCrm.Catalog` module and check the *Install this module* optio
When you click the *OK* button, ABP Studio opens the *Install Module* dialog:
{{if UI == "MVC"}}
![abp-studio-module-installation-dialog-for-catalog](images/abp-studio-module-installation-dialog-for-catalog.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-module-installation-dialog-for-catalog](images/abp-studio-module-installation-dialog-for-catalog-blazor-webapp.png)
{{end}}
Select the `ModularCrm.Catalog` and `ModularCrm.Catalog.UI` packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
Select the `ModularCrm.Catalog` and {{if UI == "MVC"}}`ModularCrm.Catalog.UI`{{else if UI == "BlazorWebApp"}}`ModularCrm.Catalog.Blazor`{{end}} packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
## Building the Main Application

58
docs/en/tutorials/modular-crm/part-03.md

@ -7,6 +7,13 @@
# Building the Catalog Module
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -35,7 +42,11 @@ Open the `ModularCrm.Catalog` module in your favorite IDE. You can right-click t
The `ModularCrm.Catalog` .NET solution should look like the following figure:
{{if UI == "MVC"}}
![catalog-module-vs-code](images/catalog-module-vs-code.png)
{{else if UI == "BlazorWebApp"}}
![catalog-module-vs-code](images/catalog-module-vs-code-blazor-webapp.png)
{{end}}
Add a new `Product` class under the `ModularCrm.Catalog` project:
@ -406,6 +417,8 @@ As a first step, you can stop the application on ABP Studio's Solution Runner if
### Creating the Products Page
{{if UI == "MVC"}}
Open the `ModularCrm.Catalog` .NET solution in your IDE, and find the `Pages/Catalog/Index.cshtml` file under the `ModularCrm.Catalog.UI` project:
![vscode-catalog-cshtml](images/vscode-catalog-cshtml.png)
@ -461,7 +474,50 @@ Here, you simply use the `IProductAppService` to get a list of all products and
</abp-card>
````
Right-click the `ModularCrm` application on ABP Studio's solution runner and select the *Start* command:
{{else if UI == "BlazorWebApp"}}
Open the `ModularCrm.Catalog` .NET solution in your IDE, and find the `Pages/Catalog/Index.razor` file under the `ModularCrm.Catalog.Blazor` project.
> Blazor WebApp placeholder screenshot file: `images/vscode-catalog-index-razor-blazor-webapp.png`
Replace the `Index.razor` file with the following content:
````razor
@page "/catalog"
@using System.Collections.Generic
@using System.Threading.Tasks
@using ModularCrm.Catalog
@inject IProductAppService ProductAppService
<h1>Products</h1>
<Card>
<CardBody>
<ListGroup>
@foreach (var product in Products)
{
<ListGroupItem>
@product.Name <span class="text-muted">(stock: @product.StockCount)</span>
</ListGroupItem>
}
</ListGroup>
</CardBody>
</Card>
@code {
private List<ProductDto> Products { get; set; } = new();
protected override async Task OnInitializedAsync()
{
Products = await ProductAppService.GetListAsync();
}
}
````
Here, you inject `IProductAppService`, get all products in `OnInitializedAsync`, and then render the result in a simple list.
{{end}}
Right-click the `ModularCrm` application on ABP Studio's Solution Runner and select the *Start* command:
![abp-studio-build-and-restart-application](images/abp-studio-build-and-restart-application.png)

23
docs/en/tutorials/modular-crm/part-04.md

@ -7,6 +7,13 @@
# Creating the Initial Ordering Module
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -39,9 +46,13 @@ That command opens a dialog to define the properties of the new module:
Set `ModularCrm.Ordering` as the *Module name*, leave the *Output folder* as is and click the *Next* button.
{{if UI == "MVC"}}
![abp-studio-add-new-standard-module-ui-dialog](images/abp-studio-add-new-standard-module-ui-dialog.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-add-new-standard-module-ui-dialog](images/abp-studio-add-new-standard-module-ui-dialog-blazor-webapp.png)
{{end}}
You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the *MVC* option and click *Next*.
You can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the {{if UI == "MVC"}}*MVC*{{else if UI == "BlazorWebApp"}}*Blazor WebApp*{{end}} option and click *Next*.
![abp-studio-add-new-standard-module-db-dialog](images/abp-studio-add-new-standard-module-db-dialog.png)
@ -53,7 +64,11 @@ You can include or not include unit tests for the new module here. We are unchec
Here is the final solution structure after adding the `ModularCrm.Ordering` module:
{{if UI == "MVC"}}
![abp-studio-modular-crm-with-standard-module](images/abp-studio-modular-crm-with-standard-module.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-modular-crm-with-standard-module](images/abp-studio-modular-crm-with-standard-module-blazor-webapp.png)
{{end}}
## Installing into the Main Application
@ -71,9 +86,13 @@ That command opens the *Import Module* dialog:
Select the `ModularCrm.Ordering` module and check the *Install this module* option as shown in the preceding figure. When you click the OK button, a new dialog is shown to select the packages to install:
{{if UI == "MVC"}}
![abp-studio-install-module-dialog](images/abp-studio-install-module-dialog-v2.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-install-module-dialog](images/abp-studio-install-module-dialog-blazor-webapp.png)
{{end}}
Select the `ModularCrm.Ordering` and `ModularCrm.Ordering.UI` packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
Select the `ModularCrm.Ordering` and {{if UI == "MVC"}}`ModularCrm.Ordering.UI`{{else if UI == "BlazorWebApp"}}`ModularCrm.Ordering.Blazor`{{end}} packages from the left area and ensure the `ModularCrm` package from the middle area was checked as shown in the preceding figure. Finally, click _OK_.
## Summary

96
docs/en/tutorials/modular-crm/part-05.md

@ -7,6 +7,13 @@
# Building the Ordering Module
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -379,12 +386,14 @@ If you check the database, you should see the entities created in the *Orders* t
## Creating the User Interface
In this section, you will create a very simple user interface to demonstrate how to build UI in the catalog module and make it work in the main application.
In this section, you will create a very simple user interface to demonstrate how to build UI in the ordering module and make it work in the main application.
As a first step, you can stop the application on ABP Studio's Solution Runner if it is currently running.
### Creating the Orders Page
{{if UI == "MVC"}}
Replace the `Index.cshtml.cs` content in the `Pages/Ordering` folder of the `ModularCrm.Ordering.UI` project with the following code block:
````csharp
@ -481,6 +490,91 @@ public class OrderingMenuContributor : IMenuContributor
> You can check the [menu documentation](../../framework/ui/mvc-razor-pages/navigation-menu.md) to learn more about manipulating menu items.
{{else if UI == "BlazorWebApp"}}
Replace the `Index.razor` content in the `Pages/Ordering` folder of the `ModularCrm.Ordering.Blazor` project with the following code block:
> Blazor WebApp placeholder screenshot file: `images/vscode-ordering-index-razor-blazor-webapp.png`
````razor
@page "/ordering"
@using System.Collections.Generic
@using System.Threading.Tasks
@using ModularCrm.Ordering
@inject IOrderAppService OrderAppService
<h1>Orders</h1>
<Card>
<CardBody>
<ListGroup>
@foreach (var order in Orders)
{
<ListGroupItem>
<strong>Customer:</strong> @order.CustomerName <br />
<strong>Product:</strong> @order.ProductId <br />
<strong>State:</strong> @order.State
</ListGroupItem>
}
</ListGroup>
</CardBody>
</Card>
@code {
private List<OrderDto> Orders { get; set; } = new();
protected override async Task OnInitializedAsync()
{
Orders = await OrderAppService.GetListAsync();
}
}
````
This page shows a list of orders on the UI. You haven't created a UI to create new orders, and we will not do it to keep this tutorial simple. If you want to learn how to create advanced UIs with ABP, please follow the [Book Store tutorial](../book-store/index.md).
### Editing the Menu Item
ABP provides a modular navigation [menu system](../../framework/ui/blazor/navigation-menu.md) where each module can contribute to the main menu dynamically.
Edit the `OrderingMenuContributor` class in the `ModularCrm.Ordering.Blazor` project:
````csharp
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
namespace ModularCrm.Ordering.Blazor.Menus;
public class OrderingMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
context.Menu.AddItem(
new ApplicationMenuItem(
OrderingMenus.Prefix, // Unique menu id
"Orders", // Menu display text
"/ordering", // URL
"fa-solid fa-basket-shopping" // Icon CSS class
)
);
return Task.CompletedTask;
}
}
````
`OrderingMenuContributor` implements the `IMenuContributor` interface, which forces us to implement the `ConfigureMenuAsync` method. In that method, you can manipulate the menu items (add new menu items, remove existing menu items or change the properties of existing menu items). The `ConfigureMenuAsync` method is executed whenever the menu is rendered on the UI, so you can dynamically decide how to manipulate the menu items.
> You can check the [menu documentation](../../framework/ui/blazor/navigation-menu.md) to learn more about manipulating menu items.
{{end}}
### Building the Application
Now, you will run the application to see the result. Please stop the application if it is already running. Then open the *Solution Runner* panel, right-click the `ModularCrm` application, and select the *Build* -> *Graph Build* command:

55
docs/en/tutorials/modular-crm/part-06.md

@ -7,6 +7,13 @@
# Integrating the Modules: Implementing Integration Services
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -138,7 +145,11 @@ Open the ABP Studio UI and stop the application if it is already running. Then o
In the opening dialog, select the *This solution* tab, find and check the `ModularCrm.Catalog.Contracts` package and click the OK button:
{{if UI == "MVC"}}
![abp-studio-add-package-reference-dialog-3](images/abp-studio-add-package-reference-dialog-3.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-add-package-reference-dialog-3](images/abp-studio-add-package-reference-dialog-3-blazor-webapp.png)
{{end}}
ABP Studio adds the package reference and arranges the [module](../../framework/architecture/modularity/basics.md) dependency.
@ -249,7 +260,9 @@ Let's see what we've changed:
* In the last line, we are converting the product list to a dictionary, where the key is `Guid Id` and the value is `string Name`. That way, we can easily find a product's name with its ID.
* Finally, we are mapping the orders to `OrderDto` objects and setting the product name by looking up the product ID in the dictionary.
Open the `Index.cshtml` file, and change the `@order.ProductId` part by `@Order.ProductName` to write the product name instead of the product ID. The final `Index.cshtml` content should be the following:
{{if UI == "MVC"}}
Open the `Index.cshtml` file, and change the `@order.ProductId` part to `@order.ProductName` to write the product name instead of the product ID. The final `Index.cshtml` content should be the following:
````html
@page
@ -273,6 +286,46 @@ Open the `Index.cshtml` file, and change the `@order.ProductId` part by `@Order.
</abp-card>
````
{{else if UI == "BlazorWebApp"}}
Open the `Index.razor` file, and change the `@order.ProductId` part to `@order.ProductName` to write the product name instead of the product ID. The final `Index.razor` content should be the following:
````razor
@page "/ordering"
@using System.Collections.Generic
@using System.Threading.Tasks
@using ModularCrm.Ordering
@inject IOrderAppService OrderAppService
<h1>Orders</h1>
<Card>
<CardBody>
<ListGroup>
@foreach (var order in Orders)
{
<ListGroupItem>
<strong>Customer:</strong> @order.CustomerName <br />
<strong>Product:</strong> @order.ProductName <br />
<strong>State:</strong> @order.State
</ListGroupItem>
}
</ListGroup>
</CardBody>
</Card>
@code {
private List<OrderDto> Orders { get; set; } = new();
protected override async Task OnInitializedAsync()
{
Orders = await OrderAppService.GetListAsync();
}
}
````
{{end}}
That's all. Now, you can graph build the main application and run it in ABP Studio to see the result:
![abp-studio-browser-list-of-orders-with-product-name](images/abp-studio-browser-list-of-orders-with-product-name.png)

15
docs/en/tutorials/modular-crm/part-07.md

@ -7,6 +7,13 @@
# Integrating the Modules: Communication via Messages (Events)
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{
@ -158,13 +165,21 @@ In the opening dialog, find and select the `ModularCrm.Ordering` module, check t
Once you click the OK button, the Ordering module is imported to the Catalog module, and an installation dialog is open:
{{if UI == "MVC"}}
![abp-studio-install-module-dialog-for-ordering](images/abp-studio-install-module-dialog-for-ordering-v2.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-install-module-dialog-for-ordering](images/abp-studio-install-module-dialog-for-ordering-v2-blazor-webapp.png)
{{end}}
Here, select the `ModularCrm.Ordering.Contracts` package on the left side (because we want to add that package reference) and `ModularCrm.Catalog` package on the middle area (because we want to add the package reference to that project). Also, select the `ModularCrm.Ordering` package on the right side, and unselect all packages on the middle area (we don't need the implementation or any other packages). Then, click the OK button to finish the installation operation.
You can check the ABP Studio's *Solution Explorer* panel to see the module import and the project reference (dependency).
{{if UI == "MVC"}}
![abp-studio-imports-and-dependencies](images/abp-studio-imports-and-dependencies-v2.png)
{{else if UI == "BlazorWebApp"}}
![abp-studio-imports-and-dependencies](images/abp-studio-imports-and-dependencies-v2-blazor-webapp.png)
{{end}}
### Handling the `OrderPlacedEto` Event

7
docs/en/tutorials/modular-crm/part-08.md

@ -7,6 +7,13 @@
# Integrating the Modules: Joining the Products and Orders Data
````json
//[doc-params]
{
"UI": ["MVC","BlazorWebApp"]
}
````
````json
//[doc-nav]
{

1538
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.Designer.cs

File diff suppressed because it is too large

160
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20260227074745_ABP10_2.cs

@ -0,0 +1,160 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Migrations
{
/// <inheritdoc />
public partial class ABP10_2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AbpPermissions_Name",
table: "AbpPermissions");
migrationBuilder.AddColumn<DateTimeOffset>(
name: "LastSignInTime",
table: "AbpUsers",
type: "datetimeoffset",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "Leaved",
table: "AbpUsers",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AlterColumn<string>(
name: "GroupName",
table: "AbpPermissions",
type: "nvarchar(128)",
maxLength: 128,
nullable: true,
oldClrType: typeof(string),
oldType: "nvarchar(128)",
oldMaxLength: 128);
migrationBuilder.AddColumn<string>(
name: "ManagementPermissionName",
table: "AbpPermissions",
type: "nvarchar(128)",
maxLength: 128,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "ResourceName",
table: "AbpPermissions",
type: "nvarchar(256)",
maxLength: 256,
nullable: true);
migrationBuilder.CreateTable(
name: "AbpResourcePermissionGrants",
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),
ResourceName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
ResourceKey = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpResourcePermissionGrants", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpUserPasskeys",
columns: table => new
{
CredentialId = table.Column<byte[]>(type: "varbinary(1024)", maxLength: 1024, nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Data = table.Column<string>(type: "nvarchar(max)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpUserPasskeys", x => x.CredentialId);
table.ForeignKey(
name: "FK_AbpUserPasskeys_AbpUsers_UserId",
column: x => x.UserId,
principalTable: "AbpUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AbpPermissions_ResourceName_Name",
table: "AbpPermissions",
columns: new[] { "ResourceName", "Name" },
unique: true,
filter: "[ResourceName] IS NOT NULL");
migrationBuilder.CreateIndex(
name: "IX_AbpResourcePermissionGrants_TenantId_Name_ResourceName_ResourceKey_ProviderName_ProviderKey",
table: "AbpResourcePermissionGrants",
columns: new[] { "TenantId", "Name", "ResourceName", "ResourceKey", "ProviderName", "ProviderKey" },
unique: true,
filter: "[TenantId] IS NOT NULL");
migrationBuilder.CreateIndex(
name: "IX_AbpUserPasskeys_UserId",
table: "AbpUserPasskeys",
column: "UserId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpResourcePermissionGrants");
migrationBuilder.DropTable(
name: "AbpUserPasskeys");
migrationBuilder.DropIndex(
name: "IX_AbpPermissions_ResourceName_Name",
table: "AbpPermissions");
migrationBuilder.DropColumn(
name: "LastSignInTime",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "Leaved",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "ManagementPermissionName",
table: "AbpPermissions");
migrationBuilder.DropColumn(
name: "ResourceName",
table: "AbpPermissions");
migrationBuilder.AlterColumn<string>(
name: "GroupName",
table: "AbpPermissions",
type: "nvarchar(128)",
maxLength: 128,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "nvarchar(128)",
oldMaxLength: 128,
oldNullable: true);
migrationBuilder.CreateIndex(
name: "IX_AbpPermissions_Name",
table: "AbpPermissions",
column: "Name",
unique: true);
}
}
}

138
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs

@ -19,7 +19,7 @@ namespace Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("ProductVersion", "10.0.0-rc.2.25502.107")
.HasAnnotation("ProductVersion", "10.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
@ -482,6 +482,15 @@ namespace Migrations
b.Property<DateTimeOffset?>("LastPasswordChangeTime")
.HasColumnType("datetimeoffset");
b.Property<DateTimeOffset?>("LastSignInTime")
.HasColumnType("datetimeoffset");
b.Property<bool>("Leaved")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("Leaved");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
@ -678,6 +687,26 @@ namespace Migrations
b.ToTable("AbpUserOrganizationUnits", (string)null);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasskey", b =>
{
b.Property<byte[]>("CredentialId")
.HasMaxLength(1024)
.HasColumnType("varbinary(1024)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.HasKey("CredentialId");
b.HasIndex("UserId");
b.ToTable("AbpUserPasskeys", (string)null);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasswordHistory", b =>
{
b.Property<Guid>("UserId")
@ -865,13 +894,16 @@ namespace Migrations
.HasColumnName("ExtraProperties");
b.Property<string>("GroupName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<bool>("IsEnabled")
.HasColumnType("bit");
b.Property<string>("ManagementPermissionName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<byte>("MultiTenancySide")
.HasColumnType("tinyint");
@ -888,6 +920,10 @@ namespace Migrations
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ResourceName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("StateCheckers")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
@ -896,8 +932,9 @@ namespace Migrations
b.HasIndex("GroupName");
b.HasIndex("Name")
.IsUnique();
b.HasIndex("ResourceName", "Name")
.IsUnique()
.HasFilter("[ResourceName] IS NOT NULL");
b.ToTable("AbpPermissions", (string)null);
});
@ -964,6 +1001,50 @@ namespace Migrations
b.ToTable("AbpPermissionGroups", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.ResourcePermissionGrant", 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<string>("ResourceKey")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ResourceName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name", "ResourceName", "ResourceKey", "ProviderName", "ProviderKey")
.IsUnique()
.HasFilter("[TenantId] IS NOT NULL");
b.ToTable("AbpResourcePermissionGrants", (string)null);
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
@ -1292,6 +1373,53 @@ namespace Migrations
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasskey", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Passkeys")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.OwnsOne("Volo.Abp.Identity.IdentityPasskeyData", "Data", b1 =>
{
b1.Property<byte[]>("IdentityUserPasskeyCredentialId");
b1.Property<byte[]>("AttestationObject");
b1.Property<byte[]>("ClientDataJson");
b1.Property<DateTimeOffset>("CreatedAt");
b1.Property<bool>("IsBackedUp");
b1.Property<bool>("IsBackupEligible");
b1.Property<bool>("IsUserVerified");
b1.Property<string>("Name");
b1.Property<byte[]>("PublicKey");
b1.Property<long>("SignCount");
b1.PrimitiveCollection<string>("Transports");
b1.HasKey("IdentityUserPasskeyCredentialId");
b1.ToTable("AbpUserPasskeys");
b1
.ToJson("Data")
.HasColumnType("nvarchar(max)");
b1.WithOwner()
.HasForeignKey("IdentityUserPasskeyCredentialId");
});
b.Navigation("Data");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasswordHistory", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
@ -1378,6 +1506,8 @@ namespace Migrations
b.Navigation("OrganizationUnits");
b.Navigation("Passkeys");
b.Navigation("PasswordHistories");
b.Navigation("Roles");

2
modules/docs/app/VoloDocs.Migrator/appsettings.json

@ -1,3 +1,3 @@
{
"ConnectionString": "Server=localhost;Database=VoloDocs;Trusted_Connection=True;TrustServerCertificate=True",
"ConnectionString": "Server=(LocalDb)\\MSSQLLocalDB;Database=VoloDocs;Trusted_Connection=True;TrustServerCertificate=True"
}

3
modules/docs/app/VoloDocs.Web/VoloDocs.Web.abppkg

@ -1,3 +1,4 @@
{
"role": "host.mvc"
"role": "host.mvc",
"projectId": "47142bf8-4bb8-41c5-9900-990a97a67e8a"
}

2
modules/docs/app/VoloDocs.Web/appsettings.json

@ -12,7 +12,7 @@
"Redis": {
"Configuration": "127.0.0.1"
},
"ConnectionString": "Server=localhost;Database=VoloDocs;Trusted_Connection=True;TrustServerCertificate=True",
"ConnectionString": "Server=(LocalDb)\\MSSQLLocalDB;Database=VoloDocs;Trusted_Connection=True;TrustServerCertificate=True",
"ElasticSearch": {
"Url": "http://localhost:9200"
},

Loading…
Cancel
Save