Appearance
Define an application
An application is the top-level unit shown in MES navigation. Its backend record owns identity and hierarchy; its jsonData document owns the configurable page. Use an application when a user needs a named entry point that opens one panel or a composed panel workspace.
Decide what belongs here
Put navigation concerns on the application record and screen behavior in jsonData.panel.
| Concern | Owner | Decision |
|---|---|---|
| Stable identity and route | id on the backend record | Do not copy the ID into the JSON envelope. |
| Navigation text and icon | name, icon | Use a localized name; use only an icon registered by the host. |
| Hierarchy and order | parent, child, displayPriority, pinnedToBottom | These fields organize applications, not panels. |
| Help text | jsonData.description | Use localized text or sanitized HTML for application-level guidance. |
| Screen composition | jsonData.panel | Choose one registered root panel; use group or tabs for multiple surfaces. |
The application API must return the record and its JSON document before the renderer can build the page. The JSON contract itself does not create backend objects, MetaTypes, methods, permissions, or linked data.
Application JSON envelope
The full runtime application type includes the backend-owned fields below. Configurator authors normally edit only jsonData.
json
{
"id": "production-planning",
"name": {
"en": "Production planning",
"ru": "Производственное планирование"
},
"icon": "schedule",
"displayPriority": 20,
"jsonData": {
"version": "1.0.0",
"description": {
"en": "Review and release production orders.",
"ru": "Проверяйте и запускайте производственные заказы."
},
"layout": {
"padding": true
},
"panel": {
"id": "planning-root",
"type": "group",
"groupLayout": { "type": "columns" },
"panels": []
}
}
}Configurable capabilities
| Path | Required | Behavior |
|---|---|---|
jsonData.version | yes in the typed contract | Must be "1.0.0". It identifies the supported document contract. |
jsonData.description | no | Localized application help displayed by the host. |
jsonData.layout.padding | no | Adds a layout class, but its current padding style is commented out. Do not depend on visible spacing. |
jsonData.panel | no in the type | Supplies the root panel. Without it the application has no configurable work surface. |
The fetched JSON is currently trusted rather than runtime-validated. A matching version therefore documents intent; it is not proof that every nested field is valid.
Defaults, ordering, and precedence
childis the API's current name for nested applications. It may benull; it is not the root panel'spanelsarray.displayPrioritycontrols application ordering where the navigation consumer honors it.pinnedToBottomis a separate placement signal.- The current locale, then the application's default locale, resolves localized strings. See values and localization.
- Panel-specific sizing and visibility begin only after
jsonData.panelis rendered. See common panel behavior.
Minimal valid configuration
This is the smallest useful JSON document. It displays a localized message and does not require an object API.
json
{
"version": "1.0.0",
"panel": {
"id": "welcome",
"type": "message",
"content": {
"heading": { "en": "Ready", "ru": "Готово" },
"text": {
"en": "Choose a task from the navigation.",
"ru": "Выберите задачу в навигации."
}
}
}
}End-to-end workspace example
The following envelope composes a master table and a detail panel. The table publishes the selected object under a stable event ID; the detail panel consumes that selection. The MetaTypes and data must already exist.
json
{
"version": "1.0.0",
"description": {
"en": "Select an order to inspect its attributes.",
"ru": "Выберите заказ, чтобы посмотреть его атрибуты."
},
"panel": {
"id": "orders-workspace",
"type": "group",
"groupLayout": { "type": "rows", "resizable": true },
"panels": [
{
"id": "orders",
"type": "table",
"panelLayout": { "size": { "value": 60, "min": 35 } },
"request": { "metaTypeName": "ProductionOrder" },
"events": [
{
"id": "orders-selected",
"name": "onObjectSelect",
"actions": [{ "name": "addSelectedObjectToRequest" }]
}
],
"columns": [
{ "attribute": "code", "label": "Code" },
{ "attribute": "status", "label": "Status" }
]
},
{
"id": "order-details",
"type": "attributes",
"panelLayout": { "size": { "value": 40, "min": 25 } },
"condition": {
"scenario": "objectSelected",
"eventId": "orders-selected"
},
"request": {
"getSelectedObjectForEventId": "orders-selected"
},
"editor": {
"fields": [
{ "attribute": "code", "readonly": true },
{ "attribute": "status", "readonly": true }
]
}
}
]
}
}The same select-and-inspect chain is implemented by a checked-in local fixture:
Open the Object and Link contract journeyThe simpler application and standard-table envelope is available here:
Open the basic local application fixtureLimits and current drift
- Application JSON is not a permission boundary. Backend and package permissions still decide what the user may read or change.
layout.paddingis declared and read, but current styling does not give it an observable layout effect.type: "group"andtype: "panels"belong to the application navigation model. They are separate from panel variant names.- A demo route proves only the capabilities visible in that fixture. It does not validate arbitrary application JSON.