chore: remove /dev/diagram test page
No longer needed — the ProcessDiagram is now integrated into ExchangeDetail via the ExecutionDiagram wrapper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,131 +0,0 @@
|
|||||||
.page {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 16px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
color: var(--text-primary, #1A1612);
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls select {
|
|
||||||
padding: 6px 10px;
|
|
||||||
border: 1px solid var(--border, #E4DFD8);
|
|
||||||
border-radius: var(--radius-sm, 5px);
|
|
||||||
background: var(--bg-surface, #FFFFFF);
|
|
||||||
color: var(--text-primary, #1A1612);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.diagramPane {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholder {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
min-height: 400px;
|
|
||||||
border: 1px dashed var(--border, #E4DFD8);
|
|
||||||
border-radius: var(--radius-md, 8px);
|
|
||||||
color: var(--text-muted, #9C9184);
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidePanel {
|
|
||||||
width: 280px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: 12px;
|
|
||||||
border: 1px solid var(--border, #E4DFD8);
|
|
||||||
border-radius: var(--radius-md, 8px);
|
|
||||||
background: var(--bg-surface, #FFFFFF);
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidePanel h3 {
|
|
||||||
margin: 0 0 8px;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--text-secondary, #5C5347);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nodeInfo {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fieldLabel {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-muted, #9C9184);
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field code, .field pre {
|
|
||||||
font-family: var(--font-mono, monospace);
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--text-primary, #1A1612);
|
|
||||||
background: var(--bg-inset, #F0EDE8);
|
|
||||||
padding: 4px 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint {
|
|
||||||
color: var(--text-muted, #9C9184);
|
|
||||||
font-size: 12px;
|
|
||||||
font-style: italic;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 2px;
|
|
||||||
max-height: 200px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logEntry {
|
|
||||||
font-family: var(--font-mono, monospace);
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--text-secondary, #5C5347);
|
|
||||||
padding: 2px 0;
|
|
||||||
border-bottom: 1px solid var(--border-subtle, #EDE9E3);
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
import { useMemo, useState } from 'react';
|
|
||||||
import { useGlobalFilters } from '@cameleer/design-system';
|
|
||||||
import { ProcessDiagram } from '../../components/ProcessDiagram';
|
|
||||||
import type { NodeConfig, NodeAction } from '../../components/ProcessDiagram';
|
|
||||||
import { useRouteCatalog } from '../../api/queries/catalog';
|
|
||||||
import styles from './DevDiagram.module.css';
|
|
||||||
|
|
||||||
export default function DevDiagram() {
|
|
||||||
const { timeRange } = useGlobalFilters();
|
|
||||||
const { data: catalog } = useRouteCatalog(
|
|
||||||
timeRange.start.toISOString(),
|
|
||||||
timeRange.end.toISOString(),
|
|
||||||
);
|
|
||||||
|
|
||||||
const [selectedApp, setSelectedApp] = useState('');
|
|
||||||
const [selectedRoute, setSelectedRoute] = useState('');
|
|
||||||
const [selectedNodeId, setSelectedNodeId] = useState('');
|
|
||||||
const [direction, setDirection] = useState<'LR' | 'TB'>('LR');
|
|
||||||
const [actionLog, setActionLog] = useState<string[]>([]);
|
|
||||||
|
|
||||||
// Extract applications and routes from catalog
|
|
||||||
// Catalog shape: Array<{ appId, routes: [{ routeId }] }>
|
|
||||||
const { apps, routes } = useMemo(() => {
|
|
||||||
if (!catalog) return { apps: [] as string[], routes: [] as string[] };
|
|
||||||
const appArr = (catalog as Array<{ appId: string; routes?: Array<{ routeId: string }> }>)
|
|
||||||
.map(a => a.appId)
|
|
||||||
.sort();
|
|
||||||
const filtered = selectedApp
|
|
||||||
? (catalog as Array<{ appId: string; routes?: Array<{ routeId: string }> }>)
|
|
||||||
.filter(a => a.appId === selectedApp)
|
|
||||||
.flatMap(a => (a.routes || []).map(r => r.routeId))
|
|
||||||
: [];
|
|
||||||
return { apps: appArr, routes: filtered };
|
|
||||||
}, [catalog, selectedApp]);
|
|
||||||
|
|
||||||
// All route IDs for the selected app (for drill-down resolution)
|
|
||||||
const knownRouteIds = useMemo(() => {
|
|
||||||
if (!catalog || !selectedApp) return new Set<string>();
|
|
||||||
const app = (catalog as Array<{ appId: string; routes?: Array<{ routeId: string }> }>)
|
|
||||||
.find(a => a.appId === selectedApp);
|
|
||||||
return new Set((app?.routes ?? []).map(r => r.routeId));
|
|
||||||
}, [catalog, selectedApp]);
|
|
||||||
|
|
||||||
// Mock node configs for testing
|
|
||||||
const nodeConfigs = useMemo(() => {
|
|
||||||
const map = new Map<string, NodeConfig>();
|
|
||||||
// We'll add some mock configs if we have a route loaded
|
|
||||||
map.set('log1', { traceEnabled: true });
|
|
||||||
map.set('to1', { tapExpression: '${header.orderId}' });
|
|
||||||
return map;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleNodeAction = (nodeId: string, action: NodeAction) => {
|
|
||||||
const msg = `[${new Date().toLocaleTimeString()}] ${action}: ${nodeId}`;
|
|
||||||
setActionLog(prev => [msg, ...prev.slice(0, 19)]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.page}>
|
|
||||||
<div className={styles.header}>
|
|
||||||
<h2>Process Diagram (Dev)</h2>
|
|
||||||
<div className={styles.controls}>
|
|
||||||
<select
|
|
||||||
value={selectedApp}
|
|
||||||
onChange={e => { setSelectedApp(e.target.value); setSelectedRoute(''); }}
|
|
||||||
>
|
|
||||||
<option value="">Select application...</option>
|
|
||||||
{apps.map(app => <option key={app} value={app}>{app}</option>)}
|
|
||||||
</select>
|
|
||||||
<select
|
|
||||||
value={selectedRoute}
|
|
||||||
onChange={e => setSelectedRoute(e.target.value)}
|
|
||||||
disabled={!selectedApp}
|
|
||||||
>
|
|
||||||
<option value="">Select route...</option>
|
|
||||||
{routes.map(r => <option key={r} value={r}>{r}</option>)}
|
|
||||||
</select>
|
|
||||||
<select value={direction} onChange={e => setDirection(e.target.value as 'LR' | 'TB')}>
|
|
||||||
<option value="LR">Left → Right</option>
|
|
||||||
<option value="TB">Top → Bottom</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.content}>
|
|
||||||
<div className={styles.diagramPane}>
|
|
||||||
{selectedApp && selectedRoute ? (
|
|
||||||
<ProcessDiagram
|
|
||||||
application={selectedApp}
|
|
||||||
routeId={selectedRoute}
|
|
||||||
direction={direction}
|
|
||||||
selectedNodeId={selectedNodeId}
|
|
||||||
onNodeSelect={setSelectedNodeId}
|
|
||||||
onNodeAction={handleNodeAction}
|
|
||||||
nodeConfigs={nodeConfigs}
|
|
||||||
knownRouteIds={knownRouteIds}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className={styles.placeholder}>
|
|
||||||
Select an application and route to view the diagram
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.sidePanel}>
|
|
||||||
<h3>Selected Node</h3>
|
|
||||||
{selectedNodeId ? (
|
|
||||||
<div className={styles.nodeInfo}>
|
|
||||||
<div className={styles.field}>
|
|
||||||
<span className={styles.fieldLabel}>Node ID</span>
|
|
||||||
<code>{selectedNodeId}</code>
|
|
||||||
</div>
|
|
||||||
{nodeConfigs.has(selectedNodeId) && (
|
|
||||||
<div className={styles.field}>
|
|
||||||
<span className={styles.fieldLabel}>Config</span>
|
|
||||||
<pre>{JSON.stringify(nodeConfigs.get(selectedNodeId), null, 2)}</pre>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<p className={styles.hint}>Click a node to inspect it</p>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<h3>Action Log</h3>
|
|
||||||
<div className={styles.log}>
|
|
||||||
{actionLog.length === 0 ? (
|
|
||||||
<p className={styles.hint}>Hover a node and use the toolbar</p>
|
|
||||||
) : (
|
|
||||||
actionLog.map((msg, i) => (
|
|
||||||
<div key={i} className={styles.logEntry}>{msg}</div>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,6 @@ const DatabaseAdminPage = lazy(() => import('./pages/Admin/DatabaseAdminPage'));
|
|||||||
const OpenSearchAdminPage = lazy(() => import('./pages/Admin/OpenSearchAdminPage'));
|
const OpenSearchAdminPage = lazy(() => import('./pages/Admin/OpenSearchAdminPage'));
|
||||||
const AppConfigPage = lazy(() => import('./pages/Admin/AppConfigPage'));
|
const AppConfigPage = lazy(() => import('./pages/Admin/AppConfigPage'));
|
||||||
const SwaggerPage = lazy(() => import('./pages/Swagger/SwaggerPage'));
|
const SwaggerPage = lazy(() => import('./pages/Swagger/SwaggerPage'));
|
||||||
const DevDiagram = lazy(() => import('./pages/DevDiagram/DevDiagram'));
|
|
||||||
|
|
||||||
function SuspenseWrapper({ children }: { children: React.ReactNode }) {
|
function SuspenseWrapper({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
@@ -64,7 +63,6 @@ export const router = createBrowserRouter([
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ path: 'api-docs', element: <SuspenseWrapper><SwaggerPage /></SuspenseWrapper> },
|
{ path: 'api-docs', element: <SuspenseWrapper><SwaggerPage /></SuspenseWrapper> },
|
||||||
{ path: 'dev/diagram', element: <SuspenseWrapper><DevDiagram /></SuspenseWrapper> },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user