Standort löschen hinzugefügt

This commit is contained in:
Erik Thiele
2026-06-05 14:01:05 +02:00
parent 078bc5deea
commit 4b29d9a27f
7 changed files with 54 additions and 2 deletions

View File

@@ -34,6 +34,8 @@ Standorte (sites) sind die oberste Organisationsebene und gruppieren Screens.
| `POST /api/customer` | API-Endpunkt (JSON mit "site"-Feld) | | `POST /api/customer` | API-Endpunkt (JSON mit "site"-Feld) |
| `GET /admin/<site>/add-screen?name=<name>` | Neuen Screen anlegen | | `GET /admin/<site>/add-screen?name=<name>` | Neuen Screen anlegen |
| `POST /admin/<site>/delete-screen/<screen>` | Screen + Medien löschen | | `POST /admin/<site>/delete-screen/<screen>` | Screen + Medien löschen |
| `GET /add-site?name=<name>` | Neuen Standort anlegen |
| `POST /admin/<site>/delete-site` | Standort + alle Screens/Medien löschen |
## Behavior To Preserve ## Behavior To Preserve
@@ -54,6 +56,8 @@ Standorte (sites) sind die oberste Organisationsebene und gruppieren Screens.
- `add_screen` legt ein Verzeichnis unter `media/<site>/<screen>/` an und einen Config-Eintrag. - `add_screen` legt ein Verzeichnis unter `media/<site>/<screen>/` an und einen Config-Eintrag.
- `delete_screen` entfernt den Screen aus der Config und löscht das Verzeichnis rekursiv. - `delete_screen` entfernt den Screen aus der Config und löscht das Verzeichnis rekursiv.
- Custom-URL-Button: pro Screen konfigurierbar (`custom_url` + `custom_url_label` + `custom_url_target`) im Admin-Formular; wird im Player als Button oben links angezeigt und öffnet die URL wahlweise in einem iframe-Overlay mit Zurück-Button (`overlay`) oder per Direkt-Weiterleitung (`redirect`); Player pausiert während das Overlay geöffnet ist. - Custom-URL-Button: pro Screen konfigurierbar (`custom_url` + `custom_url_label` + `custom_url_target`) im Admin-Formular; wird im Player als Button oben links angezeigt und öffnet die URL wahlweise in einem iframe-Overlay mit Zurück-Button (`overlay`) oder per Direkt-Weiterleitung (`redirect`); Player pausiert während das Overlay geöffnet ist.
- Neue Standorte können über den `+`-Button im Header oder über `GET /add-site?name=<name>` angelegt werden.
- `delete_site` entfernt den Standort aus Config und löscht das Medienverzeichnis rekursiv.
## Repo Quirks ## Repo Quirks

View File

@@ -129,6 +129,8 @@ docker compose up -d
| `POST /api/customer` | API-Endpunkt für Willkommensseite (JSON) | | `POST /api/customer` | API-Endpunkt für Willkommensseite (JSON) |
| `GET /media/<site>/<screen>/<file>` | Medien-Datei ausliefern | | `GET /media/<site>/<screen>/<file>` | Medien-Datei ausliefern |
| `GET /media/priority/<file>` | Priority-Medien (global) | | `GET /media/priority/<file>` | Priority-Medien (global) |
| `GET /add-site?name=<name>` | Neuen Standort anlegen |
| `POST /admin/<site>/delete-site` | Standort + alle Screens/Medien löschen |
### Admin-Portal ### Admin-Portal
@@ -142,6 +144,7 @@ http://localhost:5005/admin/<standort>
- Priority-Playlist verwalten - Priority-Playlist verwalten
- Willkommensseite generieren (bis zu 3 Kundenlogos) - Willkommensseite generieren (bis zu 3 Kundenlogos)
- Custom-URL-Aktionsbutton pro Screen konfigurieren (iframe-Overlay oder Weiterleitung) - Custom-URL-Aktionsbutton pro Screen konfigurieren (iframe-Overlay oder Weiterleitung)
- Standorte anlegen & löschen
### Player-URL ### Player-URL

31
app.py
View File

