Skip to content

Commit

Permalink
Merge pull request #129 from nitheesh-aot/continuation-report
Browse files Browse the repository at this point in the history
COMP-208: Save New Entry
  • Loading branch information
dinesh-aot authored Nov 5, 2024
2 parents 8ae74a8 + 61b15ce commit 176b827
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 111 deletions.
19 changes: 10 additions & 9 deletions compliance-web/src/components/App/Complaints/ComplaintFormUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,18 +203,19 @@ export const formatComplaintData = (
break;
}
}
if (!projectId) {
complaintData = {
unapproved_project_authorization: formData.authorization ?? "",
unapproved_project_regulated_party: formData.regulatedParty ?? "",
unapproved_project_type: formData.projectType ?? "",
unapproved_project_sub_type: formData.projectSubType ?? "",
...complaintData,
};
}
if (caseFileId) { // map the fields only for create new record, and case file id is available
complaintData.project_id = projectId;
complaintData.case_file_id = caseFileId;

if (!projectId) { // map the unapproved fields only during create mode
complaintData = {
...complaintData,
unapproved_project_authorization: formData.authorization ?? "",
unapproved_project_regulated_party: formData.regulatedParty ?? "",
unapproved_project_type: formData.projectType ?? "",
unapproved_project_sub_type: formData.projectSubType ?? "",
};
}
}
return complaintData;
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,54 @@ import ContinuationReportTimeline from "./ContinuationReportTimeline";
import { useModal } from "@/store/modalStore";
import ContinuationReportEntryModal from "./ContinuationReportEntryModal";
import { notify } from "@/store/snackbarStore";
import { useContinuationReportEntries } from "@/hooks/useContinuationReports";
import LoadingPage from "@/components/Shared/LoadingPage";
import ErrorPage from "@/components/Shared/ErrorPage";
import { useQueryClient } from "@tanstack/react-query";

