Справочник по YAML

Динамическая модель сериализуется в YAML под корневым ключом model:. На этой странице полностью документируется схема: каждое поле, его тип, является ли оно обязательным, его значение по умолчанию и правила, которые им управляют. Руководство, ориентированное на задачи, см. в разделах Определение модели и Экраны и пункты меню.

Модель

Корень model содержит следующие поля верхнего уровня:

Поле Тип Обязательно Примечания

basePackage

string

нет

Java-пакет для сгенерированных классов динамических сущностей, перечислений и экранов. Если опущено или пусто, эффективным значением является базовый пакет последнего модуля Jmix плюс .dynmod. При сериализации поле опускается, если оно равно значению по умолчанию.

enumerations

list

нет

Определения динамических перечислений. Отсутствие или null становится пустым списком.

entities

list

нет

Расширения статических сущностей и определения динамических сущностей. Отсутствие или null становится пустым списком.

Имена и разрешение

Определения сущностей сопоставляются по имени сущности Jmix:

  • Если сущность с именем name уже существует в метаданных, определение расширяет эту статическую сущность динамическими атрибутами, валидацией, уникальностью или переопределениями экранов.

  • Если сущность с таким именем в метаданных отсутствует, Динамическая модель создаёт динамическую сущность с тем же именем сущности Jmix и сгенерированным Java-классом с именем <effective basePackage>.<name>.

Используйте Java-подобные имена для динамических сущностей, атрибутов, классов перечислений и значений перечислений. Сгенерированные идентификаторы базы данных нормализуются автоматически:

  • camel case разбивается на имена с подчёркиваниями в верхнем регистре, например loyaltyLevel становится LOYALTY_LEVEL;

  • неподдерживаемые символы заменяются подчёркиваниями;

  • зарезервированные слова получают завершающее подчёркивание, например user становится USER_;

  • идентификаторы, превышающие ограничение СУБД, сокращаются с помощью 8-символьного хеша.

Значения локализации

Большинство подписей используют простую карту «локаль-сообщение»:

messages:
  en: "Loyalty level"
  de: "Treuestufe"

Некоторые поля являются локализованными значениями и принимают либо простую строку:

viewTitle: "Benefit"

либо словарь локалей:

viewTitle:
  en: "Loyalty levels"
  de: "Treuestufen"

Ключи локалей должны быть непустыми и отображаться в строки. Во время выполнения предпочтение отдаётся точной локали, затем локали только с языком, затем первому значению словаря.

Перечисления

Динамические перечисления объявляются в model.enumerations:

enumerations:
  - name: "CustomerGrade"
    messages:
      en: "Customer grade"
    values:
      - name: "PLATINUM"
        id: "30"
        messages:
          en: "Platinum"
      - name: "GOLD"
        id: "20"
        messages:
          en: "Gold"
      - name: "BRONZE"
        id: "10"
        messages:
          en: "Bronze"

Поля перечисления:

Поле Тип Обязательно Примечания

name

string

да

Короткое имя класса или полностью квалифицированное имя класса. Короткие имена разрешаются относительно basePackage.

values

list

да

Должно содержать хотя бы одно значение.

messages

map

нет

Подписи для класса перечисления.

Поля значения перечисления:

Поле Тип Обязательно Примечания

name

string

да

Имя Java-константы перечисления.

id

string

да

Хранимый ID перечисления. Все ID в одном динамическом перечислении должны быть однородными: либо все парсятся как 32-битные целые числа, либо все являются нецелочисленными строками.

messages

map

нет

Подписи для этого значения перечисления.

Динамические перечисления реализуют EnumClass<Integer>, когда все ID являются целочисленными строками, в противном случае — EnumClass<String>.

Ссылки атрибутов на перечисления используют поле enumeration:

- name: "grade"
  enumeration: "CustomerGrade" # short name, resolved via base package
  messages:
    en: "Grade"

Статические перечисления также поддерживаются, если класс реализует EnumClass. Используйте полностью квалифицированное имя класса или короткое имя, когда класс перечисления находится в basePackage. Сопоставление перечислений с БД поддерживает как целочисленные ID, так и строковые ID.

Сущности

Определения сущностей объявляются в model.entities:

