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

Profile actions #173

Merged
merged 10 commits into from
Dec 16, 2024
46 changes: 0 additions & 46 deletions compliance-web/cypress/components/App.cy.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React, { useCallback } from "react";
import MenuActionDropdown from "@/components/Shared/MenuActionDropdown";
import {
useDeleteCaseFile,
useLinkCaseFile,
useUnlinkCaseFile,
useUpdateCaseFileStatus,
} from "@/hooks/useCaseFiles";
import { CaseFile } from "@/models/CaseFile";
Expand All @@ -10,6 +12,7 @@ import ConfirmationModal from "@/components/Shared/Popups/ConfirmationModal";
import { useModal } from "@/store/modalStore";
import { notify } from "@/store/snackbarStore";
import { useRouter } from "@tanstack/react-router";
import LinkCaseFileModal from "@/components/App/CaseFiles/Profile/LinkCaseFileModal";

interface CaseFileActionsProps {
status: string;
Expand Down Expand Up @@ -37,12 +40,22 @@ const CaseFileActions: React.FC<CaseFileActionsProps> = ({
setClose();
}, [queryClient, fileNumber, setClose]);

const onLinkCaseFileSuccess = useCallback(() => {
queryClient.invalidateQueries({
queryKey: ["case-file", fileNumber],
});
notify.success("Case file link is updated");
setClose();
}, [queryClient, fileNumber, setClose]);

const onDeleteSuccess = useCallback(() => {
notify.success("Case File deleted!");
setClose();
router.navigate({ to: "/ce-database/case-files" });
}, [setClose, router]);

const { mutate: linkCaseFile } = useLinkCaseFile(onLinkCaseFileSuccess);
const { mutate: unlinkCaseFile } = useUnlinkCaseFile(onLinkCaseFileSuccess);
const { mutate: updateCaseFileStatus } = useUpdateCaseFileStatus(
onUpdateStatusSuccess
);
Expand All @@ -53,15 +66,38 @@ const CaseFileActions: React.FC<CaseFileActionsProps> = ({
text: "Link to Case File",
onClick: () => {
// Handle linking case file
setOpen({
content: (
<LinkCaseFileModal
fileNumber={fileNumber}
linkedCaseFiles={caseFileData?.caseFileLinks ?? []}
onSubmit={(caseFileId) => {
linkCaseFile({ id: caseFileData?.id ?? 0, linkId: caseFileId });
}}
/>
),
});
},
hidden: status?.toLowerCase() === "closed",
},
{
text: "Unlink from Case File",
onClick: () => {
// Handle unlinking case file
setOpen({
content: (
<LinkCaseFileModal
fileNumber={fileNumber}
onSubmit={(caseFileId) => {
unlinkCaseFile({id: caseFileData?.id ?? 0, linkId: caseFileId})
}}
linkedCaseFiles={caseFileData?.caseFileLinks ?? []}
isEdit
/>
),
});
},
hidden: true,
hidden: status?.toLowerCase() === "closed",
},
{
text: "Close Case File",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ const CaseFileGeneralInformation: React.FC<CaseFileGeneralInformationProps> = ({
size="small"
expandable={true}
/>
{!!caseFileData.caseFileLinks?.length && (
<FileProfileProperty
propertyName="Linked Case Files"
linksList={caseFileData.caseFileLinks?.map(
(link) => link.case_file_number
)}
linkRoute="/ce-database/case-files"
size="small"
/>
)}
<CaseFileComplaintsTable caseFileId={caseFileData.id} />
<CaseFileInspectionsTable caseFileId={caseFileData.id} />
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import { DialogContent, Typography, Button } from "@mui/material";
import { DialogContent } from "@mui/material";
import { FormProvider, useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import ModalTitleBar from "@/components/Shared/Modals/ModalTitleBar";
import ModalActions from "@/components/Shared/Modals/ModalActions";
import { FC, useCallback, useEffect } from "react";
import {
useCaseFilesByProjectId,
useCreateCaseFile,
} from "@/hooks/useCaseFiles";
import { FC, useEffect } from "react";
import ControlledAutoComplete from "@/components/Shared/Controlled/ControlledAutoComplete";
import { CaseFile, CaseFileAPIData } from "@/models/CaseFile";
import { notify } from "@/store/snackbarStore";
import dateUtils from "@/utils/dateUtils";
import { CaseFile } from "@/models/CaseFile";
import { useCaseFilesData } from "@/hooks/useCaseFiles";

type LinkCaseFileModalProps = {
onSubmit: (caseFileId: number) => void;
projectId?: number;
initiationId: string;
primaryOfficerId?: number;
linkedCaseFiles?: CaseFile[];
fileNumber: string;
isEdit?: boolean;
};

const linkCaseFileSchema = yup.object().shape({
Expand All @@ -36,34 +31,31 @@ const initFormData = {

const LinkCaseFileModal: FC<LinkCaseFileModalProps> = ({
onSubmit,
projectId,
initiationId,
primaryOfficerId,
linkedCaseFiles,
fileNumber,
isEdit,
}) => {
const { data: caseFilesList } = useCaseFilesByProjectId(projectId!);
const { data: caseFiles } = useCaseFilesData();

const filteredCaseFileList =
caseFiles
?.filter(
(caseFile) =>
caseFile.case_file_number !== fileNumber &&
!linkedCaseFiles?.some((linked) => linked.id === caseFile.id)
)
.sort((a, b) => a.case_file_number.localeCompare(b.case_file_number)) ??
[];

const caseFilesList = isEdit ? linkedCaseFiles : filteredCaseFileList;

const methods = useForm<LinkCaseFileFormType>({
resolver: yupResolver(linkCaseFileSchema),
mode: "onBlur",
defaultValues: initFormData,
});

const { handleSubmit, reset, watch } = methods;

const caseFileValue = watch("caseFile");

const onSuccess = useCallback(
(data: CaseFile) => {
notify.success(
`Case File ${data.case_file_number} was successfully created`
);
onSubmit(data.id);
reset();
},
[onSubmit, reset]
);

const { mutate: createCaseFile } = useCreateCaseFile(onSuccess);
const { handleSubmit, reset } = methods;

useEffect(() => {
reset(initFormData);
Expand All @@ -74,25 +66,17 @@ const LinkCaseFileModal: FC<LinkCaseFileModalProps> = ({
onSubmit(caseFileId);
};

const createNewCaseFile = () => {
const caseFileData: CaseFileAPIData = {
project_id: projectId!,
initiation_id: initiationId,
date_created: dateUtils.dateToISO(new Date()),
primary_officer_id: primaryOfficerId!,
};
createCaseFile(caseFileData);
};

return (
<FormProvider {...methods}>
<form onSubmit={handleSubmit(onSubmitHandler)}>
<ModalTitleBar title="Link to Case File" />
<ModalTitleBar
title={isEdit ? "Unlink from Case File" : "Link to Case File"}
/>
<DialogContent dividers>
<ControlledAutoComplete
name="caseFile"
label="Case File"
placeholder="Select existing Case File"
placeholder="Select Case File"
options={caseFilesList ?? []}
getOptionLabel={(option) => option.case_file_number ?? ""}
getOptionKey={(option) => option.id}
Expand All @@ -101,21 +85,12 @@ const LinkCaseFileModal: FC<LinkCaseFileModalProps> = ({
sx={{ mb: "-0.5rem" }}
disabled={!caseFilesList?.length}
/>
<Typography variant="body1" textAlign={"center"} mb={"1rem"}>
OR
</Typography>
<Button
color="secondary"
fullWidth
sx={{ mb: "2.5rem" }}
onClick={createNewCaseFile}
disabled={!!caseFileValue} // Disable button if caseFile dropdown has a value
>
Create New Case File
</Button>
</DialogContent>
{caseFilesList && caseFilesList.length > 0 && (
<ModalActions primaryActionButtonText="Link" isButtonValidation />
<ModalActions
primaryActionButtonText={isEdit ? "Unlink" : "Link"}
isButtonValidation
/>
)}
</form>
</FormProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { useModal } from "@/store/modalStore";
import { useQueryClient } from "@tanstack/react-query";
import { Complaint } from "@/models/Complaint";
import { notify } from "@/store/snackbarStore";
import { useUpdateComplaintStatus } from "@/hooks/useComplaints";
import {
useDeleteComplaint,
useUpdateComplaintStatus,
} from "@/hooks/useComplaints";
import router from "@/router/router";

interface ComplaintFileActionsProps {
status: string;
Expand All @@ -32,10 +36,17 @@ const ComplaintFileActions: React.FC<ComplaintFileActionsProps> = ({
setClose();
}, [fileNumber, queryClient, setClose]);

const onDeleteSuccess = useCallback(() => {
notify.success("Complaint deleted!");
setClose();
router.navigate({ to: "/ce-database/complaints" });
}, [setClose]);

const { mutate: updateComplaintStatus } = useUpdateComplaintStatus(
onUpdateStatusSuccess
);


const { mutate: deleteComplaint } = useDeleteComplaint(onDeleteSuccess);

const actionsList = [
{
Expand Down Expand Up @@ -93,8 +104,7 @@ const ComplaintFileActions: React.FC<ComplaintFileActionsProps> = ({
description="You are about to delete this complaint. Are you sure?"
confirmButtonText="Delete"
onConfirm={() => {
// TODO: Implement delete complaint
setClose();
deleteComplaint(complaintData?.id ?? 0);
}}
/>
),
Expand Down
22 changes: 21 additions & 1 deletion compliance-web/src/components/App/FileProfileProperty.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { Box, Typography } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import ParagraphWithReadMore from "../Shared/ParagraphWithReadMore";
import ParagraphWithReadMore from "@/components/Shared/ParagraphWithReadMore";
import PageLink from "@/components/Shared/PageLink";

export default function FileProfileProperty({
propertyName,
propertyValue,
size = "default",
expandable = false,
linksList,
linkRoute,
}: {
propertyName: string;
propertyValue?: string;
size?: "small" | "default";
expandable?: boolean;
linksList?: string[];
linkRoute?: string;
}) {
return (
<Box display={"flex"} gap={size === "small" ? 4 : 2} marginBottom={1}>
Expand All @@ -31,6 +36,21 @@ export default function FileProfileProperty({
</Typography>
}
/>
) : linksList ? (
<Box display={"flex"} gap={1}>
{linksList.map((link, index) => (
<Box
key={index}
sx={{
":not(:last-child)::after": {
content: '", "',
},
}}
>
<PageLink to={`${linkRoute}/${link}`} linkText={link} />
</Box>
))}
</Box>
) : (
<Typography variant="body1" display={"flex"} flex={1}>
{propertyValue ?? ""}
Expand Down
Loading