Создание простого приложения без кода с помощью Workflow Designer

В этом уроке я покажу вам, как создать простое No-Code приложение. Мы попытаемся создать приложение, в котором пользователь может спроектировать некоторую бизнес-логику с помощью графического интерфейса пользователя и попытаться запустить его.

🎯 Что такое No-Code?

Приложения No-Code позволяют нетехническим пользователям создавать приложения. Как это возможно? No-Code предоставляют простой пользовательский интерфейс, гораздо более простой, чем интерфейс инструментов программирования. No-Code часто адаптированы для какой-либо отрасли и подготовлены для выполнения определенной работы.

В принципе, в No-Codes можно выделить два слоя:

  • Модель — содержит определение программы, выполненное с помощью какого-либо графического интерфейса пользователя. Она готовится в основном нетехническим пользователем и может храниться в базе данных или на жестком диске.
  • Execution — этот уровень выполняет модель. Модель может быть обработана во что угодно: графический интерфейс, приложение командной строки, веб-сайт и т.д..

В этом учебнике мы сосредоточимся на рабочих процессах. Рабочий процесс — это широкая концепция, но в данном случае мы хотим использовать его для определения нашего no-code приложения. Мы хотим дать конечному пользователю возможность создать некоторый логический поток типа «прочитать некоторое значение», «сделать что-то, если значение равно 1» и т.д. Нам нужен простой графический интерфейс пользователя для определения такого потока. Для этого мы будем использовать пакет Sequential Workflow Designer.

Пакет содержит общий дизайнер. Этот типовой дизайнер позволяет нам создавать дизайнеры для конкретных случаев использования. Уровень исполнения не является частью этого компонента.

Вернемся к концепции рабочего процесса. Рабочий процесс содержит определение потока. Здесь важно отметить одну вещь: поток не обязательно должен быть линейным. Он может содержать некоторые условные операторы или циклы. Самую маленькую часть здесь мы называем шагом. Шаг представляет собой одну инструкцию или одну задачу, которую нужно выполнить. Конечно, условия или циклы — это тоже шаги.

Здесь мы подготовим два простых шага и создадим простой исполнитель рабочего процесса.

  • readUserInput — считывает пользовательский ввод в буфер.
  • sendEmail — отправляет письмо, если буфер равен некоторому значению.

👓 Конструктор последовательных рабочих процессов

Чтобы добавить пакет в ваш проект, вы можете добавить приведенный ниже код в раздел <head>.

<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.1.9/css/designer.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.1.9/css/designer-light.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.1.9/lib/designer.js"></script>
Вход в полноэкранный режим Выйти из полноэкранного режима

Если вы используете npm в своем проекте, вы можете добавить пакет с помощью npm:

npm i sequential-workflow-designer
Войти в полноэкранный режим Выйти из полноэкранного режима

🐾 Шаги

Шаги в конструкторе задаются в формате JSON. Почему JSON? Потому что его легко хранить где угодно (в базе данных, файле и т.д.).

В этом учебнике мы будем использовать только шаги task. Но дизайнер поддерживает больше типов (container, switch). Компонент задачи отображается в виде одного прямоугольника. Он не содержит дочерних элементов. Он имеет имя, некоторую иконку, один вход и один выход.

Посмотрите на приведенный ниже JSON, это определение шага задачи.

{
    "id": "unique_id",
    "componentType": "task",
    "type": "my_type",
    "name": "my_name",
    "properties": {
        "setting1": "value1",
        "setting2": "value2"
    }
}
Войти в полноэкранный режим Выйти из полноэкранного режима
  • id — уникальный идентификатор шага. Этот идентификатор относится к размещенным шагам в дизайнере. Если у нас есть 2 размещенных шага, у нас есть два уникальных идентификатора.
  • type — тип задачи, в данном руководстве у нас два типа: readUserInput и sendEmail,
  • имя — отображается на прямоугольнике,
  • свойства — здесь находятся все настройки шага, этот список зависит от типа шага.

Как я уже говорил выше, мы хотим создать 2 простых шага.

Первый — это шаг readUserInput. Мы хотим позволить пользователю изменить сообщение вопроса. Поэтому мы определим одно свойство question.

