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

Merge Develop to Staging v24.40.0 | Patch #8651

Merged
merged 5 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe("Patient Consultation in multiple combination", () => {
const patientWeight = "70";
const patientHeight = "170";
const medicineOne = "DOLOLUP";
const patientIpNumber = Math.random().toString(36).substring(7);
const patientIpNumber = `${Math.floor(Math.random() * 90 + 10)}/${Math.floor(Math.random() * 9000 + 1000)}`;

before(() => {
loginPage.loginAsDisctrictAdmin();
Expand Down Expand Up @@ -94,7 +94,7 @@ describe("Patient Consultation in multiple combination", () => {
cy.submitButton("Create Consultation");
// the above submit should fail as IP number is missing
patientConsultationPage.typePatientNumber(patientIpNumber);
patientConsultationPage.selectBed("Dummy Bed 1");
patientConsultationPage.selectBed("Dummy Bed 6");
cy.submitButton("Create Consultation");
cy.verifyNotification("Consultation created successfully");
// Below code for the prescription module only present while creating a new consultation
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/patient_spec/PatientPrescription.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PatientPage } from "../../pageobject/Patient/PatientCreation";
const patientPrescription = new PatientPrescription();
const loginPage = new LoginPage();
const patientPage = new PatientPage();
const medicineNameOne = "DOLO";
const medicineNameOne = "AGCON";
const medicineNameTwo = "FDEP PLUS";
const medicineBaseDosage = "4";
const medicineTargetDosage = "9";
Expand Down
12 changes: 12 additions & 0 deletions src/Common/hooks/useFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import PaginationComponent from "../../Components/Common/Pagination";
import { classNames, humanizeStrings } from "../../Utils/utils";
import FiltersCache from "../../Utils/FiltersCache";
import careConfig from "@careConfig";
import { triggerGoal } from "../../Integrations/Plausible";

export type FilterState = Record<string, unknown>;

Expand Down Expand Up @@ -42,6 +43,17 @@ export default function useFilters({
) => {
query = FiltersCache.utils.clean(query);
_setQueryParams(query, options);

// For each of the newly applied filters (additional filters compared to
// previously applied ones), trigger a plausible goal "Advanced filter
// applied" with the applied filter's query key and current location as tags.
Object.keys(query).forEach((filter) =>
triggerGoal("Advanced filter applied", {
filter,
location: location.pathname,
}),
);

updateCache(query);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTranslation } from "react-i18next";
import Chip from "../../../CAREUI/display/Chip";
import Timeline, {
TimelineEvent,
Expand Down Expand Up @@ -204,6 +205,7 @@ const BedTitleSuffix = ({
isLastNode?: boolean;
prevBed?: CurrentBed;
}) => {
const { t } = useTranslation();
return (
<div className="flex flex-col">
<div className="flex gap-x-2">
Expand All @@ -215,7 +217,7 @@ const BedTitleSuffix = ({
{bed.bed_object.id === prevBed?.bed_object.id
? "Asset changed in" + " "
: "Transferred to" + " "}
<span className="font-semibold">{`${bed.bed_object.name} (${bed.bed_object.bed_type}) in ${bed.bed_object.location_object?.name}`}</span>
<span className="font-semibold">{`${bed.bed_object.name} (${t(bed.bed_object.bed_type!)}) in ${bed.bed_object.location_object?.name}`}</span>
{bed.end_date === null && (
<Chip
text="In Use"
Expand Down
11 changes: 1 addition & 10 deletions src/Components/Facility/CoverImageEditModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Webcam from "react-webcam";
import { FacilityModel } from "./models";
import useWindowDimensions from "../../Common/hooks/useWindowDimensions";
import CareIcon from "../../CAREUI/icons/CareIcon";
import * as Notification from "../../Utils/Notifications.js";
import { useTranslation } from "react-i18next";
import { LocalStorageKeys } from "../../Common/constants";
import DialogModal from "../Common/Dialog";
Expand Down Expand Up @@ -130,25 +129,17 @@ const CoverImageEditModal = ({
"Bearer " + localStorage.getItem(LocalStorageKeys.accessToken),
},
async (xhr: XMLHttpRequest) => {
setIsProcessing(false);
if (xhr.status === 200) {
Success({ msg: "Cover image updated." });
setIsProcessing(false);
setIsCaptureImgBeingUploaded(false);
await sleep(1000);
onSave?.();
closeModal();
} else {
Notification.Error({
msg: "Something went wrong!",
});
setIsProcessing(false);
}
},
null,
() => {
Notification.Error({
msg: "Network Failure. Please check your internet connectivity.",
});
setIsProcessing(false);
},
);
Expand Down
11 changes: 6 additions & 5 deletions src/Components/Files/FileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export const FileUpload = (props: FileUploadProps) => {
"ods",
"pdf",
],
allowNameFallback: false,
onUpload: refetchAll,
});

Expand Down Expand Up @@ -259,7 +260,7 @@ export const FileUpload = (props: FileUploadProps) => {
</span>
<button
onClick={fileUpload.clearFiles}
disabled={!!fileUpload.progress}
disabled={fileUpload.uploading}
className="text-lg"
>
<CareIcon icon="l-times" />
Expand All @@ -271,8 +272,8 @@ export const FileUpload = (props: FileUploadProps) => {
label={t("enter_file_name")}
id="upload-file-name"
required
value={fileUpload.fileNames[0]}
disabled={!!fileUpload.progress}
value={fileUpload.fileNames[0] || ""}
disabled={fileUpload.uploading}
onChange={(e) => fileUpload.setFileName(e.value)}
error={fileUpload.error || undefined}
/>
Expand All @@ -281,7 +282,7 @@ export const FileUpload = (props: FileUploadProps) => {
onClick={() =>
fileUpload.handleFileUpload(associatedId)
}
loading={!!fileUpload.progress}
loading={fileUpload.uploading}
className="w-full"
id="upload_file_button"
>
Expand All @@ -291,7 +292,7 @@ export const FileUpload = (props: FileUploadProps) => {
<ButtonV2
variant="danger"
onClick={fileUpload.clearFiles}
disabled={!!fileUpload.progress}
disabled={fileUpload.uploading}
>
<CareIcon icon="l-trash-alt" className="" />
{t("discard")}
Expand Down
7 changes: 4 additions & 3 deletions src/Components/Patient/PatientConsentRecords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default function PatientConsentRecords(props: {
const fileUpload = useFileUpload({
type: "CONSENT_RECORD",
allowedExtensions: ["pdf", "jpg", "jpeg", "png"],
allowNameFallback: false,
});

const fileManager = useFileManager({
Expand Down Expand Up @@ -181,7 +182,7 @@ export default function PatientConsentRecords(props: {
<TextFormField
name="filename"
label="File Name"
value={fileUpload.fileNames[0]}
value={fileUpload.fileNames[0] || ""}
onChange={(e) => fileUpload.setFileName(e.value)}
/>
<div className="flex gap-2">
Expand All @@ -203,7 +204,7 @@ export default function PatientConsentRecords(props: {
handleUpload();
}
}}
loading={!!fileUpload.progress}
loading={fileUpload.uploading}
disabled={
newConsent.type === 2 &&
newConsent.patient_code_status === 0
Expand All @@ -216,7 +217,7 @@ export default function PatientConsentRecords(props: {
<ButtonV2
variant="danger"
onClick={fileUpload.clearFiles}
disabled={!!fileUpload.progress}
disabled={fileUpload.uploading}
>
<CareIcon icon="l-trash-alt" className="" />
</ButtonV2>
Expand Down
7 changes: 6 additions & 1 deletion src/Components/Users/UserAdd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,12 @@ export const UserAdd = (props: UserProps) => {
}, [state.form.phone_number_is_whatsapp, state.form.phone_number]);

const setFacility = (selected: FacilityModel | FacilityModel[] | null) => {
setSelectedFacility(selected as FacilityModel[]);
const newSelectedFacilities = selected
? Array.isArray(selected)
? selected
: [selected]
: [];
setSelectedFacility(newSelectedFacilities as FacilityModel[]);
const form = { ...state.form };
form.facilities = selected
? (selected as FacilityModel[]).map((i) => i.id!)
Expand Down
1 change: 1 addition & 0 deletions src/Locale/en/FileUpload.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"file_list_headings__supporting_info": "Supporting Info",
"file_error__choose_file": "Please choose a file to upload",
"file_error__file_name": "Please give a name for all files!",
"file_error__single_file_name": "Please give a name for the file",
"change_file": "Change File",
"file_error__file_size": "Maximum size of files is 100 MB",
"file_error__file_type": "Invalid file type \".{{extension}}\" Allowed types: {{allowedExtensions}}",
Expand Down
14 changes: 14 additions & 0 deletions src/Utils/request/uploadFile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Dispatch, SetStateAction } from "react";
import { handleUploadPercentage } from "./utils";
import * as Notification from "../../Utils/Notifications.js";

const uploadFile = (
url: string,
Expand All @@ -19,6 +20,16 @@ const uploadFile = (

xhr.onload = () => {
onLoad(xhr);
if (400 <= xhr.status && xhr.status <= 499) {
const error = JSON.parse(xhr.responseText);
if (typeof error === "object" && !Array.isArray(error)) {
Object.values(error).forEach((msg) => {
Notification.Error({ msg: msg || "Something went wrong!" });
});
} else {
Notification.Error({ msg: error || "Something went wrong!" });
}
}
};

if (setUploadPercent != null) {
Expand All @@ -28,6 +39,9 @@ const uploadFile = (
}

xhr.onerror = () => {
Notification.Error({
msg: "Network Failure. Please check your internet connectivity.",
});
onError();
};
xhr.send(file);
Expand Down
33 changes: 27 additions & 6 deletions src/Utils/useFileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
ChangeEvent,
DetailedHTMLProps,
InputHTMLAttributes,
useEffect,
useState,
} from "react";
import {
Expand All @@ -24,6 +25,8 @@ export type FileUploadOptions = {
type: string;
category?: FileCategory;
onUpload?: (file: FileUploadModel) => void;
// if allowed, will fallback to the name of the file if a seperate filename is not defined.
allowNameFallback?: boolean;
} & (
| {
allowedExtensions?: string[];
Expand Down Expand Up @@ -54,6 +57,7 @@ export type FileUploadReturn = {
setFileNames: (names: string[]) => void;
removeFile: (index: number) => void;
clearFiles: () => void;
uploading: boolean;
};

// Array of image extensions
Expand All @@ -71,13 +75,20 @@ const ExtImage: string[] = [
export default function useFileUpload(
options: FileUploadOptions,
): FileUploadReturn {
const { type, onUpload, category = "UNSPECIFIED", multiple } = options;
const {
type,
onUpload,
category = "UNSPECIFIED",
multiple,
allowNameFallback = true,
} = options;

const [uploadFileNames, setUploadFileNames] = useState<string[]>([]);
const [error, setError] = useState<string | null>(null);
const [progress, setProgress] = useState<null | number>(null);
const [cameraModalOpen, setCameraModalOpen] = useState(false);
const [audioModalOpen, setAudioModalOpen] = useState(false);
const [uploading, setUploading] = useState(false);

const [files, setFiles] = useState<File[]>([]);

Expand All @@ -104,6 +115,11 @@ export default function useFileUpload(
});
};

useEffect(() => {
const blanks = Array(files.length).fill("");
setUploadFileNames((names) => [...names, ...blanks].slice(0, files.length));
}, [files]);

const validateFileUpload = () => {
if (files.length === 0) {
setError(t("file_error__choose_file"));
Expand Down Expand Up @@ -199,9 +215,14 @@ export default function useFileUpload(

for (const [index, file] of files.entries()) {
const filename =
uploadFileNames[index] === "" && file
allowNameFallback && uploadFileNames[index] === "" && file
? file.name
: uploadFileNames[index];
if (!filename) {
setError(t("file_error__single_file_name"));
return;
}
setUploading(true);

const { data } = await request(routes.createUpload, {
body: {
Expand All @@ -220,6 +241,7 @@ export default function useFileUpload(
}
}

setUploading(false);
setFiles([]);
setUploadFileNames([]);
};
Expand All @@ -229,17 +251,15 @@ export default function useFileUpload(
<CameraCaptureDialog
show={cameraModalOpen}
onHide={() => setCameraModalOpen(false)}
onCapture={(file, fileName) => {
onCapture={(file) => {
setFiles((prev) => [...prev, file]);
setUploadFileNames((prev) => [...prev, fileName]);
}}
/>
<AudioCaptureDialog
show={audioModalOpen}
onHide={() => setAudioModalOpen(false)}
onCapture={(file, fileName) => {
onCapture={(file) => {
setFiles((prev) => [...prev, file]);
setUploadFileNames((prev) => [...prev, fileName]);
}}
autoRecord
/>
Expand Down Expand Up @@ -290,5 +310,6 @@ export default function useFileUpload(
setFiles([]);
setUploadFileNames([]);
},
uploading,
};
}
Loading