m/paliad#61 Slice C frontend pass. Discovery (Geteilte Vorlagen): - New 4th tab on /checklists between "Meine Vorlagen" and "Vorhandene Instanzen". Filters the merged catalog response to authored entries not owned by the caller (firm-visible OR globally-promoted OR share-recipient). Tab state round-trips via ?tab=gallery. - Regime filter pills (UPC / DE / EPA / OTHER) operate independently from the main Vorlagen tab. - Cards show regime badge, item count, author line, visibility chip. - Self-filter relies on /api/me email match — loadMe() fires once on page boot and is idempotent. Versioning UI on /checklists/instances/{id}: - "Vorlage aktualisiert" badge appears when the instance's template_version is known AND lags the live template version (only for authored templates; static templates never bump). Shows "v{from} → v{to}" delta. - "Änderungen anzeigen" button opens a diff modal that compares the instance's template_snapshot against the live template body. Item-level grouping by (section title, item label). Surfaces added / removed / changed items with localised section labels. Empty state when only metadata changed. i18n: 13 new keys per language (DE + EN) under checklisten.tab.gallery, checklisten.gallery.*, checklisten.filter.other, and checklisten.instance.{outdated,diff}.*. Total 2666 keys. Build hygiene: bun run build clean; i18n scan clean. Go build/vet/test + TestBootSmoke ./cmd/server/ all green.
116 lines
6.8 KiB
TypeScript
116 lines
6.8 KiB
TypeScript
import { h } from "./jsx";
|
|
import { Sidebar } from "./components/Sidebar";
|
|
import { PaliadinWidget } from "./components/PaliadinWidget";
|
|
import { BottomNav } from "./components/BottomNav";
|
|
import { Footer } from "./components/Footer";
|
|
import { PWAHead } from "./components/PWAHead";
|
|
|
|
export function renderChecklists(): string {
|
|
return "<!DOCTYPE html>" + (
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#BFF355" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<PWAHead />
|
|
<title data-i18n="checklisten.title">Checklisten — Paliad</title>
|
|
<link rel="stylesheet" href="/assets/global.css" />
|
|
</head>
|
|
<body className="has-sidebar">
|
|
<Sidebar currentPath="/checklists" />
|
|
<BottomNav currentPath="/checklists" />
|
|
|
|
<main>
|
|
<section className="tool-page">
|
|
<div className="container">
|
|
<div className="tool-header">
|
|
<h1 data-i18n="checklisten.heading">Checklisten</h1>
|
|
<p className="tool-subtitle" data-i18n="checklisten.subtitle">
|
|
Interaktive Checklisten für typische Verfahrensschritte vor UPC, BPatG und EPA.
|
|
</p>
|
|
</div>
|
|
|
|
<nav className="entity-tabs" id="checklists-tabs" aria-label="Checklisten-Ansichten">
|
|
<a className="entity-tab active" data-tab="templates" href="/checklists" data-i18n="checklisten.tab.templates">Vorlagen</a>
|
|
<a className="entity-tab" data-tab="mine" href="/checklists?tab=mine" data-i18n="checklisten.tab.mine">Meine Vorlagen</a>
|
|
<a className="entity-tab" data-tab="gallery" href="/checklists?tab=gallery" data-i18n="checklisten.tab.gallery">Geteilte Vorlagen</a>
|
|
<a className="entity-tab" data-tab="instances" href="/checklists?tab=instances" data-i18n="checklisten.tab.instances">Vorhandene Instanzen</a>
|
|
</nav>
|
|
|
|
{/* Templates tab — pick a template to inspect / instantiate */}
|
|
<section className="entity-tab-panel" id="tab-templates">
|
|
<div className="checklist-filters" id="checklist-filters">
|
|
<button className="filter-pill active" data-regime="all" type="button" data-i18n="checklisten.filter.all">Alle</button>
|
|
<button className="filter-pill" data-regime="UPC" type="button">UPC</button>
|
|
<button className="filter-pill" data-regime="DE" type="button" data-i18n="checklisten.filter.de">DE</button>
|
|
<button className="filter-pill" data-regime="EPA" type="button">EPA</button>
|
|
</div>
|
|
|
|
<div className="checklist-grid" id="checklist-grid" />
|
|
</section>
|
|
|
|
{/* Meine Vorlagen tab — caller's own authored templates */}
|
|
<section className="entity-tab-panel" id="tab-mine" style="display:none">
|
|
<div className="tool-actions" style="margin-bottom:1rem">
|
|
<a href="/checklists/new" className="btn btn-primary" data-i18n="checklisten.mine.new">Neue Vorlage</a>
|
|
</div>
|
|
<p className="entity-events-empty" id="checklists-mine-loading" data-i18n="checklisten.mine.loading">Lädt…</p>
|
|
<p className="entity-events-empty" id="checklists-mine-empty" style="display:none" data-i18n="checklisten.mine.empty">
|
|
Sie haben noch keine eigene Vorlage angelegt.
|
|
</p>
|
|
<div className="checklist-grid" id="checklists-mine-grid" style="display:none" />
|
|
</section>
|
|
|
|
{/* Geteilte Vorlagen tab — discovery surface for templates
|
|
that aren't owned by the caller (firm-published,
|
|
globally-promoted, or explicitly shared). Slice C. */}
|
|
<section className="entity-tab-panel" id="tab-gallery" style="display:none">
|
|
<div className="checklist-filters" id="checklist-gallery-filters">
|
|
<button className="filter-pill active" data-regime="all" type="button" data-i18n="checklisten.filter.all">Alle</button>
|
|
<button className="filter-pill" data-regime="UPC" type="button">UPC</button>
|
|
<button className="filter-pill" data-regime="DE" type="button" data-i18n="checklisten.filter.de">DE</button>
|
|
<button className="filter-pill" data-regime="EPA" type="button">EPA</button>
|
|
<button className="filter-pill" data-regime="OTHER" type="button" data-i18n="checklisten.filter.other">Sonstige</button>
|
|
</div>
|
|
<p className="entity-events-empty" id="checklists-gallery-loading" data-i18n="checklisten.mine.loading">Lädt…</p>
|
|
<p className="entity-events-empty" id="checklists-gallery-empty" style="display:none" data-i18n="checklisten.gallery.empty">
|
|
Noch keine geteilten Vorlagen sichtbar.
|
|
</p>
|
|
<div className="checklist-grid" id="checklists-gallery-grid" style="display:none" />
|
|
</section>
|
|
|
|
{/* Instances tab — every visible instance across templates */}
|
|
<section className="entity-tab-panel" id="tab-instances" style="display:none">
|
|
<p className="entity-events-empty" id="checklists-instances-loading" data-i18n="checklisten.instances.all.loading">Lädt…</p>
|
|
<p className="entity-events-empty" id="checklists-instances-empty" style="display:none" data-i18n="checklisten.instances.all.empty">
|
|
Noch keine Checklisten-Instanzen erfasst. Legen Sie eine über den Vorlagen-Tab an.
|
|
</p>
|
|
<div className="entity-table-wrap" id="checklists-instances-tablewrap" style="display:none">
|
|
<table className="entity-table">
|
|
<thead>
|
|
<tr>
|
|
<th data-i18n="checklisten.instances.all.col.template">Vorlage</th>
|
|
<th data-i18n="checklisten.instances.all.col.name">Name</th>
|
|
<th data-i18n="checklisten.instances.all.col.project">Projekt</th>
|
|
<th data-i18n="checklisten.instances.all.col.progress">Fortschritt</th>
|
|
<th data-i18n="checklisten.instances.all.col.created">Angelegt</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="checklists-instances-body" />
|
|
</table>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<Footer />
|
|
<PaliadinWidget />
|
|
<script src="/assets/checklists.js"></script>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|