Files
llmgw/internal/web/templates/org.html
T
Ilker ManapandClaude Opus 5.5 235bf33dcd Keep every admin table to one line per record
Headers never wrap, free text is clipped with the whole on hover, full-width
rows are only notes and forms. The cluster page hides columns empty on every
row and shortens node names; People shows two memberships and a count.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 11:02:18 +02:00

113 lines
4.9 KiB
HTML

{{define "org"}}<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{.Org.Name}} · llmgw</title><link rel="stylesheet" href="{{stylesheet}}">
</head><body><div class="wrap">
<header>
<h1>{{.Org.Name}}</h1>
<p class="sub">{{.People}} {{if eq .People 1}}person{{else}}people{{end}} ·
use, members and limits across the organization</p>
{{template "nav" .Nav}}
</header>
{{if gt (len .Orgs) 1}}
<div class="filters">
<span class="filter-label">Organization</span>
{{range .Orgs}}<a class="chip{{if eq .ID $.Org.ID}} on{{end}}" href="/org/{{.ID}}">{{.Name}}</a>{{end}}
</div>
{{end}}
{{if .Error}}<p class="error">{{.Error}}</p>{{end}}
<h2>Use</h2>
<div class="filters">
<span class="filter-label">Group by</span>
{{range .Groups}}<a class="chip{{if .Selected}} on{{end}}"
href="/org/{{$.Org.ID}}?by={{.Key}}&amp;window={{$.Window}}">{{.Label}}</a>{{end}}
<span class="filter-label">Window</span>
{{range .Windows}}<a class="chip{{if .Selected}} on{{end}}"
href="/org/{{$.Org.ID}}?by={{$.By}}&amp;window={{.Key}}">{{.Label}}</a>{{end}}
</div>
<div class="chart-row">
{{template "tschart" dict "t" .Requests "title" "Requests"
"note" "Requests made in this organization's projects."}}
{{template "tschart" dict "t" .Tokens "title" "Tokens"
"note" "Prompt and completion together."}}
</div>
{{if .Priced}}
<div class="chart-row">
{{template "tschart" dict "t" .Spend "title" "Spend" "note" "In whole units, the ones a budget is written in."}}
</div>
{{end}}
{{if .Rows}}
<table class="rows compact">
<tr><th>{{if eq .By "user"}}Person{{else if eq .By "project"}}Project{{else}}Team{{end}}</th>
<th class="num">Requests</th><th class="num">Tokens</th><th class="num">Spend</th><th class="num">Errors</th></tr>
{{range .Rows}}<tr>
<td>{{.Name}}</td><td class="num">{{compact .Requests}}</td><td class="num">{{compact .Tokens}}</td>
<td class="num">{{.Spend}}</td><td class="num">{{if .Errors}}{{.Errors}}{{else}}—{{end}}</td>
</tr>{{end}}
</table>
{{else}}<p class="empty">Nothing used in this window.</p>{{end}}
<p class="note">Only what was spent in this organization's projects. What its
people do elsewhere — in another organization, or on their own — is not shown.</p>
<h2>Teams, projects and limits</h2>
{{if .Quotas}}
<table class="rows quota-tree">
<tr><th>Where</th><th class="num">Requests/min</th><th class="num">Tokens/min</th>
<th class="num">Budget</th><th>Spent · 30 days</th></tr>
{{range .Quotas}}
<tr class="q-depth-{{.Indent}}">
<td class="q-where"><span class="q-name">{{.Path}}</span> <span class="q-kind">{{.Scope}}</span>
{{if .Models}}<div class="q-sub">only <code>{{.Models}}</code></div>{{end}}
{{if .Shadowed}}<div class="q-sub q-warn">{{.Shadowed}}</div>{{end}}</td>
<td class="num">{{template "quota-value" dict "Own" .RPM "Up" .RPMUp "From" .RPMFrom}}</td>
<td class="num">{{template "quota-value" dict "Own" .TPM "Up" .TPMUp "From" .TPMFrom}}</td>
<td class="num">{{if .Budget}}{{.Budget}}{{if .Period}}<span class="q-per">/{{.Period}}</span>{{end}}
{{else}}{{template "quota-value" dict "Own" "" "Up" .BudgetUp "From" .BudgetFrom}}{{end}}</td>
<td class="q-spent"><span class="q-spend">{{.Spend}}</span>
{{if .HasPct}}<span class="q-meter{{if ge .Percent 90}} hot{{end}}"><i style="width:{{pct .Percent 100}}%"></i></span>
<span class="q-pct">{{.Percent}}%</span>{{end}}</td>
</tr>
{{end}}
</table>
<p class="note">Limits are set by the cluster's administrators.</p>
{{end}}
<h2>Members</h2>
{{if .Members}}
<table class="rows compact">
<tr><th>Person</th><th>Member of</th><th>State</th></tr>
{{range .Members}}<tr>
<td>{{.Email}}</td>
<td>{{range .Places}}<span class="chip-m">{{.Where}}{{if eq .Role "manager"}} <b class="chip-role">manager</b>{{end}}</span>{{end}}</td>
<td class="state state-{{.State}}">{{.State}}</td>
</tr>{{end}}
</table>
{{else}}<p class="empty">Nobody is a member yet.</p>{{end}}
<footer><span>llmgw {{.Version}}</span><span>{{.Now}}</span></footer>
</div></body></html>{{end}}
{{define "org-none"}}<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Organizations · llmgw</title><link rel="stylesheet" href="{{stylesheet}}">
</head><body><div class="wrap">
<header>
<h1>Organizations</h1>
<p class="sub">There are none on this cluster</p>
{{template "nav" .Nav}}
</header>
<p>Everyone uses the gateway on their own, under their personal quota. An
organization, once there is one, gets a page here for its managers: its use by
team, project and person, its limits, and its members.</p>
<p><a href="/admin/users">Create one on the people page</a>, then make someone
its manager with the star on their membership.</p>
<footer><span>llmgw {{.Version}}</span><span>{{.Now}}</span></footer>
</div></body></html>{{end}}