L13 Planung: Menüpunkt Planung mit Plantafel und Live-Lage
Plantafel: Standard heute + nächste 4 Werktage (Kolonnen als Zeilen, heutige Spalte mit Live-Status), Heute mit Kolonnen als parallelen Spalten (6–20 Uhr), Woche/nächste Woche, Auslastung, Konflikte/Hinweise, Verzugs- und Gefährdungs-Badges, Drag & Drop (@dnd-kit/core) mit Bestätigungs-Popover und Tastatur-Alternative, ungeplante Aufträge mit Vorschlägen, früher fertig mit Vorziehen, Kolonnenkapazität-Popup. Live-Lage: Leaflet/OSM-Karte mit einem Marker je Kolonne, Liste, Polling 30 s, Hinweis keine GPS-Ortung; CSP img-src für Kacheln. Dashboard-Kacheln Planung heute und Konflikte diese Woche, Einsatz-Vorschläge im Auftragsdetail, Navigation mit Unterpunkten, Smoke-Prüfungen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -99,6 +99,17 @@ function plans(x: Awaited<ReturnType<typeof ids>>): Plan[] {
|
||||
{ path: "/search?q=Elbblick", mustContain: "Elbblick", perf: true },
|
||||
{ path: "/teams" },
|
||||
{ path: "/settings/users", expect: [200, 307, 403] },
|
||||
// L13 Planung
|
||||
{ path: "/planning", mustContain: ["Plantafel", 'data-planning-view="days"', 'data-day-count="5"', "Heute", "Team Nord", "Team Süd", "Ungeplante Aufträge"], perf: true },
|
||||
{ path: "/planning?view=today", mustContain: ['data-planning-view="today"', "Ganztägig", "Team Nord", "Team Süd"] },
|
||||
{ path: "/planning?view=week", mustContain: ['data-planning-view="week"', 'data-day-count="7"'] },
|
||||
{ path: "/dashboard", mustContain: ["Planung heute", "Teams im Einsatz"] },
|
||||
{ path: `/planning?schedule=${x.d07.id}`, mustContain: "Plantafel" },
|
||||
{ path: "/planning/live", mustContain: ["Live-Lage", "keine GPS-Ortung", "OpenStreetMap"], mustNotContain: ["startLat", "startLng"], perf: true },
|
||||
{ path: "/api/v1/planning/board", mustContain: ['"teams"', '"conflictCount"'] },
|
||||
{ path: "/api/v1/planning/live", mustContain: '"technicians"', mustNotContain: ["startLat", "startLng", "deviceInfo"] },
|
||||
{ path: `/api/v1/planning/recommendations?workOrderId=${x.d07.id}`, mustContain: '"recommendations"' },
|
||||
{ path: "/dashboard", mustContain: "Konflikte diese Woche" },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -113,6 +124,9 @@ function plans(x: Awaited<ReturnType<typeof ids>>): Plan[] {
|
||||
{ path: "/reports" },
|
||||
...(x.inReview ? [{ path: `/reports/${x.inReview.id}`, mustContain: x.d16?.number }] : []),
|
||||
{ path: m(x.d08), expect: [404] },
|
||||
// L13 Planung: team lead read-only, own team only
|
||||
{ path: "/planning", mustContain: ["Plantafel", "Team Nord", "Nur Lesezugriff"], mustNotContain: ["Team Süd"] },
|
||||
{ path: "/planning/live", mustContain: "keine GPS-Ortung", mustNotContain: ["Team Süd"] },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -141,6 +155,8 @@ function plans(x: Awaited<ReturnType<typeof ids>>): Plan[] {
|
||||
{ path: m(x.d08), expect: [404] },
|
||||
{ path: `/customers/${x.foreignCustomer.id}`, expect: [404, 307] },
|
||||
{ path: "/dashboard", expect: [307, 308], redirectTo: "/m" },
|
||||
{ path: "/planning", expect: [404] },
|
||||
{ path: "/planning/live", expect: [404] },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -167,6 +183,9 @@ function plans(x: Awaited<ReturnType<typeof ids>>): Plan[] {
|
||||
...(x.emergency ? [{ path: `/work-orders/emergency-review/${x.emergency.id}`, expect: [404] }] : []),
|
||||
...(x.imp ? [{ path: `/imports/${x.imp.id}`, expect: [404] }] : []),
|
||||
...(x.photo ? [{ path: `/files/${x.photo.documentId}`, expect: [404] }] : []),
|
||||
{ path: "/planning", mustNotContain: ["Team Nord", x.d07.number] },
|
||||
{ path: "/planning/live", mustNotContain: ["Team Nord", "Max Monteur"] },
|
||||
{ path: `/api/v1/planning/recommendations?workOrderId=${x.d07.id}`, expect: [404] },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user