Files
Projektwissen/werkzeuge/vorschau/vorschau.html
T
DanielandClaude Opus 5.5 b341a658bc Bootstrap lokal einbetten und Stil der AG anlegen (#27)
- werkzeuge/bootstrap/: Bootstrap 5.3.8 (CSS, JS-Bundle) und Bootstrap
  Icons 1.13.1 (CSS, woff2/woff) byte-gleich aus den npm-Paketen,
  Integrität geprüft; README mit Version, Quelle, Integrität, Lizenz
  und Aktualisierung; Lizenzen (MIT) daneben; .gitattributes: binary,
  die README bleibt Text mit Diff.
- werkzeuge/stil/ag_prozesse.css: eigene kleine Stilschicht (ag-*):
  Seite in voller Höhe, dunkle Navigationsleiste, hellgrauer
  Hintergrund, Karten mit farbigem Rand, Tabellenziffern, Druck.
  Vorbild VLN_SN/EA-Bilanz, nichts übernommen.
- Vorschau: Kopfzeile als dunkle Navigationsleiste mit Icon-Knöpfen;
  JavaScript, IDs und Zeichenfläche (Wasserzeichen) unverändert.
- scripts/vorschau.py bettet Bootstrap, Icons und Stil ein und setzt die
  Icon-Schrift als data:-URI ein (_schriften_einbetten); ein nicht
  einbettbarer Schriftverweis bricht laut ab.
- Tests: drei neue in test_vorschau.py; der Aufbau von
  test_bibliothek_mit_script_ende_wird_abgelehnt kopiert jetzt ganz
  werkzeuge/ (Erwartung unverändert).
- AGENTS.md: eingebettete Fremdbibliotheken sind bpmn-js und Bootstrap.
- Tests: python -m pytest -q -> 256 bestanden, 1 übersprungen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:11:29 +02:00

106 lines
5.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de" class="ag-seite">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BPMN-Vorschau</title>
<!-- Bootstrap, Bootstrap Icons und bpmn-js (bpmn.io), lokal eingebettet – siehe README.md und
werkzeuge/bootstrap/README.md. Nichts wird aus dem Netz geladen. -->
<link rel="stylesheet" href="../bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="../bootstrap/icons/bootstrap-icons.min.css">
<link rel="stylesheet" href="../stil/ag_prozesse.css">
<link rel="stylesheet" href="bpmn-js/diagram-js.css">
<link rel="stylesheet" href="bpmn-js/bpmn-js.css">
<style>
#meldung { margin: 0; padding: .25rem 1rem; border-bottom: 1px solid var(--bs-border-color); background: var(--bs-body-bg); }
#meldung:empty { display: none; }
#meldung.fehler { color: var(--bs-danger); }
#meldung.warnung { color: var(--bs-warning-text-emphasis); }
/* Zeichenfläche: das bpmn.io-Wasserzeichen unten rechts muss laut Lizenz sichtbar und unverdeckt bleiben. */
#flaeche { position: absolute; inset: 0; }
#hinweis {
position: absolute; inset: 24px 24px 64px 24px; display: flex; align-items: center; justify-content: center;
text-align: center; color: var(--bs-secondary-color); border: 2px dashed var(--bs-border-color);
border-radius: .75rem; padding: 1rem; pointer-events: none;
}
main.ziehen #hinweis { border-color: var(--ag-akzent); color: var(--ag-akzent); }
main.geladen #hinweis { display: none; }
</style>
</head>
<body class="ag-app">
<nav class="navbar navbar-dark bg-dark navbar-expand px-3 py-1 ag-nav">
<span class="navbar-brand mb-0"><i class="bi bi-diagram-3 me-1"></i>BPMN-Vorschau</span>
<span id="dateiname" class="text-secondary small text-truncate me-auto"></span>
<div class="btn-group btn-group-sm">
<label class="btn btn-outline-light" for="datei" title="Datei öffnen"><i class="bi bi-folder2-open"></i><span class="d-none d-md-inline"> Datei öffnen …</span></label>
<button type="button" class="btn btn-outline-light" id="einpassen" disabled title="Einpassen"><i class="bi bi-arrows-angle-contract"></i><span class="d-none d-md-inline"> Einpassen</span></button>
<button type="button" class="btn btn-outline-light" id="groesser" disabled title="Vergrößern"><i class="bi bi-zoom-in"></i></button>
<button type="button" class="btn btn-outline-light" id="kleiner" disabled title="Verkleinern"><i class="bi bi-zoom-out"></i></button>
</div>
<input type="file" id="datei" accept=".bpmn,.xml" hidden>
</nav>
<p id="meldung" role="status"></p>
<main id="bereich" class="ag-inhalt">
<div id="flaeche"></div>
<div id="hinweis">.bpmn-Datei hierher ziehen oder über „Datei öffnen …“ wählen.<br>
Die Datei wird nur in diesem Browser angezeigt und nirgendwohin übertragen.</div>
</main>
<script src="bpmn-js/bpmn-navigated-viewer.production.min.js"></script>
<script>
// Wird von scripts/vorschau.py durch den Inhalt einer .bpmn und ihren Namen ersetzt.
const EINGEBETTET = null;
const DATEINAME = null;
const bereich = document.getElementById('bereich');
const meldung = document.getElementById('meldung');
const knoepfe = ['einpassen', 'groesser', 'kleiner'].map(id => document.getElementById(id));
const viewer = new BpmnJS({ container: '#flaeche' });
const canvas = () => viewer.get('canvas');
function melde(text, art) {
meldung.textContent = text || '';
meldung.className = art || '';
}
async function zeige(xml, name) {
melde('');
try {
const { warnings } = await viewer.importXML(xml);
canvas().zoom('fit-viewport', 'auto');
bereich.classList.add('geladen');
knoepfe.forEach(k => { k.disabled = false; });
document.getElementById('dateiname').textContent = name || '';
document.title = name ? `${name} – BPMN-Vorschau` : 'BPMN-Vorschau';
if (warnings.length) {
melde(`${warnings.length} Warnung(en) beim Einlesen: ` + warnings.map(w => w.message).join(' | '), 'warnung');
}
} catch (fehler) {
bereich.classList.remove('geladen');
knoepfe.forEach(k => { k.disabled = true; });
melde(`Die Datei ${name || ''} lässt sich nicht als BPMN lesen: ${fehler.message}`, 'fehler');
}
}
function lies(datei) {
if (!datei) return;
datei.text().then(xml => zeige(xml, datei.name));
}
document.getElementById('datei').addEventListener('change', e => lies(e.target.files[0]));
document.getElementById('einpassen').addEventListener('click', () => canvas().zoom('fit-viewport', 'auto'));
document.getElementById('groesser').addEventListener('click', () => canvas().zoom(canvas().zoom() * 1.25));
document.getElementById('kleiner').addEventListener('click', () => canvas().zoom(canvas().zoom() / 1.25));
['dragenter', 'dragover'].forEach(art => document.addEventListener(art, e => {
e.preventDefault(); bereich.classList.add('ziehen');
}));
['dragleave', 'drop'].forEach(art => document.addEventListener(art, e => {
e.preventDefault(); bereich.classList.remove('ziehen');
}));
document.addEventListener('drop', e => lies(e.dataTransfer.files[0]));
if (EINGEBETTET) zeige(EINGEBETTET, DATEINAME);
</script>
</body>
</html>