- React 18 + TypeScript strict + AntV X6 2.x + AntD 5 + Zustand - Custom nodes: SiteNode, CrossDeviceNode, SpliceNode, DeviceNode, CardNode - 8-слойный автолейаут, порты (left/right), линии с цветами по статусу - Toolbar, дерево навигации, карточка объекта, таблица соединений - Контекстные меню, легенда, drag линий/нод, создание линий из портов - Моковые данные: 3 сайта, 10 устройств, 15 линий Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import type { Node } from '@antv/x6';
|
|
import { STATUS_COLORS } from '../../../constants/statusColors.ts';
|
|
import { SPLICE_BORDER_RADIUS } from '../../../constants/sizes.ts';
|
|
import type { EntityStatus } from '../../../types/index.ts';
|
|
|
|
interface SpliceNodeData {
|
|
name: string;
|
|
marking: string;
|
|
id1: string;
|
|
id2: string;
|
|
status: EntityStatus;
|
|
}
|
|
|
|
export function SpliceNode({ node }: { node: Node }) {
|
|
const data = node.getData() as SpliceNodeData;
|
|
const colors = STATUS_COLORS[data.status];
|
|
const size = node.getSize();
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
width: size.width,
|
|
height: size.height,
|
|
border: `1px solid ${colors.border}`,
|
|
borderRadius: SPLICE_BORDER_RADIUS,
|
|
background: colors.fill,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
boxSizing: 'border-box',
|
|
textAlign: 'center',
|
|
padding: 4,
|
|
fontSize: 10,
|
|
lineHeight: '14px',
|
|
}}
|
|
>
|
|
<div style={{ fontWeight: 700, fontSize: 11, marginBottom: 2, wordBreak: 'break-word' }}>
|
|
{data.name}
|
|
</div>
|
|
{data.marking && (
|
|
<div style={{ color: '#595959', fontSize: 9 }}>{data.marking}</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|