Skip to content

Commit

Permalink
Serve GVL languages as they are requested (#5112)
Browse files Browse the repository at this point in the history
  • Loading branch information
gilluminate authored Jul 22, 2024
1 parent bd9ba28 commit 40ab56a
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The types of changes are:

### Changed
- Moving Privacy Center endpoint logging behind debug flag [#5103](https://github.com/ethyca/fides/pull/5103)
- Serve GVL languages as they are requested [#5112](https://github.com/ethyca/fides/pull/5112)

### Developer Experience
- Add `.syncignore` to reduce file sync size with new volumes [#5104](https://github.com/ethyca/fides/pull/5104)
Expand Down
37 changes: 24 additions & 13 deletions clients/fides-js/src/components/ConsentButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,25 @@ import {
PrivacyNotice,
} from "../lib/consent-types";
import PrivacyPolicyLink from "./PrivacyPolicyLink";
import type { I18n } from "../lib/i18n";
import { DEFAULT_LOCALE, I18n, Locale } from "../lib/i18n";
import LanguageSelector from "../components/LanguageSelector";

interface ConsentButtonProps {
i18n: I18n;
availableLocales?: Locale[];
onManagePreferencesClick?: () => void;
firstButton?: VNode;
onAcceptAll: () => void;
onRejectAll: () => void;
isMobile: boolean;
options: FidesInitOptions;
saveOnly?: boolean;
isInModal?: boolean;
isTCF?: boolean;
}
export const ConsentButtons = ({
i18n,
availableLocales = [DEFAULT_LOCALE],
onManagePreferencesClick,
firstButton,
onAcceptAll,
Expand All @@ -22,17 +36,8 @@ export const ConsentButtons = ({
saveOnly = false,
options,
isInModal,
}: {
i18n: I18n;
onManagePreferencesClick?: () => void;
firstButton?: VNode;
onAcceptAll: () => void;
onRejectAll: () => void;
isMobile: boolean;
options: FidesInitOptions;
saveOnly?: boolean;
isInModal?: boolean;
}) => {
isTCF,
}: ConsentButtonProps) => {
const includeLanguageSelector = i18n.availableLanguages?.length > 1;
return (
<div id="fides-button-group">
Expand Down Expand Up @@ -69,7 +74,12 @@ export const ConsentButtons = ({
} ${includeLanguageSelector ? "fides-button-group-i18n" : ""}`}
>
{includeLanguageSelector && (
<LanguageSelector i18n={i18n} options={options} />
<LanguageSelector
i18n={i18n}
availableLocales={availableLocales}
options={options}
isTCF={!!isTCF}
/>
)}
{!!onManagePreferencesClick && (
<Button
Expand Down Expand Up @@ -157,6 +167,7 @@ export const NoticeConsentButtons = ({
return (
<ConsentButtons
i18n={i18n}
availableLocales={experience.available_locales}
onManagePreferencesClick={onManagePreferencesClick}
onAcceptAll={handleAcceptAll}
onRejectAll={handleRejectAll}
Expand Down
57 changes: 49 additions & 8 deletions clients/fides-js/src/components/LanguageSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,66 @@
import { h } from "preact";
import { I18n } from "../lib/i18n";
import {
DEFAULT_LOCALE,
I18n,
loadMessagesFromGVLTranslations,
Locale,
} from "../lib/i18n";
import { useI18n } from "../lib/i18n/i18n-context";
import MenuItem from "./MenuItem";
import { FIDES_OVERLAY_WRAPPER } from "../lib/consent-constants";
import {
FIDES_I18N_ICON,
FIDES_OVERLAY_WRAPPER,
} from "../lib/consent-constants";
import { debugLog } from "../lib/consent-utils";
import { FidesInitOptions } from "../lib/consent-types";
import { fetchGvlTranslations } from "../services/api";

interface LanguageSelectorProps {
i18n: I18n;
availableLocales: Locale[];
options: FidesInitOptions;
isTCF: boolean;
}

const LanguageSelector = ({ i18n, options }: LanguageSelectorProps) => {
const LanguageSelector = ({
i18n,
availableLocales,
options,
isTCF,
}: LanguageSelectorProps) => {
const { currentLocale, setCurrentLocale } = useI18n();

const handleLocaleSelect = (locale: string) => {
const handleLocaleSelect = async (locale: string) => {
if (locale !== i18n.locale) {
i18n.activate(locale);
setCurrentLocale(locale);
document.getElementById(FIDES_OVERLAY_WRAPPER)?.focus();
debugLog(options.debug, `Fides locale updated to ${locale}`);
if (isTCF) {
const icon = document.getElementById(FIDES_I18N_ICON);
icon?.style.setProperty("animation-name", "spin");
const gvlTranslations = await fetchGvlTranslations(
options.fidesApiUrl,
[locale],
options.debug
);
icon?.style.removeProperty("animation-name");
if (gvlTranslations && Object.keys(gvlTranslations).length) {
loadMessagesFromGVLTranslations(
i18n,
gvlTranslations,
availableLocales || [DEFAULT_LOCALE]
);
i18n.activate(locale);
setCurrentLocale(locale);
debugLog(options.debug, `Fides locale updated to ${locale}`);
} else {
// eslint-disable-next-line no-console
console.error(`Unable to load GVL translation for ${locale}`);
}
} else {
i18n.activate(locale);
setCurrentLocale(locale);
debugLog(options.debug, `Fides locale updated to ${locale}`);
}
}
document.getElementById(FIDES_OVERLAY_WRAPPER)?.focus();
};

return (
Expand All @@ -47,6 +87,7 @@ const LanguageSelector = ({ i18n, options }: LanguageSelectorProps) => {
height="100%"
viewBox="0 0 36 36"
fill="currentColor"
id="fides-i18n-icon"
>
<path
fill="currentColor"
Expand Down
17 changes: 17 additions & 0 deletions clients/fides-js/src/components/fides.css
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@
--fides-overlay-component-border-radius: 4px;
--fides-overlay-banner-offset: 48px;
--fides-banner-font-size-title: var(--16px);
--fides-overlay-language-loading-indicator-speed: 5s;
}

@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

/*
Expand Down Expand Up @@ -1158,6 +1168,13 @@ div.fides-i18n-pseudo-button {
white-space: nowrap;
}

#fides-i18n-icon {
animation-duration: var(--fides-overlay-language-loading-indicator-speed);
animation-iteration-count: infinite;
animation-timing-function: linear;
transform-origin: 50% 50%;
}

div#fides-overlay-wrapper .fides-i18n-pseudo-button {
box-sizing: content-box;
}
Expand Down
2 changes: 2 additions & 0 deletions clients/fides-js/src/components/tcf/TcfConsentButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ export const TcfConsentButtons = ({
return (
<ConsentButtons
i18n={i18n}
availableLocales={experience.available_locales}
onManagePreferencesClick={onManagePreferencesClick}
onAcceptAll={handleAcceptAll}
onRejectAll={handleRejectAll}
firstButton={firstButton}
isMobile={isMobile}
isInModal={isInModal}
options={options}
isTCF
/>
);
};
1 change: 1 addition & 0 deletions clients/fides-js/src/lib/consent-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,4 @@ export const FIDES_OVERRIDE_EXPERIENCE_LANGUAGE_VALIDATOR_MAP: {
];

export const FIDES_OVERLAY_WRAPPER = "fides-overlay-wrapper";
export const FIDES_I18N_ICON = "fides-i18n-icon";
2 changes: 1 addition & 1 deletion clients/fides-js/src/lib/initOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const initOverlay = async ({
if (experience.experience_config?.component === ComponentType.TCF_OVERLAY) {
let gvlTranslations = await fetchGvlTranslations(
options.fidesApiUrl,
experience?.available_locales,
[i18n.locale],
options.debug
);
if (
Expand Down
3 changes: 2 additions & 1 deletion clients/fides-js/src/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
RecordsServedResponse,
} from "../lib/consent-types";
import { debugLog } from "../lib/consent-utils";
import { Locale } from "~/fides";

export enum FidesEndpointPaths {
PRIVACY_EXPERIENCE = "/privacy-experience",
Expand Down Expand Up @@ -103,7 +104,7 @@ export const fetchExperience = async (

export const fetchGvlTranslations = async (
fidesApiUrl: string,
locales?: string[],
locales?: Locale[],
debug?: boolean
): Promise<GVLTranslations> => {
debugLog(debug, "Calling Fides GET GVL translations API...");
Expand Down
12 changes: 12 additions & 0 deletions clients/privacy-center/cypress/e2e/consent-i18n.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,7 @@ describe("Consent i18n", () => {
fixture,
options: { tcfEnabled: true },
});
cy.wait("@getGvlTranslations");
testTcfBannerLocalization(banner);
testTcfModalLocalization(modal);
});
Expand All @@ -1499,11 +1500,19 @@ describe("Consent i18n", () => {
fixture: "experience_tcf.json",
options: { tcfEnabled: true },
});
cy.wait("@getGvlTranslations").then((interception) => {
const { url } = interception.request;
expect(url.split("?")[1]).to.eq(`language=${ENGLISH_LOCALE}`);
});
cy.get("#fides-banner").should("be.visible");
cy.get(
`#fides-banner [data-testid='fides-i18n-option-${SPANISH_LOCALE}']`
).focus();
cy.get(`.fides-i18n-menu`).focused().click();
cy.wait("@getGvlTranslations").then((interception) => {
const { url } = interception.request;
expect(url.split("?")[1]).to.eq(`language=${SPANISH_LOCALE}`);
});
testTcfBannerLocalization(SPANISH_TCF_BANNER);
testTcfModalLocalization(SPANISH_TCF_MODAL);
});
Expand All @@ -1529,6 +1538,7 @@ describe("Consent i18n", () => {
fixture: "experience_tcf.json",
options: { tcfEnabled: true },
});
cy.wait("@getGvlTranslations");
cy.get("#fides-banner").should("be.visible");
cy.get(".fides-i18n-menu").should("not.exist");
cy.get(".fides-notice-toggle")
Expand Down Expand Up @@ -1746,6 +1756,7 @@ describe("Consent i18n", () => {
fixture: "experience_tcf.json",
options: { tcfEnabled: true },
});
cy.wait("@getGvlTranslations");
cy.get("#fides-modal-link").click();
cy.getByTestId("records-list-purposes").within(() => {
cy.get(".fides-toggle:first").contains("Off");
Expand Down Expand Up @@ -1775,6 +1786,7 @@ describe("Consent i18n", () => {
fixture: "experience_tcf.json",
options: { tcfEnabled: true },
});
cy.wait("@getGvlTranslations");
cy.get("#fides-modal-link").click();
cy.getByTestId("records-list-purposes").within(() => {
cy.get(".fides-toggle:first").contains("Off").should("not.exist");
Expand Down

0 comments on commit 40ab56a

Please sign in to comment.