From 231e074bd62631870ecd0e22391a3b893b881e26 Mon Sep 17 00:00:00 2001 From: Tom Forbes Date: Tue, 15 Oct 2024 08:59:58 +0100 Subject: [PATCH] Banner test deploySchedule (#636) * Banner test deploySchedule * update copy --- app/models/BannerTests.scala | 3 + .../bannerTests/bannerTestEditor.tsx | 28 +++++- .../bannerTests/deployScheduleEditor.tsx | 98 +++++++++++++++++++ public/src/models/banner.ts | 5 + 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 public/src/components/channelManagement/bannerTests/deployScheduleEditor.tsx diff --git a/app/models/BannerTests.scala b/app/models/BannerTests.scala index 4435f306..e8059a0b 100644 --- a/app/models/BannerTests.scala +++ b/app/models/BannerTests.scala @@ -26,6 +26,8 @@ case class BannerVariant( tickerSettings: Option[TickerSettings] = None, ) +case class BannerTestDeploySchedule(daysBetween: Int) + case class BannerTest( name: String, channel: Option[Channel], @@ -44,6 +46,7 @@ case class BannerTest( signedInStatus: Option[SignedInStatus] = Some(SignedInStatus.All), isBanditTest: Option[Boolean] = None, consentStatus: Option[ConsentStatus] = Some(ConsentStatus.All), + deploySchedule: Option[BannerTestDeploySchedule] = None, ) extends ChannelTest[BannerTest] { override def withChannel(channel: Channel): BannerTest = diff --git a/public/src/components/channelManagement/bannerTests/bannerTestEditor.tsx b/public/src/components/channelManagement/bannerTests/bannerTestEditor.tsx index bf73a49e..b139265a 100644 --- a/public/src/components/channelManagement/bannerTests/bannerTestEditor.tsx +++ b/public/src/components/channelManagement/bannerTests/bannerTestEditor.tsx @@ -16,7 +16,12 @@ import TestEditorTargetAudienceSelector from '../testEditorTargetAudienceSelecto import TestEditorArticleCountEditor, { DEFAULT_ARTICLES_VIEWED_SETTINGS, } from '../testEditorArticleCountEditor'; -import { BannerContent, BannerTest, BannerVariant } from '../../../models/banner'; +import { + BannerContent, + BannerTest, + BannerTestDeploySchedule, + BannerVariant, +} from '../../../models/banner'; import { getDefaultVariant } from './utils/defaults'; import VariantSummary from '../../tests/variants/variantSummary'; import BannerVariantPreview from './bannerVariantPreview'; @@ -33,6 +38,7 @@ import { import TestEditorContextTargeting from '../testEditorContextTargeting'; import { getDesignForVariant } from '../../../utils/bannerDesigns'; import { BanditEditor } from '../banditEditor'; +import { DeployScheduleEditor } from './deployScheduleEditor'; const copyHasTemplate = (content: BannerContent, template: string): boolean => (content.heading && content.heading.includes(template)) || @@ -152,6 +158,13 @@ const BannerTestEditor: React.FC> = ({ }); }; + const onDeployScheduleChange = (updatedDeploySchedule?: BannerTestDeploySchedule): void => { + updateTest({ + ...test, + deploySchedule: updatedDeploySchedule, + }); + }; + const renderVariantEditor = (variant: BannerVariant): React.ReactElement => ( > = ({ isDisabled={!userHasTestLocked} /> + +
+ + Deploy schedule override + + + setValidationStatusForField('deploySchedule', isValid)} + isDisabled={!userHasTestLocked} + /> +
); } diff --git a/public/src/components/channelManagement/bannerTests/deployScheduleEditor.tsx b/public/src/components/channelManagement/bannerTests/deployScheduleEditor.tsx new file mode 100644 index 00000000..75c99fe2 --- /dev/null +++ b/public/src/components/channelManagement/bannerTests/deployScheduleEditor.tsx @@ -0,0 +1,98 @@ +import React, { useEffect } from 'react'; +import { makeStyles } from '@mui/styles'; +import { FormControl, FormControlLabel, Radio, RadioGroup, TextField, Theme } from '@mui/material'; +import { BannerTestDeploySchedule } from '../../../models/banner'; +import { useForm } from 'react-hook-form'; +import { EMPTY_ERROR_HELPER_TEXT, notNumberValidator } from '../helpers/validation'; + +const useStyles = makeStyles(({ spacing }: Theme) => ({ + container: { + '& > * + *': { + marginTop: spacing(3), + }, + }, +})); + +interface DeployScheduleEditorProps { + deploySchedule?: BannerTestDeploySchedule; + onDeployScheduleChange: (deploySchedule?: BannerTestDeploySchedule) => void; + onValidationChange: (isValid: boolean) => void; + isDisabled: boolean; +} + +const DeployScheduleEditor: React.FC = ({ + deploySchedule, + onDeployScheduleChange, + onValidationChange, + isDisabled, +}: DeployScheduleEditorProps) => { + const classes = useStyles(); + + const defaultValues: BannerTestDeploySchedule = { + daysBetween: 1, + }; + const { register, errors, handleSubmit } = useForm({ + mode: 'onChange', + defaultValues, + }); + + useEffect(() => { + const isValid = Object.keys(errors).length === 0 || !deploySchedule; + onValidationChange(isValid); + }, [errors.daysBetween]); + + const onRadioGroupChange = (event: React.ChangeEvent): void => { + if (event.target.value === 'enabled') { + onDeployScheduleChange(defaultValues); + } else { + onDeployScheduleChange(undefined); + } + }; + + const onSubmit = (data: BannerTestDeploySchedule): void => { + onDeployScheduleChange(data); + }; + + return ( + +
+ + } + label="Disabled - use channel deploy schedule" + disabled={isDisabled} + /> + } + label="Enabled - override channel deploy schedule" + disabled={isDisabled} + /> + + + {deploySchedule && ( + + )} +
+
+ ); +}; + +export { DeployScheduleEditor }; diff --git a/public/src/models/banner.ts b/public/src/models/banner.ts index 61a61466..f387992b 100644 --- a/public/src/models/banner.ts +++ b/public/src/models/banner.ts @@ -35,6 +35,10 @@ export interface BannerVariant extends Variant { tickerSettings?: TickerSettings; } +export interface BannerTestDeploySchedule { + daysBetween: number; +} + export interface BannerTest extends Test { name: string; nickname?: string; @@ -47,4 +51,5 @@ export interface BannerTest extends Test { deviceType?: DeviceType; campaignName?: string; contextTargeting: PageContextTargeting; + deploySchedule?: BannerTestDeploySchedule; }