# Builder

В этом документе будут описаны важные моменты, при работе с модулем `builder` и его составляющими элементами.

<br />

## SiteFormBuilder

<br />

### Введение

Этот модуль позволяет создать форму для вставки на клиентский сайт. Сама логика генерация скрипта формы находится в отдельном репозитории [form-builder](https://gitlab.amwork.app/amwork/form-builder). Логика предпросмотра формы (4ый и 5ый шаги) реализована на отдельной странице лэндинга [mywork-landing](https://gitlab.amwork.app/amwork/mywork-landing), в систему она вставлена через `iframe`. При проблемах с просмотром формы вероятнее всего нужно будет дорабатывать этот компонент именно в репозитории лэндинга.

<br />

### Работа с генератором скрипта формы

Генератор скрипта формы на момент написания (10.07.24) использует `Preact` как базовый фреймворк, чтобы размер бандла был оптимальным. Для вступления в силу любых изменений в генераторе скрипта, его нужно собрать (`npm run build`) и поместить в `public` на лэндинг. Клиентский же скрипт, который находится в файле `script.js` перед использованием надо минифицировать с помощью команды:

```bash
# Минимизация клиентского скрипта

npm run minify-client-script
```

Результатом работы этой команды будет `script.min.js`, который уже и надо вставлять на сайт клиента или финальный шаг конструктора форм для самостоятельного копирования.

- `index.html` – для DEV окружения;
- `client-test.html`- для тестирования билда скрипта формы и клиентского скрипта в реальных условиях, его нужно запустить с помощью live-server, смотрит на `script.min.js` и папку с билдом. Не реагирует на изменения в самом скрипте, пока тот не будет пересобран.

Следует помнить, что нельзя использовать пакеты, требующие `React` как зависимость, так как это серьезно раздует размер бандла.

<br />

### Работа с превью формы на лендинге

Следует помнить, что страница предпросмотра скрипта формы должна использовать внутри себя финальную версию клиентского `script.min.js`, а также должна учитывать, что она будет вставлена в `iframe`. Она должна нормально обрабатывать как built-in вид, так и вид, когда форма открывается по кнопке в всплывающем окне.

<br />

### Работа с конструктором формы в системе

- Важно, чтобы в `IIFE` в скрипте на финальном шаге были вставлены правильные аргументы через интерполяцию.
- На момент написания (10.07.24) предполагается, что в форме может быть только одна страница. Однако модели уже включают в себя логику многостраничности.

### События аналитики в форме

Форма на сайте пользователя независимо от настроек отправляет четыре типа событий аналитики:

1. VIEW — просмотр формы (вызывается в момент первого появления формы во viewport);
2. START — начало заполнения (вызывается в момент самого первого изменения любого из полей);
3. FIELD — заполнение поля (вызывается, когда поле становится не пустым и валидным);
4. SUBMIT — отправка формы.

Каждое событие отправляется в Гугл Аналитику и Яндекс.Метрику, наличие счетчиков на странице определяется
автоматически (в зависимости от наличия определенных свойств у глобального объекта `window`).

Каждое событие имеет вид: "\{префикс}\_\{код формы\}\_\{тип события\}\_\{ID поля (только для FIELD-событий)\}".

Примеры событий:

_"WORKSPACE_FORM_XXXXXX_START"_ — начало заполнения формы XXXXXX;
_"WORKSPACE_FORM_XXXXXX_FIELD_167297"_ – заполнение поля 167297 в форме XXXXXX.

За логику отправки событий аналитики отвечает класс `AnalyticsUtil`.

### Последовательность рендера форм и режим мультиформ (несколько разных форм на одной странице)

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

1. Если включен режим мультиформ:
   1.1 Получаем элементы на странице c классом "workspace-form-builder-mount-container-\{код формы\}".
   1.2 Если такие элементы есть на странице, рендерим форму в них.
   1.3 Если таких элементов нет, **не рендерим формы.**
2. Получаем элементы на странице с классом "workspace-form-builder-mount-container".
   2.1 Если такие элементы есть на странице, рендерим форму в них.
3. Получаем элементы на странице с классом, начинающимся на "workspace-form-builder-mount-container-" («чужие» формы
   — формы из нашего конструктора, но с другим кодом).
   3.1 Если такие элементы есть **не рендерим формы.**
4. Создаем div-элемент с классом "workspace-form-builder-mount-container" рядом со скриптом и рендерим формы в него.

Самый частый сценарий использования форм — рендер в контейнеры "workspace-form-builder-mount-container". Однако, иногда
необходимо на одной и той же странице использовать несколько разных форм. Чтобы между ними не возникало конфликта,
они должны быть вставлены на сайт в _режиме «мультиформ»._ Это делается с помощью добавления в объект опций скрипта
форм значения `multiform: true` и создания контейнеров на сайте с классами "workspace-form-builder-mount-container-\{код формы\}".

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