Menu

#448 feat(ui): DMG update card in the dashboard sidebar

closed
nobody
None
2026-07-17
2026-07-15
Anonymous
No

Originally created by: Akarsh-Hegde

Summary

The dashboard had no update surface — only the tray popover showed the "Update available" banner (and update.rs's module doc already claimed a "dashboard sidebar" banner that was never implemented, or was dropped in the Tauri fold). This adds the dashboard sibling, reusing the exact same commands so both surfaces behave identically.

Placed as a small accent card at the top of the sidebar (OverviewPanel), matching the existing "Board cleanup available" CTA — noticeable without taking over the header.

What it does

  • On mount → invoke('check_update'); renders only when state === 'available' (up-to-date / error / unsupported stay silent, like the popover) — consent-based.
  • Click → invoke('install_update') (download + verify + relaunch); shows Downloading… N% from the update-progress event, and Update failed on rejection.
  • Outside Tauri (next dev browser) invoke throws, the effect swallows it, and the card never renders.

Files

  • ui/components/timeline/UpdateCard.tsx (new) — the card + all update logic.
  • ui/components/timeline/OverviewPanel.tsx — mounts <UpdateCard /> at the top of the sidebar overview.
  • ui/lib/api-types.tsUpdateStatus + UpdateProgress types mirroring update.rs.
  • ui/__tests__/update-card.test.ts (new) — guards command reuse, consent-based render, Tauri-safe degradation, the OverviewPanel mount, and that it's not a header banner.

No capability change

The dashboard window already shares the capability that grants check_update/install_update + the update-progress event (the popover uses them under the same set).

Test plan

  • tsc --noEmit: clean · next build: clean · bun test: 188 pass
  • Visual note: the card only appears in the packaged app when check_update finds a newer version, so it can't be exercised in next dev / without a real pending update (same constraint as the popover banner).

🤖 Generated with Claude Code

Related

Tickets: #456

Discussion

  • Anonymous

    Anonymous - 2026-07-15

    Originally posted by: coderabbitai[bot]

    [!IMPORTANT]

    Review skipped

    Auto reviews are disabled on base/target branches other than the default branch.

    Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.


    ⚙️ Run configuration

    Configuration used: Organization UI

    Review profile: ASSERTIVE

    Plan: Pro Plus

    Run ID: c86f3bfb-616a-4a7b-ae4d-00a41fbc235b

    You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

    Use the checkbox below for a quick retry:
    - [ ] 🔍 Trigger review

    ✨ Finishing Touches
    🧪 Generate unit tests (beta) - [ ] Create PR with unit tests - [ ] Commit unit tests in branch `feat/dashboard-update-banner`

    Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

    ❤️ Share - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

    Comment @coderabbitai help to get the list of available commands.

     
  • Anonymous

    Anonymous - 2026-07-16

    Originally posted by: adityaharishch

    Review: correctness-focused pass

    Verified the two claims that matter most for correctness:

    • check_update/install_update are pre-existing commands (lib.rs:542-543) and update-progress is an existing event — the default.json capability already lists "windows": ["main", "dashboard", "setup", "uninstall", "tray-tooltip"], so the dashboard window already had access. The PR's "no capability change" claim is accurate — no silent-invoke-denial risk here.
    • subscribe('/api/update/progress', null, 'update-progress', ...) correctly passes command: null for a delta-only stream (matches bridge.ts's documented convention — no snapshot prime, caller doesn't need one since pct naturally starts at null and the card doesn't render pre-available).

    One minor, non-blocking note: on a failed install, onInstall's retry doesn't reset pct back to null (UpdateCard.tsx — only installing/failed are reset). If a user retries after a partial download failure, the card can briefly show the stale percentage from the failed attempt until the next update-progress event arrives. Cosmetic only — not a correctness bug, and self-corrects on the first progress tick.

    Logic otherwise checks out: consent-based render (if (!status) return null gated on state === 'available'), Tauri-safe degradation (isTauri() guard on both effects, mount cleanup via cancelled flag on the async check), and the mount site (OverviewPanel.tsx, not LayoutBanners.tsx) matches the PR's stated intent from the second commit's course-correction. Test file's assertions line up with the actual component behavior.

    No correctness issues found — LGTM.

     
  • Anonymous

    Anonymous - 2026-07-17

    Originally posted by: Akarsh-Hegde

    Addressed the review feedback and resolved the merge conflicts against pre-main:

    Review fix@adityaharishch's non-blocking note: onInstall's retry path reset installing/failed but left pct stale, so retrying after a partial-download failure could briefly show the previous attempt's percentage until the next update-progress tick. Fixed by resetting pct to null in onInstall (UpdateCard.tsx), with a guarding test added in update-card.test.ts.

    Merge conflicts — merged latest pre-main in. Only one real conflict: ui/lib/api-types.ts, where this PR's UpdateStatus/UpdateProgress types and the just-merged What's New PR's ReleaseNote/RoadmapItem/WhatsNewData types both landed at the same spot in the file. Resolved by keeping both additions side by side (no logic conflict, just adjacent insertions).

    Verified after resolving: cargo test, cargo clippy -- -D warnings, cargo fmt --check, bun test (202 pass), tsc/next build all clean — and the pre-push hook (fmt + clippy + tests + UI build/tests + security audit) passed on push. CI is green.

    This is ready to be merged pending a maintainer's final look.

     
  • Anonymous

    Anonymous - 2026-07-17

    Ticket changed by: Akarsh-Hegde

    • status: open --> closed
     

Log in to post a comment.