Skip to content

Commit

Permalink
TEFCA Viewer Conditions table (#1764)
Browse files Browse the repository at this point in the history
* Import CodeableConcept in format-service

* Remove additional eCR carryover files

* Update next.config.js for tefca-viewer

* Allow for self-signed certifcates

* Condtions table working implementation

* Exploring to address build issues
  • Loading branch information
DanPaseltiner authored May 3, 2024
1 parent df3b688 commit 14c28da
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 82 deletions.
5 changes: 0 additions & 5 deletions containers/tefca-viewer/.env

This file was deleted.

43 changes: 0 additions & 43 deletions containers/tefca-viewer/api-documentation.md

This file was deleted.

4 changes: 2 additions & 2 deletions containers/tefca-viewer/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ const nextConfig = {
async rewrites() {
return [
{
source: "/ecr-viewer/:slug*",
source: "/tefca-viewer/:slug*",
destination: "/:slug*",
},
];
},
output: "standalone",
basePath: process.env.NODE_ENV === "production" ? "/ecr-viewer" : "",
basePath: process.env.NODE_ENV === "production" ? "/tefca-viewer" : "",
};

module.exports = nextConfig;
9 changes: 4 additions & 5 deletions containers/tefca-viewer/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "tefca-viewer",
"description": "The DIBBs eCR Viewer app offers a REST API for processing FHIR messages into an HTML page with key insights.",
"description": "The DIBBs TryTEFCA Viewer is a FHIR client for public health specific queries.",
"version": "1.0.1",
"private": true,
"scripts": {
"dev": "next dev --experimental-https",
"dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 next dev",
"local-dev": "npm run setup-local-env && docker compose up db seed-db -d && docker-compose logs && export DATABASE_URL=postgres://postgres:pw@localhost:5432/ecr_viewer_db && npm run dev",
"setup-local-env": "./setup-env.sh",
"build": "next build",
"start": "next start",
"build": "NODE_TLS_REJECT_UNAUTHORIZED=0 next build",
"start": "NODE_TLS_REJECT_UNAUTHORIZED=0 next start",
"lint": "next lint",
"test": "npm run test:unit && npm run test:integration",
"test:unit": "TZ=America/New_York jest",
Expand Down Expand Up @@ -54,7 +54,6 @@
"autoprefixer": "^10.0.1",
"aws-sdk-client-mock": "^3.0.1",
"chai": "^4.3.10",
"cypress": "^13.6.6",
"eslint": "^8.56.0",
"eslint-config-next": "14.0.3",
"eslint-config-prettier": "^9.1.0",
Expand Down
21 changes: 21 additions & 0 deletions containers/tefca-viewer/src/app/format-service.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CodeableConcept } from "fhir/r4";
/**
* Formats a string.
* @param input - The string to format.
Expand All @@ -15,3 +16,23 @@ export const formatString = (input: string): string => {

return result;
};

/**
* Formats a CodeableConcept object for display. If the object has a coding array,
* the first coding object is used.
* @param concept - The CodeableConcept object.
* @returns The CodeableConcept data formatted for
* display.
*/
export function formatCodeableConcept(concept: CodeableConcept) {
if (!concept.coding || concept.coding.length === 0) {
return concept.text || "";
}
const coding = concept.coding[0];
return (
<>
{" "}
{coding.display} <br /> {coding.code} <br /> {coding.system}{" "}
</>
);
}
11 changes: 6 additions & 5 deletions containers/tefca-viewer/src/app/query-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ const FHIR_SERVERS: {
meld: { hostname: "https://gw.interop.community/HeliosConnectathonSa/open/" },
ehealthexchange: {
hostname: "https://concept01.ehealthexchange.org:52780/fhirproxy/r4/",
username: "svc_eHxFHIRSandbox",
password: "willfulStrongStandurd7",
headers: {
Accept: "application/json, application/*+json, */*",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/fhir+json; charset=UTF-8",
"X-DESTINATION": "CernerHelios",
"X-POU": "TREATMENT",
"X-POU": "PUBHLTH",
"X-Request-Id": uuidv4(),
prefer: "return=representation",
"Cache-Control": "no-cache",
Expand Down Expand Up @@ -224,8 +222,11 @@ async function newbornScreeningQuery(
];
const loincFilter: string = "code=" + loincs.join(",");

const query = `/Observation?subject=${request.patientId}&code=${loincFilter}`;
const response = await fetch(request.fhir_host + query, request.init);
const query = `/Observation?subject=Patient/${request.patientId}&code=${loincFilter}`;
const response = await fetch(request.fhir_host + query, {
headers: request.headers,
...request.init,
});

if (response.status !== 200) {
console.log("response:", response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
AccordianDiv,
} from "../component-utils";
import { UseCaseQueryResponse } from "@/app/query-service";
import ConditionsTable from "./ConditionsTable";

type AccordionContainerProps = {
queryResponse: UseCaseQueryResponse;
Expand All @@ -23,6 +24,7 @@ type AccordionContainerProps = {
const AccordianContainer: React.FC<AccordionContainerProps> = ({
queryResponse,
}) => {
console.log("queryResponse:", queryResponse);
const accordionItems: any[] = [];

const patient =
Expand All @@ -32,6 +34,7 @@ const AccordianContainer: React.FC<AccordionContainerProps> = ({
const observations = queryResponse.observations
? queryResponse.observations
: null;
const conditions = queryResponse.conditions ? queryResponse.conditions : null;

if (patient) {
accordionItems.push({
Expand Down Expand Up @@ -73,6 +76,26 @@ const AccordianContainer: React.FC<AccordionContainerProps> = ({
});
}

if (conditions) {
accordionItems.push({
title: "Conditions",
content: (
<>
<AccordianSection>
<AccordianH4>
<span id="conditions">Conditions</span>
</AccordianH4>
<AccordianDiv>
<ConditionsTable conditions={conditions} />
</AccordianDiv>
</AccordianSection>
</>
),
expanded: true,
headingLevel: "h3",
});
}

//Add id, adjust title
accordionItems.forEach((item, index) => {
let formattedTitle = formatString(item["title"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from "react";
import { Table } from "@trussworks/react-uswds";
import { Condition } from "fhir/r4";
import { formatCodeableConcept } from "../../format-service";

/**
* The props for the ConditionTable component.
*/
export interface ConditionTableProps {
conditions: Condition[];
}

/**
* Displays a table of data from array of Condition resources.
* @param props - Condition table props.
* @param props.conditions - The array of Condition resources.
* @returns - The ConditionTable component.
*/
const ConditionsTable: React.FC<ConditionTableProps> = ({ conditions }) => {
return (
<Table>
<thead>
<tr>
<th>Condition</th>
<th>Status</th>
<th>Onset</th>
<th>Resolution</th>
</tr>
</thead>
<tbody>
{conditions.map((condition) => (
<tr key={condition.id}>
<td>{formatCodeableConcept(condition.code ?? {})}</td>
<td>{formatCodeableConcept(condition.clinicalStatus ?? {})}</td>
<td>{condition.onsetDateTime}</td>
<td>{condition.abatementDateTime}</td>
</tr>
))}
</tbody>
</Table>
);
};

export default ConditionsTable;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { Table } from "@trussworks/react-uswds";
import { Observation, CodeableConcept } from "fhir/r4";

import { Observation } from "fhir/r4";
import { formatCodeableConcept } from "../../format-service";
/**
* The props for the ObservationTable component.
*/
Expand Down Expand Up @@ -49,26 +49,6 @@ const ObservationTable: React.FC<ObservationTableProps> = ({
};
export default ObservationTable;

/**
* Formats a CodeableConcept object for display. If the object has a coding array,
* the first coding object is used.
* @param concept - The CodeableConcept object.
* @returns The CodeableConcept data formatted for
* display.
*/
function formatCodeableConcept(concept: CodeableConcept) {
if (!concept.coding || concept.coding.length === 0) {
return concept.text || "";
}
const coding = concept.coding[0];
return (
<>
{" "}
{coding.display} <br /> {coding.code} <br /> {coding.system}{" "}
</>
);
}

/**
* Formats the value of an Observation object for display.
* @param obs - The Observation object.
Expand Down
4 changes: 4 additions & 0 deletions containers/tefca-viewer/src/styles/custom-styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,8 @@ body {
margin-top: 2.0rem;
margin-bottom: 4.0rem;
max-width: 11em;
}

.usa-table {
width: 100%;
}
23 changes: 23 additions & 0 deletions containers/tefca-viewer/src/styles/uswds-settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,26 @@ $ASSET_PREFIX: "";
$theme-hero-image: "#{$ASSET_PREFIX}/uswds/img/hero.webp",
$utilities-use-important: true,
);

/* https://designsystem.digital.gov/documentation/settings/ */
// @use "uswds-core" with (
// // General
// $theme-show-compile-warnings: true,
// $theme-show-notifications: false,
// $theme-image-path: "../../../../../../dist/img",

// // Color

// // Component
// $theme-hero-image: "../../../../dist/img/hero.jpg",
// $theme-accordion-button-background-color: 'blue-cool-60',

// // Spacing

// // Typography
// $theme-font-path: "../../../../../../dist/fonts",


// // Utilities

// );

0 comments on commit 14c28da

Please sign in to comment.