close
Skip to content

Board view: global session filters (Unread/Running/Pinned/Recent) have no visible effect #739

Description

@vidanov

Summary

In the board view (Trello-style tag-column layout), toggling the global session filters — Unread, In progress, Pinned, or Recent — from the sort/filter dropdown does not visually change which sessions are shown in the columns.

Steps to reproduce

  1. Create at least two tag columns (board view activates when orderedColumns.length > 0).
  2. Have a mix of sessions: some unread, some running, some pinned.
  3. Open the Filter dropdown (ListFilter icon, top-right of the sidebar search bar).
  4. Toggle any filter — e.g. Unread or Pinned.
  5. Expected: columns show only sessions matching the active filter.
  6. Actual: all sessions remain visible; the filter has no apparent effect.

Root cause analysis

The filter predicate lives in filteredSlots (ChatSidebar.tsx ~L1215):

const activeFilterDefs = SESSION_FILTERS.filter(filterDef => activeFilters.has(filterDef.key))
return enrichedSlots.filter(slot => {
  if (activeFilterDefs.length > 0 && !activeFilterDefs.some(filterDef => slot[filterDef.key])) return false
  ...
})

Board columns then derive their slot list from filteredSlots:

// ChatSidebar.tsx ~L2813
const colSlots = filteredSlots.filter(s => columnMatches(col, s.tags || []))

This chain is architecturally correct. The likely causes of the observed no-op are:

1. Column with tag_ids: [] matches all slots unconditionally

columnMatches (L1184) returns true immediately when a column has no tag filter configured:

if (!col.tag_ids || col.tag_ids.length === 0) return true

A new or unconfigured column ignores all global filters because it passes every slot through. Users who have columns without tag filters will see all sessions regardless of global filter state.

2. Silent tag-ID drop in _normalize_column (backend)

When updating a column via PATCH, the backend validates tag_ids against current known tag IDs:

# chat_tags.py L183
cleaned["tag_ids"] = [str(t) for t in tag_ids if isinstance(t, str) and t in valid_ids]

Any ID not present in state._tags is silently dropped. If tags are deleted while a column still references them, the column's filter rules become empty ([]), making it show all sessions again — with no feedback to the user.

Suggested fixes

Frontend: surface "no filter configured" state on a column

When col.tag_ids.length === 0 and !col.include_untagged, show a visual cue in the column header (e.g. a dimmed "All sessions" label) so users know that column is unfiltered and global filters won't narrow it further.

Backend: warn on dropped tag IDs

In _normalize_column, detect when tag IDs were provided but all dropped (unknown IDs), and either return a 400 or include a warnings field in the response so the client can surface it.

Consideration: should global filters apply even to columns with tag_ids: []?

An open design question: should a global "Pinned" filter hide non-pinned sessions even in an "All sessions" column? Currently filteredSlots applies before columnMatches, so global filters DO reduce the set passed to every column. If the filter appears not to work, the column itself may be the issue (see point 1 above).

Environment

  • KiroCrew version: 0.1.0-insider.3 (also reproduced on 0.1.0.dev20260728)
  • Tested in: dashboard board view with 2+ tag columns

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: dashboardDashboard UI and its backend handlersbugSomething is not workingneeds-investigationTriage: requires deep analysis before a fix

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions