diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/ProcessingStatusPresentation.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/ProcessingStatusPresentation.java index a83824c..e642bf3 100644 --- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/ProcessingStatusPresentation.java +++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/batchrun/ProcessingStatusPresentation.java @@ -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"); diff --git a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java index 8e2e4ca..315e4b0 100644 --- a/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java +++ b/pdf-umbenenner-adapter-in-gui/src/main/java/de/gecheckt/pdf/umbenenner/adapter/in/gui/history/GuiHistoryTab.java @@ -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 statusFilterBox = new ComboBox<>(); + private final ComboBox statusFilterBox = new ComboBox<>(); private final Button refreshButton = new Button("Aktualisieren"); private final TableView 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 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 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()));