Skip to content

Feature/survey block - #7582

Open
gmorador-tribu wants to merge 3 commits into
feature/survey-panelfrom
feature/survey-block
Open

gmorador-tribu wants to merge 3 commits into
feature/survey-panelfrom
feature/survey-block

Conversation

@gmorador-tribu

Copy link
Copy Markdown
Contributor

Part of hypothesis/product-backlog#1751. Stacked on #7581 (the survey panel); review that one first.

While the EDU role survey is pending, the rest of the sidebar is greyed out and can't be used until the question is answered or dismissed, and annotating on the page leads to the survey instead of creating an annotation.

Two commits, which are easier to review one at a time:

  1. Block the sidebar. inert and opacity-50 on <main>, and nothing else. Help, Search and Share (opened from the top bar) stay usable, and so do the toasts. The root's scroll is locked to keep the panel in place. PendingUpdatesNotification is hidden while the survey is up. Drafts are left alone rather than discarded.
  2. Turn annotating into a pointer to the survey. A new sidebar → guest RPC, setAnnotatingEnabled. While it's off, the adder, the toolbar and the keyboard shortcuts still show, but using them creates nothing: the guest reports annotatingBlocked, the sidebar opens if it was closed, and the survey panel takes focus and plays a short pulse. FrameSyncService's createAnnotation handler also refuses anything that gets through, using the branch it already has for logged-out users.

Why not simply hide the adder: someone who never opens the sidebar would never see the survey, but would find the client had stopped annotating for no visible reason.

While the survey is pending, grey out the sidebar's content and make it
unreachable, as the PM confirmed: the panel stays usable, and so does
everything the top bar opens.

`inert` on `<main>` and nothing else. It is the only option that also stops
Tab reaching the content -- `pointer-events-none` does nothing against the
keyboard, and managing `tabIndex` by hand across the editors, menus and links
inside would not stay correct between renders -- and it takes the subtree out
of the accessibility tree by itself, so no `aria-hidden` on top. Wrapping
`<main>` alone keeps Help, Search and Share, which are its siblings inside
`.container`, usable from the top bar, and keeps ToastMessages outside, so
the error toast from a failed answer can still be read and dismissed. The
browserslist targets all ship `inert`, and Preact sets it as a property, so
`inert={false}` really does un-inert the element.

The root's scroll is taken away while the panel is up, to keep it in place.
Help, Search and Share open below the panel and can be clipped on a short
sidebar, but each has its own close button, so nobody is stuck. The panel
caps its own height, so its buttons stay reachable with large fonts or a
narrow sidebar.

PendingUpdatesNotification is hidden meanwhile: it is `fixed top-12`, so it
would float over the panel's dismiss button, and applying real-time updates
to a list nobody can reach has nothing to offer.

Existing drafts are deliberately left alone rather than discarded the way
logout does: they stay frozen behind the panel and come back once the
question is answered.
With the sidebar blocked, an annotation made on the page has nowhere to go:
its draft would open inside the inert content. Instead of creating it, send
the user to the survey.

The sidebar pushes `setAnnotatingEnabled` to every guest frame -- on connect,
for frames that arrive later such as iframes or VitalSource chapters, and on
each change. While it is off the adder and the toolbar's buttons still show,
but every way of creating an annotation -- the adder, which calls
`createAnnotationFromSelection` directly, the toolbar and the keyboard
shortcuts, which go through `createAnnotation` -- drops the selection and
reports `annotatingBlocked` instead. The sidebar then opens, if it wasn't
already, and the survey panel takes focus and plays a short pulse.

The pulse is what makes this work with the sidebar already open, where
opening it would change nothing on screen and the click would look ignored.
It also settles what to do with the sidebar closed: someone who never opens
it keeps an adder that leads to the question, rather than a client that
seems to have stopped annotating for no visible reason. The store counts the
attempts and the panel reacts to each new one, re-keying its card so that a
click during the pulse starts it again.

The selection is otherwise left alone when annotating is turned off or back
on. Clearing it would have reached across frames -- the host answers
`textUnselected` by clearing the selection in every other guest -- and text
still selected when the survey is answered can be annotated straight away. The blocked path also clears
`_pendingKeyboardMode`, which keyboard callers set before calling
`createAnnotation` and only clear on rejection, so it can't leak into the
next annotation once annotating is back on.

As a backstop, FrameSyncService's `createAnnotation` handler refuses an
annotation that reaches it while the survey is pending, through the branch
it already has for a logged-out user: open the sidebar, delete the
annotation in its frame, and never create a draft.
@gmorador-tribu
gmorador-tribu added this pull request to stack #7583 September 24, 2026 19:06
@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.62%. Comparing base (a4fc7cb) to head (6cdda53).

Additional details and impacted files
@@                  Coverage Diff                  @@
##           feature/survey-panel    #7582   +/-   ##
=====================================================
  Coverage                 99.62%   99.62%           
=====================================================
  Files                       286      286           
  Lines                     12007    12056   +49     
  Branches                   2925     2932    +7     
=====================================================
+ Hits                      11962    12011   +49     
  Misses                       45       45           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant