Довідник по UI контролам¶
Цей документ описує реальний механізм UI-контролів у прошивці JAAM Fusion: що лежить у web/, які JSON ендпоінти віддає прошивка, як фронтенд підставляє поточні значення і як параметри зберігаються в налаштування.
Зміст¶
- Як працює UI schema
- Типи контролів і їх формат
- Покроково: додати або змінити контрол
- Dropdown списки
- Умови видимості (visibility)
- Поширені помилки
- Де почитати більше
Як працює UI schema¶
Веб-інтерфейс рендериться динамічно на клієнті на основі набору JSON-ресурсів ("UI schema"):
GET /ui-schema/models— моделі полів для кожногоtype(див.web/ui_schema_models.json).GET /ui-schema/sections— секції/вкладки UI (див.web/ui_schema_sections.json).GET /ui-schema/dropdown_lists— списки опцій для dropdown (генерується вsrc/JaamWeb.cpp).GET /ui-schema/controls— список контролів без поточних значень (джерело:web/controls.json).GET /ui-schema/controls/values— поточні значення параметрів у форматі[[name, value], ...](генерується вsrc/JaamWeb.cppзALL_PARAM_MAPPINGS).
На клієнті (web/scripts.js) відбувається:
- Паралельне завантаження ресурсів (schema).
- Об'єднання
controlsзіvaluesуmergeControlsWithValues(). - Рендер кожного контролу в DOM.
Чому controls.json не містить current¶
У web/controls.json немає поля current (поточне значення). Його підставляє фронтенд, використовуючи модель з web/ui_schema_models.json:
- модель визначає порядок полів (включно з
current), mergeControlsWithValues()знаходитьname, шукає значення у/ui-schema/controls/values,- і вставляє
currentу потрібну позицію.
Висновок: якщо контрол має name і модель містить current, то для нього обов'язково має існувати запис у ALL_PARAM_MAPPINGS, інакше рендер контролу зіб'ється.
Типи контролів і їх формат¶
Офіційне джерело формату — web/ui_schema_models.json. Нижче — практичний довідник: як контрол виглядає саме у web/controls.json (тобто без current).
Параметричні контроли (мають name, потребують ALL_PARAM_MAPPINGS)¶
dropdown—controls.json:["dropdown", name, label, list, section, visibility]; відправляє зміни наPOST /parameter.dropdown_confirm—controls.json:["dropdown_confirm", name, label, list, section, visibility]; відправляє зміни наPOST /parameterпісля підтвердження.bool—controls.json:["bool", name, label, section, visibility]; відправляєvalue=1абоvalue=0наPOST /parameter.text—controls.json:["text", name, label, placeholder, section, visibility]; відправляє наPOST /text.color—controls.json:["color", name, label, section, visibility]; відправляє наPOST /colorзначення#RRGGBB.slider—controls.json:["slider", name, label, min, max, step, section, unit, visibility]; відправляє наPOST /parameterчислове значення.
Інформаційні контроли (не мають current, не потребують ALL_PARAM_MAPPINGS)¶
button—controls.json:["button", name, label, color, url, section, visibility]; навігаційна кнопка (перехід на сторінку/редактор), нічого не зберігає.label—controls.json:["label", text, section, visibility]; просто заголовок/пояснювальний рядок.info—controls.json:["info", text, color, icon, section, visibility]; інфо-панель,icon— цеpathдля SVG (Material Design Icons).
Покроково: додати або змінити контрол¶
Крок 1. Додайте або змініть контрол у web/controls.json¶
Приклад (перемикач):
Поля section і visibility мають відповідати секціям і правилам, описаним нижче.
Крок 2. Додайте маппінг у ALL_PARAM_MAPPINGS (для параметричних контролів)¶
ALL_PARAM_MAPPINGS живе в src/JaamWeb.cpp і є джерелом істини для двох речей:
- Які значення потраплять у
/ui-schema/controls/values. - Які параметри приймають
POST /parameter,POST /text,POST /color.
Формат:
де:
- перше поле (
"api_enabled") — цеnameзcontrols.json. - друге поле (
API_ENABLED) — це елементenum Typeзsrc/JaamConfig.h. - третє поле (
TYPE_BOOL) — тип даних для збереження/читання.
Крок 3. Переконайтесь, що налаштування існує¶
Якщо ви додаєте новий параметр (а не використовуєте існуючий), його треба завести в типах налаштувань і в збереженні.
Мінімальний перелік місць, які зазвичай доводиться чіпати:
src/JaamConfig.h: додати значення вenum Type.src/JaamSettings.*: додати підтримку збереження/дефолтів/валідації (залежить від типу).src/JaamWeb.cpp: додати вALL_PARAM_MAPPINGS.
Крок 4. Якщо це dropdown — додайте список у /ui-schema/dropdown_lists¶
Деталі в розділі Dropdown списки.
Крок 5. Зберіть прошивку¶
web/*.json та інші веб-асети збираються у src/web_assets.h під час PlatformIO build (pre-script tools/pre_build.py).
Команда для перевірки:
Не редагуйте src/web_assets.h вручну — це згенерований файл.
Dropdown списки¶
Dropdown використовує list-ключ, який має існувати у відповіді GET /ui-schema/dropdown_lists.
Як формується список¶
У src/JaamWeb.cpp є хелпер appendOptionsList(), який додає в JSON компактні елементи у форматі:
де:
id— числовий ідентифікатор (те, що буде збережене як значення).name— текст, який показується користувачу.sub—0/1(в UI відображається як "-- name", якщо1).disabled—0/1(опція буде disabled).
Джерело елементів: SettingListItem¶
У src/JaamConfig.h є структура:
Правила, які реально застосовуються при серіалізації списку:
- якщо
ignore == trueіshowDisabled == false— елемент не потрапляє в список взагалі; - якщо
showDisabled == true— елемент потрапляє в список зdisabled = 1.
Як додати новий список¶
- Додайте масив
SettingListItem(зазвичай уsrc/JaamConfig.cpp+externуsrc/JaamConfig.h). -
У
JaamWeb::buildUiSchemaDropdownLists()додайте заповнення JSON: -
У
web/controls.jsonвикористайте"my_list"у відповідному dropdown:
Умови видимості (visibility)¶
visibility — це рядок у контролі, який фронтенд читає з атрибута data-visibility і на його основі додає/прибирає CSS-клас hidden.
Базовий синтаксис¶
Одна умова:
Важливі обмеження, які випливають з реалізації у web/scripts.js:
- підтримуються тільки числа (
Nмає бути цілим; рядки на кшталтtrueне працюють); fieldшукається якdocument.getElementById(field);- для checkbox поточне значення — це
1або0.
Приклади (валідні):
Кілька умов через кому¶
Умови розділяються комою:
Логіка (як реалізовано):
- умови групуються за
fieldі оператором (==окремо від!=); - всередині групи
field==...діє OR (достатньо, щоб спрацювала будь-яка); - всередині групи
field!=...діє AND (мають виконатися всі); - різні групи між собою комбінуються через AND.
Поширені помилки¶
Контрол має name, але немає маппінга¶
Симптоми:
- UI ламається (поле
currentне підставляється і позиції зсуваються), або контрол відображається некоректно.
Рішення:
- додайте запис у
ALL_PARAM_MAPPINGSуsrc/JaamWeb.cpp.
name не збігається між controls.json і ALL_PARAM_MAPPINGS¶
Симптоми:
- значення не підтягується у
current, зміни не зберігаються.
Рішення:
- зробіть
nameідентичним (включно з регістром і підкресленнями).
Неправильний ValueType¶
Симптоми:
- сервер відхиляє значення як невалідне, або зберігає не те.
Підказка:
dropdown/sliderзазвичай працюють якTYPE_INT.bool—TYPE_BOOL.colorі більшістьtext—TYPE_STRING.
Visibility використовує true/false або рядки¶
Не працює, бо вирази парсяться регуляркою, яка приймає тільки -?\d+.
Правильно: api_enabled==1.
Dropdown порожній¶
Причини:
- ключ
listу контролі не існує в/ui-schema/dropdown_lists; - список серіалізується, але всі елементи відфільтровані через
ignore.
text для числового параметра¶
text відправляє значення на POST /text. Для TYPE_INT/TYPE_FLOAT там використовується нестрогий парсинг (toInt(), toFloat()), тому краще для чисел використовувати slider або dropdown.
Неправильний формат color¶
POST /color приймає тільки #RRGGBB і валідує кожний hex-символ.
Де почитати більше¶
- Web Assets — як веб-асети пакуються та кешуються.
- Архітектура — огляд модулів і ендпоінтів прошивки.
- Збірка — як зібрати прошивку з PlatformIO.
- Material Design Icons — іконки для
infoконтролів.