Skip to content

Commit

Permalink
edit chat modal and fix for appointment side panel
Browse files Browse the repository at this point in the history
  • Loading branch information
AykhanAhmadli committed Nov 1, 2024
1 parent c5adc61 commit 59c3c2e
Show file tree
Hide file tree
Showing 11 changed files with 414 additions and 105 deletions.
63 changes: 63 additions & 0 deletions packages/ehr-utils/lib/fhir/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {
OTTEHR_PATIENT_MESSAGE_CODE,
OTTEHR_PATIENT_MESSAGE_SYSTEM,
OttehrPatientMessageStatus,
RelatedPersonMaps,
SMSModel,
SMSRecipient,
} from '../types';
import { BatchInputRequest, FhirClient, User } from '@zapehr/sdk';
import { DateTime } from 'luxon';
Expand Down Expand Up @@ -41,6 +44,52 @@ export const getChatContainsUnreadMessages = (chat: Communication[]): boolean =>
return readStatusList.find((stat) => stat === false) !== undefined;
};

export const getCommunicationsAndSenders = async (
fhirClient: FhirClient,
uniqueNumbers: string[],
): Promise<(Communication | RelatedPerson)[]> => {
return await fhirClient.searchResources<Communication | RelatedPerson>({
resourceType: 'Communication',
searchParams: [
{ name: 'medium', value: ZAP_SMS_MEDIUM_CODE },
{ name: 'sender:RelatedPerson.telecom', value: uniqueNumbers.join(',') },
{ name: '_include', value: 'Communication:sender:RelatedPerson' },
],
});
};

export function getUniquePhonesNumbers(allRps: RelatedPerson[]): string[] {
const uniquePhoneNumbers: string[] = [];

allRps.forEach((rp) => {
const phone = getSMSNumberForIndividual(rp);
if (phone && !uniquePhoneNumbers.includes(phone)) uniquePhoneNumbers.push(phone);
});

return uniquePhoneNumbers;
}

export const createSmsModel = (patientId: string, allRelatedPersonMaps: RelatedPersonMaps): SMSModel | undefined => {
let rps: RelatedPerson[] = [];
try {
rps = allRelatedPersonMaps.rpsToPatientIdMap[patientId];
const recipients = filterValidRecipients(rps);
if (recipients.length) {
const allComs = recipients.flatMap((recip) => {
return allRelatedPersonMaps.commsToRpRefMap[recip.relatedPersonId] ?? [];
});
return {
hasUnreadMessages: getChatContainsUnreadMessages(allComs),
recipients,
};
}
} catch (e) {
console.log('error building sms model: ', e);
console.log('related persons value prior to error: ', rps);
}
return undefined;
};

export interface MakeOttehrMessageReadStatusInput {
userId: string;
timeRead: string;
Expand Down Expand Up @@ -148,3 +197,17 @@ export const initialsFromName = (name: string): string => {
});
return parts.join('');
};

function filterValidRecipients(relatedPersons: RelatedPerson[]): SMSRecipient[] {
// some slack alerts suggest this could be undefined, but that would mean there are patients with no RP
// or some bug preventing rp from being returned with the query
return relatedPersons
.map((rp) => {
return {
recipientResourceUri: rp.id ? `RelatedPerson/${rp.id}` : undefined,
smsNumber: getSMSNumberForIndividual(rp),
relatedPersonId: rp.id,
};
})
.filter((rec) => rec.recipientResourceUri !== undefined && rec.smsNumber !== undefined) as SMSRecipient[];
}
4 changes: 4 additions & 0 deletions packages/ehr-utils/lib/fhir/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export const getFullestAvailableName = (
return undefined;
};

export function filterResources(allResources: Resource[], resourceType: string): Resource[] {
return allResources.filter((res) => res.resourceType === resourceType && res.id);
}

