Repository navigation
EDU role survey: the sidebar panel - #7581
Open
gmorador-tribu wants to merge 3 commits into
Open
gmorador-tribu wants to merge 3 commits into
gmorador-tribu wants to merge 3 commits into
Conversation
Add the two profile preferences the EDU role survey rides on, the predicate that reads them, the store selector, and the method that records an answer. Nothing renders yet; the panel lands next. The client is told *whether* to ask, never why. `show_instructor_survey` is true only while H considers the user part of the survey's audience and they haven't answered, and the whole audience rule -- the feature flag, the first-party authority, the educational email domain -- stays in H. That is what lets the audience change without a client release, which would otherwise have to propagate through the CDN and the browser extension before it took effect. `shouldShowInstructorSurvey` takes the effective feature flags rather than `SidebarSettings` so that FrameSyncService can call it unchanged when the sidebar-blocking work needs the same answer. `isInstructorSurveyPending` wraps it in the store as the single source of truth for both. `submitInstructorSurveyResponse` sends `instructor_survey_response` on its own, following the error handling of `dismissYoutubeDisclaimer` -- toast and rethrow -- rather than `dismissSidebarTutorial`, which silently swallows failures. One method covers all three answers, dismissal included: H records a dismissal like any other answer, and any of them stops the survey being shown. The PATCH deliberately carries only that one key, because H emits `show_instructor_survey` but does not accept it back, so echoing the whole preferences object would be rejected and take the answer down with it.
Ask the question. InstructorSurveyPanel renders above the sidebar's content with Yes, No and a dismiss "x", and HypothesisApp shows it whenever the store says the survey is pending and we are in the sidebar -- not the notebook, profile or stream. Shaped after YouTubeDisclaimerBanner, which is the closest end-to-end precedent in the repo: a full-bleed banner under the top bar, its state read from the profile, its answer written through the session service. The panel needs no "answered" state of its own, because the answer comes back in the profile and unmounts it. Both effects wait for the sidebar to have been opened. The sidebar iframe is created when the page loads and starts collapsed, so the panel mounts as soon as the profile arrives whether or not anyone will ever look at it: tracking the impression at mount would count every page load of a user who never opens the sidebar, and the PRD asks who *saw* the survey. Focusing at mount has the matching problem -- a no-op while the frame is hidden, and a theft of focus from whatever the reader was doing if it weren't. `hasSidebarOpened` is sticky, so each effect runs once, on the first open; SidebarView uses it the same way to hold off connecting the streamer. Focus moves to the panel the way SidebarPanel does it, but without `role="dialog"`: that would claim the top bar is inert, and it isn't. The three controls are disabled while an answer is in flight, and re-enabled afterwards whatever happened -- on success the panel is about to unmount, but if a response ever came back still reporting the survey as pending, leaving them disabled would strand the user with a banner whose dismiss button no longer works.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7581 +/- ##
=======================================
Coverage 99.62% 99.62%
=======================================
Files 285 286 +1
Lines 11971 12007 +36
Branches 2920 2925 +5
=======================================
+ Hits 11926 11962 +36
Misses 45 45 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Render the survey as a card inside the sidebar's `.container`, next to the Help, Search and Share panels, instead of a full-bleed banner under the top bar. With the tutorial open at the same time -- which is what a newly registered instructor gets -- the banner ran wider than the Help card below it, had no border, and its dismiss "x" was drawn at CloseButton's default size, bigger than the one on the Help panel. The outer section now takes SidebarPanel's shape (`mb-4`, rounded focus ring) and the content sits in a Card, so the two line up. The dismiss button uses the same size and colours as TabHeader's close button, which is what the Help and Share panels show.
gmorador-tribu
added this pull request to stack #7583
September 24, 2026 19:06
This branch has not been deployed
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.
First of the two client PRs for the EDU role survey (issue
hypothesis/product-backlog#1751). Adds the panel that asks the question and
records the answer. The sidebar-blocking behaviour is not here -- greying
the sidebar out, pinning the panel and switching the adder off are increment
B, in a PR stacked on this one.
Needs the H side first: hypothesis/h#10196 (migration), hypothesis/h#10198
(model) and the session PR above it. Safe to merge before them, and safe to
deploy: with
instructor_surveyoff, H never sendsshow_instructor_survey,the store selector stays false and nothing renders.
What's here
src/types/api.ts--InstructorSurveyResponseand the two profilepreference keys.
src/sidebar/helpers/session.ts--shouldShowInstructorSurvey().src/sidebar/store/modules/session.ts--isInstructorSurveyPending.src/sidebar/services/session.ts--submitInstructorSurveyResponse().src/sidebar/services/api.ts-- theclient.survey.instructor_role.shownanalytics event.
src/sidebar/components/InstructorSurveyPanel.tsx-- the panel.src/sidebar/components/HypothesisApp.tsx-- renders it in the sidebar.