Journals Configuration
The journal configuration defines the data source, column set, available actions, sorting, grouping, and editing parameters. Configuration files are stored in YAML or JSON format in the ecos-uiserv service and placed in microservices at the path eapps/artifacts/ui/journal.
This page describes: ways to create and connect a journal, using record attributes and computed properties in formatters and editors, as well as the complete configuration object model.
Journal configuration is stored in ecos-uiserv. The list of loaded journals can be viewed in System Journals → Journals. Record creation options are taken from the associated type.
To add a new journal, you need to describe the type for which the journal will be described in Case Types.
Then add a
yml(preferred) orjsonconfiguration in any microservice at the path eapps/artifacts/ui/journal.
Examples
Journal with dashboards:
id: ecos-dashboards
name: { ru: Дашборды, en: Dashboards }
actions:
- uiserv/action@ecos-module-download
- uiserv/action@delete
- uiserv/action@edit
columns:
- id: moduleId
name: { ru: Идентификатор, en: Id }
- id: typeRef
name: { ru: Тип ECOS, en: ECOS Type }
- id: authority
name: { ru: Человек или группа, en: User or group }
Using Record Properties as Configuration
Journals provide the capability to use record attributes for configuring formatters and editors. To use this capability, simply specify the value of the required property in the configuration using ${...}
Example:
formatter:
type: script
config:
fn: 'return "Контрагент " + vars.inn;'
vars:
# атрибут ecos:inn будет загружен вместе со всеми другими в запросе поиска
inn: "${ecos:inn}"
Using Related Entity Properties for Cell Formatting
If we have an association (multiple or not, it doesn’t matter) and we want to format each related entity using its fields, we can use the following column configuration:
- id: some-assoc-attribute
attSchema: '{field0,field1}'
formatter:
type: script
config:
fn: 'return cell.field0 + " - " + cell.field1;'
Here, attSchema is an enumeration of the internal attributes that need to be loaded for the related entities.
The final query for the attribute some-assoc-attribute is formed from the following parts:
some-assoc-attribute— column id or, if present, theattribute[]— appended to the part from item 1 at the end, ifmultiple == true{value:?assoc,disp:?disp}— based on the column type, determines which scalars are loaded for the attribute (for associations, these are?assocand?disp)
We end up with: some-assoc-attribute[]{value:?assoc,disp:?disp}
Item 3 can be overridden by the attSchema parameter, and in the example above, the following attribute will be loaded:
some-assoc-attribute[]{field0,field1}
According to RecordsAPI rules, if aliases for values are not specified, they will be available under the names field0 and field1. The version with aliases would look like this:
some-assoc-attribute[]{alias0:field0,alias1:field1}
When loading such an attribute, we will get a result in the following format:
{
"some-assoc-attribute": [
{
"alias0": "значение атрибута field0 для первой связанной сущности",
"alias1": "значение атрибута field1 для первой связанной сущности"
},
{
"alias0": "значение атрибута field0 для второй связанной сущности",
"alias1": "значение атрибута field1 для второй связанной сущности"
}
]
}
Note
The formatter configuration described above configures only cell rendering. For the header filter and inline editing to work on an association column, you also need to set the editor field (usually type: journal). See Editors and the JournalEditor subsection.
Computed Properties
There are often situations where filters, formatters, or editors require additional data that may be loaded from a remote server. For such cases, computed properties (computed) are provided, which are described for a column or for the journal configuration as a whole.
All computed properties are divided into two levels:
Configuration Level
Record Level
The configuration level means that the property can be computed independently of the records displayed in the journal. The record level relies on record attributes for its computations. If the computed property configuration contains ${...} inserts, it is assumed to be a record-level property and needs to be computed separately for each row in the journal. If there are no such inserts, it is a configuration level, and the service can compute this property only once when the journal is first opened.
Name |
Properties |
Description |
|---|---|---|
attributes |
record: String — the record for which to get attributesattributes: String|List<String>|Map<String, String> — the attributes to load. |
Load attributes via
Records.get(record).load(attributes)
|
query |
query: String — the search query to executeattributes: String|List<String>|Map<String, String> — the attributes to load. |
Send search query via
Records.query(query, attributes)
|
script |
fn: String — script for computations. Can return a Promise.vars: Map<String, Any> — variables to be passed to the script. |
Execute script |
Example of using a computed property for selection options:
# колонка с идентификатором 'category'
- id: category
computed:
# идентификатор свойства
- id: options
# тип вычисляемого свойства
type: attributes
# конфигурация вычисляемого свойства
config:
record: app/sourceId@someCategoryRef
attributes: subcategories[]{label:?disp,value:?id}
editor:
# Указываем, что тип фильтра и inline-редактора — выбор из списка
type: select
config:
# ссылаемся на вычисляемое свойство с помощью ${...} и префикса '$computed.'
options: '${$computed.options}'
Journal Configuration Model
Model:
// Конфигурация журнала
JournalDef {
// Идентификатор журнала
id: String,
// Отображаемое имя журнала
name: MLText,
// Идентификатор источника данных, из которого будут загружаться записи.
// Как правило задается в типе, а здесь нужен только для особых случаев.
sourceId: String,
// Запись, из которой будет загружаться мета-информация для фильтров.
// По умолчанию - "{sourceId}@"
metaRecord: RecordRef,
// Предикат для поиска отображаемых записей.
// По умолчанию в журнале отображаются записи связанного типа.
// Используя это поле можно наложить дополнительные условия.
predicate: Predicate,
// Дополнительные данные для запроса при поиске записей.
// Если это поле задано, то язык поиска устанавливается predicate-with-data
// и структура query становится
// {
// data: {queryData},
// predicate: {predicate}
// }
queryData: ObjectData,
// Тип записей в журнале. Как правило это поле следует оставлять пустым,
// чтобы связь с типом указывалась в конфигурации типа.
// Данное поле полезно для случая когда у одного типа может быть несколько журналов.
typeRef: RecordRef,
// Список атрибутов для группировки записей
groupBy: List<String>,
// Сортировка по умолчанию
sortBy: List<JournalSortByDef>,
// Флаг, который определяет необходимость загрузки действий из типа.
// true - действия из типа загружаются
// false - действия из типа не загружаются
// null - действия из типа загружаются если поле actions пустое
actionsFromType: Boolean?,
// Ссылки на UI действия над записями в журнале
actions: List<RecordRef>,
// Описание UI действий в конфиге журнала. Если действие специфично только для определенного журнала
// и его использование в других частях системы не предполагается, то можно использовать данное поле.
actionsDef: List<JournalActionDef>,
// Флаг, которые определяет доступно ли inline-редактирование в журнале
editable: Boolean,
// Конфигурация колонок
columns: List<JournalColumnDef>,
// Вычисляемые значения в контексте журнала. Полезны для использования в форматтерах и редакторах.
computed: List<JournalComputedDef>,
// Флаг, который определяет что форма системная. Системные формы нельзя добавить в приложение ECOS.
system: Boolean,
// Дополнительные свойства для поддержки произвольных настроек,
// которые очень специфичны, чтобы стать частью основного конфига.
properties: ObjectData
}
// Структура для описания сортировки
JournalSortByDef {
// Атрибут для сортировки
attribute: String,
// Порядок сортировки. true - по возрастанию. false - по убыванию.
ascending: Boolean
}
JournalActionDef(
// Идентификатор действия. Не обязательный
id: String,
// Отображаемое имя действия
name: MLText,
// Отображаемое имя действия во множественном числе
pluralName: MLText,
// Иконка для действия
icon: String,
// Настройка для подтверждения действия
confirm: ActionConfirmDef,
// Тип действия
type: String,
// Конфигурация действия
config: ObjectData,
// Доступные возможности (execForRecord, execForRecords, execForQuery)
features: Map<String, Boolean>,
// Предикат для определения доступности действия
predicate: Predicate
)
// Конфигурация колонки
JournalColumnDef {
// Идентификатор колонки
val id: String,
// Отображаемое имя
val name: MLText,
// Тип атрибута (Строка, Число и др.)
val type: AttributeType?,
// Атрибут для загрузки данных. Служит для указания атрибута для загрузки, который отличен от {id}.
// Может быть вложенным (напр. ecos:counterparty.ecos:inn). Должен содержать только верхнеуровневый путь
// к загружаемому значению без скаляров
val attribute: String,
// Внутренняя схема атрибута. Используется для случаев, когда стандартная схема для AttributeType не подходит.
// Данная схема может содержать один из скаляров ('?str', '?disp', '?num' и др.) или
// пару из двух вложенных атрибутов: '{value:name,disp:?disp}'. Для пары атрибутов обязательно
// в качестве алиасов должны использоваться 'value' и 'disp'
val attSchema: String,
// Описание редактора, который будет использован в фильтрах и при инлайн редактировании.
// Если колонка searchable и editor не задан, контрол фильтра в заголовке будет пустым.
val editor: ColumnEditorDef,
// Описание форматтера, который будет использован при отрисовке ячеек в колонке.
val formatter: ColumnFormatterDef,
// Можно ли искать по колонке
val searchable: Boolean?,
// Можно ли искать по колонке используя произвольный текст
val searchableByText: Boolean?,
// Можно ли сортировать по колонке
val sortable: Boolean?,
// Можно ли группировать по колонке
val groupable: Boolean?,
// Доступно ли инлайн редактирование в колонке
val editable: Boolean?,
// Отображается ли колонка по умолчанию.
val visible: Boolean?,
// Есть ли возможность добавить колонку в журнал для отображения.
// Полезно когда отображать колонку нельзя, но искать по ней можно (searchable=true).
val hidden: Boolean?,
// Значения в колонке множественные или нет
val multiple: Boolean?,
// Вычисляемые значения для использования в форматтерах и редакторах
val computed: List<JournalComputedDef>,
// Дополнительные свойства для поддержки произвольных настроек,
// которые очень специфичны, чтобы стать частью основного конфига.
val properties: ObjectData = ObjectData.create()
}
// Конфигурация редактора
ColumnEditorDef {
type: String,
config: ObjectData
}
// Конфигурация форматтера
ColumnFormatterDef {
type: String,
config: ObjectData
}
// Конфигурация вычисляемого значения
JournalComputedDef {
id: String,
type: String,
config: ObjectData
}
Developer Tools
If you press Ctrl + Shift + LMB (Left Mouse Button) on the journal title on the journals page, its configuration will open for viewing.