implement routes #6
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_code#6
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
make sure we implement
/hero_ui_routes
Implementation Spec for Issue #6 — Hash-Based SPA Routing
Objective
Implement hash-based deep-linking across the entire
hero_code_uidashboard so that every meaningful view, object, and filter state is addressable by a canonical URL. Browser MCP agents and users must be able to bookmark, share, and directly navigate to any view by URL.Routing model:
Requirements
/#/jobs,/#/logs,/#/stats,/#/admin,/#/docs,/#/perf,/#/ide,/#/code)/#/jobs/<id>/#/jobs/<id>must be independently loadable on page load/#/jobs?status=running&engine=rhai&q=foo/#/logs?src=<source>&level=3/#/jobs/<id>/logs/#/code/<encoded-path>/#/ide?repo=<path>&file=<path>/#/docs/<doc-id>Files to Modify/Create
static/js/router.jsstatic/js/dashboard.jsstatic/js/code_manage.jsstatic/js/code_editor.jstemplates/index.html<a href="#/tab">Implementation Plan
Step 1 — Create
router.js: core hash router moduleFiles:
static/js/router.js(new)HeroRouter.parse(hash)→{ tab, id, subview, params }HeroRouter.navigate(tab, id?, subview?, params?)— writes hash, useshistory.pushStateHeroRouter.replaceState(...)— updates hash without adding history entryHeroRouter.dispatch()— parses current hash, calls registered handlerHeroRouter.handlers— map of tab name → handler functionHeroRouter.init()— attacheshashchange+DOMContentLoadedlistenerDependencies: none
Step 2 — Wire router into
index.htmlandswitchTabFiles:
templates/index.html,static/js/dashboard.jsrouter.jsbeforedashboard.jsin<script>order<button onclick="switchTab('X')">to<a href="#/X">styled identicallyswitchTab()to callHeroRouter.navigate()(guard against recursion)switchTab("jobs")in DOMContentLoaded withHeroRouter.init()Dependencies: Step 1
Step 3 — Jobs tab: row click, detail sub-route, filter params (dashboard.js)
Files:
static/js/dashboard.jsHeroRouter.handlers.jobs<tr>clickable →HeroRouter.navigate('jobs', jobId)restoreJobFilters(params)reads params and sets filter controlsloadJobs()pushes current filter state into URL viareplaceStateviewJobDetail()callsHeroRouter.navigate('jobs', jobId)at startDependencies: Step 2
Step 4 — Logs tab: source and filter params in URL (dashboard.js)
Files:
static/js/dashboard.jsHeroRouter.handlers.logsrestoreLogFilters(params)sets log filter controlsloadLogs()callsreplaceStatewith current filter params/#/logs?src=<source>Dependencies: Step 2
Step 5 — Code tab: repo row click routes (code_manage.js)
Files:
static/js/code_manage.jsHeroRouter.handlers.codeHeroRouter.navigate('code', encodeURIComponent(path))Dependencies: Step 2
Step 6 — IDE tab: repo + file state in URL (code_editor.js)
Files:
static/js/code_editor.jsHeroRouter.handlers.ideideSelectRepo()callsreplaceStateafter repo selectedreplaceStatewith repo + file paramsideSelectRepoByPath()andideOpenFileByPath()helpers for route restorationDependencies: Step 2, Step 5
Step 7 — Docs tab: section routing (dashboard.js)
Files:
static/js/dashboard.js,templates/index.htmlHeroRouter.handlers.docshref="#/docs/<id>"HeroRouter.navigate('docs', docId)on clickDependencies: Step 2
Step 8 — Simple tab routes: stats, admin, perf (dashboard.js)
Files:
static/js/dashboard.jsstats,admin,perfthat just callswitchTab(tab)Dependencies: Step 2
Acceptance Criteria
/#/jobsactivates Jobs tab/#/jobs/42activates Jobs tab and opens job 42 detail/#/jobs?status=running&engine=rhaiactivates Jobs with filters pre-set/#/jobs/42/logsopens job 42's log view/#/logsactivates Logs tab/#/logs?src=hero_code_serveractivates Logs with source pre-filtered/#/stats,/#/admin,/#/perfactivate their respective tabs/#/docs/api-referenceactivates Docs and loads API Reference section/#/ide?repo=/path/to/repoactivates IDE with that repo selected/#/ide?repo=/path/to/repo&file=/path/to/file.rhaiopens that file/#/codeactivates Code Management tab;/#/code/<encoded-path>selects that repo/#/jobs/<id>/#/code/<encoded-path>/#/logs?src=fooshows Logs tab with source pre-filtered (no extra click)/#/jobs?engine=<engine>/#/jobs?status=<status>/#/logs?src=<source>router.jsloads beforedashboard.jsinindex.htmlNotes
history.pushStatefor forward navigation andhistory.replaceStatefor filter changes (avoids polluting back stack)hashchangetriggers with a_navigatingflagencodeURIComponentrepo paths in hash segments;decodeURIComponentwhen reading back/job-outputand/file-editorstandalone pages are out of scope (separate HTML pages opened viawindow.open())BASE_PATHprefix does not affect client-side hashes — verifiedTest Results
Breakdown by crate
hero_code_lib(unit)hero_code_sdk(unit)tests/job_lifecycle(integration)tests/rhai_execution(integration)tests/rpc_dispatch(integration)hero_code,hero_code_server,hero_code_ui, etc.Build time: ~1m 18s
Note: The current changes are UI-only (JavaScript/HTML/CSS). No Rust tests cover those files, which explains the 0-test crates for
hero_code_serverandhero_code_ui. All existing Rust tests pass cleanly.Implementation Complete
Hash-based SPA routing has been implemented across the entire
hero_code_uidashboard.Changes Made
New file:
static/js/router.js— Corewindow.HeroRoutermodule:parse(),navigate(),replaceState(),dispatch(),handlersmap,init()Modified files:
templates/index.html— Loadsrouter.jsbeforedashboard.js; tab nav buttons converted to<a href="#/tab">anchorsstatic/js/dashboard.js— Registered route handlers for all tabs; job rows clickable with URL update; filter controls sync to URL; log source badges are filter links;viewJobDetailupdates URL;restoreJobFiltersandrestoreLogFiltershelpers; docs links updatedstatic/js/code_manage.js— Repo rows clickable with#/code/<encoded-path>;codeShowRepoDetail()helperstatic/js/code_editor.js— IDE state (repo + file) synced to URL;ideSelectRepoByPath()andideOpenFileByPath()helpers for route restorationRoute Coverage
/#/jobs/#/jobs/42/#/jobs?status=running&engine=rhai/#/logs/#/logs?src=hero_code_server&level=3/#/stats/#/admin/#/perf/#/docs/api-reference/#/ide?repo=/path/to/repo/#/ide?repo=/path/to/repo&file=/path/to/file.rhai/#/code/#/code/<encoded-path>Test Results