From ba4d4c012217aba584535d6a4435665b304830aa Mon Sep 17 00:00:00 2001 From: Sarvesh P Date: Mon, 25 Nov 2024 13:58:26 +0530 Subject: [PATCH 1/6] Implemented Next and Previous button for files preview --- .prettierignore | 2 +- package-lock.json | 2 +- src/components/Common/FilePreviewDialog.tsx | 84 +++++++++++++++++++-- src/components/Files/FileUpload.tsx | 12 ++- src/components/Patient/FileUploadPage.tsx | 2 - src/hooks/useFileManager.tsx | 9 ++- 6 files changed, 96 insertions(+), 15 deletions(-) diff --git a/.prettierignore b/.prettierignore index 923af917dab..09fa56eaa99 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,4 +4,4 @@ lib build *.css *.gen.tsx -*.bs.js +*.bs.js \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 63af1164ef0..5c703af8fe1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20862,4 +20862,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/components/Common/FilePreviewDialog.tsx b/src/components/Common/FilePreviewDialog.tsx index 4b7a07bd0cd..dea058a1208 100644 --- a/src/components/Common/FilePreviewDialog.tsx +++ b/src/components/Common/FilePreviewDialog.tsx @@ -4,6 +4,7 @@ import { SetStateAction, Suspense, lazy, + useEffect, useState, } from "react"; import { useTranslation } from "react-i18next"; @@ -15,6 +16,8 @@ import CircularProgress from "@/components/Common/CircularProgress"; import DialogModal from "@/components/Common/Dialog"; import { StateInterface } from "@/components/Files/FileUpload"; +import { FileUploadModel } from "../Patient/models"; + const PDFViewer = lazy(() => import("@/components/Common/PDFViewer")); export const zoom_values = [ @@ -40,6 +43,9 @@ type FilePreviewProps = { className?: string; titleAction?: ReactNode; fixedWidth?: boolean; + uploadedFiles?: FileUploadModel[]; + loadFile?: (file: FileUploadModel, associating_id: string) => void; + currentIndex: number; }; const previewExtensions = [ @@ -56,12 +62,28 @@ const previewExtensions = [ ]; const FilePreviewDialog = (props: FilePreviewProps) => { - const { show, onClose, file_state, setFileState, downloadURL, fileUrl } = - props; + const { + show, + onClose, + file_state, + setFileState, + downloadURL, + fileUrl, + uploadedFiles, + loadFile, + currentIndex, + } = props; const { t } = useTranslation(); const [page, setPage] = useState(1); const [numPages, setNumPages] = useState(1); + const [index, setIndex] = useState(currentIndex); + + useEffect(() => { + if (uploadedFiles && show) { + setIndex(currentIndex); + } + }, [uploadedFiles, show, currentIndex]); const handleZoomIn = () => { const checkFull = file_state.zoom === zoom_values.length; @@ -79,9 +101,24 @@ const FilePreviewDialog = (props: FilePreviewProps) => { }); }; + const handleNext = (newIndex: number) => { + if (!uploadedFiles || !uploadedFiles.length) return; + + if (newIndex < 0 || newIndex >= uploadedFiles.length) return; + + const nextFile = uploadedFiles[newIndex]; + + if (!nextFile || !nextFile.id) return; + + const associating_id = nextFile.associating_id || ""; + loadFile!(nextFile, associating_id); + setIndex(newIndex); + }; + const handleClose = () => { setPage(1); setNumPages(1); + setIndex(-1); onClose?.(); }; @@ -109,16 +146,28 @@ const FilePreviewDialog = (props: FilePreviewProps) => { onClose={() => { handleClose(); }} - title={t("file_preview")} + title={{t("file_preview")}} show={show} > {fileUrl ? ( <> -
-

- {file_state.name}.{file_state.extension} -

-
+
+
+

+ {file_state.name}.{file_state.extension} +

+ {uploadedFiles && + uploadedFiles[index] && + uploadedFiles[index].created_date && ( +

+ Created on{" "} + {new Date( + uploadedFiles[index].created_date!, + ).toLocaleString()} +

+ )} +
+
{downloadURL && downloadURL.length > 0 && ( {
+ {uploadedFiles && uploadedFiles.length > 1 && index > 0 && ( + handleNext(index - 1)} + > + + + )}
{file_state.isImage ? ( {
)}
+ + {uploadedFiles && + uploadedFiles.length > 1 && + index < uploadedFiles.length - 1 && ( + handleNext(index + 1)} + > + + + )}
diff --git a/src/components/Files/FileUpload.tsx b/src/components/Files/FileUpload.tsx index d98df131863..50ab3ffdb01 100644 --- a/src/components/Files/FileUpload.tsx +++ b/src/components/Files/FileUpload.tsx @@ -69,6 +69,8 @@ export interface StateInterface { isZoomInDisabled: boolean; isZoomOutDisabled: boolean; rotation: number; + id?: string; + associating_id?: string; } export const FileUpload = (props: FileUploadProps) => { @@ -208,8 +210,15 @@ export const FileUpload = (props: FileUploadProps) => { type, onArchive: refetchAll, onEdit: refetchAll, + uploadedFiles: + fileQuery?.data?.results + .slice() + .reverse() + .map((file) => ({ + ...file, + associating_id: associatedId, + })) || [], }); - const dischargeSummaryFileManager = useFileManager({ type: "DISCHARGE_SUMMARY", onArchive: refetchAll, @@ -244,7 +253,6 @@ export const FileUpload = (props: FileUploadProps) => { id: "record-audio", }, ]; - return (
{fileUpload.Dialogues} diff --git a/src/components/Patient/FileUploadPage.tsx b/src/components/Patient/FileUploadPage.tsx index 518644f54d7..d38b149ebeb 100644 --- a/src/components/Patient/FileUploadPage.tsx +++ b/src/components/Patient/FileUploadPage.tsx @@ -11,12 +11,10 @@ export default function FileUploadPage(props: { type: "CONSULTATION" | "PATIENT"; }) { const { facilityId, patientId, consultationId, type } = props; - const { data: patient } = useQuery(routes.getPatient, { pathParams: { id: patientId }, prefetch: !!patientId, }); - return ( void; onEdit?: () => void; + uploadedFiles?: FileUploadModel[]; } export interface FileManagerResult { viewFile: (file: FileUploadModel, associating_id: string) => void; @@ -48,7 +49,7 @@ export interface FileManagerResult { export default function useFileManager( options: FileManagerOptions, ): FileManagerResult { - const { type: fileType, onArchive, onEdit } = options; + const { type: fileType, onArchive, onEdit, uploadedFiles } = options; const [file_state, setFileState] = useState({ open: false, @@ -72,6 +73,7 @@ export default function useFileManager( const [editDialogueOpen, setEditDialogueOpen] = useState(null); const [editError, setEditError] = useState(""); + const [currentIndex, setCurrentIndex] = useState(-1); const getExtension = (url: string) => { const div1 = url.split("?")[0].split("."); @@ -80,6 +82,8 @@ export default function useFileManager( }; const viewFile = async (file: FileUploadModel, associating_id: string) => { + const index = uploadedFiles?.findIndex((f) => f.id === file.id) ?? -1; + setCurrentIndex(index); setFileUrl(""); setFileState({ ...file_state, open: true }); const { data } = await request(routes.retrieveUpload, { @@ -225,9 +229,12 @@ export default function useFileManager( file_state={file_state} setFileState={setFileState} downloadURL={downloadURL} + uploadedFiles={uploadedFiles} onClose={handleFilePreviewClose} fixedWidth={false} className="h-[80vh] w-full md:h-screen" + loadFile={viewFile} + currentIndex={currentIndex} /> Date: Mon, 25 Nov 2024 14:43:34 +0530 Subject: [PATCH 2/6] Update src/components/Common/FilePreviewDialog.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/components/Common/FilePreviewDialog.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/Common/FilePreviewDialog.tsx b/src/components/Common/FilePreviewDialog.tsx index dea058a1208..37f942aeaa1 100644 --- a/src/components/Common/FilePreviewDialog.tsx +++ b/src/components/Common/FilePreviewDialog.tsx @@ -102,16 +102,19 @@ const FilePreviewDialog = (props: FilePreviewProps) => { }; const handleNext = (newIndex: number) => { - if (!uploadedFiles || !uploadedFiles.length) return; + if (!uploadedFiles?.length) return; + if (!loadFile) { + console.error('loadFile handler is not defined'); + return; + } if (newIndex < 0 || newIndex >= uploadedFiles.length) return; const nextFile = uploadedFiles[newIndex]; - - if (!nextFile || !nextFile.id) return; + if (!nextFile?.id) return; const associating_id = nextFile.associating_id || ""; - loadFile!(nextFile, associating_id); + loadFile(nextFile, associating_id); setIndex(newIndex); }; From 4c7d71bcfee3004e9530f869ba3fa75f34fc86e9 Mon Sep 17 00:00:00 2001 From: Sarvesh P Date: Mon, 25 Nov 2024 15:01:56 +0530 Subject: [PATCH 3/6] Increased font size of the file name and added created on fields --- src/components/Common/FilePreviewDialog.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/Common/FilePreviewDialog.tsx b/src/components/Common/FilePreviewDialog.tsx index dea058a1208..d89a316d238 100644 --- a/src/components/Common/FilePreviewDialog.tsx +++ b/src/components/Common/FilePreviewDialog.tsx @@ -102,16 +102,20 @@ const FilePreviewDialog = (props: FilePreviewProps) => { }; const handleNext = (newIndex: number) => { - if (!uploadedFiles || !uploadedFiles.length) return; + if (!uploadedFiles?.length) return; + if (!loadFile) { + console.error("loadFile handler is not defined"); + return; + } if (newIndex < 0 || newIndex >= uploadedFiles.length) return; const nextFile = uploadedFiles[newIndex]; - if (!nextFile || !nextFile.id) return; + if (!nextFile?.id) return; const associating_id = nextFile.associating_id || ""; - loadFile!(nextFile, associating_id); + loadFile(nextFile, associating_id); setIndex(newIndex); }; @@ -153,17 +157,20 @@ const FilePreviewDialog = (props: FilePreviewProps) => { <>
-

+

{file_state.name}.{file_state.extension}

{uploadedFiles && uploadedFiles[index] && uploadedFiles[index].created_date && ( -

+

Created on{" "} {new Date( uploadedFiles[index].created_date!, - ).toLocaleString()} + ).toLocaleString("en-US", { + dateStyle: "long", + timeStyle: "short", + })}

)}
From 82a581bff9a780b6d865caf073b4d241828736d4 Mon Sep 17 00:00:00 2001 From: Sarvesh P Date: Tue, 26 Nov 2024 16:43:01 +0530 Subject: [PATCH 4/6] Implement the required changes --- src/components/Common/FilePreviewDialog.tsx | 53 ++++++++++++++------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/src/components/Common/FilePreviewDialog.tsx b/src/components/Common/FilePreviewDialog.tsx index f2b47002163..6235b33daac 100644 --- a/src/components/Common/FilePreviewDialog.tsx +++ b/src/components/Common/FilePreviewDialog.tsx @@ -103,11 +103,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => { const handleNext = (newIndex: number) => { if (!uploadedFiles?.length) return; - if (!loadFile) { - console.error("loadFile handler is not defined"); - return; - } - + if (!loadFile) return; if (newIndex < 0 || newIndex >= uploadedFiles.length) return; const nextFile = uploadedFiles[newIndex]; @@ -142,6 +138,21 @@ const FilePreviewDialog = (props: FilePreviewProps) => { : `rotate-${normalizedRotation}`; } + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (!show) return; + if (e.key === "ArrowLeft" && index > 0) { + handleNext(index - 1); + } + if (e.key === "ArrowRight" && index < (uploadedFiles?.length || 0) - 1) { + handleNext(index + 1); + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [show, index, uploadedFiles]); + return ( {
- {uploadedFiles && uploadedFiles.length > 1 && index > 0 && ( + {uploadedFiles && uploadedFiles.length > 1 && ( handleNext(index - 1)} + disabled={index <= 0} + aria-label="Previous file" + onKeyDown={(e) => + e.key === "ArrowLeft" && handleNext(index - 1) + } > @@ -237,16 +253,19 @@ const FilePreviewDialog = (props: FilePreviewProps) => { )}
- {uploadedFiles && - uploadedFiles.length > 1 && - index < uploadedFiles.length - 1 && ( - handleNext(index + 1)} - > - - - )} + {uploadedFiles && uploadedFiles.length > 1 && ( + handleNext(index + 1)} + disabled={index >= uploadedFiles.length - 1} + aria-label="Next file" + onKeyDown={(e) => + e.key === "ArrowRight" && handleNext(index + 1) + } + > + + + )}
From b4be6b87570b685162fe0a549f9965e7555996e7 Mon Sep 17 00:00:00 2001 From: Sarvesh P Date: Wed, 27 Nov 2024 12:15:38 +0530 Subject: [PATCH 5/6] Combined the checks in File Preview --- src/components/Common/FilePreviewDialog.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/Common/FilePreviewDialog.tsx b/src/components/Common/FilePreviewDialog.tsx index 6235b33daac..fa8a333515d 100644 --- a/src/components/Common/FilePreviewDialog.tsx +++ b/src/components/Common/FilePreviewDialog.tsx @@ -102,9 +102,13 @@ const FilePreviewDialog = (props: FilePreviewProps) => { }; const handleNext = (newIndex: number) => { - if (!uploadedFiles?.length) return; - if (!loadFile) return; - if (newIndex < 0 || newIndex >= uploadedFiles.length) return; + if ( + !uploadedFiles?.length || + !loadFile || + newIndex < 0 || + newIndex >= uploadedFiles.length + ) + return; const nextFile = uploadedFiles[newIndex]; if (!nextFile?.id) return; From f67bebe9db62d9d24d9fd4ad7d9149331e0d5b61 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Thu, 28 Nov 2024 15:05:51 +0530 Subject: [PATCH 6/6] update line endings --- .prettierignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 09fa56eaa99..923af917dab 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,4 +4,4 @@ lib build *.css *.gen.tsx -*.bs.js \ No newline at end of file +*.bs.js