Skip to content

Commit 3bc7e9e

Browse files
committed
Refine Flow mockups and route loading
1 parent 006fa09 commit 3bc7e9e

2 files changed

Lines changed: 81 additions & 72 deletions

File tree

web/src/App.tsx

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
import { useCallback, useState } from 'react';
1+
import { Suspense, lazy, useCallback, useState } from 'react';
22
import { Routes, Route } from 'react-router-dom';
33
import { Menu } from 'lucide-react';
44
import { useAuth } from './hooks/useAuth';
55
import Sidebar from './components/Sidebar';
66
import CommandPalette from './components/CommandPalette';
77
import ErrorBoundary from './components/ErrorBoundary';
88
import Login from './pages/Login';
9-
import Dashboard from './pages/Dashboard';
10-
import Catalog from './pages/Catalog';
11-
import EntityDetail from './pages/EntityDetail';
12-
import Actions from './pages/Actions';
13-
import AuditLog from './pages/AuditLog';
14-
import Settings from './pages/Settings';
15-
import UsersPage from './pages/Users';
16-
import Plugins from './pages/Plugins';
17-
import StatusMonitor from './pages/StatusMonitor';
18-
import GitOps from './pages/GitOps';
19-
import Harbor from './pages/Harbor';
20-
import Nexus from './pages/Nexus';
21-
import RBAC from './pages/RBAC';
22-
import TopologyExplorer from './pages/TopologyExplorer';
23-
import Flow from './pages/Flow';
9+
const Dashboard = lazy(() => import('./pages/Dashboard'));
10+
const Catalog = lazy(() => import('./pages/Catalog'));
11+
const EntityDetail = lazy(() => import('./pages/EntityDetail'));
12+
const Actions = lazy(() => import('./pages/Actions'));
13+
const AuditLog = lazy(() => import('./pages/AuditLog'));
14+
const Settings = lazy(() => import('./pages/Settings'));
15+
const UsersPage = lazy(() => import('./pages/Users'));
16+
const Plugins = lazy(() => import('./pages/Plugins'));
17+
const StatusMonitor = lazy(() => import('./pages/StatusMonitor'));
18+
const GitOps = lazy(() => import('./pages/GitOps'));
19+
const Harbor = lazy(() => import('./pages/Harbor'));
20+
const Nexus = lazy(() => import('./pages/Nexus'));
21+
const RBAC = lazy(() => import('./pages/RBAC'));
22+
const TopologyExplorer = lazy(() => import('./pages/TopologyExplorer'));
23+
const Flow = lazy(() => import('./pages/Flow'));
2424

2525

