diff --git a/CHANGELOG.md b/CHANGELOG.md index 97e34221ba2..d1e08064b8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) @@ -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) diff --git a/clients/admin-ui/src/features/configure-consent/ConsentManagementModal.tsx b/clients/admin-ui/src/features/configure-consent/ConsentManagementModal.tsx new file mode 100644 index 00000000000..184df699c71 --- /dev/null +++ b/clients/admin-ui/src/features/configure-consent/ConsentManagementModal.tsx @@ -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 ( + + + + Vendor + + {isLoading ? ( + + + + ) : ( + + initialValues={ + systemPurposeSummary as unknown as SystemPurposeSummary + } + enableReinitialize + onSubmit={() => {}} + > + {({ values }) => ( +
+ + + + {Object.entries(values?.purposes || {}).length > 0 ? ( + + ) : null} + ( + + {Object.entries(values.purposes).map( + ([purposeName], index: number) => ( + + {({ isExpanded }) => ( + <> + + + {purposeName} + + + + + + + + + + + )} + + ) + )} + + )} + /> + + + + + + )} + + )} +
+ + + + + +
+
+ ); +}; diff --git a/clients/admin-ui/src/features/configure-consent/ConsentMangagementTable.tsx b/clients/admin-ui/src/features/configure-consent/ConsentMangagementTable.tsx index f758658d866..72de2b1afbc 100644 --- a/clients/admin-ui/src/features/configure-consent/ConsentMangagementTable.tsx +++ b/clients/admin-ui/src/features/configure-consent/ConsentMangagementTable.tsx @@ -24,6 +24,10 @@ import { Option, useConsentManagementFilters, } from "~/features/configure-consent/ConsentManagementFilterModal"; +import { + ConsentManagementModal, + useConsentManagementModal, +} from "~/features/configure-consent/ConsentManagementModal"; import { useGetHealthQuery, useGetVendorReportQuery, @@ -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(); const { isOpen: isFilterOpen, @@ -109,8 +119,8 @@ export const ConsentManagementTable = () => { startRange, endRange, pageIndex, - resetPageIndexToDefault, setTotalPages, + resetPageIndexToDefault, } = useServerSidePagination(); const [globalFilter, setGlobalFilter] = useState(); @@ -222,11 +232,23 @@ export const ConsentManagementTable = () => { getCoreRowModel: getCoreRowModel(), }); + const onRowClick = (system: SystemSummary) => { + setSystemFidesKey(system.fides_key); + onRowModalOpen(); + }; + if (isReportLoading || isLoadingHealthCheck) { return ; } return ( + {isRowModalOpen && systemFidesKey ? ( + + ) : null} { - + ({ + query: (fidesKey: string) => ({ + url: `plus/system/${fidesKey}/purpose-summary`, + method: "GET", + }), + providesTags: ["System"], + }), getVendorReport: build.query< Page_SystemSummary_, { @@ -453,6 +461,7 @@ export const { useGetAllSystemVendorsQuery, usePostSystemVendorsMutation, useGetSystemHistoryQuery, + useGetSystemPurposeSummaryQuery, useUpdateCustomAssetMutation, usePatchPlusSystemConnectionConfigsMutation, useCreatePlusSaasConnectionConfigMutation, diff --git a/clients/admin-ui/src/types/api/index.ts b/clients/admin-ui/src/types/api/index.ts index d2639ac0c9a..f15f6ebd293 100644 --- a/clients/admin-ui/src/types/api/index.ts +++ b/clients/admin-ui/src/types/api/index.ts @@ -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"; diff --git a/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts b/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts index e2f3357f647..57134239df8 100644 --- a/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts +++ b/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts @@ -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", diff --git a/clients/admin-ui/src/types/api/models/SystemPurposeSummary.ts b/clients/admin-ui/src/types/api/models/SystemPurposeSummary.ts new file mode 100644 index 00000000000..c57bb717124 --- /dev/null +++ b/clients/admin-ui/src/types/api/models/SystemPurposeSummary.ts @@ -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>>; + features: Array; + data_categories: Array; +};