Browse Source

Merge branch 'dev' into 21866

pull/21873/head
maliming 2 years ago
parent
commit
436dfebd79
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 20
      .github/workflows/auto-pr.yml
  2. 8
      Directory.Packages.props
  3. 2
      docs/en/deployment/configuring-openIddict.md
  4. 0
      docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-generated-tests-ef-core.png
  5. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-generated-tests-mongo.png
  6. 0
      docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-solution-test-projects-ef-core.png
  7. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-solution-test-projects-mongo.png
  8. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-angular.png
  9. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-blazor.png
  10. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-mauiblazor.png
  11. 0
      docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-mvc.png
  12. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/bookstore-test-succeed-ef-core.png
  13. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/bookstore-test-succeed-mongo.png
  14. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/studio-browser-suite.png
  15. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/suite-book-entity-5.png
  16. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/suite-book-pages-1.png
  17. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/suite-book-pages-browser.png
  18. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/suite-custom-code-result.png
  19. 0
      docs/en/tutorials/book-store-with-abp-suite/images/suite-repository-custom-code-ef-core.png
  20. BIN
      docs/en/tutorials/book-store-with-abp-suite/images/suite-repository-custom-code-mongo.png
  21. 12
      docs/en/tutorials/book-store-with-abp-suite/index.md
  22. 16
      docs/en/tutorials/book-store-with-abp-suite/part-01.md
  23. 32
      docs/en/tutorials/book-store-with-abp-suite/part-02.md
  24. 34
      docs/en/tutorials/book-store-with-abp-suite/part-03.md
  25. 58
      docs/en/tutorials/book-store-with-abp-suite/part-04.md
  26. 62
      docs/en/tutorials/book-store-with-abp-suite/part-05.md
  27. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabTagHelperService.cs
  28. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs
  29. 4
      framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs
  30. 102
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/FirstLevelNavMenuItem.razor
  31. 22
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/FirstLevelNavMenuItem.razor.cs
  32. 79
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/SecondLevelNavMenuItem.razor
  33. 24
      modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/SecondLevelNavMenuItem.razor.cs
  34. 40
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js
  35. 4
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj
  36. 4
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
  37. 4
      templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/MyCompanyName.MyProjectName.Blazor.WebAssembly.Client.csproj
  38. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/MyCompanyName.MyProjectName.Blazor.Client.csproj
  39. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj
  40. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj
  41. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/MyCompanyName.MyProjectName.Blazor.WebApp.Client.csproj
  42. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client.csproj
  43. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.csproj
  44. 4
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp/MyCompanyName.MyProjectName.Blazor.WebApp.csproj
  45. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/MyCompanyName.MyProjectName.Blazor.Host.Client.csproj
  46. 4
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyCompanyName.MyProjectName.Blazor.Server.Host.csproj

20
.github/workflows/auto-pr.yml

@ -1,13 +1,13 @@
name: Merge branch dev with prerel-9.1
name: Merge branch dev with rel-9.1
on:
push:
branches:
- prerel-9.1
- rel-9.1
permissions:
contents: read
jobs:
merge-dev-with-prerel-9-1:
merge-dev-with-rel-9-1:
permissions:
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR
@ -18,14 +18,14 @@ jobs:
ref: dev
- name: Reset promotion branch
run: |
git fetch origin prerel-9.1:prerel-9.1
git reset --hard prerel-9.1
git fetch origin rel-9.1:rel-9.1
git reset --hard rel-9.1
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
branch: auto-merge/prerel-9-0/${{github.run_number}}
title: Merge branch dev with prerel-9.1
body: This PR generated automatically to merge dev with prerel-9.1. Please review the changed files before merging to prevent any errors that may occur.
branch: auto-merge/rel-9-1/${{github.run_number}}
title: Merge branch dev with rel-9.1
body: This PR generated automatically to merge dev with rel-9.1. Please review the changed files before merging to prevent any errors that may occur.
reviewers: maliming
draft: true
token: ${{ github.token }}
@ -34,5 +34,5 @@ jobs:
GH_TOKEN: ${{ secrets.BOT_SECRET }}
run: |
gh pr ready
gh pr review auto-merge/prerel-9-0/${{github.run_number}} --approve
gh pr merge auto-merge/prerel-9-0/${{github.run_number}} --merge --auto --delete-branch
gh pr review auto-merge/rel-9-1/${{github.run_number}} --approve
gh pr merge auto-merge/rel-9-1/${{github.run_number}} --merge --auto --delete-branch

