Skip to content

Dashboard: add On this day and Achievements toggles to Notifications Extras - #112442

Merged
alshakero merged 2 commits into
trunkfrom
update/dashboard-notifications-extras-toggles
Jul 8, 2026
Merged

Dashboard: add On this day and Achievements toggles to Notifications Extras#112442
alshakero merged 2 commits into
trunkfrom
update/dashboard-notifications-extras-toggles

Conversation

@alshakero

@alshakero alshakero commented Jul 8, 2026

Copy link
Copy Markdown
Member

Fixes phcsdm-PD-p2#comment-5237

Proposed Changes

  • Add an "On this day" toggle card to the Dashboard's Notifications → Extras screen, wired to the other.timeline.on_this_day field of the /me/notifications/settings endpoint (the same field the classic notification settings page saves).
  • Add an "Achievements" toggle card wired to the achievements-global-notifications user preference via userPreferenceQuery / userPreferenceOptimisticMutation (same storage as the classic page, so the two UIs stay in sync).
  • Both cards render in their own groups at the top of the Extras screen, before the "Email from WordPress.com" group. Labels and help text are copied verbatim from the classic UI, so no new translatable strings are introduced.
  • Saving shows the standard snackbar notices and records Tracks events (calypso_dashboard_notifications_timeline_settings_updated with setting_name: 'on_this_day', and calypso_dashboard_notifications_achievements_settings_updated).
  • Extend the Extras screen unit tests: four new tests covering rendering, saving each toggle, and the disabled-preference state, plus a /me/preferences mock for existing tests since the Achievements card now suspends on that endpoint.

Why are these changes being made?

  • The "On this day" and "Achievements" notification toggles currently only exist in the classic notification settings page. The new Dashboard's notification settings had no equivalent, so users managing notifications there couldn't control these two settings. This folds them into the Extras screen.

Testing Instructions

  • Run yarn test-client client/dashboard/me/notifications-extras.
  • Start the dashboard with yarn start-dashboard and go to Notifications → Extras.
  • Verify the "On this day" and "Achievements" cards appear above the "Email from WordPress.com" group.
  • Toggle each one: a "<name>" settings saved. snackbar should appear, and the state should match the corresponding toggles in the classic notification settings page after a reload of either page.

Pre-merge Checklist

  • Has the general commit checklist been followed? (PCYsg-hS-p2)
  • Have you written new tests for your changes?
  • Have you tested the feature in Simple (P9HQHe-k8-p2), Atomic (P9HQHe-jW-p2), and self-hosted Jetpack sites (PCYsg-g6b-p2)?
  • Have you checked for TypeScript, React or other console errors?
  • For UI changes, have you tested the affected components in dark mode?
  • Have you tested accessibility for your changes? Ensure the feature remains usable with various user agents (e.g., browsers), interfaces (e.g., keyboard navigation), and assistive technologies (e.g., screen readers) (PCYsg-S3g-p2).
  • Have you used memoizing on expensive computations? More info in Memoizing with create-selector and Using memoizing selectors and Our Approach to Data
  • Have we added the "[Status] String Freeze" label as soon as any new strings were ready for translation (p4TIVU-5Jq-p2)?
    • For UI changes, have we tested the change in various languages (for example, ES, PT, FR, or DE)? The length of text and words vary significantly between languages.
  • For changes affecting Jetpack: Have we added the "[Status] Needs Privacy Updates" label if this pull request changes what data or activity we track or use (p4TIVU-aUh-p2)?

@alshakero
alshakero marked this pull request as ready for review July 8, 2026 20:58
@alshakero
alshakero requested a review from a team as a code owner July 8, 2026 20:58
@matticbot matticbot added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Jul 8, 2026
@alshakero
alshakero force-pushed the update/dashboard-notifications-extras-toggles branch from e7e6a8f to f0120fe Compare July 8, 2026 20:59
Comment on lines +39 to +41
} );
},
} );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fix here] Issue: Error snackbar doesn't follow the project's "Failed to…" convention and is inconsistent with the existing error message in index.tsx line 85 ('Failed to save subscription settings.').

