Repository navigation
feat(analytics): deep-link Scopes sub-tabs and window (#205) - #206
Conversation
…the URL (#205) Unit tests (vm harness) and a Playwright E2E for ?sub=, ?swin= and ?wdwin=: URL wins over sessionStorage, unknown values fall back to the defaults, default URLs unchanged, clicks write the URL, reload and back/forward restore the view. Red on master. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dow (#205) The Scopes sub-tab and window and the Wardriving window lived only in sessionStorage. They are now in the hash as ?sub=, ?swin= and ?wdwin= (?window= stays the global time picker). A URL value wins, an unknown one falls back to the default, and values are only compared with ===. Without a URL value the stored one is used and written back; defaults are left out, so today's URLs are unchanged. All keys of a tab are read before any is written, since rebuilding the hash drops an empty key. _updateAnalyticsUrl drops other tabs' keys through one map (rf-health folded in). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rapport — CS-pve-agent1 PR#206 #205 — head 6b6cecaStatus: Draft, all CI jobs green on Evidence tags:
ChangesTwo commits:
AuditThe full table is in the PR description.
Tests and mutants
BrowserLocal Go server with a copy of
No page errors. Screenshot checked: Hop Depth chart and cards render. [A] CI per jobRun on head
Remaining
|
Review — CS-pve-agent3 PR#206 analytics-deeplinks — head 6b6cecaDom: APPROVE with nits Independent, read-only review. I read issue #205, the PR description and the author's report.
Evidence tags: [T] = test or CI run by me, [A] = my own code analysis, [K] = from the author's report, not re-run. Findings
There are no P1 or P2 findings. Verification points1. Scopes: read on mount, written on click, URL beats storage, back/forward, key choice
2. Escape safety (as in #194)
3. Default-state URLs are unchanged
4. Audit table
5. Tests: see below. 6. Rules
Tests and mutants
Not verified
|
Relates to #205
Summary
The Scopes tab's sub-tab (Overview / Hop Depth / Regions / Hygiene) and its 1h/24h/7d window lived only in
sessionStorage, so#/analytics?tab=scopescould not point at e.g. Hop Depth. The Wardriving tab's window had the same problem. All three are now in the hash next to?tab=:sub=overview,hopdepth,regions,hygieneoverviewswin=1h,24h,7d24hwdwin=1h,24h,7d24hExample:
#/analytics?tab=scopes&sub=hopdepth&swin=7dWhy not reuse
window=window=is already the global analytics time picker above the tab bar. It allows different values (''/1h/24h/7d/30d),_updateAnalyticsUrlwrites it on every tab switch, and it drives the shared loads (rf/topology/channels/relay-airtime). The Scopes picker is a separate control that only feeds/api/scope-stats. Sharing one key would either push the Scopes window into every other tab's fetches or let the global30d/All-data values land on a picker that has no such buttons. So each tab window gets its own key:swinfor Scopes andwdwinfor Wardriving, mirroring theirdata-win/data-wdwinbuttons.Plan / milestones
test-analytics-subtab-deeplinks-205.js, registered intest-all.sh;test-issue-205-analytics-subtab-deeplinks-e2e.jsin the CI Playwright step.public/analytics.js:_updateAnalyticsUrldrops other tabs' keys through one map.e2e-fixture.db;No config/customizer implications: nothing new is configurable.
Behaviour
sessionStorageand is stored, so a later plain click on the Scopes tab returns to it.===against a fixed list and never reach a selector or markup (as in analytics: escape-safe ?tab= lookup, pin remaining #191 test gaps, withQuery contract #193/fix(analytics): escape-safe ?tab= lookup and withQuery contract (#193) #194).#/analytics?tab=scopes.replaceState, the same as the top-level tab clicks. Switching to another tab dropssub/swin/wdwin.navigate(), which re-runsinit().?sub=) that a second read would then miss. The unit test found this during development, and it is pinned there.range/observer/from/toclearing now goes through the sameTAB_URL_PARAMSmap, with no behaviour change. This is pinned by a test.Perf
URLSearchParamsparse and at most onereplaceState. Clicks do the same.Audit of other analytics tabs' local view state
sub=(this PR, tested)swin=(this PR, tested)wdwin=(this PR, tested). It is the same pattern as Scopes.TAB_URL_PARAMS.bytes/sectioncollisions: ['bytes', 'section']toTAB_URL_PARAMSwould do it, but it changes existing URLs, so it is left out of this PR.prefix/generatenoScopeFilterrole/q/geo,neverRelayFilter.geo,adoptFilter.mode)<details>open statelocalStorageprecedence, with the keys validated againstREPEATER_METRIC_AXES.test-issue-1758-ng-filter-rerenders-e2e.js, so they are kept out of this PR.URLState.serializeSortif wanted.Pre-existing issue found during the audit (not changed):
renderScopesTabis called again on the startup theme-refresh.Tests
test-analytics-subtab-deeplinks-205.js: 69 cases in the realapp.js+url-state.js+analytics.jsin a vm. It covers:resolveViewParamtable;sub/swin/wdwin(quotes, selector-list injection,__proto__, markup) falling back to the defaults;window=staying independent;On master, 57 of 66 fail; the 3 empty-key cases were added later.
test-issue-205-analytics-subtab-deeplinks-e2e.js, added to the Playwright step:?tab=scopes&sub=hopdepth;sub/swin;#/nodes;subwith no page error;wdwincold load and click.Against the master frontend, 8 of 9 fail.
Fork guards in
deploy.ymlare unchanged (9 occurrences).Browser validation
Local Go server with the migrated
e2e-fixture.db(freshened, migrated and seeded as in CI). Results for#/analytics?tab=scopes&sub=hopdepth:…&sub=hygiene#/packets, back#/packetsNo page errors.
🤖 Generated with Claude Code