Appearance
Build editors and resolve object endpoints
Editors collect fields and submit an object, link, or method request. They are embedded by actions and by editing variants; an editor is not a standalone panel variant.
Start by deciding what is being changed and where every participating object comes from. Then choose presentation mode and fields. This order prevents a good-looking form from submitting the wrong object or relationship GUID.
Choose the mutation model
| Task | entityType / override | Required input |
|---|---|---|
| Create or update an object | entityType.object.metaTypeName | MetaType and fields |
| Create a link | entityType.link | source, target, and normally linkName |
| Create an object and link it | both object and link | one endpoint usually uses getFromCreatedObject |
| Invoke a MetaMethod | runMethod | parent, method, optional objects and params |
runMethod redirects submission to /MetaMethods/Run; it is not an additional post-save hook. Preconfigured objects/params and form values are merged by the method flow.
Presentation modes
| Mode | Behavior | Use when |
|---|---|---|
modal | Opens a dialog and waits for user input | normal create/edit flows |
panel | Uses a panel-owned editor surface | the consuming variant explicitly supports it |
direct-request | Applies defaults and submits without a form | every required value and endpoint is deterministic |
modal is the practical default in current action flows, but mode is required in the EditorType contract. Do not use direct-request when the user must choose an endpoint or provide a value.
Fields, tabs, and rows
Use either top-level fields or tabs. A tab needs a stable id, localized title, and its own fields. A { "layout": "row", "fields": [...] } group places compact controls together.
Every leaf field requires attribute. Important field behavior:
editAttributesubmits to a different path than the displayedattribute;readonlydisplays but does not provide editable input;hiddenexcludes the field from the visible/validated shared flow;type,label,listOfValue,comment,regEx, anddefaultValueoverride backend metadata when explicitly set;propertyAsIdandselectPanelconfigure object selection.
See metadata precedence and typed controls.
Object and link endpoints
A LinkEndpoint resolves one object selector at action time.
| Endpoint | Resolves from | Typical use |
|---|---|---|
objectId | fixed ObjectSelector | known configuration object |
getFromItem | current Table/Tree item | row action |
getFromCreatedObject | object created earlier in the same flow | create object, then link it |
getSelectedObjectForPanelId | last selection in a panel | cross-panel action when panel identity is stable |
getSelectedObjectForEventId | event registry selection | dependent request/editor |
getFromActionId | action result context | chained action flow |
selectPanel | user choice in an inline modal panel | endpoint cannot be known in advance |
For a linked selector, idSource decides which GUID is extracted:
- omitted or
"linkedObject": the target object's GUID; "link": the relationship entity's GUID.
Use "link" for deleting or updating the relationship. Use the default for object CRUD and methods that accept the linked object.
Endpoint support is consumer-specific. The union type documents possible sources, but a particular create, update, runMethod, reload, or event path may support only a subset. Verify the action guide before combining endpoint forms.
Minimal object editor
json
{
"mode": "modal",
"entityType": {
"object": { "metaTypeName": "ProductionOrder" }
},
"fields": [
{ "attribute": "name", "label": "Name" }
]
}The ProductionOrder MetaType must exist. The form inherits its type metadata when the metadata endpoint provides it.
Create an object and link it to the selected item
Use this editor on a row action for a parent object. The newly created operation becomes the source of the link; the clicked order is the target.
json
{
"mode": "modal",
"header": {
"title": { "en": "Create operation", "ru": "Создать операцию" },
"propertyAsId": "code"
},
"entityType": {
"object": {
"metaTypeName": "Operation"
},
"link": {
"linkName": "OrderOperation",
"source": { "getFromCreatedObject": true },
"target": { "getFromItem": true }
}
},
"fields": [
{
"attribute": "code",
"type": "String",
"label": { "en": "Code", "ru": "Код" },
"regEx": "^OP-[0-9]+$"
},
{
"attribute": "duration",
"type": "Integer",
"label": { "en": "Duration, min", "ru": "Длительность, мин" }
},
{
"attribute": "link.sequence",
"type": "Integer",
"label": { "en": "Sequence", "ru": "Порядок" }
}
]
}link.sequence belongs to link metadata/payload; the other fields belong to the new object.
Choose a target with a panel
json
{
"entityType": {
"link": {
"linkName": "OrderProduct",
"source": { "getFromItem": true },
"target": {
"selectPanel": {
"label": { "en": "Choose product", "ru": "Выберите изделие" },
"width": "48rem",
"height": "28rem",
"panel": {
"id": "product-picker",
"type": "table",
"request": { "metaTypeName": "Product" },
"pagination": { "rowsPerPage": [10] },
"columns": [
{ "attribute": "code", "label": "Code" },
{ "attribute": "name", "label": "Name" }
]
}
}
}
}
}
}The selection panel needs a complete request and a selectable variant. Its ID must not collide with the containing application.
Method-backed editor
json
{
"mode": "modal",
"runMethod": {
"parent": "ProductionOrder",
"method": "release",
"objects": [
{ "getSelectedObjectForEventId": "order-selected" }
],
"params": {
"source": "configurator"
}
},
"fields": [
{
"attribute": "comment",
"type": "Text",
"label": "Release comment"
}
]
}The MetaMethod defines the real object and parameter contract. Configurator JSON does not validate its name or payload.
Open modal, inline, typed, and object-selection editor forms Open create, update, selected-object detail, and linked-read flowsDefaults, precedence, and submission interactions
- The action or variant supplies its current item, selection, and action ID.
- The editor resolves object/link endpoints for that consumer.
- Existing-object flows load detail projections from
attributeandeditAttributepaths. - Explicit field metadata overrides loaded attribute metadata.
- Loaded values win over defaults; defaults fill only undefined fields.
- Shared validation checks regex and JSON, then the consumer submits.
- Follow-up response actions or reload actions refresh dependent surfaces.
For plain data, blank Guid and Object values normalize to null. This is a submission boundary, not a general “all empty strings become null” rule.
Limits and current drift
requiredis not enforced by the shared validator.- Editor mode support varies by consumer; a type declaration does not prove every action renders
panelmode. withLinkedAttributeis declared for object entity types, but public runtime semantics are not sufficiently verified for a recommended journey.- Endpoint variants are not universally supported by every action processor.
- Direct Link create/update/by-GUID fixture handlers exist, but the checked-in interactive Object API demo does not exercise them. Do not treat that route as runnable proof of direct Link mutations.
- Method names, parameter schemas, and permission rules belong to the backend contract.
Exact property reference
Presentation and structure:
Editor fields:
editor.{fields|tabs[].fields}[].attributeeditor.{fields|tabs[].fields}[].editAttributeeditor.{fields|tabs[].fields}[].typeeditor.{fields|tabs[].fields}[].labeleditor.{fields|tabs[].fields}[].requirededitor.{fields|tabs[].fields}[].readonlyeditor.{fields|tabs[].fields}[].hiddeneditor.{fields|tabs[].fields}[].defaultValueeditor.{fields|tabs[].fields}[].listOfValueeditor.{fields|tabs[].fields}[].commenteditor.{fields|tabs[].fields}[].regExeditor.{fields|tabs[].fields}[].propertyAsIdeditor.{fields|tabs[].fields}[].selectPaneleditor.{fields|tabs[].fields}[].layout
Object, link, and method targets:
editor.entityType.object.metaTypeNameeditor.entityType.object.withLinkedAttributeeditor.entityType.link.linkNameeditor.runMethod.parenteditor.runMethod.methodeditor.runMethod.objects[]editor.runMethod.params
LinkEndpoint target sources:
LinkEndpoint.objectIdLinkEndpoint.getFromActionIdLinkEndpoint.idSourceLinkEndpoint.getFromItemLinkEndpoint.getFromCreatedObjectLinkEndpoint.getSelectedObjectForPanelIdLinkEndpoint.getSelectedObjectForEventIdLinkEndpoint.selectPanel.panelLinkEndpoint.selectPanel.labelLinkEndpoint.selectPanel.heightLinkEndpoint.selectPanel.width