Problem / motivation
Multi-page navigation is an explicitly named core value of FastSense ("organize complex dashboards into navigable sections … multi-page navigation"), but its programmatic surface is index-only and write-only:
- Pages are created by name —
addPage('Pressures') (DashboardEngine.m:175); DashboardPage.Name is a public char (DashboardPage.m:22).
- Navigation is only by integer index —
switchPage(pageIdx) (DashboardEngine.m:240). The guard pageIdx < 1 || pageIdx > numel(obj.Pages) and obj.ActivePage = pageIdx show no char/string handling.
- There is no public introspection of page names or the active page.
grep -nE "getPageNames|getActivePageName|numPages" over DashboardEngine.m returns nothing; ActivePage is a bare index property.
So to script "go to the Pressures page" today, a caller must manually track the insertion order of addPage calls into magic integer indices, and has no public way to even list the page names or query which page is active.
Proposed feature
- Name-based navigation — overload
switchPage to accept a char/string page name in addition to a numeric index. The existing numeric path is untouched.
- Introspection getters:
getPageNames() → cellstr of page names ({Pages{i}.Name}).
getActivePageName() → the active page's Name, or '' when no pages are defined.
d.addPage('Overview');
d.addPage('Pressures');
d.switchPage('Pressures'); % new: resolves name -> index
names = d.getPageNames(); % new: {'Overview','Pressures'}
active = d.getActivePageName(); % new: 'Pressures'
d.switchPage(1); % unchanged: numeric path still works
Rough sketch
- Lib/class:
libs/Dashboard/DashboardEngine.m (single file).
switchPage(obj, page): if page is char/string, resolve to an index via exact match against {obj.Pages{:}.Name}; on no match, error('DashboardEngine:unknownPage', ...) listing valid names (consistent with the repo's "unknown key lists valid options" convention). If numeric, behave exactly as today.
getPageNames(obj): return cellfun(@(p) p.Name, obj.Pages, 'UniformOutput', false) (empty cell when no pages).
getActivePageName(obj): return obj.Pages{obj.ActivePage}.Name when ActivePage >= 1, else ''.
Value
Name-based navigation is the natural automation/scripting primitive — FastSenseCompanion, a demo script, a "jump to section" control, or a UAT test wants d.switchPage('Vibration') rather than a brittle magic index that breaks if pages are reordered (cf. #249). The getters are the read side the same callers need to build menus or assert navigation state in tests.
Constraints check
- Toolbox-free: ✅ plain
strcmp/cellfun, no toolbox.
- Backward-compatible: ✅ the numeric
switchPage path is byte-identical; the getters are new methods. No toStruct/fromStruct change — pages already round-trip via Name, so serialized dashboards are untouched.
- Pure MATLAB/Octave: ✅ R2020b+ / Octave 7+ safe.
- Widget/Tag contract: ✅ unchanged — engine-level API only.
Effort estimate
S — single file (DashboardEngine.m): a name→index resolve branch at the top of switchPage, plus two small read-only getters.
Dedup
Clean. gh issue list --search "switchPage page name navigate" / "getPageNames page navigation" return only #221 (multi-page image export, unrelated). #249 (movePage/reorderPages) reorders pages but does not navigate by name; #274 (DashboardPage.removeWidget) and #275 (DashboardListPane selection getters) are unrelated. No open/closed issue or PR touches name-based page navigation or page-name introspection.
AI-proposed via /feature-scout — needs a human product decision before implementation.
Problem / motivation
Multi-page navigation is an explicitly named core value of FastSense ("organize complex dashboards into navigable sections … multi-page navigation"), but its programmatic surface is index-only and write-only:
addPage('Pressures')(DashboardEngine.m:175);DashboardPage.Nameis a public char (DashboardPage.m:22).switchPage(pageIdx)(DashboardEngine.m:240). The guardpageIdx < 1 || pageIdx > numel(obj.Pages)andobj.ActivePage = pageIdxshow no char/string handling.grep -nE "getPageNames|getActivePageName|numPages"overDashboardEngine.mreturns nothing;ActivePageis a bare index property.So to script "go to the Pressures page" today, a caller must manually track the insertion order of
addPagecalls into magic integer indices, and has no public way to even list the page names or query which page is active.Proposed feature
switchPageto accept a char/string page name in addition to a numeric index. The existing numeric path is untouched.getPageNames()→ cellstr of page names ({Pages{i}.Name}).getActivePageName()→ the active page'sName, or''when no pages are defined.Rough sketch
libs/Dashboard/DashboardEngine.m(single file).switchPage(obj, page): ifpageis char/string, resolve to an index via exact match against{obj.Pages{:}.Name}; on no match,error('DashboardEngine:unknownPage', ...)listing valid names (consistent with the repo's "unknown key lists valid options" convention). If numeric, behave exactly as today.getPageNames(obj): returncellfun(@(p) p.Name, obj.Pages, 'UniformOutput', false)(empty cell when no pages).getActivePageName(obj): returnobj.Pages{obj.ActivePage}.NamewhenActivePage >= 1, else''.Value
Name-based navigation is the natural automation/scripting primitive —
FastSenseCompanion, a demo script, a "jump to section" control, or a UAT test wantsd.switchPage('Vibration')rather than a brittle magic index that breaks if pages are reordered (cf. #249). The getters are the read side the same callers need to build menus or assert navigation state in tests.Constraints check
strcmp/cellfun, no toolbox.switchPagepath is byte-identical; the getters are new methods. NotoStruct/fromStructchange — pages already round-trip viaName, so serialized dashboards are untouched.Effort estimate
S — single file (
DashboardEngine.m): a name→index resolve branch at the top ofswitchPage, plus two small read-only getters.Dedup
Clean.
gh issue list --search "switchPage page name navigate"/"getPageNames page navigation"return only #221 (multi-page image export, unrelated). #249 (movePage/reorderPages) reorders pages but does not navigate by name; #274 (DashboardPage.removeWidget) and #275 (DashboardListPane selection getters) are unrelated. No open/closed issue or PR touches name-based page navigation or page-name introspection.AI-proposed via /feature-scout — needs a human product decision before implementation.