Skip to content

Commit

Permalink
Merge branch 'main' into mcm/econ-periods
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmcgrath13 authored Dec 12, 2024
2 parents 4a79a81 + fc8d319 commit b6dcf73
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 97 deletions.
2 changes: 2 additions & 0 deletions containers/ecr-viewer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ If you have problems connecting to your database, use this command to see what o

If building the Docker Image doesn't work as expected, try to first run the eCR Viewer locally using the steps below.

If you consistently encounter the error message `"ecr_viewer_db" does not exist` when attempting to run the app, there could be conflicting databases running on port 5432 as part of other background processes. Try pruning any dangling Docker images and containers (`docker image prune` and `docker container prune`). If issues persist, try logging into `psql` on the command line to see what databases are running there.

## Development

### Run eCR Viewer Locally
Expand Down
7 changes: 1 addition & 6 deletions containers/ecr-viewer/src/app/services/ecrMetadataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,7 @@ const evaluateEcrAuthorDetails = (
authorDetails.push([
{
title: "Author Name",
value: formatName(
practitioner?.name?.[0].given,
practitioner?.name?.[0].family,
practitioner?.name?.[0].prefix,
practitioner?.name?.[0].suffix,
),
value: formatName(practitioner?.name?.[0]),
},
{
title: "Author Address",
Expand Down
58 changes: 17 additions & 41 deletions containers/ecr-viewer/src/app/services/evaluateFhirDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Coding,
Condition,
Encounter,
HumanName,
Location,
Organization,
PatientContact,
Expand Down Expand Up @@ -43,35 +44,21 @@ export const evaluatePatientName = (
mappings: PathMappings,
isPatientBanner: boolean,
) => {
const nameList = evaluate(fhirBundle, mappings.patientNameList);

if (nameList.length > 0) {
if (isPatientBanner) {
const name = nameList.find((name) => name.use === "official");
if (name) {
return formatName(name.given, name.family, name.prefix, name.suffix);
} else {
return formatName(
nameList[0].given,
nameList[0].family,
nameList[0].prefix,
nameList[0].suffix,
);
}
} else {
return nameList
.map((name) => {
return formatName(
name.given,
name.family,
name.prefix,
name.suffix,
nameList.length > 1 ? name?.use : undefined,
);
})
.join("\n");
}
const nameList: HumanName[] = evaluate(fhirBundle, mappings.patientNameList);

// Return early if there's no name
if (nameList.length === 0) {
return;
}

if (isPatientBanner) {
const officialName = nameList.find((n) => n.use === "official");
return formatName(officialName ?? nameList[0]);
}

return nameList
.map((name) => formatName(name, nameList.length > 1))
.join("\n");
};

/**
Expand Down Expand Up @@ -471,12 +458,7 @@ export const evaluateProviderData = (
const providerData = [
{
title: "Provider Name",
value: formatName(
practitioner?.name?.[0].given,
practitioner?.name?.[0].family,
practitioner?.name?.[0].prefix,
practitioner?.name?.[0].suffix,
),
value: formatName(practitioner?.name?.[0]),
},
{
title: "Provider Address",
Expand Down Expand Up @@ -535,13 +517,7 @@ export const evaluateEncounterCareTeamTable = (

return {
Name: {
value:
formatName(
practitioner?.name?.[0].given,
practitioner?.name?.[0].family,
practitioner?.name?.[0].prefix,
practitioner?.name?.[0].suffix,
) || noData,
value: formatName(practitioner?.name?.[0]) || noData,
},
Role: {
value: role || noData,
Expand Down
51 changes: 21 additions & 30 deletions containers/ecr-viewer/src/app/services/formatService.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { ToolTipElement } from "@/app/view-data/components/ToolTipElement";
import { Address, ContactPoint } from "fhir/r4";
import { Address, ContactPoint, HumanName } from "fhir/r4";
import { RenderableNode, safeParse } from "../view-data/utils/utils";
import sanitizeHtml from "sanitize-html";

Expand All @@ -22,39 +22,30 @@ export interface TableJson {
}

/**
* Formats a person's name using given name(s), family name, optional prefix(es), and optional suffix(es).
* @param given - Optional array of given name(s).
* @param family - Optional string representing family name or surname.
* @param [prefix] - Optional array of name prefix(es).
* @param [suffix] - Optional array of name suffix(es).
* @param [use] - Optional array of name use(s).
* @returns Formatted name.
* Formats a person's name: <use>: <prefix> <given> <family> <suffix>.
* @param humanName - The HumanName object containing the name components.
* @param withUse - Whether to include the name use in the formatted string.
* @returns The formatted name string.
*/
export const formatName = (
given?: string[],
family?: string,
prefix?: string[],
suffix?: string[],
use?: string,
) => {
const nameArray: string[] = [];
if (use) {
nameArray.push(toSentenceCase(use) + ":");
}
if (prefix) {
nameArray.push(...prefix);
}
if (given) {
nameArray.push(...given);
}
if (family) {
nameArray.push(family);
}
if (suffix) {
nameArray.push(...suffix);
humanName: HumanName | undefined,
withUse: boolean = false,
): string => {
if (!humanName) {
return "";
}

return nameArray.join(" ").trim();
const { use, prefix, given, family, suffix } = humanName;

const segments = [
...(withUse && use ? [`${toSentenceCase(use)}:`] : []),
...(prefix ?? []),
...(given ?? []),
family ?? "",
...(suffix ?? []),
];

return segments.filter(Boolean).join(" ");
};

const DEFAULT_ADDRESS_CONFIG = { includeUse: false, includePeriod: false };
Expand Down
31 changes: 17 additions & 14 deletions containers/ecr-viewer/src/app/tests/services/formatService.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,41 @@ import {
formatAddress,
formatPhoneNumber,
} from "@/app/services/formatService";
import { ContactPoint } from "fhir/r4";
import { ContactPoint, HumanName } from "fhir/r4";

describe("Format Name", () => {
const inputGiven = ["Gregory", "B"];
const inputFamily = "House";
const inputHumanName = {
given: ["Gregory", "B"],
family: "House",
} as HumanName;

it("should return only given and family name", () => {
const expectedName = "Gregory B House";

const result = formatName(inputGiven, inputFamily);
const result = formatName(inputHumanName);
expect(result).toEqual(expectedName);
});

it("should return the prefix, given, family, and suffix names", () => {
const inputPrefix = ["Dr."];
const inputSuffix = ["III"];
const expectedName = "Dr. Gregory B House III";

const result = formatName(
inputGiven,
inputFamily,
inputPrefix,
inputSuffix,
);
inputHumanName.prefix = ["Dr."];
inputHumanName.suffix = ["III"];

const result = formatName(inputHumanName);
expect(result).toEqual(expectedName);
});

it("should return an empty string", () => {
const inputEmpty: any[] = [];
const emptyHumanName = {
given: [],
family: "",
prefix: [],
suffix: [],
} as HumanName;
const expectedName = "";

const result = formatName(inputEmpty, "", inputEmpty, inputEmpty);
const result = formatName(emptyHumanName);
expect(result).toEqual(expectedName);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,7 @@ export const returnCareTeamTable = (
(nameObject) => nameObject.family,
);
if (entry.member) {
(entry.member as any).name = formatName(
practitionerNameObj?.given,
practitionerNameObj?.family,
practitionerNameObj?.prefix,
practitionerNameObj?.suffix,
);
(entry.member as any).name = formatName(practitionerNameObj);
}
});
return (
Expand Down

0 comments on commit b6dcf73

Please sign in to comment.