8
Directory.Packages.props

@ -17,10 +17,10 @@
<PackageVersion Include="AWSSDK.SecurityToken" Version="3.7.401.16" />
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.1" />
<PackageVersion Include="Azure.Storage.Blobs" Version="12.22.1" />
<PackageVersion Include="Blazorise" Version="1.6.2" />
<PackageVersion Include="Blazorise.Components" Version="1.6.2" />
<PackageVersion Include="Blazorise.DataGrid" Version="1.6.2" />
<PackageVersion Include="Blazorise.Snackbar" Version="1.6.2" />
<PackageVersion Include="Blazorise" Version="1.7.2" />
<PackageVersion Include="Blazorise.Components" Version="1.7.2" />
<PackageVersion Include="Blazorise.DataGrid" Version="1.7.2" />
<PackageVersion Include="Blazorise.Snackbar" Version="1.7.2" />
<PackageVersion Include="Castle.Core" Version="5.1.1" />
<PackageVersion Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
<PackageVersion Include="CommonMark.NET" Version="0.15.1" />

2
docs/en/deployment/configuring-openIddict.md

@ -48,4 +48,6 @@ You can use the `dotnet dev-certs https -v -ep openiddict.pfx -p 00000000-0000-0
> It is recommended to use **two** RSA certificates, distinct from the certificate(s) used for HTTPS: one for encryption, one for signing.
> If you encounter a deployment error on IIS that says **File not found** even though the file exists, it is recommended to set the application pool’s advanced settings **Load User Profile** to **True** to resolve the issue.
For more information, please refer to: https://documentation.openiddict.com/configuration/encryption-and-signing-credentials.html#registering-a-certificate-recommended-for-production-ready-scenarios

0
docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-generated-tests.png → docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-generated-tests-ef-core.png

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-generated-tests-mongo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

0
docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-solution-test-projects.png → docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-solution-test-projects-ef-core.png

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/abp-suite-solution-test-projects-mongo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-angular.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-blazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-mauiblazor.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

0
docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app.png → docs/en/tutorials/book-store-with-abp-suite/images/book-store-studio-run-app-mvc.png

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/bookstore-test-succeed.png → docs/en/tutorials/book-store-with-abp-suite/images/bookstore-test-succeed-ef-core.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 68 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/bookstore-test-succeed-mongo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/studio-browser-suite.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 142 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/suite-book-entity-5.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/suite-book-pages-1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/suite-book-pages-browser.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/suite-custom-code-result.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 80 KiB

0
docs/en/tutorials/book-store-with-abp-suite/images/suite-repository-custom-code.png → docs/en/tutorials/book-store-with-abp-suite/images/suite-repository-custom-code-ef-core.png

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

BIN
docs/en/tutorials/book-store-with-abp-suite/images/suite-repository-custom-code-mongo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

12
docs/en/tutorials/book-store-with-abp-suite/index.md

@ -1,5 +1,13 @@
# Web Application Development Tutorial (with ABP Suite)
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG","MAUIBlazor"],
"DB": ["EF", "Mongo"]
}
````
````json
//[doc-nav]
{
@ -18,8 +26,8 @@
In this tutorial series, you will build an ABP based web application named `Acme.BookStore`. This application is used to manage a list of books and their authors. It is developed using the following technologies:
* **Entity Framework Core** as the database provider.
* **MVC** as the UI Framework.
* **{{DB_Value}}** as the database provider.
* **{{UI_Value}}** as the UI Framework.
This tutorial is organized as the following parts:

16
docs/en/tutorials/book-store-with-abp-suite/part-01.md

@ -1,5 +1,13 @@
# Web Application Development Tutorial (with ABP Suite) - Part 1: Creating the Solution
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG","MAUIBlazor"],
"DB": ["EF", "Mongo"]
}
````
````json
//[doc-nav]
{
@ -20,10 +28,10 @@ You can use the following configurations:
* **Solution Template:** Application (Layered)
* **Solution Name:** `Acme.BookStore`
* **UI Framework:** {{if UI=="MVC"}} ASP.NET Core MVC / Razor Pages {{end}}
* **UI Framework:** {{UI_Value}}
* **UI Theme:** LeptonX
* **Mobile Framework:** None
* **Database Provider:** {{if DB=="EF"}} Entity Framework Core {{end}}
* **Database Provider:** {{DB_Value}}
* **Public Website:** No
* **Tiered:** No
@ -31,10 +39,6 @@ You can select the other options based on your preference.
> **Please complete the [Get Started](../../get-started/layered-web-application.md) guide and run the web application before going further.**
The initial solution structure should be like the following in the ABP Studio's [Solution Explorer](../../studio/solution-explorer.md):
![](./images/book-store-suite-solution-explorer.png)
## Summary
We've created the initial layered monolith solution. In the next part, we will learn how to create entities, and generate CRUD pages based on the specified options (including tests, UI, customizable code support etc.) with [ABP Suite](../../suite/index.md).

32
docs/en/tutorials/book-store-with-abp-suite/part-02.md

@ -1,5 +1,13 @@
# Web Application Development Tutorial (with ABP Suite) - Part 2: Creating the Books
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG","MAUIBlazor"],
"DB": ["EF", "Mongo"]
}
````
````json
//[doc-nav]
{
@ -87,9 +95,7 @@ You can leave the other configurations as default.
> ABP Suite allows you to define properties with a great range of options, for example, you can specify the property type as *string*, *int*, *float*, *Guid*, *DateTime*, and even *File* (for file upload) and also you can set any options while defining your properties, such as specifying it as *required*, or *nullable*, setting *max-min length*, *default value* and more...
After that, you can click the **Save and Generate** button to start the code generation process:
![](./images/suite-book-entity-5.png)
After that, you can click the **Save and Generate** button to start the code generation process.
ABP Suite will generate the necessary code for you. It generates:
@ -104,11 +110,27 @@ ABP Suite will generate the necessary code for you. It generates:
It will take some time to complete the process. After the process is completed, you will see a success message, you can click the *Ok* button, and then run the application by clicking the *Start* button (or alternatively, directly clicking the *run* icon) in the *Solution Runner* panel:
![](./images/book-store-studio-run-app.png)
{{ if UI == "MVC" }}
![](./images/book-store-studio-run-app-mvc.png)
{{ else if UI == "Angular" }}
![](./images/book-store-studio-run-app-angular.png)
{{ else if UI == "MAUIBlazor" }}
![](./images/book-store-studio-run-app-mauiblazor.png)
{{ else }}
![](./images/book-store-studio-run-app-blazor.png)
{{ end }}
After the application is started, you can right-click and *Browse* on the application to open it in the ABP Studio's pre-integrated browser. You can see the Books page in the following figure with a single record:
![](./images/suite-book-pages-1.png)
![](./images/suite-book-pages-browser.png)
On this page, you can create a new book, update an existing book, delete a book, export all records (or the filtered records) to excel, filter the records by using the advanced filter section, bulk delete multiple records and so on.

34
docs/en/tutorials/book-store-with-abp-suite/part-03.md

@ -1,5 +1,13 @@
# Web Application Development Tutorial (with ABP Suite) - Part 3: Creating the Authors
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG","MAUIBlazor"],
"DB": ["EF", "Mongo"]
}
````
````json
//[doc-nav]
{
@ -24,11 +32,11 @@ After generating the all necessary code for the `Book` entity, and testing the *
Click the entity selection box in the top right of the *CRUD page generation* page, and select the *-New entity-*:
![](/images/suite-author-new-entity.png)
![](./images/suite-author-new-entity.png)
Then, you can type `Author` for the *Name* field and leave the other options as is (you can change the menu icon as **pen** for a proper menu icon, and/or other options, if you wish). ABP Suite automatically calculates proper values for the rest of the inputs for you:
![](/images/suite-author-entity-1.png)
![](./images/suite-author-entity-1.png)
ABP Suite sets:
@ -52,13 +60,27 @@ You can leave the other configurations as default.
> **Note:** All properties are marked as **filterable** by default, and they appear in the advanced filter section because of that. You can set any properties you want as **not filterable** and then the related property will be removed from the advanced filter section and code will be generated accordingly.
You can click the **Save and Generate** button to start the code generation process:
![](./images/suite-book-entity-5.png)
You can click the **Save and Generate** button to start the code generation process.
ABP Suite will generate the necessary code for you. It will take some time to complete the process. After the process is completed, you will see a success message, you can click the *Ok* button, and then run the application by clicking the *Start* button (or alternatively, directly clicking the *run* icon) in the *Solution Runner* panel:
![](./images/book-store-studio-run-app.png)
{{ if UI == "MVC" }}
![](./images/book-store-studio-run-app-mvc.png)
{{ else if UI == "Angular" }}
![](./images/book-store-studio-run-app-angular.png)
{{ else if UI == "MAUIBlazor" }}
![](./images/book-store-studio-run-app-mauiblazor.png)
{{ else }}
![](./images/book-store-studio-run-app-blazor.png)
{{ end }}
After the application is started, you can right-click and *Browse* on the application to open it in the ABP Studio's pre-integrated browser and try to add a new author:

58
docs/en/tutorials/book-store-with-abp-suite/part-04.md

@ -1,5 +1,13 @@
# Web Application Development Tutorial (with ABP Suite) - Part 4: Book to Author Relation
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG","MAUIBlazor"],
"DB": ["EF", "Mongo"]
}
````
````json
//[doc-nav]
{
@ -51,7 +59,23 @@ After, specifying the metadata, you can click the *Ok* button to close the modal
It will take some time to complete the process. After the process is completed, you will see a success message, you can click the *Ok* button, and then run the application by clicking the *Start* button (or alternatively, directly clicking the *run* icon) in the *Solution Runner* panel:
![](./images/book-store-studio-run-app.png)
{{ if UI == "MVC" }}
![](./images/book-store-studio-run-app-mvc.png)
{{ else if UI == "Angular" }}
![](./images/book-store-studio-run-app-angular.png)
{{ else if UI == "MAUIBlazor" }}
![](./images/book-store-studio-run-app-mauiblazor.png)
{{ else }}
![](./images/book-store-studio-run-app-blazor.png)
{{ end }}
After the application is started, you can right-click and *Browse* on the application to open it in the ABP Studio's pre-integrated browser. You can first create an author and then create a book with the author for testing:
@ -65,15 +89,29 @@ Also, notice that, in the advanced filter section, there is an **Author** dropdo
Since you completed the bookstore application, now we can check the generated tests, and run them to see if all of them pass or not.
There are several test projects in the solution:
There are several test projects in the solution (slightly differs based on your _UI_ and _Database_ selection):
{{ if DB == "EF" }}
![](./images/abp-suite-solution-test-projects-ef-core.png)
![](./images/abp-suite-solution-test-projects.png)
{{ else if DB == "Mongo" }}
> Test projects slightly differs based on your UI and Database selection. For example, if you select MongoDB, then the `Acme.BookStore.EntityFrameworkCore.Tests` will be `Acme.BookStore.MongoDB.Tests`.
![](./images/abp-suite-solution-test-projects-mongo.png)
{{ end }}
ABP Suite generated unit & integration tests, for the `Book` & `Author` entities. If you open the **Test explorer** in your IDE, you will see the following tests are generated:
![](./images/abp-suite-generated-tests.png)
{{ if DB == "EF" }}
![](./images/abp-suite-generated-tests-ef-core.png)
{{ else if DB == "Mongo" }}
![](./images/abp-suite-generated-tests-mongo.png)
{{ end }}
ABP Suite generated tests for repository implementations & application service implementations for the generated code, if you enable *Create unit & integration tests* option, while creating the entity. Since, you already did that in the previous parts, it generated the all required tests for the entities.
@ -155,7 +193,15 @@ Since ABP Suite generated the test data seed contributors for each entity, you h
Let's execute all tests, and see the results:
![](./images/bookstore-test-succeed.png)
{{ if DB == "EF" }}
![](./images/bookstore-test-succeed-ef-core.png)
{{ else if DB == "Mongo" }}
![](./images/bookstore-test-succeed-mongo.png)
{{ end }}
## Summary

62
docs/en/tutorials/book-store-with-abp-suite/part-05.md

@ -1,5 +1,13 @@
# Web Application Development Tutorial (with ABP Suite) - Part 5: Customizing the Generated Code
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer", "BlazorWebApp","NG","MAUIBlazor"],
"DB": ["EF", "Mongo"]
}
````
````json
//[doc-nav]
{
@ -28,12 +36,22 @@ On the C# side, ABP Suite adds abstract base classes for entities, application s
You can write your custom code in those classes (with the `*.Extended.cs` extension) and next time when you need to re-generate the entity, your custom code will not be overridden (only the base abstract classes will be re-generated and your changes on Suite will be respected):
![](./images/suite-repository-custom-code.png)
{{ if DB == "EF" }}
![](./images/suite-repository-custom-code-ef-core.png)
{{ else if DB == "Mongo" }}
![](./images/suite-repository-custom-code-mongo.png)
> For example, you can create a new repository method like in the example above, and in the next CRUD page generation, you will ABP Suite won't override your custom code.
{{ end }}
> For example, you can create a new repository method like in the example above, and in the next CRUD page generation, ABP Suite won't override your custom code.
On the UI side, ABP Suite provides convenient comment placeholders within pages for MVC, Blazor, and Angular UIs. These comment sections serve as hook points where you can add your custom code.
{{ if UI == "MVC"}}
For example, if you open the *Books/Index.cshtml* file in your IDE, you will see those placeholders like following:
```xml
@ -50,6 +68,46 @@ For example, if you open the *Books/Index.cshtml* file in your IDE, you will see
You can write your custom codes between the _**<suite-custom-code-block-n></suite-custom-code-block-n>**_ placeholders and you can also extend these placeholders by customizing the [ABP Suite templates](../../suite/editing-templates.md).
{{ else if UI == "Angular" }}
Similar to services, there are two types of components:
- `abstract.component.ts`
- `component.ts`
The `.abstract.component.ts` file is recreated with each execution of schematics, while the code for `.component.ts` files is generated only once, so your custom changes are preserved.
When the _Customizable code_ is enabled, ABP Suite introduces custom comment placeholders in the HTML file as follows:
```html
<!--<suite-custom-code-block-0>-->
<!--</suite-custom-code-block-0>-->
```
{{ else }}
For example, if you open the *Books.razor* file in your IDE, you will see those placeholders like following:
```xml
@* ************************* PAGE HEADER ************************* *@
<PageHeader Title="@L["Books"]" BreadcrumbItems="BreadcrumbItems" Toolbar="Toolbar">
</PageHeader>
@* ************************* SEARCH ************************* *@
<Card>
<CardBody>
@*//<suite-custom-code-block-1>*@
@*//</suite-custom-code-block-1>*@
<Row>
@*- Code omitted for brevity *@
```
You can write your custom codes between the _**<suite-custom-code-block-n></suite-custom-code-block-n>**_ placeholders and you can also extend these placeholders by customizing the [ABP Suite templates](../../suite/editing-templates.md).
{{ end }}
> For more information, please refer to [Customizing the Generated Code documentation](../../suite/customizing-the-generated-code.md)
## Implementing Custom Code

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Tab/AbpTabTagHelperService.cs

