Skip to content

Commit

Permalink
Merge branch 'main' into allow-no-content-response
Browse files Browse the repository at this point in the history
  • Loading branch information
galvana committed May 1, 2024
2 parents 7e0f1cd + e273a1d commit 9808330
Show file tree
Hide file tree
Showing 44 changed files with 1,237 additions and 282 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ The types of changes are:

## [Unreleased](https://github.com/ethyca/fides/compare/2.35.0...main)

### Added
- Added multiple language translations support for privacy center consent page [#4785](https://github.com/ethyca/fides/pull/4785)
- Added ability to export the contents of datamap report [#1545](https://ethyca.atlassian.net/browse/PROD-1545)

### Fixed
- Remove the extra 'white-space: normal' CSS for FidesJS HTML descriptions [#4850](https://github.com/ethyca/fides/pull/4850)

## [2.35.0](https://github.com/ethyca/fides/compare/2.34.0...2.35.0)

### Added
Expand All @@ -29,6 +36,7 @@ The types of changes are:
- Added `reinitialize` method to FidesJS SDK [#4812](https://github.com/ethyca/fides/pull/4812)
- Added undeclared data category columns to data map report table [#4781](https://github.com/ethyca/fides/pull/4781)
- Fully implement pre-approval webhooks [#4822](https://github.com/ethyca/fides/pull/4822)
- Sync models and database for pre-approval webhooks [#4838](https://github.com/ethyca/fides/pull/4838)

### Changed
- Removed the Celery startup banner from the Fides worker logs [#4814](https://github.com/ethyca/fides/pull/4814)
Expand All @@ -37,13 +45,16 @@ The types of changes are:
### Fixed
- Fixed bug prevented adding new privacy center translations [#4786](https://github.com/ethyca/fides/pull/4786)
- Fixed bug where Privacy Policy links would be shown without a configured URL [#4801](https://github.com/ethyca/fides/pull/4801)
- Fixed bug prevented adding new privacy center translations [#4786](https://github.com/ethyca/fides/pull/4786)
- Fixed bug where Language selector button was overlapping other buttons when Privacy Policy wasn't present. [#4815](https://github.com/ethyca/fides/pull/4815)
- Fixed bug where icons of the Language selector were displayed too small on some sites [#4815](https://github.com/ethyca/fides/pull/4815)
- Fixed bug where GPP US National Section was incorrectly included when the State by State approach was selected [#4823]https://github.com/ethyca/fides/pull/4823
- Fixed DSR 3.0 Scheduling bug where Approved Privacy Requests that failed wouldn't change status [#4837](https://github.com/ethyca/fides/pull/4837)

## [2.34.0](https://github.com/ethyca/fides/compare/2.33.1...2.34.0)

### Added

- Added new field for modal trigger link translation [#4761](https://github.com/ethyca/fides/pull/4761)
- Added `getModalLinkLabel` method to global fides object [#4766](https://github.com/ethyca/fides/pull/4766)
- Added language switcher to fides overlay modal [#4773](https://github.com/ethyca/fides/pull/4773)
Expand All @@ -52,6 +63,7 @@ The types of changes are:
- Added developer option to force GPP API on FidesJS bundles [#4799](https://github.com/ethyca/fides/pull/4799)

### Changed

- Changed the Stripe integration for `Cards` to delete instead of update due to possible issues of a past expiration date [#4768](https://github.com/ethyca/fides/pull/4768)
- Changed display of Data Uses, Categories and Subjects to user friendly names in the Data map report [#4774](https://github.com/ethyca/fides/pull/4774)
- Update active disabled Fides.js toggle color to light grey [#4778](https://github.com/ethyca/fides/pull/4778)
Expand All @@ -60,6 +72,7 @@ The types of changes are:
- Changed GPP extension to be pre-bundled in appropriate circumstances, as opposed to another fetch [#4780](https://github.com/ethyca/fides/pull/4780)

### Fixed

- Fixed select dropdowns being cut off by edges of modal forms [#4757](https://github.com/ethyca/fides/pull/4757)
- Changed "allow user to dismiss" toggle to show on config form for TCF experience [#4755](https://github.com/ethyca/fides/pull/4755)
- Fixed issue when loading the privacy request detail page [#4775](https://github.com/ethyca/fides/pull/4775)
Expand All @@ -68,11 +81,13 @@ The types of changes are:
- Fixed the way the name identity is handled in the Privacy Center [#4791](https://github.com/ethyca/fides/pull/4791)

### Developer Experience

- Build a `fides-types.d.ts` type declaration file to include alongside our FidesJS developer docs [#4772](https://github.com/ethyca/fides/pull/4772)

## [2.33.1](https://github.com/ethyca/fides/compare/2.33.0...2.33.1)

### Added

- Adds CUSTOM_OPTIONS_PATH to Privacy Center env vars [#4769](https://github.com/ethyca/fides/pull/4769)

## [2.33.0](https://github.com/ethyca/fides/compare/2.32.0...2.33.0)
Expand Down Expand Up @@ -107,8 +122,8 @@ The types of changes are:
- Initialization issues with ExperienceNotices (#4723)[https://github.com/ethyca/fides/pull/4723]
- Re-add CORS origin regex field to admin UI (#4742)[https://github.com/ethyca/fides/pull/4742]


### Developer Experience

- Added new script to allow recompiling of fides-js when the code changes [#4744](https://github.com/ethyca/fides/pull/4744)
- Update Cookie House to support for additional locations (Canada, Quebec, EEA) and a "property_id" override [#4750](https://github.com/ethyca/fides/pull/4750)

Expand Down
18 changes: 18 additions & 0 deletions clients/admin-ui/__tests__/features/common-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getFileNameFromContentDisposition } from "~/features/common/utils";

describe("common utils", () => {
describe(getFileNameFromContentDisposition.name, () => {
it('should return "export" when contentDisposition is null', () => {
expect(getFileNameFromContentDisposition(null)).toEqual("export");
});

it("should return the filename from the contentDisposition header", () => {
const contentDisposition = "attachment; filename=something-special.csv";
expect(getFileNameFromContentDisposition(contentDisposition)).toEqual(
"something-special.csv"
);
});
});
});

export default undefined;
17 changes: 17 additions & 0 deletions clients/admin-ui/cypress/e2e/datamap-report.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,21 @@ describe("Minimal datamap report table", () => {
});
});
});

describe("Exporting", () => {
it("should open the export modal", () => {
cy.getByTestId("export-btn").click();
cy.getByTestId("export-modal").should("be.visible");
cy.getByTestId("export-format-select").should("be.visible");
cy.getByTestId("export-modal-continue-btn").should(
"contain.text",
"Download"
);
cy.getByTestId("export-modal-cancel-btn").click();
cy.getByTestId("export-modal").should("not.exist");
});

// ideally we should test the downloads, but it's a bit complex and time consuming so deferring for now
it.skip("should download the export file", () => {});
});
});
81 changes: 81 additions & 0 deletions clients/admin-ui/src/features/common/modals/StandardDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
ModalProps,
ThemingProps,
} from "@fidesui/react";

export interface StandardDialogProps extends ModalProps {
heading?: string;
cancelButtonText?: string;
cancelButtonThemingProps?: ThemingProps<"Button">;
continueButtonText?: string;
continueButtonThemingProps?: ThemingProps<"Button">;
onCancel?: () => void;
onConfirm: () => void;
isLoading?: boolean;
"data-testid"?: string;
}

const StandardDialog = ({
children,
heading,
onCancel,
onConfirm,
isLoading,
cancelButtonText,
cancelButtonThemingProps,
continueButtonText,
continueButtonThemingProps,
"data-testid": testId = "standard-dialog",
...props
}: StandardDialogProps): JSX.Element => {
const { onClose } = props;
return (
<Modal closeOnOverlayClick={isLoading} {...props}>
<ModalOverlay />
<ModalContent data-testid={testId}>
{heading && <ModalHeader>{heading}</ModalHeader>}
<ModalCloseButton disabled={isLoading} />
{children && <ModalBody>{children}</ModalBody>}
<ModalFooter
gap={3}
width="100%"
sx={{ "& button": { width: "100%" } }}
>
<Button
variant="outline"
onClick={() => {
if (onCancel) {
onCancel();
}
onClose();
}}
data-testid={`${testId ? `${testId}-` : ""}cancel-btn`}
isDisabled={isLoading}
{...cancelButtonThemingProps}
>
{cancelButtonText || "Cancel"}
</Button>
<Button
colorScheme="primary"
onClick={onConfirm}
data-testid={`${testId ? `${testId}-` : ""}continue-btn`}
isLoading={isLoading}
{...cancelButtonThemingProps}
>
{continueButtonText || "Continue"}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};

export default StandardDialog;
11 changes: 11 additions & 0 deletions clients/admin-ui/src/features/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,14 @@ export const formatDate = (value: string | number | Date): string =>

export const utf8ToB64 = (str: string): string =>
window.btoa(unescape(encodeURIComponent(str)));

export const getFileNameFromContentDisposition = (
contentDisposition: string | null
) => {
const defaultName = "export";
if (!contentDisposition) {
return defaultName;
}
const match = contentDisposition.match(/filename=(.+)/);
return match ? match[1] : defaultName;
};
5 changes: 5 additions & 0 deletions clients/admin-ui/src/features/datamap/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export const ItemTypes = {
DraggableColumnListItem: "DraggableColumnListItem",
};

export enum ExportFormat {
csv = "csv",
xlsx = "xlsx",
}

export const SYSTEM_FIDES_KEY_COLUMN_ID = "system.fides_key";
export const SYSTEM_NAME = "system.name";
export const SYSTEM_PRIVACY_DECLARATION_DATA_USE_NAME =
Expand Down
58 changes: 58 additions & 0 deletions clients/admin-ui/src/features/datamap/datamap.slice.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { createSelector, createSlice, PayloadAction } from "@reduxjs/toolkit";
import { saveAs } from "file-saver";

import type { RootState } from "~/app/store";
import { baseApi } from "~/features/common/api.slice";
import { getFileNameFromContentDisposition } from "~/features/common/utils";
import {
COLUMN_NAME_MAP,
DATA_CATEGORY_COLUMN_ID,
ExportFormat,
SYSTEM_DESCRIPTION,
SYSTEM_NAME,
SYSTEM_PRIVACY_DECLARATION_DATA_SUBJECTS_NAME,
Expand Down Expand Up @@ -104,6 +107,60 @@ const datamapApi = baseApi.injectEndpoints({
},
providesTags: ["Datamap"],
}),
exportMinimalDatamapReport: build.mutation<
Page_DatamapReport_,
{
groupBy: DATAMAP_GROUPING;
pageIndex: number;
pageSize: number;
search: string;
dataUses?: string;
dataCategories?: string;
dataSubjects?: string;
format?: ExportFormat;
}
>({
query: ({
groupBy,
pageIndex,
pageSize,
search,
dataUses,
dataCategories,
dataSubjects,
format,
}) => {
let queryString = `page=${pageIndex}&size=${pageSize}&group_by=${groupBy}`;
if (dataUses) {
queryString += `&${dataUses}`;
}
if (dataCategories) {
queryString += `&${dataCategories}`;
}
if (dataSubjects) {
queryString += `&${dataSubjects}`;
}
if (search) {
queryString += `&search=${search}`;
}
return {
url: `plus/datamap/minimal/${format}?${queryString}`,
responseHandler: async (response) => {
const filename = await getFileNameFromContentDisposition(
response.headers.get("content-disposition")
);
const arrayBuffer = await response.arrayBuffer();
const blob = new Blob([arrayBuffer], {
type:
response.headers.get("content-type") ||
"application/octet-stream",
});
saveAs(blob, filename);
return { data: undefined }; // once the file is downloaded, we no longer want this to be cached in the browser so we return undefined to RTK Query
},
};
},
}),
getDatamap: build.query<DatamapTableData, { organizationName: string }>({
query: ({ organizationName }) => ({
url: `plus/datamap/${organizationName}`,
Expand Down Expand Up @@ -156,6 +213,7 @@ export const {
useGetDatamapQuery,
useLazyGetDatamapQuery,
useGetMinimalDatamapReportQuery,
useExportMinimalDatamapReportMutation,
} = datamapApi;

export interface SettingsState {
Expand Down
50 changes: 50 additions & 0 deletions clients/admin-ui/src/features/datamap/modals/ReportExportModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Flex, FormControl, FormLabel, Select, Text } from "@fidesui/react";
import { useState } from "react";

import StandardDialog, {
StandardDialogProps,
} from "~/features/common/modals/StandardDialog";
import { ExportFormat } from "~/features/datamap/constants";

interface ReportExportModalProps
extends Omit<StandardDialogProps, "children" | "onConfirm"> {
onConfirm: (downloadType: ExportFormat) => void;
}

const ReportExportModal = (props: ReportExportModalProps): JSX.Element => {
const [downloadType, setDownloadType] = useState<ExportFormat>(
ExportFormat.csv
);
const { onConfirm } = props;

return (
<StandardDialog
heading="Export report"
continueButtonText="Download"
size="xl"
{...props}
onConfirm={() => onConfirm(downloadType)}
data-testid="export-modal"
>
<Flex direction="column" gap={3} pb={3}>
<Text textAlign="left">
Export your data map report using the options below. Depending on the
number of rows, the file may take a few minutes to process.
</Text>
<FormControl>
<FormLabel>Choose Format</FormLabel>
<Select
value={downloadType}
onChange={(e) => setDownloadType(e.target.value as ExportFormat)}
data-testid="export-format-select"
>
<option value={ExportFormat.csv}>CSV</option>
<option value={ExportFormat.xlsx}>XLSX</option>
</Select>
</FormControl>
</Flex>
</StandardDialog>
);
};

export default ReportExportModal;
Loading

0 comments on commit 9808330

Please sign in to comment.