Skip to content

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 ​

TaskentityType / overrideRequired input
Create or update an objectentityType.object.metaTypeNameMetaType and fields
Create a linkentityType.linksource, target, and normally linkName
Create an object and link itboth object and linkone endpoint usually uses getFromCreatedObject
Invoke a MetaMethodrunMethodparent, 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 ​

ModeBehaviorUse when
modalOpens a dialog and waits for user inputnormal create/edit flows
panelUses a panel-owned editor surfacethe consuming variant explicitly supports it
direct-requestSubmits without a form. create applies the editor defaults first; http without its modal editor sends no editor field values. A runMethod editor honours the mode only when a BPMN node is created and then sends no editor defaultsevery 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:

  • editAttribute submits to a different path than the displayed attribute;
  • readonly displays but does not provide editable input;
  • hidden excludes the field from the visible/validated shared flow;
  • type, label, listOfValue, comment, regEx, and defaultValue override backend metadata when explicitly set;
  • propertyAsId and selectPanel configure object selection;
  • control: "scratchFile" replaces the input with a file picker in the editor of an action with method: "runMethod". On submit the panel uploads the chosen file as a temporary file and passes its token to the method; see File for the method. The field needs an explicit "type": "String" and takes no defaultValue. Anything else is a configuration error: scratchFile in another editor, including the method-backed editor.runMethod of a create action; any other control value, an empty one included; scratchFile without "type": "String" or with a defaultValue. The field then shows the error instead of the input, and the action does not run until the configuration is fixed. Hidden fields and fields on other tabs are checked too; their errors appear in a notification when the user submits the form. An action that runs without showing its form — create with editor.mode: "direct-request", http without its modal editor, or runMethod started from attributes.panelActions or run when a BPMN node is created without its form or deleted — cannot fill any field with control, so such a field stops the action with the same notification.

See metadata precedence and typed controls.

A LinkEndpoint resolves one object selector at action time.

EndpointResolves fromTypical use
objectIdfixed ObjectSelectorknown configuration object
getFromItemcurrent Table/Tree itemrow action
getFromCreatedObjectobject created earlier in the same flowcreate object, then link it
getSelectedObjectForPanelIdlast selection in a panelcross-panel action when panel identity is stable
getSelectedObjectForEventIdevent registry selectiondependent request/editor
getFromActionIdaction result contextchained action flow
selectPaneluser choice in an inline modal panelendpoint 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.

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 flows

Defaults, precedence, and submission interactions ​

  1. The action or variant supplies its current item, selection, and action ID.
  2. The editor resolves object/link endpoints for that consumer.
  3. Existing-object flows load detail projections from attribute. They also load editAttribute unless it is the aggregation that attribute reads through: for attribute: "uom|designatorNational" and editAttribute: "uom", the request lists only uom|designatorNational.
  4. Explicit field metadata overrides loaded attribute metadata.
  5. Loaded values win over defaults; defaults fill only undefined fields.
  6. Shared validation checks regex and JSON, then the consumer submits.
  7. 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 ​

  • required is not enforced by the shared validator.
  • Editor mode support varies by consumer; a type declaration does not prove every action renders panel mode.
  • withLinkedAttribute is 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:

Object, link, and method targets:

LinkEndpoint target sources:

Next tasks ​