Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/rubicon #617

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0ebd6db
configure redirect issue for videocall
AykhanAhmadli Nov 20, 2024
950aadb
Merge pull request #601 from masslight/aykhan-end-call-redirect
AykhanAhmadli Nov 20, 2024
e9cdcdf
Merge pull request #606 from masslight/aykhan/past-slot
AykhanAhmadli Nov 21, 2024
be0af8e
Revert "End call redirect issue"
AykhanAhmadli Nov 21, 2024
ffe579d
Merge pull request #607 from masslight/revert-601-aykhan-end-call-red…
AykhanAhmadli Nov 21, 2024
d1cd9bd
Revert "Revert "End call redirect issue""
AykhanAhmadli Nov 21, 2024
392bd03
Merge pull request #608 from masslight/revert-607-revert-601-aykhan-e…
AykhanAhmadli Nov 21, 2024
76f1a7d
filter in-person appointments
AykhanAhmadli Nov 21, 2024
17b3ae7
Merge pull request #610 from masslight/duplicate-visit
AykhanAhmadli Nov 21, 2024
578b65a
Revert "Past slot time selection handling"
AykhanAhmadli Nov 21, 2024
ea5e5c0
everything but addresses #499
GiladSchneider Nov 21, 2024
4c56269
fix build
GiladSchneider Nov 21, 2024
966a2f6
everything but addresses #499
GiladSchneider Nov 21, 2024
53033e6
fix build
GiladSchneider Nov 21, 2024
5d8e150
Merge branch 'develop' into 499/editable
GiladSchneider Nov 21, 2024
f2b2c88
undo changes
GiladSchneider Nov 21, 2024
afa762e
Merge pull request #612 from masslight/499/editable
GiladSchneider Nov 21, 2024
0070c9a
Merge branch 'develop' into version-bump
GiladSchneider Nov 25, 2024
63bb327
update version
GiladSchneider Nov 25, 2024
0239835
reverts unnecesarry changes
GiladSchneider Nov 25, 2024
0d9b12c
Merge pull request #616 from masslight/version-bump
GiladSchneider Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ottehr",
"version": "0.17.0",
"version": "0.18.0",
"private": true,
"scripts": {
"test": "pnpm recursive run test",
Expand Down
2 changes: 1 addition & 1 deletion packages/ehr-utils/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ehr-utils",
"private": true,
"version": "0.17.0",
"version": "0.18.0",
"main": "lib/main.ts",
"types": "lib/main.ts",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ottehr-components/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ottehr-components",
"private": true,
"version": "0.17.0",
"version": "0.18.0",
"main": "lib/main.ts",
"types": "lib/main.ts",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/telemed-ehr/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "telemed-ehr-app",
"version": "0.17.0",
"version": "0.18.0",
"private": true,
"browserslist": {
"production": [
Expand Down
79 changes: 52 additions & 27 deletions packages/telemed-ehr/app/src/components/EmployeeInformationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ interface EmployeeForm {
lastName: string;
nameSuffix: string;
roles: string[];
phoneNumber: string;
npi: string;
}

const AVAILABLE_ROLES: {
Expand Down Expand Up @@ -150,22 +152,6 @@ export default function EmployeeInformationForm({

console.log('existingUser', existingUser);

let npiText = 'n/a';
if (existingUser?.profileResource?.identifier) {
const npi = existingUser.profileResource.identifier.find((identifier) => identifier.system === FHIR_IDENTIFIER_NPI);
if (npi && npi.value) {
npiText = npi.value;
}
}

let phoneText = '';
if (existingUser?.profileResource?.telecom) {
const phone = existingUser.profileResource.telecom.find((tel) => tel.system === 'sms')?.value;
if (phone) {
phoneText = phone;
}
}

let photoSrc = '';
if (existingUser?.profileResource?.photo) {
const photo = existingUser.profileResource.photo[0];
Expand Down Expand Up @@ -201,6 +187,26 @@ export default function EmployeeInformationForm({
setValue('middleName', middleName);
setValue('lastName', lastName);
setValue('nameSuffix', nameSuffix);

let phoneText = '';
if (existingUser?.profileResource?.telecom) {
const phone = existingUser.profileResource.telecom.find((tel) => tel.system === 'sms')?.value;
if (phone) {
phoneText = phone;
}
}
setValue('phoneNumber', phoneText);

let npiText = 'n/a';
if (existingUser?.profileResource?.identifier) {
const npi = existingUser.profileResource.identifier.find(
(identifier) => identifier.system === FHIR_IDENTIFIER_NPI,
);
if (npi && npi.value) {
npiText = npi.value;
}
}
setValue('npi', npiText);
}
}, [existingUser, setValue]);

Expand Down Expand Up @@ -229,6 +235,8 @@ export default function EmployeeInformationForm({
nameSuffix: data.nameSuffix,
selectedRoles: data.roles,
licenses: newLicenses,
phoneNumber: data.phoneNumber,
npi: data.npi,
});
} catch (error) {
console.log(`Failed to update user: ${error}`);
Expand Down Expand Up @@ -334,16 +342,19 @@ export default function EmployeeInformationForm({
disabled: true,
}}
/>
<TextField
id="outlined-read-only-input"
label="Phone"
value={phoneText}
sx={{ marginBottom: 2, width: '100%' }}
margin="dense"
InputProps={{
readOnly: true,
disabled: true,
}}
<Controller
name="phoneNumber"
control={control}
render={({ field: { onChange, value } }) => (
<TextField
id="phone-number-input"
label="Phone"
value={value || ''}
onChange={onChange}
sx={{ marginBottom: 2, width: '100%' }}
margin="dense"
/>
)}
/>

<FormControl sx={{ width: '100%' }} error={errors.roles}>
Expand Down Expand Up @@ -420,7 +431,21 @@ export default function EmployeeInformationForm({
/>
)}
/>
<label style={{ margin: '15px 0' }}>NPI: {npiText}</label>
<Controller
name="npi"
control={control}
render={({ field: { onChange, value } }) => (
<TextField
id="npi-input"
label="NPI"
required={true}
value={value || ''}
onChange={onChange}
sx={{ marginTop: 2, marginBottom: 2, width: '100%' }}
margin="dense"
/>
)}
/>
</FormControl>
{isProviderRoleSelected && (
<>
Expand Down
2 changes: 2 additions & 0 deletions packages/telemed-ehr/app/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export interface UpdateUserParameters {
nameSuffix?: string;
selectedRoles?: string[] | undefined;
licenses?: PractitionerLicense[];
phoneNumber?: string;
npi?: string;
// locations: Location[];
}

Expand Down
2 changes: 1 addition & 1 deletion packages/telemed-ehr/zambdas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "telemed-ehrzambdas",
"version": "0.17.0",
"version": "0.18.0",
"private": true,
"scripts": {
"start": "npm run start:local",
Expand Down
2 changes: 1 addition & 1 deletion packages/telemed-ehr/zambdas/src/get-appointments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export const index = async (input: ZambdaInput): Promise<APIGatewayProxyResult>
const healthcareServiceIdToResourceMap: Record<string, HealthcareService> = {};

searchResultsForSelectedDate.forEach((resource) => {
if (resource.resourceType === 'Appointment') {
if (resource.resourceType === 'Appointment' && (resource as Appointment).serviceType?.[0]?.text === 'in-person') {
allAppointments.push(resource as Appointment);
} else if (resource.resourceType === 'Patient' && resource.id) {
patientIdMap[resource.id] = resource as Patient;
Expand Down
32 changes: 30 additions & 2 deletions packages/telemed-ehr/zambdas/src/update-user/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { APIGatewayProxyResult } from 'aws-lambda';
import { Practitioner, HumanName } from 'fhir/r4';
import { PractitionerLicense, Secrets } from 'ehr-utils';
import { FHIR_IDENTIFIER_NPI, PractitionerLicense, Secrets } from 'ehr-utils';
import { RoleType } from '../../../app/src/types/types';
import { getSecret } from '../shared';
import { topLevelCatch } from '../shared/errors';
Expand All @@ -19,6 +19,8 @@ export interface UpdateUserInput {
nameSuffix?: string;
selectedRoles?: RoleType[];
licenses?: PractitionerLicense[];
phoneNumber?: string;
npi?: string;
}

let m2mtoken: string;
Expand All @@ -27,7 +29,7 @@ export const index = async (input: ZambdaInput): Promise<APIGatewayProxyResult>
console.group('validateRequestParameters');
const validatedParameters = validateRequestParameters(input);
console.log('validatedParameters:', JSON.stringify(validatedParameters, null, 4));
const { secrets, userId, firstName, middleName, lastName, nameSuffix, selectedRoles, licenses } =
const { secrets, userId, firstName, middleName, lastName, nameSuffix, selectedRoles, licenses, phoneNumber, npi } =
validatedParameters;
console.groupEnd();
console.debug('validateRequestParameters success');
Expand Down Expand Up @@ -98,14 +100,40 @@ export const index = async (input: ZambdaInput): Promise<APIGatewayProxyResult>
id: practitionerId,
name: name ? [name] : undefined,
qualification: practitionerQualificationExtension,
telecom: phoneNumber ? [{ system: 'sms', value: phoneNumber }] : undefined,
});
} else {
const existingTelecom = existingPractitionerResource.telecom || [];
const smsIndex = existingTelecom.findIndex((tel) => tel.system === 'sms');
const updatedTelecom = [...existingTelecom];
if (phoneNumber) {
if (smsIndex >= 0) {
updatedTelecom[smsIndex] = { system: 'sms', value: phoneNumber };
} else {
updatedTelecom.push({ system: 'sms', value: phoneNumber });
}
}
if (npi) {
if (!existingPractitionerResource.identifier) {
existingPractitionerResource.identifier = [];
}
const npiIndex = existingPractitionerResource.identifier.findIndex((id) => id.system === FHIR_IDENTIFIER_NPI);
if (npiIndex >= 0) {
existingPractitionerResource.identifier[npiIndex].value = npi;
} else {
existingPractitionerResource.identifier.push({
system: FHIR_IDENTIFIER_NPI,
value: npi,
});
}
}
await fhirClient.updateResource({
...existingPractitionerResource,
identifier: existingPractitionerResource.identifier,
photo: existingPractitionerResource.photo,
name: name ? [name] : undefined,
qualification: practitionerQualificationExtension,
telecom: updatedTelecom,
});
}
} catch (error: unknown) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export function validateRequestParameters(input: ZambdaInput): UpdateUserInput {
throw new Error('No request body provided');
}

const { userId, firstName, middleName, lastName, nameSuffix, selectedRoles, licenses } = JSON.parse(input.body);
const { userId, firstName, middleName, lastName, nameSuffix, selectedRoles, licenses, phoneNumber, npi } = JSON.parse(
input.body,
);

if (
userId === undefined
Expand Down Expand Up @@ -36,5 +38,7 @@ export function validateRequestParameters(input: ZambdaInput): UpdateUserInput {
licenses,
// locations,
secrets: input.secrets,
phoneNumber: phoneNumber ? phoneNumber.trim() : phoneNumber,
npi: npi ? npi.trim() : npi,
};
}
2 changes: 1 addition & 1 deletion packages/telemed-intake/app/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "telemed-intake-app",
"private": true,
"version": "0.17.0",
"version": "0.18.0",
"type": "module",
"scripts": {
"start:local": "vite",
Expand Down
4 changes: 4 additions & 0 deletions packages/telemed-intake/app/src/components/VideoControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import { CallSettingsTooltip } from './CallSettingsTooltip';
import { useVideoCallStore } from '../features/video-call';
import { otherColors } from '../IntakeThemeProvider';
import { CallSettings } from './CallSettingsDialog';
import { useNavigate } from 'react-router-dom';
import { IntakeFlowPageRoute } from 'src/App';

export const VideoControls: FC = () => {
const { toggleVideo, isVideoEnabled } = useLocalVideo();
const { muted, toggleMute } = useToggleLocalMute();
const navigate = useNavigate();

const meetingManager = useMeetingManager();
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
Expand Down Expand Up @@ -46,6 +49,7 @@ export const VideoControls: FC = () => {
const disconnect = async (): Promise<void> => {
await cleanup();
useVideoCallStore.setState({ meetingData: null });
navigate(IntakeFlowPageRoute.PatientPortal.path);
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface AppointmentState {
providerID?: string;
groupID?: string;
scheduleType?: 'location' | 'provider';
slug?: string;
}

const APOINTMENT_STATE_INITIAL: AppointmentState = {};
Expand Down
29 changes: 27 additions & 2 deletions packages/telemed-intake/app/src/pages/ConfirmDateOfBirth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { CustomContainer } from '../features/common';
import { useGetPaperwork, usePaperworkStore } from '../features/paperwork';
import { usePatientInfoStore } from '../features/patient-info';
import { useZapEHRAPIClient } from '../utils';
import { handleClosePastTimeErrorDialog, isSlotTimePassed, useZapEHRAPIClient } from '../utils';
import { decode } from 'html-entities';

const ConfirmDateOfBirth = (): JSX.Element => {
Expand All @@ -26,7 +26,11 @@ const ConfirmDateOfBirth = (): JSX.Element => {
const [requestErrorDialogOpen, setRequestErrorDialogOpen] = useState<boolean>(false);
const createAppointment = useCreateAppointmentMutation();
const [getPaperworkEnabled, setGetPaperworkEnabled] = useState<boolean>(false);
const { appointmentID } = getSelectors(useAppointmentStore, ['appointmentID']);
const { appointmentID, selectedSlot, visitType, visitService, scheduleType, slug } = getSelectors(
useAppointmentStore,
['appointmentID', 'selectedSlot', 'visitType', 'visitService', 'scheduleType', 'slug'],
);
const [isPastTimeErrorDialogOpen, setIsPastTimeErrorDialogOpen] = useState<boolean>(false);
const { patchCompletedPaperwork, setQuestions } = getSelectors(usePaperworkStore, [
'patchCompletedPaperwork',
'setQuestions',
Expand Down Expand Up @@ -116,6 +120,11 @@ const ConfirmDateOfBirth = (): JSX.Element => {
}, [challengeDay.name, challengeMonth.name, challengeYear.name, formValuesCopy]);

const createOrUpdateAppointment = (unconfirmedDateOfBirth = false): void => {
if (isSlotTimePassed(selectedSlot, visitType)) {
setIsPastTimeErrorDialogOpen(true);
return;
}

if (!apiClient) {
throw new Error('apiClient is not defined');
}
Expand Down Expand Up @@ -261,6 +270,22 @@ const ConfirmDateOfBirth = (): JSX.Element => {
closeButtonText={t('general.button.close')}
handleClose={() => setRequestErrorDialogOpen(false)}
/>
<ErrorDialog
open={isPastTimeErrorDialogOpen}
title={t('patientInfo.pastTimeError.title')}
description={t('patientInfo.pastTimeError.description')}
closeButtonText={t('patientInfo.pastTimeError.button')}
handleClose={() =>
handleClosePastTimeErrorDialog(
setIsPastTimeErrorDialogOpen,
navigate,
visitType,
visitService,
scheduleType,
slug,
)
}
/>
</>
</CustomContainer>
);
Expand Down
Loading
Loading