Виджеты дашборда и карточек
Где показывать виджеты, как настроить их высоту и доступ сотрудников.
Назначение и виджет дашборда
В настройках сервиса выберите Назначение сервиса:
- Обычный сервис — отдельный пункт в меню сервисов.
- Виджет дашборда — карточка в рабочем пространстве сотрудника вместо пункта меню.
После выбора виджета появляется плашка Настройки виджета с двумя независимыми слайдерами:
- Высота на мобильном — от 60 до 800 логических пикселей, шаг 10; стандартная высота 100.
- Высота в веб-версии — от 120 до 800 пикселей, шаг 20; стандартная высота 280.
Заголовок карточки в высоту содержимого не входит. Кнопка По умолчанию возвращает оба стандартных размера.
В мобильном приложении виджет использует тот же WebView и нативный мост, что и обычный сервис: SDK, контекст компании, артефакты, диалоги и другие поддержанные методы продолжают работать. Удержание заголовка открывает настройку рабочего пространства: виджет можно скрыть, вернуть и передвинуть. Положение и видимость сохраняются для сотрудника. Скрытый виджет не запускается. Ошибка загрузки показывает кнопку повторной попытки внутри карточки.
В веб-дашборде виджет появляется только при включённом «Разрешить в веб-версии». Нужны действующая лицензия Приложения, включённый сервис, доступ сотрудника и опубликованный код. Название, высота и содержимое берутся из сервиса; черновик не показывается. Управление порядком и видимостью находится в Виджеты дашборда, настройки сохраняются в этом браузере отдельно для пользователя и компании.
В веб-версии виджеты поддерживаются для сервисов HTML, CSS и JavaScript. Сервисы по внешнему URL доступны как виджеты только на мобильных устройствах: удалённая страница не переносится в Shadow DOM.
Код веб-виджета
Shadow DOM отделяет разметку и CSS карточки от дашборда, но не является границей безопасности JavaScript. Публикуйте здесь только доверенный код компании: в отличие от iframe обычного сервиса, JavaScript виджета исполняется в контексте страницы. Не используйте parent, top, cookie и внутренние API веб-приложения. Ключи авторизации пользователя и компании в код не передаются; данные получайте через SDK и проверяемый сервером мост.
Обычные HTML/JS и React/JSX поддерживаются. Монтируйте React через createRoot(document.getElementById('root')); поиск элементов через переданный document ограничен своим виджетом, поэтому одинаковые id в разных карточках не конфликтуют. Пишите исполняемый код во вкладке JavaScript, не в inline-обработчиках HTML или <script>. Для фона, текста и элементов используйте тему SDK и CSS-переменные; смена темы обновляет виджет без потери состояния. При скрытии React-корни размонтируются, таймеры и подписки SDK очищаются. Отписывайтесь от собственных внешних подписок в cleanup React-эффектов.
Среда SDK остаётся web: synchra.getRuntime() возвращает web, мобильные действия не запускаются и возвращают признак ignored. В мобильном WebView среда — mobile. Виджеты также поддерживаются в карточках и на экране управления — см. ниже.
Виджеты карточек и управления
В Назначение сервиса кроме обычного сервиса и виджета дашборда доступны:
| Назначение | Место показа |
|---|---|
| Виджет задачи | В конце карточки задачи, перед комментариями |
| Виджет инцидента | В конце основной карточки инцидента, перед комментариями |
| Виджет документа | В конце карточки документа |
| Виджет выезда | В конце карточки выезда команды |
| Виджет визита | В конце карточки визита |
| Виджет журнала | В конце карточки мероприятия/события журнала |
| Виджет отчёта | После содержания и вложений отчёта |
| Виджет сотрудника в управлении | В конце вкладки «Информация» карточки сотрудника |
| Виджет экрана управления | В вебе под «Ресурсами», в мобильном приложении под основной аналитикой |
Без заголовка и отступов. В настройках виджета доступен стандартный свитч с описанием: он скрывает заголовок плашки и убирает внутренние отступы контейнера одновременно в мобильной и веб-версии. Содержимое занимает всю область виджета с выбранной высотой; это не полноэкранный режим устройства. Собственные отступы HTML/CSS сервиса сохраняются. Настройка применяется ко всем назначениям виджетов; обычный сервис отображается как прежде. По умолчанию свитч выключен. На мобильном дашборде управление перемещением и видимостью остаётся доступно в режиме редактирования.
Настройка Без заголовка и отступов применяется после сохранения сервиса.
Для одного назначения можно создать несколько сервисов. Они добавляются отдельными плашками в конце карточки, перед комментариями при их наличии. Порядок — по созданию сервисов, от более ранних к новым. Назначение не даёт доступа к карточке: сначала сотрудник открывает разрешённую запись, затем загружаются доступные ему сервисы. Учитываются лицензия Приложения, доступ сервиса, его включение и публикация; в вебе дополнительно проверяется Разрешить в веб-версии. Виджеты не запускаются в предпросмотре шаблона инцидента. Веб-виджеты с внешним URL не поддерживаются, для них используйте встроенный код. Высоты на мобильном и в вебе настраиваются отдельно, как у виджета дашборда.
Единый контекст записи
Встроенный SDK предоставляет await synchra.getWidgetContext(). В обычном сервисе без карточки результат — null. В виджете возвращается единый объект:
{
"version": 1,
"placement": "task",
"provider_id": "108",
"entity": { "type": "task", "id": "42" },
"data": {
"id": 42,
"title": "Проверить оборудование",
"description": "Осмотр перед сменой",
"status": "in_progress"
}
}
placement — dashboard, task, incident, document, field_visit, visit, journal, report, control_employee или control. ID компании и записи в общей оболочке всегда строки. Для сотрудника entity.type — employee; для управления и дашборда ID обозначает компанию. В журнале ID относится к мероприятию, а ID журнала доступен в data, когда он есть в карточке.
data содержит выбранные поля отображаемой записи: название, описание, статус, доступные даты, приоритет и ID связанных участников; набор зависит от карточки, отсутствующие поля не создаются искусственно. Контекст управления включает текущие фильтры и статистику, карточки сотрудника — основные данные профиля. Конкретные ключи DTO могут отличаться между разделами и платформами; проверяйте наличие поля, не рассчитывайте на обязательный description у всех типов. Пароли, токены, секреты и другие служебные данные авторизации в контекст не включаются. Контекст — данные интерфейса, не доказательство полномочий: для операций сервер обязан отдельно проверять доступ.
Обновления приходят без перезапуска виджета. Подпишитесь на synchra.onWidgetContextChange(callback) и вызовите возвращённую функцию отписки при размонтировании:
import React, { useEffect, useState } from 'react';
function RecordInfo() {
const [context, setContext] = useState(null);
useEffect(() => {
let active = true;
synchra.getWidgetContext().then(value => { if (active) setContext(value); });
const unsubscribe = synchra.onWidgetContextChange(setContext);
return () => { active = false; unsubscribe(); };
}, []);
return <p>{context?.data?.description ?? 'Описание не указано'}</p>;
}
Во внешнем мобильном сервисе со старым пакетом SDK можно вызвать synchra.requestPayload('app.widget.context'); синхронное чтение поддерживает window.getSynchraWidgetContext(). При переходе к другой записи экземпляры виджетов создаются заново, чтобы данные разных карточек не смешивались.
Добавление нового места в приложении
Общий компонент называется ServiceWidgets. В вебе импортируйте его из @/widgets/services/ServiceWidgets, в React Native — из общего barrel-алиаса :widgets. Компоненту передаются placement, entityId, data и явный список разрешённых fields; в вебе также providerId, в мобильном он берётся из текущего рабочего пространства. Компонент сам получает доступные сервисы, применяет назначение, отображает несколько виджетов и передаёт контекст через общий движок. Новый раздел подключается добавлением назначения в реестр/серверное ограничение и одним слотом в авторизованной карточке, перед комментариями. Не передавайте весь объект контекста авторизации или незагруженную/недоступную запись.