121 lines
8.2 KiB
HTML
121 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" data-theme="dark">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>DoxaApi</title>
|
|
<base href="__DOXA_API_BASE__" />
|
|
<link rel="stylesheet" href="app.css" />
|
|
</head>
|
|
<body>
|
|
<div id="app" class="app-shell">
|
|
<header class="topbar">
|
|
<div class="topbar-left">
|
|
<div class="brand">
|
|
<div class="brand-icon">
|
|
<svg viewBox="0 0 20 20" fill="none"><path d="M3 5L9 11L3 17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /><path d="M11 17H17" stroke="currentColor" stroke-width="2" stroke-linecap="round" /></svg>
|
|
</div>
|
|
<div class="brand-text">
|
|
<span class="brand-name" id="brandTitle">DoxaApi</span>
|
|
<span class="brand-ver" id="brandVersion"></span>
|
|
</div>
|
|
</div>
|
|
<div class="api-switcher-wrap">
|
|
<select id="apiSelector" class="api-select"></select>
|
|
</div>
|
|
</div>
|
|
<div class="topbar-center">
|
|
<div class="search-wrap">
|
|
<svg viewBox="0 0 20 20" fill="none" class="search-ico"><circle cx="9" cy="9" r="6" stroke="currentColor" stroke-width="1.8" /><path d="M17 17L13.5 13.5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /></svg>
|
|
<input id="searchInput" type="text" placeholder="Search endpoints, methods, paths…" autocomplete="off" spellcheck="false" />
|
|
<kbd class="search-kbd">/</kbd>
|
|
</div>
|
|
</div>
|
|
<div class="topbar-right">
|
|
<button id="dashboardBtn" class="tb-btn" title="Analytics">
|
|
<svg viewBox="0 0 20 20" fill="none"><rect x="2" y="2" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8" /><rect x="11" y="2" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8" /><rect x="2" y="11" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8" /><rect x="11" y="11" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8" /></svg>
|
|
<span>Dashboard</span>
|
|
</button>
|
|
<button id="authBtn" class="tb-btn" title="Auth">
|
|
<svg viewBox="0 0 20 20" fill="none"><rect x="4" y="9" width="12" height="9" rx="2" stroke="currentColor" stroke-width="1.8" /><path d="M7 9V6a3 3 0 016 0v3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /></svg>
|
|
<span>Auth</span>
|
|
<span class="auth-dot" id="authBadgeDot" style="display:none"></span>
|
|
</button>
|
|
<button id="consoleBtn" class="tb-btn" title="Console">
|
|
<svg viewBox="0 0 20 20" fill="none"><rect x="2" y="3" width="16" height="14" rx="2" stroke="currentColor" stroke-width="1.8" /><path d="M6 8l4 4-4 4M12 16h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
<span>Console</span>
|
|
</button>
|
|
<div class="tb-divider"></div>
|
|
<div class="export-group">
|
|
<button id="importBtn" class="tb-btn tb-btn-accent">
|
|
<svg viewBox="0 0 20 20" fill="none"><path d="M10 3v10M6 9l4 4 4-4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /><path d="M3 15v1a1 1 0 001 1h12a1 1 0 001-1v-1" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /></svg>
|
|
Import
|
|
</button>
|
|
<div class="export-dropdown">
|
|
<button class="tb-btn export-toggle">
|
|
<svg viewBox="0 0 20 20" fill="none"><path d="M10 17V7M6 11l4-4 4 4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /><path d="M3 15v1a1 1 0 001 1h12a1 1 0 001-1v-1" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /></svg>
|
|
Export
|
|
<svg viewBox="0 0 20 20" fill="none" class="chevdown"><path d="M5 8l5 5 5-5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
</button>
|
|
<div class="export-menu" id="exportMenu">
|
|
<button id="exportDoxaApiBtn" class="export-item"><span class="export-fmt">DoxaApi</span><span class="export-desc">.json</span></button>
|
|
<button id="exportOpenApiBtn" class="export-item"><span class="export-fmt">OpenAPI 3</span><span class="export-desc">.json</span></button>
|
|
<button id="exportSwaggerBtn" class="export-item"><span class="export-fmt">Swagger 2</span><span class="export-desc">.json</span></button>
|
|
</div>
|
|
</div>
|
|
<button id="compareBtn" class="tb-btn">
|
|
<svg viewBox="0 0 20 20" fill="none"><path d="M6 5h8M6 10h8M6 15h4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /><path d="M15 12l3 3-3 3" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
Diff
|
|
</button>
|
|
</div>
|
|
<div class="tb-divider"></div>
|
|
<button id="themeToggle" class="icon-btn" title="Toggle theme">
|
|
<svg class="icon-sun" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="3.5" stroke="currentColor" stroke-width="1.8" /><path d="M10 2v2M10 16v2M2 10h2M16 10h2M4.93 4.93l1.41 1.41M13.66 13.66l1.41 1.41M4.93 15.07l1.41-1.41M13.66 6.34l1.41-1.41" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /></svg>
|
|
<svg class="icon-moon" viewBox="0 0 20 20" fill="none"><path d="M17.5 11.5A7.5 7.5 0 018.5 2.5a7.5 7.5 0 100 15 7.5 7.5 0 009-6z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" /></svg>
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="layout">
|
|
<nav class="sidebar" id="sidebar">
|
|
<div class="sidebar-inner" id="navContent"></div>
|
|
</nav>
|
|
|
|
<main class="content-area">
|
|
<div class="detail-pane" id="detailPane">
|
|
<div id="detailContent" class="detail-content"></div>
|
|
</div>
|
|
<aside class="try-pane" id="tryPane">
|
|
<div id="tryContent" class="try-content"></div>
|
|
</aside>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- Dashboard slide-over -->
|
|
<div id="dashboardPanel" class="drawer" style="display:none">
|
|
<div class="drawer-header">
|
|
<span class="drawer-title">API Analytics</span>
|
|
<button id="closeDashboard" class="icon-btn"><svg viewBox="0 0 20 20" fill="none"><path d="M5 5l10 10M15 5L5 15" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" /></svg></button>
|
|
</div>
|
|
<div class="drawer-body">
|
|
<div class="stat-grid">
|
|
<div class="stat-card"><div class="stat-val" id="totalEndpoints">—</div><div class="stat-lbl">Endpoints</div></div>
|
|
<div class="stat-card"><div class="stat-val" id="totalRequests">—</div><div class="stat-lbl">Requests</div></div>
|
|
<div class="stat-card stat-card-err"><div class="stat-val" id="totalErrors">—</div><div class="stat-lbl">Errors</div></div>
|
|
<div class="stat-card"><div class="stat-val" id="avgResponse">—</div><div class="stat-lbl">Avg. latency</div></div>
|
|
</div>
|
|
<div id="topEndpointsChart" class="dash-section"></div>
|
|
<div id="recentRequestsTable" class="dash-section"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="modalRoot"></div>
|
|
|
|
<input id="importFile" type="file" accept=".json" hidden />
|
|
<input id="diffFile" type="file" accept=".json" hidden />
|
|
|
|
<script>window.__DOXA_API_SPEC_URL__ = "__DOXA_API_SPEC_PATH__";</script>
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html> |