Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding source and submitted_by fields to privacy request #5206

Merged
merged 20 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .fides/db_dataset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,8 @@ dataset:
data_categories: [system.operations]
- name: property_id
data_categories: [system.operations]
- name: source
data_categories: [system.operations]
- name: custom_connector_template
description: 'A table used to hold custom connector templates which include a SaaS config, dataset, and an optional icon and functions'
data_categories: []
Expand Down Expand Up @@ -1293,6 +1295,10 @@ dataset:
data_categories: [ system.operations ]
- name: custom_privacy_request_fields_approved_by
data_categories: [ system.operations ]
- name: source
data_categories: [ system.operations ]
- name: submitted_by
data_categories: [ system.operations ]
- name: privacyrequesterror
data_categories: []
fields:
Expand Down
24 changes: 16 additions & 8 deletions clients/admin-ui/cypress/fixtures/privacy-requests/list.json
galvana marked this conversation as resolved.
Show resolved Hide resolved
galvana marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_6411a2ea-72d2-4111-aad3-9170ba5e5934",
Expand Down Expand Up @@ -96,7 +97,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_34650722-960c-4abd-b6a6-6dba4461dfbe",
Expand Down Expand Up @@ -142,7 +144,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_8750c782-3fad-4ae6-bbcf-219f70f537ee",
Expand Down Expand Up @@ -188,7 +191,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_8f719d4a-848d-42b9-8aaa-e7ac442ebba0",
Expand Down Expand Up @@ -234,7 +238,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_a0fe994d-f1ee-40d9-bbcb-dedb76a08efe",
Expand Down Expand Up @@ -280,7 +285,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_741784e9-1d75-4a6c-bdf7-66c9c814f1c1",
Expand Down Expand Up @@ -326,7 +332,8 @@
},
"action_required_details": null,
"resume_endpoint": null,
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
},
{
"id": "pri_4f87b8b0-f97e-45e7-8561-300a6a932d04",
Expand Down Expand Up @@ -376,7 +383,8 @@
"action_needed": null
},
"resume_endpoint": "/privacy-request/pri_4f87b8b0-f97e-45e7-8561-300a6a932d04/retry",
"days_left": 45
"days_left": 45,
"source": "Privacy Center"
}
],
"total": 8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

import ClipboardButton from "~/features/common/ClipboardButton";
import DaysLeftTag from "~/features/common/DaysLeftTag";
import { useFeatures } from "~/features/common/features";
import RequestStatusBadge from "~/features/common/RequestStatusBadge";
import RequestType from "~/features/common/RequestType";
import { PrivacyRequestEntity } from "~/features/privacy-requests/types";
Expand All @@ -25,6 +26,7 @@ type RequestDetailsProps = {
};

