Files
llmgw/internal/web/templates/fabrics.html
Ilker ManapandClaude Opus 5.5 11231d8c2b The portal in English and Turkish: a catalogue per language, a switcher at the foot of every page, landing.language, Turkish numbers and dates
Every template and handler message in internal/web goes through a JSON
catalogue under internal/web/locales/<code>/, with English as the fallback.
The language is the person's choice (a cookie set by /_lang/{code}), else
Accept-Language, else landing.language. Tests refuse a key some language
lacks, a translation with other arguments than English, and template text
left in English.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 00:12:53 +02:00

75 lines
4.1 KiB
HTML

{{define "fabrics"}}<!doctype html>
<html lang="{{lang}}"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{t "fabric.title"}} · llmgw</title><link rel="stylesheet" href="{{stylesheet}}">
</head><body><div class="wrap wide">
<header>
<h1>{{t "fabric.title"}}</h1>
<p class="sub">{{tn "fabric.sub" (len .List)}}</p>
{{if .OnAdminListener}}<nav><a href="/">{{t "fabric.nav.cluster"}}</a></nav>{{else}}{{template "nav" .Nav}}{{end}}
</header>
{{if not .List}}
<p class="empty">{{t "fabric.empty"}}</p>
{{else}}
<nav class="pills" aria-label="{{t "fabric.pills"}}">{{range .List}}<a href="{{$.Base}}/{{.ID}}"{{if $.Current}}{{if eq .ID $.Current.ID}} class="on" aria-current="page"{{end}}{{end}}>
{{if .Declared}}{{range $i, $d := .Declared}}{{if $i}}, {{end}}{{$d}}{{end}}{{else}}{{t "fabric.undeclared"}}{{end}}
<span class="note">{{.Label}}</span></a>{{end}}</nav>
{{end}}
{{with .Current}}
<div class="fabric-head">
<div>
<h2>{{if .Declared}}{{range $i, $d := .Declared}}{{if $i}}, {{end}}<code>{{$d}}</code>{{end}}{{else}}{{t "fabric.undeclared"}}{{end}}</h2>
<p class="sub">{{.Label}}
{{with .SM}} · {{t "fabric.master"}} <code>{{.GUID}}</code>{{if .LID}} {{t "fabric.lid" .LID}}{{end}}{{end}}
{{if .SMs}} · {{tn "fabric.sms" (len .SMs)}}{{end}}
{{if not .ScannedAt.IsZero}} · {{t "fabric.mapped" (ago .ScannedAt) .ScannedBy (count .TookMs)}}{{end}}</p>
</div>
</div>
{{if .Problems}}<ul class="fabric-problems">{{range .Problems}}
{{/* The level is a class and a word; the message is the fabric
checker's own, in English. */}}
<li class="{{.Level}}"><span class="tag{{if eq (printf "%s" .Level) "fail"}} bad{{end}}">{{t (print "fabric.level." .Level)}}</span> {{.Message}}</li>{{end}}
</ul>{{end}}
<div id="fabric-map" class="fabric-map" data-src="{{$.Base}}/{{.ID}}/topology.json"
data-nodes="{{if $.OnAdminListener}}/nodes{{else}}/admin/nodes{{end}}">
<div class="fm-bar">
<div class="fm-stats"></div>
<div class="fm-tools">
<span class="pills small">
<button type="button" class="on" data-mode="speed">{{t "fabric.mode.speed"}}</button>
<button type="button" data-mode="rails">{{t "fabric.mode.rails"}}</button>
</span>
<button type="button" class="fm-toggle" data-toggle="traffic">{{t "fabric.traffic"}}</button>
<button type="button" class="fm-toggle" data-toggle="problems">{{t "fabric.only_problems"}}</button>
<input type="search" class="fm-search" placeholder="{{t "fabric.find"}}" aria-label="{{t "fabric.find"}}">
<button type="button" class="fm-toggle" data-reset title="{{t "fabric.reset_hint"}}">{{t "fabric.reset"}}</button>
</div>
</div>
<div class="fm-stage">
{{/* The paragraph is outside the noscript, which holds only its words:
the drawing empties the canvas before it draws, so with script it
is gone at once. */}}
<div class="fm-canvas"><p class="fm-empty"><noscript>{{t "fabric.noscript"}}</noscript></p></div>
<div class="fm-tip" hidden></div>
<aside class="fm-panel" hidden></aside>
</div>
<div class="fm-legend">
{{/* InfiniBand's names for its speeds, the same in every language. */}}
<span translate="no"><i class="sw sp-xdr"></i>XDR</span><span translate="no"><i class="sw sp-ndr"></i>NDR</span><span translate="no"><i class="sw sp-hdr"></i>HDR</span>
<span translate="no"><i class="sw sp-edr"></i>EDR</span><span><i class="sw sp-slow"></i>{{t "fabric.legend.slower"}}</span>
<span><i class="sw degraded"></i>{{t "fabric.legend.below"}}</span>
<span><i class="dot known"></i>{{t "fabric.legend.ours"}}</span><span><i class="dot"></i>{{t "fabric.legend.other"}}</span><span><i class="dot down"></i>{{t "fabric.legend.down"}}</span>
<span class="note">{{t "fabric.legend.how"}}</span>
</div>
</div>
<script type="application/json" id="fabric-data">{{$.Data}}</script>
<script type="application/json" id="fabric-i18n">{{$.Strings}}</script>
<script src="{{asset "fabric.js"}}" defer></script>
{{end}}
<footer><span>llmgw {{.Version}}</span><span>{{.Now}}</span>{{template "langs"}}</footer>
</div></body></html>{{end}}