L1 Stammdaten: Backoffice-Seiten Kunden, Objekte, Teams und Dokumente

Listen mit Suche/Filter/Paginierung, Popups für Anlage und Bearbeitung,
Kundendetail mit Tabs, Dublettenhinweis und Zusammenführen, Objektdetail mit
Kartenlink, Dokumenten-Tab und Historie, Teamverwaltung mit Mitgliedern,
Dokumentenübersicht. Texte in messages de/en, Audit-Label Ansprechpartner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 12:26:27 +02:00
co-authored by Claude Opus 5
parent 49c5ad0e33
commit d18f4fe431
28 changed files with 3660 additions and 12 deletions
+180
View File
@@ -0,0 +1,180 @@
{
"title": "Customers",
"crumb": "Master data",
"sub": "Customers, contacts and sites in one place.",
"new": "New customer",
"searchLabel": "Search",
"searchPlaceholder": "Name, customer no., city or e-mail",
"filter": {
"status": "Status",
"all": "All (without merged)",
"apply": "Filter",
"reset": "Reset"
},
"status": {
"active": "Active",
"inactive": "Inactive",
"provisional": "Provisional",
"merged": "Merged"
},
"provisionalHint": "Provisional – back office review required",
"columns": {
"number": "Customer no.",
"name": "Name",
"city": "City",
"contact": "Contact",
"sites": "Sites",
"status": "Status"
},
"empty": "No customers found.",
"pagination": {
"prev": "Previous",
"next": "Next",
"summary": "{from}–{to} of {total}"
},
"fields": {
"customerNumber": "Customer number",
"customerNumberHint": "Leave empty to use the next free number.",
"companyName": "Company name",
"salutation": "Salutation",
"firstName": "First name",
"lastName": "Last name",
"street": "Street",
"houseNumber": "No.",
"postalCode": "Postal code",
"city": "City",
"country": "Country",
"phone": "Phone",
"mobile": "Mobile",
"email": "E-mail",
"notes": "General notes",
"billingNotes": "Billing notes",
"status": "Status",
"createdAt": "Created",
"updatedAt": "Updated"
},
"sections": {
"customer": "Customer",
"address": "Address",
"contact": "Reachability",
"notes": "Notes"
},
"form": {
"createTitle": "Create customer",
"createSub": "Business or private customer. Company name or last name is required.",
"editTitle": "Edit customer",
"create": "Create customer",
"save": "Save",
"saving": "Saving…",
"cancel": "Cancel",
"close": "Close",
"saved": "Saved.",
"required": "Required"
},
"duplicates": {
"title": "Possible duplicate",
"hint": "These customers look similar. Use an existing customer or create a new one anyway.",
"open": "Open existing customer",
"createAnyway": "Create anyway",
"score": "Match {percent} %",
"reasons": {
"customer_number": "Customer number",
"company_name": "Name",
"address": "Address",
"email": "E-mail",
"phone": "Phone"
}
},
"tabs": {
"master": "Master data",
"contacts": "Contacts",
"sites": "Sites",
"orders": "Work orders",
"documents": "Documents"
},
"detail": {
"edit": "Edit",
"confirm": "Confirm customer",
"confirmHint": "Take over the provisional customer as active after review.",
"merge": "Merge",
"delete": "Delete",
"deleteTitle": "Delete customer",
"deleteHint": "The customer is hidden. Work orders, reports and records are kept. Only possible without open work orders.",
"deleteConfirm": "Delete customer",
"mergedInto": "This customer was merged into:",
"mergedOk": "Customers merged. Contacts, sites, work orders and documents are now here.",
"back": "Back to customers",
"readOnly": "Read-only access."
},
"contacts": {
"new": "Add contact",
"createTitle": "Add contact",
"editTitle": "Edit contact",
"empty": "No contacts yet.",
"delete": "Remove",
"deleteConfirm": "Remove contact?",
"preferred": "preferred",
"fields": {
"name": "Name",
"role": "Role",
"phone": "Phone",
"mobile": "Mobile",
"email": "E-mail",
"preferredChannel": "Preferred channel",
"notes": "Remarks"
},
"channel": {
"phone": "Phone",
"mobile": "Mobile",
"email": "E-mail",
"none": "Not specified"
}
},
"sites": {
"empty": "No sites yet.",
"new": "Create site"
},
"orders": {
"empty": "No visible work orders.",
"hint": "Read-only. Work orders are edited in the work orders area.",
"columns": {
"number": "Order",
"title": "Title",
"site": "Site",
"team": "Team",
"date": "Scheduled",
"status": "Status"
}
},
"merge": {
"title": "Merge customers",
"sub": "Contacts, sites, work orders and documents are moved to the target customer. This customer is marked as merged.",
"source": "Will be merged",
"target": "Target customer",
"candidates": "Possible duplicates",
"noCandidates": "No similar customers found. Choose the target by customer number.",
"targetNumber": "Or customer number of the target",
"confirm": "Records checked. Confirm merge – this is not undone automatically.",
"submit": "Merge"
},
"errors": {
"invalid": "Please check the highlighted fields.",
"not_found": "Record not found.",
"forbidden": "You are not allowed to do this.",
"conflict": "Not possible: the record was changed or is already taken.",
"blocked": "Action currently not possible.",
"generic": "That did not work. Please try again.",
"required": "Required",
"invalidField": "Check input",
"name_required": "Enter a company name or last name.",
"number_taken": "Customer number is already taken.",
"number_allocation": "No free customer number found.",
"open_work_orders": "There are still open work orders.",
"not_provisional": "The customer is not provisional.",
"already_merged": "One of the customers is already merged.",
"same_customer": "Source and target are the same customer.",
"target_required": "Select a target customer.",
"target_not_found": "Customer number not found.",
"confirm_required": "Please confirm the merge."
}
}
+120
View File
@@ -0,0 +1,120 @@
{
"title": "Documents",
"crumb": "Storage",
"sub": "All files for customers, sites and work orders – with version, checksum and visibility.",
"empty": "No documents found.",
"columns": {
"document": "Document",
"category": "Category",
"link": "Linked to",
"visibility": "Visibility",
"version": "Version",
"size": "Size",
"uploaded": "Uploaded"
},
"filter": {
"q": "File name or title",
"category": "Category",
"allCategories": "All categories",
"customer": "Customer",
"allCustomers": "All customers",
"site": "Site",
"allSites": "All sites",
"workOrder": "Work order number",
"latestOnly": "Latest versions only",
"apply": "Filter",
"reset": "Reset"
},
"pagination": {
"prev": "Previous",
"next": "Next",
"summary": "{from}–{to} of {total}"
},
"category": {
"order_confirmation": "Order confirmation",
"technical_drawing": "Technical drawing",
"floor_plan": "Floor plan",
"wiring_diagram": "Wiring diagram",
"assembly_instructions": "Assembly instructions",
"safety_document": "Safety document",
"product_document": "Product document",
"customer_note": "Customer note",
"work_record": "Work record",
"daily_report": "Daily report",
"completion_report": "Completion report",
"customer_approval": "Customer approval",
"photo": "Photo",
"voice_note": "Voice note",
"signature": "Signature",
"other": "Other document"
},
"visibility": {
"backoffice_only": "Back office only",
"team_lead": "Team leads",
"team": "Installation team",
"customer_report": "Released for customer report"
},
"link": {
"customer": "Customer",
"site": "Site",
"workOrder": "Work order",
"none": "Not linked"
},
"upload": {
"title": "Upload document",
"file": "File",
"fileHint": "PDF up to 25 MB, images (JPEG, PNG, WebP, HEIC) up to 15 MB, audio up to 20 MB.",
"titleField": "Title (optional)",
"category": "Category",
"visibility": "Visibility",
"submit": "Upload",
"newVersion": "New version",
"newVersionTitle": "Upload new version",
"newVersionOf": "New version of \"{name}\"",
"ok": "Document saved."
},
"versions": {
"label": "v{version}",
"older": "{count, plural, one {# older version} other {# older versions}}",
"latest": "latest"
},
"actions": {
"download": "Download",
"edit": "Edit",
"delete": "Remove",
"deleteConfirm": "Remove this version?"
},
"edit": {
"title": "Edit document",
"titleField": "Title",
"save": "Save",
"saving": "Saving…",
"cancel": "Cancel"
},
"uploadErrors": {
"empty_file": "Please select a file.",
"too_large": "The file is too large.",
"unsupported_type": "File type not allowed. Allowed: PDF, JPEG, PNG, WebP, HEIC and audio.",
"type_mismatch": "File content does not match the file type.",
"malware": "The file was rejected by the virus scan.",
"scanner_unavailable": "Virus scan unavailable. Please try again later.",
"visibility_not_allowed": "This visibility is not allowed.",
"lineage_not_found": "Original document not found.",
"invalid_category": "Please choose a category.",
"site_not_found": "Site not found.",
"customer_not_found": "Customer not found.",
"forbidden": "You are not allowed to do this.",
"not_found": "Work order not found.",
"invalid": "Invalid upload.",
"generic": "Upload failed. Please try again."
},
"errors": {
"invalid": "Please check your input.",
"not_found": "Document not found.",
"forbidden": "You are not allowed to do this.",
"conflict": "Not possible.",
"blocked": "Action currently not possible.",
"generic": "That did not work. Please try again.",
"visibility_not_allowed": "This visibility is not allowed."
}
}
+137
View File
@@ -0,0 +1,137 @@
{
"title": "Sites",
"crumb": "Master data",
"sub": "Construction sites, branches and installations with notes, documents and job history.",
"new": "New site",
"searchLabel": "Search",
"searchPlaceholder": "Site, address or customer",
"filter": {
"status": "Status",
"all": "All",
"apply": "Filter",
"reset": "Reset"
},
"status": {
"active": "Active",
"inactive": "Inactive",
"provisional": "Provisional"
},
"columns": {
"name": "Site",
"customer": "Customer",
"address": "Address",
"orders": "Work orders",
"status": "Status"
},
"empty": "No sites found.",
"pagination": {
"prev": "Previous",
"next": "Next",
"summary": "{from}–{to} of {total}"
},
"fields": {
"customerId": "Customer",
"selectCustomer": "Select customer",
"name": "Site name",
"street": "Street",
"houseNumber": "No.",
"postalCode": "Postal code",
"city": "City",
"country": "Country",
"contactId": "On-site contact",
"noContact": "No stored contact",
"onSiteContact": "On-site contact (free text)",
"phone": "On-site phone",
"accessNotes": "Access notes",
"parkingNotes": "Parking notes",
"safetyNotes": "Safety information",
"technicalNotes": "Technical notes",
"status": "Status",
"latitude": "Latitude",
"longitude": "Longitude"
},
"sections": {
"base": "Site",
"address": "Address",
"onSite": "On site",
"notes": "Notes for the job",
"geo": "Coordinates (optional)"
},
"form": {
"createTitle": "Create site",
"createSub": "Every site belongs to a customer.",
"editTitle": "Edit site",
"create": "Create site",
"save": "Save",
"saving": "Saving…",
"cancel": "Cancel",
"saved": "Saved.",
"contactHint": "The customer's contacts can be selected after creating the site."
},
"tabs": {
"master": "Master data",
"documents": "Documents",
"history": "History"
},
"detail": {
"edit": "Edit",
"delete": "Delete",
"deleteTitle": "Delete site",
"deleteHint": "The site is hidden. History and records are kept. Only possible without open work orders.",
"deleteConfirm": "Delete site",
"map": "Open map (OpenStreetMap)",
"noMap": "No address for the map",
"customer": "Customer",
"back": "Back to sites",
"noNotes": "No notes stored."
},
"history": {
"title": "Job history",
"onlyApproved": "Released only",
"showAll": "All jobs",
"approvedOnlyHint": "Showing released jobs.",
"empty": "No jobs at this site yet.",
"workDone": "Work carried out",
"noWorkDone": "No activities recorded.",
"materials": "Material",
"noMaterials": "No material recorded.",
"photos": "{count, plural, =0 {No photos} one {# photo} other {# photos}}",
"reports": "Reports",
"noReports": "No released report.",
"reportType": {
"daily": "Daily report",
"completion": "Completion report"
},
"reportLink": "{type} v{version} of {date}",
"signed": "Customer signature available",
"notSigned": "No customer signature",
"followUp": "Open follow-up work",
"emergency": "Emergency",
"noTeam": "No team",
"openOrder": "Open work order"
},
"statusGroup": {
"new": "New",
"planned": "Planned",
"en_route": "On the way",
"in_progress": "In progress",
"documentation_incomplete": "Documentation incomplete",
"in_review": "In review",
"ready_for_billing": "Ready for billing",
"billed": "Billed",
"cancelled": "Cancelled"
},
"errors": {
"invalid": "Please check the highlighted fields.",
"not_found": "Record not found.",
"forbidden": "You are not allowed to do this.",
"conflict": "Not possible: the record was changed.",
"blocked": "Action currently not possible.",
"generic": "That did not work. Please try again.",
"required": "Required",
"invalidField": "Check input",
"customer_not_found": "Customer not found.",
"contact_mismatch": "The contact does not belong to this customer.",
"open_work_orders": "There are still open work orders."
}
}
+75
View File
@@ -0,0 +1,75 @@
{
"title": "Teams",
"crumb": "Master data",
"sub": "Installation teams with team lead, members and service area.",
"new": "New team",
"showInactive": "Show inactive",
"hideInactive": "Hide inactive",
"empty": "No teams yet.",
"columns": {
"name": "Team",
"leader": "Team lead",
"members": "Members",
"phone": "Phone",
"vehicle": "Vehicle",
"area": "Service area",
"status": "Status"
},
"status": {
"active": "Active",
"inactive": "Inactive"
},
"fields": {
"name": "Team name",
"leaderUserId": "Team lead",
"noLeader": "No team lead",
"status": "Status",
"phone": "Phone",
"vehicle": "Vehicle",
"area": "Service area",
"notes": "Internal notes"
},
"members": {
"title": "Members",
"add": "Add member",
"remove": "Remove",
"user": "Person",
"selectUser": "Select person",
"validFrom": "Valid from",
"validTo": "Valid until",
"validToHint": "Empty = unlimited",
"empty": "No members yet.",
"current": "current",
"ended": "ended",
"upcoming": "from {date}",
"count": "{count, plural, =0 {No members} one {# member} other {# members}}"
},
"form": {
"createTitle": "Create team",
"editTitle": "Edit team",
"sub": "Members are active users of the tenant.",
"save": "Save",
"create": "Create team",
"saving": "Saving…",
"cancel": "Cancel",
"delete": "Delete team",
"deleteHint": "The team is hidden. Only possible without open work orders.",
"deleteConfirm": "Really delete the team?"
},
"readOnly": "Read-only access.",
"errors": {
"invalid": "Please check the highlighted fields.",
"not_found": "Team not found.",
"forbidden": "You are not allowed to do this.",
"conflict": "Not possible: the name is already taken.",
"blocked": "Action currently not possible.",
"generic": "That did not work. Please try again.",
"required": "Required",
"invalidField": "Check input",
"duplicate_member": "A person is listed more than once.",
"inactive_user": "Only active users of the tenant can be added.",
"name_taken": "Team name is already taken.",
"valid_to_before_from": "\"Valid until\" is before \"valid from\".",
"open_work_orders": "Open work orders are still assigned to the team."
}
}