@ -89,7 +89,7 @@ public class AbpTabTagHelperService : AbpTagHelperService<AbpTabTagHelper>
var id = TagHelper.Name;
var attributes = GetTabContentAttributes(context, output);
var classAttributesAsString = attributes.Where(a => a.Name == "class").ToList().Select(a => a.Name).JoinAsString(" ");
var classAttributesAsString = attributes.Where(a => a.Name == "class").ToList().Select(a => a.Value).JoinAsString(" ");
var otherAttributes = attributes.Where(a => a.Name != "class").ToList();
var wrapper = new TagBuilder("div");

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs

@ -291,7 +291,7 @@ public class AbpIoSourceCodeStore : ISourceCodeStore, ITransientDependency
var result = await response.Content.ReadAsStringAsync();
var versions = JsonSerializer.Deserialize<GithubReleaseVersions>(result);
return templateName.Contains("LeptonX") ?
return (templateName.Contains("LeptonX") || templateName.Contains("lepton-x")) ?
versions.LeptonXVersions.Any(v => v.Name == version) :
versions.FrameworkAndCommercialVersions.Any(v => v.Name == version);
}

4
framework/src/Volo.Abp.Core/Volo/Abp/Modularity/AbpModuleHelper.cs

@ -11,7 +11,7 @@ public static class AbpModuleHelper
public static List<Type> FindAllModuleTypes(Type startupModuleType, ILogger? logger)
{
var moduleTypes = new List<Type>();
logger?.Log(LogLevel.Information, "Loaded ABP modules:");
logger?.Log(LogLevel.Debug, "Loaded ABP modules:");
AddModuleAndDependenciesRecursively(moduleTypes, startupModuleType, logger);
return moduleTypes;
}
@ -72,7 +72,7 @@ public static class AbpModuleHelper
}
moduleTypes.Add(moduleType);
logger?.Log(LogLevel.Information, $"{new string(' ', depth * 2)}- {moduleType.FullName}");
logger?.Log(LogLevel.Debug, $"{new string(' ', depth * 2)}- {moduleType.FullName}");
foreach (var dependedModuleType in FindDependedModuleTypes(moduleType))
{

102
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/FirstLevelNavMenuItem.razor

@ -1,61 +1,67 @@
@using Volo.Abp.UI.Navigation
@using Volo.Abp.UI.Navigation
@{
var elementId = MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_");
var cssClass = string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass;
var disabled = MenuItem.IsDisabled ? "disabled" : string.Empty;
var url = MenuItem.Url == null ? "#" : MenuItem.Url.TrimStart('/', '~');
var customComponentType = MenuItem.GetComponentTypeOrDefault();
}
@if (MenuItem.IsLeaf)
@if (customComponentType != null && typeof(ComponentBase).IsAssignableFrom(customComponentType))
{
if (customComponentType != null && typeof(ComponentBase).IsAssignableFrom(customComponentType))
{
<DynamicComponent Type="@customComponentType" />
}
else if (MenuItem.Url != null)
{
<li class="nav-item @cssClass @disabled" id="@elementId">
<a class="nav-link" href="@url" target="@MenuItem.Target">
@if (MenuItem.Icon != null)
{
if (MenuItem.Icon.StartsWith("fa"))
{
<i class="@MenuItem.Icon me-1"></i>
}
}
@MenuItem.DisplayName
</a>
</li>
}
<DynamicComponent Type="@customComponentType" />
}
else
{
<li class="nav-item">
<div class="dropdown">
@if (customComponentType != null && typeof(ComponentBase).IsAssignableFrom(customComponentType))
{
<DynamicComponent Type="@customComponentType" />
}
else
{
<a class="nav-link dropdown-toggle" @onclick="ToggleSubMenu" id="Menu_@(MenuItem.Name)" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@if (MenuItem.Icon != null)
{
if (MenuItem.Icon.StartsWith("fa"))
<Dropdown @ref="_dropdown"
Class="@(string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass)"
ElementId="@(MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_"))"
Disabled="MenuItem.IsDisabled">
<DropdownToggle ToggleIconVisible="false">
<ChildContent>
@if (MenuItem.Url != null)
{
var url = MenuItem.Url == null ? "#" : MenuItem.Url.TrimStart('/', '~');
<a class="text-white text-decoration-none" href="@url" target="@MenuItem.Target">
@if (MenuItem.Icon != null && MenuItem.Icon.StartsWith("fa"))
{
<i class="@MenuItem.Icon me-1"></i>
}
}
@MenuItem.DisplayName
</a>
}
<div class="dropdown-menu border-0 shadow-sm @(IsSubMenuOpen ? "show" : "")" aria-labelledby="Menu_@(MenuItem.Name)">
@foreach (var childMenuItem in MenuItem.Items)
@MenuItem.DisplayName
</a>
}
else
{
<SecondLevelNavMenuItem MenuItem="childMenuItem" />
<a class="text-white text-decoration-none dropdown-toggle">
@if (MenuItem.Icon != null)
{
if (MenuItem.Icon.StartsWith("fa"))
{
<i class="@MenuItem.Icon me-1"></i>
}
}
@MenuItem.DisplayName
</a>
}
</ChildContent>
</DropdownToggle>
<DropdownMenu>
@foreach (var item in MenuItem.Items)
{
if (item.Items.Any())
{
<SecondLevelNavMenuItem MenuItem="item" ParentDropdown="_dropdown" />
}
</div>
</div>
</li>
else
{
var itemUrl = item.Url == null ? "#" : item.Url.TrimStart('/', '~');
<a class="text-black text-decoration-none" href="@itemUrl">
@if (item.Icon != null)
{
<i class="@item.Icon me-1"></i>
}
<span>
@item.DisplayName
</span>
</a>
}
}
</DropdownMenu>
</Dropdown>
}

