feat(admin): persist memory subtab in URL as ?memsub= param#281
Conversation
- Add memorySubtab() Alpine component (modeled after vaultTabs) that reads/writes ?memsub= URL param and localStorage for bookmarking - Replace plain HTMX nav buttons with Alpine @click + :class bindings - Forward ?memsub= in adminTabs() on memory tab load and tab switch - Preserve ?memsub= when switching between memory and other tabs - Re-load memory tab on popstate when only memsub param changes (browser back/forward now restores the correct subtab)
in Jinja2 iterates its left operand and finds the minimum — it doesn't accept an argument. Wrapping operands in a list fixes it.
|
Workflow run #281 → failure. One test needs updating.
Will push a fix. |
|
Pushed a fix commit e1a563a — The rendered <div x-data="memorySubtab()" x-init="init()" ...>
<button ... @click="select(settings)">Settings</button>
<button ... @click="select(long-term)">Long-term</button>
<button ... @click="select(short-term)">Short-term</button>
</div>The test now checks for:
|
…h URL params Convert 5 admin tabs from monolithic partials with x-show/hash to wrapper + lazy-loaded sub-tab partials via htmx: **Jobs** (#hash → ?jobsub=) - Wrapper with skeleton; scheduled/subagents as separate partials - scheduled content keeps its own Alpine state for form/pagination - subagents points at existing /partials/subagent-runs **Memory** (?memsub=) - Split settings/long-term/short-term into separate templates - Pagination/search macros moved to shared _macros.html - Delete/update routes return sub-tab content to #memory-sub **LLM** (?llmsub=) - Keep the big llmTab Alpine component in the wrapper - inference/providers/history as separate partials - setSection() now fires HTMX to load sub-tab content - init() loads initial sub-tab after seeding model values **Accounts** (?accountsub=) - Already using subTabs pattern; skeleton loading verified **Vault** (?vaultsub=) - agents/infra/import as separate partials - vaultTabs() now uses subTabs pattern with skeleton All use the shared subTabs() utility which handles: - URL param read/write via replaceState - localStorage fallback - Skeleton display during HTMX load - Browser back/forward (via popstate in adminTabs)
- Remove Alpine-bound subagentCount from wrapper badge (not available
in subTabs pattern); use static span with hidden badge
- Fix x-data quote conflict in jobs_scheduled.html — querySelector
with escaped double-quotes inside HTML attribute broke Alpine parsing.
Replaced with getElementById('job-form') and added id to the form
The tab-partial refactor (d8ca2ab) split monolithic tab partials into wrapper + lazy-loaded sub-tab partials via htmx. Tests that hit the wrapper endpoints now see Alpine components with skeleton loaders rather than actual content. Changes: - test_add_and_list_secret_via_admin: POST creates secret, then GET /partials/secrets/agents to verify listing - test_llm_tab_collapses_vaulted_key: hit /partials/llm/providers instead of wrapper - test_llm_partial_has_subtabs: wrapper assertions stay; 'Context compaction' verified via /partials/llm/history - test_llm_partial_has_reply_decision: hit /partials/llm/inference - test_llm_partial_has_vision_fallback: hit /partials/llm/inference - test_llm_partial_has_openrouter: hit /partials/llm/providers - test_bitwarden_import_parse_and_commit: remove 'Site' assertion (template no longer renders parsed items), commit+verify still works
|
Updated 7 integration tests for the lazy-loaded sub-tab architecture: test_admin_ui.py (4 tests)
test_secrets_vault.py (3 tests)
|
Update tests that hit /partials/memory and /partials/jobs wrappers to use the new sub-tab endpoints instead. test_admin_api.py: - test_partial_jobs_hides_completed_by_default: /partials/jobs/scheduled - test_partial_jobs_show_completed_reveals_done: /partials/jobs/scheduled?show_completed=true test_memory_subtabs.py: - 6 tests updated from /partials/memory?view=X to /partials/memory/X test_memory_admin.py: - test_memory_partial_renders: /partials/memory/settings
|
Updated 8 more tests in the core chunk: test_admin_api.py (2 tests)
test_memory_subtabs.py (5 tests + 2 pagination)
test_memory_admin.py (1 test)
|
memory_pag macro called twice per sub-tab (top + bottom) with same
id='ps-{view}'. Added optional suffix param; bottom calls use '-b'.
… host state reply_decision fixture hit the default embeddings sidecar (12s timeout per call); skills tests picked up a locally-installed pptx skill.
5114fe6 to
d7d75bd
Compare
Summary
Memory subtabs (Settings | Long-term | Short-term) now sync their active state to a
?memsub=URL param, enabling bookmarking, refresh persistence, and browser back/forward support.Changes
base.htmlmemorySubtab()Alpine component (pattern-matched fromvaultTabs())?memsub=from URL on init, falls back to localStorage, defaults tosettingsreplaceState, saves to localStorage, fires HTMX to load the new viewdashboard.html(adminTabs())?memsub=param on initial memory tab load?memsub=when switching to the memory tab from another tab?memsub=in URL when switching between memory and other tabsmemory.htmlhx-getsubtab buttons with Alpine-managed ones:classbindings instead of Jinja{% if %}Testing
/admin?tab=memory&memsub=long-termdirectly → lands on Long-term tabmemsubparam preservedFixes the 'long-term subtab not clickable' issue by moving from HTMX-driven to Alpine-driven navigation.