mirror of https://github.com/abpframework/abp.git
Browse Source
Add schema definitions for forms (form-descriptor, form-field-descriptor, form-field-type, form-layout-descriptor, form-rule-descriptor) to describe named forms, fields, layouts and conditional rules. Update page-type to include a new "form" page type and extend page-descriptor with form-related properties (formName, createFormName, editFormName, createFormDisplay, editFormDisplay) and conditional validation (require formName for type 'form', keep kanban's required groupByProperty). Extend model.schema.json to include a top-level "forms" array referencing the new form definitions.pull/25039/head
8 changed files with 344 additions and 7 deletions
@ -0,0 +1,38 @@ |
|||
{ |
|||
"$schema": "https://json-schema.org/draft/2020-12/schema", |
|||
"$id": "form-descriptor.schema.json", |
|||
"title": "FormDescriptor", |
|||
"description": "Describes a named form definition bound to an entity", |
|||
"type": "object", |
|||
"properties": { |
|||
"name": { |
|||
"type": "string", |
|||
"description": "Unique identifier for the form", |
|||
"minLength": 1 |
|||
}, |
|||
"entityName": { |
|||
"type": "string", |
|||
"description": "Full name of the entity this form is bound to (e.g., 'Namespace.EntityName')", |
|||
"minLength": 1 |
|||
}, |
|||
"fields": { |
|||
"type": "array", |
|||
"description": "Flat list of all field definitions in this form", |
|||
"items": { |
|||
"$ref": "form-field-descriptor.schema.json" |
|||
} |
|||
}, |
|||
"layout": { |
|||
"$ref": "form-layout-descriptor.schema.json" |
|||
}, |
|||
"rules": { |
|||
"type": "array", |
|||
"description": "Conditional rules for field/group visibility and enabled state", |
|||
"items": { |
|||
"$ref": "form-rule-descriptor.schema.json" |
|||
} |
|||
} |
|||
}, |
|||
"required": ["name", "entityName", "fields", "layout"], |
|||
"additionalProperties": false |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
{ |
|||
"$schema": "https://json-schema.org/draft/2020-12/schema", |
|||
"$id": "form-field-descriptor.schema.json", |
|||
"title": "FormFieldDescriptor", |
|||
"description": "Describes a single field in a form", |
|||
"type": "object", |
|||
"properties": { |
|||
"id": { |
|||
"type": "string", |
|||
"description": "Unique identifier for this field within the form", |
|||
"minLength": 1 |
|||
}, |
|||
"label": { |
|||
"type": "string", |
|||
"description": "Display label for the field", |
|||
"minLength": 1 |
|||
}, |
|||
"type": { |
|||
"$ref": "form-field-type.schema.json" |
|||
}, |
|||
"binding": { |
|||
"type": ["string", "null"], |
|||
"description": "Entity property name to bind to, or null for unbound fields. Supports dotted paths like 'Parent.Name' for related entity display." |
|||
}, |
|||
"enumType": { |
|||
"type": "string", |
|||
"description": "Full enum type name for select fields" |
|||
}, |
|||
"defaultValue": { |
|||
"description": "Default value for the field" |
|||
}, |
|||
"placeholder": { |
|||
"type": "string", |
|||
"description": "Placeholder text for the input" |
|||
}, |
|||
"helpText": { |
|||
"type": "string", |
|||
"description": "Help text displayed below the field" |
|||
}, |
|||
"readOnly": { |
|||
"type": "boolean", |
|||
"description": "Whether the field is read-only", |
|||
"default": false |
|||
}, |
|||
"modeVisibility": { |
|||
"type": "string", |
|||
"enum": ["both", "createOnly", "editOnly"], |
|||
"description": "Controls in which form mode the field is visible", |
|||
"default": "both" |
|||
}, |
|||
"validations": { |
|||
"type": "array", |
|||
"description": "Form-level validation rules (override or extend entity-level validators)", |
|||
"items": { |
|||
"$ref": "validator-descriptor.schema.json" |
|||
} |
|||
} |
|||
}, |
|||
"required": ["id", "label", "type"], |
|||
"additionalProperties": false |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
{ |
|||
"$schema": "https://json-schema.org/draft/2020-12/schema", |
|||
"$id": "form-field-type.schema.json", |
|||
"title": "FormFieldType", |
|||
"description": "Available field types for form fields", |
|||
"type": "string", |
|||
"enum": [ |
|||
"text", |
|||
"textarea", |
|||
"number", |
|||
"checkbox", |
|||
"date", |
|||
"select", |
|||
"lookup", |
|||
"guid", |
|||
"computed" |
|||
] |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
{ |
|||
"$schema": "https://json-schema.org/draft/2020-12/schema", |
|||
"$id": "form-layout-descriptor.schema.json", |
|||
"title": "FormLayoutDescriptor", |
|||
"description": "Describes the visual layout of a form (tabs > groups > field placements)", |
|||
"type": "object", |
|||
"properties": { |
|||
"tabs": { |
|||
"type": "array", |
|||
"description": "Ordered list of tabs in the form", |
|||
"minItems": 1, |
|||
"items": { |
|||
"type": "object", |
|||
"properties": { |
|||
"id": { |
|||
"type": "string", |
|||
"description": "Unique identifier for this tab", |
|||
"minLength": 1 |
|||
}, |
|||
"title": { |
|||
"type": "string", |
|||
"description": "Display title for the tab", |
|||
"minLength": 1 |
|||
}, |
|||
"isDefault": { |
|||
"type": "boolean", |
|||
"description": "Whether this is the default tab (cannot be deleted, receives orphaned fields)", |
|||
"default": false |
|||
}, |
|||
"groups": { |
|||
"type": "array", |
|||
"description": "Ordered list of groups within this tab", |
|||
"minItems": 1, |
|||
"items": { |
|||
"type": "object", |
|||
"properties": { |
|||
"id": { |
|||
"type": "string", |
|||
"description": "Unique identifier for this group", |
|||
"minLength": 1 |
|||
}, |
|||
"title": { |
|||
"type": ["string", "null"], |
|||
"description": "Optional display title for the group" |
|||
}, |
|||
"isDefault": { |
|||
"type": "boolean", |
|||
"description": "Whether this is the default group (cannot be deleted, receives orphaned fields)", |
|||
"default": false |
|||
}, |
|||
"rows": { |
|||
"type": "array", |
|||
"description": "Ordered list of layout rows; each row contains one or more cells (fields placed side-by-side)", |
|||
"items": { |
|||
"type": "object", |
|||
"properties": { |
|||
"cells": { |
|||
"type": "array", |
|||
"description": "Fields placed side-by-side in this row (total colSpan should not exceed 4)", |
|||
"minItems": 1, |
|||
"items": { |
|||
"type": "object", |
|||
"properties": { |
|||
"fieldId": { |
|||
"type": "string", |
|||
"description": "Reference to a field id in the form's fields array", |
|||
"minLength": 1 |
|||
}, |
|||
"colSpan": { |
|||
"type": "integer", |
|||
"description": "Number of grid columns this field spans (1-4)", |
|||
"minimum": 1, |
|||
"maximum": 4, |
|||
"default": 4 |
|||
}, |
|||
"colStart": { |
|||
"type": "integer", |
|||
"description": "Starting grid column (1-4). Omit or null to auto-place after the previous cell.", |
|||
"minimum": 1, |
|||
"maximum": 4 |
|||
} |
|||
}, |
|||
"required": ["fieldId"], |
|||
"additionalProperties": false |
|||
} |
|||
} |
|||
}, |
|||
"required": ["cells"], |
|||
"additionalProperties": false |
|||
} |
|||
} |
|||
}, |
|||
"required": ["id", "rows"], |
|||
"additionalProperties": false |
|||
} |
|||
} |
|||
}, |
|||
"required": ["id", "title", "groups"], |
|||
"additionalProperties": false |
|||
} |
|||
} |
|||
}, |
|||
"required": ["tabs"], |
|||
"additionalProperties": false |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
{ |
|||
"$schema": "https://json-schema.org/draft/2020-12/schema", |
|||
"$id": "form-rule-descriptor.schema.json", |
|||
"title": "FormRuleDescriptor", |
|||
"description": "Describes a conditional rule with one or more actions that execute when the condition is met", |
|||
"type": "object", |
|||
"properties": { |
|||
"id": { |
|||
"type": "string", |
|||
"description": "Unique identifier for this rule", |
|||
"minLength": 1 |
|||
}, |
|||
"name": { |
|||
"type": "string", |
|||
"description": "Human-readable name for this rule (optional)" |
|||
}, |
|||
"condition": { |
|||
"type": "object", |
|||
"description": "The condition that triggers this rule", |
|||
"properties": { |
|||
"fieldId": { |
|||
"type": "string", |
|||
"description": "The field whose value is evaluated", |
|||
"minLength": 1 |
|||
}, |
|||
"operator": { |
|||
"type": "string", |
|||
"enum": ["equals", "notEquals", "isEmpty", "isNotEmpty"], |
|||
"description": "Comparison operator" |
|||
}, |
|||
"value": { |
|||
"description": "The value to compare against (not used for isEmpty/isNotEmpty)" |
|||
} |
|||
}, |
|||
"required": ["fieldId", "operator"], |
|||
"additionalProperties": false |
|||
}, |
|||
"actions": { |
|||
"type": "array", |
|||
"description": "Actions to perform when condition is met (executed in order)", |
|||
"minItems": 1, |
|||
"items": { |
|||
"type": "object", |
|||
"properties": { |
|||
"type": { |
|||
"type": "string", |
|||
"enum": ["hide", "show", "disable", "enable", "setValue"], |
|||
"description": "The action type" |
|||
}, |
|||
"targetType": { |
|||
"type": "string", |
|||
"enum": ["field", "group"], |
|||
"description": "Whether the target is a field or a group" |
|||
}, |
|||
"targetId": { |
|||
"type": "string", |
|||
"description": "The id of the target field or group", |
|||
"minLength": 1 |
|||
}, |
|||
"value": { |
|||
"description": "The value to set (only for setValue action)" |
|||
} |
|||
}, |
|||
"required": ["type", "targetType", "targetId"], |
|||
"additionalProperties": false |
|||
} |
|||
} |
|||
}, |
|||
"required": ["id", "condition", "actions"], |
|||
"additionalProperties": false |
|||
} |
|||
Loading…
Reference in new issue