#81: Enum-Rohnamen durch deutsche Anzeigetexte ersetzen

displayTextFor(ProcessingStatus) in ProcessingStatusPresentation ergaenzt.
Status-ComboBox als ComboBox<ProcessingStatus> mit StringConverter umgestellt;
Versuche-Tabelle und Detail-Statuslabel zeigen nun Anzeigetext statt Enum-Namen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-05 12:01:44 +02:00
parent 5129d3c9f6
commit 0fd0349a78
2 changed files with 43 additions and 12 deletions
@@ -3,6 +3,7 @@ package de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun;
import java.util.Objects;
import de.gecheckt.pdf.umbenenner.application.port.in.DocumentCompletionStatus;
import de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus;
/**
* Zentrale Mapping-Klasse für die visuelle Darstellung von Verarbeitungsstatus in der GUI.
@@ -250,6 +251,32 @@ public final class ProcessingStatusPresentation {
summaryCategoryFor(status));
}
// -------------------------------------------------------------------------
// Mapping für ProcessingStatus (alle acht Domain-Statuswerte)
// -------------------------------------------------------------------------
/**
* Liefert den deutschsprachigen Anzeigetext mit Icon für den angegebenen
* Domain-Verarbeitungsstatus. Kein Enum-Rohname darf für Endnutzer sichtbar sein.
*
* @param status der Domain-Verarbeitungsstatus; darf nicht {@code null} sein
* @return der Anzeigetext mit vorangestelltem Icon; nie leer
* @throws NullPointerException wenn {@code status} {@code null} ist
*/
public static String displayTextFor(ProcessingStatus status) {
Objects.requireNonNull(status, "status darf nicht null sein");
return switch (status) {
case SUCCESS -> "✓ Erfolgreich";
case FAILED_RETRYABLE -> "↻ Temporärer Fehler";
case FAILED_FINAL -> "× Dauerhaft fehlgeschlagen";
case SKIPPED_ALREADY_PROCESSED -> "≡ Bereits verarbeitet";
case SKIPPED_FINAL_FAILURE -> "⊘ Endgültig übersprungen";
case READY_FOR_AI -> "⟳ Wartet auf Verarbeitung";
case PROPOSAL_READY -> "◇ Vorschlag vorhanden";
case PROCESSING -> "▶ In Bearbeitung";
};
}
/** Nicht instanziierbar reine Utility-Klasse. */
private ProcessingStatusPresentation() {
throw new UnsupportedOperationException("Nicht instanziierbar");
@@ -15,6 +15,7 @@ import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.gecheckt.pdf.umbenenner.adapter.in.gui.batchrun.ProcessingStatusPresentation;
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecord;
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingAttempt;
import de.gecheckt.pdf.umbenenner.application.port.out.history.DocumentHistoryRow;
@@ -24,6 +25,7 @@ import de.gecheckt.pdf.umbenenner.application.usecase.DefaultHistoryOverviewUseC
import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;
import de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus;
import javafx.application.Platform;
import javafx.util.StringConverter;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@@ -107,7 +109,7 @@ public final class GuiHistoryTab {
private final Tab tab = new Tab(TAB_TITLE);
private final TextField searchField = new TextField();
private final ComboBox<String> statusFilterBox = new ComboBox<>();
private final ComboBox<ProcessingStatus> statusFilterBox = new ComboBox<>();
private final Button refreshButton = new Button("Aktualisieren");
private final TableView<DocumentHistoryRow> overviewTable = new TableView<>();
@@ -215,10 +217,14 @@ public final class GuiHistoryTab {
Tooltip.install(searchField, new Tooltip(
"Freitextsuche über Quell- und Zieldateiname (Groß-/Kleinschreibung egal)."));
statusFilterBox.getItems().add("Alle Status");
for (ProcessingStatus s : ProcessingStatus.values()) {
statusFilterBox.getItems().add(s.name());
}
statusFilterBox.setConverter(new StringConverter<>() {
@Override public String toString(ProcessingStatus s) {
return s == null ? "Alle Status" : ProcessingStatusPresentation.displayTextFor(s);
}
@Override public ProcessingStatus fromString(String text) { return null; }
});
statusFilterBox.getItems().add(null); // "Alle Status"
statusFilterBox.getItems().addAll(ProcessingStatus.values());
statusFilterBox.getSelectionModel().selectFirst();
Tooltip.install(statusFilterBox, new Tooltip("Status-Filter: nur Einträge mit diesem Status anzeigen."));
@@ -409,8 +415,8 @@ public final class GuiHistoryTab {
TableColumn<ProcessingAttempt, String> statusCol = new TableColumn<>("Status");
statusCol.setCellValueFactory(c ->
new SimpleStringProperty(
statusIcon(c.getValue().status()) + " " + c.getValue().status().name()));
statusCol.setPrefWidth(140);
ProcessingStatusPresentation.displayTextFor(c.getValue().status())));
statusCol.setPrefWidth(160);
TableColumn<ProcessingAttempt, String> providerCol = new TableColumn<>("Provider");
providerCol.setCellValueFactory(c ->
@@ -490,9 +496,8 @@ public final class GuiHistoryTab {
}
String searchText = searchField.getText();
String selectedStatus = statusFilterBox.getSelectionModel().getSelectedItem();
String statusFilter = (selectedStatus == null || "Alle Status".equals(selectedStatus))
? null : selectedStatus;
ProcessingStatus selectedStatus = statusFilterBox.getSelectionModel().getSelectedItem();
String statusFilter = selectedStatus == null ? null : selectedStatus.name();
HistoryQuery query = new HistoryQuery(searchText, statusFilter, HistoryQuery.DEFAULT_LIMIT);
@@ -673,8 +678,7 @@ public final class GuiHistoryTab {
detailSourceFileLabel.setText(record.lastKnownSourceFileName());
detailSourcePathLabel.setText(record.lastKnownSourceLocator().value());
detailSourcePathLabel.setTooltip(new Tooltip(record.lastKnownSourceLocator().value()));
String icon = statusIcon(record.overallStatus());
detailStatusLabel.setText(icon + " " + record.overallStatus().name());
detailStatusLabel.setText(ProcessingStatusPresentation.displayTextFor(record.overallStatus()));
detailStatusLabel.setStyle("-fx-text-fill: " + statusColor(record.overallStatus()) + ";");
detailStatusLabel.setTooltip(new Tooltip(statusTooltip(record.overallStatus())));
detailCreatedLabel.setText(formatInstant(record.createdAt()));