From 471b2f55c2902dccf6876f25512c2e8523fef132 Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Thu, 19 Sep 2024 19:19:14 +0530 Subject: [PATCH 1/2] Patient Registration: Adds social profile section (#8570) --- .../patient_spec/PatientRegistration.cy.ts | 4 + cypress/e2e/users_spec/user_manage.cy.ts | 149 ------------------ cypress/e2e/users_spec/user_profile.cy.ts | 82 ---------- cypress/pageobject/Patient/PatientCreation.ts | 13 ++ cypress/support/commands.ts | 4 + cypress/support/index.ts | 1 + src/Common/constants.tsx | 14 ++ src/Components/Patient/PatientHome.tsx | 54 +++++-- src/Components/Patient/PatientRegister.tsx | 114 +++++++++++--- src/Components/Patient/models.tsx | 15 +- src/Locale/en/Patient.json | 14 ++ src/Locale/en/index.js | 2 + 12 files changed, 196 insertions(+), 270 deletions(-) delete mode 100644 cypress/e2e/users_spec/user_manage.cy.ts delete mode 100644 cypress/e2e/users_spec/user_profile.cy.ts create mode 100644 src/Locale/en/Patient.json diff --git a/cypress/e2e/patient_spec/PatientRegistration.cy.ts b/cypress/e2e/patient_spec/PatientRegistration.cy.ts index 2e7ce853fc5..ef92c2e9bd1 100644 --- a/cypress/e2e/patient_spec/PatientRegistration.cy.ts +++ b/cypress/e2e/patient_spec/PatientRegistration.cy.ts @@ -101,6 +101,8 @@ describe("Patient Creation with consultation", () => { facilityPage.selectLocalBody(patientOneLocalbody); facilityPage.selectWard(patientOneWard); patientPage.selectPatientOccupation(patientOccupation); + patientPage.selectSocioeconomicStatus("MIDDLE_CLASS"); + patientPage.selectDomesticHealthcareSupport("FAMILY_MEMBER"); // Patient Medical History patientMedicalHistory.typePatientPresentHealth(patientOnePresentHealth); patientMedicalHistory.typePatientOngoingMedication( @@ -130,6 +132,8 @@ describe("Patient Creation with consultation", () => { yearOfBirth, patientOneBloodGroup, patientOccupation, + "Middle Class", + "Family member", ); patientMedicalHistory.verifyPatientMedicalDetails( patientOnePresentHealth, diff --git a/cypress/e2e/users_spec/user_manage.cy.ts b/cypress/e2e/users_spec/user_manage.cy.ts deleted file mode 100644 index c2116954354..00000000000 --- a/cypress/e2e/users_spec/user_manage.cy.ts +++ /dev/null @@ -1,149 +0,0 @@ -import LoginPage from "../../pageobject/Login/LoginPage"; -import { UserPage } from "../../pageobject/Users/UserSearch"; -import ManageUserPage from "../../pageobject/Users/ManageUserPage"; -import { UserCreationPage } from "../../pageobject/Users/UserCreation"; - -describe("Manage User", () => { - const loginPage = new LoginPage(); - const userPage = new UserPage(); - const manageUserPage = new ManageUserPage(); - const usernametolinkfacilitydoc1 = "dummydoctor4"; - const usernametolinkfacilitydoc2 = "dummydoctor5"; - const usernametolinkfacilitydoc3 = "dummydoctor6"; - const usernametolinkskill = "devdoctor"; - const userCreationPage = new UserCreationPage(); - const usernameforworkinghour = "devdistrictadmin"; - const usernamerealname = "Dummy Doctor"; - const facilitytolinkusername = "Dummy Shifting Center"; - const facilitytolinkskill = "Dummy Facility 40"; - const workinghour = "23"; - const linkedskill = "General Medicine"; - - before(() => { - loginPage.loginAsDisctrictAdmin(); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/users"); - }); - - it("linking skills for users and verify its reflection in profile", () => { - // select the district user and select one skill link and verify its profile reflection - userPage.typeInSearchInput(usernameforworkinghour); - userPage.checkUsernameText(usernameforworkinghour); - manageUserPage.clicklinkedskillbutton(); - manageUserPage.selectSkillFromDropdown(linkedskill); - manageUserPage.clickAddSkillButton(); - manageUserPage.clickCloseSlideOver(); - cy.wait(5000); - manageUserPage.clicklinkedskillbutton(); - manageUserPage.assertSkillInAddedUserSkills(linkedskill); - manageUserPage.clickCloseSlideOver(); - cy.wait(5000); - manageUserPage.navigateToProfile(); - userCreationPage.verifyElementContainsText( - "username-profile-details", - usernameforworkinghour, - ); - manageUserPage.assertSkillInAlreadyLinkedSkills(linkedskill); - }); - - it("linking skills for a doctor users and verify its reflection in doctor connect", () => { - // select a doctor user and link and unlink same skill twice and verify the badge is only shown once in doctor connect - userPage.typeInSearchInput(usernametolinkskill); - userPage.checkUsernameText(usernametolinkskill); - manageUserPage.clicklinkedskillbutton(); - manageUserPage.selectSkillFromDropdown(linkedskill); - manageUserPage.clickAddSkillButton(); - manageUserPage.clickCloseSlideOver(); - cy.wait(5000); // temporary hack to fix the failure - manageUserPage.clicklinkedskillbutton(); - manageUserPage.assertSkillInAddedUserSkills(linkedskill); - manageUserPage.clickUnlinkSkill(); - manageUserPage.clickSubmit(); - manageUserPage.selectSkillFromDropdown(linkedskill); - manageUserPage.clickAddSkillButton(); - manageUserPage.clickCloseSlideOver(); - // verifying the doctor connect - manageUserPage.navigateToFacility(); - manageUserPage.typeFacilitySearch(facilitytolinkskill); - manageUserPage.assertFacilityInCard(facilitytolinkskill); - manageUserPage.clickFacilityPatients(); - manageUserPage.clickDoctorConnectButton(); - manageUserPage.assertSkillIndoctorconnect(linkedskill); - }); - - it("add working hour for a user and verify its reflection in card and user profile", () => { - // verify mandatory field error and select working hour for a user - userPage.typeInSearchInput(usernameforworkinghour); - userPage.checkUsernameText(usernameforworkinghour); - manageUserPage.clicksetaveragehourbutton(); - manageUserPage.clearweeklyhourfield(); - manageUserPage.clickSubmit(); - manageUserPage.verifyErrorText("Value should be between 0 and 168"); - // verify the data is reflected in user card and profile page - manageUserPage.typeInWeeklyWorkingHours(workinghour); - manageUserPage.clickSubmit(); - manageUserPage.verifyWorkingHours(workinghour); - manageUserPage.navigateToProfile(); - manageUserPage.verifyProfileWorkingHours(workinghour); - }); - - it("linking and unlinking facility for multiple users, and confirm reflection in user cards and doctor connect", () => { - // verify the user doesn't have any home facility - userPage.typeInSearchInput(usernametolinkfacilitydoc1); - userPage.checkUsernameText(usernametolinkfacilitydoc1); - manageUserPage.assertHomeFacility("No Home Facility"); - // Link a new facility and ensure it is under linked facility - doctor username (1) - manageUserPage.clickFacilitiesTab(); - manageUserPage.selectFacilityFromDropdown(facilitytolinkusername); - manageUserPage.clickLinkFacility(); - manageUserPage.assertLinkedFacility(facilitytolinkusername); - // Verify in the already linked facility are not present in droplist - manageUserPage.assertFacilityNotInDropdown(facilitytolinkusername); - manageUserPage.clickCloseSlideOver(); - // Link a new facility and ensure it is under home facility - doctor username (2) - userPage.clearSearchInput(); - userPage.typeInSearchInput(usernametolinkfacilitydoc2); - userPage.checkUsernameText(usernametolinkfacilitydoc2); - manageUserPage.clickFacilitiesTab(); - manageUserPage.selectFacilityFromDropdown(facilitytolinkusername); - manageUserPage.clickLinkFacility(); - manageUserPage.clickHomeFacilityIcon(); - manageUserPage.assertnotLinkedFacility(facilitytolinkusername); - manageUserPage.assertHomeFacilitylink(facilitytolinkusername); - manageUserPage.clickCloseSlideOver(); - // verify the home facility doctor id have reflection in user card - userPage.clearSearchInput(); - userPage.typeInSearchInput(usernametolinkfacilitydoc2); - userPage.checkUsernameText(usernametolinkfacilitydoc2); - manageUserPage.assertHomeFacility(facilitytolinkusername); - // Link a new facility and unlink the facility from the doctor username (3) - userPage.clearSearchInput(); - userPage.typeInSearchInput(usernametolinkfacilitydoc3); - userPage.checkUsernameText(usernametolinkfacilitydoc3); - manageUserPage.clickFacilitiesTab(); - manageUserPage.selectFacilityFromDropdown(facilitytolinkusername); - manageUserPage.clickLinkFacility(); - manageUserPage.clickUnlinkFacilityButton(); - manageUserPage.clickSubmit(); - manageUserPage.assertnotLinkedFacility; - manageUserPage.linkedfacilitylistnotvisible(); - manageUserPage.clickCloseSlideOver(); - // Go to particular facility doctor connect and all user-id are reflected based on there access - // Path will be facility page to patient page then doctor connect button - manageUserPage.navigateToFacility(); - manageUserPage.typeFacilitySearch(facilitytolinkusername); - manageUserPage.assertFacilityInCard(facilitytolinkusername); - manageUserPage.clickFacilityPatients(); - manageUserPage.clickDoctorConnectButton(); - manageUserPage.assertDoctorConnectVisibility(usernamerealname); - }); - - afterEach(() => { - cy.saveLocalStorage(); - }); -}); diff --git a/cypress/e2e/users_spec/user_profile.cy.ts b/cypress/e2e/users_spec/user_profile.cy.ts deleted file mode 100644 index 40880d95edb..00000000000 --- a/cypress/e2e/users_spec/user_profile.cy.ts +++ /dev/null @@ -1,82 +0,0 @@ -import LoginPage from "../../pageobject/Login/LoginPage"; -import UserProfilePage from "../../pageobject/Users/UserProfilePage"; -import ManageUserPage from "../../pageobject/Users/ManageUserPage"; - -describe("Manage User Profile", () => { - const loginPage = new LoginPage(); - const userProfilePage = new UserProfilePage(); - const manageUserPage = new ManageUserPage(); - - const date_of_birth = "01011999"; - const gender = "Male"; - const email = "test@example.com"; - const phone = "+918899887788"; - const workinghours = "8"; - const doctorQualification = "MBBS"; - const doctorYoE = "10"; - const medicalCouncilRegistration = "1234567890"; - - const facilitySearch = "Dummy Facility 40"; - - before(() => { - loginPage.loginAsDevDoctor(); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/user/profile"); - }); - - it("Set Dob, Gender, Email, Phone and Working Hours for a user and verify its reflection in user profile", () => { - userProfilePage.clickEditProfileButton(); - - userProfilePage.typedate_of_birth(date_of_birth); - userProfilePage.selectGender(gender); - userProfilePage.typeEmail(email); - userProfilePage.typePhone(phone); - userProfilePage.typeWhatsApp(phone); - userProfilePage.typeWorkingHours(workinghours); - userProfilePage.typeDoctorQualification(doctorQualification); - userProfilePage.typeDoctorYoE(doctorYoE); - userProfilePage.typeMedicalCouncilRegistration(medicalCouncilRegistration); - - userProfilePage.clickUpdateButton(); - - cy.verifyNotification("Details updated successfully"); - - userProfilePage.assertdate_of_birth("01/01/1999"); - userProfilePage.assertGender(gender); - userProfilePage.assertEmail(email); - userProfilePage.assertPhone(phone); - userProfilePage.assertWhatsApp(phone); - userProfilePage.assertWorkingHours(workinghours); - }); - - it("Adding video connect link for a user and verify its reflection in user profile and doctor connect", () => { - // verify the user doesn't have any video connect link - userProfilePage.assertVideoConnectLink("-"); - // Link a new video connect link and ensure it is under video connect link - userProfilePage.clickEditProfileButton(); - userProfilePage.typeVideoConnectLink("https://www.example.com"); - userProfilePage.clickUpdateButton(); - userProfilePage.assertVideoConnectLink("https://www.example.com"); - // Edit the video connect link and ensure it is updated - userProfilePage.clickEditProfileButton(); - userProfilePage.typeVideoConnectLink("https://www.test.com"); - userProfilePage.clickUpdateButton(); - userProfilePage.assertVideoConnectLink("https://www.test.com"); - // Go to particular facility doctor connect and verify the video connect link is present - manageUserPage.navigateToFacility(); - manageUserPage.typeFacilitySearch(facilitySearch); - manageUserPage.assertFacilityInCard(facilitySearch); - manageUserPage.clickFacilityPatients(); - manageUserPage.clickDoctorConnectButton(); - manageUserPage.assertVideoConnectLink("Dev Doctor", "https://www.test.com"); - }); - - afterEach(() => { - cy.saveLocalStorage(); - }); -}); diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index db3c10fdcb5..e037f0888f0 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -117,6 +117,14 @@ export class PatientPage { cy.searchAndSelectOption("#occupation", occupation); } + selectSocioeconomicStatus(value: string) { + cy.selectRadioOption("socioeconomic_status", value); + } + + selectDomesticHealthcareSupport(value: string) { + cy.selectRadioOption("domestic_healthcare_support", value); + } + clickCreatePatient() { cy.intercept("POST", "**/api/v1/patient/").as("createPatient"); cy.get("button[data-testid='submit-button']").click(); @@ -165,6 +173,8 @@ export class PatientPage { yearOfBirth, bloodGroup, occupation, + socioeconomicStatus = null, + domesticHealthcareSupport = null, isAntenatal = false, isPostPartum = false, ) { @@ -178,6 +188,9 @@ export class PatientPage { expect($dashboard).to.contain(yearOfBirth); expect($dashboard).to.contain(bloodGroup); expect($dashboard).to.contain(occupation); + socioeconomicStatus && expect($dashboard).to.contain(socioeconomicStatus); + domesticHealthcareSupport && + expect($dashboard).to.contain(domesticHealthcareSupport); if (isAntenatal) { expect($dashboard).to.contain("Antenatal"); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index c6437505349..86d048e5f41 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -169,6 +169,10 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add("selectRadioOption", (name: string, value: string) => { + cy.get(`input[type='radio'][name='${name}'][value=${value}]`).click(); +}); + Cypress.Commands.add("clickAndTypeDate", (selector: string, date: string) => { cy.get(selector).scrollIntoView(); cy.get(selector).click(); diff --git a/cypress/support/index.ts b/cypress/support/index.ts index 9ddfd0c819a..d660246324f 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -23,6 +23,7 @@ declare global { selector: string, symptoms: string | string[], ): Chainable; + selectRadioOption(name: string, value: string): Chainable; typeAndMultiSelectOption( selector: string, input: string, diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx index 9998762cc05..8149a144ed9 100644 --- a/src/Common/constants.tsx +++ b/src/Common/constants.tsx @@ -1415,6 +1415,20 @@ export const CONSENT_PATIENT_CODE_STATUS_CHOICES = [ { id: 3, text: "Comfort Care Only" }, { id: 4, text: "Active treatment" }, ]; + +export const SOCIOECONOMIC_STATUS_CHOICES = [ + "MIDDLE_CLASS", + "POOR", + "VERY_POOR", + "WELL_OFF", +] as const; + +export const DOMESTIC_HEALTHCARE_SUPPORT_CHOICES = [ + "FAMILY_MEMBER", + "PAID_CAREGIVER", + "NO_SUPPORT", +] as const; + export const OCCUPATION_TYPES = [ { id: 27, diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index fc173f26213..6fe6ba8c3ce 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -515,24 +515,50 @@ export const PatientHome = (props: any) => { )} -
-
- Occupation + {patientData.meta_info?.occupation && ( +
+
+ {t("occupation")} +
+
+ {parseOccupation(patientData.meta_info.occupation)} +
-
- {parseOccupation(patientData.meta_info?.occupation) || "-"} + )} + {patientData.ration_card_category && ( +
+
+ {t("ration_card_category")} +
+
+ {t(`ration_card__${patientData.ration_card_category}`)} +
-
-
-
- Ration Card Category + )} + {patientData.meta_info?.socioeconomic_status && ( +
+
+ {t("socioeconomic_status")} +
+
+ {t( + `SOCIOECONOMIC_STATUS__${patientData.meta_info.socioeconomic_status}`, + )} +
-
- {patientData.ration_card_category - ? t(`ration_card__${patientData.ration_card_category}`) - : "-"} + )} + {patientData.meta_info?.domestic_healthcare_support && ( +
+
+ {t("domestic_healthcare_support")} +
+
+ {t( + `DOMESTIC_HEALTHCARE_SUPPORT__${patientData.meta_info.domestic_healthcare_support}`, + )} +
-
+ )}
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx index 17eb745496b..033d0187649 100644 --- a/src/Components/Patient/PatientRegister.tsx +++ b/src/Components/Patient/PatientRegister.tsx @@ -2,10 +2,12 @@ import * as Notification from "../../Utils/Notifications.js"; import { BLOOD_GROUPS, + DOMESTIC_HEALTHCARE_SUPPORT_CHOICES, GENDER_TYPES, MEDICAL_HISTORY_CHOICES, OCCUPATION_TYPES, RATION_CARD_CATEGORY, + SOCIOECONOMIC_STATUS_CHOICES, VACCINES, } from "../../Common/constants"; import { @@ -48,7 +50,7 @@ import { HCXPolicyModel } from "../HCX/models"; import HCXPolicyValidator from "../HCX/validators"; import InsuranceDetailsBuilder from "../HCX/InsuranceDetailsBuilder"; import LinkABHANumberModal from "../ABDM/LinkABHANumberModal"; -import { PatientModel, Occupation } from "./models"; +import { PatientModel, Occupation, PatientMeta } from "./models"; import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField"; import RadioFormField from "../Form/FormFields/RadioFormField"; import { SelectFormField } from "../Form/FormFields/SelectFormField"; @@ -77,6 +79,9 @@ import careConfig from "@careConfig"; const Loading = lazy(() => import("../Common/Loading")); const PageTitle = lazy(() => import("../Common/PageTitle")); +type PatientForm = PatientModel & + PatientMeta & { age?: number; is_postpartum?: boolean }; + interface PatientRegisterProps extends PatientModel { facilityId: string; } @@ -191,7 +196,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { const [isLoading, setIsLoading] = useState(false); const [showImport, setShowImport] = useState<{ show?: boolean; - field?: FormContextValue | null; + field?: FormContextValue | null; }>({ show: false, field: null, @@ -430,6 +435,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { occupation: data.meta_info?.occupation ? parseOccupationFromExt(data.meta_info.occupation) : null, + is_vaccinated: String(data.is_vaccinated), number_of_doses: data.number_of_doses ? String(data.number_of_doses) @@ -749,7 +755,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { formData.nationality === "India" ? formData.local_body : undefined, ward: formData.ward, meta_info: { - ...state.form?.meta_info, + ...formData.meta_info, occupation: formData.occupation ?? null, }, village: formData.village, @@ -1161,7 +1167,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { )} <>
- + defaults={id ? state.form : initForm} validate={validateForm} onSubmit={handleSubmit} @@ -1754,22 +1760,6 @@ export const PatientRegister = (props: PatientRegisterProps) => { /> )}
- o.text} - optionValue={(o) => o.id} - /> - t(`ration_card__${o}`)} - optionValue={(o) => o} - /> ) : (
@@ -1782,6 +1772,90 @@ export const PatientRegister = (props: PatientRegisterProps) => { )}
+ {field("nationality").value === "India" && ( +
+ + } + title={ +

+ Social Profile +

+ } + expanded + > +
+
+ o.text} + optionValue={(o) => o.id} + /> + t(`ration_card__${o}`)} + optionValue={(o) => o} + /> + + t(`SOCIOECONOMIC_STATUS__${o}`) + } + optionValue={(o) => o} + value={ + field("meta_info").value + ?.socioeconomic_status + } + onChange={({ name, value }) => + field("meta_info").onChange({ + name: "meta_info", + value: { + ...(field("meta_info").value ?? {}), + [name]: value, + }, + }) + } + /> + + t(`DOMESTIC_HEALTHCARE_SUPPORT__${o}`) + } + optionValue={(o) => o} + value={ + field("meta_info").value + ?.domestic_healthcare_support + } + onChange={({ name, value }) => + field("meta_info").onChange({ + name: "meta_info", + value: { + ...(field("meta_info").value ?? {}), + [name]: value, + }, + }) + } + /> +
+
+
+
+ )}
Date: Thu, 19 Sep 2024 19:20:01 +0530 Subject: [PATCH 2/2] Convert supported browsers command to a script (#8564) --- package.json | 4 ++-- scripts/generate-supported-browsers.mjs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 scripts/generate-supported-browsers.mjs diff --git a/package.json b/package.json index cfc0b3389a2..cc2c7b955c2 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "scripts": { "build:react": "cross-env NODE_ENV=production vite build", "build": "npm run generate-build-meta && npm run supported-browsers && npm run build:react", - "dev": "vite", + "dev": "npm run supported-browsers && vite", "preview": "cross-env NODE_ENV=production vite preview", "generate-build-meta": "node ./scripts/generate-build-version.js", "test": "snyk test", @@ -41,7 +41,7 @@ "lint": "eslint ./src", "lint-fix": "eslint ./src --fix", "format": "prettier ./src --write", - "supported-browsers": "echo \"export default $(browserslist-useragent-regexp --allowHigherVersions --ignorePatch --ignoreMinor);\" | sed 's/\\x1b\\[[0-9;]*m//g' > src/supportedBrowsers.ts" + "supported-browsers": "node ./scripts/generate-supported-browsers.mjs" }, "dependencies": { "@fontsource/inter": "^5.0.21", diff --git a/scripts/generate-supported-browsers.mjs b/scripts/generate-supported-browsers.mjs new file mode 100644 index 00000000000..2f8b627c57d --- /dev/null +++ b/scripts/generate-supported-browsers.mjs @@ -0,0 +1,17 @@ +import { getUserAgentRegex } from 'browserslist-useragent-regexp'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const regex = getUserAgentRegex({ + ignoreMinor: true, + ignorePatch: true, + allowZeroSubversions: false, + allowHigherVersions: true, +}); + +const supportedBrowsersPath = path.resolve(__dirname, '../src/supportedBrowsers.ts'); +fs.writeFileSync(supportedBrowsersPath, `export default ${regex};`);