Synchra.24
menu_bookДокументация
Практические материалы по запуску и развитию

Здесь собраны инструкции по запуску, разработке внутренних сценариев и встраиванию собственных инструментов в рабочий контур компании.

folderВстроенные сервисы

Виджеты дашборда и карточек

Где показывать виджеты, как настроить их высоту и доступ сотрудников.

Назначение и виджет дашборда

В настройках сервиса выберите Назначение сервиса:

  • Обычный сервис — отдельный пункт в меню сервисов.
  • Виджет дашборда — карточка в рабочем пространстве сотрудника вместо пункта меню.

После выбора виджета появляется плашка Настройки виджета с двумя независимыми слайдерами:

  • Высота на мобильном — от 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, в мобильном он берётся из текущего рабочего пространства. Компонент сам получает доступные сервисы, применяет назначение, отображает несколько виджетов и передаёт контекст через общий движок. Новый раздел подключается добавлением назначения в реестр/серверное ограничение и одним слотом в авторизованной карточке, перед комментариями. Не передавайте весь объект контекста авторизации или незагруженную/недоступную запись.