Files
homeutils/docs/superpowers/plans/2026-07-30-shared-result-ui-phase-2.md
T
2026-07-30 22:06:04 +08:00

5.4 KiB

Shared Result UI Phase 2 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Remove duplicated export-history and empty-result UI code from Scanner and MyBatis SQL Export while preserving their behavior.

Architecture: Add a small immutable adapter model between plugin-specific history rows and a reusable JavaFX history pane. Keep file-opening side effects behind injected callbacks so the shared pane only renders data and emits commands. Add a reusable empty-state component for later plugin migrations.

Tech Stack: Java 17, JavaFX, JUnit 5, Maven.

Global Constraints

  • Work only in C:\tmp\workutils-plugin-ui-refactor on branch codex/plugin-ui-refactor.
  • Do not add raw new Thread.
  • Shared UI components must not read files or launch external programs.
  • Plugin-specific persistence formats must remain unchanged.
  • Write and observe a failing test before each production behavior.

Task 1: Immutable history presentation model

Files:

  • Create: src/main/java/com/example/workutils/system/ui/history/HistoryItem.java
  • Test: src/test/java/com/example/workutils/system/ui/history/HistoryItemTest.java

Interfaces:

  • Produces: HistoryItem(String index, String query, String filePath, String count, String timestamp).

  • Produces: fileDisplay(int maxLength) for bounded single-line display.

  • Write tests proving short paths remain unchanged, long paths are ellipsized while retaining the filename, and constructor values cannot be null.

  • Run .\mvnw.cmd -q -Dtest=HistoryItemTest test and observe compilation failure because HistoryItem is absent.

  • Implement the immutable record and its display method.

  • Run the focused test and confirm it passes.

Task 2: Reusable empty state

Files:

  • Create: src/main/java/com/example/workutils/system/ui/EmptyStatePane.java
  • Modify: src/main/resources/css/light-theme.css
  • Test: src/test/java/com/example/workutils/system/ui/EmptyStateContentTest.java

Interfaces:

  • Produces: EmptyStatePane.Content(String title, String description, String actionLabel).

  • Produces: EmptyStatePane(Content content, Runnable action, int fontSize).

  • Write pure content-validation tests proving title is required and a blank action label is allowed only when no action is rendered.

  • Run the focused test and observe failure because the component is absent.

  • Implement the content model, pane, optional action button, and theme classes.

  • Run the focused test and confirm it passes.

Task 3: Reusable export history pane

Files:

  • Create: src/main/java/com/example/workutils/system/ui/history/HistoryFileCommands.java
  • Create: src/main/java/com/example/workutils/system/ui/history/ExportHistoryPane.java
  • Test: src/test/java/com/example/workutils/system/ui/history/HistoryFileCommandsTest.java

Interfaces:

  • Consumes: ObservableList<HistoryItem>.

  • Consumes: HistoryFileCommands callbacks for open file, open editor, open folder, and copy path.

  • Produces: ExportHistoryPane(String countColumnTitle, ObservableList<HistoryItem> items, HistoryFileCommands commands, int fontSize).

  • Write tests proving HistoryFileCommands rejects missing callbacks and routes each command to the supplied consumer.

  • Run the focused test and observe failure because the type is absent.

  • Implement callback validation and the shared table, action cell, tooltip, context menu, and empty-state placeholder.

  • Run the focused test and confirm it passes.

Task 4: Migrate Scanner

Files:

  • Modify: src/main/java/com/example/workutils/biz/scanner/ScannerWindow.java
  • Test: src/test/java/com/example/workutils/biz/scanner/ScannerHistoryMappingTest.java

Interfaces:

  • Consumes: HistoryItem, ExportHistoryPane, HistoryFileCommands.

  • Produces: package-visible toHistoryItem(HistoryRow row) for deterministic presentation mapping.

  • Write a mapping test for index, query, path, match count, and timestamp.

  • Run the focused test and observe failure because the mapping method is absent.

  • Replace duplicated table/action-cell construction with ExportHistoryPane.

  • Run scanner tests and confirm they pass.

Task 5: Migrate MyBatis SQL Export

Files:

  • Modify: src/main/java/com/example/workutils/biz/mybatisexport/MyBatisExportWindow.java
  • Test: src/test/java/com/example/workutils/biz/mybatisexport/MyBatisExportHistoryMappingTest.java

Interfaces:

  • Consumes: HistoryItem, ExportHistoryPane, HistoryFileCommands.

  • Produces: package-visible toHistoryItem(HistoryRow row).

  • Write a mapping test for index, query, path, export count, and timestamp.

  • Run the focused test and observe failure because the mapping method is absent.

  • Replace duplicated table/action-cell construction with ExportHistoryPane.

  • Run export tests and confirm they pass.

Task 6: Verification

Files:

  • Modify only files required by failures found during verification.

  • Run .\mvnw.cmd -q test.

  • Run .\mvnw.cmd -q -DskipTests compile.

  • Run git diff --check.

  • Confirm Scanner and MyBatis SQL Export no longer declare buildActionCell.

  • Inspect both pages without triggering scan, export, file-open, or delete side effects.