Repository source: docs/plans/feature_flags_redesign/feature_flags_redesign_step2_feature_description.md
Step 2: Feature Description — Feature Flags Page Redesign
Problem
The /tools/feature-flags/ page's fixed-width table wraps flag keys mid-word and shows four always-visible columns per flag, which doesn't scale as the flag count grows and buries the handful of flags that actually need attention.
Scope note: search/filter (toolbar with search input and status-filter chips) is deferred to a follow-up feature — it splits cleanly since it only matters once the flag count grows, and doesn't affect this feature's layout, badges, grouping, or dependency work.
User Stories
As a site operator, I want flag keys and names to stay readable at any window width so I can scan the page without keys wrapping mid-word.
As a site operator, I want to see only what deviates from normal (overridden, locked, unmet dependency) so I don't have to parse every column of every row to find what matters.
As a site operator, I want to see when a flag is inactive because a flag it depends on is off, so I understand why toggling it had no visible effect.
As a site operator, I want to toggle a flag or reset it to default with one action and get immediate feedback, so I don't need a dropdown-plus-Save round trip.
Core Requirements
Grouped-list layout with a switch per flag; no mid-word wrapping of names or keys at any width or theme.
Remove the always-visible Effective/Default/Source/Mutable columns; show overridden/locked/dependency state only as badges when relevant.
Dependency awareness for known parent/child flag pairs, with a visible "inactive — requires …" state when the parent is off.
Preserve progressive enhancement (page works without JS) and existing
data-flag-key/data-role="feature-flag-*"hooks so current tests keep working or are updated in place, not replaced.
Shared Component Inventory
templates/pages/feature_flags.php— the only template rendering this data. Reused/extended in place, not replaced.public/assets/feature_flags.js— the only JS driving the save flow. Reused/extended in place (rewritten internally for switch semantics, same file and hooks).src/ForumRewrite/Support/FeatureFlags/{FeatureFlagRegistry,FeatureFlagDefinition,FeatureFlagEvaluator,FeatureFlagState}.php— existing backend data/evaluation layer. Extended: add a displaygroup/label, extendrequiresEnabledFlagto two more pairs. No new data layer./api/set_feature_flag(viaToolsPageController) — existing save endpoint and response format. Reused as-is, no new endpoint.Site-wide CSS tokens/components (
--status-*,--active-*,--ink-soft,.card,.meta,.nav-link) in the shared stylesheet. New switch/badge/chip styles are added to this same stylesheet, built from existing tokens — not a separate page-specific stylesheet.No other page or API currently renders feature-flag state (only this template, this JS file, and the flag tests reference the
data-feature-flag-*hooks), so there is no other canonical surface to consolidate with.
Simple User Flow
Operator opens
/tools/feature-flags/.Page shows a summary line (counts) and a grouped list of flags, each with a switch.
Operator clicks a switch to toggle a mutable flag; the row updates in place with inline save feedback.
For an overridden flag, operator can click "reset to default" to revert it.
For a locked or dependency-blocked flag, operator sees why via a badge/tooltip without needing to change anything.
Success Criteria
Flag names and keys never wrap mid-word between 375px and 1150px, checked in at least light, dark, and one alternate theme.
Page stays scannable with 50+ flags (verified with a temporary test fixture) via grouping alone (search/filter is deferred, see Scope note).
All existing feature-flag tests pass (updated selectors where needed); new tests cover override/lock/dependency rendering and the no-JS POST path.
No flag row shows always-visible metadata beyond name/description/key/switch; badges appear only when a flag deviates from default, is locked, or has an unmet dependency.