Admin Settings IA stage A+B: card-targeted links and dependency announcements - #1304
Merged
Paul Lizer (paullizer) merged 2 commits intoAug 19, 2026
Conversation
Cross-references between Admin Settings tabs named a tab button directly, for
example switchTab(event, 'workspaces-tab'). That couples every link to a tab
id, so a rename or regroup breaks it silently: the button no longer exists, no
pane is activated, and the only symptom is a console warning and a URL hash
pointing at nothing.
Two of the twelve links were already broken this way. Citations referenced
Enable Video File Support and Enable Audio File Support with #workspaces, and
the prose said to see the Workspaces tab, but both settings live under Search
and Extract. Those links sent admins to the wrong tab entirely.
Links now declare the card they want with data-admin-link, and the owning tab
is resolved from the DOM at click time via closest('.tab-pane'). Cards can move
between tabs, and tabs can be renamed or regrouped, without touching a link.
The destination card is briefly highlighted so the jump is obvious.
This matters now because the information architecture rework renames and
regroups most tabs, which would have broken all twelve links at once.
switchTab had no callers left and is removed, so the coupling cannot be
reintroduced by copy-paste. The new test fails if a link points at a card that
does not exist, if the href fallback stops matching, or if the old pattern
returns.
Also sanitizes the User Agreement preview inline at the sink. It used the same
guarded-reassignment shape already corrected for the Home Page Text preview,
which reads as unsanitized to static analysis; admin_settings.html now passes a
full-file XSS scan rather than only a changed-lines scan.
Field names and card ids unchanged at 462 and 110, and the 75 functional test
files covering admin_settings.html show the same 33 pre-existing failures.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Several settings only take effect when a different setting is enabled, and the two often live in different tabs. That was communicated four different ways, none of them actionable: a static server-rendered alert, a sentence of prose, a tooltip, or a flash message only after saving. An admin could switch something on and have nothing happen with no visible reason, and no indication of where the prerequisite lived. A dependent card now declares what it needs with data-requires, and a shared module renders an inline notice with two ways to act: a mirror of the prerequisite switch, so it can be satisfied without leaving the tab, and a link to its card using the stage A resolver. The mirror deliberately carries no name attribute. Admin Settings posts one form read by field name, so a second named control would submit the value twice; the mirror drives the canonical input instead and exactly one named control per setting is ever submitted. File Sync warns rather than blocks, because the backend already accepts it as requested and reconciles once Redis is ready. Removing that would take away a deferred-intent path the backend supports on purpose. The Permissions dependency is scoped to the FeedbackAdmin toggle so the unrelated SafetyViolationAdmin toggle in the same card stays usable. Three candidate dependencies are deliberately not wired: backup source blobs are already gated in admin_data_management.js, multi-modal vision falls back to the legacy GPT deployment rather than requiring multi-endpoint, and the Redis Key Vault hint is conditional on a select value and already links correctly. The File Sync server alert is narrowed to the case the client cannot detect, Redis enabled but missing URL or credentials, so the two messages no longer overlap. Client-side gating is advisory. The backend still validates and flashes, and a test asserts that enforcement is still in place. Field names and card ids unchanged at 462 and 110, and the 75 functional test files covering admin_settings.html show the same 33 pre-existing failures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer)
merged commit Aug 19, 2026
0726aca
into
microsoft:feature/admin-settings-ia
11 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage A and B of the Admin Settings information architecture rework.
Why this comes before re-homing anything
Auditing the regroup surfaced a problem that had to be fixed first: cross-tab links are coupled to tab ids, so the regroup would break all twelve of them at once.
switchTablooks updocument.getElementById('workspaces-tab'). Rename or regroup that tab and the lookup returnsnull, no pane activates, and the only symptom is a console warning plus a URL hash pointing at nothing. Nothing fails loudly.Two links were already broken this way. Citations referenced Enable Video File Support and Enable Audio File Support with
#workspaces, and the prose said "see the Workspaces tab" — but both settings live under Search and Extract. Anyone following either link landed on the wrong tab.enable_video_file_supportvideo-intelligence-section(Search and Extract)enable_audio_file_supportai-voice-chat-section(Search and Extract)Stage A — links point at cards, not tabs
Links now name the card they want, and the owning tab is resolved from the DOM at click time:
Because the tab is derived rather than declared, cards can move between tabs and tabs can be renamed or regrouped without touching a single link. Card ids are the only contract — and the template split already proved those are stable, preserving all 110 byte-identically.
The destination card is briefly highlighted so it's obvious where you landed.
switchTabhad no callers left and is removed, so the old coupling can't be reintroduced by copy-paste.Stage B — settings announce what they need
Dependencies were previously communicated four different ways, none actionable:
flash()after savingflash()after savingA card now declares its prerequisite, and a shared module renders an inline notice with two ways to act — a mirror switch to satisfy it without leaving the tab, and a link straight to its card:
Three judgement calls worth reviewing
The mirror carries no
nameattribute. Admin Settings posts one form read by field name, so a second named control would submit the value twice. The mirror usesdata-dependency-proxy-forand drives the canonical input instead — exactly one named control per setting is ever submitted. A test enforces this.File Sync warns rather than blocks. The backend already accepts File Sync as requested and reconciles once Redis is ready (
requested_enable_file_syncvsfile_sync_effective_enabled). Hard-disabling would remove a deferred-intent path that exists on purpose. Everything else blocks.Permissions is scoped. That card holds both the SafetyViolationAdmin and FeedbackAdmin toggles, and only the latter depends on User Feedback. Blanket-disabling would switch off an unrelated control, so it declares
data-requires-scope="#require_member_of_feedback_admin". A test asserts this specific scoping, because getting it wrong is silent.Deliberately not wired
admin_data_management.jswith its own lock message. A second mechanism could disagree with the first.The backend stays authoritative
Client-side gating is a usability layer; a disabled input is a courtesy, never a control.
route_frontend_admin_settings.pystill validates and flashes, and a test asserts that enforcement is still present so the notice can't be mistaken for it.Also fixed
The User Agreement preview used the same guarded-reassignment shape already corrected for the Home Page Text preview, which reads as unsanitized to static analysis. Now sanitized inline at the sink —
admin_settings.htmlpasses a full-file XSS scan, not just a changed-lines scan.The File Sync server alert is narrowed to the case the client genuinely can't detect (Redis enabled but missing URL or credentials), so it no longer double-reports with the live notice.
Verification
admin_settings.html: 33 pre-existing failures before and after, identical setscheck_xss_sinks.pyandtest_xss_guardrails_checker.pypass locallytextContent, never string HTMLNew tests
test_admin_card_links.py— every link target exists, every href fallback matches, noswitchTabpattern returns, resolver is wired and derives the tab from the DOM.test_admin_settings_dependencies.py— every prerequisite and link target resolves, the mirror can't double-post, Permissions is correctly scoped, and backend enforcement is still in place.The first property in each is the one that matters: they fail the build if a card is renamed or removed without updating what points at it — precisely the failure mode that went unnoticed before.
Next
Stage C adds the group navigation level against the current 18 tabs, so grouping is proven before any card moves. Stage D re-homes cards one group per commit. Stage E splits
system-settings-sectionand builds the Access and Roles roster on this module's proxy handling.Docs:
docs/explanation/fixes/ADMIN_SETTINGS_CARD_TARGETED_LINKS_FIX.md,docs/explanation/features/ADMIN_SETTINGS_DEPENDENCY_ANNOUNCEMENTS.md. Version0.260.008.