feat(ui): add OperationStatus feedback primitive and OperationIndicator control

Foundation for long-running-operation feedback (P0-1). OperationStatus tracks
IsRunning/ShowIndicator(300ms grace)/Elapsed/IsStalled(60s since last Report)
via an injectable TimeProvider, no static timer. OperationIndicator binds a
status to the shared spinner style. Pre-provisions ops.* locale keys for
groups A and C; no ViewModel wired up yet.
This commit is contained in:
Mika Kuns
2026-08-12 08:31:38 +02:00
parent eca16a3506
commit ca65849280
6 changed files with 445 additions and 0 deletions
+50
View File
@@ -692,6 +692,56 @@
"lists": { "localSuffix": "{0} / lokal", "smartMyDay": "Mein Tag", "smartImportant": "Wichtig", "smartPlanned": "Geplant", "virtualQueue": "Warteschlange", "virtualRunning": "Läuft", "virtualReview": "Prüfung", "newList": "Neue Liste" },
"repoImport": { "loadFailed": "Gespeicherte Ordner konnten nicht geladen werden: {0}", "saveFailed": "Ordner konnten nicht gespeichert werden: {0}" }
},
"ops": {
"stalledHint": "Läuft weiter — Worker antwortet noch",
"merge": {
"merging": "Wird zusammengeführt…",
"verifying": "Verify-Kommando der Liste läuft… ({0})"
},
"review": {
"submitting": "Wird zur Prüfung eingereicht…",
"rejecting": "Wird abgelehnt…",
"parking": "Wird geparkt…",
"previewing": "Vorschau wird geladen…"
},
"worktrees": {
"refreshing": "Wird aktualisiert…",
"cleaningUp": "Abgeschlossene Worktrees werden aufgeräumt…",
"resetting": "Worktree wird zurückgesetzt…",
"forceRemoving": "Worktree wird zwangsweise entfernt…",
"batchMerging": "Merge {0}/{1}…"
},
"skills": {
"installing": "Skill wird geklont…",
"updating": "Skill wird aktualisiert…",
"restoringDefaults": "Standard-Agenten werden wiederhergestellt…"
},
"onlineInbox": {
"signingIn": "Wird angemeldet…"
},
"repoImport": {
"scanning": "Repositories werden gescannt…"
},
"updateCheck": {
"checking": "Wird nach Updates gesucht…"
},
"reports": {
"generatingWeekly": "Bericht wird erstellt…",
"runningDailyPrep": "Tagesvorbereitung läuft…"
},
"planning": {
"buildingIntegrationBranch": "Integrations-Branch wird erstellt…",
"loadingAggregate": "Kombinierte Vorschau wird geladen…",
"finalizing": "Plan wird finalisiert…",
"queuingSubtasks": "Teilaufgaben werden eingereiht…"
},
"worker": {
"startupRecovery": "Wiederherstellung läuft…",
"creatingWorktree": "Worktree wird erstellt…",
"rebasingAfterMerge": "Andere Worktrees werden rebased…",
"maintainingWorktrees": "Worktree-Wartung läuft…"
}
},
"usage": {
"pill": {
"empty": "Nutzung ",
+50
View File
@@ -692,6 +692,56 @@
"lists": { "localSuffix": "{0} / local", "smartMyDay": "My Day", "smartImportant": "Important", "smartPlanned": "Planned", "virtualQueue": "Queue", "virtualRunning": "Running", "virtualReview": "Review", "newList": "New list" },
"repoImport": { "loadFailed": "Couldn't load remembered folders: {0}", "saveFailed": "Couldn't save folders: {0}" }
},
"ops": {
"stalledHint": "Still running — worker hasn't responded in a while",
"merge": {
"merging": "Merging…",
"verifying": "Running the list's verify command… ({0})"
},
"review": {
"submitting": "Submitting for review…",
"rejecting": "Rejecting…",
"parking": "Parking…",
"previewing": "Loading preview…"
},
"worktrees": {
"refreshing": "Refreshing…",
"cleaningUp": "Cleaning up finished worktrees…",
"resetting": "Resetting worktree…",
"forceRemoving": "Force-removing worktree…",
"batchMerging": "Merging {0}/{1}…"
},
"skills": {
"installing": "Cloning skill…",
"updating": "Updating skill…",
"restoringDefaults": "Restoring default agents…"
},
"onlineInbox": {
"signingIn": "Signing in…"
},
"repoImport": {
"scanning": "Scanning repositories…"
},
"updateCheck": {
"checking": "Checking for updates…"
},
"reports": {
"generatingWeekly": "Generating report…",
"runningDailyPrep": "Running daily prep…"
},
"planning": {
"buildingIntegrationBranch": "Building integration branch…",
"loadingAggregate": "Loading combined preview…",
"finalizing": "Finalizing plan…",
"queuingSubtasks": "Queuing subtasks…"
},
"worker": {
"startupRecovery": "Recovering…",
"creatingWorktree": "Creating worktree…",
"rebasingAfterMerge": "Rebasing other worktrees…",
"maintainingWorktrees": "Maintaining worktrees…"
}
},
"usage": {
"pill": {
"empty": "Usage ",