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

TCF purpose summary modal #4477

Merged
merged 37 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d576cf7
refactor pagination - add client side hook
TheAndrewJackson Nov 16, 2023
a07fde6
add initial stubbed out consent table
TheAndrewJackson Nov 16, 2023
972f8d4
Add server side pagination
TheAndrewJackson Nov 17, 2023
842c3a2
Add initial filtering and search
TheAndrewJackson Nov 20, 2023
75d1c0b
Add badge cell
TheAndrewJackson Nov 20, 2023
697ccdb
update filter modal
TheAndrewJackson Nov 20, 2023
e44e743
Add initial dynamic colums and row click modal
TheAndrewJackson Nov 21, 2023
d3bcec1
Update types
TheAndrewJackson Nov 22, 2023
6ac6644
Add new routes and update modal filter
TheAndrewJackson Nov 22, 2023
4d5436b
Add purposes filter and reset
TheAndrewJackson Nov 22, 2023
bea101f
Add consent category filters and update types
TheAndrewJackson Nov 27, 2023
98f2453
handle special purposes
TheAndrewJackson Nov 27, 2023
90829e7
Fix key issue
TheAndrewJackson Nov 27, 2023
5238ad9
lints and format
TheAndrewJackson Nov 27, 2023
a828122
Fix build issues
TheAndrewJackson Nov 27, 2023
52bca0b
Merge branch 'main' into ajackson/PROD-1341/readonly_table
TheAndrewJackson Nov 27, 2023
4c6e8ba
skip some tests
TheAndrewJackson Nov 27, 2023
27b5bc1
format
TheAndrewJackson Nov 27, 2023
05413ad
update changelog
TheAndrewJackson Nov 27, 2023
715ca5f
move `ConfirmationModal` to `/common/modals`
TheAndrewJackson Nov 28, 2023
1a739ea
move `UpgradeModal` to `/common/modals`
TheAndrewJackson Nov 28, 2023
7d402f9
sort imports
TheAndrewJackson Nov 28, 2023
93f70e6
move `WarningModal` to `/common/modals`
TheAndrewJackson Nov 28, 2023
c11da02
Remove modal
TheAndrewJackson Nov 30, 2023
27544f1
Add back original vendor cookie table
TheAndrewJackson Nov 30, 2023
3fa1685
Update types
TheAndrewJackson Dec 1, 2023
e49085d
Add initial consent modal and new route
TheAndrewJackson Dec 1, 2023
7117e3c
Add loading spinner
TheAndrewJackson Dec 1, 2023
2c69b17
polish modal
TheAndrewJackson Dec 1, 2023
15040c9
Merge branch 'main' into ajackson/PROD-1467/TCF_purpose_modal
TheAndrewJackson Dec 1, 2023
2127789
format
TheAndrewJackson Dec 1, 2023
8598273
Update changelog
TheAndrewJackson Dec 1, 2023
fb48784
remove skips
TheAndrewJackson Dec 1, 2023
8fbceb6
Merge branch 'main' into ajackson/PROD-1467/TCF_purpose_modal
galvana Dec 5, 2023
352155b
Update clients/admin-ui/src/features/configure-consent/ConsentManagem…
TheAndrewJackson Dec 5, 2023
64879cb
fix build issue
TheAndrewJackson Dec 5, 2023
48a092b
PR feeback
TheAndrewJackson Dec 5, 2023
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The types of changes are:
- Paging to vendors in the TCF overlay [#4463](https://github.com/ethyca/fides/pull/4463)
- New purposes endpoint and indices to improve system lookups [#4452](https://github.com/ethyca/fides/pull/4452)
- Add support for global TCF Purpose Overrides [#4464](https://github.com/ethyca/fides/pull/4464)
- Readonly consent management table and modal [#4456](https://github.com/ethyca/fides/pull/4456), [#4477](https://github.com/ethyca/fides/pull/4477

### Fixed
- Fix type errors when TCF vendors have no dataDeclaration [#4465](https://github.com/ethyca/fides/pull/4465)
Expand All @@ -36,7 +37,6 @@ The types of changes are:
- Added feature flag for separating system name and Compass vendor selector [#4437](https://github.com/ethyca/fides/pull/4437)
- Fire GPP events per spec [#4433](https://github.com/ethyca/fides/pull/4433)
- New override option `fides_tcf_gdpr_applies` for setting `gdprApplies` on the CMP API [#4453](https://github.com/ethyca/fides/pull/4453)
- Readonly consent management table [#4456](https://github.com/ethyca/fides/pull/4456)

### Changed
- Improved bulk vendor adding table UX [#4425](https://github.com/ethyca/fides/pull/4425)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/* eslint-disable react/no-array-index-key */
import {
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
Box,
Button,
Flex,
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Spacer,
Spinner,
useDisclosure,
} from "@fidesui/react";
import { FieldArray, Form, Formik } from "formik";

import {
CustomCreatableSelect,
CustomTextInput,
Label,
} from "~/features/common/form/inputs";
import { useGetSystemPurposeSummaryQuery } from "~/features/plus/plus.slice";
import { SystemPurposeSummary } from "~/types/api";

export const useConsentManagementModal = () => {
const { isOpen, onOpen, onClose } = useDisclosure();

return { isOpen, onOpen, onClose };
};

type Props = {
isOpen: boolean;
onClose: () => void;
fidesKey: string;
};

type FormValues = SystemPurposeSummary;

export const ConsentManagementModal = ({
isOpen,
onClose,
fidesKey,
}: Props) => {
const { data: systemPurposeSummary, isLoading } =
useGetSystemPurposeSummaryQuery(fidesKey);

return (
<Modal
isOpen={isOpen}
onClose={onClose}
size="xxl"
returnFocusOnClose={false}
isCentered
>
<ModalOverlay />
<ModalContent maxWidth="800px">
<ModalHeader>Vendor</ModalHeader>
<ModalBody>
{isLoading ? (
<Flex
width="100%"
height="324px"
alignItems="center"
justifyContent="center"
>
<Spinner />
</Flex>
) : (
<Formik<FormValues>
initialValues={
systemPurposeSummary as unknown as SystemPurposeSummary
}
enableReinitialize
onSubmit={() => {}}
>
{({ values }) => (
<Form>
<Box mb={6}>
<CustomTextInput
label="Vendor Name"
variant="stacked"
name="name"
disabled
/>
</Box>
{Object.entries(values?.purposes || {}).length > 0 ? (
<Label> Purposes </Label>
) : null}
<FieldArray
TheAndrewJackson marked this conversation as resolved.
Show resolved Hide resolved
name="purposes"
render={() => (
<Accordion allowMultiple>
{Object.entries(values.purposes).map(
([purposeName], index: number) => (
<AccordionItem key={index}>
{({ isExpanded }) => (
<>
<AccordionButton
backgroundColor={
isExpanded ? "gray.50" : "unset"
}
>
<Box flex="1" textAlign="left">
{purposeName}
</Box>
<AccordionIcon />
</AccordionButton>
<AccordionPanel backgroundColor="gray.50">
<Box my={4}>
<CustomCreatableSelect
label="Data Uses"
isMulti
disableMenu
isDisabled
options={[]}
variant="stacked"
name={`purposes['${purposeName}'].data_uses`}
/>
</Box>
<CustomCreatableSelect
label="Legal Basis"
isMulti
disableMenu
isDisabled
options={[]}
variant="stacked"
name={`purposes['${purposeName}'].legal_bases`}
/>
</AccordionPanel>
</>
)}
</AccordionItem>
)
)}
</Accordion>
)}
/>
<Box my={4}>
<CustomCreatableSelect
label="Features"
isMulti
options={[]}
disableMenu
isDisabled
variant="stacked"
name="features"
/>
</Box>
<CustomCreatableSelect
label="Data Categories"
isMulti
options={[]}
disableMenu
isDisabled
variant="stacked"
name="data_categories"
/>
</Form>
)}
</Formik>
)}
</ModalBody>

<ModalFooter>
<Button variant="outline" size="sm" onClick={onClose}>
Close{" "}
</Button>
<Spacer />
</ModalFooter>
</ModalContent>
</Modal>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import {
Option,
useConsentManagementFilters,
} from "~/features/configure-consent/ConsentManagementFilterModal";
import {
ConsentManagementModal,
useConsentManagementModal,
} from "~/features/configure-consent/ConsentManagementModal";
import {
useGetHealthQuery,
useGetVendorReportQuery,
Expand All @@ -42,6 +46,12 @@ const emptyVendorReportResponse: Page_SystemSummary_ = {
export const ConsentManagementTable = () => {
const { tcf: isTcfEnabled } = useFeatures();
const { isLoading: isLoadingHealthCheck } = useGetHealthQuery();
const {
isOpen: isRowModalOpen,
onOpen: onRowModalOpen,
onClose: onRowModalClose,
} = useConsentManagementModal();
const [systemFidesKey, setSystemFidesKey] = useState<string>();

const {
isOpen: isFilterOpen,
Expand Down Expand Up @@ -109,8 +119,8 @@ export const ConsentManagementTable = () => {
startRange,
endRange,
pageIndex,
resetPageIndexToDefault,
setTotalPages,
resetPageIndexToDefault,
} = useServerSidePagination();

const [globalFilter, setGlobalFilter] = useState<string>();
Expand Down Expand Up @@ -222,11 +232,23 @@ export const ConsentManagementTable = () => {
getCoreRowModel: getCoreRowModel(),
});

const onRowClick = (system: SystemSummary) => {
setSystemFidesKey(system.fides_key);
onRowModalOpen();
};

if (isReportLoading || isLoadingHealthCheck) {
return <TableSkeletonLoader rowHeight={36} numRows={15} />;
}
return (
<Flex flex={1} direction="column" overflow="auto">
{isRowModalOpen && systemFidesKey ? (
<ConsentManagementModal
isOpen={isRowModalOpen}
fidesKey={systemFidesKey}
onClose={onRowModalClose}
/>
) : null}
<TableActionBar>
<GlobalFilterV2
globalFilter={globalFilter}
Expand Down Expand Up @@ -258,7 +280,7 @@ export const ConsentManagementTable = () => {
</Button>
</Flex>
</TableActionBar>
<FidesTableV2 tableInstance={tableInstance} />
<FidesTableV2 tableInstance={tableInstance} onRowClick={onRowClick} />
<PaginationBar
totalRows={totalRows}
pageSizes={PAGE_SIZES}
Expand Down
9 changes: 9 additions & 0 deletions clients/admin-ui/src/features/plus/plus.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
Page_SystemHistoryResponse_,
Page_SystemSummary_,
ResourceTypes,
SystemPurposeSummary,
SystemScannerStatus,
SystemScanResponse,
SystemsDiff,
Expand Down Expand Up @@ -297,6 +298,13 @@ const plusApi = baseApi.injectEndpoints({
}),
providesTags: ["Fides Cloud Config"],
}),
getSystemPurposeSummary: build.query<SystemPurposeSummary, string>({
query: (fidesKey: string) => ({
url: `plus/system/${fidesKey}/purpose-summary`,
method: "GET",
}),
providesTags: ["System"],
}),
getVendorReport: build.query<
Page_SystemSummary_,
{
Expand Down Expand Up @@ -453,6 +461,7 @@ export const {
useGetAllSystemVendorsQuery,
usePostSystemVendorsMutation,
useGetSystemHistoryQuery,
useGetSystemPurposeSummaryQuery,
useUpdateCustomAssetMutation,
usePatchPlusSystemConnectionConfigsMutation,
useCreatePlusSaasConnectionConfigMutation,
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 @@ -310,6 +310,7 @@ export type { Strategy } from "./models/Strategy";
export type { System } from "./models/System";
export type { SystemHistoryResponse } from "./models/SystemHistoryResponse";
export type { SystemMetadata } from "./models/SystemMetadata";
export type { SystemPurposeSummary } from "./models/SystemPurposeSummary";
export type { SystemResponse } from "./models/SystemResponse";
export type { SystemScanHistory } from "./models/SystemScanHistory";
export type { SystemScannerStatus } from "./models/SystemScannerStatus";
Expand Down
1 change: 1 addition & 0 deletions clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export enum ScopeRegistryEnum {
DATASET_DELETE = "dataset:delete",
DATASET_READ = "dataset:read",
ENCRYPTION_EXEC = "encryption:exec",
ENDPOINT_CACHE_UPDATE = "endpoint_cache:update",
EVALUATION_CREATE = "evaluation:create",
EVALUATION_DELETE = "evaluation:delete",
EVALUATION_READ = "evaluation:read",
Expand Down
14 changes: 14 additions & 0 deletions clients/admin-ui/src/types/api/models/SystemPurposeSummary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

/**
* A summary of privacy declaration information for a system aggregated by TCF purpose.
*/
export type SystemPurposeSummary = {
fides_key: string;
name: string;
purposes: Record<string, Record<string, Array<any>>>;
features: Array<string>;
data_categories: Array<string>;
};