Skip to content

Commit

Permalink
Require denial reason for privacy requests (#2400)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAndrewJackson authored Jan 30, 2023
1 parent f944aa9 commit fd5613e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 85 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The types of changes are:
* Unified Fides Resources: Updated test env setup and quickstart to use new endpoints [#2225](https://github.com/ethyca/fides/pull/2225)
* Update fideslang to 1.3.3 [#2343](https://github.com/ethyca/fides/pull/2343)
* Display the request type instead of the policy name on the request table [#2382](https://github.com/ethyca/fides/pull/2382)
* Make denial reasons required [#2400](https://github.com/ethyca/fides/pull/2400)
* Display the policy key on the request details page [#2395](https://github.com/ethyca/fides/pull/2395)

### Developer Experience
Expand Down
1 change: 0 additions & 1 deletion clients/admin-ui/src/features/common/form/inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,6 @@ export const CustomTextArea = ({
<Textarea
{...field}
size="sm"
width="auto"
mr={2}
{...textAreaProps}
data-testid={`input-${field.name}`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,86 +6,98 @@ import {
ModalFooter,
ModalHeader,
ModalOverlay,
Textarea,
} from "@fidesui/react";
import React from "react";
import { CustomTextArea } from "common/form/inputs";
import { Form, Formik, FormikHelpers } from "formik";
import React, { useCallback } from "react";
import * as Yup from "yup";

type DenyModalProps = {
isOpen: boolean;
isLoading: boolean;
handleMenuClose: () => void;
handleDenyRequest: (reason: string) => Promise<any>;
denialReason: string;
onChange: (e: any) => void;
};

const closeModal = (
handleMenuClose: () => void,
handleDenyRequest: (reason: string) => Promise<any>,
denialReason: string
) => {
handleDenyRequest(denialReason).then(() => {
handleMenuClose();
});
};

const initialValues = { denialReason: "" };
type FormValues = typeof initialValues;
const DenyPrivacyRequestModal = ({
isOpen,
isLoading,
handleMenuClose,
denialReason,
onChange,
handleDenyRequest,
}: DenyModalProps) => (
<Modal
isOpen={isOpen}
onClose={handleMenuClose}
isCentered
returnFocusOnClose={false}
>
<ModalOverlay />
<ModalContent width="100%" maxWidth="456px">
<ModalHeader>Privacy Request Denial</ModalHeader>
<ModalBody color="gray.500" fontSize="14px">
Please enter a reason for denying this privacy request. Please note:
this can be seen by the user in their notification email.
</ModalBody>
<ModalBody>
<Textarea
focusBorderColor="primary.600"
value={denialReason}
onChange={onChange}
disabled={isLoading}
/>
</ModalBody>
<ModalFooter>
<Button
size="sm"
width="100%"
maxWidth="198px"
colorScheme="gray.200"
mr={3}
disabled={isLoading}
onClick={handleMenuClose}
}: DenyModalProps) => {
const handleSubmit = useCallback(
(values: FormValues, formikHelpers: FormikHelpers<FormValues>) => {
const { setSubmitting } = formikHelpers;
handleDenyRequest(values.denialReason).then(() => {
setSubmitting(false);
handleMenuClose();
});
},
[handleDenyRequest, handleMenuClose]
);
return (
<Modal
isOpen={isOpen}
onClose={handleMenuClose}
isCentered
returnFocusOnClose={false}
>
<ModalOverlay />
<ModalContent width="100%" maxWidth="456px">
<Formik
initialValues={initialValues}
validationSchema={Yup.object({
denialReason: Yup.string().required().label("Reason for denial"),
})}
onSubmit={handleSubmit}
>
Close
</Button>
<Button
size="sm"
width="100%"
maxWidth="198px"
colorScheme="primary"
variant="solid"
isLoading={isLoading}
onClick={() => {
closeModal(handleMenuClose, handleDenyRequest, denialReason);
}}
>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
{({ isSubmitting, dirty, isValid }) => (
<Form>
<ModalHeader>Privacy Request Denial</ModalHeader>
<ModalBody color="gray.500" fontSize="14px">
Please enter a reason for denying this privacy request. Please
note: this can be seen by the user in their notification email.
</ModalBody>
<ModalBody>
<CustomTextArea
name="denialReason"
textAreaProps={{
focusBorderColor: "primary.600",
resize: "none",
}}
/>
</ModalBody>
<ModalFooter>
<Button
size="sm"
width="100%"
maxWidth="198px"
colorScheme="gray.200"
mr={3}
disabled={isSubmitting}
onClick={handleMenuClose}
>
Close
</Button>
<Button
type="submit"
size="sm"
width="100%"
maxWidth="198px"
colorScheme="primary"
variant="solid"
disabled={!dirty || !isValid}
isLoading={isSubmitting}
>
Confirm
</Button>
</ModalFooter>
</Form>
)}
</Formik>
</ModalContent>
</Modal>
);
};

export default DenyPrivacyRequestModal;
17 changes: 1 addition & 16 deletions clients/admin-ui/src/features/privacy-requests/RequestRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ const useRequestRow = (request: PrivacyRequestEntity) => {
const [focused, setFocused] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
const [denialReason, setDenialReason] = useState("");
const [approveRequest, approveRequestResult] = useApproveRequestMutation();
const [denyRequest, denyRequestResult] = useDenyRequestMutation();
const [denyRequest] = useDenyRequestMutation();
const handleMenuOpen = () => setMenuOpen(true);
const handleMenuClose = () => setMenuOpen(false);
const handleMouseEnter = () => setHovered(true);
Expand All @@ -69,9 +68,6 @@ const useRequestRow = (request: PrivacyRequestEntity) => {
setFocused(false);
setHovered(false);
setMenuOpen(false);
if (!denyRequestResult.isLoading) {
setDenialReason("");
}
};
const handleIdCopy = () => {
onCopy();
Expand Down Expand Up @@ -100,7 +96,6 @@ const useRequestRow = (request: PrivacyRequestEntity) => {
};
return {
approveRequestResult,
denyRequestResult,
hovered,
focused,
menuOpen,
Expand All @@ -118,8 +113,6 @@ const useRequestRow = (request: PrivacyRequestEntity) => {
handleDenyRequest,
hoverButtonRef,
shiftFocusToHoverMenu,
denialReason,
setDenialReason,
handleViewDetails,
};
};
Expand All @@ -140,7 +133,6 @@ const RequestRow: React.FC<{
handleIdCopy,
menuOpen,
approveRequestResult,
denyRequestResult,
hoverButtonRef,
modalOpen,
handleModalClose,
Expand All @@ -149,8 +141,6 @@ const RequestRow: React.FC<{
handleFocus,
handleBlur,
focused,
denialReason,
setDenialReason,
handleViewDetails,
} = useRequestRow(request);
const showMenu = hovered || menuOpen || focused;
Expand Down Expand Up @@ -279,13 +269,8 @@ const RequestRow: React.FC<{
</Button>
<DenyPrivacyRequestModal
isOpen={modalOpen}
isLoading={denyRequestResult.isLoading}
handleMenuClose={handleModalClose}
handleDenyRequest={handleDenyRequest}
denialReason={denialReason}
onChange={(e) => {
setDenialReason(e.target.value);
}}
/>
</>
)}
Expand Down

0 comments on commit fd5613e

Please sign in to comment.