Skip to content

Commit

Permalink
code review
Browse files Browse the repository at this point in the history
  • Loading branch information
CynthiaKamau committed Oct 4, 2024
1 parent b6b0978 commit 87fe3eb
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,34 @@ import {
getConceptFromMappings,
getConditionalConceptValue,
} from './helpers';
import { renderTag } from '../../encounter-list/components/tag.component';
import {
type Encounter,
type ColumnDefinition,
type TabSchema,
type ActionProps,
type ConditionalActionProps,
} from '../../encounter-list/types';
import { renderTag } from '../../encounter-list/components/tag.component';

interface FormattedColumn {
key: string;
header: string;
getValue: (encounter: any) => string;
link?: any;
getValue: (
encounter: any,
) =>
| string
| number
| Element
| { uuid: string; name: { name: string }; names?: { uuid: string; name: string; conceptNameType: string }[] }
| { form: { name: string }; encounterUuid: string; intent: string; label: string; mode: string }[];
link?: { getUrl: (encounter: any) => string; handleNavigate?: (encounter: any) => void };
concept?: string;
}

const getColumnValue = (encounter: Encounter, column: ColumnDefinition) => {
if (column.id === 'actions') {
return getActions(encounter, column);
}

if (column.statusColorMappings) {
return renderTag(encounter, column.concept, column.statusColorMappings);
}
Expand Down Expand Up @@ -105,7 +111,13 @@ export const getTabColumns = (columnsDefinition: Array<ColumnDefinition>) => {
key: column.id,
header: column.title,
concept: column.concept,
getValue: (encounter) => getColumnValue(encounter, column),
getValue: (encounter) =>
getColumnValue(encounter, column) as
| string
| number
| Element
| { uuid: string; name: { name: string }; names?: { uuid: string; name: string; conceptNameType: string }[] }
| { form: { name: string }; encounterUuid: string; intent: string; label: string; mode: string }[],
link: column.isLink
? {
getUrl: (encounter) => encounter.url,
Expand Down
70 changes: 35 additions & 35 deletions packages/esm-patient-chart-app/src/clinical-views/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib';
import { type FormSchema } from '@openmrs/esm-form-engine-lib';
import { formatDate, parseDate, formatDatetime, type Concept } from '@openmrs/esm-framework';
import { fetchPatientRelationships } from '../../encounter-list/encounter-list.resource';
import { type Encounter } from '../../encounter-list/types';
import { formatDate, parseDate, formatDatetime, type Concept, age } from '@openmrs/esm-framework';
import { type Observation, type Encounter } from '../../encounter-list/types';
import { esmPatientChartSchema } from '../../config-schema';
import { type TFunction } from 'i18next';

type LaunchAction = 'add' | 'view' | 'edit' | 'embedded-view';

Expand Down Expand Up @@ -36,18 +37,20 @@ export function launchEncounterForm(
});
}

export function formatDateTime(dateString: string): any {
export function formatDateTime(dateString: string): string {
const parsedDate = parseDate(dateString.includes('.') ? dateString.split('.')[0] : dateString);
return formatDatetime(parsedDate);
}

export function obsArrayDateComparator(left, right) {
return formatDateTime(right.obsDatetime) - formatDateTime(left.obsDatetime);
export function obsArrayDateComparator(left: Observation, right: Observation): number {
const leftDate = new Date(left.obsDatetime);
const rightDate = new Date(right.obsDatetime);
return rightDate.getTime() - leftDate.getTime();
}

export function findObs(encounter: Encounter, obsConcept: string): Record<string, any> {
export function findObs(encounter: Encounter, obsConcept: string): Observation | undefined {
const allObs = encounter?.obs?.filter((observation) => observation.concept.uuid === obsConcept) || [];
return !allObs ? {} : allObs.length === 1 ? allObs[0] : allObs.sort(obsArrayDateComparator)[0];
return !allObs ? undefined : allObs.length === 1 ? allObs[0] : allObs.sort(obsArrayDateComparator)[0];
}

export function getObsFromEncounters(encounters: Encounter, obsConcept: Concept) {
Expand All @@ -58,16 +61,19 @@ export function getObsFromEncounters(encounters: Encounter, obsConcept: Concept)
export function resolveValueUsingMappings(encounter: Encounter, concept: string, mappings) {
const obs = findObs(encounter, concept);
for (const key in mappings) {
if (mappings[key] === obs?.value?.uuid) {
return key;
if (typeof obs?.value === 'object' && 'uuid' in obs.value) {
if (mappings[key] === obs.value.uuid) {
return key;
}
}
}
return '--';
}

export function getConditionalConceptValue(encounter: any, conditionalConceptMappings, isDate) {
const { trueConcept, nonTrueConcept, dependantConcept, conditionalConcept } = conditionalConceptMappings;
const dependantUuid = findObs(encounter, dependantConcept)?.value?.uuid;
const obsValue = findObs(encounter, dependantConcept)?.value;
const dependantUuid = typeof obsValue === 'object' && 'uuid' in obsValue ? obsValue.uuid : null;
const finalConcept = dependantUuid === conditionalConcept ? trueConcept : nonTrueConcept;
return getObsFromEncounter(encounter, finalConcept, isDate);
}
Expand All @@ -94,15 +100,6 @@ export function getMultipleObsFromEncounter(encounter: Encounter, obsConcepts: A
return observations.length ? observations.join(', ') : '--';
}

async function fetchMotherName(patientUuid: string) {
let motherName = '--';
const response = await fetchPatientRelationships(patientUuid);
if (response.length) {
motherName = response[0].personA.display;
}
return motherName;
}

export function getObsFromEncounter(
encounter: Encounter,
obsConcept,
Expand All @@ -111,6 +108,7 @@ export function getObsFromEncounter(
type?: string,
fallbackConcepts?: Array<string>,
secondaryConcept?: string,
t?: TFunction,
) {
let obs = findObs(encounter, obsConcept);

Expand All @@ -121,15 +119,17 @@ export function getObsFromEncounter(
// Not sure if these concepts are similar in all implementations,
// There might be a better way to use a generic value
if (isTrueFalseConcept) {
if (
(obs?.value?.uuid != 'cf82933b-3f3f-45e7-a5ab-5d31aaee3da3' && obs?.value?.name?.name !== 'Unknown') ||
obs?.value?.name?.name === 'FALSE'
) {
return 'No';
} else if (obs?.value?.uuid == 'cf82933b-3f3f-45e7-a5ab-5d31aaee3da3') {
return 'Yes';
} else {
return obs?.value?.name?.name;
if (typeof obs?.value === 'object') {
if (
(obs?.value?.uuid != esmPatientChartSchema.trueConceptUuid._default && obs?.value?.name?.name !== 'Unknown') ||
obs?.value?.name?.name === 'FALSE'
) {
return 'No';
} else if (obs?.value?.uuid == esmPatientChartSchema.trueConceptUuid._default) {
return 'Yes';
} else {
return obs?.value?.name?.name;
}
}
}

Expand All @@ -141,9 +141,9 @@ export function getObsFromEncounter(
return encounter.encounterProviders.map((p) => p.provider.name).join(' | ');
}

// TODO: This needs to put in some other place
// TODO: This needs to be added later
if (type === 'mothersName') {
return fetchMotherName(encounter.patient.uuid);
return;
}

if (type === 'visitType') {
Expand All @@ -152,13 +152,13 @@ export function getObsFromEncounter(

// TODO: Need to get a better place for this
if (type === 'ageAtHivTest') {
return encounter.patient.age;
return age(encounter.patient.birthDate, encounter.encounterDatetime);
}

if (secondaryConcept && typeof obs.value === 'object' && obs.value.names) {
const primaryValue =
obs.value.names.find((conceptName) => conceptName.conceptNameType === 'SHORT')?.name || obs.value.name.name;
if (primaryValue === 'Other non-coded') {
obs.value.names.find((conceptName) => conceptName.conceptNameType === t('SHORT'))?.name || obs.value.name.name;
if (primaryValue === t('Other non-coded')) {
const secondaryObs = findObs(encounter, secondaryConcept);
return secondaryObs ? secondaryObs.value : '--';
}
Expand All @@ -177,7 +177,7 @@ export function getObsFromEncounter(
if (typeof obs.value === 'object' && obs.value?.names) {
return formatDate(parseDate(obs.obsDatetime), { mode: 'wide' });
} else {
return formatDate(parseDate(obs.value), { mode: 'wide' });
return typeof obs.value === 'string' ? formatDate(parseDate(obs.value), { mode: 'wide' }) : '--';
}
}

Expand Down
6 changes: 6 additions & 0 deletions packages/esm-patient-chart-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export const esmPatientChartSchema = {
_default: '/etl-latest/etl/patient/',
_description: 'Custom URL to load resources required for showing recommended visit types',
},
trueConceptUuid: {
_type: Type.String,
_description: 'Default concept uuid for true in forms',
_default: 'cf82933b-3f3f-45e7-a5ab-5d31aaee3da3',
},
};

export interface ChartConfig {
Expand Down Expand Up @@ -161,4 +166,5 @@ export interface ChartConfig {
uuid: string;
}>;
visitDiagnosisConceptUuid: string;
trueConceptUuid: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ export const renderTag = (encounter, concept, statusColorMappings) => {
return '--';
} else {
return (
<Tag type={statusColorMappings[columnStatusObs?.value?.uuid]} title={columnStatus} style={{ minWidth: '80px' }}>
<Tag
type={
typeof columnStatusObs?.value === 'object' && 'uuid' in columnStatusObs.value
? statusColorMappings[columnStatusObs.value.uuid]
: undefined
}
title={columnStatus}
style={{ minWidth: '80px' }}
>
{columnStatus}
</Tag>
);
Expand Down
19 changes: 18 additions & 1 deletion packages/esm-patient-chart-app/src/encounter-list/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,37 @@ export interface Encounter extends OpenmrsResource {
uuid: string;
display: string;
age: number;
birthDate: string;
};
location: {
uuid: string;
display: string;
name: string;
};
encounterProviders?: Array<{ encounterRole: string; provider: { uuid: string; name: string } }>;
obs: Array<OpenmrsResource>;
obs: Array<Observation>;
form?: {
uuid: string;
};
visit?: string;
}

export interface Observation {
uuid: string;
concept: { uuid: string; name: string };
value:
| {
uuid: string;
name: {
name: string;
};
names?: Array<{ uuid: string; name: string; conceptNameType: string }>;
}
| string;
groupMembers?: Array<Observation>;
obsDatetime: string;
}

export interface ListResponse<T> {
results: Array<T>;
}
Expand Down

0 comments on commit 87fe3eb

Please sign in to comment.