diff --git a/mobile/artifacts/deskhub-release.aab b/mobile/artifacts/deskhub-release.aab
index 71fa2b47..d2115ee4 100644
Binary files a/mobile/artifacts/deskhub-release.aab and b/mobile/artifacts/deskhub-release.aab differ
diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml
index a0b9eb25..4e401b66 100644
--- a/mobile/src/main/AndroidManifest.xml
+++ b/mobile/src/main/AndroidManifest.xml
@@ -1,60 +1,71 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/mobile/src/main/assets/lang_en.json b/mobile/src/main/assets/lang_en.json
index f1389c52..7e5807a9 100644
--- a/mobile/src/main/assets/lang_en.json
+++ b/mobile/src/main/assets/lang_en.json
@@ -1 +1 @@
-{"%.1f Std":"%.1f hrs","(Gast)":"(Guest)","(zusätzlich)":"(additional)","+ Aktion":"+ Action","+ Aktion hinzufügen":"+ Add action","+ Antwort hinzufügen":"+ Add answer","+ Aufgabe":"+ Task","+ Bedingung":"+ Condition","+ Bedingung hinzufügen":"+ Add condition","+ Erfassen":"+ Log time","+ Kategorie hinzufügen":"+ Add category","+ Neu":"+ New","+ Neue Aufgabe":"+ New task","+ Neue Regel":"+ New rule","+ Neuer Artikel":"+ New article","+ Neuer Textbaustein":"+ New text snippet","+ Neues Muster":"+ New pattern","+ Neues Ticket":"+ New ticket","+ Ticket erstellen":"+ Create ticket","+ hinzufügen":"+ add","0 Gerät(e) angemeldet":"0 device(s) signed in","1 Std":"1 hr","1 Tag":"1 day","1 Treffer ·":"1 hit ·","1 Woche":"1 week","10 Backups behalten":"Keep 10 backups","14 Backups behalten":"Keep 14 backups","2 Std":"2 hrs","2 Tage":"2 days","3 Backups behalten":"Keep 3 backups","3 Std":"3 hrs","3 Tage":"3 days","30 Backups behalten":"Keep 30 backups","5 Backups behalten":"Keep 5 backups","6-stelliger Code":"6-digit code","7 Backups behalten":"Keep 7 backups","7 Tage":"7 days","8 Std":"8 hrs",": bitte in der App erneut versuchen":": please try again in the app","API-Schlüssel":"API keys","Abbrechen":"Cancel","Abfrage am {} gesendet, noch keine Antwort.":"Survey sent on {}, no answer yet.","Abfrage-Intervall":"Fetch interval","Abgehend (SMTP)":"Outgoing (SMTP)","Abgehend (eigener SMTP-Server)":"Outgoing (own SMTP server)","Abmelden":"Sign out","Abmelden / Server wechseln":"Sign out / switch server","Abruf":"Fetch","Abruf aktivieren":"Enable fetching","Abruf für diese Adresse aktivieren":"Enable fetching for this address","Absender":"Sender","Absender oder Mailanbieter sperren":"Block sender or mail provider","Absender sperren":"Block sender","Absender sperren…":"Block sender…","Absender-E-Mail":"Sender email","Absender-Name":"Sender name","Absender:":"Sender:","Absendername":"Sender name","Abteilung":"Department","Abteilung aktualisieren":"Update department","Abteilung für Live-Chat-Tickets":"Department for live chat tickets","Abteilung für Tickets des Assistenten":"Department for assistant tickets","Abteilung hinzufügen":"Add department","Abteilung nicht gefunden.":"Department not found.","Abteilung setzen":"Set department","Abteilung und Priorität stammen aus dem Reiter „Konto“.":"Department and priority come from the \"Account\" tab.","Abteilung wirklich löschen?":"Really delete this department?","Abteilung ändern":"Change department","Abteilung „":"Department \"","Abteilung „Allgemeiner Support“ (nicht hinterlegt)":"Department \"General support\" (not set)","Abteilung/Priorität bestimmt die Zeiten":"Department/priority determines the times","Abteilung:":"Department:","Abteilungen":"Departments","Abteilungen verwalten":"Manage departments","Abteilungen werden geladen …":"Loading departments …","Abteilungs-E-Mail (optional)":"Department email (optional)","Abteilungs-E-Mail (optional, sonst Standardadresse)":"Department email (optional, otherwise default address)","Abteilungs-Routing-Tabelle":"Department routing table","Abteilungsinformationen":"Department information","Abteilungsleiter":"Department head","Achtung:":"Attention:","Admin benachrichtigen":"Notify admin","Admin-Protokoll":"Admin log","Admin-Protokoll einsehen":"View admin log","Administrator (alle Rechte)":"Administrator (all rights)","Administratornotizen":"Administrator notes","Administratornotizen (intern)":"Administrator notes (internal)","Adminportal":"Admin portal","Adminportal-Bereiche (\"Co-Admin\")":"Admin portal areas (\"co-admin\")","Admins benachrichtigen":"Notify admins","Adresse für Kunden:":"Address for customers:","Adresse für Kunden: {}":"Address for customers: {}","Adressen und Postfach-Abruf":"Addresses and mailbox fetching","Adressen verwaltest du unter „E-Mail-Adressen“.":"You manage addresses under \"Email addresses\".","Adressen, Priorität und Postfach-Abruf pflegst du unter":"You manage addresses, priority and mailbox fetching under","Agent anlegen":"Create agent","Agenten":"Agents","Agenten verwalten — {}":"Manage agents — {}","Aktion":"Action","Aktion nach Abruf":"Action after fetch","Aktionen":"Actions","Aktiv":"Active","Aktiv (auf dem Ticket-Formular sichtbar)":"Active (visible on the ticket form)","Aktiv (deaktivierte Rolle wird ignoriert)":"Active (a disabled role is ignored)","Aktiv (sonst deaktiviert)":"Active (otherwise disabled)","Aktiv (sonst gesperrt)":"Active (otherwise blocked)","Aktiv (wird beim Abruf berücksichtigt)":"Active (used when fetching)","Aktive Live-Chats (0)":"Active live chats (0)","Aktivieren":"Activate","Aktivität":"Activity","Aktualisiere …":"Refreshing …","Aktualisieren":"Refresh","Aktualisiert":"Updated","Aktuell keine offenen Live-Chats.":"There are currently no open live chats.","Aktuell würden":"Currently","Aktuelle Filter als Ansicht speichern":"Save current filters as a view","Aktuelle Filter speichern …":"Save current filters …","Aktuelles Passwort":"Current password","Alle":"All","Alle Absender der markierten Tickets sperren und Tickets schließen?":"Block all senders of the selected tickets and close the tickets?","Alle Abteilungen":"All departments","Alle Artikel durchsuchen":"Browse all articles","Alle Bedingungen":"All conditions","Alle Bedingungen müssen zutreffen":"All conditions must match","Alle Ergebnisse":"All results","Alle Prioritäten":"All priorities","Alle Status":"All statuses","Alle Tags":"All tags","Alle Textbausteine":"All text snippets","Alle Themen (oder Formular ohne Themenauswahl)":"All topics (or form without topic selection)","Alle Zuständigkeiten":"All assignments","Alle aktiven":"All active","Alle anlegen":"Create all","Alle außer Geschlossen":"All except closed","Alle behalten":"Keep all","Alle bekannten Datenbank-Änderungen sind eingespielt.":"All known database changes have been applied.","Alle eingegebenen Adressen sperren und Tickets schließen?":"Block all entered addresses and close tickets?","Alle löschen":"Delete all","Alle sperren":"Block all","Allgemein":"General","Allgemeine Anfrage":"General inquiry","Allgemeiner Support":"General support","Alphabetisch":"Alphabetical","Als Spam markiert":"Marked as spam","Als gelesen markieren":"Mark as read","An diesen Tagen laufen keine SLA-Fristen, unabhängig vom Wochentag.":"No SLA deadlines run on these days, regardless of the weekday.","Analysieren":"Analyze","Android fragt einmalig, ob der Browser Apps installieren darf. Das bitte erlauben.":"Android asks once whether the browser may install apps. Please allow it.","Anfrage-Quelle":"Request source","Angaben des Kunden":"Customer details","Angepasst":"Customized","Angewendet":"Applied","Anhang":"Attachment","Anhänge (optional, mehrere möglich)":"Attachments (optional, multiple allowed)","Anmelden":"Sign in","Anmelden – {}":"Sign in – {}","Anmeldung für Support-Mitarbeiter und Administratoren.":"Sign-in for support staff and administrators.","Anmeldung wird geprüft …":"Checking sign-in …","Anonymisiert":"Anonymized","Anonymisierung jetzt ausführen? Dies kann nicht rückgängig gemacht werden.":"Run anonymization now? This cannot be undone.","Anordnung der Optionen":"Order of the options","Ansicht aktualisieren":"Refresh view","Ansicht gespeichert":"View saved","Ansicht löschen":"Delete view","Ansicht löschen?":"Delete view?","Ansicht speichern":"Save view","Ansicht umbenennen":"Rename view","Ansichten":"Views","Antwort":"Answer","Antwort *":"Answer *","Antwort / Ticket":"Answer / ticket","Antwort an Kunden":"Reply to customer","Antwort anlegen":"Create answer","Antwort bearbeiten":"Edit answer","Antwort dazu anlegen":"Create an answer for it","Antwort gelöscht":"Answer deleted","Antwort gesendet":"Reply sent","Antwort gespeichert":"Answer saved","Antwort jetzt an den Kunden senden?":"Send the reply to the customer now?","Antwort löschen":"Delete answer","Antwort nicht gesendet":"Reply not sent","Antwort schreiben":"Write reply","Antwort senden":"Send reply","Antworten":"Replies","Antworten / Notiz":"Reply / note","Antworten auf häufige Fragen – oft schneller als der Weg über ein Ticket.":"Answers to common questions – often faster than opening a ticket.","Antworten, Fragen-Log, Einstellungen":"Answers, question log, settings","Antworten, Fragen-Log, Einstellungen, Synonyme":"Answers, question log, settings, synonyms","Antwort…":"Answer…","Anzeigename":"Display name","Anzeigename & URL":"Display name & URL","Anzeigename (optional)":"Display name (optional)","App öffnen, Serveradresse eingeben und anmelden.":"Open the app, enter the server address and sign in.","Apps für Mitarbeiter":"Apps for staff","Artikel":"Article","Artikel bearbeiten":"Edit article","Artikel und Kategorien":"Articles and categories","Artikel wirklich löschen?":"Really delete this article?","Auch Nachrichten durchsuchen":"Also search messages","Auf Standard zurücksetzen?":"Reset to default?","Auf später legen":"Snooze","Auf später legen: das Ticket verschwindet aus den Listen und kommt zurück, mit Benachrichtigung.":"Snooze: the ticket disappears from the lists and comes back, with a notification.","Auf „Alle Themen“ belassen, damit das Feld unabhängig vom gewählten Anliegen erscheint.":"Leave on \"All topics\" so the field appears regardless of the chosen request.","Aufbewahrungsdauer nach Schließung":"Retention period after closing","Aufgabe":"Task","Aufgabe löschen?":"Delete task?","Aufgaben":"Tasks","Aufgaben werden geladen …":"Loading tasks …","Aufrufe":"Views","Aus":"Off","Ausfall":"Outage","Auslöser":"Trigger","Ausprobieren":"Try out","Auswahl aufheben":"Clear selection","Auswahl:":"Selection:","Auswertungen":"Reports","Authenticator-Code":"Authenticator code","Auto-Antwort senden (Textbaustein)":"Send auto-reply (text snippet)","Automatisch":"Automatic","Automatisch (Routing-Tabelle / globale Standardabteilung)":"Automatic (routing table / global default department)","Automatisch (Standardadresse der Abteilung)":"Automatic (department default address)","Automatisch offline nach":"Go offline automatically after","Automatisch schließen":"Close automatically","Automatische Anonymisierung aktivieren":"Enable automatic anonymization","Automatische Backups":"Automatic backups","Automatische Backups jetzt manuell ausführen?":"Run automatic backups manually now?","Automatische Datenlöschung":"Automatic data deletion","Automatische Zeiterfassung (misst automatisch, wie lange ein Mitarbeiter ein Ticket geöffnet hat)":"Automatic time tracking (measures how long a staff member has a ticket open)","Automatischen Hintergrund-Betrieb aktiv halten":"Keep automatic background operation active","Automatischer Logout nach Inaktivität":"Automatic logout after inactivity","Automatisches Schließen":"Automatic closing","Automatisches Schließen jetzt manuell ausführen?":"Run automatic closing manually now?","Automatisierung":"Automation","Automatisierung und Auto-Antworten":"Automation and auto-replies","Backup-Intervall":"Backup interval","Backup-Rotation (lokale Kopien behalten)":"Backup rotation (local copies to keep)","Backups enthalten alle Dateien inkl.":"Backups contain all files incl.","Backups liegen in":"Backups are stored in","Backups vorhanden":"Backups available","Backups werden automatisch vor jedem Update erstellt":"Backups are created automatically before every update","Backups werden nach der Erstellung automatisch per FTP übertragen.":"Backups are transferred automatically via FTP after creation.","Bald fällig":"Due soon","Bayern":"Bavaria","Beantwortet":"Answered","Beantwortete Tickets nach":"Answered tickets after","Bearbeiten":"Edit","Bearbeitung":"Processing","Bedingungen":"Conditions","Bedingungen (optional – leer = alle Tickets)":"Conditions (optional – empty = all tickets)","Beenden":"Quit","Begrüßung":"Greeting","Behoben":"Resolved","Bei einer":"For a","Bei neuen Aktualisierungen an deinen Tickets und neuen, nicht zugewiesenen Tickets.":"On new updates to your tickets and new unassigned tickets.","Bei schweren Fehlern auf der Webseite eine E-Mail senden":"Send an email on serious errors on the website","Beide leer = immer Popups. Es gilt die Zeit des Servers, auch über Mitternacht (z. B. 22:00 bis 06:00).":"Both empty = always popups. The server time applies, also past midnight (e.g. 22:00 to 06:00).","Beim Schließen im Infobereich weiterlaufen":"Keep running in the notification area when closing","Beim Öffnen automatisch zuweisen (ein noch nicht zugewiesenes Ticket geht an den Mitarbeiter, der es öffnet)":"Assign automatically on open (an unassigned ticket goes to the staff member who opens it)","Beliebig":"Any","Beliebte Artikel":"Popular articles","Benachr.":"Notif.","Benachrichtigung bei Ticketzuweisung deaktivieren":"Disable notification on ticket assignment","Benachrichtigungen":"Notifications","Benannte Zeiten je Abteilung oder Thema":"Named times per department or topic","Benutzerdefiniert":"Custom","Benutzerdefinierte Berechtigungssets für Mitarbeiter. Ohne Rolle gelten die Standard-Mitarbeiterrechte.":"Custom permission sets for staff. Without a role, the default staff permissions apply.","Benutzerdefinierte Listen":"Custom lists","Benutzername":"Username","Benutzername (leer = E-Mail-Adresse)":"Username (empty = email address)","Benutzername / E-Mail":"Username / email","Beobachter":"Watchers","Beobachter und Cc":"Watchers and Cc","Beobachtetes Ticket aktualisiert":"Watched ticket updated","Berechtigungen":"Permissions","Berechtigungssets":"Permission sets","Bereich":"Area","Bereich „Beliebte Artikel“ auf der Startseite anzeigen":"Show the \"Popular articles\" section on the home page","Bereits registriert?":"Already registered?","Bericht erstellen":"Create report","Bericht gespeichert":"Report saved","Bericht löschen?":"Delete report?","Bericht speichern":"Save report","Bericht-Baukasten":"Report builder","Berichte":"Reports","Berichte ansehen":"View reports","Berichte einsehen":"View reports","Berichtszeitraum":"Reporting period","Beschreiben Sie Ihr Anliegen so detailliert wie möglich…":"Describe your request in as much detail as possible…","Beschreiben Sie Ihr Anliegen so genau wie möglich – das hilft uns, schneller zu helfen.":"Describe your request as precisely as possible – it helps us help you faster.","Beschreibung":"Description","Beschreibung (optional)":"Description (optional)","Beschriftung im Footer":"Footer label","Beschädigte Sitzungsdaten konnten nicht entfernt werden.":"Corrupted session data could not be removed.","Beschäftigt":"Busy","Bestätigen":"Confirm","Betreff":"Subject","Betreff & letzte Nachricht":"Subject & last message","Betreff und Kundenname in der Benachrichtigung anzeigen":"Show subject and customer name in the notification","Betreff · Ticket-Nr. · Kundenname · E-Mail":"Subject · ticket no. · customer name · email","Betrifft":"Affects","Betrifft: {}":"Affects: {}","Bewertet am":"Rated on","Bewertet am {}":"Rated on {}","Bezeichnung":"Label","Bezeichnung (z. B. Neujahr)":"Label (e.g. New Year)","Bild aus der Signatur":"Image from signature","Bild wird hochgeladen …":"Uploading image …","Bis":"To","Bis (HH:MM)":"Until (HH:MM)","Bis (JJJJ-MM-TT)":"Until (YYYY-MM-DD)","Bitte Authenticator-Code eingeben.":"Please enter the authenticator code.","Bitte Benachrichtigungen im Browser erlauben.":"Please allow notifications in the browser.","Bitte eine Datei auswaehlen.":"Please select a file.","Bitte eine Ziel-Abteilung wählen.":"Please choose a target department.","Bitte einen Zeitpunkt in der Zukunft wählen.":"Please choose a point in time in the future.","Bitte in der App anmelden.":"Please sign in in the app.","Bitte in der App neu anmelden.":"Please sign in again in the app.","Bitte mindestens ein Ticket markieren.":"Please select at least one ticket.","Bitte schildern Sie uns so viele Details wie möglich, damit wir Ihnen bestmöglich helfen können.":"Please give us as many details as possible so we can help you in the best way.","Bitte warten …":"Please wait …","Browser-Push-Benachrichtigungen":"Browser push notifications","Buchhaltung":"Accounting","Bundesland":"Federal state","Bündeln Sie mehrere Kundenkonten unter einer Firma/Organisation. Kontakte werden unter „Kunden“ zugeordnet.":"Group several customer accounts under one company/organization. Contacts are assigned under \"Customers\".","CSV exportieren":"Export CSV","Cc entfernen":"Remove Cc","Cc hinzufügen":"Add Cc","Cc hinzugefügt":"Cc added","Cc-Adresse hinzufügen":"Add Cc address","Cc-Empfänger":"Cc recipients","Chat auswählen":"Choose chat","Chat beenden":"End chat","Chat beenden?":"End chat?","Chat starten":"Start chat","Chat wird geladen …":"Loading chat …","Chat wirklich beenden?":"Really end chat?","Chats werden geladen …":"Loading chats …","Chatverlauf (an Kunde, nach Chatende)":"Chat transcript (to customer, after chat ends)","Chatverlauf per E-Mail an den Kunden senden, sobald ein Mitarbeiter den Chat beendet":"Send the chat transcript to the customer by email as soon as a staff member ends the chat","Checkbox (Ja/Nein)":"Checkbox (yes/no)","Copyright © {} – Alle Rechte vorbehalten.":"Copyright © {} – All rights reserved.","Cron-Job einrichten:":"Set up cron job:","Cron-Jobs":"Cron jobs","Cron-Status":"Cron status","Crontab-Eintrag":"Crontab entry","Crontab-Zeilen anzeigen":"Show crontab lines","Da gerade niemand direkt verfügbar ist, antworten wir Ihnen per E-Mail, sobald wir Ihre Anfrage bearbeitet haben.":"Nobody is available right now, so we will reply by email as soon as we have looked into your request.","Dann …":"Then …","Darf Tickets anlegen":"May create tickets","Darf Ticketstatus lesen (mit Ticketnummer + E-Mail des Anfragenden)":"May read ticket status (with ticket number + requester's email)","Darstellung":"Appearance","Das Ticket verschwindet aus den Listen und kommt zum gewählten Zeitpunkt zurück, mit Benachrichtigung. Antwortet der Kunde früher, kommt es sofort zurück.":"The ticket disappears from the lists and comes back at the chosen time, with a notification. If the customer replies earlier, it comes back immediately.","Das Ticket wird angelegt und gleich geschlossen. Es gibt keine Benachrichtigung an Mitarbeiter oder Kunden.":"The ticket is created and closed immediately. Neither staff nor customers are notified.","Das Token hat kein Ablaufdatum.":"The token has no expiry date.","Das gesamte Fragen-Log löschen?":"Delete the entire question log?","Das gesamte Fragen-Log wird gelöscht.":"The entire question log will be deleted.","Das sind deutsche Texte, die der Sammelmodus gesehen hat. Sie bilden die Vorlage für ein neues Sprachpaket.":"These are the German texts the collection mode has seen. They form the template for a new language pack.","Datei auf dem Handy herunterladen und öffnen.":"Download the file on your phone and open it.","Datei auswählen":"Choose file","Datei herunterladen und starten.":"Download the file and run it.","Datei per FTP in den Ordner":"Upload the file via FTP into the folder","Datenanonymisierung":"Data anonymization","Datenanonymisierung jetzt manuell ausführen?":"Run data anonymization manually now?","Datenbank":"Database","Datenschutz":"Privacy","Datenschutz & Impressum":"Privacy & legal notice","Datum":"Date","Datum (JJJJ-MM-TT)":"Date (YYYY-MM-DD)","Dazu passend":"Related","Deaktivieren":"Deactivate","Deaktiviert":"Disabled","Der Agent ist Mitglied in folgenden Teams.":"The agent is a member of the following teams.","Der Assistent beantwortet Fragen von Kunden aus der Wissensdatenbank und aus den zusätzlichen Antworten. Findet er nichts, bietet er ein Ticket an. Es wird kein externer KI-Dienst verwendet.":"The assistant answers customer questions from the knowledge base and the additional answers. If it finds nothing, it offers a ticket. No external AI service is used.","Der Assistent beantwortet Fragen von Kunden aus der Wissensdatenbank und den zusätzlichen Antworten. Findet er nichts, bietet er ein Ticket an. Es wird kein externer KI-Dienst verwendet.":"The assistant answers customer questions from the knowledge base and the additional answers. If it finds nothing, it offers a ticket. No external AI service is used.","Der Branding-Rahmen (Kopf-/Fußzeile) wird beim Versand automatisch ergänzt – hier nur den Inhalt anpassen.":"The branding frame (header/footer) is added automatically when sending – only adjust the content here.","Der Katalog konnte nicht geladen werden: SSL certificate problem: unable to get local issuer certificate":"The catalog could not be loaded: SSL certificate problem: unable to get local issuer certificate","Der Ordner install/ existiert ohne Sperrdatei. Löschen Sie den Ordner install/ vom Server.":"The install/ folder exists without a lock file. Delete the install/ folder from the server.","Der Server hat keine Antwort geliefert.":"The server did not return a response.","Design wechseln":"Switch design","DeskHub Desktop {} · Rechte und Daten kommen vom Server – genau wie in der Android-App.":"DeskHub Desktop {} · Permissions and data come from the server – just like in the Android app.","DeskHub Ticketsystem":"DeskHub ticket system","Deutsch":"German","Die":"The","Die Aktion ist fehlgeschlagen.":"The action failed.","Die Anmeldung lieferte kein Mitarbeiterprofil.":"The sign-in returned no staff profile.","Die Anmeldung lieferte kein Token.":"The sign-in returned no token.","Die Datenbank ist noch nicht aktuell. Bitte im Adminportal unter System-Update „Datenbank aktualisieren“ klicken.":"The database is not up to date yet. Please click \"Update database\" in the admin portal under System update.","Die Liste der Versionen konnte nicht geladen werden: API HTTP 0":"The list of versions could not be loaded: API HTTP 0","Die Seite konnte nicht geöffnet werden.":"The page could not be opened.","Die Server-Adresse ist ungültig.":"The server address is invalid.","Die Server-Adresse muss HTTPS verwenden.":"The server address must use HTTPS.","Die Serverantwort ist ungültig.":"The server response is invalid.","Die angeforderte Seite existiert nicht.":"The requested page does not exist.","Die geschützte Anmeldung konnte nicht gelesen werden und wurde entfernt.":"The protected sign-in could not be read and was removed.","Die geschützte Anmeldung konnte nicht gespeichert werden.":"The protected sign-in could not be saved.","Die lokale Anmeldung konnte nicht entfernt werden.":"The local sign-in could not be removed.","Die meistgelesenen Antworten aus unserer Wissensdatenbank.":"The most-read answers from our knowledge base.","Dienst entfernen?":"Remove service?","Dienst setzen auf":"Set service to","Dienstag":"Tuesday","Dienste":"Services","Dienste und Störungen für Kunden":"Services and incidents for customers","Dienste und Störungsmeldungen für Kunden":"Services and incident messages for customers","Diese Adresse gebt ihr beim ersten Start der App ein, danach meldet ihr euch mit eurem Mitarbeiter-Konto an.":"You enter this address when you first start the app, then sign in with your staff account.","Diese Antworten haben Vorrang vor der Wissensdatenbank. Der Assistent findet sie über die Wörter in der Frage und in den Stichwörtern.":"These answers take precedence over the knowledge base. The assistant finds them through the words in the question and in the keywords.","Diesen Bericht speichern":"Save this report","Dieser Abteilung sind noch keine Mitarbeiter zugewiesen. Die Zuweisung erfolgt unter „Mitarbeiter“.":"No staff members are assigned to this department yet. Assignment is done under \"Staff\".","Dieser Bewertungslink ist ungültig oder abgelaufen.":"This rating link is invalid or has expired.","Dieser Chat wird gerade von „{}“ bearbeitet – nur Ansicht.":"This chat is currently being handled by \"{}\" – view only.","Dieser Chat wurde beendet.":"This chat has ended.","Dieser Monat":"This month","Dieses Jahr":"This year","Dieses Ticket":"This ticket","Dieses Ticket wurde nicht gefunden.":"This ticket was not found.","Digitalen Assistenten einschalten":"Enable digital assistant","Digitaler Assistent":"Digital assistant","Dir fehlt das Recht „Tickets erstellen“.":"You lack the \"Create tickets\" permission.","Dir zugewiesen":"Assigned to you","Discord Webhook-URL":"Discord webhook URL","Domain (ganzer Mailanbieter)":"Domain (whole mail provider)","Domain, z.B. spam.de":"Domain, e.g. spam.com","Donnerstag":"Thursday","Dringend":"Urgent","Dropdown-Auswahl":"Dropdown selection","Druckdatum: 24.10.2026 19:44":"Print date: 24.10.2026 19:44","Druckdatum: {}":"Print date: {}","Du beobachtest das Ticket jetzt":"You are now watching the ticket","Du beobachtest das Ticket nicht mehr":"You are no longer watching the ticket","Dunkel":"Dark","E-Mail":"Email","E-Mail (optional)":"Email (optional)","E-Mail / Domain":"Email / domain","E-Mail des Kunden (optional)":"Customer email (optional)","E-Mail, z.B. spam@beispiel.de":"Email, e.g. spam@example.com","E-Mail-Abruf":"Email fetching","E-Mail-Abruf (IMAP)":"Email fetching (IMAP)","E-Mail-Abruf jetzt manuell ausführen?":"Run email fetching manually now?","E-Mail-Adresse":"Email address","E-Mail-Adresse *":"Email address *","E-Mail-Adresse bearbeiten":"Edit email address","E-Mail-Adresse oder Passwort ist falsch.":"Email address or password is incorrect.","E-Mail-Adresse wirklich löschen?":"Really delete this email address?","E-Mail-Adressen":"Email addresses","E-Mail-Adressen verwalten":"Manage email addresses","E-Mail-Adressen werden geladen …":"Loading email addresses …","E-Mail-Versand aktiv (PHP mail() Fallback)":"Email sending active (PHP mail() fallback)","E-Mail-Vorlagen":"Email templates","E-Mail-Vorlagen verwalten":"Manage email templates","E-Mails / Domains":"Emails / domains","Echter Server-Cronjob":"Real server cron job","Eigene Inhaltsseiten für das Kundenportal (z. B. Impressum, Datenschutz, Willkommen). Erreichbar unter":"Custom content pages for the customer portal (e.g. legal notice, privacy, welcome). Available at","Eigene Kundenportal-Themes":"Custom customer portal themes","Eigene Sprache als Plugin erstellen":"Create your own language as a plugin","Eigenen SMTP-Server für diese Adresse verwenden":"Use own SMTP server for this address","Eigenen SMTP-Server verwenden":"Use own SMTP server","Eigener SMTP":"Own SMTP","Eigenes Plugin hochladen":"Upload your own plugin","Eigenschaften":"Properties","Ein von dir gesetzter Status bleibt, bis der Mitarbeiter ihn selbst ändert oder du ihn erneut änderst.":"A status you set stays until the staff member changes it or you change it again.","Eine Adresse pro Zeile, optional mit Anzeigename nach einem Komma (z. B.":"One address per line, optionally with a display name after a comma (e.g.","Eine Bedingung":"One condition","Eine E-Mail oder Domain pro Zeile (oder kommagetrennt). Typ wird automatisch erkannt.":"One email or domain per line (or comma-separated). The type is detected automatically.","Eine E-Mail oder Domain pro Zeile. Typ wird automatisch erkannt.":"One email or domain per line. The type is detected automatically.","Eingang":"Inbox","Eingangsbestätigung per E-Mail an Kunden senden (nur wenn E-Mail angegeben)":"Send an acknowledgement of receipt to the customer by email (only if an email address was given)","Eingangsbestätigung per E-Mail senden":"Send acknowledgement of receipt by email","Eingeschränkt":"Degraded","Einstellungen":"Settings","Einstellungen bei neuem Ticket":"Settings for new tickets","Einstellungen konnten nicht geladen werden (hat der Server die neueste Version?).":"Settings could not be loaded (does the server have the latest version?).","Einträge":"Entries","Einzeiliger Text":"Single-line text","Einzeln":"Individually","Einzeln sperren":"Block individually","Empfänger (leer = Administratoren), mehrere mit Komma":"Recipients (empty = administrators), several separated by comma","Entfernen":"Remove","Entferntes Postfach":"Remote mailbox","Entferntes Postfach (Abruf per IMAP)":"Remote mailbox (fetch via IMAP)","Entsperren":"Unblock","Entwurf":"Draft","Entwürfe gelöscht":"Drafts deleted","Er bleibt als Ticket erhalten, verschwindet aber aus den aktiven Live-Chats.":"It remains as a ticket but disappears from the active live chats.","Ereignisse":"Events","Erfasste Arbeitszeiten":"Recorded working times","Ergebnis":"Result","Erhalten eine Kopie jeder öffentlichen Antwort per E-Mail.":"Receive a copy of every public reply by email.","Erinnerung (an Kunde, wenn er nicht reagiert)":"Reminder (to customer, if they do not respond)","Erlaubte Datei-Endungen":"Allowed file extensions","Erlaubte Dateitypen":"Allowed file types","Erlaubte IP-Adressen (optional)":"Allowed IP addresses (optional)","Erlaubte IPs":"Allowed IPs","Erledigt":"Done","Erneut":"Again","Erneut versuchen":"Try again","Ersetzt die Zeiten der Priorität für Tickets, deren Hilfethema oder Abteilung diesen Plan nutzt (Hilfethema vor Abteilung).":"Replaces the priority's times for tickets whose help topic or department uses this plan (help topic before department).","Erste Schritte":"Getting started","Erstellen":"Create","Erstellen Sie ein Kundenkonto, um Tickets zu verfolgen.":"Create a customer account to track your tickets.","Erstellen Sie unter Backup eines und prüfen Sie es.":"Create one under Backup and check it.","Erstellt":"Created","Erstellt:":"Created:","Erstreaktion":"First response","Erwartete Prüfsumme (SHA-256, optional)":"Expected checksum (SHA-256, optional)","Erweiterter Zugriff":"Extended access","Erwähnungen":"Mentions","Es sind noch keine Teams angelegt.":"No teams have been created yet.","Es sind noch keine Teams angelegt. Teams legst du unter":"No teams have been created yet. You create teams under","Es wird keine Signatur angehängt.":"No signature will be attached.","Eskalationsregeln":"Escalation rules","Eskalationsregeln jetzt manuell ausführen?":"Run escalation rules manually now?","Eskalationsregeln verwalten":"Manage escalation rules","Eskalationsregeln werden stündlich per Cron geprüft (":"Escalation rules are checked hourly via cron (","Exportieren (CSV)":"Export (CSV)","Externer Link":"External link","Externer Link (optional)":"External link (optional)","FTP speichern":"Save FTP","FTP-Host":"FTP host","FTP-Rotation (Kopien auf Server)":"FTP rotation (copies on server)","Falls Windows warnt („Der Computer wurde geschützt“):":"If Windows warns (\"Windows protected your PC\"):","Farbe (#RRGGBB)":"Color (#RRGGBB)","Favicon (Symbol im Browser-Tab)":"Favicon (icon in the browser tab)","Fehler:":"Error:","Feiertag hinzufügen":"Add holiday","Feiertage":"Holidays","Feiertage (0)":"Holidays (0)","Feiertage / Schließtage":"Holidays / closing days","Feiertage automatisch übernehmen":"Import holidays automatically","Feld":"Field","Feldtyp":"Field type","Fenster schließen":"Close window","Fertig":"Done","Fertige Designs direkt installieren. Prüfsumme und Signatur werden vor der Installation geprüft.":"Install ready-made designs directly. Checksum and signature are verified before installation.","Filter in der":"Filter in the","Filter zurücksetzen":"Reset filters","Filtern":"Filter","Firmenlogo":"Company logo","Formular":"Form","Frage":"Question","Frage / Thema":"Question / topic","Frage / Thema *":"Question / topic *","Frage ausprobieren":"Try a question","Fragen-Log":"Question log","Fragen-Log geleert":"Question log cleared","Fragen-Log leeren?":"Clear question log?","Fragen-Log: Aufbewahrung in Tagen (0 = nichts speichern)":"Question log: retention in days (0 = store nothing)","Frei konfigurierbare Auswertungen nach Erstellungsdatum der Tickets":"Freely configurable reports by ticket creation date","Freitag":"Friday","Fällig":"Due","Fällig bis":"Due until","Fällig bis (JJJJ-MM-TT HH:MM, optional)":"Due until (YYYY-MM-DD HH:MM, optional)","Für Kunden sichtbar (auf „Neues Ticket“)":"Visible to customers (on \"New ticket\")","Für alle Abteilungen":"For all departments","Für alle Mitarbeiter sichtbar":"Visible to all staff","Für automatische Backups den Cron einrichten:":"Set up cron for automatic backups:","Für dich":"For you","Gast":"Guest","Gast-Kunde":"Guest customer","Gast-Ticket zum Konto hinzufügen":"Add guest ticket to your account","Gedruckt: 24.10.2026 19:44":"Printed: 24.10.2026 19:44","Gedruckt: {}":"Printed: {}","Gefährliche Typen (PHP, EXE, SH etc.) werden immer blockiert – unabhängig von dieser Liste.":"Dangerous types (PHP, EXE, SH etc.) are always blocked – regardless of this list.","Gelöscht":"Deleted","Gelöst":"Resolved","Gelöst diesen Monat":"Resolved this month","Gelöst/Geschlossen":"Resolved/Closed","Genutzt":"Used","Geprüfte Plugins":"Verified plugins","Gerade ist niemand verfügbar – wir antworten aber, sobald wir wieder da sind.":"Nobody is available right now – we will reply as soon as we are back.","Gesammelte Texte löschen?":"Delete collected texts?","Gesammelte Texte: 556":"Collected texts: 556","Gesammelte Texte: {#}":"Collected texts: {}","Gesamt":"Total","Gesamt: {} Minuten":"Total: {} minutes","Gesamter Zeitraum":"Entire period","Gesamtgröße":"Total size","Geschlossen":"Closed","Geschäftszeiten":"Business hours","Geschäftszeiten für SLA-Berechnung verwenden":"Use business hours for SLA calculation","Geschäftszeiten verwalten":"Manage business hours","Geschäftszeiten werden geladen …":"Loading business hours …","Gespeichert":"Saved","Gespeichert ({} Gruppen)":"Saved ({} groups)","Gespeichert werden: assigned":"Saved: assigned","Gespeichert werden: keine Filter (alle Tickets)":"Saved: no filters (all tickets)","Gespeichert werden: status":"Saved: status","Gespeichert.":"Saved.","Gespeicherte Ansichten":"Saved views","Gespeicherte Berichte":"Saved reports","Gespeicherte Entwürfe löschen":"Delete saved drafts","Gespeicherte Zugangsdaten (SMTP, IMAP, Webhooks) sind mit einem eigenen Schlüssel verschlüsselt.":"Stored credentials (SMTP, IMAP, webhooks) are encrypted with a separate key.","Gesperrt":"Blocked","Gesperrt am":"Blocked on","Gesperrte Einträge (0)":"Blocked entries (0)","Geteilt von {}":"Shared by {}","Geöffnet":"Opened","Gilt für Hilfe-Thema":"Applies to help topic","Gilt für Tickets aus Formular, E-Mail, API und Live-Chat. Eine Ticket-Regel mit „Mitarbeiter zuweisen“ hat Vorrang. Im Urlaub bekommt die Vertretung das Ticket, „Reihum“ überspringt Mitarbeiter im Urlaub oder offline.":"Applies to tickets from the form, email, API and live chat. A ticket rule with \"Assign staff member\" takes precedence. On vacation, the substitute gets the ticket; \"Round robin\" skips staff on vacation or offline.","Gleichbedeutende Wörter":"Synonyms","Gleichbedeutende Wörter gespeichert":"Synonyms saved","Grund":"Reason","Grund (optional)":"Reason (optional)","Grund für alle (optional)":"Reason for all (optional)","Gruppe":"Group","Gruppieren nach":"Group by","Guten Abend":"Good evening","Guten Abend, {}":"Good evening, {}","Guten Morgen":"Good morning","Guten Morgen, {}":"Good morning, {}","Guten Tag":"Hello","Guten Tag, {}":"Hello, {}","HTML-Inhalt (Popup)":"HTML content (popup)","HTML-Inhalt (öffnet Popup). Ist ein Link gesetzt, wird das HTML-Feld ignoriert.":"HTML content (opens popup). If a link is set, the HTML field is ignored.","Handlungsbedarf ·":"Action needed ·","Hauptabteilung":"Main department","Hauptrolle":"Main role","Hell":"Light","Helpdesk-Status":"Helpdesk status","Herkunft":"Origin","Hessen":"Hesse","Heute":"Today","Heute gelöst":"Resolved today","Hier finden Sie das Archiv und den Verlauf Ihrer aktuellen und vorherigen Supportanfragen inklusive der Antworten.":"Here you can find the archive and history of your current and previous support requests, including the replies.","Hier finden Sie den Verlauf und Status Ihrer aktuellen und bisherigen Supportanfragen.":"Here you can find the history and status of your current and previous support requests.","Hier ist noch keine Android-App hinterlegt.":"No Android app has been stored here yet.","Hier ist noch keine Windows-App hinterlegt.":"No Windows app has been stored here yet.","Hier könnt ihr eigene Plugins als ZIP installieren oder aktualisieren, auch ohne Signatur. Diese Plugins sind":"Here you can install or update your own plugins as ZIP, even without a signature. These plugins are","Hilfe-Thema":"Help topic","Hilfe-Thema (optional)":"Help topic (optional)","Hilfe-Thema setzen":"Set help topic","Hilfe-Themen":"Help topics","Hilfe-Themen verwalten":"Manage help topics","Hilfethema":"Help topic","Hilfethema aktualisieren":"Update help topic","Hilfethema wirklich löschen?":"Really delete this help topic?","Hilfethemen":"Help topics","Hilfethemen werden geladen …":"Loading help topics …","Hilfethemeninformationen":"Help topic information","Hintergrundbild im dunklen Hero-Bereich. Mind. 1600×500 px, max. 5 MB.":"Background image in the dark hero area. At least 1600×500 px, max. 5 MB.","Hinweis für Administratoren: Zum Aktualisieren einer App die neue Datei per FTP in":"Note for administrators: to update an app, upload the new file via FTP to","Hinweis:":"Note:","Hinweise":"Notes","Hinweise ·":"Notes ·","Hinweistext (optional)":"Note text (optional)","Hinzufügen":"Add","Hoch":"High","Hochladen":"Upload","Hochladen & installieren":"Upload & install","Hochladen →":"Upload →","Hohe Priorität":"High priority","Häufige Fragen":"Frequently asked questions","Häufige Fragen ohne Antwort":"Frequent questions without an answer","IP-Adresse":"IP address","IP-Adressen sofort beim Speichern kürzen (letztes Oktett entfernen)":"Shorten IP addresses immediately when saving (remove last octet)","Ich wurde erwähnt":"I was mentioned","Ihr Anliegen":"Your request","Ihr Name":"Your name","Ihre Bewertung – {}":"Your rating – {}","Ihre E-Mail-Adresse":"Your email address","Ihre Kontaktdaten":"Your contact details","Ihre Nachricht...":"Your message...","Ihre Nachricht…":"Your message…","Im Browser öffnen: zusammenführen, aufteilen, drucken":"Open in browser: merge, split, print","Im Zeitraum wurden noch keine Abfragen verschickt.":"No surveys were sent in this period.","Immer (zum Testen)":"Always (for testing)","Immer an einen bestimmten Mitarbeiter":"Always to a specific staff member","Impressum":"Legal notice","In 1 Stunde":"In 1 hour","In 1 Woche":"In 1 week","In 3 Stunden":"In 3 hours","In 3 Tagen":"In 3 days","In Arbeit":"In progress","In Betrieb":"Operational","In Ordner verschieben":"Move to folder","In der Datei":"In the file","Inaktiv":"Inactive","Individuelle Berechtigungen":"Individual permissions","Individuelle Ticket-Felder":"Custom ticket fields","Informationen":"Information","Inhalt":"Content","Inhalt / Zusammenfassung":"Content / summary","Installierte Sprachen":"Installed languages","Installierte Version":"Installed version","Intern":"Internal","Interne Notiz":"Internal note","Interne Notizen":"Internal notes","Interne Notizen (vertraulich)":"Internal notes (confidential)","Interne Notizen schreiben":"Write internal notes","Interner Chat":"Internal chat","Interner Kommentar…":"Internal comment…","Jahr":"Year","Jeder Job kann hier zusätzlich jederzeit sofort manuell gestartet werden.":"Each job can also be started manually at any time here.","Jedes Postfach wird beim Abruf (Cronjob":"Each mailbox is queried individually when fetching (cron job","Jetzt anmelden":"Sign in now","Jetzt ausführen":"Run now","Jetzt erneut versuchen":"Try again now","Jetzt registrieren":"Register now","Kanal (web/email)":"Channel (web/email)","Kanal-Einstellungen → Integrationen → Webhooks → Neuer Webhook":"Channel settings → Integrations → Webhooks → New webhook","Katalog aktualisieren":"Refresh catalog","Kategorie":"Category","Kategorie wirklich löschen?":"Really delete this category?","Kategorien":"Categories","Kein Hilfethema":"No help topic","Kein Konto nötig:":"No account needed:","Kein Kunde ausgewählt.":"No customer selected.","Kein Live-Chat ausgewählt":"No live chat selected","Kein Logo hinterlegt.":"No logo stored.","Kein Spam":"Not spam","Kein Ticket ausgewählt.":"No ticket selected.","Kein Titelbild hinterlegt.":"No cover image stored.","Kein Token eingetragen (öffentlicher Zugriff).":"No token entered (public access).","Kein Update seit X Stunden":"No update for X hours","Kein Zugriff.":"No access.","Kein eigenes Favicon hinterlegt.":"No custom favicon stored.","Keine":"None","Keine Aktualisierung seit …":"No update since …","Keine Antwort seit …":"No reply since …","Keine Aufgaben gefunden.":"No tasks found.","Keine Aufgaben.":"No tasks.","Keine Berechtigungen":"No permissions","Keine Daten verfügbar.":"No data available.","Keine Einträge.":"No entries.","Keine Erwähnungen vorhanden.":"No mentions.","Keine Kunden gefunden.":"No customers found.","Keine Meldungen.":"No messages.","Keine Mitarbeiter gefunden.":"No staff found.","Keine Mitarbeiter-Antwort seit X Stunden":"No staff reply for X hours","Keine Signatur":"No signature","Keine Signatur hinterlegt.":"No signature stored.","Keine Störungen in den letzten 14 Tagen.":"No incidents in the last 14 days.","Keine Tickets gefunden.":"No tickets found.","Keine Tickets im gewählten Zeitraum.":"No tickets in the selected period.","Keine Tickets mit diesen Filtern. Unter „Aktiv“ kannst du „Alle Status“ wählen, um auch erledigte Tickets zu sehen.":"No tickets with these filters. Under \"Active\" you can choose \"All statuses\" to also see completed tickets.","Keine Tickets vorhanden.":"No tickets available.","Keine Treffer für diese Suche.":"No results for this search.","Keine Treffer.":"No results.","Keine Verbindung zum Server – nächster Versuch in {} s. Bereits geladene Daten sind eventuell veraltet.":"No connection to the server – next attempt in {} s. Data already loaded may be outdated.","Keine Verbindung zum Server.":"No connection to the server.","Keine Verbindung zum Server. Es wird automatisch erneut versucht.":"No connection to the server. It will be retried automatically.","Keine Zeiteinträge im gewählten Zeitraum.":"No time entries in the selected period.","Keine aktive DeskHub-Sitzung.":"No active DeskHub session.","Keine aktiven Chats":"No active chats","Keine lokale Anmeldung vorhanden.":"No local sign-in available.","Keine passende Antwort: Der Assistent würde anbieten, ein Ticket zu erstellen. Lege dafür eine zusätzliche Antwort an oder ergänze die Wissensdatenbank.":"No matching answer: the assistant would offer to create a ticket. Create an additional answer for it or extend the knowledge base.","Keine vorhanden.":"None available.","Keine weitere Einstellung nötig.":"No further setting needed.","Keine weiteren Mitarbeiter vorhanden.":"No more staff available.","Keine weiteren Tickets.":"No more tickets.","Kennzahlen":"Key figures","Klicke rechts auf einen Mitarbeiter":"Click a staff member on the right","Kollaboratoren":"Collaborators","Kollegen auswählen":"Select colleagues","Kommentieren":"Comment","Konfiguration":"Configuration","Kontaktdaten":"Contact details","Kontakte":"Contacts","Kontakte werden geladen …":"Loading contacts …","Konten und Zugriff":"Accounts and access","Konten, Rollen, Abteilungszugriff":"Accounts, roles, department access","Konto":"Account","Konto erstellen":"Create account","Konto erstellen – {}":"Create account – {}","Kontodaten":"Account details","Kontoinformationen":"Account information","Kontotyp":"Account type","Kopieren":"Copy","Kostenloses Konto erstellen":"Create a free account","Kunde":"Customer","Kunde nicht gefunden.":"Customer not found.","Kunde tippt …":"Customer is typing …","Kunden":"Customers","Kunden erinnern, wenn sie auf eine Antwort nicht reagieren (einmalig, vor dem automatischen Schließen)":"Remind customers if they do not respond to a reply (once, before automatic closing)","Kunden per E-Mail benachrichtigen":"Notify customers by email","Kunden werden geladen …":"Loading customers …","Kunden zu Firmen bündeln":"Group customers into companies","Kunden-Organisationen":"Customer organizations","Kundendaten":"Customer data","Kundenerinnerung":"Customer reminder","Kundenerinnerung jetzt manuell ausführen?":"Run customer reminder manually now?","Kundenprofil":"Customer profile","Kundenprofil wird geladen …":"Loading customer profile …","Kundenprofil: {}":"Customer profile: {}","Kundenverzeichnis":"Customer directory","Kundenzufriedenheit":"Customer satisfaction","Kundenzufriedenheit (letzte 30 Tage)":"Customer satisfaction (last 30 days)","Kundenzufriedenheit ({} Tage)":"Customer satisfaction ({} days)","Kurzbeschreibung (optional)":"Short description (optional)","Kurze Zusammenfassung Ihres Problems":"Short summary of your problem","Lade …":"Loading …","Lade…":"Loading…","Leere Vorlage laden":"Load empty template","Legen Sie fest, welche zusätzlichen Bereiche auf der Kundenportal-Startseite angezeigt werden.":"Choose which additional sections are shown on the customer portal home page.","Leiter, Mitglieder, E-Mail":"Lead, members, email","Leiter: {} · {} Mitglieder":"Lead: {} · {} members","Leitung":"Lead","Leserecht":"Read permission","Letzte 30 Tage":"Last 30 days","Letzte 7 Tage":"Last 7 days","Letzte Zustellung":"Last delivery","Letzter Abruf":"Last fetch","Letzter Abruf: {}.":"Last fetch: {}.","Letztes Auto-Backup":"Last auto backup","Letztes Backup":"Last backup","Link anfordern":"Request link","Link kopieren":"Copy link","Link kopiert":"Link copied","Link nicht gültig":"Link not valid","Link-Adresse":"Link address","Live-Chat":"Live chat","Live-Chat (Kunden)":"Live chat (customers)","Live-Chat im Kundenportal (Chat-Widget unten rechts, auch ohne Kundenkonto nutzbar)":"Live chat in the customer portal (chat widget at the bottom right, also usable without a customer account)","Live-Chat ist derzeit":"Live chat is currently","Live-Chat {} · Wissensdatenbank im Portal {}":"Live chat {} · Knowledge base in the portal {}","Log geleert":"Log cleared","Log leeren":"Clear log","Lädt …":"Loading …","Löschen":"Delete","Lösen":"Resolve","Lösung":"Solution","Lösung (Std)":"Resolution (hrs)","Lösung (h)":"Resolution (h)","Lösung fällig":"Resolution due","Lösung fällig: {}":"Resolution due: {}","Lösungszeit (Std)":"Resolution time (hrs)","Lösungszeit (Std.)":"Resolution time (hrs.)","Mail senden nach":"Send email after","Manuell":"Manual","Manuelles Update":"Manual update","Markierte Tickets wirklich unwiderruflich löschen?":"Really delete the selected tickets permanently?","Maximale Dateigröße":"Maximum file size","Mecklenburg-Vorpommern":"Mecklenburg-Western Pomerania","Mehr":"More","Mehr laden":"Load more","Mehrere":"Several","Mehrere Adressen auf einmal anlegen":"Create several addresses at once","Mehrere sperren":"Block several","Mehrzeiliger Text":"Multi-line text","Mein Profil":"My profile","Mein Status":"My status","Mein Status:":"My status:","Meine":"My","Meine Ansicht":"My view","Meine Erwähnungen":"My mentions","Meine Signatur":"My signature","Meine Signatur (nicht hinterlegt)":"My signature (not set)","Meine Signatur bearbeiten":"Edit my signature","Meine Tickets":"My tickets","Meine Tickets ansehen":"View my tickets","Meine Tickets – {}":"My tickets – {}","Meine offenen":"My open","Melden Sie sich an, um alle Ihre Tickets im Überblick zu sehen.":"Sign in to see all your tickets at a glance.","Meldung gelöscht":"Message deleted","Meldung löschen":"Delete message","Meldung löschen?":"Delete message?","Meldung veröffentlicht":"Message published","Meldungen":"Messages","Meldungen (letzte 14 Tage)":"Messages (last 14 days)","Mindestens 10 Zeichen mit Groß- und Kleinbuchstaben, einer Ziffer und einem Sonderzeichen.":"At least 10 characters with upper and lower case letters, a digit and a special character.","Mindestens eine Bedingung":"At least one condition","Minuten":"Minutes","Minuten (5–480). Countdown wird oben rechts angezeigt.":"Minutes (5–480). Countdown is shown at the top right.","Minuten ohne Aktivität":"Minutes without activity","Mir zugewiesen":"Assigned to me","Mir zuweisen":"Assign to me","Mit Windows starten":"Start with Windows","Mit deinem Mitarbeiterkonto anmelden":"Sign in with your staff account","Mit den Apps bearbeitet ihr Tickets am PC oder unterwegs. Beide haben ein helles und dunkles Design.":"With the apps you work on tickets at the PC or on the go. Both have a light and a dark design.","Mitarbeiter":"Staff","Mitarbeiter (nur bei „Immer an einen bestimmten Mitarbeiter“)":"Staff member (only for \"Always to a specific staff member\")","Mitarbeiter auswählen":"Select staff member","Mitarbeiter können diese Textbausteine beim Beantworten eines Tickets per Klick in die Antwort einfügen.":"Staff can insert these text snippets into a reply with one click when answering a ticket.","Mitarbeiter löschen":"Delete staff member","Mitarbeiter tippt …":"Agent is typing …","Mitarbeiter verwalten":"Manage staff","Mitarbeiter werden geladen …":"Loading staff …","Mitarbeiter wirklich löschen?":"Really delete this staff member?","Mitarbeiter zuweisen":"Assign staff member","Mitarbeiter-Anmeldung":"Staff sign-in","Mitarbeiter-Bereich":"Staff area","Mitarbeiter-Gruppen":"Staff groups","Mitarbeiter-Login – {}":"Staff login – {}","Mitarbeiter-Login →":"Staff login →","Mitarbeiter-Verzeichnis":"Staff directory","Mitarbeiterbereich":"Staff area","Mitglied in Teams":"Member of teams","Mitglieder":"Members","Mitglieder (2)":"Members (2)","Mitglieder lassen sich nach dem Erstellen unter „Mitarbeiter“ zuweisen.":"Members can be assigned under \"Staff\" after creating.","Mitglieder: {}":"Members: {}","Mittwoch":"Wednesday","Monat":"Month","Monate":"Months","Monatlich":"Monthly","Montag":"Monday","Morgen 8:00":"Tomorrow 8:00","Morgen früh (8:00 Uhr)":"Tomorrow morning (8:00)","Nach Mitarbeiter:":"By staff member:","Nach Priorität":"By priority","Nach Status":"By status","Nach Stunden":"By hours","Nach dem Update Browser-Cache leeren":"Clear the browser cache after the update","Nach wie vielen Tagen ohne Kundenreaktion":"After how many days without customer response","Nach wie vielen Tagen ohne Reaktion":"After how many days without response","Nachricht":"Message","Nachricht eingeben...":"Enter message...","Nachricht verfassen":"Compose message","Nachricht …":"Message …","Nachricht…":"Message…","Nachricht… (Strg+Enter zum Senden)":"Message… (Ctrl+Enter to send)","Name der Ansicht":"Name of the view","Name der Vorlage":"Name of the template","Name des Assistenten":"Name of the assistant","Name des Kunden":"Customer name","Name in der Benachrichtigung (optional)":"Name in the notification (optional)","Name oder E-Mail":"Name or email","Name oder E-Mail suchen…":"Search name or email…","Nebeneinander":"Side by side","Neu":"New","Neue Abteilung":"New department","Neue Abteilung hinzufügen":"Add new department","Neue Adresse":"New address","Neue Antwort":"New reply","Neue Antwort (an Kunde)":"New reply (to customer)","Neue Aufgabe":"New task","Neue E-Mail-Adresse":"New email address","Neue Eskalationsregel":"New escalation rule","Neue Kategorie":"New category","Neue Kundenantwort":"New customer reply","Neue Liste hinzufügen":"Add new list","Neue Meldung (Störung oder Wartung)":"New message (incident or maintenance)","Neue Organisation":"New organization","Neue Priorität":"New priority","Neue Priorität hinzufügen":"Add new priority","Neue Regel":"New rule","Neue Regel hinzufügen":"Add new rule","Neue Rolle":"New role","Neue Rolle hinzufügen":"Add new role","Neue Seite hinzufügen":"Add new page","Neue Stufe":"New level","Neue Ticket-Regel":"New ticket rule","Neue Tickets automatisch zuweisen":"Assign new tickets automatically","Neue Tickets, Kundenantworten und Zuweisungen":"New tickets, customer replies and assignments","Neue Vorlage":"New template","Neuen Agenten hinzufügen":"Add new agent","Neuen Chat starten":"Start a new chat","Neuen SLA-Plan hinzufügen":"Add new SLA plan","Neuen Schlüssel erstellen":"Create new key","Neuen Webhook hinzufügen":"Add new webhook","Neuer Agent":"New agent","Neuer Artikel":"New article","Neuer Dienst, z. B. Webseite":"New service, e.g. website","Neuer Live-Chat":"New live chat","Neuer Mitarbeiter":"New staff member","Neuer SLA-Plan":"New SLA plan","Neues Bild hochladen (JPG, PNG, WEBP · max. 2 MB)":"Upload new image (JPG, PNG, WEBP · max. 2 MB)","Neues Feld":"New field","Neues Hilfethema":"New help topic","Neues Hilfethema hinzufügen":"Add new help topic","Neues Passwort":"New password","Neues Passwort (leer = unverändert)":"New password (empty = unchanged)","Neues Postfach":"New mailbox","Neues Team":"New team","Neues Team hinzufügen":"Add new team","Neues Ticket":"New ticket","Neues Ticket (an Abteilung)":"New ticket (to department)","Neues Ticket erstellen":"Create new ticket","Neues Ticket eröffnen":"Open a new ticket","Neues Ticket für diesen Kunden":"New ticket for this customer","Neues Ticket – {}":"New ticket – {}","Nicht angemeldet.":"Not signed in.","Nicht automatisch zuweisen":"Do not assign automatically","Nicht für den Produktivbetrieb geeignet. Bitte in":"Not suitable for production use. Please in","Nicht gespeichert: bitte Uhrzeiten prüfen (z. B. 22:00) oder später erneut versuchen.":"Not saved: please check the times (e.g. 22:00) or try again later.","Nicht mehr beobachten":"Stop watching","Nicht prüfbar: die eigene Adresse ließ sich nicht abrufen.":"Cannot be checked: your own address could not be fetched.","Nicht unterstützte HTTP-Methode: {}":"Unsupported HTTP method: {}","Nicht zugew.":"Unassigned","Nicht zugewiesen":"Unassigned","Niedersachsen":"Lower Saxony","Niedrig":"Low","Niemand. Beobachter bekommen Benachrichtigungen, ohne dass ihnen das Ticket zugewiesen ist.":"Nobody. Watchers receive notifications without the ticket being assigned to them.","Niemand. Cc-Empfänger bekommen die öffentlichen Antworten per E-Mail in Kopie.":"Nobody. Cc recipients receive the public replies by email in copy.","Noch kein Konto?":"No account yet?","Noch kein Postfach angelegt.":"No mailbox created yet.","Noch keine API-Schlüssel angelegt.":"No API keys created yet.","Noch keine Abfragen verschickt.":"No surveys sent yet.","Noch keine Abteilungen.":"No departments yet.","Noch keine Artikel.":"No articles yet.","Noch keine Backups vorhanden.":"No backups available yet.","Noch keine Dienste eingetragen.":"No services entered yet.","Noch keine E-Mail-Adressen angelegt.":"No email addresses created yet.","Noch keine Einträge.":"No entries yet.","Noch keine Eskalationsregeln. Erstellen Sie eine neue Regel mit dem Button oben.":"No escalation rules yet. Create a new rule with the button above.","Noch keine Eskalationsregeln. Mit + eine neue Regel anlegen.":"No escalation rules yet. Create a new rule with +.","Noch keine Feiertage eingetragen.":"No holidays entered yet.","Noch keine Hilfethemen.":"No help topics yet.","Noch keine Listen angelegt.":"No lists created yet.","Noch keine Muster angelegt.":"No patterns created yet.","Noch keine Nachrichten vorhanden.":"No messages yet.","Noch keine Nachrichten.":"No messages.","Noch keine Nachrichten. Schreib die erste!":"No messages yet. Write the first one!","Noch keine Notizen.":"No notes yet.","Noch keine Organisationen angelegt.":"No organizations created yet.","Noch keine Organisationen.":"No organizations yet.","Noch keine Plugins installiert.":"No plugins installed yet.","Noch keine Prioritäten.":"No priorities yet.","Noch keine SLA-Pläne angelegt.":"No SLA plans created yet.","Noch keine Seiten angelegt.":"No pages created yet.","Noch keine Teams angelegt.":"No teams created yet.","Noch keine Teams.":"No teams yet.","Noch keine Ticket-Regeln angelegt.":"No ticket rules created yet.","Noch keine Ticket-Regeln. Mit + eine neue Regel anlegen.":"No ticket rules yet. Create a new rule with +.","Noch keine Vorlagen.":"No templates yet.","Noch keine Webhooks angelegt.":"No webhooks created yet.","Noch keine Zeit erfasst.":"No time recorded yet.","Noch keine benutzerdefinierten Rollen angelegt.":"No custom roles created yet.","Noch keine benutzerdefinierten Rollen. Ohne eigene Rolle gelten die Standard-Agentenrechte.":"No custom roles yet. Without a role of their own, the default agent permissions apply.","Noch keine eigenen Themes hochgeladen.":"No custom themes uploaded yet.","Noch keine gespeicherten Ansichten vorhanden.":"No saved views yet.","Noch keine individuellen Felder angelegt.":"No custom fields created yet.","Noch keine zusätzlichen Antworten.":"No additional answers yet.","Noch nie":"Never","Nordrhein-Westfalen":"North Rhine-Westphalia","Normale Tickets":"Normal tickets","Notiz":"Note","Notiz (optional)":"Note (optional)","Notiz (optional, z.B. «In Besprechung bis 14:00»)":"Note (optional, e.g. \"In a meeting until 14:00\")","Notiz gespeichert":"Note saved","Notiz hinzufügen…":"Add note…","Notiz speichern":"Save note","Notizen":"Notes","Notizen (optional)":"Notes (optional)","Nr.":"No.","Nummer kopieren":"Copy number","Nummer kopiert":"Number copied","Nur Abteilung":"Department only","Nur Administratoren dürfen die Statusseite ändern.":"Only administrators may change the status page.","Nur Bereiche, für die du freigeschaltet bist.":"Only areas you are authorized for.","Nur Lesezugriff, solange {} diesen Chat bearbeitet.":"Read-only while {} is handling this chat.","Nur Priorität":"Priority only","Nur Status (kommagetrennt, z.B. open,pending)":"Only status (comma-separated, e.g. open,pending)","Nur ausfüllen, wenn der Anbieter eine Prüfsumme nennt":"Only fill in if the provider states a checksum","Nur ausfüllen, wenn der Anbieter eine Signatur nennt":"Only fill in if the provider states a signature","Nur benachrichtigen":"Notify only","Nur in der installierten Version verfügbar.":"Only available in the installed version.","Nur interne Notiz speichern":"Save internal note only","Nur nötig, wenn das Repository mit den Releases":"Only needed if the repository with the releases","Nur signierte Releases:":"Signed releases only:","Nur wenn der Live-Chat aus oder niemand erreichbar ist (Standard)":"Only if live chat is off or nobody can be reached (default)","Nur wenn der Live-Chat ausgeschaltet oder niemand erreichbar ist (Standard)":"Only if live chat is switched off or nobody can be reached (default)","Offen":"Open","Offene Tickets":"Open tickets","Offline (Wartungsmodus)":"Offline (maintenance mode)","Offline-Nachricht":"Offline message","Ohne Konto: Geben Sie Ihre Ticketnummer und E-Mail-Adresse ein.":"Without an account: enter your ticket number and email address.","Ohne eigenen Server wird der globale SMTP aus den Einstellungen genutzt.":"Without its own server the global SMTP from the settings is used.","Online Mitarbeiter":"Staff online","Option 1: Datei in den DeskHub-Ordner legen (für große Dateien empfohlen)":"Option 1: put the file in the DeskHub folder (recommended for large files)","Option 2: Direkt hochladen (in Teilen von 5 MB, passend zum Limit dieses Servers)":"Option 2: upload directly (in 5 MB parts, matching this server's limit)","Optionale Felder beim Anlegen:":"Optional fields when creating:","Optionen":"Options","Optionen (eine pro Zeile)":"Options (one per line)","Optionen bei neuem Ticket":"Options for new tickets","Ordner":"Folder","Ordner mit diesen Dateien packen:":"Pack the folder with these files:","Organisation":"Organization","Organisation bearbeiten":"Edit organization","Organisationen":"Organizations","Organisationen verwalten":"Manage organizations","Organisationen werden geladen …":"Loading organizations …","Passwort":"Password","Passwort (leer = unverändert)":"Password (empty = unchanged)","Passwort *":"Password *","Passwort eingeben":"Enter password","Passwort vergessen":"Forgot password","Passwort vergessen – {}":"Forgot password – {}","Passwort vergessen?":"Forgot your password?","Passwort wiederholen":"Repeat password","Passwort ändern":"Change password","Pause":"Break","Pausiert":"Paused","Pflichtfeld":"Required field","Pflichtfelder sind mit":"Required fields are marked with","Platzhalter:":"Placeholders:","Plugins (Hintergrundaufgaben)":"Plugins (background tasks)","Plugins (Hintergrundaufgaben) jetzt manuell ausführen?":"Run plugins (background tasks) manually now?","Popups und stille Zeiten":"Popups and quiet hours","Postfach":"Mailbox","Postfach / Ordner":"Mailbox / folder","Postfach testen":"Test mailbox","Postfächer (E-Mail-Abruf)":"Mailboxes (email fetching)","Postfächer für den E-Mail-Abruf":"Mailboxes for email fetching","Postfächer verwalten →":"Manage mailboxes →","Postfächer werden jetzt direkt bei der jeweiligen":"Mailboxes are now fetched directly at the respective","Priorisiert: mir zugewiesen oder unbearbeitet":"Prioritized: assigned to me or unprocessed","Priorität":"Priority","Priorität bearbeiten":"Edit priority","Priorität für Tickets des Assistenten":"Priority for assistant tickets","Priorität setzen":"Set priority","Priorität wirklich löschen?":"Really delete this priority?","Priorität:":"Priority:","Prioritäten & SLA-Zeiten":"Priorities & SLA times","Prioritäten / SLA":"Priorities / SLA","Prioritäten / SLA verwalten":"Manage priorities / SLA","Prioritäten werden geladen …":"Loading priorities …","Profil":"Profile","Profilbild":"Profile picture","Protokoll wird geladen …":"Loading log …","Prüfen ·":"Check ·","Push fehlgeschlagen:":"Push failed:","Push-Benachrichtigungen senden":"Send push notifications","Push-Benachrichtigungen sind auf diesem Server nicht verfügbar (OpenSSL-Erweiterung fehlt oder PHP zu alt).":"Push notifications are not available on this server (OpenSSL extension missing or PHP too old).","Quelle":"Source","Quelltext":"Source code","Radio-Auswahl (Punkte)":"Radio selection (dots)","Reaktion":"Response","Reaktion (Std)":"Response (hrs)","Reaktion (h)":"Response (h)","Reaktion {} Std · Lösung {} Std":"Response {} hrs · resolution {} hrs","Reaktion: {}h · Lösung: {}h":"Response: {}h · resolution: {}h","Reaktions- und Lösungszeit ab Ticketerstellung bzw. Prioritätsänderung. Mit aktivierten":"Response and resolution time from ticket creation or priority change. With enabled","Reaktions- und Lösungszeiten":"Response and resolution times","Reaktionszeit (Std)":"Response time (hrs)","Reaktionszeit (Std.)":"Response time (hrs.)","Rechnungsfrage":"Billing question","Rechte":"Permissions","Regel":"Rule","Regel bearbeiten":"Edit rule","Regeln für überfällige Tickets":"Rules for overdue tickets","Regeln werden geladen …":"Loading rules …","Registrierte Kundenkonten und Gast-Anfrager (ohne Konto) aus allen Tickets.":"Registered customer accounts and guest requesters (without account) from all tickets.","Registriertes Konto":"Registered account","Reihenfolge":"Order","Reihum an die Mitarbeiter der Abteilung":"Round robin among the department's staff","Reiner Text. Adressen mit https:// werden anklickbar.":"Plain text. Addresses with https:// become clickable.","Rheinland-Pfalz":"Rhineland-Palatinate","Richtung:":"Direction:","Rolle":"Role","Rolle (für Mitarbeiter)":"Role (for staff)","Rolle bearbeiten":"Edit role","Rolle:":"Role:","Rollen":"Roles","Rollen legst du unter":"You create roles under","Rollen und ihre Rechte legst du unter „Rollen“ an.":"You create roles and their permissions under \"Roles\".","Rollen verwalten":"Manage roles","Rollen werden geladen …":"Loading roles …","Rollenname":"Role name","SLA Erste Antwort":"SLA first response","SLA Lösung":"SLA resolution","SLA überschritten":"SLA breached","SLA-Fristen":"SLA deadlines","SLA-Plan":"SLA plan","SLA-Plan (leer = Abteilung/Priorität)":"SLA plan (empty = department/priority)","SLA-Plan (leer = Zeiten der Priorität)":"SLA plan (empty = priority's times)","SLA-Plan aktualisieren":"Update SLA plan","SLA-Pläne":"SLA plans","SLA-Pläne werden geladen …":"Loading SLA plans …","SLA-Prüfung":"SLA check","SLA-Prüfung jetzt manuell ausführen?":"Run SLA check manually now?","SLA-Quote":"SLA rate","SLA-Status":"SLA status","SLA-Uhr nur innerhalb der Geschäftszeiten laufen lassen":"Run the SLA clock only within business hours","SLA-Zeitfenster, Feiertage":"SLA time windows, holidays","SLA: Alle":"SLA: All","SMTP testen":"Test SMTP","SMTP-Server":"SMTP server","SMTP-Versand":"SMTP sending","SQL-Datei hochladen oder Pfad angeben":"Upload SQL file or enter path","SQLite-Modus aktiv:":"SQLite mode active:","Sachsen":"Saxony","Sachsen-Anhalt":"Saxony-Anhalt","Sammelmodus für Übersetzer:":"Collection mode for translators:","Samstag":"Saturday","Schichtplan bearbeiten":"Edit shift schedule","Schließen":"Close","Schließt Tickets, auf die der Kunde nach einer Antwort nicht mehr reagiert.":"Closes tickets the customer no longer responds to after a reply.","Schlüssel":"Key","Schlüssel erstellen":"Create key","Schnellfilter":"Quick filters","Schnellsuche / Befehle":"Quick search / commands","Seit":"Since","Seit 24.10.2026 19:44 geöffnet – wird beim Antworten automatisch als Zeit erfasst.":"Open since 24.10.2026 19:44 – time is recorded automatically when you reply.","Seite nicht gefunden":"Page not found","Seite nicht gefunden – {}":"Page not found – {}","Seite {}":"Page {}","Seite {} · {} Tickets":"Page {} · {} tickets","Seiten":"Pages","Seiten-Verwaltung":"Page management","Seitenleiste einblenden":"Show sidebar","Seitenleiste einklappen":"Collapse sidebar","Senden":"Send","Sendet …":"Sending …","Server-Adresse":"Server address","Server-Fehler ({}).":"Server error ({}).","Server: 0,00 MB":"Server: 0.00 MB","Serveradresse für die Anmeldung":"Server address for sign-in","Serverfehler ({}).":"Server error ({}).","Servicezeit (Std)":"Service time (hrs)","Setzen":"Set","Setzen auf:":"Set to:","Sicherheitsprüfung":"Security check","Signatur":"Signature","Signatur (E-Mail-Fuß für Antworten ohne Mitarbeiter-Signatur)":"Signature (email footer for replies without a staff signature)","Signatur (E-Mail-Fuß für eigene Antworten)":"Signature (email footer for own replies)","Signatur (optional)":"Signature (optional)","Signatur (optional, Base64)":"Signature (optional, Base64)","Sitzung abgelaufen – bitte neu anmelden.":"Session expired – please sign in again.","So kommen Benachrichtigungen auch bei geschlossenem Fenster an. Beenden über das Tray-Menü.":"This way notifications also arrive when the window is closed. Quit via the tray menu.","So nutzt du die API":"How to use the API","Sonntag":"Sunday","Sortieren nach":"Sort by","Sortiermodus:":"Sort mode:","Sortierung":"Sorting","Spam-/Junk-Ordner":"Spam/junk folder","Speichern":"Save","Speichert die aktuellen Filter (Reiter, Suche, Abteilung, Priorität).":"Saves the current filters (tab, search, department, priority).","Speichert die aktuellen Filter.":"Saves the current filters.","Speichert …":"Saving …","Sperre aufgehoben":"Lock released","Sperre aufheben":"Remove lock","Sperre aufheben und übernehmen":"Release lock and take over","Sperren":"Block","Sperrliste":"Block list","Sperrliste ist leer.":"The block list is empty.","Sperrliste ist leer. Mit + eine E-Mail-Adresse oder Domain sperren.":"The block list is empty. Block an email address or domain with +.","Sperrliste wird geladen …":"Loading block list …","Sprachen":"Languages","Stand":"As of","Stand: {} Uhr":"As of: {}","Standard":"Default","Standard-Absenderadresse der Abteilung":"Department's default sender address","Standard-Absenderadresse dieser Abteilung":"Default sender address of this department","Standard-Berichte":"Default reports","Standard-Mitarbeiterrechte (ohne eigene Rolle)":"Default staff permissions (without own role)","Standardabteilung":"Default department","Standardabteilung (bzw. Abteilung des Themas)":"Default department (or the topic's department)","Standardabteilung (für E-Mail-Tickets ohne Zuordnung)":"Default department (for email tickets without assignment)","Standardabteilung verwenden":"Use default department","Standardpriorität (optional)":"Default priority (optional)","Standardsprache (für alle, die noch keine Flagge gewählt haben)":"Default language (for everyone who has not yet chosen a flag)","Startet DeskHub beim Anmelden im Hintergrund (Tray).":"Starts DeskHub in the background (tray) when signing in.","Startseiten-Inhalte":"Home page content","Statistiken":"Statistics","Statistiken werden geladen …":"Loading statistics …","Status & Schichten":"Status & shifts","Status & Vorschau":"Status & preview","Status abfragen:":"Query status:","Status der Mitarbeiter":"Staff status","Status der Mitarbeiter ändern (Admin)":"Change staff status (admin)","Status gesetzt":"Status set","Status geändert":"Status changed","Status nach Antwort":"Status after reply","Status nach dem Senden":"Status after sending","Status prüfen":"Check status","Status setzen":"Set status","Status setzen…":"Set status…","Status von":"Status of","Status von {}":"Status of {}","Status wird geladen …":"Loading status …","Status ändern, z. B. auf Offline setzen":"Change status, e.g. set to offline","Status, Leiter, Mitglieder, E-Mail":"Status, lead, members, email","Status: automatisch":"Status: automatic","Statusseite":"Status page","Statusseite ausgeschaltet":"Status page switched off","Statusseite eingeschaltet":"Status page switched on","Statusseite für Kunden anzeigen":"Show status page to customers","Statusseite für Kunden anzeigen (Link „Status“ im Kundenbereich)":"Show status page to customers (link \"Status\" in the customer area)","Statusseite wird geladen …":"Loading status page …","Std":"hrs","Std.":"hrs.","Stichwörter":"Keywords","Stichwörter (durch Komma)":"Keywords (comma-separated)","Stichwörter (optional, durch Komma getrennt)":"Keywords (optional, comma-separated)","Stichwörter: {}":"Keywords: {}","Stille Zeiten (keine Popups)":"Quiet hours (no popups)","Strg+F5":"Ctrl+F5","Stufe":"Level","Stunden":"Hours","Störung:":"Incident:","Stündliche Prüfung. Letzte Ausführung: noch nie":"Hourly check. Last run: never","Suchbegriff eingeben …":"Enter a search term …","Suche":"Search","Suchen":"Search","Suchen (Betreff, Nummer, Kunde, Text)… Strg+F":"Search (subject, number, customer, text)… Ctrl+F","Suchen …":"Searching …","Suchen…":"Search…","Supportcenter":"Support center","Supportcenter-Startseite":"Support center home","Supportcenter-Startseite – {}":"Support center home – {}","System-Update":"System update","Systemstandard":"System default","Systemstatus":"System status","Systemstatus – {}":"System status – {}","Tag hinzufügen":"Add tag","Tag-Name":"Tag name","Tage":"Days","Tage (am besten kürzer als die Frist zum automatischen Schließen)":"Days (preferably shorter than the period for automatic closing)","Tage ohne Reaktion":"Days without response","Tagen schließen":"days","Tastenkürzel":"Keyboard shortcuts","Team (als Administrator kannst du den Status ändern)":"Team (as administrator you can change the status)","Team bearbeiten":"Edit team","Team-Chat":"Team chat","Team-Übersicht":"Team overview","Team-Übersicht (zum Ändern antippen)":"Team overview (tap to change)","Teamleiter":"Team lead","Teamname":"Team name","Teams verwalten":"Manage teams","Teams werden geladen …":"Loading teams …","Technik":"Technology","Technisches Problem":"Technical issue","Teilweise eingeschränkt":"Partially degraded","Telefon":"Phone","Telefonnummer (optional)":"Phone number (optional)","Telegram Bot-Token":"Telegram bot token","Telegram Chat-ID":"Telegram chat ID","Test-Benachrichtigung":"Test notification","Test-Benachrichtigung – so sieht eine Meldung aus.":"Test notification – this is what a message looks like.","Test-Mail senden":"Send test email","Testen":"Test","Testnachricht an meine Geräte":"Test message to my devices","Testnachricht senden":"Send test message","Tests verwenden die gespeicherten Werte.":"Tests use the saved values.","Text (HTML erlaubt)":"Text (HTML allowed)","Text (Vorschau)":"Text (preview)","Text, wenn er keine Antwort findet":"Text if it finds no answer","Textbaustein wirklich löschen?":"Really delete this text snippet?","Textbausteine verwalten":"Manage text snippets","Textbaustein…":"Text snippet…","Texte der automatischen E-Mails":"Texts of the automatic emails","Texte der automatischen Mails":"Texts of the automatic emails","Thema":"Topic","Thema, Abteilung, Priorität":"Topic, department, priority","Thema, Typ, Abteilung, Priorität":"Topic, type, department, priority","Theme hochladen":"Upload theme","Theme-Paket":"Theme package","Themen":"Topics","Themes aus dem Katalog":"Themes from the catalog","Thüringen":"Thuringia","Ticket #{}":"Ticket #{}","Ticket #{} – {}":"Ticket #{1} – {2}","Ticket anlegen (JSON). Antwort:":"Create ticket (JSON). Response:","Ticket ansehen":"View ticket","Ticket ansehen – {}":"View ticket – {}","Ticket auf später legen":"Snooze ticket","Ticket eingegangen":"Ticket received","Ticket erstellen":"Create ticket","Ticket erstellt":"Ticket created","Ticket erstellt (an Kunde)":"Ticket created (to customer)","Ticket hinzufügen":"Add ticket","Ticket im Namen eines Kunden anlegen – z.B. bei Telefonanrufen oder Vor-Ort-Anfragen.":"Create a ticket on behalf of a customer – e.g. for phone calls or on-site requests.","Ticket inkl. Verlauf unwiderruflich löschen?":"Permanently delete the ticket including its history?","Ticket ist überfällig (SLA überschritten)":"Ticket is overdue (SLA exceeded)","Ticket mir zugewiesen":"Ticket assigned to me","Ticket offen seit X Stunden":"Ticket open for X hours","Ticket schließen (wird angelegt, aber sofort geschlossen)":"Close ticket (is created but closed immediately)","Ticket verknüpfen (Ticket-Nr., optional)":"Link ticket (ticket no., optional)","Ticket verwerfen (z.B. Spam)":"Discard ticket (e.g. spam)","Ticket wird geladen …":"Loading ticket …","Ticket wurde aktualisiert":"Ticket was updated","Ticket wurde {}, aber nicht alle Original-Mails konnten verschoben werden:":"Ticket was {}, but not all original emails could be moved:","Ticket überfällig (an Admins)":"Ticket overdue (to admins)","Ticket(s) anonymisiert (geschlossen/gelöst, älter als 24 Monate).":"ticket(s) anonymized (closed/resolved, older than 24 months).","Ticket, Kunde oder Bereich suchen…":"Search ticket, customer or area…","Ticket-Berechtigungen":"Ticket permissions","Ticket-Bewertung aktivieren (Kunden können nach Schließung 1–5 Sterne vergeben)":"Enable ticket rating (customers can give 1–5 stars after closing)","Ticket-Details":"Ticket details","Ticket-Felder":"Ticket fields","Ticket-Formular":"Ticket form","Ticket-Liste":"Ticket list","Ticket-Nachrichten":"Ticket messages","Ticket-Nr.:":"Ticket no.:","Ticket-Nummer, Betreff, Status":"Ticket number, subject, status","Ticket-Regel bearbeiten":"Edit ticket rule","Ticket-Regeln":"Ticket rules","Ticket-Regeln (Filter)":"Ticket rules (filter)","Ticket-Regeln, Auto-Antworten":"Ticket rules, auto-replies","Ticket-Vorlagen":"Ticket templates","Ticketaktivität":"Ticket activity","Ticketnummer":"Ticket number","Ticketnummer kopieren":"Copy ticket number","Ticketnummer oder Betreff suchen…":"Search ticket number or subject…","Ticketnummer verknüpfen (optional)":"Link ticket number (optional)","Ticketnummer, Betreff, Kunde oder Bereich…":"Ticket number, subject, customer or area…","Tickets ({#})":"Tickets ({})","Tickets automatisch schließen, wenn der Kunde nach einer Antwort nicht mehr reagiert":"Close tickets automatically if the customer does not respond after a reply","Tickets beantworten":"Reply to tickets","Tickets durchsuchen":"Search tickets","Tickets erstellen":"Create tickets","Tickets gesamt":"Total tickets","Tickets im Namen von Kunden erstellen":"Create tickets on behalf of customers","Tickets löschen":"Delete tickets","Tickets lösen/schließen":"Resolve/close tickets","Tickets schließen/lösen":"Close/resolve tickets","Tickets verschieben":"Move tickets","Tickets werden geladen …":"Loading tickets …","Tickets zusammenführen":"Merge tickets","Tickets zuweisen":"Assign tickets","Tickets übertragen":"Transfer tickets","Ticketstatus überprüfen":"Check ticket status","Titel":"Title","Titelbild (Hero-Banner)":"Cover image (hero banner)","To-dos für dich und dein Team":"To-dos for you and your team","Token aus Gitea einfügen":"Paste token from Gitea","Typ":"Type","Täglich":"Daily","Um Ihnen weiterhelfen zu können, benötigen wir noch ein paar zusätzli…":"To help you further, we need a few additional details…","Unbeantwortet":"Unanswered","Unbekannt":"Unknown","Ungültige Eingabe.":"Invalid input.","Ungültige verschlüsselte Sitzungsdaten.":"Invalid encrypted session data.","Untereinander":"Stacked","Unterhaltung wird geladen …":"Loading conversation …","Unterstützt werden SQL-Dumps von osTicket 1.10 bis 1.18 (phpMyAdmin-Export oder":"SQL dumps from osTicket 1.10 to 1.18 are supported (phpMyAdmin export or","Update für die Kunden":"Update for the customers","Update senden":"Send update","Update veröffentlicht":"Update published","Updates: neue Datei laden und darüber installieren. Eure Anmeldung bleibt erhalten.":"Updates: load a new file and install over it. Your sign-in is kept.","Ursache gefunden":"Cause found","Verbindung testen":"Test connection","Verbindung wiederhergestellt":"Connection restored","Verfügbar":"Available","Verfügbare Platzhalter:":"Available placeholders:","Verfügbarkeit":"Availability","Verfügbarkeit & Schichten":"Availability & shifts","Verfügbarkeit und Team-Übersicht":"Availability and team overview","Verfügbarkeit wird geprüft…":"Checking availability…","Vergangene Meldungen (letzte 14 Tage)":"Past incidents (last 14 days)","Verknüpftes Ticket":"Linked ticket","Verknüpfung":"Link","Verlauf":"History","Verlauf (1 Nachricht)":"History (1 message)","Verlauf und Status Ihrer aktuellen und bisherigen Supportanfragen.":"History and status of your current and previous support requests.","Verlauf, Tags und Collaborators werden ins Ziel-Ticket verschoben. Dieses Ticket wird geschlossen.":"History, tags and collaborators are moved to the target ticket. This ticket will be closed.","Verlinkter Teil des Textes":"Linked part of the text","Verschlüsselung":"Encryption","Vertraulich/Intern":"Confidential/Internal","Verwalten":"Manage","Verwaltung":"Administration","Verwenden →":"Use →","Verzeichnis":"Directory","Veröffentlichen":"Publish","Veröffentlicht":"Published","Vielen Dank für Ihre Nachricht. Wir haben Ihr Anliegen erhalten und k…":"Thank you for your message. We have received your request and…","Vielen Dank! Ihr Ticket wurde erstellt.":"Thank you! Your ticket has been created.","Von":"From","Von (HH:MM)":"From (HH:MM)","Von (JJJJ-MM-TT)":"From (YYYY-MM-DD)","Vorgabe für den Betreff":"Default for the subject","Vorhandene Backups":"Existing backups","Vorhandene Vorlagen":"Existing templates","Vorlage":"Template","Vorlage einfügen":"Insert template","Vorlage laden":"Load template","Vorlagen":"Templates","Vorlagen / Textbausteine":"Templates / text snippets","Vorlagen werden geladen …":"Loading templates …","Vorname Nachname":"First name last name","Vorschau":"Preview","Wann ist er aktiv?":"When is it active?","Wann?":"When?","Wartend":"Waiting","Wartet auf Kunde":"Waiting for customer","Wartung":"Maintenance","Was ist passiert? Was tun wir dagegen?":"What happened? What are we doing about it?","Was ist zu tun?":"What needs to be done?","Was wird anonymisiert?":"What is anonymized?","Website-URL":"Website URL","Weiter ›":"Next ›","Weitere":"More","Weitere Aktionen":"More actions","Weitere Informationen benötigt":"More information needed","Weitere Informationen → Trotzdem ausführen":"More information → Run anyway","Weitere Tickets des Kunden":"More tickets from the customer","Weitere laden":"Load more","Weiterer Treffer:":"Another match:","Weiterer Treffer: {}":"Another match: {}","Wenige Stunden pro Tag (z. B. nur abends) lassen die Fälligkeit in":"A few hours per day (e.g. only evenings) let the due date in","Wenn …":"If …","Wert":"Value","Wie System":"Like system","Wie Windows (automatisch)":"Like Windows (automatic)","Wie erstelle ich ein Ticket?":"How do I create a ticket?","Wie können wir helfen?":"How can we help?","Wie lange dauert die Bearbeitung?":"How long does processing take?","Wieder geöffnet":"Reopened","Wieder öffnen":"Reopen","Wiederkehrende Tickets":"Recurring tickets","Wiederkehrende Tickets jetzt manuell ausführen?":"Run recurring tickets manually now?","Wiedervorlage":"Snooze","Wiedervorlage aufgehoben":"Snooze removed","Wiedervorlage aufheben":"Remove snooze","Wiedervorlage fällig":"Snooze due","Wiedervorlage gesetzt":"Snooze set","Wiedervorlage und Beobachten":"Snooze and watching","Wiedervorlagen":"Snoozes","Wiedervorlagen jetzt manuell ausführen?":"Run snoozes manually now?","Willkommen zurück, {}":"Welcome back, {}","Willkommen, Gast":"Welcome, Guest","Willkommen, {}":"Welcome, {}","Windows-Benachrichtigungen anzeigen":"Show Windows notifications","Wir senden Ihnen einen Link zum Zurücksetzen.":"We will send you a reset link.","Wird beobachtet":"Being monitored","Wird berechnet …":"Calculating …","Wird erstellt …":"Creating …","Wird geladen …":"Loading …","Wird gerade von {} bearbeitet – Sie sehen live mit, können hier aber nicht antworten.":"Currently being handled by {} – you can watch live but cannot reply here.","Wird gerade von {} bearbeitet.":"Currently being handled by {}.","Wird gespeichert …":"Saving …","Wird gesperrt …":"Blocking …","Wird im Browser-Tab, in E-Mails und in der Web-App angezeigt.":"Shown in the browser tab, in emails and in the web app.","Wird in E-Mail-Links verwendet. Kein abschließendes /":"Used in email links. No trailing /","Wird nur an öffentliche Antworten angehängt, nicht an interne Notizen.":"Only appended to public replies, not to internal notes.","Wird untersucht":"Investigating","Wird verwendet, wenn ein eingegangenes E-Mail-Ticket als Spam markiert wird.":"Used when an incoming email ticket is marked as spam.","Wirklich löschen?":"Really delete?","Wirklich sperren?":"Really block?","Wirksame Rechte":"Effective permissions","Wissensdatenbank":"Knowledge base","Wissensdatenbank durchsuchen oder direkt ein Ticket eröffnen – wir antworten so schnell wie möglich.":"Search the knowledge base or open a ticket right away – we will reply as quickly as possible.","Wissensdatenbank im Kundenportal anzeigen":"Show knowledge base in the customer portal","Wissensdatenbank verwalten":"Manage knowledge base","Wissensdatenbank wird geladen …":"Loading knowledge base …","Wissensdatenbank – {}":"Knowledge base – {}","Woche":"Week","Wochenzeiten":"Weekly hours","Wofür soll die App ein Popup zeigen?":"What should the app show a popup for?","Wonach suchen Sie?":"What are you looking for?","Worum geht es?":"What is it about?","Wähle die Abteilungen, zu denen der Agent Zugang haben soll.":"Choose the departments the agent should have access to.","Wähle, wofür die App ein Popup zeigen soll.":"Choose what the app should show a popup for.","Wöchentlich":"Weekly","Wörter":"Words","Wörter, die Kunden und Artikel unterschiedlich nennen, aber dasselbe meinen. Eine Gruppe je Zeile, durch Komma getrennt, zum Beispiel „Zugang, Einladung, beitreten“. Einige Gruppen sind eingebaut, deine ergänzen oder überschreiben sie.":"Words that customers and articles name differently but mean the same. One group per line, separated by commas, for example \"access, invitation, join\". Some groups are built in, yours add to or override them.","ZIP-Datei":"ZIP file","ZIP-Datei von Gitea hochladen und installieren.":"Upload and install a ZIP file from Gitea.","Zahl":"Number","Zeigt, was Kunden den Assistenten gefragt haben und ob er eine Antwort fand. Gespeichert werden nur Frage und Ergebnis (kein Name, keine E-Mail-Adresse).":"Shows what customers asked the assistant and whether it found an answer. Only the question and result are stored (no name, no email address).","Zeigt, was Kunden gefragt haben und ob der Assistent eine Antwort fand. Gespeichert werden nur Frage und Ergebnis.":"Shows what customers asked and whether the assistant found an answer. Only the question and result are stored.","Zeigt, was der Assistent auf eine Kundenfrage antworten würde (ohne Zähler und ohne Ticket).":"Shows what the assistant would answer to a customer question (without counters and without a ticket).","Zeit":"Time","Zeiten der Priorität verwenden":"Use the priority's times","Zeiten je Abteilung oder Thema":"Times per department or topic","Zeiten je Mitarbeiter":"Times per staff member","Zeiten werden geladen …":"Loading times …","Zeiterfassung":"Time tracking","Zeiterfassung einsehen":"View time tracking","Zeitplan aus":"Schedule off","Zeitplan speichern":"Save schedule","Zeitraum":"Period","Zeitzone":"Time zone","Ziel":"Target","Zielordner":"Target folder","Zielordner (bei Verschieben)":"Target folder (when moving)","Zielverzeichnis":"Target directory","Zitieren":"Quote","Zu einem Zeitpunkt …":"At a point in time …","Zu lange offen seit …":"Open for too long since …","Zufriedenheitsabfrage":"Satisfaction survey","Zufriedenheitsabfrage jetzt manuell ausführen?":"Run the satisfaction survey manually now?","Zugang":"Access","Zugang zum Update-Server":"Access to the update server","Zugang, Einladung, beitreten Geld zurück, Erstattung, Rückzahlung":"access, invitation, join money back, refund, reimbursement","Zugewiesen":"Assigned","Zugewiesen an":"Assigned to","Zugewiesen:":"Assigned:","Zugewiesenen Mitarbeiter benachrichtigen":"Notify assigned staff member","Zugriffstoken":"Access token","Zuletzt aktiv":"Last active","Zuletzt aktualisiert":"Last updated","Zuletzt genutzt":"Last used","Zum Ändern fehlt das Recht „Teams verwalten“.":"The \"Manage teams\" permission is missing to change this.","Zuordnung":"Assignment","Zurück":"Back","Zurück zu Tickets":"Back to tickets","Zurück zur Startseite":"Back to home","Zurück zur Ticketliste":"Back to ticket list","Zurückgesetzt":"Reset","Zurückgestellt":"Postponed","Zurücksetzen":"Reset","Zusammenführen":"Merge","Zustand":"State","Zustand geändert":"State changed","Zustand jetzt:":"Current state:","Zustand jetzt: {}":"State now: {}","Zuständig":"Responsible","Zuständigen benachrichtigen":"Notify responsible person","Zusätzlich":"Additionally","Zusätzliche Antwort":"Additional answer","Zusätzliche Antworten":"Additional answers","Zuweisen":"Assign","Zuweisen an":"Assign to","Zuweisen…":"Assign…","Zuweisung":"Assignment","Zuweisung geändert":"Assignment changed","Zuweisungen änderst du unter":"You change assignments under","Zuweisungen änderst du unter „Mitarbeiter“.":"You change assignments under \"Staff\".","Zweiten Faktor bestätigen":"Confirm second factor","absteigend":"descending","aktiv (Kunden sehen den Assistenten)":"active (customers see the assistant)","aktiv gerade eben":"active just now","alle 2 Minuten":"every 2 minutes","alle 30 Sekunden":"every 30 seconds","alle 5 Minuten":"every 5 minutes","als Spam markiert":"marked as spam","an":"on","auf":"to","ausgeschaltet":"switched off","beginnt mit":"starts with","bis":"until","bis (HH:MM)":"until (HH:MM)","ein Ticket eröffnen":"open a ticket","eingeschaltet":"switched on","endet mit":"ends with","enthält":"contains","enthält nicht":"does not contain","gekennzeichnet.":"marked.","geändert":"changed","in Ordnung":"OK","in {#} Min":"in {} min","in {#} Std {#} Min":"in {1}h {2}m","ist genau":"is exactly","jede Minute":"every minute","kein bestimmter Dienst":"no specific service","keine Abteilung":"no department","keine Abteilungs-E-Mail":"no department email","leer = von überall; sonst kommagetrennt":"empty = from anywhere; otherwise comma-separated","mind. 10 Zeichen, Groß-/Klein, Ziffer, Sonderzeichen":"min. 10 characters, upper/lower case, digit, special character","mitarbeiter@firma.de":"staff@company.com","nicht vom Herausgeber geprüft":"not verified by the publisher","nicht ändern":"do not change","noch keins":"none yet","oder":"or","oder direkt":"or directly","privat":"private","um alle Ihre Tickets im Überblick zu behalten.":"to keep all your tickets at a glance.","und":"and","von":"from","von (HH:MM)":"from (HH:MM)","vor {#} Min (überfällig)":"{} min ago (overdue)","vor {#} Min.":"{} min. ago","vor {#} Std {#} Min (überfällig)":"{1}h {2}m ago (overdue)","wird nur an Antworten an den Kunden angehängt":"is only attached to replies to the customer","z. B. E-Mail-Versand verzögert":"e.g. email delivery delayed","z. B. Ich habe die Nutzerbedingungen gelesen und akzeptiert.":"e.g. I have read and accept the terms of use.","z. B. Lieferzeit, Paket, Lieferung":"e.g. delivery time, parcel, delivery","z. B. Meine überfälligen":"e.g. My overdue","z. B. Mit freundlichen Grüßen Ihr Support-Team":"e.g. Kind regards, your support team","z. B. Mit freundlichen Grüßen Max Mustermann":"e.g. Kind regards, Max Mustermann","z. B. Monatsbericht Support":"e.g. Monthly support report","z. B. Neuer Mitarbeiter":"e.g. New employee","z. B. Nutzerbedingungen":"e.g. Terms of use","z. B. Passwort zurücksetzen, Rechnung, Versand …":"e.g. reset password, invoice, shipping …","z. B. Vertragsnummer":"e.g. Contract number","z. B. Website-Kontaktformular":"e.g. Website contact form","z. B. Wie lange dauert der Versand?":"e.g. How long does shipping take?","z. B. Wie setze ich mein Passwort zurück?":"e.g. How do I reset my password?","z.B. Import aus alter Sperrliste":"e.g. Import from old block list","z.B. Junk, Spam oder INBOX.Junk":"e.g. Junk, Spam or INBOX.Junk","z.B. Tag der Deutschen Einheit":"e.g. German Unity Day","z.B. Technik-Postfach":"e.g. Technical mailbox","z.B. wiederholter Spam":"e.g. repeated spam","z.B. „In Besprechung bis 14:00“":"e.g. \"In a meeting until 14:00\"","zurückgeholt":"restored","zählen nur die dort eingetragenen Öffnungszeiten.":"only the opening hours entered there count.","{#} Artikel":"{} article(s)","{#} Aufrufe":"{} views","{#} Tag(e)":"{} day(s)","{#} Treffer":"{} hits","{} Abteilung(en) · {} Hilfethema/-themen":"{} department(s) · {} help topic(s)","{} Aktualisierung(en) an deinen Tickets":"{} update(s) to your tickets","{} Antworten von {} Abfragen":"{} answers from {} surveys","{} Artikel":"{} articles","{} Bedingung(en) ({})":"{} condition(s) ({})","{} Einträge · Seite {} von {}":"{} entries · page {} of {}","{} Einträge · Seite {}/{}":"{} entries · page {}/{}","{} Kontakte":"{} contacts","{} Mitarbeiter":"{} staff","{} Mitglied(er)":"{} member(s)","{} Std":"{} hrs","{} Tickets":"{} tickets","{} ausgewählt":"{} selected","{} gesperrt, {} übersprungen.":"{} blocked, {} skipped.","{} neue(s) nicht zugewiesene(s) Ticket(s)":"{} new unassigned ticket(s)","{} offen":"{} open","{} von 5":"{} of 5","{} · erstellt am {}":"{1} · created {2}","{} · {} · erstellt {}":"{} · {} · created {}","{} überfällig":"{} overdue","{}: {} Ticket(s)":"{}: {} ticket(s)","{}× angewendet":"applied {}×","{}× genutzt · {}":"used {}× · {}","· Handeln":"· Act","· Hinweis":"· Notice","· In Ordnung":"· OK","· Leiter: {}":"· Lead: {}","· Letzte automatische Prüfung: Noch nie":"· Last automatic check: never","· Letzter Abruf: Noch nie":"· Last fetch: never","· Live-Chat {} · Wissensdatenbank im Portal {}":"· Live chat {} · Knowledge base in the portal {}","· Prüfen":"· Check","· fällig {}":"· due {}","· für alle":"· for everyone","· {} Fehler ({})":"· {} errors ({})","· über den DeskHub-Push-Dienst, es ist nichts einzurichten":"· via the DeskHub push service, nothing to set up","Ältere Backups werden automatisch gelöscht wenn das Limit erreicht wird.":"Older backups are deleted automatically when the limit is reached.","Änderungen speichern":"Save changes","Änderungen und Mailfehler":"Changes and failed emails","Änderungen und fehlgeschlagene Mails":"Changes and failed emails","Öffentlich":"Public","Öffentlich (für Kunden sichtbar)":"Public (visible to customers)","Öffentliche Antwort senden":"Send public reply","Öffnen Sie zuerst den persönlichen Ticket-Link aus der Ticket-E-Mail in diesem Browser. Anschließend können Sie das Ticket hier Ihrem Konto hinzufügen, wenn die Ticket-E-Mail-Adresse mit Ihrer Konto-E-Mail-Adresse übereinstimmt.":"First open the personal ticket link from the ticket email in this browser. You can then add the ticket to your account here if the ticket email address matches your account email address.","Öffnungszeiten je Wochentag":"Opening hours per weekday","Öffnungszeiten speichern":"Save opening hours","Öffnungszeiten und Feiertage":"Opening hours and holidays","Ø Bewertung · {} Antworten von {} Abfragen":"Ø rating · {} answers from {} surveys","Ø Erste Antwort":"Ø First response","Ø Erstreaktion":"Ø First response","Ø Lösungszeit":"Ø Resolution time","Überfällig":"Overdue","Überfällig seit …":"Overdue since …","Übergeordnetes Thema":"Parent topic","Überschrift":"Heading","Übersicht":"Overview","– Abteilung wählen –":"– choose department –","– Download nur im Web":"– Download on the web only","– Hilfe-Thema wählen –":"– choose help topic –","– Interne Notizen, sichtbar für alle Administratoren":"– Internal notes, visible to all administrators","– Mitarbeiter wählen –":"– choose staff member –","– Priorität wählen –":"– choose priority –","– Standard-Mitarbeiterrechte –":"– default staff permissions –","– Textbaustein wählen –":"– choose text snippet –","– Vorlage wählen –":"– choose template –","– auswählen –":"– select –","– bitte wählen –":"– please choose –","– kein Leiter –":"– no lead –","– kein Thema –":"– no topic –","– kein bestimmter Dienst –":"– no specific service –","– keine Änderung –":"– no change –","– keine –":"– none –","– nicht vorgeben –":"– do not preset –","– nicht zugewiesen –":"– unassigned –","– nicht ändern –":"– do not change –","– ohne Vorlage –":"– without template –","– wählen –":"– choose –","— Abteilung auswählen —":"— select department —","— Automatisch (Standardadresse der Abteilung) —":"— Automatic (department default address) —","— Automatisch —":"— Automatic —","— Bitte wählen —":"— Please choose —","— Keine(r) —":"— None —","— Niemand —":"— Nobody —","— Oberste Hilfethemenebene —":"— Top help topic level —","— Standard —":"— Default —","— Standardabteilung (bzw. Abteilung des gewählten Themas) —":"— Default department (or department of the chosen topic) —","— Systemstandard —":"— System default —","— Zeiten der Priorität verwenden —":"— Use the priority's times —","— keine —":"— none —","— nicht ändern —":"— do not change —","— niemand —":"— nobody —","— ohne Vorlage —":"— without template —","‹ Liste":"‹ List","‹ Verwaltung":"‹ Administration","‹ Zurück":"‹ Back","ℹ️ Ausführung hochgeladener Dateien":"ℹ️ Execution of uploaded files","ℹ️ Erreichbarkeit interner Dateien":"ℹ️ Accessibility of internal files","ℹ️ Hinweise":"ℹ️ Notes","← Einstellungen":"← Settings","← Zum Kundenportal":"← To the customer portal","← Zur Anmeldung":"← Back to sign in","← Zur Ticket-Liste":"← To the ticket list","← Zurück":"← Back","↑ Priorität: {}":"↑ Priority: {}","→ bleiben erhalten":"→ are kept","↓ CSV exportieren":"↓ Export CSV","↩️ Spam-Markierung aufheben":"↩️ Remove spam mark","⏰ Automatischer Zeitplan":"⏰ Automatic schedule","⏱ Zeiterfassung":"⏱ Time tracking","⏱ Zeiterfassung läuft":"⏱ Time tracking running","○ Noch kein Postfach eingerichtet":"○ No mailbox set up yet","○ deaktiviert":"○ disabled","⚙ Einstellungen":"⚙ Settings","⚠️ Administratoren ohne Zwei-Faktor-Anmeldung":"⚠️ Administrators without two-factor authentication","⚠️ Datenbank: SQLite":"⚠️ Database: SQLite","⚠️ Noch kein geprüftes Backup":"⚠️ No verified backup yet","⛔ Absender sperren":"⛔ Block sender","⛔ Gesperrt":"⛔ Blocked","✅ Verschlüsselungsschlüssel gesetzt":"✅ Encryption key set","✍ Signatur":"✍ Signature","✓ Berichte einsehen":"✓ View reports","✓ Die Datenbank ist aktuell":"✓ The database is up to date","✓ Interne Notizen schreiben":"✓ Write internal notes","✓ Push ist aktiv":"✓ Push is active","✓ Tickets beantworten":"✓ Reply to tickets","✓ Tickets im Namen von Kunden erstellen":"✓ Create tickets on behalf of customers","✓ Tickets schließen/lösen":"✓ Close/resolve tickets","✓ Tickets zuweisen (Mitarbeiter/Team)":"✓ Assign tickets (staff/team)","✓ Tickets übertragen (Abteilung ändern)":"✓ Transfer tickets (change department)","✕ Abteilungen verwalten":"✕ Manage departments","✕ Admin-Protokoll einsehen":"✕ View admin log","✕ Digitalen Assistenten verwalten":"✕ Manage digital assistant","✕ E-Mail-Adressen verwalten":"✕ Manage email addresses","✕ E-Mail-Vorlagen verwalten":"✕ Manage email templates","✕ Eskalationsregeln verwalten":"✕ Manage escalation rules","✕ Filter zurücksetzen":"✕ Reset filters","✕ Geschäftszeiten verwalten":"✕ Manage business hours","✕ Hilfe-Themen verwalten":"✕ Manage help topics","✕ Mitarbeiter verwalten":"✕ Manage staff","✕ Organisationen verwalten":"✕ Manage organizations","✕ Prioritäten / SLA verwalten":"✕ Manage priorities / SLA","✕ Rollen verwalten":"✕ Manage roles","✕ Teams verwalten":"✕ Manage teams","✕ Textbausteine verwalten":"✕ Manage text snippets","✕ Tickets löschen":"✕ Delete tickets","✕ Wissensdatenbank verwalten":"✕ Manage knowledge base","✕ Zeiterfassung einsehen":"✕ View time tracking","❌ Installationsassistent ist nicht gesperrt":"❌ The installation wizard is not locked","❌ Website-URL nutzt kein HTTPS":"❌ Website URL does not use HTTPS","⬆️ Hochladen & installieren":"⬆️ Upload & install","🌐 Im Browser":"🌐 In browser","🌐 Web (im Namen)":"🌐 Web (on behalf)","🏖 Urlaub":"🏖 Vacation","👁 Beobachten":"👁 Watch","👁 Beobachtet":"👁 Watched","👁 Nicht mehr beobachten":"👁 Stop watching","👁 Ticket beobachten":"👁 Watch ticket","👋 Hallo! Wie können wir Ihnen helfen?":"👋 Hello! How can we help you?","👤 Konto":"👤 Account","💤 Auf später":"💤 Snooze","💤 Ausgeblendet bis {} Uhr, dann kommt das Ticket zurück.":"💤 Hidden until {}, then the ticket comes back.","💤 Wiedervorlage":"💤 Snooze","💤 bis":"💤 until","💬 Live-Chat":"💬 Live chat","💾 Backup jetzt erstellen":"💾 Create backup now","📄 Impressum":"📄 Legal notice","📎 Datei":"📎 File","📞 Telefon":"📞 Phone","📡 FTP-Upload":"📡 FTP upload","📥 osTicket Import":"📥 osTicket import","📧 E-Mail":"📧 Email","📧 Mitarbeiter":"📧 Staff","📱 Android-App: Push-Benachrichtigungen":"📱 Android app: push notifications","📱 Android-App: Welche Popups?":"📱 Android app: which popups?","🔄 Automatischer Hintergrund-Betrieb (ohne Server-Cronjob)":"🔄 Automatic background operation (without server cron job)","🔄 Erneut prüfen":"🔄 Check again","🔄 System-Update":"🔄 System update","🔒 Datenschutz":"🔒 Privacy","🔒 Datenschutzerklärung":"🔒 Privacy policy","🔒 Dieses Ticket wird gerade von „{}“ bearbeitet. Als Administrator kannst du es trotzdem lesen und bearbeiten.":"🔒 This ticket is currently being handled by \"{}\". As administrator you can still read and edit it.","🔒 Sicherheit":"🔒 Security","🔒 Wird gerade von {} bearbeitet – Sie sehen live mit, können hier aber nicht schreiben.":"🔒 Currently being handled by {} – you can watch live but cannot write here.","🔓 freigeben":"🔓 release","🔔 Meine Erwähnungen":"🔔 My mentions","🔴 Beschäftigt":"🔴 Busy","🔴 Überfällig":"🔴 Overdue","🖥 Intern":"🖥 Internal","🖥 Vor Ort / Intern":"🖥 On site / internal","🖨 Drucken":"🖨 Print","🖨 Drucken / Als PDF speichern":"🖨 Print / Save as PDF","🖨️ Ticket drucken":"🖨️ Print ticket","🖼️ Bild einfügen":"🖼️ Insert image","🗄 Datenbank aktualisieren":"🗄 Update database","🗑 Ticket löschen":"🗑 Delete ticket","🚫 Als Spam markieren":"🚫 Mark as spam","🚫 Sperren":"🚫 Block","🟡 Bald fällig":"🟡 Due soon","🟡 Bald fällig (< 4 Std.)":"🟡 Due soon (< 4 hrs)","🟡 Pause":"🟡 Break","🟢 Im Zeitplan":"🟢 On schedule","🟢 Verfügbar":"🟢 Available","+ Ansicht speichern":"+ Save view"}
\ No newline at end of file
+{"%.1f Std":"%.1f hrs","(Gast)":"(Guest)","(automatisch, inaktiv)":"(automatic, inactive)","(nicht hinterlegt)":"(not set)","(zusätzlich)":"(additional)","+ Aktion":"+ Action","+ Aktion hinzufügen":"+ Add action","+ Antwort hinzufügen":"+ Add answer","+ Aufgabe":"+ Task","+ Bedingung":"+ Condition","+ Bedingung hinzufügen":"+ Add condition","+ Erfassen":"+ Log time","+ Kategorie hinzufügen":"+ Add category","+ Neu":"+ New","+ Neue Aufgabe":"+ New task","+ Neue Regel":"+ New rule","+ Neuer Artikel":"+ New article","+ Neuer Textbaustein":"+ New text snippet","+ Neues Muster":"+ New pattern","+ Neues Ticket":"+ New ticket","+ Ticket erstellen":"+ Create ticket","+ hinzufügen":"+ add","0 Gerät(e) angemeldet":"0 device(s) signed in","1 Std":"1 hr","1 Tag":"1 day","1 Treffer ·":"1 hit ·","1 Woche":"1 week","10 Backups behalten":"Keep 10 backups","14 Backups behalten":"Keep 14 backups","2 Std":"2 hrs","2 Tage":"2 days","3 Backups behalten":"Keep 3 backups","3 Std":"3 hrs","3 Tage":"3 days","30 Backups behalten":"Keep 30 backups","5 Backups behalten":"Keep 5 backups","6-stelliger Code":"6-digit code","7 Backups behalten":"Keep 7 backups","7 Tage":"7 days","8 Std":"8 hrs",": bitte in der App erneut versuchen":": please try again in the app","API-Schlüssel":"API keys","Abbrechen":"Cancel","Abfrage am {} gesendet, noch keine Antwort.":"Survey sent on {}, no answer yet.","Abfrage-Intervall":"Fetch interval","Abgehend (SMTP)":"Outgoing (SMTP)","Abgehend (eigener SMTP-Server)":"Outgoing (own SMTP server)","Abmelden":"Sign out","Abmelden / Server wechseln":"Sign out / switch server","Abruf":"Fetch","Abruf aktivieren":"Enable fetching","Abruf für diese Adresse aktivieren":"Enable fetching for this address","Absender":"Sender","Absender oder Mailanbieter sperren":"Block sender or mail provider","Absender sperren":"Block sender","Absender sperren…":"Block sender…","Absender-E-Mail":"Sender email","Absender-Name":"Sender name","Absender:":"Sender:","Absendername":"Sender name","Abteilung":"Department","Abteilung aktualisieren":"Update department","Abteilung aktualisiert:":"Department updated:","Abteilung erstellt:":"Department created:","Abteilung für Live-Chat-Tickets":"Department for live chat tickets","Abteilung für Tickets des Assistenten":"Department for assistant tickets","Abteilung hinzufügen":"Add department","Abteilung nicht gefunden.":"Department not found.","Abteilung setzen":"Set department","Abteilung und Priorität stammen aus dem Reiter „Konto“.":"Department and priority come from the \"Account\" tab.","Abteilung wirklich löschen?":"Really delete this department?","Abteilung ändern":"Change department","Abteilung „":"Department \"","Abteilung „Allgemeiner Support“ (nicht hinterlegt)":"Department \"General support\" (not set)","Abteilung/Priorität bestimmt die Zeiten":"Department/priority determines the times","Abteilung:":"Department:","Abteilungen":"Departments","Abteilungen verwalten":"Manage departments","Abteilungen werden geladen …":"Loading departments …","Abteilungs-E-Mail (optional)":"Department email (optional)","Abteilungs-E-Mail (optional, sonst Standardadresse)":"Department email (optional, otherwise default address)","Abteilungs-Routing-Tabelle":"Department routing table","Abteilungsinformationen":"Department information","Abteilungsleiter":"Department head","Achtung:":"Attention:","Admin benachrichtigen":"Notify admin","Admin-Protokoll":"Admin log","Admin-Protokoll einsehen":"View admin log","Administrator (alle Rechte)":"Administrator (all rights)","Administratornotizen":"Administrator notes","Administratornotizen (intern)":"Administrator notes (internal)","Adminportal":"Admin portal","Adminportal-Bereiche (\"Co-Admin\")":"Admin portal areas (\"co-admin\")","Admins benachrichtigen":"Notify admins","Adresse für Kunden:":"Address for customers:","Adresse für Kunden: {}":"Address for customers: {}","Adressen und Postfach-Abruf":"Addresses and mailbox fetching","Adressen verwaltest du unter „E-Mail-Adressen“.":"You manage addresses under \"Email addresses\".","Adressen, Priorität und Postfach-Abruf pflegst du unter":"You manage addresses, priority and mailbox fetching under","Agent anlegen":"Create agent","Agenten":"Agents","Agenten verwalten — {}":"Manage agents — {}","Aktion":"Action","Aktion nach Abruf":"Action after fetch","Aktionen":"Actions","Aktiv":"Active","Aktiv (auf dem Ticket-Formular sichtbar)":"Active (visible on the ticket form)","Aktiv (deaktivierte Rolle wird ignoriert)":"Active (a disabled role is ignored)","Aktiv (sonst deaktiviert)":"Active (otherwise disabled)","Aktiv (sonst gesperrt)":"Active (otherwise blocked)","Aktiv (wird beim Abruf berücksichtigt)":"Active (used when fetching)","Aktive Live-Chats (0)":"Active live chats (0)","Aktivieren":"Activate","Aktivität":"Activity","Aktualisiere …":"Refreshing …","Aktualisieren":"Refresh","Aktualisiert":"Updated","Aktuell keine offenen Live-Chats.":"There are currently no open live chats.","Aktuell würden":"Currently","Aktuelle Filter als Ansicht speichern":"Save current filters as a view","Aktuelle Filter speichern …":"Save current filters …","Aktuelles Passwort":"Current password","Alle":"All","Alle Absender der markierten Tickets sperren und Tickets schließen?":"Block all senders of the selected tickets and close the tickets?","Alle Abteilungen":"All departments","Alle Artikel durchsuchen":"Browse all articles","Alle Bedingungen":"All conditions","Alle Bedingungen müssen zutreffen":"All conditions must match","Alle Ergebnisse":"All results","Alle Prioritäten":"All priorities","Alle Status":"All statuses","Alle Tags":"All tags","Alle Textbausteine":"All text snippets","Alle Themen (oder Formular ohne Themenauswahl)":"All topics (or form without topic selection)","Alle Zuständigkeiten":"All assignments","Alle aktiven":"All active","Alle anlegen":"Create all","Alle außer Geschlossen":"All except closed","Alle behalten":"Keep all","Alle bekannten Datenbank-Änderungen sind eingespielt.":"All known database changes have been applied.","Alle eingegebenen Adressen sperren und Tickets schließen?":"Block all entered addresses and close tickets?","Alle löschen":"Delete all","Alle sperren":"Block all","Allgemein":"General","Allgemeine Anfrage":"General inquiry","Allgemeiner Support":"General support","Alphabetisch":"Alphabetical","Als Spam markiert":"Marked as spam","Als gelesen markieren":"Mark as read","An diesen Tagen laufen keine SLA-Fristen, unabhängig vom Wochentag.":"No SLA deadlines run on these days, regardless of the weekday.","Analysieren":"Analyze","Android fragt einmalig, ob der Browser Apps installieren darf. Das bitte erlauben.":"Android asks once whether the browser may install apps. Please allow it.","Anfrage-Quelle":"Request source","Angaben des Kunden":"Customer details","Angepasst":"Customized","Angewendet":"Applied","Anhang":"Attachment","Anhänge (optional, mehrere möglich)":"Attachments (optional, multiple allowed)","Anmelden":"Sign in","Anmelden – {}":"Sign in – {}","Anmeldung für Support-Mitarbeiter und Administratoren.":"Sign-in for support staff and administrators.","Anmeldung wird geprüft …":"Checking sign-in …","Anonymisiert":"Anonymized","Anonymisierung jetzt ausführen? Dies kann nicht rückgängig gemacht werden.":"Run anonymization now? This cannot be undone.","Anordnung der Optionen":"Order of the options","Ansicht aktualisieren":"Refresh view","Ansicht gespeichert":"View saved","Ansicht löschen":"Delete view","Ansicht löschen?":"Delete view?","Ansicht nicht gefunden.":"View not found.","Ansicht speichern":"Save view","Ansicht umbenennen":"Rename view","Ansichten":"Views","Antwort":"Answer","Antwort *":"Answer *","Antwort / Ticket":"Answer / ticket","Antwort an Kunden":"Reply to customer","Antwort anlegen":"Create answer","Antwort bearbeiten":"Edit answer","Antwort dazu anlegen":"Create an answer for it","Antwort gelöscht":"Answer deleted","Antwort gesendet":"Reply sent","Antwort gespeichert":"Answer saved","Antwort jetzt an den Kunden senden?":"Send the reply to the customer now?","Antwort löschen":"Delete answer","Antwort nicht gesendet":"Reply not sent","Antwort schreiben":"Write reply","Antwort senden":"Send reply","Antworten":"Replies","Antworten / Notiz":"Reply / note","Antworten auf häufige Fragen – oft schneller als der Weg über ein Ticket.":"Answers to common questions – often faster than opening a ticket.","Antworten, Fragen-Log, Einstellungen":"Answers, question log, settings","Antworten, Fragen-Log, Einstellungen, Synonyme":"Answers, question log, settings, synonyms","Antwort…":"Answer…","Anzeigename":"Display name","Anzeigename & URL":"Display name & URL","Anzeigename (optional)":"Display name (optional)","App öffnen, Serveradresse eingeben und anmelden.":"Open the app, enter the server address and sign in.","Apps für Mitarbeiter":"Apps for staff","Artikel":"Article","Artikel bearbeiten":"Edit article","Artikel und Kategorien":"Articles and categories","Artikel wirklich löschen?":"Really delete this article?","Auch Nachrichten durchsuchen":"Also search messages","Auf Standard zurücksetzen?":"Reset to default?","Auf diese Abteilung besteht kein Zugriff.":"You do not have access to this department.","Auf dieses Ticket besteht kein Zugriff.":"You do not have access to this ticket.","Auf später legen":"Snooze","Auf später legen: das Ticket verschwindet aus den Listen und kommt zurück, mit Benachrichtigung.":"Snooze: the ticket disappears from the lists and comes back, with a notification.","Auf „Alle Themen“ belassen, damit das Feld unabhängig vom gewählten Anliegen erscheint.":"Leave on \"All topics\" so the field appears regardless of the chosen request.","Aufbewahrungsdauer nach Schließung":"Retention period after closing","Aufgabe":"Task","Aufgabe löschen?":"Delete task?","Aufgaben":"Tasks","Aufgaben werden geladen …":"Loading tasks …","Aufrufe":"Views","Aus":"Off","Ausfall":"Outage","Auslöser":"Trigger","Ausprobieren":"Try out","Auswahl aufheben":"Clear selection","Auswahl:":"Selection:","Auswertungen":"Reports","Authenticator-Code":"Authenticator code","Auto-Antwort senden (Textbaustein)":"Send auto-reply (text snippet)","Automatisch":"Automatic","Automatisch (Routing-Tabelle / globale Standardabteilung)":"Automatic (routing table / global default department)","Automatisch (Standardadresse der Abteilung)":"Automatic (department default address)","Automatisch offline nach":"Go offline automatically after","Automatisch schließen":"Close automatically","Automatische Anonymisierung aktivieren":"Enable automatic anonymization","Automatische Backups":"Automatic backups","Automatische Backups jetzt manuell ausführen?":"Run automatic backups manually now?","Automatische Datenlöschung":"Automatic data deletion","Automatische Zeiterfassung (misst automatisch, wie lange ein Mitarbeiter ein Ticket geöffnet hat)":"Automatic time tracking (measures how long a staff member has a ticket open)","Automatischen Hintergrund-Betrieb aktiv halten":"Keep automatic background operation active","Automatischer Logout nach Inaktivität":"Automatic logout after inactivity","Automatisches Schließen":"Automatic closing","Automatisches Schließen jetzt manuell ausführen?":"Run automatic closing manually now?","Automatisierung":"Automation","Automatisierung und Auto-Antworten":"Automation and auto-replies","Backup-Intervall":"Backup interval","Backup-Rotation (lokale Kopien behalten)":"Backup rotation (local copies to keep)","Backups enthalten alle Dateien inkl.":"Backups contain all files incl.","Backups liegen in":"Backups are stored in","Backups vorhanden":"Backups available","Backups werden automatisch vor jedem Update erstellt":"Backups are created automatically before every update","Backups werden nach der Erstellung automatisch per FTP übertragen.":"Backups are transferred automatically via FTP after creation.","Bald fällig":"Due soon","Bayern":"Bavaria","Beantwortet":"Answered","Beantwortete Tickets nach":"Answered tickets after","Bearbeiten":"Edit","Bearbeitung":"Processing","Bedingungen":"Conditions","Bedingungen (optional – leer = alle Tickets)":"Conditions (optional – empty = all tickets)","Beenden":"Quit","Begrüßung":"Greeting","Behoben":"Resolved","Bei einer":"For a","Bei neuen Aktualisierungen an deinen Tickets und neuen, nicht zugewiesenen Tickets.":"On new updates to your tickets and new unassigned tickets.","Bei schweren Fehlern auf der Webseite eine E-Mail senden":"Send an email on serious errors on the website","Beide leer = immer Popups. Es gilt die Zeit des Servers, auch über Mitternacht (z. B. 22:00 bis 06:00).":"Both empty = always popups. The server time applies, also past midnight (e.g. 22:00 to 06:00).","Beim Schließen im Infobereich weiterlaufen":"Keep running in the notification area when closing","Beim Öffnen automatisch zuweisen (ein noch nicht zugewiesenes Ticket geht an den Mitarbeiter, der es öffnet)":"Assign automatically on open (an unassigned ticket goes to the staff member who opens it)","Beliebig":"Any","Beliebte Artikel":"Popular articles","Benachr.":"Notif.","Benachrichtigung bei Ticketzuweisung deaktivieren":"Disable notification on ticket assignment","Benachrichtigungen":"Notifications","Benannte Zeiten je Abteilung oder Thema":"Named times per department or topic","Benutzerdefiniert":"Custom","Benutzerdefinierte Berechtigungssets für Mitarbeiter. Ohne Rolle gelten die Standard-Mitarbeiterrechte.":"Custom permission sets for staff. Without a role, the default staff permissions apply.","Benutzerdefinierte Listen":"Custom lists","Benutzername":"Username","Benutzername (leer = E-Mail-Adresse)":"Username (empty = email address)","Benutzername / E-Mail":"Username / email","Beobachter":"Watchers","Beobachter und Cc":"Watchers and Cc","Beobachtetes Ticket aktualisiert":"Watched ticket updated","Berechtigungen":"Permissions","Berechtigungssets":"Permission sets","Bereich":"Area","Bereich „Beliebte Artikel“ auf der Startseite anzeigen":"Show the \"Popular articles\" section on the home page","Bereits registriert?":"Already registered?","Bericht erstellen":"Create report","Bericht gespeichert":"Report saved","Bericht löschen?":"Delete report?","Bericht nicht gefunden.":"Report not found.","Bericht speichern":"Save report","Bericht-Baukasten":"Report builder","Berichte":"Reports","Berichte ansehen":"View reports","Berichte einsehen":"View reports","Berichtszeitraum":"Reporting period","Beschreiben Sie Ihr Anliegen so detailliert wie möglich…":"Describe your request in as much detail as possible…","Beschreiben Sie Ihr Anliegen so genau wie möglich – das hilft uns, schneller zu helfen.":"Describe your request as precisely as possible – it helps us help you faster.","Beschreibung":"Description","Beschreibung (optional)":"Description (optional)","Beschriftung im Footer":"Footer label","Beschädigte Sitzungsdaten konnten nicht entfernt werden.":"Corrupted session data could not be removed.","Beschäftigt":"Busy","Bestätigen":"Confirm","Betreff":"Subject","Betreff & letzte Nachricht":"Subject & last message","Betreff und Kundenname in der Benachrichtigung anzeigen":"Show subject and customer name in the notification","Betreff · Ticket-Nr. · Kundenname · E-Mail":"Subject · ticket no. · customer name · email","Betrifft":"Affects","Betrifft: {}":"Affects: {}","Bewertet am":"Rated on","Bewertet am {}":"Rated on {}","Bezeichnung":"Label","Bezeichnung (z. B. Neujahr)":"Label (e.g. New Year)","Bild aus der Signatur":"Image from signature","Bild wird hochgeladen …":"Uploading image …","Bis":"To","Bis (HH:MM)":"Until (HH:MM)","Bis (JJJJ-MM-TT)":"Until (YYYY-MM-DD)","Bitte Authenticator-Code eingeben.":"Please enter the authenticator code.","Bitte Benachrichtigungen im Browser erlauben.":"Please allow notifications in the browser.","Bitte Server-Adresse eingeben.":"Please enter the server address.","Bitte ein gültiges Datum angeben.":"Please enter a valid date.","Bitte eine Beschreibung eingeben.":"Please enter a description.","Bitte eine Bilddatei auswählen.":"Please select an image file.","Bitte eine Datei auswaehlen.":"Please select a file.","Bitte eine Frage (Titel) und die Antwort angeben.":"Please enter a question (title) and the answer.","Bitte eine Frage eingeben.":"Please enter a question.","Bitte eine Nachricht eingeben.":"Please enter a message.","Bitte eine Ziel-Abteilung wählen.":"Please choose a target department.","Bitte eine gültige E-Mail-Adresse angeben (oder leer lassen).":"Please enter a valid email address (or leave empty).","Bitte eine gültige E-Mail-Adresse angeben.":"Please enter a valid email address.","Bitte eine gültige Farbe im Format #RRGGBB angeben.":"Please enter a valid color in the format #RRGGBB.","Bitte eine gültige Kategorie wählen.":"Please select a valid category.","Bitte einen Betreff angeben.":"Please enter a subject.","Bitte einen Empfänger angeben.":"Please enter a recipient.","Bitte einen Inhalt angeben.":"Please enter some content.","Bitte einen Kategorienamen angeben.":"Please enter a category name.","Bitte einen Namen angeben.":"Please enter a name.","Bitte einen Namen für den Bericht angeben.":"Please enter a name for the report.","Bitte einen Namen für den Feiertag angeben.":"Please enter a name for the holiday.","Bitte einen Text angeben.":"Please enter a text.","Bitte einen Titel angeben.":"Please enter a title.","Bitte einen Wert angeben.":"Please enter a value.","Bitte einen Zeitpunkt in der Zukunft wählen.":"Please choose a point in time in the future.","Bitte geben Sie eine Nachricht ein.":"Please enter a message.","Bitte gültige SLA-Stunden angeben (größer als 0).":"Please enter valid SLA hours (greater than 0).","Bitte in der App anmelden.":"Please sign in in the app.","Bitte in der App neu anmelden.":"Please sign in again in the app.","Bitte mindestens ein Ticket markieren.":"Please select at least one ticket.","Bitte mindestens eine Aktion festlegen.":"Please define at least one action.","Bitte mindestens eine Bedingung mit einem Wert angeben.":"Please enter at least one condition with a value.","Bitte schildern Sie uns so viele Details wie möglich, damit wir Ihnen bestmöglich helfen können.":"Please give us as many details as possible so we can help you in the best way.","Bitte userId oder email angeben.":"Please provide userId or email.","Bitte warten …":"Please wait …","Browser-Push-Benachrichtigungen":"Browser push notifications","Buchhaltung":"Accounting","Bundesland":"Federal state","Bündeln Sie mehrere Kundenkonten unter einer Firma/Organisation. Kontakte werden unter „Kunden“ zugeordnet.":"Group several customer accounts under one company/organization. Contacts are assigned under \"Customers\".","CSV exportieren":"Export CSV","Cc entfernen":"Remove Cc","Cc hinzufügen":"Add Cc","Cc hinzugefügt":"Cc added","Cc-Adresse hinzufügen":"Add Cc address","Cc-Empfänger":"Cc recipients","Chat auswählen":"Choose chat","Chat beenden":"End chat","Chat beenden?":"End chat?","Chat nicht gefunden oder kein Zugriff.":"Chat not found or no access.","Chat starten":"Start chat","Chat wird geladen …":"Loading chat …","Chat wirklich beenden?":"Really end chat?","Chats werden geladen …":"Loading chats …","Chatverlauf (an Kunde, nach Chatende)":"Chat transcript (to customer, after chat ends)","Chatverlauf per E-Mail an den Kunden senden, sobald ein Mitarbeiter den Chat beendet":"Send the chat transcript to the customer by email as soon as a staff member ends the chat","Checkbox (Ja/Nein)":"Checkbox (yes/no)","Copyright © {} – Alle Rechte vorbehalten.":"Copyright © {} – All rights reserved.","Cron-Job einrichten:":"Set up cron job:","Cron-Jobs":"Cron jobs","Cron-Status":"Cron status","Crontab-Eintrag":"Crontab entry","Crontab-Zeilen anzeigen":"Show crontab lines","Da gerade niemand direkt verfügbar ist, antworten wir Ihnen per E-Mail, sobald wir Ihre Anfrage bearbeitet haben.":"Nobody is available right now, so we will reply by email as soon as we have looked into your request.","Dann …":"Then …","Darf Tickets anlegen":"May create tickets","Darf Ticketstatus lesen (mit Ticketnummer + E-Mail des Anfragenden)":"May read ticket status (with ticket number + requester's email)","Darstellung":"Appearance","Das Backup {} ist nicht wiederherstellbar: {} Bitte unter Backup ein neues erstellen.":"The backup {} cannot be restored: {} Please create a new one under Backup.","Das Geräte-Token ist ungültig.":"The device token is invalid.","Das Log ist noch nicht verfügbar. Bitte im Adminportal unter System-Update „Datenbank aktualisieren“ klicken.":"The log is not available yet. Please click “Update database” in the admin portal under System update.","Das Log ist noch nicht verfügbar. Bitte „Datenbank aktualisieren“ ausführen.":"The log is not available yet. Please run “Update database”.","Das Plugin hat keine gültige Antwort geliefert.":"The plugin did not return a valid response.","Das Ticket verschwindet aus den Listen und kommt zum gewählten Zeitpunkt zurück, mit Benachrichtigung. Antwortet der Kunde früher, kommt es sofort zurück.":"The ticket disappears from the lists and comes back at the chosen time, with a notification. If the customer replies earlier, it comes back immediately.","Das Ticket wird angelegt und gleich geschlossen. Es gibt keine Benachrichtigung an Mitarbeiter oder Kunden.":"The ticket is created and closed immediately. Neither staff nor customers are notified.","Das Ticket wurde nicht gefunden.":"The ticket was not found.","Das Token hat kein Ablaufdatum.":"The token has no expiry date.","Das gesamte Fragen-Log löschen?":"Delete the entire question log?","Das gesamte Fragen-Log wird gelöscht.":"The entire question log will be deleted.","Das sind deutsche Texte, die der Sammelmodus gesehen hat. Sie bilden die Vorlage für ein neues Sprachpaket.":"These are the German texts the collection mode has seen. They form the template for a new language pack.","Das verknüpfte Ticket wurde nicht gefunden.":"The linked ticket was not found.","Datei auf dem Handy herunterladen und öffnen.":"Download the file on your phone and open it.","Datei auswählen":"Choose file","Datei herunterladen und starten.":"Download the file and run it.","Datei per FTP in den Ordner":"Upload the file via FTP into the folder","Datenanonymisierung":"Data anonymization","Datenanonymisierung jetzt manuell ausführen?":"Run data anonymization manually now?","Datenbank":"Database","Datenschutz":"Privacy","Datenschutz & Impressum":"Privacy & legal notice","Datum":"Date","Datum (JJJJ-MM-TT)":"Date (YYYY-MM-DD)","Dazu passend":"Related","Deaktivieren":"Deactivate","Deaktiviert":"Disabled","Der Agent ist Mitglied in folgenden Teams.":"The agent is a member of the following teams.","Der Artikel wurde nicht gefunden.":"The article was not found.","Der Assistent beantwortet Fragen von Kunden aus der Wissensdatenbank und aus den zusätzlichen Antworten. Findet er nichts, bietet er ein Ticket an. Es wird kein externer KI-Dienst verwendet.":"The assistant answers customer questions from the knowledge base and the additional answers. If it finds nothing, it offers a ticket. No external AI service is used.","Der Assistent beantwortet Fragen von Kunden aus der Wissensdatenbank und den zusätzlichen Antworten. Findet er nichts, bietet er ein Ticket an. Es wird kein externer KI-Dienst verwendet.":"The assistant answers customer questions from the knowledge base and the additional answers. If it finds nothing, it offers a ticket. No external AI service is used.","Der Authenticator-Code ist ungültig.":"The authenticator code is invalid.","Der Branding-Rahmen (Kopf-/Fußzeile) wird beim Versand automatisch ergänzt – hier nur den Inhalt anpassen.":"The branding frame (header/footer) is added automatically when sending – only adjust the content here.","Der Eintrag wurde nicht gefunden.":"The entry was not found.","Der Empfänger wurde nicht gefunden.":"The recipient was not found.","Der JSON-Inhalt ist ungültig.":"The JSON content is invalid.","Der Katalog konnte nicht geladen werden: SSL certificate problem: unable to get local issuer certificate":"The catalog could not be loaded: SSL certificate problem: unable to get local issuer certificate","Der Kunde wurde nicht gefunden.":"The customer was not found.","Der Mail-Abruf wurde seit {} nicht ausgeführt. Läuft der Cronjob (cron/fetch_emails.php)?":"Mail retrieval has not run since {}. Is the cron job (cron/fetch_emails.php) running?","Der Mitarbeiter wurde nicht gefunden.":"The staff member was not found.","Der Nachrichtentyp ist ungültig.":"The message type is invalid.","Der Ordner install/ existiert ohne Sperrdatei. Löschen Sie den Ordner install/ vom Server.":"The install/ folder exists without a lock file. Delete the install/ folder from the server.","Der Server hat eine unerwartete Adresse geliefert.":"The server returned an unexpected address.","Der Server hat keine Antwort geliefert.":"The server did not return a response.","Der Server hat keine Datei geliefert.":"The server did not deliver a file.","Der Server hat keine SMTP-Begrüßung gesendet.":"The server did not send an SMTP greeting.","Der Server konnte den Upload-Teil nicht speichern (Speicherplatz oder Schreibrechte). Bitte die Datei per FTP hochladen (Option 1).":"The server could not store the upload part (disk space or write permissions). Please upload the file via FTP (option 1).","Der Server lehnt den Upload-Teil ab, er ist größer als erlaubt (upload_max_filesize":"The server rejects the upload part because it is larger than allowed (upload_max_filesize","Der Status ist ungültig.":"The status is invalid.","Der Upload ist fehlgeschlagen.":"The upload failed.","Der Zielstatus ist ungültig.":"The target status is invalid.","Der ausgewählte Mitarbeiter ist nicht verfügbar.":"The selected staff member is not available.","Der letzte E-Mail-Versand ist fehlgeschlagen ({}): {}":"The last email sending failed ({}): {}","Der since-Zeitstempel ist ungültig.":"The since timestamp is invalid.","Design wechseln":"Switch design","DeskHub Desktop {} · Rechte und Daten kommen vom Server – genau wie in der Android-App.":"DeskHub Desktop {} · Permissions and data come from the server – just like in the Android app.","DeskHub Ticketsystem":"DeskHub ticket system","DeskHub öffnen":"Open DeskHub","Deutsch":"German","Die":"The","Die Abteilung ist ungültig.":"The department is invalid.","Die Aktion ist fehlgeschlagen.":"The action failed.","Die Anfrage ist zu groß.":"The request is too large.","Die Anfrage konnte nicht verarbeitet werden.":"The request could not be processed.","Die Anmeldung ist abgelaufen. Bitte melden Sie sich erneut an.":"The login has expired. Please log in again.","Die Anmeldung lieferte kein Mitarbeiterprofil.":"The sign-in returned no staff profile.","Die Anmeldung lieferte kein Token.":"The sign-in returned no token.","Die Antwort gibt es nicht.":"The reply does not exist.","Die Datei ist zu groß (max. 5 MB).":"The file is too large (max. 5 MB).","Die Datenbank ist noch nicht aktuell. Bitte im Adminportal unter System-Update „Datenbank aktualisieren“ klicken.":"The database is not up to date yet. Please click \"Update database\" in the admin portal under System update.","Die Datenbank ist noch nicht aktuell. Bitte „Datenbank aktualisieren“ ausführen.":"The database is not up to date yet. Please run “Update database”.","Die Liste der Versionen konnte nicht geladen werden: API HTTP 0":"The list of versions could not be loaded: API HTTP 0","Die Mitarbeiter-ID ist ungültig.":"The staff ID is invalid.","Die Nachricht ist zu lang.":"The message is too long.","Die PHP-IMAP-Erweiterung fehlt – eingehende Mails können nicht abgerufen werden.":"The PHP IMAP extension is missing – incoming mail cannot be fetched.","Die Priorität ist ungültig.":"The priority is invalid.","Die Reaktionszeit darf nicht länger als die Lösungszeit sein.":"The response time must not be longer than the resolution time.","Die Regel wurde nicht gefunden.":"The rule was not found.","Die Seite konnte nicht geöffnet werden.":"The page could not be opened.","Die Server-Adresse ist ungültig.":"The server address is invalid.","Die Server-Adresse muss HTTPS verwenden.":"The server address must use HTTPS.","Die Serverantwort ist ungültig.":"The server response is invalid.","Die Sitzung ist abgelaufen oder der Upload-Teil war größer als der Server erlaubt (post_max_size":"The session expired or the upload part was larger than the server allows (post_max_size","Die Sitzung ist abgelaufen. Bitte laden Sie die Seite neu.":"The session has expired. Please reload the page.","Die Wiedervorlage muss in der Zukunft liegen (höchstens 1 Jahr).":"The follow-up must be in the future (1 year at most).","Die angeforderte Seite existiert nicht.":"The requested page does not exist.","Die geschützte Anmeldung konnte nicht gelesen werden und wurde entfernt.":"The protected sign-in could not be read and was removed.","Die geschützte Anmeldung konnte nicht gespeichert werden.":"The protected sign-in could not be saved.","Die heruntergeladene Datei ist beschädigt (Prüfsumme stimmt nicht). Bitte erneut versuchen.":"The downloaded file is damaged (checksum does not match). Please try again.","Die lokale Anmeldung konnte nicht entfernt werden.":"The local sign-in could not be removed.","Die meistgelesenen Antworten aus unserer Wissensdatenbank.":"The most-read answers from our knowledge base.","Die mobile Anmeldung ist ausschließlich über HTTPS erlaubt.":"Mobile login is only allowed via HTTPS.","Dienst entfernen?":"Remove service?","Dienst setzen auf":"Set service to","Dienstag":"Tuesday","Dienste":"Services","Dienste und Störungen für Kunden":"Services and incidents for customers","Dienste und Störungsmeldungen für Kunden":"Services and incident messages for customers","Diese Abteilung ist deaktiviert. Bitte eine aktive Abteilung wählen.":"This department is disabled. Please select an active department.","Diese Adresse gebt ihr beim ersten Start der App ein, danach meldet ihr euch mit eurem Mitarbeiter-Konto an.":"You enter this address when you first start the app, then sign in with your staff account.","Diese Ansicht gehört einem anderen Mitarbeiter.":"This view belongs to another staff member.","Diese Antworten haben Vorrang vor der Wissensdatenbank. Der Assistent findet sie über die Wörter in der Frage und in den Stichwörtern.":"These answers take precedence over the knowledge base. The assistant finds them through the words in the question and in the keywords.","Diese E-Mail-Adresse steht auf der Sperrliste.":"This email address is on the block list.","Diese Funktion ist nur für Administratoren verfügbar.":"This function is only available to administrators.","Diese HTTP-Methode wird nicht unterstützt.":"This HTTP method is not supported.","Diese Kategorie enthält noch Artikel und kann nicht gelöscht werden.":"This category still contains articles and cannot be deleted.","Diese Priorität wird noch von Tickets verwendet und kann nicht gelöscht werden.":"This priority is still used by tickets and cannot be deleted.","Diese Seite darf nicht geöffnet werden.":"This page must not be opened.","Diesen Bericht speichern":"Save this report","Dieser Abteilung sind noch keine Mitarbeiter zugewiesen. Die Zuweisung erfolgt unter „Mitarbeiter“.":"No staff members are assigned to this department yet. Assignment is done under \"Staff\".","Dieser Bericht gehört einem anderen Mitarbeiter.":"This report belongs to another staff member.","Dieser Bewertungslink ist ungültig oder abgelaufen.":"This rating link is invalid or has expired.","Dieser Chat wird gerade von \"{}\" bearbeitet. Sie können nur zuschauen.":"This chat is currently being handled by \"{}\". You can only watch.","Dieser Chat wird gerade von „{}“ bearbeitet – nur Ansicht.":"This chat is currently being handled by \"{}\" – view only.","Dieser Chat wurde beendet.":"This chat has ended.","Dieser Chat wurde bereits beendet.":"This chat has already ended.","Dieser Monat":"This month","Dieses Jahr":"This year","Dieses Ticket":"This ticket","Dieses Ticket wird gerade von \"{}\" bearbeitet und kann nicht gleichzeitig geöffnet werden.":"This ticket is currently being edited by \"{}\" and cannot be opened at the same time.","Dieses Ticket wird gerade von \"{}\" bearbeitet.":"This ticket is currently being edited by \"{}\".","Dieses Ticket wurde nicht gefunden.":"This ticket was not found.","Digitalen Assistenten einschalten":"Enable digital assistant","Digitaler Assistent":"Digital assistant","Dir fehlt das Recht „Tickets erstellen“.":"You lack the \"Create tickets\" permission.","Dir zugewiesen":"Assigned to you","Discord Webhook-URL":"Discord webhook URL","Domain (ganzer Mailanbieter)":"Domain (whole mail provider)","Domain, z.B. spam.de":"Domain, e.g. spam.com","Donnerstag":"Thursday","Dringend":"Urgent","Dropdown-Auswahl":"Dropdown selection","Druckdatum: 24.10.2026 19:44":"Print date: 24.10.2026 19:44","Druckdatum: {}":"Print date: {}","Du beobachtest das Ticket jetzt":"You are now watching the ticket","Du beobachtest das Ticket nicht mehr":"You are no longer watching the ticket","Dunkel":"Dark","E-Mail":"Email","E-Mail (optional)":"Email (optional)","E-Mail / Domain":"Email / domain","E-Mail des Kunden (optional)":"Customer email (optional)","E-Mail, z.B. spam@beispiel.de":"Email, e.g. spam@example.com","E-Mail-Abruf":"Email fetching","E-Mail-Abruf (IMAP)":"Email fetching (IMAP)","E-Mail-Abruf jetzt manuell ausführen?":"Run email fetching manually now?","E-Mail-Adresse":"Email address","E-Mail-Adresse *":"Email address *","E-Mail-Adresse bearbeiten":"Edit email address","E-Mail-Adresse erstellt:":"Email address created:","E-Mail-Adresse oder Passwort ist falsch.":"Email address or password is incorrect.","E-Mail-Adresse und Passwort sind erforderlich.":"Email address and password are required.","E-Mail-Adresse wirklich löschen?":"Really delete this email address?","E-Mail-Adressen":"Email addresses","E-Mail-Adressen verwalten":"Manage email addresses","E-Mail-Adressen werden geladen …":"Loading email addresses …","E-Mail-Versand aktiv (PHP mail() Fallback)":"Email sending active (PHP mail() fallback)","E-Mail-Vorlagen":"Email templates","E-Mail-Vorlagen verwalten":"Manage email templates","E-Mails / Domains":"Emails / domains","Echter Server-Cronjob":"Real server cron job","Eigene Inhaltsseiten für das Kundenportal (z. B. Impressum, Datenschutz, Willkommen). Erreichbar unter":"Custom content pages for the customer portal (e.g. legal notice, privacy, welcome). Available at","Eigene Kundenportal-Themes":"Custom customer portal themes","Eigene Sprache als Plugin erstellen":"Create your own language as a plugin","Eigenen SMTP-Server für diese Adresse verwenden":"Use own SMTP server for this address","Eigenen SMTP-Server verwenden":"Use own SMTP server","Eigener SMTP":"Own SMTP","Eigenes Plugin hochladen":"Upload your own plugin","Eigenschaften":"Properties","Ein JSON-Objekt wird erwartet.":"A JSON object is expected.","Ein Mitarbeiter mit dieser E-Mail-Adresse existiert bereits.":"A staff member with this email address already exists.","Ein gültiges Bearer-Token ist erforderlich.":"A valid bearer token is required.","Ein von dir gesetzter Status bleibt, bis der Mitarbeiter ihn selbst ändert oder du ihn erneut änderst.":"A status you set stays until the staff member changes it or you change it again.","Eine Adresse pro Zeile, optional mit Anzeigename nach einem Komma (z. B.":"One address per line, optionally with a display name after a comma (e.g.","Eine Bedingung":"One condition","Eine E-Mail oder Domain pro Zeile (oder kommagetrennt). Typ wird automatisch erkannt.":"One email or domain per line (or comma-separated). The type is detected automatically.","Eine E-Mail oder Domain pro Zeile. Typ wird automatisch erkannt.":"One email or domain per line. The type is detected automatically.","Eine Priorität mit diesem Namen existiert bereits.":"A priority with this name already exists.","Eine Rolle mit diesem Namen existiert bereits.":"A role with this name already exists.","Eine Ticketnummer ist erforderlich.":"A ticket number is required.","Eingang":"Inbox","Eingangsbestätigung per E-Mail an Kunden senden (nur wenn E-Mail angegeben)":"Send an acknowledgement of receipt to the customer by email (only if an email address was given)","Eingangsbestätigung per E-Mail senden":"Send acknowledgement of receipt by email","Eingeschränkt":"Degraded","Einstellungen":"Settings","Einstellungen bei neuem Ticket":"Settings for new tickets","Einstellungen konnten nicht geladen werden (hat der Server die neueste Version?).":"Settings could not be loaded (does the server have the latest version?).","Einträge":"Entries","Einzeiliger Text":"Single-line text","Einzeln":"Individually","Einzeln sperren":"Block individually","Empfänger (leer = Administratoren), mehrere mit Komma":"Recipients (empty = administrators), several separated by comma","Entfernen":"Remove","Entferntes Postfach":"Remote mailbox","Entferntes Postfach (Abruf per IMAP)":"Remote mailbox (fetch via IMAP)","Entsperren":"Unblock","Entwurf":"Draft","Entwürfe gelöscht":"Drafts deleted","Er bleibt als Ticket erhalten, verschwindet aber aus den aktiven Live-Chats.":"It remains as a ticket but disappears from the active live chats.","Ereignisse":"Events","Erfasste Arbeitszeiten":"Recorded working times","Ergebnis":"Result","Erhalten eine Kopie jeder öffentlichen Antwort per E-Mail.":"Receive a copy of every public reply by email.","Erinnerung (an Kunde, wenn er nicht reagiert)":"Reminder (to customer, if they do not respond)","Erlaubte Datei-Endungen":"Allowed file extensions","Erlaubte Dateitypen":"Allowed file types","Erlaubte IP-Adressen (optional)":"Allowed IP addresses (optional)","Erlaubte IPs":"Allowed IPs","Erledigt":"Done","Erneut":"Again","Erneut versuchen":"Try again","Ersetzt die Zeiten der Priorität für Tickets, deren Hilfethema oder Abteilung diesen Plan nutzt (Hilfethema vor Abteilung).":"Replaces the priority's times for tickets whose help topic or department uses this plan (help topic before department).","Erste Schritte":"Getting started","Erstellen":"Create","Erstellen Sie ein Kundenkonto, um Tickets zu verfolgen.":"Create a customer account to track your tickets.","Erstellen Sie unter Backup eines und prüfen Sie es.":"Create one under Backup and check it.","Erstellt":"Created","Erstellt:":"Created:","Erstreaktion":"First response","Erwartete Prüfsumme (SHA-256, optional)":"Expected checksum (SHA-256, optional)","Erweiterter Zugriff":"Extended access","Erwähnungen":"Mentions","Es sind noch keine Teams angelegt.":"No teams have been created yet.","Es sind noch keine Teams angelegt. Teams legst du unter":"No teams have been created yet. You create teams under","Es wird keine Signatur angehängt.":"No signature will be attached.","Eskalationsregeln":"Escalation rules","Eskalationsregeln jetzt manuell ausführen?":"Run escalation rules manually now?","Eskalationsregeln verwalten":"Manage escalation rules","Eskalationsregeln werden stündlich per Cron geprüft (":"Escalation rules are checked hourly via cron (","Exportieren (CSV)":"Export (CSV)","Externer Link":"External link","Externer Link (optional)":"External link (optional)","FTP speichern":"Save FTP","FTP-Host":"FTP host","FTP-Rotation (Kopien auf Server)":"FTP rotation (copies on server)","Falls Windows warnt („Der Computer wurde geschützt“):":"If Windows warns (\"Windows protected your PC\"):","Farbe (#RRGGBB)":"Color (#RRGGBB)","Favicon (Symbol im Browser-Tab)":"Favicon (icon in the browser tab)","Fehler:":"Error:","Feiertag hinzufügen":"Add holiday","Feiertage":"Holidays","Feiertage (0)":"Holidays (0)","Feiertage / Schließtage":"Holidays / closing days","Feiertage automatisch übernehmen":"Import holidays automatically","Feld":"Field","Feldtyp":"Field type","Fenster schließen":"Close window","Fertig":"Done","Fertige Designs direkt installieren. Prüfsumme und Signatur werden vor der Installation geprüft.":"Install ready-made designs directly. Checksum and signature are verified before installation.","Filter in der":"Filter in the","Filter zurücksetzen":"Reset filters","Filtern":"Filter","Firmenlogo":"Company logo","Formular":"Form","Frage":"Question","Frage / Thema":"Question / topic","Frage / Thema *":"Question / topic *","Frage ausprobieren":"Try a question","Fragen-Log":"Question log","Fragen-Log geleert":"Question log cleared","Fragen-Log leeren?":"Clear question log?","Fragen-Log: Aufbewahrung in Tagen (0 = nichts speichern)":"Question log: retention in days (0 = store nothing)","Frei konfigurierbare Auswertungen nach Erstellungsdatum der Tickets":"Freely configurable reports by ticket creation date","Freitag":"Friday","Fällig":"Due","Fällig bis":"Due until","Fällig bis (JJJJ-MM-TT HH:MM, optional)":"Due until (YYYY-MM-DD HH:MM, optional)","Für Kunden sichtbar (auf „Neues Ticket“)":"Visible to customers (on \"New ticket\")","Für alle Abteilungen":"For all departments","Für alle Mitarbeiter sichtbar":"Visible to all staff","Für automatische Backups den Cron einrichten:":"Set up cron for automatic backups:","Für dich":"For you","Für diese Aktion fehlt die erforderliche Berechtigung.":"The required permission for this action is missing.","Für diese Funktion fehlt die erforderliche Berechtigung.":"The required permission for this function is missing.","Gast":"Guest","Gast-Kunde":"Guest customer","Gast-Ticket zum Konto hinzufügen":"Add guest ticket to your account","Gedruckt: 24.10.2026 19:44":"Printed: 24.10.2026 19:44","Gedruckt: {}":"Printed: {}","Gefährliche Typen (PHP, EXE, SH etc.) werden immer blockiert – unabhängig von dieser Liste.":"Dangerous types (PHP, EXE, SH etc.) are always blocked – regardless of this list.","Gelöscht":"Deleted","Gelöst":"Resolved","Gelöst diesen Monat":"Resolved this month","Gelöst/Geschlossen":"Resolved/Closed","Genutzt":"Used","Geprüfte Plugins":"Verified plugins","Gerade ist niemand verfügbar – wir antworten aber, sobald wir wieder da sind.":"Nobody is available right now – we will reply as soon as we are back.","Gesammelte Texte löschen?":"Delete collected texts?","Gesammelte Texte: 556":"Collected texts: 556","Gesammelte Texte: {#}":"Collected texts: {}","Gesamt":"Total","Gesamt: {} Minuten":"Total: {} minutes","Gesamter Zeitraum":"Entire period","Gesamtgröße":"Total size","Geschlossen":"Closed","Geschäftszeiten":"Business hours","Geschäftszeiten für SLA-Berechnung verwenden":"Use business hours for SLA calculation","Geschäftszeiten verwalten":"Manage business hours","Geschäftszeiten werden geladen …":"Loading business hours …","Gespeichert":"Saved","Gespeichert ({} Gruppen)":"Saved ({} groups)","Gespeichert werden: assigned":"Saved: assigned","Gespeichert werden: keine Filter (alle Tickets)":"Saved: no filters (all tickets)","Gespeichert werden: status":"Saved: status","Gespeichert.":"Saved.","Gespeicherte Ansichten":"Saved views","Gespeicherte Berichte":"Saved reports","Gespeicherte Entwürfe löschen":"Delete saved drafts","Gespeicherte Zugangsdaten (SMTP, IMAP, Webhooks) sind mit einem eigenen Schlüssel verschlüsselt.":"Stored credentials (SMTP, IMAP, webhooks) are encrypted with a separate key.","Gesperrt":"Blocked","Gesperrt am":"Blocked on","Gesperrte Einträge (0)":"Blocked entries (0)","Geteilt von {}":"Shared by {}","Geöffnet":"Opened","Gilt für Hilfe-Thema":"Applies to help topic","Gilt für Tickets aus Formular, E-Mail, API und Live-Chat. Eine Ticket-Regel mit „Mitarbeiter zuweisen“ hat Vorrang. Im Urlaub bekommt die Vertretung das Ticket, „Reihum“ überspringt Mitarbeiter im Urlaub oder offline.":"Applies to tickets from the form, email, API and live chat. A ticket rule with \"Assign staff member\" takes precedence. On vacation, the substitute gets the ticket; \"Round robin\" skips staff on vacation or offline.","Gleichbedeutende Wörter":"Synonyms","Gleichbedeutende Wörter gespeichert":"Synonyms saved","Grund":"Reason","Grund (optional)":"Reason (optional)","Grund für alle (optional)":"Reason for all (optional)","Gruppe":"Group","Gruppieren nach":"Group by","Guten Abend":"Good evening","Guten Abend, {}":"Good evening, {}","Guten Morgen":"Good morning","Guten Morgen, {}":"Good morning, {}","Guten Tag":"Hello","Guten Tag, {}":"Hello, {}","HTML-Inhalt (Popup)":"HTML content (popup)","HTML-Inhalt (öffnet Popup). Ist ein Link gesetzt, wird das HTML-Feld ignoriert.":"HTML content (opens popup). If a link is set, the HTML field is ignored.","Handlungsbedarf ·":"Action needed ·","Hauptabteilung":"Main department","Hauptrolle":"Main role","Hell":"Light","Helpdesk-Status":"Helpdesk status","Herkunft":"Origin","Hessen":"Hesse","Heute":"Today","Heute gelöst":"Resolved today","Hier finden Sie das Archiv und den Verlauf Ihrer aktuellen und vorherigen Supportanfragen inklusive der Antworten.":"Here you can find the archive and history of your current and previous support requests, including the replies.","Hier finden Sie den Verlauf und Status Ihrer aktuellen und bisherigen Supportanfragen.":"Here you can find the history and status of your current and previous support requests.","Hier ist noch keine Android-App hinterlegt.":"No Android app has been stored here yet.","Hier ist noch keine Windows-App hinterlegt.":"No Windows app has been stored here yet.","Hier könnt ihr eigene Plugins als ZIP installieren oder aktualisieren, auch ohne Signatur. Diese Plugins sind":"Here you can install or update your own plugins as ZIP, even without a signature. These plugins are","Hilfe-Thema":"Help topic","Hilfe-Thema (optional)":"Help topic (optional)","Hilfe-Thema setzen":"Set help topic","Hilfe-Themen":"Help topics","Hilfe-Themen verwalten":"Manage help topics","Hilfethema":"Help topic","Hilfethema aktualisieren":"Update help topic","Hilfethema erstellt:":"Help topic created:","Hilfethema wirklich löschen?":"Really delete this help topic?","Hilfethemen":"Help topics","Hilfethemen werden geladen …":"Loading help topics …","Hilfethemeninformationen":"Help topic information","Hintergrundbild im dunklen Hero-Bereich. Mind. 1600×500 px, max. 5 MB.":"Background image in the dark hero area. At least 1600×500 px, max. 5 MB.","Hinweis für Administratoren: Zum Aktualisieren einer App die neue Datei per FTP in":"Note for administrators: to update an app, upload the new file via FTP to","Hinweis:":"Note:","Hinweise":"Notes","Hinweise ·":"Notes ·","Hinweistext (optional)":"Note text (optional)","Hinzufügen":"Add","Hoch":"High","Hochladen":"Upload","Hochladen & installieren":"Upload & install","Hochladen →":"Upload →","Hohe Priorität":"High priority","Häufige Fragen":"Frequently asked questions","Häufige Fragen ohne Antwort":"Frequent questions without an answer","IP-Adresse":"IP address","IP-Adressen sofort beim Speichern kürzen (letztes Oktett entfernen)":"Shorten IP addresses immediately when saving (remove last octet)","Ich wurde erwähnt":"I was mentioned","Ihr Anliegen":"Your request","Ihr Name":"Your name","Ihre Bewertung – {}":"Your rating – {}","Ihre E-Mail-Adresse":"Your email address","Ihre Kontaktdaten":"Your contact details","Ihre Nachricht...":"Your message...","Ihre Nachricht…":"Your message…","Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es erneut.":"Your session has expired. Please reload the page and try again.","Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu.":"Your session has expired. Please reload the page.","Im Browser öffnen: zusammenführen, aufteilen, drucken":"Open in browser: merge, split, print","Im Zeitraum wurden noch keine Abfragen verschickt.":"No surveys were sent in this period.","Immer (zum Testen)":"Always (for testing)","Immer an einen bestimmten Mitarbeiter":"Always to a specific staff member","Impressum":"Legal notice","In 1 Stunde":"In 1 hour","In 1 Woche":"In 1 week","In 3 Stunden":"In 3 hours","In 3 Tagen":"In 3 days","In Arbeit":"In progress","In Betrieb":"Operational","In Ordner verschieben":"Move to folder","In der Datei":"In the file","Inaktiv":"Inactive","Individuelle Berechtigungen":"Individual permissions","Individuelle Ticket-Felder":"Custom ticket fields","Informationen":"Information","Inhalt":"Content","Inhalt / Zusammenfassung":"Content / summary","Installierte Sprachen":"Installed languages","Installierte Version":"Installed version","Intern":"Internal","Interne Notiz":"Internal note","Interne Notizen":"Internal notes","Interne Notizen (vertraulich)":"Internal notes (confidential)","Interne Notizen schreiben":"Write internal notes","Interner Chat":"Internal chat","Interner Kommentar…":"Internal comment…","Jahr":"Year","Jeder Job kann hier zusätzlich jederzeit sofort manuell gestartet werden.":"Each job can also be started manually at any time here.","Jedes Postfach wird beim Abruf (Cronjob":"Each mailbox is queried individually when fetching (cron job","Jetzt aktualisieren":"Update now","Jetzt anmelden":"Sign in now","Jetzt ausführen":"Run now","Jetzt erneut versuchen":"Try again now","Jetzt registrieren":"Register now","Kanal (web/email)":"Channel (web/email)","Kanal-Einstellungen → Integrationen → Webhooks → Neuer Webhook":"Channel settings → Integrations → Webhooks → New webhook","Katalog aktualisieren":"Refresh catalog","Kategorie":"Category","Kategorie wirklich löschen?":"Really delete this category?","Kategorien":"Categories","Kein Absturzbericht übermittelt.":"No crash report was submitted.","Kein Hilfethema":"No help topic","Kein Konto nötig:":"No account needed:","Kein Kunde ausgewählt.":"No customer selected.","Kein Live-Chat ausgewählt":"No live chat selected","Kein Logo hinterlegt.":"No logo stored.","Kein Spam":"Not spam","Kein Ticket ausgewählt.":"No ticket selected.","Kein Titelbild hinterlegt.":"No cover image stored.","Kein Token eingetragen (öffentlicher Zugriff).":"No token entered (public access).","Kein Update seit X Stunden":"No update for X hours","Kein Zugriff auf diese Abteilung.":"No access to this department.","Kein Zugriff auf diese Datei.":"No access to this file.","Kein Zugriff.":"No access.","Kein Zugriffstoken (Dienstkonto prüfen)":"No access token (check the service account)","Kein eigenes Favicon hinterlegt.":"No custom favicon stored.","Keine":"None","Keine Aktualisierung seit …":"No update since …","Keine Antwort seit …":"No reply since …","Keine Aufgaben gefunden.":"No tasks found.","Keine Aufgaben.":"No tasks.","Keine Berechtigung.":"No permission.","Keine Berechtigungen":"No permissions","Keine Daten verfügbar.":"No data available.","Keine Einträge.":"No entries.","Keine Erwähnungen vorhanden.":"No mentions.","Keine Kunden gefunden.":"No customers found.","Keine Meldungen.":"No messages.","Keine Mitarbeiter gefunden.":"No staff found.","Keine Mitarbeiter-Antwort seit X Stunden":"No staff reply for X hours","Keine Signatur":"No signature","Keine Signatur hinterlegt.":"No signature stored.","Keine Störungen in den letzten 14 Tagen.":"No incidents in the last 14 days.","Keine Tickets gefunden.":"No tickets found.","Keine Tickets im gewählten Zeitraum.":"No tickets in the selected period.","Keine Tickets mit diesen Filtern. Unter „Aktiv“ kannst du „Alle Status“ wählen, um auch erledigte Tickets zu sehen.":"No tickets with these filters. Under \"Active\" you can choose \"All statuses\" to also see completed tickets.","Keine Tickets vorhanden.":"No tickets available.","Keine Treffer für diese Suche.":"No results for this search.","Keine Treffer.":"No results.","Keine Update-Information vorhanden.":"No update information available.","Keine Verbindung zum Server – nächster Versuch in {} s. Bereits geladene Daten sind eventuell veraltet.":"No connection to the server – next attempt in {} s. Data already loaded may be outdated.","Keine Verbindung zum Server.":"No connection to the server.","Keine Verbindung zum Server. Es wird automatisch erneut versucht.":"No connection to the server. It will be retried automatically.","Keine Zeiteinträge im gewählten Zeitraum.":"No time entries in the selected period.","Keine aktive DeskHub-Sitzung.":"No active DeskHub session.","Keine aktiven Chats":"No active chats","Keine lokale Anmeldung vorhanden.":"No local sign-in available.","Keine passende Antwort: Der Assistent würde anbieten, ein Ticket zu erstellen. Lege dafür eine zusätzliche Antwort an oder ergänze die Wissensdatenbank.":"No matching answer: the assistant would offer to create a ticket. Create an additional answer for it or extend the knowledge base.","Keine vorhanden.":"None available.","Keine weitere Einstellung nötig.":"No further setting needed.","Keine weiteren Mitarbeiter vorhanden.":"No more staff available.","Keine weiteren Tickets.":"No more tickets.","Kennzahlen":"Key figures","Klicke rechts auf einen Mitarbeiter":"Click a staff member on the right","Kollaborator hinzugefügt: {}":"Collaborator added: {}","Kollaboratoren":"Collaborators","Kollegen auswählen":"Select colleagues","Kommentieren":"Comment","Konfiguration":"Configuration","Kontaktdaten":"Contact details","Kontakte":"Contacts","Kontakte werden geladen …":"Loading contacts …","Konten und Zugriff":"Accounts and access","Konten, Rollen, Abteilungszugriff":"Accounts, roles, department access","Konto":"Account","Konto erstellen":"Create account","Konto erstellen – {}":"Create account – {}","Kontodaten":"Account details","Kontoinformationen":"Account information","Kontotyp":"Account type","Kopieren":"Copy","Kostenloses Konto erstellen":"Create a free account","Kunde":"Customer","Kunde nicht gefunden.":"Customer not found.","Kunde tippt …":"Customer is typing …","Kunden":"Customers","Kunden erinnern, wenn sie auf eine Antwort nicht reagieren (einmalig, vor dem automatischen Schließen)":"Remind customers if they do not respond to a reply (once, before automatic closing)","Kunden per E-Mail benachrichtigen":"Notify customers by email","Kunden werden geladen …":"Loading customers …","Kunden zu Firmen bündeln":"Group customers into companies","Kunden-Organisationen":"Customer organizations","Kundendaten":"Customer data","Kundenerinnerung":"Customer reminder","Kundenerinnerung jetzt manuell ausführen?":"Run customer reminder manually now?","Kundenprofil":"Customer profile","Kundenprofil wird geladen …":"Loading customer profile …","Kundenprofil: {}":"Customer profile: {}","Kundenverzeichnis":"Customer directory","Kundenzufriedenheit":"Customer satisfaction","Kundenzufriedenheit (letzte 30 Tage)":"Customer satisfaction (last 30 days)","Kundenzufriedenheit ({} Tage)":"Customer satisfaction ({} days)","Kurzbeschreibung (optional)":"Short description (optional)","Kurze Zusammenfassung Ihres Problems":"Short summary of your problem","Lade …":"Loading …","Lade…":"Loading…","Leere Vorlage laden":"Load empty template","Legen Sie fest, welche zusätzlichen Bereiche auf der Kundenportal-Startseite angezeigt werden.":"Choose which additional sections are shown on the customer portal home page.","Leiter, Mitglieder, E-Mail":"Lead, members, email","Leiter: {} · {} Mitglieder":"Lead: {} · {} members","Leitung":"Lead","Leserecht":"Read permission","Letzte 30 Tage":"Last 30 days","Letzte 7 Tage":"Last 7 days","Letzte Zustellung":"Last delivery","Letzter Abruf":"Last fetch","Letzter Abruf: {}.":"Last fetch: {}.","Letzter Erfolg: {}":"Last success: {}","Letztes Auto-Backup":"Last auto backup","Letztes Backup":"Last backup","Link anfordern":"Request link","Link kopieren":"Copy link","Link kopiert":"Link copied","Link nicht gültig":"Link not valid","Link-Adresse":"Link address","Live-Chat":"Live chat","Live-Chat (Kunden)":"Live chat (customers)","Live-Chat im Kundenportal (Chat-Widget unten rechts, auch ohne Kundenkonto nutzbar)":"Live chat in the customer portal (chat widget at the bottom right, also usable without a customer account)","Live-Chat ist derzeit":"Live chat is currently","Live-Chat {} · Wissensdatenbank im Portal {}":"Live chat {} · Knowledge base in the portal {}","Log geleert":"Log cleared","Log leeren":"Clear log","Lädt …":"Loading …","Löschen":"Delete","Lösen":"Resolve","Lösung":"Solution","Lösung (Std)":"Resolution (hrs)","Lösung (h)":"Resolution (h)","Lösung fällig":"Resolution due","Lösung fällig: {}":"Resolution due: {}","Lösungszeit (Std)":"Resolution time (hrs)","Lösungszeit (Std.)":"Resolution time (hrs.)","Mail senden nach":"Send email after","Manuell":"Manual","Manuelles Update":"Manual update","Markierte Tickets wirklich unwiderruflich löschen?":"Really delete the selected tickets permanently?","Maximale Dateigröße":"Maximum file size","Mecklenburg-Vorpommern":"Mecklenburg-Western Pomerania","Mehr":"More","Mehr laden":"Load more","Mehrere":"Several","Mehrere Adressen auf einmal anlegen":"Create several addresses at once","Mehrere sperren":"Block several","Mehrzeiliger Text":"Multi-line text","Mein Profil":"My profile","Mein Status":"My status","Mein Status:":"My status:","Meine":"My","Meine Ansicht":"My view","Meine Erwähnungen":"My mentions","Meine Signatur":"My signature","Meine Signatur (nicht hinterlegt)":"My signature (not set)","Meine Signatur bearbeiten":"Edit my signature","Meine Tickets":"My tickets","Meine Tickets ansehen":"View my tickets","Meine Tickets – {}":"My tickets – {}","Meine offenen":"My open","Melden Sie sich an, um alle Ihre Tickets im Überblick zu sehen.":"Sign in to see all your tickets at a glance.","Meldung gelöscht":"Message deleted","Meldung löschen":"Delete message","Meldung löschen?":"Delete message?","Meldung veröffentlicht":"Message published","Meldungen":"Messages","Meldungen (letzte 14 Tage)":"Messages (last 14 days)","Mindestens 10 Zeichen mit Groß- und Kleinbuchstaben, einer Ziffer und einem Sonderzeichen.":"At least 10 characters with upper and lower case letters, a digit and a special character.","Mindestens eine Bedingung":"At least one condition","Minuten":"Minutes","Minuten (5–480). Countdown wird oben rechts angezeigt.":"Minutes (5–480). Countdown is shown at the top right.","Minuten ohne Aktivität":"Minutes without activity","Mir zugewiesen":"Assigned to me","Mir zuweisen":"Assign to me","Mit Windows starten":"Start with Windows","Mit deinem Mitarbeiterkonto anmelden":"Sign in with your staff account","Mit den Apps bearbeitet ihr Tickets am PC oder unterwegs. Beide haben ein helles und dunkles Design.":"With the apps you work on tickets at the PC or on the go. Both have a light and a dark design.","Mitarbeiter":"Staff","Mitarbeiter (nur bei „Immer an einen bestimmten Mitarbeiter“)":"Staff member (only for \"Always to a specific staff member\")","Mitarbeiter auswählen":"Select staff member","Mitarbeiter können diese Textbausteine beim Beantworten eines Tickets per Klick in die Antwort einfügen.":"Staff can insert these text snippets into a reply with one click when answering a ticket.","Mitarbeiter löschen":"Delete staff member","Mitarbeiter nicht gefunden.":"Staff member not found.","Mitarbeiter tippt …":"Agent is typing …","Mitarbeiter verwalten":"Manage staff","Mitarbeiter werden geladen …":"Loading staff …","Mitarbeiter wirklich löschen?":"Really delete this staff member?","Mitarbeiter zuweisen":"Assign staff member","Mitarbeiter-Anmeldung":"Staff sign-in","Mitarbeiter-Bereich":"Staff area","Mitarbeiter-Gruppen":"Staff groups","Mitarbeiter-Login – {}":"Staff login – {}","Mitarbeiter-Login →":"Staff login →","Mitarbeiter-Verzeichnis":"Staff directory","Mitarbeiterbereich":"Staff area","Mitglied in Teams":"Member of teams","Mitglieder":"Members","Mitglieder (2)":"Members (2)","Mitglieder lassen sich nach dem Erstellen unter „Mitarbeiter“ zuweisen.":"Members can be assigned under \"Staff\" after creating.","Mitglieder: {}":"Members: {}","Mittwoch":"Wednesday","Monat":"Month","Monate":"Months","Monatlich":"Monthly","Montag":"Monday","Morgen 8:00":"Tomorrow 8:00","Morgen früh (8:00 Uhr)":"Tomorrow morning (8:00)","Nach Mitarbeiter:":"By staff member:","Nach Priorität":"By priority","Nach Status":"By status","Nach Stunden":"By hours","Nach dem Update Browser-Cache leeren":"Clear the browser cache after the update","Nach wie vielen Tagen ohne Kundenreaktion":"After how many days without customer response","Nach wie vielen Tagen ohne Reaktion":"After how many days without response","Nachricht":"Message","Nachricht eingeben...":"Enter message...","Nachricht verfassen":"Compose message","Nachricht …":"Message …","Nachricht…":"Message…","Nachricht… (Strg+Enter zum Senden)":"Message… (Ctrl+Enter to send)","Name der Ansicht":"Name of the view","Name der Vorlage":"Name of the template","Name des Assistenten":"Name of the assistant","Name des Kunden":"Customer name","Name in der Benachrichtigung (optional)":"Name in the notification (optional)","Name oder E-Mail":"Name or email","Name oder E-Mail suchen…":"Search name or email…","Nebeneinander":"Side by side","Neu":"New","Neue Abteilung":"New department","Neue Abteilung hinzufügen":"Add new department","Neue Adresse":"New address","Neue Antwort":"New reply","Neue Antwort (an Kunde)":"New reply (to customer)","Neue Aufgabe":"New task","Neue E-Mail-Adresse":"New email address","Neue Eskalationsregel":"New escalation rule","Neue Kategorie":"New category","Neue Kundenantwort":"New customer reply","Neue Liste hinzufügen":"Add new list","Neue Meldung (Störung oder Wartung)":"New message (incident or maintenance)","Neue Organisation":"New organization","Neue Priorität":"New priority","Neue Priorität hinzufügen":"Add new priority","Neue Regel":"New rule","Neue Regel hinzufügen":"Add new rule","Neue Rolle":"New role","Neue Rolle hinzufügen":"Add new role","Neue Seite hinzufügen":"Add new page","Neue Stufe":"New level","Neue Ticket-Regel":"New ticket rule","Neue Tickets automatisch zuweisen":"Assign new tickets automatically","Neue Tickets, Kundenantworten und Zuweisungen":"New tickets, customer replies and assignments","Neue Vorlage":"New template","Neuen Agenten hinzufügen":"Add new agent","Neuen Chat starten":"Start a new chat","Neuen SLA-Plan hinzufügen":"Add new SLA plan","Neuen Schlüssel erstellen":"Create new key","Neuen Webhook hinzufügen":"Add new webhook","Neuer Agent":"New agent","Neuer Artikel":"New article","Neuer Dienst, z. B. Webseite":"New service, e.g. website","Neuer Live-Chat":"New live chat","Neuer Mitarbeiter":"New staff member","Neuer SLA-Plan":"New SLA plan","Neues Bild hochladen (JPG, PNG, WEBP · max. 2 MB)":"Upload new image (JPG, PNG, WEBP · max. 2 MB)","Neues Feld":"New field","Neues Hilfethema":"New help topic","Neues Hilfethema hinzufügen":"Add new help topic","Neues Passwort":"New password","Neues Passwort (leer = unverändert)":"New password (empty = unchanged)","Neues Postfach":"New mailbox","Neues Team":"New team","Neues Team hinzufügen":"Add new team","Neues Ticket":"New ticket","Neues Ticket (an Abteilung)":"New ticket (to department)","Neues Ticket erstellen":"Create new ticket","Neues Ticket eröffnen":"Open a new ticket","Neues Ticket für diesen Kunden":"New ticket for this customer","Neues Ticket – {}":"New ticket – {}","Nicht angemeldet.":"Not signed in.","Nicht automatisch zuweisen":"Do not assign automatically","Nicht für den Produktivbetrieb geeignet. Bitte in":"Not suitable for production use. Please in","Nicht gespeichert: bitte Uhrzeiten prüfen (z. B. 22:00) oder später erneut versuchen.":"Not saved: please check the times (e.g. 22:00) or try again later.","Nicht mehr beobachten":"Stop watching","Nicht prüfbar: die eigene Adresse ließ sich nicht abrufen.":"Cannot be checked: your own address could not be fetched.","Nicht unterstützte HTTP-Methode: {}":"Unsupported HTTP method: {}","Nicht zugew.":"Unassigned","Nicht zugewiesen":"Unassigned","Niedersachsen":"Lower Saxony","Niedrig":"Low","Niemand. Beobachter bekommen Benachrichtigungen, ohne dass ihnen das Ticket zugewiesen ist.":"Nobody. Watchers receive notifications without the ticket being assigned to them.","Niemand. Cc-Empfänger bekommen die öffentlichen Antworten per E-Mail in Kopie.":"Nobody. Cc recipients receive the public replies by email in copy.","Noch kein Konto?":"No account yet?","Noch kein Postfach angelegt.":"No mailbox created yet.","Noch keine API-Schlüssel angelegt.":"No API keys created yet.","Noch keine Abfragen verschickt.":"No surveys sent yet.","Noch keine Abteilungen.":"No departments yet.","Noch keine Artikel.":"No articles yet.","Noch keine Backups vorhanden.":"No backups available yet.","Noch keine Dienste eingetragen.":"No services entered yet.","Noch keine E-Mail-Adressen angelegt.":"No email addresses created yet.","Noch keine Einträge.":"No entries yet.","Noch keine Eskalationsregeln. Erstellen Sie eine neue Regel mit dem Button oben.":"No escalation rules yet. Create a new rule with the button above.","Noch keine Eskalationsregeln. Mit + eine neue Regel anlegen.":"No escalation rules yet. Create a new rule with +.","Noch keine Feiertage eingetragen.":"No holidays entered yet.","Noch keine Hilfethemen.":"No help topics yet.","Noch keine Listen angelegt.":"No lists created yet.","Noch keine Muster angelegt.":"No patterns created yet.","Noch keine Nachrichten vorhanden.":"No messages yet.","Noch keine Nachrichten.":"No messages.","Noch keine Nachrichten. Schreib die erste!":"No messages yet. Write the first one!","Noch keine Notizen.":"No notes yet.","Noch keine Organisationen angelegt.":"No organizations created yet.","Noch keine Organisationen.":"No organizations yet.","Noch keine Plugins installiert.":"No plugins installed yet.","Noch keine Prioritäten.":"No priorities yet.","Noch keine SLA-Pläne angelegt.":"No SLA plans created yet.","Noch keine Seiten angelegt.":"No pages created yet.","Noch keine Teams angelegt.":"No teams created yet.","Noch keine Teams.":"No teams yet.","Noch keine Ticket-Regeln angelegt.":"No ticket rules created yet.","Noch keine Ticket-Regeln. Mit + eine neue Regel anlegen.":"No ticket rules yet. Create a new rule with +.","Noch keine Vorlagen.":"No templates yet.","Noch keine Webhooks angelegt.":"No webhooks created yet.","Noch keine Zeit erfasst.":"No time recorded yet.","Noch keine benutzerdefinierten Rollen angelegt.":"No custom roles created yet.","Noch keine benutzerdefinierten Rollen. Ohne eigene Rolle gelten die Standard-Agentenrechte.":"No custom roles yet. Without a role of their own, the default agent permissions apply.","Noch keine eigenen Themes hochgeladen.":"No custom themes uploaded yet.","Noch keine gespeicherten Ansichten vorhanden.":"No saved views yet.","Noch keine individuellen Felder angelegt.":"No custom fields created yet.","Noch keine zusätzlichen Antworten.":"No additional answers yet.","Noch nie":"Never","Nordrhein-Westfalen":"North Rhine-Westphalia","Normale Tickets":"Normal tickets","Notiz":"Note","Notiz (optional)":"Note (optional)","Notiz (optional, z.B. «In Besprechung bis 14:00»)":"Note (optional, e.g. \"In a meeting until 14:00\")","Notiz gespeichert":"Note saved","Notiz hinzufügen…":"Add note…","Notiz speichern":"Save note","Notizen":"Notes","Notizen (optional)":"Notes (optional)","Nr.":"No.","Nummer kopieren":"Copy number","Nummer kopiert":"Number copied","Nur Abteilung":"Department only","Nur Administratoren dürfen den Status anderer Mitarbeiter ändern.":"Only administrators may change the status of other staff members.","Nur Administratoren dürfen die Statusseite ändern.":"Only administrators may change the status page.","Nur Administratoren können Ticket-Regeln verwalten.":"Only administrators can manage ticket rules.","Nur Administratoren können die Sperre eines anderen Mitarbeiters aufheben.":"Only administrators can release another staff member’s lock.","Nur Bereiche, für die du freigeschaltet bist.":"Only areas you are authorized for.","Nur Domain angeben, z.B. spam.de (ohne @).":"Enter the domain only, e.g. spam.com (without @).","Nur E-Mail-Tickets können als Spam geändert werden.":"Only email tickets can be changed to spam.","Nur Lesezugriff, solange {} diesen Chat bearbeitet.":"Read-only while {} is handling this chat.","Nur Priorität":"Priority only","Nur Status (kommagetrennt, z.B. open,pending)":"Only status (comma-separated, e.g. open,pending)","Nur ausfüllen, wenn der Anbieter eine Prüfsumme nennt":"Only fill in if the provider states a checksum","Nur ausfüllen, wenn der Anbieter eine Signatur nennt":"Only fill in if the provider states a signature","Nur benachrichtigen":"Notify only","Nur in der installierten Version verfügbar.":"Only available in the installed version.","Nur interne Notiz speichern":"Save internal note only","Nur nötig, wenn das Repository mit den Releases":"Only needed if the repository with the releases","Nur signierte Releases:":"Signed releases only:","Nur wenn der Live-Chat aus oder niemand erreichbar ist (Standard)":"Only if live chat is off or nobody can be reached (default)","Nur wenn der Live-Chat ausgeschaltet oder niemand erreichbar ist (Standard)":"Only if live chat is switched off or nobody can be reached (default)","ODER":"OR","Offen":"Open","Offene Tickets":"Open tickets","Offline (Wartungsmodus)":"Offline (maintenance mode)","Offline-Nachricht":"Offline message","Ohne Konto: Geben Sie Ihre Ticketnummer und E-Mail-Adresse ein.":"Without an account: enter your ticket number and email address.","Ohne eigenen Server wird der globale SMTP aus den Einstellungen genutzt.":"Without its own server the global SMTP from the settings is used.","Online Mitarbeiter":"Staff online","Option 1: Datei in den DeskHub-Ordner legen (für große Dateien empfohlen)":"Option 1: put the file in the DeskHub folder (recommended for large files)","Option 2: Direkt hochladen (in Teilen von 5 MB, passend zum Limit dieses Servers)":"Option 2: upload directly (in 5 MB parts, matching this server's limit)","Optionale Felder beim Anlegen:":"Optional fields when creating:","Optionen":"Options","Optionen (eine pro Zeile)":"Options (one per line)","Optionen bei neuem Ticket":"Options for new tickets","Ordner":"Folder","Ordner mit diesen Dateien packen:":"Pack the folder with these files:","Organisation":"Organization","Organisation bearbeiten":"Edit organization","Organisationen":"Organizations","Organisationen verwalten":"Manage organizations","Organisationen werden geladen …":"Loading organizations …","Passwort":"Password","Passwort (leer = unverändert)":"Password (empty = unchanged)","Passwort *":"Password *","Passwort eingeben":"Enter password","Passwort vergessen":"Forgot password","Passwort vergessen – {}":"Forgot password – {}","Passwort vergessen?":"Forgot your password?","Passwort wiederholen":"Repeat password","Passwort ändern":"Change password","Pause":"Break","Pausiert":"Paused","Pflichtfeld":"Required field","Pflichtfelder sind mit":"Required fields are marked with","Platzhalter:":"Placeholders:","Plugin-Endpunkt nicht gefunden oder Plugin nicht aktiv.":"Plugin endpoint not found or plugin not active.","Plugins (Hintergrundaufgaben)":"Plugins (background tasks)","Plugins (Hintergrundaufgaben) jetzt manuell ausführen?":"Run plugins (background tasks) manually now?","Popups und stille Zeiten":"Popups and quiet hours","Postfach":"Mailbox","Postfach / Ordner":"Mailbox / folder","Postfach testen":"Test mailbox","Postfach „{}“ ist nicht erreichbar ({#} Fehlversuche in Folge).":"Mailbox “{}” is not reachable ({} consecutive failed attempts).","Postfach „{}“ ist nicht erreichbar ({#} Fehlversuche in Folge). {}":"Mailbox “{}” is not reachable ({} consecutive failed attempts). {}","Postfach „{}“: letzter Abruf fehlgeschlagen.":"Mailbox “{}”: last retrieval failed.","Postfach „{}“: letzter Abruf fehlgeschlagen. {}":"Mailbox “{}”: last retrieval failed. {}","Postfächer (E-Mail-Abruf)":"Mailboxes (email fetching)","Postfächer für den E-Mail-Abruf":"Mailboxes for email fetching","Postfächer verwalten →":"Manage mailboxes →","Postfächer werden jetzt direkt bei der jeweiligen":"Mailboxes are now fetched directly at the respective","Priorisiert: mir zugewiesen oder unbearbeitet":"Prioritized: assigned to me or unprocessed","Priorität":"Priority","Priorität bearbeiten":"Edit priority","Priorität für Tickets des Assistenten":"Priority for assistant tickets","Priorität setzen":"Set priority","Priorität wirklich löschen?":"Really delete this priority?","Priorität:":"Priority:","Prioritäten & SLA-Zeiten":"Priorities & SLA times","Prioritäten / SLA":"Priorities / SLA","Prioritäten / SLA verwalten":"Manage priorities / SLA","Prioritäten werden geladen …":"Loading priorities …","Profil":"Profile","Profilbild":"Profile picture","Protokoll wird geladen …":"Loading log …","Prüfen ·":"Check ·","Push fehlgeschlagen:":"Push failed:","Push-Benachrichtigungen senden":"Send push notifications","Push-Benachrichtigungen sind auf diesem Server nicht verfügbar (OpenSSL-Erweiterung fehlt oder PHP zu alt).":"Push notifications are not available on this server (OpenSSL extension missing or PHP too old).","Quelle":"Source","Quelltext":"Source code","Radio-Auswahl (Punkte)":"Radio selection (dots)","Reaktion":"Response","Reaktion (Std)":"Response (hrs)","Reaktion (h)":"Response (h)","Reaktion {} Std · Lösung {} Std":"Response {} hrs · resolution {} hrs","Reaktion: {}h · Lösung: {}h":"Response: {}h · resolution: {}h","Reaktions- und Lösungszeit ab Ticketerstellung bzw. Prioritätsänderung. Mit aktivierten":"Response and resolution time from ticket creation or priority change. With enabled","Reaktions- und Lösungszeiten":"Response and resolution times","Reaktionszeit (Std)":"Response time (hrs)","Reaktionszeit (Std.)":"Response time (hrs.)","Rechnungsfrage":"Billing question","Rechte":"Permissions","Regel":"Rule","Regel bearbeiten":"Edit rule","Regeln für überfällige Tickets":"Rules for overdue tickets","Regeln werden geladen …":"Loading rules …","Registrierte Kundenkonten und Gast-Anfrager (ohne Konto) aus allen Tickets.":"Registered customer accounts and guest requesters (without account) from all tickets.","Registriertes Konto":"Registered account","Reihenfolge":"Order","Reihum an die Mitarbeiter der Abteilung":"Round robin among the department's staff","Reiner Text. Adressen mit https:// werden anklickbar.":"Plain text. Addresses with https:// become clickable.","Rheinland-Pfalz":"Rhineland-Palatinate","Richtung:":"Direction:","Rolle":"Role","Rolle (für Mitarbeiter)":"Role (for staff)","Rolle bearbeiten":"Edit role","Rolle:":"Role:","Rollen":"Roles","Rollen legst du unter":"You create roles under","Rollen und ihre Rechte legst du unter „Rollen“ an.":"You create roles and their permissions under \"Roles\".","Rollen verwalten":"Manage roles","Rollen werden geladen …":"Loading roles …","Rollenname":"Role name","SLA Erste Antwort":"SLA first response","SLA Lösung":"SLA resolution","SLA überschritten":"SLA breached","SLA-Fristen":"SLA deadlines","SLA-Plan":"SLA plan","SLA-Plan (leer = Abteilung/Priorität)":"SLA plan (empty = department/priority)","SLA-Plan (leer = Zeiten der Priorität)":"SLA plan (empty = priority's times)","SLA-Plan aktualisieren":"Update SLA plan","SLA-Plan erstellt:":"SLA plan created:","SLA-Pläne":"SLA plans","SLA-Pläne werden geladen …":"Loading SLA plans …","SLA-Prüfung":"SLA check","SLA-Prüfung jetzt manuell ausführen?":"Run SLA check manually now?","SLA-Quote":"SLA rate","SLA-Status":"SLA status","SLA-Uhr nur innerhalb der Geschäftszeiten laufen lassen":"Run the SLA clock only within business hours","SLA-Zeitfenster, Feiertage":"SLA time windows, holidays","SLA: Alle":"SLA: All","SMTP testen":"Test SMTP","SMTP-Server":"SMTP server","SMTP-Versand":"SMTP sending","SQL-Datei hochladen oder Pfad angeben":"Upload SQL file or enter path","SQLite-Modus aktiv:":"SQLite mode active:","Sachsen":"Saxony","Sachsen-Anhalt":"Saxony-Anhalt","Sammelmodus für Übersetzer:":"Collection mode for translators:","Samstag":"Saturday","Schichtplan bearbeiten":"Edit shift schedule","Schließen":"Close","Schließt Tickets, auf die der Kunde nach einer Antwort nicht mehr reagiert.":"Closes tickets the customer no longer responds to after a reply.","Schlüssel":"Key","Schlüssel erstellen":"Create key","Schnellfilter":"Quick filters","Schnellsuche / Befehle":"Quick search / commands","Seit":"Since","Seit 24.10.2026 19:44 geöffnet – wird beim Antworten automatisch als Zeit erfasst.":"Open since 24.10.2026 19:44 – time is recorded automatically when you reply.","Seite nicht gefunden":"Page not found","Seite nicht gefunden – {}":"Page not found – {}","Seite {}":"Page {}","Seite {} · {} Tickets":"Page {} · {} tickets","Seiten":"Pages","Seiten-Verwaltung":"Page management","Seitenleiste einblenden":"Show sidebar","Seitenleiste einklappen":"Collapse sidebar","Senden":"Send","Sendet …":"Sending …","Server nicht erreichbar.":"Server not reachable.","Server-Adresse":"Server address","Server-Fehler ({}).":"Server error ({}).","Server: 0,00 MB":"Server: 0.00 MB","Serveradresse für die Anmeldung":"Server address for sign-in","Serverfehler ({}).":"Server error ({}).","Servicezeit (Std)":"Service time (hrs)","Setzen":"Set","Setzen auf:":"Set to:","Sicherheitsprüfung":"Security check","Sie haben keinen Zugriff auf Tickets dieser Abteilung.":"You do not have access to tickets of this department.","Sie haben keinen Zugriff auf die Abteilung des Ziel-Tickets.":"You do not have access to the department of the target ticket.","Sie haben keinen Zugriff auf die Abteilung „{}“.":"You do not have access to the department “{}”.","Sie haben keinen Zugriff auf diese Abteilung.":"You do not have access to this department.","Sie können Ihr eigenes Konto nicht deaktivieren.":"You cannot disable your own account.","Sie können Ihr eigenes Konto nicht löschen.":"You cannot delete your own account.","Signatur":"Signature","Signatur (E-Mail-Fuß für Antworten ohne Mitarbeiter-Signatur)":"Signature (email footer for replies without a staff signature)","Signatur (E-Mail-Fuß für eigene Antworten)":"Signature (email footer for own replies)","Signatur (optional)":"Signature (optional)","Signatur (optional, Base64)":"Signature (optional, Base64)","Sitzung abgelaufen – bitte neu anmelden.":"Session expired – please sign in again.","Sitzung abgelaufen. Bitte neu anmelden.":"Session expired. Please log in again.","So kommen Benachrichtigungen auch bei geschlossenem Fenster an. Beenden über das Tray-Menü.":"This way notifications also arrive when the window is closed. Quit via the tray menu.","So nutzt du die API":"How to use the API","Sonntag":"Sunday","Sortieren nach":"Sort by","Sortiermodus:":"Sort mode:","Sortierung":"Sorting","Spam-/Junk-Ordner":"Spam/junk folder","Speichern":"Save","Speichert die aktuellen Filter (Reiter, Suche, Abteilung, Priorität).":"Saves the current filters (tab, search, department, priority).","Speichert die aktuellen Filter.":"Saves the current filters.","Speichert …":"Saving …","Sperre aufgehoben":"Lock released","Sperre aufheben":"Remove lock","Sperre aufheben und übernehmen":"Release lock and take over","Sperren":"Block","Sperrliste":"Block list","Sperrliste ist leer.":"The block list is empty.","Sperrliste ist leer. Mit + eine E-Mail-Adresse oder Domain sperren.":"The block list is empty. Block an email address or domain with +.","Sperrliste wird geladen …":"Loading block list …","Sprachen":"Languages","Später":"Later","Stand":"As of","Stand: {} Uhr":"As of: {}","Standard":"Default","Standard-Absenderadresse der Abteilung":"Department's default sender address","Standard-Absenderadresse dieser Abteilung":"Default sender address of this department","Standard-Berichte":"Default reports","Standard-Mitarbeiterrechte (ohne eigene Rolle)":"Default staff permissions (without own role)","Standardabteilung":"Default department","Standardabteilung (bzw. Abteilung des Themas)":"Default department (or the topic's department)","Standardabteilung (für E-Mail-Tickets ohne Zuordnung)":"Default department (for email tickets without assignment)","Standardabteilung verwenden":"Use default department","Standardpriorität (optional)":"Default priority (optional)","Standardsprache (für alle, die noch keine Flagge gewählt haben)":"Default language (for everyone who has not yet chosen a flag)","Startet DeskHub beim Anmelden im Hintergrund (Tray).":"Starts DeskHub in the background (tray) when signing in.","Startseiten-Inhalte":"Home page content","Statistiken":"Statistics","Statistiken werden geladen …":"Loading statistics …","Status & Schichten":"Status & shifts","Status & Vorschau":"Status & preview","Status abfragen:":"Query status:","Status der Mitarbeiter":"Staff status","Status der Mitarbeiter ändern (Admin)":"Change staff status (admin)","Status gesetzt":"Status set","Status geändert":"Status changed","Status geändert:":"Status changed:","Status nach Antwort":"Status after reply","Status nach dem Senden":"Status after sending","Status prüfen":"Check status","Status setzen":"Set status","Status setzen…":"Set status…","Status von":"Status of","Status von {}":"Status of {}","Status wird geladen …":"Loading status …","Status ändern, z. B. auf Offline setzen":"Change status, e.g. set to offline","Status, Leiter, Mitglieder, E-Mail":"Status, lead, members, email","Status: automatisch":"Status: automatic","Statusseite":"Status page","Statusseite ausgeschaltet":"Status page switched off","Statusseite eingeschaltet":"Status page switched on","Statusseite für Kunden anzeigen":"Show status page to customers","Statusseite für Kunden anzeigen (Link „Status“ im Kundenbereich)":"Show status page to customers (link \"Status\" in the customer area)","Statusseite wird geladen …":"Loading status page …","Std":"hrs","Std.":"hrs.","Stichwörter":"Keywords","Stichwörter (durch Komma)":"Keywords (comma-separated)","Stichwörter (optional, durch Komma getrennt)":"Keywords (optional, comma-separated)","Stichwörter: {}":"Keywords: {}","Stille Zeiten (keine Popups)":"Quiet hours (no popups)","Stille Zeiten bitte als Uhrzeit von/bis angeben (z. B. 22:00 und 06:00).":"Please enter quiet hours as a time from/to (e.g. 22:00 and 06:00).","Strg + Enter":"Ctrl + Enter","Strg + K":"Ctrl + K","Strg + N":"Ctrl + N","Strg K":"Ctrl K","Strg+F5":"Ctrl+F5","Stufe":"Level","Stunden":"Hours","Störung:":"Incident:","Stündliche Prüfung. Letzte Ausführung: noch nie":"Hourly check. Last run: never","Suchbegriff eingeben …":"Enter a search term …","Suche":"Search","Suchen":"Search","Suchen (Betreff, Nummer, Kunde, Text)… Strg+F":"Search (subject, number, customer, text)… Ctrl+F","Suchen …":"Searching …","Suchen…":"Search…","Supportcenter":"Support center","Supportcenter-Startseite":"Support center home","Supportcenter-Startseite – {}":"Support center home – {}","System-Update":"System update","Systemstandard":"System default","Systemstatus":"System status","Systemstatus – {}":"System status – {}","Tag hinzufügen":"Add tag","Tag-Name":"Tag name","Tage":"Days","Tage (am besten kürzer als die Frist zum automatischen Schließen)":"Days (preferably shorter than the period for automatic closing)","Tage ohne Reaktion":"Days without response","Tagen schließen":"days","Tastenkürzel":"Keyboard shortcuts","Team (als Administrator kannst du den Status ändern)":"Team (as administrator you can change the status)","Team bearbeiten":"Edit team","Team erstellt:":"Team created:","Team-Chat":"Team chat","Team-Übersicht":"Team overview","Team-Übersicht (zum Ändern antippen)":"Team overview (tap to change)","Teamleiter":"Team lead","Teamname":"Team name","Teams verwalten":"Manage teams","Teams werden geladen …":"Loading teams …","Technik":"Technology","Technisches Problem":"Technical issue","Teilweise eingeschränkt":"Partially degraded","Telefon":"Phone","Telefonnummer (optional)":"Phone number (optional)","Telegram Bot-Token":"Telegram bot token","Telegram Chat-ID":"Telegram chat ID","Test-Benachrichtigung":"Test notification","Test-Benachrichtigung – so sieht eine Meldung aus.":"Test notification – this is what a message looks like.","Test-Mail senden":"Send test email","Testen":"Test","Testnachricht an meine Geräte":"Test message to my devices","Testnachricht senden":"Send test message","Tests verwenden die gespeicherten Werte.":"Tests use the saved values.","Text (HTML erlaubt)":"Text (HTML allowed)","Text (Vorschau)":"Text (preview)","Text, wenn er keine Antwort findet":"Text if it finds no answer","Textbaustein wirklich löschen?":"Really delete this text snippet?","Textbausteine verwalten":"Manage text snippets","Textbaustein…":"Text snippet…","Texte der automatischen E-Mails":"Texts of the automatic emails","Texte der automatischen Mails":"Texts of the automatic emails","Thema":"Topic","Thema, Abteilung, Priorität":"Topic, department, priority","Thema, Typ, Abteilung, Priorität":"Topic, type, department, priority","Theme hochladen":"Upload theme","Theme-Paket":"Theme package","Themen":"Topics","Themes aus dem Katalog":"Themes from the catalog","Thüringen":"Thuringia","Ticket #{}":"Ticket #{}","Ticket #{} – {}":"Ticket #{1} – {2}","Ticket anlegen (JSON). Antwort:":"Create ticket (JSON). Response:","Ticket ansehen":"View ticket","Ticket ansehen – {}":"View ticket – {}","Ticket auf später legen":"Snooze ticket","Ticket eingegangen":"Ticket received","Ticket erstellen":"Create ticket","Ticket erstellt":"Ticket created","Ticket erstellt (an Kunde)":"Ticket created (to customer)","Ticket hinzufügen":"Add ticket","Ticket im Namen eines Kunden anlegen – z.B. bei Telefonanrufen oder Vor-Ort-Anfragen.":"Create a ticket on behalf of a customer – e.g. for phone calls or on-site requests.","Ticket inkl. Verlauf unwiderruflich löschen?":"Permanently delete the ticket including its history?","Ticket ist überfällig (SLA überschritten)":"Ticket is overdue (SLA exceeded)","Ticket mir zugewiesen":"Ticket assigned to me","Ticket offen seit X Stunden":"Ticket open for X hours","Ticket schließen":"Close ticket","Ticket schließen (wird angelegt, aber sofort geschlossen)":"Close ticket (is created but closed immediately)","Ticket verknüpfen (Ticket-Nr., optional)":"Link ticket (ticket no., optional)","Ticket verwerfen (z.B. Spam)":"Discard ticket (e.g. spam)","Ticket wird geladen …":"Loading ticket …","Ticket wurde aktualisiert":"Ticket was updated","Ticket wurde {}, aber nicht alle Original-Mails konnten verschoben werden:":"Ticket was {}, but not all original emails could be moved:","Ticket überfällig (an Admins)":"Ticket overdue (to admins)","Ticket(s) anonymisiert (geschlossen/gelöst, älter als 24 Monate).":"ticket(s) anonymized (closed/resolved, older than 24 months).","Ticket, Kunde oder Bereich suchen…":"Search ticket, customer or area…","Ticket-Berechtigungen":"Ticket permissions","Ticket-Bewertung aktivieren (Kunden können nach Schließung 1–5 Sterne vergeben)":"Enable ticket rating (customers can give 1–5 stars after closing)","Ticket-Details":"Ticket details","Ticket-Felder":"Ticket fields","Ticket-Formular":"Ticket form","Ticket-Liste":"Ticket list","Ticket-Nachrichten":"Ticket messages","Ticket-Nr.:":"Ticket no.:","Ticket-Nummer, Betreff, Status":"Ticket number, subject, status","Ticket-Regel bearbeiten":"Edit ticket rule","Ticket-Regeln":"Ticket rules","Ticket-Regeln (Filter)":"Ticket rules (filter)","Ticket-Regeln, Auto-Antworten":"Ticket rules, auto-replies","Ticket-Vorlagen":"Ticket templates","Ticketaktivität":"Ticket activity","Ticketnummer":"Ticket number","Ticketnummer kopieren":"Copy ticket number","Ticketnummer oder Betreff suchen…":"Search ticket number or subject…","Ticketnummer verknüpfen (optional)":"Link ticket number (optional)","Ticketnummer, Betreff, Kunde oder Bereich…":"Ticket number, subject, customer or area…","Tickets ({#})":"Tickets ({})","Tickets automatisch schließen, wenn der Kunde nach einer Antwort nicht mehr reagiert":"Close tickets automatically if the customer does not respond after a reply","Tickets beantworten":"Reply to tickets","Tickets durchsuchen":"Search tickets","Tickets erstellen":"Create tickets","Tickets gesamt":"Total tickets","Tickets im Namen von Kunden erstellen":"Create tickets on behalf of customers","Tickets löschen":"Delete tickets","Tickets lösen/schließen":"Resolve/close tickets","Tickets schließen/lösen":"Close/resolve tickets","Tickets verschieben":"Move tickets","Tickets werden geladen …":"Loading tickets …","Tickets zusammenführen":"Merge tickets","Tickets zuweisen":"Assign tickets","Tickets übertragen":"Transfer tickets","Ticketstatus überprüfen":"Check ticket status","Titel":"Title","Titelbild (Hero-Banner)":"Cover image (hero banner)","To-dos für dich und dein Team":"To-dos for you and your team","Token aus Gitea einfügen":"Paste token from Gitea","Typ":"Type","Täglich":"Daily","UND":"AND","Um Ihnen weiterhelfen zu können, benötigen wir noch ein paar zusätzli…":"To help you further, we need a few additional details…","Unbeantwortet":"Unanswered","Unbekannt":"Unknown","Unbekannter Serverfehler.":"Unknown server error.","Ungültige Anfrage (CSRF-Token fehlt oder ist ungültig). Bitte gehen Sie zurück und versuchen Sie es erneut.":"Invalid request (CSRF token missing or invalid). Please go back and try again.","Ungültige Anfrage.":"Invalid request.","Ungültige E-Mail-Adresse.":"Invalid email address.","Ungültige Eingabe.":"Invalid input.","Ungültige Seite.":"Invalid page.","Ungültige verschlüsselte Sitzungsdaten.":"Invalid encrypted session data.","Ungültiger Dienst oder Zustand.":"Invalid service or state.","Ungültiger Pfad.":"Invalid path.","Ungültiger Status.":"Invalid status.","Ungültiger Trigger.":"Invalid trigger.","Ungültiger Zielstatus.":"Invalid target status.","Untereinander":"Stacked","Unterhaltung wird geladen …":"Loading conversation …","Unterstützt werden SQL-Dumps von osTicket 1.10 bis 1.18 (phpMyAdmin-Export oder":"SQL dumps from osTicket 1.10 to 1.18 are supported (phpMyAdmin export or","Update für die Kunden":"Update for the customers","Update konnte nicht geladen werden.":"The update could not be loaded.","Update senden":"Send update","Update verfügbar: DeskHub {} (installiert: {})":"Update available: DeskHub {} (installed: {})","Update verfügbar: DeskHub {} (installiert: {}) {}":"Update available: DeskHub {} (installed: {}) {}","Update verfügbar: DeskHub {} (installiert: {}).":"Update available: DeskHub {} (installed: {}).","Update verfügbar: DeskHub {} (installiert: {}). {}":"Update available: DeskHub {} (installed: {}). {}","Update veröffentlicht":"Update published","Update {} wird geladen … {} %":"Downloading update {} … {} %","Updates: neue Datei laden und darüber installieren. Eure Anmeldung bleibt erhalten.":"Updates: load a new file and install over it. Your sign-in is kept.","Ursache gefunden":"Cause found","Verbindung testen":"Test connection","Verbindung wiederhergestellt":"Connection restored","Verfügbar":"Available","Verfügbare Platzhalter:":"Available placeholders:","Verfügbarkeit":"Availability","Verfügbarkeit & Schichten":"Availability & shifts","Verfügbarkeit und Team-Übersicht":"Availability and team overview","Verfügbarkeit wird geprüft…":"Checking availability…","Vergangene Meldungen (letzte 14 Tage)":"Past incidents (last 14 days)","Verknüpftes Ticket":"Linked ticket","Verknüpfung":"Link","Verlauf":"History","Verlauf (1 Nachricht)":"History (1 message)","Verlauf und Status Ihrer aktuellen und bisherigen Supportanfragen.":"History and status of your current and previous support requests.","Verlauf, Tags und Collaborators werden ins Ziel-Ticket verschoben. Dieses Ticket wird geschlossen.":"History, tags and collaborators are moved to the target ticket. This ticket will be closed.","Verlinkter Teil des Textes":"Linked part of the text","Verschlüsselung":"Encryption","Vertraulich/Intern":"Confidential/Internal","Verwalten":"Manage","Verwaltung":"Administration","Verwenden →":"Use →","Verzeichnis":"Directory","Veröffentlichen":"Publish","Veröffentlicht":"Published","Vielen Dank für Ihre Nachricht. Wir haben Ihr Anliegen erhalten und k…":"Thank you for your message. We have received your request and…","Vielen Dank! Ihr Ticket wurde erstellt.":"Thank you! Your ticket has been created.","Von":"From","Von (HH:MM)":"From (HH:MM)","Von (JJJJ-MM-TT)":"From (YYYY-MM-DD)","Vorgabe für den Betreff":"Default for the subject","Vorhandene Backups":"Existing backups","Vorhandene Vorlagen":"Existing templates","Vorlage":"Template","Vorlage einfügen":"Insert template","Vorlage laden":"Load template","Vorlagen":"Templates","Vorlagen / Textbausteine":"Templates / text snippets","Vorlagen werden geladen …":"Loading templates …","Vorname Nachname":"First name last name","Vorschau":"Preview","Wann ist er aktiv?":"When is it active?","Wann?":"When?","Wartend":"Waiting","Wartet auf Kunde":"Waiting for customer","Wartung":"Maintenance","Was ist passiert? Was tun wir dagegen?":"What happened? What are we doing about it?","Was ist zu tun?":"What needs to be done?","Was wird anonymisiert?":"What is anonymized?","Website-URL":"Website URL","Weiter ›":"Next ›","Weitere":"More","Weitere Aktionen":"More actions","Weitere Informationen benötigt":"More information needed","Weitere Informationen → Trotzdem ausführen":"More information → Run anyway","Weitere Tickets des Kunden":"More tickets from the customer","Weitere laden":"Load more","Weiterer Treffer:":"Another match:","Weiterer Treffer: {}":"Another match: {}","Wenige Stunden pro Tag (z. B. nur abends) lassen die Fälligkeit in":"A few hours per day (e.g. only evenings) let the due date in","Wenn …":"If …","Wert":"Value","Wie System":"Like system","Wie Windows (automatisch)":"Like Windows (automatic)","Wie erstelle ich ein Ticket?":"How do I create a ticket?","Wie können wir helfen?":"How can we help?","Wie lange dauert die Bearbeitung?":"How long does processing take?","Wieder geöffnet":"Reopened","Wieder öffnen":"Reopen","Wiederkehrende Tickets":"Recurring tickets","Wiederkehrende Tickets jetzt manuell ausführen?":"Run recurring tickets manually now?","Wiedervorlage":"Snooze","Wiedervorlage aufgehoben":"Snooze removed","Wiedervorlage aufheben":"Remove snooze","Wiedervorlage fällig":"Snooze due","Wiedervorlage gesetzt":"Snooze set","Wiedervorlage und Beobachten":"Snooze and watching","Wiedervorlagen":"Snoozes","Wiedervorlagen jetzt manuell ausführen?":"Run snoozes manually now?","Willkommen zurück, {}":"Welcome back, {}","Willkommen, Gast":"Welcome, Guest","Willkommen, {}":"Welcome, {}","Windows-Benachrichtigungen anzeigen":"Show Windows notifications","Wir senden Ihnen einen Link zum Zurücksetzen.":"We will send you a reset link.","Wird beobachtet":"Being monitored","Wird berechnet …":"Calculating …","Wird erstellt …":"Creating …","Wird geladen …":"Loading …","Wird gerade von {} bearbeitet – Sie sehen live mit, können hier aber nicht antworten.":"Currently being handled by {} – you can watch live but cannot reply here.","Wird gerade von {} bearbeitet.":"Currently being handled by {}.","Wird gespeichert …":"Saving …","Wird gesperrt …":"Blocking …","Wird im Browser-Tab, in E-Mails und in der Web-App angezeigt.":"Shown in the browser tab, in emails and in the web app.","Wird in E-Mail-Links verwendet. Kein abschließendes /":"Used in email links. No trailing /","Wird nur an öffentliche Antworten angehängt, nicht an interne Notizen.":"Only appended to public replies, not to internal notes.","Wird untersucht":"Investigating","Wird verwendet, wenn ein eingegangenes E-Mail-Ticket als Spam markiert wird.":"Used when an incoming email ticket is marked as spam.","Wirklich löschen?":"Really delete?","Wirklich sperren?":"Really block?","Wirksame Rechte":"Effective permissions","Wissensdatenbank":"Knowledge base","Wissensdatenbank durchsuchen oder direkt ein Ticket eröffnen – wir antworten so schnell wie möglich.":"Search the knowledge base or open a ticket right away – we will reply as quickly as possible.","Wissensdatenbank im Kundenportal anzeigen":"Show knowledge base in the customer portal","Wissensdatenbank verwalten":"Manage knowledge base","Wissensdatenbank wird geladen …":"Loading knowledge base …","Wissensdatenbank – {}":"Knowledge base – {}","Woche":"Week","Wochenzeiten":"Weekly hours","Wofür soll die App ein Popup zeigen?":"What should the app show a popup for?","Wonach suchen Sie?":"What are you looking for?","Worum geht es?":"What is it about?","Wähle die Abteilungen, zu denen der Agent Zugang haben soll.":"Choose the departments the agent should have access to.","Wähle, wofür die App ein Popup zeigen soll.":"Choose what the app should show a popup for.","Wöchentlich":"Weekly","Wörter":"Words","Wörter, die Kunden und Artikel unterschiedlich nennen, aber dasselbe meinen. Eine Gruppe je Zeile, durch Komma getrennt, zum Beispiel „Zugang, Einladung, beitreten“. Einige Gruppen sind eingebaut, deine ergänzen oder überschreiben sie.":"Words that customers and articles name differently but mean the same. One group per line, separated by commas, for example \"access, invitation, join\". Some groups are built in, yours add to or override them.","ZIP-Datei":"ZIP file","ZIP-Datei von Gitea hochladen und installieren.":"Upload and install a ZIP file from Gitea.","Zahl":"Number","Zeigt, was Kunden den Assistenten gefragt haben und ob er eine Antwort fand. Gespeichert werden nur Frage und Ergebnis (kein Name, keine E-Mail-Adresse).":"Shows what customers asked the assistant and whether it found an answer. Only the question and result are stored (no name, no email address).","Zeigt, was Kunden gefragt haben und ob der Assistent eine Antwort fand. Gespeichert werden nur Frage und Ergebnis.":"Shows what customers asked and whether the assistant found an answer. Only the question and result are stored.","Zeigt, was der Assistent auf eine Kundenfrage antworten würde (ohne Zähler und ohne Ticket).":"Shows what the assistant would answer to a customer question (without counters and without a ticket).","Zeit":"Time","Zeiten der Priorität verwenden":"Use the priority's times","Zeiten je Abteilung oder Thema":"Times per department or topic","Zeiten je Mitarbeiter":"Times per staff member","Zeiten werden geladen …":"Loading times …","Zeiterfassung":"Time tracking","Zeiterfassung einsehen":"View time tracking","Zeitplan aus":"Schedule off","Zeitplan speichern":"Save schedule","Zeitraum":"Period","Zeitzone":"Time zone","Ziel":"Target","Zielordner":"Target folder","Zielordner (bei Verschieben)":"Target folder (when moving)","Zielverzeichnis":"Target directory","Zitieren":"Quote","Zu einem Zeitpunkt …":"At a point in time …","Zu lange offen seit …":"Open for too long since …","Zu viele Anfragen. Bitte in einer Minute erneut versuchen.":"Too many requests. Please try again in a minute.","Zu viele Anfragen. Bitte versuchen Sie es in einigen Minuten erneut.":"Too many requests. Please try again in a few minutes.","Zu viele Anfragen. Bitte versuchen Sie es später erneut.":"Too many requests. Please try again later.","Zu viele Anmeldeversuche für dieses Konto. Bitte warten Sie einige Minuten.":"Too many login attempts for this account. Please wait a few minutes.","Zu viele Anmeldeversuche. Bitte versuchen Sie es in einigen Minuten erneut.":"Too many login attempts. Please try again in a few minutes.","Zu viele Anmeldeversuche. Bitte versuchen Sie es später erneut.":"Too many login attempts. Please try again later.","Zu viele Chat-Anfragen. Bitte versuchen Sie es in ein paar Minuten erneut.":"Too many chat requests. Please try again in a few minutes.","Zu viele Nachrichten. Bitte kurz warten.":"Too many messages. Please wait a moment.","Zu viele Registrierungsversuche. Bitte warten Sie eine Stunde.":"Too many registration attempts. Please wait an hour.","Zu viele Versuche. Bitte versuchen Sie es in einigen Minuten erneut.":"Too many attempts. Please try again in a few minutes.","Zu viele Versuche. Bitte warten Sie einige Minuten.":"Too many attempts. Please wait a few minutes.","Zufriedenheitsabfrage":"Satisfaction survey","Zufriedenheitsabfrage jetzt manuell ausführen?":"Run the satisfaction survey manually now?","Zugang":"Access","Zugang zum Update-Server":"Access to the update server","Zugang, Einladung, beitreten Geld zurück, Erstattung, Rückzahlung":"access, invitation, join money back, refund, reimbursement","Zugewiesen":"Assigned","Zugewiesen an":"Assigned to","Zugewiesen:":"Assigned:","Zugewiesenen Mitarbeiter benachrichtigen":"Notify assigned staff member","Zugriffstoken":"Access token","Zuletzt aktiv":"Last active","Zuletzt aktualisiert":"Last updated","Zuletzt genutzt":"Last used","Zum Ändern fehlt das Recht „Teams verwalten“.":"The \"Manage teams\" permission is missing to change this.","Zuordnung":"Assignment","Zurück":"Back","Zurück zu Tickets":"Back to tickets","Zurück zur Startseite":"Back to home","Zurück zur Ticketliste":"Back to ticket list","Zurückgesetzt":"Reset","Zurückgestellt":"Postponed","Zurücksetzen":"Reset","Zusammenführen":"Merge","Zustand":"State","Zustand geändert":"State changed","Zustand jetzt:":"Current state:","Zustand jetzt: {}":"State now: {}","Zuständig":"Responsible","Zuständigen benachrichtigen":"Notify responsible person","Zusätzlich":"Additionally","Zusätzliche Antwort":"Additional answer","Zusätzliche Antworten":"Additional answers","Zuweisen":"Assign","Zuweisen an":"Assign to","Zuweisen…":"Assign…","Zuweisung":"Assignment","Zuweisung geändert":"Assignment changed","Zuweisungen änderst du unter":"You change assignments under","Zuweisungen änderst du unter „Mitarbeiter“.":"You change assignments under \"Staff\".","Zweiten Faktor bestätigen":"Confirm second factor","absteigend":"descending","aktiv (Kunden sehen den Assistenten)":"active (customers see the assistant)","aktiv gerade eben":"active just now","alle 2 Minuten":"every 2 minutes","alle 30 Sekunden":"every 30 seconds","alle 5 Minuten":"every 5 minutes","als Spam markiert":"marked as spam","an":"on","auf":"to","ausgeschaltet":"switched off","automatisch offline (inaktiv)":"automatically offline (inactive)","beginnt mit":"starts with","bereit, aber gerade nicht sichtbar":"ready, but not visible right now","bis":"until","bis (HH:MM)":"until (HH:MM)","ein Ticket eröffnen":"open a ticket","eingeschaltet":"switched on","endet mit":"ends with","enthält":"contains","enthält nicht":"does not contain","gekennzeichnet.":"marked.","geändert":"changed","in Ordnung":"OK","in {#} Min":"in {} min","in {#} Std {#} Min":"in {1}h {2}m","ist genau":"is exactly","jede Minute":"every minute","kein bestimmter Dienst":"no specific service","keine Abteilung":"no department","keine Abteilungs-E-Mail":"no department email","leer = von überall; sonst kommagetrennt":"empty = from anywhere; otherwise comma-separated","mind. 10 Zeichen, Groß-/Klein, Ziffer, Sonderzeichen":"min. 10 characters, upper/lower case, digit, special character","mitarbeiter@firma.de":"staff@company.com","nicht vom Herausgeber geprüft":"not verified by the publisher","nicht ändern":"do not change","noch keins":"none yet","oder":"or","oder direkt":"or directly","privat":"private","um alle Ihre Tickets im Überblick zu behalten.":"to keep all your tickets at a glance.","und":"and","von":"from","von (HH:MM)":"from (HH:MM)","vor {#} Min (überfällig)":"{} min ago (overdue)","vor {#} Min.":"{} min. ago","vor {#} Std {#} Min (überfällig)":"{1}h {2}m ago (overdue)","wird nur an Antworten an den Kunden angehängt":"is only attached to replies to the customer","z. B. E-Mail-Versand verzögert":"e.g. email delivery delayed","z. B. Ich habe die Nutzerbedingungen gelesen und akzeptiert.":"e.g. I have read and accept the terms of use.","z. B. Lieferzeit, Paket, Lieferung":"e.g. delivery time, parcel, delivery","z. B. Meine überfälligen":"e.g. My overdue","z. B. Mit freundlichen Grüßen Ihr Support-Team":"e.g. Kind regards, your support team","z. B. Mit freundlichen Grüßen Max Mustermann":"e.g. Kind regards, Max Mustermann","z. B. Monatsbericht Support":"e.g. Monthly support report","z. B. Neuer Mitarbeiter":"e.g. New employee","z. B. Nutzerbedingungen":"e.g. Terms of use","z. B. Passwort zurücksetzen, Rechnung, Versand …":"e.g. reset password, invoice, shipping …","z. B. Vertragsnummer":"e.g. Contract number","z. B. Website-Kontaktformular":"e.g. Website contact form","z. B. Wie lange dauert der Versand?":"e.g. How long does shipping take?","z. B. Wie setze ich mein Passwort zurück?":"e.g. How do I reset my password?","z.B. Import aus alter Sperrliste":"e.g. Import from old block list","z.B. Junk, Spam oder INBOX.Junk":"e.g. Junk, Spam or INBOX.Junk","z.B. Tag der Deutschen Einheit":"e.g. German Unity Day","z.B. Technik-Postfach":"e.g. Technical mailbox","z.B. wiederholter Spam":"e.g. repeated spam","z.B. „In Besprechung bis 14:00“":"e.g. \"In a meeting until 14:00\"","zurückgeholt":"restored","zählen nur die dort eingetragenen Öffnungszeiten.":"only the opening hours entered there count.","{#} Artikel":"{} article(s)","{#} Aufrufe":"{} views","{#} Tag(e)":"{} day(s)","{#} Treffer":"{} hits","{} Abteilung(en) · {} Hilfethema/-themen":"{} department(s) · {} help topic(s)","{} Aktualisierung(en) an deinen Tickets":"{} update(s) to your tickets","{} Antworten von {} Abfragen":"{} answers from {} surveys","{} Artikel":"{} articles","{} Bedingung(en) ({})":"{} condition(s) ({})","{} Einträge · Seite {} von {}":"{} entries · page {} of {}","{} Einträge · Seite {}/{}":"{} entries · page {}/{}","{} Kontakte":"{} contacts","{} Mitarbeiter":"{} staff","{} Mitglied(er)":"{} member(s)","{} Std":"{} hrs","{} Tickets":"{} tickets","{} ausgewählt":"{} selected","{} gesperrt, {} übersprungen.":"{} blocked, {} skipped.","{} neue(s) nicht zugewiesene(s) Ticket(s)":"{} new unassigned ticket(s)","{} offen":"{} open","{} von 5":"{} of 5","{} · erstellt am {}":"{1} · created {2}","{} · {} · erstellt {}":"{} · {} · created {}","{} überfällig":"{} overdue","{}: {} Ticket(s)":"{}: {} ticket(s)","{}× angewendet":"applied {}×","{}× genutzt · {}":"used {}× · {}","· Handeln":"· Act","· Hinweis":"· Notice","· In Ordnung":"· OK","· Leiter: {}":"· Lead: {}","· Letzte automatische Prüfung: Noch nie":"· Last automatic check: never","· Letzter Abruf: Noch nie":"· Last fetch: never","· Live-Chat {} · Wissensdatenbank im Portal {}":"· Live chat {} · Knowledge base in the portal {}","· Prüfen":"· Check","· fällig {}":"· due {}","· für alle":"· for everyone","· {} Fehler ({})":"· {} errors ({})","· über den DeskHub-Push-Dienst, es ist nichts einzurichten":"· via the DeskHub push service, nothing to set up","Ältere Backups werden automatisch gelöscht wenn das Limit erreicht wird.":"Older backups are deleted automatically when the limit is reached.","Änderungen speichern":"Save changes","Änderungen und Mailfehler":"Changes and failed emails","Änderungen und fehlgeschlagene Mails":"Changes and failed emails","Öffentlich":"Public","Öffentlich (für Kunden sichtbar)":"Public (visible to customers)","Öffentliche Antwort senden":"Send public reply","Öffnen Sie zuerst den persönlichen Ticket-Link aus der Ticket-E-Mail in diesem Browser. Anschließend können Sie das Ticket hier Ihrem Konto hinzufügen, wenn die Ticket-E-Mail-Adresse mit Ihrer Konto-E-Mail-Adresse übereinstimmt.":"First open the personal ticket link from the ticket email in this browser. You can then add the ticket to your account here if the ticket email address matches your account email address.","Öffnungszeiten je Wochentag":"Opening hours per weekday","Öffnungszeiten speichern":"Save opening hours","Öffnungszeiten und Feiertage":"Opening hours and holidays","Ø Bewertung · {} Antworten von {} Abfragen":"Ø rating · {} answers from {} surveys","Ø Erste Antwort":"Ø First response","Ø Erstreaktion":"Ø First response","Ø Lösungszeit":"Ø Resolution time","Überfällig":"Overdue","Überfällig seit …":"Overdue since …","Übergeordnetes Thema":"Parent topic","Überschrift":"Heading","Übersicht":"Overview","– Abteilung wählen –":"– choose department –","– Download nur im Web":"– Download on the web only","– Hilfe-Thema wählen –":"– choose help topic –","– Interne Notizen, sichtbar für alle Administratoren":"– Internal notes, visible to all administrators","– Mitarbeiter wählen –":"– choose staff member –","– Priorität wählen –":"– choose priority –","– Standard-Mitarbeiterrechte –":"– default staff permissions –","– Textbaustein wählen –":"– choose text snippet –","– Vorlage wählen –":"– choose template –","– auswählen –":"– select –","– bitte wählen –":"– please choose –","– kein Leiter –":"– no lead –","– kein Thema –":"– no topic –","– kein bestimmter Dienst –":"– no specific service –","– keine Änderung –":"– no change –","– keine –":"– none –","– nicht vorgeben –":"– do not preset –","– nicht zugewiesen –":"– unassigned –","– nicht ändern –":"– do not change –","– ohne Vorlage –":"– without template –","– wählen –":"– choose –","— Abteilung auswählen —":"— select department —","— Automatisch (Standardadresse der Abteilung) —":"— Automatic (department default address) —","— Automatisch —":"— Automatic —","— Bitte wählen —":"— Please choose —","— Keine(r) —":"— None —","— Niemand —":"— Nobody —","— Oberste Hilfethemenebene —":"— Top help topic level —","— Standard —":"— Default —","— Standardabteilung (bzw. Abteilung des gewählten Themas) —":"— Default department (or department of the chosen topic) —","— Systemstandard —":"— System default —","— Zeiten der Priorität verwenden —":"— Use the priority's times —","— keine —":"— none —","— nicht ändern —":"— do not change —","— niemand —":"— nobody —","— ohne Vorlage —":"— without template —","‹ Liste":"‹ List","‹ Verwaltung":"‹ Administration","‹ Zurück":"‹ Back","ℹ️ Ausführung hochgeladener Dateien":"ℹ️ Execution of uploaded files","ℹ️ Erreichbarkeit interner Dateien":"ℹ️ Accessibility of internal files","ℹ️ Hinweise":"ℹ️ Notes","← Einstellungen":"← Settings","← Zum Kundenportal":"← To the customer portal","← Zur Anmeldung":"← Back to sign in","← Zur Ticket-Liste":"← To the ticket list","← Zurück":"← Back","↑ Priorität: {}":"↑ Priority: {}","→ bleiben erhalten":"→ are kept","↓ CSV exportieren":"↓ Export CSV","↩️ Spam-Markierung aufheben":"↩️ Remove spam mark","⏰ Automatischer Zeitplan":"⏰ Automatic schedule","⏱ Zeiterfassung":"⏱ Time tracking","⏱ Zeiterfassung läuft":"⏱ Time tracking running","○ Noch kein Postfach eingerichtet":"○ No mailbox set up yet","○ deaktiviert":"○ disabled","⚙ Einstellungen":"⚙ Settings","⚠️ Administratoren ohne Zwei-Faktor-Anmeldung":"⚠️ Administrators without two-factor authentication","⚠️ Datenbank: SQLite":"⚠️ Database: SQLite","⚠️ Noch kein geprüftes Backup":"⚠️ No verified backup yet","⛔ Absender sperren":"⛔ Block sender","⛔ Gesperrt":"⛔ Blocked","✅ Verschlüsselungsschlüssel gesetzt":"✅ Encryption key set","✍ Signatur":"✍ Signature","✓ Berichte einsehen":"✓ View reports","✓ Die Datenbank ist aktuell":"✓ The database is up to date","✓ Interne Notizen schreiben":"✓ Write internal notes","✓ Push ist aktiv":"✓ Push is active","✓ Tickets beantworten":"✓ Reply to tickets","✓ Tickets im Namen von Kunden erstellen":"✓ Create tickets on behalf of customers","✓ Tickets schließen/lösen":"✓ Close/resolve tickets","✓ Tickets zuweisen (Mitarbeiter/Team)":"✓ Assign tickets (staff/team)","✓ Tickets übertragen (Abteilung ändern)":"✓ Transfer tickets (change department)","✕ Abteilungen verwalten":"✕ Manage departments","✕ Admin-Protokoll einsehen":"✕ View admin log","✕ Digitalen Assistenten verwalten":"✕ Manage digital assistant","✕ E-Mail-Adressen verwalten":"✕ Manage email addresses","✕ E-Mail-Vorlagen verwalten":"✕ Manage email templates","✕ Eskalationsregeln verwalten":"✕ Manage escalation rules","✕ Filter zurücksetzen":"✕ Reset filters","✕ Geschäftszeiten verwalten":"✕ Manage business hours","✕ Hilfe-Themen verwalten":"✕ Manage help topics","✕ Mitarbeiter verwalten":"✕ Manage staff","✕ Organisationen verwalten":"✕ Manage organizations","✕ Prioritäten / SLA verwalten":"✕ Manage priorities / SLA","✕ Rollen verwalten":"✕ Manage roles","✕ Teams verwalten":"✕ Manage teams","✕ Textbausteine verwalten":"✕ Manage text snippets","✕ Tickets löschen":"✕ Delete tickets","✕ Wissensdatenbank verwalten":"✕ Manage knowledge base","✕ Zeiterfassung einsehen":"✕ View time tracking","❌ Installationsassistent ist nicht gesperrt":"❌ The installation wizard is not locked","❌ Website-URL nutzt kein HTTPS":"❌ Website URL does not use HTTPS","⬆️ Hochladen & installieren":"⬆️ Upload & install","+ Ansicht speichern":"+ Save view","🌐 Im Browser":"🌐 In browser","🌐 Web (im Namen)":"🌐 Web (on behalf)","🏖 Urlaub":"🏖 Vacation","👁 Beobachten":"👁 Watch","👁 Beobachtet":"👁 Watched","👁 Nicht mehr beobachten":"👁 Stop watching","👁 Ticket beobachten":"👁 Watch ticket","👋 Hallo! Wie können wir Ihnen helfen?":"👋 Hello! How can we help you?","👤 Konto":"👤 Account","💤 Auf später":"💤 Snooze","💤 Ausgeblendet bis {} Uhr, dann kommt das Ticket zurück.":"💤 Hidden until {}, then the ticket comes back.","💤 Wiedervorlage":"💤 Snooze","💤 bis":"💤 until","💬 Live-Chat":"💬 Live chat","💾 Backup jetzt erstellen":"💾 Create backup now","📄 Impressum":"📄 Legal notice","📎 Datei":"📎 File","📞 Telefon":"📞 Phone","📡 FTP-Upload":"📡 FTP upload","📥 osTicket Import":"📥 osTicket import","📧 E-Mail":"📧 Email","📧 Mitarbeiter":"📧 Staff","📱 Android-App: Push-Benachrichtigungen":"📱 Android app: push notifications","📱 Android-App: Welche Popups?":"📱 Android app: which popups?","🔄 Automatischer Hintergrund-Betrieb (ohne Server-Cronjob)":"🔄 Automatic background operation (without server cron job)","🔄 Erneut prüfen":"🔄 Check again","🔄 System-Update":"🔄 System update","🔒 Datenschutz":"🔒 Privacy","🔒 Datenschutzerklärung":"🔒 Privacy policy","🔒 Dieses Ticket wird gerade von „{}“ bearbeitet. Als Administrator kannst du es trotzdem lesen und bearbeiten.":"🔒 This ticket is currently being handled by \"{}\". As administrator you can still read and edit it.","🔒 Sicherheit":"🔒 Security","🔒 Wird gerade von {} bearbeitet – Sie sehen live mit, können hier aber nicht schreiben.":"🔒 Currently being handled by {} – you can watch live but cannot write here.","🔓 freigeben":"🔓 release","🔔 Meine Erwähnungen":"🔔 My mentions","🔴 Beschäftigt":"🔴 Busy","🔴 Überfällig":"🔴 Overdue","🖥 Intern":"🖥 Internal","🖥 Vor Ort / Intern":"🖥 On site / internal","🖨 Drucken":"🖨 Print","🖨 Drucken / Als PDF speichern":"🖨 Print / Save as PDF","🖨️ Ticket drucken":"🖨️ Print ticket","🖼️ Bild einfügen":"🖼️ Insert image","🗄 Datenbank aktualisieren":"🗄 Update database","🗑 Ticket löschen":"🗑 Delete ticket","🚫 Als Spam markieren":"🚫 Mark as spam","🚫 Sperren":"🚫 Block","🟡 Bald fällig":"🟡 Due soon","🟡 Bald fällig (< 4 Std.)":"🟡 Due soon (< 4 hrs)","🟡 Pause":"🟡 Break","🟢 Im Zeitplan":"🟢 On schedule","🟢 Verfügbar":"🟢 Available"}
\ No newline at end of file
diff --git a/mobile/src/main/java/de/deskhub/staff/AppConnectionPing.kt b/mobile/src/main/java/de/deskhub/staff/AppConnectionPing.kt
new file mode 100644
index 00000000..1ce0e781
--- /dev/null
+++ b/mobile/src/main/java/de/deskhub/staff/AppConnectionPing.kt
@@ -0,0 +1,66 @@
+package de.deskhub.staff
+
+import android.content.Context
+import androidx.work.Constraints
+import androidx.work.CoroutineWorker
+import androidx.work.ExistingPeriodicWorkPolicy
+import androidx.work.NetworkType
+import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.WorkerParameters
+import de.deskhub.staff.data.remote.DeskHubApi
+import de.deskhub.staff.data.security.SecureSessionStore
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.runBlocking
+import java.util.concurrent.TimeUnit
+import kotlin.concurrent.thread
+
+/** Sends a liveness request without changing the staff member's presence status. */
+class AppConnectionWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
+ override suspend fun doWork(): Result {
+ val session = SecureSessionStore(applicationContext).load() ?: return Result.success()
+ if (session.token.isBlank() || session.serverUrl.isBlank()) return Result.success()
+ return try {
+ DeskHubApi(session.serverUrl) { session.token }.me()
+ Result.success()
+ } catch (cancelled: CancellationException) {
+ throw cancelled
+ } catch (_: Exception) {
+ Result.retry()
+ }
+ }
+}
+
+object AppConnectionPing {
+ private const val WORK_NAME = "deskhub-app-connection-heartbeat"
+
+ /** Quick heartbeat while the app is visible. */
+ fun send(context: Context) {
+ val app = context.applicationContext
+ thread(name = "app-connection-ping") {
+ try {
+ val session = SecureSessionStore(app).load() ?: return@thread
+ if (session.token.isBlank() || session.serverUrl.isBlank()) return@thread
+ runBlocking { DeskHubApi(session.serverUrl) { session.token }.me() }
+ } catch (_: Exception) {
+ // The next foreground or background heartbeat will retry.
+ }
+ }
+ }
+
+ /** Android schedules this network-constrained worker periodically, including in the background. */
+ fun scheduleBackground(context: Context) {
+ val constraints = Constraints.Builder()
+ .setRequiredNetworkType(NetworkType.CONNECTED)
+ .build()
+ val request = PeriodicWorkRequestBuilder(15, TimeUnit.MINUTES)
+ .setConstraints(constraints)
+ .build()
+ WorkManager.getInstance(context.applicationContext)
+ .enqueueUniquePeriodicWork(WORK_NAME, ExistingPeriodicWorkPolicy.UPDATE, request)
+ }
+
+ fun cancelBackground(context: Context) {
+ WorkManager.getInstance(context.applicationContext).cancelUniqueWork(WORK_NAME)
+ }
+}
diff --git a/mobile/src/main/java/de/deskhub/staff/data/remote/DeskHubApi.kt b/mobile/src/main/java/de/deskhub/staff/data/remote/DeskHubApi.kt
index 5c04909b..58b3eaca 100644
--- a/mobile/src/main/java/de/deskhub/staff/data/remote/DeskHubApi.kt
+++ b/mobile/src/main/java/de/deskhub/staff/data/remote/DeskHubApi.kt
@@ -1,661 +1,702 @@
-package de.deskhub.staff.data.remote
-
-import com.google.gson.GsonBuilder
-import de.deskhub.staff.data.remote.dto.ActivityResponseDto
-import de.deskhub.staff.data.remote.dto.AssistantAnswerResponseDto
-import de.deskhub.staff.data.remote.dto.AssistantAnswersDto
-import de.deskhub.staff.data.remote.dto.AssistantLogDto
-import de.deskhub.staff.data.remote.dto.AssistantOkDto
-import de.deskhub.staff.data.remote.dto.AssistantOverviewDto
-import de.deskhub.staff.data.remote.dto.AssistantTestDto
-import de.deskhub.staff.data.remote.dto.CannedResponseListResponse
-import de.deskhub.staff.data.remote.dto.CreateTicketRequest
-import de.deskhub.staff.data.remote.dto.CreateTicketResponse
-import de.deskhub.staff.data.remote.dto.CustomerListResponse
-import de.deskhub.staff.data.remote.dto.CustomerProfileResponse
-import de.deskhub.staff.data.remote.dto.AuditLogResponse
-import de.deskhub.staff.data.remote.dto.BanBulkAddRequest
-import de.deskhub.staff.data.remote.dto.BanBulkAddResponse
-import de.deskhub.staff.data.remote.dto.BanCreateRequest
-import de.deskhub.staff.data.remote.dto.BanDeleteRequest
-import de.deskhub.staff.data.remote.dto.BanlistResponse
-import de.deskhub.staff.data.remote.dto.BusinessHolidayAddRequest
-import de.deskhub.staff.data.remote.dto.ChatContactsResponse
-import de.deskhub.staff.data.remote.dto.ChatConversationResponse
-import de.deskhub.staff.data.remote.dto.ChatSendRequest
-import de.deskhub.staff.data.remote.dto.ChatSendResponse
-import de.deskhub.staff.data.remote.dto.AutoCloseSaveRequest
-import de.deskhub.staff.data.remote.dto.AvailabilityResponse
-import de.deskhub.staff.data.remote.dto.AvailabilitySetRequest
-import de.deskhub.staff.data.remote.dto.AvailabilitySetResponse
-import de.deskhub.staff.data.remote.dto.LiveChatActionRequest
-import de.deskhub.staff.data.remote.dto.LiveChatListResponse
-import de.deskhub.staff.data.remote.dto.LiveChatMessagesResponse
-import de.deskhub.staff.data.remote.dto.LiveChatSendRequest
-import de.deskhub.staff.data.remote.dto.LiveChatSendResponse
-import de.deskhub.staff.data.remote.dto.TicketRuleIdRequest
-import de.deskhub.staff.data.remote.dto.TicketRuleSaveRequest
-import de.deskhub.staff.data.remote.dto.TicketRuleSaveResponse
-import de.deskhub.staff.data.remote.dto.TicketRulesResponse
-import de.deskhub.staff.data.remote.dto.BusinessHolidayDeleteRequest
-import de.deskhub.staff.data.remote.dto.BusinessHourDto
-import de.deskhub.staff.data.remote.dto.BusinessHoursResponse
-import de.deskhub.staff.data.remote.dto.BusinessHoursSaveRequest
-import de.deskhub.staff.data.remote.dto.DashboardResponseDto
-import de.deskhub.staff.data.remote.dto.DepartmentDeleteRequest
-import de.deskhub.staff.data.remote.dto.DepartmentListResponse
-import de.deskhub.staff.data.remote.dto.DepartmentSaveRequest
-import de.deskhub.staff.data.remote.dto.EmailAddressActionRequest
-import de.deskhub.staff.data.remote.dto.EmailAddressActionResponse
-import de.deskhub.staff.data.remote.dto.EmailAddressDeleteRequest
-import de.deskhub.staff.data.remote.dto.EmailAddressListResponse
-import de.deskhub.staff.data.remote.dto.EmailAddressSaveRequest
-import de.deskhub.staff.data.remote.dto.EmailTemplateListResponse
-import de.deskhub.staff.data.remote.dto.EmailTemplateResetRequest
-import de.deskhub.staff.data.remote.dto.EmailTemplateSaveRequest
-import de.deskhub.staff.data.remote.dto.ErrorEnvelope
-import de.deskhub.staff.data.remote.dto.EscalationDeleteRequest
-import de.deskhub.staff.data.remote.dto.EscalationRulesResponse
-import de.deskhub.staff.data.remote.dto.EscalationSaveRequest
-import de.deskhub.staff.data.remote.dto.EscalationToggleRequest
-import de.deskhub.staff.data.remote.dto.HelpTopicDeleteRequest
-import de.deskhub.staff.data.remote.dto.HelpTopicListResponse
-import de.deskhub.staff.data.remote.dto.HelpTopicSaveRequest
-import de.deskhub.staff.data.remote.dto.IdResponse
-import de.deskhub.staff.data.remote.dto.KbCreateCategoryRequest
-import de.deskhub.staff.data.remote.dto.KbDeleteArticleRequest
-import de.deskhub.staff.data.remote.dto.KbDeleteCategoryRequest
-import de.deskhub.staff.data.remote.dto.KbIdResponse
-import de.deskhub.staff.data.remote.dto.KbResponse
-import de.deskhub.staff.data.remote.dto.KbSaveArticleRequest
-import de.deskhub.staff.data.remote.dto.LoginRequest
-import de.deskhub.staff.data.remote.dto.LoginResponse
-import de.deskhub.staff.data.remote.dto.MessageRequest
-import de.deskhub.staff.data.remote.dto.MessageResponse
-import de.deskhub.staff.data.remote.dto.MetadataResponse
-import de.deskhub.staff.data.remote.dto.OrganizationDeleteRequest
-import de.deskhub.staff.data.remote.dto.OrganizationListResponse
-import de.deskhub.staff.data.remote.dto.OrganizationSaveRequest
-import de.deskhub.staff.data.remote.dto.PriorityDeleteRequest
-import de.deskhub.staff.data.remote.dto.PriorityListResponse
-import de.deskhub.staff.data.remote.dto.PrioritySaveRequest
-import de.deskhub.staff.data.remote.dto.RoleDeleteRequest
-import de.deskhub.staff.data.remote.dto.RoleListResponse
-import de.deskhub.staff.data.remote.dto.RoleSaveRequest
-import de.deskhub.staff.data.remote.dto.StaffAdminDeleteRequest
-import de.deskhub.staff.data.remote.dto.StaffAdminListResponse
-import de.deskhub.staff.data.remote.dto.StaffAdminSaveRequest
-import de.deskhub.staff.data.remote.dto.StaffResponse
-import de.deskhub.staff.data.remote.dto.TaskCreateRequest
-import de.deskhub.staff.data.remote.dto.TaskDeleteRequest
-import de.deskhub.staff.data.remote.dto.TaskListResponse
-import de.deskhub.staff.data.remote.dto.TaskUpdateStatusRequest
-import de.deskhub.staff.data.remote.dto.TeamDeleteRequest
-import de.deskhub.staff.data.remote.dto.TeamListResponse
-import de.deskhub.staff.data.remote.dto.TeamSaveRequest
-import de.deskhub.staff.data.remote.dto.TeamToggleRequest
-import de.deskhub.staff.data.remote.dto.TicketPageResponse
-import de.deskhub.staff.data.remote.dto.UploadImageResponse
-import de.deskhub.staff.data.remote.dto.TicketResponse
-import de.deskhub.staff.data.remote.dto.TicketSpamRequest
-import de.deskhub.staff.data.remote.dto.TicketSpamResponse
-import de.deskhub.staff.data.remote.dto.TicketSummaryResponse
-import de.deskhub.staff.data.remote.dto.TimeEntriesResponse
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import okhttp3.HttpUrl
-import okhttp3.HttpUrl.Companion.toHttpUrl
-import okhttp3.MediaType.Companion.toMediaType
-import okhttp3.MultipartBody
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.RequestBody.Companion.toRequestBody
-import java.net.URI
-import java.util.concurrent.TimeUnit
-
-class ApiException(
- val status: Int,
- val code: String,
- override val message: String,
-) : Exception(message)
-
-object DeskHubUrl {
- fun normalize(input: String): String {
- val candidate = input.trim().let {
- if (it.contains("://")) it else "https://$it"
- }
- val uri = runCatching { URI(candidate) }
- .getOrElse { throw IllegalArgumentException("Die Server-Adresse ist ungültig.") }
- require(uri.scheme.equals("https", ignoreCase = true)) {
- "Die Server-Adresse muss HTTPS verwenden."
- }
- require(uri.host != null && uri.userInfo == null && uri.query == null && uri.fragment == null) {
- "Die Server-Adresse ist ungültig."
- }
- val path = uri.path.orEmpty().trimEnd('/')
- return URI("https", null, uri.host, uri.port, path, null, null).toASCIIString()
- }
-}
-
-class DeskHubApi(
- serverUrl: String,
- private val tokenProvider: () -> String?,
-) {
- private val baseUrl = DeskHubUrl.normalize(serverUrl)
- private val gson = GsonBuilder().serializeNulls().create()
- private val jsonType = "application/json; charset=utf-8".toMediaType()
- private val client = OkHttpClient.Builder()
- .connectTimeout(15, TimeUnit.SECONDS)
- .readTimeout(30, TimeUnit.SECONDS)
- .writeTimeout(30, TimeUnit.SECONDS)
- .retryOnConnectionFailure(true)
- .build()
-
- suspend fun login(request: LoginRequest): LoginResponse =
- execute("login.php", "POST", request, LoginResponse::class.java, authenticated = false)
-
- suspend fun me(): StaffResponse =
- execute("me.php", "GET", null, StaffResponse::class.java)
-
- suspend fun metadata(): MetadataResponse =
- execute("metadata.php", "GET", null, MetadataResponse::class.java)
-
- suspend fun tickets(query: Map): TicketPageResponse =
- execute("tickets.php", "GET", null, TicketPageResponse::class.java, query = query)
-
- suspend fun ticket(number: String): TicketResponse =
- execute(
- "ticket.php",
- "GET",
- null,
- TicketResponse::class.java,
- query = mapOf("number" to number),
- )
-
- suspend fun assistantOverview(): AssistantOverviewDto =
- execute("assistant.php", "GET", null, AssistantOverviewDto::class.java, query = mapOf("section" to "overview"))
-
- suspend fun assistantAnswers(): AssistantAnswersDto =
- execute("assistant.php", "GET", null, AssistantAnswersDto::class.java, query = mapOf("section" to "answers"))
-
- suspend fun assistantLog(query: Map): AssistantLogDto =
- execute("assistant.php", "GET", null, AssistantLogDto::class.java, query = query + ("section" to "log"))
-
- suspend fun assistantAction(request: Map): AssistantOkDto =
- execute("assistant.php", "POST", request, AssistantOkDto::class.java)
-
- suspend fun assistantSaveAnswer(request: Map): AssistantAnswerResponseDto =
- execute("assistant.php", "POST", request, AssistantAnswerResponseDto::class.java)
-
- suspend fun assistantTest(question: String): AssistantTestDto =
- execute("assistant.php", "POST", mapOf("action" to "test", "question" to question), AssistantTestDto::class.java)
-
- suspend fun updateTicket(request: Map): TicketSummaryResponse =
- execute("ticket_update.php", "PATCH", request, TicketSummaryResponse::class.java)
-
- suspend fun addMessage(request: MessageRequest): MessageResponse =
- execute("ticket_message.php", "POST", request, MessageResponse::class.java)
-
- suspend fun ticketSpam(number: String, action: String): TicketSpamResponse =
- execute("ticket_spam.php", "POST", TicketSpamRequest(number = number, action = action), TicketSpamResponse::class.java)
-
- suspend fun cannedResponses(): CannedResponseListResponse =
- execute("canned_responses.php", "GET", null, CannedResponseListResponse::class.java)
-
- suspend fun dashboard(): DashboardResponseDto =
- execute("dashboard.php", "GET", null, DashboardResponseDto::class.java)
-
- suspend fun customers(query: String): CustomerListResponse =
- execute(
- "customers.php",
- "GET",
- null,
- CustomerListResponse::class.java,
- query = if (query.isBlank()) emptyMap() else mapOf("q" to query),
- )
-
- suspend fun customer(userId: Int?, email: String?): CustomerProfileResponse {
- val query = buildMap {
- if (userId != null) put("userId", userId.toString()) else email?.let { put("email", it) }
- }
- return execute("customer.php", "GET", null, CustomerProfileResponse::class.java, query = query)
- }
-
- suspend fun createTicket(request: CreateTicketRequest): CreateTicketResponse =
- execute("ticket_create.php", "POST", request, CreateTicketResponse::class.java)
-
- suspend fun activity(since: String): ActivityResponseDto =
- execute("activity.php", "GET", null, ActivityResponseDto::class.java, query = mapOf("since" to since))
-
- suspend fun logout() {
- execute("logout.php", "POST", emptyMap(), Map::class.java)
- }
-
- suspend fun pushPrefs(): de.deskhub.staff.data.remote.dto.PushPrefsDto =
- execute("push_prefs.php", "GET", null, de.deskhub.staff.data.remote.dto.PushPrefsDto::class.java)
-
- suspend fun savePushPrefs(request: de.deskhub.staff.data.remote.dto.PushPrefsRequest): de.deskhub.staff.data.remote.dto.PushPrefsDto =
- execute("push_prefs.php", "POST", request, de.deskhub.staff.data.remote.dto.PushPrefsDto::class.java)
-
- suspend fun crashReport(request: de.deskhub.staff.data.remote.dto.CrashReportRequest) {
- execute("crash_report.php", "POST", request, Map::class.java)
- }
-
- suspend fun pushDevice(request: de.deskhub.staff.data.remote.dto.PushDeviceRequest): de.deskhub.staff.data.remote.dto.PushDeviceResponse =
- execute("push_device.php", "POST", request, de.deskhub.staff.data.remote.dto.PushDeviceResponse::class.java)
-
- // ─── Admin: Wissensdatenbank ─────────────────────────────────────────────
-
- suspend fun kb(): KbResponse =
- execute("kb.php", "GET", null, KbResponse::class.java)
-
- suspend fun kbSaveArticle(request: KbSaveArticleRequest): KbIdResponse =
- execute("kb.php", "POST", request, KbIdResponse::class.java)
-
- suspend fun kbDeleteArticle(id: Int) {
- execute("kb.php", "POST", KbDeleteArticleRequest(id = id), Map::class.java)
- }
-
- suspend fun kbCreateCategory(name: String): KbIdResponse =
- execute("kb.php", "POST", KbCreateCategoryRequest(name = name), KbIdResponse::class.java)
-
- suspend fun kbDeleteCategory(id: Int) {
- execute("kb.php", "POST", KbDeleteCategoryRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Zeiterfassung ────────────────────────────────────────────────
-
- suspend fun timeEntries(query: Map): TimeEntriesResponse =
- execute("time_entries.php", "GET", null, TimeEntriesResponse::class.java, query = query)
-
- // ─── Admin: Eskalationsregeln ────────────────────────────────────────────
-
- suspend fun escalationRules(): EscalationRulesResponse =
- execute("escalation_rules.php", "GET", null, EscalationRulesResponse::class.java)
-
- suspend fun escalationSave(request: EscalationSaveRequest): KbIdResponse =
- execute("escalation_rules.php", "POST", request, KbIdResponse::class.java)
-
- suspend fun escalationDelete(id: Int) {
- execute("escalation_rules.php", "POST", EscalationDeleteRequest(id = id), Map::class.java)
- }
-
- suspend fun escalationToggle(id: Int) {
- execute("escalation_rules.php", "POST", EscalationToggleRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Sperrliste ───────────────────────────────────────────────────
-
- suspend fun banlist(): BanlistResponse =
- execute("banlist.php", "GET", null, BanlistResponse::class.java)
-
- suspend fun banCreate(matchType: String, value: String, reason: String?) {
- execute("banlist.php", "POST", BanCreateRequest(matchType = matchType, value = value, reason = reason), Map::class.java)
- }
-
- suspend fun banBulkAdd(values: String, reason: String?): BanBulkAddResponse =
- execute("banlist.php", "POST", BanBulkAddRequest(values = values, reason = reason), BanBulkAddResponse::class.java)
-
- suspend fun banDelete(id: Int) {
- execute("banlist.php", "POST", BanDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Abteilungen ──────────────────────────────────────────────────
-
- suspend fun departments(): DepartmentListResponse =
- execute("departments.php", "GET", null, DepartmentListResponse::class.java)
-
- suspend fun departmentSave(request: DepartmentSaveRequest): IdResponse =
- execute("departments.php", "POST", request, IdResponse::class.java)
-
- suspend fun departmentDelete(id: Int) {
- execute("departments.php", "POST", DepartmentDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Prioritäten ──────────────────────────────────────────────────
-
- suspend fun report(query: Map): de.deskhub.staff.data.remote.dto.ReportResponseDto =
- execute("report_builder.php", "GET", null, de.deskhub.staff.data.remote.dto.ReportResponseDto::class.java, query = query)
-
- suspend fun reportSave(request: de.deskhub.staff.data.remote.dto.ReportSaveRequest): IdResponse =
- execute("report_builder.php", "POST", request, IdResponse::class.java)
-
- suspend fun reportDelete(id: Int) {
- execute("report_builder.php", "POST", de.deskhub.staff.data.remote.dto.ReportDeleteRequest(id = id), Map::class.java)
- }
-
- suspend fun savedViews(): de.deskhub.staff.data.remote.dto.SavedViewListResponse =
- execute("queues.php", "GET", null, de.deskhub.staff.data.remote.dto.SavedViewListResponse::class.java)
-
- suspend fun savedViewSave(request: de.deskhub.staff.data.remote.dto.SavedViewSaveRequest): IdResponse =
- execute("queues.php", "POST", request, IdResponse::class.java)
-
- suspend fun savedViewDelete(id: Int) {
- execute("queues.php", "POST", de.deskhub.staff.data.remote.dto.SavedViewDeleteRequest(id = id), Map::class.java)
- }
-
- suspend fun slaPlans(): de.deskhub.staff.data.remote.dto.SlaPlanListResponse =
- execute("sla_plans.php", "GET", null, de.deskhub.staff.data.remote.dto.SlaPlanListResponse::class.java)
-
- suspend fun slaPlanSave(request: de.deskhub.staff.data.remote.dto.SlaPlanSaveRequest): IdResponse =
- execute("sla_plans.php", "POST", request, IdResponse::class.java)
-
- suspend fun slaPlanDelete(id: Int) {
- execute("sla_plans.php", "POST", de.deskhub.staff.data.remote.dto.SlaPlanDeleteRequest(id = id), Map::class.java)
- }
-
- suspend fun prioritiesAdmin(): PriorityListResponse =
- execute("priorities.php", "GET", null, PriorityListResponse::class.java)
-
- suspend fun prioritySave(request: PrioritySaveRequest): IdResponse =
- execute("priorities.php", "POST", request, IdResponse::class.java)
-
- suspend fun priorityDelete(id: Int) {
- execute("priorities.php", "POST", PriorityDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Hilfe-Themen ─────────────────────────────────────────────────
-
- suspend fun helpTopics(): HelpTopicListResponse =
- execute("help_topics.php", "GET", null, HelpTopicListResponse::class.java)
-
- suspend fun helpTopicSave(request: HelpTopicSaveRequest): IdResponse =
- execute("help_topics.php", "POST", request, IdResponse::class.java)
-
- suspend fun helpTopicDelete(id: Int) {
- execute("help_topics.php", "POST", HelpTopicDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Organisationen ───────────────────────────────────────────────
-
- suspend fun organizations(): OrganizationListResponse =
- execute("organizations.php", "GET", null, OrganizationListResponse::class.java)
-
- suspend fun organizationSave(request: OrganizationSaveRequest): IdResponse =
- execute("organizations.php", "POST", request, IdResponse::class.java)
-
- suspend fun organizationDelete(id: Int) {
- execute("organizations.php", "POST", OrganizationDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Teams ────────────────────────────────────────────────────────
-
- suspend fun teams(): TeamListResponse =
- execute("teams.php", "GET", null, TeamListResponse::class.java)
-
- suspend fun teamSave(request: TeamSaveRequest): IdResponse =
- execute("teams.php", "POST", request, IdResponse::class.java)
-
- suspend fun teamToggle(id: Int) {
- execute("teams.php", "POST", TeamToggleRequest(id = id), Map::class.java)
- }
-
- suspend fun teamDelete(id: Int) {
- execute("teams.php", "POST", TeamDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Rollen ───────────────────────────────────────────────────────
-
- suspend fun roles(): RoleListResponse =
- execute("roles.php", "GET", null, RoleListResponse::class.java)
-
- suspend fun roleSave(request: RoleSaveRequest): IdResponse =
- execute("roles.php", "POST", request, IdResponse::class.java)
-
- suspend fun roleDelete(id: Int) {
- execute("roles.php", "POST", RoleDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Mitarbeiter ──────────────────────────────────────────────────
-
- suspend fun staffAdminList(): StaffAdminListResponse =
- execute("staff_manage.php", "GET", null, StaffAdminListResponse::class.java)
-
- suspend fun staffAdminSave(request: StaffAdminSaveRequest): IdResponse =
- execute("staff_manage.php", "POST", request, IdResponse::class.java)
-
- suspend fun staffAdminDelete(id: Int) {
- execute("staff_manage.php", "POST", StaffAdminDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: Geschäftszeiten ──────────────────────────────────────────────
-
- suspend fun businessHours(): BusinessHoursResponse =
- execute("business_hours.php", "GET", null, BusinessHoursResponse::class.java)
-
- suspend fun businessHoursSave(enabled: Boolean, hours: List) {
- execute("business_hours.php", "POST", BusinessHoursSaveRequest(enabled = enabled, hours = hours), Map::class.java)
- }
-
- suspend fun businessHolidayAdd(date: String, name: String): IdResponse =
- execute("business_hours.php", "POST", BusinessHolidayAddRequest(date = date, name = name), IdResponse::class.java)
-
- suspend fun businessHolidayDelete(id: Int) {
- execute("business_hours.php", "POST", BusinessHolidayDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: E-Mail-Adressen ──────────────────────────────────────────────
-
- suspend fun emailAddresses(): EmailAddressListResponse =
- execute("email_addresses.php", "GET", null, EmailAddressListResponse::class.java)
-
- suspend fun emailAddressSave(request: EmailAddressSaveRequest): IdResponse =
- execute("email_addresses.php", "POST", request, IdResponse::class.java)
-
- suspend fun emailAddressAction(action: String, id: Int): EmailAddressActionResponse =
- execute("email_addresses.php", "POST", EmailAddressActionRequest(action = action, id = id), EmailAddressActionResponse::class.java)
-
- suspend fun emailAddressDelete(id: Int) {
- execute("email_addresses.php", "POST", EmailAddressDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Admin: E-Mail-Vorlagen ──────────────────────────────────────────────
-
- suspend fun emailTemplates(): EmailTemplateListResponse =
- execute("email_templates.php", "GET", null, EmailTemplateListResponse::class.java)
-
- suspend fun emailTemplateSave(key: String, subject: String, bodyText: String) {
- execute("email_templates.php", "POST", EmailTemplateSaveRequest(key = key, subject = subject, body = bodyText), Map::class.java)
- }
-
- suspend fun emailTemplateReset(key: String) {
- execute("email_templates.php", "POST", EmailTemplateResetRequest(key = key), Map::class.java)
- }
-
- // ─── Admin: Admin-Protokoll ──────────────────────────────────────────────
-
- suspend fun auditLog(page: Int): AuditLogResponse =
- execute("audit_log.php", "GET", null, AuditLogResponse::class.java, query = mapOf("page" to page.toString()))
-
- // ─── Aufgaben ────────────────────────────────────────────────────────────
-
- suspend fun tasks(filter: String): TaskListResponse =
- execute("tasks.php", "GET", null, TaskListResponse::class.java, query = mapOf("filter" to filter))
-
- suspend fun taskCreate(request: TaskCreateRequest): IdResponse =
- execute("tasks.php", "POST", request, IdResponse::class.java)
-
- suspend fun taskUpdateStatus(id: Int, status: String) {
- execute("tasks.php", "POST", TaskUpdateStatusRequest(id = id, status = status), Map::class.java)
- }
-
- suspend fun taskDelete(id: Int) {
- execute("tasks.php", "POST", TaskDeleteRequest(id = id), Map::class.java)
- }
-
- // ─── Interner Chat ───────────────────────────────────────────────────────
-
- suspend fun chatContacts(): ChatContactsResponse =
- execute("chat.php", "GET", null, ChatContactsResponse::class.java)
-
- suspend fun chatConversation(withId: Int): ChatConversationResponse =
- execute("chat.php", "GET", null, ChatConversationResponse::class.java, query = mapOf("with" to withId.toString()))
-
- suspend fun chatSend(toId: Int, message: String): ChatSendResponse =
- execute("chat.php", "POST", ChatSendRequest(toId = toId, message = message), ChatSendResponse::class.java)
-
- // ─── Live-Chat (Kunden-Widget) ───────────────────────────────────────────
-
- suspend fun liveChatList(): LiveChatListResponse =
- execute("live_chat.php", "GET", null, LiveChatListResponse::class.java, query = mapOf("action" to "list"))
-
- suspend fun liveChatMessages(number: String, since: Int): LiveChatMessagesResponse =
- execute(
- "live_chat.php", "GET", null, LiveChatMessagesResponse::class.java,
- query = mapOf("action" to "messages", "number" to number, "since" to since.toString()),
- )
-
- suspend fun liveChatSend(number: String, message: String): LiveChatSendResponse =
- execute("live_chat.php", "POST", LiveChatSendRequest(number = number, message = message), LiveChatSendResponse::class.java)
-
- suspend fun liveChatTyping(number: String) {
- execute("live_chat.php", "POST", LiveChatActionRequest(action = "typing", number = number), Map::class.java)
- }
-
- suspend fun liveChatEnd(number: String) {
- execute("live_chat.php", "POST", LiveChatActionRequest(action = "end", number = number), Map::class.java)
- }
-
- // ─── Verfügbarkeit (Status) ──────────────────────────────────────────────
-
- suspend fun availability(): AvailabilityResponse =
- execute("availability.php", "GET", null, AvailabilityResponse::class.java)
-
- // ─── Cc-Empfänger, Vorlagen, Zufriedenheit, Statusseite ──────────────────
-
- suspend fun collaboratorAction(number: String, action: String, email: String? = null, id: Int? = null): de.deskhub.staff.data.remote.dto.CollaboratorsResponse =
- execute(
- "ticket_collaborators.php", "POST", mapOf("number" to number, "action" to action, "email" to email, "id" to id),
- de.deskhub.staff.data.remote.dto.CollaboratorsResponse::class.java,
- )
-
- suspend fun ticketTemplates(): de.deskhub.staff.data.remote.dto.TicketTemplatesResponse =
- execute("ticket_templates.php", "GET", null, de.deskhub.staff.data.remote.dto.TicketTemplatesResponse::class.java)
-
- suspend fun csatStats(days: Int): de.deskhub.staff.data.remote.dto.CsatResponse =
- execute("csat.php", "GET", null, de.deskhub.staff.data.remote.dto.CsatResponse::class.java, query = mapOf("days" to days.toString()))
-
- suspend fun statusPage(): de.deskhub.staff.data.remote.dto.StatusResponse =
- execute("status.php", "GET", null, de.deskhub.staff.data.remote.dto.StatusResponse::class.java)
-
- suspend fun statusAction(request: Map): de.deskhub.staff.data.remote.dto.StatusResponse =
- execute("status.php", "POST", request, de.deskhub.staff.data.remote.dto.StatusResponse::class.java)
-
- suspend fun unlockTicket(number: String): de.deskhub.staff.data.remote.dto.TicketUnlockResponse =
- execute("ticket_unlock.php", "POST", de.deskhub.staff.data.remote.dto.TicketUnlockRequest(number), de.deskhub.staff.data.remote.dto.TicketUnlockResponse::class.java)
-
- suspend fun setAvailability(status: String, note: String, staffId: Int? = null): AvailabilitySetResponse =
- execute("availability.php", "POST", AvailabilitySetRequest(status, note, staffId), AvailabilitySetResponse::class.java)
-
- /** Berührungs-Ping: die Person nutzt die App gerade (verhindert den automatischen Offline-Status). */
- suspend fun presence() {
- execute("presence.php", "POST", emptyMap(), Map::class.java)
- }
-
- // ─── Ticket-Regeln (Automatisierung) ─────────────────────────────────────
-
- suspend fun ticketRules(): TicketRulesResponse =
- execute("ticket_rules.php", "GET", null, TicketRulesResponse::class.java)
-
- suspend fun saveTicketRule(request: TicketRuleSaveRequest): TicketRuleSaveResponse =
- execute("ticket_rules.php", "POST", request, TicketRuleSaveResponse::class.java)
-
- suspend fun toggleTicketRule(id: Int) {
- execute("ticket_rules.php", "POST", TicketRuleIdRequest("toggle", id), Map::class.java)
- }
-
- suspend fun deleteTicketRule(id: Int) {
- execute("ticket_rules.php", "POST", TicketRuleIdRequest("delete", id), Map::class.java)
- }
-
- suspend fun saveAutoClose(enabled: Boolean, days: Int) {
- execute("ticket_rules.php", "POST", AutoCloseSaveRequest(enabled = enabled, days = days), Map::class.java)
- }
-
- private suspend fun execute(
- path: String,
- method: String,
- payload: Any?,
- responseType: Class,
- authenticated: Boolean = true,
- query: Map = emptyMap(),
- ): T = withContext(Dispatchers.IO) {
- val urlBuilder = "$baseUrl/api/staff/v1/$path".toHttpUrl().newBuilder()
- query.forEach { (key, value) -> urlBuilder.addQueryParameter(key, value) }
- val requestBuilder = Request.Builder()
- .url(urlBuilder.build())
- .header("Accept", "application/json")
- .header("Cache-Control", "no-cache, no-store")
- .header("Pragma", "no-cache")
- if (authenticated) {
- val token = tokenProvider()
- ?: throw ApiException(401, "UNAUTHENTICATED", "Keine lokale Anmeldung vorhanden.")
- requestBuilder.header("Authorization", "Bearer $token")
- requestBuilder.header("X-DeskHub-Authorization", "Bearer $token") // Ersatz-Header: viele Hoster entfernen "Authorization"
- }
- val body = payload?.let { gson.toJson(it).toRequestBody(jsonType) }
- when (method) {
- "GET" -> requestBuilder.get()
- "POST" -> requestBuilder.post(body ?: ByteArray(0).toRequestBody(jsonType))
- "PATCH" -> requestBuilder.patch(body ?: ByteArray(0).toRequestBody(jsonType))
- else -> error("Nicht unterstützte HTTP-Methode: $method")
- }
-
- val call = try {
- client.newCall(requestBuilder.build()).execute()
- } catch (e: java.io.IOException) {
- // Kein Netz, Server nicht erreichbar oder Zeitüberschreitung
- ConnectionMonitor.set(true)
- throw ApiException(0, "NETWORK", "Keine Verbindung zum Server.")
- }
- ConnectionMonitor.set(call.code in 502..504)
- call.use { response ->
- val responseBody = response.body?.string().orEmpty()
- if (!response.isSuccessful) {
- val envelope = runCatching { gson.fromJson(responseBody, ErrorEnvelope::class.java) }.getOrNull()
- throw ApiException(
- response.code,
- envelope?.error?.code ?: "HTTP_${response.code}",
- envelope?.error?.message ?: "Serverfehler (${response.code}).",
- )
- }
- if (responseBody.isBlank()) {
- throw ApiException(response.code, "EMPTY_RESPONSE", "Der Server hat keine Antwort geliefert.")
- }
- gson.fromJson(responseBody, responseType)
- ?: throw ApiException(response.code, "INVALID_RESPONSE", "Die Serverantwort ist ungültig.")
- }
- }
-
- /** Lädt ein Bild hoch (z.B. für eine Signatur) und liefert dessen öffentliche URL zurück. */
- suspend fun uploadImage(bytes: ByteArray, filename: String, mimeType: String): UploadImageResponse =
- withContext(Dispatchers.IO) {
- val token = tokenProvider()
- ?: throw ApiException(401, "UNAUTHENTICATED", "Keine lokale Anmeldung vorhanden.")
- val body = MultipartBody.Builder()
- .setType(MultipartBody.FORM)
- .addFormDataPart("image", filename, bytes.toRequestBody(mimeType.toMediaType()))
- .build()
- val request = Request.Builder()
- .url("$baseUrl/api/staff/v1/upload_image.php".toHttpUrl())
- .header("Accept", "application/json")
- .header("Authorization", "Bearer $token")
- .header("X-DeskHub-Authorization", "Bearer $token")
- .post(body)
- .build()
-
- client.newCall(request).execute().use { response ->
- val responseBody = response.body?.string().orEmpty()
- if (!response.isSuccessful) {
- val envelope = runCatching { gson.fromJson(responseBody, ErrorEnvelope::class.java) }.getOrNull()
- throw ApiException(
- response.code,
- envelope?.error?.code ?: "HTTP_${response.code}",
- envelope?.error?.message ?: "Serverfehler (${response.code}).",
- )
- }
- gson.fromJson(responseBody, UploadImageResponse::class.java)
- ?: throw ApiException(response.code, "INVALID_RESPONSE", "Die Serverantwort ist ungültig.")
- }
- }
-}
+package de.deskhub.staff.data.remote
+
+import com.google.gson.GsonBuilder
+import de.deskhub.staff.data.remote.dto.ActivityResponseDto
+import de.deskhub.staff.data.remote.dto.AssistantAnswerResponseDto
+import de.deskhub.staff.data.remote.dto.AssistantAnswersDto
+import de.deskhub.staff.data.remote.dto.AssistantLogDto
+import de.deskhub.staff.data.remote.dto.AssistantOkDto
+import de.deskhub.staff.data.remote.dto.AssistantOverviewDto
+import de.deskhub.staff.data.remote.dto.AssistantTestDto
+import de.deskhub.staff.data.remote.dto.CannedResponseListResponse
+import de.deskhub.staff.data.remote.dto.CreateTicketRequest
+import de.deskhub.staff.data.remote.dto.CreateTicketResponse
+import de.deskhub.staff.data.remote.dto.CustomerListResponse
+import de.deskhub.staff.data.remote.dto.CustomerProfileResponse
+import de.deskhub.staff.data.remote.dto.AuditLogResponse
+import de.deskhub.staff.data.remote.dto.BanBulkAddRequest
+import de.deskhub.staff.data.remote.dto.BanBulkAddResponse
+import de.deskhub.staff.data.remote.dto.BanCreateRequest
+import de.deskhub.staff.data.remote.dto.BanDeleteRequest
+import de.deskhub.staff.data.remote.dto.BanlistResponse
+import de.deskhub.staff.data.remote.dto.BusinessHolidayAddRequest
+import de.deskhub.staff.data.remote.dto.ChatContactsResponse
+import de.deskhub.staff.data.remote.dto.ChatConversationResponse
+import de.deskhub.staff.data.remote.dto.ChatSendRequest
+import de.deskhub.staff.data.remote.dto.ChatSendResponse
+import de.deskhub.staff.data.remote.dto.AutoCloseSaveRequest
+import de.deskhub.staff.data.remote.dto.AvailabilityResponse
+import de.deskhub.staff.data.remote.dto.AvailabilitySetRequest
+import de.deskhub.staff.data.remote.dto.AvailabilitySetResponse
+import de.deskhub.staff.data.remote.dto.LiveChatActionRequest
+import de.deskhub.staff.data.remote.dto.LiveChatListResponse
+import de.deskhub.staff.data.remote.dto.LiveChatMessagesResponse
+import de.deskhub.staff.data.remote.dto.LiveChatSendRequest
+import de.deskhub.staff.data.remote.dto.LiveChatSendResponse
+import de.deskhub.staff.data.remote.dto.TicketRuleIdRequest
+import de.deskhub.staff.data.remote.dto.TicketRuleSaveRequest
+import de.deskhub.staff.data.remote.dto.TicketRuleSaveResponse
+import de.deskhub.staff.data.remote.dto.TicketRulesResponse
+import de.deskhub.staff.data.remote.dto.BusinessHolidayDeleteRequest
+import de.deskhub.staff.data.remote.dto.BusinessHourDto
+import de.deskhub.staff.data.remote.dto.BusinessHoursResponse
+import de.deskhub.staff.data.remote.dto.BusinessHoursSaveRequest
+import de.deskhub.staff.data.remote.dto.DashboardResponseDto
+import de.deskhub.staff.data.remote.dto.DepartmentDeleteRequest
+import de.deskhub.staff.data.remote.dto.DepartmentListResponse
+import de.deskhub.staff.data.remote.dto.DepartmentSaveRequest
+import de.deskhub.staff.data.remote.dto.EmailAddressActionRequest
+import de.deskhub.staff.data.remote.dto.EmailAddressActionResponse
+import de.deskhub.staff.data.remote.dto.EmailAddressDeleteRequest
+import de.deskhub.staff.data.remote.dto.EmailAddressListResponse
+import de.deskhub.staff.data.remote.dto.EmailAddressSaveRequest
+import de.deskhub.staff.data.remote.dto.EmailTemplateListResponse
+import de.deskhub.staff.data.remote.dto.EmailTemplateResetRequest
+import de.deskhub.staff.data.remote.dto.EmailTemplateSaveRequest
+import de.deskhub.staff.data.remote.dto.ErrorEnvelope
+import de.deskhub.staff.data.remote.dto.EscalationDeleteRequest
+import de.deskhub.staff.data.remote.dto.EscalationRulesResponse
+import de.deskhub.staff.data.remote.dto.EscalationSaveRequest
+import de.deskhub.staff.data.remote.dto.EscalationToggleRequest
+import de.deskhub.staff.data.remote.dto.HelpTopicDeleteRequest
+import de.deskhub.staff.data.remote.dto.HelpTopicListResponse
+import de.deskhub.staff.data.remote.dto.HelpTopicSaveRequest
+import de.deskhub.staff.data.remote.dto.IdResponse
+import de.deskhub.staff.data.remote.dto.KbCreateCategoryRequest
+import de.deskhub.staff.data.remote.dto.KbDeleteArticleRequest
+import de.deskhub.staff.data.remote.dto.KbDeleteCategoryRequest
+import de.deskhub.staff.data.remote.dto.KbIdResponse
+import de.deskhub.staff.data.remote.dto.KbResponse
+import de.deskhub.staff.data.remote.dto.KbSaveArticleRequest
+import de.deskhub.staff.data.remote.dto.LoginRequest
+import de.deskhub.staff.data.remote.dto.LoginResponse
+import de.deskhub.staff.data.remote.dto.MessageRequest
+import de.deskhub.staff.data.remote.dto.MessageResponse
+import de.deskhub.staff.data.remote.dto.MetadataResponse
+import de.deskhub.staff.data.remote.dto.OrganizationDeleteRequest
+import de.deskhub.staff.data.remote.dto.OrganizationListResponse
+import de.deskhub.staff.data.remote.dto.OrganizationSaveRequest
+import de.deskhub.staff.data.remote.dto.PriorityDeleteRequest
+import de.deskhub.staff.data.remote.dto.PriorityListResponse
+import de.deskhub.staff.data.remote.dto.PrioritySaveRequest
+import de.deskhub.staff.data.remote.dto.RoleDeleteRequest
+import de.deskhub.staff.data.remote.dto.RoleListResponse
+import de.deskhub.staff.data.remote.dto.RoleSaveRequest
+import de.deskhub.staff.data.remote.dto.StaffAdminDeleteRequest
+import de.deskhub.staff.data.remote.dto.StaffAdminListResponse
+import de.deskhub.staff.data.remote.dto.StaffAdminSaveRequest
+import de.deskhub.staff.data.remote.dto.StaffResponse
+import de.deskhub.staff.data.remote.dto.TaskCreateRequest
+import de.deskhub.staff.data.remote.dto.TaskDeleteRequest
+import de.deskhub.staff.data.remote.dto.TaskListResponse
+import de.deskhub.staff.data.remote.dto.TaskUpdateStatusRequest
+import de.deskhub.staff.data.remote.dto.TeamDeleteRequest
+import de.deskhub.staff.data.remote.dto.TeamListResponse
+import de.deskhub.staff.data.remote.dto.TeamSaveRequest
+import de.deskhub.staff.data.remote.dto.TeamToggleRequest
+import de.deskhub.staff.data.remote.dto.TicketPageResponse
+import de.deskhub.staff.data.remote.dto.UploadImageResponse
+import de.deskhub.staff.data.remote.dto.TicketResponse
+import de.deskhub.staff.data.remote.dto.TicketSpamRequest
+import de.deskhub.staff.data.remote.dto.TicketSpamResponse
+import de.deskhub.staff.data.remote.dto.TicketSummaryResponse
+import de.deskhub.staff.data.remote.dto.TimeEntriesResponse
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import okhttp3.HttpUrl
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import okhttp3.MediaType.Companion.toMediaType
+import okhttp3.MultipartBody
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.RequestBody.Companion.toRequestBody
+import java.net.URI
+import java.util.concurrent.TimeUnit
+
+class ApiException(
+ val status: Int,
+ val code: String,
+ override val message: String,
+) : Exception(message)
+
+object DeskHubUrl {
+ fun normalize(input: String): String {
+ val candidate = input.trim().let {
+ if (it.contains("://")) it else "https://$it"
+ }
+ val uri = runCatching { URI(candidate) }
+ .getOrElse { throw IllegalArgumentException("Die Server-Adresse ist ungültig.") }
+ require(uri.scheme.equals("https", ignoreCase = true)) {
+ "Die Server-Adresse muss HTTPS verwenden."
+ }
+ require(uri.host != null && uri.userInfo == null && uri.query == null && uri.fragment == null) {
+ "Die Server-Adresse ist ungültig."
+ }
+ val path = uri.path.orEmpty().trimEnd('/')
+ return URI("https", null, uri.host, uri.port, path, null, null).toASCIIString()
+ }
+}
+
+class DeskHubApi(
+ serverUrl: String,
+ private val tokenProvider: () -> String?,
+) {
+ private val baseUrl = DeskHubUrl.normalize(serverUrl)
+ private val gson = GsonBuilder().serializeNulls().create()
+ private val jsonType = "application/json; charset=utf-8".toMediaType()
+ private val client = OkHttpClient.Builder()
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .writeTimeout(30, TimeUnit.SECONDS)
+ .retryOnConnectionFailure(true)
+ .build()
+
+ suspend fun login(request: LoginRequest): LoginResponse =
+ execute("login.php", "POST", request, LoginResponse::class.java, authenticated = false)
+
+ suspend fun me(): StaffResponse =
+ execute("me.php", "GET", null, StaffResponse::class.java)
+
+ suspend fun metadata(): MetadataResponse =
+ execute("metadata.php", "GET", null, MetadataResponse::class.java)
+
+ suspend fun tickets(query: Map): TicketPageResponse =
+ execute("tickets.php", "GET", null, TicketPageResponse::class.java, query = query)
+
+ suspend fun ticket(number: String): TicketResponse =
+ execute(
+ "ticket.php",
+ "GET",
+ null,
+ TicketResponse::class.java,
+ query = mapOf("number" to number),
+ )
+
+ suspend fun assistantOverview(): AssistantOverviewDto =
+ execute("assistant.php", "GET", null, AssistantOverviewDto::class.java, query = mapOf("section" to "overview"))
+
+ suspend fun assistantAnswers(): AssistantAnswersDto =
+ execute("assistant.php", "GET", null, AssistantAnswersDto::class.java, query = mapOf("section" to "answers"))
+
+ suspend fun assistantLog(query: Map): AssistantLogDto =
+ execute("assistant.php", "GET", null, AssistantLogDto::class.java, query = query + ("section" to "log"))
+
+ suspend fun assistantAction(request: Map): AssistantOkDto =
+ execute("assistant.php", "POST", request, AssistantOkDto::class.java)
+
+ suspend fun assistantSaveAnswer(request: Map): AssistantAnswerResponseDto =
+ execute("assistant.php", "POST", request, AssistantAnswerResponseDto::class.java)
+
+ suspend fun assistantTest(question: String): AssistantTestDto =
+ execute("assistant.php", "POST", mapOf("action" to "test", "question" to question), AssistantTestDto::class.java)
+
+ suspend fun updateTicket(request: Map): TicketSummaryResponse =
+ execute("ticket_update.php", "PATCH", request, TicketSummaryResponse::class.java)
+
+ suspend fun addMessage(request: MessageRequest): MessageResponse =
+ execute("ticket_message.php", "POST", request, MessageResponse::class.java)
+
+ suspend fun ticketSpam(number: String, action: String): TicketSpamResponse =
+ execute("ticket_spam.php", "POST", TicketSpamRequest(number = number, action = action), TicketSpamResponse::class.java)
+
+ suspend fun cannedResponses(): CannedResponseListResponse =
+ execute("canned_responses.php", "GET", null, CannedResponseListResponse::class.java)
+
+ suspend fun dashboard(): DashboardResponseDto =
+ execute("dashboard.php", "GET", null, DashboardResponseDto::class.java)
+
+ suspend fun customers(query: String): CustomerListResponse =
+ execute(
+ "customers.php",
+ "GET",
+ null,
+ CustomerListResponse::class.java,
+ query = if (query.isBlank()) emptyMap() else mapOf("q" to query),
+ )
+
+ suspend fun customer(userId: Int?, email: String?): CustomerProfileResponse {
+ val query = buildMap {
+ if (userId != null) put("userId", userId.toString()) else email?.let { put("email", it) }
+ }
+ return execute("customer.php", "GET", null, CustomerProfileResponse::class.java, query = query)
+ }
+
+ suspend fun createTicket(request: CreateTicketRequest): CreateTicketResponse =
+ execute("ticket_create.php", "POST", request, CreateTicketResponse::class.java)
+
+ suspend fun activity(since: String): ActivityResponseDto =
+ execute("activity.php", "GET", null, ActivityResponseDto::class.java, query = mapOf("since" to since))
+
+ /** Neueste veröffentlichte Android-Version (Quelle: Plugin-Webseite, über den DeskHub-Server). */
+ suspend fun appUpdate(): de.deskhub.staff.data.remote.dto.AppUpdateDto =
+ execute("app_update.php", "GET", null, de.deskhub.staff.data.remote.dto.AppUpdateDto::class.java, query = mapOf("platform" to "android"))
+
+ /** Lädt die APK nach [target] und prüft die SHA-256-Prüfsumme; [onProgress] liefert 0–100. */
+ suspend fun downloadAppUpdate(target: java.io.File, expectedSha256: String, onProgress: (Int) -> Unit) = withContext(Dispatchers.IO) {
+ val token = tokenProvider() ?: throw ApiException(401, "UNAUTHENTICATED", "Keine lokale Anmeldung vorhanden.")
+ val request = Request.Builder()
+ .url("$baseUrl/api/staff/v1/app_update.php".toHttpUrl().newBuilder().addQueryParameter("platform", "android").addQueryParameter("download", "1").build())
+ .header("Authorization", "Bearer $token")
+ .header("X-DeskHub-Authorization", "Bearer $token")
+ .build()
+ val longClient = client.newBuilder().readTimeout(120, TimeUnit.SECONDS).build()
+ val response = try { longClient.newCall(request).execute() } catch (e: java.io.IOException) { throw ApiException(0, "NETWORK", "Keine Verbindung zum Server.") }
+ response.use { r ->
+ if (!r.isSuccessful) throw ApiException(r.code, "HTTP_${r.code}", "Download fehlgeschlagen (${r.code}).")
+ val body = r.body ?: throw ApiException(r.code, "EMPTY_RESPONSE", "Der Server hat keine Datei geliefert.")
+ val total = body.contentLength()
+ val digest = java.security.MessageDigest.getInstance("SHA-256")
+ target.parentFile?.mkdirs()
+ var got = 0L
+ var last = -1
+ body.byteStream().use { input ->
+ target.outputStream().use { output ->
+ val buffer = ByteArray(64 * 1024)
+ while (true) {
+ val n = input.read(buffer)
+ if (n < 0) break
+ output.write(buffer, 0, n); digest.update(buffer, 0, n); got += n
+ if (total > 0) { val pct = (got * 100 / total).toInt(); if (pct != last) { last = pct; onProgress(pct) } }
+ }
+ }
+ }
+ val sha = digest.digest().joinToString("") { "%02x".format(it) }
+ if (!sha.equals(expectedSha256, ignoreCase = true)) {
+ target.delete()
+ throw ApiException(0, "CHECKSUM", "Die heruntergeladene Datei ist beschädigt (Prüfsumme stimmt nicht). Bitte erneut versuchen.")
+ }
+ }
+ }
+
+ suspend fun logout() {
+ execute("logout.php", "POST", emptyMap(), Map::class.java)
+ }
+
+ suspend fun pushPrefs(): de.deskhub.staff.data.remote.dto.PushPrefsDto =
+ execute("push_prefs.php", "GET", null, de.deskhub.staff.data.remote.dto.PushPrefsDto::class.java)
+
+ suspend fun savePushPrefs(request: de.deskhub.staff.data.remote.dto.PushPrefsRequest): de.deskhub.staff.data.remote.dto.PushPrefsDto =
+ execute("push_prefs.php", "POST", request, de.deskhub.staff.data.remote.dto.PushPrefsDto::class.java)
+
+ suspend fun crashReport(request: de.deskhub.staff.data.remote.dto.CrashReportRequest) {
+ execute("crash_report.php", "POST", request, Map::class.java)
+ }
+
+ suspend fun pushDevice(request: de.deskhub.staff.data.remote.dto.PushDeviceRequest): de.deskhub.staff.data.remote.dto.PushDeviceResponse =
+ execute("push_device.php", "POST", request, de.deskhub.staff.data.remote.dto.PushDeviceResponse::class.java)
+
+ // ─── Admin: Wissensdatenbank ─────────────────────────────────────────────
+
+ suspend fun kb(): KbResponse =
+ execute("kb.php", "GET", null, KbResponse::class.java)
+
+ suspend fun kbSaveArticle(request: KbSaveArticleRequest): KbIdResponse =
+ execute("kb.php", "POST", request, KbIdResponse::class.java)
+
+ suspend fun kbDeleteArticle(id: Int) {
+ execute("kb.php", "POST", KbDeleteArticleRequest(id = id), Map::class.java)
+ }
+
+ suspend fun kbCreateCategory(name: String): KbIdResponse =
+ execute("kb.php", "POST", KbCreateCategoryRequest(name = name), KbIdResponse::class.java)
+
+ suspend fun kbDeleteCategory(id: Int) {
+ execute("kb.php", "POST", KbDeleteCategoryRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Zeiterfassung ────────────────────────────────────────────────
+
+ suspend fun timeEntries(query: Map): TimeEntriesResponse =
+ execute("time_entries.php", "GET", null, TimeEntriesResponse::class.java, query = query)
+
+ // ─── Admin: Eskalationsregeln ────────────────────────────────────────────
+
+ suspend fun escalationRules(): EscalationRulesResponse =
+ execute("escalation_rules.php", "GET", null, EscalationRulesResponse::class.java)
+
+ suspend fun escalationSave(request: EscalationSaveRequest): KbIdResponse =
+ execute("escalation_rules.php", "POST", request, KbIdResponse::class.java)
+
+ suspend fun escalationDelete(id: Int) {
+ execute("escalation_rules.php", "POST", EscalationDeleteRequest(id = id), Map::class.java)
+ }
+
+ suspend fun escalationToggle(id: Int) {
+ execute("escalation_rules.php", "POST", EscalationToggleRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Sperrliste ───────────────────────────────────────────────────
+
+ suspend fun banlist(): BanlistResponse =
+ execute("banlist.php", "GET", null, BanlistResponse::class.java)
+
+ suspend fun banCreate(matchType: String, value: String, reason: String?) {
+ execute("banlist.php", "POST", BanCreateRequest(matchType = matchType, value = value, reason = reason), Map::class.java)
+ }
+
+ suspend fun banBulkAdd(values: String, reason: String?): BanBulkAddResponse =
+ execute("banlist.php", "POST", BanBulkAddRequest(values = values, reason = reason), BanBulkAddResponse::class.java)
+
+ suspend fun banDelete(id: Int) {
+ execute("banlist.php", "POST", BanDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Abteilungen ──────────────────────────────────────────────────
+
+ suspend fun departments(): DepartmentListResponse =
+ execute("departments.php", "GET", null, DepartmentListResponse::class.java)
+
+ suspend fun departmentSave(request: DepartmentSaveRequest): IdResponse =
+ execute("departments.php", "POST", request, IdResponse::class.java)
+
+ suspend fun departmentDelete(id: Int) {
+ execute("departments.php", "POST", DepartmentDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Prioritäten ──────────────────────────────────────────────────
+
+ suspend fun report(query: Map): de.deskhub.staff.data.remote.dto.ReportResponseDto =
+ execute("report_builder.php", "GET", null, de.deskhub.staff.data.remote.dto.ReportResponseDto::class.java, query = query)
+
+ suspend fun reportSave(request: de.deskhub.staff.data.remote.dto.ReportSaveRequest): IdResponse =
+ execute("report_builder.php", "POST", request, IdResponse::class.java)
+
+ suspend fun reportDelete(id: Int) {
+ execute("report_builder.php", "POST", de.deskhub.staff.data.remote.dto.ReportDeleteRequest(id = id), Map::class.java)
+ }
+
+ suspend fun savedViews(): de.deskhub.staff.data.remote.dto.SavedViewListResponse =
+ execute("queues.php", "GET", null, de.deskhub.staff.data.remote.dto.SavedViewListResponse::class.java)
+
+ suspend fun savedViewSave(request: de.deskhub.staff.data.remote.dto.SavedViewSaveRequest): IdResponse =
+ execute("queues.php", "POST", request, IdResponse::class.java)
+
+ suspend fun savedViewDelete(id: Int) {
+ execute("queues.php", "POST", de.deskhub.staff.data.remote.dto.SavedViewDeleteRequest(id = id), Map::class.java)
+ }
+
+ suspend fun slaPlans(): de.deskhub.staff.data.remote.dto.SlaPlanListResponse =
+ execute("sla_plans.php", "GET", null, de.deskhub.staff.data.remote.dto.SlaPlanListResponse::class.java)
+
+ suspend fun slaPlanSave(request: de.deskhub.staff.data.remote.dto.SlaPlanSaveRequest): IdResponse =
+ execute("sla_plans.php", "POST", request, IdResponse::class.java)
+
+ suspend fun slaPlanDelete(id: Int) {
+ execute("sla_plans.php", "POST", de.deskhub.staff.data.remote.dto.SlaPlanDeleteRequest(id = id), Map::class.java)
+ }
+
+ suspend fun prioritiesAdmin(): PriorityListResponse =
+ execute("priorities.php", "GET", null, PriorityListResponse::class.java)
+
+ suspend fun prioritySave(request: PrioritySaveRequest): IdResponse =
+ execute("priorities.php", "POST", request, IdResponse::class.java)
+
+ suspend fun priorityDelete(id: Int) {
+ execute("priorities.php", "POST", PriorityDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Hilfe-Themen ─────────────────────────────────────────────────
+
+ suspend fun helpTopics(): HelpTopicListResponse =
+ execute("help_topics.php", "GET", null, HelpTopicListResponse::class.java)
+
+ suspend fun helpTopicSave(request: HelpTopicSaveRequest): IdResponse =
+ execute("help_topics.php", "POST", request, IdResponse::class.java)
+
+ suspend fun helpTopicDelete(id: Int) {
+ execute("help_topics.php", "POST", HelpTopicDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Organisationen ───────────────────────────────────────────────
+
+ suspend fun organizations(): OrganizationListResponse =
+ execute("organizations.php", "GET", null, OrganizationListResponse::class.java)
+
+ suspend fun organizationSave(request: OrganizationSaveRequest): IdResponse =
+ execute("organizations.php", "POST", request, IdResponse::class.java)
+
+ suspend fun organizationDelete(id: Int) {
+ execute("organizations.php", "POST", OrganizationDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Teams ────────────────────────────────────────────────────────
+
+ suspend fun teams(): TeamListResponse =
+ execute("teams.php", "GET", null, TeamListResponse::class.java)
+
+ suspend fun teamSave(request: TeamSaveRequest): IdResponse =
+ execute("teams.php", "POST", request, IdResponse::class.java)
+
+ suspend fun teamToggle(id: Int) {
+ execute("teams.php", "POST", TeamToggleRequest(id = id), Map::class.java)
+ }
+
+ suspend fun teamDelete(id: Int) {
+ execute("teams.php", "POST", TeamDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Rollen ───────────────────────────────────────────────────────
+
+ suspend fun roles(): RoleListResponse =
+ execute("roles.php", "GET", null, RoleListResponse::class.java)
+
+ suspend fun roleSave(request: RoleSaveRequest): IdResponse =
+ execute("roles.php", "POST", request, IdResponse::class.java)
+
+ suspend fun roleDelete(id: Int) {
+ execute("roles.php", "POST", RoleDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Mitarbeiter ──────────────────────────────────────────────────
+
+ suspend fun staffAdminList(): StaffAdminListResponse =
+ execute("staff_manage.php", "GET", null, StaffAdminListResponse::class.java)
+
+ suspend fun staffAdminSave(request: StaffAdminSaveRequest): IdResponse =
+ execute("staff_manage.php", "POST", request, IdResponse::class.java)
+
+ suspend fun staffAdminDelete(id: Int) {
+ execute("staff_manage.php", "POST", StaffAdminDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: Geschäftszeiten ──────────────────────────────────────────────
+
+ suspend fun businessHours(): BusinessHoursResponse =
+ execute("business_hours.php", "GET", null, BusinessHoursResponse::class.java)
+
+ suspend fun businessHoursSave(enabled: Boolean, hours: List) {
+ execute("business_hours.php", "POST", BusinessHoursSaveRequest(enabled = enabled, hours = hours), Map::class.java)
+ }
+
+ suspend fun businessHolidayAdd(date: String, name: String): IdResponse =
+ execute("business_hours.php", "POST", BusinessHolidayAddRequest(date = date, name = name), IdResponse::class.java)
+
+ suspend fun businessHolidayDelete(id: Int) {
+ execute("business_hours.php", "POST", BusinessHolidayDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: E-Mail-Adressen ──────────────────────────────────────────────
+
+ suspend fun emailAddresses(): EmailAddressListResponse =
+ execute("email_addresses.php", "GET", null, EmailAddressListResponse::class.java)
+
+ suspend fun emailAddressSave(request: EmailAddressSaveRequest): IdResponse =
+ execute("email_addresses.php", "POST", request, IdResponse::class.java)
+
+ suspend fun emailAddressAction(action: String, id: Int): EmailAddressActionResponse =
+ execute("email_addresses.php", "POST", EmailAddressActionRequest(action = action, id = id), EmailAddressActionResponse::class.java)
+
+ suspend fun emailAddressDelete(id: Int) {
+ execute("email_addresses.php", "POST", EmailAddressDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Admin: E-Mail-Vorlagen ──────────────────────────────────────────────
+
+ suspend fun emailTemplates(): EmailTemplateListResponse =
+ execute("email_templates.php", "GET", null, EmailTemplateListResponse::class.java)
+
+ suspend fun emailTemplateSave(key: String, subject: String, bodyText: String) {
+ execute("email_templates.php", "POST", EmailTemplateSaveRequest(key = key, subject = subject, body = bodyText), Map::class.java)
+ }
+
+ suspend fun emailTemplateReset(key: String) {
+ execute("email_templates.php", "POST", EmailTemplateResetRequest(key = key), Map::class.java)
+ }
+
+ // ─── Admin: Admin-Protokoll ──────────────────────────────────────────────
+
+ suspend fun auditLog(page: Int): AuditLogResponse =
+ execute("audit_log.php", "GET", null, AuditLogResponse::class.java, query = mapOf("page" to page.toString()))
+
+ // ─── Aufgaben ────────────────────────────────────────────────────────────
+
+ suspend fun tasks(filter: String): TaskListResponse =
+ execute("tasks.php", "GET", null, TaskListResponse::class.java, query = mapOf("filter" to filter))
+
+ suspend fun taskCreate(request: TaskCreateRequest): IdResponse =
+ execute("tasks.php", "POST", request, IdResponse::class.java)
+
+ suspend fun taskUpdateStatus(id: Int, status: String) {
+ execute("tasks.php", "POST", TaskUpdateStatusRequest(id = id, status = status), Map::class.java)
+ }
+
+ suspend fun taskDelete(id: Int) {
+ execute("tasks.php", "POST", TaskDeleteRequest(id = id), Map::class.java)
+ }
+
+ // ─── Interner Chat ───────────────────────────────────────────────────────
+
+ suspend fun chatContacts(): ChatContactsResponse =
+ execute("chat.php", "GET", null, ChatContactsResponse::class.java)
+
+ suspend fun chatConversation(withId: Int): ChatConversationResponse =
+ execute("chat.php", "GET", null, ChatConversationResponse::class.java, query = mapOf("with" to withId.toString()))
+
+ suspend fun chatSend(toId: Int, message: String): ChatSendResponse =
+ execute("chat.php", "POST", ChatSendRequest(toId = toId, message = message), ChatSendResponse::class.java)
+
+ // ─── Live-Chat (Kunden-Widget) ───────────────────────────────────────────
+
+ suspend fun liveChatList(): LiveChatListResponse =
+ execute("live_chat.php", "GET", null, LiveChatListResponse::class.java, query = mapOf("action" to "list"))
+
+ suspend fun liveChatMessages(number: String, since: Int): LiveChatMessagesResponse =
+ execute(
+ "live_chat.php", "GET", null, LiveChatMessagesResponse::class.java,
+ query = mapOf("action" to "messages", "number" to number, "since" to since.toString()),
+ )
+
+ suspend fun liveChatSend(number: String, message: String): LiveChatSendResponse =
+ execute("live_chat.php", "POST", LiveChatSendRequest(number = number, message = message), LiveChatSendResponse::class.java)
+
+ suspend fun liveChatTyping(number: String) {
+ execute("live_chat.php", "POST", LiveChatActionRequest(action = "typing", number = number), Map::class.java)
+ }
+
+ suspend fun liveChatEnd(number: String) {
+ execute("live_chat.php", "POST", LiveChatActionRequest(action = "end", number = number), Map::class.java)
+ }
+
+ // ─── Verfügbarkeit (Status) ──────────────────────────────────────────────
+
+ suspend fun availability(): AvailabilityResponse =
+ execute("availability.php", "GET", null, AvailabilityResponse::class.java)
+
+ // ─── Cc-Empfänger, Vorlagen, Zufriedenheit, Statusseite ──────────────────
+
+ suspend fun collaboratorAction(number: String, action: String, email: String? = null, id: Int? = null): de.deskhub.staff.data.remote.dto.CollaboratorsResponse =
+ execute(
+ "ticket_collaborators.php", "POST", mapOf("number" to number, "action" to action, "email" to email, "id" to id),
+ de.deskhub.staff.data.remote.dto.CollaboratorsResponse::class.java,
+ )
+
+ suspend fun ticketTemplates(): de.deskhub.staff.data.remote.dto.TicketTemplatesResponse =
+ execute("ticket_templates.php", "GET", null, de.deskhub.staff.data.remote.dto.TicketTemplatesResponse::class.java)
+
+ suspend fun csatStats(days: Int): de.deskhub.staff.data.remote.dto.CsatResponse =
+ execute("csat.php", "GET", null, de.deskhub.staff.data.remote.dto.CsatResponse::class.java, query = mapOf("days" to days.toString()))
+
+ suspend fun statusPage(): de.deskhub.staff.data.remote.dto.StatusResponse =
+ execute("status.php", "GET", null, de.deskhub.staff.data.remote.dto.StatusResponse::class.java)
+
+ suspend fun statusAction(request: Map): de.deskhub.staff.data.remote.dto.StatusResponse =
+ execute("status.php", "POST", request, de.deskhub.staff.data.remote.dto.StatusResponse::class.java)
+
+ suspend fun unlockTicket(number: String): de.deskhub.staff.data.remote.dto.TicketUnlockResponse =
+ execute("ticket_unlock.php", "POST", de.deskhub.staff.data.remote.dto.TicketUnlockRequest(number), de.deskhub.staff.data.remote.dto.TicketUnlockResponse::class.java)
+
+ suspend fun setAvailability(status: String, note: String, staffId: Int? = null): AvailabilitySetResponse =
+ execute("availability.php", "POST", AvailabilitySetRequest(status, note, staffId), AvailabilitySetResponse::class.java)
+
+ /** Berührungs-Ping: die Person nutzt die App gerade (verhindert den automatischen Offline-Status). */
+ suspend fun presence() {
+ execute("presence.php", "POST", emptyMap(), Map::class.java)
+ }
+
+ // ─── Ticket-Regeln (Automatisierung) ─────────────────────────────────────
+
+ suspend fun ticketRules(): TicketRulesResponse =
+ execute("ticket_rules.php", "GET", null, TicketRulesResponse::class.java)
+
+ suspend fun saveTicketRule(request: TicketRuleSaveRequest): TicketRuleSaveResponse =
+ execute("ticket_rules.php", "POST", request, TicketRuleSaveResponse::class.java)
+
+ suspend fun toggleTicketRule(id: Int) {
+ execute("ticket_rules.php", "POST", TicketRuleIdRequest("toggle", id), Map::class.java)
+ }
+
+ suspend fun deleteTicketRule(id: Int) {
+ execute("ticket_rules.php", "POST", TicketRuleIdRequest("delete", id), Map::class.java)
+ }
+
+ suspend fun saveAutoClose(enabled: Boolean, days: Int) {
+ execute("ticket_rules.php", "POST", AutoCloseSaveRequest(enabled = enabled, days = days), Map::class.java)
+ }
+
+ private suspend fun execute(
+ path: String,
+ method: String,
+ payload: Any?,
+ responseType: Class,
+ authenticated: Boolean = true,
+ query: Map = emptyMap(),
+ ): T = withContext(Dispatchers.IO) {
+ val urlBuilder = "$baseUrl/api/staff/v1/$path".toHttpUrl().newBuilder()
+ query.forEach { (key, value) -> urlBuilder.addQueryParameter(key, value) }
+ val requestBuilder = Request.Builder()
+ .url(urlBuilder.build())
+ .header("Accept", "application/json")
+ .header("Cache-Control", "no-cache, no-store")
+ .header("Pragma", "no-cache")
+ if (authenticated) {
+ val token = tokenProvider()
+ ?: throw ApiException(401, "UNAUTHENTICATED", "Keine lokale Anmeldung vorhanden.")
+ requestBuilder.header("Authorization", "Bearer $token")
+ requestBuilder.header("X-DeskHub-Authorization", "Bearer $token") // Ersatz-Header: viele Hoster entfernen "Authorization"
+ }
+ val body = payload?.let { gson.toJson(it).toRequestBody(jsonType) }
+ when (method) {
+ "GET" -> requestBuilder.get()
+ "POST" -> requestBuilder.post(body ?: ByteArray(0).toRequestBody(jsonType))
+ "PATCH" -> requestBuilder.patch(body ?: ByteArray(0).toRequestBody(jsonType))
+ else -> error("Nicht unterstützte HTTP-Methode: $method")
+ }
+
+ val call = try {
+ client.newCall(requestBuilder.build()).execute()
+ } catch (e: java.io.IOException) {
+ // Kein Netz, Server nicht erreichbar oder Zeitüberschreitung
+ ConnectionMonitor.set(true)
+ throw ApiException(0, "NETWORK", "Keine Verbindung zum Server.")
+ }
+ ConnectionMonitor.set(call.code in 502..504)
+ call.use { response ->
+ val responseBody = response.body?.string().orEmpty()
+ if (!response.isSuccessful) {
+ val envelope = runCatching { gson.fromJson(responseBody, ErrorEnvelope::class.java) }.getOrNull()
+ throw ApiException(
+ response.code,
+ envelope?.error?.code ?: "HTTP_${response.code}",
+ envelope?.error?.message ?: "Serverfehler (${response.code}).",
+ )
+ }
+ if (responseBody.isBlank()) {
+ throw ApiException(response.code, "EMPTY_RESPONSE", "Der Server hat keine Antwort geliefert.")
+ }
+ gson.fromJson(responseBody, responseType)
+ ?: throw ApiException(response.code, "INVALID_RESPONSE", "Die Serverantwort ist ungültig.")
+ }
+ }
+
+ /** Lädt ein Bild hoch (z.B. für eine Signatur) und liefert dessen öffentliche URL zurück. */
+ suspend fun uploadImage(bytes: ByteArray, filename: String, mimeType: String): UploadImageResponse =
+ withContext(Dispatchers.IO) {
+ val token = tokenProvider()
+ ?: throw ApiException(401, "UNAUTHENTICATED", "Keine lokale Anmeldung vorhanden.")
+ val body = MultipartBody.Builder()
+ .setType(MultipartBody.FORM)
+ .addFormDataPart("image", filename, bytes.toRequestBody(mimeType.toMediaType()))
+ .build()
+ val request = Request.Builder()
+ .url("$baseUrl/api/staff/v1/upload_image.php".toHttpUrl())
+ .header("Accept", "application/json")
+ .header("Authorization", "Bearer $token")
+ .header("X-DeskHub-Authorization", "Bearer $token")
+ .post(body)
+ .build()
+
+ client.newCall(request).execute().use { response ->
+ val responseBody = response.body?.string().orEmpty()
+ if (!response.isSuccessful) {
+ val envelope = runCatching { gson.fromJson(responseBody, ErrorEnvelope::class.java) }.getOrNull()
+ throw ApiException(
+ response.code,
+ envelope?.error?.code ?: "HTTP_${response.code}",
+ envelope?.error?.message ?: "Serverfehler (${response.code}).",
+ )
+ }
+ gson.fromJson(responseBody, UploadImageResponse::class.java)
+ ?: throw ApiException(response.code, "INVALID_RESPONSE", "Die Serverantwort ist ungültig.")
+ }
+ }
+}
diff --git a/mobile/src/main/java/de/deskhub/staff/data/remote/dto/ApiDtos.kt b/mobile/src/main/java/de/deskhub/staff/data/remote/dto/ApiDtos.kt
index e8bc8c2a..fe1ff35d 100644
--- a/mobile/src/main/java/de/deskhub/staff/data/remote/dto/ApiDtos.kt
+++ b/mobile/src/main/java/de/deskhub/staff/data/remote/dto/ApiDtos.kt
@@ -1211,3 +1211,11 @@ data class AutoCloseSaveRequest(val action: String = "save_auto_close", val enab
// ─── Bild-Upload (z.B. für Signaturen) ───────────────────────────────────────
data class UploadImageResponse(val url: String = "")
+
+data class AppUpdateDto(
+ val available: Boolean = false,
+ val version: String = "",
+ val sha256: String = "",
+ val size: Long = 0,
+ val notes: String = "",
+)