22
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/FirstLevelNavMenuItem.razor.cs

@ -1,4 +1,5 @@
using System;
using Blazorise;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Volo.Abp.UI.Navigation;
@ -7,31 +8,26 @@ namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic;
public partial class FirstLevelNavMenuItem : IDisposable
{
[Inject] private NavigationManager NavigationManager { get; set; }
[Parameter]
public ApplicationMenuItem MenuItem { get; set; }
public ApplicationMenuItem MenuItem { get; set; } = default!;
private Dropdown _dropdown;
public bool IsSubMenuOpen { get; set; }
[Inject]
private NavigationManager NavigationManager { get; set; }
protected override void OnInitialized()
{
NavigationManager.LocationChanged += OnLocationChanged;
}
private void ToggleSubMenu()
protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
IsSubMenuOpen = !IsSubMenuOpen;
_dropdown?.Hide();
}
public void Dispose()
public virtual void Dispose()
{
NavigationManager.LocationChanged -= OnLocationChanged;
}
private void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
IsSubMenuOpen = false;
InvokeAsync(StateHasChanged);
}
}

79
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/SecondLevelNavMenuItem.razor

@ -1,55 +1,48 @@
@using Volo.Abp.UI.Navigation
@using Volo.Abp.UI.Navigation
@{
var elementId = MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_");
var cssClass = string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass;
var disabled = MenuItem.IsDisabled ? "disabled" : string.Empty;
var url = MenuItem.Url == null ? "#" : MenuItem.Url.TrimStart('/', '~');
var customComponentType = MenuItem.GetComponentTypeOrDefault();
}
@if (MenuItem.IsLeaf)
@if (customComponentType != null && typeof(ComponentBase).IsAssignableFrom(customComponentType))
{
if (customComponentType != null && typeof(ComponentBase).IsAssignableFrom(customComponentType))
{
<DynamicComponent Type="@customComponentType" />
}
else if (MenuItem.Url != null)
{
<a class="dropdown-item @cssClass @disabled" href="@url" target="@MenuItem.Target" id="@elementId">
@if (MenuItem.Icon != null)
{
<i class="@MenuItem.Icon me-1"></i>
}
<span>
@MenuItem.DisplayName
</span>
</a>
}
<DynamicComponent Type="@customComponentType" />
}
else
{
<div class="dropdown-submenu">
@if (customComponentType != null && typeof(ComponentBase).IsAssignableFrom(customComponentType))
{
<DynamicComponent Type="@customComponentType" />
}
else
{
<a role="button" @onclick="ToggleSubMenu" class="btn dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
@if (MenuItem.Icon != null)
<Dropdown @ref="_dropdown"
Class="@(string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass)"
ElementId="@(MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_"))"
Disabled="MenuItem.IsDisabled">
<DropdownToggle Class="me-3">
<ChildContent>
@if (MenuItem.Icon != null && MenuItem.Icon.StartsWith("fa"))
{
<i class="@MenuItem.Icon me-1"></i>
}
<span>
@MenuItem.DisplayName
</span>
</a>
}
<div class="dropdown-menu border-0 shadow-sm @(IsSubMenuOpen ? "show" : "")">
@foreach (var childMenuItem in MenuItem.Items)
@MenuItem.DisplayName
</ChildContent>
</DropdownToggle>
<DropdownMenu>
@foreach (var item in MenuItem.Items)
{
<SecondLevelNavMenuItem MenuItem="@childMenuItem"/>
if (item.Items.Any())
{
<SecondLevelNavMenuItem MenuItem="item" ParentDropdown="_dropdown"/>
}
else
{
var itemUrl = item.Url == null ? "#" : item.Url.TrimStart('/', '~');
<a class="text-black text-decoration-none" href="@itemUrl">
@if (item.Icon != null)
{
<i class="@item.Icon me-1"></i>
}
<span>
@item.DisplayName
</span>
</a>
}
}
</div>
</div>
}
</DropdownMenu>
</Dropdown>
}

