feat: OpenEMR Telehealth screensharing & Third Party (#6207)
commit5416f3c3bf9da49822e875fdce460866555db8bc
authorStephen Nielson <snielson@discoverandchange.com>
Thu, 9 Mar 2023 21:35:59 +0000 (9 16:35 -0500)
committerGitHub <noreply@github.com>
Thu, 9 Mar 2023 21:35:59 +0000 (9 16:35 -0500)
tree7c51fa30a128a780436327841bec51582628d837
parent76065cc1a912511083751bc166d824b32b3e531b
feat: OpenEMR Telehealth screensharing & Third Party (#6207)

Overall changelog for this PR is the following:
- Add participant (add a third party participant) as either a new patient or using existing patient search
- Redesigned layout with collapsible participant list
- Controls fade out after five seconds of mouse / touch screen inactivity
- Share screen with participants
- Patient invitation email when telehealth session starts
- Third party invitation email when third party recipient is added
- Direct patient launch screen from email (will redirect to login page if not logged in)
- Improved OpenEMR email validation for patient portal and patient db insert
- Telehealth hooks on email invitations for developer enhancements (such as sending invitation via SMS)
- Minimized note taking session screen default position setting (Top Left, Bottom Left, Top Right, Bottom Right options)
- Minimized session screen will remember drag position during session if you move it to another location
- Redesigned mobile view to better support both landscape and portrait displays
- Pinned participants allow you to select a participant you want to always show in the main presentation screen
- Pending appointments no longer show a launch icon for patient appointments
- Pending appointments launched by a provider will automatically convert into a regular appointment instead of requiring the status to be changed before they can launch
- Participants now show the name of the person on the video screen
  If the local camera / microphone cannot be acquired it notifies the user of the device failure
- Bug Fix - Reassigning launched telehealth session now correctly allows patient access
- Bug Fix - prevent patient from immediately rejoining closed session when provider leaves
- Bug Fix - improved load times by lazy loading singleton service classes
- Bug Fix - expired sessions would show the launch button on the add edit event screen which would then display an error when clicked
- Bug Fix - Launching a second telehealth session in the same day for the same patient would often grab the earlier session for the patient and the patient would be unable to join
- Bug Fix - added ACL checks on the room controller action dispatcher to prevent improper access to the api

Got the initial screen share launch hook in.

* Initial screensharing commit WIP

Broke up the telehealth.js into separate files to make it easier to
reason and compose the pieces together.  Initial work on the
screensharing pieces and updated the comlink bridge library to support
the screensharing.

Added exception handling for when the bridge is down to notify the user
of the problem.

Added a settings verification piece in the module.

* Fix bugs with refactor

* WIP 2 send and accept share screen requests

* WIP patient screensharing, 3rd party setup

Did work to help setup calls and screensharing so we can have more than
one party on the call.

Also got the screensharing working from patient to provider.  Still
having bugs with screensharing from provider to patient which is the
next step to work on.

Updated the cvb version so we can receive the event for the screenshare
end.

* Screensharing implementation

Provider to patient and patient to provider screensharing with two way
calling.

* WIP implement ability for 3rd party calls.

On the backend we send down a participant list when a user attempts to
join the room of who is in the room, etc so we can know who to make the
calls to.

On the frontend we allow those users who are in the participant list to
join the call.

We still need to handle the third party attempting to join and letting
them in.

* WIP 3rd Party Telehealth configure,patient portal

Made it so the 3rd party telehealth shows up on the patient portal when
there is an active session.

Also added a configure dialog to the provider.  Stubbed out the
participant lists and made it so they get updated on the telehealth
session.

* WIP Telehealth implement add patient logic

Implemented the backend database structure for third party invitation to
the telehealth session.

Implemented creating a patient from the provider to invite them as a 3rd
party to the telehealth sesison.

Setup initial work for searching for duplicate patients to avoid
re-creating patients.

Changed out the settings configuration on the frontend for the provider
to be an add patient dialog.

* Third party invitation create and search

Made it so the third party search works with the FHIR endpoints for
returning a list of patients to invite to the session.

Also made changes to handle the adding of the invitation for a new
patient.

* Twig templates for telehealth invitations

Email invitations implemented with twig templates and OpenEMR logo.

* Handle invite errors better

* Add third party invitation flag

Since the third party invitation email relies on the portal being
enabled and configured we need to add that to the settings to make sure
we only enable 3rd party invitations when the portal is configured
properly.

* PSR fixes, 3rd party invitations

Made it so the 3rd party invitations go through the index-portal action
dispatcher.  Got the email invitations setup properly.

Did a bunch of PSR fixes.

* Make video bar centered

* Fix third party screen display w/ missing patient

If the patient was not on the call but the third party user had joined
the 3rd party would not show on the main screen.  Changed it so the 3rd
party shows on the main screen, made it so if the patient joins it
refocuses on the patient for the provider.

* Fix third party session update logic

Sessions were not updating for the 3rd party so when patient joins it
would not connect to the patient.

* Minor html fix, add debug telehealth script

* Breaking minimize/maximize conference code out

Broke the code out into its own class so we can isolate the behavior of
the minimized conference room to handle multiple participants.

* Fix minimized telehealth display

Made the minimized display show the toolbar correctly.

Made the minimized display hide the local speaker in the participant
list and display the remote speakers correctly.

* Add language translations, move expand button

Expand button should be at the front when the screen is minimized.
Added the language translations.

* Thirdparty screenshare, invitation dialog changes

Fixed third party screenshare calls as screenshare was working for only one participant.
Added the name of the caller to the title property for the videos.  Now when
you hover the mouse over the video it shows who the caller is.  Helpful for
debugging.

Added the current third party invitation to the dialog screen so we can see
who was invited.

Changed the dialog screen to update the new participant when the screen loads.

Updated the presentation screen css

* Fix UI glitches on telehealth.

Fixed the screensharing slot not hiding when the call ends.

Fix the blue background on the video.

Changed up the index-portal and invitation join link to go directly to
the index-portal which will redirect to the portal login page if the
user isn't logged in.

* Telehealth audio monitoring, telehealth email.

screenshare changes.

* Telehealth screensharing, participant controls

Initial work on participant controls to handle pinning.

Fixed bugs with the screensharing that cropped up when we added the
audio monitor.

Refactored the participant list so the videos show up in a their own
container that we can add participant controls to it.

* Telehealth Pinned caller, participant label

Made a participant label show up for remote callers.  Still need a label
for the local caller.

Added in the toggling of a pinned caller to keep the focus on that
caller.  Clicking on the video toggle sets the pinned status.  Need to
handle the user clicking the pinned icon as well to toggle / untoggle.

* Refactored ATSlot into a class

* Telehealth participant labels, minimized fixes

Fixed UI elements on minimized telehealth participant.

Fixed participant label displays.

Fixed some errors on closing the patient conference room.

* Committing build artifacts

* Lazy load service classes

* Fix add dialog screen

patient values were not being populated and double buttons shown when
its a brand new third party invitation

* Refactoring work for mobile display

* Refactor twigs for easier debug/iterations

Need to make some major iteration changes for mobile support so I
refactored the twig so I can iterate quickly on the mobile changes I
want to try out.

* Telehealth major UX update to support mobile

Changed up the user interface to support mobile better.  Moved the
participant list to be an overlay that can be expanded and contracted.

Made the video control bar icons more responsive, changed them to use a
light on dark contrast.

Refactored a lot of twig files to better support testing.

Made it so the video controls hide on inactivity and show up on mouse
movement or on clicking the main screen on the video.

* Fix conference minimize screen.

* Telehealth invite links, refactor services

Refactored some of the Room controller code into a
ParticipantListService, FormattedPatientService, and
TeleHealthProvisioningService so I could test the patient invitation
code in isolation.

Pulled out the invite patient modal so we can refactor that.

Removed the old telehealth.js file since its been abstracted now into
several smaller classes.

Added a dependency injection container to the Bootstrap class so we can
better handle lazy loading and DI for the telehealth.  Right now its
just a hashmap array, but in the future perhaps I use the Symfony DI
container.

* PSR fixes, telehealth invitation event hooks.

Fixed the PSR issues.

Added a TelehealthNotificationSendEvent class event that other modules
can listen to and hook into when a notification event is being sent.

This allows event listeners to change up the recipients, change up the
message or do additional notification transports.  For example the
notification could be sent via text message as well for the invitation.

* Committing telehealth compiled assets

* Add patient dialog fixes, participant list bug fix

Had a bug where if the patient is in the session and the provider adds
another patient to the call, the third party patient can't join until
the patient leaves the call and joins again.  This happened because the
patient was not receiving the updated participant list.  Now everytime
there is a session update (every 5 seconds) it sends down a basic list of the
participants in the call. If the participants are different than the
local client has, the local client hits the server to get the full
participant details.  This makes it so the third party can now join the
call to the patient when they join the session.  Took a while to find
and fix this bug.

Changed up the patient dialog so it updates the patient list when a
patient succesfully is added.

* Committing build assets

* Change screensharing to single browser request

Made the screensharing api to be a single browser request that will be
shared across the other callers once the comlink bugs have been
resolved.

Removed the old cvb.min.js file that is not being used anymore.

* Escaping and urlencoding security fixes

* Fix xlt bug and invitation urls

invitation urls do not work in email clients when using attr_url.

Fixed mispelled xlt escaping.

* Access denied exception better display screen

Made it so we display a session expired or not found screen when its an
access denied exception to avoid revealing any details about the
session.

* Feature detected screenshare to hide on mobile.

Mobile devices don't support screensharing so we feature detect it to
hide on the mobile device.

* Renamed pc_eid component for consistency

* Hide launch video icon on pending patient appts.

Pending appointments can't be launched so we hide the appointment on
them.

* ACL check and pending appt session launches

Instead of breaking and rejecting an appointment launch, we set a
pending appointment to the default empty status if a provider/user
launches the appointment.

I also added ACL checks on the set_current_appt_encounter so that
patients can't change their own appointments to remove the pending
status.  Now only users with calendar write access can launch the
telehealth session.

* Updated Comlink api with screensharing changes.

This version shows only a single launch window when someone shares the
screen.

There continues to be an outstanding bug however when the screenshare
ends that only ends the screensharing for one session.

* Updated Comlink api with screensharing changes.

This version shows only a single launch window when someone shares the
screen instead of the double screenshare when there is a third party.

* Committing bundled versions

* Minimized session placement feature

Implemented a default placement location for the minimized telehealth
session during use.

Made it so that minimizing the session and dragging it to another area
and then expanding it will remember where the session was last dragged
to.

Added a method to the drag/resize utility script to be able to set the
intial default location for a drag/drop item.

* Fix email search, rename twig file

Changed thirdparty twig file to be patient-participant since it applies
to both thirdparty and the original patient now.

Fixed the email search by urlencoding the component.  Also if an email
address is not present it displays an error in the search preventing the
patient from being added.

* Fixed appointment launch button

If an appointment is expired, the appointment launch button still
showed.  We now display an error message if the appointment is expired.

* Fix launch bug where incorrect session was grabbed

Fixed a bug where a telehealth appt for the same patient on the same day
would often come back with the wrong session when launched.  The session
was being grabbed by the encounter which has a m:1 relationship to
telehealth sessions.  Fixed it so the session now launches from the
appointment relationship which has a 1:1 relationship.

* Fixed two session close bugs.

Fixed where closing the session would allow the patient/third party to
briefly immediately rejoin the session even though no host is present.

Fixed the issue where if a provider leaves the session and rejoins, if
the patient / third party rejoin they would not see each other in the
session.  Had to fix the slot cleanup to work properly when the session
closes.

* Fixed calendar launch button to handle correct dates

* Fix telehealth session launch w/ patient change

If the patient was changed for the appointment after launching a telehealth session
it would allow the provider to launch the appointment but the patient
could never join due to the mismatched pids.  Fixed that in this commit.

* Email validation fixes

Made it so additional correct email addresses work as well as local
unicode addresses.

Added a date selector to the invite patient and implemented the email
validation.

* Validation errors, Email validation change

Made it so that detailed validation errors show up for the patient on
the patient invitation dialog for telehealth.

Also changed the email validation to use filter_var and support local
unicode addresses.

* Fhir webroot fix, disable action btns

During a save or search on the add patient dialog we disable the save
buttons.

Also made it so the fhir url will work if OpenEMR is installed inside a
webroot.

* Fix style errors.

* Removed debug code and old TODOs

* Style fixes, refactored var for conference room

* Committing compiled assets

* Add copyright notices, fix up todos

* Fix copy invitation link,session position optional

The copy invitation was broken when we switched from pure html rendering
to js rendering.

Also made the session position config optional.

* Committing compiled assets

* Show appointment notes on telehealth screen.

* Only send telehealth email if notifications setup.

Added a method to the MyMailer class that checks if the SMTP settings
are configured.

I utilize this method in the telehealth module to make sure we only send
the email if the SMTP settings are actually setup correctly.

* Fix escaping issues for url and twig.

Made it so the url escaping on the invitation emails is properly escaped
for input parameters.

Also fixed some other minor escaping issues.

* Skip showing error message for index-portal access

Since we are sending users directly to the index-portal page to launch
their telehealth session we don't want to display this as an error.

* Remove warning for invalid global in smtp mailer

* Fix styles

* Fix audio issue.

Audio microphone was having issues.

* Fix join button color.

Change the join button color to be more prominent.

* Release 2.0 release

Updated changelog, readme with documentation instructions and info
version number.

* Added docs link and UX for telehealth

Added a link to the user guide and documentation as well as broke out
tabs for the support and the setup pieces.

* Fix mobile control bars not showing up

Made it so the mobile control video bar shows up on devices.  Had a
problem where the viewport unit (98vh) was not including the browser
search bar at the top.  Added both a javascript and css solution to the
problem.

* Fix empty line css failure.
84 files changed:
interface/modules/custom_modules/oe-module-comlink-telehealth/CHANGELOG.md
interface/modules/custom_modules/oe-module-comlink-telehealth/Readme.md
interface/modules/custom_modules/oe-module-comlink-telehealth/info.txt
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/css/telehealth.css
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/cvb.min.js [deleted file]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/dist/telehealth.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/dist/telehealth.min.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/dist/telehealth.min.js.LICENSE.txt [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/package-lock.json [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/package.json [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/add-patient-dialog.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/at-slot.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/caller-slot.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/conference-room.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/configure-session-call-dialog.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/confirm-session-close-dialog.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/cvb.min.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/local-caller-slot.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/minimized-conference-room.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/patient-conference-room.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/presentation-screen.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/registration-checker.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/telehealth-bridge.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/telehealth.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/video-bar-button.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/src/video-bar.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/telehealth-calendar.js
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/telehealth-patient.js
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/telehealth.js [deleted file]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/webpack-dev.config.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/assets/js/webpack.config.js [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/public/index-portal.php
interface/modules/custom_modules/oe-module-comlink-telehealth/sql/table.sql
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Bootstrap.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Controller/Admin/TeleHealthPatientAdminController.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Controller/TeleHealthCalendarController.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Controller/TeleHealthFrontendSettingsController.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Controller/TeleHealthPatientPortalController.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Controller/TeleHealthVideoRegistrationController.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Controller/TeleconferenceRoomController.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Events/TelehealthNotificationSendEvent.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Exception/TelehealthProvisioningServiceRequestException.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Exception/TelehealthValidationException.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Models/NotificationSendAddress.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Repository/TeleHealthSessionRepository.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Repository/TeleHealthUserRepository.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Services/FormattedPatientService.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Services/ParticipantListService.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Services/TeleHealthParticipantInvitationMailerService.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Services/TeleHealthProvisioningService.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Services/TeleHealthRemoteRegistrationService.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/TelehealthGlobalConfig.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Util/CalendarUtils.php
interface/modules/custom_modules/oe-module-comlink-telehealth/src/Validators/TelehealthPatientValidator.php [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/conference-room.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/conference-room/conference-room-main-layout.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/conference-room/modal-invite-patient.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/conference-room/patient-participant-row.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/conference-room/room-participant-container.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/emails/telehealth-invitation-existing.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/emails/telehealth-invitation-existing.text.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/emails/telehealth-invitation-new.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/emails/telehealth-invitation-new.text.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/local-participant-container.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/patient-portal.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/portal/thirdparty.html.twig [new file with mode: 0644]
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/telehealth-frontend-settings.js.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/video-control-bar.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/waiting-room-patient.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/waiting-room-provider.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/comlink/waiting-room.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/emails/partials/patient/email-message-fhir-access.html.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/emails/partials/patient/email-message-fhir-access.text.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/patient/partials/registration-code.html.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/templates/portal/appointment-item.html.twig
interface/modules/custom_modules/oe-module-comlink-telehealth/welcome.php
library/classes/postmaster.php
library/js/utility.js
portal/verify_session.php
src/Common/Utils/ValidationUtils.php [new file with mode: 0644]
src/Services/AppointmentService.php
src/Services/PatientAccessOnsiteService.php
src/Validators/PatientValidator.php
tests/Tests/Unit/Common/Utils/ValidationUtilsTest.php [new file with mode: 0644]