export default function ContinuationReport() {
export type ContinuationReportContextType = {
caseFileId: number;
contextType: string;
contextId: number;
};

export default function ContinuationReport({
caseFileId,
contextType,
contextId,
}: ContinuationReportContextType) {
const queryClient = useQueryClient();
const { appHeaderHeight } = useMenuStore();
const { setOpen, setClose } = useModal();

const {
status,
data: continuationReportData,
isError,
error,
isLoading,
} = useContinuationReportEntries(caseFileId);

const handleAddNewEntry = () => {
setOpen({
content: <ContinuationReportEntryModal onSubmit={handleOnSubmit} />,
content: (
<ContinuationReportEntryModal
onSubmit={handleOnSubmit}
context={{ caseFileId, contextType, contextId }}
/>
),
width: "640px",
});
};

const handleOnSubmit = (submitMsg: string) => {
// queryClient.invalidateQueries({ queryKey: ["staff-users"] });
queryClient.invalidateQueries({
queryKey: ["continuation-reports", caseFileId],
});
setClose();
notify.success(submitMsg);
};

const dummyCRTimeline = [
{
date: "2024-09-31T08:48:38.311Z",
text: "BRUCEJ_20240007_IR001 is created.",
},
{
date: "2024-10-28T23:28:11.311Z",
text: "<New entry added with rich text info>",
},
{
date: "2024-10-31T18:45:21.311Z",
text: "20240007 is created.",
},
];

return (
<Box
width={"40%"}
Expand Down Expand Up @@ -77,7 +92,15 @@ export default function ContinuationReport() {
),
}}
/>
<ContinuationReportTimeline crtList={dummyCRTimeline} />
{!caseFileId || status === "pending" ? (
<LoadingPage isLoading={isLoading} />
) : isError ? (
<ErrorPage error={error} hideBackButton />
) : continuationReportData.length ? (
<ContinuationReportTimeline crtList={continuationReportData} />
) : (
<Typography variant="subtitle2" textAlign={"center"} mt={4}>-- No Records --</Typography>
)}
</Box>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import { yupResolver } from "@hookform/resolvers/yup";
import ModalTitleBar from "@/components/Shared/Modals/ModalTitleBar";
import ModalActions from "@/components/Shared/Modals/ModalActions";
import { Dayjs } from "dayjs";
import { ContinuationReportFormData } from "@/models/ContinuationReport";
import { ContinuationReportAPIData, ContinuationReportFormData } from "@/models/ContinuationReport";
import ControlledRichTextEditor from "@/components/Shared/Controlled/ControlledRichTextEditor";
import ControlledDateTimeField from "@/components/Shared/Controlled/ControlledDateTimeField";
import { useCreateContinuationReportEntry } from "@/hooks/useContinuationReports";
import dateUtils from "@/utils/dateUtils";
import { ContinuationReportContextType } from "./ContinuationReport";

type ContinuationReportEntryModal = {
onSubmit: (submitMsg: string) => void;
continuationReportEntry?: unknown;
context: ContinuationReportContextType;
};

const continuationReportFormSchema = yup.object().shape({
Expand All @@ -22,8 +26,8 @@ const continuationReportFormSchema = yup.object().shape({
.required("Date Created is required"),
entry: yup
.object({
html: yup.string(),
text: yup.string(),
html: yup.string().required("Entry is required"),
text: yup.string().required("Entry is required"),
})
.nullable()
.required("Entry is required"),
Expand All @@ -41,6 +45,7 @@ const initFormData: ContinuationReportFormData = {
const ContinuationReportEntryModal: React.FC<ContinuationReportEntryModal> = ({
onSubmit,
continuationReportEntry,
context,
}) => {
const defaultValues = useMemo<ContinuationReportFormData>(() => {
if (continuationReportEntry) {
Expand All @@ -63,19 +68,31 @@ const ContinuationReportEntryModal: React.FC<ContinuationReportEntryModal> = ({
}
}, [defaultValues, reset, continuationReportEntry]);

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const onSuccess = () => {
onSubmit(
continuationReportEntry ? "Successfully updated!" : "Successfully added!"
);
};

// const { mutate: addStaff } = useAddStaff(onSuccess);
const { mutate: addEntry } = useCreateContinuationReportEntry(onSuccess);
// const { mutate: updateStaff } = useUpdateStaff(onSuccess);

const onSubmitHandler = (data: ContinuationReportSchemaType) => {
// eslint-disable-next-line no-console
console.log(data);
const crEntry: ContinuationReportAPIData = {
case_file_id: context.caseFileId,
text: data.entry.text,
rich_text: data.entry.html,
date_created: dateUtils.dateToISO(data.dateOfEntry),
context_type: context.contextType,
context_id: context.contextId
}
if(continuationReportEntry) {
//TODO: Update
} else {
addEntry(crEntry)
}
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import TimelineContent from "@mui/lab/TimelineContent";
import TimelineDot from "@mui/lab/TimelineDot";
import TimelineOppositeContent from "@mui/lab/TimelineOppositeContent";
import { Stack, Typography } from "@mui/material";
import { ContinuationReport } from "@/models/ContinuationReport";

// TODO: Change according to model from API reponse
interface ContinuationReportTimelineProps {
crtList: { date: string; text: string }[];
crtList: ContinuationReport[];
}

export default function ContinuationReportTimeline({
Expand All @@ -24,17 +25,17 @@ export default function ContinuationReportTimeline({
}}
>
{crtList.map((crt) => (
<TimelineItem key={crt.date}>
<TimelineItem key={crt.date_created}>
<TimelineOppositeContent
color="textSecondary"
sx={{ padding: "8px 8px 4px 0px", flex: 0.1 }}
>
<Stack width={72}>
<Typography variant="caption">
{dateUtils.formatDate(crt.date)}
{dateUtils.formatDate(crt.date_created)}
</Typography>
<Typography variant="caption">
{dateUtils.formatDate(crt.date, "HH:mm")}
{dateUtils.formatDate(crt.date_created, "HH:mm")}
</Typography>
</Stack>
</TimelineOppositeContent>
Expand All @@ -44,7 +45,7 @@ export default function ContinuationReportTimeline({
<TimelineConnector />
)}
</TimelineSeparator>
<TimelineContent sx={{ p: "6px 0px 4px 8px" }}>
<TimelineContent sx={{ p: "4px 0px 4px 8px" }}>
<Typography variant="subtitle2">{crt.text}</Typography>
</TimelineContent>
</TimelineItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,18 +180,19 @@ export const formatInspectionData = (
...inspectionData,
};
}
if (!projectId) {
inspectionData = {
unapproved_project_authorization: formData.authorization ?? "",
unapproved_project_regulated_party: formData.regulatedParty ?? "",
unapproved_project_type: formData.projectType ?? "",
unapproved_project_sub_type: formData.projectSubType ?? "",
...inspectionData,
};
}
if (caseFileId) { // map the fields only for create new inspection, and case file id is available
inspectionData.project_id = projectId;
inspectionData.case_file_id = caseFileId;

if (!projectId) { // map the unapproved fields only during create mode
inspectionData = {
...inspectionData,
unapproved_project_authorization: formData.authorization ?? "",
unapproved_project_regulated_party: formData.regulatedParty ?? "",
unapproved_project_type: formData.projectType ?? "",
unapproved_project_sub_type: formData.projectSubType ?? "",
};
}
}
return inspectionData;
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from "react";
import React, { useEffect, useRef, useCallback } from "react";
import Quill from "quill";
import "quill/dist/quill.snow.css"; // Include the default theme
import { Controller, useFormContext } from "react-hook-form";
Expand All @@ -24,10 +24,41 @@ const ControlledRichTextEditor: React.FC<ControlledRichTextEditorProps> = ({
formState: { errors, defaultValues },
} = useFormContext();

const insertImageToEditor = useCallback((imageUrl: string) => {
const range = quillRef.current?.getSelection();
if (range) {
quillRef.current?.insertEmbed(range.index, "image", imageUrl);
}
}, []);

const handleImageUpload = useCallback(() => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.click();

input.onchange = async () => {
const file = input.files ? input.files[0] : null;
if (file) {
try {
// const signedUrl = await getSignedUrl();
// await uploadImageToS3(file, signedUrl);
// const imageUrl = signedUrl.split("?")[0];
// insertImageToEditor(imageUrl);
insertImageToEditor(
"https://citz-gdx.objectstore.gov.bc.ca/epic-engage/f1bb940c-9b80-450d-a0eb-66ebf4f8f34e.png"
);
} catch (error) {
// eslint-disable-next-line no-console
console.error("Error uploading image:", error);
}
}
};
}, [insertImageToEditor]);

useEffect(() => {
if (!editorRef.current || quillRef.current) return;

// Initialize Quill editor
quillRef.current = new Quill(editorRef.current, {
theme: "snow",
placeholder: placeholder,
Expand All @@ -39,56 +70,22 @@ const ControlledRichTextEditor: React.FC<ControlledRichTextEditorProps> = ({
["link"],
],
handlers: {
image: () => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.click();

input.onchange = async () => {
const file = input.files ? input.files[0] : null;
if (file) {
try {
// const signedUrl = await getSignedUrl();
// await uploadImageToS3(file, signedUrl);
// const imageUrl = signedUrl.split("?")[0];
// insertImageToEditor(imageUrl);
insertImageToEditor(
"https://citz-gdx.objectstore.gov.bc.ca/epic-engage/f1bb940c-9b80-450d-a0eb-66ebf4f8f34e.png"
);
} catch (error) {
// eslint-disable-next-line no-console
console.error("Error uploading image:", error);
}
}
};
},
image: handleImageUpload,
},
},
},
});

const insertImageToEditor = (imageUrl: string) => {
const range = quillRef.current?.getSelection();
if (range) {
quillRef.current?.insertEmbed(range.index, "image", imageUrl);
}
};

if (defaultValues?.[name]?.html) {
quillRef.current.root.innerHTML = defaultValues[name].html;
}

// Set initial form value if there's any
if (quillRef.current) {
quillRef.current.on("text-change", () => {
const htmlContent = quillRef.current?.root.innerHTML || "";
const plainText = quillRef.current?.getText()?.trim() || "";

setValue(name, { html: htmlContent, text: plainText });
});
}
}, [defaultValues, name, placeholder, setValue]);
quillRef.current.on("text-change", () => {
const htmlContent = quillRef.current?.root.innerHTML || "";
const plainText = quillRef.current?.getText()?.trim() || "";
setValue(name, { html: htmlContent, text: plainText });
});
}, [defaultValues, name, placeholder, setValue, handleImageUpload]);

return (
<FormControl fullWidth>
Expand Down Expand Up @@ -116,7 +113,6 @@ const ControlledRichTextEditor: React.FC<ControlledRichTextEditorProps> = ({
style={{ minHeight: "180px" }}
defaultValue={field.value.html || ""}
/>
{/* Quill container */}
{errors[name] && <span>{errors[name]?.message?.toString()}</span>}
</Box>
)}
Expand Down
Loading

0 comments on commit 176b827

Please sign in to comment.