diff --git a/README.md b/README.md index 4ec237b..ba6e52b 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,187 @@ erreichbar ist und die Durchwahl als Kennung nutzt. ### Bedienung +Es gibt genau **eine** Adresse: + +``` +http://SERVER:8080/zentrale +``` + +Durchwahl eintragen, **Weiter** klicken - die Seite zeigt dann, was fuer diese Person +gerade gilt. Derselbe Weg fuehrt zum Uebernehmen und zum Freigeben, es muss sich also +niemand eine zweite, persoenliche Adresse gemerkt haben, um die Zentrale wieder +loszuwerden. + +| Lage | Angebot | +|------|---------| +| Zentrale frei | **Zentrale besetzen** | +| jemand anderes sitzt darauf | **Zentrale uebernehmen**, mit Hinweis was mit dieser Person passiert | +| man sitzt selbst darauf | **Zentrale freigeben** | +| es ist der eigene Stammplatz | kein Knopf, nur der Hinweis dass nichts zu tun ist | + +Wer gerade auf der Zentrale sitzt, steht immer oben auf der Seite - auch ohne +Durchwahl. Wartet jemand auf seine Rueckkehr, steht das ebenfalls dort. + +Jede Aktion leitet auf `/zentrale` zurueck (POST/Redirect/GET). Man landet also nie auf +einer Formular-Antwort, die beim Neuladen die Aktion wiederholen wuerde. + +Fuer QR-Codes pro Person gibt es die Kurzform `/zentrale/{durchwahl}`. Sie leitet +lediglich auf `/zentrale?durchwahl=...` um - es bleibt bei der einen Seite. + +### Verhalten + +- `callstart`: Setzt WLED auf Telefon-Farbe (Standard: Rot), aber **nur** wenn der Mitarbeiter laut Zeiterfassung anwesend oder im Homeoffice ist +- `callend`: Setzt WLED zurueck auf den Zeiterfassungs-Status. Der Teams-Status wird beim naechsten Polling-Zyklus (15s) automatisch aktualisiert +- Waehrend eines aktiven Telefonats ueberschreibt das Teams-Polling die Farbe nicht +- Die Telefon-Farbe (`phone_active`) ist unter **Farb-Regeln** konfigurierbar + +## Logo + +Unter **Einstellungen > Logo** kann ein kundenspezifisches Logo hochgeladen werden. Es +erscheint in der Seitenleiste, auf der Login-Seite und auf der Zentrale-Seite. + +- Formate: PNG, JPG, SVG, WEBP, GIF, maximal 2 MB +- Dargestellt wird eine Hoehe von etwa 40 Pixeln. Die Seitenleiste ist dunkel, ein Logo + mit heller Schrift oder transparentem Hintergrund wirkt dort am besten - die + Einstellungsseite zeigt eine Vorschau auf hellem und dunklem Grund. +- Die Datei liegt unter `static/custom/` und ist per `.gitignore` von der Versionierung + ausgenommen. **Ein `git pull` ueberschreibt das Kundenlogo nicht.** +- Mit **Zurueck zum Standardlogo** wird die Datei entfernt und wieder + `static/logo.png` aus dem Repository verwendet. + +## Zentrale (Self-Service) + +Ein Busylight im Empfangsbereich wird wechselnd besetzt. Damit die Mitarbeiter das +selbst umstellen koennen, gibt es eine eigene Seite, die **ohne Admin-Passwort** +erreichbar ist und die Durchwahl als Kennung nutzt. + +### Einrichtung + +1. Unter **Benutzer** die **Durchwahl** pro Mitarbeiter eintragen (dieselbe wie fuer den Telefon-Webhook) +2. Unter **Einstellungen > Zentrale (Self-Service)** das Busylight des Empfangs und das Segment auswaehlen +3. Die Seite `http://SERVER:8080/zentrale` an die Mitarbeiter geben + +### Bedienung + +``` +http://SERVER:8080/zentrale - Durchwahl eingeben +http://SERVER:8080/zentrale/{durchwahl} - Zustandsseite pro Person, als Lesezeichen + oder QR-Code +``` + +Die Bedienung laeuft in zwei Schritten. Auf `/zentrale` gibt man seine Durchwahl ein +und landet auf der eigenen Zustandsseite `/zentrale/{durchwahl}`. Dort steht, wer +gerade auf der Zentrale sitzt und welche Knoepfe zur Verfuegung stehen - geaendert +wird erst per Klick. + +Die Zustandsseite ist die eigentliche Adresse fuer den Alltag und als Lesezeichen +gedacht. Sie zeigt immer den echten Zustand, passt die Knoepfe daran an und ist +gefahrlos neu ladbar: + +| Lage | Angebot | +|------|---------| +| Zentrale frei | **Zentrale besetzen**, ohne Rueckfrage | +| jemand anderes sitzt darauf | **Zentrale uebernehmen** mit Rueckfrage, siehe unten | +| man sitzt selbst darauf | **Zurueck auf mein Tuerschild** | +| es ist der eigene Stammplatz | kein Knopf, nur der Hinweis dass nichts zu tun ist | + +### Verhalten + +- `callstart`: Setzt WLED auf Telefon-Farbe (Standard: Rot), aber **nur** wenn der Mitarbeiter laut Zeiterfassung anwesend oder im Homeoffice ist +- `callend`: Setzt WLED zurueck auf den Zeiterfassungs-Status. Der Teams-Status wird beim naechsten Polling-Zyklus (15s) automatisch aktualisiert +- Waehrend eines aktiven Telefonats ueberschreibt das Teams-Polling die Farbe nicht +- Die Telefon-Farbe (`phone_active`) ist unter **Farb-Regeln** konfigurierbar + +## Logo + +Unter **Einstellungen > Logo** kann ein kundenspezifisches Logo hochgeladen werden. Es +erscheint in der Seitenleiste, auf der Login-Seite und auf der Zentrale-Seite. + +- Formate: PNG, JPG, SVG, WEBP, GIF, maximal 2 MB +- Dargestellt wird eine Hoehe von etwa 40 Pixeln. Die Seitenleiste ist dunkel, ein Logo + mit heller Schrift oder transparentem Hintergrund wirkt dort am besten - die + Einstellungsseite zeigt eine Vorschau auf hellem und dunklem Grund. +- Die Datei liegt unter `static/custom/` und ist per `.gitignore` von der Versionierung + ausgenommen. **Ein `git pull` ueberschreibt das Kundenlogo nicht.** +- Mit **Zurueck zum Standardlogo** wird die Datei entfernt und wieder + `static/logo.png` aus dem Repository verwendet. + +## Zentrale (Self-Service) + +Ein Busylight im Empfangsbereich wird wechselnd besetzt. Damit die Mitarbeiter das +selbst umstellen koennen, gibt es eine eigene Seite, die **ohne Admin-Passwort** +erreichbar ist und die Durchwahl als Kennung nutzt. + +### Einrichtung + +1. Unter **Benutzer** die **Durchwahl** pro Mitarbeiter eintragen (dieselbe wie fuer den Telefon-Webhook) +2. Unter **Einstellungen > Zentrale (Self-Service)** das Busylight des Empfangs und das Segment auswaehlen +3. Die Seite `http://SERVER:8080/zentrale` an die Mitarbeiter geben + +### Bedienung + +Es gibt genau **eine** Adresse: + +``` +http://SERVER:8080/zentrale +``` + +Durchwahl eintragen, **Weiter** klicken - die Seite zeigt dann, was fuer diese Person +gerade gilt. Derselbe Weg fuehrt zum Uebernehmen und zum Freigeben, es muss sich also +niemand eine zweite, persoenliche Adresse gemerkt haben, um die Zentrale wieder +loszuwerden. + +| Lage | Angebot | +|------|---------| +| Zentrale frei | **Zentrale besetzen** | +| jemand anderes sitzt darauf | **Zentrale uebernehmen**, mit Hinweis was mit dieser Person passiert | +| man sitzt selbst darauf | **Zentrale freigeben** | +| es ist der eigene Stammplatz | kein Knopf, nur der Hinweis dass nichts zu tun ist | + +Wer gerade auf der Zentrale sitzt, steht immer oben auf der Seite - auch ohne +Durchwahl. Wartet jemand auf seine Rueckkehr, steht das ebenfalls dort. + +Jede Aktion leitet auf `/zentrale` zurueck (POST/Redirect/GET). Man landet also nie auf +einer Formular-Antwort, die beim Neuladen die Aktion wiederholen wuerde. + +Fuer QR-Codes pro Person gibt es die Kurzform `/zentrale/{durchwahl}`. Sie leitet +lediglich auf `/zentrale?durchwahl=...` um - es bleibt bei der einen Seite. + +### Verhalten + +- `callstart`: Setzt WLED auf Telefon-Farbe (Standard: Rot), aber **nur** wenn der Mitarbeiter laut Zeiterfassung anwesend oder im Homeoffice ist +- `callend`: Setzt WLED zurueck auf den Zeiterfassungs-Status. Der Teams-Status wird beim naechsten Polling-Zyklus (15s) automatisch aktualisiert +- Waehrend eines aktiven Telefonats ueberschreibt das Teams-Polling die Farbe nicht +- Die Telefon-Farbe (`phone_active`) ist unter **Farb-Regeln** konfigurierbar + +## Logo + +Unter **Einstellungen > Logo** kann ein kundenspezifisches Logo hochgeladen werden. Es +erscheint in der Seitenleiste, auf der Login-Seite und auf der Zentrale-Seite. + +- Formate: PNG, JPG, SVG, WEBP, GIF, maximal 2 MB +- Dargestellt wird eine Hoehe von etwa 40 Pixeln. Die Seitenleiste ist dunkel, ein Logo + mit heller Schrift oder transparentem Hintergrund wirkt dort am besten - die + Einstellungsseite zeigt eine Vorschau auf hellem und dunklem Grund. +- Die Datei liegt unter `static/custom/` und ist per `.gitignore` von der Versionierung + ausgenommen. **Ein `git pull` ueberschreibt das Kundenlogo nicht.** +- Mit **Zurueck zum Standardlogo** wird die Datei entfernt und wieder + `static/logo.png` aus dem Repository verwendet. + +## Zentrale (Self-Service) + +Ein Busylight im Empfangsbereich wird wechselnd besetzt. Damit die Mitarbeiter das +selbst umstellen koennen, gibt es eine eigene Seite, die **ohne Admin-Passwort** +erreichbar ist und die Durchwahl als Kennung nutzt. + +### Einrichtung + +1. Unter **Benutzer** die **Durchwahl** pro Mitarbeiter eintragen (dieselbe wie fuer den Telefon-Webhook) +2. Unter **Einstellungen > Zentrale (Self-Service)** das Busylight des Empfangs und das Segment auswaehlen +3. Die Seite `http://SERVER:8080/zentrale` an die Mitarbeiter geben + +### Bedienung + ``` http://SERVER:8080/zentrale - Durchwahl eingeben http://SERVER:8080/zentrale/{durchwahl} - Zustandsseite pro Person, als Lesezeichen @@ -387,11 +568,11 @@ busylight/ - Unter Tuerschilder den Status pruefen ("Alle jetzt pruefen") - Netzwerkverbindung pruefen: `curl http://HOSTNAME/json/info` -### Auf /zentrale fehlt der Knopf zum Zurueckgeben +### Wie gibt man die Zentrale wieder frei? -Der ist absichtlich erst auf der Zustandsseite `/zentrale/{durchwahl}` zu sehen, denn -vorher weiss die Anwendung nicht, wer zurueckgeben will. Durchwahl eingeben, **Weiter** -klicken - dann erscheint der passende Knopf. +Auf `/zentrale` die eigene Durchwahl eintragen und **Weiter** klicken - dann erscheint +**Zentrale freigeben**. Es ist derselbe Weg wie beim Uebernehmen, eine gemerkte Adresse +braucht es nicht. ### Zentrale-Seite sagt "noch nicht eingerichtet" diff --git a/app.py b/app.py index e189d2b..8823b30 100644 --- a/app.py +++ b/app.py @@ -666,51 +666,47 @@ def _zentrale_page(request, conn, target, extension="", user=None, done=None): def _zentrale_redirect(extension, done): - """Nach jeder Aktion zurueck auf die Zustandsseite (POST/Redirect/GET).""" + """Nach jeder Aktion zurueck auf /zentrale (POST/Redirect/GET). + + Es gibt absichtlich nur diese eine Adresse: wer die Zentrale freigeben will, + soll sich keine zweite URL gemerkt haben muessen. + """ ext = quote((extension or "").strip(), safe="") if not ext: return RedirectResponse(f"/zentrale?done={done}", status_code=303) - return RedirectResponse(f"/zentrale/{ext}?done={done}", status_code=303) + return RedirectResponse(f"/zentrale?durchwahl={ext}&done={done}", status_code=303) @app.get("/zentrale", response_class=HTMLResponse) async def zentrale_page(request: Request): - """Self-Service-Seite fuer den Empfangsbereich. Absichtlich ohne Admin-Login.""" - # Das Formular schickt die Durchwahl per GET - auf die Personenseite umleiten, - # damit die Adresse merkbar und neu ladbar ist. + """Self-Service-Seite fuer den Empfangsbereich. Absichtlich ohne Admin-Login. + + Die eine Adresse fuer alles: Durchwahl eintragen, und die Seite zeigt die + Knoepfe, die fuer diese Person gerade gelten - Uebernehmen oder Freigeben. + """ typed = (request.query_params.get("durchwahl") or "").strip() - if typed: - return RedirectResponse(f"/zentrale/{quote(typed, safe='')}", status_code=303) + done = request.query_params.get("done") - conn = database.get_db() - try: - return _zentrale_page(request, conn, _selfservice_target(conn), - done=request.query_params.get("done")) - finally: - conn.close() - - -@app.get("/zentrale/{extension}", response_class=HTMLResponse) -async def zentrale_page_for_extension(request: Request, extension: str): - """Zustandsseite pro Mitarbeiter. Zeigt nur an, geaendert wird per Knopf.""" conn = database.get_db() try: target = _selfservice_target(conn) - user = _user_by_extension(extension, conn) - done = request.query_params.get("done") if user else "err_unbekannt" - return _zentrale_page(request, conn, target, extension=extension, user=user, done=done) + user = _user_by_extension(typed, conn) if typed else None + if typed and not user and not done: + done = "err_unbekannt" + return _zentrale_page(request, conn, target, extension=typed, user=user, done=done) finally: conn.close() -@app.post("/api/zentrale/uebernehmen") -async def zentrale_takeover(extension: str = Form(...), confirm: str = Form("")): - """Mitarbeiter setzt sich selbst auf das Busylight der Zentrale. +@app.get("/zentrale/{extension}") +async def zentrale_page_for_extension(extension: str): + """Kurzform fuer QR-Codes. Leitet auf die eine Adresse um.""" + return RedirectResponse(f"/zentrale?durchwahl={quote(extension, safe='')}", status_code=303) - Sitzt bereits jemand anderes darauf, braucht es eine ausdrueckliche - Bestaetigung. Eine Rueckgabe zu erzwingen waere die Alternative, wuerde die - Zentrale aber sperren, sobald jemand ohne Freigabe nach Hause geht. - """ + +@app.post("/api/zentrale/uebernehmen") +async def zentrale_takeover(extension: str = Form(...)): + """Mitarbeiter setzt sich selbst auf das Busylight der Zentrale.""" conn = database.get_db() try: target = _selfservice_target(conn) @@ -721,14 +717,6 @@ async def zentrale_takeover(extension: str = Form(...), confirm: str = Form("")) if not user: return _zentrale_redirect(extension, "err_unbekannt") - if confirm != "ja": - besetzt = conn.execute(""" - SELECT 1 FROM assignments - WHERE wled_device_id = ? AND segment = ? AND user_azure_id != ? - """, (target["id"], target["segment"], user["azure_id"])).fetchone() - if besetzt: - return _zentrale_redirect(extension, "bestaetigen") - already = conn.execute(""" SELECT 1 FROM assignments WHERE user_azure_id = ? AND wled_device_id = ? AND segment = ? diff --git a/templates/zentrale.html b/templates/zentrale.html index 1d9865b..19d9894 100644 --- a/templates/zentrale.html +++ b/templates/zentrale.html @@ -70,8 +70,8 @@ {{ target.name }} (Segment {{ target.segment }})