Skip to content

Commit

Permalink
Hide translation interface in notice/experience form when translation…
Browse files Browse the repository at this point in the history
…s aren't enabled (#4728)
  • Loading branch information
jpople authored Mar 20, 2024
1 parent 8ec8fd9 commit dd1f329
Show file tree
Hide file tree
Showing 20 changed files with 204 additions and 78 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ The types of changes are:
### Added
- Added models for Privacy Center configuration (for plus users) [#4716](https://github.com/ethyca/fides/pull/4716)

### Changed
- Updated privacy notice & experience forms to hide translation UI when user doesn't have translation feature [#4728](https://github.com/ethyca/fides/pull/4728)

### Fixed
- Fixed responsive issues with the buttons on the integration screen [#4729](https://github.com/ethyca/fides/pull/4729)

Expand Down
19 changes: 18 additions & 1 deletion clients/admin-ui/cypress/e2e/privacy-experiences.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { stubPlus } from "cypress/support/stubs";
import { stubPlus, stubTranslationConfig } from "cypress/support/stubs";

import { PRIVACY_EXPERIENCE_ROUTE } from "~/features/common/nav/v2/routes";
import { RoleRegistryEnum } from "~/types/api";
Expand Down Expand Up @@ -192,4 +192,21 @@ describe("Privacy experiences", () => {
});
});
});

describe("translation interface", () => {
it("shows the language interface when translations are enabled", () => {
stubTranslationConfig(true);
cy.visit(`${PRIVACY_EXPERIENCE_ROUTE}/new`);
cy.wait("@getTranslationConfig");
cy.getByTestId("input-auto_detect_language").should("exist");
});

it("shows an edit button instead when translations are disabled", () => {
stubTranslationConfig(false);
cy.visit(`${PRIVACY_EXPERIENCE_ROUTE}/new`);
cy.wait("@getTranslationConfig");
cy.getByTestId("input-auto_detect_language").should("not.exist");
cy.getByTestId("edit-experience-btn").should("exist");
});
});
});
19 changes: 19 additions & 0 deletions clients/admin-ui/cypress/e2e/privacy-notices.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
stubPlus,
stubPrivacyNoticesCrud,
stubTaxonomyEntities,
stubTranslationConfig,
} from "cypress/support/stubs";

import { PRIVACY_NOTICES_ROUTE } from "~/features/common/nav/v2/routes";
Expand Down Expand Up @@ -307,6 +308,7 @@ describe("Privacy notices", () => {
});

it("can create a new privacy notice", () => {
stubTranslationConfig(true);
cy.visit(`${PRIVACY_NOTICES_ROUTE}/new`);
cy.getByTestId("new-privacy-notice-page");
const notice = {
Expand Down Expand Up @@ -382,4 +384,21 @@ describe("Privacy notices", () => {
cy.getByTestId("input-notice_key").clear().type("custom_key");
});
});

describe("translation interface", () => {
it("shows the translation interface when translations are enabled", () => {
stubLanguages();
stubTranslationConfig(true);
cy.visit(`${PRIVACY_NOTICES_ROUTE}/new`);
cy.wait("@getTranslationConfig");
cy.getByTestId("add-language-btn").should("exist");
});

it("doesn't show the translation interface when translations are disabled", () => {
stubTranslationConfig(false);
cy.visit(`${PRIVACY_NOTICES_ROUTE}/new`);
cy.wait("@getTranslationConfig");
cy.getByTestId("add-language-btn").should("not.exist");
});
});
});
11 changes: 11 additions & 0 deletions clients/admin-ui/cypress/support/stubs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,14 @@ export const stubSystemVendors = () => {
fixture: "systems/system-vendors.json",
}).as("getSystemVendors");
};

