polish(network): visual refinements across node, edge, and panel components

- DeviceNode: flat bg-card (no surface gradient), darker icon plate inset,
  correct text-muted token for category label
- GroupNode: label pill gets bg-card/90 background so it reads against canvas
- ConnectionEdge: label now has border + bg-card so it doesn't float invisible
- BaseHandle: tightened to 12px with accent-toned border
- NodeStatusIndicator: glow reduced to 0.15 opacity (design system compliant)
- ContextMenu: Ungroup now uses Ungroup icon instead of BoxSelect
- DeviceToolbar: group type icons coloured with semantic palette
- PropertiesPanel: empty state gets icon tile + cleaner copy hierarchy
- DiagramEditor: shortcut ? button repositioned above MiniMap, accent hover
- NetworkDiagrams list: card thumbnail placeholder uses dot-grid pattern,
  card menu gets icons and divider before destructive action

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #139.
This commit is contained in:
chihlasm
2026-04-14 05:35:25 +00:00
parent 015df1fe5f
commit b433b232dc
10 changed files with 48 additions and 33 deletions

View File

@@ -853,11 +853,11 @@ function DiagramEditorInner() {
{nodes.length === 0 && !loading && (
<CanvasEmptyPrompt onGenerate={handleAIGenerate} />
)}
{/* Keyboard shortcut hint button — bottom-right corner */}
{/* Keyboard shortcut hint button — above the MiniMap */}
<button
onClick={() => setShowShortcuts(true)}
title="Keyboard shortcuts (?)"
className="absolute bottom-4 right-4 z-10 flex h-7 w-7 items-center justify-center rounded-full border border-default bg-card text-[11px] font-semibold text-muted-foreground hover:border-hover hover:text-primary"
className="absolute bottom-[175px] right-3 z-10 flex h-6 w-6 items-center justify-center rounded-full border border-default bg-card text-[11px] font-semibold text-muted-foreground hover:border-accent hover:text-accent transition-colors"
>
?
</button>

View File

@@ -1,6 +1,6 @@
import { useState, useEffect, useCallback, useMemo, useRef } from 'react'
import { useNavigate } from 'react-router-dom'
import { Plus, Search, Network, MoreHorizontal, Upload, ChevronDown, FileJson, FileOutput } from 'lucide-react'
import { Plus, Search, Network, MoreHorizontal, Upload, ChevronDown, FileJson, FileOutput, ExternalLink, Copy, Archive } from 'lucide-react'
import { cn } from '@/lib/utils'
import { networkDiagramsApi } from '@/api'
import { toast } from '@/lib/toast'
@@ -444,8 +444,16 @@ export default function NetworkDiagramsPage() {
/>
</div>
) : (
<div className="mb-2 flex h-[120px] items-center justify-center rounded border border-default bg-elevated">
<Network size={32} className="text-muted-foreground/30" />
<div className="relative mb-2 flex h-[120px] items-center justify-center overflow-hidden rounded border border-default bg-[#0e1016]">
<svg className="absolute inset-0 h-full w-full opacity-30" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id={`dots-${d.id}`} x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="0.8" fill="#4f5666" />
</pattern>
</defs>
<rect width="100%" height="100%" fill={`url(#dots-${d.id})`} />
</svg>
<Network size={24} className="relative text-muted-foreground/20" />
</div>
)}
{d.node_count > 0 && (
@@ -482,20 +490,24 @@ export default function NetworkDiagramsPage() {
<>
<button
onClick={e => { e.stopPropagation(); navigate(`/network-diagrams/${d.id}`) }}
className="w-full px-3 py-1.5 text-left text-xs text-primary hover:bg-elevated"
className="flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-primary hover:bg-elevated"
>
<ExternalLink size={12} className="text-muted-foreground" />
Open
</button>
<button
onClick={e => { e.stopPropagation(); handleDuplicate(d.id) }}
className="w-full px-3 py-1.5 text-left text-xs text-primary hover:bg-elevated"
className="flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-primary hover:bg-elevated"
>
<Copy size={12} className="text-muted-foreground" />
Duplicate
</button>
<div className="my-1 border-t border-default" />
<button
onClick={e => { e.stopPropagation(); setConfirmArchiveId(d.id) }}
className="w-full px-3 py-1.5 text-left text-xs text-red-400 hover:bg-elevated"
className="flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-red-400 hover:bg-elevated"
>
<Archive size={12} />
Archive
</button>
</>