Skip to content

Commit

Permalink
ui/dataset: "Classify" toggle for fidesctl-plus (#1057)
Browse files Browse the repository at this point in the history
* ui/dataset: Spacing improvements for generate form

* ui/inputs: CustomSwitch component for switches

* ui/dataset: "Classify" toggle for fidesctl-plus

* ui/dataset: Cypress test when classify is available

* Update changelog
  • Loading branch information
ssangervasi authored and PSalant726 committed Sep 20, 2022
1 parent f31e96a commit 25e6c4e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 29 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ The types of changes are:

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

* Changed behavior of `load_default_taxonomy` to append instead of upsert [#1040](https://github.com/ethyca/fides/pull/1040)
### Added

* Dataset generation enhancements using Fides Classify for Plus users:
* Added toggle for enabling classify during generation. [#1057](https://github.com/ethyca/fides/pull/1057)
* New page to add a system via yaml [#1062](https://github.com/ethyca/fides/pull/1062)

### Changed

* Changed behavior of `load_default_taxonomy` to append instead of upsert [#1040](https://github.com/ethyca/fides/pull/1040)

## [1.8.4](https://github.com/ethyca/fides/compare/1.8.3...1.8.4) - 2022-09-09

### Added
Expand Down
27 changes: 27 additions & 0 deletions clients/ctl/admin-ui/cypress/e2e/datasets-classify.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* This test suite is a parallel of datests.cy.ts for testing Dataset features when the user has
* access to the Fidescls API. This suite should cover the behavior that is different when a
* dataset is classified.
*/
describe("Datasets with Fides Classify", () => {
beforeEach(() => {
cy.intercept("GET", "/api/v1/plus/health", {
statusCode: 200,
body: {
status: "healthy",
core_fidesctl_version: "1.8",
},
}).as("getPlusHealth");
});

describe("Creating datasets", () => {
it("Shows the classify switch", () => {
cy.visit("/dataset/new");
cy.getByTestId("connect-db-btn").click();

cy.getByTestId("input-classify").find("input").should("be.checked");
cy.getByTestId("input-classify").click();
cy.getByTestId("input-classify").find("input").should("not.be.checked");
});
});
});
36 changes: 36 additions & 0 deletions clients/ctl/admin-ui/src/features/common/form/inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Radio,
RadioGroup,
Stack,
Switch,
Textarea,
TextareaProps,
} from "@fidesui/react";
Expand Down Expand Up @@ -465,3 +466,38 @@ export const CustomRadioGroup = ({
</FormControl>
);
};

interface CustomSwitchProps {
label: string;
tooltip?: string;
}
export const CustomSwitch = ({
label,
tooltip,
...props
}: CustomSwitchProps & FieldHookConfig<boolean>) => {
const [field, meta] = useField({ ...props, type: "checkbox" });
const isInvalid = !!(meta.touched && meta.error);

return (
<FormControl isInvalid={isInvalid}>
<Grid templateColumns="1fr 3fr" justifyContent="center">
<FormLabel htmlFor={props.id || props.name} my={0}>
{label}
</FormLabel>
<Box display="flex" alignItems="center">
<Switch
name={field.name}
isChecked={field.checked}
onChange={field.onChange}
onBlur={field.onBlur}
colorScheme="secondary"
mr={2}
data-testid={`input-${field.name}`}
/>
{tooltip ? <QuestionTooltip label={tooltip} /> : null}
</Box>
</Grid>
</FormControl>
);
};
69 changes: 41 additions & 28 deletions clients/ctl/admin-ui/src/features/dataset/DatabaseConnectForm.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { Box, Button, Spinner, Text, useToast } from "@fidesui/react";
import { Box, Button, Text, useToast, VStack } from "@fidesui/react";
import { SerializedError } from "@reduxjs/toolkit";
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
import { Form, Formik, FormikHelpers } from "formik";
import { useRouter } from "next/router";
import * as Yup from "yup";

import { useFeatures } from "~/features/common/features.slice";
import { DEFAULT_ORGANIZATION_FIDES_KEY } from "~/features/organization";
import {
Dataset,
GenerateResponse,
GenerateTypes,
ValidTargets,
} from "~/types/api";

import { CustomTextInput } from "../common/form/inputs";
import { CustomSwitch, CustomTextInput } from "../common/form/inputs";
import { getErrorMessage } from "../common/helpers";
import { successToastParams } from "../common/toast";
import {
Expand All @@ -21,7 +23,7 @@ import {
useGenerateDatasetMutation,
} from "./dataset.slice";

const initialValues = { url: "" };
const initialValues = { url: "", classify: false };

type FormValues = typeof initialValues;

Expand All @@ -30,12 +32,13 @@ const ValidationSchema = Yup.object().shape({
});

const DatabaseConnectForm = () => {
// TODO: where should this come from?
const organizationKey = "default_organization";
const [generate, { isLoading: isGenerating }] = useGenerateDatasetMutation();
const [createDataset, { isLoading: isCreating }] = useCreateDatasetMutation();
const isLoading = isGenerating || isCreating;

const toast = useToast();
const router = useRouter();
const features = useFeatures();

const handleSubmit = async (
values: FormValues,
Expand Down Expand Up @@ -65,7 +68,7 @@ const DatabaseConnectForm = () => {
};

const response = await generate({
organization_key: organizationKey,
organization_key: DEFAULT_ORGANIZATION_FIDES_KEY,
generate: {
config: { connection_string: values.url },
target: ValidTargets.DB,
Expand All @@ -83,35 +86,45 @@ const DatabaseConnectForm = () => {

return (
<Formik
initialValues={initialValues}
initialValues={{ ...initialValues, classify: features.plus }}
validationSchema={ValidationSchema}
onSubmit={handleSubmit}
validateOnChange={false}
validateOnBlur={false}
>
{({ isSubmitting }) => (
<Form>
<Text size="sm" color="gray.700" mb={8}>
Connect to one of your databases using a connection URL. You may
have received this URL from a colleague or your Ethyca developer
support engineer.
</Text>
<Box mb={8}>
<CustomTextInput name="url" label="Database URL" />
</Box>
<Box display="flex" alignItems="center">
<Button
size="sm"
colorScheme="primary"
type="submit"
disabled={isSubmitting}
mr="2"
data-testid="create-dataset-btn"
>
Create dataset
</Button>
{isGenerating || isCreating ? <Spinner /> : null}
</Box>
<VStack spacing={8} align="left">
<Text size="sm" color="gray.700">
Connect to one of your databases using a connection URL. You may
have received this URL from a colleague or your Ethyca developer
support engineer.
</Text>
<Box>
<CustomTextInput name="url" label="Database URL" />
</Box>

{features.plus ? (
<CustomSwitch
name="classify"
label="Classify dataset"
tooltip="In addition to generating the Dataset, Fidescls will scan the database to determine the locations of possible PII and suggest labels based on the contents of your tables."
/>
) : null}

<Box>
<Button
size="sm"
colorScheme="primary"
type="submit"
isLoading={isSubmitting || isLoading}
isDisabled={isSubmitting || isLoading}
data-testid="create-dataset-btn"
>
Generate dataset
</Button>
</Box>
</VStack>
</Form>
)}
</Formik>
Expand Down

0 comments on commit 25e6c4e

Please sign in to comment.