Skip to content

fix(bucket): show event count and a not-found state for unknown buckets - #1022

Merged
ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/bucket-view-eventcount-not-found
Oct 6, 2026
Merged

ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/bucket-view-eventcount-not-found

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Two bugs on the bucket page (Raw Data → bucket → Open), found while dogfooding v0.13.2 and reproduced on master (45e9c41).

1. Eventcount is always blank. getEventCount read (await countEvents(id)).data. aw-client's _get already unwraps the response body, so the call returns a number and .data is undefined. The server answers correctly (GET /api/0/buckets/aw-watcher-window_bob/events/count returns 49828). Fix: use the value directly. Edge case: aw-client 0.3.x unwraps with (res && res.data) || res, so a count of 0 comes back as the raw response. That case still reads .data.

2. An unknown bucket id renders a fake bucket. #/buckets/does-not-exist showed three error banners (two TypeErrors and the server's 404 text), an empty metadata table, and Created: <now>. That came from bucket() falling back to { id }. Now, once the bucket list has loaded, an unknown id shows a "No bucket named X" alert with a link back to the bucket list, and the count/events requests are skipped.

Also removes a leftover console.log(this.bucket) in bucket_with_events.

Before / after

Before (v0.13.2) After
Existing bucket
Unknown bucket

The "after" screenshots come from a production vite build of this branch, running against a live aw-server v0.13.2.

Tests

test/unit/Bucket.test.js mounts the view with a mocked store and client and covers three cases: a numeric count, a count of 0 returned as the raw response, and an unknown bucket. On master, the numeric-count and unknown-bucket tests fail. On this branch, all three pass.

@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.30%. Comparing base (95cd6b4) to head (9305b3c).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1022   +/-   ##
=======================================
  Coverage   63.30%   63.30%           
=======================================
  Files          52       52           
  Lines        3608     3608           
  Branches      892      892           
=======================================
  Hits         2284     2284           
+ Misses       1309     1243   -66     
- Partials       15       81   +66     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Adds not-found state and event count display to bucket view.

The PR appears safe to merge, though the previously reported refresh-path issues remain.

Findings

  1. P2 Failed refresh leaves blank detail ▶
  2. P2 Unknown bucket fetches twice ▶

Summary

The PR restores the bucket event count, shows a not-found state for unknown buckets, and adds tests for those paths.

  • A stale bucket-list entry is refreshed before the view declares a bucket missing.
  • The two unresolved earlier findings remain: a failed refresh leaves the detail blank, and a cold visit to an unknown bucket fetches the list twice.

Reviews (3) · Last reviewed commit: "fix(bucket): refresh a stale bucket list..."

Comment thread src/views/Bucket.vue
Comment thread test/unit/Bucket.test.js Outdated
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@TimeToBuildBob

TimeToBuildBob commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 AI code review

This PR fixes the bucket detail view in src/views/Bucket.vue: it removes the fallback fake bucket object, adds a not-found alert shown after the bucket list is loaded, refreshes the bucket list once before declaring a bucket missing, and changes getEventCount to handle aw-client's unwrapped numeric response as well as the raw response for a count of 0. It also adds a new unit test file test/unit/Bucket.test.js covering the numeric count, zero count, stale-list refresh, and not-found cases.

Safe to merge — no P0/P1 findings

Confidence 5/5

✅ No thread-worthy findings. Advisory notes follow; they are retained without opening review threads.

2 advisory findings (summary-only, not scored)

These P2 guard, heuristic, trade-off, or documentation claims are retained for judgment without opening review threads.

⚠️ P2 medium — src/views/Bucket.vue:68

The bucket_with_events computed still spreads this.bucket unconditionally. When notFound is true, this.bucket is undefined, so { ...undefined, events: this.events } produces { events: [] }. The template guards the vis-timeline and aw-eventlist with v-else-if="bucket", so those components are not rendered in the not-found state, and the computed is not evaluated by the template. However, the watch: { daterange } handler calls getEvents(this.id) whenever daterange changes, and getEvents calls getBucketWithEvents which is mocked but in production would issue a request for a non-existent bucket. The daterange watcher is active even when the bucket is not found, because the input-timeinterval is not rendered in the not-found branch, so no daterange change can occur from the UI. But if the component is reused with a different id prop (e.g., navigating from one bucket to another), the watcher may fire before the new bucket loads, and getEvents would call getBucketWithEvents with an undefined bucket. This is a pre-existing issue not introduced by this PR, and the not-found state prevents the UI from triggering it. The PR does not add a guard in getEvents for missing bucket, but the not-found branch avoids rendering the time interval, so no user-visible break. This is a guard-level observation.

