Создание настроек элемента для моделирования бизнес-процесса в дизайнере
Перед тем как добавлять настройки элемента для моделирования, нужно:
- создать приложение и модуль;
- создать классический модуль для ELMA4.
В названии модуля, реализующего настройки элемента для моделирования в дизайнере, рекомендуется добавлять постфикс .Diagram, например, EleWise.ELMA.Workflow.Diagrams.
Реализация
В папке DevServer откройте файл appsettings.json. Затем в тексте сценария в разделе "DevServer" добавьте настройку "DevelopMode": "Pro", как показано на рисунке ниже.
Запустите DevServer командой server.
Реализация в классическом модуле ELMA4
Модуль должен ссылаться на две системные библиотеки: EleWise.ELMA.Workflow и EleWise.ELMA.SDK.Diagrams. Это нужно для реализации элемента для моделирования, его настроек и визуализации.
Сначала добавьте визуальную часть формы элемента. Для этого создайте интерфейс EleWise.ELMA.Workflow.BPMN.Diagrams.Shapes.IWebDiagrammerElementShape:
ExampleElementShape
internal sealed class ExampleElementShape : IWebDiagrammerElementShape
{
private Color strokeColor, backgroundColor;
/// <summary>
/// Ctor
/// </summary>
public ExampleElementShape()
{
strokeColor = Color.FromArgb(255, 253, 227, 107);
backgroundColor = Color.FromArgb(255, 254, 246, 206);
}
/// <summary>
/// Ширина фигуры по-умолчанию
/// </summary>
public int Width => 100;
/// <summary>
/// Высота фигуры по-умолчанию
/// </summary>
public int Height => 100;
/// <summary>
/// Толщина границы
/// </summary>
public int StrokeWidth => 1;
/// <summary>
/// Цвет границы
/// </summary>
public Color StrokeColor => strokeColor;
/// <summary>
/// Цвет фона
/// </summary>
public Color BackgroundColor => backgroundColor;
}
Если в классическом модуле ELMA4 элемент уже создан, добавьте атрибут WebDiagrammerShapeAttribute:
ExampleElement
[WebDiagrammerShape(typeof(ExampleElementShape))]
public sealed class ExampleElement : BPMNFlowElement
{
...
}
Если в классическом модуле элемента нет, добавьте его:
ExampleElement
[WebDiagrammerShape(typeof(ExampleElementShape))]
public sealed class ExampleElement : BPMNFlowElement
{
/// <summary>
/// Элемент панели инструментов
/// </summary>
[Component(Order = 100)]
private class ToolboxItem : IBPMNToolboxItem, IContainingElementIcon
{
...
}
/// <summary>
/// Какое-то собственное свойство
/// </summary>
public string SomeImportantField { get; set; }
...
}
Примеры
- Пример реализации панели инструментов:
ToolboxItem
/// <summary>
/// Элемент панели инструментов
/// </summary>
[Component(Order = 100)]
private class ToolboxItem : IBPMNToolboxItem, IContainingElementIcon
{
/// <summary>
/// Имя элемента
/// </summary>
public string Name => SR.T("Пример элемента");
/// <summary>
/// Uid группы элементов в панели инструментов
/// </summary>
public Guid GroupUid => ExampleElementGroup.Uid;
/// <summary>
/// Иконка для отображения элементов в панели инструментов в десктопной версии
/// </summary>
public Image Image => new Bitmap(16, 16);
/// <summary>
/// Тип элемента
/// </summary>
public Type ElementType => typeof(ExampleElement);
/// <summary>
/// Название иконки в web-версии
/// </summary>
public string ElementIcon => "user";
}
- Пример реализации группы:
ExampleElementGroup
/// <summary>
/// Группа "Тестовая группа" на панели Toolbox в дизайнере
/// </summary>
[Component(Order = 100)]
internal sealed class ExampleElementGroup : IBPMNToolboxItemGroup
{
internal static readonly Guid Uid = new Guid("{D308A6B2-C225-41C6-A1CD-D4613D06DDC9}");
/// <inheritdoc />
public Guid PanelUid => ExampleElementPanel.Uid;
/// <inheritdoc />
public Guid GroupUid => Uid;
/// <inheritdoc />
public Guid ParentGroupUid => Guid.Empty;
/// <inheritdoc />
public string Name => SR.T("Тестовая группа");
}
- Пример реализации панели:
ExampleElementGroup
/// <summary>
/// Панель "тестовая" в toolbox дизайнера
/// </summary>
[Component(Order = 100)]
internal sealed class ExampleElementPanel : IBPMNToolboxItemPanel
{
internal static readonly Guid Uid = new Guid("{D4FB15CA-D9E3-4D17-A19B-18699C886EBA}");
/// <inheritdoc />
public Guid PanelUid => Uid;
/// <inheritdoc />
public string Title => SR.T("Тестовая панель");
/// <inheritdoc />
public Image Image => null;
}
Теперь можно сформировать пакет с расширением .nupkg и добавить его к источникам пакетов DevServer. Вы также можете установить пакет на сервере ELMA4.
Реализация в модуле КИ
Сначала создайте публичную структуру обмена данными (СОД). Для всех СОД – элементов диаграммера существуют вложенные структуры, так как все типы элементов являются наследниками. В нашем примере нужно указать Базовый класс элемента диаграммы BPMN в качестве вложенной структуры. Чтобы этот тип стал доступен в модуле, в Списке зависимостей модуля выберите Модуль „Элементы диаграммы модуля „Процессы“ Дизайнера конфигурации.
Теперь в публичной СОД в качестве вложенной структуры укажите Базовый класс элемента диаграммы BPMN.
Для корректной работы следует добавлять свойства, соответствующие типу и имени оригинального класса из серверного модуля.
Далее создайте маппинг. В настройках СОД перейдите на вкладку Системные и укажите Пространство имен, как показано на рисунке ниже.
Если у вас нет этой настройки или вкладки, проверьте, внесены ли изменения в файл appsettings.json.
Реализация компонента
Для использования компонентов дизайнера в Список зависимостей модуля добавьте следующие модули:
- Модуль „Процессы“ Дизайнера конфигурации (EleWise.ELMA.Workflow.Designer);
- Модуль „Диаграммер“ Дизайнера конфигурации (EleWise.ELMA.Diagrams.Designer);
- Модуль „Элементы диаграммы модуля „Безопасность“ Дизайнера конфигурации.
Для отображения компонентов настроек элементов используйте форму объекта. С её помощью СОД можно связать с целевым компонентом.
В новом компоненте укажите следующие настройки для свойства с входным значением:
- в поле Отображаемое имя * укажите Model;
- в поле Тип выберите созданную ранее СОД, например, ExampleElementDTO;
- включите опцию Входное;
- установите флажок в настройке Обязательно для заполнения.
Для всех настроек элементов используйте компонент Меню с формой.
Во всех существующих компонентах настроек элементов используется компонент Общая панель действий настроек элемента, который позволяет добавлять дополнительные действия. Если вам не нужно нестандартное оформление панели действий, используйте этот компонент. Разместите его в строке в заголовке компонента меню.
Этот компонент принимает:
- функцию сохранения;
- функцию отмены;
- базовый элемент для моделирования;
- контракт расширения.
Внешний контракт расширения можно выбрать, если вы хотите использовать нестандартные значения. Это поле необязательно для заполнения.
Пример контроллера с функциями панели действий:
ExampleElementGroup
private readonly INotificationService notificationService;
/// <summary>
/// Ctor
/// </summary>
/// <param name="notificationService">Сервис нотификаций</param>
public ComponentController(INotificationService notificationService)
{
this.notificationService = notificationService;
}
/// <summary>
/// Сценарий вычисления значения свойства "Базовый элемент"
/// </summary>
public BaseBPMNElementDTO GetBaseBPMNElement()
{
return Context.Model.As<BaseBPMNElementDTO>();
}
/// <summary>
/// Действие при сохранении
/// </summary>
public async Task Save()
{
if (!Component.Validation.IsValid)
{
var errorMessage = string.Join("\n",
Component.Validation.Errors.GroupBy(e => e.ErrorMessage).Select(group => group.Key));
notificationService.Error(SR.T("Ошибка валидации"), errorMessage, false);
return;
}
await GetBaseBPMNElement().Save(Context.Model.As<ElementDTO>());
}
/// <summary>
/// Действие при отмене
/// </summary>
/// <returns></returns>
public Task Cancel()
{
return GetBaseBPMNElement().Cancel();
}
/// <summary>
/// Сценарий вычисления значения свойства "Элемент"
/// </summary>
public EleWise.ELMA.SDK.Diagrams.DTO.Model.ElementDTO GetBaseElement()
{
return Context.Model.As<ElementDTO>();
}
На рисунке ниже представлена форма с настройками элемента с одним полем и общей формой элемента ([Настройки элемента] Общие).
Для привязки компонента к визуальному отображению типа настроек в компоненте настройте реализацию форм Создание, Редактирование и Просмотр.
Теперь можно опубликовать модуль/приложение и импортировать в ELMA4 для проверки работоспособности.