Как создать плагин для боковой панели (dock)
Слот dock добавляет кнопку плагина в панель в правом нижнем углу Трекера. Кнопка доступна на любой странице, а плагин открывается в выдвижной панели справа и не мешает работать со страницей под ней. Слот подходит для инструментов, которые нужны постоянно и не привязаны к одной сущности: чат с командой или ассистентом, заметки, таймер, быстрые справочники.
1. Создание проекта через CLI
Чтобы создать новый плагин для этого слота, используйте команду создания приложения:
weavix create
В ответ на вопрос Select a template: выберите default — отдельного шаблона для слота dock пока нет. Остальные шаги заполните по запросу, затем объявите слот в манифесте, как описано ниже.
2. Что такое слот dock
Плагин в слоте dock:
- получает кнопку в панели плагинов в правом нижнем углу на всех страницах Трекера, кроме раздела администрирования;
- при нажатии на кнопку открывается в выдвижной панели у правого края экрана; страница под панелью остаётся доступной;
- занимает всю высоту панели. Ширина по умолчанию — 480 px, пользователь может менять её перетаскиванием в пределах 320–1200 px, настройка сохраняется в браузере;
- после первого открытия остаётся загруженным при закрытии панели и при переходах между страницами: панель скрывается, а не выгружает плагин, поэтому состояние и открытые соединения сохраняются. Исключение — раздел администрирования: там панель плагинов не показывается, и плагин выгружается;
- открыт только один: открытие другого плагина из панели закрывает текущий.
Пользователь закрывает панель кнопкой закрытия, клавишей Esc или щелчком вне панели. Кнопка закрепления в заголовке панели отключает закрытие по щелчку вне её — так удобно копировать текст из тикета в плагин. Состояние закрепления сохраняется в браузере.
Панель и кнопки скрываются, пока открыта боковая панель тикета — она занимает тот же край экрана. После её закрытия панель плагина показывается снова.
Если плагинов больше, чем помещается в панель кнопок, остальные доступны в меню Ещё плагины. Ширину панели кнопок пользователь тоже может менять.
Только десктопная версия
Слот доступен только в десктопной версии Трекера. В мобильном приложении кнопки плагинов не показываются.
3. Манифест плагина
В манифесте нужно объявить слот dock.
Пример структуры manifest.json:
{
"$schema": "./manifest.schema.json",
"manifest_version": 1,
"supported_services": ["tracker"],
"slug": "team-chat",
"version": "0.1.0",
"name": {
"ru": "Чат команды",
"en": "Team chat"
},
"description": {
"ru": "Чат команды рядом с любым тикетом",
"en": "Team chat next to any issue"
},
"support": [{"type": "email", "value": "support@example.com"}],
"permissions": {
"data": ["tracker:issues:read"]
},
"slots": {
"tracker": {
"dock": [
{
"entrypoint": "index.html",
"title": {
"ru": "Чат команды",
"en": "Team chat"
},
"description": {
"ru": "Обсуждайте тикеты, не покидая страницу",
"en": "Discuss issues without leaving the page"
},
"contextLevel": "full"
}
]
}
}
}
Важно
title— подпись кнопки во всплывающей подсказке и заголовок открытой панели. Выбирайте короткое название.- На кнопке показывается логотип плагина
public/logo.svg— тот же, что в каталоге. Отдельный значок для слота не задаётся. Логотип отображается в размере 24×24 px, поэтому он должен быть квадратным и читаемым в мелком размере. contextLevel: "full"нужен, чтобы получать путь текущей страницы. У слота нет сущности, поэтому на уровнеbasicконтекст слота пуст.
4. Контекст слота
Плагин получает контекст через slotContext. Тип контекста:
export type DockSlotContext = {
/** Путь текущей страницы Трекера, например `/STARTREK-1234` или `/boards/42` */
path: string;
};
Контекст обновляется при каждом переходе пользователя по Трекеру: Трекер отправляет событие context.changed, а хук useTrackerPluginContext возвращает новое значение. Так плагин, открытый в панели, может реагировать на то, какой тикет или доска сейчас на экране.
Получить контекст в коде:
import { useTrackerPluginContext } from '@weavix/tracker-plugin-sdk-react';
const ISSUE_PATH = /^\/([A-Za-z0-9]{2,25}-\d+)(?:\/|$)/;
function App() {
const { slotContext } = useTrackerPluginContext<'dock'>('full');
const issueKey = slotContext?.path.match(ISSUE_PATH)?.[1];
return issueKey ? <IssueChat issueKey={issueKey} /> : <TeamChat />;
}
Данные самой сущности в контекст не входят — запрашивайте их через API Трекера по ключу из пути.
5. Размер панели
Плагин занимает всю высоту панели, поэтому автоматическое изменение высоты для этого слота не применяется. Ширину панели плагин может предложить через hostApi.updateContentSize в пикселях:
await hostApi.updateContentSize({ width: 640 });
Трекер применяет предложенную ширину, пока пользователь сам не изменил ширину панели: сохранённая пользователем ширина имеет приоритет. Значение ограничивается диапазоном 320–1200 px.
6. Закрытие панели из плагина
Вызов hostApi.close() закрывает панель так же, как кнопка закрытия. Плагин при этом остаётся загруженным и откроется в том же состоянии. Payload закрытия для этого слота не определён.