From 533091c333099ca0202cebad968f124297b414df Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 22:08:48 +0000 Subject: [PATCH] =?UTF-8?q?Workers=20P4:=20Pult=20=E2=80=93=20als=20Mensch?= =?UTF-8?q?=20antworten,=20Vorschau=20freigeben,=20Antwort=20des=20Kunden?= =?UTF-8?q?=20einf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 --- src/components/workers/PultList.jsx | 172 +++++++-- src/lib/workersApi.js | 27 +- src/lib/workersPult.js | 91 ++++- src/styles/workers.css | 19 + tests/unit/workersApi.test.mjs | 45 ++- tests/unit/workersPult.test.mjs | 163 ++++++++- tests/unit/workersPultUi.test.mjs | 532 +++++++++++++++++++++++++++- 7 files changed, 1001 insertions(+), 48 deletions(-) diff --git a/src/components/workers/PultList.jsx b/src/components/workers/PultList.jsx index 0d839ec..1fe2f5b 100644 --- a/src/components/workers/PultList.jsx +++ b/src/components/workers/PultList.jsx @@ -5,11 +5,13 @@ import EmptyState from '../ui/EmptyState' import { copyTextChecked } from '../CopyableCredential' import { useEmployees } from '../../hooks/useEmployees' import { usePultFeed } from '../../hooks/usePultFeed' -import { PULT_FILTERS, copyAndOpen, mailtoHref, rowModel } from '../../lib/workersPult' +import { + ACTION_FAILED, PULT_FILTERS, REPLY_TEXT_MAX, actionErrorText, charCount, copyAndOpen, mailtoHref, pasteDoneText, rowModel, validateReplyText, +} from '../../lib/workersPult' import ProspectPanel from './ProspectPanel' -const CONFIRM_MS = 4000 // so lange gilt die Rückfrage „Wirklich verwerfen?“ nach dem ersten Klick -const ACTION_FAILED = 'Das hat nicht geklappt.' +const CONFIRM_MS = 4000 // so lange gilt die Rückfrage „Wirklich verwerfen?“ bzw. „Wirklich freigeben?“ nach dem ersten Klick +const NO_FIELDS = Object.freeze({}) // Eintrag ohne bearbeitete Felder // Leerzustand je Filter const EMPTY = { @@ -42,12 +44,29 @@ function rowName(label, title, joiner = ': ') { return t === '' ? label : `${label}${joiner}${t}` } +// Aufgeklapptes Feld unter den Aktionen: „Als Mensch antworten“ (.wk-pult-reply) und „Antwort des Kunden einfügen“ (.wk-pult-paste). +// Textfeld, Zähler (Zeichen wie der Dienst sie zählt, höchstens REPLY_TEXT_MAX) und ein Knopf; die Prüfung macht die Zeile beim Absenden. +function TextPanel({ className, label, hint, value, onChange, submitLabel, onSubmit, busy }) { + const count = charCount(value) + return ( +
+ {hint &&

{hint}

} +