Error message should be helpful where possible, although it is not always possible. The message should begin with "Failed":
Failed to save {setting name}.

typography-and-copy.md

Suggestion:

Suggested change
} );
},
} );
createErrorNotice(
sprintf(
/* translators: %s is the name of the setting */ __( 'Failed to save %s settings.' ),
__( 'Achievements' )
),
{ type: 'snackbar' }
);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 9b5d579 — error notice now uses the Failed to save %s settings. pattern.

Comment on lines +47 to +49
},
}
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fix here] Issue: Same as achievements-card — error snackbar should begin with "Failed" per the project convention and to stay consistent with the existing error in this screen.

Error message should be helpful where possible, although it is not always possible. The message should begin with "Failed":
Failed to save {setting name}.

typography-and-copy.md

Suggestion:

Suggested change
},
}
);
createErrorNotice(
sprintf(
/* translators: %s is the name of the setting */ __( 'Failed to save %s settings.' ),
__( 'On this day' )
),
{ type: 'snackbar' }
);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 9b5d579 — error notice now uses the Failed to save %s settings. pattern.

Comment on lines +14 to +16
const { data: notifications } = useSuspenseQuery(
userPreferenceQuery( 'achievements-global-notifications' )
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fix here] Issue: useSuspenseQuery will suspend this component, but the route loader at app/router/me.tsx:1013 only prefetches userNotificationsSettingsQuery(). Because userPreferenceQuery isn't prefetched, there'll be a waterfall: the notification settings query resolves first, the component tree starts rendering, then this card suspends a second time to fetch preferences.

Data is prefetched through route loaders where possible

data-library.md

A good strategy is to use a router's loader function to fetch just enough data to allow a component's layout to be rendered definitively.

ui-components.md

Suggestion: Add rawUserPreferencesQuery() (or userPreferenceQuery('achievements-global-notifications')) to the route loader so both fetches run in parallel:

loader: async () => {
  await Promise.all( [
    queryClient.ensureQueryData( userNotificationsSettingsQuery() ),
    queryClient.ensureQueryData( rawUserPreferencesQuery() ),
  ] );
},

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 9b5d579 — the Extras route loader now prefetches rawUserPreferencesQuery() in parallel with the notification settings query, so the Achievements card no longer causes a second suspense round-trip.

@alshakero

Copy link
Copy Markdown
Member Author

@Automattic/lego please feel free to review! I'll address in a follow up.

@alshakero
alshakero enabled auto-merge July 8, 2026 21:18
@alshakero
alshakero added this pull request to the merge queue Jul 8, 2026
Merged via the queue into trunk with commit 4f612e9 Jul 8, 2026
26 checks passed
@alshakero
alshakero deleted the update/dashboard-notifications-extras-toggles branch July 8, 2026 21:30
@github-actions github-actions Bot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Jul 8, 2026
@a8ci18n

a8ci18n commented Jul 8, 2026

Copy link
Copy Markdown

This Pull Request is now available for translation here: https://translate.wordpress.com/deliverables/34249462

Some locales (Hebrew) have been temporarily machine-translated due to translator availability. All other translations are usually ready within a few days. Untranslated and machine-translated strings will be sent for translation next Monday and are expected to be completed by the following Friday.

Hi @alshakero, could you please edit the description of this PR and add a screenshot for our translators? Ideally it'd include this string: Failed to save %s settings.

Thank you in advance!

checked={ !! data.other.timeline.on_this_day }
disabled={ isMutating }
label={ __( 'On this day' ) }
help={ __( 'Reminders about your posts from past years' ) }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should have a "." at the end.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, these are notifications in the Notification panel correct? The "Achievements" section makes that explicit: "Receive notifications when you unlock new achievements.". Should we be explicit for this one as well?