- name: "Benefit"
  messages:
    en: "Benefit"
  attributes:
    - name: "name"
      javaClass: "java.lang.String"
      instanceName: true
      messages:
        en: "Name"
  views:
    - type: "detail"
      viewId: "Benefit.detail"
      viewTitle: "Benefit"
      descriptor:
        template: "default"
Поле Тип Обязательно Примечания

name

string

да

Имя сущности Jmix. Существующее имя в метаданных означает расширение статической сущности; в противном случае создаётся динамическая сущность.

store

string

нет

Физическое JPA-хранилище для динамических сущностей. Пустое значение и main сериализуются как опущенные. Определения статических сущностей могут объявлять хранилище, только если оно совпадает с хранилищем сущности в метаданных. Хранилище существующей динамической сущности изменить нельзя.

attributes

list

нет

Динамические атрибуты. Отсутствие или null становится пустым списком.

uniqueConstraints

list

нет

Именованные ограничения уникальности на уровне сущности.

views

list

нет

Экраны UI, принадлежащие сущности.

resourceRoles

object

нет

CRUD-разрешения ролей для сущности. Поддерживается только для динамических сущностей.

validation

object

нет

Ограничения валидации на уровне сущности.

messages

map

нет

Подписи сущности.

Таблицы динамических сущностей используют настраиваемый префикс jmix.dynmodel.dynamic-entity-table-prefix, по умолчанию DYN_. Динамические атрибуты статических сущностей хранятся в дополнительных таблицах с использованием jmix.dynmodel.static-entity-table-prefix, по умолчанию DYN_. Дополнительные таблицы статических сущностей создаются в том же физическом хранилище, что и владеющая ими статическая сущность.

Атрибуты

Каждый атрибут должен определять ровно один вид:

  • тип данных: javaClass;

  • ссылка: entityName;

  • перечисление: enumeration.

- name: "Customer"
  attributes:
    - name: "taxId"
      javaClass: "java.lang.String"
      length: 20
      required: true
      unique: true
      validation:
        constraints:
          - annotation: "Pattern"
            parameters:
              regexp: "^[A-Z0-9-]+$"
            message:
              en: "Tax ID can contain uppercase letters, digits and dashes only"
      messages:
        en: "Tax ID"
Поле Тип Обязательно Примечания

name

string

да

Имя атрибута.

javaClass

string

вид

Java-класс для атрибутов типа данных. См. поддерживаемые значения ниже.

entityName

string

вид

Имя целевой сущности Jmix для ссылок и коллекций.

enumeration

string

вид

Имя динамического или статического перечисления. Короткие имена разрешаются через basePackage.

length

integer

нет

Длина для строк, значений URI, массивов байтов и перечислений со строковыми ID.

lob

boolean

нет

Индикатор LOB. Поддерживается только для атрибутов java.lang.String и byte[].

required

boolean

нет

Добавляет метаданные обязательности и правило валидации NotNull группы по умолчанию. Не создаёт ограничение БД NOT NULL.

unique

boolean

нет

Сокращённая запись для ограничения уникальности по одному атрибуту с именем <attributeName>Unique.

instanceName

boolean

нет

Помечает атрибут как свойство имени экземпляра. Если помечено несколько атрибутов, используется первый, а последующие игнорируются с предупреждением.

collection

boolean

нет

Делает ссылку entityName упорядоченным списком композиции.

calculated

object

нет

Делает атрибут доступным только для чтения и нехранимым.

validation

object

нет

Ограничения на уровне атрибута. Не разрешены для вычисляемых атрибутов.

resourceRoles

object

нет

Разрешения view/modify для атрибута.

messages

map

нет

Подписи атрибута.

Поддерживаемые значения javaClass

Атрибуты типа данных, хранимые в БД, сопоставляются с SQL-типами фреймворком. Используйте эти значения при написании YAML вручную:

Значение YAML Тип Java Сопоставление SQL по умолчанию

java.lang.String

String

varchar(255); length переопределяет размер

java.net.URI

URI

varchar(1024); length переопределяет размер

