improve admin overview

This commit is contained in:
tdurieux
2026-05-11 12:07:36 +03:00
parent 03e18fd572
commit afd9f36cfb
6 changed files with 80 additions and 51 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
{
"core.min.js": "core.3db744fc07.min.js",
"vendor.min.js": "vendor.9aa24967d7.min.js",
"vendor.min.js": "vendor.09f02f70c0.min.js",
"mermaid.min.js": "mermaid.f848a72d16.min.js",
"all.min.css": "all.f79970ad3b.min.css"
"all.min.css": "all.4c26d8bfc7.min.css"
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+43 -23
View File
@@ -5872,28 +5872,6 @@ body {
gap: 16px;
margin-bottom: 2px;
}
.overview-page .ov-header-actions { display: flex; align-items: center; gap: 12px; }
.overview-page .ov-range-btns {
display: inline-flex;
border: 1px solid var(--border-color);
border-radius: 8px;
overflow: hidden;
}
.overview-page .ov-range-btns .btn {
border: none;
border-radius: 0;
border-right: 1px solid var(--border-color);
padding: 5px 14px;
font-family: var(--font-mono);
font-size: 0.76rem;
background: transparent;
color: var(--ink-muted);
}
.overview-page .ov-range-btns .btn:last-child { border-right: none; }
.overview-page .ov-range-btns .btn.active {
background: var(--primary-bg);
color: var(--primary-color);
}
/* Status dot */
.overview-page .ov-dot {
@@ -5989,7 +5967,7 @@ body {
/* ── Chart cards ─────────────────────────────────────────────── */
.overview-page .ov-chart-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
margin-bottom: 18px;
}
@@ -6026,8 +6004,10 @@ body {
.overview-page .ov-dot-accent { background: var(--accent, #3B4AD6); }
.overview-page .ov-dot-ok-fill { background: #2F7A44; }
.overview-page .ov-dot-user-fill { background: #8B5E2E; }
.overview-page .ov-dot-new-user-fill { background: #C48A2E; }
.dark-mode .overview-page .ov-dot-ok-fill { background: #7DC894; }
.dark-mode .overview-page .ov-dot-user-fill { background: #D0A15F; }
.dark-mode .overview-page .ov-dot-new-user-fill { background: #E8B970; }
/* Spark bar chart */
.overview-page .ov-spark-bars {
@@ -6041,6 +6021,7 @@ body {
display: flex;
align-items: flex-end;
height: 100%;
position: relative;
}
.overview-page .ov-spark-fill {
width: 100%;
@@ -6051,9 +6032,48 @@ body {
}
.overview-page .ov-spark-fill-alt { background: #2F7A44; }
.overview-page .ov-spark-fill-user { background: #8B5E2E; }
.overview-page .ov-spark-fill-new-user { background: #C48A2E; }
.dark-mode .overview-page .ov-spark-fill-alt { background: #7DC894; }
.dark-mode .overview-page .ov-spark-fill-user { background: #D0A15F; }
.dark-mode .overview-page .ov-spark-fill-new-user { background: #E8B970; }
.overview-page .ov-spark-col:hover .ov-spark-fill { opacity: 1; }
.overview-page .ov-spark-col.has-tip::after {
content: attr(data-tip);
position: absolute;
left: 50%;
bottom: calc(100% + 10px);
transform: translateX(-50%) translateY(4px);
z-index: 10;
padding: 6px 8px;
border-radius: 6px;
background: var(--color);
color: var(--background-color);
font-family: var(--font-mono);
font-size: 0.68rem;
line-height: 1;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 120ms ease, transform 120ms ease;
}
.overview-page .ov-spark-col.has-tip::before {
content: "";
position: absolute;
left: 50%;
bottom: calc(100% + 4px);
transform: translateX(-50%) translateY(4px);
z-index: 10;
border: 5px solid transparent;
border-top-color: var(--color);
opacity: 0;
pointer-events: none;
transition: opacity 120ms ease, transform 120ms ease;
}
.overview-page .ov-spark-col.has-tip:hover::after,
.overview-page .ov-spark-col.has-tip:hover::before {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
.overview-page .ov-spark-x {
display: flex;
justify-content: space-between;
+32 -20
View File
@@ -3,15 +3,6 @@
<div class="ov-header">
<h1 class="paper-page-title">Overview</h1>
<div class="ov-header-actions">
<div class="ov-range-btns">
<button class="btn btn-sm" ng-class="{active: range === '1h'}" ng-click="setRange('1h')">1h</button>
<button class="btn btn-sm" ng-class="{active: range === '6h'}" ng-click="setRange('6h')">6h</button>
<button class="btn btn-sm" ng-class="{active: range === '24h'}" ng-click="setRange('24h')">24h</button>
<button class="btn btn-sm" ng-class="{active: range === '7d'}" ng-click="setRange('7d')">7d</button>
<button class="btn btn-sm" ng-class="{active: range === '30d'}" ng-click="setRange('30d')">30d</button>
</div>
</div>
</div>
<nav class="admin-nav">
@@ -62,7 +53,7 @@
<div class="ov-daily-card">
<div class="ov-daily-label">New repos today</div>
<div class="ov-daily-value">+{{data.daily.today.repositories | number}}</div>
<div class="ov-daily-sub">day-over-day total</div>
<div class="ov-daily-sub">since yesterday</div>
</div>
<div class="ov-daily-card">
<div class="ov-daily-label">New users today</div>
@@ -72,7 +63,7 @@
<div class="ov-daily-card">
<div class="ov-daily-label">Page views today</div>
<div class="ov-daily-value">+{{data.daily.today.pageViews | number}}</div>
<div class="ov-daily-sub">since yesterday snapshot</div>
<div class="ov-daily-sub">since yesterday</div>
</div>
</section>
@@ -84,8 +75,9 @@
<span class="ov-chart-legend"><span class="ov-dot-legend ov-dot-accent"></span>views/day</span>
</div>
<div class="ov-spark-bars" ng-if="data.history.length">
<div class="ov-spark-col" ng-repeat="d in data.history track by $index"
title="{{historyLabel(d)}}: +{{d.dailyPageViews | number}} views">
<div class="ov-spark-col has-tip" ng-repeat="d in data.history track by $index"
ng-attr-data-tip="{{historyLabel(d)}}: +{{d.dailyPageViews | number}} views"
ng-attr-aria-label="{{historyLabel(d)}}: +{{d.dailyPageViews | number}} views">
<span class="ov-spark-fill" ng-style="{height: historyBarH(d, 'dailyPageViews') + 'px'}"></span>
</div>
</div>
@@ -101,8 +93,9 @@
<span class="ov-chart-legend"><span class="ov-dot-legend ov-dot-ok-fill"></span>repos/day</span>
</div>
<div class="ov-spark-bars" ng-if="data.history.length">
<div class="ov-spark-col" ng-repeat="d in data.history track by $index"
title="{{historyLabel(d)}}: +{{d.dailyRepositories | number}} repos">
<div class="ov-spark-col has-tip" ng-repeat="d in data.history track by $index"
ng-attr-data-tip="{{historyLabel(d)}}: +{{d.dailyRepositories | number}} repos"
ng-attr-aria-label="{{historyLabel(d)}}: +{{d.dailyRepositories | number}} repos">
<span class="ov-spark-fill ov-spark-fill-alt" ng-style="{height: historyBarH(d, 'dailyRepositories') + 'px'}"></span>
</div>
</div>
@@ -114,13 +107,32 @@
</div>
<div class="ov-chart-card">
<div class="ov-chart-head">
<span class="ov-chart-title">New users &middot; 30d</span>
<span class="ov-chart-legend"><span class="ov-dot-legend ov-dot-user-fill"></span>users/day</span>
<span class="ov-chart-title">Users &middot; 30d</span>
<span class="ov-chart-legend"><span class="ov-dot-legend ov-dot-user-fill"></span>total users</span>
</div>
<div class="ov-spark-bars" ng-if="data.history.length">
<div class="ov-spark-col" ng-repeat="d in data.history track by $index"
title="{{historyLabel(d)}}: +{{d.dailyUsers | number}} users">
<span class="ov-spark-fill ov-spark-fill-user" ng-style="{height: historyBarH(d, 'dailyUsers') + 'px'}"></span>
<div class="ov-spark-col has-tip" ng-repeat="d in data.history track by $index"
ng-attr-data-tip="{{historyLabel(d)}}: {{d.nbUsers | number}} users"
ng-attr-aria-label="{{historyLabel(d)}}: {{d.nbUsers | number}} users">
<span class="ov-spark-fill ov-spark-fill-user" ng-style="{height: historyBarH(d, 'nbUsers') + 'px'}"></span>
</div>
</div>
<div class="ov-spark-x" ng-if="data.history.length">
<span>{{historyLabel(data.history[0])}}</span>
<span>{{historyLabel(data.history[Math.floor(data.history.length/2)])}}</span>
<span>{{historyLabel(data.history[data.history.length - 1])}}</span>
</div>
</div>
<div class="ov-chart-card">
<div class="ov-chart-head">
<span class="ov-chart-title">New users &middot; 30d</span>
<span class="ov-chart-legend"><span class="ov-dot-legend ov-dot-new-user-fill"></span>users/day</span>
</div>
<div class="ov-spark-bars" ng-if="data.history.length">
<div class="ov-spark-col has-tip" ng-repeat="d in data.history track by $index"
ng-attr-data-tip="{{historyLabel(d)}}: +{{d.dailyUsers | number}} users"
ng-attr-aria-label="{{historyLabel(d)}}: +{{d.dailyUsers | number}} users">
<span class="ov-spark-fill ov-spark-fill-new-user" ng-style="{height: historyBarH(d, 'dailyUsers') + 'px'}"></span>
</div>
</div>
<div class="ov-spark-x" ng-if="data.history.length">
+1 -4
View File
@@ -1756,9 +1756,6 @@ angular
$scope.data = null;
$scope.loading = true;
$scope.error = null;
$scope.range = "24h";
$scope.setRange = function (r) { $scope.range = r; };
function humanBytes(b) {
if (b == null) return "—";
@@ -1869,7 +1866,7 @@ angular
$scope.error = null;
historyMaxes = {};
(r.data.history || []).forEach(function (d) {
["dailyPageViews", "dailyRepositories", "dailyUsers"].forEach(function (k) {
["dailyPageViews", "dailyRepositories", "dailyUsers", "nbUsers"].forEach(function (k) {
if (!historyMaxes[k] || d[k] > historyMaxes[k]) historyMaxes[k] = d[k];
});
});
+1 -1
View File
File diff suppressed because one or more lines are too long