Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add consent targeting to RRCP #571

Merged
merged 9 commits into from
Apr 19, 2024
1 change: 1 addition & 0 deletions app/models/BannerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ case class BannerTest(
deviceType: Option[DeviceType] = None,
campaignName: Option[String] = Some("NOT_IN_CAMPAIGN"),
signedInStatus: Option[SignedInStatus] = Some(SignedInStatus.All),
consentStatus: Option[ConsentStatus] = Some(ConsentStatus.All),
) extends ChannelTest[BannerTest] {

override def withChannel(channel: Channel): BannerTest =
Expand Down
16 changes: 16 additions & 0 deletions app/models/ConsentStatus.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package models

import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.{ deriveEnumerationDecoder, deriveEnumerationEncoder }
import io.circe.{Decoder, Encoder}

sealed trait ConsentStatus

object ConsentStatus {
case object All extends ConsentStatus
case object HasConsented extends ConsentStatus
case object HasNotConsented extends ConsentStatus
implicit val customConfig: Configuration = Configuration.default.withDefaults
implicit val decoder: Decoder[ConsentStatus] = deriveEnumerationDecoder[ConsentStatus]
implicit val encoder: Encoder[ConsentStatus] = deriveEnumerationEncoder[ConsentStatus]
}
1 change: 1 addition & 0 deletions app/models/EpicTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ case class EpicTest(
deviceType: Option[DeviceType] = None,
campaignName: Option[String] = Some("NOT_IN_CAMPAIGN"),
signedInStatus: Option[SignedInStatus] = Some(SignedInStatus.All),
consentStatus: Option[ConsentStatus] = Some(ConsentStatus.All),
) extends ChannelTest[EpicTest] {

override def withChannel(channel: Channel): EpicTest = this.copy(channel = Some(channel))
Expand Down
1 change: 1 addition & 0 deletions app/models/HeaderTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ case class HeaderTest(
deviceType: Option[DeviceType] = None,
campaignName: Option[String] = Some("NOT_IN_CAMPAIGN"),
signedInStatus: Option[SignedInStatus] = Some(SignedInStatus.All),
consentStatus: Option[ConsentStatus] = Some(ConsentStatus.All),
) extends ChannelTest[HeaderTest] {

override def withChannel(channel: Channel): HeaderTest = this.copy(channel = Some(channel))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React, { useEffect, useState } from 'react';
import { Region } from '../../../utils/models';
import { ArticlesViewedSettings, DeviceType, SignedInStatus, UserCohort } from '../helpers/shared';
import {
ArticlesViewedSettings,
ConsentStatus,
DeviceType,
SignedInStatus,
UserCohort,
} from '../helpers/shared';
import { ARTICLE_COUNT_TEMPLATE } from '../helpers/validation';
import { Typography } from '@mui/material';
import BannerTestVariantEditor from './bannerTestVariantEditor';
Expand Down Expand Up @@ -128,6 +134,10 @@ const BannerTestEditor: React.FC<ValidatedTestEditorProps<BannerTest>> = ({
onTestChange({ ...test, signedInStatus });
};

const onConsentStatusChange = (consentStatus: ConsentStatus): void => {
onTestChange({ ...test, consentStatus });
};

const onArticlesViewedSettingsChange = (
updatedArticlesViewedSettings?: ArticlesViewedSettings,
): void => {
Expand Down Expand Up @@ -263,6 +273,9 @@ const BannerTestEditor: React.FC<ValidatedTestEditorProps<BannerTest>> = ({
showDeviceTypeSelector={true}
selectedSignedInStatus={test.signedInStatus}
onSignedInStatusChange={onSignedInStatusChange}
selectedConsentStatus={test.consentStatus}
onConsentStatusChange={onConsentStatusChange}
showConsentStatusSelector={true}
/>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DeviceType,
SignedInStatus,
PageContextTargeting,
ConsentStatus,
Copy link
Contributor

Choose a reason for hiding this comment

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

we can edit it in the Epic editor, does it need to be added to the epic model?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah really good catch here! I've added it to the model for epics and headers but since the scope of this ticket is just for banners we have hidden the toggles from epics and headers but the functionality is there when we do decide to expand

} from '../helpers/shared';
import { FormControlLabel, Switch, Typography } from '@mui/material';
import CampaignSelector from '../CampaignSelector';
Expand Down Expand Up @@ -158,6 +159,10 @@ export const getEpicTestEditor = (
onTestChange({ ...test, signedInStatus });
};

const onConsentChange = (consentStatus: ConsentStatus): void => {
onTestChange({ ...test, consentStatus });
};

const onArticlesViewedSettingsChange = (
updatedArticlesViewedSettings?: ArticlesViewedSettings,
): void => {
Expand Down Expand Up @@ -332,6 +337,9 @@ export const getEpicTestEditor = (
showDeviceTypeSelector={epicEditorConfig.allowDeviceTypeTargeting}
selectedSignedInStatus={test.signedInStatus}
onSignedInStatusChange={onSignedInStatusChange}
selectedConsentStatus={test.consentStatus}
onConsentStatusChange={onConsentChange}
showConsentStatusSelector={false}
platform={epicEditorConfig.platform}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Region } from '../../../utils/models';

import { DeviceType, SignedInStatus, UserCohort } from '../helpers/shared';
import { ConsentStatus, DeviceType, SignedInStatus, UserCohort } from '../helpers/shared';

import { Typography } from '@mui/material';
import HeaderTestVariantEditor from './headerTestVariantEditor';
Expand Down Expand Up @@ -73,6 +73,10 @@ const HeaderTestEditor: React.FC<ValidatedTestEditorProps<HeaderTest>> = ({
onTestChange({ ...test, signedInStatus });
};

const onConsentChange = (consentStatus: ConsentStatus): void => {
onTestChange({ ...test, consentStatus });
};

const renderVariantEditor = (variant: HeaderVariant): React.ReactElement => (
<HeaderTestVariantEditor
key={`head-${test.name}-${variant.name}`}
Expand Down Expand Up @@ -181,6 +185,9 @@ const HeaderTestEditor: React.FC<ValidatedTestEditorProps<HeaderTest>> = ({
showDeviceTypeSelector={true}
selectedSignedInStatus={test.signedInStatus}
onSignedInStatusChange={onSignedInStatusChange}
selectedConsentStatus={test.consentStatus}
onConsentStatusChange={onConsentChange}
showConsentStatusSelector={false}
/>
</div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions public/src/components/channelManagement/helpers/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface Test {
userCohort?: string;
channel?: string;
signedInStatus?: SignedInStatus;
consentStatus?: ConsentStatus;
}

export interface EpicEditorConfig {
Expand Down Expand Up @@ -253,6 +254,8 @@ export type ContributionFrequency = 'ONE_OFF' | 'MONTHLY' | 'ANNUAL';

export type DeviceType = 'Mobile' | 'Desktop' | 'All' | 'iOS' | 'Android';

export type ConsentStatus = 'HasConsented' | 'HasNotConsented' | 'All';

export interface Image {
mainUrl: string;
altText: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import React from 'react';
import { Theme, Typography } from '@mui/material';
import { makeStyles } from '@mui/styles';
import { Region } from '../../utils/models';
import { DeviceType, SignedInStatus, UserCohort, TestPlatform } from './helpers/shared';
import {
DeviceType,
SignedInStatus,
UserCohort,
TestPlatform,
ConsentStatus,
} from './helpers/shared';

import TestEditorTargetRegionsSelector from './testEditorTargetRegionsSelector';
import TypedRadioGroup from './TypedRadioGroup';
Expand Down Expand Up @@ -41,6 +47,9 @@ interface TestEditorTargetAudienceSelectorProps {
showDeviceTypeSelector: boolean;
selectedSignedInStatus?: SignedInStatus;
onSignedInStatusChange: (signedInStatus: SignedInStatus) => void;
selectedConsentStatus?: ConsentStatus;
onConsentStatusChange: (consentStatus: ConsentStatus) => void;
showConsentStatusSelector: boolean;
platform?: TestPlatform;
}
const TestEditorTargetAudienceSelector: React.FC<TestEditorTargetAudienceSelectorProps> = ({
Expand All @@ -56,6 +65,9 @@ const TestEditorTargetAudienceSelector: React.FC<TestEditorTargetAudienceSelecto
showDeviceTypeSelector,
selectedSignedInStatus,
onSignedInStatusChange,
selectedConsentStatus,
onConsentStatusChange,
showConsentStatusSelector,
platform,
}: TestEditorTargetAudienceSelectorProps) => {
const classes = useStyles();
Expand Down Expand Up @@ -120,6 +132,22 @@ const TestEditorTargetAudienceSelector: React.FC<TestEditorTargetAudienceSelecto
}}
/>
</div>

{showConsentStatusSelector && (
<div className={classes.sectionContainer}>
<Typography className={classes.heading}>Consent Status</Typography>
<TypedRadioGroup
selectedValue={selectedConsentStatus ?? 'All'}
onChange={onConsentStatusChange}
isDisabled={isDisabled}
labels={{
All: 'All',
HasConsented: 'Has consented',
HasNotConsented: 'Has not consented',
}}
/>
</div>
)}
</div>
);
};
Expand Down
Loading