Skip to content

Commit

Permalink
Basic consent reporting UI (#4488)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpople committed Dec 7, 2023
1 parent 92ecd09 commit 69145d8
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The types of changes are:
- TCF override management [#4484](https://github.com/ethyca/fides/pull/4484)
- Readonly consent management table and modal [#4456](https://github.com/ethyca/fides/pull/4456), [#4477](https://github.com/ethyca/fides/pull/4477)
- Access and erasure support for Gong [#4461](https://github.com/ethyca/fides/pull/4461)
- Add new UI for CSV consent reporting [#4488](https://github.com/ethyca/fides/pull/4488)

### Changed
- Increased max number of preferences allowed in privacy preference API calls [#4469](https://github.com/ethyca/fides/pull/4469)
Expand Down
79 changes: 79 additions & 0 deletions clients/admin-ui/cypress/e2e/consent-reporting.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { stubPlus } from "cypress/support/stubs";

import { CONSENT_REPORTING_ROUTE } from "~/features/common/nav/v2/routes";

describe("Consent reporting", () => {
beforeEach(() => {
cy.login();
});

describe("access", () => {
it("can access the consent reporting page", () => {
stubPlus(true, {
core_fides_version: "1.9.6",
fidesplus_server: "healthy",
fidesplus_version: "1.9.6",
system_scanner: {
enabled: false,
cluster_health: null,
cluster_error: null,
},
dictionary: {
enabled: false,
service_health: null,
service_error: null,
},
tcf: {
enabled: false,
},
fides_cloud: {
enabled: false,
},
});
cy.visit(CONSENT_REPORTING_ROUTE);
cy.getByTestId("consent-reporting");
});
it("can't access without plus", () => {
stubPlus(false);
cy.visit(CONSENT_REPORTING_ROUTE);
cy.getByTestId("home-content");
});
});

describe("downloading reports", () => {
beforeEach(() => {
stubPlus(true, {
core_fides_version: "1.9.6",
fidesplus_server: "healthy",
fidesplus_version: "1.9.6",
system_scanner: {
enabled: false,
cluster_health: null,
cluster_error: null,
},
dictionary: {
enabled: false,
service_health: null,
service_error: null,
},
tcf: {
enabled: false,
},
fides_cloud: {
enabled: false,
},
});
cy.visit(CONSENT_REPORTING_ROUTE);
});
it("can request a report", () => {
cy.intercept({
url: "/api/v1/plus/consent_reporting*",
method: "GET",
}).as("getConsentReport");
cy.getByTestId("input-from-date").type("2023-11-01");
cy.getByTestId("input-to-date").type("2023-11-07");
cy.getByTestId("download-btn").click();
cy.wait("@getConsentReport");
});
});
});
1 change: 1 addition & 0 deletions clients/admin-ui/src/features/common/api.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const baseApi = createApi({
"User",
"Configuration Settings",
"TCF Purpose Override",
"Consent Reporting",
],
endpoints: () => ({}),
});
7 changes: 7 additions & 0 deletions clients/admin-ui/src/features/common/nav/v2/nav-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ export const NAV_CONFIG: NavConfigGroup[] = [
requiresPlus: true,
scopes: [ScopeRegistryEnum.PRIVACY_EXPERIENCE_READ],
},
{
title: "Consent reporting",
path: routes.CONSENT_REPORTING_ROUTE,
requiresFlag: "consentReporting",
requiresPlus: true,
scopes: [ScopeRegistryEnum.PRIVACY_NOTICE_READ],
},
],
},
{
Expand Down
1 change: 1 addition & 0 deletions clients/admin-ui/src/features/common/nav/v2/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const PRIVACY_EXPERIENCE_ROUTE = "/consent/privacy-experience";
export const PRIVACY_NOTICES_ROUTE = "/consent/privacy-notices";
export const CONFIGURE_CONSENT_ROUTE = "/consent/configure";
export const ADD_MULTIPLE_VENDORS_ROUTE = "/consent/configure/add-vendors";
export const CONSENT_REPORTING_ROUTE = "/consent/reporting";

// Management group
export const USER_MANAGEMENT_ROUTE = "/user-management";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
Button,
HStack,
Input,
InputGroup,
InputLeftAddon,
useToast,
} from "@fidesui/react";
import { useState } from "react";

import { getErrorMessage } from "~/features/common/helpers";
import { useLazyDownloadReportQuery } from "~/features/consent-reporting/consent-reporting.slice";

const ConsentReporting = () => {
const [startDate, setStartDate] = useState<string>("");
const [endDate, setEndDate] = useState<string>("");

const toast = useToast();

const [downloadReportTrigger, { isLoading }] = useLazyDownloadReportQuery();

const handleDownloadClicked = async () => {
const result = await downloadReportTrigger({ startDate, endDate });
if (result.isError) {
const message = getErrorMessage(
result.error,
"A problem occurred while generating your consent report. Please try again."
);
toast({ status: "error", description: message });
} else {
const a = document.createElement("a");
const csvBlob = new Blob([result.data], { type: "text/csv" });
a.href = window.URL.createObjectURL(csvBlob);
a.download = `consent-reports.csv`;
a.click();
}
};

return (
<HStack gap={4} maxWidth="720px" data-testid="consent-reporting">
<InputGroup size="sm" flex={1}>
<InputLeftAddon borderRadius="md">From</InputLeftAddon>
<Input
type="date"
name="From"
value={startDate}
max={endDate || undefined}
onChange={(e) => setStartDate(e.target.value)}
borderRadius="md"
data-testid="input-from-date"
/>
</InputGroup>
<InputGroup size="sm" flex={1}>
<InputLeftAddon borderRadius="md">To</InputLeftAddon>
<Input
type="date"
name="To"
value={endDate}
min={startDate || undefined}
onChange={(e) => setEndDate(e.target.value)}
borderRadius="md"
data-testid="input-to-date"
/>
</InputGroup>
<Button
onClick={handleDownloadClicked}
isLoading={isLoading}
colorScheme="primary"
size="sm"
data-testid="download-btn"
>
Download report
</Button>
</HStack>
);
};

export default ConsentReporting;
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { baseApi } from "~/features/common/api.slice";

type DateRange = {
startDate?: string;
endDate?: string;
};

export function convertDateRangeToSearchParams({
startDate,
endDate,
}: DateRange) {
let startDateISO;
if (startDate) {
startDateISO = new Date(startDate);
startDateISO.setUTCHours(0, 0, 0);
}

let endDateISO;
if (endDate) {
endDateISO = new Date(endDate);
endDateISO.setUTCHours(0, 0, 0);
}

return {
...(startDateISO ? { created_gt: startDateISO.toISOString() } : {}),
...(endDateISO ? { created_lt: endDateISO.toISOString() } : {}),
};
}

export const consentReportingApi = baseApi.injectEndpoints({
endpoints: (build) => ({
downloadReport: build.query<any, DateRange>({
query: ({ startDate, endDate }) => {
const params = {
...convertDateRangeToSearchParams({ startDate, endDate }),
download_csv: "true",
};
return {
url: "plus/consent_reporting",
params,
responseHandler: "content-type",
};
},
providesTags: ["Consent Reporting"],
}),
}),
});

export const { useLazyDownloadReportQuery } = consentReportingApi;
6 changes: 6 additions & 0 deletions clients/admin-ui/src/flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,11 @@
"development": true,
"test": true,
"production": false
},
"consentReporting": {
"description": "Page to download consent reports by date",
"development": true,
"test": true,
"production": false
}
}
44 changes: 44 additions & 0 deletions clients/admin-ui/src/pages/consent/reporting/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Box, Breadcrumb, BreadcrumbItem, Heading, Text } from "@fidesui/react";
import NextLink from "next/link";
import React from "react";

