feat: enconf-Layout-Patterns übertragen — responsive Card-Tabellen, PageHeader, StatCards
Über die Architect-RAG-Suche (ac_search_code_global) drei UX-Muster aus dem enconf-Schwesterprojekt (React/Ant Design) identifiziert und als reines CSS/HTML nachgebaut, da Deklarix bewusst kein SPA ist: - .table-responsive: Tabellen werden unter 640px zu einer Card-Liste statt horizontal zu scrollen (enconfs ProTable-Verhalten), via data-label-Attribut je <td>. Angewendet auf beide Werkzeugkatalog-Tabellen. - .page-header: Titel+Unterzeile links, primäre Aktion rechts, statt eines nackten <h1> mit Link irgendwo unten. - .stat-cards: Kennzahl-Kacheln mit farbigem Akzentrand (nur farbig bei Wert > 0) statt einfacher Text-Links, auf der Startseite.
This commit is contained in:
34
CLAUDE.md
34
CLAUDE.md
@@ -598,6 +598,40 @@ wie die Formular-Abschnitte angehoben (600/1rem statt 500/0.9375rem) —
|
|||||||
für eine einheitliche Überschriften-Hierarchie statt Zufallsgrößen je
|
für eine einheitliche Überschriften-Hierarchie statt Zufallsgrößen je
|
||||||
nach UA-Stylesheet.
|
nach UA-Stylesheet.
|
||||||
|
|
||||||
|
**enconf-Patterns übertragen (2026-08-31):** enconf (Schwesterprojekt)
|
||||||
|
ist React + Ant Design (`ProTable`/`StatCard`/`PageHeader`-Komponenten)
|
||||||
|
— nicht 1:1 übernehmbar, da Deklarix bewusst kein SPA ist, aber die
|
||||||
|
*Muster* wurden als reines CSS/HTML nachgebaut (recherchiert über die
|
||||||
|
Architect-RAG-Suche, `ac_search_code_global`, da das enconf-Repo selbst
|
||||||
|
außerhalb des Arbeitsverzeichnisses liegt):
|
||||||
|
|
||||||
|
- **`.table-responsive`** (ersetzt `.table-scroll` schrittweise) —
|
||||||
|
enconfs `ProTable.tsx` schaltet auf schmalen Screens von Tabelle auf
|
||||||
|
eine Card-Liste um (`renderMobileCard` via `Grid.useBreakpoint()`),
|
||||||
|
statt horizontal zu scrollen. Nachgebaut rein in CSS: unter 640px
|
||||||
|
werden `<tr>` zu Karten, `<td>` zu Label/Wert-Zeilen (`content:
|
||||||
|
attr(data-label)` im `::before`) — jedes `<td>` braucht dafür ein
|
||||||
|
`data-label="Spaltenname"`-Attribut. Ab 640px normale Tabelle mit
|
||||||
|
Scroll-Fade als Sicherheitsnetz. Bisher angewendet auf beide
|
||||||
|
Werkzeugkatalog-Tabellen; `.table-scroll` (nur Scroll-Fade, keine
|
||||||
|
Card-Umschaltung) bleibt für noch nicht migrierte Tabellen (Register,
|
||||||
|
Nutzer-Import-Ergebnis) bestehen.
|
||||||
|
- **`.page-header`** (Titel+Unterzeile links, primäre Aktion rechts,
|
||||||
|
stapelt auf Mobile) — ersetzt einen nackten `<h1>` mit einem Link
|
||||||
|
irgendwo unten auf der Seite. Bisher auf den Werkzeugkatalog
|
||||||
|
angewendet (Betreiber + Mandant, inkl. "Eigene Werkzeuge"-Abschnitt).
|
||||||
|
- **`.stat-cards`/`.stat-card`** — Kennzahl-Kacheln mit farbigem oberem
|
||||||
|
Akzentrand (blau normal, gelb/rot nur wenn der Wert > 0 ist — keine
|
||||||
|
Farbe ohne Grund) statt einfacher Text-Links; `.stat-card-action` für
|
||||||
|
die primäre Handlungs-Kachel (z. B. "Antrag stellen"). Kein
|
||||||
|
Icon-Set/keine Icon-Bibliothek eingeführt (enconf nutzt
|
||||||
|
`@ant-design/icons`, das ist React-spezifisch) — bewusste
|
||||||
|
Vereinfachung. Angewendet auf die Startseite (`index.html`).
|
||||||
|
|
||||||
|
Noch nicht auf weitere Tabellen/Seiten übertragen (Register,
|
||||||
|
Nutzerliste, Abteilungen, Fälle-Posteingang, Betreiber-Dashboard) —
|
||||||
|
nächste Kandidaten, falls das Muster fortgesetzt werden soll.
|
||||||
|
|
||||||
**Verifikationsmethode für CSS-Änderungen:** Live-Cookie-Auth per
|
**Verifikationsmethode für CSS-Änderungen:** Live-Cookie-Auth per
|
||||||
Chromium-Headless/CDP ist im Sandbox-Environment nicht möglich (kein
|
Chromium-Headless/CDP ist im Sandbox-Environment nicht möglich (kein
|
||||||
websocket-Python-Modul) — stattdessen: Seite per `curl -b cookies.txt`
|
websocket-Python-Modul) — stattdessen: Seite per `curl -b cookies.txt`
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ func TestIndexZeigtEigeneOffeneAntraege(t *testing.T) {
|
|||||||
if resp.Code != http.StatusOK {
|
if resp.Code != http.StatusOK {
|
||||||
t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String())
|
t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String())
|
||||||
}
|
}
|
||||||
if !strings.Contains(resp.Body.String(), `href="/antraege">Meine offenen Anträge <span class="status">1</span>`) {
|
body := resp.Body.String()
|
||||||
t.Errorf("expected 1 offenen Antrag auf der Startseite, got: %s", resp.Body.String())
|
if !strings.Contains(body, `href="/antraege"`) || !strings.Contains(body, `stat-card-value">1</span>`) || !strings.Contains(body, "Meine offenen Anträge") {
|
||||||
|
t.Errorf("expected 1 offenen Antrag auf der Startseite, got: %s", body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,8 +29,9 @@ func TestIndexZeigtPosteingangNurFuerFachebene(t *testing.T) {
|
|||||||
if resp.Code != http.StatusOK {
|
if resp.Code != http.StatusOK {
|
||||||
t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String())
|
t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String())
|
||||||
}
|
}
|
||||||
if !strings.Contains(resp.Body.String(), `href="/faelle">Posteingang <span class="status">1</span>`) {
|
body := resp.Body.String()
|
||||||
t.Errorf("expected 1 offenen Fall im Posteingang auf der Startseite, got: %s", resp.Body.String())
|
if !strings.Contains(body, `href="/faelle"`) || !strings.Contains(body, `stat-card-value">1</span>`) || !strings.Contains(body, "Posteingang") {
|
||||||
|
t.Errorf("expected 1 offenen Fall im Posteingang auf der Startseite, got: %s", body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ func TestIndexZeigtPlattformLinkFuerBetreiber(t *testing.T) {
|
|||||||
if resp.Code != http.StatusOK {
|
if resp.Code != http.StatusOK {
|
||||||
t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String())
|
t.Fatalf("status = %d, body: %s", resp.Code, resp.Body.String())
|
||||||
}
|
}
|
||||||
if !strings.Contains(resp.Body.String(), `href="/betreiber">Zur Plattform`) {
|
if !strings.Contains(resp.Body.String(), `href="/betreiber"`) || !strings.Contains(resp.Body.String(), "Zur Plattform") {
|
||||||
t.Errorf("expected a Plattform link for betreiber, got: %s", resp.Body.String())
|
t.Errorf("expected a Plattform link for betreiber, got: %s", resp.Body.String())
|
||||||
}
|
}
|
||||||
if strings.Contains(resp.Body.String(), "Antrag stellen") {
|
if strings.Contains(resp.Body.String(), "Antrag stellen") {
|
||||||
|
|||||||
@@ -792,6 +792,183 @@ tbody tr:hover {
|
|||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Responsive Tabellen — Card-Ansicht auf dem Handy ────────────────
|
||||||
|
enconf-Pattern (ProTable.tsx): auf schmalen Screens wird nicht
|
||||||
|
horizontal gescrollt, sondern jede Zeile zu einer eigenen Karte mit
|
||||||
|
Label/Wert-Paaren. Braucht data-label="Spaltenname" auf jedem <td>.
|
||||||
|
Ab 640px bleibt es eine normale Tabelle (mit Scroll-Fade als
|
||||||
|
Sicherheitsnetz bei vielen Spalten). */
|
||||||
|
.table-responsive {
|
||||||
|
overflow-x: auto;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
-webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
|
||||||
|
mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.table-responsive {
|
||||||
|
overflow-x: visible;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-mask-image: none;
|
||||||
|
mask-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive table,
|
||||||
|
.table-responsive tbody,
|
||||||
|
.table-responsive tr,
|
||||||
|
.table-responsive td {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive thead {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive tbody tr {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive td {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 12px;
|
||||||
|
text-align: right;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive td:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-responsive td::before {
|
||||||
|
content: attr(data-label);
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-heading);
|
||||||
|
text-align: left;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Seitenkopf (PageHeader-Pattern, enconf) ─────────────────────────
|
||||||
|
Titel + Unterzeile links, primäre Aktion rechts — statt eines
|
||||||
|
nackten <h1> mit einem Link irgendwo unten auf der Seite. */
|
||||||
|
.page-header {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header h1 {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .hinweis {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .page-header-action {
|
||||||
|
margin-top: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
background: var(--branding-primary);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header .page-header-action:hover {
|
||||||
|
filter: brightness(0.94);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Kennzahl-Kacheln (StatCard-Pattern, enconf Dashboard) ───────────
|
||||||
|
Vorher: einfache Text-Links in einer Liste ohne visuelle Priorität.
|
||||||
|
Jetzt: farbiger oberer Akzentrand + große Zahl + Klick navigiert zur
|
||||||
|
Liste, wie enconfs StatCard-Komponente — nur ohne Icon-Bibliothek. */
|
||||||
|
.stat-cards {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 0 24px;
|
||||||
|
padding: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
display: block;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-top: 3px solid var(--branding-primary);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
padding: 16px 18px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: box-shadow 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-value {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--color-heading);
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-muted);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-mittel {
|
||||||
|
border-top-color: var(--color-mittel);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-hoch {
|
||||||
|
border-top-color: var(--color-hoch);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-action {
|
||||||
|
background: var(--branding-primary);
|
||||||
|
border-color: var(--branding-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card-action .stat-card-label {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ab hier mehr Platz (Tablet) — der Container bekommt spürbaren
|
/* Ab hier mehr Platz (Tablet) — der Container bekommt spürbaren
|
||||||
Rand statt volle Breite, sonst bleibt alles identisch. */
|
Rand statt volle Breite, sonst bleibt alles identisch. */
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
|
|||||||
@@ -5,7 +5,13 @@
|
|||||||
{{template "nav" .Nav}}
|
{{template "nav" .Nav}}
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<p><a href="/betreiber">← Plattform</a></p>
|
<p><a href="/betreiber">← Plattform</a></p>
|
||||||
|
<div class="page-header">
|
||||||
|
<div>
|
||||||
<h1>Werkzeugkatalog</h1>
|
<h1>Werkzeugkatalog</h1>
|
||||||
|
<p class="hinweis">Zentral gepflegt, für alle Mandanten sichtbar.</p>
|
||||||
|
</div>
|
||||||
|
<a class="page-header-action" href="/betreiber/werkzeuge/neu">Werkzeug anlegen</a>
|
||||||
|
</div>
|
||||||
<form method="get">
|
<form method="get">
|
||||||
<div class="filter-bar">
|
<div class="filter-bar">
|
||||||
<input type="search" name="q" value="{{.Filter.Suche}}" placeholder="Suche (Name, Anbieter, Land)">
|
<input type="search" name="q" value="{{.Filter.Suche}}" placeholder="Suche (Name, Anbieter, Land)">
|
||||||
@@ -23,7 +29,7 @@
|
|||||||
{{if not .Werkzeuge}}
|
{{if not .Werkzeuge}}
|
||||||
<p class="hinweis">{{if .Filter.Aktiv}}Keine Treffer für diese Filter.{{else}}Noch keine zentralen Katalogeinträge.{{end}}</p>
|
<p class="hinweis">{{if .Filter.Aktiv}}Keine Treffer für diese Filter.{{else}}Noch keine zentralen Katalogeinträge.{{end}}</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="table-scroll">
|
<div class="table-responsive">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -35,16 +41,16 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{range .Werkzeuge}}
|
{{range .Werkzeuge}}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="/betreiber/werkzeuge/{{.ID}}">{{.Name}}</a></td>
|
<td data-label="Name"><a href="/betreiber/werkzeuge/{{.ID}}">{{.Name}}</a></td>
|
||||||
<td>{{.Anbieter}}</td>
|
<td data-label="Anbieter">{{.Anbieter}}</td>
|
||||||
<td>{{.Verarbeitungslaender}}</td>
|
<td data-label="Verarbeitungsländer">{{.Verarbeitungslaender}}</td>
|
||||||
<td>{{if .DPFZertifiziert}}ja{{else}}nein{{end}}</td>
|
<td data-label="DPF">{{if .DPFZertifiziert}}ja{{else}}nein{{end}}</td>
|
||||||
<td>{{if .AVVVerfuegbar}}ja{{else}}nein{{end}}</td>
|
<td data-label="AVV">{{if .AVVVerfuegbar}}ja{{else}}nein{{end}}</td>
|
||||||
<td>{{if .TrainingStandard}}ja{{else}}nein{{end}}</td>
|
<td data-label="Training aus">{{if .TrainingStandard}}ja{{else}}nein{{end}}</td>
|
||||||
<td>{{.Aufbewahrung}}</td>
|
<td data-label="Aufbewahrung">{{.Aufbewahrung}}</td>
|
||||||
<td>{{.Zertifizierungen}}</td>
|
<td data-label="Zertifizierungen">{{.Zertifizierungen}}</td>
|
||||||
<td>{{.GeeigneteZwecke}}</td>
|
<td data-label="Geeignete Zwecke">{{.GeeigneteZwecke}}</td>
|
||||||
<td>{{.LetztePruefung}} <span class="status {{.PruefStatusCSS}}">{{.PruefStatusLabel}}</span></td>
|
<td data-label="Zuletzt geprüft">{{.LetztePruefung}} <span class="status {{.PruefStatusCSS}}">{{.PruefStatusLabel}}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -59,7 +65,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</form>
|
</form>
|
||||||
<p><a href="/betreiber/werkzeuge/neu">Werkzeug anlegen</a></p>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -6,15 +6,25 @@
|
|||||||
<div class="page">
|
<div class="page">
|
||||||
<h1>Willkommen bei Deklarix</h1>
|
<h1>Willkommen bei Deklarix</h1>
|
||||||
{{if .Nav.IsBetreiber}}
|
{{if .Nav.IsBetreiber}}
|
||||||
<ul class="admin-kacheln">
|
<ul class="stat-cards">
|
||||||
<li><a href="/betreiber">Zur Plattform</a></li>
|
<li><a class="stat-card stat-card-action" href="/betreiber"><span class="stat-card-label">Zur Plattform →</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{{else}}
|
{{else}}
|
||||||
<ul class="admin-kacheln">
|
<ul class="stat-cards">
|
||||||
<li><a href="/antraege/neu">Antrag stellen</a></li>
|
<li><a class="stat-card stat-card-action" href="/antraege/neu"><span class="stat-card-label">Antrag stellen →</span></a></li>
|
||||||
<li><a href="/antraege">Meine offenen Anträge <span class="status">{{.OffeneAntraege}}</span></a></li>
|
<li>
|
||||||
|
<a class="stat-card{{if .OffeneAntraege}} stat-card-mittel{{end}}" href="/antraege">
|
||||||
|
<span class="stat-card-value">{{.OffeneAntraege}}</span>
|
||||||
|
<span class="stat-card-label">Meine offenen Anträge</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
{{if .ZeigePosteingang}}
|
{{if .ZeigePosteingang}}
|
||||||
<li><a href="/faelle">Posteingang <span class="status">{{.OffenerPosteingang}}</span></a></li>
|
<li>
|
||||||
|
<a class="stat-card{{if .OffenerPosteingang}} stat-card-hoch{{end}}" href="/faelle">
|
||||||
|
<span class="stat-card-value">{{.OffenerPosteingang}}</span>
|
||||||
|
<span class="stat-card-label">Posteingang</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -6,12 +6,16 @@
|
|||||||
<div class="page">
|
<div class="page">
|
||||||
<h1>Werkzeugkatalog</h1>
|
<h1>Werkzeugkatalog</h1>
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<div>
|
||||||
<h2>Zentraler Katalog</h2>
|
<h2>Zentraler Katalog</h2>
|
||||||
<p class="hinweis">
|
<p class="hinweis">
|
||||||
Wird von der Plattform gepflegt. Ein gesperrtes Werkzeug bleibt im
|
Wird von der Plattform gepflegt. Ein gesperrtes Werkzeug bleibt im
|
||||||
zentralen Katalog unverändert — es wird nur für diesen Mandanten aus
|
zentralen Katalog unverändert — es wird nur für diesen Mandanten
|
||||||
der Werkzeugsuche ausgeblendet.
|
aus der Werkzeugsuche ausgeblendet.
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<form method="get" class="filter-bar">
|
<form method="get" class="filter-bar">
|
||||||
<input type="search" name="q" value="{{.Filter.Suche}}" placeholder="Suche (Name, Anbieter, Land)">
|
<input type="search" name="q" value="{{.Filter.Suche}}" placeholder="Suche (Name, Anbieter, Land)">
|
||||||
<select name="zweck">
|
<select name="zweck">
|
||||||
@@ -27,7 +31,7 @@
|
|||||||
{{if not .Werkzeuge}}
|
{{if not .Werkzeuge}}
|
||||||
<p class="hinweis">{{if .Filter.Aktiv}}Keine Treffer für diese Filter.{{else}}Der zentrale Katalog ist noch leer.{{end}}</p>
|
<p class="hinweis">{{if .Filter.Aktiv}}Keine Treffer für diese Filter.{{else}}Der zentrale Katalog ist noch leer.{{end}}</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="table-scroll">
|
<div class="table-responsive">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -38,15 +42,15 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{range .Werkzeuge}}
|
{{range .Werkzeuge}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.Name}}</td>
|
<td data-label="Name">{{.Name}}</td>
|
||||||
<td>{{.Anbieter}}</td>
|
<td data-label="Anbieter">{{.Anbieter}}</td>
|
||||||
<td>{{.Verarbeitungslaender}}</td>
|
<td data-label="Verarbeitungsländer">{{.Verarbeitungslaender}}</td>
|
||||||
<td>{{if .AVVVerfuegbar}}ja{{else}}nein{{end}}</td>
|
<td data-label="AVV">{{if .AVVVerfuegbar}}ja{{else}}nein{{end}}</td>
|
||||||
<td>{{if .TrainingStandard}}ja{{else}}nein{{end}}</td>
|
<td data-label="Training aus">{{if .TrainingStandard}}ja{{else}}nein{{end}}</td>
|
||||||
<td>{{.Aufbewahrung}}</td>
|
<td data-label="Aufbewahrung">{{.Aufbewahrung}}</td>
|
||||||
<td>{{.GeeigneteZwecke}}</td>
|
<td data-label="Geeignete Zwecke">{{.GeeigneteZwecke}}</td>
|
||||||
<td>{{.LetztePruefung}} <span class="status {{.PruefStatusCSS}}">{{.PruefStatusLabel}}</span></td>
|
<td data-label="Zuletzt geprüft">{{.LetztePruefung}} <span class="status {{.PruefStatusCSS}}">{{.PruefStatusLabel}}</span></td>
|
||||||
<td>
|
<td data-label="Status">
|
||||||
{{if .Gesperrt}}
|
{{if .Gesperrt}}
|
||||||
<span class="status">gesperrt</span>
|
<span class="status">gesperrt</span>
|
||||||
<form method="post" action="/verwaltung/werkzeuge/{{.ID}}/entsperren" style="display:inline">
|
<form method="post" action="/verwaltung/werkzeuge/{{.ID}}/entsperren" style="display:inline">
|
||||||
@@ -87,15 +91,20 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<div>
|
||||||
<h2>Eigene Werkzeuge</h2>
|
<h2>Eigene Werkzeuge</h2>
|
||||||
<p class="hinweis">
|
<p class="hinweis">
|
||||||
Zusätzliche Katalogeinträge nur für diesen Mandanten — sichtbar nur
|
Zusätzliche Katalogeinträge nur für diesen Mandanten — sichtbar nur
|
||||||
hier, nicht im zentralen Katalog der Plattform.
|
hier, nicht im zentralen Katalog der Plattform.
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
<a class="page-header-action" href="/verwaltung/werkzeuge/neu">Eigenes Werkzeug anlegen</a>
|
||||||
|
</div>
|
||||||
{{if not .EigeneWerkzeuge}}
|
{{if not .EigeneWerkzeuge}}
|
||||||
<p class="hinweis">Noch keine eigenen Werkzeuge.</p>
|
<p class="hinweis">Noch keine eigenen Werkzeuge.</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="table-scroll">
|
<div class="table-responsive">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th>Name</th><th>Anbieter</th><th>Verarbeitungsländer</th><th>Zuletzt geprüft</th></tr>
|
<tr><th>Name</th><th>Anbieter</th><th>Verarbeitungsländer</th><th>Zuletzt geprüft</th></tr>
|
||||||
@@ -103,17 +112,16 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{range .EigeneWerkzeuge}}
|
{{range .EigeneWerkzeuge}}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="/verwaltung/werkzeuge/{{.ID}}">{{.Name}}</a></td>
|
<td data-label="Name"><a href="/verwaltung/werkzeuge/{{.ID}}">{{.Name}}</a></td>
|
||||||
<td>{{.Anbieter}}</td>
|
<td data-label="Anbieter">{{.Anbieter}}</td>
|
||||||
<td>{{.Verarbeitungslaender}}</td>
|
<td data-label="Verarbeitungsländer">{{.Verarbeitungslaender}}</td>
|
||||||
<td>{{.LetztePruefung}}</td>
|
<td data-label="Zuletzt geprüft">{{.LetztePruefung}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<p><a href="/verwaltung/werkzeuge/neu">Eigenes Werkzeug anlegen</a></p>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user