1.2. Способы интеграции с ARTA Synergy

  1. Синхронизация/интеграция server-side

    1. Событийная

    2. Прямая

  2. Модуль, влияющий на ход исполнения маршрута

    1. Блокирующий процесс

    2. SQL-запрос

  3. Приложение, работающее от имени пользователя по API

  4. Ссылки на модули системы

  5. WEB-модуль, встроенный в ARTA Synergy

  6. Дополнительный обработчик для стандартного процесса ARTA Synergy

  7. Внешние модули-компоненты (ВМК)

    1. Добавление ВМК

    2. События для ВМК

  8. Интеграция с Elasticsearch и Kibana для реализации аналитических дашбордов

1.2.1. Синхронизация/интеграция server-side

Существует два основных подхода для интеграции с Synergy:

  • Прямая интеграция — интеграционные модули разрабатываются с использованием API Synergy и интегрируемых систем. Синхронизация данных между системами и координация обмена между ними остаётся за разработчиком интеграционного модуля

  • Событийная интеграция — когда какая-либо из подсистем Synergy генерирует различные события, связанные с какими-либо данными. Обработчики этих событий (на стороне Synergy) при необходимости преобразовывают данные событий и передают их интегрируемой системе через какой-либо транспортный уровень

1.2.1.1. Прямая

ARTA Synergy предоставляет API для доступа к своим функциям с помощью rest сервисов. Описание методов API можно посмотреть в javadoc. Авторизация для всех методов API — Basic HTTP, подробнее о способах авторизации см. Способы авторизации в ARTA Synergy

1.2.1.2. Событийная

Под «событием» мы будем подразумевать сообщение о каком-либо изменении в Arta Synergy, содержащее тип события и минимально необходимые для получения связанной с событием информации либо воздействия на Synergy данные. Обработчик события (или событий) — программный модуль, читающий сообщения о событиях из JMS Queue или JMS Topic и осуществляющий, при необходимости, доступ к экземпляру Synergy, сгенерировавшему сообщение, с помощью API Synergy.

Обработчик событий является отдельным от Arta Synergy приложением, которое может работать как на том же сервере приложений, что и Arta Synergy, так и на удалённом.

Кроме этого, обработчик события может иметь собственные конфигурационные файлы, необходимые для реализации целевого назначения.

Обработчик событий может обрабатывать как конкретное событие (например, event.registers.formdata.add), так и класс событий (например, event.registers.*).

Обработка события может происходить в 3 этапа:

  1. Получение события

  2. Получение и преобразование необходимых обработчику данных

  3. Передача сформированного пакета данных далее (опционально)

ARTA Synergy генерирует событие в случае, если для этого события настроены обработчики. Обработчики событий настраиваются в конфигурационном файле ${jboss.home}/standalone/configuration/arta/api-observation-configuration.xml.

Сообщение, помещаемое в очередь JMS, представляет собой экземпляр javax.jms.TextMessage. Тело сообщения зависит от типа события, его описание можно посмотреть ниже среди описаний типов событий. Каждое событие содержит свойство api_event, указывающее на тип события, вызвавшего его (содержимое тега <event>event.registers.formdata.add</event> в конфигурационном файле).

Например:

<configuration>
    <listener> 
        <queue>java:jboss/queues/Synergy/UsersQueue</queue>
        <event>event.users.*</event>
    </listener>
    <listener> 
        <queue>java:jboss/queues/Synergy/RegisterCreateDocQueue</queue>
        <event>event.registers.formdata.add</event>
    </listener>
</configuration>

В этом примере настроены обработчики:

  1. java:jboss/queues/Synergy/UsersQueue для всех событий класса event.users.*, т.е. всех событий, связанных с пользователятми: event.users.account.change, event.users.formdata.change, event.users.account.add и т.д.

  2. java:jboss/queues/Synergy/RegisterCreateDocQueue для события добавления записи реестра event.registers.formdata.add.

Рассмотрим, например, код обработчика очереди UsersQueue:

public class UsersMessagesListener implements MessageListener {

    public void onMessage(Message message) {
        //Получаем идентификатор пользователя, для которого 
        //сгенерировано событие
        String userID = ((TextMessage) message).getText();
        //Получаем тип события
        String eventType = message.getStringProperty("api_event");

        //Выполнение действие по получению дополнительных данных через API
        //и прочих операций, зависящих от условий решаемой задачи
    }
}

Ниже описаны типы событий, которые могут быть сгенерированы ARTA Synergy.

Для события [event.orgstructure.department.formdata.change] - идентификатор подразделения, для события [event.orgstructure.position.formdata.change] - идентификатор должности, для события [event.users.formdata.change] - идентификатор пользователя будет передаваться как основной параметр, остальные как свойства. Получить их можно следующим образом:


public void onMessage(Message message) {
    //Получение идентификатора пользователя/должности/подразделения (В зависимости от события на которое подписаны)
    String userID = ((TextMessage) message).getText();
    //Получаем идентификатор формы
    String formUUID = message.getStringProperty("formUUID");
}
1.2.1.2.1. События ARTA Synergy
1.2.1.2.1.1. События пользователей

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

  • [event.users.account.change] Изменение данных полей первичной карточки пользователя, т.е. параметров его учётной записи:

    • Фамилия

    • Имя

    • Отчество

    • Логин

    • Код для показателей

    • e-mail

    • JID

    • Личная папка пользователя

  • [event.users.formdata.change] Изменение данных карточек пользователей на основе форм, ассоциированных с ним посредством функциональности «Отдел кадров». Для данного события передаются следующие данные:

    • userID - ID пользователя

    • formUUID - ID формы карточки пользователя

    • dataUUID - ID данных по форме

  • [event.users.account.add] Добавление новой записи учётной записи пользователя (и связанными с ней файлами по формам «отдела кадров»)

  • [event.users.account.delete] Удаление (пометка «удалённые») учётной записи пользователя (и связанных с ней файлов по формам «отдела кадров»)

  • [event.users.contactdata.change] Изменение «контактных данных» пользователя — изменение/добавление записей раздела «Контакты» профиля пользователя (модуль «Сотрудники») следующих типов:

    • Skype

    • Рабочий телефон

    • XMPP

    • Адрес

    • Мобильный телефон

    • Почта

    • Телефон

Для всех событий типа event.users.* передаваемые данные — ID пользователя Synergy.

1.2.1.2.1.2. События должностей

Данные события генерируются для каждого из нижеописанных случаев c должностями:

  • [event.orgstructure.position.add] Добавление новой должности

  • [event.orgstructure.position.change] Изменение данных должности - добавление/изменение/удаление следующей информации:

    • Общее:

      • Название должности (на трех языках)

      • Код для показателей

      • Подразделение

      • Шифр

      • Необходимое количество штатных единиц

      • Тип назначения целей

      • Номер

    • Управление модулями

    • Показатели - статус активности

  • [event.orgstructure.position.formdata.change] Изменение данных карточки должности на основе формы, ассоциированной с ней посредством функциональности «Отдел кадров». Для данного события передаются следующие данные:

    • positionID - ID должности

    • assistantID - ID заместителя, передается только при изменении данных карточки заместителя

    • formUUID - ID формы карточки должности

    • dataUUID - ID данных по форме

  • [event.orgstructure.position.delete] Удаление должности

Для всех событий типа event.orgstructure.position.* передаваемые данные - ID должности Synergy.

Итерационные задачи по реализации: 0281, 0493

1.2.1.2.1.3. События подразделений

Данные события генерируются для каждого из нижеописанных случаев c подразделениями:

  • [event.orgstructure.department.add] Добавление нового департамента

  • [event.orgstructure.department.change] Изменение данных подразделения - добавление/изменение/удаление следующей информации:

    • Общее:

      • Информация о подразделении:

        • Название (на трех языках)

        • Номер

        • Код для показателей

        • Родительское подразделение (для всех узлов, кроме корневого)

        • Удаленный филиал

      • Информация о руководителе подразделения:

        • Название должности (на трех языках)

        • Тип назначения целей

        • Руководитель

        • И.О. руководителя

      • Заместители:

        • Название (на трех языках)

        • Номер

        • Пользователь

        • Подразделения, в которых данный пользователь будет выполнять обязанности заместителя

    • Управление модулями

    • Показатели - статус активности

    • Права на дела:

      • Наследовать права от родительского подразделения

      • Дело

      • Тип документа

Замечание

Ввиду особенностей реализации при сохранении подразделения отдельно сохраняется его карточка, отдельно - заместители. Таким образом, в данном случае событие event.orgstructure.department.change будет отправлено дважды, а при изменении заместителей через метод API rest/api/positions/assistant/save - единожды.

  • [event.orgstructure.department.formdata.change] Изменение данных карточки подразделения на основе формы, ассоциированной с ней посредством функциональности «Отдел кадров». Для данного события передаются следующие данные:

    • departmentID - ID подразделения

    • formUUID - ID формы карточки подразделения

    • dataUUID - ID данных по форме

  • [event.orgstructure.department.delete] Удаление подразделения

Для всех событий типа event.orgstructure.department.* передаваемые данные - ID подразделения Synergy.

Итерационные задачи по реализации: 0281, 0493

1.2.1.2.1.4. События реестров

Событие для реестра не генерируются самостоятельно и не имеют предопределенных названий. Для того, чтобы для реестра было сгенерировано событие, необходимо в процесс активации / изменения / удаления реестра добавить процесс «Событие реестра» и указать в поле «Название» его название.

Название события должно начинаться со строки event.registries.formdata.. Для различных событий и для различных реестров могут быть указаны разные либо одинаковые названия событий в зависимости от целей решаемой задачи.

Рисунок 1.1. Процесс «Событие реестра»

Процесс «Событие реестра»

Подробнее о настройке и использовании реестров можно узнать в Руководстве Методолога, раздел Реестры, и Руководстве Пользователя, раздел Реестры.

1.2.1.2.1.5. События адресной книги

Объекты адресной книги (люди, организации) могут генерировать следующие события:

  • [event.addressbook.contact.add] Добавление нового контакта адресной книги

  • [event.addressbook.contact.change] Изменение данных контакта адресной книги: добавление / изменение / удаление записей карточки контакта. Событие генерируется при изменении:

    • данных в дополнительной карточке

    • данных в стандартной карточке:

      • «Люди»: ФИО, дата рождения, изображение, телефон, мобильный, e-mail, адрес, IM, URL, место работы, примечание, ключевые слова, поля дополнительной карточки, а также доступность контакта

      • «Организации»: название, изображение, сайт, адрес, телефон, мобильный, e-mail, поля дополнительной карточки, а также доступность контакта

  • [event.addressbook.contact.change] Изменение данных контакта адресной книги

  • [event.addressbook.contact.delete] Удаление контакта адресной книги

Для всех событий типа event.addressbook.contact.* передаваемые данные - это ID контакта адресной книги Synergy.

Итерационные задачи по реализации: AB1.

1.2.1.2.1.6. События работ
  • [event.workflow.work.create] Создание работы

  • [event.workflow.work.change] Изменение следующих параметров работы:

    • название

    • нагрузка

    • приоритет

    • сроки

    • ключевые слова

    • повторение

    • форма завершения

    • прогресс

  • [event.workflow.work.completion] Фактическое завершение работы

  • [event.workflow.work.expired] Работа просрочилась

  • [event.workflow.work.delete] Удаление работы

Примечание

При добавлении/изменении/удалении комментария к работе, аналогичное событие для документов в очередь не добавляется.

Для события [event.workflow.work.expired] используется системная настройка «Интервал проверки работ на просроченность (в минутах)» (Конфигуратор -> Настройки системы -> Параметры уведомлений)

Минимальный набор передаваемых данных для всех событий типа event.workflow.work.*:

  • идентификатор работы

Если работа запускается по реестру, то также обязательно передаются:

  • идентификатор данных по форме записи реестра (свойство с ключом dataUUID)

  • идентификатор документа реестра (свойство с ключом documentID)

В случае, если генерируется любое событие по работе, порожденной мероприятием проекта, в свойствах сообщения (ключ ArrangementID) передается идентификатор этого мероприятия (ParentID).

Для работ по процессу «работа по форме» (вызванного как непосредственно из маршрута реестра, так и из шаблона маршрута), кроме всего прочего, также передаются данные из дополнительных полей, настроенных непосредственно в самом процессе «работа по форме».

Итерационные задачи по реализации: AS25, AS26

1.2.1.2.1.7. События по проектам
  • [event.projects.arrangement.create] Создание мероприятия проекта

  • [event.projects.arrangement.delete] Удаление мероприятия проекта

  • [event.projects.arrangement.restore] Восстановление мероприятия проекта

  • [event.projects.arrangement.responsibles] Фактическое изменение списка ответственных за мероприятие проекта

Примечание: событие изменения списка ответственных не включает случаи, когда выбранному ответственному создается работа-запрос стать ответственным и когда он отказывает в этом запросе. Таким образом, учитывается только фактическое назначение ответственного за мероприятие проекта.

  • [event.projects.arrangement.progress] Выставление прогресса мероприятия

Минимальный набор передаваемых данных для всех событий типа event.projects.arrangement.* - это идентификатор мероприятия проекта.

Итерационные задачи по реализации: AS29, AS30

1.2.1.2.1.8. События по документам
  • [event.docflow.document.register] Регистрация документа в журнале

Минимальный набор передаваемых данных в сообщении для события [event.docflow.document.register] - идентификатор документа.

В свойствах сообщения (ключ registerID) передаётся идентификатор журнала.

Итерационные задачи по реализации: AS35.

1.2.1.2.1.9. События по формам
  • [event.form.formdata.change] Создание и сохранение данных по форме

Минимальный набор передаваемых данных в сообщении для события [event.form.formdata.change]:

  • dataUUID - идентификатор данных по форме;

  • formID - идентификатор формы;

  • isNew - сохранены ли данные:

    • true - новые;

    • false - существующие.

В свойствах сообщения (ключ dataUUID) также передаётся идентификатор данных по форме.

1.2.1.2.1.10. События комментариев

Данные события генерируются для каждого из нижеописанных случаев:

Комментарии к работе

  • [event.comment.work.add] Добавление нового комментария к работе

  • [event.comment.work.change] Изменение комментария к работе

  • [event.comment.work.delete] Удаление комментария к работе

Примечание

При добавлении/изменении/удалении комментария к работе, аналогичное событие для документов в очередь не добавляется.

Комментарии к документу

  • [event.comment.document.add] Добавление нового комментария к документу

  • [event.comment.document.change] Изменение комментария к документу

  • [event.comment.document.delete] Удаление комментария к документу

Личные комментарии

  • [event.comment.personal.add] Добавление нового личного комментария

  • [event.comment.personal.change] Изменение личного комментария

  • [event.comment.personal.delete] Удаление личного комментария

Комментарии к проекту/мероприятию

  • [event.comment.action.add] Добавление нового комментария к мероприятию проекта

  • [event.comment.action.change] Изменение комментария к мероприятию проекта

  • [event.comment.action.delete] Удаление комментария к мероприятию проекта

Для всех событий типа event.comment.* передаваемые данные зависят от типа комментария и выглядят следующим образом:

  • Комментарий к работе:

    • идентификатор комментария (свойство с ключом message text)

    • идентификатор автора комментария (свойство с ключом userID)

    • идентификатор документа (свойство с ключом documentID)

    • идентификатор работы (свойство с ключом actionID)

  • Комментарий к документу:

    • идентификатор комментария (свойство с ключом message text)

    • идентификатор автора комментария (свойство с ключом userID)

    • идентификатор документа (свойство с ключом documentID)

  • Личный комментарий:

    • идентификатор комментария (свойство с ключом message text)

    • идентификатор автора комментария (свойство с ключом userID)

    • идентификатор документа (свойство с ключом documentID)

    • идентификатор работы (свойство с ключом actionID)

  • Комментарий к мероприятию:

    • идентификатор комментария (свойство с ключом message text)

    • идентификатор автора комментария (свойство с ключом userID)

    • идентификатор проекта (свойство с ключом projectID)

    • идентификатор мероприятия (свойство с ключом actionID)

    Примечание

    В случае, если объектом события является комментарий к проекту, то параметры projectID и actionID будут равны.

Итерационные задачи по реализации: 0345

1.2.1.2.1.11. Генерация произвольных событий

В ARTA Synergy имеется метод API, позволяет генерировать произвольные события.

URL метода: rest/api/events/create. Типа запроса: POST.

Метод принимает следующие обязательные параметры:

  • eventName - название события (строка);

  • eventMsg - произвольный json (строка).

В случае успешного выполнения метода сервер вернет сообщение «Событие успешно сгенерировано».

Пример:

Событие, генерируемое мобильным клиентом по координатам GPS:

eventName=event.ext.gps&eventMsg={"lat":333.333,"lon":222.222}

Итерационные задачи по реализации: API41.

1.2.2. Модуль, влияющий на ход исполнения маршрута

1.2.2.1. Блокирующий процесс

Блокирующий процесс предназначен для того, чтобы предоставить возможность в маршрут активации/изменения/удаления реестра вставить асинхронный вызов внешнего модуля. Основное отличие блокирующего процесса от события реестра (см. События реестров) заключается в том, что:

  • при использовании блокирующего процесса маршрут реестра дожидается ответа о результате выполнения операции внешним модулем

  • блокирующий процесс может завершиться положительно или отрицательно, что повлияет на дальнейшую работу маршрута (Если блокирующий процесс завершится отрицательно — процесс остановится, если положительно — то продолжит работу дальше)

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

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

Конфигурация блокирующего процесса:

Для того, чтобы добавить блокирующий процесс, необходимо выполнить следующие действия:

  1. Добавить процесс с в маршрут реестра в конфигураторе:

Рисунок 1.2.


Название процесса должно начинаться с event.blocking. и далее строка, характеризующая суть блокирующего процесса.

  1. Создать очередь JMS для блокирующего процесса. Для этого необходимо в конфигурационный файл jboss (в стандартной установке это /opt/synergy/jboss/standalone/configuration/standalone-onesynergy.xml) в секцию <subsystem xmlns="urn:jboss:domain:messaging:1.2"> добавить:

<jms-queue name="ExampleQueue">
    <entry name="java:jboss/queues/Integration/ExampleQueue"/>
    <durable>true</durable>
</jms-queue>
  1. Связать очередь и процесс через конфигурационный файл {$jboss.home}/standalone/configuration/arta/api-observation-configuration.xml, добавив в него следующее:

<listener>
     <queue>java:jboss/queues/Integration/ExampleQueue</queue>
     <event>event.blocking.example</event>
</listener>

Обратите внимание, что название блокирующего процесса, указанное в маршруте в конфигураторе должно быть равно значению тега в конфигурационном файле api-observation-configuration.xml (в данном примере: event.blocking.example) и название очереди должно совпадать со значением тега queue конфигурационного файла api-observation-configuration.xml (в данном примере: java:jboss/queues/Integration/ExampleQueue)

Сообщение, передаваемое в очередь, является экземпляром TextMessage. Содержимым сообщения является объект JSON с полями:

  1. dataUUID — идентификатор данных по форме записи реестра

  2. executionID — идентификатор блокирующего процесса

  3. documentID — идентификатор документа реестра

После того, как модуль обратится к внешней системе и выполнит необходимые действия, он должен вызвать метод API Synergy для того, чтобы возвратить результат выполнения процесса и продолжить работу маршрута. Для того, чтобы это сделать, необходимо вызвать метод API kz.arta.synergy.samples.processes.blocking.ProcessesService#signalProcess.

Примечание:

Сигнал блокирующему процессу (API - signalProcess) для его разблокировки/блокировки нужно отправлять после того, как этот процесс был запущен, то есть после того как транзакция с запуском процесса была завершена. Для этого, перед отправкой сигнала, проверяйте на наличие такого процесса в БД. В противном случае, блокирующий процесс может завершиться в транзакции, но в маршруте нет.

В примере кода ниже разблокировка маршрута осуществляется в методе onMessage. Если время выполнения действия значительно или зависит от внешних факторов (например, доступность интегрируемой системы, или необходимость ввода пользователем данных в интегрируемой системе), то разблокировка маршрута может произойти позже, в любой другой момент времени из другого метода, а сам метод onMessage должен завершиться без ошибок, «запомнив» переданные параметры.

package kz.arta.synergy.samples.processes.blocking;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * <p><Пример блокирующего процесса</p>
 */
public class BlockingQueueListener implements MessageListener {
    
    public void onMessage(Message message) {

        String dataUUID = null;
        String executionID = null;
        String documentID = null;

        if (!(message instanceof TextMessage)){
            return;
        }

        try {

            JsonFactory factory = new JsonFactory();
            JsonParser parser = factory.createJsonParser(((TextMessage) message).getText());
            JsonToken token = null;

            while ((token = parser.nextToken()) != null) {
                if (token == JsonToken.FIELD_NAME) {
                    String fieldName = parser.getText();
                    parser.nextToken();
                    String value = parser.getText();
                    if (fieldName.equals("dataUUID")){
                        dataUUID = value;
                    } else if (fieldName.equals("executionID")){
                        executionID = value;
                    } else if (fieldName.equals("documentID")){
                        documentID = value;
                    }
                }
            }

         //Выполнение каких-либо действий
         ….......

            //Разблокировка маршрута

            String address = "http://127.0.0.1:8080/Synergy";
            String login = "1";
            String password = "1";
            String signal = "got_agree";
            boolean isSuccess = false;

            try {
                URL url = new URL(address + "/rest/api/processes/signal?signal=" + signal + "&executionID=" + executionID + "&param1=resolution&value1=signal_is_" + signal);

                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Accept", "application/json; charset=utf-8");

                String encoded = Base64.encode((login + ":" + password).getBytes());
                conn.setRequestProperty("Authorization", "Basic " + encoded);

                String output;
                StringBuffer result = new StringBuffer();

                BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

                while ((output = br.readLine()) != null) {
                    result.append(output);
                }

                conn.disconnect();

                JsonFactory factory = new JsonFactory();
                JsonParser parser = factory.createJsonParser(result.toString());
                JsonToken token = null;

                while ((token = parser.nextToken()) != null) {
                    if (token == JsonToken.FIELD_NAME) {
                        String fieldName = parser.getText();
                        token = parser.nextToken();
                        if (fieldName.equals("errorCode") && parser.getText().equals("0")){
                            isSuccess = true;
                        }
                    }
                }
            } catch (Exception exc){
                logger.error(exc.getMessage(), exc);
            }

        } catch (Exception exc){
            logger.error(exc.getMessage(), exc);
        }
    }
}

