Fix #44: Ersetze Status-Icons durch Unicode-Symbole mit Farben

- SUCCESS: ✓ (U+2713) mit #2e7d32 (grün)
- FAILED_RETRYABLE: ↻ (U+21BB) mit #d98200 (orange)
- FAILED_PERMANENT: × (U+00D7) mit #c62828 (rot)
- SKIPPED_ALREADY_PROCESSED: ≡ (U+2261) mit #1565c0 (blau-grau)
- SKIPPED_FINAL_FAILURE: ⊘ (U+2298) mit #757575 (grau)

Die neue Methode statusColor() gibt CSS-Hex-Farben zurück.
Font: 16px, font-weight: bold

Betroffene Dateien:
- GuiBatchRunResultRow.java: neue statusColor() Methode
- GuiBatchRunResultRowTest.java: Icons aktualisiert
- GuiBatchRunCoordinatorTest.java: Icons aktualisiert
- GuiBatchRunTabSmokeTest.java: Icons aktualisiert

Alle 323 Tests bestanden.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 07:55:49 +02:00
parent 3877359b42
commit 0b5a441a5d
4 changed files with 43 additions and 22 deletions
@@ -70,7 +70,7 @@ public record GuiBatchRunResultRow(
/**
* Icon shown in the status column when a document's persistence status has been reset.
*/
static final String RESET_PENDING_ICON = "\u27F3"; // ⟳ CLOCKWISE GAPPED CIRCLE ARROW
static final String RESET_PENDING_ICON = ""; // ⟳ CLOCKWISE GAPPED CIRCLE ARROW
/**
* Compact constructor normalising optional holders and validating mandatory fields.
@@ -192,24 +192,45 @@ public record GuiBatchRunResultRow(
}
/**
* Returns the status icon for this row as a Unicode character that renders reliably
* in JavaFX on Windows.
* Gibt das Status-Icon für diese Zeile als Unicode-Zeichen zurück, das in JavaFX
* unter Windows zuverlässig dargestellt wird (16px, bold).
* <p>
* When {@code resetPending} is {@code true} the reset icon is returned regardless of
* the underlying status.
* Wenn {@code resetPending} den Wert {@code true} hat, wird unabhängig vom
* eigentlichen Status das Reset-Icon zurückgegeben.
*
* @return the corresponding status character
* @return das entsprechende Status-Zeichen
*/
public String statusIcon() {
if (resetPending) {
return RESET_PENDING_ICON;
}
return switch (status) {
case SUCCESS -> "\u2714"; // ✔ HEAVY CHECK MARK
case FAILED_RETRYABLE -> "\u26A0"; // ⚠ WARNING SIGN
case FAILED_PERMANENT -> "\u2718"; // ✘ HEAVY BALLOT X
case SKIPPED_ALREADY_PROCESSED -> "\u23ED"; // ⏭ NEXT TRACK BUTTON
case SKIPPED_FINAL_FAILURE -> "\u2298"; // ⊘ CIRCLED DIVISION SLASH
case SUCCESS -> ""; // CHECK MARK
case FAILED_RETRYABLE -> ""; // ↻ CLOCKWISE OPEN CIRCLE ARROW
case FAILED_PERMANENT -> "×"; // × MULTIPLICATION SIGN
case SKIPPED_ALREADY_PROCESSED -> ""; // ≡ IDENTICAL TO
case SKIPPED_FINAL_FAILURE -> ""; // ⊘ CIRCLED DIVISION SLASH
};
}
/**
* Gibt die CSS-Farbe für das Status-Icon dieser Zeile zurück.
* <p>
* Wenn {@code resetPending} den Wert {@code true} hat, wird unabhängig vom
* eigentlichen Status die Reset-Farbe zurückgegeben.
*
* @return die entsprechende CSS-Hex-Farbe (z.B. "#2e7d32")
*/
public String statusColor() {
if (resetPending) {
return "#757575"; // Grau für Reset-pending
}
return switch (status) {
case SUCCESS -> "#2e7d32"; // Grün
case FAILED_RETRYABLE -> "#d98200"; // Orange
case FAILED_PERMANENT -> "#c62828"; // Rot
case SKIPPED_ALREADY_PROCESSED -> "#1565c0"; // Blau-Grau
case SKIPPED_FINAL_FAILURE -> "#757575"; // Grau
};
}
@@ -287,10 +287,10 @@ class GuiBatchRunCoordinatorTest {
@Test
void resultRowIcons_matchSpecification() {
assertEquals("\u2714", row(DocumentCompletionStatus.SUCCESS).statusIcon());
assertEquals("\u26A0", row(DocumentCompletionStatus.FAILED_RETRYABLE).statusIcon());
assertEquals("\u2718", row(DocumentCompletionStatus.FAILED_PERMANENT).statusIcon());
assertEquals("\u23ED", row(DocumentCompletionStatus.SKIPPED_ALREADY_PROCESSED).statusIcon());
assertEquals("", row(DocumentCompletionStatus.SUCCESS).statusIcon());
assertEquals("", row(DocumentCompletionStatus.FAILED_RETRYABLE).statusIcon());
assertEquals("×", row(DocumentCompletionStatus.FAILED_PERMANENT).statusIcon());
assertEquals("", row(DocumentCompletionStatus.SKIPPED_ALREADY_PROCESSED).statusIcon());
}
@Test
@@ -95,27 +95,27 @@ class GuiBatchRunResultRowTest {
@Test
void statusIcon_success_isCheckMark() {
assertEquals("\u2714", row(DocumentCompletionStatus.SUCCESS).statusIcon());
assertEquals("", row(DocumentCompletionStatus.SUCCESS).statusIcon());
}
@Test
void statusIcon_failedRetryable_isWarning() {
assertEquals("\u26A0", row(DocumentCompletionStatus.FAILED_RETRYABLE).statusIcon());
assertEquals("", row(DocumentCompletionStatus.FAILED_RETRYABLE).statusIcon());
}
@Test
void statusIcon_failedPermanent_isBallotX() {
assertEquals("\u2718", row(DocumentCompletionStatus.FAILED_PERMANENT).statusIcon());
assertEquals("×", row(DocumentCompletionStatus.FAILED_PERMANENT).statusIcon());
}
@Test
void statusIcon_skippedAlreadyProcessed_isNextTrack() {
assertEquals("\u23ED", row(DocumentCompletionStatus.SKIPPED_ALREADY_PROCESSED).statusIcon());
assertEquals("", row(DocumentCompletionStatus.SKIPPED_ALREADY_PROCESSED).statusIcon());
}
@Test
void statusIcon_skippedFinalFailure_isCircledDivisionSlash() {
assertEquals("\u2298", row(DocumentCompletionStatus.SKIPPED_FINAL_FAILURE).statusIcon());
assertEquals("", row(DocumentCompletionStatus.SKIPPED_FINAL_FAILURE).statusIcon());
}
@Test
@@ -140,10 +140,10 @@ class GuiBatchRunTabSmokeTest {
tab().resultTable().getSelectionModel().select(1);
assertTrue(tab().detailArea().getText().contains(GuiBatchRunTab.NO_REASONING_TEXT));
// SKIPPED_ALREADY_PROCESSED muss das Weiterspulen-Icon ⏭ tragen, nicht .
// SKIPPED_ALREADY_PROCESSED trägt das Identisch-Icon ≡, nicht .
GuiBatchRunResultRow skippedRow = tab().resultTable().getItems().get(2);
assertEquals(DocumentCompletionStatus.SKIPPED_ALREADY_PROCESSED, skippedRow.status());
assertEquals("\u23ED", skippedRow.statusIcon());
assertEquals("", skippedRow.statusIcon());
});
}