export const getPatchOperationForNewMetaTag = (resource: Resource, newTag: Coding): Operation => {
if (resource.meta == undefined) {
return {
Expand Down
1 change: 1 addition & 0 deletions packages/ehr-utils/lib/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './formatPhoneNumber';
export * from './paperwork';
export * from './practitioner';
export * from './telemed-appointment.helper';
export * from './mappers';
99 changes: 99 additions & 0 deletions packages/ehr-utils/lib/helpers/mappers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { FhirClient } from '@zapehr/sdk';
import { Communication, RelatedPerson, Resource } from 'fhir/r4';
import { removePrefix } from '.';
import {
filterResources,
getCommunicationsAndSenders,
getSMSNumberForIndividual,
getUniquePhonesNumbers,
} from '../fhir';
import { RelatedPersonMaps } from '../types';

export const relatedPersonAndCommunicationMaps = async (
fhirClient: FhirClient,
inputResources: Resource[],
): Promise<RelatedPersonMaps> => {
const allRelatedPersons = filterResources(inputResources, 'RelatedPerson') as RelatedPerson[];
const rpsPhoneNumbers = getUniquePhonesNumbers(allRelatedPersons);
const rpsToPatientIdMap = mapRelatedPersonToPatientId(allRelatedPersons);
const rpToIdMap = mapRelatedPersonToId(allRelatedPersons);
const foundResources = await getCommunicationsAndSenders(fhirClient, rpsPhoneNumbers);
const foundRelatedPersons = filterResources(foundResources, 'RelatedPerson') as RelatedPerson[];
Object.assign(rpToIdMap, mapRelatedPersonToId(foundRelatedPersons));
rpsPhoneNumbers.concat(getUniquePhonesNumbers(foundRelatedPersons)); // do better here
const rpsRefsToPhoneNumberMap = mapRelatedPersonsRefsToPhoneNumber(foundRelatedPersons);

const foundCommunications = filterResources(foundResources, 'Communication') as Communication[];
const commsToRpRefMap = mapCommunicationsToRelatedPersonRef(foundCommunications, rpToIdMap, rpsRefsToPhoneNumberMap);

return {
rpsToPatientIdMap,
commsToRpRefMap,
};
};

function mapRelatedPersonToPatientId(allRps: RelatedPerson[]): Record<string, RelatedPerson[]> {
const rpsToPatientIdMap: Record<string, RelatedPerson[]> = {};

allRps.forEach((rp) => {
const patientId = removePrefix('Patient/', rp.patient.reference || '');
if (patientId) {
if (rpsToPatientIdMap[patientId]) rpsToPatientIdMap[patientId].push(rp);
else rpsToPatientIdMap[patientId] = [rp];
}
});

return rpsToPatientIdMap;
}

function mapRelatedPersonToId(allRps: RelatedPerson[]): Record<string, RelatedPerson> {
const rpToIdMap: Record<string, RelatedPerson> = {};

allRps.forEach((rp) => {
rpToIdMap['RelatedPerson/' + rp.id] = rp;
});

return rpToIdMap;
}

function mapRelatedPersonsRefsToPhoneNumber(allRps: RelatedPerson[]): Record<string, string[]> {
const relatedPersonRefToPhoneNumber: Record<string, string[]> = {};

allRps.forEach((rp) => {
const rpRef = `RelatedPerson/${rp.id}`;
const pn = getSMSNumberForIndividual(rp as RelatedPerson);
if (pn) {
if (relatedPersonRefToPhoneNumber[pn]) relatedPersonRefToPhoneNumber[pn].push(rpRef);
else relatedPersonRefToPhoneNumber[pn] = [rpRef];
}
});
return relatedPersonRefToPhoneNumber;
}

function mapCommunicationsToRelatedPersonRef(
allCommunications: Communication[],
rpToIdMap: Record<string, RelatedPerson>,
rpsRefsToPhoneNumberMap: Record<string, string[]>,
): Record<string, Communication[]> {
const commsToRpRefMap: Record<string, Communication[]> = {};

allCommunications.forEach((comm) => {
const communication = comm as Communication;
const rpRef = communication.sender?.reference;
if (rpRef) {
const senderResource = rpToIdMap[rpRef];
if (senderResource) {
const smsNumber = getSMSNumberForIndividual(senderResource);
if (smsNumber) {
const allRPsWithThisNumber = rpsRefsToPhoneNumberMap[smsNumber];
allRPsWithThisNumber.forEach((rpRef) => {
if (commsToRpRefMap[rpRef]) commsToRpRefMap[rpRef].push(communication);
else commsToRpRefMap[rpRef] = [communication];
});
}
}
}
});

return commsToRpRefMap;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { ApptTab } from './AppointmentTabs';
import CustomChip from './CustomChip';
import { GenericToolTip, PaperworkToolTipContent } from './GenericToolTip';
import { VisitStatus, StatusLabel } from '../helpers/mappingUtils';
import { quickTexts } from '../telemed/utils';

interface AppointmentTableProps {
appointment: UCAppointmentInformation;
Expand Down Expand Up @@ -795,6 +796,7 @@ export default function AppointmentTableRow({
currentLocation={location}
onClose={() => setChatModalOpen(false)}
onMarkAllRead={() => setHasUnread(false)}
quickTexts={quickTexts}
/>
)}
</TableRow>
Expand Down
5 changes: 5 additions & 0 deletions packages/telemed-ehr/app/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export const ReasonForVisitOptions = [
'Eye concern',
];

export enum LANGUAGES {
spanish = 'spanish',
english = 'english',
}

export const phoneNumberRegex = /^\d{10}$/;

export const MAXIMUM_CHARACTER_LIMIT = 160;
Expand Down
Loading

0 comments on commit 59c3c2e

Please sign in to comment.