Skip to content

Commit

Permalink
Merge pull request #9938 from google/enhancement/9889-refactor-rrm-se…
Browse files Browse the repository at this point in the history
…tup-cta-banner
  • Loading branch information
aaemnnosttv authored Jan 10, 2025
2 parents cee0e15 + c2172ee commit 414f6b5
Show file tree
Hide file tree
Showing 14 changed files with 589 additions and 449 deletions.
10 changes: 0 additions & 10 deletions assets/js/components/DashboardMainApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
AudienceSegmentationSetupCTAWidget,
AudienceSelectionPanel,
} from '../modules/analytics-4/components/audience-segmentation/dashboard';
import ReaderRevenueManagerSetupCTABanner from '../modules/reader-revenue-manager/components/dashboard/ReaderRevenueManagerSetupCTABanner';
import EntitySearchInput from './EntitySearchInput';
import DateRangeSelector from './DateRangeSelector';
import HelpMenu from './help/HelpMenu';
Expand Down Expand Up @@ -88,7 +87,6 @@ import {

export default function DashboardMainApp() {
const audienceSegmentationEnabled = useFeature( 'audienceSegmentation' );
const readerRevenueManagerEnabled = useFeature( 'rrmModule' );

const [ showSurveyPortal, setShowSurveyPortal ] = useState( false );

Expand Down Expand Up @@ -276,14 +274,6 @@ export default function DashboardMainApp() {
</Fragment>
) }

{ ! viewOnlyDashboard && (
<Fragment>
{ readerRevenueManagerEnabled && (
<ReaderRevenueManagerSetupCTABanner />
) }
</Fragment>
) }

<Notifications
areaSlug={ NOTIFICATION_AREAS.BANNERS_BELOW_NAV }
groupID={ NOTIFICATION_GROUPS.SETUP_CTAS }
Expand Down
15 changes: 4 additions & 11 deletions assets/js/components/notifications/FirstPartyModeSetupBanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,9 @@ export default function FirstPartyModeSetupBanner( { id, Notification } ) {
return null;
}

const getBannerSVG = () => {
if ( breakpoint === BREAKPOINT_SMALL ) {
return FPMSetupCTASVGMobile;
}

if ( breakpoint === BREAKPOINT_TABLET ) {
return FPMSetupCTASVGTablet;
}

return FPMSetupCTASVGDesktop;
const breakpointSVGMap = {
[ BREAKPOINT_SMALL ]: FPMSetupCTASVGMobile,
[ BREAKPOINT_TABLET ]: FPMSetupCTASVGTablet,
};

return (
Expand Down Expand Up @@ -201,7 +194,7 @@ export default function FirstPartyModeSetupBanner( { id, Notification } ) {
} }
/>
}
SVG={ getBannerSVG() }
SVG={ breakpointSVGMap[ breakpoint ] || FPMSetupCTASVGDesktop }
/>
</Notification>
);
Expand Down
80 changes: 76 additions & 4 deletions assets/js/googlesitekit/notifications/datastore/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ export const actions = {
* @param {WPComponent} [settings.Component] React component used to display the contents of this notification.
* @param {number} [settings.priority] Notification's priority for ordering (lower number is higher priority, like WordPress hooks). Ideally in increments of 10. Default 10.
* @param {string} [settings.areaSlug] The slug of the area where the notification should be rendered, e.g. notification-area-banners-above-nav.
* @param {string} [settings.groupID] The ID of the group of notifications that should be rendered in their own individual queue.
* @param {string} [settings.groupID] Optional. The ID of the group of notifications that should be rendered in their own individual queue. Default 'default'.
* @param {Array.<string>} [settings.viewContexts] Array of Site Kit contexts, e.g. VIEW_CONTEXT_MAIN_DASHBOARD.
* @param {Function} [settings.checkRequirements] Optional. Callback function to determine if the notification should be queued.
* @param {boolean} [settings.isDismissible] Flag to check if the notification should be queued and is not dismissed.
* @param {boolean} [settings.isDismissible] Optional. Flag to check if the notification should be queued and is not dismissed.
* @param {number} [settings.dismissRetries] Optional. An integer number denoting how many times a notification should be shown again on dismissal. Default 0.
* @return {Object} Redux-style action.
*/
registerNotification(
Expand All @@ -80,6 +81,7 @@ export const actions = {
viewContexts,
checkRequirements,
isDismissible,
dismissRetries = 0,
}
) {
invariant(
Expand Down Expand Up @@ -117,6 +119,7 @@ export const actions = {
viewContexts,
checkRequirements,
isDismissible,
dismissRetries,
},
},
type: REGISTER_NOTIFICATION,
Expand Down Expand Up @@ -226,6 +229,25 @@ export const actions = {
return;
}

// Use prompts if a notification should be shown again until it
// is dismissed for a certain number of retries.
if ( notification.dismissRetries > 0 ) {
const dismissCount = registry
.select( CORE_USER )
.getPromptDismissCount( id );

const expirationInSeconds =
dismissCount < notification.dismissRetries
? expiresInSeconds
: 0;

return yield commonActions.await(
registry.dispatch( CORE_USER ).dismissPrompt( id, {
expiresInSeconds: expirationInSeconds,
} )
);
}

return yield commonActions.await(
registry
.dispatch( CORE_USER )
Expand Down Expand Up @@ -407,8 +429,8 @@ export const selectors = {
/**
* Determines whether a notification is dismissed or not.
*
* Currently, this selector simply forwards the call to the dismissed items API.
* We can potentially add more notification-specific logic here in the future.
* If the notification should appear again for a certain number of times after dismissal,
* then we store them as prompts. So we check for dismissed prompts instead of dismissed items.
*
* @since 1.132.0
*
Expand All @@ -418,9 +440,59 @@ export const selectors = {
*/
isNotificationDismissed: createRegistrySelector(
( select ) => ( state, id ) => {
const notification =
select( CORE_NOTIFICATIONS ).getNotification( id );

if ( notification === undefined ) {
return undefined;
}

if ( notification.dismissRetries > 0 ) {
return select( CORE_USER ).isPromptDismissed( id );
}

return select( CORE_USER ).isItemDismissed( id );
}
),
/**
* Determines whether a notification that can reappear again for a fixed number of times
* on dismissal is at its final appearance.
*
* @since n.e.x.t
*
* @param {Object} state Data store's state.
* @param {string} id Notification id.
* @return {(boolean|undefined)} TRUE if notification is on its final retry, otherwise FALSE, `undefined` if not resolved yet.
*/
isNotificationDismissalFinal: createRegistrySelector(
( select ) => ( state, id ) => {
const notification =
select( CORE_NOTIFICATIONS ).getNotification( id );

if ( notification === undefined ) {
return undefined;
}

invariant(
notification.isDismissible,
'Notification should be dismissible to check if a notification is on its final dismissal.'
);

// If a notification does not have retries, it always will be on its final render.
if ( notification.dismissRetries === 0 ) {
return true;
}

const dismissCount =
select( CORE_USER ).getPromptDismissCount( id );

if ( dismissCount >= notification.dismissRetries ) {
return true;
}

return false;
}
),
};

export default {
Expand Down
Loading

0 comments on commit 414f6b5

Please sign in to comment.