1.2.2.2. SQL-запрос

1.2.3. Приложение, работающее от имени пользователя по API

Пример: мобильное приложение

1.2.4. Ссылки на модули системы и их внутренние элементы

Ссылки на модули и различные объекты Synergy можно использовать как внутри основного web-приложения (в этом случае предпочтительно использовать относительные ссылки, чтобы не перезагружать страницу), так и во внешних системах.

Общий вид ссылок:

http[s]://host[:port]/Application?param1=value1&param2=value2#param3=value3&param4=value4

где

  • host - доменное имя или ip-адрес сервера Synergy

  • port - порт

  • Application:

    • Synergy - основное приложение

    • Configurator - Конфигуратор

    • SynergyAdmin - административное приложение

  • param1, param2 - параметры абсолютной ссылки

  • param3, param4 - параметры относительной ссылки

Параметры абсолютной ссылки - это, как правило:

  • locale - локаль загружаемой системы

  • nocache - специальный параметр, предотвращающий случайное кэширование

остальные параметры можно передавать как параметры относительной ссылки.

Ниже для краткости будем приводить образец относительной ссылки

1.2.4.1. Ссылка на модуль системы

#submodule=module_id

где module_id:

  • workflow - Потоки работ

  • calendar - Ежедневник

  • repository - Хранилище

  • plans - Проекты

  • pointers - Цели и показатели

  • employees - Сотрудники

При переходе по ссылке откроется указанный модуль.

1.2.4.1.1. Ссылка на документ и файл в нём
#submodule=common&file_identifier=some_file_id&action=open_document&document_identifier=some_doc_id

При переходе по такой ссылке откроется указанный документ с основным файлом, а если указан file_identifier - то откроется документ с этим файлом.

1.2.4.1.2. Ссылка на проект и мероприятие в нем
#submodule=plans&action=open_action&action_identifier=some_action_id&project_identifier=some_project_id

При переходе по такой ссылке откроется указанный проект, а если указан action_identifier - то в проекте будет выделено это мероприятие.

1.2.4.1.3. Ссылка на профиль пользователя
#submodule=employees&innermodule=structure&action=open_user&user_identifier=some_user_id

При переходе по такой ссылке будет открыт модуль «Сотрудники», а в нем - профиль указанного пользователя

1.2.4.1.4. Отключение всего пользовательского клиентского скриптинга

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

1.2.5. WEB-модуль, встроенный в ARTA Synergy

Web-приложение внешнего модуля открывается в iframe в окне основного приложения. При этом рабочая область внешнего модуля занимает всю область страницы, кроме панели меню и панели задач:

Рисунок 1.3. Веб-модуль

Веб-модуль

На данный момент существует пользовательский интерфейс для добавления нового модуля. Для этого нужно перейти в Конфигуратор -> Настройки системы -> Управление модулями -> Внешние модули и нажать на кнопку «Добавить».

Рисунок 1.4. Внешние модули

Внешние модули

В открывшемся окне нужно заполнить следующие поля:

  • «Идентификатор» - поле должно содержать уникальное значение.

  • «Название на русском/казахском/английском языке» - название модуля в соответствующем интерфейсе.

  • «Адрес приложения» - поле для ввода URL.

  • «Описание модуля» - поле для описания данного модуля.

  • «Иконка» - задает иконку модуля в пользовательской подсистеме (по умолчанию внешний модуль имеет стандартную иконку). Для того, чтобы изменить стандартную иконку, нужно кликнуть по кнопке «Выберите файл» и в диалоге выбора файла указать файл формата PNG, размер которого не превышает 28х26.

Рисунок 1.5. Добавление нового внешнего модуля

Добавление нового внешнего модуля

Однако, если необходимо, это можно сделать с помощью SQL-запроса в таблицу outer_modules, вставив запись со следующими полями:

  • id — идентификатор модуля, должен совпадать с идентификатором вашего проекта в репозитории проектов

  • nameru, namekz, nameen — название модуля на русском, казахском и английском языках соответственно

  • url — адрес приложения

  • description — описание модуля

  • active — активен ли модуль, 1/0.

Для реализации SSO приложений, ARTA Synergy при загрузке интегрированного модуля будет в строку URL добавлять три параметра:

  1. locale — локаль авторизованного пользователя

  2. sso_hash — hash-сумма для идентификации пользователя.

  3. host — адрес, с которого загружено приложение Synergy

Например, если URL приложения http://host:port/plans_module, то запрашиваться будет URL http://host:port/plans_module?locale=locale_value&sso_hash=sso_hash_value

Интегрированный модуль должен будет будет получить из URL параметр sso_hash и запросить по API у ARTA Synergy информацию об авторизованном пользователе (идентификатор, имя). Если метод API возвращает информацию о пользователе, это подтверждает, что данный пользователь действительно авторизован с данного хоста, в данном браузере.

Далее строка sso_hash будет использована для Сессионной авторизации и вызова API Arta Synergy.

В ARTA Synergy реализована возможность обращения к ее модулям по относительной ссылке. Такая же возможность существует для внешних web-модулей. Переход по ссылке вида:

#submodule=outer&outerModuleID=значение_из_таблицы_outer_modules&прочие_параметры_по_желанию_модуля

активирует в Synergy заданный модуль и передаст ему заданные в url-e параметры (параметры locale, sso_hash, host также будут переданы, несмотря на то, что они отсутствуют в ссылке).

Часто возникает необходимость в этой ссылке передать ссылку на текущий документ. Для этого можно добавить в ссылку параметр, значение которого будет равно ${docID} — эта строка в web-интерфейсе просмотрщика форм Synergy будет заменена на идентификатор данного документа.

1.2.6. Дополнительный обработчик для стандартного процесса ARTA Synergy

Цель данного вида интеграции — дать возможность проверить возможность запуска стандартного процесса и, при необходимости, прервать его.

Стандартный функционал платформы ARTA Synergy дает возможность запретить отправку документов на согласование, утверждение, если количество уровней оргструктуры между отправителем и получателем превышает некоторое настроенное значение. Но в некоторых компаниях существуют более сложные правила, ограничивающие возможность отправки документов/работ. В этих случаях необходима разработка данного обработчика.

Обработчик может быть применён к процессам:

  • «работа» (assignment-single)

  • «согласование» (agreement-single)

  • «утверждение» (approval-single)

  • «ознакомление» (acquaintance-single)

  • «отправка документа» (send-document)

  • «общий процесс при запуске по формам» (common-process-by-form)

  • «отправка документа по форме» (send-document-by-form)

Обработчик представляет собой Java-класс, реализующий интерфейс

kz.arta.synergy.integration.api.bp.StartHandlerIF.

Данный интерфейс находится в библиотеке integration-api.jar, которую можно взять здесь:

svn://scm.forge.arta.local/svnroot/synergy/trunk/build/artifacts/integration-api.jar

Примечание.

Начиная с итерации 66 данная библиотека входит в стандартный пакет arta-synergy-synergy. Она лежит в папке /opt/synergy/jboss/standalone/deployments/Synergy.ear/lib.

Интерфейс содержит два метода:

  • makeDecision — проверяет возможно ли выполнение процесса

  • getResolution — возвращает текст, который должен быть записан в ход исполнения

Более подробную информацию о полях методов можно посмотреть в javadoc к этим методам, которые доступны в integration-api.jar (библиотека содержит и скомпилированные классы, и исходный код).

Установка обработчика для процесса осуществляется с помощью конфигурационного файла ${jboss.server.config.dir}/arta/process-handlers-configuration.xml, имеющего следующий формат:

<?xml version="1.0" encoding="UTF-8"?> 
<process-handlers-configuration 
  xmlns="http://www.arta.kz/xml/ns/ai" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.arta.kz/xml/ns/arta 
  http://www.arta.kz/xml/ns/ai/process-handlers-configuration .xsd"> 
 <handlers>
     <handler>
         <process>assignment-single</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
     <handler>
         <process>agreement-single</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
     <handler>
         <process>approval-single</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
     <handler>
         <process>acquaintance-single</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
     <handler>
         <process>send-document</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
 </handlers>
</process-handlers-configuration>

Обработчики выполняются последовательно до тех пор, пока метод makeDecision одного из них не вернет false, после этого процесс прерывается.

Библиотеку, содержащую обработчик необходимо скопировать в папку /opt/synergy/jboss/standalone/deployments/Synergy.ear/lib.

После копирования библиотеки обработчика и изменения файла process-handlers-configuration.xml JBoss необходимо перезапустить.

Примечание. Процесс common-process-by-form запускает процессы agreement-single, approval-single, acquaintance-single, assignment-single (подпроцессы). Поэтому, если обработчик будет запрещать выполнение подпроцесса и при этом разрешать выполнение процесса common-process-by-form, то подпроцессы все равно будут прерваны. Аналогично, если выполнение common-process-by-form разрешено, а выполнение подпроцесса запрещено, подпроцессы будут прерваны.

Пример использования

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

Для установки внешнего модуля из репозитория необходимо установить пакет arta-synergy-ext-sendcontrol.

Далее на остановленном JBoss в конфигурационном файле ${jboss.server.config.dir}/arta/process-handlers-configuration.xml необходимо прописать следующие обработчики процесса:

<?xml version="1.0" encoding="UTF-8"?> 
<process-handlers-configuration 
  xmlns="http://www.arta.kz/xml/ns/ai" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.arta.kz/xml/ns/arta 
  http://www.arta.kz/xml/ns/ai/process-handlers-configuration .xsd"> 
 <handlers>
     <handler>
         <process>assignment-single</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
     <handler>
         <process>agreement-single</process>
         <handler-providers>kz.arta.synergy.ext.blocking.SendControlHandler</handler-providers>
     </handler>
 </handlers>
</process-handlers-configuration>

Установка групп (каким группам пользователей Synergy) разрешать либо блокировать процессы осуществляется с помощью конфигурационного файла ${jboss.server.config.dir}/arta/ext/send-control.xml. Пример настройки:

<?xml version="1.0" encoding="UTF-8"?> 
<send-control> 
    
    <!--
        Идентификаторы групп, членам которых разрешено отправлять 
        что-либо из блоков `deny`
    -->
    <from>
        <allow>35</allow>
    </from>
    
    <!--
        Идентификаторы групп, членам которых могут отправлять что-либо 
        только пользователи групп из блоков `allow`, если таковые есть. 
        В противном случае, никто ничего этим пользователям отправить
        не сможет.
    -->
    <to>
        <deny comment="Вы не можете отправлять что-либо на согласование данному пользователю">111</deny>
    </to>
