Browse Source

Add low-code images and update docs

Add seven illustrative screenshots to docs/en/low-code/images (actions-menu.png, create-modal.png, data-grid.png, foreign-access-modal.png, interceptor-error.png, menu-items.png, quick-look.png) and update docs/en/low-code/index.md to include references to the menu, data grid, and create/edit modal images to better demonstrate the Low-Code UI features.
pull/24925/head
SALİH ÖZKARA 7 months ago
parent
commit
c23ce47d55
  1. 87
      docs/en/low-code/fluent-api.md
  2. 4
      docs/en/low-code/foreign-access.md
  3. BIN
      docs/en/low-code/images/actions-menu.png
  4. BIN
      docs/en/low-code/images/create-modal.png
  5. BIN
      docs/en/low-code/images/data-grid.png
  6. BIN
      docs/en/low-code/images/foreign-access-modal.png
  7. BIN
      docs/en/low-code/images/interceptor-error.png
  8. BIN
      docs/en/low-code/images/menu-items.png
  9. BIN
      docs/en/low-code/images/quick-look.png
  10. 6
      docs/en/low-code/index.md
  11. 2
      docs/en/low-code/interceptors.md

87
docs/en/low-code/fluent-api.md

@ -16,7 +16,7 @@ C# Attributes and the Fluent API are the **recommended way** to define dynamic e
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Products")] [DynamicEntityUI(PageTitle = "Products")]
public class Product : DynamicEntityBase public class Product
{ {
[DynamicPropertyUnique] [DynamicPropertyUnique]
public string Name { get; set; } public string Name { get; set; }
@ -30,7 +30,18 @@ public class Product : DynamicEntityBase
} }
```` ````
### Step 2: Add Migration and Run ### Step 2: Register the Assembly
````csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
AbpDynamicEntityConfig.SourceAssemblies.Add(
new DynamicEntityAssemblyInfo(typeof(YourDomainModule).Assembly)
);
}
````
### Step 3: Add Migration and Run
```bash ```bash
dotnet ef migrations add Added_Product dotnet ef migrations add Added_Product
@ -39,12 +50,12 @@ dotnet ef database update
You now have a complete Product management page with data grid, create/edit modals, search, sorting, and pagination. You now have a complete Product management page with data grid, create/edit modals, search, sorting, and pagination.
### Step 3: Add Relationships ### Step 4: Add Relationships
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Orders")] [DynamicEntityUI(PageTitle = "Orders")]
public class Order : DynamicEntityBase public class Order
{ {
[DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)] [DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)]
public Guid CustomerId { get; set; } public Guid CustomerId { get; set; }
@ -54,7 +65,7 @@ public class Order : DynamicEntityBase
} }
[DynamicEntity(Parent = "MyApp.Orders.Order")] [DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine : DynamicEntityBase public class OrderLine
{ {
[DynamicForeignKey("MyApp.Products.Product", "Name")] [DynamicForeignKey("MyApp.Products.Product", "Name")]
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
@ -86,7 +97,7 @@ Marks a class as a dynamic entity. The entity name is derived from the class nam
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
public class Product : DynamicEntityBase public class Product
{ {
public string Name { get; set; } public string Name { get; set; }
public decimal Price { get; set; } public decimal Price { get; set; }
@ -97,7 +108,7 @@ Use the `Parent` property for parent-child (master-detail) relationships:
````csharp ````csharp
[DynamicEntity(Parent = "MyApp.Orders.Order")] [DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine : DynamicEntityBase public class OrderLine
{ {
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public int Quantity { get; set; } public int Quantity { get; set; }
@ -111,7 +122,7 @@ Configures entity-level UI. Entities with `PageTitle` get a menu item and a dedi
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Product Management")] [DynamicEntityUI(PageTitle = "Product Management")]
public class Product : DynamicEntityBase public class Product
{ {
// ... // ...
} }
@ -157,6 +168,10 @@ public string RegistrationNumber { get; set; }
| `EditingFormAvailability` | enum | `Available` | Visibility on edit form | | `EditingFormAvailability` | enum | `Available` | Visibility on edit form |
| `QuickLookOrder` | int | `-2` | Order in quick-look panel | | `QuickLookOrder` | int | `-2` | Order in quick-look panel |
The quick-look panel shows a summary of the selected record:
![Quick-look panel showing entity details](images/quick-look.png)
### `[DynamicPropertyServerOnly]` ### `[DynamicPropertyServerOnly]`
Hides a property from API clients entirely. It is stored in the database but never returned to the client: Hides a property from API clients entirely. It is stored in the database but never returned to the client:
@ -200,7 +215,7 @@ Defines JavaScript interceptors on a class for CRUD lifecycle hooks:
InterceptorType.Post, InterceptorType.Post,
"context.log('Deleted: ' + context.commandArgs.entityId);" "context.log('Deleted: ' + context.commandArgs.entityId);"
)] )]
public class Organization : DynamicEntityBase public class Organization
{ {
public string Name { get; set; } public string Name { get; set; }
} }
@ -230,7 +245,7 @@ Reference in an entity:
````csharp ````csharp
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Organizations")] [DynamicEntityUI(PageTitle = "Organizations")]
public class Organization : DynamicEntityBase public class Organization
{ {
public string Name { get; set; } public string Name { get; set; }
public OrganizationType OrganizationType { get; set; } public OrganizationType OrganizationType { get; set; }
@ -261,38 +276,28 @@ The Fluent API has the **highest priority** in the configuration system. Use `Ab
### Basic Usage ### Basic Usage
Configure in your Low-Code Initializer (e.g. `MyAppLowCodeInitializer`): Configure in your Domain module's `ConfigureServices`:
````csharp ````csharp
public static class MyAppLowCodeInitializer public override void ConfigureServices(ServiceConfigurationContext context)
{ {
private static readonly AsyncOneTimeRunner Runner = new(); AbpDynamicEntityConfig.EntityConfigurations.Configure(
"MyApp.Products.Product",
public static async Task InitializeAsync() entity =>
{
await Runner.RunAsync(async () =>
{ {
AbpDynamicEntityConfig.EntityConfigurations.Configure( entity.DefaultDisplayPropertyName = "Name";
"MyApp.Products.Product",
entity =>
{
entity.DefaultDisplayPropertyName = "Name";
var priceProperty = entity.AddOrGetProperty("Price");
priceProperty.AsRequired();
priceProperty.UI = new EntityPropertyUIDescriptor
{
DisplayName = "Unit Price",
CreationFormAvailability = EntityPropertyUIFormAvailability.Available
};
entity.AddOrGetProperty("InternalNotes").AsServerOnly();
}
);
await DynamicModelManager.Instance.InitializeAsync(); var priceProperty = entity.AddOrGetProperty("Price");
}); priceProperty.AsRequired();
} priceProperty.UI = new EntityPropertyUIDescriptor
{
DisplayName = "Unit Price",
CreationFormAvailability = EntityPropertyUIFormAvailability.Available
};
entity.AddOrGetProperty("InternalNotes").AsServerOnly();
}
);
} }
```` ````
@ -434,7 +439,7 @@ public enum OrderStatus
// Customer entity // Customer entity
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Customers")] [DynamicEntityUI(PageTitle = "Customers")]
public class Customer : DynamicEntityBase public class Customer
{ {
[DynamicPropertyUnique] [DynamicPropertyUnique]
public string Name { get; set; } public string Name { get; set; }
@ -452,7 +457,7 @@ public class Customer : DynamicEntityBase
// Product entity // Product entity
[DynamicEntity] [DynamicEntity]
[DynamicEntityUI(PageTitle = "Products")] [DynamicEntityUI(PageTitle = "Products")]
public class Product : DynamicEntityBase public class Product
{ {
[DynamicPropertyUnique] [DynamicPropertyUnique]
public string Name { get; set; } public string Name { get; set; }
@ -473,7 +478,7 @@ public class Product : DynamicEntityBase
} }
}" }"
)] )]
public class Order : DynamicEntityBase public class Order
{ {
[DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)] [DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)]
public Guid CustomerId { get; set; } public Guid CustomerId { get; set; }
@ -484,7 +489,7 @@ public class Order : DynamicEntityBase
} }
[DynamicEntity(Parent = "MyApp.Orders.Order")] [DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine : DynamicEntityBase public class OrderLine
{ {
[DynamicForeignKey("MyApp.Products.Product", "Name")] [DynamicForeignKey("MyApp.Products.Product", "Name")]
public Guid ProductId { get; set; } public Guid ProductId { get; set; }

4
docs/en/low-code/foreign-access.md

@ -108,6 +108,8 @@ Set the `access` field on a foreign key property:
When foreign access is configured between two **dynamic entities**: When foreign access is configured between two **dynamic entities**:
![Actions menu showing foreign access items (Order, Visited Country, etc.)](images/actions-menu.png)
### `ForeignAccess.View` ### `ForeignAccess.View`
An **action menu item** appears on the target entity's data grid row (e.g., a "Visited Countries" item on the Country row). Clicking it opens a read-only modal showing related records. An **action menu item** appears on the target entity's data grid row (e.g., a "Visited Countries" item on the Country row). Clicking it opens a read-only modal showing related records.
@ -116,6 +118,8 @@ An **action menu item** appears on the target entity's data grid row (e.g., a "V
An **action menu item** appears on the target entity's data grid row (e.g., an "Orders" item on the Customer row). Clicking it opens a fully functional CRUD modal where users can create, edit, and delete related records. An **action menu item** appears on the target entity's data grid row (e.g., an "Orders" item on the Customer row). Clicking it opens a fully functional CRUD modal where users can create, edit, and delete related records.
![Foreign access modal with full CRUD capabilities](images/foreign-access-modal.png)
### `ForeignAccess.None` ### `ForeignAccess.None`
No action menu item is added. The foreign key exists only for data integrity and lookup display. No action menu item is added. The foreign key exists only for data integrity and lookup display.

BIN
docs/en/low-code/images/actions-menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/en/low-code/images/create-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/en/low-code/images/data-grid.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
docs/en/low-code/images/foreign-access-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/en/low-code/images/interceptor-error.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/en/low-code/images/menu-items.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
docs/en/low-code/images/quick-look.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

6
docs/en/low-code/index.md

@ -17,6 +17,8 @@ The ABP Low-Code System allows you to define entities using C# attributes or Flu
No need to write DTOs, application services, repositories, or UI pages manually. No need to write DTOs, application services, repositories, or UI pages manually.
![Auto-generated menu items in the sidebar](images/menu-items.png)
## Why Low-Code? ## Why Low-Code?
Traditionally, adding a new entity with full CRUD functionality to an ABP application requires: Traditionally, adding a new entity with full CRUD functionality to an ABP application requires:
@ -51,6 +53,10 @@ public class Product : DynamicEntityBase
Run `dotnet ef migrations add Added_Product` and start your application. You get a complete Product management page with search, filtering, sorting, pagination, create/edit forms, and foreign key dropdown — all auto-generated. Run `dotnet ef migrations add Added_Product` and start your application. You get a complete Product management page with search, filtering, sorting, pagination, create/edit forms, and foreign key dropdown — all auto-generated.
![Auto-generated data grid with search, filters, and actions](images/data-grid.png)
![Auto-generated create/edit modal with form fields and foreign key lookups](images/create-modal.png)
## Getting Started ## Getting Started
### 1. Create a Low-Code Initializer ### 1. Create a Low-Code Initializer

2
docs/en/low-code/interceptors.md

@ -136,6 +136,8 @@ Set this variable to a string to **abort** the operation and return an error:
globalError = 'Cannot delete this entity!'; globalError = 'Cannot delete this entity!';
``` ```
![Interceptor validation error displayed in the UI](images/interceptor-error.png)
## Examples ## Examples
### Pre-Create: Validation ### Pre-Create: Validation

Loading…
Cancel
Save