feat(exercise): Übungs-Cockpit nutzt den Modul-Baukasten + Testplan (v1.5.6)
- Übungen zeigen jetzt zusätzlich zu Zielen/Auswertung dieselben eigenen Tabellen-Module wie Einsätze (z.B. Atemschutz, Kräfte vor Ort) - Live-Sync der Modul-Zeilen auch in der Übung (journal-updated Socket) - docs/TESTPLAN.md: strukturierter Handy-/Einsatz-Testplan Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
49
docs/TESTPLAN.md
Normal file
49
docs/TESTPLAN.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Handy-/Einsatz-Testplan
|
||||
|
||||
Kurzer, strukturierter Durchlauf nach jedem grösseren Deploy — am besten einmal
|
||||
am **Handy** und einmal am **Desktop**. Abhaken, was funktioniert.
|
||||
|
||||
## 1. Einsatz anlegen
|
||||
- [ ] 🔥 **Neu → Neuer Einsatz**: Dialog öffnet, Standort wird automatisch als Ort vorgeschlagen
|
||||
- [ ] Titel eingeben → **Erstellen** → Karte startet am Einsatzort
|
||||
- [ ] Kopfzeile zeigt den Einsatz mittig (Status-Punkt rot, Nr, Titel, Ort), Uhr rechts
|
||||
|
||||
## 2. Karte & Symbole (der wichtige Handy-Test)
|
||||
- [ ] Symbol **antippen** → Hinweis erscheint → **auf Karte tippen** platziert es
|
||||
- [ ] Mehrere gleiche Symbole nacheinander setzen → Zähler steigt → **Fertig**
|
||||
- [ ] Symbol antippen (auf der Karte) → drehen/skalieren/löschen
|
||||
- [ ] Zeichnen: Pfeil/Linie ziehen → Dialog fragt **Normal / Leitung / Rettungsachse**
|
||||
- [ ] Eigene **GPS-Position** sichtbar (Punkt + Genauigkeit), Karte bleibt am Einsatzort
|
||||
- [ ] **Vollbild-Button** (oben links) blendet die Browser-Leiste aus
|
||||
|
||||
## 3. Auto-Bearbeitung
|
||||
- [ ] Ohne „Bearbeitung starten" direkt zeichnen können (Lock wird automatisch übernommen)
|
||||
- [ ] Zweites Gerät/Person: sieht Änderungen live, Karte ist dort gesperrt
|
||||
- [ ] Statuszeile zeigt „Sie bearbeiten" + **freigeben**
|
||||
|
||||
## 4. Cockpit-Module (Baukasten)
|
||||
- [ ] Journal-Tab → **Module** (als Admin): Modul an/aus, Reihenfolge, eigenes Modul erstellen
|
||||
- [ ] Neues Modul (z.B. Atemschutz) erscheint im Cockpit, Zeilen anlegen/haken/löschen
|
||||
- [ ] Änderungen live auf zweitem Gerät sichtbar
|
||||
|
||||
## 5. Journal & Rapport
|
||||
- [ ] Journal-Eintrag erfassen (mit Vorschlags-Leiste), Erledigt-Haken, Korrektur
|
||||
- [ ] SOMA/Pendenzen bedienen
|
||||
- [ ] **Rapport** erzeugen → PDF enthält Journal, SOMA, Pendenzen **und die eigenen Module**
|
||||
- [ ] Rapport per E-Mail / Drucken
|
||||
|
||||
## 6. Übung
|
||||
- [ ] 🎓 **Neu → Neue Übung** → Übungs-Cockpit mit Zielen + Auswertung
|
||||
- [ ] Übungsziele mit Status (Erreicht/Teilweise/…), Auswertung speichert automatisch
|
||||
- [ ] Eigene Module erscheinen auch in der Übung
|
||||
|
||||
## 7. Offline
|
||||
- [ ] Einsatz öffnen → Toast „Karte offline verfügbar" abwarten
|
||||
- [ ] Flugmodus an → Karte im Einsatzgebiet bleibt sichtbar, zeichnen möglich
|
||||
- [ ] Flugmodus aus → Änderungen werden synchronisiert (Statuszeile „Offline" verschwindet)
|
||||
|
||||
## 8. Beenden
|
||||
- [ ] **Einsatz beenden** (Kopfzeile/Menü) → In-App-Bestätigung → gespeichert & geschlossen
|
||||
|
||||
---
|
||||
_Bei Problemen: betroffenen Schritt notieren + ggf. Screenshot, dann gezielt fixen._
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lageplan",
|
||||
"version": "1.5.5",
|
||||
"version": "1.5.6",
|
||||
"description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -4,6 +4,9 @@ import { useState, useEffect, useRef, useCallback } from 'react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { useToast } from '@/components/ui/use-toast'
|
||||
import { getSocket } from '@/lib/socket'
|
||||
import { TableModule } from '@/components/journal/modules/table-module'
|
||||
import type { CockpitModule } from '@/lib/modules'
|
||||
import {
|
||||
GraduationCap,
|
||||
Plus,
|
||||
@@ -15,6 +18,7 @@ import {
|
||||
Trash2,
|
||||
ClipboardCheck,
|
||||
Loader2,
|
||||
Blocks,
|
||||
} from 'lucide-react'
|
||||
|
||||
type GoalStatus = 'OPEN' | 'REACHED' | 'PARTIAL' | 'MISSED'
|
||||
@@ -74,6 +78,24 @@ export function ExerciseCockpit({ projectId, projectTitle, canEdit, initialEvalu
|
||||
const evalDebounce = useRef<NodeJS.Timeout | null>(null)
|
||||
const { toast } = useToast()
|
||||
|
||||
// Modul-Baukasten: dieselben eigenen Tabellen-Module wie im Einsatz
|
||||
const [tableModules, setTableModules] = useState<CockpitModule[]>([])
|
||||
useEffect(() => {
|
||||
fetch('/api/tenant/modules')
|
||||
.then(r => r.ok ? r.json() : null)
|
||||
.then(data => {
|
||||
if (data?.modules) {
|
||||
setTableModules(data.modules.filter((m: CockpitModule) => m.enabled && m.type === 'table' && m.columns?.length))
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
const notifyModuleChanged = useCallback(() => {
|
||||
if (!projectId) return
|
||||
try { getSocket().emit('journal-updated', { projectId }) } catch { /* offline */ }
|
||||
}, [projectId])
|
||||
|
||||
// Ziele laden
|
||||
const loadGoals = useCallback(async () => {
|
||||
if (!projectId) {
|
||||
@@ -299,6 +321,19 @@ export function ExerciseCockpit({ projectId, projectTitle, canEdit, initialEvalu
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground mt-1">Wird automatisch gespeichert.</p>
|
||||
</section>
|
||||
|
||||
{/* Eigene Cockpit-Module (Modul-Baukasten) — z.B. Atemschutz, Kräfte vor Ort */}
|
||||
{projectId && tableModules.map((mod) => (
|
||||
<section key={mod.id}>
|
||||
<h3 className="text-sm font-semibold flex items-center gap-2 mb-3 text-foreground/80">
|
||||
<Blocks className="w-4 h-4 text-blue-600" />
|
||||
{mod.name}
|
||||
</h3>
|
||||
<div className="border rounded-lg bg-white dark:bg-card overflow-hidden">
|
||||
<TableModule projectId={projectId} module={mod} canEdit={canEdit} notifyChanged={notifyModuleChanged} />
|
||||
</div>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user