HERMES-GIELIE/static
Hermes Bot 6a75907802 feat(sidebar): add "Unassigned" project-filter chip for sessions without a project
Spliced from contributor PRs #1497 (Thanatos-Z) and #1513 (AlexeyDsov), which
both added the ability to filter the sidebar to sessions with no project_id
assigned. Lands here as a focused PR with the best of both:

## Synthesis decisions

- **Sentinel constant approach** (from #1497, Thanatos-Z): single state
  variable (`_activeProject` set to `NO_PROJECT_FILTER` sentinel) instead
  of a parallel `_showNoneProject` boolean. No two-state-machine ambiguity,
  no risk of "All" + "Unassigned" both reading active. Clicking "All"
  automatically clears the unassigned filter because there is only one
  variable to reset.

- **Conditional rendering** (from #1497): the chip only appears when
  there are actually unassigned sessions to filter to (`hasUnprojected`).
  Common case where every session is organized → chip stays hidden,
  uncluttered chip bar. The project-bar itself also renders when there
  are unassigned sessions (was previously gated on `_allProjects.length`).

- **Dashed-border visual treatment** (from #1497): `.project-chip.no-project
  {border-style:dashed;}` distinguishes the chip from real project chips
  so it reads as a meta-filter ("things without a project") rather than
  another project. Subtle but present.

- **"Unassigned" label** (new): clearer than #1497s "No project" (which
  reads like a status filter) or #1513s "None" (which is ambiguous —
  none of what?). Matches the conventional file-manager / task-tracker
  mental model: "things not yet assigned to a category." Tooltip elaborates:
  "Show conversations not yet assigned to a project."

- **Branched empty-state copy**: when the Unassigned filter is active
  and the result is empty, show "No unassigned sessions." instead of
  the generic "No sessions in this project yet."

## Tests

7 new tests in tests/test_sidebar_unassigned_filter.py pin every contract:
sentinel constant declared; filter logic uses !s.project_id when sentinel
is active; chip only renders when hasUnprojected; chip label and click
handler; visual treatment (dashed border + .no-project class); empty-state
copy branches on the active filter; All chip handler clears _activeProject
to null (would catch a regression if a parallel _showNoneProject boolean
is ever reintroduced).

Local full suite: 3929 → 3936 passing (+7).

Live verified at port 8789 with seeded data (5 projects + 73 unassigned
sessions in active profile): chip appears between "All" and project chips
when unassigned sessions exist; click cycles correctly; clicking a real
project hides the Unassigned chip from active state; clicking "All"
deactivates everything; dashed border present per getComputedStyle.

Co-authored-by: Thanatos-Z <thanatos-z@users.noreply.github.com>
Co-authored-by: Alexey Denisov <AlexeyDsov@users.noreply.github.com>
2026-05-03 07:08:08 +00:00
..
vendor chore: vendor streaming-markdown@0.2.15, remove CDN dependency 2026-04-24 01:05:20 +00:00
apple-touch-icon.png feature: add manifest and icons to enable app install on android 2026-05-02 19:06:39 +02:00
boot.js fix: add sidebar cancel for running sessions 2026-05-03 08:46:36 +08:00
commands.js fix: anchor active sessions per browser tab 2026-05-01 19:52:05 +08:00
favicon-32.png fix: add favicon (SVG + PNG + ICO), fix static MIME types (#613) 2026-04-16 20:11:02 -07:00
favicon-192.png feature: add manifest and icons to enable app install on android 2026-05-02 19:06:39 +02:00
favicon-512.png feature: add manifest and icons to enable app install on android 2026-05-02 19:06:39 +02:00
favicon-512.svg feature: add manifest and icons to enable app install on android 2026-05-02 19:06:39 +02:00
favicon.ico fix: add favicon (SVG + PNG + ICO), fix static MIME types (#613) 2026-04-16 20:11:02 -07:00
favicon.svg fix: add favicon (SVG + PNG + ICO), fix static MIME types (#613) 2026-04-16 20:11:02 -07:00
i18n.js fix(onboarding): allow keyless setup for self-hosted providers (#1499 third sub-bug) 2026-05-03 03:07:07 +00:00
icons.js fix(composer): distinct voice-mode icon, descriptive labels, opt-in pref (#1488) 2026-05-02 22:16:23 +00:00
index.html fix(sw-cache): version style.css link so old SW cannot return stale CSS (#1507) 2026-05-03 06:09:47 +00:00
login.js fix(login): retry connectivity probe every 3s, auto-reload when server recovers 2026-05-01 19:54:47 +00:00
manifest.json feature: add manifest and icons to enable app install on android 2026-05-02 19:06:39 +02:00
messages.js fix(sessions): sync URL after session id rotation (#1395) 2026-05-02 17:41:05 +00:00
onboarding.js fix(onboarding): allow keyless setup for self-hosted providers (#1499 third sub-bug) 2026-05-03 03:07:07 +00:00
panels.js fix(composer): distinct voice-mode icon, descriptive labels, opt-in pref (#1488) 2026-05-02 22:16:23 +00:00
sessions.js feat(sidebar): add "Unassigned" project-filter chip for sessions without a project 2026-05-03 07:08:08 +00:00
style.css feat(sidebar): add "Unassigned" project-filter chip for sessions without a project 2026-05-03 07:08:08 +00:00
sw.js fix(sw-cache): version style.css link so old SW cannot return stale CSS (#1507) 2026-05-03 06:09:47 +00:00
terminal.js fix: anchor active sessions per browser tab 2026-05-01 19:52:05 +08:00
ui.js fix: P0 bugfixes — tool-card args, sw.js path, CLI rename, scroll pinning 2026-05-02 23:39:52 +00:00
workspace.js fix: anchor active sessions per browser tab 2026-05-01 19:52:05 +08:00