import("../Common/Loading"));
@@ -139,7 +140,7 @@ export const HospitalList = () => {
className="border-grey-500 mt-4 cursor-pointer whitespace-nowrap rounded-md border bg-white p-16 text-center text-sm font-semibold shadow hover:bg-gray-300"
onClick={() => navigate("/facility/create")}
>
-
{t("no_duplicate_facility")}
diff --git a/src/Components/Facility/InventoryLog.tsx b/src/Components/Facility/InventoryLog.tsx
index 474de009f76..96dd564d53c 100644
--- a/src/Components/Facility/InventoryLog.tsx
+++ b/src/Components/Facility/InventoryLog.tsx
@@ -94,7 +94,10 @@ export default function InventoryLog(props: any) {
{inventoryItem.quantity_in_default_unit}{" "}
{inventoryItem.item_object?.default_unit?.name}
{inventoryItem.probable_accident && (
-
+
)}
diff --git a/src/Components/Facility/Investigations/InvestigationSuggestions.tsx b/src/Components/Facility/Investigations/InvestigationSuggestions.tsx
index 4d614d224e6..3be01b5d7e8 100644
--- a/src/Components/Facility/Investigations/InvestigationSuggestions.tsx
+++ b/src/Components/Facility/Investigations/InvestigationSuggestions.tsx
@@ -128,7 +128,7 @@ export default function ViewInvestigationSuggestions(props: {
{type}
{investigationMissed && (
-
+
Investigation Missed!
@@ -136,7 +136,7 @@ export default function ViewInvestigationSuggestions(props: {
)}
{investigated && !investigationMissed && (
-
+
Investigation Recorded
diff --git a/src/Components/Facility/LocationManagement.tsx b/src/Components/Facility/LocationManagement.tsx
index f296f4d0bbd..985d6a029fe 100644
--- a/src/Components/Facility/LocationManagement.tsx
+++ b/src/Components/Facility/LocationManagement.tsx
@@ -211,16 +211,13 @@ const Location = ({
}: LocationProps) => (
-
-
-
+
+
+
{name}
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 8943d7fe21a..2e04312d277 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -12,6 +12,8 @@ import routes from "../../Redux/api";
import { PatientNoteStateType } from "./models";
import useKeyboardShortcut from "use-keyboard-shortcut";
import AutoExpandingTextInputFormField from "../Form/FormFields/AutoExpandingTextInputFormField.js";
+import * as Sentry from "@sentry/browser";
+import useAuthUser from "../../Common/hooks/useAuthUser";
interface PatientNotesProps {
patientId: string;
@@ -26,6 +28,33 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
const [reload, setReload] = useState(false);
const [focused, setFocused] = useState(false);
+ const { username } = useAuthUser();
+
+ const intialSubscriptionState = async () => {
+ try {
+ const res = await request(routes.getUserPnconfig, {
+ pathParams: { username },
+ });
+ const reg = await navigator.serviceWorker.ready;
+ const subscription = await reg.pushManager.getSubscription();
+ if (!subscription && !res.data?.pf_endpoint) {
+ Notification.Warn({
+ msg: "Please subscribe to notifications to get live updates on doctor notes.",
+ });
+ } else if (subscription?.endpoint !== res.data?.pf_endpoint) {
+ Notification.Warn({
+ msg: "Please subscribe to notifications on this device to get live updates on doctor notes.",
+ });
+ }
+ } catch (error) {
+ Sentry.captureException(error);
+ }
+ };
+
+ useEffect(() => {
+ intialSubscriptionState();
+ }, []);
+
const initialData: PatientNoteStateType = {
notes: [],
cPage: 1,
diff --git a/src/Components/Facility/TreatmentSummary.tsx b/src/Components/Facility/TreatmentSummary.tsx
index b6caebc750e..b55c86216a7 100644
--- a/src/Components/Facility/TreatmentSummary.tsx
+++ b/src/Components/Facility/TreatmentSummary.tsx
@@ -4,6 +4,7 @@ import useSlug from "../../Common/hooks/useSlug";
import useAppHistory from "../../Common/hooks/useAppHistory";
import routes from "../../Redux/api";
import useQuery from "../../Utils/request/useQuery";
+import CareIcon from "../../CAREUI/icons/CareIcon";
const TreatmentSummary = (props: any) => {
const { consultationId, patientId } = props;
@@ -35,10 +36,10 @@ const TreatmentSummary = (props: any) => {
onClick={(_) => window.print()}
className="btn btn-primary mr-2"
>
- Print Treatment Summary
+ Print Treatment Summary
goBack(url)} className="btn btn-default">
- Close
+ Close
diff --git a/src/Components/HCX/misc.ts b/src/Components/HCX/misc.ts
index 9476f19c081..dba0a290b85 100644
--- a/src/Components/HCX/misc.ts
+++ b/src/Components/HCX/misc.ts
@@ -1,9 +1,3 @@
-export interface PerformedByModel {
- id: string;
- first_name: string;
- last_name: string;
- username: string;
- email: string;
- user_type: string;
- last_login: string;
-}
+import { UserBareMinimum } from "../Users/models";
+
+export type PerformedByModel = UserBareMinimum;
diff --git a/src/Components/Notifications/NotificationsList.tsx b/src/Components/Notifications/NotificationsList.tsx
index 6066bf6c66b..1ce23dafdbc 100644
--- a/src/Components/Notifications/NotificationsList.tsx
+++ b/src/Components/Notifications/NotificationsList.tsx
@@ -4,7 +4,7 @@ import Spinner from "../Common/Spinner";
import { NOTIFICATION_EVENTS } from "../../Common/constants";
import { Error } from "../../Utils/Notifications.js";
import { classNames, formatDateTime } from "../../Utils/utils";
-import CareIcon from "../../CAREUI/icons/CareIcon";
+import CareIcon, { IconName } from "../../CAREUI/icons/CareIcon";
import * as Sentry from "@sentry/browser";
import {
ShrinkedSidebarItem,
@@ -73,8 +73,9 @@ const NotificationTile = ({
const getNotificationTitle = (id: string) =>
NOTIFICATION_EVENTS.find((notification) => notification.id === id)?.text;
- const getNotificationIcon = (id: string) =>
- NOTIFICATION_EVENTS.find((notification) => notification.id === id)?.icon;
+ const getNotificationIcon = (id: string): IconName =>
+ NOTIFICATION_EVENTS.find((notification) => notification.id === id)?.icon ||
+ "default";
return (
{
@@ -93,7 +94,10 @@ const NotificationTile = ({
{getNotificationTitle(result.event)}
-
+
{result.message}
@@ -479,13 +483,13 @@ export default function NotificationsList({
o.text}
optionValue={(o) => o.id}
- optionIcon={(o) => }
+ optionIcon={(o) => }
onChange={(v) => setEventFilter(v || "")}
/>
diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx
index 56e26dff022..288d46f7359 100644
--- a/src/Components/Patient/DailyRounds.tsx
+++ b/src/Components/Patient/DailyRounds.tsx
@@ -575,7 +575,7 @@ export const DailyRounds = (props: any) => {
label="Respiratory Rate"
unit="bpm"
start={0}
- end={50}
+ end={150}
step={1}
thresholds={[
{
diff --git a/src/Components/Patient/FileUpload.tsx b/src/Components/Patient/FileUpload.tsx
index 77c67abeadd..4976bb0c91f 100644
--- a/src/Components/Patient/FileUpload.tsx
+++ b/src/Components/Patient/FileUpload.tsx
@@ -3,21 +3,12 @@ import CircularProgress from "../Common/components/CircularProgress";
import {
useCallback,
useState,
- useEffect,
useRef,
lazy,
ChangeEvent,
+ useEffect,
} from "react";
-import { useDispatch } from "react-redux";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import {
- viewUpload,
- retrieveUpload,
- createUpload,
- getPatient,
- editUpload,
-} from "../../Redux/actions";
-import { FileUploadModel } from "./models";
+import { CreateFileResponse, FileUploadModel } from "./models";
import * as Notification from "../../Utils/Notifications.js";
import { VoiceRecorder } from "../../Utils/VoiceRecorder";
import Pagination from "../Common/Pagination";
@@ -39,6 +30,9 @@ import AuthorizedChild from "../../CAREUI/misc/AuthorizedChild";
import Page from "../Common/components/Page";
import FilePreviewDialog from "../Common/FilePreviewDialog";
import useAuthUser from "../../Common/hooks/useAuthUser";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
+import request from "../../Utils/request/request";
const Loading = lazy(() => import("../Common/Loading"));
@@ -145,7 +139,6 @@ export const FileUpload = (props: FileUploadProps) => {
claimId,
} = props;
const id = patientId;
- const dispatch: any = useDispatch();
const [isLoading, setIsLoading] = useState(false);
const [uploadedArchievedFiles, setuploadedArchievedFiles] = useState<
Array
@@ -157,7 +150,6 @@ export const FileUpload = (props: FileUploadProps) => {
useState>([{}]);
const [uploadStarted, setUploadStarted] = useState(false);
const [audiouploadStarted, setAudioUploadStarted] = useState(false);
- const [reload, setReload] = useState(false);
const [uploadPercent, setUploadPercent] = useState(0);
const [uploadFileName, setUploadFileName] = useState("");
const [uploadFileError, setUploadFileError] = useState("");
@@ -204,8 +196,6 @@ export const FileUpload = (props: FileUploadProps) => {
const [totalDischargeSummaryFilesCount, setTotalDischargeSummaryFilesCount] =
useState(0);
const [offset, setOffset] = useState(0);
- const [facilityName, setFacilityName] = useState("");
- const [patientName, setPatientName] = useState("");
const [modalOpenForEdit, setModalOpenForEdit] = useState(false);
const [modalOpenForCamera, setModalOpenForCamera] = useState(false);
const [modalOpenForArchive, setModalOpenForArchive] = useState(false);
@@ -219,28 +209,15 @@ export const FileUpload = (props: FileUploadProps) => {
const [sortFileState, setSortFileState] = useState("UNARCHIVED");
const authUser = useAuthUser();
const limit = RESULTS_PER_PAGE_LIMIT;
- const [isActive, setIsActive] = useState(true);
const [tabs, setTabs] = useState([
{ name: "Unarchived Files", value: "UNARCHIVED" },
{ name: "Archived Files", value: "ARCHIVED" },
]);
- useEffect(() => {
- async function fetchPatientName() {
- if (patientId) {
- const res = await dispatch(getPatient({ id: patientId }));
- if (res.data) {
- setPatientName(res.data.name);
- setFacilityName(res.data.facility_object.name);
- setIsActive(res.data.is_active);
- }
- } else {
- setPatientName("");
- setFacilityName("");
- }
- }
- fetchPatientName();
- }, [dispatch, patientId]);
+ const { data: patient } = useQuery(routes.getPatient, {
+ pathParams: { id: patientId },
+ prefetch: !!patientId,
+ });
const captureImage = () => {
setPreviewImage(webRef.current.getScreenshot());
@@ -298,104 +275,93 @@ export const FileUpload = (props: FileUploadProps) => {
}
};
- const fetchData = useCallback(
- async (status: statusType) => {
- setIsLoading(true);
- const unarchivedFileData = {
+ const fetchData = useCallback(async () => {
+ setIsLoading(true);
+
+ const unarchivedQuery = await request(routes.viewUpload, {
+ query: {
file_type: type,
associating_id: getAssociatedId(),
is_archived: false,
limit: limit,
offset: offset,
- };
- let res = await dispatch(viewUpload(unarchivedFileData));
- if (!status.aborted) {
- if (res?.data) {
- audio_urls(res.data.results);
- setuploadedUnarchievedFiles(
- res?.data?.results?.filter(
- (file: FileUploadModel) =>
- file.upload_completed || file.file_category === "AUDIO"
- )
- );
- setTotalUnarchievedFilesCount(res.data.count);
- }
- setIsLoading(false);
- }
- const archivedFileData = {
+ },
+ });
+
+ if (unarchivedQuery.data) {
+ audio_urls(unarchivedQuery.data.results);
+ setuploadedUnarchievedFiles(
+ unarchivedQuery.data.results?.filter(
+ (file) => file.upload_completed || file.file_category === "AUDIO"
+ )
+ );
+ setTotalUnarchievedFilesCount(unarchivedQuery.data.count);
+ }
+
+ const archivedQuery = await request(routes.viewUpload, {
+ query: {
file_type: type,
associating_id: getAssociatedId(),
is_archived: true,
limit: limit,
offset: offset,
- };
- res = await dispatch(viewUpload(archivedFileData));
- if (!status.aborted) {
- if (res?.data) {
- setuploadedArchievedFiles(res.data.results);
- setTotalArchievedFilesCount(res.data.count);
- }
- setIsLoading(false);
- }
- if (type === "CONSULTATION") {
- const dischargeSummaryFileData = {
+ },
+ });
+
+ if (archivedQuery.data) {
+ setuploadedArchievedFiles(archivedQuery.data.results);
+ setTotalArchievedFilesCount(archivedQuery.data.count);
+ }
+
+ if (type === "CONSULTATION") {
+ const dischargeSummaryQuery = await request(routes.viewUpload, {
+ query: {
file_type: "DISCHARGE_SUMMARY",
associating_id: getAssociatedId(),
is_archived: false,
limit: limit,
offset: offset,
- };
- res = await dispatch(viewUpload(dischargeSummaryFileData));
- if (!status.aborted) {
- if (res?.data) {
- setuploadedDischargeSummaryFiles(res.data.results);
- setTotalDischargeSummaryFilesCount(res.data.count);
- if (res?.data?.results?.length > 0) {
- setTabs([
- ...tabs,
- {
- name: "Discharge Summary",
- value: "DISCHARGE_SUMMARY",
- },
- ]);
- }
- }
+ },
+ });
+ if (dischargeSummaryQuery.data) {
+ setuploadedDischargeSummaryFiles(dischargeSummaryQuery.data.results);
+ setTotalDischargeSummaryFilesCount(dischargeSummaryQuery.data.count);
+ if (dischargeSummaryQuery.data?.results?.length) {
+ setTabs([
+ ...tabs,
+ {
+ name: "Discharge Summary",
+ value: "DISCHARGE_SUMMARY",
+ },
+ ]);
}
- setIsLoading(false);
}
- },
- [dispatch, id, offset]
- );
+ }
- // Store all audio urls for each audio file
- const audio_urls = (files: any) => {
- let audio_files = files || [];
- audio_files = audio_files.filter(
- (x: FileUploadModel) => x.file_category === "AUDIO"
- );
+ setIsLoading(false);
+ }, [id, offset]);
- const getURL = async (audio_files: any) => {
- const data = { file_type: type, associating_id: getAssociatedId() };
- const all_urls: any = {};
+ useEffect(() => {
+ fetchData();
+ }, [fetchData]);
- for (const x of audio_files) {
- if (x.id) {
- const responseData = await dispatch(retrieveUpload(data, x.id));
- all_urls[`${x.id}`] = responseData.data.read_signed_url;
- }
- }
- seturl(all_urls);
- };
- getURL(audio_files);
+ // Store all audio urls for each audio file
+ const audio_urls = async (files: FileUploadModel[]) => {
+ const audioFiles = files.filter((x) => x.file_category === "AUDIO");
+ const query = { file_type: type, associating_id: getAssociatedId() };
+ const urls = await Promise.all(
+ audioFiles.map(async (file) => {
+ const id = file.id as string;
+ const { data } = await request(routes.retrieveUpload, {
+ query,
+ pathParams: { id: id as string },
+ });
+ return [id, data?.read_signed_url];
+ })
+ );
+ seturl(Object.fromEntries(urls));
};
- useAbortableEffect(
- (status: statusType) => {
- fetchData(status);
- },
- [dispatch, fetchData, id, reload]
- );
-
// Function to extract the extension of the file
const getExtension = (url: string) => {
const div1 = url.split("?")[0].split(".");
@@ -404,6 +370,7 @@ export const FileUpload = (props: FileUploadProps) => {
};
const getIconClassName = (extensionName: string | undefined) => {
+ if (!extensionName) return "l-file-medical";
// check for image files
if (
[
@@ -421,9 +388,9 @@ export const FileUpload = (props: FileUploadProps) => {
".pjp",
".svg",
".webp",
- ].some((ext) => ext === extensionName)
+ ].includes(extensionName)
) {
- return "fa-solid fa-file-image";
+ return "l-image";
}
// check for video files
if (
@@ -443,58 +410,46 @@ export const FileUpload = (props: FileUploadProps) => {
".qt",
".flv",
".swf",
- ].some((ext) => ext === extensionName)
+ ].includes(extensionName)
) {
- return "fa-solid fa-file-video";
- }
- // check for compressed files
- if (extensionName === ".zip" || extensionName === ".rar") {
- return "fa-solid fa-file-zipper";
- }
- // check for misclaneous files whose icons are available freely in fontawesome
- if (extensionName === ".pdf") {
- return "fa-solid fa-file-pdf";
- }
- if (extensionName === ".docx") {
- return "fa-solid fa-file-word";
- }
- if (extensionName === ".csv") {
- return "fa-solid fa-file-csv";
- }
- if (extensionName === ".xlsx") {
- return "fa-solid fa-file-excel";
- }
- if (extensionName === ".txt") {
- return "fa-solid fa-file-lines";
+ return "l-video";
}
+
if (extensionName === ".pptx") {
- return "fa-solid fa-file-powerpoint";
+ return "l-presentation-play";
}
- return "fa-solid fa-file-medical";
+ return "l-file-medical";
};
- const loadFile = async (id: any) => {
+ const loadFile = async (id: string) => {
setFileUrl("");
setFileState({ ...file_state, open: true });
- const data = {
- file_type: sortFileState === "DISCHARGE_SUMMARY" ? sortFileState : type,
- associating_id: getAssociatedId(),
- };
- const responseData = await dispatch(retrieveUpload(data, id));
- const file_extension = getExtension(responseData.data.read_signed_url);
- if (file_extension === "pdf") {
- window.open(responseData.data.read_signed_url, "_blank");
+ const { data } = await request(routes.retrieveUpload, {
+ query: {
+ file_type: sortFileState === "DISCHARGE_SUMMARY" ? sortFileState : type,
+ associating_id: getAssociatedId(),
+ },
+ pathParams: { id },
+ });
+
+ if (!data) return;
+
+ const signedUrl = data.read_signed_url as string;
+ const extension = getExtension(signedUrl);
+
+ if (extension === "pdf") {
+ window.open(signedUrl, "_blank");
setFileState({ ...file_state, open: false });
} else {
setFileState({
...file_state,
open: true,
- name: responseData.data.name,
- extension: file_extension,
- isImage: ExtImage.includes(file_extension),
+ name: data.name as string,
+ extension,
+ isImage: ExtImage.includes(extension),
});
- downloadFileUrl(responseData.data.read_signed_url);
- setFileUrl(responseData.data.read_signed_url);
+ downloadFileUrl(signedUrl);
+ setFileUrl(signedUrl);
}
};
@@ -518,63 +473,54 @@ export const FileUpload = (props: FileUploadProps) => {
}
};
- const partialupdateFileName = async (id: any, name: string) => {
- const data = {
- file_type: sortFileState === "DISCHARGE_SUMMARY" ? sortFileState : type,
- name: name,
- associating_id: getAssociatedId(),
- };
- if (validateEditFileName(name)) {
- const res = await dispatch(
- editUpload({ name: data.name }, id, data.file_type, data.associating_id)
- );
- if (res && res.status === 200) {
- fetchData(res.status);
- Notification.Success({
- msg: "File name changed successfully",
- });
- setbtnloader(false);
- setModalOpenForEdit(false);
- } else {
- setbtnloader(false);
- }
- } else {
+ const partialupdateFileName = async (id: string, name: string) => {
+ if (!validateEditFileName(name)) {
setbtnloader(false);
+ return;
}
+
+ const fileType =
+ sortFileState === "DISCHARGE_SUMMARY" ? sortFileState : type;
+
+ const { res } = await request(routes.editUpload, {
+ body: { name },
+ pathParams: {
+ id,
+ fileType,
+ associatingId: getAssociatedId(),
+ },
+ });
+
+ if (res?.ok) {
+ fetchData();
+ Notification.Success({ msg: "File name changed successfully" });
+ setModalOpenForEdit(false);
+ }
+ setbtnloader(false);
};
- const archiveFile = async (id: any, archiveReason: string) => {
- const data = {
- file_type: type,
- is_archived: true,
- archive_reason: archiveReason,
- associating_id: getAssociatedId(),
- };
- if (validateArchiveReason(archiveReason)) {
- const res = await dispatch(
- editUpload(
- {
- is_archived: data.is_archived,
- archive_reason: data.archive_reason,
- },
- id,
- data.file_type,
- data.associating_id
- )
- );
- if (res && res.status === 200) {
- fetchData(res.status);
- Notification.Success({
- msg: "File archived successfully",
- });
- setbtnloader(false);
- setModalOpenForArchive(false);
- } else {
- setbtnloader(false);
- }
- } else {
+ const archiveFile = async (id: string, archive_reason: string) => {
+ if (!validateArchiveReason(archiveReason)) {
setbtnloader(false);
+ return;
}
+
+ const { res } = await request(routes.editUpload, {
+ body: { is_archived: true, archive_reason },
+ pathParams: {
+ id,
+ fileType: type,
+ associatingId: getAssociatedId(),
+ },
+ });
+
+ if (res?.ok) {
+ fetchData();
+ Notification.Success({ msg: "File archived successfully" });
+ setModalOpenForArchive(false);
+ }
+
+ setbtnloader(false);
};
const renderFileUpload = (item: FileUploadModel) => {
@@ -590,7 +536,10 @@ export const FileUpload = (props: FileUploadProps) => {
-
+
@@ -703,11 +652,10 @@ export const FileUpload = (props: FileUploadProps) => {
-
+
@@ -739,7 +687,7 @@ export const FileUpload = (props: FileUploadProps) => {
{
- loadFile(item.id);
+ loadFile(item.id!);
}}
className="m-1 w-full sm:w-auto"
>
@@ -813,7 +761,10 @@ export const FileUpload = (props: FileUploadProps) => {
/>
-
+
) : (
@@ -832,11 +783,10 @@ export const FileUpload = (props: FileUploadProps) => {
/>
-
+
)}
@@ -932,9 +882,9 @@ export const FileUpload = (props: FileUploadProps) => {
setFile(f);
};
- const uploadfile = (response: any) => {
- const url = response.data.signed_url;
- const internal_name = response.data.internal_name;
+ const uploadfile = async (data: CreateFileResponse) => {
+ const url = data.signed_url;
+ const internal_name = data.internal_name;
const f = file;
if (!f) return;
const newFile = new File([f], `${internal_name}`);
@@ -951,6 +901,7 @@ export const FileUpload = (props: FileUploadProps) => {
setUploadPercent(percentCompleted);
},
};
+
return new Promise
((resolve, reject) => {
axios
.put(url, newFile, config)
@@ -959,13 +910,12 @@ export const FileUpload = (props: FileUploadProps) => {
// setUploadSuccess(true);
setFile(null);
setUploadFileName("");
- setReload(!reload);
- fetchData({ aborted: false });
+ fetchData();
Notification.Success({
msg: "File Uploaded Successfully",
});
setUploadFileError("");
- resolve(response);
+ resolve();
})
.catch((e) => {
Notification.Error({
@@ -994,18 +944,18 @@ export const FileUpload = (props: FileUploadProps) => {
}
return true;
};
- const markUploadComplete = async (response: any) => {
- return dispatch(
- editUpload(
- { upload_completed: true },
- response.data.id,
- type,
- getAssociatedId()
- )
- );
+ const markUploadComplete = (data: CreateFileResponse) => {
+ return request(routes.editUpload, {
+ body: { upload_completed: true },
+ pathParams: {
+ id: data.id,
+ fileType: type,
+ associatingId: getAssociatedId(),
+ },
+ });
};
- const handleUpload = async (status: any) => {
+ const handleUpload = async () => {
if (!validateFileUpload()) return;
const f = file;
@@ -1013,24 +963,23 @@ export const FileUpload = (props: FileUploadProps) => {
const filename = uploadFileName === "" && f ? f.name : uploadFileName;
const name = f?.name;
setUploadStarted(true);
- // setUploadSuccess(false);
- const requestData = {
- original_name: name,
- file_type: type,
- name: filename,
- associating_id: getAssociatedId(),
- file_category: category,
- mime_type: f?.type,
- };
- dispatch(createUpload(requestData))
- .then(uploadfile)
- .then(markUploadComplete)
- .catch(() => {
- setUploadStarted(false);
- })
- .then(() => {
- fetchData(status);
- });
+
+ const { data } = await request(routes.createUpload, {
+ body: {
+ original_name: name,
+ file_type: type,
+ name: filename,
+ associating_id: getAssociatedId(),
+ file_category: category,
+ mime_type: f?.type,
+ },
+ });
+
+ if (data) {
+ await uploadfile(data);
+ await markUploadComplete(data);
+ await fetchData();
+ }
};
const createAudioBlob = (createdBlob: Blob) => {
@@ -1071,7 +1020,7 @@ export const FileUpload = (props: FileUploadProps) => {
setAudioUploadStarted(false);
// setUploadSuccess(true);
setAudioName("");
- setReload(!reload);
+ fetchData();
Notification.Success({
msg: "File Uploaded Successfully",
});
@@ -1102,16 +1051,17 @@ export const FileUpload = (props: FileUploadProps) => {
const filename =
audioName.trim().length === 0 ? Date.now().toString() : audioName.trim();
setAudioUploadStarted(true);
- // setUploadSuccess(false);
- const requestData = {
- original_name: name,
- file_type: type,
- name: filename,
- associating_id: getAssociatedId(),
- file_category: category,
- mime_type: audioBlob?.type,
- };
- dispatch(createUpload(requestData))
+
+ request(routes.createUpload, {
+ body: {
+ original_name: name,
+ file_type: type,
+ name: filename,
+ associating_id: getAssociatedId(),
+ file_category: category,
+ mime_type: audioBlob?.type,
+ },
+ })
.then(uploadAudiofile)
.catch(() => {
setAudioUploadStarted(false);
@@ -1318,7 +1268,7 @@ export const FileUpload = (props: FileUploadProps) => {
onSubmit={(event: any) => {
event.preventDefault();
setbtnloader(true);
- partialupdateFileName(modalDetails?.id, editFileName);
+ partialupdateFileName(modalDetails!.id!, editFileName);
}}
className="flex w-full flex-col"
>
@@ -1364,7 +1314,7 @@ export const FileUpload = (props: FileUploadProps) => {
onSubmit={(event: any) => {
event.preventDefault();
setbtnloader(true);
- archiveFile(modalDetails?.id, archiveReason);
+ archiveFile(modalDetails!.id!, archiveReason);
}}
className="mx-2 my-4 flex w-full flex-col"
>
@@ -1433,8 +1383,8 @@ export const FileUpload = (props: FileUploadProps) => {
hideBack={hideBack}
breadcrumbs={false}
crumbsReplacements={{
- [facilityId]: { name: facilityName },
- [patientId]: { name: patientName },
+ [facilityId]: { name: patient?.facility_object?.name },
+ [patientId]: { name: patient?.name },
}}
backUrl={
type === "CONSULTATION"
@@ -1558,8 +1508,12 @@ export const FileUpload = (props: FileUploadProps) => {
handleUpload({ status })}
+ disabled={
+ !file ||
+ !uploadFileName ||
+ (patient && !patient.is_active)
+ }
+ onClick={handleUpload}
className="w-full"
>
@@ -1576,7 +1530,7 @@ export const FileUpload = (props: FileUploadProps) => {
setUploadFileName("");
}}
>
-
+
)}
diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx
index 534a3e876a1..d853a5cf71a 100644
--- a/src/Components/Patient/ManagePatients.tsx
+++ b/src/Components/Patient/ManagePatients.tsx
@@ -511,7 +511,10 @@ export const PatientManager = () => {
) : (
-
+
)}
diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx
index 22dc86117f4..1e74b1ac566 100644
--- a/src/Components/Patient/PatientHome.tsx
+++ b/src/Components/Patient/PatientHome.tsx
@@ -284,7 +284,7 @@ export const PatientHome = (props: any) => {
target="_blank"
rel="noreferrer"
>
-
Video Call
+
Video Call
)}
@@ -308,7 +308,7 @@ export const PatientHome = (props: any) => {
-
+
You have not created a consultation for the patient in{" "}
{patientData.facility_object?.name || "-"}
@@ -409,7 +409,10 @@ export const PatientHome = (props: any) => {
-
+
{patientData.facility_object?.name || "-"}
@@ -445,7 +448,7 @@ export const PatientHome = (props: any) => {
className="text-sm font-normal text-sky-600 hover:text-sky-300"
rel="noreferrer"
>
- Chat on WhatsApp
+ Chat on WhatsApp
@@ -470,7 +473,7 @@ export const PatientHome = (props: any) => {
className="text-sm font-normal text-sky-600 hover:text-sky-300"
rel="noreferrer"
>
-
Chat on WhatsApp
+
Chat on WhatsApp
@@ -548,7 +551,7 @@ export const PatientHome = (props: any) => {
: " bg-red-600/5 p-1 text-sm font-normal text-red-600")
}
>
-
+
{(dayjs().isBefore(patientData.review_time)
? "Review before: "
@@ -616,7 +619,7 @@ export const PatientHome = (props: any) => {
name="death_report"
onClick={() => navigate(`/death_report/${id}`)}
>
-
+
Death Report
diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index 25683e1a461..fe6c7b64895 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -185,7 +185,10 @@ export default function PatientInfoCard(props: {
) : (
-
+
)}
@@ -218,10 +221,11 @@ export default function PatientInfoCard(props: {
href={`/facility/${consultation?.facility}`}
className="mt-2 items-center justify-center text-sm font-semibold text-black hover:text-primary-600 lg:hidden"
>
-
+ />
{consultation?.facility_name}
@@ -234,10 +238,11 @@ export default function PatientInfoCard(props: {
href={`/facility/${consultation?.facility}`}
className="hidden font-semibold text-black hover:text-primary-600 lg:block"
>
-
+ />
{consultation?.facility_name}
@@ -301,7 +306,7 @@ export default function PatientInfoCard(props: {
: " bg-red-400 text-white")
}
>
-
+
{dayjs().isBefore(patient.review_time)
? "Review before: "
: "Review Missed: "}
@@ -432,7 +437,10 @@ export default function PatientInfoCard(props: {
{consultation?.treating_physician_object
? `${consultation?.treating_physician_object.first_name} ${consultation?.treating_physician_object.last_name}`
: consultation?.deprecated_verified_by}
-
+
)}
@@ -531,7 +539,7 @@ export default function PatientInfoCard(props: {
title={"Manage Patient"}
icon={
}
className="xl:justify-center"
- containerClassName="w-full lg:w-auto mt-2 2xl:mt-0 flex justify-center"
+ containerClassName="w-full lg:w-auto mt-2 2xl:mt-0 flex justify-center z-20"
>
{[
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx
index 2f18ef36dbb..c6b260efe87 100644
--- a/src/Components/Patient/PatientRegister.tsx
+++ b/src/Components/Patient/PatientRegister.tsx
@@ -1387,7 +1387,10 @@ export const PatientRegister = (props: PatientRegisterProps) => {
/>
{showAutoFilledPincode && (
-
+
State and District auto-filled from Pincode
diff --git a/src/Components/Patient/UpdateStatusDialog.tsx b/src/Components/Patient/UpdateStatusDialog.tsx
index 11f442b7a65..c302aa1b957 100644
--- a/src/Components/Patient/UpdateStatusDialog.tsx
+++ b/src/Components/Patient/UpdateStatusDialog.tsx
@@ -5,10 +5,8 @@ import {
SAMPLE_TEST_RESULT,
SAMPLE_FLOW_RULES,
} from "../../Common/constants";
-import { SampleTestModel } from "./models";
+import { CreateFileResponse, SampleTestModel } from "./models";
import * as Notification from "../../Utils/Notifications.js";
-import { createUpload, editUpload } from "../../Redux/actions";
-import { useDispatch } from "react-redux";
import { header_content_type, LinearProgressWithLabel } from "./FileUpload";
import { Submit } from "../Common/components/ButtonV2";
import CareIcon from "../../CAREUI/icons/CareIcon";
@@ -18,6 +16,8 @@ import { FieldChangeEvent } from "../Form/FormFields/Utils";
import TextFormField from "../Form/FormFields/TextFormField";
import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField";
import { useTranslation } from "react-i18next";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
interface Props {
sample: SampleTestModel;
@@ -62,7 +62,6 @@ const UpdateStatusDialog = (props: Props) => {
const [uploadPercent, setUploadPercent] = useState(0);
const [uploadStarted, setUploadStarted] = useState(false);
const [uploadDone, setUploadDone] = useState(false);
- const redux_dispatch: any = useDispatch();
const currentStatus = SAMPLE_TEST_STATUS.find(
(i) => i.text === sample.status
@@ -97,9 +96,10 @@ const UpdateStatusDialog = (props: Props) => {
dispatch({ type: "set_form", form });
};
- const uploadfile = (response: any) => {
- const url = response.data.signed_url;
- const internal_name = response.data.internal_name;
+ const uploadfile = (data: CreateFileResponse) => {
+ const url = data.signed_url;
+ const internal_name = data.internal_name;
+
const f = file;
if (f === undefined) return;
const newFile = new File([f], `${internal_name}`);
@@ -116,29 +116,27 @@ const UpdateStatusDialog = (props: Props) => {
setUploadPercent(percentCompleted);
},
};
+
axios
.put(url, newFile, config)
.then(() => {
setUploadStarted(false);
setUploadDone(true);
- redux_dispatch(
- editUpload(
- { upload_completed: true },
- response.data.id,
- "SAMPLE_MANAGEMENT",
- sample.id?.toString() ?? ""
- )
- );
- Notification.Success({
- msg: "File Uploaded Successfully",
+ request(routes.editUpload, {
+ pathParams: {
+ id: data.id,
+ fileType: "SAMPLE_MANAGEMENT",
+ associatingId: sample.id?.toString() ?? "",
+ },
+ body: { upload_completed: true },
});
+
+ Notification.Success({ msg: "File Uploaded Successfully" });
})
- .catch(() => {
- setUploadStarted(false);
- });
+ .catch(() => setUploadStarted(false));
};
- const onFileChange = (e: React.ChangeEvent): any => {
+ const onFileChange = (e: React.ChangeEvent) => {
if (e.target.files == null) {
throw new Error("Error finding e.target.files");
}
@@ -155,19 +153,21 @@ const UpdateStatusDialog = (props: Props) => {
const name = f.name;
setUploadStarted(true);
setUploadDone(false);
- const requestData = {
- original_name: name,
- file_type: "SAMPLE_MANAGEMENT",
- name: `${sample.patient_name} Sample Report`,
- associating_id: sample.id,
- file_category: category,
- mime_type: contentType,
- };
- redux_dispatch(createUpload(requestData))
- .then(uploadfile)
- .catch(() => {
- setUploadStarted(false);
- });
+
+ const { data } = await request(routes.createUpload, {
+ body: {
+ original_name: name,
+ file_type: "SAMPLE_MANAGEMENT",
+ name: `${sample.patient_name} Sample Report`,
+ associating_id: sample.id,
+ file_category: category,
+ mime_type: contentType,
+ },
+ });
+
+ if (data) {
+ uploadfile(data);
+ }
};
return (
diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx
index fc87bedcb14..05eb780069d 100644
--- a/src/Components/Patient/models.tsx
+++ b/src/Components/Patient/models.tsx
@@ -147,7 +147,7 @@ export interface SampleTestModel {
is_unusual_course?: boolean;
sample_type?: string;
sample_type_other?: string;
- id?: number;
+ id?: string;
status?: string;
result?: string;
icmr_category?: string;
@@ -337,16 +337,36 @@ export interface FacilityNameModel {
// File Upload Models
+type FileCategory = "UNSPECIFIED" | "XRAY" | "AUDIO" | "IDENTITY_PROOF";
+
+export interface CreateFileRequest {
+ file_type: string;
+ file_category: FileCategory;
+ name: string;
+ associating_id: string;
+ original_name: string;
+ mime_type: string;
+}
+
+export interface CreateFileResponse {
+ id: string;
+ file_type: string;
+ file_category: FileCategory;
+ signed_url: string;
+ internal_name: string;
+}
+
export interface FileUploadModel {
id?: string;
name?: string;
created_date?: string;
upload_completed?: boolean;
- uploaded_by?: { username?: string };
- file_category?: string;
+ uploaded_by?: PerformedByModel;
+ file_category?: FileCategory;
+ read_signed_url?: string;
is_archived?: boolean;
archive_reason?: string;
extension?: string;
- archived_by?: { username?: string };
+ archived_by?: PerformedByModel;
archived_datetime?: string;
}
diff --git a/src/Components/Resource/ListView.tsx b/src/Components/Resource/ListView.tsx
index 05b2ce2f4bb..2cf8b9eb26d 100644
--- a/src/Components/Resource/ListView.tsx
+++ b/src/Components/Resource/ListView.tsx
@@ -77,7 +77,7 @@ export default function ListView() {
title="Resource status"
className="flex items-center text-sm font-medium leading-5 text-gray-500"
>
-
+
{resource.status}
@@ -88,7 +88,7 @@ export default function ListView() {
title=" Origin facility"
className="flex items-center text-sm font-medium leading-5 text-gray-500"
>
-
+
{(resource.origin_facility_object || {}).name}
@@ -99,7 +99,7 @@ export default function ListView() {
title="Resource approving facility"
className="flex items-center text-sm font-medium leading-5 text-gray-500"
>
-
+
{(resource.approving_facility_object || {}).name}
@@ -110,7 +110,7 @@ export default function ListView() {
title=" Assigned facility"
className="flex items-center text-sm font-medium leading-5 text-gray-500"
>
-
+
{(resource.assigned_facility_object || {}).name ||
@@ -131,7 +131,7 @@ export default function ListView() {
: "rounded bg-red-400 p-1 text-white")
}
>
-
+
{formatDateTime(resource.modified_date) || "--"}
@@ -146,7 +146,7 @@ export default function ListView() {
onClick={(_) => navigate(`/resource/${resource.id}`)}
className="btn btn-default mr-2 w-full bg-white"
>
- All Details
+ All Details
@@ -204,7 +204,11 @@ export default function ListView() {
className="text-xs hover:text-blue-800"
onClick={() => refetch()}
>
-