I guess it's confusing because we have "Extras" in the notifications section but then the section below is "Email from WordPress.com". I wonder why that section isn't in the me/notifications/emails section... Unrelated to this PR. I'll open an issue for that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frankly, I copied this as-is from /me/notifications just to fix the bug. @Copons probably understands this better.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should have a "." at the end.

Fixed in #112464

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alshakero I think Steven was recommending to make the OTD copy more explicit. Something like this:

- Reminders about your posts from past years.
+ Receive notification reminders about your posts from past years.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh, my bad. I'll take a nap and check this out. Apparently I'm not functioning well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My fault for rambling! Thanks for the updates!

disabled={ isPending }
label={ __( 'Achievements' ) }
help={ __(
'Receive notifications when you unlock new achievements. This setting overrides site-level settings.'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This setting overrides site-level settings"? I don't quite understand this. I have site-level Achievements settings?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @Copons.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have site-level Achievements settings?

@StevenDufresne yep!

In MSD, they have been moved to /me/notifications/sites. Just open a site and...

Screenshot 2026-07-09 at 11 22 59

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it, when the global setting was originally introduced, it contained a link to /me/notifications:

https://github.com/Automattic/wp-calypso/pull/110110/changes#diff-9380b2a481cfab3dc49408e68c0b1b708fdd71519c3e3dc1a1d691e1e2d00ad7R149-R156

The link was dropped when the setting was moved out of the Achievements screen and into /me/notifications.

Now that we have separate Notifications -> Sites and -> Extras screens, it would make sense to restore the link. I'll look into it. 🙂

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Likely pedantic, but site-level threw me off a bit. That felt like something in wp-admin. Maybe it's just the way I think about levels.

Maybe it's easier to read as:

Receive notifications for new achievements. Site-specific achievement notification settings will be ignored.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not pedantic at all! This was an RSM project, and we certainly didn't focus on a label copy. 😅

I don't know if "ignore" is correct.
Disabling achievement notifications globally certainly ignores any enabled site-specific notifications, but the opposite is not true. You can keep notifications on globally and disable them per-site.

The problem is that achievements can be about a specific site, but also about the user in general. "Old" achievements were most/all about a specific site, but those we introduced are largely about the user. Hence the reason for adding a global disable.

@matticbot

matticbot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

App Entrypoints (~0 bytes added 📈 [gzipped])

Details
name                    parsed_size           gzip_size
entry-dashboard-dotcom        +48 B  (+0.0%)       +0 B
entry-dashboard-ciab          +48 B  (+0.0%)       +0 B
entry-dashboard-a4a           +48 B  (+0.0%)       +0 B

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.

Sections (~2 bytes added 📈 [gzipped])

Details
name                parsed_size           gzip_size
staging-site              +48 B  (+0.0%)       +2 B  (+0.0%)
sites-dashboard           +48 B  (+0.0%)       +2 B  (+0.0%)
site-settings             +48 B  (+0.0%)       +2 B  (+0.0%)
site-performance          +48 B  (+0.0%)       +2 B  (+0.0%)
site-monitoring           +48 B  (+0.0%)       +2 B  (+0.0%)
site-logs                 +48 B  (+0.0%)       +2 B  (+0.0%)
plans                     +48 B  (+0.0%)       +2 B  (+0.0%)
overview                  +48 B  (+0.0%)       +2 B  (+0.0%)
hosting                   +48 B  (+0.0%)       +2 B  (+0.0%)
github-deployments        +48 B  (+0.0%)       +2 B  (+0.0%)
domains                   +48 B  (+0.0%)       +2 B  (+0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Async-loaded Components (~2 bytes added 📈 [gzipped])

Details
name                                                                   parsed_size           gzip_size
async-load-calypso-my-sites-customer-home-celebrate-site-launch-modal        +48 B  (+0.0%)       +2 B  (+0.0%)

React components that are loaded lazily, when a certain part of UI is displayed for the first time.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

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.

5 participants