Rename Java packages from com.cameleer3 to com.cameleer, module directories from cameleer3-* to cameleer-*, and all references throughout workflows, Dockerfiles, docs, migrations, and pom.xml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1503 lines
56 KiB
HTML
1503 lines
56 KiB
HTML
<!--
|
|
============================================================================
|
|
CAMELEER — Dashboard Visual Design Mock
|
|
============================================================================
|
|
|
|
DESIGN RATIONALE
|
|
================
|
|
|
|
1. COLOR PHILOSOPHY — "Desert Dusk"
|
|
Moving away from the generic dark-navy dashboard, this design uses a
|
|
warm sandstone/parchment palette inspired by desert caravans (the camel
|
|
connection). The base is a warm off-white (#FAF8F5) with layered ivory
|
|
surfaces. The accent color is a rich amber-gold (#C6820E) that evokes
|
|
caravan lanterns. This creates a distinctive identity that no other
|
|
monitoring tool has — most are cold blue/gray.
|
|
|
|
2. TYPOGRAPHY
|
|
DM Sans for body text (geometric, modern, highly legible at small sizes).
|
|
JetBrains Mono for data values and code (excellent number alignment).
|
|
Four-level hierarchy: Page title (20px/700), Section headers (13px/600
|
|
uppercase tracking), Body (13px/400), Meta (11px/400 muted).
|
|
|
|
3. INFORMATION DENSITY
|
|
Inspired by the nJAMS three-panel layout: operators need to see many
|
|
executions at once. Rows are compact (40px) but not cramped. The stats
|
|
bar uses horizontal cards rather than tall boxes to preserve vertical
|
|
space for the table. A metrics panel below the fold provides trend data
|
|
without cluttering the primary view.
|
|
|
|
4. STATUS COLORS
|
|
Success: Warm olive-green (#3D7C47) — natural, not neon
|
|
Warning: Burnt orange (#C27516) — distinct from the amber accent
|
|
Error: Terracotta red (#C0392B) — warm red, not alarming pink
|
|
Running: Teal (#1A7F8E) — cool contrast against warm palette
|
|
|
|
5. LAYOUT
|
|
Three zones: Navigation sidebar (220px, warm dark), Main content (flex),
|
|
optional detail panel. The sidebar uses a deep warm charcoal (#2C2520)
|
|
instead of pure black — keeping the warm family. Active items get a
|
|
golden left-border accent.
|
|
|
|
6. BRAND IDENTITY
|
|
The camel silhouette in the logo area, warm desert tones, and the name
|
|
"Cameleer" (one who leads camels) create a cohesive brand. The overall
|
|
feel is "premium craft tool" rather than "enterprise dashboard."
|
|
============================================================================
|
|
-->
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=1920">
|
|
<title>Cameleer — Route Execution Monitor</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<style>
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
RESET & FOUNDATIONS
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
:root {
|
|
/* ── Surface palette (warm parchment) ── */
|
|
--bg-body: #F5F2ED;
|
|
--bg-surface: #FFFFFF;
|
|
--bg-raised: #FAF8F5;
|
|
--bg-inset: #F0EDE8;
|
|
--bg-hover: #F5F0EA;
|
|
|
|
/* ── Sidebar (warm charcoal) ── */
|
|
--sidebar-bg: #2C2520;
|
|
--sidebar-hover: #3A322C;
|
|
--sidebar-active: #4A3F38;
|
|
--sidebar-text: #BFB5A8;
|
|
--sidebar-muted: #7A6F63;
|
|
|
|
/* ── Text ── */
|
|
--text-primary: #1A1612;
|
|
--text-secondary: #5C5347;
|
|
--text-muted: #9C9184;
|
|
--text-faint: #C4BAB0;
|
|
|
|
/* ── Borders ── */
|
|
--border: #E4DFD8;
|
|
--border-subtle: #EDE9E3;
|
|
|
|
/* ── Brand accent (amber-gold) ── */
|
|
--amber: #C6820E;
|
|
--amber-light: #F0D9A8;
|
|
--amber-bg: #FDF6E9;
|
|
--amber-deep: #8B5A06;
|
|
|
|
/* ── Status colors ── */
|
|
--success: #3D7C47;
|
|
--success-bg: #EFF7F0;
|
|
--success-border: #C2DFC6;
|
|
--warning: #C27516;
|
|
--warning-bg: #FEF5E7;
|
|
--warning-border: #F0D9A8;
|
|
--error: #C0392B;
|
|
--error-bg: #FDF0EE;
|
|
--error-border: #F0C4BE;
|
|
--running: #1A7F8E;
|
|
--running-bg: #E8F5F7;
|
|
--running-border: #B0DDE4;
|
|
|
|
/* ── Typography ── */
|
|
--font-body: 'DM Sans', system-ui, -apple-system, sans-serif;
|
|
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
|
|
/* ── Radii ── */
|
|
--radius-sm: 5px;
|
|
--radius-md: 8px;
|
|
--radius-lg: 12px;
|
|
|
|
/* ── Shadows ── */
|
|
--shadow-sm: 0 1px 2px rgba(44, 37, 32, 0.06);
|
|
--shadow-md: 0 2px 8px rgba(44, 37, 32, 0.08);
|
|
--shadow-lg: 0 4px 16px rgba(44, 37, 32, 0.10);
|
|
--shadow-card: 0 1px 3px rgba(44, 37, 32, 0.04), 0 0 0 1px rgba(44, 37, 32, 0.04);
|
|
}
|
|
|
|
html { font-size: 14px; }
|
|
body {
|
|
font-family: var(--font-body);
|
|
background: var(--bg-body);
|
|
color: var(--text-primary);
|
|
line-height: 1.5;
|
|
min-height: 100vh;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
SCROLLBAR
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
::-webkit-scrollbar-track { background: transparent; }
|
|
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
|
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
LAYOUT SKELETON
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.app {
|
|
display: flex;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
SIDEBAR
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.sidebar {
|
|
width: 220px;
|
|
flex-shrink: 0;
|
|
background: var(--sidebar-bg);
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.sidebar-logo {
|
|
padding: 18px 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
border-bottom: 1px solid rgba(255,255,255,0.06);
|
|
}
|
|
|
|
.sidebar-logo svg { flex-shrink: 0; }
|
|
|
|
.sidebar-logo .brand {
|
|
font-family: var(--font-mono);
|
|
font-weight: 600;
|
|
font-size: 15px;
|
|
color: var(--amber-light);
|
|
letter-spacing: -0.3px;
|
|
}
|
|
|
|
.sidebar-logo .version {
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
color: var(--sidebar-muted);
|
|
margin-left: 2px;
|
|
}
|
|
|
|
/* Sidebar search */
|
|
.sidebar-search {
|
|
padding: 12px 14px;
|
|
}
|
|
|
|
.sidebar-search input {
|
|
width: 100%;
|
|
background: rgba(255,255,255,0.06);
|
|
border: 1px solid rgba(255,255,255,0.08);
|
|
border-radius: var(--radius-sm);
|
|
padding: 7px 10px 7px 30px;
|
|
color: var(--sidebar-text);
|
|
font-family: var(--font-body);
|
|
font-size: 12px;
|
|
outline: none;
|
|
transition: border-color 0.15s;
|
|
}
|
|
|
|
.sidebar-search input::placeholder { color: var(--sidebar-muted); }
|
|
.sidebar-search input:focus { border-color: rgba(198, 130, 14, 0.4); }
|
|
|
|
.sidebar-search-wrap {
|
|
position: relative;
|
|
}
|
|
|
|
.sidebar-search-wrap .search-icon {
|
|
position: absolute;
|
|
left: 9px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
color: var(--sidebar-muted);
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* Section header */
|
|
.sidebar-section {
|
|
padding: 16px 14px 6px;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1.2px;
|
|
color: var(--sidebar-muted);
|
|
}
|
|
|
|
/* Sidebar items */
|
|
.sidebar-items {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 0 6px;
|
|
}
|
|
|
|
.sidebar-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
padding: 8px 14px;
|
|
border-radius: var(--radius-sm);
|
|
color: var(--sidebar-text);
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
transition: all 0.12s;
|
|
text-decoration: none;
|
|
border-left: 3px solid transparent;
|
|
margin-bottom: 1px;
|
|
}
|
|
|
|
.sidebar-item:hover {
|
|
background: var(--sidebar-hover);
|
|
color: #E8DFD4;
|
|
}
|
|
|
|
.sidebar-item.active {
|
|
background: var(--sidebar-active);
|
|
color: var(--amber-light);
|
|
border-left-color: var(--amber);
|
|
}
|
|
|
|
.sidebar-item .health {
|
|
width: 7px;
|
|
height: 7px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.health-live { background: #5DB866; box-shadow: 0 0 6px rgba(93, 184, 102, 0.4); }
|
|
.health-stale { background: var(--warning); }
|
|
.health-dead { background: var(--sidebar-muted); }
|
|
|
|
.sidebar-item .item-info { flex: 1; min-width: 0; }
|
|
.sidebar-item .item-name {
|
|
font-weight: 500;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.sidebar-item .item-meta {
|
|
font-size: 11px;
|
|
color: var(--sidebar-muted);
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.sidebar-item .item-count {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--sidebar-muted);
|
|
background: rgba(255,255,255,0.06);
|
|
padding: 1px 6px;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.sidebar-item.active .item-count {
|
|
background: rgba(198, 130, 14, 0.2);
|
|
color: var(--amber-light);
|
|
}
|
|
|
|
/* Sidebar divider */
|
|
.sidebar-divider {
|
|
height: 1px;
|
|
background: rgba(255,255,255,0.06);
|
|
margin: 8px 14px;
|
|
}
|
|
|
|
/* Sidebar bottom */
|
|
.sidebar-bottom {
|
|
border-top: 1px solid rgba(255,255,255,0.06);
|
|
padding: 8px 6px;
|
|
}
|
|
|
|
.sidebar-bottom .sidebar-item {
|
|
font-size: 12px;
|
|
color: var(--sidebar-muted);
|
|
border-left: 3px solid transparent;
|
|
}
|
|
|
|
.sidebar-bottom .sidebar-item:hover {
|
|
color: var(--sidebar-text);
|
|
}
|
|
|
|
.sidebar-bottom .sidebar-item .bottom-icon {
|
|
font-size: 14px;
|
|
width: 18px;
|
|
text-align: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
MAIN CONTENT AREA
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.main {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ── Top Bar ── */
|
|
.topbar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 0 28px;
|
|
height: 52px;
|
|
flex-shrink: 0;
|
|
background: var(--bg-surface);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.topbar-breadcrumb {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.topbar-breadcrumb .crumb-active {
|
|
color: var(--text-primary);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.topbar-breadcrumb .crumb-sep {
|
|
color: var(--text-faint);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.topbar-right {
|
|
margin-left: auto;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.topbar-env {
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
padding: 3px 10px;
|
|
border-radius: 10px;
|
|
background: var(--success-bg);
|
|
color: var(--success);
|
|
border: 1px solid var(--success-border);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.topbar-user {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.topbar-avatar {
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: 50%;
|
|
background: var(--amber-bg);
|
|
color: var(--amber);
|
|
font-weight: 600;
|
|
font-size: 11px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: 1px solid var(--amber-light);
|
|
}
|
|
|
|
.topbar-search {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 5px 12px;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--bg-raised);
|
|
color: var(--text-muted);
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
transition: border-color 0.15s;
|
|
min-width: 200px;
|
|
}
|
|
|
|
.topbar-search:hover { border-color: var(--text-faint); }
|
|
|
|
.topbar-kbd {
|
|
font-family: var(--font-mono);
|
|
font-size: 10px;
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border);
|
|
padding: 0 4px;
|
|
border-radius: 3px;
|
|
color: var(--text-faint);
|
|
margin-left: auto;
|
|
}
|
|
|
|
/* ── Content scroll container ── */
|
|
.content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 24px 28px 40px;
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
PAGE HEADER
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.page-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.page-header h1 {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
letter-spacing: -0.3px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.page-header .subtitle {
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.live-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 7px;
|
|
padding: 7px 16px;
|
|
border: 1px solid var(--success-border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--success-bg);
|
|
color: var(--success);
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all 0.15s;
|
|
}
|
|
|
|
.live-btn:hover {
|
|
background: #E2F0E4;
|
|
}
|
|
|
|
.live-dot {
|
|
width: 7px;
|
|
height: 7px;
|
|
border-radius: 50%;
|
|
background: var(--success);
|
|
animation: pulse 2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { box-shadow: 0 0 0 0 rgba(61, 124, 71, 0.35); }
|
|
50% { box-shadow: 0 0 0 5px rgba(61, 124, 71, 0); }
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
FILTER BAR
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.filter-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 16px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.filter-input-wrap {
|
|
position: relative;
|
|
flex: 1;
|
|
max-width: 360px;
|
|
}
|
|
|
|
.filter-input-wrap .fi-icon {
|
|
position: absolute;
|
|
left: 10px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
color: var(--text-faint);
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-input {
|
|
width: 100%;
|
|
padding: 8px 12px 8px 32px;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--bg-surface);
|
|
color: var(--text-primary);
|
|
font-family: var(--font-body);
|
|
font-size: 13px;
|
|
outline: none;
|
|
transition: border-color 0.15s;
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.filter-input::placeholder { color: var(--text-faint); }
|
|
.filter-input:focus { border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-bg); }
|
|
|
|
.filter-pills {
|
|
display: flex;
|
|
gap: 4px;
|
|
}
|
|
|
|
.filter-pill {
|
|
padding: 6px 14px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 20px;
|
|
background: var(--bg-surface);
|
|
color: var(--text-secondary);
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all 0.12s;
|
|
white-space: nowrap;
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.filter-pill:hover {
|
|
border-color: var(--text-faint);
|
|
background: var(--bg-raised);
|
|
}
|
|
|
|
.filter-pill.active {
|
|
background: var(--amber-bg);
|
|
border-color: var(--amber-light);
|
|
color: var(--amber-deep);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.filter-pill .pill-count {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
margin-left: 4px;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.filter-pill.active .pill-count { opacity: 1; }
|
|
|
|
.filter-select {
|
|
padding: 7px 28px 7px 10px;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--bg-surface);
|
|
color: var(--text-secondary);
|
|
font-family: var(--font-body);
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
outline: none;
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239C9184' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 10px center;
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
STATS BAR
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.stats-bar {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.stat-card {
|
|
flex: 1;
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: var(--radius-md);
|
|
padding: 14px 18px;
|
|
box-shadow: var(--shadow-card);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 14px;
|
|
transition: box-shadow 0.15s;
|
|
}
|
|
|
|
.stat-card:hover {
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
.stat-icon {
|
|
width: 38px;
|
|
height: 38px;
|
|
border-radius: var(--radius-md);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 16px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.stat-icon.total { background: var(--bg-inset); color: var(--text-secondary); }
|
|
.stat-icon.success { background: var(--success-bg); color: var(--success); }
|
|
.stat-icon.warning { background: var(--warning-bg); color: var(--warning); }
|
|
.stat-icon.error { background: var(--error-bg); color: var(--error); }
|
|
.stat-icon.duration { background: var(--running-bg); color: var(--running); }
|
|
|
|
.stat-info { min-width: 0; }
|
|
|
|
.stat-label {
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.6px;
|
|
color: var(--text-muted);
|
|
margin-bottom: 1px;
|
|
}
|
|
|
|
.stat-value {
|
|
font-family: var(--font-mono);
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.stat-value.success-val { color: var(--success); }
|
|
.stat-value.warning-val { color: var(--warning); }
|
|
.stat-value.error-val { color: var(--error); }
|
|
|
|
.stat-trend {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--success);
|
|
margin-top: 1px;
|
|
}
|
|
|
|
.stat-trend.down { color: var(--error); }
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
EXECUTION TABLE
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.table-section {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-card);
|
|
overflow: hidden;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.table-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 12px 18px;
|
|
border-bottom: 1px solid var(--border-subtle);
|
|
}
|
|
|
|
.table-title {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.table-meta {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
thead {
|
|
background: var(--bg-raised);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
th {
|
|
padding: 10px 16px;
|
|
text-align: left;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.8px;
|
|
color: var(--text-muted);
|
|
white-space: nowrap;
|
|
user-select: none;
|
|
cursor: pointer;
|
|
transition: color 0.12s;
|
|
}
|
|
|
|
th:hover { color: var(--text-secondary); }
|
|
|
|
th.sorted {
|
|
color: var(--amber);
|
|
}
|
|
|
|
th .sort-arrow {
|
|
font-size: 8px;
|
|
margin-left: 3px;
|
|
opacity: 0.4;
|
|
}
|
|
|
|
th.sorted .sort-arrow { opacity: 1; }
|
|
|
|
tr {
|
|
border-bottom: 1px solid var(--border-subtle);
|
|
transition: background 0.08s;
|
|
cursor: pointer;
|
|
}
|
|
|
|
tr:last-child { border-bottom: none; }
|
|
tr:hover { background: var(--bg-hover); }
|
|
|
|
td {
|
|
padding: 10px 16px;
|
|
font-size: 13px;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.td-route {
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.td-route:hover { color: var(--amber); }
|
|
|
|
.td-mono {
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.td-id {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--text-muted);
|
|
max-width: 120px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.td-group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.td-group-dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: var(--amber);
|
|
}
|
|
|
|
/* Status badges */
|
|
.status-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
padding: 3px 10px;
|
|
border-radius: 12px;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.2px;
|
|
}
|
|
|
|
.status-success {
|
|
background: var(--success-bg);
|
|
color: var(--success);
|
|
border: 1px solid var(--success-border);
|
|
}
|
|
|
|
.status-warning {
|
|
background: var(--warning-bg);
|
|
color: var(--warning);
|
|
border: 1px solid var(--warning-border);
|
|
}
|
|
|
|
.status-error {
|
|
background: var(--error-bg);
|
|
color: var(--error);
|
|
border: 1px solid var(--error-border);
|
|
}
|
|
|
|
.status-running {
|
|
background: var(--running-bg);
|
|
color: var(--running);
|
|
border: 1px solid var(--running-border);
|
|
}
|
|
|
|
.status-dot {
|
|
width: 5px;
|
|
height: 5px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.status-success .status-dot { background: var(--success); }
|
|
.status-warning .status-dot { background: var(--warning); }
|
|
.status-error .status-dot { background: var(--error); }
|
|
.status-running .status-dot { background: var(--running); animation: pulse-sm 1.5s ease-in-out infinite; }
|
|
|
|
@keyframes pulse-sm {
|
|
0%, 100% { box-shadow: 0 0 0 0 rgba(26, 127, 142, 0.3); }
|
|
50% { box-shadow: 0 0 0 3px rgba(26, 127, 142, 0); }
|
|
}
|
|
|
|
/* Duration bar (visual sparkline in duration column) */
|
|
.duration-bar-wrap {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.duration-bar {
|
|
width: 60px;
|
|
height: 4px;
|
|
background: var(--bg-inset);
|
|
border-radius: 2px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.duration-bar-fill {
|
|
height: 100%;
|
|
border-radius: 2px;
|
|
background: var(--running);
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
.duration-bar-fill.fast { background: var(--success); }
|
|
.duration-bar-fill.medium { background: var(--warning); }
|
|
.duration-bar-fill.slow { background: var(--error); }
|
|
|
|
/* Pagination */
|
|
.table-footer {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 10px 18px;
|
|
border-top: 1px solid var(--border-subtle);
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.pagination {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.page-btn {
|
|
padding: 4px 10px;
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
background: var(--bg-surface);
|
|
color: var(--text-secondary);
|
|
font-size: 12px;
|
|
font-family: var(--font-mono);
|
|
cursor: pointer;
|
|
transition: all 0.12s;
|
|
}
|
|
|
|
.page-btn:hover { background: var(--bg-raised); border-color: var(--text-faint); }
|
|
.page-btn.active {
|
|
background: var(--amber-bg);
|
|
border-color: var(--amber-light);
|
|
color: var(--amber-deep);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
METRICS PANEL
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.metrics-row {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
gap: 16px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.metric-card {
|
|
background: var(--bg-surface);
|
|
border: 1px solid var(--border-subtle);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-card);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.metric-card-header {
|
|
padding: 14px 18px 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.metric-card-title {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--text-secondary);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.metric-card-value {
|
|
font-family: var(--font-mono);
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.metric-chart {
|
|
padding: 12px 18px 14px;
|
|
height: 100px;
|
|
position: relative;
|
|
}
|
|
|
|
/* SVG Chart styling */
|
|
.chart-line {
|
|
fill: none;
|
|
stroke-width: 2;
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
}
|
|
|
|
.chart-area {
|
|
opacity: 0.12;
|
|
}
|
|
|
|
.chart-grid-line {
|
|
stroke: var(--border-subtle);
|
|
stroke-width: 1;
|
|
stroke-dasharray: 3 3;
|
|
}
|
|
|
|
.chart-label {
|
|
font-family: var(--font-mono);
|
|
font-size: 9px;
|
|
fill: var(--text-faint);
|
|
}
|
|
|
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
UTILITY CLASSES
|
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
.mono { font-family: var(--font-mono); }
|
|
.text-muted { color: var(--text-muted); }
|
|
.text-secondary { color: var(--text-secondary); }
|
|
.flex-center { display: flex; align-items: center; }
|
|
|
|
/* Fade-in animation */
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(6px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.animate-in {
|
|
animation: fadeIn 0.35s ease-out both;
|
|
}
|
|
|
|
.delay-1 { animation-delay: 0.04s; }
|
|
.delay-2 { animation-delay: 0.08s; }
|
|
.delay-3 { animation-delay: 0.12s; }
|
|
.delay-4 { animation-delay: 0.16s; }
|
|
.delay-5 { animation-delay: 0.20s; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="app">
|
|
<!-- ═══════════════════════════════════════════════════════════════════
|
|
SIDEBAR
|
|
═══════════════════════════════════════════════════════════════════ -->
|
|
<aside class="sidebar">
|
|
<div class="sidebar-logo">
|
|
<svg width="24" height="26" viewBox="940 300 900 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path style="fill:#C6820E" d="M 1385.2768,1205.0273 c -1.7727,-1.0809 -3.4419,-2.9917 -3.7093,-4.2463 -0.2674,-1.2545 -0.6851,-23.881 -0.9282,-50.281 -0.4544,-49.3389 -1.4003,-65.7355 -5.6645,-98.1921 -10.4552,-79.57719 -28.3441,-125.96796 -62.5438,-162.19311 -9.2529,-9.80096 -19.9748,-18.38696 -33.931,-27.17162 -12.6119,-7.93853 -24.8581,-13.73088 -49.5,-23.41316 -41.7081,-16.38789 -67.8677,-32.29827 -89.0588,-54.16599 -34.7586,-35.86827 -54.3653,-83.30392 -59.0504,-142.86402 -0.8357,-10.6245 -0.92,-22.5842 -0.2891,-41 0.4899,-14.3 0.8164,-35.225 0.7255,-46.5 -0.1983,-24.59199 -2.0251,-34.76973 -8.4617,-47.14159 -6.2021,-11.92135 -10.364,-15.10789 -36.2345,-27.74305 -25.4032,-12.40694 -27.7701,-13.30168 -35.4717,-13.40961 -4.63013,-0.0649 -7.47783,0.72754 -15.6593,4.35747 -9.86218,4.37563 -10.15161,4.43672 -21,4.43267 -10.86566,-0.004 -11.08917,-0.0517 -18.30169,-3.90103 -17.43524,-9.3052 -21.50075,-23.5772 -13.55784,-47.59486 2.73631,-8.27402 10.00732,-22.43593 14.69263,-28.61719 5.4984,-7.25394 10.89014,-11.83885 20.83968,-17.72117 15.06768,-8.90827 29.60254,-11.98884 63.90372,-13.54403 l 16.5765,-0.75156 14.9235,-7.05735 c 8.2079,-3.88154 17.1735,-7.76831 19.9235,-8.63727 7.7052,-2.43474 21.059,-4.67186 27.8605,-4.66741 8.0518,0.005 22.643,2.41202 30.0139,4.95066 l 5.8744,2.02321 4.8856,-4.09041 c 10.341,-8.65797 18.6496,-12.95738 28.96,-14.98583 6.9966,-1.37649 26.3532,-0.64631 32.1116,1.21134 4.5531,1.46885 5.4951,3.7902 6.3689,15.69592 1.5167,20.66426 -5.0112,40.44987 -18.1772,55.09363 -4.3065,4.78983 -4.5016,5.25488 -3.4977,8.33516 4.5184,13.86447 5.3154,38.07517 2.1537,65.42564 -5.169,44.71349 -5.0411,70.7797 0.5404,110.15637 6.8135,48.06863 22.3335,73.51874 48.2051,79.04779 24.1748,5.16643 45.2921,-5.78181 66.8353,-34.65077 4.809,-6.4442 11.1363,-14.93006 14.0608,-18.85747 7.3865,-9.91943 25.6102,-27.11708 35.952,-33.92766 12.5235,-8.24739 26.8808,-14.74833 42.8527,-19.40354 15.4108,-4.49168 26.7091,-9.74984 36.2432,-16.86731 3.4338,-2.56341 13.3338,-12.03104 22,-21.03916 26.2356,-27.27067 44.5755,-40.32368 66.9928,-47.68062 19.1052,-6.26998 35.4927,-7.73718 50.8681,-4.55427 37.0856,7.67726 63.5507,26.77589 100.2888,72.37362 16.6011,20.60463 29.9711,32.07977 51.6071,44.29313 39.3131,22.19195 50.1228,30.50985 68.8076,52.94655 5.4963,6.6 12.9187,14.91604 16.4941,18.4801 33.6796,33.57259 54.1965,72.51092 61.6587,117.0199 2.7315,16.29242 3.3374,26.62538 3.1861,54.33713 l -0.1465,26.83714 -2.7975,2.40572 c -3.9132,3.36522 -7.2806,3.99163 -11.2591,2.09442 -6.4731,-3.08682 -6.5715,-3.57833 -6.878,-34.36929 -0.2908,-29.2175 -2.0265,-46.13705 -6.6479,-64.80512 -3.2997,-13.32891 -12.2529,-34.61943 -17.0313,-40.5 l -2.0314,-2.5 0.5698,3.5 c 5.8574,35.97875 4.2855,72.40287 -5.3946,125 -8.4016,45.65054 -4.3665,69.39588 20.7318,122 11.4175,23.93009 12.5452,27.25907 12.4212,36.6684 -0.1018,7.7227 -2.5346,19.5162 -13.1674,63.8316 -1.0558,4.4 -3.5336,14.975 -5.5063,23.5 -1.9727,8.525 -4.2259,18.2 -5.0072,21.5 -0.7812,3.3 -3.4495,15.225 -5.9296,26.5 -9.1636,41.6596 -13.4372,59.8787 -14.5204,61.9027 -2.4994,4.6702 -5.2312,5.0973 -32.6024,5.0973 H 1765.8 l -3.4,-3.4 c -2.3518,-2.3518 -3.4,-4.3226 -3.4,-6.3925 0,-1.6458 2.2347,-12.1533 4.966,-23.35 8.6906,-35.6259 11.6969,-54.778 12.6921,-80.8575 1.3475,-35.3073 -4.6406,-62.7687 -18.7825,-86.137 -7.6672,-12.66954 -11.9163,-17.84148 -29.8756,-36.36415 -22.9362,-23.65574 -34.6222,-39.72583 -47.9268,-65.90697 -5.7294,-11.27448 -13.6061,-31.99995 -15.5051,-40.79778 -0.3212,-1.48824 -1.0176,-3.84619 -1.5475,-5.2399 l -0.9634,-2.534 -11.7786,7.15145 c -38.634,23.45687 -74.5513,34.71091 -124.1895,38.91257 -14.5402,1.23075 -58.2359,0.66344 -71.9142,-0.93369 -5.4419,-0.63542 -6.4542,-0.49723 -7.25,0.98972 -0.5545,1.03621 -0.9249,60.63835 -0.9249,148.84365 0,161.6262 0.4025,151.2052 -5.9673,154.4992 -2.3865,1.2341 -7.4633,1.5162 -27.233,1.5132 -22.3926,-0 -24.5527,-0.158 -27.5229,-1.969 z M 1424,1045.6452 c 0,-87.21053 0.3878,-144.17994 1.0365,-152.24998 1.8115,-22.53829 7.2373,-44.8067 16.1142,-66.13567 20.7842,-49.93942 66.8961,-95.01414 129.8493,-126.92865 14.9469,-7.57742 29.2834,-13.56192 41.5,-17.32336 3.85,-1.1854 7.9,-2.55654 9,-3.04699 6.0644,-2.70386 29.8837,-6.94397 39.0685,-6.95465 16.5354,-0.0192 29.4209,10.53866 32.4491,26.58755 1.5763,8.35375 1.0812,11.63345 -4.5147,29.90655 -10.1916,33.28037 -13.3229,61.96134 -10.0442,92 3.2262,29.55737 10.5673,53.87028 23.6898,78.45848 11.023,20.65405 21.7624,35.21113 38.7623,52.54152 17.2909,17.62693 24.0427,25.40931 30.3653,35 26.0619,39.5327 33.1081,82.6442 23.6173,144.5 -1.6936,11.0379 -7.1852,37.5413 -10.412,50.25 l -0.6982,2.75 h 11.041 c 9.6675,0 11.1002,-0.2177 11.5165,-1.75 0.2615,-0.9625 1.1691,-4.9 2.0169,-8.75 4.2214,-19.1689 6.8202,-30.513 8.1326,-35.5 1.361,-5.1717 9.3524,-39.8413 18.5555,-80.5 2.2408,-9.9 5.3554,-23.4 6.9213,-30 4.9646,-20.9246 5.3189,-23.3077 4.1531,-27.9371 -0.5856,-2.32595 -4.0498,-10.49161 -7.6981,-18.14594 -9.222,-19.34804 -12.2871,-26.05688 -14.0769,-30.8114 -5.3001,-14.07878 -9.5733,-27.65251 -11.9961,-38.10556 -2.5547,-11.02237 -2.7797,-13.62939 -2.7612,-32 0.019,-19.36303 0.1714,-20.85991 4.7729,-47 6.161,-34.99931 7.6003,-48.16042 7.6003,-69.5 -10e-5,-33.76835 -6.5703,-63.86472 -19.8286,-90.82854 -6.3511,-12.91659 -11.7543,-20.74668 -21.037,-30.48614 -12.8375,-13.46928 -22.9472,-20.76621 -47.0954,-33.9923 -11.7394,-6.42975 -28.8576,-17.82564 -36.5,-24.2987 -10.6672,-9.03504 -17.2351,-15.91058 -32.8553,-34.39432 -16.848,-19.93653 -31.9446,-35.04489 -42.6447,-42.67772 -10.3431,-7.37816 -15.6552,-10.10769 -28,-14.38707 -9.1747,-3.18048 -10.0479,-3.29466 -25.5,-3.33475 -15.5657,-0.0404 -16.2561,0.0478 -25.4354,3.24965 -23.091,8.0544 -33.3943,15.26018 -59.5646,41.65777 -30.5973,30.86299 -38.6661,35.8414 -77,47.50846 -16.2269,4.93872 -34.1287,15.69697 -44.617,26.81301 -10.992,11.6499 -13.307,14.35965 -22.3589,26.17065 -19.0735,24.88726 -27.0799,33.14259 -41.0241,42.29946 -10.0586,6.60527 -20.3327,9.75956 -33.9507,10.42334 -37.2243,1.81441 -62.5379,-17.55119 -76.1054,-58.2228 -11.652,-34.92922 -16.8948,-93.36051 -12.158,-135.5 5.892,-52.41494 5.8488,-63.62373 -0.3099,-80.57433 -4.7448,-13.05916 -4.7675,-12.96705 5.716,-23.17933 5.7642,-5.61509 9.7601,-10.45668 11.1613,-13.52373 2.7419,-6.00142 5.1126,-15.9207 5.1319,-21.47261 L 1198,352 l -5.9651,0 c -11.169,0 -21.7558,5.31928 -28.8986,14.51992 -5.5094,7.09667 -9.8889,9.41118 -14.4261,7.62413 -22.7413,-8.95689 -39.8334,-10.59845 -57.5511,-5.52733 -3.1125,0.89085 -11.6238,4.5155 -18.9141,8.05478 -15.4059,7.47927 -22.5958,9.28006 -37.245,9.32847 -31.9108,0.10543 -56.25892,6.94953 -67.17127,18.88141 -8.24539,9.01574 -18.57001,32.98439 -17.63456,40.9387 0.20038,1.70385 1.68501,3.56683 4.30583,5.40313 6.15036,4.30931 11.64453,4.02586 24.53725,-1.26587 9.37877,-3.84945 11.49879,-4.33904 20.46275,-4.7256 12.5127,-0.5396 16.1351,0.57224 41.5,12.73763 28.326,13.58558 38.6034,16.26339 54.7762,14.27212 10.7814,-1.32746 19.6601,-4.77604 26.9813,-10.47981 10.8957,-8.48862 12.7264,-9.11418 18.2752,-6.24475 3.4802,1.79966 5.9673,6.17527 5.9673,10.49833 0,5.2273 -12.3619,16.07427 -24.373,21.38616 -8.3575,3.69608 -19.5481,6.59858 -25.4408,6.59858 -2.8524,0 -5.1862,0.40847 -5.1862,0.90771 0,0.49925 1.1261,3.08675 2.5024,5.75 7.4849,14.48347 10.3469,40.93277 8.5814,79.30477 -1.8809,40.87852 -1.063,65.17107 3.0314,90.03752 1.9205,11.66347 7.4026,31.07934 11.5058,40.75 3.6541,8.61199 4.8919,11.32366 8.5592,18.75 7.5496,15.28823 16.3315,27.16362 30.7439,41.57393 20.487,20.48403 39.3629,32.17675 72.4974,44.90876 32.2544,12.39381 46.3332,19.15119 64.0627,30.7482 24.2965,15.89251 40.6199,31.86253 55.9811,54.76911 15.3367,22.87022 26.7091,49.93352 35.5759,84.66142 7.4833,29.30908 14.5942,79.14828 16.5733,116.15948 0.3771,7.0514 0.7727,14.0264 0.879,15.5 0.1064,1.4735 0.2639,17.1916 0.35,34.9291 L 1403,1185 h 10.5 10.5 z m 109.6148,-166.12974 c 32.3584,-3.61532 59.7448,-11.3892 85.9116,-24.38672 13.8501,-6.87965 33.6049,-18.83328 37.1094,-22.455 0.7986,-0.82533 0.878,-3.10315 0.2676,-7.67374 -0.4775,-3.575 -0.9114,-15.05 -0.9643,-25.5 -0.1555,-30.74924 3.0015,-49.74257 13.6751,-82.27105 3.3477,-10.20267 3.1984,-15.57022 -0.5373,-19.30587 -2.563,-2.563 -3.6408,-2.92269 -8.75,-2.91989 -17.9704,0.01 -50.057,9.8542 -78.4604,24.07205 -31.505,15.77045 -56.5528,33.57164 -78.5866,55.85076 -22.9969,23.25282 -37.4392,45.78809 -46.737,72.92624 -3.3375,9.74165 -8.0905,29.93345 -7.2451,30.77886 2.3874,2.38739 64.9877,3.04398 84.317,0.88436 z"/>
|
|
</svg>
|
|
<div>
|
|
<span class="brand">cameleer</span><span class="version">v3</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="sidebar-search">
|
|
<div class="sidebar-search-wrap">
|
|
<span class="search-icon">◊</span>
|
|
<input type="text" placeholder="Filter applications...">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="sidebar-section">Applications</div>
|
|
|
|
<div class="sidebar-items">
|
|
<div class="sidebar-item">
|
|
<span class="health health-live"></span>
|
|
<div class="item-info">
|
|
<div class="item-name">All Applications</div>
|
|
</div>
|
|
<span class="item-count">3</span>
|
|
</div>
|
|
|
|
<div style="height: 1px; background: rgba(255,255,255,0.06); margin: 4px 14px;"></div>
|
|
|
|
<div class="sidebar-item active">
|
|
<span class="health health-live"></span>
|
|
<div class="item-info">
|
|
<div class="item-name">order-service</div>
|
|
<div class="item-meta">2 instances</div>
|
|
</div>
|
|
<span class="item-count">847</span>
|
|
</div>
|
|
|
|
<div class="sidebar-item">
|
|
<span class="health health-live"></span>
|
|
<div class="item-info">
|
|
<div class="item-name">payment-gateway</div>
|
|
<div class="item-meta">1 instance</div>
|
|
</div>
|
|
<span class="item-count">312</span>
|
|
</div>
|
|
|
|
<div class="sidebar-item">
|
|
<span class="health health-stale"></span>
|
|
<div class="item-info">
|
|
<div class="item-name">notification-hub</div>
|
|
<div class="item-meta">1 instance</div>
|
|
</div>
|
|
<span class="item-count">45</span>
|
|
</div>
|
|
|
|
<div class="sidebar-section">Routes</div>
|
|
|
|
<div class="sidebar-item" style="padding-left: 24px;">
|
|
<span style="color: var(--sidebar-muted); font-size: 11px;">▸</span>
|
|
<div class="item-info">
|
|
<div class="item-name">order-processing</div>
|
|
</div>
|
|
<span class="item-count">523</span>
|
|
</div>
|
|
|
|
<div class="sidebar-item" style="padding-left: 24px;">
|
|
<span style="color: var(--sidebar-muted); font-size: 11px;">▸</span>
|
|
<div class="item-info">
|
|
<div class="item-name">order-validation</div>
|
|
</div>
|
|
<span class="item-count">215</span>
|
|
</div>
|
|
|
|
<div class="sidebar-item" style="padding-left: 24px;">
|
|
<span style="color: var(--sidebar-muted); font-size: 11px;">▸</span>
|
|
<div class="item-info">
|
|
<div class="item-name">inventory-check</div>
|
|
</div>
|
|
<span class="item-count">109</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="sidebar-bottom">
|
|
<div class="sidebar-item">
|
|
<span class="bottom-icon">•</span>
|
|
<div class="item-info"><div class="item-name">Route Diagrams</div></div>
|
|
</div>
|
|
<div class="sidebar-item">
|
|
<span class="bottom-icon">⚙</span>
|
|
<div class="item-info"><div class="item-name">Admin</div></div>
|
|
</div>
|
|
<div class="sidebar-item">
|
|
<span class="bottom-icon">«»</span>
|
|
<div class="item-info"><div class="item-name">API Docs</div></div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════════════
|
|
MAIN
|
|
═══════════════════════════════════════════════════════════════════ -->
|
|
<div class="main">
|
|
<!-- Top bar -->
|
|
<div class="topbar">
|
|
<div class="topbar-breadcrumb">
|
|
<span>Applications</span>
|
|
<span class="crumb-sep">/</span>
|
|
<span class="crumb-active">order-service</span>
|
|
</div>
|
|
|
|
<div class="topbar-search">
|
|
<span style="font-size: 13px; color: var(--text-faint);">🔎︎</span>
|
|
<span>Search executions...</span>
|
|
<span class="topbar-kbd">Ctrl+K</span>
|
|
</div>
|
|
|
|
<div class="topbar-right">
|
|
<span class="topbar-env">PRODUCTION</span>
|
|
<div class="topbar-user">
|
|
<span>hendrik</span>
|
|
<div class="topbar-avatar">H</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="content">
|
|
<!-- Page header -->
|
|
<div class="page-header animate-in">
|
|
<div>
|
|
<h1>Execution Explorer</h1>
|
|
<div class="subtitle">order-service — last 24 hours</div>
|
|
</div>
|
|
<button class="live-btn">
|
|
<span class="live-dot"></span>
|
|
LIVE
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Filter bar -->
|
|
<div class="filter-bar animate-in delay-1">
|
|
<div class="filter-input-wrap">
|
|
<span class="fi-icon">🔎︎</span>
|
|
<input class="filter-input" type="text" placeholder="Search by route, correlation ID, body content...">
|
|
</div>
|
|
|
|
<div class="filter-pills">
|
|
<div class="filter-pill active">All<span class="pill-count">1,204</span></div>
|
|
<div class="filter-pill">
|
|
<span style="color: var(--success);">•</span> Success<span class="pill-count">1,142</span>
|
|
</div>
|
|
<div class="filter-pill">
|
|
<span style="color: var(--warning);">•</span> Warning<span class="pill-count">38</span>
|
|
</div>
|
|
<div class="filter-pill">
|
|
<span style="color: var(--error);">•</span> Error<span class="pill-count">7</span>
|
|
</div>
|
|
<div class="filter-pill">
|
|
<span style="color: var(--running);">•</span> Running<span class="pill-count">17</span>
|
|
</div>
|
|
</div>
|
|
|
|
<select class="filter-select">
|
|
<option>Last 24 hours</option>
|
|
<option>Last 1 hour</option>
|
|
<option>Last 7 days</option>
|
|
<option>Custom range</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Stats bar -->
|
|
<div class="stats-bar animate-in delay-2">
|
|
<div class="stat-card">
|
|
<div class="stat-icon total">∑</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">Total</div>
|
|
<div class="stat-value">1,204</div>
|
|
<div class="stat-trend">+12% vs yesterday</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon success">✓</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">Success</div>
|
|
<div class="stat-value success-val">1,142</div>
|
|
<div class="stat-trend">94.8% rate</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon warning">⚠</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">Warnings</div>
|
|
<div class="stat-value warning-val">38</div>
|
|
<div class="stat-trend down">+5 vs yesterday</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon error">✗</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">Errors</div>
|
|
<div class="stat-value error-val">7</div>
|
|
<div class="stat-trend">0.58% rate</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-icon duration">⏱</div>
|
|
<div class="stat-info">
|
|
<div class="stat-label">Avg Duration</div>
|
|
<div class="stat-value">247<span style="font-size:13px; font-weight:400; color: var(--text-muted)">ms</span></div>
|
|
<div class="stat-trend">-8% vs yesterday</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Execution table -->
|
|
<div class="table-section animate-in delay-3">
|
|
<div class="table-header">
|
|
<span class="table-title">Recent Executions</span>
|
|
<span class="table-meta">Showing 1–20 of 1,204</span>
|
|
</div>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Route</th>
|
|
<th>Application</th>
|
|
<th class="sorted">Started <span class="sort-arrow">▼</span></th>
|
|
<th>Duration</th>
|
|
<th>Correlation ID</th>
|
|
<th>Processors</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
|
<td class="td-route">order-processing</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:47.182</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">124ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 25%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">a8f3e2d1-4b5c</td>
|
|
<td class="td-mono">12</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-running"><span class="status-dot"></span>Running</span></td>
|
|
<td class="td-route">payment-flow</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:45.903</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">1.2s</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill" style="width: 60%; background: var(--running);"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">b7c2a1f0-9d8e</td>
|
|
<td class="td-mono">8/15</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
|
<td class="td-route">order-validation</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:44.571</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">89ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 18%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">c6d1b0a9-7f3e</td>
|
|
<td class="td-mono">7</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-warning"><span class="status-dot"></span>Warning</span></td>
|
|
<td class="td-route">inventory-check</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:42.008</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">892ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill medium" style="width: 55%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">d5e0c9b8-6a2d</td>
|
|
<td class="td-mono">9</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
|
<td class="td-route">order-processing</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:39.245</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">156ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 30%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">e4f9d8c7-5b1c</td>
|
|
<td class="td-mono">12</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-error"><span class="status-dot"></span>Error</span></td>
|
|
<td class="td-route">shipment-notify</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:37.891</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">2.4s</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill slow" style="width: 90%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">f3a8b7c6-4d0e</td>
|
|
<td class="td-mono">5/11</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
|
<td class="td-route">payment-flow</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:35.124</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">341ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 40%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">a2b7c6d5-3e9f</td>
|
|
<td class="td-mono">15</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
|
<td class="td-route">order-processing</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:33.567</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">98ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 20%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">b1c6d5e4-2f8a</td>
|
|
<td class="td-mono">12</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-running"><span class="status-dot"></span>Running</span></td>
|
|
<td class="td-route">order-processing</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:31.230</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">2.8s</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill" style="width: 75%; background: var(--running);"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">c0d5e4f3-1a7b</td>
|
|
<td class="td-mono">10/12</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="status-badge status-success"><span class="status-dot"></span>Success</span></td>
|
|
<td class="td-route">order-validation</td>
|
|
<td><div class="td-group"><span class="td-group-dot"></span> order-service</div></td>
|
|
<td class="td-mono">14:23:28.892</td>
|
|
<td>
|
|
<div class="duration-bar-wrap">
|
|
<span class="td-mono">67ms</span>
|
|
<div class="duration-bar"><div class="duration-bar-fill fast" style="width: 14%"></div></div>
|
|
</div>
|
|
</td>
|
|
<td class="td-id">d9e4f3a2-0b6c</td>
|
|
<td class="td-mono">7</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="table-footer">
|
|
<span class="mono" style="font-size: 12px;">20 rows per page</span>
|
|
<div class="pagination">
|
|
<button class="page-btn">‹</button>
|
|
<button class="page-btn active">1</button>
|
|
<button class="page-btn">2</button>
|
|
<button class="page-btn">3</button>
|
|
<button class="page-btn">...</button>
|
|
<button class="page-btn">61</button>
|
|
<button class="page-btn">›</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Metrics panel -->
|
|
<div class="metrics-row animate-in delay-4">
|
|
<!-- Throughput chart -->
|
|
<div class="metric-card">
|
|
<div class="metric-card-header">
|
|
<span class="metric-card-title">Throughput</span>
|
|
<span class="metric-card-value">52<span style="font-size:11px; font-weight:400; color: var(--text-muted)">/min</span></span>
|
|
</div>
|
|
<div class="metric-chart">
|
|
<svg width="100%" height="100%" viewBox="0 0 300 70" preserveAspectRatio="none">
|
|
<!-- Grid lines -->
|
|
<line x1="0" y1="17.5" x2="300" y2="17.5" class="chart-grid-line"/>
|
|
<line x1="0" y1="35" x2="300" y2="35" class="chart-grid-line"/>
|
|
<line x1="0" y1="52.5" x2="300" y2="52.5" class="chart-grid-line"/>
|
|
<!-- Area fill -->
|
|
<path d="M0,55 L20,48 40,50 60,42 80,38 100,35 120,30 140,32 160,25 180,22 200,28 220,20 240,15 260,18 280,12 300,10 L300,70 L0,70 Z"
|
|
fill="#C6820E" class="chart-area"/>
|
|
<!-- Line -->
|
|
<path d="M0,55 L20,48 40,50 60,42 80,38 100,35 120,30 140,32 160,25 180,22 200,28 220,20 240,15 260,18 280,12 300,10"
|
|
stroke="#C6820E" class="chart-line"/>
|
|
<!-- Labels -->
|
|
<text x="0" y="68" class="chart-label">12:00</text>
|
|
<text x="145" y="68" class="chart-label">13:00</text>
|
|
<text x="290" y="68" class="chart-label">14:00</text>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Error rate chart -->
|
|
<div class="metric-card">
|
|
<div class="metric-card-header">
|
|
<span class="metric-card-title">Error Rate</span>
|
|
<span class="metric-card-value" style="color: var(--error);">0.58<span style="font-size:11px; font-weight:400; color: var(--text-muted)">%</span></span>
|
|
</div>
|
|
<div class="metric-chart">
|
|
<svg width="100%" height="100%" viewBox="0 0 300 70" preserveAspectRatio="none">
|
|
<line x1="0" y1="17.5" x2="300" y2="17.5" class="chart-grid-line"/>
|
|
<line x1="0" y1="35" x2="300" y2="35" class="chart-grid-line"/>
|
|
<line x1="0" y1="52.5" x2="300" y2="52.5" class="chart-grid-line"/>
|
|
<!-- Bar chart for errors -->
|
|
<rect x="5" y="60" width="14" height="10" rx="2" fill="var(--error-border)"/>
|
|
<rect x="25" y="55" width="14" height="15" rx="2" fill="var(--error-border)"/>
|
|
<rect x="45" y="62" width="14" height="8" rx="2" fill="var(--error-border)"/>
|
|
<rect x="65" y="58" width="14" height="12" rx="2" fill="var(--error-border)"/>
|
|
<rect x="85" y="65" width="14" height="5" rx="2" fill="var(--error-border)"/>
|
|
<rect x="105" y="63" width="14" height="7" rx="2" fill="var(--error-border)"/>
|
|
<rect x="125" y="60" width="14" height="10" rx="2" fill="var(--error-border)"/>
|
|
<rect x="145" y="45" width="14" height="25" rx="2" fill="var(--error)"/>
|
|
<rect x="165" y="55" width="14" height="15" rx="2" fill="var(--error-border)"/>
|
|
<rect x="185" y="58" width="14" height="12" rx="2" fill="var(--error-border)"/>
|
|
<rect x="205" y="63" width="14" height="7" rx="2" fill="var(--error-border)"/>
|
|
<rect x="225" y="60" width="14" height="10" rx="2" fill="var(--error-border)"/>
|
|
<rect x="245" y="55" width="14" height="15" rx="2" fill="var(--error-border)"/>
|
|
<rect x="265" y="50" width="14" height="20" rx="2" fill="var(--error)"/>
|
|
<rect x="285" y="58" width="14" height="12" rx="2" fill="var(--error-border)"/>
|
|
<text x="0" y="68" class="chart-label">12:00</text>
|
|
<text x="145" y="68" class="chart-label">13:00</text>
|
|
<text x="290" y="68" class="chart-label">14:00</text>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Latency chart -->
|
|
<div class="metric-card">
|
|
<div class="metric-card-header">
|
|
<span class="metric-card-title">P95 Latency</span>
|
|
<span class="metric-card-value">412<span style="font-size:11px; font-weight:400; color: var(--text-muted)">ms</span></span>
|
|
</div>
|
|
<div class="metric-chart">
|
|
<svg width="100%" height="100%" viewBox="0 0 300 70" preserveAspectRatio="none">
|
|
<line x1="0" y1="17.5" x2="300" y2="17.5" class="chart-grid-line"/>
|
|
<line x1="0" y1="35" x2="300" y2="35" class="chart-grid-line"/>
|
|
<line x1="0" y1="52.5" x2="300" y2="52.5" class="chart-grid-line"/>
|
|
<!-- P95 area -->
|
|
<path d="M0,35 L20,32 40,38 60,30 80,25 100,28 120,35 140,40 160,32 180,28 200,22 220,30 240,25 260,20 280,28 300,25 L300,70 L0,70 Z"
|
|
fill="#1A7F8E" class="chart-area"/>
|
|
<!-- P50 line -->
|
|
<path d="M0,50 L20,48 40,52 60,45 80,42 100,46 120,50 140,52 160,47 180,44 200,40 220,45 240,42 260,38 280,43 300,40"
|
|
stroke="#1A7F8E" stroke-opacity="0.4" class="chart-line" stroke-dasharray="4 3"/>
|
|
<!-- P95 line -->
|
|
<path d="M0,35 L20,32 40,38 60,30 80,25 100,28 120,35 140,40 160,32 180,28 200,22 220,30 240,25 260,20 280,28 300,25"
|
|
stroke="#1A7F8E" class="chart-line"/>
|
|
<text x="0" y="68" class="chart-label">12:00</text>
|
|
<text x="145" y="68" class="chart-label">13:00</text>
|
|
<text x="290" y="68" class="chart-label">14:00</text>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- /content -->
|
|
</div><!-- /main -->
|
|
</div><!-- /app -->
|
|
</body>
|
|
</html>
|