Files
projax/web
mAi 9a8ea8f31e feat(views): Phase 5j slice G — show_count badges + icon registry
Per m's v1 picks (2026-05-29):
- Q6 (icon picker): yes, with curated keys + SVG registry.
- Q8 (show_count badge): yes, opt-in checkbox + sidebar badge.

Icon registry (web/icons.go):
- 7 curated keys: folder (default), clock, star, tag, inbox, box,
  file-text. Each maps to a Feather-style 24x24 SVG matching the rest
  of the projax sidebar aesthetic. Returns template.HTML so layout.tmpl
  emits markup verbatim. Unknown / nil keys fall back to folder.
- RenderViewIcon(*string) is template-callable; IconRegistryKeys()
  feeds the editor's <select>.
- Funcs map in web/server.go gains a "renderIcon" entry.

show_count badge (web/server.go + web/templates/layout.tmpl):
- render() now computes per-saved-view counts when ANY view in the
  list has ShowCount=true. One ListAll per render, shared across all
  show-count views; for each opted-in view the persisted filter_json
  is decoded into a TreeFilter and matched against every item.
- Counts pass to the template as UserViewCounts (slug → count). The
  template renders {{index $counts $slug}} inside a nav-badge span
  next to the view's name.

Template updates:
- layout.tmpl: replaces the diamond-glyph placeholder with
  {{renderIcon .Icon}}; show_count views emit a .nav-badge next to
  their name.
- view_editor.tmpl: icon <select> now sourced from IconKeys data
  (the editor handler passes IconRegistryKeys()).

CSS additions:
- nav-badge: muted-color, surface-background, pill-shaped, pushed to
  the right via margin-left:auto so the badge aligns with the row's
  end regardless of name length.
- nav-item-user-view.active .nav-badge: switches to accent border +
  color so the active row's badge stays legible.

Tests:
- TestSidebarShowCountBadge — seeds show_count=true view, asserts
  .nav-badge markup in the sidebar.
- TestSidebarIconRenders — seeds icon=star view, asserts the
  distinctive star polygon path lands in the sidebar SVG.

Drag-reorder UI stays parked (m's Q7=(b) v2). sort_order column is
server-assigned MAX+1 on create; the column was wired in slice A and
ReorderViews is ready for slice G's followup.
2026-05-29 12:07:54 +02:00
..