Browse Source

Merge branch 'dev' into timezone

pull/22236/head
maliming 1 year ago
parent
commit
72b9bac78b
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 2
      docs/en/cli/index.md
  2. 86
      docs/en/docs-nav.json
  3. 26
      docs/en/framework/api-development/dynamic-csharp-clients.md
  4. 24
      docs/en/framework/api-development/static-csharp-clients.md
  5. 39
      docs/en/framework/data/mongodb/index.md
  6. 64
      docs/en/framework/ui/blazor/basic-theme.md
  7. 29
      docs/en/framework/ui/blazor/theming.md
  8. BIN
      docs/en/get-started/images/abp-studio-new-microservice-solution-dialog-optional-modules.png
  9. BIN
      docs/en/get-started/images/abp-studio-new-microservice-solution-dialog-properties.png
  10. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png
  11. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-additional-services.png
  12. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-microservice.png
  13. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-microservice.png
  14. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-dynamic-localization.png
  15. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework-microservice.png
  16. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-multi-tenancy.png
  17. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-public-web-site.png
  18. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-ui-framework-microservice.png
  19. BIN
      docs/en/get-started/images/abp-studio-new-solution-dialog-ui-theme-microservice.png
  20. 16
      docs/en/get-started/microservice.md
  21. 6
      docs/en/release-info/migration-guides/abp-9-1.md
  22. 4
      docs/en/solution-templates/layered-web-application/cors-configuration.md
  23. 121
      docs/en/solution-templates/layered-web-application/health-check-configuration.md
  24. 2
      docs/en/solution-templates/microservice/adding-new-microservices.md
  25. 4
      docs/en/solution-templates/microservice/cors-configuration.md
  26. 110
      docs/en/solution-templates/microservice/health-check-configuration.md
  27. 4
      docs/en/solution-templates/single-layer-web-application/cors-configuration.md
  28. 115
      docs/en/solution-templates/single-layer-web-application/health-check-configuration.md
  29. BIN
      docs/en/studio/images/monitoring-applications/overall.png
  30. BIN
      docs/en/studio/images/solution-runner/csharp-application-context-menu-build.png
  31. BIN
      docs/en/studio/images/solution-runner/csharp-application-context-menu-monitor.png
  32. BIN
      docs/en/studio/images/solution-runner/csharp-application-context-menu.png
  33. BIN
      docs/en/studio/images/solution-runner/solutioın-runner-properties.png
  34. 1
      docs/en/studio/monitoring-applications.md
  35. 4
      docs/en/studio/release-notes.md
  36. 5
      docs/en/studio/running-applications.md
  37. 2
      docs/en/studio/version-mapping.md
  38. 16
      docs/en/tutorials/book-store/part-01.md
  39. 17
      docs/en/tutorials/todo/layered/index.md
  40. 14
      docs/en/tutorials/todo/single-layer/index.md
  41. 87
      docs/en/ui-themes/lepton-x-lite/blazor.md
  42. 222
      docs/en/ui-themes/lepton-x/blazor.md
  43. 6
      docs/en/ui-themes/lepton/customizing-lepton-theme.md
  44. 28
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
  45. 42
      framework/src/Volo.Abp.BlazoriseUI/Components/EntityActions.razor
  46. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs
  47. 12
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/HelpCommand.cs
  48. 6
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Internal/HideFromCommandList.cs
  49. 1
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Internal/RecreateInitialMigrationCommand.cs
  50. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json
  51. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json
  52. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json
  53. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json
  54. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json
  55. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json
  56. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json
  57. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json
  58. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json
  59. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json
  60. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json
  61. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json
  62. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json
  63. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json
  64. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json
  65. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json
  66. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json
  67. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json
  68. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json
  69. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json
  70. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json
  71. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json
  72. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sv.json
  73. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json
  74. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json
  75. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json
  76. 3
      framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json
  77. 31
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts

2
docs/en/cli/index.md

@ -918,6 +918,8 @@ Usage:
abp bundle [options]
````
> This command is no longer needed if you are using Global Assets feature. See [Managing Global Scripts & Styles](../framework/ui/blazor/global-scripts-styles.md) for more information.
#### Options
* ```--working-directory``` or ```-wd```: Specifies the working directory. This option is useful when executing directory doesn't contain a Blazor project file.

86
docs/en/docs-nav.json

