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 1 month 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
[DynamicEntity]
[DynamicEntityUI(PageTitle = "Products")]
public class Product : DynamicEntityBase
public class Product
{
[DynamicPropertyUnique]
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
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.
### Step 3: Add Relationships
### Step 4: Add Relationships
````csharp
[DynamicEntity]
[DynamicEntityUI(PageTitle = "Orders")]
public class Order : DynamicEntityBase
public class Order
{
[DynamicForeignKey("MyApp.Customers.Customer", "Name", ForeignAccess.Edit)]
public Guid CustomerId { get; set; }
@ -54,7 +65,7 @@ public class Order : DynamicEntityBase
}
[DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine : DynamicEntityBase
public class OrderLine
{
[DynamicForeignKey("MyApp.Products.Product", "Name")]
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
[DynamicEntity]
public class Product : DynamicEntityBase
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
@ -97,7 +108,7 @@ Use the `Parent` property for parent-child (master-detail) relationships:
````csharp
[DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine : DynamicEntityBase
public class OrderLine
{
public Guid ProductId { 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
[DynamicEntity]
[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 |
| `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]`
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,
"context.log('Deleted: ' + context.commandArgs.entityId);"
)]
public class Organization : DynamicEntityBase
public class Organization
{
public string Name { get; set; }
}
@ -230,7 +245,7 @@ Reference in an entity:
````csharp
[DynamicEntity]
[DynamicEntityUI(PageTitle = "Organizations")]
public class Organization : DynamicEntityBase
public class Organization
{
public string Name { 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
Configure in your Low-Code Initializer (e.g. `MyAppLowCodeInitializer`):
Configure in your Domain module's `ConfigureServices`:
````csharp
public static class MyAppLowCodeInitializer
public override void ConfigureServices(ServiceConfigurationContext context)
{
private static readonly AsyncOneTimeRunner Runner = new();
public static async Task InitializeAsync()
{
await Runner.RunAsync(async () =>
AbpDynamicEntityConfig.EntityConfigurations.Configure(
"MyApp.Products.Product",
entity =>
{
AbpDynamicEntityConfig.EntityConfigurations.Configure(
"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();
}
);
entity.DefaultDisplayPropertyName = "Name";
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
[DynamicEntity]
[DynamicEntityUI(PageTitle = "Customers")]
public class Customer : DynamicEntityBase
public class Customer
{
[DynamicPropertyUnique]
public string Name { get; set; }
@ -452,7 +457,7 @@ public class Customer : DynamicEntityBase
// Product entity
[DynamicEntity]
[DynamicEntityUI(PageTitle = "Products")]
public class Product : DynamicEntityBase
public class Product
{
[DynamicPropertyUnique]
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)]
public Guid CustomerId { get; set; }
@ -484,7 +489,7 @@ public class Order : DynamicEntityBase
}
[DynamicEntity(Parent = "MyApp.Orders.Order")]
public class OrderLine : DynamicEntityBase
public class OrderLine
{
[DynamicForeignKey("MyApp.Products.Product", "Name")]
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**:
![Actions menu showing foreign access items (Order, Visited Country, etc.)](images/actions-menu.png)
### `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.
@ -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.
![Foreign access modal with full CRUD capabilities](images/foreign-access-modal.png)
### `ForeignAccess.None`
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.
![Auto-generated menu items in the sidebar](images/menu-items.png)
## Why Low-Code?
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.
![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
### 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!';
```
![Interceptor validation error displayed in the UI](images/interceptor-error.png)
## Examples
### Pre-Create: Validation

Loading…
Cancel
Save