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

3271 data categories for manual connectors #3330

Merged
merged 7 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The types of changes are:
- Add infrastructure for "overlay" consent components (Preact, CSS bundling, etc.) and initial version of consent banner [#3191](https://github.com/ethyca/fides/pull/3191)
- Support pseudonymous consent requests with `fides_user_device_id` for the new consent workflow [#3203](https://github.com/ethyca/fides/pull/3203)
- Fides user device id filter to GET Privacy Experience List endpoint to stash user preferences on embedded notices [#3302](https://github.com/ethyca/fides/pull/3302)
- Support for data categories on manual webhook fields [#3330](https://github.com/ethyca/fides/pull/3330)

### Changed

Expand Down
32 changes: 18 additions & 14 deletions clients/admin-ui/src/features/common/form/inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export interface Option {
label: string;
}
interface SelectProps {
label: string;
label?: string;
labelProps?: FormLabelProps;
tooltip?: string;
options: Option[];
Expand Down Expand Up @@ -429,10 +429,12 @@ export const CustomSelect = ({
if (variant === "inline") {
return (
<FormControl isInvalid={isInvalid} isRequired={isRequired}>
<Grid templateColumns="1fr 3fr">
<Label htmlFor={props.id || props.name} {...labelProps}>
{label}
</Label>
<Grid templateColumns={label ? "1fr 3fr" : "1fr"}>
{label ? (
<Label htmlFor={props.id || props.name} {...labelProps}>
{label}
</Label>
) : null}
<Flex alignItems="center" data-testid={`input-${field.name}`}>
<Flex flexDir="column" flexGrow={1} mr={2}>
<SelectInput
Expand Down Expand Up @@ -465,15 +467,17 @@ export const CustomSelect = ({
<FormControl isInvalid={isInvalid} isRequired={isRequired}>
<VStack alignItems="start">
<Flex alignItems="center">
<Label
htmlFor={props.id || props.name}
fontSize="sm"
my={0}
mr={1}
{...labelProps}
>
{label}
</Label>
{label ? (
<Label
htmlFor={props.id || props.name}
fontSize="sm"
my={0}
mr={1}
{...labelProps}
>
{label}
</Label>
) : null}
{tooltip ? <QuestionTooltip label={tooltip} /> : null}
</Flex>
<Box width="100%" data-testid={`input-${field.name}`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { useRouter } from "next/router";
import React from "react";
import * as Yup from "yup";

import { useAppSelector } from "~/app/hooks";
import { CustomSelect } from "~/features/common/form/inputs";
import { DATASTORE_CONNECTION_ROUTE } from "~/features/common/nav/v2/routes";
import { useGetAllDataCategoriesQuery } from "~/features/taxonomy";
import { selectDataCategories } from "~/features/taxonomy/taxonomy.slice";

import CustomInput from "../forms/CustomInput";
import { ButtonGroup as ManualButtonGroup } from "./ButtonGroup";
Expand All @@ -22,6 +26,9 @@ const DSRCustomizationForm: React.FC<DSRCustomizationFormProps> = ({
isSubmitting = false,
onSaveClick,
}) => {
const { isLoading: isLoadingDataCategories } = useGetAllDataCategoriesQuery();
const allDataCategories = useAppSelector(selectDataCategories);

const router = useRouter();
const { errorAlert } = useAlert();

Expand All @@ -38,6 +45,10 @@ const DSRCustomizationForm: React.FC<DSRCustomizationFormProps> = ({
onSaveClick(values, actions);
};

if (isLoadingDataCategories) {
return null;
}

return (
<Formik
enableReinitialize
Expand All @@ -49,6 +60,7 @@ const DSRCustomizationForm: React.FC<DSRCustomizationFormProps> = ({
{
pii_field: "",
dsr_package_label: "",
data_categories: [],
},
] as Field[]),
}}
Expand All @@ -68,6 +80,7 @@ const DSRCustomizationForm: React.FC<DSRCustomizationFormProps> = ({
.min(1, "DSR Package Label must have at least one character")
.max(200, "DSR Package Label has a maximum of 200 characters")
.label("DSR Package Label"),
data_categories: Yup.array(Yup.string()).label("Data Categories"),
})
),
})}
Expand All @@ -93,36 +106,49 @@ const DSRCustomizationForm: React.FC<DSRCustomizationFormProps> = ({
>
<Box w="416px">PII Field</Box>
<Box w="416px">DSR Package Label</Box>
<Box />
<Box w="416px">Data Categories</Box>
<Box visibility="hidden">
<TrashCanSolidIcon />
</Box>
</HStack>
<Box
maxH="calc(100vh - 484px)"
paddingRight="13px"
overflow="auto"
>
<Box>
{fields && fields.length > 0
? fields.map((_field: Field, index: number) => (
<HStack
// eslint-disable-next-line react/no-array-index-key
key={index}
mt={index > 0 ? "12px" : undefined}
spacing="24px"
align="flex-start"
>
<Box h="57px" w="416px">
<Box minH="57px" w="416px">
<CustomInput
autoFocus={index === 0}
displayHelpIcon={false}
isRequired
name={`fields.${index}.pii_field`}
/>
</Box>
<Box h="57px" w="416px">
<Box minH="57px" w="416px">
<CustomInput
displayHelpIcon={false}
isRequired
name={`fields.${index}.dsr_package_label`}
/>
</Box>
<Box minH="57px" w="416px">
<CustomSelect
name={`fields.${index}.data_categories`}
options={allDataCategories.map(
(data_category) => ({
value: data_category.fides_key,
label: data_category.fides_key,
})
)}
isRequired
isMulti
/>
</Box>
<Box
h="57px"
visibility={index > 0 ? "visible" : "hidden"}
Expand All @@ -146,6 +172,7 @@ const DSRCustomizationForm: React.FC<DSRCustomizationFormProps> = ({
fieldArrayProps.push({
pii_field: "",
dsr_package_label: "",
data_categories: [],
});
}}
_hover={{ cursor: "pointer" }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type Field = {
pii_field: string;
dsr_package_label: string;
data_categories?: string[];
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
export type ManualWebhookField = {
pii_field: string;
dsr_package_label?: string;
data_categories?: string[];
};
2 changes: 2 additions & 0 deletions src/fides/api/schemas/manual_webhook_schemas.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import TYPE_CHECKING, List, Optional, Set

from fideslang.validation import FidesKey
from pydantic import ConstrainedStr, conlist, validator

from fides.api.schemas.base_class import FidesSchema
Expand Down Expand Up @@ -29,6 +30,7 @@ class ManualWebhookField(FidesSchema):

pii_field: PIIFieldType
dsr_package_label: Optional[DSRLabelFieldType] = None
data_categories: Optional[List[FidesKey]] = None

@validator("dsr_package_label")
def convert_empty_string_dsr_package_label(
Expand Down
12 changes: 10 additions & 2 deletions tests/fixtures/manual_webhook_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ def access_manual_webhook(db, integration_manual_webhook_config) -> ConnectionCo
data={
"connection_config_id": integration_manual_webhook_config.id,
"fields": [
{"pii_field": "email", "dsr_package_label": "email"},
{"pii_field": "Last Name", "dsr_package_label": "last_name"},
{
"pii_field": "email",
"dsr_package_label": "email",
"data_categories": ["user.contact.email"],
},
{
"pii_field": "Last Name",
"dsr_package_label": "last_name",
"data_categories": ["user.name"],
},
],
},
)
Expand Down
Loading