Store sidebar navigation mode as a user preference
What does this MR do and why?
Stores the tailored sidebar navigation mode (compact / all_categories) as a user preference in the database, so the choice follows the user across browsers and devices. Today it lives only in localStorage (added in !253007 (merged)).
This is the backend half of a two-MR stack. The frontend MR (!262884) is stacked on this branch and has to deploy after it.
- Adds
user_preferences.sidebar_navigation_mode(smallint, default0=compact,NOT NULL). - Adds the
UserPreference#sidebar_navigation_modeenum (prefix: true) and delegates it fromUser. - Exposes it in GraphQL as the
SidebarNavigationModeenum, a field onUserPreferences, and an argument onuserPreferencesUpdate. Both are markedexperimentfor 19.6. An explicitnullis ignored, like the other non-nullable preferences. - Includes
sidebar_navigation_modein the logged-in super sidebar payload (SidebarsHelper#super_sidebar_logged_in_context). Logged-out users don't get the key.
The control is only shown while the hide_unpinned_sidebar_items (gitlab_com_derisk) flag is enabled.
For engineering reviewers: please confirm that userPreferencesUpdate (GraphQL) is the right write path, rather than a REST action next to Users::PinsController.
Why a dedicated column instead of JSONB
No more sidebar preferences are planned right now. A typed enum column is validated by Rails and GraphQL without needing a JSON schema, and adding another column later is cheap.
Note on db/structure.sql
The author's local database had drifted from master, so a regenerated dump picked up unrelated changes. db/structure.sql was edited by hand to add just the one column line, in the position and format Rails dumps it. The migration was checked up and down on main, ci, and sec.
References
- #630926
- !262884 (frontend, stacked on this MR)
- !253007 (merged) (original discussion)
Screenshots or screen recordings
Not applicable: backend only, no UI change.
How to set up and validate locally
- Run
bin/rails db:migrate. - In GraphiQL (
/-/graphql-explorer), run:You should getmutation { userPreferencesUpdate(input: { sidebarNavigationMode: ALL_CATEGORIES }) { errors userPreferences { sidebarNavigationMode } } }ALL_CATEGORIESback. - In the Rails console,
User.find_by(username: 'root').sidebar_navigation_modeshould return"all_categories".
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.