diff --git a/package.json b/package.json index e0e71e6e..e350259c 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,8 @@ }, "dependencies": { "@carbon/react": "^1.14.0", - "lodash-es": "^4.17.21" + "lodash-es": "^4.17.21", + "react-to-print": "^2.14.15" }, "peerDependencies": { "@openmrs/esm-framework": "*", diff --git a/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx b/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx index a9a6dfab..f9999955 100644 --- a/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx +++ b/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx @@ -1,26 +1,26 @@ -import { showModal, useSession } from "@openmrs/esm-framework"; import React, { useCallback } from "react"; import { useTranslation } from "react-i18next"; import { Button, Tooltip } from "@carbon/react"; import { View } from "@carbon/react/icons"; import { launchPatientWorkspace } from "@openmrs/esm-patient-common-lib"; -import { LaboratoryResponse } from "../laboratory-order.resource"; interface ViewLaboratoryItemActionMenuProps { closeModal: () => void; + encounterUuid: string; } const ViewLaboratoryItemActionMenu: React.FC< ViewLaboratoryItemActionMenuProps -> = () => { +> = ({ encounterUuid }) => { const { t } = useTranslation(); const handleClick = useCallback( () => launchPatientWorkspace("results-summary", { workspaceTitle: `Results Summary Form`, + encounterUuid, }), - [] + [encounterUuid] ); return ( diff --git a/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts b/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts index e69de29b..6a44a96d 100644 --- a/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts +++ b/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts @@ -0,0 +1,290 @@ +import { openmrsFetch } from "@openmrs/esm-framework"; +import useSWR from "swr"; + +export interface EncounterResponse { + uuid: string; + display: string; + encounterDatetime: string; + patient: Patient; + location: Location; + form: Form; + encounterType: EncounterType2; + obs: Ob[]; + orders: Order[]; + voided: boolean; + auditInfo: AuditInfo; + visit: Visit; + encounterProviders: any[]; + diagnoses: any[]; + links: Link[]; + resourceVersion: string; +} + +export interface Patient { + uuid: string; + display: string; + links: Link[]; +} + +export interface Link { + rel: string; + uri: string; + resourceAlias: string; +} + +export interface Location { + uuid: string; + display: string; + name: string; + description: any; + address1: any; + address2: any; + cityVillage: any; + stateProvince: any; + country: string; + postalCode: any; + latitude: any; + longitude: any; + countyDistrict: any; + address3: any; + address4: any; + address5: any; + address6: any; + tags: Tag[]; + parentLocation: ParentLocation; + childLocations: ChildLocation[]; + retired: boolean; + attributes: any[]; + address7: any; + address8: any; + address9: any; + address10: any; + address11: any; + address12: any; + address13: any; + address14: any; + address15: any; + links: Link[]; + resourceVersion: string; +} + +export interface Tag { + uuid: string; + display: string; + links: Link[]; +} + +export interface ParentLocation { + uuid: string; + display: string; + links: Link[]; +} + +export interface ChildLocation { + uuid: string; + display: string; + links: Link[]; +} + +export interface Form { + uuid: string; + display: string; + name: string; + description: string; + encounterType: EncounterType; + version: string; + build: any; + published: boolean; + formFields: any[]; + retired: boolean; + resources: Resource[]; + links: Link[]; + resourceVersion: string; +} + +export interface EncounterType { + uuid: string; + display: string; + links: Link[]; +} + +export interface Resource { + uuid: string; + display: string; + links: Link[]; +} + +export interface EncounterType2 { + uuid: string; + display: string; + name: string; + description: string; + retired: boolean; + links: Link[]; + resourceVersion: string; +} + +export interface Ob { + uuid: string; + display: string; + concept: Concept; + person: Person; + obsDatetime: string; + accessionNumber: any; + obsGroup: any; + valueCodedName: any; + groupMembers: any; + comment: any; + location: Location2; + order: any; + encounter: Encounter; + voided: boolean; + value: any; + valueModifier: any; + formFieldPath: string; + formFieldNamespace: string; + links: Link[]; + resourceVersion: string; +} + +export interface Concept { + uuid: string; + display: string; + links: Link[]; +} + +export interface Person { + uuid: string; + display: string; + links: Link[]; +} + +export interface Location2 { + uuid: string; + display: string; + links: Link[]; +} + +export interface Encounter { + uuid: string; + display: string; + links: Link[]; +} + +export interface Order { + uuid: string; + orderNumber: string; + accessionNumber: any; + patient: Patient; + concept: Concept; + action: string; + careSetting: CareSetting; + previousOrder: any; + dateActivated: string; + scheduledDate: any; + dateStopped: any; + autoExpireDate: any; + encounter: Encounter; + orderer: Orderer; + orderReason: any; + orderReasonNonCoded: any; + orderType: OrderType; + urgency: string; + instructions: any; + commentToFulfiller: any; + display: string; + specimenSource: any; + laterality: any; + clinicalHistory: any; + frequency: any; + numberOfRepeats: any; + links: Link[]; + type: string; + resourceVersion: string; +} + +export interface CareSetting { + uuid: string; + display: string; + links: Link[]; +} + +export interface Encounter { + uuid: string; + display: string; + links: Link[]; +} + +export interface Orderer { + uuid: string; + display: string; + links: Link[]; +} + +export interface OrderType { + uuid: string; + display: string; + name: string; + javaClassName: string; + retired: boolean; + description: string; + conceptClasses: any[]; + parent: any; + links: Link[]; + resourceVersion: string; +} + +export interface AuditInfo { + creator: Creator; + dateCreated: string; + changedBy: any; + dateChanged: any; +} + +export interface Creator { + uuid: string; + display: string; + links: Link[]; +} + +export interface Visit { + uuid: string; + display: string; + patient: Patient; + visitType: VisitType; + indication: any; + location: Location; + startDatetime: string; + stopDatetime: any; + encounters: Encounter[]; + attributes: any[]; + voided: boolean; + links: Link[]; + resourceVersion: string; +} + +export interface VisitType { + uuid: string; + display: string; + links: Link[]; +} + +export interface Encounter { + uuid: string; + display: string; + links: Link[]; +} + +export function useGetEncounterById(encounterUuid: string) { + const apiUrl = `/ws/rest/v1/encounter/${encounterUuid}?v=full`; + const { data, error, isLoading } = useSWR<{ data: EncounterResponse }, Error>( + apiUrl, + openmrsFetch + ); + + return { + encounter: data?.data, + isLoading, + isError: error, + }; +} diff --git a/src/patient-chart/laboratory-order.component.tsx b/src/patient-chart/laboratory-order.component.tsx index e80c4b6b..6931b556 100644 --- a/src/patient-chart/laboratory-order.component.tsx +++ b/src/patient-chart/laboratory-order.component.tsx @@ -2,12 +2,7 @@ import React, { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { EmptyState } from "@ohri/openmrs-esm-ohri-commons-lib"; import styles from "./laboratory-order.scss"; -import { - formatDate, - parseDate, - usePagination, - useSession, -} from "@openmrs/esm-framework"; +import { usePagination, useSession } from "@openmrs/esm-framework"; import { DataTable, DataTableSkeleton, @@ -85,7 +80,7 @@ const LaboratoryOrder: React.FC = ({ } else { let filteredItems = []; items.map((item) => { - const newArray = item?.orders.filter( + const newArray = item?.orders?.filter( (order) => order?.concept?.display .toLowerCase() @@ -127,16 +122,9 @@ const LaboratoryOrder: React.FC = ({ const tableRows = useMemo(() => { return paginatedLabEntries?.map((entry) => ({ ...entry, + id: entry.uuid, encounterDate: { - content: ( - - {formatDate(parseDate(entry.encounterDatetime), { - time: false, - noToday: true, - mode: "wide", - })} - - ), + content: {entry.encounterDatetime}, }, orders: { content: ( @@ -166,7 +154,10 @@ const LaboratoryOrder: React.FC = ({ actions: { content: ( <> - true} /> + true} + encounterUuid={entry.uuid} + /> ), }, diff --git a/src/patient-chart/results-summary/results-summary.component.tsx b/src/patient-chart/results-summary/results-summary.component.tsx index 379fb1d6..91513538 100644 --- a/src/patient-chart/results-summary/results-summary.component.tsx +++ b/src/patient-chart/results-summary/results-summary.component.tsx @@ -1,56 +1,54 @@ -import React, { Children } from "react"; -import { - Button, - DataTable, - DataTableHeader, - DataTableSkeleton, - DefinitionTooltip, - Layer, - Pagination, - Tab, - Table, - TableBody, - TableCell, - TableContainer, - TableExpandedRow, - TableExpandHeader, - TableExpandRow, - TableHead, - TableHeader, - TableRow, - TableToolbar, - TableToolbarContent, - TableToolbarSearch, - TabList, - TabPanel, - TabPanels, - Tabs, - Tag, - Tile, -} from "@carbon/react"; +import React, { useEffect, useRef, useState } from "react"; +import { Button, DataTableSkeleton } from "@carbon/react"; import { Printer, MailAll, Edit } from "@carbon/react/icons"; import styles from "./results-summary.scss"; import TestsResults from "./test-results-table.component"; -import { LaboratoryResponse } from "../laboratory-order.resource"; +import { useReactToPrint } from "react-to-print"; +import { useGetEncounterById } from "../laboratory-item/view-laboratory-item.resource"; +import { ErrorState } from "@openmrs/esm-patient-common-lib"; interface ResultsSummaryProps { - labRequest: LaboratoryResponse; + encounterUuid: string; } -const ResultsSummary: React.FC = () => { +const ResultsSummary: React.FC = ({ encounterUuid }) => { + // get encouter details + const { encounter, isLoading, isError } = useGetEncounterById(encounterUuid); + const PrintButtonAction: React.FC = () => { - const handleButtonClick = (event: MouseEvent) => { - event.preventDefault(); - }; + const [isPrinting, setIsPrinting] = useState(false); + + const contentToPrintRef = useRef(null); + + const onBeforeGetContentResolve = useRef(null); + + useEffect(() => { + if (onBeforeGetContentResolve.current) { + onBeforeGetContentResolve.current(); + } + }, [isPrinting]); + + const handlePrint = useReactToPrint({ + content: () => contentToPrintRef.current, + onBeforeGetContent: () => + new Promise((resolve) => { + onBeforeGetContentResolve.current = resolve; + setIsPrinting(true); + }), + onAfterPrint: () => { + onBeforeGetContentResolve.current = null; + setIsPrinting(false); + }, + }); + return ( - +
+
); }; @@ -64,9 +62,7 @@ const ResultsSummary: React.FC = () => { size="sm" onClick={(e) => handleButtonClick(e)} renderIcon={(props) => } - > - {/* {children} */} - + /> ); }; @@ -80,49 +76,62 @@ const ResultsSummary: React.FC = () => { size="sm" onClick={(e) => handleButtonClick(e)} renderIcon={(props) => } - > - {/* {children} */} - + /> ); }; - return ( - <> -
-
-
-
- - + if (isLoading) { + return ; + } + if (isError) { + return ; + } + + if (encounter) { + console.info("Encounter data---->", encounter); + // const encounter = JSON.parse(encounter); + return ( + <> +
+
+
+
+ + +
-
-
-
-
- Date : - Ordered By : -
-
-
-
-
- Results Ordered +
+
+
+ + Date : {encounter?.encounterDatetime} + + + Ordered By : {encounter?.auditInfo?.creator?.display} +
-
- +
+
+
+
+ Results Ordered +
+
+ +
- -
-
- -
- - ); + +
+ +
+ + ); + } }; export default ResultsSummary; diff --git a/src/patient-chart/results-summary/results-summary.scss b/src/patient-chart/results-summary/results-summary.scss index 978fbc48..13d789f1 100644 --- a/src/patient-chart/results-summary/results-summary.scss +++ b/src/patient-chart/results-summary/results-summary.scss @@ -68,4 +68,4 @@ left: 0.5rem; margin-right: -50%; } - } \ No newline at end of file + } diff --git a/src/patient-chart/results-summary/test-results-delete-action-menu.component.tsx b/src/patient-chart/results-summary/test-results-delete-action-menu.component.tsx new file mode 100644 index 00000000..0353014f --- /dev/null +++ b/src/patient-chart/results-summary/test-results-delete-action-menu.component.tsx @@ -0,0 +1,27 @@ +import { showModal, useSession } from "@openmrs/esm-framework"; +import React, { useCallback } from "react"; +import { useTranslation } from "react-i18next"; +import { Button, Tooltip } from "@carbon/react"; +import { TrashCan } from "@carbon/react/icons"; + +interface RescendTestResultActionMenuProps { + closeModal: () => void; +} + +const DeleteTestResultActionMenu: React.FC< + RescendTestResultActionMenuProps +> = () => { + const { t } = useTranslation(); + + return ( + + + + ); +}; + +export default DeleteTestResultActionMenu; diff --git a/src/patient-chart/results-summary/test-results-action-menu.component.tsx b/src/patient-chart/results-summary/test-results-rescend-action-menu.component.tsx similarity index 100% rename from src/patient-chart/results-summary/test-results-action-menu.component.tsx rename to src/patient-chart/results-summary/test-results-rescend-action-menu.component.tsx diff --git a/src/patient-chart/results-summary/test-results-table.component.tsx b/src/patient-chart/results-summary/test-results-table.component.tsx index e6c5c378..e11f5336 100644 --- a/src/patient-chart/results-summary/test-results-table.component.tsx +++ b/src/patient-chart/results-summary/test-results-table.component.tsx @@ -10,84 +10,62 @@ import { TableHead, TableHeader, TableRow, - TableToolbar, - TableToolbarContent, - TableToolbarSearch, - Layer, - Tag, - DataTableHeader, Tile, } from "@carbon/react"; import styles from "./results-summary.scss"; -import RescentTestResultActionMenu from "./test-results-action-menu.component"; +import RescendTestResultActionMenu from "./test-results-rescend-action-menu.component"; import { Order } from "../laboratory-order.resource"; +import DeleteTestResultActionMenu from "./test-results-delete-action-menu.component"; interface TestOrdersProps { - order: Order; + orders: Order[]; } -const TestsResults: React.FC = () => { +const TestsResults: React.FC = ({ orders }) => { const { t } = useTranslation(); - const [isLoading, setIsLoading] = useState(false); - - const initialItems = useMemo(() => { - const items = [ - { - id: 0, - order: "CD4", - result: "30-56", - }, - { - id: 1, - order: "LFTs", - result: "34-90", - }, - { - id: 2, - order: "Malaria", - result: "Positive ( + )", - }, - ]; - return items; - }, []); - let columns = [ { id: 0, - header: t("order", "Order"), - key: "order", + header: t("orderNo", "OrderNo"), + key: "orderNo", + }, + { id: 1, header: t("order", "Order"), key: "order" }, + { + id: 2, + header: t("expectedResult", "Expected Results"), + key: "expectedResults", }, - { id: 1, header: t("result", "Result"), key: "result" }, - { id: 2, header: t("actions", "Actions"), key: "actions" }, + { id: 3, header: t("actions", "Actions"), key: "actions" }, ]; - - const [items, setItems] = useState(initialItems); + const [items, setItems] = useState(orders); const tableRows = useMemo(() => { return items?.map((entry) => ({ ...entry, + id: entry.uuid, + orderNo: { + content: {entry.orderNumber}, + }, order: { - content: {entry.order}, + content: {entry.display}, }, - result: { - content: {entry.result}, + + expectedResult: { + content: --, }, actions: { content: ( <> - true} /> + true} /> + true} /> ), }, })); }, [items]); - if (isLoading) { - return ; - } - if (items?.length >= 0) { return (
diff --git a/yarn.lock b/yarn.lock index 70009b9e..c45417c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5484,6 +5484,7 @@ __metadata: react-plotly.js: ^2.0.0 react-router-dom: ^6.11.2 react-table: ^7.8.0 + react-to-print: ^2.14.15 rxjs: ^6.6.7 swc-loader: ^0.2.3 turbo: ^1.10.12 @@ -17946,6 +17947,16 @@ openmrs@next: languageName: node linkType: hard +"react-to-print@npm:^2.14.15": + version: 2.14.15 + resolution: "react-to-print@npm:2.14.15" + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 00259ab12f3bfe9eeae1424dc0d09bfd04f2c090ad98c5a7ac0052427bd3cc95fa401b46d03bd0a9e7e1ca637ae74e309969d4cff5ec81f8274e7198382e5464 + languageName: node + linkType: hard + "react-waypoint@npm:^10.3.0": version: 10.3.0 resolution: "react-waypoint@npm:10.3.0"