.. _journal_settings: Настройки журнала с примерами =============================== .. contents:: :depth: 3 На этой странице собраны практические примеры настройки журналов: использование выражений в атрибутах колонок, настройка предикатов для фильтрации, конфигурирование поиска по ассоциациям и отображение суммы по числовым колонкам. .. _expression_attributes: Выражения в качестве атрибутов -------------------------------- .. note:: Выражения должны поддерживаться источником данных. Фронтенд передаёт настроенные атрибуты в источник данных «как есть» и ожидает, что сервер понимает, как с ними работать. При настройке колонки журнала можно перейти в расширенные настройки и в поле **«Атрибут»** указать сложное выражение, которое в дальнейшем можно будет использовать для группировки, сортировки, поиска и отображения. .. image:: _static/journal_settings/expression_attribute.png :width: 300 :align: center Выражение должно быть записано в круглых скобках. Исключение — если выражение состоит из одной функции, то скобки не требуются. Подробнее о синтаксисе и списке доступных функций можно посмотреть в :ref:`ecos-data `. .. _journal_filter_current_user: Фильтрация записей журнала по текущему пользователю ---------------------------------------------------- Чтобы в журнале отображались только записи, связанные с текущим пользователем (например, где он является инициатором, ответственным, автором и т.д.), в настройках журнала перейдите во вкладку **Расширенные настройки** и в **Предикате** укажите: .. code-block:: json {"t":"eq", "att": "initiator", "val": "${$user?id}"} где: - **initiator** — атрибут (ассоциация), по которому выполняется фильтрация. Замените на нужный атрибут, например: ``author``, ``responsible``, ``assignee`` и т.д. - **$user** — контекстный атрибут, содержащий данные текущего пользователя. Выражение ``${$user?id}`` возвращает идентификатор текущего пользователя. .. tip:: Данный подход универсален — достаточно заменить имя атрибута в ``att`` на любую ассоциацию с пользователем, чтобы фильтровать записи по нужному полю. .. _searchAttribute: Параметр «Атрибут для поиска» ---------------------------------- В конфигурацию столбца журнала добавлен параметр **«Атрибут для поиска»** — атрибут, который нужно получить у записей из подзапроса. По умолчанию из подзапроса берутся идентификаторы найденных сущностей, но при необходимости можно взять у этих сущностей какой-то атрибут. В любом журнале со включёнными фильтрами выбрать столбец с текстовым поиском, задать фильтр. При применении фильтра UI строит и отправляет запрос с url: ``http://host/gateway/api/records/query?`` В теле запроса — query-предикат, который был задан фильтром по столбцу: .. code-block:: "query": { ... { "att": "someAttName", "t": "eq", "val": "1000" } ... } При построении этого query в предикате значение ``att`` меняется на значение параметра ``searchAttribute`` из конфигурации столбца журнала. Такой поиск планируется использовать для вычисляемых атрибутов. Отображать в журнале они будут то, что сконфигурировано в ``computed att``, а поиск должен выполняться по заданному в конфигурации столбца атрибуту. Фильтр по тексту в колонке «assoc». Настройки innerQuery ----------------------------------------------------------- 1. Расширены настройки — добавлена возможность использовать **RecordsQuery**. Например, на вычисляемых полях, что позволяет формировать произвольный запрос к разным источникам данных. 2. Для решения вопроса — когда пользователь выбирает произвольные предикаты (Contains, Equals, Starts with, …) при настройке фильтра — добавлен ещё один тег в запрос: **$PREDICATE_TYPE** — для его замены на клиентской части. 3. Добавлен атрибут — **innerQueryAttribute** — для возможности настройки отображения: .. code-block:: searchConfig: { delimiters: [], searchByText: { { "innerQuery": { "sourceId": "", "page": { "maxItems": 25 }, "query": { "t": "and", "val": [ { "att": "TYPE", "val": "currency", "t": "eq" }, { "att": "currencyCode", "val": "$TEXT", "t": "$PREDICATE_TYPE" } ] } }, "innerQueryAttribute": "" } } } Рассмотрим пример. Настроим поиск только по колонке **«Статус»**. 1. Перейти в дополнительные настройки колонки: .. image:: _static/journal_settings/01.png :width: 500 :align: center 2. Тип редактора указать **text**: .. image:: _static/journal_settings/02.png :width: 500 :align: center 3. В разделе **Search Config** в **запросе** введите: .. tip:: Запрос нужно задавать как можно точнее, с указанием типа запрашиваемой ноды. .. code-block:: json { "t": "and", "val": [ { "att": "TYPE", "val": "icase:caseStatus", "t": "eq" }, { "att": "title", "val": "$TEXT", "t": "$PREDICATE_TYPE" } ] } 4. Укажите необходимое **Количество записей подзапроса**: **Количество записей подзапроса** — сколько максимально записей на данный запрос вернёт сервер. Далее эти ноды будут использоваться как фильтр для формирования основного запроса — для отображения нужных записей в самом журнале. Но в ответе также будет приходить число, сколько сервер всего нашёл записей, и если это число больше указанного количества записей подзапроса, то в интерфейсе будет показываться сообщение о необходимости задать более точный фильтр. .. image:: _static/journal_settings/03.png :width: 500 :align: center Сохраните. Поиск осуществляется только по колонке **«Статус»**: .. image:: _static/journal_settings/04.png :width: 700 :align: center Настройки фильтрации колонки ----------------------------- В журнале для колонок появилась настройка **headerFilterEditor**. В настройках типа данных можно изменить фильтр с Select Journal на текстовое поле: Фильтр **Select Journal**: .. image:: _static/journal_settings/j_user_29.png :width: 700 :align: center Для изменения необходимо в журнале рядом с названием нажать: .. image:: _static/journal_settings/j_user_25.png :width: 700 :align: center У необходимой колонки нажать **«Дополнительно»**: .. image:: _static/journal_settings/j_user_26.png :width: 600 :align: center Указать настройки, как ниже: .. image:: _static/journal_settings/j_user_27.png :width: 400 :align: center Фильтр **Select Journal** изменён на текстовый: .. image:: _static/journal_settings/j_user_28.png :width: 700 :align: center .. _column_sum: Настройки отображения суммы для колонки ----------------------------------------- Добавлена поддержка группировки по всем записям в журнале с использованием :ref:`предиката `: .. code-block:: javascript await Records.query({sourceId: 'emodel/ecos-contract', query: {}, language: 'predicate', groupBy: ['*']}, 'sum(amount)'); .. code-block:: javascript await Records.queryOne({sourceId: 'emodel/ecos-contract', query: {}, language: 'predicate', groupBy: ['*']}, 'sum(amount)?num'); Включение или выключение отображения суммы для каждой колонки производится отдельно по каждому атрибуту. Тип атрибута должен быть **Number**. .. image:: _static/journal_settings/j_user_32.png :width: 600 :align: center | .. image:: _static/journal_settings/j_user_33.png :width: 500 :align: center Общая сумма учитывает только форматтеры :ref:`NumberFormatter ` и :ref:`DurationFormatter `. В нижней части столбца будет отображаться общая сумма значений столбца: .. image:: _static/journal_settings/j_user_31.png :width: 700 :align: center Отображение записей, отфильтрованных по значению из списка, при использовании стандартного или нестандартного атрибута ассоциации --------------------------------------------------------------------------------------------------------------------------------- 1. Если настроить атрибут для загрузки через точку, то фильтрация, сортировка и группировка будут работать, но уже не по ассоциации, а по типу вложенного атрибута. 2. Если нужен поиск по ассоциации, но в колонке должно отображаться имя сущности, то есть два пути: - Обычно для таких сценариев в типе сущности-справочника настраивается **Шаблон отображаемого имени (Display Name Template)**, куда выводится значение нужного атрибута. Например: ``${short}``. Преимущество этого подхода в том, что ссылки на эти сущности будут человекочитаемыми в любой части системы и отображаться одинаково. - Если же в большинстве случаев имя сущности должно быть одно, а в колонке журнала — частный случай, то эту задачу можно решить через форматтеры. Пример: .. code-block:: json { "id": "legalEntity", "type": "ASSOC", "formatter": { "type": "script", "config": { "vars": { "customVar": "${legalEntity.inn}" }, "fn": "return vars.customVar;" } } } где: - **legalEntity** — ассоциация; - **inn** — вложенный атрибут. В таком случае поиск будет работать по ассоциации, а в колонке будет отображаться значение из указанного атрибута. Сортировка колонок журнала -------------------------- .. _journal_column_sorting: Поведение сортировки по клику ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ При нажатии на заголовок колонки журнала применяется сортировка. Направление сортировки при **первом** клике определяется автоматически, исходя из типа данных атрибута колонки. Это улучшает удобство работы: числовые и датовые поля, как правило, интереснее просматривать в порядке «от новых/больших к старым/меньшим», а текстовые — в алфавитном порядке. Таблица направлений по умолчанию '''''''''''''''''''''''''''''''''' .. list-table:: :widths: 40 30 30 :header-rows: 1 :class: tight-table * - Тип атрибута - Первый клик - Пример * - ``DATE``, ``DATETIME`` - По убыванию (``ascending: false``) - Новые записи — сверху * - ``NUMBER``, ``INT``, ``LONG``, ``FLOAT``, ``DOUBLE`` - По убыванию (``ascending: false``) - Большие значения — сверху * - Остальные типы (``TEXT``, ``MLTEXT``, ``ASSOC``, ``BOOLEAN`` и др.) - По возрастанию (``ascending: true``) - Алфавитный порядок A → Z Последующие клики по той же колонке переключают направление на противоположное. Сортировка по другой колонке сбрасывает предыдущую и снова применяет направление по умолчанию для нового типа. Значок сортировки в заголовке ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Иконка сортировки в заголовке колонки отображается корректно: - **Активная сортировка** — иконка подсвечена и показывает направление (↑ или ↓). - **Нет сортировки** — иконка не подсвечена (серая/скрытая). Это позволяет сразу определить, по какой колонке и в каком направлении отсортирован журнал. Сортировка по умолчанию в конфигурации журнала ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Помимо интерактивной сортировки, в конфигурации журнала можно задать начальную сортировку через поле ``sortBy``. В этом случае журнал откроется уже отсортированным, независимо от типа атрибута: .. code-block:: yaml sortBy: - attribute: createdDate ascending: false .. note:: Поле ``ascending`` в ``sortBy`` имеет приоритет над автоматическим направлением по типу данных — оно применяется только при первом пользовательском клике на заголовок колонки. Подробнее о модели конфигурации ``JournalSortByDef`` см. :ref:`Конфигурация журналов`.