Files
crank/apps/ui/html/usage.html
T
2026-03-30 01:49:32 +03:00

230 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<base href="../">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Crank — Usage</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/layout.css">
<link rel="stylesheet" href="css/pages.css">
<link rel="stylesheet" href="css/usage.css">
<script>try{if(!localStorage.getItem('crank_user'))window.location.replace('login.html');}catch(e){}</script>
<script src="js/config.js"></script>
<script src="js/i18n.js"></script>
<script src="js/api.js"></script>
<script src="js/workspace.js"></script>
</head>
<body>
<nav class="navbar">
<a href="index.html" class="nav-logo">
<div class="nav-logo-mark"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" fill="white"><path fill-rule="evenodd" d="M 10.000,1.800 L 12.287,3.962 L 15.408,3.557 L 15.987,6.650 L 18.750,8.157 L 17.400,11.000 L 18.750,13.843 L 15.987,15.350 L 15.408,18.443 L 12.287,18.038 L 10.000,20.200 L 7.713,18.038 L 4.592,18.443 L 4.013,15.350 L 1.250,13.843 L 2.600,11.000 L 1.250,8.157 L 4.013,6.650 L 4.592,3.557 L 7.713,3.962 Z M 12.800,11.000 A 2.8 2.8 0 1 0 7.200,11.000 A 2.8 2.8 0 1 0 12.800,11.000 Z"/><path fill-rule="evenodd" d="M 11.791,15.604 Q 16.083,17.179 21.375,21.154 A 2.00 2.00 0 1 1 23.625,17.846 Q 19.782,15.610 14.940,10.973 Z M 24.300,19.500 A 1.8 1.8 0 1 0 20.700,19.500 A 1.8 1.8 0 1 0 24.300,19.500 Z"/><path d="M 10.0,9.7 L 11.3,11.0 L 10.0,12.3 L 8.7,11.0 Z" fill="rgba(0,0,0,0.3)"/></svg></div>
<span class="nav-logo-text">Crank</span>
</a>
<!-- Workspace switcher -->
<div class="ws-switcher" id="ws-switcher">
<button class="ws-switcher-trigger" onclick="toggleWsSwitcher(event)">
<div class="ws-dot" id="ws-dot">A</div>
<span class="ws-current-name" id="ws-current-name">acme-workspace</span>
<svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6l4 4 4-4"/></svg>
</button>
<div class="ws-dropdown" id="ws-dropdown" style="display:none">
<div class="ws-dropdown-label">Your workspaces</div>
<div id="ws-dropdown-list"></div>
<div class="ws-dropdown-footer">
<button class="ws-dropdown-create" onclick="window.location.href='workspace-setup.html?mode=create'">
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M8 3v10M3 8h10"/></svg>
Create workspace
</button>
</div>
</div>
</div>
<div class="nav-links">
<a href="index.html" class="nav-link" data-i18n="nav.operations">Operations</a>
<a href="html/agents.html" class="nav-link" data-i18n="nav.agents">Agents</a>
<a href="html/api-keys.html" class="nav-link" data-i18n="nav.apikeys">API Keys</a>
<a href="html/logs.html" class="nav-link" data-i18n="nav.logs">Logs</a>
<a href="html/usage.html" class="nav-link active" data-i18n="nav.usage">Usage</a>
</div>
<div class="nav-right">
<button class="nav-hamburger" aria-label="Menu"><span></span><span></span><span></span></button>
<div class="nav-kbd">
<svg width="12" height="12"><use href="icons/general/grid.svg#icon"/></svg>
<span>⌘K</span>
</div>
<button class="nav-icon-btn" title="Notifications">
<svg width="15" height="15"><use href="icons/general/bell.svg#icon"/></svg>
</button>
<div class="nav-divider"></div>
<div class="user-menu">
<div class="nav-avatar" title="Account">AT</div>
<div class="user-dropdown">
<div class="user-dropdown-header">
<div class="user-dropdown-name">Operator</div>
<div class="user-dropdown-role">Admin · acme-workspace</div>
</div>
<button class="user-dropdown-item" data-action="settings-link">
<svg width="13" height="13"><use href="icons/general/settings.svg#icon"/></svg>
<span data-i18n="nav.settings">Settings</span>
</button>
<div class="dropdown-divider"></div>
<button class="user-dropdown-item danger" data-action="logout">
<svg width="13" height="13"><use href="icons/general/logout.svg#icon"/></svg>
<span data-i18n="nav.logout">Log out</span>
</button>
</div>
</div>
</div>
</nav>
<div class="mobile-nav">
<a href="index.html" class="mobile-nav-link" data-i18n="nav.operations">Operations</a>
<a href="html/agents.html" class="mobile-nav-link" data-i18n="nav.agents">Agents</a>
<a href="html/api-keys.html" class="mobile-nav-link" data-i18n="nav.apikeys">API Keys</a>
<a href="html/logs.html" class="mobile-nav-link" data-i18n="nav.logs">Logs</a>
<a href="html/usage.html" class="mobile-nav-link active" data-i18n="nav.usage">Usage</a>
</div>
<div class="page">
<div class="page-header">
<div class="page-header-text">
<h1 class="page-title" data-i18n="usage.title">Usage</h1>
<p class="page-subtitle">Invocation metrics for all operations in your workspace.</p>
</div>
<div class="page-header-actions">
<select class="period-select" id="period">
<option value="7d" selected>Last 7 days</option>
<option value="30d">Last 30 days</option>
<option value="90d">Last 90 days</option>
<option value="this_month">This month</option>
</select>
<button class="btn-secondary" type="button">
<svg width="13" height="13" viewBox="0 0 16 16" fill="currentColor"><path d="M7.47 1.72a.75.75 0 011.06 0l4.5 4.5a.75.75 0 01-1.06 1.06L8.75 4.06v8.94a.75.75 0 01-1.5 0V4.06L4.53 7.28a.75.75 0 01-1.06-1.06l4.5-4.5zM1.5 13.75a.75.75 0 01.75-.75h11.5a.75.75 0 010 1.5H2.25a.75.75 0 01-.75-.75z"/></svg>
Export CSV
</button>
</div>
</div>
<!-- Stat cards -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-label">Total invocations</div>
<div class="stat-value">28,341</div>
<div class="stat-delta up">
<svg width="11" height="11" viewBox="0 0 12 12" fill="currentColor"><path d="M6 2l4 4H7v4H5V6H2l4-4z"/></svg>
+12% vs prior period
</div>
</div>
<div class="stat-card">
<div class="stat-label">Success rate</div>
<div class="stat-value">98.6%</div>
<div class="stat-delta up">
<svg width="11" height="11" viewBox="0 0 12 12" fill="currentColor"><path d="M6 2l4 4H7v4H5V6H2l4-4z"/></svg>
+0.3pp vs prior period
</div>
</div>
<div class="stat-card">
<div class="stat-label">Median latency (p50)</div>
<div class="stat-value">124ms</div>
<div class="stat-delta up">
<svg width="11" height="11" viewBox="0 0 12 12" fill="currentColor"><path d="M6 2l4 4H7v4H5V6H2l4-4z"/></svg>
-18ms vs prior period
</div>
</div>
<div class="stat-card">
<div class="stat-label">p99 latency</div>
<div class="stat-value">2.1s</div>
<div class="stat-delta down">
<svg width="11" height="11" viewBox="0 0 12 12" fill="currentColor"><path d="M6 10L2 6h3V2h2v4h3l-4 4z"/></svg>
+340ms vs prior period
</div>
</div>
</div>
<!-- Invocations chart -->
<div class="section-card" style="margin-bottom:20px;">
<div class="section-card-header">
<div class="section-card-title">Invocations over time</div>
<div style="display:flex;align-items:center;gap:12px;font-size:12px;color:var(--text-muted);">
<span style="display:flex;align-items:center;gap:5px;"><span style="width:10px;height:10px;border-radius:2px;background:var(--accent);display:inline-block;"></span>Success</span>
<span style="display:flex;align-items:center;gap:5px;"><span style="width:10px;height:10px;border-radius:2px;background:var(--red);display:inline-block;"></span>Error</span>
</div>
</div>
<div class="section-card-body" style="padding-bottom:28px;">
<div class="chart-placeholder" id="chart-bars"></div>
</div>
</div>
<!-- Per-operation table -->
<div class="section-card">
<div class="section-card-header">
<div>
<div class="section-card-title">By operation</div>
<div class="section-card-subtitle">Breakdown for last 7 days</div>
</div>
</div>
<table class="data-table">
<thead>
<tr>
<th>Operation</th>
<th>Protocol</th>
<th style="text-align:right;">Calls</th>
<th style="text-align:right;">Errors</th>
<th style="text-align:right;">Error rate</th>
<th>Latency (p50 / p95 / p99)</th>
<th style="text-align:right;">Traffic share</th>
</tr>
</thead>
<tbody id="usage-tbody">
</tbody>
</table>
</div>
</div>
<!-- Template: chart bar column -->
<template id="tmpl-chart-bar">
<div class="chart-col" style="flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;justify-content:flex-end;position:relative;">
<div class="chart-bar error" style="width:100%;"></div>
<div class="chart-bar success" style="width:100%;"></div>
<div class="chart-col-label" style="position:absolute;bottom:-22px;font-size:10.5px;color:var(--text-muted);text-align:center;width:100%;"></div>
</div>
</template>
<!-- Template: usage stats table row -->
<template id="tmpl-usage-row">
<tr>
<td>
<div class="col-name"></div>
<div class="col-op-slug" style="font-family:monospace;font-size:11px;color:var(--text-muted);"></div>
</td>
<td><span class="badge col-proto" style="border-color:rgba(88,166,255,0.25);background:rgba(88,166,255,0.07);color:var(--blue);"></span></td>
<td class="col-calls" style="text-align:right;font-variant-numeric:tabular-nums;"></td>
<td class="col-errors" style="text-align:right;font-variant-numeric:tabular-nums;"></td>
<td class="col-err-rate" style="text-align:right;font-variant-numeric:tabular-nums;"></td>
<td class="col-latency">
<div class="latency-bar">
<div class="latency-seg latency-p50"></div>
<div class="latency-seg latency-p95"></div>
<div class="latency-seg latency-p99"></div>
</div>
<div class="col-latency-text" style="font-size:11px;color:var(--text-muted);margin-top:3px;font-family:monospace;"></div>
</td>
<td style="text-align:right;min-width:120px;">
<div class="col-quota-label" style="font-size:11.5px;color:var(--text-muted);margin-bottom:3px;"></div>
<div class="quota-bar-wrap"><div class="quota-bar-fill col-quota-fill"></div></div>
</td>
</tr>
</template>
<script src="js/nav.js"></script>
<script src="js/usage.js"></script>
</body>
</html>