183 lines
9.8 KiB
TypeScript
183 lines
9.8 KiB
TypeScript
import { Text } from "@consta/uikit/Text";
|
|
|
|
/** Раздел справки: заголовок + список строк «что» → «как». */
|
|
interface HelpSection {
|
|
title: string;
|
|
rows: { term: string; description: string }[];
|
|
}
|
|
|
|
const EDIT_SECTIONS: HelpSection[] = [
|
|
{
|
|
title: "Работа со схемой",
|
|
rows: [
|
|
{
|
|
term: "Выбор и редактирование",
|
|
description:
|
|
"Клик по фигуре или связи — справа откроется панель со свойствами: название, описание, цвет, размер текста. Закрыть панель — стрелкой в её углу или кликом по свободному месту холста.",
|
|
},
|
|
{
|
|
term: "Добавление",
|
|
description:
|
|
"Кнопка «Добавить элемент» слева сверху — фигура появится в центре видимой области.",
|
|
},
|
|
{
|
|
term: "Соединение фигур",
|
|
description:
|
|
"Навести курсор на фигуру и потянуть от точки на её границе к другой фигуре. Точка есть с каждой из четырёх сторон.",
|
|
},
|
|
{
|
|
term: "Вложенные процессы",
|
|
description:
|
|
"Выбрать действие и нажать «Войти в под-процесс →» в боковой панели — внутри можно собрать детальную схему этого шага. Вернуться на уровень выше — через «хлебные крошки» сверху (они появляются, когда боковая панель закрыта). У фигур с вложением есть значок ⇒.",
|
|
},
|
|
{
|
|
term: "Выравнивание",
|
|
description:
|
|
"При перетаскивании фигура сама примагничивается к центрам соседних по горизонтали и вертикали — по линиям видно, к чему именно.",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Горячие клавиши",
|
|
rows: [
|
|
{ term: "Ctrl + Z", description: "Отменить последнее действие" },
|
|
{
|
|
term: "Ctrl + C / Ctrl + V",
|
|
description: "Копировать и вставить выбранную фигуру",
|
|
},
|
|
{ term: "Delete", description: "Удалить выбранную фигуру или связь" },
|
|
],
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Режим просмотра — только то, что в нём действительно доступно: фигуры
|
|
* нельзя двигать, создавать, соединять и удалять, горячие клавиши и
|
|
* отмена отключены, связи не выделяются. Поэтому здесь нет ни слова про
|
|
* перетаскивание, добавление и правку — иначе справка обещала бы то,
|
|
* чего в этом режиме нет.
|
|
*/
|
|
const VIEW_SECTIONS: HelpSection[] = [
|
|
{
|
|
title: "Просмотр схемы",
|
|
rows: [
|
|
{
|
|
term: "Описание шага",
|
|
description:
|
|
"Клик по фигуре — справа откроется панель с её названием, описанием, ответственным и длительностью, если они заданы. Закрыть панель — стрелкой в её углу или кликом по свободному месту холста.",
|
|
},
|
|
{
|
|
term: "Вложенные процессы",
|
|
description:
|
|
"У фигур со значком ⇒ внутри есть своя схема: выберите такую фигуру и нажмите «Открыть вложенный процесс →». Вернуться на уровень выше — через «хлебные крошки» сверху (они видны, когда боковая панель закрыта).",
|
|
},
|
|
{
|
|
term: "Масштаб и навигация",
|
|
description:
|
|
"Кнопки «+» и «−» в панели слева внизу, либо колесо мыши. Кнопка «⛶» вписывает всю схему в экран. Чтобы сдвинуть схему, зажмите пустое место холста и ведите мышью.",
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const NOTATION_SECTION: HelpSection = {
|
|
title: "Элементы нотации BPMN",
|
|
rows: [
|
|
{
|
|
term: "Действие (Task)",
|
|
description:
|
|
"Шаг процесса — то, что делается. Подтип задаёт характер работы: пользователем, сервисом, скриптом, вручную, по бизнес-правилам, отправка или получение сообщения.",
|
|
},
|
|
{
|
|
term: "События (Event)",
|
|
description:
|
|
"Круги: начальное — с чего процесс стартует, промежуточное — что происходит по ходу, конечное — чем завершается. Иконка внутри показывает триггер: сообщение, таймер, условие, сигнал, ошибка и другие. Для каждого вида события доступны только допустимые триггеры.",
|
|
},
|
|
{
|
|
term: "Шлюзы (Gateway)",
|
|
description:
|
|
"Ромбы — точки ветвления. XOR (✕): ровно один путь из нескольких. AND (+): все пути одновременно. OR (○): один или несколько сразу. Сложный: нестандартная логика, описывается текстом. По событию: путь выбирается тем, какое событие произойдёт первым.",
|
|
},
|
|
{
|
|
term: "Документ (Data Object)",
|
|
description:
|
|
"Вход или выход шага — документ, файл, данные. Соединяется с действием пунктирной линией (это связь данных, а не поток управления).",
|
|
},
|
|
{
|
|
term: "Подсказка",
|
|
description:
|
|
"Не элемент нотации, а поясняющая заметка: цветной блок с текстом, который размещается рядом с фигурами. Связи к нему не подключаются.",
|
|
},
|
|
],
|
|
};
|
|
|
|
interface HelpPanelProps {
|
|
mode: "edit" | "view";
|
|
/**
|
|
* Можно ли вернуться к редактированию кнопкой с карандашом. Когда режим
|
|
* зафиксирован хостом (`?mode=view`), кнопки нет — и обещать её нельзя.
|
|
*/
|
|
canSwitchMode: boolean;
|
|
}
|
|
|
|
/**
|
|
* Справка — выпадающая панель под кнопкой «?», а не модалка во весь экран:
|
|
* приложение живёт внутри iframe на странице портала, и оверлей на весь
|
|
* viewport перекрыл бы только сам iframe, выглядя оторванным от страницы.
|
|
* Рендерится обычным потоком внутри Panel холста, без портала в body —
|
|
* так панель гарантированно остаётся в границах приложения.
|
|
*/
|
|
export function HelpPanel({ mode, canSwitchMode }: HelpPanelProps) {
|
|
const modeSections = mode === "edit" ? EDIT_SECTIONS : VIEW_SECTIONS;
|
|
|
|
// Про режимы рассказываем только в редактировании — там это осмысленный
|
|
// переход «сейчас правлю, хочу посмотреть». В просмотре не рассказываем
|
|
// вовсе: читателю схемы незачем знать про режим редактирования, а когда
|
|
// просмотр зафиксирован хостом (`?mode=view`), выйти из него и нельзя.
|
|
const modeSwitchSection: HelpSection[] =
|
|
mode === "edit" && canSwitchMode ?
|
|
[
|
|
{
|
|
title: "Режимы",
|
|
rows: [
|
|
{
|
|
term: "Перейти к просмотру",
|
|
description:
|
|
"Кнопка с глазом в панели слева внизу — схема станет только для чтения: фигуры нельзя двигать, создавать и удалять.",
|
|
},
|
|
],
|
|
},
|
|
]
|
|
: [];
|
|
|
|
const sections = [...modeSections, ...modeSwitchSection, NOTATION_SECTION];
|
|
|
|
return (
|
|
<div className="help-panel">
|
|
{sections.map((section) => (
|
|
<div key={section.title} className="help-panel__section">
|
|
<Text size="xs" weight="semibold" className="help-panel__section-title">
|
|
{section.title}
|
|
</Text>
|
|
<dl className="help-panel__list">
|
|
{section.rows.map((row) => (
|
|
<div key={row.term} className="help-panel__row">
|
|
<dt>
|
|
<Text size="2xs" weight="semibold">
|
|
{row.term}
|
|
</Text>
|
|
</dt>
|
|
<dd>
|
|
<Text size="2xs" view="secondary">
|
|
{row.description}
|
|
</Text>
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|