Files
Portal-Chart-Builder/src/HelpPanel.tsx
T

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>
);
}