export const stubTranslationConfig = (enabled: boolean) => {
cy.intercept("GET", "/api/v1/config*", {
body: {
consent: {
enable_translations: enabled,
enable_oob_translations: enabled,
},
},
}).as("getTranslationConfig");
};
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
import { PrivacyExperienceForm } from "~/features/privacy-experience/PrivacyExperienceForm";
import PrivacyExperienceTranslationForm from "~/features/privacy-experience/PrivacyExperienceTranslationForm";
import { selectAllPrivacyNotices } from "~/features/privacy-notices/privacy-notices.slice";
import { useGetConfigurationSettingsQuery } from "~/features/privacy-requests";
import {
ComponentType,
ExperienceConfigCreate,
Expand Down Expand Up @@ -91,6 +92,11 @@ const ConfigurePrivacyExperience = ({

const router = useRouter();

const { data: appConfig } = useGetConfigurationSettingsQuery({
api_set: false,
});
const translationsEnabled = appConfig?.consent?.enable_translations;

const languagePage = useAppSelector(selectLanguagePage);
const languagePageSize = useAppSelector(selectLanguagePageSize);
useGetAllLanguagesQuery({ page: languagePage, size: languagePageSize });
Expand Down Expand Up @@ -184,12 +190,14 @@ const ConfigurePrivacyExperience = ({
{translationToEdit ? (
<PrivacyExperienceTranslationForm
translation={translationToEdit}
translationsEnabled={translationsEnabled}
isOOB={usingOOBValues}
onReturnToMainForm={handleExitTranslationForm}
/>
) : (
<PrivacyExperienceForm
allPrivacyNotices={allPrivacyNotices}
translationsEnabled={translationsEnabled}
onSelectTranslation={handleTranslationSelected}
onCreateTranslation={handleCreateNewTranslation}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const NewJavaScriptTag = ({ property }: Props) => {
const fidesJsScriptTag = useMemo(() => {
const script = FIDES_JS_SCRIPT_TEMPLATE.replace(
PROPERTY_UNIQUE_ID_TEMPLATE,
property.id.toString()
property.id!.toString()
);
if (isFidesCloud && isSuccess && fidesCloudConfig?.privacy_center_url) {
script.replace(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
ArrowForwardIcon,
Box,
Button,
ButtonGroup,
Expand Down Expand Up @@ -81,10 +82,12 @@ export const PrivacyExperienceConfigColumnLayout = ({

export const PrivacyExperienceForm = ({
allPrivacyNotices,
translationsEnabled,
onSelectTranslation,
onCreateTranslation,
}: {
allPrivacyNotices: LimitedPrivacyNoticeResponseSchema[];
translationsEnabled?: boolean;
onSelectTranslation: (t: ExperienceTranslation) => void;
onCreateTranslation: (lang: SupportedLanguage) => ExperienceTranslation;
}) => {
Expand Down Expand Up @@ -241,34 +244,48 @@ export const PrivacyExperienceForm = ({
getItemLabel={(item) => PRIVACY_NOTICE_REGION_RECORD[item]}
draggable
/>
<ScrollableList
label="Languages for this experience"
addButtonLabel="Add language"
values={values.translations ?? []}
setValues={(newValues) => setFieldValue("translations", newValues)}
idField="language"
canDeleteItem={(item) => !item.is_default}
allItems={allLanguages
.slice()
.sort((a, b) => a.name.localeCompare(b.name))
.map((lang) => ({
language: lang.id as SupportedLanguage,
is_default: false,
}))}
getItemLabel={getTranslationDisplayName}
createNewValue={(opt) =>
onCreateTranslation(opt.value as SupportedLanguage)
}
onRowClick={onSelectTranslation}
selectOnAdd
draggable
/>
<CustomSwitch
name="auto_detect_language"
id="auto_detect_language"
label="Auto detect language"
variant="stacked"
/>
{translationsEnabled ? (
<>
<ScrollableList
label="Languages for this experience"
addButtonLabel="Add language"
values={values.translations ?? []}
setValues={(newValues) => setFieldValue("translations", newValues)}
idField="language"
canDeleteItem={(item) => !item.is_default}
allItems={allLanguages
.slice()
.sort((a, b) => a.name.localeCompare(b.name))
.map((lang) => ({
language: lang.id as SupportedLanguage,
is_default: false,
}))}
getItemLabel={getTranslationDisplayName}
createNewValue={(opt) =>
onCreateTranslation(opt.value as SupportedLanguage)
}
onRowClick={onSelectTranslation}
selectOnAdd
draggable
/>
<CustomSwitch
name="auto_detect_language"
id="auto_detect_language"
label="Auto detect language"
variant="stacked"
/>
</>
) : (
<Button
variant="outline"
size="sm"
rightIcon={<ArrowForwardIcon />}
onClick={() => onSelectTranslation(values.translations![0])}
data-testid="edit-experience-btn"
>
Edit experience text
</Button>
)}
</PrivacyExperienceConfigColumnLayout>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ export const OOBTranslationNotice = ({

const PrivacyExperienceTranslationForm = ({
translation,
translationsEnabled,
isOOB,
onReturnToMainForm,
}: {
translation: TranslationWithLanguageName;
translationsEnabled?: boolean;
isOOB?: boolean;
onReturnToMainForm: () => void;
}) => {
Expand Down Expand Up @@ -148,46 +150,57 @@ const PrivacyExperienceTranslationForm = ({
</ButtonGroup>
);

let unsavedChangesMessage;
if (!translationsEnabled) {
unsavedChangesMessage =
"You have unsaved changes to this experience text. Discard changes?";
} else {
unsavedChangesMessage = isEditing
? "You have unsaved changes to this translation. Discard changes?"
: "This translation has not been added to your experience. Discard translation?";
}

return (
<PrivacyExperienceConfigColumnLayout buttonPanel={buttonPanel}>
<BackButtonNonLink onClick={handleLeaveForm} mt={4} />
<WarningModal
isOpen={unsavedChangesIsOpen}
onClose={onCloseUnsavedChanges}
title="Translation not saved"
message={
<Text>
{isEditing
? "You have unsaved changes to this translation. Discard changes?"
: "This translation has not been added to your experience. Discard translation?"}
</Text>
}
title={translationsEnabled ? "Translation not saved" : "Text not saved"}
message={<Text>{unsavedChangesMessage}</Text>}
confirmButtonText="Discard"
handleConfirm={discardChanges}
/>
<WarningModal
isOpen={newDefaultIsOpen}
onClose={onCloseNewDefault}
title="Update default language"
message={
<Text>
Are you sure you want to update the default language of this
experience?
</Text>
}
handleConfirm={() => setNewDefaultTranslation(translationIndex)}
/>
<Heading fontSize="md" fontWeight="semibold">
Edit {translation.name} translation
{translationsEnabled
? `Edit ${translation.name} translation`
: "Edit experience text"}
</Heading>
{isOOB ? <OOBTranslationNotice languageName={translation.name} /> : null}
<CustomSwitch
name={`translations.${translationIndex}.is_default`}
id={`translations.${translationIndex}.is_default`}
label="Default language"
isDisabled={initialTranslation.is_default}
variant="stacked"
/>
{translationsEnabled ? (
<>
<CustomSwitch
name={`translations.${translationIndex}.is_default`}
id={`translations.${translationIndex}.is_default`}
label="Default language"
isDisabled={initialTranslation.is_default}
variant="stacked"
/>
<WarningModal
isOpen={newDefaultIsOpen}
onClose={onCloseNewDefault}
title="Update default language"
message={
<Text>
Are you sure you want to update the default language of this
experience?
</Text>
}
handleConfirm={() => setNewDefaultTranslation(translationIndex)}
/>
</>
) : null}

<CustomTextInput
name={`translations.${translationIndex}.title`}
id={`translations.${translationIndex}.title`}
Expand Down
Loading

0 comments on commit dd1f329

Please sign in to comment.