import Layout from "~/features/common/Layout";
import { CONSENT_REPORTING_ROUTE } from "~/features/common/nav/v2/routes";
import ConsentReporting from "~/features/consent-reporting/ConsentReporting";

const ConsentReportingPage = () => (
<Layout title="Configure consent">
<Box mb={4}>
<Heading fontSize="2xl" fontWeight="semibold" mb={2} data-testid="header">
Configure consent
</Heading>
<Box>
<Breadcrumb
fontWeight="medium"
fontSize="sm"
color="gray.600"
data-testid="breadcrumbs"
>
<BreadcrumbItem>
<NextLink href={CONSENT_REPORTING_ROUTE}>Consent</NextLink>
</BreadcrumbItem>
<BreadcrumbItem color="complimentary.500">
<NextLink href="#">Reporting</NextLink>
</BreadcrumbItem>
</Breadcrumb>
</Box>
</Box>
<Text fontSize="sm" mb={8} width={{ base: "100%", lg: "50%" }}>
Download a CSV containing a report of consent preferences made by users on
your sites. Select a date range below and click &quot;Download
report&quot;. Depending on the number of records in the date range you
select, it may take several minutes to prepare the file after you click
&quot;Download report&quot;.
</Text>
<Box data-testid="consent">
<ConsentReporting />
</Box>
</Layout>
);

export default ConsentReportingPage;

0 comments on commit 69145d8

Please sign in to comment.