Типы данных ============ .. _data_types: .. contents:: :depth: 3 Общий обзор (Overview) ------------------------ **Тип данных** - основной артефакт ECM, описывающий объект. В типе данных определяются метаданные, которые будет содержать объект, статусы жизненного цикла, роли, которые могут работать с объектом. Тип данных связан с формой и журналом. Типы данных - артефакты с типом **model/type**. В Citeck на основе типа данных создаются следующие артефакты: * :ref:`Форма` * :ref:`Журнал` .. _data_types_types: Иерархия системных типов и логика их наследования ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ У каждого типа данных должен быть родитель. Базовые типы данных: .. image:: _static/data_types/type_1.png :width: 300 :align: center **Кейс (case)** - тип для хранения записи, изменяемой во времени посредстовом связи ее с бизнес-процессом (не явлется статической). Маркером того, что тип будет кейсом является необходимость прикрепления к нему процесса и указания при создании общей информации, атрибутов, ролей, статусов и матрицы прав. **Справочник (datalist)** - тип для хранения наборов бизнес-данных, которые будут использоваться как статические данные для документов, не участвующие непосредственно в бизнес-процессах. Маркером того, что тип будет даталистом является указание при его создании только общей информации и перечня атрибутов. В качестве родителя можно использовать созданный ранее тип данных. Родительские атрибуты попадают в список **наследуемых атрибутов** (:ref:`Атрибуты`) и по флагу **«Наследовать»** можно наследовать форму, действия, шаблон нумерации. Описание перехода к разделу через интерфейс ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _data_types_admin: Для просмотра существующих типов и их редактирования создан журнал **"Типы данных" (Рабочее пространство "Раздел администратора" - Модель)**: .. image:: _static/data_types/type_2.png :width: 600 :align: center По умолчанию в журнале не отображаются системные типы. Для отображения **ТОЛЬКО** системных типов перейдите в настройки таблицы, выставите **Системный тип - Да**: .. image:: _static/data_types/system_types.png :width: 600 :align: center Варианты получения экземпляра типа ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Тип данных можно создать или загрузить уже созданный в систему. Создание """"""""" Подробнее см. раздел ниже Для создания типа данных необходимо нажать **+ - Создать новый тип**: .. image:: _static/data_types/new_type_1.png :width: 500 :align: center Откроется форма создания типа данных: .. image:: _static/data_types/new_type.png :width: 600 :align: center Загрузка """"""""" Для загрузки созданного типа данных необходимо нажать **+ - Загрузить тип**: .. image:: _static/data_types/download_type.png :width: 500 :align: center Файл формата .yaml Пример описания типа ~~~~~~~~~~~~~~~~~~~~~ .. code-block:: yaml id: hr-offices-type name: ru: Офисы storageType: ECOS_MODEL parentRef: emodel/type@data-list formRef: uiserv/form@hr-offices-form journalRef: uiserv/journal@hr-offices-journal inheritActions: false defaultCreateVariant: true model: attributes: - id: officesCode name: ru: Код - id: officesCity name: ru: Город - id: officesAddress name: ru: Адрес Доступные действия с записью ----------------------------- .. image:: _static/data_types/actions.png :width: 600 :align: center В журнале администратору с каждой записью доступен стандартный набор действий: - :ref:`редактировать права`; - скачать в виде json-файла; - удалить; - открыть карточку в соседней вкладке; - открыть на редактирование; - редактировать json-файл; - копировать. Создание нового типа ---------------------- Форма создания нового типа состоит из следующих вкладок: .. image:: _static/data_types/tabs.png :width: 600 :align: center :ref:`Основные` – основные характеристики типа данных. :ref:`Атрибуты`– характеристика, определяющая свойства объекта. :ref:`Аспекты`– функционал расширения типа данных без изменения самого типа. :ref:`Роли` – роли, которые участвуют в работе с объектом. :ref:`Статусы`– статусы, по которым объект будет перемещаться по мере выполнения бизнес-процесса. :ref:`Стадии`– этапы жизненного цикла документа. :ref:`Варианты создания` – настройка поддержки выбора варианта создания после выбора типа :ref:`Связи` – настраиваются для отображения, добавления и удаления связанных объектов в виджете «Связи»» на карточке объекта. :ref:`Конфигурация контента` – настройки работы с содержимым (контентом). :ref:`Представления` – настройки режима отображения данных в виде списка. Основные ~~~~~~~~~ .. _data_types_main: .. image:: _static/data_types/tab_main.png :width: 600 :align: center **Родитель, форму, журнал**, указанные по умолчанию можно изменять. .. list-table:: :widths: 10 30 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание - Пример заполнения * - 1 - **Id (обязательное)** - уникальный идентификатор типа - test_type (snake case) * - 2 - **Имя** - локализованное название компонента - Тестовый тип * - 3 - **Шаблон отображения имени** - | локализованный шаблон заголовка записи, отображаемого при запросах ее локализованного имени (расширеный вариант для параметра п.2). | Поддерживает выражения с использованием данных записи - Тестовый тип № ${counter} * - 4 - **Описание** - локализованное описание данного типа (необязательно). - Тип, используемый для тестовых целей * - 5 - **Родитель** - тип данных, на основании которого, создается текущий. - | выбирается из списка предлагаемых: | :ref:`Кейс (по умолчанию), Справочник `, Документ, Файл библиотеки документов, Публикация | Остальное – иные созданные ранее типы данных, на основе которых можно создать новый тип. * - 6 - **Форма** - | ссылка на форму, которая будет открываться при инициировании создания записи данного типа. | Наследование формы позволяет не заполнять в дочернем типе поле **"форма"**, это поле в итоге заполнится значением из родительского типа. - есть вариант создания автоматически по умолчанию (Форма по умолчанию), создания вручную (Создать-Создать форму), загрузки (Создать-Загрузить форму). * - 7 - **Журнал** - ссылка на журнал, который будет отображать записи данного типа - есть вариант создания автоматически по умолчанию (Журнал по умолчанию), создания вручную (Создать-Создать журнал), загрузки (Создать-Загрузить журнал). * - 8 - **Шаблон нумерации** - | шаблон нумерации :ref:`См. Шаблоны нумерации` | Возможно наследование шаблона нумерации от родительского или же наоборот его запрет (управляется проставлением соответствующего флага). - выбирается из списка предлагаемых * - 9 - **Форма дополнительной конфигурации типа** - форма для поля config, которое является произвольным объектом, с возможностью редактировать её, используя форму. - * - 10 - **Действия** - | ссылки на действия, которые будут доступны в соответсвующем виджете всех записей данного типа, а также в журнале, связанном с типом (:ref:`подробнее о действиях`). | Возможно наследование действий от родительского или же наоборот его запрет (управляется проставлением соответсвующего флага) - выбирается из списка предлагаемых * - 11 - **Тип источника данных** - хранилище, в которое будут заноситься записи данного типа (название отражает не использумую БД, а сервис, в БД которого будут направляться запросы). Значение "По умолчанию" означает, что для места хранения будет использоваться "ID источника данных (12)" из текущего или родительского типа и при этом не будет никакого автоматического создания хранилища. Т.е. при типе источника данных "По умолчанию" предполагается, что место хранения уже подготовлено заранее. - выбирается из списка предлагаемых. * - 14 - **ID источника данных** - идентифтикатор источника для случая, когда используется хранилище не встроенное по умлочанию в систему (в случае когда в п.14 выбран выриант Custom). - test_datasource (snake case) * - 13 - **Видимость в рабочих пространствах** - | - **По умолчанию** – назначается типу данных по умолчанию. | - **Приватная** – экземпляры типа данных доступны в рамках рабочего пространства, в котором созданы. | - **Публичная** – экземпляры типа данных доступны пользователям в соответствии с правами, не зависимо от рабочего пространства, в котором созданы. - * - 14 - **Рабочее пространство по умолчанию** - в каком рабочем пространстве будет отображаться по умолчанию - * - 15 - **Политика проверки прав при поиске** - | позволяет настроить поиск с проверкой прав непосредственно записи, её родителя или вовсе отключить проверку прав при поиске. | В любом режиме результат поиска дополнительно проверяется на наличие доступа. - * - 16 - **Канбан доска** - выбор канбан-доски :ref:`См. Канбан-доска` - Создание и редактрование журнала, формы из типа данных """""""""""""""""""""""""""""""""""""""""""""""""""""""" Рассмотрим на примере журнала: .. image:: _static/data_types/new_journal.png :width: 400 :align: center При нажатии на **"Создать-создать журнал"** открывается форма создания журнала: .. image:: _static/data_types/new_journal_1.png :width: 400 :align: center При нажатии на **"Создать-загрузить журнал"** открывается форма загрузки журнала: .. image:: _static/data_types/new_journal_2.png :width: 400 :align: center Функциональность реализована в настройках компонента :ref:`Select Journal во вкладке "Кастомные"` При нажатии на **"Изменить"** открывается журнал, содержащий все созданные в системе журналы: .. image:: _static/data_types/new_journal_3.png :width: 400 :align: center При нажатии на **Редактировать** открывается форма редактирования соответствующей выбранной сущности на новой вкладке. Атрибуты ~~~~~~~~~ .. _ecos-model_label: .. image:: _static/data_types/tab_attributes.png :width: 600 :align: center .. list-table:: :widths: 10 30 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание - Пример заполнения * - 1 - **Id** - идентификатор поля, по которому оно будет доступно на форме, в журнале. - testAttribute (camelCase) * - 2 - **Имя** - имя поля для отображения пользователю. - Тестовый атрибут * - 3 - **Тип** - тип поля. :ref:`Поддерживаемые типы` - выбирается из списка предлагаемых. По умолчанию выставляется text. * - 4 - **Множественный** - множественный ввод разрешен - флаг * - 5 - **Обязательный** - поле обязательно к заполнению - флаг * - 6 - **Настройка прав для атрибута** - функционал, позволяющий произвести настройку прав доступа в отношении "Роль-Статус" для конкретного атрибута. :ref:`См. подробно` - выбирается состояние доступа атрибута на пересечении сетки "Роль-Статус" * - 7 - **Вычисляемые атрибуты** - функионал, позволяющий установить выражение-зависимость, позволяющий гибко создавать производные атрибуты :ref:`См. подробно` - настройка конфигурации в зависимости от типа и сложности вычисления атрибута * - 8 - **Наследуемые атрибуты** - отображение значений наследумых от родительского типа атрибутов в соответсвии с п. 1, 2 и 6 (при условии что родительский тип задан и имеет атрибуты) - отсутствует * - 9 - **Настройка прав для типа данных** - | функционал, позволяющий произвести настройку прав доступа документа в отношении "Роль-Статус". | А также выгрузить и удалить полную схему прав (включая настройки из п.6) :ref:`См. подробно` - выбирается состояние доступа документа на пересечении сетки "Роль-Статус" Возможные типы атрибутов: """"""""""""""""""""""""" .. _ecos-model_types: .. list-table:: :widths: 10 20 :align: center :class: tight-table * - **Text** - | Текст | По кнопке **"Настроить"** выбрать, текстовый атрибут является Уникальным. | При этом добавляется проверка уникальности таких атрибутов при создании и редактировании записей. | При приватной видимости уникальность проверяется для каждого созданного рабочего пространства, при публичной видимости - для всех созданных рабочих пространств. .. image:: _static/data_types/text_unique.png :width: 400 :align: center * - **Options** - | Возможность настраивать ограничения на атрибуты в виде списка возможных значений. | По кнопке **"Настроить"** можно настроить варианты для выбора с их отображаемым именем: .. image:: _static/data_types/options_type.png :width: 400 :align: center | Этот тип атриубута учтен при генерации авто-формы (на форме будет ecosSelect с вариантами, которые настроены в атрибуте) и в авто-журнале (фильтр будет выпадающим списком). | На бэкенде добавлена проверка значения у таких атрибутов, и если пользователь пытается записать значение, которое отсутствует в списке, то будет выдана ошибка. * - **MLText** - Текст с локализацией. Содержание меняется в зависимости от выбранной локализации. * - **Person** - Пользователь из оргструктуры * - **Group** - Группа пользователей из оргструктуры * - **Authority** - Пользователь или группа. Это по сути базовый тип и для пользователей и для групп * - **Association** - | Связь с другой сущностью. | По кнопке **"Настроить"** выбрать тип данных и при необходимости выставить признак дочерней ассоциации: .. image:: _static/data_types/association_type.png :width: 400 :align: center | У дочерней сущности автоматически появляется ассоциация ``_parent`` | При проверке прав если для текущей сущности нет специфичных настроек прав, то проверяются родительские. | При удалении родителя так же удаляются все связанные сущности. | Для дочерних ассоциаций есть защита от цикличной зависимости. | | Таким образом образуется двухсторонняя связь: | - от дочернего к родителю по системному атрибуту ``_parent``, | - от родителя к дочернему по настроенному атрибуту. * - **Number** - Число * - **Boolean** - Булево значение да/нет; * - **Date** - Дата * - **DateTime** - Дата с временем; * - **Content** - Содержимое. Как правило поля с этим типом используются для сохранения больших объемов данных. Например - содержимое документа. * - **JSON** - Текстовый, структурированный формат данных. Например: .. code-block:: json {"some": "data"} * - **Binary** - | Массив байт. Похож на контент, но намного проще. | Не рекомендуется здесь хранить более 1мб данных. Вычисляемые атрибуты """"""""""""""""""""" .. _count_attributes: .. image:: _static/data_types/count_1.png :width: 600 :align: center | .. image:: _static/data_types/count_2.png :width: 400 :align: center **Тип** - тип вычисляемого атрибута. Поддерживаются: * **Script** - вычисление атрибута на основе ``javascript'а``; * **Attribute** - вычисление атрибута на основе другого атрибута (можно делать алиас на глубоко вложенный атрибут. Например: ``counterparty.idocs:fullOrganizationName?str)``; * **Значение** - константное значение; * **Counter** - значение будет генерироваться по счетчику при создании документа и не меняться со временем. * **Template** - шаблонная строка. Можно использовать вставки вида ${…}. Например: ``${someAttribute?str}``. Вместо данного плейсхолдера будет подставлено значение укзанного атрибута; .. image:: _static/data_types/count_3.png :width: 400 :align: center **Метод хранения** - тип сохранения. Определяет, нужно или нет сохранять вычисленное значение и если да, то в какие моменты. Возможные значения: * **None** - сохранение не нужно. При каждом обращении вычисляем значение заново; * **On empty** - сохранять вычисленное значение только если сохраненное значение отсутствует (т.е. при запросе значения вернулся ``null``); * **On create** - сохранять вычисленное значение только после создания. Последующие мутации никак данный атрибут не затронут и он будет работать как обычный атрибут. * **On mutate** - сохранять вычисленное значение при каждой мутации. В случае использования :ref:`Records API` для изменения записи гарантируется актуальность значения. Возможности атрибута с типом **script** **************************************** Объекты в глобальной области видимости: .. list-table:: :widths: 10 20 :align: center :class: tight-table * - **Records** - адаптер для RecordsService; - Методы: .. code-block:: text get(recordRef: String): AttValueScriptCtx // возвращает объект аналогичный value, который описан выше query(query: Object, attributes: Any?) // возвращает объект вида: .. code-block:: json { "records": [{ "id": "emodel/person@ivan.petrov", "attribute0": "value0", "attribute1": "value1" }, { "id": "emodel/person@petr.ivanov", "attribute00": "value00", "attribute11": "value11" } ], "totalCount": 123 "hasMore": true } * - **value** - текущий документ; - | Свойства .. code-block:: text id: String //глобальный идентификатор записи localId: String //локальный идентификатор записи | Методы: .. code-block:: text load(attributes: Any?): Any? // загрузка атрибутов у текущей записи. Можно передавать массив, строку и объект | Пример: | Вычислить атрибут на основе трех других: .. code-block:: var firstName = value.load('firstName'); var lastName = value.load('lastName'); return lastName + ' ' + firstName; * - **log** - логгер. - [уточнить] .. warning:: Прикладных сервисов в контексте скрипта нет. Примеры ********* Заполнение инициатора (initiator) текущим пользователем: .. image:: _static/data_types/calculated_value_example.png :width: 600 :align: center Матрица прав """"""""""""" .. _permissions: **Матрица прав** - таблица, которая показывает, какими правами обладает конкретная роль на отдельные виды данных. Права могут быть настроены отдельно на документ, отдельно на его атрибуты. Матрицы, созданные для типов данных хранятся в :ref:`журнале Матрицы`. Настройка прав **************** Настройка прав осуществляется на форме редактирования типа во вкладке :guilabel:`Атрибуты`. .. _doc_rights: Права на документ: .. image:: _static/data_types/matrix_1.png :width: 600 :align: center | .. image:: _static/data_types/matrix_2.png :width: 400 :align: center .. important:: Чтобы сформированные по умолчанию права на документ вступили в силу, нажмите **Сохранить** .. _attribute_rights: Права на атрибут: .. image:: _static/data_types/matrix_3.png :width: 600 :align: center | .. image:: _static/data_types/matrix_4.png :width: 400 :align: center .. important:: Чтобы сформированные по умолчанию права на атрибут вступили в силу, нажмите **Сохранить** .. important:: Если пользователь участвует одновременно в нескольких ролях, то получает наибольшие права из тех, что ему доступны согласно матрице. .. important:: При разработке модуля необходимо по соответствующей кнопке скачать матрицу прав. Полученный json поместить в модель по пути: ``app/artifacts/model/permissions`` Настрока прав на атрибуты в зависимости от каких-либо алгоритмов ****************************************************************** В конфигурации матриц прав есть массив **rules**: .. code-block:: data class PermissionRule( val roles: Set = emptySet(), val permissions: Set = emptySet(), val statuses: Set = emptySet(), val condition: Predicate = VoidPredicate.INSTANCE, val type: RuleType = RuleType.ALLOW ) Через правила можно писать кастомные условия для включения/отключения правила и реализовать с помощью :ref:`вычисляемых атрибутов` почти любую логику. Если не хватает вычисляемых атрибутов, то есть :ref:`внешние миксины`, которые можно реализовать в :ref:`кастомном микросервисе`. Настройка доступа к атрибуту только, если автор записи/пользователь относится к определённой группе ************************************************************************************************************ Для того чтобы узнать принадлежит ли текущий пользователь к группе можно использовать компонент :ref:`AsyncData` в разделе **Данные**: .. code-block:: Тип: Запись ID записи: emodel/person@{{user}} Атрибуты: isAdmin -> authorities._has.GROUP_ECOS_ADMINISTRATORS?bool (пример с группой администраторов) Имя свойства: ИМЯ_ПО_КОТОРОМУ_МОЖНО_ПОЛУЧИТЬ_РЕЗУЛЬТАТ_ВЫЧИСЛЕНИЙ В связанном поле, которому нужны данные из AsyncData, нужно добавить **Обновлять при** с указанием созданной AsyncData и после этого в логике можно ссылаться на данные в AsyncData. При этом важный момент - логику не нужно делать в обе стороны (показать поле и скрыть). Нужно настроить компонент по дефолту (скрыто поле или не скрыто) + логику, которая переводит компонент в другое состояние. Если вдруг условия для логики перестанет выполняться, то форма сама вернется к исходному состоянию. Для получения статуса редактируемой записи можно так же использовать AsyncData с ID записи {{recordId}}. :download:`json с данными формы <../files/async-data-user-group-example.json>` Ее можно открыть действием **Тестировать форму**. Вычисление прав **************** Вычисление прав для **PermissionsDef** (документа или атрибута) делится на два этапа: **1. Применение матрицы прав** <*Роль, <Статус, Уровень_прав*>>. Есть 3 уровня прав: * **NONE** - нет прав; * **READ** - чтение; * **WRITE** - чтение и запись. **2. Применение правил**. Правила нужны в случаях, когда логика распределения прав не укладывается в простую матрицу. Примеры: * Если есть 2 состояния документа в одном статусе, но с разными правами; * Если уровень прав зависит от атрибутов документа. Значения, которые вычисляются на этапах 1 и 2 должны быть абсолютными. Т.е. если у нас есть конфигурация прав, то она на 100% описывает текущий уровень прав и не предполагает наличие дополнительных механизмов. * Роли и статусы берутся из конфигурации типа. Если какой-то роли или статуса нет в конфигурации типа, то наличие этих сущностей в конфиге прав игнорируется. * Если для роли, статуса или атрибута нет настройки прав, но они присутствуют в типе, то по умолчанию выставляется право только на чтение. * Если у документа выставлен статус или есть роль, которые отсутствуют в конфиге типа, то права для них по умолчанию пустые (нет возможности даже читать). Пограничные условия ********************* Данные условия относятся к настройкам матрицы без системных статусов и ролей. .. csv-table:: :header: "Статус есть в типе","Статус есть в матрице","Роль есть в типе","Роль есть в матрице","Уровень прав" :widths: 10, 10, 10, 10, 20 "Да","Да","Да","Да","Из матрицы" "Да","Да","Да","Нет","Чтение" "Да","Да","Нет","Да","Нет прав" "Да","Да","Нет","Нет","Нет прав" "Да","Нет","Да","Да","Чтение" "Да","Нет","Да","Нет","Чтение" "Да","Нет","Нет","Да","Нет прав" "Да","Нет","Нет","Нет","Нет прав" "Нет","Да","Да","Да","Нет прав" "Нет","Да","Да","Нет","Нет прав" "Нет","Да","Нет","Да","Нет прав" "Нет","Да","Нет","Нет","Нет прав" "Нет","Нет","Да","Да","Нет прав" "Нет","Нет","Да","Нет","Нет прав" "Нет","Нет","Нет","Да","Нет прав" "Нет","Нет","Нет","Нет","Нет прав" Системные статусы и роли ************************* При необходимости можно настроить в типе системные статусы и роли. Для этого достаточно указать **ID** равным одному из предопределенных значений: **Роли:** 1. **EVERYONE** - виртуальная роль, к которой относятся все пользователи. *Assignees* у такой роли всегда пустые, но если роль **EVERYONE** по матрице получает права, то они распространяются на всех пользователей в системе. **Статусы:** 1. **EMPTY** - пустой статус. Полезен для приватных сущностей, которые недоступны на чтение всем пользователям в системе. Пустой статус может быть в случае если процесс для кейса не найден или операция старта процесса еще не завершилась; 2. **ANY** - любой статус. Вариант использования: для справочников можно задать права для **ANY** и **EVERYONE** на чтение, а для изменения записей завести отдельную группу. Например в модуле **Офферы** для справочного типа данных **Грейды**: .. image:: _static/data_types/system_roles_statuses.png :width: 700 :align: center Модель описания прав ********************* Основная логика находится в библиотеке **ecos-model-lib**. Конфигурация прав хранится в микросервисе **ecos-model**. :: TypePermsDef id: String // Идентификатор настроек. Уникальный в пределах системы typeRef: RecordRef // Тип данных, к которому относятся настройки прав permissions: PermissionsDef // Настройка прав на документ attributes: Map // Настройка прав на атрибуты :: PermissionsDef matrix: Map> // Матрица прав <Роль, <Статус, Уровень_прав>>. rules: List // Дополнительные правила для гибкой настройки :: PermissionLevel (enum) NONE // нет прав READ // права на чтение WRITE // права на чтение и запись :: PermissionRule roles: Set // Роли, для которых применяется правило permissions: Set // Список прав statuses: Set // Статусы, в которых данное правило применимо. Пустой список - любой статус condition: Predicate // Условие, по которому данное правило применимо в формате предиката (см. Язык предикатов). type: RuleType // Тип правила RuleType (enum) ALLOW - разрешение. Если правило активно, то permissions добавляются для указанных ролей REVOKE - отбирание прав. Если правило активно, то permissions убираются из списка уже существующих прав у ролей Наследование прав ******************* При поиске матрицы прав учитывается иерархия типов данных. При этом ищется первая не пустая конфигурация и дальше поиск прекращается. Т.е. никакого объединения настроек прав из разных типов не происходит. **Пример конфигурации** :: id: "2a5c3f00-06d5-4b62-8192-1b9116f12db4" typeRef: "emodel/type@contracts-cat-doctype-contract" permissions matrix: confirmers: approval: WRITE reworking: NONE initiator: approval: READ reworking: WRITE scan-man: approval: WRITE reworking: NONE rules: [] attributes:: name: matrix: confirmers: approval: WRITE reworking: NONE initiator: approval: READ reworking: WRITE scan-man: approval: WRITE reworking: NONE rules: [] title: matrix: confirmers: approval: WRITE reworking: NONE initiator: approval: READ reworking: WRITE scan-man: approval: WRITE reworking: NONE rules: [] Обновление прав в БД ********************** Права в БД на данный момент обновляются только при изменении записи или при явном вызове перерасчета прав. Т.е. если в роль добавить человека напрямую или добавить новую роль к типу и/или изменить матрицу прав, то перерасчет для уже созданных записей автоматически не произойдет. Чтобы пересчитать права можно выполнить следующий javascipt код в консоли браузера от имени пользователя с правами администратора: .. code-block:: var rec = Records.get('emodel/update-permissions@'); rec.att('typeRef', 'emodel/type@type-to-update'); await rec.save(); Обработка будет запущена асинхронно. Статус можно будет смотреть в логах микросервиса **ecos-model**. Если записей сотни, то обработка не должна занять больше 10-15 секунд. Аспекты ~~~~~~~~~ .. _type_aspects: .. image:: _static/data_types/tab_aspects.png :width: 600 :align: center Выберите спект из списка. По кнопке **"Настроить"** можно отредактировать конфигурацию - открывается форма, настроенная для :ref:`аспекта`. Атрибуты из добавленных аспектов будут доступны в создаваемом типе данных. Роли ~~~~~ .. _roles_statuses: .. image:: _static/data_types/tab_roles.png :width: 600 :align: center .. list-table:: :widths: 10 30 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание - Пример заполнения * - 1 - **Id** - уникальный идентификатор роли - myTestRole (camel case) * - 2 - **Название логики** - имя роли - Тестовая роль * - 3 - **Участники роли** - | статическое заполнение роли. | Выбор группы и/или отдельных пользователей из оргструктуры, которые будут выполнять функцию данной роли. - выбирается из списка оргуструктуры организации * - 4 - **Атрибуты** - динамическое заполнение роли. Выбор атрибута типа, на который будет ссылаться роль для получения назначаемых пользователей. - выбирается из списка предлагаемых атрибутов * - 5 - **Динамическая роль** - | динамическое заполнение роли. Возможные варианты: Script, Attribute, Значение, DMN. См. :ref:`подробно` | Установление произвольной гибкой логики, по которой будет произведено вычисление состава пользователей роли. - настройка конфигурации в зависимости от сложности и набора заивисимых данных для вычисления состава роли .. note:: Если пользователь или группа есть в любом из трех полей **Участники роли, Атрибуты, Динамическая роль**, то считается что пользователь/группа является представителем роли. т.е. происходит объединение по **ИЛИ**. Тип роли DMN """""""""""" .. _dmn_role: При выборе типа **DMN** необходимо выбрать опубликованное **Решение** из журнала. .. image:: _static/data_types/dmn_role.png :width: 500 :align: center Статусы ~~~~~~~ .. _associations: .. image:: _static/data_types/tab_statuses.png :width: 600 :align: center .. list-table:: :widths: 10 30 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание - Пример заполнения * - 1 - **Id** - уникальный идентификатор статуса - testStatus (camel case) * - 2 - **Название логики** - имя статуса - Тестовый статус * - 3 - **Статус по умолчанию** - выбор статуса по умолчанию для типа, с которым будет создаваться объект. - | выбирается из списка предлагаемых. Например, черновик. | Частый кейс - использования функционала черновика, где bpmn процесс еще не запущен, но необходимо, чтобы рекорд имел какой-то начальный статус. На форме документа статус может быть отражен следующим образом: .. image:: _static/data_types/form_status.png :width: 600 :align: center В компоненте :ref:`Text field `: - название поля может быть любым, - имя свойства - **_status**, - скрыть и заблокировать на ввод, если необходимо не отображать на форме. Стадии ~~~~~~ .. _stages: **Стадии** — этапы жизненного цикла документа. В каждую стадию входит один или несколько статусов. .. image:: _static/data_types/tab_stages.png :width: 600 :align: center Прежде, чем приступить к работе над стадиями, необходимо заполнить :ref:`Статусы`. .. list-table:: :widths: 10 30 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание - Пример заполнения * - 1 - **Название стадии** - Наименование стадии - testStage (camel case) * - 2 - **Статусы** - Перечень статусов, входящих в стадию - Выбирается из списка предлагаемых статусов Каждый статус может быть назначен только на одну стадию: .. image:: _static/data_types/tab_stages_2.png :width: 600 :align: center Стадии отображаются в виджете :ref:`виджете "Стадии"` Варианты создания ~~~~~~~~~~~~~~~~~~ .. _create: Настройка поддержки выбора варианта создания после выбора типа настраиваются на вкладке :guilabel:`Варианты создания` .. image:: _static/data_types/tab_create.png :width: 600 :align: center .. list-table:: :widths: 10 30 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание - Пример заполнения * - 1 - **Id** - уникальный идентификатор варианта создания - testCreate (camel case) * - 2 - **Имя** - имя поля для отображения пользователю. - Тестовый статус * - 3 - **Форма** - выбор формы для варианта создания - * - 4 - **Разрешен для** - пользователь или группа, для которых разрешен функционал. - * - 5 - **Дополнительно** - дополнительные настройки. - * - 6 - **Вариант создания по умолчанию** - Нужно или нет автоматически сгенерировать вариант создания для типа - * - 7 - **Добавить варианты создания дочерних типов** - Нужно или нет в списке вариантов создания текущего типа отображать варианты создания дочерних типов - * - 8 - **Действие после создания** - | Возможность настроить действие после создания карточки. | Если ничего не выбрать, то по умолчанию будет открываться карточка записи. | Если выбрать **Действие отсутствует (none)**, то после создания карточки не будет перехода на карточку. | Данная настройка наследуется от родительского типа и для базового типа data-list из коробки установлено действие none. - .. image:: _static/data_types/create_full.png :width: 600 :align: center | .. image:: _static/data_types/create_full_1.png :width: 300 :align: center Ограничение прав на создание """""""""""""""""""""""""""""""""" Создание можно ограничить через настройку вариантов создания. **"+"** в журнале и пункт в меню **"Создать"** появляются только, если для пользователя есть доступные варианты создания. В настройке типа можно отключить вариант создания по умолчанию и добавить новый с указанием групп, которые будут иметь к нему доступ. Заполнение имени и формы опционально. Если оставить эти поля пустыми, то они вычислятся автоматически. .. image:: _static/data_types/create_rights.png :width: 600 :align: center Связи ~~~~~~ .. _datatypes_associations: .. image:: _static/data_types/tab_relations.png :width: 600 :align: center .. list-table:: :widths: 10 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание * - 1 - **Id** - | идентификатор связи. Обязательное поле (если не заполнено, то сервер такую связь не сохраняет). | Это поле нужно для: | 1. Перезаписывания конфигурации связи в дочернем типе. Т.е. если мы в дочернем типе укажем тот же ID, то по сути перезатрем конфигурацию связи | 2. Указания атрибута, в котором связь сохранится (если не задано значение в поле "Атрибут") * - 2 - **Имя** - имя связи для отображения в интерфейсе * - 3 - **Атрибут** - | в который новые связи будут добавляться и из которого будут загружаться. | Как правило это ассоциация из вкладки :guilabel:`Атрибуты`. Если не задано то используется значение поля ID. * - 4 - **Направление связи** - | определяет какие связи отображать в виджете связей. Любая связь строится по принципу **SOURCE -> TARGET** | | - **SOURCE** - обратная к **TARGET** связь у источника. При открытии карточки **TARGET** мы увидим нашу связь. При открытии карточки **SOURCE** мы ничего не увидим. | | - **TARGET** - связь отображается только у документа, который хотим привязать. При открытии карточки **TARGET** мы ничего не увидим. При открытии карточки **SOURCE** мы увидим нашу связь. | | - **BOTH** - двухсторонняя связь. И на карточке **SOURCE** и на карточке **TARGET** увидим нашу связь. * - 5 - **Связанный тип** - тип сущностей, с которыми мы можем связать наш документ. * - 6 - **Журналы** - список журналов, которые можно использовать для создания новой связи. Если необходимо создавать связи не с одним определенным типом. * - 7 - **Загружать список журналов из целевого типа** - | загрузка списка журналов из типа данных. | Возможные значения - null, true, false. Пример: .. image:: _static/data_types/association_example.png :width: 600 :align: center **Связи (associations)** настраиваются для отображения, добавления и удаления связанных объектов в виджете формы :ref:`«Связи документов»` на карточке объекта. .. image:: _static/data_types/connections.png :width: 400 :align: center Связь документа с простой ссылкой """"""""""""""""""""""""""""""""""" Для добавления возможности связать документ с простой ссылкой (**Id** - webLinks, **Направление связи** - Target): .. image:: _static/data_types/association_example_weblink.png :width: 600 :align: center Связь в обе стороны """"""""""""""""""""" .. _associations_both_sides: Для связи в обе стороны необходимо, чтобы у источника ассоциации и у цели ассоциации была настроена ассоциация в типе с одним ID. .. list-table:: :widths: 20 20 :align: center * - | .. image:: _static/data_types/both_link_1.png :width: 500 :align: center - | .. image:: _static/data_types/both_link_2.png :width: 500 :align: center Простой пример настройки связей: """"""""""""""""""""""""""""""""" 1. Создадим 2 типа данных: - **Sons**: .. list-table:: :widths: 30 30 :align: center :class: tight-table * - .. image:: _static/data_types/Sample/r_01.png :width: 600 :align: center - .. image:: _static/data_types/Sample/r_02.png :width: 600 :align: center - **Dad**: .. list-table:: :widths: 30 30 :align: center :class: tight-table * - .. image:: _static/data_types/Sample/r_03.png :width: 600 :align: center - .. image:: _static/data_types/Sample/r_04.png :width: 600 :align: center | **Son** зададим ассоциацией: .. image:: _static/data_types/Sample/r_05.png :width: 300 :align: center 2. Заполним журнал **Sons** элементами: .. image:: _static/data_types/Sample/r_06.png :width: 700 :align: center 3. Заполним **Dad** - добавим к нему **sons**: .. image:: _static/data_types/Sample/r_07.png :width: 700 :align: center **Случай 1.** Чтобы **у Dad в виджете «Связи» отображались Sons.** Для этого необходимо: 1. Перейти в тип данных **Dad** во вкладку **«Связи»**, настроить: .. image:: _static/data_types/Sample/r_08.png :width: 600 :align: center 1. **Идентификатор связи.** 2. **Наименование связи**, которое будет использоваться в виджете. 3. **Атрибут**, в который новые связи будут добавляться и из которого будут загружаться. 4. **Направление связи.** **Source** является **Dad**, **target**, соответственно, **Sons**. 5. **Тип данных.** Для добавления элементов в виджете по нажатию **+**, и правильного отображения столбцов в нем. 2. Перейти в журнал **Dad**, открыть карточку: .. image:: _static/data_types/Sample/r_09.png :width: 700 :align: center | .. image:: _static/data_types/Sample/r_10.png :width: 600 :align: center **Случай 2.** Чтобы **у каждого Son в виджете «Связи» отображался его Dad.** Для этого необходимо: 1. Перейти в тип данных **Sons** во вкладку **«Связи»**, настроить: .. image:: _static/data_types/Sample/r_11.png :width: 600 :align: center 1. **Идентификатор связи.** 2. **Наименование связи**, которое будет использоваться в виджете. 3. **Атрибут**, в который новые связи будут добавляться и из которого будут загружаться. 4. **Направление связи.** **Source** является **Son**, **target**, соответственно, **Dad**. 5. **Тип данных.** Для добавления элементов в виджете по нажатию **+**, и правильного отображения столбцов в нем. Перейти в журнал **Sons**, открыть карточку: .. image:: _static/data_types/Sample/r_12.png :width: 600 :align: center Конфигурация контента ~~~~~~~~~~~~~~~~~~~~~~~~ .. _datatypes_content: Работа с контентом в Citeck осуществляется с использованием атрибутов типа данных с типом **"Содержимое"**. Атрибут _content """""""""""""""""" Атрибут ``_content`` служит для доступа к основному контенту записи без необходимости узнавать в каком именно атрибуте хранится контент. По умолчанию атрибут с контентом - content, но этот атрибут можно переопределить в типе во вкладке :guilabel:`Конфигурация контента`. При загрузке нового контента в свойство ``_content`` имя содержимого записывается в свойство **name** сущности (если оно определено в атрибутах). Контент в свойстве ``_content`` всегда имеет имя, которое совпадает с именем сущности (оно переопределяет имя самого контента). Настройка типа """"""""""""""" .. image:: _static/data_types/tab_content.png :width: 600 :align: center .. list-table:: :widths: 10 30 30 :header-rows: 1 :align: center :class: tight-table * - п/п - Наименование - Описание * - 1 - **Атрибут с основным контентом** - | атрибут, в котором находится контент, который доступен через свойство ``_content``. | Может быть сложным с указанием свойства из связанной сущности. Например - **linkedRecord.content**. | Если это поле оставить пустым, то основным полем с контентом будет **content**. * - 2 - **Тип хранилища** - | хранилище, где будет сохраняться контент. | По умолчанию **“local“**, что в свою очередь означает, что контент будет сохраняться в БД в той же схеме, что и таблица сущностей создаваемого типа данных. | Подробно о :ref:`смене типа хранилища`. * - 3 - **Атрибут с контентом для предпросмотра** - | атрибут, в котором находится контент, который будет использоваться для предпросмотра документа. | Если не указать значение, то используется **"Атрибут с основным контентом"** Java """""" .. _EcosContentApi: Для работы в java с контентом следует использовать интерфейс EcosContentApi: Загрузка: .. code-block:: java EntityRef tempFile = contentApi.uploadTempFile() .withMimeType("application/pdf") .writeContent((writer) -> writer.writeBytes(imageContent1)); ObjectData attributeForMutation = ObjectData.create() .set("customContentAtt", tempFile); // Создание EntityRef newFileWithContent = recordsService.create("emodel/test", attributeForMutation); // Обновление recordsService.mutate(newFileWithContent, attributeForMutation); Чтение: .. code-block:: java EntityRef ref = EntityRef.valueOf("emodel/test@localId"); EcosContentData contentData = contentApi.getContent(ref, "attributeWithContent"); if (contentData == null) { throw new RuntimeException("Content is null"); } // При работе с файлами, максимальный размер которых может быть более ~20мб // чтение контента в массив байт следует по возможности избегать. Иначе есть риск получить OutOfMemoryError byte[] bytes = contentData.readContent(reader -> { try { return IOUtils.toByteArray(reader); } catch (Exception e) { throw new RuntimeException(e); } }); Представления ~~~~~~~~~~~~~ .. _datatypes_views: Настройка отображения данных в журнале в виде списка. .. image:: _static/data_types/tab_views.png :width: 600 :align: center Включение флага **«Включить режим отображения в виде списка»** добавлет поля для выбора **«Атрибута с заголовком для элемента списка»**, **«Атрибута с текстом для элемента списка»**. .. image:: _static/data_types/tab_views_1.png :width: 600 :align: center Система добавляет в тип данных аспект listview, настройки попадают в поле config этого аспекта (можно проверить в json). При этом на вкладке аспект listview не доступен и не виден. Можно использовать для представления списка новостей, базы знаний, перечисления товаров или оборудования. Пример представления данных в виде списка: .. image:: _static/data_types/tab_views_2.png :width: 600 :align: center Описание параметров типа --------------------------- .. _type_parameters: .. list-table:: :widths: 5 10 :class: tight-table * - **id: String** - Уникальный идентификатор типа. Не наследуется. * - **name: MLText** - Имя типа. Не наследуется. * - **description: MLText** - Описание типа. Не наследуется. * - **storageType: String** - Тип хранилища. Не наследуется. * - **sourceId: String** - Идентификатор источника данных. Вычисляется по правилам: * Если задан, то остается как есть. * Если не задан. то: * Если **storageType = DEFAULT**, то берем sourceId родительского типа. * Если **storageType = ECOS_MODEL**, то вычисляем sourceId на базе идентификатора типа. * Если **storageType = ALFRESCO**, то в sourceId записывается "alfresco/" * - **parentRef: EntityRef** - Ссылка на родительский тип. Не наследуется. * - **formRef: EntityRef** - Ссылка на форму. Наследуется если значение **пустое** И **inheritForm == true**. * Если ссылка указывает на **uiserv/form@DEFAULT_FORM**, то в formRef записывается **"uiserv/form@type$" + id типа**. * - **journalRef: EntityRef** - Ссылка на журнал. Не наследуется. * Если ссылка указывает на **uiserv/journal@DEFAULT_JOURNAL**, то в journalRef записывается **"uiserv/journal@type$" + id типа**. * - **defaultStatus: String** - Статус по умолчанию. Если не задан, то наследуется от родителя. * - **boardRef: EntityRef** - Ссылка на канбан доску. Не наследуется. * - **dashboardType: String** - Тип дашборда. Если не задан, то наследуется от родителя. * - **inheritForm: Boolean** - Флаг для включения и отключения наследования формы. Не наследуется. * - **inheritActions: Boolean** - Флаг для включения и отключения наследования действий. Не наследуется. * - **inheritNumTemplate: Boolean** - Флаг для включения и отключения наследования шаблона нумерации. Не наследуется. * - **dispNameTemplate: MLText** - Шаблон отображаемого имени. Если не задан, то наследуется от родителя. * - **numTemplateRef: EntityRef** - Шаблон нумерации. Если не задан и флаг inheritNumTemplate == true, то наследуются от родителя. * - **actions: List** - Действия. Если не заданы И флаг inheritActions == true, то наследуются от родителя. * - **associations: List** - Ассоциации. Родительские ассоциации объединяются с ассоциациями текущего типа. Если id у ассоциаций совпадает, то происходит перезапись. * - **defaultCreateVariant: Boolean?** - Нужно ли генерировать вариант создания по умолчанию. Не наследуется. * - **createVariants: List** - Варианты создания. Не наследуются. Вычисляются по правилам: * Если **defaultCreateVariant == true**, то в список добавляется вариант создания с идентификатором **DEFAULT**. * Если **createVariantsForChildTypes == true**, то варианты создания текущего типа будут содержать варианты создания дочерних типов. * - **createVariantsForChildTypes: Boolean** - Нужно ли добавлять в варианты создания варианты создания дочерних типов. Не наследуется. * - **configFormRef: EntityRef** - Форма для доп. конфига. Если не задана, то наследуется. * - **config: ObjectData** - Доп. конфиг. Не наследуется * - **model: TypeModelDef** - Модель. Наследуется. Ниже подробнее. * - - model.attributes - Атрибуты типа. Наследуются от родителя и объединяются с атрибутами текущего типа. Если id совпадает, то происходит полное переопределение. * - - model.systemAttributes - Системные атрибуты типа. Наследуются от родителя и объединяются с системными атрибутами текущего типа. Если id совпадает, то происходит полное переопределение. * - - model.roles - Роли типа. Наследуются от родителя и объединяются с ролями текущего типа. Если id совпадает, то происходит полное переопределение. * - - model.statuses - Статусы типа. Наследуются от родителя и объединяются со статусами текущего типа. Если id совпадает, то происходит полное переопределение. * - - model.stages - Стадии типа. Не наследуются от родителя. * - **docLib: DocLibDef** - Настройки библиотеки документов. Не наследуются. * - **contentConfig: TypeContentConfig** - Настройка работы с контентом. Наследуется. Ниже подробнее * - - contentConfig.path - Путь до атрибута с основным контентом документа. Если не задан, то наследуется от родителя. * - - contentConfig.previewPath - Путь до атрибута с основным контентом для превью. Если не задан, то наследуется от родителя. Если и в родителе он не задан, то берется значение path. * - - contentConfig.storageRef - Ссылка на хранилище контента. Если не задана, то берется из родителя. * - - contentConfig.storageConfig - Конфигурация хранилища контента. Берется из родителя если storageRef не задан. * - **properties** - Доп. настройки типа. Не наследуются. * - **aspects** - Аспекты типа. Аспекты родителя объединяются с аспектами в текущем типе. Если поле ref у аспектов совпадает, то происходит переопределение. * - **queryPermsPolicy** - Политика поиска с проверкой прав. Наследуется от родителя если текущее значение DEFAULT * - **assignablePerms** - Назначаемые права. Объединяются с назначаемыми правами родительского типа. Отображаемое имя сущности -------------------------- Есть несколько сценариев для работы с отображаемым именем сущности. 1. Если необходимо, чтобы имя сущности всегда формировалось по шаблону, то следует использовать поле ``dispNameTemplate`` в типе; 2. Если необходимо, чтобы именем сущности можно было управлять, то следует в список атрибутов добавить атрибут с **id = 'name'**. Система автоматически будет использовать это поле для отображаемого имени (:ref:`скаляр` **?disp** в Records API) a. Можно вывести поле name на форму и тогда пользователь сможет сам им управлять b. Можно поле **name** не выводить на форму, но позволить пользователю работать с ``_content`` атрибутом. В этом случае при загрузке нового контента автоматически будет изменяться поле name и => отображаемое имя. Настройка прав для описания типов --------------------------------- .. _data_type_rights: В журнале типов для редактирования прав на конкретный тип доступна кнопка: .. image:: _static/data_types/rights_1.png :width: 600 :align: center При нажатии на эту кнопку можно настроить права на конкретный тип: .. image:: _static/data_types/rights_2.png :width: 600 :align: center Доступные права для редактирования: .. list-table:: :widths: 3 5 :header-rows: 1 :class: tight-table * - Идентификатор - Описание * - read - Право на чтение. На данный момент не проверяется т.к. конфигурации типов доступны всем. * - write - Право на изменение типа. * - create-children - Право на создание дочерних типов Право на изменение типа имеют три категории пользователей: 1. Системные администраторы 2. Пользователи, которым выданы права write системным администратором 3. Создатель типа Наследование прав ~~~~~~~~~~~~~~~~~~ Все права по умолчанию наследуются от родительского типа к дочерним, но это поведение можно отключить если убрать флаг **"Наследовать права"** при настройке прав на тип. Право на создание типа без родителя ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Если при создании типа поле с родительским типом оставить пустым, то родителем у такого типа будет тип с идентификатором **"base"**. Если нужно чтобы определенные пользователи могли создавать типы с любыми родителями, то следует выдать права **"create-children"** на тип **"base"**. Автоматически сгенерированные формы и журналы в типе данных ------------------------------------------------------------ .. _auto_journal_form: Для типа данных доступны автоматически генерируемая форма и журнал: .. image:: _static/data_types/auto_1.png :width: 600 :align: center Рассмотрим подробнее на примере. Заполним атрибуты типа данных: .. image:: _static/data_types/auto_2.png :width: 600 :align: center | На форме типа после создания становятся доступны действия с автосгенерированными формой и журналом: .. image:: _static/data_types/auto_3.png :width: 600 :align: center Журнал ~~~~~~~ .. _auto_journal: Журнал получает идентификатор – **type$idтипа**, название - как и тип данных, и может полноценно использоваться в системе – может быть добавлен в :ref:`меню`: .. image:: _static/data_types/auto_18.png :width: 500 :align: center | Перейти в журнал и создать элемент журнала: .. image:: _static/data_types/auto_19.png :width: 600 :align: center | Перейдем в журнал **«Журналы»**: .. image:: _static/data_types/auto_20.png :width: 600 :align: center Автосгенерированный журнал нельзя редактировать, т.к. он генерируется на лету при каждом обращении. Для журнала доступны действия: - скачать, - редактировать json, - копировать, - открыть журнал в соседней вкладке. По нажатию на *глаз* открывается дашборд для просмотра свойств сгенерированного журнала: .. image:: _static/data_types/auto_21.png :width: 600 :align: center Изменение автосгенерированного журнала """"""""""""""""""""""""""""""""""""""" Вариант 1 ********** Если необходимо изменить журнал. Например, чтобы в журнале не отображалось какое-то из полей. Для этого необходимо скопировать журнал из карточки типа данных. .. image:: _static/data_types/auto_22.png :width: 600 :align: center Переименовать: .. image:: _static/data_types/auto_23.png :width: 400 :align: center В типе данных проставляется данный журнал и становятся доступны действия, включая редактирование: .. image:: _static/data_types/auto_24.png :width: 600 :align: center Нажать **«Редактировать»**: .. image:: _static/data_types/auto_25.png :width: 600 :align: center Внести изменения и сохранить. Вариант 2 ********** Если автосгенерованный журнал уже добавлен в левое меню, то откройте журнал и нажмите на шестеренку: .. image:: _static/data_types/auto_journal_1.png :width: 600 :align: center Далее в окне представлены настройки: .. image:: _static/data_types/auto_journal_2.png :width: 300 :align: center Введите **Идентификатор** для нового журнала. В **Типе данных** по умолчанию указан тот тип, для которого был автоматически создан журнал. На форме настроек можно убрать все типы данных, если нет необходимости менять у них журнал по завершении создания нового артефакта. Сохраните. После подтверждения настроек открывается форма изменения виртуального журнала с предуказанным полем **«Идентификатор журнала»** (из настройки выше): .. image:: _static/data_types/auto_journal_3.png :width: 600 :align: center Внесите изменения и сохраните. После сохранения происходит создание нового журнала и в выбранных типах данных автосгенерированный журнал изменяется на созданный: .. image:: _static/data_types/auto_journal_4.png :width: 600 :align: center Форма ~~~~~~ .. _auto_form: Для созданного типа данных для формы доступны следующие действия: .. list-table:: :widths: 10 60 :align: center * - .. image:: _static/data_types/auto_4.png :width: 30 :align: center - | Тестировать форму - как будет выглядеть форма в итоговом виде: .. image:: _static/data_types/auto_5.png :width: 400 :align: center | Для просмотра формы необходимо нажать **Submit**: .. image:: _static/data_types/auto_6.png :width: 400 :align: center | На форме присутствуют поля в соответствии с данными и типом, указанным в атрибутах. * - .. image:: _static/data_types/auto_7.png :width: 30 :align: center - | Автосгенерированную форму можно скопировать, чтобы присвоить идентификатор и отредактировать под себя. :ref:`См. подробнее ниже` Перейдем в журнал **«Формы»**. Форма получает идентификатор – **type$idтипа**, название - как у типа данных. .. image:: _static/data_types/auto_8.png :width: 700 :align: center | Автосгенерированную форму нельзя редактировать. Для формы доступны действия: - тестировать форму, - скачать, - редактировать json, - копировать, - открыть форму в соседней вкладке. По нажатию на *глаз* открывается дашборд для просмотра свойств сгенерированной формы: .. image:: _static/data_types/auto_9.png :width: 700 :align: center | Изменение автосгенерированной формы """""""""""""""""""""""""""""""""""" .. _auto_form_change: Вариант 1 ********** Если необходимо изменить форму. Например, чтобы в форме инициатор выбирался автоматически как текущий пользователь. Для этого необходимо скопировать формуиз карточки типа данных. .. image:: _static/data_types/auto_10.png :width: 600 :align: center Переименовать: .. image:: _static/data_types/auto_11.png :width: 400 :align: center В типе данных проставляется данная форма и становятся доступны действия, включая редактирование: .. image:: _static/data_types/auto_12.png :width: 600 :align: center Нажать **«Редактировать»**: .. image:: _static/data_types/auto_13.png :width: 600 :align: center Далее перейти к редактированию компонента: .. image:: _static/data_types/auto_14.png :width: 600 :align: center На вкладке **«Кастомные»** выставить чекбокс **«Текущий пользователь по умолчанию»**, сохранить компонент: .. image:: _static/data_types/auto_15.png :width: 600 :align: center Далее сохранить форму, тип данных. В журнале **«Формы»** при этом пропадет автосгенерированная форма, т.к. она не выбрана по умолчанию в типе данных. И добавлена созданная вручную, для которой доступны и редактирование, и удаление: .. image:: _static/data_types/auto_16.png :width: 600 :align: center | Проверим – при создании заявления на отпуск инициатором автоматически проставляется текущий пользователь: .. image:: _static/data_types/auto_17.png :width: 700 :align: center Вариант 2 ********** Если автосгенерованный журнал уже добавлен в левое меню, то откройте журнал, нажмите +, и далее на открывшейся форме нажмите на шестеренку: .. image:: _static/data_types/auto_form_1.png :width: 600 :align: center Далее в окне представлены настройки: .. image:: _static/data_types/auto_form_2.png :width: 400 :align: center Введите **Идентификатор** для новой формы. В **Типе данных** по умолчанию указан тот тип, для которого была автоматически создана форма. На форме настроек можно убрать все типы данных, если нет необходимости менять у них форму по завершении создания нового артефакта. Сохраните. После подтверждения настроек открывается форма изменения виртуальной формы с предуказанным полем **«ID формы»** (из настройки выше): .. image:: _static/data_types/auto_form_3.png :width: 600 :align: center Внесите изменения и сохраните. После сохранения происходит создание новой формы и в выбранных типах данных автосгенерированная форма изменяется на созданный: .. image:: _static/data_types/auto_form_4.png :width: 600 :align: center