</send-control>

1.2.6.1. Исходный код SendControl:

  • public link

  • private link > Примечание > > В этом примере настроено, что перепоручение и отправка на согласование > возможны только от пользователей группы «35» пользователям группы «111». > При попытке выполнения указанных действий пользователям, не входящим в > группу «111», система отобразит указанную ошибку.

1.2.7. Внешние модули-компоненты (ВМК)

Интеграция с помощью внешнего-модуля компонента предназначена для добавления или замены каких-либо элементов пользовательского web-интерфейса ARTA Synergy. Для этого необходимо описать пользовательский компонент, который и будет служить внешним модулем-компонентом, а затем указать для него место размещения и способ вставки.

1.2.7.1. Добавление ВМК

Для настройки пользовательских компонентов методологу нужно во вкладке «Процессы» конфигуратора выбрать пункт «Пользовательские компоненты».

Рисунок 1.6. Пользовательские компоненты

Пользовательские компоненты

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

  • «Название» - название пользовательского компонента, является обязательным полем;

  • «Исходный код» - код компонента, написанный на HTML/CSS. Можно также добавить сюда и код на javascript, но делать этого не рекомендуется, т.к. для js вызывать функции отсюда будет сложнее. Для написания скрипта следует использовать поле «Исходный код скрипта»;

  • «Исходный код скрипта» - код скрипта, написанный на javascript, с помощью которого можно настроить содержимое компонента, обратившись к существующим в системе API, описание которых можно посмотреть в javadoc и воспользовавшись возможностью обработать необходимые клиентские события. Для этого нужно вызвать функцию $EVENT_BUS.subscribe() и указать ей в качестве параметров необходимое событие и функцию, которую это событие обрабатывает.

    $EVENT_BUS.subscribe(new EventHandler ('WORK_USERS_CHANGED', handlerUsersSelected));

    Также объект EVENT_BUS позволяет отписываться от событий и создавать новые. Для возможности указания новых событий необходимо обратиться к центру решений.

«Строгий режим» JavaScript:

Начиная с версии Synergy 3.14, все пользовательские скрипты выполняются с добавлением директивы use strict. Эта директива означает, что соответствующий ей код будет выполнятся в так называемом «строгом режиме», поддерживающем стандарт JavaScript ECMAScript5.

Примечание:

Если код скрипта содержит конструкции, не соответствующие стандарту ES5, то они не будут выполняться. Это не является ошибкой Synergy.

Использование пользовательских компонентов как полей формы

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

  • отсутствует в полях формы реестра;

  • отсутствует в фильтрах реестра;

  • не учитывается при поиске в реестре;

  • не участвует в сортировке реестра;

  • отсутствует во всех видах сопоставлений;

  • не учитывается во всех спец.процессах (например, в условном переходе).

Для того, чтобы пользователький компонент присутствовал в сопоставлениях, необходимо, чтобы в его модели были реализованы методы setAsfData и getAsfData (см. «Создание нового компонента»), а также чтобы возвращалась структура компонента вида:

{ 
    "id": "id", 
    "type": "type", 
    "value": "value", 
    "key": "key"
}

Для снятия остальных ограничений достаточно реализации метода getAsfData и корректности возвращаемой структуры.

Пример:

В качестве примера расмотрим реализацию пользовательского компонента «Load info», который показывает перегруженных сотрудников при создании работы (данный компонент входит в стандартную поставку Synergy).

Итерационные задачи по реализации: 0193: Компонент предупреждение о перегрузке

Исходный код содержит следующий простой HTML код:

<!-- Определим добавляемый элемент, указав для него необходимый стиль. -->
<span id = "workloadLable" style="color:red; padding-top: 10px"> </span>
<!-- За содержимое элемента будет отвечать исходный код скрипта.       -->

Исходный код скрипта устроен более сложным образом. Рассмотрим реализацию функции получающей данные из api:

function ajaxUserWL(ar){
    // Функция filtrAr() исключает из массива повторения пользователей.
    ar = filtreAr(ar);

    // Используем массив, который подходит под формат `json`, определенный в `api`.
    // Данный формат необходимо всегда уточнять в javadoc.
    var req = [];
    for (var i = 0; i < ar.length; i++){
        var r = {userID: ar[i].userId,
            startDate: getCurrentDateFormated(),
            finishDate: getCurrentDateFormated()};
        req.push(r);
    }

    // Вызываем функцию, которая для пользователей из массива req, вызовет
    // api, возвращающую их загруженность. Перегруженные пользователи
    // добавляются в массив res и формируют содержимое HTML тага.
    jQuery.ajax({

        // Вызов необходимого api.
        url: 'rest/person/workload/m',
        type: 'post',
        data: JSON.stringify(req),
        contentType: 'application/json',
        dataType: 'json',

        // Функция осуществляет проверку на перегруженность и помещает таких
        // сотрудников в массив res
        success: function (data) {
            res = [];
            for (var i = 0; i < ar.length; i++) {
                var user = data[ar[i].userId];
                if (user == null) {
                    continue;
                }
                for (var j = 0; j < user.length; j++) {

                    // Проверка на перегруженность.
                    if (parseFloat(user[j].value) > 100) {
                        res.push(ar[i]);
                    }
                }
            }

            // Функция определяет формат, в котором будет выводиться инофрмация.
            overloadUsers(res);
        }
    });
}

Итерационные задачи по реализации: 0195: API получения нагрузки

Замечание:

Полную реализацию компонента можно посмотреть в настройках пользовательских компонентов, выбрав компонент «Load info».

Замечание:

Для API, находящихся по URL rest/%api/method%, авторизация будет происходить по куки (как в браузере), поэтому его можно вызывать авторизованному в Synergy пользователю. Для API, находящихся по другим адресам URL, необходимо настроить процесс авторизации (см. Способы авторизации). Сделать это можно например так: вызвать API по адресу https://%логин%:%пароль%@%адрес/метода/api%

Для того, чтобы выбрать, где использовать пользовательский компонент, методологу необходимо во вкладке «Процессы» выбрать пункт «Внешние модули-компоненты» и добавить новый внешний модуль-компонент.

Рисунок 1.7. Внешние модули-компоненты

Внешние модули-компоненты

Настройка внешнего модуля-компонента включает в себя настройку следующих полей:

  • «Название» - название внешнего модуля-компонента, является обязательным полем;

  • «Место размещения» - выбрать один из доступных вариантов для указания места, в котором будет находиться пользовательский компонент. На данный момент доступны следующие альтернативы:

    • «onLoad» - пользовательский компонент будет выводиться при загрузке приложения;

    • «Depricated» - место, используемое для вывода пользовательских компонентов в старых версиях, не рекомендуется к применению;

    • «BPM/Workflow/Create/Work» - пользовательский компонент будет выводиться в диалоговом окне создания работы;

    • «Shell/TopPanel/Right» - пользовательский компонент будет выводиться на верхней панели оболочки Synergy, левее поля «Поиск».

    Для размещения пользовательского компонента в новом месте необходимо его запрашивать у центра решений (в качестве доработки API).

  • «Название пользовательского компонента» - выбрать один из доступных вариантов пользовательских компонентов, настроенных ранее;

  • «Тип вставки» - выбрать один из доступных вариантов:

    • «ADD» - добавляет тег пользовательского компонента к тегу места размещения;

    • «REPLACE» - удаляются потомки тега места размещения и в него помещается пользовательский тег (замена всех потомков тега места размещения).

1.2.7.2. События для ВМК

Для работы ВМК в Synergy реализована отправка событий в JS EventBus.

Пример использования события из нового проигрывателя форм в JS:

AS.FORMS.bus.on(AS.FORMS.EVENT_TYPE.formShow, function (event, model, view) {
    var calendarModel = model.getModelWithId('cmp-1'); //Передается идентификатор компонента
    calendarModel.on(AS.FORMS.EVENT_TYPE.valueChange, function () {
        var value = calendarModel.getValue();
        console.log(value);
    });
});

Ниже описаны параметры для каждого события.

1.2.7.2.1. WORK_USERS_CHANGED

WORK_USERS_CHANGED - изменены исполнители работы в диалоге создания работы.

  • в качестве аргумента передается список выбранных пользователей в виде массива JSON с полями: userId, lastname, firstname, patronymic

  • добавлено в версии 3.0

1.2.7.2.2. WORK_DIALOG_UPDATE

WORK_DIALOG_UPDATE - обновлен диалог создания работы.

  • в качестве аргумента передается список выбранных пользователей в виде массива JSON с полями: userId, lastname, firstname, patronymic

  • добавлено в версии 3.0

1.2.7.2.3. SETTINGS_LOADED

SETTINGS_LOADED - загружены настройки приложения.

  • в качестве аргумента передается null

  • добавлено в версии 3.3

1.2.7.2.4. DEPARTMENT_ENTITY_CHANGED

DEPARTMENT_ENTITY_CHANGED - подразделение обновлено в компоненте формы.

  • в качестве аргумента передается JSON с полями id и values

  • values - массив JSON с полями: value - отображаемое имя, key - идентификатор пользователя

  • добавлено в версии 3.6

1.2.7.2.5. FORM_LOADED

FORM_LOADED - компоненты формы прорисованы

  • в качестве аргумента передаётся пустой JSON объект с полем dataID.

  • добавлено в версии 3.6

Пример использования события в JS:

$EVENT_BUS.subscribe(new EventHandler('FORM_LOADED', handlerUsersSelected));
        function handlerUsersSelected(event, args) {
            console.log("event FORM_LOADED");
            var component = jQuery('img#image_for_portlet');
            if (component === null || component.length === 0) {
                console.log("no success");
                return;
            }
            console.log("success!!");
            console.log(component.parentNode);
            console.log(component);
            var mySpan = document.createElement("div");
            mySpan.innerHTML = "<div id='portlet_div' ><iframe frameborder = "0" height = "100%" id = "portlet1" src = "http://192.168.2.119:8080/widget/web/guest/home/-/meetups" width = "100%" > </iframe ></div > ";
            component.replaceWith(mySpan.innerHTML);
        }
            var checkAgain = function() {
                setTimeout(handlerUsersSelected, 5000);
            };
1.2.7.2.6. REGISTRY_SELECTED

REGISTRY_SELECTED - нажата кнопка «Создать», когда в навигаторе выделен активный реестр.

  • в качестве аргумента передаётся JSON объект вида:

registryCode:"reg_code"
registryId:"9034810f-5f18-44b9-948a-8f78a5f1ec9d"
  • добавлено в версии 3.14

Кроме того, атрибуты registryCode и registryId содержатся в элементе списка реестров, например:

<table cellspacing="0" 
       cellpadding="0" 
       synergytest="RegistryTreeElement" 
       registryid="82356e07-a859-49cc-8adf-896c32725810" 
       registrycode="Заявление_о_приеме_на_работу_(вариант_2,_на_двух_языках)" 
       style="display: inline;" 
       class="commonLabelBold">
<colgroup> <col> </colgroup> 
<tbody>
    <tr>
        <td>007 Заявление о приеме на работу на период</td>
        <td style="white-space: nowrap;"></td>
    </tr>
