Skip to content

Commit

Permalink
Allow for using CompleteOptionsToggle as more choices
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfarrell76 committed Dec 12, 2024
1 parent 09fc2b4 commit d30bcac
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 34 deletions.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-6b67494872-10.zip
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-afc6995412-10.zip
Binary file not shown.
16 changes: 8 additions & 8 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
data-secondary-policy="http://transcend.io/test"
src="https://cdn.transcend.io/cm/443312ef-12f9-494d-85f5-969894260cc7/airgap.js"
onload="window.airgapScriptLoadEvent=event;"
data-more-choices="CompleteOptionsToggles"
data-regime="GDPR"
></script>
<!-- <script
Expand Down
6 changes: 5 additions & 1 deletion src/components/AcceptAllOrMoreChoices.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ViewState } from '@transcend-io/airgap.js-types';
import { ObjByString } from '@transcend-io/type-utils';
import { h, JSX } from 'preact';
import { useIntl } from 'react-intl';
Expand All @@ -12,11 +13,14 @@ import { Button } from './Button';
export function AcceptAllOrMoreChoices({
handleSetViewState,
globalUiVariables,
moreChoicesViewState,
}: {
/** Function to change viewState */
handleSetViewState: HandleSetViewState;
/** Global variables to pass to message contents */
globalUiVariables: ObjByString;
/** The view state to use for more-choices redirect */
moreChoicesViewState: ViewState;
}): JSX.Element {
const { airgap } = useAirgap();
const { formatMessage } = useIntl();
Expand All @@ -39,7 +43,7 @@ export function AcceptAllOrMoreChoices({
event: JSX.TargetedEvent<HTMLButtonElement, MouseEvent>,
): void => {
event.preventDefault();
handleSetViewState('CompleteOptions');
handleSetViewState(moreChoicesViewState);
};

return (
Expand Down
6 changes: 5 additions & 1 deletion src/components/AcceptOrRejectAllOrMoreChoices.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ViewState } from '@transcend-io/airgap.js-types';
import { ObjByString } from '@transcend-io/type-utils';
import { h, JSX } from 'preact';
import { useIntl } from 'react-intl';
Expand All @@ -12,11 +13,14 @@ import { Button } from './Button';
export function AcceptOrRejectAllOrMoreChoices({
handleSetViewState,
globalUiVariables,
moreChoicesViewState,
}: {
/** Function to change viewState */
handleSetViewState: HandleSetViewState;
/** Global UI view state variables */
globalUiVariables: ObjByString;
/** The view state to use for more-choices redirect */
moreChoicesViewState: ViewState;
}): JSX.Element {
const { airgap } = useAirgap();
const { formatMessage } = useIntl();
Expand Down Expand Up @@ -50,7 +54,7 @@ export function AcceptOrRejectAllOrMoreChoices({
event: JSX.TargetedEvent<HTMLButtonElement, MouseEvent>,
): void => {
event.preventDefault();
handleSetViewState('CompleteOptions');
handleSetViewState(moreChoicesViewState);
};

return (
Expand Down
1 change: 1 addition & 0 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export function App({
airgap={airgap}
modalOpenAuth={auth}
viewState={viewState}
moreChoicesViewState={config.moreChoices}

Check failure on line 131 in src/components/App.tsx

View workflow job for this annotation

GitHub Actions / build-and-upload-artifacts

Property 'moreChoices' does not exist on type '{ theme: { primaryColor: string; fontColor: string; }; breakpoints: { tablet: string; desktop: string; }; privacyPolicy: string; secondaryPolicy: string; css: string; messages: string; initialViewStateByPrivacyRegime: { ...; }; dismissedViewState: "Collapsed" | "Closed"; } & { ...; }'.
config={config}
supportedLanguages={supportedLanguages}
firstSelectedViewState={firstSelectedViewState}
Expand Down
22 changes: 16 additions & 6 deletions src/components/BottomMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ const VIEW_STATE_TO_MESSAGE: { [k in ViewState]: DefinedMessage | undefined } =
bottomMenuMessages.showPolicyButtonPrivacyPolicyNoticeWithCloseButton,
};

// FIXME airgap.js-types
const SKIP_SIMPLER_CHOICES_IF_ACTIVE = [
'CompleteOptions',
'CompleteOptionsInverted',
'CompleteOptionsToggles',
];

/**
* Renders the menu for the bottom of the banner
*/
Expand All @@ -53,6 +60,7 @@ export function BottomMenu({
secondaryPolicy,
privacyPolicy,
globalUiVariables,
moreChoicesViewState,
}: {
/** The first view state when opening the modal */
firstSelectedViewState: ViewState | null;
Expand All @@ -66,6 +74,8 @@ export function BottomMenu({
secondaryPolicy: string;
/** Global UI view state variables */
globalUiVariables: ObjByString;
/** The view state to use for more-choices redirect */
moreChoicesViewState: ViewState;
}): JSX.Element {
const { formatMessage } = useIntl();
const policyMessage = VIEW_STATE_TO_MESSAGE[viewState];
Expand Down Expand Up @@ -98,16 +108,16 @@ export function BottomMenu({
'AcceptOrRejectAnalytics',
'AcceptAllOrMoreChoices',
'AcceptOrRejectAllOrMoreChoices',
'CompleteOptionsInverted',
'DoNotSellExplainer',
'CompleteOptionsToggles',
'LanguageOptions',
'AcceptAllRejectAllToggle',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
].includes(viewState as any) &&
(viewState === 'CompleteOptions' ? (
(SKIP_SIMPLER_CHOICES_IF_ACTIVE.includes(viewState) ? (
!firstSelectedViewState ||
firstSelectedViewState === 'CompleteOptions' ? null : (
SKIP_SIMPLER_CHOICES_IF_ACTIVE.includes(
firstSelectedViewState,
) ? null : (
<div className="bottom-menu-item-container">
<MenuItem
label={formatMessage(
Expand All @@ -132,7 +142,7 @@ export function BottomMenu({
globalUiVariables,
)}
type="button"
onClick={() => handleSetViewState('CompleteOptions')}
onClick={() => handleSetViewState(moreChoicesViewState)}
>
{formatMessage(
bottomMenuMessages.moreChoicesButtonPrimary,
Expand All @@ -151,7 +161,7 @@ export function BottomMenu({
globalUiVariables,
)}
type="button"
onClick={() => handleSetViewState('CompleteOptions')}
onClick={() => handleSetViewState(moreChoicesViewState)}
>
{formatMessage(
noticeAndDoNotSellMessages.doNotSellPrimary,
Expand Down
6 changes: 6 additions & 0 deletions src/components/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export function Main({
handleSetViewState,
handleChangeLanguage,
supportedLanguages,
moreChoicesViewState,
modalOpenAuth,
}: {
/** Global variables for UI view state */
Expand All @@ -69,6 +70,8 @@ export function Main({
handleChangeLanguage: (language: ConsentManagerLanguageKey) => void;
/** Set of supported languages */
supportedLanguages: ConsentManagerLanguageKey[];
/** The view state to use for more-choices redirect */
moreChoicesViewState: ViewState;
}): JSX.Element {
const { formatMessage } = useIntl();
// need to focus the element marked with data-initialFocus when the modal is opened
Expand Down Expand Up @@ -186,13 +189,15 @@ export function Main({
<AcceptAllOrMoreChoices
handleSetViewState={handleSetViewState}
globalUiVariables={globalUiVariables}
moreChoicesViewState={moreChoicesViewState}
/>
)}

{viewState === 'AcceptOrRejectAllOrMoreChoices' && (
<AcceptOrRejectAllOrMoreChoices
handleSetViewState={handleSetViewState}
globalUiVariables={globalUiVariables}
moreChoicesViewState={moreChoicesViewState}
/>
)}

Expand Down Expand Up @@ -250,6 +255,7 @@ export function Main({
privacyPolicy={config.privacyPolicy}
secondaryPolicy={config.secondaryPolicy}
globalUiVariables={globalUiVariables}
moreChoicesViewState={moreChoicesViewState}
/>
<LanguageButton
handleSetViewState={handleSetViewState}
Expand Down
6 changes: 5 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ const baseConfig: Omit<
tablet: '640px',
desktop: '1024px',
},
moreChoices: 'CompleteOptions',
initialViewStateByPrivacyRegime: DEFAULT_VIEW_STATE_BY_PRIVACY_REGIME_COPIED,
};
// FIXME
} as any;

/**
* Merges config from defaults and settings. JSON is automatically decoded.
Expand Down Expand Up @@ -98,6 +100,8 @@ export function getMergedConfig(): MergedConsentManagerConfig {
config.secondaryPolicy ??= secondaryPolicy;
config.dismissedViewState ??= dismissedViewState;
config.languages ??= languages;
// FIXME
(config as any).moreChoices ??= 'CompleteOptions';
if (typeof config.initialViewStateByPrivacyRegime === 'string') {
config.initialViewStateByPrivacyRegime = JSON.parse(
config.initialViewStateByPrivacyRegime,
Expand Down
22 changes: 22 additions & 0 deletions src/tests/AcceptAllOrMoreChoices.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('AcceptAllOrMoreChoices', () => {
<AcceptAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);
expect(snapshot).toMatchSnapshot();
Expand All @@ -33,6 +34,7 @@ describe('AcceptAllOrMoreChoices', () => {
<AcceptAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);

Expand All @@ -52,6 +54,7 @@ describe('AcceptAllOrMoreChoices', () => {
<AcceptAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);

Expand All @@ -77,6 +80,7 @@ describe('AcceptAllOrMoreChoices', () => {
handleSetViewState={(state) => {
calledArg = state;
}}
moreChoicesViewState="CompleteOptions"
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
/>,
);
Expand All @@ -86,4 +90,22 @@ describe('AcceptAllOrMoreChoices', () => {

expect(calledArg).toEqual('CompleteOptions');
});

test('that CompleteOptionsToggles is opened', () => {
let calledArg;
const { container } = render(
<AcceptAllOrMoreChoices
handleSetViewState={(state) => {
calledArg = state;
}}
moreChoicesViewState="CompleteOptionsToggles"
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
/>,
);

const moreChoicesButton = container.querySelector('button:nth-of-type(2)');
if (moreChoicesButton) fireEvent.click(moreChoicesButton);

expect(calledArg).toEqual('CompleteOptionsToggles');
});
});
23 changes: 23 additions & 0 deletions src/tests/AcceptOrRejectAllOrMoreChoices.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('AcceptOrRejectAllOrMoreChoices', () => {
<AcceptOrRejectAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);
expect(snapshot).toMatchSnapshot();
Expand All @@ -31,6 +32,7 @@ describe('AcceptOrRejectAllOrMoreChoices', () => {
<AcceptOrRejectAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);

Expand All @@ -52,6 +54,7 @@ describe('AcceptOrRejectAllOrMoreChoices', () => {
<AcceptOrRejectAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);

Expand All @@ -77,6 +80,7 @@ describe('AcceptOrRejectAllOrMoreChoices', () => {
<AcceptOrRejectAllOrMoreChoices
handleSetViewState={() => null}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);

Expand All @@ -103,6 +107,7 @@ describe('AcceptOrRejectAllOrMoreChoices', () => {
calledArg = state;
}}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptions"
/>,
);

Expand All @@ -111,4 +116,22 @@ describe('AcceptOrRejectAllOrMoreChoices', () => {

expect(calledArg).toEqual('CompleteOptions');
});

test('that CompleteOptionsToggles is opened', () => {
let calledArg;
const { container } = render(
<AcceptOrRejectAllOrMoreChoices
handleSetViewState={(state) => {
calledArg = state;
}}
globalUiVariables={MOCK_TEMPLATE_VARIABLES}
moreChoicesViewState="CompleteOptionsToggles"
/>,
);

const moreChoicesButton = container.querySelector('button:nth-of-type(3)');
if (moreChoicesButton) fireEvent.click(moreChoicesButton);

expect(calledArg).toEqual('CompleteOptionsToggles');
});
});
27 changes: 13 additions & 14 deletions src/tests/__snapshots__/CompleteOptions.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ exports[`CompleteOptions matches snapshot 1`] = `
><input
class="toggle-input"
type="checkbox"
id="essential-purposes"
name="Essential purposes"
id="essential"
name="Essential"
disabled=""
/><span class="toggle-checkmark"></span>Essential purposes</label
/><span class="toggle-checkmark"></span>Essential</label
><label
class="toggle-label"
aria-label="Click to disable collection of data for this purpose – functionality"
title="Click to disable collection of data for this purpose – functionality"
aria-label="Click to disable collection of data for this purpose – functional"
title="Click to disable collection of data for this purpose – functional"
><input
class="toggle-input"
type="checkbox"
id="functionality"
name="Functionality"
id="functional"
name="Functional"
data-initialfocus="true"
/><span class="toggle-checkmark"></span>Functionality</label
/><span class="toggle-checkmark"></span>Functional</label
><label
class="toggle-label"
aria-label="Click to disable collection of data for this purpose – analytics"
Expand All @@ -58,15 +58,14 @@ exports[`CompleteOptions matches snapshot 1`] = `
/><span class="toggle-checkmark"></span>Advertising</label
><label
class="toggle-label"
aria-label="Click to disable collection of data for this purpose – sale of personal information"
title="Click to disable collection of data for this purpose – sale of personal information"
aria-label="Click to disable collection of data for this purpose – saleofinfo"
title="Click to disable collection of data for this purpose – saleofinfo"
><input
class="toggle-input"
type="checkbox"
id="sale-of-personal-information"
name="Sale of personal information"
/><span class="toggle-checkmark"></span>Sale of personal
information</label
id="saleofinfo"
name="SaleOfInfo"
/><span class="toggle-checkmark"></span>SaleOfInfo</label
><label
class="toggle-label"
aria-label="Click to disable collection of data for this purpose – custompurpose"
Expand Down
Loading

0 comments on commit d30bcac

Please sign in to comment.