@@ -477,6 +477,37 @@ def admin_redirect():
return "<h1>Kein Standort konfiguriert</h1><p>Bitte lege einen Standort im media-Verzeichnis an.</p>", 200 return "<h1>Kein Standort konfiguriert</h1><p>Bitte lege einen Standort im media-Verzeichnis an.</p>", 200
@app.route("/add-site")
@login_required
def add_site():
name = request.args.get("name", "").strip().lower()
if not name:
return redirect("/admin")
cfg = load_config()
cfg.setdefault("sites", {}).setdefault(name, {"screens": {}})
os.makedirs(os.path.join(MEDIA_DIR, name), exist_ok=True)
save_config(cfg)
return redirect(f"/admin/{name}")
@app.route("/admin/<site>/delete-site", methods=["POST"])
@login_required
def delete_site(site):
cfg = load_config()
cfg.get("sites", {}).pop(site, None)
save_config(cfg)
site_dir = os.path.join(MEDIA_DIR, site)
if os.path.isdir(site_dir):
import shutil
shutil.rmtree(site_dir)
sites = get_site_list(cfg)
return redirect(f"/admin/{sites[0]}" if sites else "/admin")
@app.route("/admin/<site>") @app.route("/admin/<site>")
@login_required @login_required
def admin(site): def admin(site):

View File

@@ -37,7 +37,7 @@
"newsticker_enabled": true, "newsticker_enabled": true,
"custom_url": "https://dva-stage.cancom-ds.de/voice-agent", "custom_url": "https://dva-stage.cancom-ds.de/voice-agent",
"custom_url_label": "Welcome Agent", "custom_url_label": "Welcome Agent",
"custom_url_enabled": true, "custom_url_enabled": false,
"custom_url_target": "redirect" "custom_url_target": "redirect"
}, },
"casino": { "casino": {

View File

@@ -20,6 +20,10 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<a class="btn btn-outline-secondary me-2" href="javascript:void(0)"
onclick="var n=prompt('Name des neuen Standorts:'); if(n&&n.trim()) location.href='/add-site?name='+encodeURIComponent(n.trim().toLowerCase());"
title="Neuen Standort anlegen"
style="display:inline-flex;align-items:center;justify-content:center;min-width:2.5rem;min-height:2.5rem;"><i class="ti ti-plus"></i></a>
<div> <div>
<button class="btn btn-outline-secondary theme-toggle" id="theme-toggle" title="Dark Mode umschalten"> <button class="btn btn-outline-secondary theme-toggle" id="theme-toggle" title="Dark Mode umschalten">
<i class="ti ti-moon"></i> <i class="ti ti-moon"></i>

View File

@@ -136,6 +136,7 @@
--tblr-card-inner-border-radius: 1rem; --tblr-card-inner-border-radius: 1rem;
border: 1px solid var(--ccm-border); border: 1px solid var(--ccm-border);
border-radius: 1rem; border-radius: 1rem;
border-left: 6px solid var(--ccm-primary);
} }
.app-footer-separator { .app-footer-separator {
@@ -145,7 +146,6 @@
.card-header { .card-header {
background-color: #eeeeee; background-color: #eeeeee;
border-left: 6px solid var(--ccm-primary);
padding-left: 1rem; padding-left: 1rem;
font-weight: 600; font-weight: 600;
} }

View File

@@ -112,6 +112,16 @@
<div class="page-wrapper"> <div class="page-wrapper">
<div class="container-xl mt-4"> <div class="container-xl mt-4">
<!-- ========================= -->
<!-- STANDORT VERWALTUNG -->
<!-- ========================= -->
<div class="d-flex justify-content-end mb-3">
<form action="/admin/{{ current_site }}/delete-site" method="post"
onsubmit="return confirm('Standort »{{ current_site }}« wirklich löschen? Alle Screens und Medien werden gelöscht.')">
<button type="submit" class="btn btn-outline-danger btn-sm"><i class="ti ti-building-off me-1"></i>Standort löschen</button>
</form>
</div>
<!-- ========================= --> <!-- ========================= -->
<!-- SCREENS --> <!-- SCREENS -->
<!-- ========================= --> <!-- ========================= -->