{
    "componentType": "task",
    "type": "readUserInput",
    "name": "Read User Input",
    "properties": {
        "question": "Ask me"
    }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Следующий шаг — sendEmail. Здесь мы хотим позволить пользователю определить email и добавить условие ifReqisterEquals, которое позволяет отправить письмо, если пользователь на последнем шаге readUserInput ввел определенное значение. По сути, я ввожу здесь простое условие.

{
    "componentType": "task",
    "type": "sendEmail",
    "name": "Send E-mail",
    "properties": {
        "ifReqisterEquals": "1",
        "email": "x@example.com"
    }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

🔨 Панель инструментов

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

const toolboxConfig = {
    groups: [
        {
            name: 'Steps',
            steps: [
                {
                    componentType: 'task',
                    type: 'readUserInput',
                    name: 'Read User Input',
                    properties: {
                        question: 'Ask me'
                    }
                },
                {
                    componentType: 'task',
                    type: 'sendEmail',
                    name: 'Send E-mail',
                    properties: {
                        ifReqisterEquals: '1',
                        email: 'x@example.com'
                    }
                }
            ]
        }
    ]
};
Войти в полноэкранный режим Выход из полноэкранного режима

Конфигурация разделена на группы. Каждая группа содержит шаги. Шаги имеют ту же структуру, которую я представил выше, за одним исключением. Здесь мы не предоставляем поле id. Это поле будет добавлено с уникальным ID после сброса.

🐝 Иконки

Мы можем настроить иконку для определенного componentType и type шага. Для этого нам нужно создать конфигурацию.

const stepsConfig = {
    iconUrlProvider: (componentType, type) => {
        return `./assets/icon-task.svg`
    },

    validator: (step) => true
};
Вход в полноэкранный режим Выйти из полноэкранного режима

В этом руководстве мы используем только одну иконку для всех типов шагов. Но вы можете использовать аргументы componentType и type для предоставления конкретных иконок.

Что такое валидатор? Он проверяет, правильно ли настроен шаг. В этом руководстве мы не будем использовать эту функцию.

📇 Редакторы

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

const editorConfig = {
    globalEditorProvider: (definition) => {
        const editor = document.createElement('div');
        editor.innerText = 'Select a step.';
        return editor;
    },
    stepEditorProvider: (step) => {
        // create a step's editor here and return it
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Основная проблема здесь заключается в том, что у нас может быть много типов шагов (в этом учебнике их 2). Это означает, что для каждого шага нужен свой редактор, потому что каждый шаг содержит различные настройки.

Здесь представлен базовый редактор шага readUserInput.

function createEditorForReadUserInput(step) {
    const editor = document.createElement('div');
    const label = document.createElement('label');
    label.innerText = 'Question';
    const input = document.createElement('input');
    input.setAttribute('type', 'text');
    input.value = step.properties['question'];
    input.addEventListener('input', () => {
        step.properties['question'] = input.value;
    });

    editor.appendChild(label);
    editor.appendChild(input);
    return editor;
}
Войти в полноэкранный режим Выход из полноэкранного режима

А здесь редактор шага sendEmail.

function createEditorForSendEmail(step) {
    const editor = document.createElement('div');
    const propNames = ['ifReqisterEquals', 'email'];
    for (let propName of propNames) {
        const label = document.createElement('label');
        label.innerText = propName;
        const input = document.createElement('input');
        input.setAttribute('type', 'text');
        input.value = step.properties[propName];
        input.addEventListener('input', () => {
            step.properties[propName] = input.value;
        });

        editor.appendChild(label);
        editor.appendChild(input);
    }
    return editor;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Как вы видите, эти редакторы обновляют step.properties после изменения пользователем.

У нас есть два генератора, но нам нужно собрать все вместе в свойство stepEditorProvider.

stepEditorProvider: (step) => {
  if (step.type === 'readUserInput')
    return createEditorForReadUserInput(step);
  if (step.type === 'sendEmail')
    return createEditorForSendEmail(step);
  throw new Error('Not supported');
}
Вход в полноэкранный режим Выход из полноэкранного режима

📐 Создание дизайнера

Теперь мы можем создать дизайнер.

const config = {
    toolbox: toolboxConfig,
    steps: stepsConfig,
    editors: editorConfig
};
Войти в полноэкранный режим Выйти из полноэкранного режима

Мы можем дать начальное определение рабочего процесса. Но в данном учебнике мы не будем этого делать.

const startDefinition = {
    properties: {},
    sequence: []
};
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот и все. Давайте создадим конструктор.

const placeholder = document.getElementById('designer');
const designer = sequentialWorkflowDesigner.create(
    placeholder, 
    startDefinition, 
    config);
Войти в полноэкранный режим Выйти из полноэкранного режима

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

🚀 Выполнение

Последняя часть — это выполнение. Здесь мы хотим выполнить разработанный поток.

Нам нужно подготовить код для шага readUserInput. Этот шаг очень прост. Мы задаем вопрос пользователю и сохраняем ответ. Вопрос задается в свойстве question.

let register = null;

if (step.type === 'readUserInput') {
   register = prompt(step.properties['question']);
}
Вход в полноэкранный режим Выход из полноэкранного режима

Шаг sendEmail немного сложнее. Здесь мы отправляем письмо, если ранее выбранное пользователем значение равно некоторому значению. Значение определяется в свойстве ifReqisterEquals.

if (step.type === 'sendEmail') {
  if (step.properties['ifReqisterEquals'] === register) {
     alert(`E-mail sent to ${step.properties['email']}`);
  }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Но как мы можем прочитать определение рабочего процесса? Очень просто.

const definition = designer.getDefinition();
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы можете проверить конечное состояние здесь.

function runWorkflow() {
    const definition = designer.getDefinition();

    let register = null;

    for (let step of definition.sequence) {
        if (step.type === 'readUserInput') {
            register = prompt(step['question']);
        }
        else if (step.type === 'sendEmail') {
            if (step.properties['ifReqisterEquals'] === register) {
                alert(`E-mail sent to ${step.properties['email']}`);
            }
        }
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Теперь нам нужно вызвать функцию runWorkflow.

📦 Примеры

Вы можете протестировать готовый проект здесь.

Кстати, вы можете ознакомиться с приведенными ниже онлайн-демонстрациями компонента Sequential Workflow Designer.

  • ❎ Полный экран
  • 🌅 Фильтр изображений
  • ⛅ Светло-темный
  • ⏩ Живое тестирование
  • 🔴 Частицы
  • 🤖 Генератор кода

Оцените статью
devanswers.ru
Добавить комментарий