@ -783,78 +783,6 @@
"path": "framework/architecture",
"isIndex": true
},
{
"text": "Module Development Best Practices",
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices",
"isIndex": true
},
{
"text": "Module Architecture",
"path": "framework/architecture/best-practices/module-architecture.md"
},
{
"text": "Domain Layer",
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices/domain-layer-overview.md",
"isIndex": true
},
{
"text": "Entities",
"path": "framework/architecture/best-practices/entities.md"
},
{
"text": "Repositories",
"path": "framework/architecture/best-practices/repositories.md"
},
{
"text": "Domain Services",
"path": "framework/architecture/best-practices/domain-services.md"
}
]
},
{
"text": "Application Layer",
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices/application-layer-overview.md",
"isIndex": true
},
{
"text": "Application Services",
"path": "framework/architecture/best-practices/application-services.md"
},
{
"text": "Data Transfer Objects",
"path": "framework/architecture/best-practices/data-transfer-objects.md"
}
]
},
{
"text": "Data Access",
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices/data-access-overview.md",
"isIndex": true
},
{
"text": "Entity Framework Core Integration",
"path": "framework/architecture/best-practices/entity-framework-core-integration.md"
},
{
"text": "MongoDB Integration",
"path": "framework/architecture/best-practices/mongodb-integration.md"
}
]
}
]
},
{
"text": "Modularity",
"items": [
@ -970,7 +898,8 @@
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices"
"path": "framework/architecture/best-practices",
"isIndex": true
},
{
"text": "Module Architecture",
@ -981,7 +910,8 @@
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices/domain-layer-overview.md"
"path": "framework/architecture/best-practices/domain-layer-overview.md",
"isIndex": true
},
{
"text": "Entities",
@ -1002,7 +932,8 @@
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices/application-layer-overview.md"
"path": "framework/architecture/best-practices/application-layer-overview.md",
"isIndex": true
},
{
"text": "Application Services",
@ -1019,7 +950,8 @@
"items": [
{
"text": "Overview",
"path": "framework/architecture/best-practices/data-access-overview.md"
"path": "framework/architecture/best-practices/data-access-overview.md",
"isIndex": true
},
{
"text": "Entity Framework Core Integration",
@ -1032,7 +964,7 @@
]
}
]
}
},
]
},
{

26
docs/en/framework/api-development/dynamic-csharp-clients.md

@ -163,6 +163,30 @@ context.Services.AddHttpClientProxies(
`remoteServiceConfigurationName` parameter matches the service endpoint configured via `AbpRemoteServiceOptions`. If the `BookStore` endpoint is not defined then it fallbacks to the `Default` endpoint.
#### Remote Service Configuration Provider
You may need to get the remote service configuration for a specific remote service in some cases. For this, you can use the `IRemoteServiceConfigurationProvider` interface.
**Example: Get the remote service configuration for the "BookStore" remote service**
````csharp
public class MyService : ITransientDependency
{
private readonly IRemoteServiceConfigurationProvider _remoteServiceConfigurationProvider;
public MyService(IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider)
{
_remoteServiceConfigurationProvider = remoteServiceConfigurationProvider;
}
public async Task GetRemoteServiceConfiguration()
{
var configuration = await _remoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync("BookStore");
Console.WriteLine(configuration.BaseUrl);
}
}
````
### As Default Services
When you create a service proxy for `IBookAppService`, you can directly inject the `IBookAppService` to use the proxy client (as shown in the usage section). You can pass `asDefaultServices: false` to the `AddHttpClientProxies` method to disable this feature.
@ -204,6 +228,8 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
This example uses the [Microsoft.Extensions.Http.Polly](https://www.nuget.org/packages/Microsoft.Extensions.Http.Polly) package. You also need to import the `Polly` namespace (`using Polly;`) to be able to use the `WaitAndRetryAsync` method.
## See Also
* [Static C# Client Proxies](./static-csharp-clients.md)

24
docs/en/framework/api-development/static-csharp-clients.md

@ -244,6 +244,30 @@ context.Services.AddStaticHttpClientProxies(
`remoteServiceConfigurationName` parameter matches the service endpoint configured via `AbpRemoteServiceOptions`. If the `BookStore` endpoint is not defined then it fallbacks to the `Default` endpoint.
#### Remote Service Configuration Provider
You may need to get the remote service configuration for a specific remote service in some cases. For this, you can use the `IRemoteServiceConfigurationProvider` interface.
**Example: Get the remote service configuration for the "BookStore" remote service**
````csharp
public class MyService : ITransientDependency
{
private readonly IRemoteServiceConfigurationProvider _remoteServiceConfigurationProvider;
public MyService(IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider)
{
_remoteServiceConfigurationProvider = remoteServiceConfigurationProvider;
}
public async Task GetRemoteServiceConfiguration()
{
var configuration = await _remoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync("BookStore");
Console.WriteLine(configuration.BaseUrl);
}
}
````
### Retry/Failure Logic & Polly Integration
If you want to add retry logic for the failing remote HTTP calls for the client proxies, you can configure the `AbpHttpClientBuilderOptions` in the `PreConfigureServices` method of your module class.

39
docs/en/framework/data/mongodb/index.md

@ -309,16 +309,39 @@ public class BookService
### Transactions
MongoDB supports multi-document transactions starting from the version 4.0 and the ABP supports it. However, the [startup template](../../../solution-templates) **disables** transactions by default. If your MongoDB **server** supports transactions, you can enable the it in the *YourProjectMongoDbModule* class:
MongoDB supports multi-document transactions starting from the version 4.0 and the ABP supports it. However, the [startup template](../../../solution-templates) **disables** transactions by default. If your MongoDB **server** supports transactions, you can enable them in the *YourProjectMongoDbModule* class:
```csharp
Configure<AbpUnitOfWorkDefaultOptions>(options =>
{
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Auto;
});
Remove the following code to enable transactions:
```diff
- context.Services.AddAlwaysDisableUnitOfWorkTransaction();
- Configure<AbpUnitOfWorkDefaultOptions>(options =>
- {
- options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
- });
```
> Or you can delete this code since this is already the default behavior.
#### Setting up a Transaction-Enabled MongoDB Replica Set in Docker
Use the following `docker-compose.yml` to create a local MongoDB Replica Set that supports transactions. The connection string will be `mongodb://localhost:27017/YourProjectName?replicaSet=rs0`.
```yaml
version: "3.8"
services:
mongo:
image: mongo:8.0
command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"]
ports:
- 27017:27017
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'127.0.0.1:27017'}]}) }" | mongosh --port 27017 --quiet
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
```
### Advanced Topics
@ -510,4 +533,4 @@ public class MyCustomMongoDbBulkOperationProvider
* [Entities](../../architecture/domain-driven-design/entities.md)
* [Repositories](../../architecture/domain-driven-design/repositories.md)
* [Video tutorial](https://abp.io/video-courses/essentials/abp-mongodb)
* [Video tutorial](https://abp.io/video-courses/essentials/abp-mongodb)

64
docs/en/framework/ui/blazor/basic-theme.md

@ -19,17 +19,26 @@ If you need to manually this theme, follow the steps below:
{{if UI == "Blazor"}}
* Install the [Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme) NuGet package to your web project.
* Add `AbpAspNetCoreComponentsWebAssemblyBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../architecture/modularity/basics.md) in the your Blazor UI project.
* Use `Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic.App` as the root component of your application in the `ConfigureServices` method of your module:
```csharp
var builder = context.Services.GetSingletonInstance<WebAssemblyHostBuilder>();
builder.RootComponents.Add<App>("#ApplicationContainer");
```
`#ApplicationContainer` is a selector (like `<div id="ApplicationContainer">Loading...</div>`) in the `index.html`.
* Execute `abp bundle` command under blazor project once.
* Install the [Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Bundling](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Bundling) NuGet package to your `Blazor` project.
* Add `AbpAspNetCoreComponentsWebAssemblyBasicThemeBundlingModule` into the `[DependsOn(...)]` attribute for your [module class](../../architecture/modularity/basics.md) in the your `Blazor` project.
* Install the [Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme) NuGet package to your `Blazor.Client` project.
* Add `AbpAspNetCoreComponentsWebAssemblyBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../architecture/modularity/basics.md) in the your `Blazor.Client` project.
Update `Routes.razor` file in `Blazor.Client` project as below:
````csharp
@using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic
@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="WebAppAdditionalAssembliesHelper.GetAssemblies<YourBlazorClientModule>()">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
</Found>
</Router>
````
{{end}}
@ -41,21 +50,38 @@ If you need to manually this theme, follow the steps below:
* Add `AbpAspNetCoreComponentsServerBasicThemeModule` into the `[DependsOn(...)]` attribute for your [module class](../../architecture/modularity/basics.md) in the your Blazor UI project.
* Perform following changes in `Pages/_Host.cshtml` file
* Perform following changes in `App.razor` file
* Add usings at the top of the page.
```html
@using Volo.Abp.AspNetCore.Components.Server.BasicTheme.Bundling
@using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic
```
* Add Basic theme style bundles between `<head>` tags.
```html
<abp-style-bundle name="@BlazorBasicThemeBundles.Styles.Global" />
* Then replace script & style bunles as following
```
* Add `App` component of Basic Theme in the body section of page.
```html
<component type="typeof(App)" render-mode="Server" />
<AbpStyles BundleName="@BlazorBasicThemeBundles.Styles.Global" />
```
```
<AbpScripts BundleName="@BlazorBasicThemeBundles.Scripts.Global" />
```
Update `Routes.razor` file as below:
````csharp
@using Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic
@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing
@using Microsoft.Extensions.Options
@inject IOptions<AbpRouterOptions> RouterOptions
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
</Found>
</Router>
````
{{end}}
## The Layout

29
docs/en/framework/ui/blazor/theming.md

@ -106,22 +106,35 @@ using Volo.Abp.Bundling;
namespace MyTheme
{
public class MyThemeBundleContributor : IBundleContributor
public class MyThemeBundleContributor : BundleContributor
{
public void AddScripts(BundleContext context)
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("_content/MyTheme/styles.css");
}
}
}
````
public void AddStyles(BundleContext context)
```cs
[DependsOn(
typeof(AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule)
)]
public class MyBlazorWebAssemblyBundlingModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpBundlingOptions>(options =>
{
context.Add("_content/MyTheme/styles.css");
}
// Add style bundle
options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global)
.AddContributors(typeof(MyThemeBundleContributor));
});
}
}
````
```
`styles.css` file should be added into the `wwwroot` folder of the theme project for this example. When you use the `abp bundle` command, this class is automatically discovered and executed to add the style to the page.
`styles.css` file should be added into the `wwwroot` folder of the theme project for this example.
See the [Global Styles and Scripts](global-scripts-styles.md) document for more.

BIN
docs/en/get-started/images/abp-studio-new-microservice-solution-dialog-optional-modules.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/en/get-started/images/abp-studio-new-microservice-solution-dialog-properties.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 55 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-additional-services.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-database-configurations-microservice.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-database-provider-microservice.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 48 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-dynamic-localization.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-mobile-framework-microservice.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 58 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-multi-tenancy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-public-web-site.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 43 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-ui-framework-microservice.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 90 KiB

BIN
docs/en/get-started/images/abp-studio-new-solution-dialog-ui-theme-microservice.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 45 KiB

16
docs/en/get-started/microservice.md

@ -49,7 +49,11 @@ On that screen, you can decide on your database provider by selecting one of the
![abp-studio-new-solution-dialog-database-configurations](images/abp-studio-new-solution-dialog-database-configurations-microservice.png)
Here, select the DBMS right for you, then click the *Next* button to navigate to the *UI Framework* selection:
Here, select the DBMS right for you, then click the *Next* button to navigate to the *Multi-Tenancy* selection:
![abp-studio-new-solution-dialog-multi-tenancy](images/abp-studio-new-solution-dialog-multi-tenancy.png)
On that screen, you can enable multi-tenancy for your solution. After selecting this option, click the Next button to proceed to the *UI Framework* selection screen.
![abp-studio-new-solution-dialog-ui-framework](images/abp-studio-new-solution-dialog-ui-framework-microservice.png)
@ -67,6 +71,10 @@ Pick the one best for you, or select the *None* if you don't want a mobile appli
You can select a public website to be created in your solution. The public website is a simple landing page that can be used to introduce your product, provide documentation, and so on.
![abp-studio-new-solution-dialog-dynamic-localization](images/abp-studio-new-solution-dialog-dynamic-localization.png)
On that screen, you can enable dynamic localization. After selecting this option, click the Next button to proceed to the *Optional Modules* selection screen.
![abp-studio-new-microservice-solution-dialog-optional-modules](images/abp-studio-new-microservice-solution-dialog-optional-modules.png)
Each item in that list is a pre-built application module. You can click the blue icon near to the module name to get more information about the module. You can leave the list as is (so, it installs the most common and used modules for you) or customize based on your preference.
@ -88,6 +96,12 @@ Click the Next button to see *Additional Options* selection:
If you unchecked the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files which include the Helm charts and other Kubernetes related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login. Lastly, you can specify the *Include Tests* option to include the test projects in the solution.
Click the Next button to see *Additional Services* screen:
![abp-studio-new-solution-dialog-additional-services](images/abp-studio-new-solution-dialog-additional-services.png)
On that screen, allows you to include extra microservices in your ABP solution during the creation process. This feature lets you extend your solution with business-specific services right from the start.
Now, we are ready to allow ABP Studio to create our solution. Just click the *Create* button and let the ABP Studio do the rest for you. After clicking the *Create* button, the dialog is closed and your solution is loaded into ABP Studio:
![abp-studio-created-new-microservice-solution](images/abp-studio-created-new-microservice-solution.png)

6
docs/en/release-info/migration-guides/abp-9-1.md

@ -2,6 +2,8 @@
This document is a guide for upgrading ABP v9.0 solutions to ABP v9.1. There are no breaking changes in this version that would affect your application.
Only you might need to update some constant names due to the OpenIddict 6.0 upgrade, which is explained in the following migration guide:
You might need to update some constant names due to the OpenIddict 6.0 upgrade, which is explained in the following migration guide:
- [OpenIddict 5.x to 6.x Migration Guide](./openiddict5-to-6.md)
- [OpenIddict 5.x to 6.x Migration Guide](./openiddict5-to-6.md)
In addition, ABP version 9.1 has been upgraded to incorporate Angular version 19. Consequently, we recommend migrating your application to [Angular v19](https://angular.dev/update-guide) to ensure compatibility.

4
docs/en/solution-templates/layered-web-application/cors-configuration.md

@ -8,8 +8,8 @@
"Path": "solution-templates/layered-web-application/blob-storing"
},
"Next": {
"Name": "Helm Charts and Kubernetes",
"Path": "solution-templates/layered-web-application/helm-charts-and-kubernetes"
"Name": "Health Check Configuration",
"Path": "solution-templates/layered-web-application/health-check-configuration"
}
}
```

121
docs/en/solution-templates/layered-web-application/health-check-configuration.md

@ -0,0 +1,121 @@
# Layered Solution: Health Check Configuration
```json
//[doc-nav]
{
"Previous": {
"Name": "CORS Configuration",
"Path": "solution-templates/single-layer-web-application/cors-configuration"
},
"Next": {
"Name": "Helm Charts and Kubernetes",
"Path": "solution-templates/layered-web-application/helm-charts-and-kubernetes"
}
}
```
Health Check is a feature that allows applications to monitor their health and diagnose potential issues. The layered solution template comes with pre-configured Health Check system.
In the layered solution template, Health Check configuration is applied in the following cases:
- When [MVC](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#mvc) is selected as the web application type.
- When [Blazor Server](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#blazor-server) is selected as the web application type.
- When [Blazor WebAssembly](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#blazor-webassembly) is selected as the web application type (configured at the backend).
- When [Blazor WebApp](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#blazor-webapp) is selected as the web application type (configured at the backend).
- When [Angular](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#angular) is selected as the web application type (configured at the backend).
- When [No UI](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#no-ui) is selected as the web application type (configured at the backend).
### Configuration in `HealthChecksBuilderExtensions.cs`
Health Checks are configured in the `HealthChecksBuilderExtensions` class. This class extends `IServiceCollection` to register health check services and configure health check UI endpoints.
#### Default Configuration
The default setup is as follows:
```csharp
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
namespace MyCompanyName.MyProjectName.HealthChecks;
public static class HealthChecksBuilderExtensions
{
public static void AddMyProjectNameHealthChecks(this IServiceCollection services)
{
// Add your health checks here
var healthChecksBuilder = services.AddHealthChecks();
healthChecksBuilder.AddCheck<MyProjectNameDatabaseCheck>("MyProjectName DbContext Check", tags: new string[] { "database" });
// Read configuration for health check URL
var configuration = services.GetConfiguration();
var healthCheckUrl = configuration["App:HealthCheckUrl"] ?? "/health-status";
services.ConfigureHealthCheckEndpoint(healthCheckUrl);
// Configure HealthChecks UI
var healthChecksUiBuilder = services.AddHealthChecksUI(settings =>
{
settings.AddHealthCheckEndpoint("MyProjectName Health Status", healthCheckUrl);
});
// Set HealthCheck UI storage
healthChecksUiBuilder.AddInMemoryStorage();
services.MapHealthChecksUiEndpoints(options =>
{
options.UIPath = "/health-ui";
options.ApiPath = "/health-api";
});
}
private static IServiceCollection ConfigureHealthCheckEndpoint(this IServiceCollection services, string path)
{
....
}
private static IServiceCollection MapHealthChecksUiEndpoints(this IServiceCollection services, Action<global::HealthChecks.UI.Configuration.Options>? setupOption = null)
{
....
}
}
```
### Database Health Check Implementation
The `MyProjectNameDatabaseCheck` class is a custom implementation of a health check that verifies database connectivity using `IIdentityRoleRepository`.
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace MyCompanyName.MyProjectName.HealthChecks;
public class MyProjectNameDatabaseCheck : IHealthCheck, ITransientDependency
{
protected readonly IIdentityRoleRepository IdentityRoleRepository;
public MyProjectNameDatabaseCheck(IIdentityRoleRepository identityRoleRepository)
{
IdentityRoleRepository = identityRoleRepository;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await IdentityRoleRepository.GetListAsync(sorting: nameof(IdentityRole.Id), maxResultCount: 1, cancellationToken: cancellationToken);
return HealthCheckResult.Healthy($"Could connect to database and get record.");
}
catch (Exception e)
{
return HealthCheckResult.Unhealthy($"Error when trying to get database record. ", e);
}
}
}
```

2
docs/en/solution-templates/microservice/adding-new-microservices.md

@ -24,6 +24,8 @@ To add a new microservice to the solution, you can use the `service_nolayers` te
In ABP Studio [Solution Explorer](../../studio/solution-explorer.md#adding-a-new-microservice-module), right-click on the `services` folder and select `Add` -> `New Module` -> `Microservice`.
You can also add microservices during the project creation process by using the Additional Services screen. For more details, refer to the [Additional Services](../../get-started/microservice.md) section.
![new-microservice](images/new-microservice.png)
It opens the `Create New Module` dialog. Enter the name of the new microservice, specify the output directory if needed, and click the `Next` button. There is a naming convention: the *Module name* should include the solution name as a prefix, and the use of the dot (.) character in the *Module name* is not allowed.

4
docs/en/solution-templates/microservice/cors-configuration.md

@ -4,8 +4,8 @@
//[doc-nav]
{
"Next": {
"Name": "Communication in the Microservice solution",
"Path": "solution-templates/microservice/communication"
"Name": "Health Check Configuration",
"Path": "solution-templates/microservice/health-check-configuration"
}
}
````

110
docs/en/solution-templates/microservice/health-check-configuration.md

@ -0,0 +1,110 @@
# Microservice Solution: Health Check Configuration
```json
//[doc-nav]
{
"Next": {
"Name": "Communication in the Microservice solution",
"Path": "solution-templates/microservice/communication"
}
}
```
Health Check is a feature that allows applications to monitor their health and diagnose potential issues. The Microservice solution template comes with pre-configured Health Check system.
In the Microservice solution template, Health Check configuration is applied in all the services, gateways and UI applications (except Blazor Wasm & Blazor WebApp applications UI applications).
### Configuration in `HealthChecksBuilderExtensions.cs`
Health Checks are configured in the `HealthChecksBuilderExtensions` class. This class extends `IServiceCollection` to register health check services and configure health check UI endpoints.
#### Default Configuration
The default setup is as follows:
```csharp
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
namespace MyCompanyName.MyProjectName.HealthChecks;
public static class HealthChecksBuilderExtensions
{
public static void AddMyProjectNameHealthChecks(this IServiceCollection services)
{
// Add your health checks here
var healthChecksBuilder = services.AddHealthChecks();
healthChecksBuilder.AddCheck<MyProjectNameDatabaseCheck>("MyProjectName DbContext Check", tags: new string[] { "database" });
// Read configuration for health check URL
var configuration = services.GetConfiguration();
var healthCheckUrl = configuration["App:HealthCheckUrl"] ?? "/health-status";
services.ConfigureHealthCheckEndpoint(healthCheckUrl);
// Configure HealthChecks UI
var healthChecksUiBuilder = services.AddHealthChecksUI(settings =>
{
settings.AddHealthCheckEndpoint("MyProjectName Health Status", healthCheckUrl);
});
// Set HealthCheck UI storage
healthChecksUiBuilder.AddInMemoryStorage();
services.MapHealthChecksUiEndpoints(options =>
{
options.UIPath = "/health-ui";
options.ApiPath = "/health-api";
});
}
private static IServiceCollection ConfigureHealthCheckEndpoint(this IServiceCollection services, string path)
{
....
}
private static IServiceCollection MapHealthChecksUiEndpoints(this IServiceCollection services, Action<global::HealthChecks.UI.Configuration.Options>? setupOption = null)
{
....
}
}
```
### Database Health Check Implementation
The `MyProjectNameDatabaseCheck` class is a custom implementation of a health check that verifies database connectivity in the applications with database connection. Example:
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace MyCompanyName.MyProjectName.HealthChecks;
public class MyProjectNameDatabaseCheck : IHealthCheck, ITransientDependency
{
protected readonly IIdentityRoleRepository IdentityRoleRepository;
public MyProjectNameDatabaseCheck(IIdentityRoleRepository identityRoleRepository)
{
IdentityRoleRepository = identityRoleRepository;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await IdentityRoleRepository.GetListAsync(sorting: nameof(IdentityRole.Id), maxResultCount: 1, cancellationToken: cancellationToken);
return HealthCheckResult.Healthy($"Could connect to database and get record.");
}
catch (Exception e)
{
return HealthCheckResult.Unhealthy($"Error when trying to get database record. ", e);
}
}
}
```

4
docs/en/solution-templates/single-layer-web-application/cors-configuration.md

@ -6,6 +6,10 @@
"Previous": {
"Name": "BLOB Storing",
"Path": "solution-templates/single-layer-web-application/blob-storing"
},
"Next": {
"Name": "Health Check Configuration",
"Path": "solution-templates/single-layer-web-application/health-check-configuration"
}
}
```

115
docs/en/solution-templates/single-layer-web-application/health-check-configuration.md

@ -0,0 +1,115 @@
# Single Layer Solution: Health Check Configuration
```json
//[doc-nav]
{
"Previous": {
"Name": "CORS Configuration",
"Path": "solution-templates/single-layer-web-application/cors-configuration"
}
}
```
Health Check is a feature that allows applications to monitor their health and diagnose potential issues. The single-layer solution template comes with pre-configured Health Check system.
In the single-layer solution template, Health Check configuration is applied in the following cases:
- When [MVC](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#mvc) is selected as the web application type.
- When [Blazor Server](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#blazor-server) is selected as the web application type.
- When [Angular](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#angular) is selected as the web application type (configured at the backend).
- When [No UI](https://abp.io/docs/latest/solution-templates/single-layer-web-application/web-applications#no-ui) is selected as the web application type (configured at the backend).
### Configuration in `HealthChecksBuilderExtensions.cs`
Health Checks are configured in the `HealthChecksBuilderExtensions` class. This class extends `IServiceCollection` to register health check services and configure health check UI endpoints.
#### Default Configuration
The default setup is as follows:
```csharp
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
namespace MyCompanyName.MyProjectName.HealthChecks;
public static class HealthChecksBuilderExtensions
{
public static void AddMyProjectNameHealthChecks(this IServiceCollection services)
{
// Add your health checks here
var healthChecksBuilder = services.AddHealthChecks();
healthChecksBuilder.AddCheck<MyProjectNameDatabaseCheck>("MyProjectName DbContext Check", tags: new string[] { "database" });
// Read configuration for health check URL
var configuration = services.GetConfiguration();
var healthCheckUrl = configuration["App:HealthCheckUrl"] ?? "/health-status";
services.ConfigureHealthCheckEndpoint(healthCheckUrl);
// Configure HealthChecks UI
var healthChecksUiBuilder = services.AddHealthChecksUI(settings =>
{
settings.AddHealthCheckEndpoint("MyProjectName Health Status", healthCheckUrl);
});
// Set HealthCheck UI storage
healthChecksUiBuilder.AddInMemoryStorage();
services.MapHealthChecksUiEndpoints(options =>
{
options.UIPath = "/health-ui";
options.ApiPath = "/health-api";
});
}
private static IServiceCollection ConfigureHealthCheckEndpoint(this IServiceCollection services, string path)
{
....
}
private static IServiceCollection MapHealthChecksUiEndpoints(this IServiceCollection services, Action<global::HealthChecks.UI.Configuration.Options>? setupOption = null)
{
....
}
}
```
### Database Health Check Implementation
The `MyProjectNameDatabaseCheck` class is a custom implementation of a health check that verifies database connectivity using `IIdentityRoleRepository`.
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace MyCompanyName.MyProjectName.HealthChecks;
public class MyProjectNameDatabaseCheck : IHealthCheck, ITransientDependency
{
protected readonly IIdentityRoleRepository IdentityRoleRepository;
public MyProjectNameDatabaseCheck(IIdentityRoleRepository identityRoleRepository)
{
IdentityRoleRepository = identityRoleRepository;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await IdentityRoleRepository.GetListAsync(sorting: nameof(IdentityRole.Id), maxResultCount: 1, cancellationToken: cancellationToken);
return HealthCheckResult.Healthy($"Could connect to database and get record.");
}
catch (Exception e)
{
return HealthCheckResult.Unhealthy($"Error when trying to get database record. ", e);
}
}
}
```

BIN
docs/en/studio/images/monitoring-applications/overall.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 54 KiB

BIN
docs/en/studio/images/solution-runner/csharp-application-context-menu-build.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 33 KiB

BIN
docs/en/studio/images/solution-runner/csharp-application-context-menu-monitor.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/en/studio/images/solution-runner/csharp-application-context-menu.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/en/studio/images/solution-runner/solutioın-runner-properties.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 30 KiB

1
docs/en/studio/monitoring-applications.md

@ -59,6 +59,7 @@ In the data grid, details for each application are displayed. It's possible to s
- `Name`: The name of the application.
- `State`: The state of the application. It can take on several values such as *Scheduled*, *Starting*, *Started*, *Stopping* and *Stopped*. In the event of an application crash during its starting, the state is mark as *Scheduled*, we can cancel the starting process at that stage.
- `Health` : The health state of the application. Clicking on the icon shows the latest health check response. Displays `N/A` if the application is not running or health check is not configured for the application.
- `Instances`: Indicates the count of running instances for the application. This value is particularly helpful when scaling the application within a Kubernetes, providing visibility into the number of currently active instances.
- `Uptime`: The time elapsed since the application started.
- `Requests`: The number of HTTP requests received by the application.

4
docs/en/studio/release-notes.md

@ -2,6 +2,10 @@
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.25 (2025-03-12)
* Added ready/health check for solution runner.
## 0.9.24 (2025-03-11)
* Added automatic installation of necessary dependencies.

5
docs/en/studio/running-applications.md

@ -196,16 +196,19 @@ When the C# application is connected to ABP Studio, it starts sending telemetry
![csharp-application-context-menu-monitor](images/solution-runner/csharp-application-context-menu-monitor.png)
- `Browse`: ABP Studio includes a browser tool for accessing websites and running applications. You can click this option to view the application in the ABP Studio browser. However, this option is only accessible if the application is started.
- Health Status : If Health Check endpoints are defined, it allows you to browse Health UI and see the latest health check response.
- `Requests`: It opens the *HTTP Requests* tab with adding the selected application filter. You can view all *HTTP Requests* received by your applications.
- `Exceptions`: We can display all exceptions on this tab. It opens the *Exceptions* tab with selected application.
- `Logs`: Clicking this option opens the *Logs* tab with adding the selected application filter.
### Properties
We can open the *Application Properties* window to change *Launch url*, *Kubernetes service* and *run* information. To access the *Application Properties* window, navigate to a C# application, right-click to view the context menu, and select the Properties option.
We can open the *Application Properties* window to change *Launch url*, *Health check endpoints*, *Kubernetes service* and *run* information. To access the *Application Properties* window, navigate to a C# application, right-click to view the context menu, and select the Properties option.
![solutioın-runner-properties](images/solution-runner/solutioın-runner-properties.png)
- **Health check endpoint**: Endpoint for controlling the health status of the application periodically. If the application doesn't have a endpoint for health check, you can enter `/` to use the home page of the application as health check endpoint.
- **Health UI endpoint**: Endpoint of the Health UI page of the application.
- **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.

2
docs/en/studio/version-mapping.md

@ -4,7 +4,7 @@ This document provides a general overview of the relationship between various ve
| **ABP Studio Version** | **ABP Version of Startup Template** |
|------------------------|---------------------------|
| 0.9.24 | 9.1.0 |
| 0.9.24 - 0.9.25 | 9.1.0 |
| 0.9.22 - 0.9.23 | 9.0.4 |
| 0.9.20 - 0.9.21 | 9.0.3 |
| 0.9.17 to 0.9.19 | 9.0.2 |

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

@ -36,22 +36,6 @@ abp install-libs
> We suggest you install [Yarn v1.22+ (not v2)](https://classic.yarnpkg.com/en/docs/install) to prevent possible package inconsistencies, if you haven't installed it yet.
{{if UI=="Blazor" || UI=="BlazorWebApp"}}
### Bundling and Minification
`abp bundle` command offers bundling and minification support for client-side resources (JavaScript and CSS files) for Blazor projects. This command automatically run when you create a new solution with the [ABP CLI](../../cli).
However, sometimes you might need to run this command manually. To update script & style references without worrying about dependencies, ordering, etc. in a project, you can run this command in the directory of your `*.Blazor.Client` project:
```bash
abp bundle
```
> For more details about managing style and script references in Blazor or MAUI Blazor apps, see [Managing Global Scripts & Styles](../../framework/ui/blazor/global-scripts-styles.md).
{{end}}
## Create the Book Entity
**Domain layer** in the startup template is separated into two projects:

17
docs/en/tutorials/todo/layered/index.md

@ -113,23 +113,6 @@ abp install-libs
> We suggest you install [Yarn v1.22+ (not v2)](https://classic.yarnpkg.com/en/docs/install) to prevent possible package inconsistencies, if you haven't installed it yet.
{{if UI=="Blazor" || UI=="BlazorWebApp" || UI=="MAUIBlazor"}}
#### Bundling and Minification
`abp bundle` command offers bundling and minification support for client-side resources (JavaScript and CSS files) for Blazor projects. This command automatically run when you create a new solution with the [ABP CLI](../../../cli/index.md).
However, sometimes you might need to run this command manually. To update script & style references without worrying about dependencies, ordering, etc. in a project, you can run this command in the directory of your `Blazor.Client` application:
````bash
abp bundle
````
> For more details about managing style and script references in Blazor or MAUI Blazor apps, see [Managing Global Scripts & Styles](../../../framework/ui/blazor/global-scripts-styles.md).
{{end}}
### Run the Application
{{if UI=="MVC" || UI=="BlazorServer" || UI=="BlazorWebApp"}}

14
docs/en/tutorials/todo/single-layer/index.md

@ -115,20 +115,6 @@ abp install-libs
> We suggest you install [Yarn v1.22+ (not v2)](https://classic.yarnpkg.com/en/docs/install) to prevent possible package inconsistencies, if you haven't installed it yet.
{{if UI=="Blazor" || UI=="BlazorServer"}}
#### Bundling and Minification
Run the following command in the directory of your blazor application:
```bash
abp bundle
```
> For more details about managing style and script references in Blazor or MAUI Blazor apps, see [Managing Global Scripts & Styles](../../../framework/ui/blazor/global-scripts-styles.md).
{{end}}
### Run the Application
{{if UI=="MVC" || UI=="BlazorServer"}}

87
docs/en/ui-themes/lepton-x-lite/blazor.md

@ -21,7 +21,27 @@ This theme is **already installed** when you create a new solution using the sta
- Complete the [MVC Razor Pages Installation](asp-net-core.md#installation) for the **HttpApi.Host** application first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and if Auth Server is separated, install to the **OpenIddict**_.
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme** package to your **Blazor WebAssembly** application with the following command:
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme.Bundling** package to your **Blazor** application with the following command:
```bash
dotnet add package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme.Bundling --prerelease
```
- Remove **Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Bundling** reference from the project since it's not necessary after switching to LeptonX Lite.
- Remove the old theme from the **DependsOn** attribute in your module class and add the **AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule** type to the **DependsOn** attribute.
```diff
[DependsOn(
// Remove BasicTheme module from DependsOn attribute
- typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeBundlingModule),
// Add LeptonX Lite module to DependsOn attribute
+ typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule),
)]
```
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme** package to your **Blazor.Client** application with the following command:
```bash
dotnet add package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme --prerelease
@ -41,14 +61,21 @@ This theme is **already installed** when you create a new solution using the sta
)]
```
- Change startup App component with the LeptonX one.
```csharp
// Make sure the 'App' comes from 'Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite' namespace.
builder.RootComponents.Add<App>("#ApplicationContainer");
```
- Run the `abp bundle` command in your **Blazor** application folder.
Update `Routes.razor` file in `Blazor.Client` project as below:
````csharp
@using Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite
@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="WebAppAdditionalAssembliesHelper.GetAssemblies<YourBlazorClientModule>()">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
</Found>
</Router>
````
{{end}}
@ -93,27 +120,37 @@ builder.RootComponents.Add<App>("#ApplicationContainer");
});
```
- Update `_Host.cshtml` file. _(located under **Pages** folder by default.)_
- Add following usings to Locate **App** and **BlazorLeptonXLiteThemeBundles** classes.
- Update `App.razor` file. _(located under **Components** folder by default.)_
- Add following namespace at the top of the page.
```csharp
@using Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite
@using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme.Bundling
@ using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme.Bundling
```
- Then replace script & style bundles as following:
```diff
// Remove following line
- <abp-style-bundle name="@BlazorBasicThemeBundles.Styles.Global" />
// Add following line instead
+ <abp-style-bundle name="@BlazorLeptonXLiteThemeBundles.Styles.Global" />
- Then replace script & style bunles as following
```
<AbpStyles BundleName="@BlazorLeptonXLiteThemeBundles.Styles.Global" />
```
```diff
// Remove following line
- <abp-script-bundle name="@BlazorBasicThemeBundles.Scripts.Global" />
// Add following line instead
+ <abp-script-bundle name="@BlazorLeptonXLiteThemeBundles.Scripts.Global" />
```
<AbpScripts BundleName="@BlazorLeptonXLiteThemeBundles.Scripts.Global" />
```
Update `Routes.razor` file as below:
````csharp
@using Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite
@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing
@using Microsoft.Extensions.Options
@inject IOptions<AbpRouterOptions> RouterOptions
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
<NotAuthorized>
<RedirectToLogin />
</NotAuthorized>
</AuthorizeRouteView>
</Found>
</Router>
````
{{end}}

222
docs/en/ui-themes/lepton-x/blazor.md

@ -13,37 +13,95 @@ LeptonX theme is implemented and ready to use with ABP. No custom implementation
{{if UI == "Blazor"}}
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme** package to your **Blazor WASM** application.
- Complete the [MVC Razor Pages Installation](asp-net-core.md#installation) for the **HttpApi.Host** application first. _If the solution is tiered/micro-service, complete the MVC steps for all MVC applications such as **HttpApi.Host** and if Auth Server is separated, install to the **OpenIddict**_.
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme.Bundling** package to your **Blazor** application with the following command:
```bash
dotnet add package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme
dotnet add package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme.Bundling --prerelease
```
- Remove old theme from **DependsOn** attribute in your module class and add **AbpAspNetCoreComponentsWebAssemblyLeptonXThemeModule** type to **DependsOn** attribute.
- Remove **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme.Bundling** reference from the project since it's not necessary after switching to LeptonX Lite.
- Remove the old theme from the **DependsOn** attribute in your module class and add the **AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule** type to the **DependsOn** attribute.
```diff
[DependsOn(
- typeof(LeptonThemeManagementBlazorModule),
- typeof(AbpAspNetCoreComponentsWebAssemblyLeptonThemeModule),
+ typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXThemeModule)
// Remove LeptonTheme module from DependsOn attribute
- typeof(AbpAspNetCoreComponentsWebAssemblyLeptonThemeBundlingModule),
// Add LeptonX Lite module to DependsOn attribute
+ typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule),
)]
```
- Change startup `App` component with the LeptonX one.
- Add following using declaration and remove your old theme using declaration.
```csharp
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components;
```
- Add **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme** package to your **Blazor.Client** application with the following command:
- Make sure `App` component in following block is `Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.App`
```csharp
// Make sure the 'App' comes from 'Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components' namespace.
builder.RootComponents.Add<App>("#ApplicationContainer");
```
- If you can't remove or not sure which one is the old theme's using statements, you can use full name of that class:
```csharp
builder.RootComponents.Add<Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.App>("#ApplicationContainer");
```
```bash
dotnet add package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme --prerelease
```
- Remove **Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme** reference from the project since it's not necessary after switching to LeptonX Lite.
- Remove the old theme from the **DependsOn** attribute in your module class and add the **AbpAspNetCoreComponentsWebAssemblyLeptonXThemeModule** type to the **DependsOn** attribute.
```diff
[DependsOn(
// Remove LeptonTheme module from DependsOn attribute
- typeof(AbpAspNetCoreComponentsWebAssemblyLeptonThemeModule),
// Add LeptonX Lite module to DependsOn attribute
+ typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXThemeModule),
)]
```
Update `Routes.razor` file in `Blazor.Client` project as below:
````csharp
@using Microsoft.Extensions.Options
@using Microsoft.Extensions.Localization
@using global::Localization.Resources.AbpUi
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout
@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing
@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp
@inject IOptions<AbpRouterOptions> RouterOptions
@inject IOptions<LeptonXThemeBlazorOptions> LayoutOptions
@inject IStringLocalizer<AbpUiResource> UiLocalizer
<CascadingAuthenticationState>
<Router AppAssembly="RouterOptions.Value.AppAssembly" AdditionalAssemblies="WebAppAdditionalAssembliesHelper.GetAssemblies<YourBlazorClientModule>()">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@LayoutOptions.Value.Layout">
<NotAuthorized>
@if (context.User?.Identity?.IsAuthenticated != true)
{
<RedirectToLogin/>
}
else
{
<ErrorView
Title="@UiLocalizer["403Message"]"
HttpStatusCode="403"
Message="@UiLocalizer["403MessageDetail"]"/>
}
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="@LayoutOptions.Value.Layout">
<ErrorView
Title="@UiLocalizer["404Message"]"
HttpStatusCode="404"
Message="@UiLocalizer["404MessageDetail"]"/>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
````
{{end}}
@ -78,22 +136,66 @@ LeptonX theme is implemented and ready to use with ABP. No custom implementation
});
```
- Update `_Host.cshtml` file. _(located under **Pages** folder by default.)_
- Add following usings to Locate **App** and **BlazorLeptonXThemeBundles** classes.
- Update `App.razor` file. _(located under **Components** folder by default.)_
- Add following namespace at the top of the page.
```csharp
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components
@using Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.Bundling
```
- Then replace script & style bunles as following
```diff
- <abp-style-bundle name="@BlazorBasicThemeBundles.Styles.Global" />
+ <abp-style-bundle name="@BlazorLeptonXThemeBundles.Styles.Global" />
```
<AbpStyles BundleName="@BlazorLeptonXThemeBundles.Styles.Global" />
```
```diff
- <abp-script-bundle name="@BlazorBasicThemeBundles.Scripts.Global" />
+ <abp-script-bundle name="@BlazorLeptonXThemeBundles.Scripts.Global" />
```
<AbpStyles BundleName="@BlazorLeptonXThemeBundles.Styles.Global" />
```
Update `Routes.razor` file as below:
````csharp
@using Microsoft.Extensions.Options
@using Microsoft.Extensions.Localization
@using global::Localization.Resources.AbpUi
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components
@using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout
@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing
@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp
@inject IOptions<AbpRouterOptions> RouterOptions
@inject IOptions<LeptonXThemeBlazorOptions> LayoutOptions
@inject IStringLocalizer<AbpUiResource> UiLocalizer
<CascadingAuthenticationState>
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@LayoutOptions.Value.Layout">
<NotAuthorized>
@if (context.User?.Identity?.IsAuthenticated != true)
{
<RedirectToLogin/>
}
else
{
<ErrorView
Title="@UiLocalizer["403Message"]"
HttpStatusCode="403"
Message="@UiLocalizer["403MessageDetail"]"/>
}
</NotAuthorized>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="@LayoutOptions.Value.Layout">
<ErrorView
Title="@UiLocalizer["404Message"]"
HttpStatusCode="404"
Message="@UiLocalizer["404MessageDetail"]"/>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
````
{{end}}
---
@ -167,33 +269,6 @@ Layout options of Blazor UI can be manageable via using **LeptonXThemeMvcOptions
});
```
{{if UI == "Blazor"}}
#### Updating Bundles on Layout Changes
Layout changes requires bundling and restarting the application. Before bundling, you have to add your layout to `appsettings.json`. Make sure `AbpCli:Bundle:Paramters` has `LeptonXTheme.Layout` key with your layout name. Available values are `side-menu` & `top-menu`.
_You can add the following section to root level of your appsettings.json file if not added._
```json
"AbpCli": {
"Bundle": {
"Mode": "BundleAndMinify", /* Options: None, Bundle, BundleAndMinify */
"Name": "global",
"Parameters": {
"LeptonXTheme.Layout": "top-menu" /* Options: side-menu, top-menu */
}
}
}
```
Then you can run bundling command with ABP Cli
```bash
abp bundle
```
{{end}}
### Toolbars
LeptonX includes separeted toolbars for desktop & mobile. You can manage toolbars independently. Toolbar names can be accessible in the **LeptonXToolbars** class.
@ -224,6 +299,7 @@ public async Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
{{end}}
## Layouts
**LeptonX** offers two **ready-made layouts** for your web application. One of them is **placed** with the **menu items** on the **top** and the other with the **menu items** on the **sides**.
@ -258,7 +334,7 @@ You can override layouts by following the steps below:
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(SideMenuLayout))]
[Dependency(ReplaceServices = true)]
@ -305,7 +381,7 @@ If you need to replace the component, you can follow the steps below.
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(Breadcrumbs))]
[Dependency(ReplaceServices = true)]
@ -338,7 +414,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(ContentToolbar))]
[Dependency(ReplaceServices = true)]
@ -371,7 +447,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(GeneralSettings))]
[Dependency(ReplaceServices = true)]
@ -404,7 +480,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.Common;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MobileGeneralSettings))]
[Dependency(ReplaceServices = true)]
@ -443,7 +519,7 @@ Components used in the side menu layout.
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.Navigation;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainMenu))]
[Dependency(ReplaceServices = true)]
@ -474,7 +550,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.Navigation;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainMenu))]
[Dependency(ReplaceServices = true)]
@ -507,7 +583,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.Navigation;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MobileNavbar))]
[Dependency(ReplaceServices = true)]
@ -540,7 +616,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.MainHeader;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainHeader))]
[Dependency(ReplaceServices = true)]
@ -577,7 +653,7 @@ If you need to replace the component, you can follow the steps below.
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.MainHeader;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainHeaderBranding))]
[Dependency(ReplaceServices = true)]
@ -614,7 +690,7 @@ If you need to replace the component, you can follow the steps below.
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.SideMenu.MainHeader;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainHeaderToolbar))]
[Dependency(ReplaceServices = true)]
@ -653,7 +729,7 @@ Components used in the top menu layout.
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu.Navigation;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainMenu))]
[Dependency(ReplaceServices = true)]
@ -684,7 +760,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu.Navigation;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainMenu))]
[Dependency(ReplaceServices = true)]
@ -717,7 +793,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu.Navigation;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MobileNavbar))]
[Dependency(ReplaceServices = true)]
@ -750,7 +826,7 @@ namespace LeptonXLite.DemoApp.Blazor.MyComponents
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu.MainHeader;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainHeader))]
[Dependency(ReplaceServices = true)]
@ -785,7 +861,7 @@ Application branding can be customized with the `IBrandingProvider`. See the [Br
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu.MainHeader;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainHeaderBranding))]
[Dependency(ReplaceServices = true)]
@ -822,7 +898,7 @@ If you need to replace the component, you can follow the steps below.
using Volo.Abp.AspNetCore.Components.Web.LeptonXTheme.Components.ApplicationLayout.TopMenu.MainHeader;
using Volo.Abp.DependencyInjection;
namespace LeptonXLite.DemoApp.Blazor.MyComponents
namespace LeptonX.DemoApp.Blazor.MyComponents
{
[ExposeServices(typeof(MainHeaderToolbar))]
[Dependency(ReplaceServices = true)]

6
docs/en/ui-themes/lepton/customizing-lepton-theme.md

@ -229,12 +229,6 @@ Configure<<Volo.Abp.AspNetCore.Components.Web.LeptonTheme.LeptonThemeOptions>(op
}
```
Run the following ABP CLI command to bundle the `custom.css`
```bash
abp bundle
```
{{end}}

28
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js

@ -84,12 +84,9 @@ var abp = abp || {};
};
var _createButtonDropdown = function (record, field, tableInstance) {
if (field.items.length === 1) {
if (field.items.length === 1 && getVisibilityValue(field.items[0].visible, record, tableInstance)) {
var firstItem = field.items[0];
if (!getVisibilityValue(firstItem.visible, record, tableInstance)) {
return $('');
}
var $button = $('<button type="button" class="btn btn-primary btn-sm abp-action-button"></button>');
if (firstItem.displayNameHtml) {
@ -159,8 +156,9 @@ var abp = abp || {};
$dropdownButton.addClass(field.cssClass);
}
var isEntityActionsDisabled = true;
var $dropdownItemsContainer = $('<ul/>').addClass('dropdown-menu');
for (var i = 0; i < field.items.length; i++) {
var fieldItem = field.items[i];
@ -169,6 +167,7 @@ var abp = abp || {};
continue;
}
isEntityActionsDisabled = false;
var $dropdownItem = _createDropdownItem(record, fieldItem, tableInstance);
if (fieldItem.enabled && !fieldItem.enabled({ record: record, table: tableInstance })) {
@ -180,11 +179,22 @@ var abp = abp || {};
if ($dropdownItemsContainer.find('li').length > 0) {
$dropdownItemsContainer.appendTo($container);
} else {
$dropdownButton.addClass('d-none');
}
$dropdownButton.prependTo($container);
if (isEntityActionsDisabled) {
$dropdownButton.attr('disabled', 'disabled');
var $tooltip = $('<div/>');
$tooltip.attr('title', localize("EntityActionsDisabledTooltip"));
$tooltip.attr('data-bs-toggle', 'tooltip');
new bootstrap.Tooltip($tooltip);
$dropdownButton.appendTo($tooltip);
$tooltip.prependTo($container);
}else{
$dropdownButton.prependTo($container);
}
if (bootstrap) {
new bootstrap.Dropdown($dropdownButton, {

42
framework/src/Volo.Abp.BlazoriseUI/Components/EntityActions.razor

@ -1,27 +1,29 @@
@typeparam TItem
<CascadingValue Value="this" IsFixed="true">
@if ( Type == ActionType.Dropdown )
@if ( Type == ActionType.Dropdown || (Type == ActionType.Button && DisabledOrNoActions()))
{
<Dropdown Disabled="@DisabledOrNoActions()">
@if ( HasPrimaryAction )
{
<Button Block="true"
Color="@PrimaryAction!.Color"
Clicked="async ()=> await PrimaryAction.ActionClickedAsync()"
Disabled=@PrimaryAction.Disabled>
@PrimaryAction.Text
</Button>
<DropdownToggle Color="@ToggleColor" Split="true" />
}
else
{
<DropdownToggle Class="btn-block" Color="@ToggleColor">
@ToggleText
</DropdownToggle>
}
<DropdownMenu>
@ChildContent
</DropdownMenu>
<Tooltip Text="@(DisabledOrNoActions() ? UiLocalizer["EntityActionsDisabledTooltip"] : string.Empty)">
@if ( HasPrimaryAction )
{
<Button Block="true"
Color="@PrimaryAction!.Color"
Clicked="async ()=> await PrimaryAction.ActionClickedAsync()"
Disabled=@PrimaryAction.Disabled>
@PrimaryAction.Text
</Button>
<DropdownToggle Color="@ToggleColor" Split="true" />
}
else
{
<DropdownToggle Class="btn-block" Color="@ToggleColor">
@ToggleText
</DropdownToggle>
}
<DropdownMenu>
@ChildContent
</DropdownMenu>
</Tooltip>
</Dropdown>
}
else

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/CreateMigrationAndRunMigratorCommand.cs

@ -5,12 +5,14 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Internal;
using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands;
[HideFromCommandList]
public class CreateMigrationAndRunMigratorCommand : IConsoleCommand, ITransientDependency
{
private readonly InitialMigrationCreator _initialMigrationCreator;

12
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/HelpCommand.cs

@ -1,4 +1,6 @@
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@ -7,6 +9,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Internal;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands;
@ -65,7 +68,7 @@ public class HelpCommand : IConsoleCommand, ITransientDependency
sb.AppendLine("Command List:");
sb.AppendLine("");
foreach (var command in AbpCliOptions.Commands.ToArray())
foreach (var command in AbpCliOptions.Commands.ToArray().Where(NotHiddenFromCommandList))
{
var method = command.Value.GetMethod("GetShortDescription", BindingFlags.Static | BindingFlags.Public);
if (method == null)
@ -92,6 +95,11 @@ public class HelpCommand : IConsoleCommand, ITransientDependency
return sb.ToString();
}
private bool NotHiddenFromCommandList(KeyValuePair<string, Type> command)
{
return command.Value.GetCustomAttribute(typeof(HideFromCommandList)) == null;
}
public static string GetShortDescription()
{
return "Show command line help. Write ` abp help <command> `";

6
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Internal/HideFromCommandList.cs

@ -0,0 +1,6 @@
using System;
namespace Volo.Abp.Cli.Commands.Internal;
public class HideFromCommandList : Attribute
{}

1
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Internal/RecreateInitialMigrationCommand.cs

@ -9,6 +9,7 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands.Internal;
[HideFromCommandList]
public class RecreateInitialMigrationCommand : IConsoleCommand, ITransientDependency
{
public const string Name = "recreate-initial-migration";

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json

@ -60,6 +60,7 @@
"AddNew": "اضف جديد",
"ProfilePicture": "الصوره الشخصيه",
"Theme": "سمة",
"NotAssigned": "غيرمعتمد"
"NotAssigned": "غيرمعتمد",
"EntityActionsDisabledTooltip": "ليس لديك إذن لتنفيذ أي إجراء."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json

@ -60,6 +60,7 @@
"AddNew": "Přidat nový",
"ProfilePicture": "Profilový obrázek",
"Theme": "Téma",
"NotAssigned": "Nepřiřazena"
"NotAssigned": "Nepřiřazena",
"EntityActionsDisabledTooltip": "Nemáte oprávnění provést žádnou akci."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json

@ -60,6 +60,7 @@
"AddNew": "Neue hinzufügen",
"ProfilePicture": "Profilbild",
"Theme": "Thema",
"NotAssigned": "Nicht zugeordnet"
"NotAssigned": "Nicht zugeordnet",
"EntityActionsDisabledTooltip": "Sie haben keine Berechtigung, Aktionen auszuführen."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json

@ -54,6 +54,7 @@
"ManageYourAccount": "Διαχείριση Λογαριασμού",
"OthersGroup": "άλλος",
"Today": "Σήμερα",
"Apply": "Ισχύουν"
"Apply": "Ισχύουν",
"EntityActionsDisabledTooltip": "Δεν έχετε δικαίωμα να εκτελέσετε καμία ενέργεια."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json

@ -55,6 +55,7 @@
"OthersGroup": "Other",
"NotAssigned": "Not Assigned",
"Today": "Today",
"Apply": "Apply"
"Apply": "Apply",
"EntityActionsDisabledTooltip": "You do not have permission to perform any action."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json

@ -60,6 +60,7 @@
"AddNew": "Add new",
"ProfilePicture": "Profile picture",
"Theme": "Theme",
"NotAssigned": "Not Assigned"
"NotAssigned": "Not Assigned",
"EntityActionsDisabledTooltip": "You do not have permission to perform any action."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json

@ -60,6 +60,7 @@
"AddNew": "Agregar nuevo",
"ProfilePicture": "Foto de perfil",
"Theme": "Tema",
"NotAssigned": "No asignado"
"NotAssigned": "No asignado",
"EntityActionsDisabledTooltip": "No tienes permisos para realizar ninguna acción."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json

@ -54,6 +54,7 @@
"ManageYourAccount": "حساب خود را مدیریت کنید",
"OthersGroup": "دیگر",
"Today": "امروز",
"Apply": "درخواست دادن"
"Apply": "درخواست دادن",
"EntityActionsDisabledTooltip": "شما دسترسی به انجام هر گونه عملیات ندارید."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json

@ -60,6 +60,7 @@
"AddNew": "Lisää uusi",
"ProfilePicture": "Profiilikuva",
"Theme": "Teema",
"NotAssigned": "Ei määritetty"
"NotAssigned": "Ei määritetty",
"EntityActionsDisabledTooltip": "Sinulla ei ole oikeutta suorittaa mitään toimintoa."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json

@ -60,6 +60,7 @@
"AddNew": "Ajouter un nouveau",
"ProfilePicture": "Image de profil",
"Theme": "Thème",
"NotAssigned": "Non attribué"
"NotAssigned": "Non attribué",
"EntityActionsDisabledTooltip": "Vous n&#39;avez pas les permissions pour effectuer une action."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json

@ -60,6 +60,7 @@
"AddNew": "नया जोड़ो",
"ProfilePicture": "प्रोफ़ाइल फोटो",
"Theme": "विषय",
"NotAssigned": "सौंपा नहीं गया है"
"NotAssigned": "सौंपा नहीं गया है",
"EntityActionsDisabledTooltip": "आपके पास कोई कार्रवाई नहीं है जो करने के लिए है।"
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json

@ -60,6 +60,7 @@
"AddNew": "Dodaj novi",
"ProfilePicture": "Profilna slika",
"Theme": "Tema",
"NotAssigned": "Nije dodijeljeno"
"NotAssigned": "Nije dodijeljeno",
"EntityActionsDisabledTooltip": "Nemate dozvolu za izvođenje bilo kakve akcije."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json

@ -60,6 +60,7 @@
"AddNew": "Új hozzáadása",
"ProfilePicture": "Profil kép",
"Theme": "Téma",
"NotAssigned": "Nem kijelölt"
"NotAssigned": "Nem kijelölt",
"EntityActionsDisabledTooltip": "Nincs jogosultsága bármely művelethez."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json

@ -60,6 +60,7 @@
"AddNew": "Bæta við nýju",
"ProfilePicture": "Forsíðumynd",
"Theme": "Þema",
"NotAssigned": "Ekki skráður"
"NotAssigned": "Ekki skráður",
"EntityActionsDisabledTooltip": "Þú hefur ekki aðgang að þessum aðgerðum."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json

@ -60,6 +60,7 @@
"AddNew": "Aggiungere nuova",
"ProfilePicture": "Immagine del profilo",
"Theme": "Tema",
"NotAssigned": "Non assegnato"
"NotAssigned": "Non assegnato",
"EntityActionsDisabledTooltip": "Non hai i permessi per eseguire alcuna azione."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json

@ -60,6 +60,7 @@
"AddNew": "Nieuw toevoegen",
"ProfilePicture": "Profielfoto",
"Theme": "Thema",
"NotAssigned": "Niet toegekend"
"NotAssigned": "Niet toegekend",
"EntityActionsDisabledTooltip": "U hebt geen toegang tot deze acties."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json

@ -60,6 +60,7 @@
"AddNew": "Dodaj nowe",
"ProfilePicture": "Zdjęcie profilowe",
"Theme": "Temat",
"NotAssigned": "Nie przypisano"
"NotAssigned": "Nie przypisano",
"EntityActionsDisabledTooltip": "Nie masz uprawnień do wykonania żadnej akcji."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json

@ -60,6 +60,7 @@
"AddNew": "Adicionar novo",
"ProfilePicture": "Foto do perfil",
"Theme": "Tema",
"NotAssigned": "Não atribuído"
"NotAssigned": "Não atribuído",
"EntityActionsDisabledTooltip": "Você não tem permissão para executar qualquer ação."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json

@ -60,6 +60,7 @@
"AddNew": "Adăuga nou",
"ProfilePicture": "Poză de profil",
"Theme": "Temă",
"NotAssigned": "Nealocat"
"NotAssigned": "Nealocat",
"EntityActionsDisabledTooltip": "Nu aveți permisiune să efectuați nicio acțiune."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json

@ -60,6 +60,7 @@
"AddNew": "Добавить новое",
"ProfilePicture": "Изображение профиля",
"Theme": "Тема",
"NotAssigned": "Не назначен"
"NotAssigned": "Не назначен",
"EntityActionsDisabledTooltip": "У вас нет прав на выполнение каких-либо действий."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json

@ -60,6 +60,7 @@
"AddNew": "Pridať nové",
"ProfilePicture": "Profilový obrázok",
"Theme": "Téma",
"NotAssigned": "Nepridelené"
"NotAssigned": "Nepridelené",
"EntityActionsDisabledTooltip": "Nemáte oprávnenie vykonávať žiadnu akciu."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json

@ -60,6 +60,7 @@
"AddNew": "Dodaj novo",
"ProfilePicture": "Profilna slika",
"Theme": "Tema",
"NotAssigned": "Ni dodeljena"
"NotAssigned": "Ni dodeljena",
"EntityActionsDisabledTooltip": "Nimate pravic za izvajanje kakršne koli dejanje."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sv.json

@ -59,6 +59,7 @@
"AddNew": "Lägg till ny",
"ProfilePicture": "Profilbild",
"Theme": "Tema",
"NotAssigned": "Ej tilldelad"
"NotAssigned": "Ej tilldelad",
"EntityActionsDisabledTooltip": "Du har inte tillgång till dessa åtgärder."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json

@ -60,6 +60,7 @@
"AddNew": "Yeni ekle",
"ProfilePicture": "Profil resmi",
"Theme": "Tema",
"NotAssigned": "Atanmadı"
"NotAssigned": "Atanmadı",
"EntityActionsDisabledTooltip": "Bu işlemi gerçekleştirmek için yeterli yetkiniz yok."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json

@ -60,6 +60,7 @@
"AddNew": "Thêm mới",
"ProfilePicture": "Ảnh đại diện",
"Theme": "chủ đề",
"NotAssigned": "Không được chỉ định"
"NotAssigned": "Không được chỉ định",
"EntityActionsDisabledTooltip": "Bạn không có quyền thực hiện bất kỳ hành động nào."
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json

@ -60,6 +60,7 @@
"AddNew": "添新",
"ProfilePicture": "个人资料图片",
"Theme": "主题",
"NotAssigned": "未分配"
"NotAssigned": "未分配",
"EntityActionsDisabledTooltip": "您没有权限执行任何操作。"
}
}

3
framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json

@ -60,6 +60,7 @@
"AddNew": "添新",
"ProfilePicture": "個人資料圖片",
"Theme": "主題",
"NotAssigned": "未分配"
"NotAssigned": "未分配",
"EntityActionsDisabledTooltip": "您沒有權限執行任何操作。"
}
}

31
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts

@ -40,27 +40,34 @@ type PermissionWithGroupName = PermissionGrantInfoDto & {
exportAs: 'abpPermissionManagement',
styles: [
`
.overflow-scroll {
max-height: 70vh;
overflow-y: scroll;
}
.scroll-in-modal {
overflow: auto;
max-height: calc(100vh - 15rem);
}
fieldset legend {
float: none;
width: auto;
/*
To maintain a 28px top margin and 28px bottom margin when the modal reaches full height, the scrollable area needs to be 100vh - 23.1rem
*/
max-height: calc(100vh - 23.1rem);
}
.lpx-scroll-pills-container ul {
display: block;
max-height: 500px;
overflow-y: auto;
}
/* Target mobile screens */
@media (max-width: 768px) {
.scroll-in-modal {
max-height: calc(100vh - 15rem);
}
.lpx-scroll-pills-container ul {
max-height: 500px;
}
}
fieldset legend {
float: none;
width: auto;
}
.lpx-scroll-pills-container .tab-content {
padding-top: 0 !important;
padding-bottom: 0 !important;

Loading…
Cancel
Save