2026-03-24 17:05:06 +01:00
|
|
|
import { useState, useMemo, useCallback } from 'react';
|
2026-03-26 22:26:28 +01:00
|
|
|
import { useParams, useNavigate, useSearchParams, Link } from 'react-router';
|
2026-03-27 23:16:39 +01:00
|
|
|
import { Pencil, Trash2 } from 'lucide-react';
|
2026-03-23 18:25:58 +01:00
|
|
|
import {
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
KpiStrip,
|
|
|
|
|
Badge,
|
|
|
|
|
StatusDot,
|
|
|
|
|
DataTable,
|
2026-04-09 18:47:55 +02:00
|
|
|
EmptyState,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
Tabs,
|
2026-04-12 19:44:55 +02:00
|
|
|
ThemedChart,
|
|
|
|
|
Area,
|
|
|
|
|
Line,
|
|
|
|
|
Bar,
|
|
|
|
|
ReferenceLine,
|
|
|
|
|
CHART_COLORS,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
RouteFlow,
|
|
|
|
|
Spinner,
|
2026-03-23 18:25:58 +01:00
|
|
|
MonoText,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
Sparkline,
|
2026-03-26 18:44:06 +01:00
|
|
|
Toggle,
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
Button,
|
|
|
|
|
Modal,
|
|
|
|
|
FormField,
|
|
|
|
|
Input,
|
|
|
|
|
Select,
|
|
|
|
|
Textarea,
|
|
|
|
|
Collapsible,
|
|
|
|
|
ConfirmDialog,
|
2026-03-23 18:25:58 +01:00
|
|
|
} from '@cameleer/design-system';
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
import type { KpiItem, Column } from '@cameleer/design-system';
|
2026-03-23 18:25:58 +01:00
|
|
|
import { useGlobalFilters } from '@cameleer/design-system';
|
2026-04-08 23:43:14 +02:00
|
|
|
import { useCatalog } from '../../api/queries/catalog';
|
2026-03-23 18:25:58 +01:00
|
|
|
import { useDiagramByRoute } from '../../api/queries/diagrams';
|
|
|
|
|
import { useProcessorMetrics } from '../../api/queries/processor-metrics';
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
import { useStatsTimeseries, useSearchExecutions, useExecutionStats } from '../../api/queries/executions';
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
import { useApplicationConfig, useUpdateApplicationConfig, useTestExpression } from '../../api/queries/commands';
|
2026-04-09 16:01:50 +02:00
|
|
|
import { useEnvironmentStore } from '../../api/environment-store';
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
import type { TapDefinition } from '../../api/queries/commands';
|
2026-04-08 23:43:14 +02:00
|
|
|
import type { ExecutionSummary } from '../../api/types';
|
|
|
|
|
import type { CatalogApp, CatalogRoute } from '../../api/queries/catalog';
|
2026-03-27 09:15:06 +01:00
|
|
|
import { buildFlowSegments } from '../../utils/diagram-mapping';
|
fix: resolve UI glitches and improve consistency
- Sidebar: make +App button more subtle (lower opacity, brightens on hover)
- Sidebar: add filter chips to hide empty routes and offline/stale apps
- Sidebar: hide filter chips and +App button when sidebar is collapsed
- Exchange table: reorder columns to Status, Attributes, App, Route, Started, Duration; remove ExchangeId and Agent columns
- Exchange detail log tab: query by exchangeId only (no applicationId required), filter by processorId when processor selected
- KPI tooltips: styled tooltips with current/previous values, time period labels, percentage change, themed with DS variables
- KPI tooltips: fix overflow by left-aligning first two and right-aligning last two
- Exchange detail: show full datetime (YYYY-MM-DD HH:mm:ss.SSS) for start/end times
- Status labels: unify to title-case (Completed, Failed, Running) across all views
- Status filter buttons: match title-case labels (Completed, Warning, Failed, Running)
- Create app: show full external URL using routingDomain from env config or window.location.origin fallback
- Create app: add Runtime Type selector and Custom Arguments to Resources tab
- Create app: add Sensitive Keys tab with agent defaults, global keys, and app-specific keys (matching admin page design)
- Create app: add placeholder text to all Input fields for consistency
- Update design-system to 0.1.52 (sidebar collapse toggle fix)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 19:41:36 +02:00
|
|
|
import { statusLabel } from '../../utils/format-utils';
|
2026-03-23 18:25:58 +01:00
|
|
|
import styles from './RouteDetail.module.css';
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
import tableStyles from '../../styles/table-section.module.css';
|
|
|
|
|
import rateStyles from '../../styles/rate-colors.module.css';
|
|
|
|
|
import chartCardStyles from '../../styles/chart-card.module.css';
|
|
|
|
|
import tapModalStyles from '../../components/TapConfigModal.module.css';
|
2026-03-23 18:25:58 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// ── Row types ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
2026-03-23 18:25:58 +01:00
|
|
|
interface ExchangeRow extends ExecutionSummary {
|
|
|
|
|
id: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface ProcessorRow {
|
|
|
|
|
id: string;
|
|
|
|
|
processorId: string;
|
|
|
|
|
callCount: number;
|
|
|
|
|
avgDurationMs: number;
|
|
|
|
|
p99DurationMs: number;
|
|
|
|
|
errorCount: number;
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
errorRate: number;
|
|
|
|
|
sparkline: number[];
|
2026-03-23 18:25:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface ErrorPattern {
|
|
|
|
|
message: string;
|
|
|
|
|
count: number;
|
|
|
|
|
lastSeen: string;
|
|
|
|
|
}
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// ── Processor type badge classes ─────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const TYPE_STYLE_MAP: Record<string, string> = {
|
|
|
|
|
consumer: styles.typeConsumer,
|
|
|
|
|
producer: styles.typeProducer,
|
|
|
|
|
enricher: styles.typeEnricher,
|
|
|
|
|
validator: styles.typeValidator,
|
|
|
|
|
transformer: styles.typeTransformer,
|
|
|
|
|
router: styles.typeRouter,
|
|
|
|
|
processor: styles.typeProcessor,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function classifyProcessorType(processorId: string): string {
|
|
|
|
|
const lower = processorId.toLowerCase();
|
|
|
|
|
if (lower.startsWith('from(') || lower.includes('consumer')) return 'consumer';
|
|
|
|
|
if (lower.startsWith('to(')) return 'producer';
|
|
|
|
|
if (lower.includes('enrich')) return 'enricher';
|
|
|
|
|
if (lower.includes('validate') || lower.includes('check')) return 'validator';
|
|
|
|
|
if (lower.includes('unmarshal') || lower.includes('marshal')) return 'transformer';
|
|
|
|
|
if (lower.includes('route') || lower.includes('choice')) return 'router';
|
|
|
|
|
return 'processor';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Processor table columns ──────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
function makeProcessorColumns(css: typeof styles): Column<ProcessorRow>[] {
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
key: 'processorId',
|
|
|
|
|
header: 'Processor',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<span className={css.routeNameCell}>{row.processorId}</span>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'callCount',
|
|
|
|
|
header: 'Invocations',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<MonoText size="sm">{row.callCount.toLocaleString()}</MonoText>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'avgDurationMs',
|
|
|
|
|
header: 'Avg Duration',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => {
|
|
|
|
|
const cls = row.avgDurationMs > 200 ? css.rateBad : row.avgDurationMs > 100 ? css.rateWarn : css.rateGood;
|
|
|
|
|
return <MonoText size="sm" className={cls}>{Math.round(row.avgDurationMs)}ms</MonoText>;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'p99DurationMs',
|
|
|
|
|
header: 'p99 Duration',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => {
|
|
|
|
|
const cls = row.p99DurationMs > 300 ? css.rateBad : row.p99DurationMs > 200 ? css.rateWarn : css.rateGood;
|
|
|
|
|
return <MonoText size="sm" className={cls}>{Math.round(row.p99DurationMs)}ms</MonoText>;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'errorCount',
|
|
|
|
|
header: 'Errors',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<MonoText size="sm" className={row.errorCount > 10 ? css.rateBad : css.rateNeutral}>
|
|
|
|
|
{row.errorCount}
|
|
|
|
|
</MonoText>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'errorRate',
|
|
|
|
|
header: 'Error Rate',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => {
|
|
|
|
|
const cls = row.errorRate > 1 ? css.rateBad : row.errorRate > 0.5 ? css.rateWarn : css.rateGood;
|
|
|
|
|
return <MonoText size="sm" className={cls}>{row.errorRate.toFixed(2)}%</MonoText>;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'sparkline',
|
|
|
|
|
header: 'Trend',
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<Sparkline data={row.sparkline} width={80} height={24} />
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Exchange table columns ───────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const EXCHANGE_COLUMNS: Column<ExchangeRow>[] = [
|
|
|
|
|
{
|
|
|
|
|
key: 'status',
|
|
|
|
|
header: 'Status',
|
|
|
|
|
width: '80px',
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<StatusDot variant={row.status === 'COMPLETED' ? 'success' : row.status === 'FAILED' ? 'error' : 'running'} />
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'executionId',
|
|
|
|
|
header: 'Exchange ID',
|
|
|
|
|
render: (_, row) => <MonoText size="xs">{row.executionId.slice(0, 12)}</MonoText>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'startTime',
|
|
|
|
|
header: 'Started',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => new Date(row.startTime).toLocaleTimeString(),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'durationMs',
|
|
|
|
|
header: 'Duration',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => `${row.durationMs}ms`,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// ── Build KPI items ──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
function buildDetailKpiItems(
|
|
|
|
|
stats: {
|
|
|
|
|
totalCount: number;
|
|
|
|
|
failedCount: number;
|
|
|
|
|
avgDurationMs: number;
|
|
|
|
|
p99LatencyMs: number;
|
|
|
|
|
activeCount: number;
|
|
|
|
|
prevTotalCount: number;
|
|
|
|
|
prevFailedCount: number;
|
|
|
|
|
prevP99LatencyMs: number;
|
|
|
|
|
} | undefined,
|
|
|
|
|
throughputSparkline: number[],
|
|
|
|
|
errorSparkline: number[],
|
|
|
|
|
latencySparkline: number[],
|
|
|
|
|
): KpiItem[] {
|
|
|
|
|
const totalCount = stats?.totalCount ?? 0;
|
|
|
|
|
const failedCount = stats?.failedCount ?? 0;
|
|
|
|
|
const prevTotalCount = stats?.prevTotalCount ?? 0;
|
|
|
|
|
const p99Ms = stats?.p99LatencyMs ?? 0;
|
|
|
|
|
const prevP99Ms = stats?.prevP99LatencyMs ?? 0;
|
|
|
|
|
const avgMs = stats?.avgDurationMs ?? 0;
|
|
|
|
|
const activeCount = stats?.activeCount ?? 0;
|
|
|
|
|
|
|
|
|
|
const errorRate = totalCount > 0 ? (failedCount / totalCount) * 100 : 0;
|
|
|
|
|
const successRate = totalCount > 0 ? ((totalCount - failedCount) / totalCount) * 100 : 100;
|
|
|
|
|
|
|
|
|
|
const throughputPctChange = prevTotalCount > 0
|
|
|
|
|
? Math.round(((totalCount - prevTotalCount) / prevTotalCount) * 100)
|
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
label: 'Total Throughput',
|
|
|
|
|
value: totalCount.toLocaleString(),
|
|
|
|
|
trend: {
|
|
|
|
|
label: throughputPctChange >= 0 ? `\u25B2 +${throughputPctChange}%` : `\u25BC ${throughputPctChange}%`,
|
|
|
|
|
variant: throughputPctChange >= 0 ? 'success' as const : 'error' as const,
|
|
|
|
|
},
|
|
|
|
|
subtitle: `${activeCount} in-flight`,
|
|
|
|
|
sparkline: throughputSparkline,
|
|
|
|
|
borderColor: 'var(--amber)',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'System Error Rate',
|
|
|
|
|
value: `${errorRate.toFixed(2)}%`,
|
|
|
|
|
trend: {
|
|
|
|
|
label: errorRate < 1 ? '\u25BC low' : `\u25B2 ${errorRate.toFixed(1)}%`,
|
|
|
|
|
variant: errorRate < 1 ? 'success' as const : 'error' as const,
|
|
|
|
|
},
|
|
|
|
|
subtitle: `${failedCount} errors / ${totalCount.toLocaleString()} total`,
|
|
|
|
|
sparkline: errorSparkline,
|
|
|
|
|
borderColor: errorRate < 1 ? 'var(--success)' : 'var(--error)',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Latency P99',
|
|
|
|
|
value: `${p99Ms}ms`,
|
|
|
|
|
trend: {
|
|
|
|
|
label: p99Ms > prevP99Ms ? `\u25B2 +${p99Ms - prevP99Ms}ms` : `\u25BC ${prevP99Ms - p99Ms}ms`,
|
|
|
|
|
variant: p99Ms > 300 ? 'error' as const : 'warning' as const,
|
|
|
|
|
},
|
|
|
|
|
subtitle: `Avg ${avgMs}ms \u00B7 SLA <300ms`,
|
|
|
|
|
sparkline: latencySparkline,
|
|
|
|
|
borderColor: p99Ms > 300 ? 'var(--warning)' : 'var(--success)',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Success Rate',
|
|
|
|
|
value: `${successRate.toFixed(1)}%`,
|
|
|
|
|
trend: { label: '\u2194', variant: 'muted' as const },
|
|
|
|
|
subtitle: `${totalCount - failedCount} ok / ${failedCount} failed`,
|
|
|
|
|
borderColor: 'var(--success)',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'In-Flight',
|
|
|
|
|
value: String(activeCount),
|
|
|
|
|
trend: { label: '\u2194', variant: 'muted' as const },
|
|
|
|
|
subtitle: `${activeCount} active exchanges`,
|
|
|
|
|
borderColor: 'var(--amber)',
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Component ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
2026-03-23 18:25:58 +01:00
|
|
|
export default function RouteDetail() {
|
|
|
|
|
const { appId, routeId } = useParams();
|
|
|
|
|
const navigate = useNavigate();
|
2026-04-09 16:01:50 +02:00
|
|
|
const selectedEnv = useEnvironmentStore((s) => s.environment);
|
2026-03-23 18:25:58 +01:00
|
|
|
const { timeRange } = useGlobalFilters();
|
|
|
|
|
const timeFrom = timeRange.start.toISOString();
|
|
|
|
|
const timeTo = timeRange.end.toISOString();
|
|
|
|
|
|
2026-03-26 22:26:28 +01:00
|
|
|
const [searchParams] = useSearchParams();
|
|
|
|
|
const [activeTab, setActiveTab] = useState(searchParams.get('tab') || 'performance');
|
2026-03-24 17:05:06 +01:00
|
|
|
const [recentSortField, setRecentSortField] = useState<string>('startTime');
|
|
|
|
|
const [recentSortDir, setRecentSortDir] = useState<'asc' | 'desc'>('desc');
|
|
|
|
|
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
// ── Tap modal state ────────────────────────────────────────────────────────
|
|
|
|
|
const [tapModalOpen, setTapModalOpen] = useState(false);
|
|
|
|
|
const [editingTap, setEditingTap] = useState<TapDefinition | null>(null);
|
|
|
|
|
const [tapName, setTapName] = useState('');
|
|
|
|
|
const [tapProcessor, setTapProcessor] = useState('');
|
|
|
|
|
const [tapLanguage, setTapLanguage] = useState('simple');
|
|
|
|
|
const [tapTarget, setTapTarget] = useState<'INPUT' | 'OUTPUT' | 'BOTH'>('OUTPUT');
|
|
|
|
|
const [tapExpression, setTapExpression] = useState('');
|
|
|
|
|
const [tapType, setTapType] = useState<'BUSINESS_OBJECT' | 'CORRELATION' | 'EVENT' | 'CUSTOM'>('BUSINESS_OBJECT');
|
|
|
|
|
const [tapEnabled, setTapEnabled] = useState(true);
|
|
|
|
|
const [deletingTap, setDeletingTap] = useState<TapDefinition | null>(null);
|
|
|
|
|
|
|
|
|
|
// ── Test expression state ──────────────────────────────────────────────────
|
|
|
|
|
const [testTab, setTestTab] = useState('recent');
|
|
|
|
|
const [testPayload, setTestPayload] = useState('');
|
|
|
|
|
const [testResult, setTestResult] = useState<{ result?: string; error?: string } | null>(null);
|
|
|
|
|
const [testExchangeId, setTestExchangeId] = useState('');
|
|
|
|
|
|
2026-03-24 17:05:06 +01:00
|
|
|
const handleRecentSortChange = useCallback((key: string, dir: 'asc' | 'desc') => {
|
|
|
|
|
setRecentSortField(key);
|
|
|
|
|
setRecentSortDir(dir);
|
|
|
|
|
}, []);
|
2026-03-23 18:25:58 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// ── API queries ────────────────────────────────────────────────────────────
|
2026-04-09 16:01:50 +02:00
|
|
|
const { data: catalog } = useCatalog(selectedEnv);
|
2026-03-23 18:25:58 +01:00
|
|
|
const { data: diagram } = useDiagramByRoute(appId, routeId);
|
2026-04-09 16:01:50 +02:00
|
|
|
const { data: processorMetrics, isLoading: processorLoading } = useProcessorMetrics(routeId ?? null, appId, selectedEnv);
|
|
|
|
|
const { data: stats } = useExecutionStats(timeFrom, timeTo, routeId, appId, selectedEnv);
|
|
|
|
|
const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, routeId, appId, selectedEnv);
|
2026-03-23 18:25:58 +01:00
|
|
|
const { data: recentResult, isLoading: recentLoading } = useSearchExecutions({
|
|
|
|
|
timeFrom,
|
|
|
|
|
timeTo,
|
|
|
|
|
routeId: routeId || undefined,
|
2026-04-01 20:55:19 +02:00
|
|
|
applicationId: appId || undefined,
|
2026-04-09 16:01:50 +02:00
|
|
|
environment: selectedEnv,
|
2026-03-24 17:05:06 +01:00
|
|
|
sortField: recentSortField,
|
|
|
|
|
sortDir: recentSortDir,
|
2026-03-23 18:25:58 +01:00
|
|
|
offset: 0,
|
|
|
|
|
limit: 50,
|
|
|
|
|
});
|
|
|
|
|
const { data: errorResult } = useSearchExecutions({
|
|
|
|
|
timeFrom,
|
|
|
|
|
timeTo,
|
|
|
|
|
routeId: routeId || undefined,
|
2026-04-01 20:55:19 +02:00
|
|
|
applicationId: appId || undefined,
|
2026-04-09 16:01:50 +02:00
|
|
|
environment: selectedEnv,
|
2026-03-23 18:25:58 +01:00
|
|
|
status: 'FAILED',
|
|
|
|
|
offset: 0,
|
|
|
|
|
limit: 200,
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-26 18:44:06 +01:00
|
|
|
// ── Application config ──────────────────────────────────────────────────────
|
|
|
|
|
const config = useApplicationConfig(appId);
|
|
|
|
|
const updateConfig = useUpdateApplicationConfig();
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
const testExpressionMutation = useTestExpression();
|
2026-03-26 18:44:06 +01:00
|
|
|
|
|
|
|
|
const isRecording = config.data?.routeRecording?.[routeId!] !== false;
|
|
|
|
|
|
|
|
|
|
function toggleRecording() {
|
|
|
|
|
if (!config.data) return;
|
|
|
|
|
const routeRecording = { ...config.data.routeRecording, [routeId!]: !isRecording };
|
2026-04-09 16:28:09 +02:00
|
|
|
updateConfig.mutate({ config: { ...config.data, routeRecording }, environment: selectedEnv });
|
2026-03-26 18:44:06 +01:00
|
|
|
}
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// ── Derived data ───────────────────────────────────────────────────────────
|
|
|
|
|
|
2026-04-08 23:43:14 +02:00
|
|
|
const appEntry: CatalogApp | undefined = useMemo(() =>
|
|
|
|
|
(catalog || []).find((e: CatalogApp) => e.slug === appId),
|
2026-03-23 18:25:58 +01:00
|
|
|
[catalog, appId],
|
|
|
|
|
);
|
|
|
|
|
|
2026-04-08 23:43:14 +02:00
|
|
|
const routeSummary: CatalogRoute | undefined = useMemo(() =>
|
|
|
|
|
appEntry?.routes?.find((r: CatalogRoute) => r.routeId === routeId),
|
2026-03-23 18:25:58 +01:00
|
|
|
[appEntry, routeId],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const health = appEntry?.health ?? 'unknown';
|
|
|
|
|
const exchangeCount = routeSummary?.exchangeCount ?? 0;
|
|
|
|
|
const lastSeen = routeSummary?.lastSeen
|
|
|
|
|
? new Date(routeSummary.lastSeen).toLocaleString()
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
: '\u2014';
|
2026-03-23 18:25:58 +01:00
|
|
|
|
|
|
|
|
const healthVariant = useMemo((): 'success' | 'warning' | 'error' | 'dead' => {
|
|
|
|
|
const h = health.toLowerCase();
|
|
|
|
|
if (h === 'healthy') return 'success';
|
|
|
|
|
if (h === 'degraded') return 'warning';
|
|
|
|
|
if (h === 'unhealthy') return 'error';
|
|
|
|
|
return 'dead';
|
|
|
|
|
}, [health]);
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// Route flow from diagram
|
2026-03-25 18:34:58 +01:00
|
|
|
const diagramFlows = useMemo(() => {
|
2026-03-23 18:25:58 +01:00
|
|
|
if (!diagram?.nodes) return [];
|
2026-03-27 09:15:06 +01:00
|
|
|
return buildFlowSegments(diagram.nodes, []).flows;
|
2026-03-23 18:25:58 +01:00
|
|
|
}, [diagram]);
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// Processor table rows
|
2026-03-23 18:25:58 +01:00
|
|
|
const processorRows: ProcessorRow[] = useMemo(() =>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
(processorMetrics || []).map((p: any) => {
|
|
|
|
|
const callCount = p.callCount ?? 0;
|
|
|
|
|
const errorCount = p.errorCount ?? 0;
|
|
|
|
|
const errRate = callCount > 0 ? (errorCount / callCount) * 100 : 0;
|
|
|
|
|
return {
|
|
|
|
|
id: p.processorId,
|
|
|
|
|
processorId: p.processorId,
|
|
|
|
|
type: classifyProcessorType(p.processorId ?? ''),
|
|
|
|
|
callCount,
|
|
|
|
|
avgDurationMs: p.avgDurationMs ?? 0,
|
|
|
|
|
p99DurationMs: p.p99DurationMs ?? 0,
|
|
|
|
|
errorCount,
|
|
|
|
|
errorRate: Number(errRate.toFixed(2)),
|
|
|
|
|
sparkline: p.sparkline ?? [],
|
|
|
|
|
};
|
|
|
|
|
}),
|
2026-03-23 18:25:58 +01:00
|
|
|
[processorMetrics],
|
|
|
|
|
);
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// Timeseries-derived data
|
|
|
|
|
const throughputSparkline = useMemo(() =>
|
|
|
|
|
(timeseries?.buckets || []).map((b) => b.totalCount),
|
|
|
|
|
[timeseries],
|
|
|
|
|
);
|
|
|
|
|
const errorSparkline = useMemo(() =>
|
|
|
|
|
(timeseries?.buckets || []).map((b) => b.failedCount),
|
|
|
|
|
[timeseries],
|
|
|
|
|
);
|
|
|
|
|
const latencySparkline = useMemo(() =>
|
|
|
|
|
(timeseries?.buckets || []).map((b) => b.p99DurationMs),
|
|
|
|
|
[timeseries],
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-23 18:25:58 +01:00
|
|
|
const chartData = useMemo(() =>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
(timeseries?.buckets || []).map((b) => {
|
|
|
|
|
const ts = new Date(b.time);
|
|
|
|
|
return {
|
|
|
|
|
time: !isNaN(ts.getTime())
|
|
|
|
|
? ts.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
|
|
|
: '\u2014',
|
|
|
|
|
throughput: b.totalCount,
|
|
|
|
|
latency: b.avgDurationMs,
|
|
|
|
|
errors: b.failedCount,
|
|
|
|
|
successRate: b.totalCount > 0 ? ((b.totalCount - b.failedCount) / b.totalCount) * 100 : 100,
|
|
|
|
|
};
|
|
|
|
|
}),
|
2026-03-23 18:25:58 +01:00
|
|
|
[timeseries],
|
|
|
|
|
);
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// Exchange rows
|
2026-03-23 18:25:58 +01:00
|
|
|
const exchangeRows: ExchangeRow[] = useMemo(() =>
|
|
|
|
|
(recentResult?.data || []).map((e: ExecutionSummary) => ({ ...e, id: e.executionId })),
|
|
|
|
|
[recentResult],
|
|
|
|
|
);
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// Error patterns
|
2026-03-23 18:25:58 +01:00
|
|
|
const errorPatterns: ErrorPattern[] = useMemo(() => {
|
|
|
|
|
const failed = (errorResult?.data || []) as ExecutionSummary[];
|
|
|
|
|
const grouped = new Map<string, { count: number; lastSeen: string }>();
|
|
|
|
|
for (const ex of failed) {
|
|
|
|
|
const msg = ex.errorMessage || 'Unknown error';
|
|
|
|
|
const existing = grouped.get(msg);
|
|
|
|
|
if (!existing) {
|
|
|
|
|
grouped.set(msg, { count: 1, lastSeen: ex.startTime ?? '' });
|
|
|
|
|
} else {
|
|
|
|
|
existing.count += 1;
|
|
|
|
|
if ((ex.startTime ?? '') > existing.lastSeen) {
|
|
|
|
|
existing.lastSeen = ex.startTime ?? '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Array.from(grouped.entries())
|
|
|
|
|
.map(([message, { count, lastSeen: ls }]) => ({
|
|
|
|
|
message,
|
|
|
|
|
count,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
lastSeen: ls ? new Date(ls).toLocaleString() : '\u2014',
|
2026-03-23 18:25:58 +01:00
|
|
|
}))
|
|
|
|
|
.sort((a, b) => b.count - a.count);
|
|
|
|
|
}, [errorResult]);
|
|
|
|
|
|
2026-03-26 18:44:06 +01:00
|
|
|
// Route taps — cross-reference config taps with diagram processor IDs
|
|
|
|
|
const routeTaps = useMemo(() => {
|
|
|
|
|
if (!config.data?.taps || !diagram) return [];
|
|
|
|
|
const routeProcessorIds = new Set(
|
|
|
|
|
(diagram.nodes || []).map((n: any) => n.id).filter(Boolean),
|
|
|
|
|
);
|
|
|
|
|
return config.data.taps.filter(t => routeProcessorIds.has(t.processorId));
|
|
|
|
|
}, [config.data?.taps, diagram]);
|
|
|
|
|
|
|
|
|
|
const activeTapCount = routeTaps.filter(t => t.enabled).length;
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// KPI items
|
2026-03-26 18:44:06 +01:00
|
|
|
const kpiItems = useMemo(() => {
|
|
|
|
|
const base = buildDetailKpiItems(stats, throughputSparkline, errorSparkline, latencySparkline);
|
|
|
|
|
base.push({
|
|
|
|
|
label: 'Active Taps',
|
|
|
|
|
value: String(activeTapCount),
|
|
|
|
|
trend: { label: `${routeTaps.length} total`, variant: 'muted' as const },
|
|
|
|
|
subtitle: `${activeTapCount} enabled / ${routeTaps.length} configured`,
|
|
|
|
|
borderColor: 'var(--running)',
|
|
|
|
|
});
|
|
|
|
|
return base;
|
|
|
|
|
}, [stats, throughputSparkline, errorSparkline, latencySparkline, activeTapCount, routeTaps.length]);
|
2026-03-23 18:25:58 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const processorColumns = useMemo(() => makeProcessorColumns(styles), []);
|
2026-03-23 18:25:58 +01:00
|
|
|
|
|
|
|
|
const tabs = [
|
|
|
|
|
{ label: 'Performance', value: 'performance' },
|
|
|
|
|
{ label: 'Recent Executions', value: 'executions', count: exchangeRows.length },
|
|
|
|
|
{ label: 'Error Patterns', value: 'errors', count: errorPatterns.length },
|
2026-03-26 18:44:06 +01:00
|
|
|
{ label: 'Taps', value: 'taps', count: routeTaps.length },
|
2026-03-23 18:25:58 +01:00
|
|
|
];
|
|
|
|
|
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
// ── Tap helpers ──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const processorOptions = useMemo(() => {
|
|
|
|
|
if (!diagram?.nodes) return [];
|
|
|
|
|
return (diagram.nodes as Array<{ id?: string; label?: string }>)
|
|
|
|
|
.filter((n) => n.id)
|
|
|
|
|
.map((n) => ({ value: n.id!, label: n.label || n.id! }));
|
|
|
|
|
}, [diagram]);
|
|
|
|
|
|
|
|
|
|
function openTapModal(tap: TapDefinition | null) {
|
|
|
|
|
if (tap) {
|
|
|
|
|
setEditingTap(tap);
|
|
|
|
|
setTapName(tap.attributeName);
|
|
|
|
|
setTapProcessor(tap.processorId);
|
|
|
|
|
setTapLanguage(tap.language);
|
|
|
|
|
setTapTarget(tap.target);
|
|
|
|
|
setTapExpression(tap.expression);
|
|
|
|
|
setTapType(tap.attributeType);
|
|
|
|
|
setTapEnabled(tap.enabled);
|
|
|
|
|
} else {
|
|
|
|
|
setEditingTap(null);
|
|
|
|
|
setTapName('');
|
|
|
|
|
setTapProcessor(processorOptions[0]?.value ?? '');
|
|
|
|
|
setTapLanguage('simple');
|
|
|
|
|
setTapTarget('OUTPUT');
|
|
|
|
|
setTapExpression('');
|
|
|
|
|
setTapType('BUSINESS_OBJECT');
|
|
|
|
|
setTapEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
setTestResult(null);
|
|
|
|
|
setTestPayload('');
|
|
|
|
|
setTestExchangeId('');
|
|
|
|
|
setTapModalOpen(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function saveTap() {
|
|
|
|
|
if (!config.data) return;
|
|
|
|
|
const tap: TapDefinition = {
|
2026-03-26 19:46:32 +01:00
|
|
|
tapId: editingTap?.tapId || `tap-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
processorId: tapProcessor,
|
|
|
|
|
target: tapTarget,
|
|
|
|
|
expression: tapExpression,
|
|
|
|
|
language: tapLanguage,
|
|
|
|
|
attributeName: tapName,
|
|
|
|
|
attributeType: tapType,
|
|
|
|
|
enabled: tapEnabled,
|
|
|
|
|
version: editingTap ? editingTap.version + 1 : 1,
|
|
|
|
|
};
|
|
|
|
|
const taps = editingTap
|
|
|
|
|
? config.data.taps.map(t => t.tapId === editingTap.tapId ? tap : t)
|
|
|
|
|
: [...(config.data.taps || []), tap];
|
2026-04-09 16:28:09 +02:00
|
|
|
updateConfig.mutate({ config: { ...config.data, taps }, environment: selectedEnv });
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
setTapModalOpen(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deleteTap(tap: TapDefinition) {
|
|
|
|
|
if (!config.data) return;
|
|
|
|
|
const taps = config.data.taps.filter(t => t.tapId !== tap.tapId);
|
2026-04-09 16:28:09 +02:00
|
|
|
updateConfig.mutate({ config: { ...config.data, taps }, environment: selectedEnv });
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
setDeletingTap(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function toggleTapEnabled(tap: TapDefinition) {
|
|
|
|
|
if (!config.data) return;
|
|
|
|
|
const taps = config.data.taps.map(t =>
|
|
|
|
|
t.tapId === tap.tapId ? { ...t, enabled: !t.enabled } : t,
|
|
|
|
|
);
|
2026-04-09 16:28:09 +02:00
|
|
|
updateConfig.mutate({ config: { ...config.data, taps }, environment: selectedEnv });
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runTestExpression() {
|
|
|
|
|
if (!appId) return;
|
|
|
|
|
const body = testTab === 'recent' ? testExchangeId : testPayload;
|
|
|
|
|
testExpressionMutation.mutate(
|
|
|
|
|
{ application: appId, expression: tapExpression, language: tapLanguage, body, target: tapTarget },
|
|
|
|
|
{ onSuccess: (data) => setTestResult(data), onError: (err) => setTestResult({ error: (err as Error).message }) },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tapColumns: Column<TapDefinition & { id: string }>[] = useMemo(() => [
|
|
|
|
|
{
|
|
|
|
|
key: 'attributeName',
|
|
|
|
|
header: 'Attribute',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => <span>{row.attributeName}</span>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'processorId',
|
|
|
|
|
header: 'Processor',
|
|
|
|
|
sortable: true,
|
|
|
|
|
render: (_, row) => <MonoText size="xs">{row.processorId}</MonoText>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'expression',
|
|
|
|
|
header: 'Expression',
|
|
|
|
|
render: (_, row) => <MonoText size="xs">{row.expression}</MonoText>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'language',
|
|
|
|
|
header: 'Language',
|
|
|
|
|
render: (_, row) => <Badge label={row.language} color="auto" />,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'target',
|
|
|
|
|
header: 'Target',
|
|
|
|
|
render: (_, row) => <Badge label={row.target} color="auto" />,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'attributeType',
|
|
|
|
|
header: 'Type',
|
|
|
|
|
render: (_, row) => <Badge label={row.attributeType} color="auto" />,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'enabled',
|
|
|
|
|
header: 'Enabled',
|
|
|
|
|
width: '80px',
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<Toggle
|
|
|
|
|
checked={row.enabled}
|
|
|
|
|
onChange={() => toggleTapEnabled(row)}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'actions' as any,
|
|
|
|
|
header: '',
|
2026-03-26 21:32:05 +01:00
|
|
|
width: '80px',
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
render: (_, row) => (
|
|
|
|
|
<div className={styles.tapActions}>
|
2026-03-27 23:16:39 +01:00
|
|
|
<button className={styles.tapActionBtn} title="Edit" onClick={() => openTapModal(row)}><Pencil size={14} /></button>
|
|
|
|
|
<button className={styles.tapActionBtn} title="Delete" onClick={() => setDeletingTap(row)}><Trash2 size={14} /></button>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
], [config.data, processorOptions]);
|
|
|
|
|
|
|
|
|
|
const languageOptions = [
|
|
|
|
|
{ value: 'simple', label: 'Simple' },
|
|
|
|
|
{ value: 'jsonpath', label: 'JSONPath' },
|
|
|
|
|
{ value: 'xpath', label: 'XPath' },
|
|
|
|
|
{ value: 'jq', label: 'jq' },
|
|
|
|
|
{ value: 'groovy', label: 'Groovy' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const targetOptions = [
|
|
|
|
|
{ value: 'INPUT', label: 'Input' },
|
|
|
|
|
{ value: 'OUTPUT', label: 'Output' },
|
|
|
|
|
{ value: 'BOTH', label: 'Both' },
|
|
|
|
|
];
|
|
|
|
|
|
2026-03-26 19:47:39 +01:00
|
|
|
const typeChoices: Array<{ value: TapDefinition['attributeType']; label: string; tooltip: string }> = [
|
|
|
|
|
{ value: 'BUSINESS_OBJECT', label: 'Business Object', tooltip: 'A key business identifier like orderId, customerId, or invoiceNumber' },
|
|
|
|
|
{ value: 'CORRELATION', label: 'Correlation', tooltip: 'Used to correlate related exchanges across routes or services' },
|
|
|
|
|
{ value: 'EVENT', label: 'Event', tooltip: 'Marks a business event occurrence like orderPlaced or paymentReceived' },
|
|
|
|
|
{ value: 'CUSTOM', label: 'Custom', tooltip: 'General-purpose attribute for any other extraction need' },
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const recentExchangeOptions = useMemo(() =>
|
|
|
|
|
exchangeRows.slice(0, 20).map(e => ({
|
|
|
|
|
value: e.executionId,
|
fix: resolve UI glitches and improve consistency
- Sidebar: make +App button more subtle (lower opacity, brightens on hover)
- Sidebar: add filter chips to hide empty routes and offline/stale apps
- Sidebar: hide filter chips and +App button when sidebar is collapsed
- Exchange table: reorder columns to Status, Attributes, App, Route, Started, Duration; remove ExchangeId and Agent columns
- Exchange detail log tab: query by exchangeId only (no applicationId required), filter by processorId when processor selected
- KPI tooltips: styled tooltips with current/previous values, time period labels, percentage change, themed with DS variables
- KPI tooltips: fix overflow by left-aligning first two and right-aligning last two
- Exchange detail: show full datetime (YYYY-MM-DD HH:mm:ss.SSS) for start/end times
- Status labels: unify to title-case (Completed, Failed, Running) across all views
- Status filter buttons: match title-case labels (Completed, Warning, Failed, Running)
- Create app: show full external URL using routingDomain from env config or window.location.origin fallback
- Create app: add Runtime Type selector and Custom Arguments to Resources tab
- Create app: add Sensitive Keys tab with agent defaults, global keys, and app-specific keys (matching admin page design)
- Create app: add placeholder text to all Input fields for consistency
- Update design-system to 0.1.52 (sidebar collapse toggle fix)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 19:41:36 +02:00
|
|
|
label: `${e.executionId.slice(0, 12)} — ${statusLabel(e.status)}`,
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
})),
|
|
|
|
|
[exchangeRows],
|
|
|
|
|
);
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
// ── Render ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
2026-03-23 18:25:58 +01:00
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<Link to={`/routes/${appId}`} className={styles.backLink}>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
← {appId} routes
|
2026-03-23 18:25:58 +01:00
|
|
|
</Link>
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
{/* Route header card */}
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.headerCard}>
|
|
|
|
|
<div className={styles.headerRow}>
|
|
|
|
|
<div className={styles.headerLeft}>
|
|
|
|
|
<StatusDot variant={healthVariant} />
|
|
|
|
|
<h2 style={{ margin: 0, fontSize: 18, fontWeight: 700 }}>{routeId}</h2>
|
|
|
|
|
<Badge label={appId ?? ''} color="auto" />
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.headerRight}>
|
2026-03-26 18:44:06 +01:00
|
|
|
<div className={styles.recordingPill}>
|
|
|
|
|
<span className={styles.recordingLabel}>Recording</span>
|
|
|
|
|
<Toggle checked={isRecording} onChange={toggleRecording} />
|
|
|
|
|
</div>
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.headerStat}>
|
|
|
|
|
<div className={styles.headerStatLabel}>Exchanges</div>
|
|
|
|
|
<div className={styles.headerStatValue}>{exchangeCount.toLocaleString()}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.headerStat}>
|
|
|
|
|
<div className={styles.headerStatLabel}>Last Seen</div>
|
|
|
|
|
<div className={styles.headerStatValue}>{lastSeen}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
{/* KPI strip */}
|
|
|
|
|
<KpiStrip items={kpiItems} />
|
|
|
|
|
|
|
|
|
|
{/* Diagram + Processor Stats grid */}
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.diagramStatsGrid}>
|
|
|
|
|
<div className={styles.diagramPane}>
|
|
|
|
|
<div className={styles.paneTitle}>Route Diagram</div>
|
2026-03-25 18:34:58 +01:00
|
|
|
{diagramFlows.length > 0 ? (
|
|
|
|
|
<RouteFlow flows={diagramFlows} />
|
2026-03-23 18:25:58 +01:00
|
|
|
) : (
|
2026-04-09 18:47:55 +02:00
|
|
|
<EmptyState title="No diagram" description="No diagram available for this route." />
|
2026-03-23 18:25:58 +01:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.statsPane}>
|
|
|
|
|
<div className={styles.paneTitle}>Processor Stats</div>
|
|
|
|
|
{processorLoading ? (
|
|
|
|
|
<Spinner size="sm" />
|
|
|
|
|
) : processorRows.length > 0 ? (
|
|
|
|
|
<DataTable columns={processorColumns} data={processorRows} sortable pageSize={10} />
|
|
|
|
|
) : (
|
2026-04-09 18:47:55 +02:00
|
|
|
<EmptyState title="No processor data" description="No processor data available." />
|
2026-03-23 18:25:58 +01:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
{/* Processor Performance table (full width) */}
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={`${tableStyles.tableSection} ${styles.tableSection}`}>
|
|
|
|
|
<div className={tableStyles.tableHeader}>
|
|
|
|
|
<span className={tableStyles.tableTitle}>Processor Performance</span>
|
|
|
|
|
<div className={tableStyles.tableRight}>
|
|
|
|
|
<span className={tableStyles.tableMeta}>{processorRows.length} processors</span>
|
2026-04-03 22:05:29 +02:00
|
|
|
<Badge label="AUTO" color="success" />
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<DataTable
|
|
|
|
|
columns={processorColumns}
|
|
|
|
|
data={processorRows}
|
|
|
|
|
sortable
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Route Flow section */}
|
2026-03-25 18:34:58 +01:00
|
|
|
{diagramFlows.length > 0 && (
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<div className={styles.routeFlowSection}>
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={tableStyles.tableHeader}>
|
|
|
|
|
<span className={tableStyles.tableTitle}>Route Flow</span>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
</div>
|
2026-03-25 18:34:58 +01:00
|
|
|
<RouteFlow flows={diagramFlows} />
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Tabbed section: Performance charts, Recent Executions, Error Patterns */}
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.tabSection}>
|
|
|
|
|
<Tabs tabs={tabs} active={activeTab} onChange={setActiveTab} />
|
|
|
|
|
|
|
|
|
|
{activeTab === 'performance' && (
|
|
|
|
|
<div className={styles.chartGrid} style={{ marginTop: 16 }}>
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={chartCardStyles.chartCard}>
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.chartTitle}>Throughput</div>
|
2026-04-12 19:44:55 +02:00
|
|
|
<ThemedChart data={chartData} height={200} xDataKey="time" yLabel="msg/s">
|
|
|
|
|
<Area dataKey="throughput" name="Throughput" stroke={CHART_COLORS[0]}
|
|
|
|
|
fill={CHART_COLORS[0]} fillOpacity={0.1} strokeWidth={2} dot={false} />
|
|
|
|
|
</ThemedChart>
|
2026-03-23 18:25:58 +01:00
|
|
|
</div>
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={chartCardStyles.chartCard}>
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.chartTitle}>Latency</div>
|
2026-04-12 19:44:55 +02:00
|
|
|
<ThemedChart data={chartData} height={200} xDataKey="time" yLabel="ms">
|
|
|
|
|
<Line dataKey="latency" name="Latency" stroke={CHART_COLORS[0]} strokeWidth={2} dot={false} />
|
|
|
|
|
<ReferenceLine y={300} stroke="var(--error)" strokeDasharray="5 3"
|
|
|
|
|
label={{ value: 'SLA 300ms', position: 'right', fill: 'var(--error)', fontSize: 9 }} />
|
|
|
|
|
</ThemedChart>
|
2026-03-23 18:25:58 +01:00
|
|
|
</div>
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={chartCardStyles.chartCard}>
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.chartTitle}>Errors</div>
|
2026-04-12 19:44:55 +02:00
|
|
|
<ThemedChart data={chartData} height={200} xDataKey="time" yLabel="errors">
|
|
|
|
|
<Bar dataKey="errors" name="Errors" fill={CHART_COLORS[1]} />
|
|
|
|
|
</ThemedChart>
|
2026-03-23 18:25:58 +01:00
|
|
|
</div>
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={chartCardStyles.chartCard}>
|
2026-03-23 18:25:58 +01:00
|
|
|
<div className={styles.chartTitle}>Success Rate</div>
|
2026-04-12 19:44:55 +02:00
|
|
|
<ThemedChart data={chartData} height={200} xDataKey="time" yLabel="%">
|
|
|
|
|
<Area dataKey="successRate" name="Success Rate" stroke={CHART_COLORS[0]}
|
|
|
|
|
fill={CHART_COLORS[0]} fillOpacity={0.1} strokeWidth={2} dot={false} />
|
|
|
|
|
</ThemedChart>
|
2026-03-23 18:25:58 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{activeTab === 'executions' && (
|
|
|
|
|
<div className={styles.executionsTable} style={{ marginTop: 16 }}>
|
|
|
|
|
{recentLoading ? (
|
|
|
|
|
<div style={{ padding: 24, display: 'flex', justifyContent: 'center' }}>
|
|
|
|
|
<Spinner size="sm" />
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<DataTable
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
columns={EXCHANGE_COLUMNS}
|
2026-03-23 18:25:58 +01:00
|
|
|
data={exchangeRows}
|
|
|
|
|
onRowClick={(row) => navigate(`/exchanges/${row.executionId}`)}
|
|
|
|
|
sortable
|
|
|
|
|
pageSize={20}
|
2026-03-24 17:05:06 +01:00
|
|
|
onSortChange={handleRecentSortChange}
|
2026-03-23 18:25:58 +01:00
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{activeTab === 'errors' && (
|
|
|
|
|
<div className={styles.errorPatterns} style={{ marginTop: 16 }}>
|
|
|
|
|
{errorPatterns.length === 0 ? (
|
2026-04-09 18:47:55 +02:00
|
|
|
<EmptyState title="No error patterns" description="No error patterns found in the selected time range." />
|
2026-03-23 18:25:58 +01:00
|
|
|
) : (
|
|
|
|
|
errorPatterns.map((ep, i) => (
|
|
|
|
|
<div key={i} className={styles.errorRow}>
|
|
|
|
|
<span className={styles.errorMessage} title={ep.message}>{ep.message}</span>
|
|
|
|
|
<span className={styles.errorCount}>{ep.count}x</span>
|
|
|
|
|
<span className={styles.errorTime}>{ep.lastSeen}</span>
|
|
|
|
|
</div>
|
|
|
|
|
))
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-03-26 18:44:06 +01:00
|
|
|
|
|
|
|
|
{activeTab === 'taps' && (
|
|
|
|
|
<div className={styles.tapsSection}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
<div className={styles.tapsHeader}>
|
|
|
|
|
<span className={styles.tapsTitle}>Data Extraction Taps</span>
|
|
|
|
|
<Button variant="primary" size="sm" onClick={() => openTapModal(null)}>+ Add Tap</Button>
|
2026-03-26 18:44:06 +01:00
|
|
|
</div>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
{routeTaps.length === 0 ? (
|
2026-04-09 18:47:55 +02:00
|
|
|
<EmptyState title="No taps" description="No taps configured for this route. Add a tap to extract business attributes from exchange data." />
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
) : (
|
|
|
|
|
<DataTable
|
|
|
|
|
columns={tapColumns}
|
|
|
|
|
data={routeTaps.map(t => ({ ...t, id: t.tapId }))}
|
|
|
|
|
flush
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-03-26 18:44:06 +01:00
|
|
|
</div>
|
|
|
|
|
)}
|
2026-03-23 18:25:58 +01:00
|
|
|
</div>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
|
|
|
|
|
{/* Tap Modal */}
|
|
|
|
|
<Modal open={tapModalOpen} onClose={() => setTapModalOpen(false)} title={editingTap ? 'Edit Tap' : 'Add Tap'} size="lg">
|
|
|
|
|
<div className={styles.tapModalBody}>
|
|
|
|
|
<FormField label="Attribute Name">
|
|
|
|
|
<Input value={tapName} onChange={(e) => setTapName(e.target.value)} placeholder="e.g. orderId" />
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
|
|
<FormField label="Processor">
|
|
|
|
|
<Select
|
|
|
|
|
options={processorOptions}
|
|
|
|
|
value={tapProcessor}
|
|
|
|
|
onChange={(e) => setTapProcessor(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
|
|
<div className={styles.tapFormRow}>
|
|
|
|
|
<FormField label="Language">
|
|
|
|
|
<Select
|
|
|
|
|
options={languageOptions}
|
|
|
|
|
value={tapLanguage}
|
|
|
|
|
onChange={(e) => setTapLanguage(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</FormField>
|
|
|
|
|
<FormField label="Target">
|
|
|
|
|
<Select
|
|
|
|
|
options={targetOptions}
|
|
|
|
|
value={tapTarget}
|
|
|
|
|
onChange={(e) => setTapTarget(e.target.value as 'INPUT' | 'OUTPUT' | 'BOTH')}
|
|
|
|
|
/>
|
|
|
|
|
</FormField>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<FormField label="Expression">
|
|
|
|
|
<Textarea
|
|
|
|
|
className={styles.monoTextarea}
|
|
|
|
|
value={tapExpression}
|
|
|
|
|
onChange={(e) => setTapExpression(e.target.value)}
|
|
|
|
|
placeholder="e.g. ${body.orderId}"
|
|
|
|
|
rows={3}
|
|
|
|
|
/>
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
|
|
<FormField label="Type">
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={tapModalStyles.typeSelector}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
{typeChoices.map(tc => (
|
|
|
|
|
<button
|
|
|
|
|
key={tc.value}
|
|
|
|
|
type="button"
|
2026-03-26 19:47:39 +01:00
|
|
|
title={tc.tooltip}
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
className={`${tapModalStyles.typeOption} ${tapType === tc.value ? tapModalStyles.typeOptionActive : ''}`}
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
onClick={() => setTapType(tc.value)}
|
|
|
|
|
>
|
|
|
|
|
{tc.label}
|
|
|
|
|
</button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
|
|
<div className={styles.tapFormRow}>
|
|
|
|
|
<FormField label="Enabled">
|
|
|
|
|
<Toggle checked={tapEnabled} onChange={() => setTapEnabled(!tapEnabled)} />
|
|
|
|
|
</FormField>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Test Expression */}
|
|
|
|
|
<Collapsible title="Test Expression" defaultOpen>
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={tapModalStyles.testSection}>
|
|
|
|
|
<div className={tapModalStyles.testTabs}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
<button
|
|
|
|
|
type="button"
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
className={`${tapModalStyles.testTabBtn} ${testTab === 'recent' ? tapModalStyles.testTabBtnActive : ''}`}
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
onClick={() => setTestTab('recent')}
|
|
|
|
|
>
|
|
|
|
|
Recent Exchange
|
|
|
|
|
</button>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
className={`${tapModalStyles.testTabBtn} ${testTab === 'custom' ? tapModalStyles.testTabBtnActive : ''}`}
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
onClick={() => setTestTab('custom')}
|
|
|
|
|
>
|
|
|
|
|
Custom Payload
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{testTab === 'recent' && (
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={tapModalStyles.testBody}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
<Select
|
|
|
|
|
options={recentExchangeOptions.length > 0 ? recentExchangeOptions : [{ value: '', label: 'No recent exchanges' }]}
|
|
|
|
|
value={testExchangeId}
|
|
|
|
|
onChange={(e) => setTestExchangeId(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{testTab === 'custom' && (
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={tapModalStyles.testBody}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
<Textarea
|
|
|
|
|
className={styles.monoTextarea}
|
|
|
|
|
value={testPayload}
|
|
|
|
|
onChange={(e) => setTestPayload(e.target.value)}
|
|
|
|
|
placeholder='{"orderId": "12345", ...}'
|
|
|
|
|
rows={4}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={tapModalStyles.testBody}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
<Button
|
|
|
|
|
variant="secondary"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={runTestExpression}
|
|
|
|
|
loading={testExpressionMutation.isPending}
|
|
|
|
|
disabled={!tapExpression}
|
|
|
|
|
>
|
|
|
|
|
Test
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{testResult && (
|
refactor: UI consistency — shared CSS, design system colors, no inline styles
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.
Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).
Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.
Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.
58 files changed, net -219 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
|
|
|
<div className={`${tapModalStyles.testResult} ${testResult.error ? tapModalStyles.testError : tapModalStyles.testSuccess}`}>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
{testResult.error ?? testResult.result ?? 'No result'}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</Collapsible>
|
|
|
|
|
|
|
|
|
|
<div className={styles.tapModalFooter}>
|
2026-04-09 18:39:22 +02:00
|
|
|
<Button variant="ghost" onClick={() => setTapModalOpen(false)}>Cancel</Button>
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
<Button variant="primary" onClick={saveTap} disabled={!tapName || !tapProcessor || !tapExpression}>Save</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
{/* Delete Tap Confirm */}
|
|
|
|
|
<ConfirmDialog
|
|
|
|
|
open={!!deletingTap}
|
|
|
|
|
onClose={() => setDeletingTap(null)}
|
|
|
|
|
onConfirm={() => deletingTap && deleteTap(deletingTap)}
|
|
|
|
|
title="Delete Tap"
|
|
|
|
|
message={`This will remove the tap "${deletingTap?.attributeName ?? ''}" from the configuration.`}
|
|
|
|
|
confirmText={deletingTap?.attributeName ?? ''}
|
|
|
|
|
confirmLabel="Delete"
|
|
|
|
|
variant="danger"
|
2026-04-09 18:39:22 +02:00
|
|
|
loading={updateConfig.isPending}
|
feat(ui): add taps DataTable, CRUD modal with test expression to RouteDetail
- Replace taps tab placeholder with full DataTable showing all route taps
- Add columns: attribute, processor, expression, language, target, type, enabled toggle, actions
- Add tap modal with form fields: attribute name, processor select, language, target, expression, type selector
- Implement inline enable/disable toggle per tap row
- Add ConfirmDialog for tap deletion
- Add test expression section with Recent Exchange and Custom Payload tabs
- Add save/edit/delete tap operations via application config update
- Add all supporting CSS module classes (no inline styles)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:44:36 +01:00
|
|
|
/>
|
2026-03-23 18:25:58 +01:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|