Conversation
Add comprehensive Low-Code System documentation and navigation. Introduces new docs under docs/en/low-code (index.md, fluent-api.md, model-json.md, scripting-api.md, interceptors.md, custom-endpoints.md, reference-entities.md, foreign-access.md) and updates docs/en/docs-nav.json to include a "Low-Code System" section linking these pages.
Add support and documentation for a new interceptor type, Replace, which runs JavaScript instead of the default DB operation. Updates made across low-code docs: - docs/en/low-code/interceptors.md: Document Replace semantics for Create/Update/Delete, add examples and model.json/type notes. - docs/en/low-code/fluent-api.md: Expand AddInterceptor docs to list allowed name/type values and note Replace behavior; small attribute call-site change (DynamicPropertySetByClients(false)). - docs/en/low-code/index.md: Simplify Getting Started by removing the package table and renumbering steps (register assembly, configure DbContext, define entity, add migration). - docs/en/low-code/scripting-api.md: Remove db.getList entry from the scripting API table. These changes clarify interceptor capabilities (Pre/Post/Replace) and streamline the quickstart instructions.
Replace "ABP Low-Code Module" with "ABP Low-Code System" across low-code documentation to reflect the naming change. Updated the doc-seo JSON descriptions and a couple of in-page references. Affected files: docs/en/low-code/custom-endpoints.md, docs/en/low-code/foreign-access.md, docs/en/low-code/interceptors.md, docs/en/low-code/model-json.md, docs/en/low-code/reference-entities.md, docs/en/low-code/scripting-api.md.
Clarify interceptor behavior in low-code docs: update fluent-api.md and interceptors.md to state that Replace Create interceptors must return the new entity's Id (Guid) so the system can fetch and return the created entity. Added an example showing `return result.Id;` after `db.insert(...)`, and noted that Replace-Update and Replace-Delete do not need to return a value.
Expand Low-Code documentation: - Custom Endpoints: added request/headers/params variables, many response helpers (created, noContent, unauthorized, forbidden, error, response) and logging helpers. - Fluent API: added Enum localization section, switched to property-based API names (DefaultDisplayPropertyName, AddOrGetProperty, etc.), added examples for chaining, foreign keys and interceptors, and generic Configure<T> usage. - Index: documented Export (Excel/CSV) flow and endpoints, plus Custom Commands/Queries usage and discovery; clarified DynamicEntityAppService and UI app service methods. - Interceptors & Scripting API: expanded context.commandArgs, context.currentUser and context.emailSender surfaces; added logging methods; added db.exists and updated available scripting methods. - model.json: added validator examples and a comprehensive validator table (url, phone, regularExpression, range, min/max, etc.). - reference-entities: removed a couple of reference rows (IdentityRole, Tenant). These edits improve developer guidance and add examples for using the low-code features.
Reflect API and copy updates in low-code docs. foreign-access.md: replace ConfigureProperty/SetForeignKey example with entity.AddOrGetProperty and assignment of a ForeignKeyDescriptor (EntityName, DisplayPropertyName, Access). index.md: minor wording tweaks for clarity and a corrected link anchor to the three-layer configuration system. model-json.md: remove the empty "foreignKeys" array from the entity JSON example to avoid implying it's required.
Update Low-Code docs to introduce a Low-Code Initializer pattern and model.json hot-reload support. Shows using DynamicEntityAssemblyInfo with rootNamespace and projectRootPath, adds a parameter table, and replaces simple assembly registration with an AsyncOneTimeRunner-based InitializeAsync that registers reference entities, assemblies, optional fluent API configs, and calls DynamicModelManager.Instance.InitializeAsync(). Adds a ResolveDomainSourcePath helper, guidance to call the initializer from Program.cs (and DbMigrator/other entry points) before building the app, and notes fallback to embedded resources when projectRootPath is empty.
Update low-code documentation examples to reflect API changes: make entity classes inherit DynamicEntityBase across examples, remove the separate "Register the Assembly" step and renumber steps, and introduce an async low-code initializer (MyAppLowCodeInitializer) using AsyncOneTimeRunner and DynamicModelManager.Instance.InitializeAsync. Also adjust command/query examples: CustomProductCreateCommand now derives from CreateCommand<Product> and returns Guid, and a CustomQuery (Single) example was added. These edits align docs with the new initialization flow and base entity type.
Improve Low-Code docs to clarify the distinction between dynamic entities and reference entities and to tighten foreign-access semantics. Updates across fluent-api, foreign-access, index, model-json, reference-entities, and scripting-api: explain that foreign access applies only between dynamic entities and that action menus appear on the target entity's UI; adjust wording for source/target terminology and permission behavior; add a comparison table for dynamic vs reference entities; update the reference-entity registration example to an async initializer pattern and show DynamicModelManager initialization; and note in the scripting API that insert/update/delete only apply to dynamic entities. These changes are editorial to reduce confusion around read-only reference entities and foreign key behavior.
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.
Update low-code Fluent API docs: add docs/en/images/quick-look.png and refactor examples to use DynamicEntityBase for entities. Remove the separate assembly registration step and replace the ConfigureServices sample with a Low-Code initializer (MyAppLowCodeInitializer) that uses AsyncOneTimeRunner and an async InitializeAsync which calls DynamicModelManager.Instance.InitializeAsync(). Also adjust step numbering and small samples to reflect these API changes (add server-only/internal property, set UI descriptors, etc.).
Remove docs/en/images/quick-look.png and replace/update the image at docs/en/low-code/images/quick-look.png. Consolidates the quick-look asset into the low-code subdirectory and updates the binary image file.
|
Images automagically compressed by Calibre's image-actions ✨ Compression reduced images by 51.3%, saving 115.6 KB.
|
There was a problem hiding this comment.
Pull request overview
This pull request adds comprehensive documentation for the ABP Low-Code System, a new feature that enables developers to build admin panels with auto-generated CRUD UI, APIs, and permissions using C# attributes, Fluent API, or JSON configuration.
Changes:
- Adds 8 new markdown documentation files covering all aspects of the Low-Code System
- Includes 4 supporting images for UI demonstrations
- Updates the documentation navigation to include a new "Low-Code System" section
Reviewed changes
Copilot reviewed 9 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/en/low-code/index.md | Overview document explaining the Low-Code System, its benefits, getting started guide, and key features |
| docs/en/low-code/fluent-api.md | Comprehensive guide on using C# attributes and Fluent API to define dynamic entities with code examples |
| docs/en/low-code/model-json.md | Documentation for the declarative JSON-based entity definition approach |
| docs/en/low-code/reference-entities.md | Explains how to link dynamic entities to existing C# entities for foreign key relationships |
| docs/en/low-code/interceptors.md | Guide for adding custom JavaScript business logic to CRUD operations |
| docs/en/low-code/scripting-api.md | Complete API reference for the server-side JavaScript scripting engine |
| docs/en/low-code/custom-endpoints.md | Documentation for creating custom REST API endpoints with JavaScript handlers |
| docs/en/low-code/foreign-access.md | Explains foreign access control for managing related entities through the UI |
| docs/en/low-code/images/*.png | Supporting images demonstrating UI features |
| docs/en/docs-nav.json | Navigation structure update to include the Low-Code System section |
| "method": "GET", | ||
| "description": "Get product statistics", | ||
| "requireAuthentication": false, | ||
| "javascript": "var count = await db.count('LowCodeDemo.Products.Product');\nreturn ok({ totalProducts: count });" |
There was a problem hiding this comment.
The example uses db.count() which is not documented in the Scripting API. According to the Scripting API documentation, the correct method should be either db.getCount('LowCodeDemo.Products.Product') or db.query('LowCodeDemo.Products.Product').count(). Please update this example to use one of the documented methods.
| "javascript": "var count = await db.count('LowCodeDemo.Products.Product');\nreturn ok({ totalProducts: count });" | |
| "javascript": "var count = await db.getCount('LowCodeDemo.Products.Product');\nreturn ok({ totalProducts: count });" |
| "route": "/api/custom/products/stats", | ||
| "method": "GET", | ||
| "requireAuthentication": false, | ||
| "javascript": "var totalCount = await db.count('LowCodeDemo.Products.Product');\nvar avgPrice = totalCount > 0 ? await db.query('LowCodeDemo.Products.Product').average(p => p.Price) : 0;\nreturn ok({ totalProducts: totalCount, averagePrice: avgPrice });" |
There was a problem hiding this comment.
The example uses db.count() which is not documented in the Scripting API. According to the Scripting API documentation, the correct method should be either db.getCount('LowCodeDemo.Products.Product') or db.query('LowCodeDemo.Products.Product').count(). Please update this example to use one of the documented methods.
| "route": "/api/custom/dashboard", | ||
| "method": "GET", | ||
| "requireAuthentication": true, | ||
| "javascript": "var productCount = await db.count('LowCodeDemo.Products.Product');\nvar customerCount = await db.count('LowCodeDemo.Customers.Customer');\nvar orderCount = await db.count('LowCodeDemo.Orders.Order');\nreturn ok({ products: productCount, customers: customerCount, orders: orderCount, user: user.isAuthenticated ? user.userName : 'Anonymous' });" |
There was a problem hiding this comment.
The example uses db.count() which is not documented in the Scripting API. According to the Scripting API documentation, the correct method should be either db.getCount('LowCodeDemo.Products.Product') or db.query('LowCodeDemo.Products.Product').count(). Please update this example to use one of the documented methods.
| "route": "/api/custom/products/stats", | ||
| "method": "GET", | ||
| "requireAuthentication": false, | ||
| "javascript": "var count = await db.count('Products.Product'); return ok({ total: count });" |
There was a problem hiding this comment.
The example uses db.count() which is not documented in the Scripting API. According to the Scripting API documentation, the correct method should be either db.getCount('Products.Product') or db.query('Products.Product').count(). Please update this example to use one of the documented methods.
| "javascript": "var count = await db.count('Products.Product'); return ok({ total: count });" | |
| "javascript": "var count = await db.getCount('Products.Product'); return ok({ total: count });" |
Move base.OnModelCreating(builder) to after builder.ConfigureDynamicEntities() in the docs example. This ensures dynamic entities are configured before the base model creation, reflecting the correct order to register dynamic entities in DbContext.OnModelCreating.
|
Images automagically compressed by Calibre's image-actions ✨ Compression reduced images by 15.3%, saving 14.6 KB.
2 images did not require optimisation. |
|
Images automagically compressed by Calibre's image-actions ✨ Compression reduced images by 16.2%, saving 11.1 KB.
4 images did not require optimisation. |
|
Images automagically compressed by Calibre's image-actions ✨ Compression reduced images by 14.5%, saving 8.3 KB.
4 images did not require optimisation. |
No description provided.