settings/SU-4: extract ScopeChips primitive; reuse across all scoped pages #835

Closed
opened 2026-05-04 20:03:17 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As a developer, I want one ScopeChips primitive used by every settings page that has scope (Service, Agent types, Labels, Per-agent secrets), so that the scope-switch UX is identical and chip styling lives in one place.

Context

ScopeChips is duplicated:

  • apps/web/src/routes/settings.service.tsx:50-89 — Builtin / Global.
  • apps/web/src/routes/settings.agent-types.tsx:70-108 — Builtin / Global / Agent type / Instance.

Labels (settings.labels.tsx) and the AES Secrets store could also benefit but currently have ad-hoc tab-style pickers.

Acceptance criteria

Primitive

  • New file apps/web/src/components/settings-scope-chips.tsx exports ScopeChips.
  • Props: scopes: string[], active: string, available: Set<string>, onSelect, readOnly?: Set<string>, labels?: Record<string,string>.
  • Visual parity with current implementations (active = accent fill, exists+inactive = surface-high, missing = dashed border + + glyph, readOnly = disabled).
  • Lives in fixed slot — under page title / above section content.

Migration

  • settings.service.tsx imports the primitive; deletes its local copy.
  • settings.agent-types.tsx imports the primitive; deletes its local copy.
  • No regressions on either page (test snapshots pass).

Tests

  • Unit test covering: active styling, missing-scope dashed style, read-only disabled, label override.

Out of scope

  • Adding scope chips to Labels or AES Secrets — separate follow-up if/when scope support lands there.

References

  • apps/web/src/routes/settings.service.tsx:50-89
  • apps/web/src/routes/settings.agent-types.tsx:70-108
  • apps/web/CLAUDE.md border-radius + shadow conventions.
## User story As a developer, I want one `ScopeChips` primitive used by every settings page that has scope (Service, Agent types, Labels, Per-agent secrets), so that the scope-switch UX is identical and chip styling lives in one place. ## Context `ScopeChips` is duplicated: - `apps/web/src/routes/settings.service.tsx:50-89` — Builtin / Global. - `apps/web/src/routes/settings.agent-types.tsx:70-108` — Builtin / Global / Agent type / Instance. Labels (`settings.labels.tsx`) and the AES Secrets store could also benefit but currently have ad-hoc tab-style pickers. ## Acceptance criteria ### Primitive - [ ] New file `apps/web/src/components/settings-scope-chips.tsx` exports `ScopeChips`. - [ ] Props: `scopes: string[]`, `active: string`, `available: Set<string>`, `onSelect`, `readOnly?: Set<string>`, `labels?: Record<string,string>`. - [ ] Visual parity with current implementations (active = accent fill, exists+inactive = surface-high, missing = dashed border + `+` glyph, readOnly = disabled). - [ ] Lives in fixed slot — under page title / above section content. ### Migration - [ ] `settings.service.tsx` imports the primitive; deletes its local copy. - [ ] `settings.agent-types.tsx` imports the primitive; deletes its local copy. - [ ] No regressions on either page (test snapshots pass). ### Tests - [ ] Unit test covering: active styling, missing-scope dashed style, read-only disabled, label override. ## Out of scope - Adding scope chips to Labels or AES Secrets — separate follow-up if/when scope support lands there. ## References - `apps/web/src/routes/settings.service.tsx:50-89` - `apps/web/src/routes/settings.agent-types.tsx:70-108` - `apps/web/CLAUDE.md` border-radius + shadow conventions.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#835
No description provided.