feat(web/mazenet): polish editor UX

Canvas grew a deployed prop so nodes can visually distinguish "live in
docker" from "planned". ContextMenu learned nested submenus with
ChevronRight affordance; NetBox renders a ShieldAlert for DMZ LANs;
Palette got additional lucide icons. Dead PendingChange union pulled
out of types.ts — Phase-3 mutation ops are driven by the API layer now,
not a frontend type.
This commit is contained in:
2026-04-21 10:24:32 -04:00
parent 59d618d25f
commit 4727ea0af2
7 changed files with 115 additions and 74 deletions

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { Globe, GitMerge } from 'lucide-react';
import { Globe, GitMerge, ShieldAlert } from 'lucide-react';
import type { Net } from './types';
import type { ResizeHandle } from './useMazeInteraction';
@@ -8,6 +8,7 @@ interface Props {
selected: boolean;
dropTarget: boolean;
inactive: boolean;
deployed?: boolean;
onSelect?: (id: string) => void;
onHeaderMouseDown?: (id: string) => (e: React.MouseEvent) => void;
onResizeMouseDown?: (id: string, handle: ResizeHandle) => (e: React.MouseEvent) => void;
@@ -16,17 +17,19 @@ interface Props {
}
const NetBox: React.FC<Props> = ({
net, selected, dropTarget, inactive, onSelect, onHeaderMouseDown, onResizeMouseDown, onContextMenu, children,
net, selected, dropTarget, inactive, deployed, onSelect, onHeaderMouseDown, onResizeMouseDown, onContextMenu, children,
}) => {
const classes = [
'maze-net-box',
net.kind === 'internet' ? 'internet' : '',
net.kind === 'dmz' ? 'dmz' : '',
selected ? 'selected' : '',
dropTarget ? 'drop-target' : '',
inactive ? 'inactive' : '',
deployed ? 'deployed' : '',
].filter(Boolean).join(' ');
const Icon = net.kind === 'internet' ? Globe : GitMerge;
const Icon = net.kind === 'internet' ? Globe : net.kind === 'dmz' ? ShieldAlert : GitMerge;
const resizable = net.kind !== 'internet';
const handleBoxDown = (e: React.MouseEvent) => {