Skip to content

Commit

Permalink
Merge branch 'develop' into issues/10428/comment-section
Browse files Browse the repository at this point in the history
  • Loading branch information
modamaan authored Feb 11, 2025
2 parents 31e43f5 + 29060ed commit e640ead
Show file tree
Hide file tree
Showing 47 changed files with 1,375 additions and 606 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ REACT_APP_META_DESCRIPTION="Revolutionizing EMR with AI: Open Healthcare Network
REACT_APP_COVER_IMAGE=https://cdn.ohc.network/care_logo.svg
REACT_APP_COVER_IMAGE_ALT=https://cdn.ohc.network/care_logo.svg
REACT_PUBLIC_URL=https://care.ohc.network
HEADERS="/*\n Strict-Transport-Security: max-age=63072000; includeSubDomains; preload\n X-XSS-Protection: 1; mode=block\n X-Frame-Options: SAMEORIGIN\n X-Content-Type-Options: nosniff\n Referrer-Policy: strict-origin-when-cross-origin\n Permissions-Policy: geolocation=(self), microphone=()"

# Care API URL without the /api prefix
REACT_CARE_API_URL=https://careapi.ohc.network
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ src/pluginMap.ts
# Federation Temp files
/.__mf__temp
public/sbom/*
public/_headers
8 changes: 4 additions & 4 deletions cypress/pageObject/Patients/PatientEncounter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ export class PatientEncounter {
}

clickPatientDetailsButton() {
cy.verifyAndClickElement(
'[data-cy="patient-details-button"]',
"Patient Details",
);
cy.get('[data-cy="patient-details-button"]')
.filter(":visible")
.first()
.click();
return this;
}

Expand Down
263 changes: 138 additions & 125 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "care_fe",
"version": "2.10.0",
"version": "2.12.0",
"description": "Care is a Digital Public Good enabling TeleICU & Decentralised Administration of Healthcare Capacity across States.",
"private": true,
"repository": {
Expand Down Expand Up @@ -35,7 +35,7 @@
"supported-browsers": "node ./scripts/generate-supported-browsers.mjs",
"build": "npm run setup && npm run build:meta && npm run supported-browsers && npm run build:react",
"setup": "tsx scripts/setup-care-apps.ts",
"postinstall": "tsx scripts/install-platform-deps.ts && tsx scripts/generate-sbom-data.ts",
"postinstall": "tsx scripts/install-platform-deps.ts && tsx scripts/generate-sbom-data.ts && tsx scripts/generate-headers.ts",
"test": "snyk test",
"cypress:open": "cross-env NODE_ENV=development cypress open",
"cypress:run": "cross-env NODE_ENV=development cypress run",
Expand Down Expand Up @@ -97,7 +97,7 @@
"input-otp": "^1.4.2",
"jspdf": "^2.5.2",
"libphonenumber-js": "^1.11.18",
"lucide-react": "^0.474.0",
"lucide-react": "^0.475.0",
"markdown-it": "^14.1.0",
"next-themes": "^0.4.3",
"postcss-loader": "^8.1.1",
Expand Down Expand Up @@ -180,8 +180,8 @@
"optionalDependencies": {
"@esbuild/linux-arm64": "latest",
"@esbuild/linux-x64": "latest",
"@rollup/rollup-linux-arm64-gnu": "4.34.4",
"@rollup/rollup-linux-x64-gnu": "4.34.4"
"@rollup/rollup-linux-arm64-gnu": "4.34.6",
"@rollup/rollup-linux-x64-gnu": "4.34.6"
},
"browserslist": {
"production": [
Expand All @@ -199,7 +199,6 @@
"*.{ts,tsx,js,jsx}": [
"prettier --write --ignore-unknown --plugin prettier-plugin-tailwindcss --plugin @trivago/prettier-plugin-sort-imports",
"eslint --fix",
"unimported",
"git update-index --again"
],
"public/locale/*.json": [
Expand All @@ -210,4 +209,4 @@
"node": ">=22.8.0"
},
"packageManager": "npm@10.9.2"
}
}
11 changes: 11 additions & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@
"administered_on": "Administered on",
"administration_dosage_range_error": "Dosage should be between start and target dosage",
"administration_notes": "Administration Notes",
"admission_source": "Admission Source",
"admit_source": "Admit Source",
"admitted": "Admitted",
"admitted_on": "Admitted On",
Expand Down Expand Up @@ -562,6 +563,7 @@
"claim__use__claim": "Claim",
"claim__use__preauthorization": "Pre Authorization",
"claims": "Claims",
"class_history": "Class History",
"clear": "Clear",
"clear_all_filters": "Clear all filters",
"clear_home_facility": "Clear Home Facility",
Expand Down Expand Up @@ -698,6 +700,7 @@
"deleting": "Deleting...",
"demography": "Demography",
"denied_on": "Denied On",
"department": "Department",
"departments": "Departments",
"departments_and_teams": "Departments and Teams",
"describe_why_the_asset_is_not_working": "Describe why the asset is not working",
Expand Down Expand Up @@ -919,6 +922,7 @@
"encounter_suggestion__OP": "Out-patient visit",
"encounter_suggestion__R": "Consultation",
"encounter_suggestion_edit_disallowed": "Not allowed to switch to this option in edit consultation",
"encounter_type": "Encounter Type",
"encounters": "Encounters",
"end_date": "End date",
"end_datetime": "End Date/Time",
Expand Down Expand Up @@ -1242,6 +1246,7 @@
"location_created": "Location Created",
"location_details": "Location Details",
"location_form": "Location Form",
"location_history": "Location History",
"location_management": "Location Management",
"location_updated": "Location Updated",
"location_updated_successfully": "Location updated successfully",
Expand Down Expand Up @@ -1281,6 +1286,7 @@
"mark_as_noshow": "Mark as no-show",
"mark_as_read": "Mark as Read",
"mark_as_unread": "Mark as Unread",
"mark_encounter_as_complete_confirmation": "Are you sure you would like to mark this encounter as complete?",
"mark_inactive": "Mark Inactive",
"mark_resolved": "Mark Resolved",
"mark_this_transfer_as_complete_question": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient",
Expand All @@ -1300,6 +1306,7 @@
"medication_administration_saved": "Medicine Administration saved",
"medication_already_marked_as_error": "Medication already marked as entered in error",
"medication_taken_between": "Medication Taken Between",
"medications": "Medications",
"medicine": "Medicine",
"medicine_administration": "Medicine Administration",
"medicine_administration_history": "Medicine Administration History",
Expand Down Expand Up @@ -1481,6 +1488,7 @@
"on": "on",
"on_emergency_basis": " on emergency basis",
"on_hold": "On Hold",
"ongoing": "Ongoing",
"ongoing_medications": "Ongoing Medications",
"online": "Online",
"only_indian_mobile_numbers_supported": "Currently only Indian numbers are supported",
Expand Down Expand Up @@ -2052,6 +2060,7 @@
"state": "State",
"state_reason_for_archiving": "State reason for archiving <strong>{{name}}</strong> file?",
"status": "Status",
"status_history": "Status History",
"stop": "Stop",
"stop_recording": "Stop Recording",
"stopped": "Stopped",
Expand Down Expand Up @@ -2192,11 +2201,13 @@
"update_available": "Update Available",
"update_bed": "Update Bed",
"update_department": "Update Department",
"update_encounter": "Update Encounter",
"update_encounter_details": "Update Encounter Details",
"update_existing_facility": "Update the details of the existing facility.",
"update_facility": "Update Facility",
"update_facility_middleware_success": "Facility middleware updated successfully",
"update_hospitalisation_details": "Update Hospitalisation Details",
"update_location": "Update Location",
"update_log": "Update Log",
"update_password": "Update Password",
"update_patient_details": "Update Patient Details",
Expand Down
27 changes: 27 additions & 0 deletions scripts/generate-headers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { writeFile } from "fs/promises";
import path from "path";

const headers = process.env.HEADERS;
const header_folder = path.join(__dirname, "..", "public");

async function writeHeaders() {
if (!headers) {
console.warn("HEADERS environment variable is not set.");
process.exit(0);
}

console.log("HEADERS environment variable is set.");
const headersPath = path.join(header_folder, "_headers");
console.log(`Writing headers to file at path: ${headersPath}`);

try {
await writeFile(headersPath, headers, "utf-8");
console.log("Headers written to file successfully.");
process.exit(0);
} catch (error) {
console.error("Error writing headers to file:", error);
process.exit(0);
}
}

writeHeaders();
1 change: 1 addition & 0 deletions src/Providers/AuthUserProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default function AuthUserProvider({
queryFn: query(routes.token_refresh, {
body: { refresh: refreshToken || "" },
}),
refetchIntervalInBackground: true,
refetchInterval: careConfig.auth.tokenRefreshInterval,
enabled: !!refreshToken && !!user,
});
Expand Down
17 changes: 13 additions & 4 deletions src/Routers/routes/ConsultationRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import QuestionnaireResponseView from "@/components/Facility/ConsultationDetails/QuestionnaireResponseView";
import EncounterQuestionnaire from "@/components/Patient/EncounterQuestionnaire";
import FileUploadPage from "@/components/Patient/FileUploadPage";
import TreatmentSummary from "@/components/Patient/TreatmentSummary";

import { AppRoutes } from "@/Routers/AppRouter";
import { EncounterShow } from "@/pages/Encounters/EncounterShow";
import { PrintPrescription } from "@/pages/Encounters/PrintPrescription";

const consultationRoutes: AppRoutes = {
"/facility/:facilityId/encounter/:encounterId/prescriptions/print": ({
facilityId,
encounterId,
}) => <PrintPrescription facilityId={facilityId} encounterId={encounterId} />,
"/facility/:facilityId/patient/:patientId/encounter/:encounterId/prescriptions/print":
({ facilityId, encounterId, patientId }) => (
<PrintPrescription
facilityId={facilityId}
encounterId={encounterId}
patientId={patientId}
/>
),
"/facility/:facilityId/patient/:patientId/encounter/:encounterId/treatment_summary":
({ facilityId, encounterId }) => (
<TreatmentSummary facilityId={facilityId} encounterId={encounterId} />
),
"/facility/:facilityId/encounter/:encounterId/:tab": ({
facilityId,
encounterId,
Expand Down
4 changes: 2 additions & 2 deletions src/Utils/request/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { PaginatedResponse } from "@/Utils/request/types";
import { AppointmentPatientRegister } from "@/pages/Patient/Utils";
import { Encounter, EncounterEditRequest } from "@/types/emr/encounter";
import { MedicationAdministration } from "@/types/emr/medicationAdministration/medicationAdministration";
import { MedicationStatement } from "@/types/emr/medicationStatement";
import { MedicationStatementRead } from "@/types/emr/medicationStatement";
import { PartialPatientModel, Patient } from "@/types/emr/newPatient";
import {
Observation,
Expand Down Expand Up @@ -655,7 +655,7 @@ const routes = {
list: {
path: "/api/v1/patient/{patientId}/medication/statement/",
method: "GET",
TRes: Type<PaginatedResponse<MedicationStatement>>(),
TRes: Type<PaginatedResponse<MedicationStatementRead>>(),
},
},

Expand Down
75 changes: 74 additions & 1 deletion src/Utils/request/query.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import careConfig from "@careConfig";

import { RESULTS_PER_PAGE_LIMIT } from "@/common/constants";

import { getResponseBody } from "@/Utils/request/request";
import { ApiCallOptions, ApiRoute, HTTPError } from "@/Utils/request/types";
import {
ApiCallOptions,
ApiRoute,
HTTPError,
PaginatedResponse,
} from "@/Utils/request/types";
import { makeHeaders, makeUrl } from "@/Utils/request/utils";
import { sleep } from "@/Utils/utils";

Expand Down Expand Up @@ -113,3 +120,69 @@ const debouncedQuery = <Route extends ApiRoute<unknown, unknown>>(
};
};
query.debounced = debouncedQuery;

/**
* Creates a TanStack Query compatible paginated query function.
*
* This function is useful for fetching paginated data from an API.
* It will fetch all pages of data and return a single array of results.
*
* To disable pagination, set the `maxPages` option to `1`.
* Leaving it unset will fetch all pages.
*
* Example:
* ```tsx
* const { data, isLoading } = useQuery({
* queryKey: ["patient-search", facilityId, search],
* queryFn: query.paginated(patientsApi.search, {
* pathParams: { facilityId },
* queryParams: { limit: 10, offset: 0, search },
* }),
* });
* ```
*/
const paginatedQuery = <
Route extends ApiRoute<PaginatedResponse<unknown>, unknown>,
>(
route: Route,
options?: ApiCallOptions<Route> & { pageSize?: number; maxPages?: number },
) => {
return async ({ signal }: { signal: AbortSignal }) => {
const items: Route["TRes"]["results"] = [];
let hasNextPage = true;
let page = 0;
let count = 0;

const pageSize = options?.pageSize ?? RESULTS_PER_PAGE_LIMIT;

while (hasNextPage) {
const res = await query(route, {
...options,
queryParams: {
limit: pageSize,
offset: page * pageSize,
...options?.queryParams,
},
})({ signal });

count = res.count;
items.push(...res.results);

if (options?.maxPages && page >= options.maxPages - 1) {
hasNextPage = false;
}

if (items.length >= res.count) {
hasNextPage = false;
}

page++;
}

return {
count,
results: items,
};
};
};
query.paginated = paginatedQuery;
2 changes: 0 additions & 2 deletions src/Utils/request/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,5 @@ declare module "@tanstack/react-query" {

export interface PaginatedResponse<TItem> {
count: number;
next: string | null;
previous: string | null;
results: TItem[];
}
1 change: 1 addition & 0 deletions src/components/Auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ const Login = (props: LoginProps) => {
name="otp"
type="text"
value={otp}
autoComplete="one-time-code"
onChange={(e) => {
setOtp(e.target.value);
setOtpValidationError("");
Expand Down
Loading

0 comments on commit e640ead

Please sign in to comment.