Dashboard: every number leads somewhere, real counts, and new charts
- Cards and charts link to the page they're about: pending messages to the queue, bans to blocked IPs, report warnings to the reports, and so on, shown only to viewers who may open that page. - A one-line status under the greeting: what needs a look (failed tasks, messages retrying, recipients given up on) or, when nothing does, what's there. Each phrase is a link. - Counts from the server's own objects stand in for live metrics it can't report, and a live number with no source reads as unknown, not zero. - Who uses the space: a treemap of people sized by storage, colored by how near their quota they are, each tile opening the account. - Where mail is waiting: queued recipients by destination, split into waiting, retrying and given up, each row opening the filtered queue. - The weekly rhythm: messages by hour and weekday, shown once metric history exists. - Dashboard tabs are titled by their label.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { hrefFor, linkForMetrics } from './links';
|
||||
import { summarizeQueue } from './serverFacts';
|
||||
import { weeklyGrid } from './rhythm';
|
||||
|
||||
describe('linkForMetrics', () => {
|
||||
it('sends each number to where you act on it', () => {
|
||||
expect(linkForMetrics(['queue.count'])?.viewName).toBe('x:QueuedMessage');
|
||||
expect(linkForMetrics(['user.count'])?.viewName).toBe('x:Account/User');
|
||||
expect(linkForMetrics(['queue.message-queued'])?.viewName).toBe('x:Trace/InboundDelivery');
|
||||
expect(linkForMetrics(['queue.authenticated-message-queued'])?.viewName).toBe('x:Trace/OutboundDelivery');
|
||||
expect(linkForMetrics(['security.scan-ban'])).toMatchObject({ viewName: 'x:BlockedIp', section: 'Settings' });
|
||||
expect(linkForMetrics(['incoming-report.tls-report-with-warnings'])?.viewName).toBe('x:TlsExternalReport');
|
||||
});
|
||||
|
||||
it('takes the first metric that has a home', () => {
|
||||
expect(linkForMetrics(['no.such', 'domain.count'])?.viewName).toBe('x:Domain');
|
||||
expect(linkForMetrics(['no.such'])).toBeNull();
|
||||
});
|
||||
|
||||
it('carries filters the list page understands', () => {
|
||||
expect(hrefFor({ viewName: 'x:QueuedMessage', section: 'Management', label: '', filters: { to: 'a.com' } })).toBe(
|
||||
'/Management/x:QueuedMessage?f.to=a.com',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('summarizeQueue', () => {
|
||||
it('groups outstanding recipients by destination, busiest first', () => {
|
||||
const { waiting, retrying } = summarizeQueue([
|
||||
{
|
||||
recipients: {
|
||||
'[email protected]': { status: { '@type': 'TemporaryFailure' } },
|
||||
'[email protected]': { status: { '@type': 'Scheduled' } },
|
||||
'[email protected]': { status: { '@type': 'Completed' } },
|
||||
},
|
||||
},
|
||||
{ recipients: { '[email protected]': { status: { '@type': 'PermanentFailure' } } } },
|
||||
{ recipients: { '[email protected]': {} } },
|
||||
]);
|
||||
expect(waiting).toEqual([
|
||||
{ domain: 'gmail.com', scheduled: 2, retrying: 1, failed: 0 },
|
||||
{ domain: 'example.org', scheduled: 0, retrying: 0, failed: 1 },
|
||||
]);
|
||||
expect(retrying).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('weeklyGrid', () => {
|
||||
it('buckets samples by local weekday (Monday first) and hour', () => {
|
||||
const at = (d: Date, count: number, metric = 'queue.message-queued') => ({
|
||||
'@type': 'Counter' as const,
|
||||
metric,
|
||||
count,
|
||||
timestamp: d.toISOString(),
|
||||
});
|
||||
const monday9 = new Date(2024, 0, 1, 9, 30);
|
||||
const sunday23 = new Date(2024, 0, 7, 23, 5);
|
||||
const grid = weeklyGrid([at(monday9, 3), at(monday9, 2), at(sunday23, 1), at(monday9, 50, 'other.metric')]);
|
||||
expect(grid[0][9]).toBe(5);
|
||||
expect(grid[6][23]).toBe(1);
|
||||
expect(grid.flat().reduce((a, b) => a + b, 0)).toBe(6);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user