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:
@@ -27,9 +27,13 @@ function useFullName(username: string | null): string | null {
|
||||
if (!username) return;
|
||||
let live = true;
|
||||
const localPart = username.split('@')[0];
|
||||
jmapQueryAndGet('x:Account', getAccountId('x:Account'), { filter: { name: localPart } }, ['description', 'emailAddress'])
|
||||
jmapQueryAndGet('x:Account', getAccountId('x:Account'), { filter: { name: localPart } }, [
|
||||
'description',
|
||||
'emailAddress',
|
||||
])
|
||||
.then((responses) => {
|
||||
const list = (responses[1]?.[1] as { list?: { description?: string | null; emailAddress?: string }[] }).list ?? [];
|
||||
const list =
|
||||
(responses[1]?.[1] as { list?: { description?: string | null; emailAddress?: string }[] }).list ?? [];
|
||||
const own = list.find((a) => a.emailAddress?.toLowerCase() === username.toLowerCase());
|
||||
const name = own?.description?.trim();
|
||||
if (live && name) setFullName(name);
|
||||
|
||||
Reference in New Issue
Block a user