const RequestDetails = ({ subjectRequest }: RequestDetailsProps) => {
const { plus: hasPlus } = useFeatures();
const { id, status, policy } = subjectRequest;

return (
Expand Down Expand Up @@ -55,7 +57,23 @@ const RequestDetails = ({ subjectRequest }: RequestDetailsProps) => {
</Text>
<ClipboardButton copyText={id} />
</Flex>

{hasPlus && subjectRequest.source && (
<Flex>
<Text mb={4} mr={2} fontSize="sm" color="gray.900" fontWeight="500">
Source:
</Text>
<Box>
<Tag
color="white"
bg="primary.400"
fontWeight="medium"
fontSize="sm"
>
{subjectRequest.source}
galvana marked this conversation as resolved.
Show resolved Hide resolved
</Tag>
</Box>
</Flex>
)}
<Flex alignItems="center">
<Text mb={4} mr={2} fontSize="sm" color="gray.900" fontWeight="500">
Request type:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";

import { selectToken } from "~/features/auth";
import { useFeatures } from "~/features/common/features";
import { DownloadLightIcon } from "~/features/common/Icon";
import {
FidesTableV2,
Expand All @@ -43,6 +44,7 @@ import { RequestTableFilterModal } from "~/features/privacy-requests/RequestTabl
import { PrivacyRequestEntity } from "~/features/privacy-requests/types";

export const RequestTable = ({ ...props }: BoxProps): JSX.Element => {
const { plus: hasPlus } = useFeatures();
const [requestIdFilter, setRequestIdFilter] = useState<string>();
const [revealPII, setRevealPII] = useState<boolean>(false);
const filters = useSelector(selectPrivacyRequestFilters);
Expand Down Expand Up @@ -124,7 +126,10 @@ export const RequestTable = ({ ...props }: BoxProps): JSX.Element => {
const tableInstance = useReactTable<PrivacyRequestEntity>({
getCoreRowModel: getCoreRowModel(),
data: requests,
columns: useMemo(() => getRequestTableColumns(revealPII), [revealPII]),
columns: useMemo(
() => getRequestTableColumns(revealPII, hasPlus),
galvana marked this conversation as resolved.
Show resolved Hide resolved
[revealPII, hasPlus],
),
getRowId: (row) => `${row.status}-${row.id}`,
manualPagination: true,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { createColumnHelper } from "@tanstack/react-table";

import { DefaultCell, DefaultHeaderCell } from "~/features/common/table/v2";
import {
BadgeCell,
DefaultCell,
DefaultHeaderCell,
} from "~/features/common/table/v2";
import { formatDate, getPII } from "~/features/common/utils";
import {
RequestActionTypeCell,
Expand All @@ -14,9 +18,10 @@ import { PrivacyRequestEntity } from "~/features/privacy-requests/types";
enum COLUMN_IDS {
STATUS = "status",
DAYS_LEFT = "due_date",
SOURCE = "source",
REQUEST_TYPE = "request_type",
SUBJECT_IDENTITY = "subject_identity",
TIME_RECIEVED = "created_at",
TIME_RECEIVED = "created_at",
galvana marked this conversation as resolved.
Show resolved Hide resolved
CREATED_BY = "created_by",
REVIEWER = "reviewer",
ID = "id",
Expand All @@ -25,7 +30,7 @@ enum COLUMN_IDS {

const columnHelper = createColumnHelper<PrivacyRequestEntity>();

export const getRequestTableColumns = (revealPII = false) => [
export const getRequestTableColumns = (revealPII = false, hasPlus = false) => [
columnHelper.accessor((row) => row.status, {
id: COLUMN_IDS.STATUS,
cell: ({ getValue }) => <RequestStatusBadgeCell value={getValue()} />,
Expand All @@ -42,6 +47,21 @@ export const getRequestTableColumns = (revealPII = false) => [
),
header: (props) => <DefaultHeaderCell value="Days left" {...props} />,
}),
...(hasPlus
? [
columnHelper.accessor((row) => row.source, {
id: COLUMN_IDS.SOURCE,
cell: (props) =>
props.getValue() ? (
<BadgeCell value={props.getValue()!} />
) : (
<DefaultCell value={undefined} />
),
header: (props) => <DefaultHeaderCell value="Source" {...props} />,
enableSorting: false,
}),
]
: []),
galvana marked this conversation as resolved.
Show resolved Hide resolved
columnHelper.accessor((row) => row.policy.rules, {
id: COLUMN_IDS.REQUEST_TYPE,
cell: ({ getValue }) => <RequestActionTypeCell value={getValue()} />,
Expand All @@ -63,7 +83,7 @@ export const getRequestTableColumns = (revealPII = false) => [
},
),
columnHelper.accessor((row) => row.created_at, {
id: COLUMN_IDS.TIME_RECIEVED,
id: COLUMN_IDS.TIME_RECEIVED,
cell: ({ getValue }) => <DefaultCell value={formatDate(getValue())} />,
header: (props) => <DefaultHeaderCell value="Time received" {...props} />,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ const SubjectIdentities = ({ subjectRequest }: SubjectIdentitiesProps) => {
return (
<>
<Flex direction="row" justifyContent="space-between">
<Heading color="gray.900" fontSize="lg" fontWeight="semibold" mb={4}>
<Heading
color="gray.900"
fontSize="lg"
fontWeight="semibold"
mb={4}
mt={4}
galvana marked this conversation as resolved.
Show resolved Hide resolved
>
Subject identities
</Heading>
<Flex flexShrink={0} alignItems="flex-start">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PrivacyRequestStatus,
SecurityApplicationConfig,
} from "~/types/api";
import { PrivacyRequestSource } from "~/types/api/models/PrivacyRequestSource";

import type { RootState } from "../../app/store";
import { BASE_URL } from "../../constants";
Expand Down Expand Up @@ -317,7 +318,10 @@ export const privacyRequestApi = baseApi.injectEndpoints({
query: (payload) => ({
url: `privacy-request/authenticated`,
method: "POST",
body: payload,
body: payload.map((item) => ({
...item,
source: PrivacyRequestSource.REQUEST_MANAGER,
galvana marked this conversation as resolved.
Show resolved Hide resolved
})),
}),
invalidatesTags: () => ["Request"],
}),
Expand Down
1 change: 1 addition & 0 deletions clients/admin-ui/src/features/privacy-requests/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface PrivacyRequestEntity {
reviewed_by: string;
id: string;
days_left?: number;
source?: string;
}

export interface PrivacyRequestResponse {
Expand Down
1 change: 1 addition & 0 deletions clients/admin-ui/src/types/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ export type { PrivacyRequestOption } from "./models/PrivacyRequestOption";
export type { PrivacyRequestResponse } from "./models/PrivacyRequestResponse";
export type { PrivacyRequestResumeFormat } from "./models/PrivacyRequestResumeFormat";
export type { PrivacyRequestReviewer } from "./models/PrivacyRequestReviewer";
export { PrivacyRequestSource } from "./models/PrivacyRequestSource";
export { PrivacyRequestStatus } from "./models/PrivacyRequestStatus";
export type { PrivacyRequestTaskSchema } from "./models/PrivacyRequestTaskSchema";
export type { PrivacyRequestVerboseResponse } from "./models/PrivacyRequestVerboseResponse";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import type { fides__api__schemas__redis_cache__CustomPrivacyRequestField } from "./fides__api__schemas__redis_cache__CustomPrivacyRequestField";
import type { Identity } from "./Identity";
import type { PrivacyRequestSource } from "./PrivacyRequestSource";

/**
* An extension of the base fides model with the addition of plus-only fields
Expand All @@ -15,4 +16,5 @@ export type ConsentRequestCreateExtended = {
fides__api__schemas__redis_cache__CustomPrivacyRequestField
> | null;
property_id?: string | null;
source?: PrivacyRequestSource;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import type { Consent } from "./Consent";
import type { fides__api__schemas__redis_cache__CustomPrivacyRequestField } from "./fides__api__schemas__redis_cache__CustomPrivacyRequestField";
import type { Identity } from "./Identity";
import type { PrivacyRequestSource } from "./PrivacyRequestSource";

/**
* Data required to create a PrivacyRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import type { CheckpointActionRequiredDetails } from "./CheckpointActionRequiredDetails";
import type { PolicyResponse } from "./PolicyResponse";
import type { PrivacyRequestReviewer } from "./PrivacyRequestReviewer";
import type { PrivacyRequestSource } from "./PrivacyRequestSource";
import type { PrivacyRequestStatus } from "./PrivacyRequestStatus";

/**
Expand Down
13 changes: 13 additions & 0 deletions clients/admin-ui/src/types/api/models/PrivacyRequestSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

/**
* The source where the privacy request originated from
*/
export enum PrivacyRequestSource {
PRIVACY_CENTER = "Privacy Center",
REQUEST_MANAGER = "Request Manager",
CONSENT_WEBHOOK = "Consent Webhook",
FIDES_JS = "Fides.js",
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { CheckpointActionRequiredDetails } from "./CheckpointActionRequired
import type { ExecutionAndAuditLogResponse } from "./ExecutionAndAuditLogResponse";
import type { PolicyResponse } from "./PolicyResponse";
import type { PrivacyRequestReviewer } from "./PrivacyRequestReviewer";
import type { PrivacyRequestSource } from "./PrivacyRequestSource";
import type { PrivacyRequestStatus } from "./PrivacyRequestStatus";

/**
Expand Down
1 change: 1 addition & 0 deletions clients/cypress-e2e/cypress/e2e/smoke_test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe("Smoke test", () => {
},
policy_key: "default_access_policy",
property_id: null,
source: "Privacy Center",
},
]);
});
Expand Down
1 change: 1 addition & 0 deletions clients/fides-js/src/lib/consent-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ export type PrivacyPreferencesRequest = {
user_geography?: string;
method?: ConsentMethod;
served_notice_history_id?: string;
source?: string;
};

export type ConsentOptionCreate = {
Expand Down
2 changes: 1 addition & 1 deletion clients/fides-js/src/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export const patchUserPreference = async (
debugLog(options.debug, "Calling Fides save preferences API");
const fetchOptions: RequestInit = {
...PATCH_FETCH_OPTIONS,
body: JSON.stringify(preferences),
body: JSON.stringify({ ...preferences, source: "Fides.js" }),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possible to use a shared CONST here? instead of "Fides.js"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// See: PrivacyRequestSource enum in Fides
const REQUEST_SOURCE = "Fides.js";

};
const response = await fetch(
`${options.fidesApiUrl}${FidesEndpointPaths.PRIVACY_PREFERENCES}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { PhoneInput } from "~/components/phone-input";
import { defaultIdentityInput } from "~/constants";
import { useConfig } from "~/features/common/config.slice";
import { useSettings } from "~/features/common/settings.slice";
import { PrivacyRequestSource } from "~/types/api/models/PrivacyRequestSource";

type KnownKeys = {
email: string;
Expand Down Expand Up @@ -95,6 +96,7 @@ const useConsentRequestForm = ({
fides_user_device_id: cookie.identity.fides_user_device_id,
},
custom_privacy_request_fields: transformedCustomPrivacyRequestFields,
source: PrivacyRequestSource.PRIVACY_CENTER,
};
const handleError = ({
title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { useConfig } from "~/features/common/config.slice";
import { useProperty } from "~/features/common/property.slice";
import { useSettings } from "~/features/common/settings.slice";
import { PrivacyRequestStatus } from "~/types";
import { PrivacyRequestSource } from "~/types/api/models/PrivacyRequestSource";
import { CustomIdentity, PrivacyRequestOption } from "~/types/config";

type FormValues = {
Expand Down Expand Up @@ -157,6 +158,7 @@ const usePrivacyRequestForm = ({
}),
policy_key: action.policy_key,
property_id: property?.id || null,
source: PrivacyRequestSource.PRIVACY_CENTER,
},
];

Expand Down
Loading
Loading