</tbody>
</table>
1.2.7.2.7. USER_CHOOSER_CREATED

USER_CHOOSER_CREATED - обновлено тэговое поле выбора пользователя в диалоге.

  • в качестве аргумента передаются два параметра: событие и объект, содержащий ссылку на компонент выбор пользователя (в поле args).

  • добавлено в версии 3.12 Tengri

Пример обработчика события добавления компонента выбора пользователя, который выводит идентификатор компонента в консоль браузера:

function onUserChooserCreated(evt, chooser){
        var id = getUserChooserId(chooser.args);
        console.log(id);
}

Оперировать компонентом выбора пользователя можно следующими функциями:

  • getUserChooserId(chooserComponent) - получение идентификатора компонента выбора пользователя;

  • getUserChooserShowAll(chooserComponent) - получение настройки «Разрешить добавлять соисполнителей к работам, не являющихся подчиненными»

  • setUserChooserSelectedIds(chooserComponent, arrayOfUsersIds) - выбрать переданных пользователей;

  • getUserChooserSelectedIds(chooserComponent) - получить идентификаторы выбранных пользователей.

Идентификаторы компонентов выбора пользователя:

  1. Диалог создания работы создания работы:

    • исполнитель - editWorkUserChooser

    • ответственные - editWorkResponsibleUserChooser

    • автор - editWorkAuthorUserChooser

  2. Отправить-> переслать:

    • адресаты - sendDocumentUserChooser

  3. Отправить -> перепоручить:

    • исполнитель - assignmentSendUserChooser

    • ответственные - assignmentSendResponsibleUserChooser

  4. Отправить на согласование, утверждение, ознакомление:

    • адресаты - sendWorkUserChooser

  5. Отправить по маршруту:

    • ответственный - editRouteSendDialog

  6. все остальные компоненты будут иметь идентификатор userChooser.

В каждый DOM элемент компонента выбора пользователя добавляется атрибут userchooser со значением идентификатора компонента выбора пользователя.

1.2.8. Скриптинг в формах: модели, свойства и методы

Основные требования и некоторые детали задачи описаны в соответствующей постановке: «Скриптинг в формах»

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

Примеры использования скриптинга см. здесь.

Используемые технологии и библиотеки:

  • jQuery

  • Underscore - утилиты

  • Backbone - UI компоненты

  • Marionette - UI компоненты

  • jQuery ui - UI компоненты

  • math.js - поддержка математики больших чисел

  • base64.js - добавляет методы btoa, atob для браузеров, в которых их нет (в частности IE 9, 10)

  • XregExp.js - поддержка более сложных регулярных выражений

Схемы работы проигрывателя:

Рисунок 1.8. Схема 1, общая схема работы проигрывателя

Схема 1, общая схема работы проигрывателя

Рисунок 1.9. Схема 2, процесс изменения модели

Схема 2, процесс изменения модели

Рисунок 1.10. Схема 3, процесс изменения значения компонента

Схема 3, процесс изменения значения компонента

Рисунок 1.11. Схема 4, взаимодействие со средой

Схема 4, взаимодействие со средой

Общедоступные объекты:

  • AS - общее пространство имен

  • AS.FORMS - формы

  • AS.COMPONENTS - компоненты, которые могут быть использованы отдельно от проигрывателя форм

  • AS.SERVICES - сервисы

  • AS.LOGGER - логгер

  • AS.OPTIONS - настройки

  • AS.DICTIONARIES - кэш справочников

Типы событий:

  • formShow : 'formShow' - отображение формы (построение новой формы)

  • formDestroy : "formDestroy" - метод destroy модели проигрывателя

  • dataLoad: 'dataLoad' - подгрузка данных

  • valueChange: 'valueChange' - изменение значения модели

  • markInvalid : 'markInvalid' - необходимость отображению подсветить невалидное значение

  • tableRowAdd: 'tableRowAdd' - добавление ряда в таблице

  • tableRowDelete: 'tableRowDelete' - удаление ряда в таблице

  • dictionaryLoad : 'dictionaryLoad' - подгрузка справочника

  • tagEdit : 'tagEdit' - редактирование тега

  • tagDelete : 'tagDelete' - удаление тега

  • loadComponentAdditionalInfo : 'loadComponentAdditionalInfo' - подгрузка дополнительной информации компонента (сейчас используется для пользовательского компонента)

Особенности реализации:

В области видимости скрипта (добавленный как к компоненту, так и пользовательскому компоненту) имеются следующие переменные:

  • model - модель текущего компонента;

  • view - отображение текущего компонента;

  • editable - режим (просмотр / редактирование);

  • model.playerModel - модель проигрывателя;

  • view.playerView - отображение проигрывателя.

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

if (!model.inited)
  {
    //манипулирование моделями
    model.inited = true;
  }

«Строгий режим» JavaScript:

Начиная с версии Synergy 3.14, все пользовательские скрипты выполняются с добавлением директивы use strict. Эта директива означает, что соответствующий ей код будет выполнятся в так называемом «строгом режиме», поддерживающем стандарт JavaScript ECMAScript5.

Примечание:

Если код скрипта содержит конструкции, не соответствующие стандарту ES5, то они не будут выполняться. Это не является ошибкой Synergy.

Ссылки для быстрого перехода по документу:

1.2.8.1. Создание экземпляра проигрывателя и его методы

Для того, чтобы создать экземпляр проигрывателя, необходимо вызвать метод AS.FORMS.createPlayer().

Методы проигрывателя:

Наименование Аргумент Описание

showFormData

formUid(*)

Отображение последней версии формы по ее идентификатору

showFormData

formUid(*), version

Отображение указанной версии формы по ее идентификатору

showFormData

formUid(*), version, dataUid

Отображение формы по сведениям, содержащимся в последней версии данных по форме (параметры formUid и version игнорируются)

showFormData

formUid(*), version, dataUid, dataVersion

Отображение формы по сведениям, содержащимся в указанной версии данных по форме (параметры formUid и version игнорируются)

showFormByCode

formCode(*), version

Отображение формы по ее коду без создания соответствующего экземляра asfData.

dataLoaded

definition(*), data

Построение формы согласно definition и заполнение asfData значением параметра data

saveFormData

hander(*)

Сохранение данных формы, после которого выполняется функция handler с параметром asfDataUUID

destroy

Удаления экземпляра проигрывателя

Примечания:

  • (*) - параметр обязателен.

  • dataLoaded - вспомогательный метод, вызывающийся при выполнении методов showFormData и showFormByCode.

1.2.8.2. Базовые модели и отображения

Базовая модель.

Наименование Тип Описание

asfProperty

asfProperty

Определение компонента из описания формы

playerModel

AS.FORMS.PlayerModel

Модель проигрывателя

Базовые свойства модели.

Наименование Аргумент Описание

getErrors

Получение ошибок заполнения поля согласно настройкам asfProperty

isEmpty

Пустое ли значение

getLocale

Получение локали, настроенной в компоненте

isValid

Валидно ли текущее значение модели согласно настройкам asfProperty

fireChangeEvents

Вызов событий изменения значения формы

getHTMLValue

Получение HTML-представления текстового значения поля со стилями

doSetValue

newValue

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

getValue

Получение значения

getTextValue

Получение текстового значения

getAsfData

Int blockNumber

Получение asfData с указанным номером блока (если это компонент статической таблицы, то передавать эту переменную не нужно)

setAsfData

asfData

Вставить значение asfData

Примечание.

getErrors возвращает массив ошибок. Если массив пустой, значит ошибки отсутствуют, иначе - его элементы имеют поля:

  • errorCode - код ошибки;

  • id - идентификатор компонента.

Возможные коды ошибок:

  • emptyValue

  • wrongValue

  • deletedValue

  • valueTooHigh

  • valueTooSmall

Для одного и того же компонента может быть как несколько ошибок, так может и не быть ни одной.

Базовое отображение.

Наименование Тип Описание

model

Наследует AS.FORMS.Model

Модель

container

div

Контейнер, в котором будет отрисовываться отображение

input

input

Поле ввода для некоторых компонентов:

  • текстовое поле

  • числовое поле

  • многострочный текст

playerView

Отображение проигрывателя

Базовые методы отображения.

Наименование Аргумент Описание

unmarkInvalid

Убрать пометку неправильно заполненного поля

markInvalid

Пометить поле как неправильно заполненное

checkValid

Проверить корректность текущего значения (если поле заполнено неверно, то вызовется метод markInvalid)

setEnabled

boolean enabled

Сделать доступным или недоступным для редактирования

setVisible

boolean visible

Сделать видимым или невидимым

updateValueFromModel

Обновить отображение согласно значению модели

Примечание.

Если скрывается последний компонент в строке, то вся строка принимает минимальную высоту 18 px.

1.2.8.3. Модели и отображения, которые не имеют специфичных свойств или переопределения методов

  • AS.FORMS.DocAttributeModel - модель компонента «Свойства документа»;

  • AS.FORMS.DocAttributeView - отображение компонента «Свойства документа»;

  • AS.FORMS.DocLinkModel - модель компонента «Ссылка на документ»;

  • AS.FORMS.DocLinkTextView - отображение компонента «Ссылка на документ» в режиме редактирования

  • AS.FORMS.DocLinkView - отображение компонента «Ссылка на документ» в режиме просмотра;

  • AS.FORMS.ImageModel - модель компонента «Изображение»;

  • AS.FORMS.ImageView - отображение компонента «Изображение»;

  • AS.FORMS.LabelModel - модель компонента «Неизменяемый текст»;

  • AS.FORMS.LabelView - отображение компонента «Неизменяемый текст»;

  • AS.FORMS.SimpleModel - модель компонентов «Многострочное поле», «Номер», «HTD-редактор», «Ход выполнения», «Лист резолюций», «Лист подписей»;

  • AS.FORMS.TextBoxModel - модель текстового поля.

1.2.8.4. Модели и отображения, которые имеют специфичные свойства или методы

Модели и отображения проигрывателя.

  • AS.FORMS.PlayerModel - модель проигрывателя

Свойства:

Наименование Тип Описание

models

Массив AS.FORMS.TableModel

Массив моделей страниц

errorDataLoad

boolean

true - если описание формы содержит ошибки

formId

string

Идентификатор формы

asfDataId

string

Идентификатор данных

nodeId

string

Идентификатор ноды данных

hasChanges

boolean

Имеются ли изменения

formName

string

Наименование формы

formats

string

Форматы печати

defaultPrintFormat

string

Формат печати по умолчанию

hasMobile

boolean

Имеется ли мобильное представление

hasPrintable

boolean

Имеется ли печатное представление

formCode

string

Код формы

Методы:

Наименование Аргумент Описание

buildModelsDefinition

definition

Построить форму по описанию

getModelWithId

cmpId, tableId, tableBlockIndex

Получение модели компонента с указанным идентификатором в указанной таблице и указанном блоке, если идентификатор таблицы не указан, то ищется модель компонента на странице или в статических таблицах

  • AS.FORMS.PlayerView - отображение проигрывателя

Свойства:

Наименование Тип Описание

view