24
modules/basic-theme/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/SecondLevelNavMenuItem.razor.cs

@ -1,4 +1,5 @@
using System;
using Blazorise;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Volo.Abp.UI.Navigation;
@ -7,31 +8,30 @@ namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic;
public partial class SecondLevelNavMenuItem : IDisposable
{
[Inject] private NavigationManager NavigationManager { get; set; }
[Parameter]
public ApplicationMenuItem MenuItem { get; set; } = default!;
[Parameter]
public ApplicationMenuItem MenuItem { get; set; }
public Dropdown ParentDropdown { get; set; } = default!;
private Dropdown _dropdown;
public bool IsSubMenuOpen { get; set; }
[Inject]
private NavigationManager NavigationManager { get; set; }
protected override void OnInitialized()
{
NavigationManager.LocationChanged += OnLocationChanged;
}
private void ToggleSubMenu()
protected virtual void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
IsSubMenuOpen = !IsSubMenuOpen;
ParentDropdown?.Hide();
_dropdown?.Hide();
}
public void Dispose()
public virtual void Dispose()
{
NavigationManager.LocationChanged -= OnLocationChanged;
}
private void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
IsSubMenuOpen = false;
InvokeAsync(StateHasChanged);
}
}

40
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js

@ -49,15 +49,10 @@ var doc = doc || {};
return;
}
for(var i = 0; i < lazyLiElements.length; i++){
var $li = $(lazyLiElements[i]);
if($li.has("ul").length === 0){
var $a = $li.find("a");
var node = doc.lazyExpandableNavigation.findNode($a.text(), $a.attr("href"), doc.project.navigation);
node.items.forEach(item => {
doc.lazyExpandableNavigation.renderNodeAsHtml($li, item, true);
})
}
doc.lazyExpandableNavigation.load(lazyLiElements[i]);
var $li = $(lazyLiElements[i]);
var childLazyLiElements = $li.find("li.lazy-expand");
if(childLazyLiElements.length > 0){
doc.lazyExpandableNavigation.isAllLoaded = false;
@ -68,6 +63,23 @@ var doc = doc || {};
}
doc.lazyExpandableNavigation.isAllLoaded = true;
},
load : function(lazyLiEment){
var $li = $(lazyLiEment);
if($li.has("ul").length > 0){
return;
}
var $a = $li.find("a");
var text = $a.contents().filter(function() { return this.nodeType === 3 }).text();
var node = doc.lazyExpandableNavigation.findNode(text, $a.attr("href") , doc.project.navigation);
if(!node || !node.items){
return;
}
node.items.forEach(item => {
doc.lazyExpandableNavigation.renderNodeAsHtml($li, item, true);
})
}
}
@ -370,17 +382,7 @@ var doc = doc || {};
}
});
$("li .lazy-expand").on('click', function(){
var $this = $(this);
if($this.has("ul").length > 0){
return;
}
var $a = $this.find("a");
var node = doc.lazyExpandableNavigation.findNode($a.text(), $a.attr("href") , doc.project.navigation);
node.items.forEach(item => {
doc.lazyExpandableNavigation.renderNodeAsHtml($this, item, true);
})
doc.lazyExpandableNavigation.load(this);
initLazyExpandNavigation();
});
}

4
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyCompanyName.MyProjectName.Blazor.Server.Mongo.csproj

@ -8,8 +8,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
</ItemGroup>

4
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj

@ -8,8 +8,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
</ItemGroup>

4
templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Client/MyCompanyName.MyProjectName.Blazor.WebAssembly.Client.csproj

@ -9,8 +9,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
</ItemGroup>

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Client/MyCompanyName.MyProjectName.Blazor.Client.csproj

@ -12,8 +12,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
</ItemGroup>

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj

@ -14,8 +14,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.0" />

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj

@ -15,8 +15,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
</ItemGroup>

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Client/MyCompanyName.MyProjectName.Blazor.WebApp.Client.csproj

@ -13,8 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
</ItemGroup>

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client.csproj

@ -13,8 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
</ItemGroup>

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered/MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.csproj

@ -16,8 +16,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.0" />

4
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.WebApp/MyCompanyName.MyProjectName.Blazor.WebApp.csproj

@ -16,8 +16,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
</ItemGroup>

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Host.Client/MyCompanyName.MyProjectName.Blazor.Host.Client.csproj

@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
</ItemGroup>

4
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyCompanyName.MyProjectName.Blazor.Server.Host.csproj

@ -13,8 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="Blazorise.Bootstrap5" Version="1.7.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.7.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0" />

Loading…
Cancel
Save