How this was verified: Checked the template: vis-timeline and aw-eventlist are inside the v-else-if="bucket" div, so they are not rendered when notFound. The daterange watcher is defined but the input-timeinterval is also inside that div, so no daterange change can occur in not-found state. The computed is not evaluated by the template in that state.

⚠️ P2 medium — test/unit/Bucket.test.js:80

The test 'shows a count of 0 when aw-client returns the raw response' mocks mockCountEvents.mockResolvedValue({ data: 0, status: 200 }) and expects wrapper.vm.eventcount to be 0. This test passes because the code reads count.data when count is not a number. However, the test does not assert that the raw response is actually the shape aw-client 0.3.x returns; it only checks the unwrapping logic. The test is not vacuous because it exercises the branch, but it does not pin the contract with aw-client's actual response shape. The PR description says aw-client 0.3.x returns the raw response when the body is falsy, and the test uses a plausible shape. This is acceptable test coverage, not a defect.

How this was verified: The test asserts eventcount is 0, which exercises the fallback branch. The mock shape matches the described aw-client behavior.

Files changed (2) — the diff as I read it
  • src/views/Bucket.vue — Adds notFound state and alert, removes bucket fallback, refreshes bucket list before missing, and unwraps countEvents response.
  • test/unit/Bucket.test.js — Adds unit tests for the bucket view with mocked store and client.
Previous review passes
commit score findings engine when
6303cb62aa84 5/5 0 llm 2026-10-02 02:53 UTC

Reviewed f60212e656ec · openrouter/deepseek/deepseek-v4-flash-0731 · llm engine · 63s · about this reviewer

Maintainer commands

@TimeToBuildBob review (own line) — fresh review · @TimeToBuildBob fix — a worker acts on the findings. Once per comment; 👀 = received.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread src/views/Bucket.vue
await this.getEventCount(this.id);
if (!this.bucket) {
// The cached list may predate this bucket, so refresh before calling it missing.
await this.bucketsStore.loadBuckets();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Failed refresh leaves blank detail

If the bucket-list refresh fails, this await stops the mount hook before loaded becomes true. The page then shows only the bucket ID, with neither a not-found state nor an explanation that loading failed, and it does not retry.

Comment thread src/views/Bucket.vue
Comment on lines +82 to +84
if (!this.bucket) {
// The cached list may predate this bucket, so refresh before calling it missing.
await this.bucketsStore.loadBuckets();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unknown bucket fetches twice

On a cold visit to an unknown bucket, ensureLoaded() already fetches the empty bucket list. This branch fetches it again before showing “No bucket named …”, adding an unnecessary request and delay.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

- countEvents() already returns the unwrapped body, so .data was undefined
  and Eventcount always rendered blank. Handle aw-client 0.3.x returning the
  raw response for a falsy body (count 0).
- An unknown bucket id rendered a fake bucket (Created = now) plus several
  error banners. Show a 'No bucket named X' alert instead and skip the
  count/events requests.
- Drop a leftover console.log in bucket_with_events.

Git-Session-Id: 6562
The cached bucket list can predate a bucket created after it was loaded,
so a cache miss now triggers loadBuckets() before the view declares the
bucket missing. Tests now emit an initial date range from the
input-timeinterval stub and assert no events request for a missing
bucket.

Git-Session-Id: ff69
@TimeToBuildBob
TimeToBuildBob force-pushed the fix/bucket-view-eventcount-not-found branch from f60212e to 9305b3c Compare October 6, 2026 12:32
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Rebased onto current master after #1054 landed the overlapping event-count fix. The conflict resolution keeps #1054's empty-data-row guard and this PR's not-found/stale-cache behavior plus zero-count compatibility. New head: 9305b3c.

Verified locally: npx jest test/unit/Bucket.test.js --runInBand (4 passed), ESLint on both changed files, and git diff --check. Fresh CI is running.

@ErikBjare

Copy link
Copy Markdown
Member

@greptileai review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants