Skip to content

Commit

Permalink
[1073] ui/dataset: Show status badge for datasets using classificatio…
Browse files Browse the repository at this point in the history
…n results (#1074)

* ui/plus: Classifications grouped by dataset fides key

* ui/dataset: Show status badge for datasets using classification results

* ui/dataset: Cypress tests for classified table

* Update changelog
  • Loading branch information
ssangervasi authored and PSalant726 committed Sep 20, 2022
1 parent 11908bb commit 044863a
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The types of changes are:
* Dataset generation enhancements using Fides Classify for Plus users:
* Added toggle for enabling classify during generation. [#1057](https://github.com/ethyca/fides/pull/1057)
* Initial implementation of API request to kick off classify, with confirmation modal. [#1069](https://github.com/ethyca/fides/pull/1069)
* Initial Classification & Review status for generated datasets. [#1074](https://github.com/ethyca/fides/pull/1074)
* New page to add a system via yaml [#1062](https://github.com/ethyca/fides/pull/1062)
* Skeleton of page to add a system manually [#1068](https://github.com/ethyca/fides/pull/1068)

Expand Down
28 changes: 28 additions & 0 deletions clients/ctl/admin-ui/cypress/e2e/datasets-classify.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,32 @@ describe("Datasets with Fides Classify", () => {
cy.getByTestId("toast-success-msg");
});
});

describe("List of datasets with classifications", () => {
beforeEach(() => {
cy.intercept("GET", "/api/v1/dataset", { fixture: "datasets.json" }).as(
"getDatasets"
);
cy.intercept("GET", "/api/v1/plus/classification", {
fixture: "classification/list.json",
}).as("getClassificationList");
});

it("Shows the each dataset's classification status", () => {
cy.visit("/dataset");
cy.wait("@getDatasets");
cy.wait("@getClassificationList");
cy.getByTestId("dataset-table");
cy.getByTestId("dataset-status-demo_users_dataset").contains("Unknown");
cy.getByTestId("dataset-status-demo_users_dataset_2").contains(
"Processing"
);
cy.getByTestId("dataset-status-demo_users_dataset_3").contains(
"Awaiting Review"
);
cy.getByTestId("dataset-status-demo_users_dataset_4").contains(
"Classified"
);
});
});
});
45 changes: 45 additions & 0 deletions clients/ctl/admin-ui/cypress/fixtures/classification/list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[
{
"id": "2",
"fides_key": "demo_users_dataset_2",
"status": "processing"
},
{
"id": "3",
"fides_key": "demo_users_dataset_3",
"status": "review",
"classification": {
"data_categories": ["user"],
"collections": [
{
"name": "users",
"fields": [
{
"name": "device",
"data_categories": ["user.device"]
}
]
}
]
}
},
{
"id": "4",
"fides_key": "demo_users_dataset_4",
"status": "classified",
"classification": {
"data_categories": ["user"],
"collections": [
{
"name": "users",
"fields": [
{
"name": "device",
"data_categories": ["user.device"]
}
]
}
]
}
}
]
6 changes: 3 additions & 3 deletions clients/ctl/admin-ui/src/features/common/features.slice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useGetHealthQuery } from "./plus.slice";
import { useHasPlus } from "./plus.slice";

/**
* Features are currently stateless and only use the Plus API. However, this a ".slice" file because
Expand All @@ -9,9 +9,9 @@ export interface Features {
}

export const useFeatures = (): Features => {
const { isSuccess } = useGetHealthQuery();
const hasPlus = useHasPlus();

return {
plus: isSuccess,
plus: hasPlus,
};
};
39 changes: 38 additions & 1 deletion clients/ctl/admin-ui/src/features/common/plus.slice.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createSelector } from "@reduxjs/toolkit";
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

import { Dataset } from "~/types/api";
Expand Down Expand Up @@ -50,7 +51,43 @@ export const plusApi = createApi({
body,
}),
}),
getAllClassifications: build.query<ClassificationResponse[], void>({
query: () => `classification/`,
}),
}),
});

export const { useGetHealthQuery, useCreateClassificationMutation } = plusApi;
export const {
useGetHealthQuery,
useCreateClassificationMutation,
useGetAllClassificationsQuery,
} = plusApi;

export const useHasPlus = () => {
const { isSuccess: hasPlus } = useGetHealthQuery();
return hasPlus;
};

const emptyClassifications: ClassificationResponse[] = [];
const selectClassificationsMap = createSelector(
({ data }: { data?: ClassificationResponse[] }) =>
data ?? emptyClassifications,
(dataCategories) => ({
map: new Map(dataCategories.map((c) => [c.fides_key, c])),
})
);

/**
* Convenience hook for looking up a Classification by Dataset key.
*/
export const useClassificationsMap = (): Map<
string,
ClassificationResponse
> => {
const hasPlus = useHasPlus();
const { map } = useGetAllClassificationsQuery(undefined, {
skip: !hasPlus,
selectFromResult: selectClassificationsMap,
});
return map;
};
44 changes: 37 additions & 7 deletions clients/ctl/admin-ui/src/features/dataset/DatasetTable.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { Table, Tbody, Td, Th, Thead, Tr } from "@fidesui/react";
import {
Badge,
Table,
Tbody,
Td,
Th,
Thead,
Tooltip,
Tr,
} from "@fidesui/react";
import { useDispatch, useSelector } from "react-redux";

import { useClassificationsMap } from "~/features/common/plus.slice";
import { Dataset } from "~/types/api";

import { selectActiveDataset, setActiveDataset } from "./dataset.slice";
import { STATUS_DISPLAY } from "./constants";
import {
selectActiveDataset,
setActiveDataset,
useGetAllDatasetsQuery,
} from "./dataset.slice";

interface Props {
datasets: Dataset[] | undefined;
}

const DatasetsTable = ({ datasets }: Props) => {
const DatasetsTable = () => {
const dispatch = useDispatch();
const activeDataset = useSelector(selectActiveDataset);

const { data: datasets } = useGetAllDatasetsQuery();
const classificationsMap = useClassificationsMap();

const handleRowClick = (dataset: Dataset) => {
// toggle the active dataset
if (dataset.fides_key === activeDataset?.fides_key) {
Expand All @@ -32,13 +46,18 @@ const DatasetsTable = ({ datasets }: Props) => {
<Th pl={1}>Name</Th>
<Th pl={1}>Fides Key</Th>
<Th pl={1}>Description</Th>
<Th pl={1}>Status</Th>
</Tr>
</Thead>
<Tbody>
{datasets.map((dataset) => {
const isActive =
activeDataset && activeDataset.fides_key === dataset.fides_key;

const classification = classificationsMap.get(dataset.fides_key);
const statusDisplay =
STATUS_DISPLAY[classification?.status ?? "default"];

return (
<Tr
key={dataset.fides_key}
Expand All @@ -57,6 +76,17 @@ const DatasetsTable = ({ datasets }: Props) => {
<Td pl={1}>{dataset.name}</Td>
<Td pl={1}>{dataset.fides_key}</Td>
<Td pl={1}>{dataset.description}</Td>
<Td pl={1}>
<Tooltip label={statusDisplay.tooltip}>
<Badge
variant="solid"
colorScheme={statusDisplay.color}
data-testid={`dataset-status-${dataset.fides_key}`}
>
{statusDisplay.title}
</Badge>
</Tooltip>
</Td>
</Tr>
);
})}
Expand Down
29 changes: 29 additions & 0 deletions clients/ctl/admin-ui/src/features/dataset/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,32 @@ export const FIELD = {
"Arrays of Data Category resources, identified by fides_key, that apply to this field.",
},
};

/**
* Details to display about datasets based on status. Status is currently only determined by the
* classification feature.
*/
export const STATUS_DISPLAY = {
processing: {
title: "Processing",
tooltip:
"This dataset is currently being generated and classified. You will be notified when this process is complete",
color: "orange",
},
review: {
title: "Awaiting Review",
tooltip:
"This dataset has been automatically classified. Review the results and update the dataset.",
color: "orange",
},
classified: {
title: "Classified",
tooltip: "This dataset has been classified.",
color: "green",
},
default: {
title: "Unknown",
tooltip: "This dataset must be manually updated.",
color: "gray",
},
};
15 changes: 2 additions & 13 deletions clients/ctl/admin-ui/src/pages/dataset/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,8 @@ import {
} from "~/features/dataset/dataset.slice";
import DatasetsTable from "~/features/dataset/DatasetTable";

const useDatasetsTable = () => {
const { data, isLoading } = useGetAllDatasetsQuery();

return {
isLoading,
datasets: data,
};
};

const DataSets: NextPage = () => {
const { isLoading, datasets } = useDatasetsTable();
const { isLoading } = useGetAllDatasetsQuery();
const activeDataset = useSelector(selectActiveDataset);
const router = useRouter();
const toast = useToast();
Expand All @@ -57,9 +48,7 @@ const DataSets: NextPage = () => {
</BreadcrumbItem>
</Breadcrumb>
</Box>
<Box mb={4}>
{isLoading ? <Spinner /> : <DatasetsTable datasets={datasets} />}
</Box>
<Box mb={4}>{isLoading ? <Spinner /> : <DatasetsTable />}</Box>
<Box>
<Button
size="sm"
Expand Down

0 comments on commit 044863a

Please sign in to comment.