Массив AS.FORMS.TableStaticView

Массив отображений страниц

editable

boolean

true - если описание формы содержит ошибки

Методы:

Наименование Аргумент Описание

setEditable

Boolean editable

Устанавливает режим отображения чтение/запись

getViewWithId

cmpId, tableId, tableBlockIndex

Получение отображения компонента с указанным идентификатором в указанной таблице и указанном блоке, если идентификатор таблицы не указан, то ищется модель компонента на странице или в статических таблицах

appendTo

HTML element

Отображает проигрыватель в заданном компоненте

destroy

Модели и отображения компонентов.

1.2.8.4.1. Модели и отображения компонентов «Страница» и «Таблица»
  • AS.FORMS.TableModel - модель компонентов «Страница» и «Таблица»

Методы:

Наименование Аргумент Описание

createRow

Добавляет блок таблицы

removeRow

Номер блока

Удаляет блок таблицы

getTextValue

Возвращает форматированное значение свертки

isHaveHeader

Есть ли заголовок

isPage

Является ли страницей

isStatic

Является ли статической таблицей

isParagraph

Включена ли свертка

  • AS.FORMS.TableStaticView - отображение статической таблицы

Методы:

Наименование Аргумент Описание

getRowsCount

Возвращает количество рядов таблицы

setColumnVisible

Int columnNumber boolean visible

Делает столбец таблицы видимым / невидимым

getInvisibleColumns

Возвращает список невидимых столбцов

getViewWithId

cmpId, tableId, tableBlockIndex

Получение отображения компонента с указанным идентификатором в указанной таблице и указанном блоке, если идентификатор таблицы не указан, то ищется модель компонента на странице или в статических таблицах

  • AS.FORMS.TableDynamicView - отображение динамической таблицы

Методы:

Наименование Аргумент Описание

setEnabled

Разрешает либо запрещает пользователю добавлять и удалять блоки, при этом программная возможность остается

setColumnVisible

Int columnNumber boolean visible

Делает столбец таблицы видимым / невидимым

getInvisibleColumns

Возвращает список невидимых столбцов

getViewWithId

cmpId, tableId, tableBlockIndex

Получение отображения компонента с указанным идентификатором в указанной таблице и указанном блоке, если идентификатор таблицы не указан, то ищется модель компонента на странице или в статических таблицах

mergeCell

  • Int Row

  • int column

  • int rowsCount

  • int columnCount

Объединяет ячейки в блоке

splitCell

Row, column

Разъединяет ячейки

getRowsCount

Возвращает количество рядов таблицы

getBlocksCount

Возвращает количество блоков таблицы

  • AS.FORMS.TableParagraphView - отображение динамической таблицы в свертке

1.2.8.4.2. Модели и отображения компонента «Числовое поле»
  • AS.FORMS.NumericModel - модель компонента «Числовое поле»

Формат asfData:

1.2.8.4.2.1. Формат данных компонента «Числовое поле»
{
  "id": "cmp-qdg8xo", 
  "type": "numericinput", 
  "value": "2 222,00", //текстовое представление
  "key": "2222.00" //числовое представление
}
  • AS.FORMS.NumericInputView - отображение компонента «Числовое поле»

1.2.8.4.3. Модели и отображения компонентов выбора
  • AS.FORMS.ComboBoxModel - модель компонентов «Выпадающий список», «Выбор вариантов», «Переключатель вариантов»

Формат asfData выпадающего списка:

1.2.8.4.3.1. Формат данных компонента «Выпадающий список»
{
  "id": "cmp-7gj2xv", 
  "type": "listbox", 
  "value": "наименование выбранного элемента", 
  "key": "значение выбранного элемента"
}

Формат asfData выбора вариантов:

