Skip to content

Server search/filter, coloured tag pills, and tag-tree grouping across all three surfaces #2008

Description

@jakemorgangit

Hi Erik — a feature proposal for finding and organising servers as the monitored list grows. Flagging up front what already exists so this is framed as extend + bring to parity, not reinvent.

What's there today

  • Viewer already has hierarchical server tags (config.server_tags with parent_id / sort_order, many-to-many via server_tag_map), and renders them as a collapsible tag tree in the sidebar (servers nested under tag headers). Nice foundation.
  • Tags have no colour (no colour column), are not shown as pills, and don't appear on the Overview cards.
  • Lite and the web viewer have no tag concept at all — no tree, no grouping.
  • Search / filter by server name (or tag) does not exist on any surface — the Viewer's FleetView even reserves a seam for it, but it's unbuilt. Lite's Overview and the web fleet page have a sort control only.

A bug I hit while auditing this: tag editing silently fails for the viewer role

The "Assign Tags" submenu (and create/rename/delete) appears to do nothing on a managed store. The wiring is fine — AssignTag_Click calls AssignServerTagAsync and reloads — but every tag write routes through ExecuteWriteAsync, and the viewer role has no write grant on config.server_tags / config.server_tag_map (neither provision-roles.sql nor DarlingManagedRoles grants them — custom_views got its viewer write grant, the tag tables were missed). So on a store where the Viewer connects as the least-privilege viewer role, the INSERT hits 42501, ExecuteWriteAsync degrades it to ViewerReadOnlyException, and the click's catch logs "Assign/unassign failed" and shows nothing. Net effect: tags are effectively read-only from the Viewer on any provisioned store.

Happy to send this as a tiny standalone fix (add the viewer INSERT/UPDATE/DELETE grants on the two tag tables, mirroring the custom_views grant) ahead of the feature below, if you'd prefer to decouple it.

The gap

On a large fleet you can't quickly find a server, and — even where tags exist (the Viewer) — they're editable only in theory, invisible except as sidebar grouping, and absent from Lite and the web entirely. DEV/PROD/TEST/etc. live only in people's heads or server names.

Proposal (suggested as two stages)

Stage 1 — search/filter (self-contained, high value). A search box on the servers list and the overview/dashboard, on all three surfaces, filtering by server name (and by tag where tags exist). In the Viewer it slots into the FleetView.Rebuild seam already reserved for it. No schema change; ships independently.

Stage 2 — finish + spread tags.

  • Fix the viewer-role grant gap above so tag editing actually persists.
  • Add a colour to the tag model — a nullable colour column, auto-assigned from a rotating palette on tag creation and user-overridable — and render a server's tags as distinct coloured pills on the server cards / overview.
  • Bring tags to Lite and the web viewer: a tag model mirroring Darling's hierarchical many-to-many shape (cross-surface parity), the Viewer's sidebar tag-tree grouping brought over as opt-in drill-down (SSMS Object-Explorer style), and pills.

Search then narrows within the tree; pills annotate each card.

Per-surface scope

  • Viewer: add a colour column to config.server_tags (migration) + a colour picker in the tag UI; render tags as pills on the Overview cards (today they only group the sidebar tree); add the search box at the Rebuild seam.
  • Lite: greenfield — a tag model (DuckDB tables mirroring Darling's shape for parity), a manage-tags UI, tree grouping + pills on the Overview, and the search box next to the existing sort control.
  • Web: /api/fleet gains tag data (it emits none today); the fleet page gains a search input, tag pills on the cards, and tree/group rendering.

Open questions

  1. Stage it as above, or one PR? And would you want the viewer-grant fix as its own tiny standalone PR first (it's a real bug independent of the feature)?
  2. Colour — a nullable column on config.server_tags, auto-assigned + user-overridable as I've proposed? Any palette/convention to match, or a preferred storage shape?
  3. Lite tag model — mirror Darling's hierarchical many-to-many shape for parity (my assumption), or keep Lite simpler?
  4. Web tags — read-only on the web with assignment staying in the desktop apps (my assumption), or editable there too?

Happy to shape any of it to fit the project's direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions