The poll timer was reading from job.output in memory, which depended on
run_job's async task populating it. Now OperationLog reads new content
directly from the log file using seek, making it independent of the
async task. Also store the asyncio task reference to prevent GC.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backup and restore operations now run as background jobs instead of
blocking modal screens. Users can navigate away and check progress
from a dedicated Running Tasks screen. OperationLog supports attaching
to running jobs with live output polling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Other OperationLog dialogs (crontab show, remote test, retention) no
longer display the spinner since they complete quickly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses rich.spinner.Spinner with set_interval refresh instead of
Textual's LoadingIndicator which caused rendering failures.
Spinner shows dots animation while running, changes to checkmark on finish.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts all spinner/loading indicator changes and debug code.
Restores the exact code from commit 0e02ba6 which was confirmed working.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LoadingIndicator was causing OperationLog ModalScreen to fail silently
during compose. Replaced with a simple Static emoji spinner (⏳→✅).
Reverted screen push patterns back to simple callback approach.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add wait_ready() to OperationLog and await it in all callers before
starting CLI commands. Ensures the modal with spinner is fully rendered
before streaming begins.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows an animated spinner next to the title while backup, restore,
retention, remote test, and schedule operations are running. Spinner
hides when the operation completes via finish().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The worker starts streaming output before the modal screen finishes
composing. Buffer writes until on_mount fires, then flush.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Text.from_markup() for strings containing Rich tags
so [red]...[/red] renders as colored text instead of raw tags.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>