Skip to content

Commit

Permalink
Make the banner the initial layer (#4142)
Browse files Browse the repository at this point in the history
  • Loading branch information
allisonking authored Sep 22, 2023
1 parent 72e8346 commit 83f07cd
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 125 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The types of changes are:
- Added further config options to customize the privacy center [#4090](https://github.com/ethyca/fides/pull/4090)
- CORS configuration page [#4073](https://github.com/ethyca/fides/pull/4073)
- Refactored `fides.js` components so that they can take data structures that are not necessarily privacy notices [#3870](https://github.com/ethyca/fides/pull/3870)
- Moved the initial TCF layer to the banner [#4142](https://github.com/ethyca/fides/pull/4142)

### Fixed
- Allows CDN to cache empty experience responses from fides.js API [#4113](https://github.com/ethyca/fides/pull/4113)
Expand Down
8 changes: 4 additions & 4 deletions clients/fides-js/src/components/ConsentBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, FunctionComponent, VNode } from "preact";
import { h, FunctionComponent, ComponentChildren } from "preact";
import { getConsentContext } from "../lib/consent-context";
import { ExperienceConfig } from "../lib/consent-types";
import CloseButton from "./CloseButton";
Expand All @@ -8,14 +8,14 @@ interface BannerProps {
experience: ExperienceConfig;
onClose: () => void;
bannerIsOpen: boolean;
buttonGroup: VNode;
children: ComponentChildren;
}

const ConsentBanner: FunctionComponent<BannerProps> = ({
experience,
buttonGroup,
onClose,
bannerIsOpen,
children,
}) => {
const showGpcBadge = getConsentContext().globalPrivacyControl;
return (
Expand Down Expand Up @@ -45,7 +45,7 @@ const ConsentBanner: FunctionComponent<BannerProps> = ({
>
{experience.description}
</div>
{buttonGroup}
{children}
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions clients/fides-js/src/components/fides.css
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ div#fides-banner-description {
line-height: 1.2em;
min-width: 33%;
flex: 1;
margin-bottom: 0.5em;
}

div#fides-button-group {
Expand Down
25 changes: 12 additions & 13 deletions clients/fides-js/src/components/notices/NoticeOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,18 @@ const NoticeOverlay: FunctionComponent<OverlayProps> = ({
bannerIsOpen={isOpen}
onClose={onClose}
experience={experienceConfig}
buttonGroup={
<NoticeConsentButtons
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
enabledKeys={draftEnabledNoticeKeys}
onSave={(keys) => {
handleUpdatePreferences(keys);
onSave();
}}
isAcknowledge={isAllNoticeOnly}
/>
}
/>
>
<NoticeConsentButtons
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
enabledKeys={draftEnabledNoticeKeys}
onSave={(keys) => {
handleUpdatePreferences(keys);
onSave();
}}
isAcknowledge={isAllNoticeOnly}
/>
</ConsentBanner>
) : null
}
renderModalContent={({ onClose }) => (
Expand Down
102 changes: 19 additions & 83 deletions clients/fides-js/src/components/tcf/TcfModalContent.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,9 @@
import { h } from "preact";
import { useState } from "preact/hooks";
import TcfTabs from "./TcfTabs";
import { TcfConsentButtons } from "./TcfConsentButtons";
import { ButtonType, PrivacyExperience } from "../../lib/consent-types";
import type { EnabledIds, UpdateEnabledIds } from "./TcfOverlay";
import Button from "../Button";
import InitialLayer from "./InitialLayer";

const BackButton = ({ onClick }: { onClick: () => void }) => (
<button type="button" className="fides-back-button" onClick={onClick}>
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none">
<path
fill="#2D3748"
d="M3.914 5.5H10v1H3.914l2.682 2.682-.707.707L2 6l3.889-3.889.707.707L3.914 5.5Z"
/>
</svg>
Back
</button>
);

const ManagePreferencesLink = ({
linkLabel,
onClick,
}: {
linkLabel: string;
onClick: () => void;
}) => (
<button type="button" onClick={onClick} className="fides-link-button">
{linkLabel}
</button>
);

const TcfModalContent = ({
experience,
Expand All @@ -41,63 +15,25 @@ const TcfModalContent = ({
draftIds: EnabledIds;
onChange: (payload: UpdateEnabledIds) => void;
onSave: (keys: EnabledIds) => void;
}) => {
const [isInitialLayer, setIsInitialLayer] = useState(true);
const goToSecondLayer = () => {
setIsInitialLayer(false);
};
if (isInitialLayer) {
return (
<div>
<InitialLayer
experience={experience}
managePreferencesLink={
<ManagePreferencesLink
onClick={goToSecondLayer}
linkLabel={
experience.experience_config?.privacy_preferences_link_label ||
""
}
/>
}
/>
<TcfConsentButtons
experience={experience}
onSave={onSave}
firstButton={
<Button
buttonType={ButtonType.SECONDARY}
label={
experience.experience_config?.privacy_preferences_link_label
}
onClick={goToSecondLayer}
/>
}
}) => (
<div>
<TcfTabs
experience={experience}
enabledIds={draftIds}
onChange={onChange}
/>
<TcfConsentButtons
experience={experience}
onSave={onSave}
firstButton={
<Button
buttonType={ButtonType.SECONDARY}
label={experience.experience_config?.save_button_label}
onClick={() => onSave(draftIds)}
/>
</div>
);
}
return (
<div>
<BackButton onClick={() => setIsInitialLayer(true)} />
<TcfTabs
experience={experience}
enabledIds={draftIds}
onChange={onChange}
/>
<TcfConsentButtons
experience={experience}
onSave={onSave}
firstButton={
<Button
buttonType={ButtonType.SECONDARY}
label={experience.experience_config?.save_button_label}
onClick={() => onSave(draftIds)}
/>
}
/>
</div>
);
};
}
/>
</div>
);

export default TcfModalContent;
35 changes: 24 additions & 11 deletions clients/fides-js/src/components/tcf/TcfOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { ConsentMethod, PrivacyExperience } from "../../lib/consent-types";
import TcfModalContent from "./TcfModalContent";
import { generateTcString } from "../../lib/tcf";
import { FidesCookie } from "../../lib/cookie";
import InitialLayer from "./InitialLayer";

const resolveConsentValueFromTcfModel = (
model: TCFPurposeRecord | TCFFeatureRecord | TCFVendorRecord
Expand Down Expand Up @@ -226,17 +227,29 @@ const TcfOverlay: FunctionComponent<OverlayProps> = ({
bannerIsOpen={isOpen}
onClose={onClose}
experience={experienceConfig}
buttonGroup={
<TcfConsentButtons
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
onSave={(keys) => {
handleUpdateAllPreferences(keys);
onSave();
}}
/>
}
/>
>
<InitialLayer
experience={experience}
managePreferencesLink={
<button
type="button"
onClick={onManagePreferencesClick}
className="fides-link-button"
>
{experience.experience_config
?.privacy_preferences_link_label || ""}
</button>
}
/>
<TcfConsentButtons
experience={experience}
onManagePreferencesClick={onManagePreferencesClick}
onSave={(keys) => {
handleUpdateAllPreferences(keys);
onSave();
}}
/>
</ConsentBanner>
) : null
}
renderModalContent={({ onClose }) => (
Expand Down
32 changes: 18 additions & 14 deletions clients/privacy-center/cypress/e2e/consent-banner-tcf.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,29 +146,33 @@ describe("Fides-js TCF", () => {
});

describe("initial layer", () => {
beforeEach(() => {
cy.get("#fides-modal-link").click();
});

it("can render purposes in the initial layer as a stack", () => {
cy.get("span").contains(STACK_1.name);
cy.get("span").contains(PURPOSE_3.name);
cy.get("div#fides-banner").within(() => {
cy.get("span").contains(STACK_1.name);
cy.get("span").contains(PURPOSE_3.name);

cy.get("span").contains(STACK_1.name).click();
[PURPOSE_1.id, PURPOSE_2.id, PURPOSE_4.id, PURPOSE_5.id].forEach(
(id) => {
cy.get("li").contains(`Purpose ${id}`);
}
);
});
});

cy.get("span").contains(STACK_1.name).click();
[PURPOSE_1.id, PURPOSE_2.id, PURPOSE_4.id, PURPOSE_5.id].forEach((id) => {
cy.get("li").contains(`Purpose ${id}`);
it("can open the modal", () => {
cy.get("div#fides-banner").within(() => {
cy.get("#fides-button-group").within(() => {
cy.get("button").contains("Manage preferences").click();
});
});
cy.get("#fides-tab-Purposes");
});
});

describe("second layer", () => {
beforeEach(() => {
cy.get("#fides-modal-link").click();
cy.getByTestId("fides-modal-content").within(() => {
cy.get("#fides-banner-button-secondary")
.contains("Manage preferences")
.click();
});
});

describe("rendering the TCF modal", () => {
Expand Down

0 comments on commit 83f07cd

Please sign in to comment.