1.2.8.4.3.2. Формат данных компонента «Выбор вариантов»
{
  "id": "cmp-7gj2xv", 
  "type": "check", 
  "value": ["значение элемента 1", "значение элемента 2", "значение элемента 3"], 
  "key": ["наименование элемента 1", "наименование элемента 2", "наименование элемента 3]
}

Формат asfData переключателя вариантов:

1.2.8.4.3.3. Формат данных компонента «Переключатель вариантов»
{
  "id": "cmp-7gj2xv", 
  "type": "radio", 
  "value": "значение выбранного элемента", 
  "key": "наименование выбранного элемента"
}

Свойства:

Наименование Тип Описание

listElements

[{value : «value1», key : «key1»}, …]

Массив всех элементов компонента не зависимо от фильтра

listCurrentElements

[{value : «value1», key : «key1»}, …]

Массив элементов компонента согласно фильтру, если таковой имеется, либо массив всех элементов

Методы:

Наименование Аргумент Описание

updateModelData

Обновляет данные текущих элементов компонента согласно фильтрам

getTextValues

Получение массива выбранных текстовых значений

getValue

Возвращает массив выбранных идентификаторов

setValue

Идентификатор либо массив идентификаторов

Вставляет значение

1.2.8.4.4. Модели и отображения компонента «Дата/время»
  • AS.FORMS.DateModel - модель компонента «Дата/время»

Формат asfData:

1.2.8.4.4.1. Формат данных компонента «Дата/время»
{
  "id": "cmp-pfa3r5", 
  "type": "date", 
  "value": "2016-маусым-15", 
  "key": "2016-06-15 12:07:00"
}

Методы:

Наименование Аргумент Описание

getValue

Возвращает строковое представление даты в формате «yyyy-MM-dd HH:mm:ss», например 2016-05-25 16:16:16

setValue

Принимает строковое значение даты в формате «yyyy-MM-dd HH:mm:ss», например 2016-05-25 16:16:16

Вставляет значение

Примечание.

Значение даты хранится как строка в формате yyyy-MM-dd HH:mm:ss. Пустое значение хранится как ____-__-__ __:__:__ или как null.

  • AS.FORMS.DateView - отображение компонента «Дата/время»

1.2.8.4.5. Модели и отображения компонента «Файл»
  • AS.FORMS.FileModel - модель компонента «Файл»

Формат asfData:

1.2.8.4.5.1. Формат данных компонента «Файл»
{
  "id": "cmp-d84aev", 
  "type": "file", 
  "value": "Файл.png", //имя файла
  "key": "14064b88-633c-4748-b9c6-9fbf8c8a86e6" //идентификатор файла в хранилище
}

Методы:

Наименование Аргумент Описание

getValue

Возвращает null либо данные, которые имеют следующие обязательные поля:

  • identifier

  • name

  • path

  • mime

  • fromStorage (true/false)

setValue

Объект с обязательными полями:

  • identifier

  • name

  • path

  • mime

  • fromStorage (true/false)

Вставляет значение

  • AS.FORMS.FileView - отображение компонента «Файл»

1.2.8.4.6. Модели и отображения компонента «Ссылка»
  • AS.FORMS.LinkModel - модель компонента «Ссылка»

Формат asfData:

1.2.8.4.6.1. Формат данных компонента «Ссылка»
{
  "id": "cmp-7u4wuv", 
  "type": "link", 
  "value": "#submodule=common&action=open_document&document_identifier=${docID}", 
  "key": "Документ; false"
}

Примечание.

Значение параметра key состоит из надписи к ссылке и через «; » (с пробелом) опцию, открывать ли ссылку в новом окне.

Методы:

Наименование Аргумент Описание

getValue

Возвращает описание ссылки:

  • value: «url»

  • key: «label; openInNew»

setValue

Объект с полями:

  • value: «url»

  • key: «label; openInNew»

Например:

  • value: «http://ya.ru»

  • key: «OPEN YA; true»

Вставляет значение

getTextValue

Возвращает подпись ссылки

isOpenInNew

Открывать ли ссылку в новом окне

setValueFromInput

Объект с полями:

  • url

  • title

  • openInNew

Обновляет значение

  • AS.FORMS.LinkView - отображение компонента «Ссылка»

1.2.8.4.7. Модели и отображения компонента «Пользователь»
  • AS.FORMS.UserLinkModel - модель компонента «Пользователь»

Формат asfData:

1.2.8.4.7.1. Формат данных компонента «Пользователи»

Формат данных для единственного значения:

{
  "id": "cmp-7gj2xv", 
  "type": "entity", 
  "value": "Фамилия Имя Отчество", 
  "key": "1ba41729-871f-4575-88d8-5a6c3de6297a",
  "formatVersion": "V1",
  "manualTags": {"identifier" : "введенный вручную тэг"}
}

Формат данных для множественного значения:

{
  "id": "cmp-7gj2xv", 
  "type": "entity", 
  "value": "formattedName1, formattedName2, formattedName3", 
  "key": "identifier1;identifier2;identifier3",
  "formatVersion": "V1",
  "manualTags": {"identifier1" : "введенный вручную тэг"}
}

Примечание.

manualTags - это пользователи, для которых были изменены названия вручную.

key - это список id выбранных пользователей, разделенных «;».

Идентификаторы могут иметь приставки:

  • без приставки - пользователь;

  • g - группа (g-идентификатор_группы);

  • text - произвольный текст (text-номер_просто_число);

  • contact - контакт адресной книги (contact-идентификатор_контакта).

Методы:

Наименование Аргумент Описание

getValue

Возвращает массив данных, которые содержат обязательные поля:

  • personID - идентификатор пользователя

  • personName - название пользователя

а также необязательные:

  • positionName - название должности пользователя (если существует)

  • customFields:

    {

    • calendarColor - цвет статуса

    • calendarStatusLabel - текст статуса (например «Введен ручную»)

    }

getSelectedIds

Возвращает массив строк - идентификаторов выбранных пользователей

setValue

Объект с обязательными полями:

  • personID - идентификатор пользователя

  • personName - название пользователя

а также необязательные:

  • positionName - название должности пользователя (если существует)

  • customFields:

    {

    • calendarColor - цвет статуса

    • calendarStatusLabel - текст статуса (например «Введен ручную»)

    }

  • AS.FORMS.UserLinkView - отображение компонента «Пользователь»

1.2.8.4.8. Модели и отображения компонента «Должность»
  • AS.FORMS.PositionLinkModel - модель компонента «Должность»

Формат asfData:

1.2.8.4.8.1. Формат данных компонента «Должности»
{
  "id": "cmp-rgi3pr", 
  "type": "entity", 
  "value": "название должности", 
  "key": "f1af818e-cd5d-4390-9e96-b26dd148e42d",
  "formatVersion": "V1",
  "manualTags": {"identifier" : "введенный вручную тэг"}
}

Примечание.

manualTags - это должности, для которых были изменены названия вручную.

Методы:

Наименование Аргумент Описание

getValue

Возвращает массив данных, которые содержат обязательные поля:

  • elementID - идентификатор должности

  • elementName - название должности

а также необязательные:

  • departmentName - название подразделения, которому принадлежит должность

  • status - текст статуса (например, «Введен ручную»)

  • statusColor - цвет статуса

getSelectedIds

Возвращает массив строк - идентификаторов выбранных должностей

setValue

Объект с обязательными полями:

  • elementID - идентификатор должности

  • elementName - название должности

а также необязательные:

  • departmentName - название подразделения, которому принадлежит должность

  • status - текст статуса (например, «Введен ручную»)

  • statusColor - цвет статуса

  • AS.FORMS.PositionLinkView - отображение компонента «Должность»

1.2.8.4.9. Модели и отображения компонента «Подразделение»
  • AS.FORMS.DepartmentLinkModel - модель компонента «Подразделение»

Формат asfData:

1.2.8.4.9.1. Формат данных компонента «Подразделения»

Формат данных для единственного значения:

{
  "id": "cmp-7gj2xv", 
  "type": "entity", 
  "value": "название подразделения", 
  "key": "4a76ae9b-a460-431a-9edc-c9bf2966f2fb",
  "formatVersion": "V1",
  "manualTags": {"identifier" : "введенный вручную тэг"}
}

Формат данных для множественного значения:

{
  "id": "cmp-7gj2xv", 
  "type": "entity", 
  "value": "name1;; name1;; name3;; name4", 
  "key": "identifier1;identifier2;identifier3",
  "formatVersion": "V1",
  "manualTags": {"identifier" : "введенный вручную тэг"}
}

Примечание.

manualTags - это подразделения, для которых были изменены названия вручную.

key - это список id выбранных подразделений, разделенных «;».

Для множественного значения в качестве разделителя наименований value используется «;; » (с пробелом после точек с запятой).

Методы:

Наименование Аргумент Описание

getValue

Возвращает массив данных, которые содержат обязательные поля:

  • departmentId - идентификатор подразделения

  • departmentName - название подразделения

а также необязательные:

  • parentName - название подразделения, которому принадлежит должность

  • hasChildren - имеются ли дочерние подразделения

  • status - текст статуса (например, «Введен ручную»)

  • statusColor - цвет статуса

getSelectedIds

Возвращает массив строк - идентификаторов выбранных подразделений

setValue

Объект с обязательными полями:

  • departmentId - идентификатор подразделения

  • elementName - название подразделения

а также необязательные:

  • parentName - название подразделения, которому принадлежит должность

  • hasChildren - имеются ли дочерние подразделения

  • status - текст статуса (например, «Введен ручную»)

  • statusColor - цвет статуса

  • AS.FORMS.DepartmentLinkView - отображение компонента «Подразделение»

1.2.8.4.10. Модели и отображения компонента «Период повторения»
  • AS.FORMS.RepeatPeriodModel - модель компонента «Период повторения»

Формат asfData:

1.2.8.4.10.1. Формат данных компонента «Период повторения»

Формат данных для значения «Нет»:

{
  "id": "cmp-mqk3ik", 
  "type": "repeater", 
  "value": "Нет",
  "key": "0"
}

Формат данных для значения «По дням недели»:

{
  "id": "cmp-mqk3ik", 
  "type": "repeater", 
  "value": "По дням недели: Понедельник, Воскресенье",
  "key": "1|1.0;7.0"
}

Примечание.

Значение параметра value состоит из типа значения («По дням недели») и через «: » список полных названий дней недели, разделенных «, ».

Значение параметра key состоит из типа значения (1 - это по дням недели) и через «|» список значений, разделенных «;», каждое значение в формате порядковый_номер_дня_недели.0.

Формат данных для значения «По дням месяца»:

{
  "id": "cmp-mqk3ik", 
  "type": "repeater", 
  "value": "По дням месяца: 12, 17, 23",
  "key": "2|12.0;17.0;23.0"
}

Примечание.

Значение параметра value состоит из типа значения («По дням месяца») и через «: » список дней месяца, разделенных «, ».

Значение параметра key состоит из типа значения (2 - это по дням месяца) и через «|» список значений, разделенных «;», каждое значение в формате день_месяца.0.

Формат данных для значения «Ежегодно»:

{
  "id": "cmp-mqk3ik", 
  "type": "repeater", 
  "value": "Ежегодно: 4.1, 5.11, 7.12, 9.30",
  "key": "4|1.4; 11.5; 12.7; 30.9"
}

Примечание.

Значение параметра value состоит из типа значения («Ежегодно») и через «: » список дней года, разделенных «, », каждое значение в формате номер_месяца.номер_дня.

Значение параметра key состоит из типа значения (4 - это ежегодно) и через «|» список значений, разделенных «; », каждое значение в формате номер_дня.номер_месяца.

Свойства:

Наименование Тип Описание

type

Int

Тип периода (0 - нет, 1 - по дням недели, 2 - по дням месяца, 4 - ежегодно

Методы:

Наименование Аргумент Описание

getValue

Возвращает массив элементов согласно типу, например [«4.1», «5.11», «7.12», «9.30»]

setValue

Строка следующего типа: 4|1.4;11.5;12.7;30.9

Вставляет значение

setValueFromInput

Int type array <String> selectedDays

Обновляет значение модели type

  • type - тип периода

  • selectedDays - массив строк согласно типу, например [«4.1», «5.11», «7.12», «9.30»]

getTypeText

Возвращает текстовую расшифровку выбранного типа

getValueString

  • value строка типа «7.12» согласно формату и типу

  • type - тип периода

  • full - полное представление (используется для режима просмотра)

Возвращает строчное представление данных

  • AS.FORMS.RepeatPeriodView - отображение компонента «Период повторения»

1.2.8.4.11. Модели и отображения компонента «Ссылка на проект»
  • AS.FORMS.ProjectLinkModel - модель компонента «Ссылка на проект»

Формат asfData:

1.2.8.4.11.1. Формат данных компонента «Ссылка на проект/портфель»
{
  "id": "cmp-7gj2xv", 
  "type": "projectlink", 
  "value": "Проект: %название%", //для портфеля "Портфель: %название%"
  "key": "00e24c3d-d3de-423a-9b86-5d501975b922", 
  "valueID": "00e24c3d-d3de-423a-9b86-5d501975b922"
}

Методы:

Наименование Аргумент Описание

getValue

Возвращает идентификатор выбранного проекта или портфеля

setValue

Идентификатор проекта или портфеля, либо null

Вставляет значение

setValueFromInput

Объект с полями:

  • actionID - идентификатор

  • name - название

  • elementType - тип элемента (256 - проект, 128 - портфель)

Обновляет значение компонента

  • AS.FORMS.ProjectLinkView - отображение компонента «Ссылка на проект»

1.2.8.4.12. Модели и отображения компонента «Ссылка на реестр»
  • AS.FORMS.RegistryLinkModel - модель компонента «Ссылка на реестр»

Формат asfData:

1.2.8.4.12.1. Формат данных компонента «Ссылка на реестр»
{
  "id": "cmp-6vrrkp", 
  "type": "reglink", 
  "value": "1111-GPON", //значащее содержимое через «-»
  "key": "a1b478c0-2d33-11e6-b327-3085a93a6496", 
  "valueID": "a1b478c0-2d33-11e6-b327-3085a93a6496",
  "username": "Admin Admin Admin",
  "userID": "1"
}

Методы:

Наименование Аргумент Описание

getValue

Возвращает идентификатор выбранного документа реестра

setValue

Идентификатор документа реестра

Вставляет значение

getRegistryID

Возвращает идентификатор реестра

  • AS.FORMS.RegistryLinkView - отображение компонента «Ссылка на реестр»

1.2.8.4.13. Модели и отображения компонента «Ссылка на адресную книгу»
  • AS.FORMS.AddressLinkModel - модель компонента «Ссылка на адресную книгу»

Формат asfData:

1.2.8.4.13.1. Формат данных компонента «Ссылка на адресную книгу»
{
  "id": "cmp-7gj2xv", 
  "type": "personlink", 
  "value": "Фамилия Имя Отчество (Организация)", //для организации "Организация (Адрес)"
  "key": "0:idenitifier", 
  "valueID": "0:identifier"
}

Примечание.

Цифра, предваряющая идентификатор, означает тип контакта: 0 - люди, 1 - организация.

Методы:

Наименование Аргумент Описание

getValue

Возвращает идентификатор выбранной записи

setValue

Идентификатор записи

Вставляет значение

setValueFromInput

Объект с полями:

  • newValue - идентификатор

  • newTextValue - подпись

  • newType - тип контакта (0 - люди, 1 - организация)

Обновляет значение компонента

  • AS.FORMS.AddressLinkView - отображение компонента «Ссылка на адресную книгу»

1.2.8.4.14. Модели и отображения компонента «Ссылка на файл в хранилище»
  • AS.FORMS.FileLinkModel - модель компонента «Ссылка на файл в хранилище»

Формат asfData:

1.2.8.4.14.1. Формат данных компонента «Ссылка на файл в Хранилище»
{
  "id": "cmp-5hpcpy", 
  "type": "filelink", 
  "value": "Файл.pdf", //название файла
  "key": "36afa2d9-cd78-4638-8132-773a69ff0c55" //идентификатор файла
}

Методы:

Наименование Аргумент Описание

getValue

Возвращает null либо данные, которые имеют следующие обязательные поля:

  • identifier

  • name

  • icon

setValue

Объект с обязательными полями:

  • identifier

  • name

  • icon

Вставляет значение

  • AS.FORMS.FileLinkView - отображение компонента «Ссылка на файл в хранилище»

1.2.8.5. Методы поля ввода с тегами

События:

Наименование Аргумент Описание

tagEdit

  • event - событие

  • tag - объект, подпись которого была изменена

  • tagArea - поле ввода с тегами

Возникает при изменении подписи у элемента поля ввода с тегами

tagDelete

  • event - событие

  • tag - объект, который был удален

  • tagArea - поле ввода с тегами

Возникает при удалении элемента поля ввода с тегами

Методы:

Наименование Аргумент Описание

Конструктор

  • css - объект с css свойствами, обычно передается ширина поля ввода с тегами

  • width - число, максимальная ширина поля ввода; если передается 0, то рассчитывается исходя из ширины css

  • multivalue - может ли принимать множественные значения

  • editContent - доступно ли редактирование тегов объектов

  • canAddRandomText - можно ли добавлять в качестве элементов произвольно набранный пользователем текст

  • suggestHandler - обработчик, который вызывается для отображения пользователю подсказки; если передать null, то у пользователя не будет встроенного inline поиска; в обработчик передается один параметр - введенный пользователем текст

  • createRandom - обработчик, который добавляет введенный пользователем тег; в метод передается название тега

focus

Переводит фокус на поле ввода

addValue

  • value - добавляемое значение

  • updateSuggestionInput перерисовать ли поле ввода с тегами

Добавляет значение

markValidity

  • valid - валидно ли поле

Помечает поле правильно либо неправильно заполненным; неправильно заполненное поле обводится красным цветом и подсвечивается

getValues

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

setValues

  • values - массив значений, может содержать произвольные объекты, у которых обязательно должно быть свойства tagName (подпись тега)

Устанавливает значение поля ввода с тегами

setVisible

visible

Определяет видимость компонента

setEditable

editable

Доступен ли компонент для редактирования

getWidget

Получение компонента, который можно добавить в дом

1.2.8.6. Методы AS.SERVICES

Методы:

Наименование Аргумент Описание

showDropDown

values - массив значений [{value : «value1», title : «title1», selected : true}, [{value : «value2», title : «title2»}, [{value : «value3», title : «title3»}]

anchor - якорный компонент, к которому следует привязать popup

minWidth - минимальная ширина

handler - callback

Отображает выпадающий список

В callback передается value выбранного значения

showDatePicker

value - объект типа Date

anchor - якорный компонент, к которому следует привязать popup

input - поле ввода даты (можно передать null), используется для передачи фокуса

handler : callback

Отображает компонент выбора даты

showUserChooserDialog

values, multiSelectable, isGroupSelectable, showWithoutPosition, filterPositionID, filterDepartmentID, locale, handler

Отображает диалог выбора пользователей

В callback передается массив, содержащий объекты со следующими полями:

  • personID - идентификатор пользователя

  • personName - название пользователя

а также необязательные:

  • positionName - название должности пользователя (если существует)

  • customFields:

    {

    • calendarColor - цвет статуса

    • calendarStatusLabel - текст статуса (например «Введен ручную»)

    }

showPositionChooserDialog

values, multiSelect, filterUserId, filterDepartmentId, showVacant, locale, handler

Отображает диалог выбора должностей

В callback передается массив, содержащий объекты со следующими полями:

  • elementID - идентификатор должности

  • elementName - название должности

а также необязательные:

  • departmentName - название подразделения, которому принадлежит должность

  • status: текст статуса (например, «Введен ручную»)

  • statusColor - цвет статуса

showDepartmentChooserDialog

values, multiSelectable, filterUserID, filterPositionID, filterDepartmentID, filterChildDepartmentID, locale, handler

Отображает диалог выбора департаментов

В callback передается массив, содержащий объекты со следующими полями:

  • departmentId - идентификатор подразделения

  • departmentName - название подразделения

а также необязательные:

  • parentName - название подразделения, которому принадлежит должность

  • hasChildren - имеются ли дочерние подразделения

  • status - текст статуса (например, «Введен ручную»)

  • statusColor - цвет статуса

showProjectLinkDialog

handler

Отображает диалог выбора проекта/портфеля

В callback передается массив, содержащий объекты со следующими полями:

  • actionID - идентификатор

  • name - название

  • elementType - тип элемента (256 - проект, 128 - портфель)

showRegisterLinkDialog

registry, handler

Отображает диалог выбора записи реестра

В callback передается идентификатор выбранного документа

showWaitWindow

Отображает окно ожидания

Каждая платформа реализует свое окно, внутри Synergy это реализовано, для встраивания в другой портал необходимо данный метод переопределить

hideWaitWindow

Скрывает окно ожидания

Каждая платформа реализует свое окно, внутри Synergy это реализовано, для встраивания в другой портал необходимо данный метод переопределить

unAuthorized

Url - URLметода API, при вызове которого появилась ошибка 401

Скрывает окно ожидания

Каждая платформа реализует свое окно, внутри Synergy это реализовано, для встраивания в другой портал необходимо данный метод переопределить

1.2.8.7. Утилита при вызове методов API Synergy

Методы AS.FORMS.ApiUtils:

Наименование Аргумент Описание

addAuthHeader

Добавляет заголовок с параметрами авторизации

getFullUrl

UrlPart - «rest/api/asforms/form_ext?formID=»

Формирует частичный (при наличии) либо полный URL до метода API

simpleAsyncGet

UrlPart - «rest/api/asforms/form_ext?formID=»

callback - куда вернуть результат

dataType - тип данных

data - данные

errorHandler — callback в случае ошибки (при ошибке 401 вызовется метод AS.SERVICES.unAuthorized)

Выполняет GET-запрос к API Synergy

Автоматически добавит заголовки

simpleAsyncPost

UrlPart - «rest/api/asforms/form_ext?formID=»

callback - куда вернуть результат

dataType - тип данных

data - данные

contentType - тип содержания

errorHandler — callback в случае ошибки (при ошибке 401 вызовется метод AS.SERVICES.unAuthorized)

Выполняет GET-запрос к API Synergy

Автоматически добавит заголовки

1.2.8.8. Утилиты для работы с asfData и asfDefinition

Методы AS.FORMS.ASFDataUtils:

Наименование Аргумент Описание

getComponentLocale

asfProperty

Получение локали, настроенной в компоненте

isReadOnly

model

Является ли компонент не редактируемым согласно настроек

getBaseAsfData

  • asfProperty - настройки компонента из описания формы

  • blockNumber

  • value

  • key

Получение базового объекта для формирования данных для сохранения в Synergy. Получив таким образом объект, можно добавить к нему собственные свойства (см. пример ниже)

1.2.8.9. Утилиты для работы с датами

Методы AS.FORMS.DateUtils:

Наименование Аргумент Описание

isEmpty

DateStr

Соответствует ли переданная строка пустому значению, например 201-- будет считаться пустым значением

parseDate

DateStr

Возвращает объект дата соответствующей строке, если строка не соответствует формату, то null

formatDate

Date, format

Форматирует дату согласно формату

getMonthName

number

Получение полного названия месяца по номеру

getMonthShortName

number

Получение сокращенного названия месяца по номеру

getMonthPossessiveName

number

Получение названия месяца в родительном падеже

getWeekDayName

number

Получение названия дня недели по номеру

getWeekDayShortName

number

Получение сокращенного названия дня недели по номеру

1.2.8.10. Утилиты для работы с компонентами

Методы AS.FORMS.ComponentUtils:

Наименование Аргумент Описание

createModel

Asfproperty, playerModel

Создание модели компонента

createView

Model, playerView, editable

Создание отображения компонента

createContainer

Создание контейнера компонента

makeBus

object

Делает из любого переданного объекта шину событий, добавляет методы:

  • trigger(event, [аргументы ивента]) - вызвать событие

  • on(event, handler) - подписаться на событие

  • off(event, handler) - отписаться от события

createFunction

Code - код, prefixCode - код приставка

Создание функции из строк кода

1.2.8.11. Создание нового компонента

Перед созданием нового компонента необходимо определиться со следующими вопросами:

  1. Какие данные он будет хранить?

  2. Какие ошибки валидации данного компонента существуют?

  3. Как компонент должен выглядеть в режиме просмотра, редактирования, неправильно заполненным в режиме редактирования?

Ответив на эти вопросы, можно приступить к написанию компонента.

Предположим, нужно хранить в качестве значения компонента 3 поля:

  • identifier - идентификатор выбранного значения;

  • name - наименование;

  • info - дополнительная информация.

Таким образом, в переменной value модели будет объект, содержащий эти 3 поля. Например:

value = { identifier : 1, name : «Наименование», info : «Дополнительная информация» }

Данный объект необходимо передавать в метод модели setValue, а получать в методе модели getValue.

Чтобы эти данные сохранялись в файл по форме и поднимались при последующем открытии, необходимо реализовать 2 метода модели:

  • getAsfData(blockNumber)

  • setAsfData(asfData)

Необходимо учесть, что поля сохраняемого объекта asfData могут иметь лишь следующий перечень наименований:

  • value - обычно это текстовое значение компонента;

  • key - обычно это значение компонента;

  • valueID - дополнительный идентификатор;

  • username - имя пользователя;

  • userID - идентификатор пользователя;

  • values - массив строк;

  • key - массив строк.

Все эти поля необязательны, но объект, сохраняемый в файле по форме, может иметь только такие свойства.

Пример реализации этих методов:


model.getAsfData = function(blockNumber){
    if(model.getValue()) {
        /*следующий метод сформирует правильную запись для сохранения в файле по форме 
           при этом:
            model.getValue().title — запишется в поле value
            model.getValue().value — запишется в поле key*/
        var result = AS.FORMS.ASFDataUtils.getBaseAsfData(model.asfProperty, blockNumber, model.getValue().name , model.getValue().identifier);
        /* дописываем необходимую информацию в поле valueID*/
        result.valueID = model.getValue().info ;
        return result;
    } else {
        return AS.FORMS.ASFDataUtils.getBaseAsfData(model.asfProperty, blockNumber);
    }
};

model.setAsfData = function(asfData){
    if(!asfData || !asfData.value) {
        return;
    }
    /*читаем данные из объекта из файла по форме: дополнительная информация была сохранена в поле valueID и теперь читаем из него*/
    var value = { value : asfData.key, title : asfData.value, info : asfData.valueID};

    model.setValue(value);
};

Далее необходимо определить список специальных ошибок. Например, пользователь может выбирать значениями с некоторыми идентификаторами . Для этого необходимо переопределить метод модели getSpecialErrors.


model.getSpecialErrors = function() {
    if(model.getValue()) {
        if(model.getValue().identifier == '0') {
            return {id : model.asfProperty.id, errorCode : AS.FORMS.INPUT_ERROR_TYPE.wrongValue};
        }
    }
};

В данном примере проверяется, является ли значение идентификатора равным 0. Если да, то это значит, что компонент неправильно заполнен и возвращается ошибка. Synergy при этом будет показывать, что данные заполнены некорректно.

Работа с моделью теперь завершена.

Далее будем работать с отображением.

Предположим, что на вопрос №3 даны следующие ответы:

  1. В режиме просмотра компонент должен представлять собой просто подпись.

  2. В режиме редактирования - это недоступное для редактирования поле ввода и кнопка, по нажатию на которую открывается диалог выбора записи.

  3. Неправильно заполненное поле должно подсвечивать красным кнопку компонента.

Необходимо инициализировать отображение, в зависимости от режима (просмотр или редактирование).

В области видимости есть переменная editable:

  • editable = false соответствует режиму просмотра;

  • editable = true соответствует режиму редактирования.

Для режима просмотра достаточно иметь div, куда будет вставлено тестовое описание поля, и реализовать метод updateValueFromModel.

Пример:


var textView = jQuery('<div>', {class : "asf-label"});
view.container.append(textView);
view.updateValueFromModel = function(){
    textView.html(model.getValue().name);
};

Создается div, который добавляется в контейнер компонента. При любом изменении модели автоматически вызовется метод updateValueFromModel и значение изменится.

Для режима редактирования необходимо создать div, кнопку, а также реализовать методы updateValueFromModel, markInvalid, unmarkInvalid.

Пример:


/**
 * инициализируем внешний вид компонента, див и кнопку
 */
var inputView = jQuery('<div>', {class : "asf-label", style : "width:calc(100% - 30px)"});
var button = jQuery('<button>', {class : "asf-browseButton"});
view.container.append(inputView);
view.container.append(button);
/**
 * обновляем значение отображения в зависимости от значения модели
 */
view.updateValueFromModel = function(){
    inputView.html(model.getValue().name);
};
/**
 * метод помечает поле как неправильно заполненное
 */
view.markInvalid = function(){
   button.css("background-color", "#aa3344");
};
/**
 * метод убирает пометку неправильно заполненного поля
 */
view.unmarkInvalid = function(){
    button.css("background-color", "");
};
/**
 * вызываем какой-нибудь диалог выбора пользователя
 */
button.onclick(function(){
    var value = {identifier : "1", name : "name "+math.rand(), info : "additional info"};   // тут прописывается какая-нибудь логика получения этого значения
    model.setValue(value);
});