* [web] open a comment from a URL
* [web] add "View comment" button to digest email
* [web] open a tracked change from a URL
* [web] add "View suggestion" button to digest email
* [web] open the review panel from an open=review-panel URL
* [web] drop the digest email CTA and collapse the deep links to t=review
* [web] add an Open project button to the section overflow row and plain-text view links
* [web] validate the comment and change deep-link ids as object ids
* [web] collapse the deep-link resolvers into a single DeepLink component
* fix: scrolling into view when below the fold
* fix: address claude review
* fix: style adjustments
* fix: updating types to accomodate accepted/rejected changes
---------
Co-authored-by: Jimmy Domagala-Tang <jimmy.domagala-tang@overleaf.com>
GitOrigin-RevId: dab535591a93e1c3849a6b2a0dcc3e3934354385
* [security] bump cypress 15.12.0 -> 15.20.1 to drop unpatched extract-zip
extract-zip <=2.0.1 has no patched release (GHSA-jmr9-qjv8-65gv). It was a
transitive dependency of cypress, used only to unpack Cypress's own binary.
Cypress 15.20.1 replaces extract-zip with yauzl directly, so upgrading the
parent removes the vulnerable package entirely.
Also bumps the pinned cypress/included Docker base image used by
test_frontend_ct / server-ce e2e / saas-e2e.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* [security] fix cy.get<T> alias typing broken by cypress 15.20.1
Cypress 15.20.1 adds a dedicated Chainable.get overload for alias strings
(get<S>(alias: `@${string}`): Chainable<S>), which now takes priority over
the generic selector overload. cy.get<HTMLInputElement>('@input') therefore
resolved to Chainable<HTMLInputElement> instead of
Chainable<JQuery<HTMLInputElement>>, so .then(element => element.get(0))
no longer type-checked. Pass the JQuery-wrapped type explicitly to match
the new overload.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
GitOrigin-RevId: f4a56a2d5948b5aaf00a07ecb384fc75abf6de53
* load affiliations data when rendering library page
* address Copilot review feedback on PR #36522
- default userAffiliations to [] if getUserFullEmails fails, matching
ProjectListController's error handling, so Library/Trash still render
when the institutions service is unavailable
- stop mutating the affiliation object when attaching the email
- rename a misleading test title (affiliation is not necessarily confirmed)
- fix sidebar-ds-nav "hides the widget" tests: they were only waiting for
the /api/project fetch to be called, not for the project list state to
settle, so they passed even before the affiliations check ran
GitOrigin-RevId: 7d04ae7f7dc8d1526c2deb8959099f6e9fe9c4ee
* [web] Remove SubscriptionFormatters, format subscription dates in the frontend
Replace the server-formatted nextPaymentDueAt/nextPaymentDueDate/
trialEndsAtFormatted fields with the raw periodEnd date and format in
the React dashboard (same strings as before, English + UTC). Also
consolidate hand-rolled trial checks onto isInFreeTrial /
SubscriptionHelper.isInTrial.
* [web] Remove the now-unused dateformat dependency
* [web] Address review: payment-dates unit test, UTC dates in acceptance test
Add a dedicated unit test asserting the exact formatted strings from
formatPaymentDate/formatPaymentDateTime, and use explicit UTC timestamps
in the SubscriptionDashboard acceptance fixtures instead of
local-timezone Date constructors.
GitOrigin-RevId: 16ac4f1098b14ef9f1478d22cf39c1357ead7dea
* [web] Add cancel-loss-messaging split test
Populate the cancel confirmation step with plan-specific losses when the
cancel-loss-messaging split test is enabled: "Are you sure you want to
cancel?" heading, the subscription end date, and a card listing what the
user loses moving to the Free plan (compile timeout, AI, collaborators,
history), with the lost benefit struck through next to its Free-plan
replacement.
Shown only to non-trial Student/Standard/Pro individual subscribers with
no other retention offer (trial extension or downgrade upsell) — those
keep the existing confirmation.
Copy matches the mockups in the ticket. No new analytics events; the
existing subscription-page-cancel-button-click / subscription-cancelled
funnel is used.
Part of #35765
* [web] Consolidate ActiveSubscription stories, add cancel confirmation story
Replace the 13 fixture-per-story exports with a single Dashboard story
driven by controls (subscription fixture select, flexible licensing,
cancel-loss-messaging variant), using the CSF factories pattern. Add a
CancelConfirmation story that renders the cancel confirmation step
directly so the cancel-loss-messaging variant can be previewed without
clicking through, with a Professional fixture available to see the Pro
loss rows.
* [web] Use withSplitTests for the ActiveSubscription stories
Register cancel-loss-messaging in defaultSplitTestsArgTypes and drive the
stories' variant from the shared withSplitTests decorator (radio control,
SplitTestContext provided from args) instead of hand-rolled meta tags and
SplitTestProvider. Generalize withSplitTests' typing so it composes with
CSF factories (preview.meta) as well as legacy meta objects.
* [web] Fix Storybook indexing of the ActiveSubscription stories
Storybook's static CSF indexer requires preview.meta() to receive an
object literal, so spread withSplitTests' argTypes/decorators into the
meta literal instead of wrapping the whole config in the helper call.
* [web] Compose ActiveSubscription stories from orthogonal controls
- Wrap the stories in #subscription-dashboard-root so the dashboard's
scoped styles (e.g. the cancel-loss strikethrough) apply in Storybook
- Replace the single fixture dropdown with independent controls (group,
plan, period, currency, trial, status, pending plan change, add-ons,
coupons, pending license change), building the subscription from the
fixtures' base + patches
- Guard impossible mixes with argTypes `if` conditions: individual-only
controls hide when group is on, and pendingLicenseChange only shows
for groups
* [web] Add student plan to the ActiveSubscription story controls
The cancel-loss-messaging variant has student-specific rows (AI
Assistant / 10 collaborators), so the plan control needs a student
option. Groups have no student plans, so for group subscriptions the
student choice maps to the Standard group fixture.
* [web] Provide ol-plans in the ActiveSubscription stories
The cancel confirmation's downgrade branch (monthly Standard is
isEligibleForDowngradeUpsell) looks up paid-personal in ol-plans and
spins forever when the meta tag is missing. Provide ol-plans and
ol-groupPlans from the fixtures, matching the test render helper.
GitOrigin-RevId: e8491c8d39ed059e42ea3442e8d70c3ef304b009
* [editor-core] gracefully handle no-op TextOperation
* [web] avoid sending sync to pdf requests without a ?file
* [validation-tools] log deeper nested violations
* [editor-core] fix round trip of EditNoOperation
* [web] use custom error for sync to pdf w/o file, fix tests
* [validation-tools] include request params in log msg for violation
* Revert "[editor-core] gracefully handle no-op TextOperation"
This reverts commit c1d37261d5db72b37dbf39428c54edcfb5423f41.
* [web] gracefully handle rejected sync to pdf from context menu
GitOrigin-RevId: 21de7dc96b23575b0d67b6eb0c68ed9c2f86292b
* Simplify the new project dropdown
* Simplify the New project dropdown
* removing artefact of rebase
GitOrigin-RevId: e7e4dc48c10f2297abcd7c5b489ff2308bf9e18b
* feat: transitioning optimized images from a compile mode to a project level toggle. We still persist it for the proect and between users, and ensure that draft mode does not interact with it (silently disabled while draft mode is on)
* feat: cleaning up unused var, tests, and locales
* feat: updating copy
GitOrigin-RevId: 8010edfab164980f14125739e481d8b512f6b3df
* [web] Read subscription.features on Group Management rendering
Fixes 'ai-toggling' not properly read on Group Management rendering, causing the Feature Controls option not being displayed in certain scenarios.
GitOrigin-RevId: 4465fea15279d650d9d231e85072f1d85f2358be