Контракт UI-extension
Декларативные виджеты и разделы. Protocol 1, без исполняемого frontend из пакета.
Отдельное согласование
Это реализованный контракт для отдельно одобренных расширений, не возможность любого пользовательского BTP. Нужны подтвержденный пакет и отдельное разрешение BlueTraktor на contribution, подходящая лицензия, работающий экземпляр точного пакета (ID, версия, digest) и все объявленные permissions у пользователя.
Обычная подпись издателя или лицензия сами по себе не разрешают расширять интерфейс. Для проверки передайте исходники, manifest, metadata и результаты тестов команде BlueTraktor. Издательские операции и ключи не входят в задачу автора; самостоятельное добавление contributions в обычный стартер приводит к отказу inspection.
Manifest contribution
Пример предполагает plugin.id = io.example.sensors, но сам по себе не является одобрением. В пакете допускается не более одного ui-extension, минимум одно permission; ID permissions начинаются с <plugin-id>.. Если permissions несколько, пользователю нужны все. Право изменять dashboard и ACL папки проверяется отдельно.
[[contributions]]
kind = "ui-extension"
id = "io.example.sensors.ui"
protocol_version = 1
[[contributions.permissions]]
id = "io.example.sensors.ui.view"
group = "Датчики"
title = "Просмотр виджетов датчиков"
default_roles = ["admin", "root"]Каталог пакета
Фиксированный путь: schemas/extensions.json. Дополнительного поля catalog в manifest нет. Неизвестные ключи запрещены. Любое изменение metadata после выпуска требует повторной сборки и согласования пакета.
| Поле | Контракт |
|---|---|
| schemaVersion | Ровно 1 |
| provider | Точно plugin.id |
| widgets | От 1 до 64 описаний |
| sections | Необязательно, до 16 разделов |
| Размер каталога | До 64 KiB |
Описание виджета
| Поле | Ограничение |
|---|---|
| id | <plugin-id>/<widget-name>, до 160 ASCII-символов; без .. и // |
| schemaVersion | 1 |
| title / category | Непустые, до 100 / 80 символов |
| description | До 500 символов, простой текст |
| icon | Имя встроенной иконки, до 50 букв/цифр; не URL |
| renderer | metric или chart |
| visualization | Совместимый вид из списка ниже |
| fields | До 9 уникальных стандартных полей |
| size | width 220..1200, height 180..1000, minWidth 160..1200, minHeight 120..1000 |
| defaults | Все семь обязательных ключей, описанных ниже |
Виды и поля
- metric: number, status, progress, thermometer, text.
- chart: line, step, stacked-area, bars, horizontal-bars, stacked-bars, pie, donut, scatter, radar, heatmap, funnel, polar.
- fields: value, range, unit, status, series, history, xy, matrix, limits.
- Минимальные размеры не превышают начальные. Поля выбирают стандартные controls, а не собственную программу.
- defaults: конечные min и max; precision - целое 0..6; history - целое 10..600; color - #RRGGBB; activeText и inactiveText - строки до 80 символов. Все семь ключей обязательны.
Полный пример metadata
{
"schemaVersion": 1,
"provider": "io.example.sensors",
"widgets": [{
"id": "io.example.sensors/temperature",
"schemaVersion": 1,
"title": "Температура",
"category": "Датчики",
"description": "Числовое показание температуры",
"icon": "Thermometer",
"renderer": "metric",
"visualization": "number",
"fields": ["value", "range", "unit", "limits"],
"size": { "width": 360, "height": 240, "minWidth": 220, "minHeight": 180 },
"defaults": {
"min": 0, "max": 100, "precision": 1, "history": 60,
"color": "#57C9AD", "activeText": "Работает", "inactiveText": "Остановлен"
}
}],
"sections": [{
"id": "io.example.sensors/sensors",
"title": "Датчики",
"icon": "Gauge",
"placement": "main",
"view": "widget-catalog",
"widgetTypes": ["io.example.sensors/temperature"]
}]
}Разделы и ограничения UI
placement: main, settings или usepi. view: только widget-catalog. widgetTypes содержит 1..64 уникальных ID из того же каталога. Раздел показывает разрешенные типы на системной странице, не переписывает URL, меню или встроенные экраны.
Не передавайте ECharts option, formatter functions, CSS, JavaScript, HTML, iframe или сетевые адреса. Неизвестному renderer нужна отдельная проверенная реализация в BlueTraktor; пакет не может добавить ее сам. Общие runtime-пределы: до 32 providers, 256 дополнительных виджетов и 128 разделов.
Подключение и остановка
- Установите согласованный пакет, создайте экземпляр, настройте grants и запустите его.
- Выдайте пользователям permissions просмотра; дополнительные виды появятся в каталоге dashboard, разделы - в заявленном месте.
- При остановке экземпляра, отсутствии прав, лицензии или подтверждения source становится недоступным. Обнаружение изменений не мгновенное.
- При неоднозначных активных версиях одного provider сначала остановите старую версию.
- Сохраненные записи dashboard не удаляются при исчезновении source. Недоступный provider не дает права редактировать неизвестный payload.
Импорт и совместимость
Экспорт сохраняет и недоступные виджеты как данные. Импорту нужен установленный, работающий и доступный source: архив сам по себе не разрешает неизвестный тип. Сначала восстановите соответствующий пакет и права. При несовместимом изменении используйте новый type ID или согласованную системную миграцию, не меняйте схему существующего типа молча.
Проверки расширения
- Положительный путь установки и повторной загрузки пакета.
- Неизвестные keys/renderers, чужой namespace, дубли ID, поврежденный JSON и граничные размеры.
- Отсутствие одного из permissions, неработающий экземпляр, смена аккаунта и недоступный source.
- Обновление, остановка, удаление, экспорт/импорт и сохранность исходных записей dashboard.
- Настольные и мобильные экраны без перекрытий.