-
Notifications
You must be signed in to change notification settings - Fork 252
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
(feat) O3-4363 - Add Visit context header to Order, Visit Note, and F… #2222
base: main
Are you sure you want to change the base?
Conversation
import styles from './start-visit-dialog.scss'; | ||
|
||
interface StartVisitDialogProps { | ||
patientUuid: string; | ||
closeModal: () => void; | ||
visitType: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing this as it doesn't seem to be used. This was brought up before:
https://github.com/openmrs/openmrs-esm-patient-chart/pull/640/files#diff-7e621046e4d227da306880633891cb2d35e4f168f95967ff73f00aa973bc6d06R10
Size Change: -267 kB (-1.62%) Total Size: 16.2 MB
ℹ️ View Unchanged
|
Hi @chibongho! Thanks for your work on this. I have a suggestion to re-model the entire system. Could we integrate the header context into the workspace system itself? When calling Alternatively, we could create an extension slot based on the property mentioned above (rendered by the workspace system) and attach the RDE visit context extension (from the patient chart). However, I believe it would be better to handle all RDE-related tasks from a separate app (@openmrs/esm-patient-rde-app), as these changes would not only affect the patient chart but also the ward patient workspace. In summary, we have two main points to consider: rendering the extension slot (workspace renderer) and the extension (from the patient chart or the patient RDE app, whichever is more suitable). Please let me know your thoughts on this. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am seeing a lot of duplicated work which can be done in the useVisit
hook.
Alongside, we should work on the workspace system to render an extension slot if we pass the slot names. Hence we won't have to duplicate our effort in every patient workspace and directly use the workspace system to do out work.
A sample example will be:
import {launchWorkspace} from '@openmrs/esm-framework';
launchPatientWorkspace = (workspaceName, additionalProps) => launchPatientWorkspace(workspaceName, {...additionalProps, renderExtensionSlots: ['visit-context-header-slot']}
return ( | ||
<> | ||
{isRdeEnabled && <ExtensionSlot name="visit-context-header-slot" state={{ patientUuid }} />} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I am talking about, why should we go manually into every patient chart workspace and render the extension slot, when we can use the workspace system to do the same?
return ( | ||
<div className={styles.container}> | ||
{isRdeEnabled && <ExtensionSlot name="visit-context-header-slot" state={{ patientUuid }} />} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
type OpenmrsResource, | ||
type Privilege, | ||
type Visit, | ||
} from '@openmrs/esm-framework'; | ||
import useSWR, { mutate } from 'swr'; | ||
import { type ChartConfig } from '../../config-schema'; | ||
|
||
export function useInfiniteVisits(patientUuid: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why re-working on what is already implemented in the useVisit
hook
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useVisit()
makes a request to fetch active visit(s) for the patient, and another request to fetch the visit currently in the visit context. This function is different; its using useSWRInfinite()
to get all the visits of the patient.
import { getVisitStore, useStoreWithActions, type Visit } from '@openmrs/esm-framework'; | ||
|
||
export function useVisitContextStore() { | ||
return useStoreWithActions(getVisitStore(), { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be moved into the react utils? Also, isn't this indirectly useVisit
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not useVisit()
in that it doesn't make requests to fetch visits, but it's not a bad idea to merge them into the same hook.
And yes, it should be moved to react-utils. I plan to do it in a separate PR. I also have a TODO in VisitContextHeader
about moving a useEffect
hook into useVisit
(in react-utils) as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’ve noticed a lot of repetitive work that could be handled using the useVisit
hook. Additionally, we should improve the workspace system to render an extension slot when we provide the slot names. This way, we won’t have to duplicate our efforts in each patient workspace and can directly use the workspace system to accomplish our tasks.
Here’s a sample example:
import {launchWorkspace} from '@openmrs/esm-framework';
launchPatientWorkspace = (workspaceName, additionalProps) => launchPatientWorkspace(workspaceName, {...additionalProps, renderExtensionSlots: ['visit-context-header-slot']}
Not sure what's duplicated. Can you elaborate?
It only takes 1 extra of of code to render a slot, across 3 different patient chart workspaces. Adding this feature will add more complexity. It also assumes the slot will be placed at the top, which is less flexible than just adding an slot within the workspace wherever we want it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chibongho , generally looks good, though admittedly this was a lot to review and not something I'm able to dive super deeply into.
I asked some questions, but mainly to better understand naming conventions.
At the end of the day, it's probably best to get this in sooner rather than later and start testing/playing around with it, but it would be to good to confirm with @ibacher and @denniskigen that there aren'y any releases imminent, because this definitely risks introducing instabiliity.
@@ -10,6 +10,9 @@ interface RetrospectiveVisitLabelProps { | |||
|
|||
const RetrospectiveVisitLabel: React.FC<RetrospectiveVisitLabelProps> = ({ currentVisit }) => { | |||
const { t } = useTranslation(); | |||
if (!currentVisit) { | |||
return <></>; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only render the retrospective entry toggle if it's not the current visit? (I'm probably just not understanding this correctly and it's legacy functionality anyway?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, current visit means the visit in the current context, not the active visit?
const { t } = useTranslation(); | ||
const { currentVisit, isLoading } = useVisit(patientUuid); | ||
const { manuallySetVisitUuid, setVisitContext } = useVisitContextStore(); | ||
const isActiveVisit = !Boolean(currentVisit && currentVisit.stopDatetime); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It occurs to me that there's likely to be confusion where people think current visit = active visit (see my confusion above) though a better name hasn't come to mind for me yet.
// This hook is needed because the `useVisit` hook sometimes | ||
// returns a currentVisit that isn't actually the one in the visit context. | ||
// TODO: move this into the useVisit hook | ||
useEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay... :) Hopefully this will make more sense to me when we get to the the visit context hook... "manuallySetVisit" isn't super intuitive...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I still don't understand after reviewing the code... what is the case when a currentVisit isn't actually on the one in the visit context?
return ( | ||
<> | ||
{isActive | ||
? t('currentActiveVisit', 'Current active visit') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is end-user-facing, but this does continue to propagate the confusion about what "current' means.
return useStoreWithActions(getVisitStore(), { | ||
setVisitContext(_, newSelectedVisit: Visit) { | ||
return { | ||
manuallySetVisitUuid: newSelectedVisit.uuid, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain how this is different from other ways the visit context visit is set?
…orms workspaces
Requirements
Summary
This PR adds RDE features: a new visit context header to the patient chart workspaces (order / visit note / clinical forms), and a new visit switcher modal accessible from the visit context header.
The concept of a "Visit Context" when viewing a patient chart is not new; previous RDE work has that when the
rde
feature flag is turned on). Screenshots from before this change:Instead of rendering in the top nav, the visit context header is rendered at the top of the workspace with this change, See the mockups here.
The new changes are behind the existing
rde
feature flag, so they should not be noticeable for most people.Notes:
encounterDatetime
), but it doesn't work. See: https://openmrs.atlassian.net/browse/O3-4420encounterDateTime
set to the visit's start time. However the order'sdateActivated
field is set tonow
. Is that expected?now
, and is tied to the active visit, instead of the past visit in the visit context.Screenshots
The visit context header in a workspace:
![image](https://private-user-images.githubusercontent.com/509602/408318828-33ef256b-18f4-470e-bbe9-18ecc567ce1e.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzNTU2ODIsIm5iZiI6MTczOTM1NTM4MiwicGF0aCI6Ii81MDk2MDIvNDA4MzE4ODI4LTMzZWYyNTZiLTE4ZjQtNDcwZS1iYmU5LTE4ZWNjNTY3Y2UxZS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjEyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxMlQxMDE2MjJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1jZmExYzIxODNhODZjZGFmNzU5NmQwZjQ1MGViZjQxNGM2OTMyMTJiODA5NTFlMWZiMzZiODA0NzRlNWVjMWExJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.LcPQuad-XDVqVaO_-HyK9dZgX6RLfrkCHPpWKPBudL0)
The modal that opens when clicking on "change" in the visit context header. The same modal also shows when the user tries to open the order / visit notes / forms workspace without a visit (active or past) in context.
![image](https://private-user-images.githubusercontent.com/509602/408318926-36ea4c10-2b4b-47de-a805-ee364e87f276.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzNTU2ODIsIm5iZiI6MTczOTM1NTM4MiwicGF0aCI6Ii81MDk2MDIvNDA4MzE4OTI2LTM2ZWE0YzEwLTJiNGItNDdkZS1hODA1LWVlMzY0ZTg3ZjI3Ni5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjEyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxMlQxMDE2MjJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1jODhhYTExNDY0MWMwNWU2ZTFkOWE3ZTAzZTZhMTg2ZDJiMDZkZThjNjNlODRjNzUyZDYxOGI0Y2YxODg1NWEyJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.11XlRoQ5Lu4hqsHkpDYHAt8IDhOTbiUaJ2ZeR1OilUE)
Related Issue
https://openmrs.atlassian.net/browse/O3-4363
Other