227 lines
11 KiB
HTML
227 lines
11 KiB
HTML
{{/*
|
||
Gemeinsame Bausteine aller Seiten.
|
||
|
||
Statt eines verschachtelten Layout-Templates gibt es hier Blöcke, die jede
|
||
Seite einbindet. Das ist etwas mehr Tipparbeit je Seite, dafür braucht es
|
||
keine Template-Vererbung — und man sieht jeder Seitendatei an, wie sie
|
||
aufgebaut ist.
|
||
|
||
html-anfang / html-ende Dokumentrahmen (auch von der Anmeldeseite genutzt)
|
||
kopf / fuss Rahmen, Kopfleiste und Seitenleiste
|
||
*/}}
|
||
|
||
{{define "html-anfang"}}<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>{{.Title}} – Munin</title>
|
||
<link rel="stylesheet" href="/static/style.css">
|
||
</head>
|
||
<body>
|
||
{{end}}
|
||
|
||
{{define "html-ende"}}
|
||
<script src="/static/confirm.js"></script>
|
||
<script src="/static/preview.js"></script>
|
||
<script src="/static/autocomplete.js"></script>
|
||
<script src="/static/graph.js"></script>
|
||
<script src="/static/tagfilter.js"></script>
|
||
<script src="/static/ungespeichert.js"></script>
|
||
<script src="/static/aehnlich.js"></script>
|
||
<script src="/static/tastenkuerzel.js"></script>
|
||
</body>
|
||
</html>
|
||
{{end}}
|
||
|
||
{{define "kopf"}}{{template "html-anfang" .}}
|
||
|
||
{{/* Schmale Kopfleiste über die ganze Breite: Marke, Workspace-Umschalter,
|
||
Hilfe und Abmelden. Alles Weitere steht in der Seitenleiste.
|
||
|
||
Die Hilfe steht hier oben statt unten in der Seitenleiste: Dort rutschte
|
||
sie bei vielen Projekten und Schlagworten aus dem Blick — gerade dann,
|
||
wenn man sie sucht.
|
||
|
||
Der Umschalter steht bewusst hier statt in der Seitenleiste — ein
|
||
Plattform-Admin mit mehreren Abteilungen muss auf jeder Seite sehen,
|
||
WELCHEN Workspace er gerade bearbeitet, nicht nur auf der Auswahlseite
|
||
selbst. Für einen Projekt-Zugang (immer genau ein Workspace) bleibt der
|
||
Umschalter weg — WorkspaceName ist dann leer. */}}
|
||
<header class="kopfleiste">
|
||
<div class="kopfleiste-innen">
|
||
<div class="reihe">
|
||
<a class="marke-wort" href="/">Munin</a>
|
||
{{if .Session.IsPlatformAdmin}}{{if .Session.WorkspaceName}}
|
||
<a class="arbeitsbereich" href="/admin/workspaces">
|
||
<span class="arbeitsbereich-trenner" aria-hidden="true">/</span>
|
||
<span class="arbeitsbereich-name">{{.Session.WorkspaceName}}</span>
|
||
<span class="arbeitsbereich-pfeil" aria-hidden="true">⌄</span>
|
||
</a>
|
||
{{end}}{{else if .Session.IsWorkspaceAdmin}}
|
||
{{/* Der Workspace-Admin hat genau einen Workspace — der Name steht
|
||
zur Orientierung da, ohne Umschalter. */}}
|
||
<span class="arbeitsbereich">
|
||
<span class="arbeitsbereich-trenner" aria-hidden="true">/</span>
|
||
<span class="arbeitsbereich-name">{{.Session.WorkspaceName}}</span>
|
||
</span>
|
||
{{end}}
|
||
</div>
|
||
<div class="reihe kopfleiste-aktionen">
|
||
<a href="/hilfe" class="kopfleiste-link{{if eq .Bereich "hilfe"}} aktiv{{end}}"
|
||
{{if eq .Bereich "hilfe"}}aria-current="page"{{end}}>Hilfe<span class="nur-breit"> & Einstieg</span></a>
|
||
<form method="POST" action="/logout" class="reihe">
|
||
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
||
<button type="submit" class="wie-link">Abmelden</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="gerüst">
|
||
{{/* ── Seitenleiste ──────────────────────────────────────────────────────
|
||
Enthält drei Gruppen: die Projekte, die Bereiche des aktuellen Projekts
|
||
und dessen Schlagworte. Die Schlagworte stehen hier statt als Filterzeile
|
||
über der Liste — sie sind Navigation, und die Liste bekommt so mehr Platz. */}}
|
||
<aside class="seitenleiste">
|
||
|
||
{{if .Session.CanManageProjects}}
|
||
<nav class="nav-gruppe">
|
||
<h2 class="nav-titel">Projekte</h2>
|
||
<ul class="nav-liste">
|
||
{{$aktuell := .Project.Slug}}
|
||
{{range .Nav.Projects}}
|
||
<li><a href="/p/{{.Slug}}/" {{if eq $aktuell .Slug}}class="aktiv"{{end}}>{{.Name}}</a></li>
|
||
{{end}}
|
||
</ul>
|
||
<ul class="nav-liste leise">
|
||
<li><a href="/admin/projects" {{if eq .Bereich "projekte"}}class="aktiv"{{end}}>Verwalten…</a></li>
|
||
</ul>
|
||
</nav>
|
||
{{end}}
|
||
|
||
{{/* Die Bereiche des aktuellen Projekts. Die Überschrift ist der
|
||
Projektname — für einen Projekt-Key ist das zugleich die einzige
|
||
Ortsangabe, denn eine Projektliste bekommt er nicht zu sehen. */}}
|
||
{{if .Project.Slug}}
|
||
<nav class="nav-gruppe">
|
||
<h2 class="nav-titel">{{.Project.Name}}</h2>
|
||
<ul class="nav-liste">
|
||
<li><a href="/p/{{.Project.Slug}}/" {{if eq .Bereich "eintraege"}}class="aktiv"{{end}}>Einträge</a></li>
|
||
<li><a href="/p/{{.Project.Slug}}/graph" {{if eq .Bereich "graph"}}class="aktiv"{{end}}>Graph</a></li>
|
||
{{if .Session.CanManageKeys}}
|
||
<li><a href="/p/{{.Project.Slug}}/keys" {{if eq .Bereich "zugaenge"}}class="aktiv"{{end}}>Zugänge</a></li>
|
||
{{end}}
|
||
{{if .Session.CanImport}}
|
||
<li><a href="/p/{{.Project.Slug}}/import" {{if eq .Bereich "import"}}class="aktiv"{{end}}>Import</a></li>
|
||
{{end}}
|
||
<li><a href="/p/{{.Project.Slug}}/usage" {{if eq .Bereich "nutzung"}}class="aktiv"{{end}}>Nutzung</a></li>
|
||
<li><a href="/p/{{.Project.Slug}}/audit" {{if eq .Bereich "protokoll"}}class="aktiv"{{end}}>Protokoll</a></li>
|
||
{{if .Session.CanWrite}}
|
||
<li><a href="/p/{{.Project.Slug}}/trash" {{if eq .Bereich "papierkorb"}}class="aktiv"{{end}}>Papierkorb</a></li>
|
||
{{end}}
|
||
</ul>
|
||
</nav>
|
||
|
||
{{if .Nav.Tags}}
|
||
<nav class="nav-gruppe schlagworte">
|
||
<h2 class="nav-titel">Schlagworte</h2>
|
||
<ul class="nav-liste">
|
||
{{$slug := .Project.Slug}}{{$tag := .AktivesTag}}
|
||
{{range .Nav.Tags}}
|
||
<li>
|
||
<a href="/p/{{$slug}}/?tag={{.Tag}}" {{if eq $tag .Tag}}class="aktiv"{{end}}>
|
||
<span class="nav-text">{{.Tag}}</span>
|
||
<span class="nav-zahl">{{.Count}}</span>
|
||
</a>
|
||
</li>
|
||
{{end}}
|
||
</ul>
|
||
{{/* Die Seitenleiste zeigt nur die häufigsten Schlagworte (navTagLimit
|
||
in internal/web/server.go). Gibt es mehr, führt dieser Link zur
|
||
vollständigen, filterbaren Liste. */}}
|
||
{{if gt .Nav.TagsGesamt (len .Nav.Tags)}}
|
||
<ul class="nav-liste leise">
|
||
<li><a href="/p/{{.Project.Slug}}/tags" {{if eq .Bereich "schlagworte"}}class="aktiv"{{end}}>
|
||
<span class="nav-text">Alle Schlagworte…</span>
|
||
<span class="nav-zahl">{{.Nav.TagsGesamt}}</span>
|
||
</a></li>
|
||
</ul>
|
||
{{end}}
|
||
</nav>
|
||
{{end}}
|
||
{{end}}
|
||
|
||
{{if .Session.IsPlatformAdmin}}
|
||
<nav class="nav-gruppe">
|
||
<h2 class="nav-titel">Plattform</h2>
|
||
<ul class="nav-liste">
|
||
<li><a href="/admin/overview" {{if eq .Bereich "ueberblick"}}class="aktiv"{{end}}>Überblick (Workspace)</a></li>
|
||
<li><a href="/admin/search" {{if eq .Bereich "suche"}}class="aktiv"{{end}}>Suche (alle Projekte)</a></li>
|
||
<li><a href="/admin/audit">Protokoll (alle)</a></li>
|
||
<li><a href="/admin/workspaces" {{if eq .Bereich "workspaces"}}class="aktiv"{{end}}>Workspaces</a></li>
|
||
<li><a href="/admin/system" {{if eq .Bereich "system"}}class="aktiv"{{end}}>System</a></li>
|
||
</ul>
|
||
</nav>
|
||
{{else if .Session.IsWorkspaceAdmin}}
|
||
<nav class="nav-gruppe">
|
||
<h2 class="nav-titel">Workspace</h2>
|
||
<ul class="nav-liste">
|
||
<li><a href="/admin/overview" {{if eq .Bereich "ueberblick"}}class="aktiv"{{end}}>Überblick</a></li>
|
||
<li><a href="/admin/search" {{if eq .Bereich "suche"}}class="aktiv"{{end}}>Suche (alle Projekte)</a></li>
|
||
<li><a href="/admin/audit">Protokoll (alle)</a></li>
|
||
</ul>
|
||
</nav>
|
||
{{end}}
|
||
|
||
</aside>
|
||
|
||
<main class="inhalt">
|
||
{{if .Error}}<div class="meldung fehler">{{.Error}}</div>{{end}}
|
||
{{if .Flash}}<div class="meldung hinweis">{{.Flash}}</div>{{end}}
|
||
{{end}}
|
||
|
||
{{/* hilfelink setzt ein kleines "?" neben eine Überschrift oder ein Feld, das
|
||
zur passenden Stelle der eingebauten Hilfe führt (AUSBAUSTUFEN.md 5.4).
|
||
Aufruf mit dem Ziel unterhalb von /hilfe/, auf Wunsch mit Abschnitt:
|
||
{{template "hilfelink" "weboberflaeche#markdown-im-inhalt"}}
|
||
Die Abschnittsnamen entstehen aus den Überschriften der Hilfeseiten
|
||
(internal/markdown, ankerIDs). Ein Test in web_test.go prüft, dass jedes
|
||
Ziel in den Templates wirklich existiert — wer eine Überschrift umbenennt,
|
||
merkt es also.
|
||
|
||
Die Hilfe öffnet in einem neuen Tab: Wer mitten im Bearbeiten nachschlägt,
|
||
soll dabei nicht seinen ungespeicherten Text verlieren. rel="noopener"
|
||
verhindert, dass der neue Tab auf das Fenster dieser Seite zugreifen kann. */}}
|
||
{{define "hilfelink"}}<a class="hilfe-link" href="/hilfe/{{.}}" target="_blank" rel="noopener" title="Hilfe zu diesem Thema (neuer Tab)" aria-label="Hilfe zu diesem Thema (öffnet in neuem Tab)">?</a>{{end}}
|
||
|
||
{{define "fuss"}}
|
||
</main>
|
||
</div>
|
||
{{template "html-ende" .}}
|
||
{{end}}
|
||
|
||
{{/* Balkendiagramm der System- und Überblicksseite. Die Zahlen rechnet
|
||
internal/web/diagramm.go aus; hier wird nur gezeichnet. */}}
|
||
{{define "diagramm"}}
|
||
{{if .Leer}}
|
||
<p class="hilfe diagramm-leer">Keine im ganzen Zeitraum.</p>
|
||
{{else}}
|
||
<svg class="diagramm" viewBox="0 0 {{.Breite}} {{.Hoehe}}" role="img" aria-label="{{.Titel}}">
|
||
{{range .Gitter}}
|
||
<line class="diagramm-gitter" x1="{{$.Links}}" x2="{{$.Rechts}}" y1="{{.Y}}" y2="{{.Y}}"/>
|
||
<text class="diagramm-text" x="{{$.Links}}" dx="-6" y="{{.Y}}" dy="4" text-anchor="end">{{.Text}}</text>
|
||
{{end}}
|
||
{{range .Balken}}
|
||
<g>
|
||
<title>{{.Titel}}</title>
|
||
<rect class="diagramm-treffer" x="{{.X}}" y="0" width="{{.Breite}}" height="{{$.Grund}}"/>
|
||
{{range .Teile}}<rect class="{{.Klasse}}" x="{{.X}}" y="{{.Y}}" width="{{.Breite}}" height="{{.Hoehe}}" rx="2"/>{{end}}
|
||
</g>
|
||
{{end}}
|
||
{{range .Achse}}
|
||
<text class="diagramm-text" x="{{.X}}" y="{{$.Hoehe}}" dy="-4" text-anchor="middle">{{.Text}}</text>
|
||
{{end}}
|
||
</svg>
|
||
{{end}}
|
||
{{end}}
|