Files
workutils/docs/superpowers/plans/2026-08-01-workutils-unified-ui-p3-limited-adaptation.md
T
2026-08-01 12:42:14 +08:00

337 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WorkUtils Unified UI P3 Limited Adaptation and Finalization 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:** Apply the unified theme to Git review, mobile UI automation, settings, and plugin management without structural rewrites, then remove remaining application-level visual inconsistencies and complete full regression/visual acceptance.
**Architecture:** Treat the four limited modules as compatibility consumers of P0 components. Only replace visual construction, style classes, fonts, icons, and shell entry points; retain their existing controllers, panes, services, and state machines. Finish with repository-wide architecture guards that prevent regression to Emoji, duplicate settings navigation, arbitrary fonts, and ad-hoc loading code.
**Tech Stack:** Java 17, JavaFX 17.0.15, AtlantaFX 2.0.1, P0–P2 shared UI components, JUnit 5, Maven Wrapper.
## Global Constraints
- Do not refactor Git review window structure, review workflow, service boundaries, or DiffEngine.
- Do not split mobile UI automation or rewrite its run/record state machine.
- Do not change settings information architecture, persistence, validation, or plugin-management behavior.
- Preserve Windows native title-bar controls and the light-only theme.
- Settings remains top-right-only in the application shell; no sidebar duplicate may return.
- Use Feather through `AppIcon`/`IconFactory`; no visible Emoji or mixed icon set in the application UI.
- Visual checks are read-only: do not submit reviews, run mobile automation, change settings, reorder plugins, synchronize Git, or write exports.
---
## File Structure
### Create
- `src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java` — repository-wide regression guard.
### Modify
- `src/main/java/com/example/workutils/biz/gitreview/GitReviewWindow.java`
- `src/main/java/com/example/workutils/biz/mobileuiauto/MobileUiAutomationWindow.java`
- `src/main/java/com/example/workutils/system/config/SettingsWindow.java`
- `src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java`
- `src/main/java/com/example/workutils/system/plugin/PluginDescriptor.java`
- Plugin descriptor/factory classes under `src/main/java/com/example/workutils/biz/*/*Plugin.java`
- `src/main/resources/css/light-theme.css`
- `src/test/java/com/example/workutils/system/ui/SharedPaneAccessibilityTest.java`
- `src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java`
## Task 1: Add repository-wide visual architecture guards
**Files:**
- Create: `src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java`
**Interfaces:**
- Produces `source(String): SourceFile` and an explicit `limitedUiSources()` list. Start with Git review only; append mobile, settings/plugin management, then all plugin descriptors in their migration tasks so every task ends green.
- [ ] **Step 1: Write the failing architecture tests**
```java
private record SourceFile(Path path, String text) {}
private static SourceFile source(String relativePath) throws IOException {
Path path = Path.of("src/main/java/com/example/workutils", relativePath);
return new SourceFile(path, Files.readString(path));
}
private static List<SourceFile> limitedUiSources() throws IOException {
return List.of(source("biz/gitreview/GitReviewWindow.java"));
}
private static long count(List<SourceFile> files, String needle) {
return files.stream()
.mapToLong(file -> (file.text().length()
- file.text().replace(needle, "").length()) / needle.length())
.sum();
}
@Test
void applicationUiDoesNotUseEmojiIconsOrHardcodedMicrosoftYaHei() throws IOException {
for (SourceFile file : limitedUiSources()) {
assertFalse(file.text().contains("Microsoft YaHei"), file.path().toString());
assertFalse(file.text().matches("(?s).*new Label\\(\"[⚙🛠✅❌❓▶].*"),
file.path().toString());
}
}
@Test
void settingsAndLoadingHaveSingleOwners() throws IOException {
String app = Files.readString(Path.of(
"src/main/java/com/example/workutils/WorkUtilsApplication.java"));
assertFalse(app.contains("new MainWindow.NavItem(\n AppIcon.SETTINGS, \"系统设置\""));
assertEquals(0, count(limitedUiSources(), "setBtnLoading("));
}
```
Limit Emoji scanning to JavaFX application controls. Exclude `ApiDocGenerator` HTML output where symbols may be document content rather than application chrome.
- [ ] **Step 2: Run and record failures**
Run: `.\mvnw.cmd -q -Dtest=UnifiedUiArchitectureTest test`
Expected: FAIL on Git review fonts/icons. Continue directly to Task 2 before committing.
## Task 2: Theme-adapt Git review without structural refactoring
**Files:**
- Modify: `src/main/java/com/example/workutils/biz/gitreview/GitReviewWindow.java`
- Modify: `src/main/resources/css/light-theme.css`
- Include: `src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java`
**Interfaces:**
- Preserves every existing method signature, pane hierarchy, review action, service call, and loading behavior.
- Consumes only P0 tokens/icons/style classes.
- [ ] **Step 1: Add a structural checksum assertion before edits**
```java
assertTrue(source.contains("class GitReviewWindow"));
assertTrue(source.contains("GitReviewService"));
assertFalse(source.contains("new AppShell("));
```
The window must remain a plugin content view and must not create its own shell.
- [ ] **Step 2: Replace visual literals only**
Replace direct fonts, colors, button graphics, and local spinner construction with semantic style classes, `IconFactory`, and `LoadingButtonBinder`. Do not extract panes, rename business methods, or change action ordering.
- [ ] **Step 3: Run Git review compilation/architecture checks**
Run: `.\mvnw.cmd -q -Dtest=UnifiedUiArchitectureTest,WindowNotificationDependencyTest test`
Expected: Git review visual assertions pass; notification boundary remains intact.
- [ ] **Step 4: Capture read-only Git review states**
Capture initial/empty/configured views without starting a review. Verify shell typography and icons while confirming the internal layout is structurally unchanged.
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/example/workutils/biz/gitreview/GitReviewWindow.java src/main/resources/css/light-theme.css src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
git commit -m "适配 Git 评审统一主题"
```
## Task 3: Theme-adapt mobile UI automation without state-machine changes
**Files:**
- Modify: `src/main/java/com/example/workutils/biz/mobileuiauto/MobileUiAutomationWindow.java`
- Modify: `src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java`
**Interfaces:**
- Preserves `MobileAutomationService`, `AutomationRunHandle`, callback types, run/record controls, and current window composition.
- [ ] **Step 1: Add source boundary assertions**
First append `biz/mobileuiauto/MobileUiAutomationWindow.java` to `limitedUiSources()`, then add:
```java
assertTrue(source.contains("MobileAutomationService"));
assertTrue(source.contains("AutomationRunHandle"));
assertFalse(source.contains("class RecordingStateMachine"));
assertFalse(source.contains("class RunStateMachine"));
```
- [ ] **Step 2: Replace only theme consumers**
Use token fonts, shared controls, Feather icons, and CSS classes. Preserve current button event handlers and every service/callback interaction. If a control has ad-hoc spinner code, bind its existing operation state through `LoadingButtonBinder` only when an `AsyncOperationController` already exists; otherwise style the existing state without creating a new state machine in P3.
- [ ] **Step 3: Run compile and architecture tests**
Run: `.\mvnw.cmd -q -Dtest=UnifiedUiArchitectureTest test`
Run: `.\mvnw.cmd -q -DskipTests compile`
Expected: both pass; no new run/record state types appear.
- [ ] **Step 4: Capture read-only states**
Capture the idle screen only. Do not connect devices, start recordings, run scripts, or alter execution history.
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/example/workutils/biz/mobileuiauto/MobileUiAutomationWindow.java src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java src/main/resources/css/light-theme.css
git commit -m "适配手机 UI 自动化统一主题"
```
## Task 4: Theme-adapt settings and plugin management
**Files:**
- Modify: `src/main/java/com/example/workutils/system/config/SettingsWindow.java`
- Modify: `src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java`
- Modify: `src/test/java/com/example/workutils/system/ui/SharedPaneAccessibilityTest.java`
- Modify: `src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java`
- Modify: `src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java`
**Interfaces:**
- Preserves all settings tabs, save/reload behavior, config files, data-source management, plugin enable/order behavior, and drag/drop semantics.
- [ ] **Step 1: Add failing unique-entry and accessibility assertions**
First append `system/config/SettingsWindow.java` and `system/plugin/PluginManagementWindow.java` to `limitedUiSources()`, then add:
```java
String app = Files.readString(Path.of(
"src/main/java/com/example/workutils/WorkUtilsApplication.java"));
String management = Files.readString(Path.of(
"src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java"));
assertFalse(app.contains("AppIcon.SETTINGS, \"系统设置\","));
assertTrue(management.contains("setAccessibleText(\"拖动调整插件顺序\")"));
```
- [ ] **Step 2: Run focused tests and verify failure**
Run: `.\mvnw.cmd -q -Dtest=DefaultPluginConfigurationTest,SharedPaneAccessibilityTest,UnifiedUiArchitectureTest test`
Expected: FAIL on remaining Unicode grip/icon or missing accessible labels.
- [ ] **Step 3: Apply theme classes without changing information architecture**
Replace fonts/icons/inline styles; keep all current tabs and field grouping. Replace the `≡` drag label with Feather `MENU`, preserving drag handlers and user data. Do not move settings sections or change persistence.
- [ ] **Step 4: Run focused tests and capture**
Run: `.\mvnw.cmd -q -Dtest=DefaultPluginConfigurationTest,SharedPaneAccessibilityTest,UnifiedUiArchitectureTest test`
Expected: PASS. Open settings from the top-right entry and inspect tabs without saving or reordering anything.
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/example/workutils/system/config/SettingsWindow.java src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java src/test/java/com/example/workutils/system/ui/SharedPaneAccessibilityTest.java src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java src/main/resources/css/light-theme.css
git commit -m "适配设置与插件管理统一主题"
```
## Task 5: Replace remaining descriptor Emoji with semantic icons
**Files:**
- Modify: `src/main/java/com/example/workutils/system/plugin/PluginDescriptor.java`
- Modify: plugin classes matching `src/main/java/com/example/workutils/biz/*/*Plugin.java`
- Modify: `src/main/java/com/example/workutils/WorkUtilsApplication.java`
- Modify: `src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java`
- Modify: `src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java`
**Interfaces:**
- Changes `PluginDescriptor.icon` from `String` to `AppIcon`.
- Changes `getIcon(): String` to `getIcon(): AppIcon` and all factory/embedding call sites accordingly.
- [ ] **Step 1: Add a failing descriptor type assertion**
Expand `limitedUiSources()` to all JavaFX application UI and plugin descriptor/factory sources using `Files.walk`, while explicitly excluding `biz/apidoc/generator/ApiDocGenerator.java` because it renders document content rather than application chrome. Then add:
```java
@Test
void descriptorCarriesSemanticIconType() {
PluginDescriptor descriptor = PluginDescriptor.builder()
.id("scan")
.name("扫描功能")
.icon(AppIcon.SCANNER)
.build();
AppIcon icon = descriptor.getIcon();
assertEquals(AppIcon.SCANNER, icon);
}
```
Add a compile-time expectation in call sites by assigning `AppIcon icon = descriptor.getIcon()`.
- [ ] **Step 2: Run and verify failure**
Run: `.\mvnw.cmd -q -Dtest=DefaultPluginConfigurationTest,UnifiedUiArchitectureTest test`
Expected: FAIL/compile failure while descriptors still return strings.
- [ ] **Step 3: Migrate the descriptor type atomically**
Update constructor, getter, all plugin declarations, `MainWindow.NavItem`, plugin management rows, and embed calls in one changeset. Use the semantic mappings defined in P0; do not expose Feather enum types outside `system.ui.icon`.
- [ ] **Step 4: Run full tests**
Run: `.\mvnw.cmd -q test`
Expected: PASS with zero failures/errors.
- [ ] **Step 5: Commit**
```powershell
git add src/main/java/com/example/workutils/system/plugin src/main/java/com/example/workutils/biz src/main/java/com/example/workutils/WorkUtilsApplication.java src/test/java/com/example/workutils/system/plugin src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
git commit -m "完成插件语义图标迁移"
```
## Task 6: Full visual, accessibility, and regression acceptance
**Files:**
- Modify only when acceptance finds a concrete defect in a previously touched P0–P3 file.
- Update tests first for every discovered defect.
**Interfaces:**
- Produces no new product API; this task validates the approved design and guards.
- [ ] **Step 1: Run all automated gates fresh**
Run: `.\mvnw.cmd -q test`
Run: `.\mvnw.cmd -q -DskipTests compile`
Run: `git diff --check`
Expected: all exit 0, zero test failures/errors.
- [ ] **Step 2: Run repository scans**
Run: `rg -n 'Microsoft YaHei|setBtnLoading\(|new ProgressIndicator\(|⚙️|🛠|▶' src/main/java/com/example/workutils`
Expected: no application-chrome matches. Document-content matches are allowed only where `UnifiedUiArchitectureTest` explicitly excludes them.
- [ ] **Step 3: Capture the full read-only screenshot matrix**
Capture welcome plus every enabled plugin at 1440px expanded, 1440px collapsed, and 1024px expanded. For API export also capture a controlled loading state. Use non-sensitive fixture/sample data and do not trigger external/file-changing operations.
- [ ] **Step 4: Compare against the approved visual baseline**
Place the approved reference and each implementation screenshot side by side at matching viewport/state. Check header 48px, rail 214/56px, unique settings location, type scale, icon baseline, 8px spacing rhythm, control height, row height, border/radius, focus visibility, loading stability, and clipping.
- [ ] **Step 5: Keyboard/accessibility smoke test**
Tab through header settings, navigation, primary form controls, action buttons, cancel controls where real, tabs, history actions, and collapsed-rail tooltips. Confirm accessible text changes with operation state and focus never disappears.
- [ ] **Step 6: Fix defects through red-green cycles**
For each defect: add one failing focused test, run it to confirm failure, make the smallest P0–P3 file change, rerun the focused test, then rerun the full gate. Do not bundle unrelated visual polish.
- [ ] **Step 7: Commit final verified fixes**
```powershell
git add src/main src/test
git commit -m "完成统一 UI 视觉验收"
```
If acceptance requires no code changes, do not create an empty commit.
## P3 Completion Gate
Completion requires fresh evidence from full tests, compile, `git diff --check`, repository scans, the complete screenshot matrix, side-by-side reference comparisons, and keyboard/accessibility smoke checks. Do not claim the unified UI complete from automated tests alone.