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>
This commit is contained in:
+4
-1
@@ -12,5 +12,8 @@
|
||||
*.docx binary
|
||||
*.vsdx binary
|
||||
|
||||
# Eingebettete Fremdbibliothek (werkzeuge/vorschau/README.md): Bytes unverändert lassen, keine Diffs
|
||||
# Eingebettete Fremdbibliotheken (werkzeuge/vorschau/README.md, werkzeuge/bootstrap/README.md):
|
||||
# Bytes unverändert lassen, keine Diffs. Die README daneben bleibt Text.
|
||||
werkzeuge/vorschau/bpmn-js/** binary
|
||||
werkzeuge/bootstrap/** binary
|
||||
werkzeuge/bootstrap/README.md text eol=lf diff merge
|
||||
|
||||
@@ -61,8 +61,9 @@ Sie bleibt bewusst kurz: Details liegen in `docs/` und werden nur bei Bedarf gel
|
||||
- Rollen und Verantwortliche in Prozessmodellen als Funktion benennen („Sachbearbeitung Flurbereinigung"),
|
||||
nie als Person.
|
||||
- Keine Python-Abhängigkeiten außer der Standardbibliothek und `pytest` ohne Issue-Absprache und Eintrag in
|
||||
`fallstricke.md`. Einzige eingebettete Fremdbibliothek ist bpmn-js unter `werkzeuge/vorschau/bpmn-js/` –
|
||||
nicht von Hand ändern, Aktualisierung nach `werkzeuge/vorschau/README.md`.
|
||||
`fallstricke.md`. Eingebettete Fremdbibliotheken sind nur bpmn-js (`werkzeuge/vorschau/bpmn-js/`) und Bootstrap
|
||||
mit Bootstrap Icons (`werkzeuge/bootstrap/`) – nicht von Hand ändern, Aktualisierung nach der jeweiligen
|
||||
`README.md`. Eigene Gestaltung gehört nach `werkzeuge/stil/ag_prozesse.css`. Weitere nur per Issue.
|
||||
- **Die Markdown-Syntax und das Ablageformat der Prozessbibliothek sind Verträge.** Wer sie ändert, prüft vorher
|
||||
alle Modelle der Bibliothek, zieht `Anleitung.md` bzw. `docs/leitfaden/08_prozessbibliothek.md` nach und nennt die Änderung im Pull
|
||||
Request unter „Änderungen an Syntax und Ablageformat“.
|
||||
|
||||
@@ -31,6 +31,10 @@ Skills sind übernommen, alles QGIS- und Plugin-Spezifische ist entfernt. Kern i
|
||||
|
||||
## Erledigt
|
||||
|
||||
- 25.09.2026 **Bootstrap lokal eingebettet, Stil der AG** (#27): Bootstrap 5.3.8 und Bootstrap Icons 1.13.1
|
||||
unter `werkzeuge/bootstrap/`, eigene Regeln in `werkzeuge/stil/ag_prozesse.css`; die BPMN-Vorschau hat jetzt eine
|
||||
dunkle Navigationsleiste wie die Anwendungen in VLN_SN und bleibt offline.
|
||||
|
||||
- 25.09.2026 **Vorwärtskanten weichen Elementen aus** (#22): Umweg über freie Linien, nur wenn der
|
||||
Standardweg ein Element schneidet; Belastungstest (126 Fälle) als dauerhafter Test. Beispiele unverändert.
|
||||
|
||||
|
||||
@@ -116,6 +116,11 @@ Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik
|
||||
|
||||
## Umgebung und Werkzeuge
|
||||
|
||||
- **Relative Verweise in eingebetteten Stylesheets gehen in der Einzeldatei verloren.** Die CSS der Bootstrap Icons
|
||||
lädt ihre Schrift über `url("fonts/bootstrap-icons.woff2?…")`. Beim direkten Öffnen von `vorschau.html` klappt
|
||||
das, in der von `scripts/vorschau.py` erzeugten Einzeldatei nicht. Deshalb setzt `_schriften_einbetten()` die
|
||||
woff2-Schrift als `data:`-URI ein und lässt den woff-Rückfall weg. Ein Test verlangt, dass jede `url(...)` der
|
||||
erzeugten Seite `data:` oder ein Fragment (`#…`, SVG-Verweise aus bpmn-js) ist. (#27, 25.09.2026)
|
||||
- **Öffentliche Organisation heißt nicht öffentliches Repo.** In Gitea haben Organisation und Repo getrennte
|
||||
Sichtbarkeit. `AG_Prozesse` war öffentlich, `Projektwissen` privat: Die Weboberfläche zeigte es angemeldeten
|
||||
Personen normal, die API ohne Anmeldung lieferte 404. `scripts/gitea.py` liest bewusst ohne Token und braucht deshalb
|
||||
|
||||
+31
-3
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Zeigt eine BPMN-Datei oder eine Arbeitsschritt-.md als Diagramm im Browser – offline, ohne PICTURE.
|
||||
|
||||
Grundlage ist werkzeuge/vorschau/vorschau.html mit der lokal eingebetteten Bibliothek bpmn-js (bpmn.io).
|
||||
Das Skript erzeugt daraus eine einzelne, in sich geschlossene HTML-Datei (Bibliothek, Stile und Diagramm
|
||||
eingebettet) und öffnet sie im Standardbrowser. Es wird nichts übertragen; die Seite lädt nichts aus dem Netz.
|
||||
Grundlage ist werkzeuge/vorschau/vorschau.html mit der lokal eingebetteten Bibliothek bpmn-js (bpmn.io), gestaltet
|
||||
mit Bootstrap und dem Stil der AG (werkzeuge/bootstrap/, werkzeuge/stil/). Das Skript erzeugt daraus eine einzelne,
|
||||
in sich geschlossene HTML-Datei (Bibliotheken, Stile, Icon-Schrift und Diagramm eingebettet) und öffnet sie im
|
||||
Standardbrowser. Es wird nichts übertragen; die Seite lädt nichts aus dem Netz.
|
||||
|
||||
Aufrufe (aus dem Workspace-Root):
|
||||
python scripts/vorschau.py Prozessbibliothek/antrag-pruefen/antrag-pruefen.bpmn
|
||||
@@ -19,7 +20,9 @@ Exit-Code: 0 = in Ordnung, 1 = Datei fehlt oder lässt sich nicht umwandeln.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import webbrowser
|
||||
@@ -32,6 +35,10 @@ SKILL = ROOT / ".agents" / "skills" / "sn-bpmn"
|
||||
|
||||
# Stellen in vorschau.html, die beim Einbetten ersetzt werden. Ein Test prüft, dass es sie gibt.
|
||||
EINBETTUNGEN = {
|
||||
'<link rel="stylesheet" href="../bootstrap/bootstrap.min.css">': ("style", "../bootstrap/bootstrap.min.css"),
|
||||
'<link rel="stylesheet" href="../bootstrap/icons/bootstrap-icons.min.css">':
|
||||
("style", "../bootstrap/icons/bootstrap-icons.min.css"),
|
||||
'<link rel="stylesheet" href="../stil/ag_prozesse.css">': ("style", "../stil/ag_prozesse.css"),
|
||||
'<link rel="stylesheet" href="bpmn-js/diagram-js.css">': ("style", "bpmn-js/diagram-js.css"),
|
||||
'<link rel="stylesheet" href="bpmn-js/bpmn-js.css">': ("style", "bpmn-js/bpmn-js.css"),
|
||||
'<script src="bpmn-js/bpmn-navigated-viewer.production.min.js"></script>':
|
||||
@@ -47,6 +54,25 @@ PLATZHALTER_NAME = "const DATEINAME = null;"
|
||||
VERBOTEN = {"script": ("</script", "<script"), "style": ("</style",)}
|
||||
|
||||
|
||||
# Die Icon-CSS verweist relativ auf ihre Schrift (url("fonts/bootstrap-icons.woff2?…")). In der erzeugten Einzeldatei
|
||||
# gäbe es diese Datei nicht: die woff2-Schrift wird als data:-URI eingesetzt, der woff-Rückfall entfällt (#27).
|
||||
SCHRIFT = re.compile(r'url\("fonts/(?P<datei>[^"?]+)(?:\?[^"]*)?"\)\s*format\("(?P<format>[\w-]+)"\)')
|
||||
|
||||
|
||||
def _schriften_einbetten(inhalt: str, ordner: Path) -> str:
|
||||
"""Ersetzt in einer CSS die relativen Schriftverweise: woff2 als data:-URI, alle übrigen Formate fallen weg."""
|
||||
def ersetze(treffer: re.Match) -> str:
|
||||
if treffer["format"] != "woff2":
|
||||
return ""
|
||||
daten = base64.b64encode((ordner / "fonts" / treffer["datei"]).read_bytes()).decode("ascii")
|
||||
return f'url("data:font/woff2;base64,{daten}") format("woff2")'
|
||||
ergebnis = SCHRIFT.sub(ersetze, inhalt)
|
||||
ergebnis = re.sub(r',\s*(?=[;}])', '', ergebnis) # Komma vor dem entfallenen Rückfall
|
||||
if 'url("fonts/' in ergebnis:
|
||||
raise RuntimeError("Icon-CSS enthält einen Schriftverweis, der sich nicht einbetten lässt")
|
||||
return ergebnis
|
||||
|
||||
|
||||
def _js_wert(text: str | None) -> str:
|
||||
"""Als JavaScript-Literal, sicher innerhalb von <script>: jedes '<' wird als \\u003c geschrieben."""
|
||||
return json.dumps(text, ensure_ascii=False).replace("<", "\\u003c")
|
||||
@@ -59,6 +85,8 @@ def baue_html(bpmn_xml: str, name: str | None = None) -> str:
|
||||
if fundstelle not in html:
|
||||
raise RuntimeError(f"{VORLAGE.name}: '{fundstelle}' fehlt – Vorlage und scripts/vorschau.py passen nicht zusammen")
|
||||
inhalt = (VORSCHAU / datei).read_text(encoding="utf-8")
|
||||
if 'url("fonts/' in inhalt:
|
||||
inhalt = _schriften_einbetten(inhalt, (VORSCHAU / datei).parent)
|
||||
for sequenz in VERBOTEN[art]:
|
||||
if sequenz in inhalt.lower():
|
||||
raise RuntimeError(f"{datei} enthält '{sequenz}' und kann nicht sicher eingebettet werden")
|
||||
|
||||
+38
-2
@@ -33,6 +33,42 @@ def test_lizenz_von_bpmn_js_liegt_bei():
|
||||
assert "watermark" in lizenz
|
||||
|
||||
|
||||
BOOTSTRAP = ROOT / "werkzeuge" / "bootstrap"
|
||||
STIL = ROOT / "werkzeuge" / "stil" / "ag_prozesse.css"
|
||||
|
||||
|
||||
def test_bootstrap_und_icons_liegen_mit_lizenz_bei():
|
||||
"""Prüft, dass Bootstrap (CSS, JS-Bundle) und Bootstrap Icons (CSS, Schrift) lokal mit ihren MIT-Lizenzen und einer
|
||||
README zu Version und Quelle eingebettet sind (Issue #27)."""
|
||||
for datei in ("bootstrap.min.css", "bootstrap.bundle.min.js", "LICENSE", "README.md",
|
||||
"icons/bootstrap-icons.min.css", "icons/fonts/bootstrap-icons.woff2", "icons/LICENSE"):
|
||||
assert (BOOTSTRAP / datei).is_file(), f"fehlt: werkzeuge/bootstrap/{datei}"
|
||||
for lizenz in ("LICENSE", "icons/LICENSE"):
|
||||
assert "MIT License" in (BOOTSTRAP / lizenz).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_vorlage_nutzt_bootstrap_und_den_stil_der_ag():
|
||||
"""Prüft, dass die Vorschau Bootstrap, die Bootstrap Icons und das gemeinsame Stylesheet der AG einbindet
|
||||
(Issue #27)."""
|
||||
html = vorschau.VORLAGE.read_text(encoding="utf-8")
|
||||
for verweis in ("../bootstrap/bootstrap.min.css", "../bootstrap/icons/bootstrap-icons.min.css",
|
||||
"../stil/ag_prozesse.css"):
|
||||
assert f'href="{verweis}"' in html, f"nicht eingebunden: {verweis}"
|
||||
assert STIL.is_file()
|
||||
|
||||
|
||||
def test_erzeugte_seite_laedt_auch_die_icon_schrift_nicht_nach():
|
||||
"""Prüft, dass in der erzeugten Seite jede CSS-Adresse url(...) eine data:-Quelle oder ein Fragment im selben
|
||||
Dokument ist – auch die Schrift der Bootstrap Icons, die im Original relativ auf fonts/ verweist (Issue #27)."""
|
||||
html = vorschau.baue_html(BEISPIEL_BPMN.read_text(encoding="utf-8"), BEISPIEL_BPMN.name)
|
||||
adressen = re.findall(r"url\(\s*['\"]?([^'\")]+)", html)
|
||||
assert any(a.startswith("data:font/woff2;base64,") for a in adressen), "Icon-Schrift nicht eingebettet"
|
||||
# erlaubt sind data:-Quellen und Verweise auf SVG-Fragmente im selben Dokument (url(#…), aus bpmn-js)
|
||||
fremd = [a for a in adressen if not a.startswith(("data:", "#"))]
|
||||
assert fremd == [], fremd[:3]
|
||||
assert ".ag-nav" in html, "Stil der AG nicht eingebettet"
|
||||
|
||||
|
||||
def test_erzeugte_seite_ist_in_sich_geschlossen():
|
||||
"""Prüft, dass die erzeugte Seite Bibliothek und Stile eingebettet hat und keine Datei mehr nachlädt."""
|
||||
html = vorschau.baue_html(BEISPIEL_BPMN.read_text(encoding="utf-8"), BEISPIEL_BPMN.name)
|
||||
@@ -62,8 +98,8 @@ def test_script_ende_im_diagramm_bricht_die_seite_nicht_auf():
|
||||
|
||||
def test_bibliothek_mit_script_ende_wird_abgelehnt(tmp_path, monkeypatch):
|
||||
"""Prüft, dass eine (etwa nach einem Update) nicht sicher einbettbare Bibliothek einen Fehler auslöst."""
|
||||
kopie = tmp_path / "vorschau"
|
||||
shutil.copytree(vorschau.VORSCHAU, kopie)
|
||||
shutil.copytree(vorschau.VORSCHAU.parent, tmp_path / "werkzeuge") # Vorlage braucht auch ../bootstrap, ../stil
|
||||
kopie = tmp_path / "werkzeuge" / "vorschau"
|
||||
js = kopie / "bpmn-js" / "bpmn-navigated-viewer.production.min.js"
|
||||
js.write_text(js.read_text(encoding="utf-8") + '\nvar x = "</script>";', encoding="utf-8")
|
||||
monkeypatch.setattr(vorschau, "VORSCHAU", kopie)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2025 The Bootstrap Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Bootstrap und Bootstrap Icons (lokal eingebettet)
|
||||
|
||||
Grundlage für das Aussehen der HTML-Seiten der AG, zuerst der BPMN-Vorschau (`werkzeuge/vorschau/`). Vorbild ist die
|
||||
Anmutung der Anwendungen in VLN_SN (`docs/wissen/vln_sn.md`). Die Bibliotheken liegen lokal, weil unsere Werkzeuge
|
||||
offline arbeiten. Die eigenen Regeln stehen in `werkzeuge/stil/ag_prozesse.css`, nicht hier.
|
||||
|
||||
## Eingebettete Dateien
|
||||
|
||||
| | Bootstrap | Bootstrap Icons |
|
||||
|---|---|---|
|
||||
| Paket (npm) | `bootstrap` 5.3.8 | `bootstrap-icons` 1.13.1 |
|
||||
| Quelle | `https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz` | `https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz` |
|
||||
| Integrität (npm) | `sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==` | `sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==` |
|
||||
| Dateien | `dist/css/bootstrap.min.css` → `bootstrap.min.css`, `dist/js/bootstrap.bundle.min.js` → `bootstrap.bundle.min.js` | `font/bootstrap-icons.min.css` → `icons/bootstrap-icons.min.css`, `font/fonts/bootstrap-icons.woff2` und `.woff` → `icons/fonts/` |
|
||||
| Lizenz | MIT, `LICENSE` | MIT, `icons/LICENSE` |
|
||||
|
||||
Die Dateien sind **byte-gleich** mit dem Paket (`.gitattributes`: `binary`). Nicht von Hand ändern.
|
||||
|
||||
## Hinweise
|
||||
|
||||
- **Nichts aus dem Netz.** Die CSS verweist nur auf eingebettete `data:`-Grafiken bzw. auf `icons/fonts/`.
|
||||
Die `sourceMappingURL`-Kommentare zeigen auf Dateien, die bewusst fehlen. Browser fragen sie höchstens bei
|
||||
geöffneten Entwicklerwerkzeugen an.
|
||||
- **Einzeldatei der Vorschau.** `scripts/vorschau.py` bettet die Stylesheets in die erzeugte Seite ein und setzt
|
||||
dabei die woff2-Schrift der Icons als `data:`-URI ein. Der woff-Rückfall entfällt dort, er wird nur beim direkten
|
||||
Öffnen von `vorschau.html` in sehr alten Browsern gebraucht.
|
||||
- **JavaScript-Bundle** (mit Popper) liegt für Bedienelemente wie Modal oder Tooltip bereit. Die Vorschau braucht
|
||||
es derzeit nicht und bindet es nicht ein.
|
||||
|
||||
## Aktualisieren
|
||||
|
||||
1. In der npm-Registry die neue Version nachsehen (`https://registry.npmjs.org/bootstrap/latest`, entsprechend
|
||||
`bootstrap-icons`) und das Paket (`dist.tarball`) herunterladen.
|
||||
2. Integrität prüfen: `sha512-` + Base64 der SHA-512 des Pakets muss `dist.integrity` entsprechen.
|
||||
3. Die Dateien aus der Tabelle unverändert übernehmen, Tabelle (Version, Quelle, Integrität) nachziehen.
|
||||
4. `python -m pytest -q` (prüft u. a., dass die Vorschau nichts nachlädt) und die Vorschau im Browser ansehen.
|
||||
5. Pull Request mit Verweis auf die Release-Hinweise der neuen Version.
|
||||
+7
File diff suppressed because one or more lines are too long
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019-2024 The Bootstrap Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,34 @@
|
||||
/* Gemeinsamer Stil der HTML-Seiten der AG Prozesse, aufbauend auf Bootstrap 5 (werkzeuge/bootstrap/).
|
||||
Anmutung wie die Anwendungen in VLN_SN (Vorbild EA-Bilanz, siehe docs/wissen/vln_sn.md) – eigene Regeln,
|
||||
nichts übernommen. Klassen beginnen mit "ag-", damit sie sich nicht mit Bootstrap überschneiden. */
|
||||
|
||||
:root {
|
||||
--ag-akzent: var(--bs-primary, #0d6efd);
|
||||
--ag-schrift: .9rem;
|
||||
}
|
||||
|
||||
/* Seite in voller Höhe: dunkle Navigationsleiste oben, Arbeitsbereich darunter */
|
||||
html.ag-seite, html.ag-seite body { height: 100%; }
|
||||
.ag-app {
|
||||
display: flex; flex-direction: column; height: 100vh; overflow: hidden;
|
||||
font-size: var(--ag-schrift);
|
||||
background: var(--bs-tertiary-bg, #f4f5f7);
|
||||
}
|
||||
.ag-nav { flex: 0 0 auto; }
|
||||
.ag-nav .navbar-brand { font-size: 1rem; }
|
||||
.ag-nav .btn-group { flex-wrap: nowrap; }
|
||||
.ag-inhalt { flex: 1 1 auto; min-height: 0; position: relative; background: var(--bs-body-bg, #fff); }
|
||||
|
||||
/* Karten mit farbigem linken Rand je Kategorie */
|
||||
.ag-karte { border-left: 4px solid var(--ag-akzent); }
|
||||
.ag-karte-erfolg { border-left-color: var(--bs-success, #198754); }
|
||||
.ag-karte-warnung { border-left-color: var(--bs-warning, #ffc107); }
|
||||
.ag-karte-fehler { border-left-color: var(--bs-danger, #dc3545); }
|
||||
|
||||
/* Zahlen in Tabellenziffern, rechtsbündig */
|
||||
.ag-zahl { font-variant-numeric: tabular-nums; text-align: right; }
|
||||
|
||||
@media print {
|
||||
.ag-nav { display: none !important; }
|
||||
.ag-app { height: auto; overflow: visible; background: #fff; }
|
||||
}
|
||||
@@ -24,6 +24,12 @@ berechnet hat. Damit eignet sie sich, um Entwürfe vor der Freigabe und Modellä
|
||||
PICTURE kann dieselbe Datei anders darstellen (eigene Schriften, eigene Behandlung von Anschlusspunkten). Der Import
|
||||
in PICTURE bleibt deshalb der letzte Nachweis.
|
||||
|
||||
## Aussehen
|
||||
|
||||
Die Seite nutzt Bootstrap mit Bootstrap Icons (`werkzeuge/bootstrap/`, eigene README) und den gemeinsamen Stil der
|
||||
AG (`werkzeuge/stil/ag_prozesse.css`): dunkle Navigationsleiste mit Knopfgruppe wie in den Anwendungen von VLN_SN.
|
||||
`scripts/vorschau.py` bettet alles in die erzeugte Einzeldatei ein, auch die Icon-Schrift.
|
||||
|
||||
## Eingebettete Bibliothek
|
||||
|
||||
| | |
|
||||
|
||||
@@ -1,70 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<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>
|
||||
<!-- bpmn-js (bpmn.io), lokal eingebettet – siehe README.md. Nichts wird aus dem Netz geladen. -->
|
||||
<!-- 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>
|
||||
:root {
|
||||
--hintergrund: #ffffff;
|
||||
--leiste: #f3f5f7;
|
||||
--rand: #d0d7de;
|
||||
--text: #1f2328;
|
||||
--gedaempft: #59636e;
|
||||
--akzent: #0b6bcb;
|
||||
--fehler: #b42318;
|
||||
--warnung: #9a6700;
|
||||
}
|
||||
html, body { height: 100%; margin: 0; }
|
||||
body {
|
||||
display: flex; flex-direction: column;
|
||||
font-family: "Segoe UI", system-ui, sans-serif; font-size: 14px;
|
||||
color: var(--text); background: var(--hintergrund);
|
||||
}
|
||||
header {
|
||||
display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
|
||||
padding: 8px 16px; background: var(--leiste); border-bottom: 1px solid var(--rand);
|
||||
}
|
||||
header h1 { font-size: 15px; font-weight: 600; margin: 0 12px 0 0; }
|
||||
button, label.knopf {
|
||||
font: inherit; padding: 4px 10px; border: 1px solid var(--rand); border-radius: 6px;
|
||||
background: #fff; color: var(--text); cursor: pointer;
|
||||
}
|
||||
button:hover, label.knopf:hover { border-color: var(--akzent); }
|
||||
button:disabled { opacity: .5; cursor: default; }
|
||||
#datei { display: none; }
|
||||
#dateiname { color: var(--gedaempft); overflow-wrap: anywhere; }
|
||||
#meldung { flex-basis: 100%; margin: 0; }
|
||||
#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(--fehler); }
|
||||
#meldung.warnung { color: var(--warnung); }
|
||||
#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. */
|
||||
main { position: relative; flex: 1; min-height: 0; }
|
||||
#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(--gedaempft); border: 2px dashed var(--rand); border-radius: 12px;
|
||||
padding: 16px; pointer-events: none;
|
||||
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(--akzent); color: var(--akzent); }
|
||||
main.ziehen #hinweis { border-color: var(--ag-akzent); color: var(--ag-akzent); }
|
||||
main.geladen #hinweis { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>BPMN-Vorschau</h1>
|
||||
<label class="knopf" for="datei">Datei öffnen …</label>
|
||||
<input type="file" id="datei" accept=".bpmn,.xml">
|
||||
<button type="button" id="einpassen" disabled>Einpassen</button>
|
||||
<button type="button" id="groesser" disabled title="Vergrößern">+</button>
|
||||
<button type="button" id="kleiner" disabled title="Verkleinern">−</button>
|
||||
<span id="dateiname"></span>
|
||||
<p id="meldung" role="status"></p>
|
||||
</header>
|
||||
<main id="bereich">
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user