fix(widget): group category time by full path, matching the Activity view - #231
fix(widget): group category time by full path, matching the Activity view#231TimeToBuildBob wants to merge 1 commit into
Conversation
…view The widget rolled every event up to its top-level category ($category[0]), so "Work > Programming" and "Work > Planning" collapsed into a single "Work" row. Totals still matched the Activity view because the sum is unchanged, but per-category times disagreed — the symptom reported in ActivityWatch#142. aw-webui builds cat_events with merge_events_by_keys(events, ["\$category"]) and labels them with \$category.join(" > ") (SelectableVisualization.vue top_categories namefunc). Mirror that: group by the full category path and label it the same way. Adds unit tests for parseCategories; three of them fail against the old top-level rollup.
Greptile SummaryThe PR aligns widget category aggregation with the Activity view by grouping events using their complete category path rather than only the top-level category.
Confidence Score: 5/5The PR appears safe to merge, with the full-path grouping behavior covered by focused regression tests. The changed parser consistently aggregates and labels complete category paths while preserving total durations and existing duration ordering, and no reachable blocking or non-blocking defect remains. Important Files Changed
Reviews (1): Last reviewed commit: "fix(widget): group category time by full..." | Re-trigger Greptile |
|
CI-green and mergeable (Greptile 5/5) — 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. |
Fixes the per-category discrepancy @ErikBjare reported in #142 ("category time presented seems to diff from Activity view (total time matches though)").
Cause
parseCategories()aggregated by$category[0]— the top-level category only. So["Work","Programming"]and["Work","Planning"]both landed in oneWorkbucket. The total was unaffected (same events, same durations), which is exactly why totals matched while per-category rows did not.The Activity view groups by the full category path: aw-webui builds
cat_eventswithmerge_events_by_keys(events, ["$category"])and renders them withnamefunc="e => e.data['$category'].join(' > ')"(SelectableVisualization.vue,top_categories).Fix
Group by the full category path and label it the same way (
"Work > Programming").Tests
Adds
CategoryTimeWidgetUpdaterTest(6 cases). Three of them fail against the old top-level rollup and pass with the fix:parseCategories_keepsSubcategoriesSeparateparseCategories_mergesRepeatsOfTheSamePathparseCategories_sortsByDurationDescendingVerified locally with
./gradlew :mobile:testDebugUnitTest --tests 'net.activitywatch.android.widget.*'.Not in this PR
NotifyWorker.parseCategorySeconds()has the same top-level rollup, but its keys are matched against configured alert categories, so changing it would alter alert behaviour. Worth a separate look.