diff --git a/Directory.Packages.props b/Directory.Packages.props
index 01d1a458ca..9b3c349f59 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -114,7 +114,7 @@
-
+
@@ -125,7 +125,7 @@
-
+
diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md
index 75e6a17bb9..61d5986588 100644
--- a/docs/en/cli/index.md
+++ b/docs/en/cli/index.md
@@ -227,15 +227,15 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `--no-kubernetes-configuration` or `-nkc`: Skips the Kubernetes configuration files.
* `--no-social-logins` or `-nsl`: Skipts the social login configuration.
* `--no-tests` or `-ntp`: Does not add test projects.
-* *Module Options*: You can skip some modules if you don't want to add them to your solution (*Available for* ***Team*** *or higher licenses*). Available commands:
+* *Module Options*: You can skip some modules if you don't want to add them to your solution, or include if you want them (*Available for* ***Team*** *or higher licenses*). Available commands:
* `-no-saas`: Skips the Saas module.
* `-no-gdpr`: Skips the GDPR module.
* `-no-openiddict-admin-ui`: Skips the OpenIddict Admin UI module.
* `-no-audit-logging`: Skips the Audit Logging module.
- * `-no-file-management`: Skips the File Management module.
* `-no-language-management`: Skips the Language Management module.
* `-no-text-template-management`: Skips the Text Template Management module.
- * `-no-chat`: Skips the Chat module.
+ * `-file-management`: Includes the File Management module.
+ * `-chat`: Includes the Chat module.
* `--legacy`: Generates a legacy solution.
* `trust-version`: Trusts the user's version and does not check if the version exists or not. If the template with the given version is found in the cache, it will be used, otherwise throws an exception.
diff --git a/docs/en/framework/ui/maui/index.md b/docs/en/framework/ui/maui/index.md
index 69f9518e92..573278a060 100644
--- a/docs/en/framework/ui/maui/index.md
+++ b/docs/en/framework/ui/maui/index.md
@@ -40,6 +40,9 @@ Open a command line terminal and run the `adb reverse` command to expose a port
> You should replace "44305" with the real port.
> You should run the command after starting the emulator.
+> If you don't have a separate installation of Android Debug Bridge, you can open it from **Visual Studio** by following toolbar menu `Tools` > `Android` > `Android Adb Command Prompt`. Android emulator has to be running for this operation.
+
+
### iOS
The iOS simulator uses the host machine network. Therefore, applications running in the simulator can connect to web services running on your local machine via the machines IP address or via the localhost hostname. For example, given a local secure web service that exposes a GET operation via the /api/todoitems/ relative URI, an application running on the iOS simulator can consume the operation by sending a GET request to https://localhost:/api/todoitems/.
diff --git a/docs/en/solution-templates/microservice/guides/add-new-microservice.md b/docs/en/solution-templates/microservice/guides/add-new-microservice.md
index 12c8b527e8..f68f315dd7 100644
--- a/docs/en/solution-templates/microservice/guides/add-new-microservice.md
+++ b/docs/en/solution-templates/microservice/guides/add-new-microservice.md
@@ -1,3 +1 @@
-# ABP Studio Microservice Solution: Adding New Microservices
-
-This document is planned to be written later.
\ No newline at end of file
+> This document is [moved to here](../adding-new-microservices.md).
\ No newline at end of file
diff --git a/docs/en/studio/images/solution-runner/cli-application-context-menu.png b/docs/en/studio/images/solution-runner/cli-application-context-menu.png
index 0e35ecec0b..0a66138e61 100644
Binary files a/docs/en/studio/images/solution-runner/cli-application-context-menu.png and b/docs/en/studio/images/solution-runner/cli-application-context-menu.png differ
diff --git a/docs/en/studio/images/solution-runner/csharp-application-context-menu-build.png b/docs/en/studio/images/solution-runner/csharp-application-context-menu-build.png
index dea4556ad7..aec7d5d0d7 100644
Binary files a/docs/en/studio/images/solution-runner/csharp-application-context-menu-build.png and b/docs/en/studio/images/solution-runner/csharp-application-context-menu-build.png differ
diff --git a/docs/en/studio/images/solution-runner/csharp-application-context-menu-monitor.png b/docs/en/studio/images/solution-runner/csharp-application-context-menu-monitor.png
index 0743fb5ae9..42eca8cf00 100644
Binary files a/docs/en/studio/images/solution-runner/csharp-application-context-menu-monitor.png and b/docs/en/studio/images/solution-runner/csharp-application-context-menu-monitor.png differ
diff --git a/docs/en/studio/images/solution-runner/csharp-application-context-menu.png b/docs/en/studio/images/solution-runner/csharp-application-context-menu.png
index cd007f59a3..76c90a2e95 100644
Binary files a/docs/en/studio/images/solution-runner/csharp-application-context-menu.png and b/docs/en/studio/images/solution-runner/csharp-application-context-menu.png differ
diff --git a/docs/en/studio/images/solution-runner/folder-context-menu-add.png b/docs/en/studio/images/solution-runner/folder-context-menu-add.png
index 4dda7cfe03..c83a54f5e0 100644
Binary files a/docs/en/studio/images/solution-runner/folder-context-menu-add.png and b/docs/en/studio/images/solution-runner/folder-context-menu-add.png differ
diff --git a/docs/en/studio/images/solution-runner/folder-context-menu-build.png b/docs/en/studio/images/solution-runner/folder-context-menu-build.png
index ce72b6d8f5..3e5ad9b56d 100644
Binary files a/docs/en/studio/images/solution-runner/folder-context-menu-build.png and b/docs/en/studio/images/solution-runner/folder-context-menu-build.png differ
diff --git a/docs/en/studio/images/solution-runner/folder-context-menu.png b/docs/en/studio/images/solution-runner/folder-context-menu.png
index 1bc4478352..c17cb8659d 100644
Binary files a/docs/en/studio/images/solution-runner/folder-context-menu.png and b/docs/en/studio/images/solution-runner/folder-context-menu.png differ
diff --git a/docs/en/studio/images/solution-runner/manage-start-actions.png b/docs/en/studio/images/solution-runner/manage-start-actions.png
new file mode 100644
index 0000000000..4b96c08d3e
Binary files /dev/null and b/docs/en/studio/images/solution-runner/manage-start-actions.png differ
diff --git a/docs/en/studio/images/solution-runner/profile-root-context-menu-add.png b/docs/en/studio/images/solution-runner/profile-root-context-menu-add.png
index 11b8da1362..ec26ebcaf0 100644
Binary files a/docs/en/studio/images/solution-runner/profile-root-context-menu-add.png and b/docs/en/studio/images/solution-runner/profile-root-context-menu-add.png differ
diff --git a/docs/en/studio/images/solution-runner/profile-root-context-menu-build.png b/docs/en/studio/images/solution-runner/profile-root-context-menu-build.png
index 972f850149..db2ae4de3a 100644
Binary files a/docs/en/studio/images/solution-runner/profile-root-context-menu-build.png and b/docs/en/studio/images/solution-runner/profile-root-context-menu-build.png differ
diff --git a/docs/en/studio/images/solution-runner/profile-root-context-menu.png b/docs/en/studio/images/solution-runner/profile-root-context-menu.png
index a94f5b3704..d81bf68514 100644
Binary files a/docs/en/studio/images/solution-runner/profile-root-context-menu.png and b/docs/en/studio/images/solution-runner/profile-root-context-menu.png differ
diff --git a/docs/en/studio/images/solution-runner/solutioın-runner-properties.png b/docs/en/studio/images/solution-runner/solutioın-runner-properties.png
index 0dcbd08b1e..8611f8be3d 100644
Binary files a/docs/en/studio/images/solution-runner/solutioın-runner-properties.png and b/docs/en/studio/images/solution-runner/solutioın-runner-properties.png differ
diff --git a/docs/en/studio/release-notes.md b/docs/en/studio/release-notes.md
index 6d5016d111..282d038c5e 100644
--- a/docs/en/studio/release-notes.md
+++ b/docs/en/studio/release-notes.md
@@ -2,6 +2,13 @@
This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version.
+## 0.9.15 (2024-12-05)
+
+* Upgraded templates to version `9.0.1`.
+* Fixed problems in the microservice service_nolayers template.
+* Fixed microservice angular template for wrong file-management module reference.
+* Fixed added extra lines in the hosts.txt file.
+
## 0.9.14 (2024-12-03)
* Refactored `dotnet watch` command in solution runner.
diff --git a/docs/en/studio/running-applications.md b/docs/en/studio/running-applications.md
index a4dc4f8388..9e266ef7a9 100644
--- a/docs/en/studio/running-applications.md
+++ b/docs/en/studio/running-applications.md
@@ -41,27 +41,22 @@ When you click *Add New Profile*, it opens the *Create New Profile* window. You
## Using the Profile
-After selecting the current profile, which is the *Default* profile that comes pre-configured, we can utilize the tree items. This allows us to execute collective commands and create various tree structures based on our specific needs. You can navigate through the root of the tree and right-click to view the context menu, which includes 3 options: `Run`, `Build` and `Add`.
+After selecting the current profile, which is the *Default* profile that comes pre-configured, we can utilize the tree items. This allows us to execute collective commands and create various tree structures based on our specific needs. You can navigate through the root of the tree and right-click to view the context menu, which includes the following options: `Start All`, `Stop All`, `Build`, `Add`, and `Manage Start Actions`.

-### Run
+### Start/Stop All
-We can start/stop the applications with this option. Go to root of the tree and right-click to view the context menu, in this example *Acme.Bookstore(Default)* -> *Run*.
-
-
+We can start/stop the applications with these options. Go to the root of the tree and right-click to view the context menu:
- `Start All`: Start all(CLI, C#) applications.
- `Stop All`: Stop all(CLI, C#) applications.
-- `Build & Start All`: Builds each C# application in the [Background Tasks](./overview#background-tasks) and starts all (CLI, C#) applications after the build tasks are completed.
-
-> `Start All` doesn't build the C# applications before running. If you're running it for the first time or if you've made changes, you should build the applications. You can simply use the `Build & Start All`.
-> You can change the current profile while applications are running in the previous profile. The applications continue to run under the previous profile. For example if we start the `Acme.BookStore.AdministrationService`, `Acme.BookStore.IdentityService` applications when current profile is *team-1* and after change the current profile to *team-2* the applications continue to run under *team-1*.
+> You can change the current profile while applications are running in the previous profile. The applications continue to run under the previous profile. For example, if we start the `Acme.BookStore.AdministrationService`, `Acme.BookStore.IdentityService` applications when the current profile is *team-1* and after changing the current profile to *team-2* the applications continue to run under *team-1*.
### Build
-We can use common [dotnet](https://learn.microsoft.com/en-us/dotnet/core/tools) commands in this option. Go to root of the tree and right-click to view the context menu, in this example *Acme.Bookstore(Default)* -> *Build*, there are 4 options available:
+We can use common [dotnet](https://learn.microsoft.com/en-us/dotnet/core/tools) commands in this option. Go to the root of the tree and right-click to view the context menu, in this example *Acme.Bookstore(Default)* -> *Build*, there are 4 options available:

@@ -80,7 +75,7 @@ We can add 3 different item type to *Profile* for defining the tree structure. T
#### C# Application
-When we go to root of the tree and right-click, in this example *Acme.BookStore(Default)* -> *Add* -> *C# Application* it opens the *Add Application* window. There are two methods to add applications: *This solution* and *External*. To add via the *This solution* tab, follow these steps:
+When we go to the root of the tree and right-click, in this example *Acme.BookStore(Default)* -> *Add* -> *C# Application* it opens the *Add Application* window. There are two methods to add applications: *This solution* and *External*. To add via the *This solution* tab, follow these steps:

@@ -98,7 +93,7 @@ The C# project doesn't have to be within the current [Solution Explorer](./solut
- `Path`: Provide the path to the .csproj file you wish to add. The path will be [normalized](https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#path-normalization), allowing the project location to be flexible, as long as it's accessible from the current [ABP Solution](./concepts.md#solution).
- `Name`: Give an arbitrary name to see in solution runner. This name should be unique for each profile.
-- `Launch url`: Is the url when we want to browse. But if added project doesn't have launch url we can leave it empty.
+- `Launch url`: This is the url when we want to browse. But if the added project doesn't have launch url we can leave it empty.
- `Kubernetes service`: If you're not using the *Kubernetes* panel leave it empty. But if there is a helm chart for added application we should give the correct regex pattern. It's necessary for browse, when we connect the kubernetes cluster we should browse the services instead *Launch url*. Give the matching regex pattern for your helm chart kubernetes service name.
You can click the `OK` button to add the C# application to the profile.
@@ -137,17 +132,27 @@ You can click the `OK` button to add the folder to the profile.
- To remove a folder from the tree, open the context menu by right-clicking the folder and selecting *Delete*.
- When starting applications, they continue to restart until the application starts gracefully. To stop the restarting process when attempting to restart the application, click the icon on the left. Additionally, you can review the *Logs* to understand why the application isn't starting gracefully.
+### Manage Start Actions
+
+This command will open a dialog where you can set start actions and start orders of sub-applications and sub-folders.
+
+
+
+You can order the applications by dragging the icon in the first column. In the screenshot above, applications & folders are ordered like this: *Applications under infrastructure* > *Applications under services* > *Applications under gateways* > *AuthServer* > *Angular*. You can also set starting order and other actions for each folder by performing `right click > Manage Start Actions` on them.
+
+- **Action**: There are two options: `Start` and `Don't start`. This is usefull if you want to exclude applications from batch start.
+- **Build**: This option allows to disable/enable build before starting the application. If you are working on a single application, you can exclude the other applications from build to save time. This option can also be set by performing `right click > properties` on applications.
+- **Watch**: When enabled, changes in your code are watched and dotnet hot-reloads the application or restarts it if needed. This option also can be set by performing `right click > properties` on applications.
+
## Folder
-We already now why we need folder in the [previous](./running-applications.md#folder) section, we can use collective commands within this folder items. To do that go to folder and open the context menu by right-clicking, which includes 5 options `Start`, `Build`, `Add`, `Rename` and `Delete`.
+We already now why we need folder in the [previous](./running-applications.md#folder) section, we can use collective commands within this folder items. To do that go to folder and open the context menu by right-clicking, which includes 5 options `Start`, `Stop`, `Build`, `Add`, `Manage Start Actions`, `Rename` and `Delete`.

-### Start
-
-You can see the context menu by right-clicking *Folder* -> *Start*, it's [similar](#run) like *Acme.BookStore(Default)* -> *Run* options, there are 3 options available. The only difference with root of the tree and folder is gonna be execute in selected folder.
+### Start/Stop
-
+You can see the context menu by right-clicking *Folder*. It will start/stop all the applications under the folder.
### Build
@@ -157,7 +162,7 @@ You can see the context menu by right-clicking *Folder* -> *Start*, it's [simila
### Add
-*Folder* -> *Add* context menu, it's the [same](#add) options like *Acme.BookStore(Default)* -> *Add* there are 3 options avaiable. The only difference, it's gonna add item to selected folder.
+*Folder* -> *Add* context menu, it's the [same](#add) options like *Acme.BookStore(Default)* -> *Add* there are 3 options avaiable. The only difference, it's gonna add item to the selected folder.

@@ -168,29 +173,16 @@ You can see the context menu by right-clicking *Folder* -> *Start*, it's [simila
## C# Application
-The .NET icon indicates that the application is a C# project. After we [add](#c-application) the C# applications to root of the tree or folder, we can go to any C# application and right-click to view the context menu; `Run`, `Build`, `Browse`, `Requests`, `Exceptions`, `Logs`, `Copy URL`, `Properties`, `Remove`.
+The .NET icon indicates that the application is a C# project. After we [add](#c-application) the C# applications to the root of the tree or folder, we can go to any C# application and right-click to view the context menu; `Start`, `Build`, `Browse`, `Requests`, `Exceptions`, `Logs`, `Copy URL`, `Properties`, `Remove`.

-### Run
-
-We have several options in C# applications. Those options are `Start`(If the application started this option shown as `Stop`), `Build & Start`(If the application started this option shown as `Build & Restart`), `Enable Watch`(If the watch is enabled this option shown as `Disable Watch`), `Restart`(It's only shown when the application started)
-
-
+### Start
-- `Start`: Starts the selected application. This option doesn't build before run. If you're running it for the first time or if you've made changes, you should build the application. If the application is started this option changed as `Stop`.
-- `Build & Start`: We can simply use if we wanna build first and start. If the application is started this option changes to `Build & Restart`.
-- `Enable Watch`: When this option is enabled, there's no need to perform `Build & Start` after any change. ABP Studio watches for changes, re-builds, and re-runs your application automatically upon saving. If this option is enabled it changes to `Disable Watch`.
-- `Restart`: Restarts the application. This option visible only if the application started.
+Starts the selected application. Once it is started, *Stop* and *Restart* options will be available.
> When you start the C# application, you should see a *chain* icon next to the application name, that means the started application connected to ABP Studio. C# applications can connect to ABP Studio even when running from outside the ABP Studio environment, for example debugging with Visual Studio. If the application is run from outside the ABP Studio environment, it will display *(external)* information next to the chain icon.
-> When *Watch* is enable you should see an *eye* icon next to the application name.
-
-> Hint: Performing CTRL+Click on the start icon left to a stopped C# application equals to `Build & Start` command. Same applies for folders.
-
-
-
### Build
It's the [similar](#build) options like root of the tree options. The only difference between them it's gonna be execute the selected application.
@@ -214,7 +206,10 @@ We can open the *Application Properties* window to change *Launch url*, *Kuberne

-You can click the `OK` button to save the changes.
+- **Skip build before starting**: When enabled, application is started without build and it makes starting faster. This is useful when you are working on a single application out of multiple, so you don't need to build others everytime they start.
+- **Watch changes while running**: When enabled, you should see an *eye* icon next to the application name.
+
+
### Miscellaneous
@@ -228,7 +223,7 @@ CLI applications uses the [powershell](https://learn.microsoft.com/en-us/powersh

-- `Run`: This option includes 3 actions: *Start*, *Stop*, and *Restart* for the CLI application.
+- `Start`: Starts the application. Once it is started, *Start* and *Restart* options will be available.
- `Browse`: This option is available when a *Launch URL* is specified upon adding the CLI application. It opens the *Browse* tab, can be clicked while the application is running.
- `Logs`: It opens the *Logs* tab, we can see the logs for *Start* and *Stop* commands.
- `Copy URL`: This option copies the *Launch URL* of the selected application. It is visible if there is a specified *Launch URL*
diff --git a/docs/en/studio/version-mapping.md b/docs/en/studio/version-mapping.md
index 428282ea48..fe91ffe89a 100644
--- a/docs/en/studio/version-mapping.md
+++ b/docs/en/studio/version-mapping.md
@@ -4,6 +4,7 @@ This document provides a general overview of the relationship between various ve
| **ABP Studio Version** | **ABP Version of Startup Template** |
|------------------------|---------------------------|
+| 0.9.15 | 9.0.1 |
| 0.9.9 to 0.9.14 | 9.0.0 |
| 0.9.8 | 8.3.4 |
| 0.9.5 to 0.9.7 | 8.3.3 |
diff --git a/docs/en/tutorials/book-store-with-abp-suite/part-01.md b/docs/en/tutorials/book-store-with-abp-suite/part-01.md
index d3a258448a..152d22fb04 100644
--- a/docs/en/tutorials/book-store-with-abp-suite/part-01.md
+++ b/docs/en/tutorials/book-store-with-abp-suite/part-01.md
@@ -10,6 +10,10 @@
````json
//[doc-nav]
{
+ "Previous": {
+ "Name": "Overview",
+ "Path": "tutorials/book-store-with-abp-suite/index"
+ },
"Next": {
"Name": "Creating the Books",
"Path": "tutorials/book-store-with-abp-suite/part-02"
@@ -21,11 +25,14 @@ Before starting the development, create a new solution named `Acme.BookStore` an
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 Theme:** LeptonX
* **Mobile Framework:** None
* **Database Provider:** {{if DB=="EF"}} Entity Framework Core {{end}}
+* **Public Website:** No
+* **Tiered:** No
You can select the other options based on your preference.
diff --git a/docs/en/tutorials/book-store-with-abp-suite/part-02.md b/docs/en/tutorials/book-store-with-abp-suite/part-02.md
index b9eca0166c..bc0f8fd251 100644
--- a/docs/en/tutorials/book-store-with-abp-suite/part-02.md
+++ b/docs/en/tutorials/book-store-with-abp-suite/part-02.md
@@ -36,7 +36,28 @@ After clicking the related command, pre-integrated browser of ABP Studio should
## Creating the Book Entity
-Let's create a `Book` entity with some properties. First, type `Book` for the *Name* field and leave the other options as is. ABP Suite automatically calculates proper values for the rest of the inputs for you:
+Before creating the `Book` entity, first we can create a `BookType` enum in the `Acme.BookStore.Domain.Shared` project under the **Books** folder as follows:
+
+```csharp
+namespace Acme.BookStore.Books;
+
+public enum BookType
+{
+ Undefined,
+ Adventure,
+ Biography,
+ Dystopia,
+ Fantastic,
+ Horror,
+ Science,
+ ScienceFiction,
+ Poetry
+}
+```
+
+After creating an _enum_ file in your project, you can define it as a property while creating the entity. ABP Suite asks for an enum path to read the enum file, and set the namespace, and enum name in the generated code accordingly. Then, you can create the `Book` entity with some properties.
+
+Type `Book` for the *Name* field and leave the other options as is. ABP Suite automatically calculates proper values for the rest of the inputs for you:

@@ -55,10 +76,16 @@ After, specifying the entity metadata, open the *Properties* tab and create the

-Here the details:
+While defining the properties, you define a *Type* property with the type of *enum*. ABP Suite asks for an enum path and fill the all other inputs by reading the specified enum file. Therefore, you can specify the enum path for the `Type` property like in the following figure:
+
+
+
+> After you select the enum file, ABP Suite automatically sets the namespace and enum name, and lists your enum values in the next section. You can change these values, but for now, you can leave as is.
+
+Here is the all details for the `Book` entity:
* `Name` is **required**, it's a **string** property and maximum length is **128**.
-* `Type` is an **enum** and the enum file path is *\Acme.BookStore.Domain.Shared\Books\BookType.cs* (we will create the file, in the next section).
+* `Type` is an **enum** and the enum file path is *\Acme.BookStore.Domain.Shared\Books\BookType.cs*.
* `PublishDate` is a **DateTime** property and **not nullable**.
* `Price` is a **float** property and **required**.
@@ -66,33 +93,6 @@ 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...
-While defining the properties, you defined a *Type* property with the type of *enum*. ABP Suite asks for an enum path to read the enum file, and set the namespace, and enum name in the generated code.
-
-For that purpose, you should create a `BookType` enum in the `Acme.BookStore.Domain.Shared` project under the **Books** folder as follows:
-
-```csharp
-namespace Acme.BookStore.Books;
-
-public enum BookType
-{
- Undefined,
- Adventure,
- Biography,
- Dystopia,
- Fantastic,
- Horror,
- Science,
- ScienceFiction,
- Poetry
-}
-```
-
-Then, you can specify the enum path for the `Type` property in ABP Suite like in the following figure:
-
-
-
-> After you select the enum file, ABP Suite automatically sets the namespace and enum name, and lists your enum values in the next section. You can change these values, but for now, you can leave as is.
-
After that, you can click the **Save and Generate** button to start the code generation process:

@@ -106,7 +106,7 @@ ABP Suite will generate the necessary code for you. It generates:
* **Unit & integration tests**,
* A new **migration** (and also applies to the database),
* All related **permission**, **object mapping** and **navigation menu item** configurations,
-* and all required **UI components and pages**.
+* and all required **UI components and pages**...
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 build & start the application by clicking the *Run -> Build & Start* button in the *Solution Runner* panel:
diff --git a/docs/en/tutorials/book-store-with-abp-suite/part-03.md b/docs/en/tutorials/book-store-with-abp-suite/part-03.md
index 9f5e1acf6d..d61f43aae5 100644
--- a/docs/en/tutorials/book-store-with-abp-suite/part-03.md
+++ b/docs/en/tutorials/book-store-with-abp-suite/part-03.md
@@ -50,9 +50,9 @@ After, specifying the entity metadata, open the *Properties* tab and create the
Here the details:
-* `Name` is **required**, it's a **string** property, and it's a **textarea**. Minimum length is **2** and maximum length is **128**.
+* `Name` is **required**, it's a **string** property. Minimum length is **2** and maximum length is **128**.
* `BirthDate` is a **DateTime** property and **not nullable**.
-* `ShortBio` is a **string** property, it's **required**, maximum length is **256**.
+* `ShortBio` is **required**, it's a **string** property, it's a **textarea**, maximum length is **256**.
You can leave the other configurations as default.
diff --git a/docs/en/tutorials/book-store-with-abp-suite/part-04.md b/docs/en/tutorials/book-store-with-abp-suite/part-04.md
index ee4497bbfd..aaa0eb3966 100644
--- a/docs/en/tutorials/book-store-with-abp-suite/part-04.md
+++ b/docs/en/tutorials/book-store-with-abp-suite/part-04.md
@@ -49,6 +49,8 @@ Here is the details:
* Selected the display property as *Name*, this will be used in the dropdown component to set an author with a book & also it will be shown in the datatable of the *Books* page.
* Also, made the relation **required** and set it **filterable** so books can be filterable by authors.
+> **Note**: You should delete all existing books in the database (if any), before the code generation. Because, a new foreign-key will be added to the _books_ table and if there is any record in the table, then a new migration can't apply to the database and you may need to update the database manually.
+
After, specifying the metadata, you can click the *Ok* button to close the modal. Then, click the **Save and generate** button to start code generation process. ABP Suite will establish one-to-many relationship between the entities, and will generate all necessary code automatically:

diff --git a/docs/en/tutorials/book-store/part-02.md b/docs/en/tutorials/book-store/part-02.md
index bb812e7d81..3ff19437cd 100644
--- a/docs/en/tutorials/book-store/part-02.md
+++ b/docs/en/tutorials/book-store/part-02.md
@@ -577,8 +577,6 @@ Open the `Books.razor` and replace the content as the following:
@using Volo.Abp.Application.Dtos
@using Acme.BookStore.Books
@using Acme.BookStore.Localization
-@using Microsoft.Extensions.Localization
-@inject IStringLocalizer L
@inherits AbpCrudPageBase
@@ -625,13 +623,21 @@ Open the `Books.razor` and replace the content as the following:
+
+@code
+{
+ public Books() // Constructor
+ {
+ LocalizationResource = typeof(BookStoreResource);
+ }
+}
````
> If you see some syntax errors, you can ignore them if your application is properly built and running. Visual Studio still has some bugs with Blazor.
* Inherited from `AbpCrudPageBase` which implements all the CRUD details for us.
* `Entities`, `TotalCount`, `PageSize`, `OnDataGridReadAsync` are defined in the base class.
-* Injected `IStringLocalizer` (as `L` object) and used for localization.
+* `LocalizationResource` is set to the `BookStoreResource` to localize the texts.
While the code above is pretty easy to understand, you can check the Blazorise [Card](https://blazorise.com/docs/components/card/) and [DataGrid](https://blazorise.com/docs/extensions/datagrid/) documents to understand them better.
diff --git a/docs/en/tutorials/book-store/part-03.md b/docs/en/tutorials/book-store/part-03.md
index 65f6d482dd..fc4e851b94 100644
--- a/docs/en/tutorials/book-store/part-03.md
+++ b/docs/en/tutorials/book-store/part-03.md
@@ -1351,7 +1351,6 @@ Here's the complete code to create the book management CRUD page, that has been
@using Acme.BookStore.Localization
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Components.Web
-@inject IStringLocalizer L
@inject AbpBlazorMessageLocalizerHelper LH
@inherits AbpCrudPageBase
@@ -1396,7 +1395,7 @@ Here's the complete code to create the book management CRUD page, that has been
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
- @L[$"Enum:BookType.{context.Type}"]
+ @L[$"Enum:BookType.{context.Type:D}"]
+
+@code
+{
+ public Books() // Constructor
+ {
+ LocalizationResource = typeof(BookStoreResource);
+ }
+}
````
{{end}}
diff --git a/docs/en/tutorials/book-store/part-05.md b/docs/en/tutorials/book-store/part-05.md
index 95ee1f53a6..d4815c5a96 100644
--- a/docs/en/tutorials/book-store/part-05.md
+++ b/docs/en/tutorials/book-store/part-05.md
@@ -420,6 +420,8 @@ Add the following code block to the end of the `Books.razor` file:
{
public Books() // Constructor
{
+ LocalizationResource = typeof(BookStoreResource);
+
CreatePolicyName = BookStorePermissions.Books.Create;
UpdatePolicyName = BookStorePermissions.Books.Edit;
DeletePolicyName = BookStorePermissions.Books.Delete;
@@ -509,14 +511,11 @@ var bookStoreMenu = new ApplicationMenuItem(
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
-if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
-{
- bookStoreMenu.AddItem(new ApplicationMenuItem(
- "BooksStore.Books",
- l["Menu:Books"],
- url: "/books"
- ));
-}
+bookStoreMenu.AddItem(new ApplicationMenuItem(
+ "BooksStore.Books",
+ l["Menu:Books"],
+ url: "/books"
+).RequirePermissions(BookStorePermissions.Books.Default));
````
You also need to add `async` keyword to the `ConfigureMenuAsync` method and re-arrange the return value. The final `ConfigureMainMenuAsync` method should be the following:
@@ -545,14 +544,11 @@ private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
- if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
- {
- bookStoreMenu.AddItem(new ApplicationMenuItem(
- "BooksStore.Books",
- l["Menu:Books"],
- url: "/books"
- ));
- }
+ bookStoreMenu.AddItem(new ApplicationMenuItem(
+ "BooksStore.Books",
+ l["Menu:Books"],
+ url: "/books"
+ ).RequirePermissions(BookStorePermissions.Books.Default));
}
````
diff --git a/docs/en/tutorials/book-store/part-06.md b/docs/en/tutorials/book-store/part-06.md
index 58a83cfc16..05e1d04460 100644
--- a/docs/en/tutorials/book-store/part-06.md
+++ b/docs/en/tutorials/book-store/part-06.md
@@ -41,7 +41,6 @@ Create an `Authors` folder (namespace) in the `Acme.BookStore.Domain` project an
````csharp
using System;
-using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
@@ -115,7 +114,6 @@ Created this class inside the `Acme.BookStore.Domain.Shared` project since we wi
````csharp
using System;
using System.Threading.Tasks;
-using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Domain.Services;
diff --git a/docs/en/tutorials/book-store/part-09.md b/docs/en/tutorials/book-store/part-09.md
index 3c1b0cb7d5..d481dbe92e 100644
--- a/docs/en/tutorials/book-store/part-09.md
+++ b/docs/en/tutorials/book-store/part-09.md
@@ -1214,14 +1214,11 @@ You will need to declare a `using Acme.BookStore.Authors;` statement to the begi
Open the `BookStoreMenuContributor.cs` in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add the following code to the end of the `ConfigureMainMenuAsync` method:
````csharp
-if (await context.IsGrantedAsync(BookStorePermissions.Authors.Default))
-{
- context.Menu.AddItem(new ApplicationMenuItem(
+context.Menu.AddItem(new ApplicationMenuItem(
"BooksStore.Authors",
l["Menu:Authors"],
url: "/authors"
- ));
-}
+ ).RequirePermissions(BookStorePermissions.Books.Default));
````
### Localizations
diff --git a/docs/en/tutorials/book-store/part-10.md b/docs/en/tutorials/book-store/part-10.md
index 928881ffec..c4383aa5c9 100644
--- a/docs/en/tutorials/book-store/part-10.md
+++ b/docs/en/tutorials/book-store/part-10.md
@@ -1132,6 +1132,8 @@ The final `@code` block should be the following:
public Books() // Constructor
{
+ LocalizationResource = typeof(BookStoreResource);
+
CreatePolicyName = BookStorePermissions.Books.Create;
UpdatePolicyName = BookStorePermissions.Books.Edit;
DeletePolicyName = BookStorePermissions.Books.Delete;
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
index bd653faf55..3cada3bf46 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
@@ -15,6 +15,7 @@ using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Security;
using Volo.Abp.AspNetCore.Security.Claims;
+using Volo.Abp.AspNetCore.StaticFiles;
using Volo.Abp.AspNetCore.Tracing;
using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.AspNetCore.VirtualFileSystem;
@@ -126,6 +127,38 @@ public static class AbpApplicationBuilderExtensions
return app.UseMiddleware();
}
+ ///
+ /// Configures the application to serve static files that match the specified filename patterns with the WebRootFileProvider of the application.
+ ///
+ /// The used to configure the application pipeline.
+ /// The file name patterns to include when serving static files (e.g., "appsettings*.json").
+ /// Supports glob patterns. See Glob patterns documentation.
+ ///
+ /// The instance.
+ public static IApplicationBuilder UseStaticFilesForPatterns(this IApplicationBuilder app, params string[] includeFileNamePatterns)
+ {
+ return UseStaticFilesForPatterns(app, includeFileNamePatterns, app.ApplicationServices.GetRequiredService().WebRootFileProvider);
+ }
+
+ ///
+ /// Configures the application to serve static files that match the specified filename patterns with the specified file provider.
+ ///
+ /// The used to configure the application pipeline.
+ /// The file name patterns to include when serving static files (e.g., "appsettings*.json").
+ /// Supports glob patterns. See Glob patterns documentation.
+ ///
+ /// The
+ /// The instance.
+ public static IApplicationBuilder UseStaticFilesForPatterns(this IApplicationBuilder app, string[] includeFileNamePatterns, IFileProvider fileProvider)
+ {
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ FileProvider = new AbpStaticFileProvider(includeFileNamePatterns, fileProvider)
+ });
+
+ return app;
+ }
+
///
/// MapAbpStaticAssets is used to serve the files from the abp virtual file system embedded resources(js/css) and call the MapStaticAssets.
///
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/StaticFiles/AbpStaticFileProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/StaticFiles/AbpStaticFileProvider.cs
new file mode 100644
index 0000000000..f7893932f2
--- /dev/null
+++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/StaticFiles/AbpStaticFileProvider.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Extensions.FileProviders;
+using Microsoft.Extensions.FileSystemGlobbing;
+using Microsoft.Extensions.Primitives;
+
+namespace Volo.Abp.AspNetCore.StaticFiles;
+
+public class AbpStaticFileProvider : IFileProvider
+{
+ private readonly Matcher _matcher;
+ private readonly IFileProvider _fileProvider;
+
+ /// The file provider to be used to get the files.
+ /// The file name patterns to include when serving static files (e.g., "appsettings*.json").
+ /// Supports glob patterns. See Glob patterns documentation.
+ ///
+ public AbpStaticFileProvider(IReadOnlyList fileNamePatterns, IFileProvider fileProvider)
+ {
+ _fileProvider = fileProvider;
+ _matcher = new Matcher(StringComparison.OrdinalIgnoreCase);
+ _matcher.AddIncludePatterns(fileNamePatterns);
+ }
+
+ public IDirectoryContents GetDirectoryContents(string subpath)
+ {
+ return new NotFoundDirectoryContents();
+ }
+
+ public IFileInfo GetFileInfo(string subpath)
+ {
+ return _matcher.Match(Path.GetFileName(subpath)).HasMatches ?
+ _fileProvider.GetFileInfo(subpath) :
+ new NotFoundFileInfo(subpath);
+ }
+
+ public IChangeToken Watch(string filter)
+ {
+ return NullChangeToken.Singleton;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs
index 8695c0c418..333ae59e3f 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Auth/AuthService.cs
@@ -85,7 +85,11 @@ public class AuthService : IAuthService, ITransientDependency
}
var accessToken = await AuthenticationService.GetAccessTokenAsync(configuration);
-
+
+ if (!Directory.Exists(CliPaths.Root))
+ {
+ Directory.CreateDirectory(CliPaths.Root);
+ }
File.WriteAllText(CliPaths.AccessToken, accessToken, Encoding.UTF8);
}
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs
index 9f23645fb9..4ece393913 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using NuGet.Versioning;
using System.IO;
using System.Linq;
@@ -39,6 +40,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
var latestVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates: includeReleaseCandidates);
var latestReleaseCandidateVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates: true);
var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core");
+ var latestStableVersions = await _packageVersionCheckerService.GetLatestStableVersionsAsync();
async Task UpdateAsync(string filePath)
{
@@ -55,7 +57,8 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
latestVersionInfo.Version,
latestReleaseCandidateVersionInfo.Version,
latestVersionFromMyGet,
- version);
+ version,
+ latestStableVersions: latestStableVersions);
fs.Seek(0, SeekOrigin.Begin);
fs.SetLength(0);
@@ -83,6 +86,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
var latestVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core");
var latestReleaseCandidateVersionInfo = await _packageVersionCheckerService.GetLatestVersionOrNullAsync("Volo.Abp.Core", includeReleaseCandidates: true);
var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core");
+ var latestStableVersions = await _packageVersionCheckerService.GetLatestStableVersionsAsync();
using (var fs = File.Open(projectPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
@@ -97,7 +101,8 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
latestVersionInfo.Version,
latestReleaseCandidateVersionInfo.Version,
latestVersionFromMyGet,
- version);
+ version,
+ latestStableVersions: latestStableVersions);
fs.Seek(0, SeekOrigin.Begin);
fs.SetLength(0);
@@ -114,13 +119,20 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
protected virtual async Task UpdateInternalAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false)
{
+ var latestStableVersions = await _packageVersionCheckerService.GetLatestStableVersionsAsync();
+
using (var fs = File.Open(projectPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
using (var sr = new StreamReader(fs, Encoding.Default, true))
{
var fileContent = await sr.ReadToEndAsync();
- var updatedContent = await UpdateVoloPackagesAsync(fileContent, includeNightlyPreviews, includeReleaseCandidates, switchToStable);
+ var updatedContent = await UpdateVoloPackagesAsync(
+ fileContent,
+ includeNightlyPreviews,
+ includeReleaseCandidates,
+ switchToStable,
+ latestStableVersions: latestStableVersions);
fs.Seek(0, SeekOrigin.Begin);
fs.SetLength(0);
@@ -153,7 +165,8 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
SemanticVersion latestNugetVersion = null,
SemanticVersion latestNugetReleaseCandidateVersion = null,
string latestMyGetVersion = null,
- string specifiedVersion = null)
+ string specifiedVersion = null,
+ List latestStableVersions = null)
{
string packageId = null;
@@ -206,29 +219,39 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
if (!specifiedVersion.IsNullOrWhiteSpace())
{
- if (isLeptonXPackage || isStudioPackage)
+ var leptonXPackageVersion = latestStableVersions?
+ .FirstOrDefault(v => v.Version.Equals(specifiedVersion, StringComparison.InvariantCultureIgnoreCase))?.LeptonX?.Version;
+
+ if ((isLeptonXPackage && string.IsNullOrWhiteSpace(leptonXPackageVersion)) || isStudioPackage)
{
Logger.LogWarning("Package: {PackageId} could not be updated. Please manually update the package version yourself to prevent version mismatches!", packageId);
continue;
}
- if (await SpecifiedVersionExists(specifiedVersion, packageId))
+ var isLeptonXPackageWithVersion = isLeptonXPackage && !string.IsNullOrWhiteSpace(leptonXPackageVersion);
+
+ if (isLeptonXPackageWithVersion || await SpecifiedVersionExists(specifiedVersion, packageId))
+ {
+ TryUpdatingPackage(isLeptonXPackageWithVersion ? leptonXPackageVersion : specifiedVersion);
+ }
+ else
{
- var specifiedSemanticVersion = SemanticVersion.Parse(specifiedVersion);
+ Logger.LogWarning("Package \"{PackageId}\" specified version v{SpecifiedVersion} does not exist!", packageId, specifiedVersion);
+ }
+
+ void TryUpdatingPackage(string versionToUpdate)
+ {
+ var specifiedSemanticVersion = SemanticVersion.Parse(versionToUpdate);
if (specifiedSemanticVersion > currentSemanticVersion)
{
- Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, specifiedVersion);
- versionAttribute.Value = specifiedVersion;
+ Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, versionToUpdate);
+ versionAttribute.Value = versionToUpdate;
}
else
{
- Logger.LogWarning("Unable to update package \"{PackageId}\" version v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, specifiedVersion);
+ Logger.LogWarning("Unable to update package \"{PackageId}\" version v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, versionToUpdate);
}
}
- else
- {
- Logger.LogWarning("Package \"{PackageId}\" specified version v{SpecifiedVersion} does not exist!", packageId, specifiedVersion);
- }
}
else
{
@@ -252,7 +275,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency
}
else
{
- latestVersion = latestMyGetVersion == null ? await GetLatestVersionFromMyGet(packageId) : latestMyGetVersion;
+ latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId);
}
if(latestVersion == null)
diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs
index d5764c1c0e..316c53e01e 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Version/PackageVersionCheckerService.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
+using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Http;
@@ -111,6 +112,11 @@ public class PackageVersionCheckerService : ITransientDependency
? new LatestVersionInfo(semanticVersion, latestStableVersionResult.Message)
: null;
}
+
+ public async Task> GetLatestStableVersionsAsync()
+ {
+ return await GetLatestStableVersionsInternalAsync();
+ }
private static ConcurrentDictionary CommercialPackagesCache { get; } = new ();
@@ -225,7 +231,7 @@ public class PackageVersionCheckerService : ITransientDependency
_apiKeyResult ??= await _apiKeyService.GetApiKeyOrNullAsync();
}
- private async Task GetLatestStableVersionOrNullAsync()
+ private async Task> GetLatestStableVersionsInternalAsync()
{
try
{
@@ -241,16 +247,24 @@ public class PackageVersionCheckerService : ITransientDependency
var content = await responseMessage.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize>(content);
-
- return result.FirstOrDefault(x => x.Type.ToLowerInvariant() == "stable");
+ return result.OrderBy(q => q.Type.ToLowerInvariant() == "stable").ThenBy(q => SemanticVersion.Parse(q.Version)).ToList();
}
}
catch
{
- return null;
+ return [];
}
}
+ private async Task GetLatestStableVersionOrNullAsync()
+ {
+ var latestStableVersionsResult = await GetLatestStableVersionsInternalAsync();
+
+ return latestStableVersionsResult.Count <= 0
+ ? null
+ : latestStableVersionsResult.FirstOrDefault();
+ }
+
public class NuGetSearchResultDto
{
public int TotalHits { get; set; }
@@ -270,6 +284,11 @@ public class PackageVersionCheckerService : ITransientDependency
public List Versions { get; set; }
}
+ public class LeptonXThemeInfo
+ {
+ public string Version { get; set; }
+ }
+
public class LatestStableVersionResult
{
public string Version { get; set; }
@@ -279,5 +298,8 @@ public class PackageVersionCheckerService : ITransientDependency
public string Type { get; set; }
public string Message { get; set; }
+
+ [CanBeNull]
+ public LeptonXThemeInfo LeptonX { get; set; }
}
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj
index 2948ef0cfb..8f14308ed6 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj
+++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo.Abp.EntityFrameworkCore.Oracle.csproj
@@ -21,7 +21,6 @@
-
diff --git a/latest-versions.json b/latest-versions.json
index 27908ad9cb..e2c60800a3 100644
--- a/latest-versions.json
+++ b/latest-versions.json
@@ -3,6 +3,27 @@
"version": "9.0.1",
"releaseDate": "",
"type": "stable",
- "message": ""
+ "message": "",
+ "leptonx": {
+ "version": "4.0.1"
+ }
+ },
+ {
+ "version": "9.0.0",
+ "releaseDate": "",
+ "type": "stable",
+ "message": "",
+ "leptonx": {
+ "version": "4.0.0"
+ }
+ },
+ {
+ "version": "8.3.1",
+ "releaseDate": "",
+ "type": "stable",
+ "message": "",
+ "leptonx": {
+ "version": "3.3.1"
+ }
}
]
\ No newline at end of file
diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs
index 50e6035b9b..a0b7de8c07 100644
--- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs
+++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs
@@ -154,7 +154,7 @@ public partial class PermissionManagementModal
var updateDto = new UpdatePermissionsDto
{
- Permissions = _groups
+ Permissions = _allGroups
.SelectMany(g => g.Permissions)
.Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name })
.ToArray()