diff --git a/i18next-parser.config.js b/i18next-parser.config.js index a46a32f8..20715daf 100644 --- a/i18next-parser.config.js +++ b/i18next-parser.config.js @@ -1,14 +1,14 @@ module.exports = { - contextSeparator: '_', + contextSeparator: "_", // Key separator used in your translation keys createOldCatalogs: false, // Save the \_old files - defaultNamespace: 'translations', + defaultNamespace: "translations", // Default namespace used in your i18next config - defaultValue: '', + defaultValue: "", // Default value to give to empty keys // You may also specify a function accepting the locale, namespace, and key as arguments @@ -18,43 +18,43 @@ module.exports = { keepRemoved: false, // Keep keys from the catalog that are no longer in code - keySeparator: '.', + keySeparator: ".", // Key separator used in your translation keys // If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance. // see below for more details lexers: { - hbs: ['HandlebarsLexer'], - handlebars: ['HandlebarsLexer'], + hbs: ["HandlebarsLexer"], + handlebars: ["HandlebarsLexer"], - htm: ['HTMLLexer'], - html: ['HTMLLexer'], + htm: ["HTMLLexer"], + html: ["HTMLLexer"], - mjs: ['JavascriptLexer'], - js: ['JavascriptLexer'], // if you're writing jsx inside .js files, change this to JsxLexer - ts: ['JavascriptLexer'], - jsx: ['JsxLexer'], - tsx: ['JsxLexer'], + mjs: ["JavascriptLexer"], + js: ["JavascriptLexer"], // if you're writing jsx inside .js files, change this to JsxLexer + ts: ["JavascriptLexer"], + jsx: ["JsxLexer"], + tsx: ["JsxLexer"], - default: ['JavascriptLexer'], + default: ["JavascriptLexer"], }, - lineEnding: 'auto', + lineEnding: "auto", // Control the line ending. See options at https://github.com/ryanve/eol - locales: ['en', 'am', 'es', 'fr', 'km', 'he'], + locales: ["en", "am", "es", "fr", "km", "he"], // An array of the locales in your applications - namespaceSeparator: ':', + namespaceSeparator: ":", // Namespace separator used in your translation keys // If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance. - output: '$NAMESPACE/$LOCALE.json', + output: "$NAMESPACE/$LOCALE.json", // Supports $LOCALE and $NAMESPACE injection // Supports JSON (.json) and YAML (.yml) file formats // Where to write the locale files relative to process.cwd() - pluralSeparator: '_', + pluralSeparator: "_", // Plural separator used in your translation keys // If you want to use plain english keys, separators such as `_` might conflict. You might want to set `pluralSeparator` to a different string that does not occur in your keys. diff --git a/package.json b/package.json index e350259c..7e6e36c8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "main": "src/index.ts", "source": true, "scripts": { - "start": "openmrs develop --backend http://167.71.32.250:8080", + "start": "openmrs develop --backend https://ugandaemr-backend.mets.or.ug", "serve": "webpack serve --mode=development", "build": "webpack --mode production", "analyze": "webpack --mode=production --env analyze=true", diff --git a/src/config-schema.ts b/src/config-schema.ts index 0a052944..d000a457 100644 --- a/src/config-schema.ts +++ b/src/config-schema.ts @@ -21,6 +21,11 @@ export const configSchema = { _default: "214e27a1-606a-4b1e-a96e-d736c87069d5", _description: "Concept uuid for the laboratory tool encounter type.", }, + laboratoryOrderTypeUuid: { + _type: Type.String, + _default: "52a447d3-a64a-11e3-9aeb-50e549534c5e", + _description: "Uuid for orderType", + }, }; export type Config = { 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 f9999955..2dc6144e 100644 --- a/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx +++ b/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx @@ -3,24 +3,25 @@ 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 { EncounterResponse } from "./view-laboratory-item.resource"; interface ViewLaboratoryItemActionMenuProps { closeModal: () => void; - encounterUuid: string; + encounter: EncounterResponse; } const ViewLaboratoryItemActionMenu: React.FC< ViewLaboratoryItemActionMenuProps -> = ({ encounterUuid }) => { +> = ({ encounter }) => { const { t } = useTranslation(); const handleClick = useCallback( () => launchPatientWorkspace("results-summary", { workspaceTitle: `Results Summary Form`, - encounterUuid, + encounter, }), - [encounterUuid] + [encounter] ); 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 6a44a96d..d43161a1 100644 --- a/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts +++ b/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts @@ -136,7 +136,7 @@ export interface Ob { groupMembers: any; comment: any; location: Location2; - order: any; + order: Order; encounter: Encounter; voided: boolean; value: any; diff --git a/src/patient-chart/laboratory-order.component.tsx b/src/patient-chart/laboratory-order.component.tsx index bf9f4f80..78830704 100644 --- a/src/patient-chart/laboratory-order.component.tsx +++ b/src/patient-chart/laboratory-order.component.tsx @@ -9,6 +9,7 @@ import { openmrsFetch, parseDate, ErrorState, + useLayoutType, } from "@openmrs/esm-framework"; import { @@ -29,9 +30,13 @@ import { DataTableHeader, Tile, Pagination, + TableExpandHeader, + TableExpandRow, + TableExpandedRow, } from "@carbon/react"; import ViewLaboratoryItemActionMenu from "./laboratory-item/view-laboratory-item.component"; -import { useLabOrders } from "./laboratory-order.resource"; +import { getOrderColor, useLabOrders } from "./laboratory-order.resource"; +import TestsResults from "./results-summary/test-results-table.component"; interface LaboratoryOrderOverviewProps { patientUuid: string; @@ -50,6 +55,8 @@ const LaboratoryOrder: React.FC = ({ }) => { const { t } = useTranslation(); + const isTablet = useLayoutType() === "tablet"; + const { labRequests, isLoading: loading, @@ -70,8 +77,8 @@ const LaboratoryOrder: React.FC = ({ let columns = [ { id: 0, - header: t("encounterDate", "Encouter Date"), - key: "encounterDate", + header: t("orderDate", "Order Date"), + key: "orderDate", }, { id: 1, header: t("orders", "Order"), key: "orders" }, { id: 2, header: t("location", "Location"), key: "location" }, @@ -135,11 +142,11 @@ const LaboratoryOrder: React.FC = ({ return paginatedLabEntries?.map((entry) => ({ ...entry, id: entry.uuid, - encounterDate: { + orderDate: { content: ( {formatDate(parseDate(entry.encounterDatetime), { - time: true, + time: false, })} ), @@ -148,17 +155,22 @@ const LaboratoryOrder: React.FC = ({ content: ( <> {entry.orders.map((order) => { - return ( - - {order?.concept?.display} - - ); + if (order?.type === "testorder") { + return ( + + {order?.concept?.display} + + ); + } })} ), @@ -174,7 +186,7 @@ const LaboratoryOrder: React.FC = ({ <> true} - encounterUuid={entry.uuid} + encounter={entry} /> ), @@ -198,6 +210,7 @@ const LaboratoryOrder: React.FC = ({ headers={columns} useZebraStyles filterRows={handleFilter} + size={isTablet ? "lg" : "sm"} > {({ rows, headers, getHeaderProps, getTableProps, getRowProps }) => ( @@ -210,6 +223,47 @@ const LaboratoryOrder: React.FC = ({ }} > +
+ Key: + + {"Completed"} + + + {"Rejected"} + + + {"Requested"} + +
= ({ > + {headers.map((header) => ( {header.header} @@ -237,13 +292,28 @@ const LaboratoryOrder: React.FC = ({ {rows.map((row, index) => { return ( - + {row.cells.map((cell) => ( {cell.value?.content ?? cell.value} ))} - + + {row.isExpanded ? ( + + + + ) : ( + + )} ); })} diff --git a/src/patient-chart/laboratory-order.resource.ts b/src/patient-chart/laboratory-order.resource.ts index b295e4d0..a76dbb14 100644 --- a/src/patient-chart/laboratory-order.resource.ts +++ b/src/patient-chart/laboratory-order.resource.ts @@ -1,4 +1,4 @@ -import { openmrsFetch, useConfig } from "@openmrs/esm-framework"; +import { formatDate, openmrsFetch, useConfig } from "@openmrs/esm-framework"; import useSWR from "swr"; export interface LaboratoryResponse { @@ -131,7 +131,7 @@ export interface Ob { accessionNumber: any; obsGroup: any; valueCodedName: any; - groupMembers: any; + groupMembers: GroupMember[]; comment: any; location: Location; order: any; @@ -145,6 +145,35 @@ export interface Ob { resourceVersion: string; } +export interface GroupMember { + uuid: string; + display: string; + concept: Concept; + person: Person; + obsDatetime: string; + accessionNumber: any; + obsGroup: ObsGroup; + valueCodedName: any; + groupMembers: any; + comment: any; + location: Location; + order: Order; + encounter: Encounter; + voided: boolean; + value: number; + valueModifier: any; + formFieldPath: any; + formFieldNamespace: any; + links: Link[]; + resourceVersion: string; +} + +export interface ObsGroup { + uuid: string; + display: string; + links: Link[]; +} + export interface Concept { uuid: string; display: string; @@ -231,7 +260,7 @@ export interface Order { previousOrder: any; dateActivated: string; scheduledDate: any; - dateStopped: any; + dateStopped: string; autoExpireDate: any; encounter: Encounter; orderer: Orderer; @@ -301,6 +330,29 @@ export interface OrderType { resourceVersion: string; } +export const getOrderColor = (activated: string, stopped: string) => { + const numAct = formatWaitTime(activated); + let testStopped: Number; + if (stopped === null) { + testStopped = 0; + } + + if (numAct >= 0 && testStopped == 0) { + return "#6F6F6F"; // #6F6F6F + } else { + return "green"; // green + } +}; + +export const formatWaitTime = (waitTime: string) => { + const num = parseInt(waitTime); + const hours = num / 60; + const rhours = Math.floor(hours); + const minutes = (hours - rhours) * 60; + const rminutes = Math.round(minutes); + return rminutes; +}; + export function useLabOrders(patientUuid: string) { const config = useConfig(); const { laboratoryEncounterTypeUuid } = config; diff --git a/src/patient-chart/results-summary/results-summary.component.tsx b/src/patient-chart/results-summary/results-summary.component.tsx index 0c3b5acd..b724dbc3 100644 --- a/src/patient-chart/results-summary/results-summary.component.tsx +++ b/src/patient-chart/results-summary/results-summary.component.tsx @@ -10,28 +10,22 @@ import { Printer, MailAll, Edit } from "@carbon/react/icons"; import styles from "./results-summary.scss"; import TestsResults from "./test-results-table.component"; import { useReactToPrint } from "react-to-print"; -import { - EncounterResponse, - useGetEncounterById, -} from "../laboratory-item/view-laboratory-item.resource"; -import { ErrorState } from "@openmrs/esm-patient-common-lib"; +import { EncounterResponse } from "../laboratory-item/view-laboratory-item.resource"; import PrintResultsSummary from "./print-results-summary.component"; import { formatDate, parseDate, showModal } from "@openmrs/esm-framework"; import { useTranslation } from "react-i18next"; +import { Order } from "../laboratory-order.resource"; interface ResultsSummaryProps { - encounterUuid: string; -} - -interface EditResultsProps { - encounterResponse: EncounterResponse; + encounter: EncounterResponse; } -const ResultsSummary: React.FC = ({ encounterUuid }) => { +const ResultsSummary: React.FC = ({ encounter }) => { const { t } = useTranslation(); // get encouter details - const { encounter, isLoading, isError } = useGetEncounterById(encounterUuid); + // const { encounter, isLoading, isError } = useGetEncounterById(encounterUuid); + // print button const PrintButtonAction: React.FC = () => { const [isPrinting, setIsPrinting] = useState(false); @@ -73,6 +67,7 @@ const ResultsSummary: React.FC = ({ encounterUuid }) => { ); }; + // email button const EmailButtonAction: React.FC = () => { const handleButtonClick = (event: MouseEvent) => { event.preventDefault(); @@ -87,32 +82,14 @@ const ResultsSummary: React.FC = ({ encounterUuid }) => { ); }; - const EditButtonAction: React.FC = ({ - encounterResponse, - }) => { - console.info("encounter edit", encounter); + // if (encounter) { + // return ; + // } + // if (isError) { + // return ; + // } - const launchEditResultModal = useCallback(() => { - const dispose = showModal("edit-results-dialog", { - encounterResponse, - closeModal: () => dispose(), - }); - }, [encounterResponse]); - return ( -