[B

byte[]

varbinary(255); length переопределяет размер

java.lang.Boolean или boolean

Boolean

boolean

java.lang.Character или char

Character

char(1)

java.lang.Integer или int

Integer

integer

java.lang.Long или long

Long

bigint

java.lang.Short или short

Short

smallint

java.lang.Double или double

Double

double

java.lang.Float или float

Float

real

java.math.BigDecimal

BigDecimal

decimal(38, 18)

java.math.BigInteger

BigInteger

decimal(38, 0)

java.time.LocalDate

LocalDate

date

java.time.LocalTime

LocalTime

time

java.time.LocalDateTime

LocalDateTime

timestamp

java.time.OffsetTime

OffsetTime

time with time zone

java.time.OffsetDateTime

OffsetDateTime

timestamp with time zone

java.util.UUID

UUID

UUID-тип, специфичный для БД

Примечания:

  • Сериализатор хранит значения Class#getName() Java. Для массива байтов это [B; скопируйте сериализованное значение, если не уверены.

  • Другие Java-классы не поддерживаются хранилищем Динамической модели, если не расширено сопоставление типов БД.

Отклонения, специфичные для БД:

Тип HSQLDB / H2 PostgreSQL MySQL / MariaDB SQL Server Oracle

UUID

uuid

uuid

char(32)

uniqueidentifier

char(32)

String

varchar(n)

varchar(n)

varchar(n)

nvarchar(n)

varchar2(n)

byte[]

varbinary(n)

bytea

varbinary(n)

varbinary(n)

raw(min(n, 2000))

Boolean

boolean

boolean

bit

bit

char(1)

OffsetTime

time with time zone

time with time zone

time, хранится в UTC

datetimeoffset

timestamp with time zone

OffsetDateTime

timestamp with time zone

timestamp with time zone

datetime, хранится в UTC

datetimeoffset

timestamp with time zone

String + lob: true

clob

text

longtext

nvarchar(max)

clob

byte[] + lob: true

blob

bytea

longblob

varbinary(max)

blob

Ссылки

Одиночные ссылки используют entityName:

- name: "loyaltyLevel"
  entityName: "LoyaltyLevel"
  messages:
    en: "Loyalty level"

Правила:

  • Цель должна разрешаться в динамическую сущность, объявленную в модели, или в существующую статическую сущность.

  • Динамические ссылки хранят значение первичного ключа цели.

  • Статические цели с составными первичными ключами не поддерживаются.

  • Владелец и цель должны находиться в одном физическом хранилище.

Коллекции

Атрибуты-коллекции являются упорядоченными списками композиции:

- name: "benefits"
  entityName: "Benefit"
  collection: true
  messages:
    en: "Benefits"

Правила:

  • entityName обязательно.

  • Цель должна быть динамической сущностью.

  • javaClass, enumeration, lob и instanceName не поддерживаются.

  • Коллекции не могут участвовать в ограничениях уникальности.

  • Владелец и цель должны находиться в одном физическом хранилище.

  • Статические владельцы с составными первичными ключами не поддерживаются.

Динамическая модель создаёт внутренние дочерние свойства для обратной ссылки на владельца и столбца порядка. Они не записываются в YAML.

Вычисляемые атрибуты

Вычисляемые атрибуты — это доступные только для чтения, нехранимые свойства, вычисляемые при обращении:

- name: "publicSummary"
  javaClass: "java.lang.String"
  calculated:
    evaluator: "spel"
    expression: "(name ?: '') + ': ' + (description ?: '')"
    dependsOn:
      - "name"
      - "description"
  messages:
    en: "Public summary"
Поле Тип Обязательно Примечания

evaluator

string

нет

Имя вычислителя, возвращаемое методом getName() бина DynamicCalculatedAttributeEvaluator. Если опущено или пусто, используется jmix.dynmodel.calculated-attributes.default-evaluator, затем spel.

expression

string

да

Выражение, специфичное для вычислителя. Встроенный вычислитель spel использует ограниченный SimpleEvaluationContext.

dependsOn

list

нет

Имена непосредственных свойств для загрузки вместе с вычисляемым атрибутом. Пути с точками отклоняются. Отсутствие или null становится пустым списком.

Правила:

  • Вычисляемый атрибут должен объявлять ровно один результирующий тип с помощью javaClass или enumeration.

  • entityName, collection, required, validation и уникальность не поддерживаются.

  • lob: true является лишь подсказкой UI-метаданных и всё равно требует, чтобы javaClass был java.lang.String или byte[].

  • Зависимости должны существовать в той же сущности — либо в текущей модели, либо в существующих метаданных.

  • Циклы между вычисляемыми атрибутами в одной сущности отклоняются.

  • Изменение существующего хранимого атрибута на вычисляемый или существующего вычисляемого атрибута на хранимый не поддерживается. Изменение результирующего типа вычисляемого атрибута также не поддерживается.

Встроенный вычислитель SpEL разрешает чтение свойств с учётом метаданных и зарегистрированные функции DynamicCalculatedAttributeFunction. Он не предоставляет доступ к Spring-бинам, T(…​), конструкторам, произвольным вызовам методов, рефлексии, доступу к загрузчику классов или инфраструктурным API.

Валидация атрибута

Валидация атрибута объявляется в attributes[].validation.constraints:

validation:
  constraints:
    - annotation: "Pattern"
      parameters:
        regexp: "^[A-Z0-9-]+$"
      message:
        en: "Tax ID can contain uppercase letters, digits and dashes only"

Поля ограничения:

Поле Тип Обязательно Примечания

annotation

string

да

Псевдоним ограничения. См. поддерживаемые псевдонимы ниже.

parameters

map

нет

Значения YAML — скаляр/список/объект. Имена параметров зависят от ограничения. Отсутствие становится пустой картой.

groups

list

нет

Псевдонимы групп или полностью квалифицированные имена классов групп валидации. Отсутствие означает Default.

message

локализованное значение

нет

Простая строка или карта локалей.

Поддерживаемые группы:

  • Default;

  • UiComponentChecks;

  • UiCrossFieldChecks;

  • RestApiChecks;

  • полностью квалифицированные имена классов, разрешаемые с помощью Class.forName().

Поддерживаемые ограничения атрибута:

Псевдоним Применяется к Параметры

NotNull

любой атрибут

нет

NotEmpty

строки, коллекции, массивы

нет

NotBlank

строки

нет

Size

строки, коллекции, массивы

min необязательно, по умолчанию 0; max необязательно, по умолчанию Integer.MAX_VALUE

Length

строки

min необязательно, по умолчанию 0; max необязательно, по умолчанию Integer.MAX_VALUE

Min

числовые

value

Max

числовые

value

DecimalMin

числовые

value; inclusive необязательное булево, по умолчанию true

DecimalMax

числовые

value; inclusive необязательное булево, по умолчанию true

Digits

числовые

integer; fraction

Positive

числовые

нет

PositiveOrZero

числовые

нет

Negative

числовые

нет

NegativeOrZero

числовые

нет

Past

дата/время

нет

PastOrPresent

дата/время

нет

Future

дата/время

нет

FutureOrPresent

дата/время

нет

Pattern

строки

regexp

Email

строки

нет

AssertTrue

булевы

нет

AssertFalse

булевы

нет

Валидация использует семантику null из Bean Validation: null является корректным, если только правилом не является NotNull, NotEmpty, NotBlank, AssertTrue или AssertFalse.

required: true эквивалентно обязательным UI-метаданным плюс правилу NotNull группы по умолчанию. Метаданные валидации не создают ограничений БД.

Валидация сущности

Валидация на уровне сущности объявляется в entities[].validation.constraints:

validation:
  constraints:
    - name: "discountDescriptionRequired"
      target: "entity"
      type: "expression"
      evaluator: "spel"
      expression: "discount == null || description != null"
      attributes:
        - "discount"
        - "description"
      path: "description"
      groups:
        - "UiCrossFieldChecks"
        - "RestApiChecks"
      message:
        en: "Description is required when discount is specified"
Поле Тип Обязательно Примечания

name

string

нет

Имя ограничения для диагностики.

target

string

да

Должно быть entity.

type

string

да

expression или bean.

evaluator

string

expression

Встроенный вычислитель выражений — spel. Пустое значение также разрешается в spel.

expression

string

expression

Должно вычисляться в true для корректных сущностей.

validator

string

bean

Имя, возвращаемое бином DynamicModelConstraintValidator.

attributes

list

нет

Имена участвующих атрибутов. Каждое имя должно существовать в модели или метаданных.

path

string

нет

Путь свойства нарушения. Пустое значение означает нарушение на уровне бина.

groups

list

нет

Те же псевдонимы групп, что и при валидации атрибута.

message

локализованное значение

нет

Простая строка или карта локалей.

Ограничения-выражения используют тот же подход с ограниченным доступом к свойствам SpEL, что и вычисляемые атрибуты. Ограничения-бины делегируются бинам DynamicModelConstraintValidator приложения.

Ограничения уникальности

Уникальность по одному атрибуту:

unique: true

Составная уникальность:

uniqueConstraints:
  - name: "customerCountryTaxIdUnique"
    attributes:
      - "countryCode"
      - "taxId"
    message:
      en: "Tax ID must be unique within a country"
Поле Тип Обязательно Примечания

name

string

да

Логическое имя ограничения. Должно быть непустым и уникальным в рамках сущности. Физическое имя в БД генерируется из имени таблицы плюс это значение.

attributes

list

да

Хотя бы один прямой динамический атрибут. Дублирующиеся имена отклоняются.

message

локализованное значение

нет

Сообщение о нарушении.

Правила:

  • attributes[].unique: true нормализуется в именованное ограничение на уровне сущности перед сравнением и планированием DDL.

  • Участвовать могут только прямые хранимые одиночные динамические атрибуты.

  • Вычисляемые атрибуты, коллекции и LOB-атрибуты отклоняются.

  • Статические владельцы с мягким удалением не поддерживаются.

  • Применение нового ограничения уникальности завершается неудачей, если существующие строки уже содержат дубликаты.

  • Уникальность для nullable-значений следует поведению целевой СУБД.

Ресурсные роли

Объявления динамических resourceRoles создают аддитивные политики ресурсов во время выполнения. Опущенные объявления не предоставляют доступ. Роли, перечисленные в jmix.dynmodel.security.full-access-roles, предоставляют полный доступ ко всем ресурсам динамической модели; по умолчанию это system-full-access.

Коды ролей должны быть непустыми. Отсутствующие коды ролей логируются и не предоставляют доступ.

CRUD-разрешения на уровне сущности поддерживаются только для динамических сущностей:

resourceRoles:
  read:
    - "employee"
    - "manager"
  create:
    - "manager"
  update:
    - "manager"
  delete:
    - "manager"

Разрешения атрибутов поддерживаются для динамических атрибутов как статических, так и динамических сущностей:

- name: "countryCode"
  javaClass: "java.lang.String"
  length: 2
  resourceRoles:
    view:
      - "employee"
      - "manager"
    modify:
      - "manager"
  messages:
    en: "Country code"

Разрешения для экранов и меню являются списками:

views:
  - type: "list"
    viewId: "LoyaltyLevel.list"
    viewRoute: "loyalty-levels"
    viewTitle:
      en: "Loyalty levels"
      de: "Treuestufen"
    templateParams:
      includeProperties: ["name", "discount"]
      excludeProperties: ["publicSummary"]
    resourceRoles:
      - "employee"
      - "manager"
    menuItem:
      parentMenu: "application"
      insertBefore: "Customer.list"
      title:
        en: "Loyalty levels"
      resourceRoles:
        - "employee"
        - "manager"
    descriptor:
      template: "default"

Экраны

Экраны объявляются в entities[].views.

views:
  - type: "list"
    viewId: "LoyaltyLevel.list"
    viewRoute: "loyalty-levels"
    viewTitle:
      en: "Loyalty levels"
      de: "Treuestufen"
    templateParams:
      includeProperties: ["name", "discount"]
      excludeProperties: ["publicSummary"]
    resourceRoles:
      - "employee"
      - "manager"
    menuItem:
      parentMenu: "application"
      insertBefore: "Customer.list"
      title:
        en: "Loyalty levels"
      resourceRoles:
        - "employee"
        - "manager"
    descriptor:
      template: "default"

Поля экрана:

Поле Тип Обязательно Примечания

type

string

динамические сущности

list или detail. Регистронезависимо при десериализации. Обязательно для экранов динамических сущностей. Экраны статических сущностей могут вывести его из зарегистрированного базового экрана.

viewId

string

да

Уникальный ID экрана. Объявления динамических и статических экранов должны задавать его явно.

viewRoute

string

нет

Сегмент маршрута динамической сущности. По умолчанию слаг, созданный из viewId; экраны детального просмотра добавляют /:id. Экраны статических сущностей не поддерживают это поле.

viewTitle

локализованное значение

нет

Заголовок экрана динамической сущности. Экраны статических сущностей не поддерживают это поле.

templateParams

map

нет

Параметры шаблона динамической сущности. Экраны статических сущностей не поддерживают это поле.

resourceRoles

list

нет

Коды ролей, которые могут открыть экран. Экраны статических сущностей не поддерживают это поле.

menuItem

object

нет

Пункт меню динамической сущности. Экраны статических сущностей не поддерживают это поле.

descriptor

object

статические сущности

Объявление дескриптора. Экраны динамических сущностей могут опустить его для использования шаблона по умолчанию. Экраны статических сущностей должны предоставлять descriptor.source.

lookupComponentId

string

нет

ID компонента выбора экрана списка динамической сущности. По умолчанию dataGrid. Экраны статических сущностей не поддерживают это поле.

editedEntityContainerId

string

нет

ID контейнера редактируемой сущности экрана детального просмотра динамической сущности. По умолчанию entityDc. Экраны статических сущностей не поддерживают это поле.

Экраны динамических сущностей

Правила:

  • type должен быть list или detail.

  • viewId должен быть задан явно и должен быть уникальным.

  • Если viewRoute опущено, он генерируется из viewId путём приведения к нижнему регистру и замены неалфавитно-цифровых последовательностей на -.

  • Маршруты детального просмотра автоматически добавляют /:id; поэтому сам viewRoute не должен заканчиваться на /:id.

  • Первый объявленный экран списка становится основным экраном списка для динамической сущности. Первый объявленный экран детального просмотра становится основным экраном детального просмотра.

  • descriptor может быть опущен, использовать template: "default", использовать путь к пользовательскому ресурсу-шаблону или предоставлять литеральный source.

  • Если используется descriptor.source, он должен быть корректным XML с корнем <view xmlns="http://jmix.io/schema/flowui/view">.

  • Явные дескрипторы списка должны содержать ID компонента выбора, по умолчанию dataGrid.

  • Явные дескрипторы детального просмотра должны содержать ID контейнера редактируемой сущности, по умолчанию entityDc.

Шаблоны по умолчанию:

  • io/jmix/flowui/view/template/list-view.ftl для экранов списка;

  • io/jmix/flowui/view/template/detail-template.ftl для экранов детального просмотра.

templateParams — это YAML-объект, передаваемый в рендеринг шаблона дескриптора. Динамическая модель не определяет для него фиксированную схему; поддерживаемые ключи зависят от выбранного шаблона. Например, шаблон может потреблять фильтры свойств в виде списка строк:

templateParams:
  includeProperties: ["name", "discount"]
  excludeProperties: ["publicSummary"]

Переопределения экранов статических сущностей

Объявления экранов статических сущностей переопределяют XML-дескриптор уже зарегистрированного экрана:

- viewId: "Customer.list"
  descriptor:
    source: |
      <?xml version="1.0" encoding="UTF-8" standalone="no"?>
      <view xmlns="http://jmix.io/schema/flowui/view"
            extends="com/company/sample/view/customer/customer-list-view.xml">
          <layout>
              <dataGrid id="customersDataGrid">
                  <columns>
                      <column property="taxId"/>
                  </columns>
              </dataGrid>
          </layout>
      </view>

Правила:

  • viewId обязательно и должно ссылаться на зарегистрированный статический экран.

  • type может быть опущен; он выводится из класса контроллера.

  • Поддерживается только descriptor.source.

  • descriptor.template, viewRoute, viewTitle, templateParams, resourceRoles, menuItem, lookupComponentId и editedEntityContainerId отклоняются.

  • Сгенерированный контроллер является подклассом текущего зарегистрированного контроллера и сохраняет его маршрут.

Дескриптор

descriptor должен содержать ровно одно из:

descriptor:
  template: "default"

или:

descriptor:
  source: |
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <view xmlns="http://jmix.io/schema/flowui/view"
          extends="com/company/sample/view/customer/customer-list-view.xml">
        <layout>
            <dataGrid id="customersDataGrid">
                <columns>
                    <column property="taxId"/>
                </columns>
            </dataGrid>
        </layout>
    </view>

Поля menuItem:

Поле Тип Обязательно Примечания

parentMenu

string

да

Существующий или новый ID родительского меню. Если не найден, создаётся корневое меню с этим ID.

insertBefore

string

нет

Вставить перед соседним ID меню, если он найден; в противном случае добавить в конец.

title

локализованное значение

нет

По умолчанию используется заголовок экрана, когда опущено.

resourceRoles

list

нет

Коды ролей, которые могут получить доступ к пункту меню.

Пункты меню экранов детального просмотра получают параметр маршрута id=new.