Сделал элементы согласно нотации, убрал хэш при билде

This commit is contained in:
NikitaKalitov
2026-07-28 14:03:16 +03:00
parent 99d48f393a
commit 33939dffaf
7 changed files with 767 additions and 208 deletions
+111 -21
View File
@@ -10,8 +10,24 @@ import {
DEFAULT_NODE_FONT_SIZE,
DEFAULT_NODE_TEXT_COLOR,
DEFAULT_TASK_BORDER_RADIUS,
EVENT_SUBTYPE_ICON,
EVENT_SUBTYPE_LABEL,
EVENT_SUBTYPES_BY_KIND,
TASK_SUBTYPE_ICON,
TASK_SUBTYPE_LABEL,
} from "./nodes";
import type { DiagramNodeData, NodeKind } from "./types";
import type { DiagramNodeData, EventSubtype, NodeKind, TaskSubtype } from "./types";
const TASK_SUBTYPES: TaskSubtype[] = [
"none",
"user",
"service",
"script",
"manual",
"businessRule",
"send",
"receive",
];
// Every gradient defined in palette.css, across its three "for diagrams /
// flowcharts / semantic highlights" sections. Consta's ColorPicker `palette`
@@ -48,15 +64,21 @@ const TEXT_COLOR_PRESETS: { hex: string; label: string }[] = [
];
const TYPE_LABELS: Record<NodeKind, string> = {
task: "Задача",
startEvent: "Начальное событие",
intermediateEvent: "Промежуточное событие",
endEvent: "Конечное событие",
exclusiveGateway: "Исключающий шлюз",
parallelGateway: "Параллельный шлюз",
inclusiveGateway: "Включающий шлюз",
task: "Действие (Task)",
startEvent: "Начальное событие (Start Event)",
intermediateEvent: "Промежуточное событие (Intermediate Event)",
endEvent: "Конечное событие (End Event)",
exclusiveGateway: "Исключающий шлюз (XOR)",
parallelGateway: "Параллельный шлюз (AND)",
inclusiveGateway: "Включающий шлюз (OR)",
complexGateway: "Сложный шлюз (Complex)",
eventBasedGateway: "Шлюз на основе событий (Event-based)",
hint: "Подсказка",
dataObject: "Документ (Data Object)",
};
const EVENT_KINDS = new Set<NodeKind>(["startEvent", "intermediateEvent", "endEvent"]);
interface NodeInspectorProps {
nodeId: string;
nodeType: NodeKind;
@@ -109,6 +131,12 @@ export function NodeInspector({
if (mode === "view") {
const hasMeta = Boolean(data.responsible || data.duration);
const subtypeLabel =
nodeType === "task"
? TASK_SUBTYPE_LABEL[(data.subtype as TaskSubtype | undefined) ?? "none"]
: EVENT_KINDS.has(nodeType)
? EVENT_SUBTYPE_LABEL[(data.subtype as EventSubtype | undefined) ?? "none"]
: undefined;
return (
<div className="node-inspector">
<div className="node-inspector__header">
@@ -117,6 +145,12 @@ export function NodeInspector({
</Text>
</div>
{subtypeLabel && (
<Text size="xs" view="secondary">
{subtypeLabel}
</Text>
)}
<Text size="l" className="node-inspector__label">
{data.label}
</Text>
@@ -196,6 +230,60 @@ export function NodeInspector({
/>
</div>
{nodeType === "task" && (
<div className="node-inspector__field">
<Text size="xs" view="secondary">
Тип задачи
</Text>
<div className="node-inspector__presets">
{TASK_SUBTYPES.map((subtype) => {
const Icon = TASK_SUBTYPE_ICON[subtype];
const isActive = (data.subtype ?? "none") === subtype;
return (
<button
key={subtype}
type="button"
title={TASK_SUBTYPE_LABEL[subtype]}
aria-label={TASK_SUBTYPE_LABEL[subtype]}
className={`node-inspector__subtype${isActive ? " node-inspector__subtype--active" : ""}`}
onClick={() => onChange({ subtype })}
>
{Icon ? <Icon size="s" /> : <Text size="xs">—</Text>}
</button>
);
})}
</div>
</div>
)}
{EVENT_KINDS.has(nodeType) && (
<div className="node-inspector__field">
<Text size="xs" view="secondary">
Тип триггера
</Text>
<div className="node-inspector__presets">
{EVENT_SUBTYPES_BY_KIND[nodeType as "startEvent" | "intermediateEvent" | "endEvent"].map(
(subtype: EventSubtype) => {
const Icon = EVENT_SUBTYPE_ICON[subtype];
const isActive = (data.subtype ?? "none") === subtype;
return (
<button
key={subtype}
type="button"
title={EVENT_SUBTYPE_LABEL[subtype]}
aria-label={EVENT_SUBTYPE_LABEL[subtype]}
className={`node-inspector__subtype${isActive ? " node-inspector__subtype--active" : ""}`}
onClick={() => onChange({ subtype })}
>
{Icon ? <Icon size="s" /> : <Text size="xs">—</Text>}
</button>
);
},
)}
</div>
</div>
)}
<div className="node-inspector__field">
<Text size="xs" view="secondary">
Цвет фона
@@ -306,6 +394,21 @@ export function NodeInspector({
onChange={(value) => onChange({ description: value ?? "" })}
/>
{(nodeType === "task" || nodeType === "hint") && (
<TextField
label="Скругление углов"
type="number"
size="s"
min={0}
max={25}
value={String(data.borderRadius ?? DEFAULT_TASK_BORDER_RADIUS)}
onChange={(value) => {
const n = Number(value);
if (value && !Number.isNaN(n)) onChange({ borderRadius: n });
}}
/>
)}
{nodeType === "task" && (
<>
<TextField
@@ -322,19 +425,6 @@ export function NodeInspector({
onChange={(value) => onChange({ duration: value ?? "" })}
/>
<TextField
label="Скругление углов"
type="number"
size="s"
min={0}
max={25}
value={String(data.borderRadius ?? DEFAULT_TASK_BORDER_RADIUS)}
onChange={(value) => {
const n = Number(value);
if (value && !Number.isNaN(n)) onChange({ borderRadius: n });
}}
/>
<Button
size="s"
view="ghost"