2626
function AuthenticatedLayout() {
@@ -41,30 +41,32 @@ function AuthenticatedLayout() {
4141
</button>
4242
</div>
4343
<ErrorBoundary>
44-
<Routes>
45-
<Route path="/flow" element={<div className="px-4 py-6 sm:px-6 sm:py-8"><Flow /></div>} />
46-
<Route path="/topology" element={<div className="px-4 py-6 sm:px-6 sm:py-8"><TopologyExplorer /></div>} />
47-
<Route path="/users" element={<div className="px-4 py-6 sm:px-6 sm:py-8"><UsersPage /></div>} />
48-
<Route path="*" element={
49-
<div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 sm:py-8">
50-
<Routes>
51-
<Route path="/" element={<Dashboard />} />
52-
<Route path="/catalog" element={<Catalog />} />
53-
<Route path="/catalog/:kind" element={<Catalog />} />
54-
<Route path="/catalog/:kind/:name" element={<EntityDetail />} />
55-
<Route path="/actions" element={<Actions />} />
56-
<Route path="/audit" element={<AuditLog />} />
57-
<Route path="/plugins" element={<Plugins />} />
58-
<Route path="/status" element={<StatusMonitor />} />
59-
<Route path="/gitops" element={<GitOps />} />
60-
<Route path="/harbor" element={<Harbor />} />
61-
<Route path="/nexus" element={<Nexus />} />
62-
<Route path="/rbac" element={<RBAC />} />
63-
<Route path="/settings" element={<Settings />} />
64-
</Routes>
65-
</div>
66-
} />
67-
</Routes>
44+
<Suspense fallback={<LoadingScreen />}>
45+
<Routes>
46+
<Route path="/flow" element={<div className="px-4 py-6 sm:px-6 sm:py-8"><Flow /></div>} />
47+
<Route path="/topology" element={<div className="px-4 py-6 sm:px-6 sm:py-8"><TopologyExplorer /></div>} />
48+
<Route path="/users" element={<div className="px-4 py-6 sm:px-6 sm:py-8"><UsersPage /></div>} />
49+
<Route path="*" element={
50+
<div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 sm:py-8">
51+
<Routes>
52+
<Route path="/" element={<Dashboard />} />
53+
<Route path="/catalog" element={<Catalog />} />
54+
<Route path="/catalog/:kind" element={<Catalog />} />
55+
<Route path="/catalog/:kind/:name" element={<EntityDetail />} />
56+
<Route path="/actions" element={<Actions />} />
57+
<Route path="/audit" element={<AuditLog />} />
58+
<Route path="/plugins" element={<Plugins />} />
59+
<Route path="/status" element={<StatusMonitor />} />
60+
<Route path="/gitops" element={<GitOps />} />
61+
<Route path="/harbor" element={<Harbor />} />
62+
<Route path="/nexus" element={<Nexus />} />
63+
<Route path="/rbac" element={<RBAC />} />
64+
<Route path="/settings" element={<Settings />} />
65+
</Routes>
66+
</div>
67+
} />
68+
</Routes>
69+
</Suspense>
6870
</ErrorBoundary>
6971
</main>
7072
<CommandPalette />

web/src/pages/Flow.tsx

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ export default function Flow() {
13441344
<div
13451345
key={node.id}
13461346
data-flow-node="true"
1347-
className={`absolute rounded-2xl shadow-sm transition-shadow ${
1347+
className={`group absolute rounded-2xl shadow-sm transition-shadow ${
13481348
active || connectSource ? 'shadow-lg' : 'hover:shadow-md'
13491349
}`}
13501350
style={nodeOuterStyle}
@@ -1447,10 +1447,17 @@ export default function Flow() {
14471447
startHeight: nodeSize.height,
14481448
});
14491449
}}
1450-
className="absolute bottom-1.5 right-1.5 h-4 w-4 cursor-se-resize rounded-sm border border-[var(--gantry-border)] bg-[var(--gantry-bg-primary)]/90 shadow-sm"
1450+
className={`absolute -bottom-2.5 -right-2.5 flex h-6 w-6 cursor-se-resize items-center justify-center rounded-full border shadow-lg transition-all ${
1451+
active
1452+
? 'border-[var(--gantry-accent)] bg-[var(--gantry-accent)] text-[var(--gantry-bg-primary)] opacity-100'
1453+
: 'border-[var(--gantry-border)] bg-[var(--gantry-bg-primary)] text-[var(--gantry-text-secondary)] opacity-0 group-hover:opacity-100'
1454+
}`}
14511455
title="Resize shape"
14521456
>
1453-
<span className="pointer-events-none absolute bottom-0.5 right-0.5 h-2 w-2 border-b border-r border-[var(--gantry-text-secondary)]" />
1457+
<span className="pointer-events-none relative block h-2.5 w-2.5">
1458+
<span className="absolute bottom-0 right-0 h-2.5 w-2.5 border-b-2 border-r-2 border-current" />
1459+
<span className="absolute bottom-0.5 right-0.5 h-1.5 w-1.5 border-b-2 border-r-2 border-current opacity-80" />
1460+
</span>
14541461
</button>
14551462
)}
14561463
</div>
@@ -1638,6 +1645,35 @@ export default function Flow() {
16381645
<section className="space-y-4">
16391646
{renderSavedFlowsCard()}
16401647

1648+
<div className="rounded-2xl border border-[var(--gantry-border)] bg-[var(--gantry-bg-primary)] p-4">
1649+
<div>
1650+
<h2 className="text-sm font-semibold text-[var(--gantry-text-primary)]">Add Mockups</h2>
1651+
<p className="mt-1 text-xs text-[var(--gantry-text-secondary)]">Use simple shapes for future systems, external actors, or rough architecture sketches.</p>
1652+
</div>
1653+
<div className="mt-4 space-y-2">
1654+
{MOCK_NODE_LIBRARY.map((template) => (
1655+
<button
1656+
key={`${template.shape}:${template.label}`}
1657+
onClick={() => addMockNode(template)}
1658+
className="flex w-full items-start justify-between rounded-xl border border-[var(--gantry-border)] bg-[var(--gantry-bg-secondary)] px-3 py-3 text-left transition-colors hover:bg-[var(--gantry-bg-tertiary)]"
1659+
>
1660+
<div>
1661+
<div className="text-sm font-medium text-[var(--gantry-text-primary)]">{template.label}</div>
1662+
<div className="mt-1 text-xs text-[var(--gantry-text-secondary)]">
1663+
{mockShapeLabel(template.shape)} · {template.subtitle}
1664+
</div>
1665+
</div>
1666+
<span
1667+
className="rounded-full px-2 py-0.5 text-[11px] font-medium"
1668+
style={{ backgroundColor: `${template.color}1A`, color: template.color }}
1669+
>
1670+
Add
1671+
</span>
1672+
</button>
1673+
))}
1674+
</div>
1675+
</div>
1676+
16411677
<div className="rounded-2xl border border-[var(--gantry-border)] bg-[var(--gantry-bg-primary)] p-4">
16421678
<div className="flex items-center justify-between gap-3">
16431679
<div>
@@ -1690,35 +1726,6 @@ export default function Flow() {
16901726
})}
16911727
</div>
16921728
</div>
1693-
1694-
<div className="rounded-2xl border border-[var(--gantry-border)] bg-[var(--gantry-bg-primary)] p-4">
1695-
<div>
1696-
<h2 className="text-sm font-semibold text-[var(--gantry-text-primary)]">Add Mockups</h2>
1697-
<p className="mt-1 text-xs text-[var(--gantry-text-secondary)]">Use simple shapes for future systems, external actors, or rough architecture sketches.</p>
1698-
</div>
1699-
<div className="mt-4 space-y-2">
1700-
{MOCK_NODE_LIBRARY.map((template) => (
1701-
<button
1702-
key={`${template.shape}:${template.label}`}
1703-
onClick={() => addMockNode(template)}
1704-
className="flex w-full items-start justify-between rounded-xl border border-[var(--gantry-border)] bg-[var(--gantry-bg-secondary)] px-3 py-3 text-left transition-colors hover:bg-[var(--gantry-bg-tertiary)]"
1705-
>
1706-
<div>
1707-
<div className="text-sm font-medium text-[var(--gantry-text-primary)]">{template.label}</div>
1708-
<div className="mt-1 text-xs text-[var(--gantry-text-secondary)]">
1709-
{mockShapeLabel(template.shape)} · {template.subtitle}
1710-
</div>
1711-
</div>
1712-
<span
1713-
className="rounded-full px-2 py-0.5 text-[11px] font-medium"
1714-
style={{ backgroundColor: `${template.color}1A`, color: template.color }}
1715-
>
1716-
Add
1717-
</span>
1718-
</button>
1719-
))}
1720-
</div>
1721-
</div>
17221729
</section>
17231730

17241731
<section className="space-y-4">

0 commit comments

Comments
 (0)