Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | 7x 7x 7x 7x 7x 18x 7x 7x 25x 25x 25x 25x 25x 25x 4x 3x 3x 1x 1x 1x 1x 1x 25x | import NiceModal, { useModal } from "@ebay/nice-modal-react";
import { yupResolver } from "@hookform/resolvers/yup";
import { Box, Grid, Stack, styled } from "@mui/material";
import { ControlledDatePicker } from "@sections/PayBuilder/Forms/DateAndLocation/components/ControlledDatePicker";
import GiveButton from "@shared/Button/GiveButton";
import { HFGiveInput } from "@shared/HFInputs/HFGiveInput/HFGiveInput";
import HFGiveRadio from "@shared/HFInputs/HFGiveRadio";
import GiveBaseModal from "@shared/modals/GiveBaseModal";
import GiveText from "@shared/Text/GiveText";
import { showMessage } from "@common/Toast";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
import moment from "moment";
import { FormProvider, useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import * as Yup from "yup";
import { usePublishDocument } from "../api/useLegalDocumentMutations";
const VERSION_TAKEN_HINT = "version";
const NOTIFY_LABEL = "Publish and Notify";
const NOTIFY_DESCRIPTION =
"Changes are applied immediately and notifications are sent via email.";
const NO_NOTIFY_LABEL = "Publish without Notifying";
const NO_NOTIFY_DESCRIPTION =
"Changes are applied immediately without triggering notifications.";
const RadioCard = styled(Box)(({ theme }) => ({
border: `1px solid ${theme.palette.border?.primary}`,
borderRadius: "12px",
padding: "16px",
}));
interface Props {
documentID: number;
name: string;
version: string;
showSendNotification?: boolean;
/** Where to navigate after a successful publish (the documents list). */
listPath: string;
}
type FormType = {
version: string;
date: Date;
notify: boolean;
};
const schema = Yup.object().shape({
date: Yup.date()
.typeError("Please provide a valid date")
.nullable()
.required("A date is required"),
version: Yup.string()
.trim()
.required("A version is required")
.min(1, "A version is required")
.max(32, "A version label must be 32 characters or fewer"),
});
const PublishModal = NiceModal.create(
({ documentID, version, showSendNotification, name, listPath }: Props) => {
const { remove, visible } = useModal();
const { isMobileView } = useCustomThemeV2();
const navigate = useNavigate();
const publish = usePublishDocument(documentID);
const methods = useForm<FormType>({
resolver: yupResolver(schema),
mode: "all",
reValidateMode: "onChange",
defaultValues: {
version,
date: moment().toDate(),
// The notify radios only render for notifiable types; when hidden the
// default is the payload, and the BE 409s notify:true for other types.
notify: !!showSendNotification,
},
});
const handlePublish = methods.handleSubmit((form) =>
publish.mutate(
{
version: form.version,
publishedDate: moment(form.date).format("YYYY-MM-DD"),
notify: !!form.notify,
},
{
onSuccess: () => {
remove();
navigate(listPath);
},
onError: (err: any) => {
const status = err?.response?.status;
const message = err?.response?.data?.message;
// 409 conflicts are not auto-toasted by the interceptor. A version-taken
// conflict belongs on the version field; anything else is a toast.
Eif (status === 409 && message) {
if (String(message).toLowerCase().includes(VERSION_TAKEN_HINT)) {
methods.setError("version", { type: "manual", message });
} else E{
showMessage("Error", message);
}
}
// 400s (future date / invalid version) are already toasted globally.
},
},
),
);
return (
<GiveBaseModal
title={`Publish Updates to ${name}`}
onClose={remove}
open={visible}
height={isMobileView ? "fit-content" : undefined}
buttons={
<>
<GiveButton
label="Cancel"
size="large"
onClick={remove}
variant="ghost"
/>
<GiveButton
label="Publish"
size="large"
onClick={handlePublish}
loading={publish.isLoading}
/>
</>
}
>
<FormProvider {...methods}>
<Stack gap="24px">
<Grid container spacing="24px">
<Grid item xs={12} sm={6}>
<HFGiveInput label="Version" name="version" />
</Grid>
<Grid item xs={12} sm={6}>
<ControlledDatePicker name="date" label="Date" useUTCMoment maxDate={moment()} />
</Grid>
</Grid>
{showSendNotification && (
<Stack gap="12px">
<GiveText variant="bodyL">Send Notification</GiveText>
<RadioCard>
<HFGiveRadio name="notify" label={NOTIFY_LABEL} description={NOTIFY_DESCRIPTION} />
</RadioCard>
<RadioCard>
<HFGiveRadio
name="notify"
label={NO_NOTIFY_LABEL}
description={NO_NOTIFY_DESCRIPTION}
inverse
/>
</RadioCard>
</Stack>
)}
</Stack>
</FormProvider>
</GiveBaseModal>
);
},
);
export default PublishModal;
|