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:
2026-09-15 10:13:50 +02:00
co-authored by Claude Opus 5
parent 5e10523df6
commit ee17134863
25 changed files with 2557 additions and 3 deletions
+3
View File
@@ -1,6 +1,9 @@
{
"dashboard": "Dashboard",
"workOrders": "Work orders",
"planning": "Planning",
"planningBoard": "Planning board",
"planningLive": "Live situation",
"emergencyReview": "Emergency review",
"imports": "Import",
"customers": "Customers",
+199
View File
@@ -0,0 +1,199 @@
{
"crumb": "Planning",
"weekday": { "0": "Mon", "1": "Tue", "2": "Wed", "3": "Thu", "4": "Fri", "5": "Sat", "6": "Sun" },
"board": {
"title": "Planning board",
"sub": "Schedule orders per team and day – utilization and overlaps at a glance.",
"readOnly": "Read-only – you see your own teams.",
"viewLabel": "View",
"view": { "today": "Today", "days": "5 days", "week": "Week", "nextWeek": "Next week" },
"navLabel": "Change period",
"prevWeek": "Previous week",
"nextWeek": "Next week",
"prevDay": "Previous day",
"nextDay": "Next day",
"prevDays": "Previous 5 working days",
"nextDays": "Next 5 working days",
"todayLabel": "Today · {day}",
"time": "Time",
"today": "Today",
"range": "{from} – {to}",
"team": "Team",
"noTeams": "No active teams in this selection.",
"showMembers": "Show members of {team}",
"hideMembers": "Hide members of {team}",
"memberHint": "Individually assigned",
"load": "{planned} / {capacity} · {percent} %",
"loadNoCapacity": "{planned} · no capacity",
"notWorkingDay": "Not a working day",
"allDay": "All day",
"free": "free",
"narrowHint": "The planning board is designed for screens from 1024 px. Here you see a simple list.",
"capacity": "Capacity",
"capacityOf": "Edit capacity of {team}",
"move": "Move …",
"schedule": "Schedule …",
"dragHint": "Drag cards onto a day with the mouse or use “Schedule …” / “Move …” with the keyboard.",
"open": "Open order",
"saved": "{number} scheduled: {team}, {day}.",
"savedWithConflicts": "{number} scheduled: {team}, {day}. Attention: {count} conflict(s) on the target day.",
"priority": "Priority: {priority}",
"emergency": "Emergency",
"multiDay": "multi-day",
"duration": "Duration {duration}",
"listDayEmpty": "Nothing planned",
"crewCapacity": "Crew · {capacity} per working day · {count} people",
"delayRisk": "Delay likely · {percent} %",
"delayOverrun": "Duration exceeded · {percent} %",
"atRisk": "at risk due to delay of {number}"
},
"freed": {
"title": "Finished early",
"badge": "{team} · {minutes} early",
"available": "{minutes} free from {time}",
"pullForward": "Pull forward",
"kindPullForward": "Planned order of {team}",
"kindNearby": "Unplanned, {distance} away",
"noSuggestions": "No suitable order for the free time.",
"hint": "Hint only – nothing is moved automatically."
},
"conflicts": {
"label": "Conflict",
"count": "{count, plural, =0 {No conflicts} one {# conflict} other {# conflicts}}",
"overbooked": "Overbooked by {over}",
"overlap": "Overlap: {a} and {b}",
"assignee_double_booked": "{user} double-booked: {a} and {b}",
"outside_working_days": "Outside working days",
"crew_incomplete": "Crew incomplete: {count} active person(s)",
"hintLabel": "Hint",
"short": {
"overbooked": "Overbooked",
"overlap": "Overlap",
"assignee_double_booked": "Double-booked",
"outside_working_days": "Not a working day",
"crew_incomplete": "Crew incomplete"
}
},
"filters": {
"title": "Filter",
"team": "Team",
"orderType": "Order type",
"priority": "Priority",
"any": "All",
"apply": "Apply",
"reset": "Reset"
},
"unplanned": {
"title": "Unplanned orders",
"empty": "No unplanned orders.",
"noTeam": "no team",
"noDate": "no date",
"noLocation": "no location",
"suggestions": "Suggestions"
},
"dialog": {
"title": "Schedule order",
"team": "Team",
"date": "Date",
"time": "Start",
"noTime": "No time (all day)",
"duration": "Duration in minutes",
"durationHint": "Prefilled from the order or order type ({duration}).",
"save": "Save",
"saving": "Saving …",
"cancel": "Cancel",
"close": "Close"
},
"errors": {
"conflict": "The order was changed in the meantime. The view was refreshed – please schedule again.",
"forbidden": "You are not allowed to do this.",
"not_found": "Order not found.",
"invalid": "Please check your input.",
"planned_end_before_start": "The end is before the start.",
"not_schedulable": "This order is already in progress and is not moved here.",
"team_not_found": "Team not found or not active.",
"not_editable": "This order can no longer be changed.",
"network": "No connection. Please try again.",
"generic": "Saving was not possible. Please try again."
},
"recommend": {
"title": "Suggestions",
"sub": "Suggestions only, by straight-line distance and schedule – you decide the assignment.",
"loading": "Calculating suggestions …",
"reason": "{distance} from {number} · {team} still has {free} free on {day}",
"reasonTight": "{distance} from {number} · {team} on {day} tight: {free} free, {required} needed",
"card": "{day} · {team} · {distance} from {number} · {free} free",
"tight": "tight",
"take": "Use",
"noCoordinates": "Address not located – geocoding was requested. Please open again later.",
"addressNotFound": "Address not located – the address was not found. Please check the site.",
"notSchedulable": "This order is already in progress.",
"none": "No team has an order within {radius} km with free capacity in the next {days} days.",
"nearbyTitle": "Nearby, also unplanned",
"nearbyQuestion": "These orders are within {radius} km – schedule them together?",
"nearbyEmpty": "No other unplanned orders nearby.",
"planTogether": "Schedule together",
"close": "Close suggestions",
"failed": "Suggestions could not be loaded.",
"sectionTitle": "Assignment suggestions",
"openBoard": "Open planning board"
},
"live": {
"title": "Live situation",
"sub": "Who is currently on which job?",
"privacy": "Location = site of the running order, no GPS tracking.",
"status": { "en_route": "En route", "working": "Working", "paused": "Break", "free": "Free" },
"freeHint": "no running job",
"since": "since {time}",
"updated": "Last updated: {time}",
"refresh": "Refresh",
"refreshing": "Refreshing …",
"updateFailed": "Update failed – showing the last state.",
"tabsLabel": "Display",
"tabs": { "map": "Map", "list": "List" },
"filterTeam": "Team",
"filterStatus": "Status",
"all": "All",
"noLocation": "no location",
"hiddenOrder": "Job outside your area",
"next": "Still planned today",
"nothingNext": "Nothing else planned today",
"attentionTitle": "Today without start",
"attentionEmpty": "All of today's orders have started or are planned later.",
"reason": { "not_accepted": "Not accepted", "overdue": "Start time passed" },
"empty": "No technicians in this selection.",
"markerCount": "{count} people at this location",
"mapLabel": "Map of running jobs",
"mapLoading": "Loading map …",
"withoutLocation": "{count} running jobs without location (list only)",
"noTeam": "no team",
"crewsTitle": "Crews",
"soloTitle": "Without team",
"crewMembers": "Members",
"memberAt": "at {number}",
"delayRisk": "Delay likely · {percent} %",
"delayOverrun": "Duration exceeded · {percent} %",
"worked": "{worked} of {planned} recorded"
},
"capacity": {
"title": "Team capacity",
"sub": "Basis for utilization and suggestions",
"minutes": "Crew working day in minutes",
"minutesHint": "The crew works together: capacity per working day, not per person.",
"days": "Working days",
"save": "Save",
"saving": "Saving …",
"errors": {
"invalid": "Please check your input.",
"forbidden": "You are not allowed to do this.",
"not_found": "Team not found.",
"generic": "Saving was not possible."
}
},
"dashboardTile": {
"title": "Conflicts this week",
"hint": "Overbooking, overlap, double booking",
"todayTitle": "Planning today",
"todayHint": "Teams on the job · {conflicts} conflict(s) · {unplanned} unplanned orders"
}
}