Patient Summary Widgets Sprint

Tomorrow, we’ll kick off a new sprint. We’ll be working on patient summary widgets for Reference Application. In 2 weeks we’ll implement 6 new widgets! @ssmusoke did a great job at documenting them all at https://wiki.openmrs.org/display/docs/Patient+Summary+Widget+Documentation

If you are keen on coding in Angular, learning some about the app framework and using OpenMRS REST API, do join us!

The sprint dashboard is at: https://issues.openmrs.org/secure/RapidBoard.jspa?rapidView=103&sprint=127

We’ll have @adamg and @tmarzeion working on the sprint thanks to @SolDevelo partnering with the Uganda project!

5 Likes

Cool!

I see you mentioned Angular, but the patient summary is still implemented in old-school UI Framework, and the requirements for the widgets are that they’re packaged as “fragments” in the UI Framework.

I hope we can plan for a future where (a, sooner) we move away from UI Framework for the patient summary, and (b, later) we move away from Angular 1.x.

Ideally you would actually write the code for these widgets in a plain html+javascript project (and maybe even configure it in such a way that you can test and iterate on the widgets purely based on mocked calls to OpenMRS’s REST API)

Then in the coreapps module (or wherever) we use something like npm install to fetch the javascript, and just have a thin GSP wrapper that takes care of exposing the functionality as a fragment.

In fact, trying to think ahead, I propose that we change the section configuration parameters a bit from what @ssmusoke wrote in the wiki page. We should plan for a single “dashboard config json” which contains an array of widget configs. Each widget config should have a widgetUid (this replaces provider and fragmentId; I guess its value would be like “coreapps.latestObsForConceptList”). We don’t need order because the widgets are already in order in the array. We don’t need extensionId because that’s implied by the dashboard config json file.

If we go this way, the entire dashboard config needs to be somewhere directly admin-editable (I prefer the Bahmni approach of a config folder for the implementation, that can also be a source-controlled repo, but we could also store it in the DB). I.e. for configuring the dashboard we’d move away from the model where “various modules attach to the extension point, and the framework figures out the ordering” to a model where “user configures it directly”.

[This is not where I expected to end up when I started replying to the post. I was actually going to talk about planning for being able to support angular2 or react widgets in the future, and maybe planning for storing data in a shared redux store that multiple widgets could render from…and I haven’t even gotten there yet. :slight_smile: ]

@darius interesting:

  1. Can you provide a link to any documentation on the approach in Bahmni

  2. What additions to the AppFramework are needed to make this approach work?

  3. How would an implementation add new widgets to an existing dashboard config without having to create a new one. Or is this a requirement? What has been the experience with Bahmni?

Darius, Angular 1.x is globally available on the dashboard page so we can use it in fragments. I wanted to have almost no logic in a fragment controller and reuse it with the app template for different widgets written in Angular + REST. See RA-1301.

I wonder how in the “one dashboard config” approach other modules would contribute widgets to the dashboard. Is the idea that the single fragment with a thin GSP wrapper would have to take care of finding widgets defined in modules? Isn’t it what the app framework already does? To me it seems like doing the same thing as having individual apps, but a layer higher. Or else we could actually define multiple apps in one json and call it a dashboard config json, but I understand it’s not your ultimate goal here.

I’m in favor of doing more with plain html+js instead of using our proprietary App and UI framework, but it needs to be well thought out, if we want to achieve the same plug-ability. I don’t think we should be doing that in this sprint. It should start from a spike on finding the best way to approach that, which I am very interested in doing!

That said, if you already have a solution in your head to make it work then we can totally delay the sprint until we have the new framework in place!

@ssmusoke, also do I recall correctly that you would like to be able to configure some of the widgets to be displayed in other places in addition to the patient dashboard?

The approach used for the widgets needs to support the following:

  1. Ease of configuration by implementors (code, GUI or otherwise) - since each widget actually requires implementation specific information, concepts etc to work

  2. Ease of extension by developers - these are the first widgets that I hope will spawn more usable dashboards and even more complex widgets with time

  3. Ability to place widgets in different locations and dashboards - currently we have only Clinician Facing and Registration Summary dashboards. It would be interesting to see:

  • Program specific dashboards - at least with UgandaEMR we are adding MCH and Tuberculosis programs
  • Info tips leveraging widgets (say as a form is being entered with a more Info tooltip for a specific area)

I know this does not directly answer the questions, but I am hoping that it provides additional context.

2 Likes

You should not delay. I won’t have much time to think about this in the next month; I’m trying to share a blast of thoughts right now that hopefully can guide some of the choices you all make. Let me try to summarize some key points.

We have two goals here: reusable widgets, and user-configurable dashboard(s).

Reusable widgets

  • Our current technology stack (uiframework+gsp + angular 1.x) has an expiration date; we know we’ll need to move to something new, but we haven’t yet decided what. And we’re not gong to decide right now.
  • The future technology stack will surely involve modern HTML, CSS, JS, REST, and a component approach.
  • The configuration interface for each new widget should be “plain old json” defined by the domain of “a widget you can embed in a dashboard” and not be specific to uiframework.
  • Someday we’ll rewrite the JS behind the widget (so don’t worry about this), but hopefully we can preserve the HTML+CSS and any new REST calls (so, get these right)

User-configurable dashboard(s):

App Framework, and its Apps with Extensions is a very helpful generic tool, but Bahmni has a much better specific solution to configurable dashboards.

(Actually I think it’s a better philosophical approach for OpenMRS, since it’s more approachable by implementers. I mention this a bit in this post: Managing App Definitions and Extensions in OpenMRS - #9 by darius)

Basically, instead of the model where you add a bunch of extensions that attach to the “patientDashboard.firstColumnFragments” extension point, the model is to write a dashboard config file. Here is their default version of dashboard.json.

The benefit is that it’s clear how a typical admin configures their dashboard (just edit the file, to change labels, or add widgets) and how to handle multiple dashboards (just have two files).

You’d need to write glue code that takes this json and uses uiframework to actually render the dashboard and include the widgets, but eventually we’d be able to just rewrite the glue code for a different tech stack, but the dashboard configs could remain exactly the same.

I would envision something like:

{ sections: [
    {
        title: "String or MESSAGE_KEY",
        icon: "stethescope",
        widget: "coreapps.latestObsForConceptList",
        widgetConfig: {
            concepts: [ "CIEL:5089", "CIEL:5090" ],
            maxAge: "1y"
        }
    }
    // and more widgets here...
]}

The glue code would take care of applying decoration, and knowing that “coreapps.latestObsForConceptList” means ui.includeFragment("coreapps", "latestObsForConceptList").

One follow-up comment… These are actually two independent ideas:

  1. Fit for purpose format for defining a dashboard from reusable widgets, without directly tying to the uiframework
  2. storing that dashboard config in a configuration file (and eventually supporting multiple)

We should do 1 now for sure, whether or not we do 2.

-Darius (by phone)

Folks,

I’m a seasoned web developer with an interest in leveraging the full capability of HTML5 and Javascript to implement advanced user interfaces for web-based applications. I’m new to OpenMRS, but I saw this thread and was immediately interested in this dialogue. I’m a proponent of plain of json and am working on modular GUI architectures that launch the entire application with a single page load.

My goals for the architecture include loadable modules that can be developed independently and verified in a test harness, so that they can be linked into the overall UI by simply granting permission to access the module.

Other goals include field level locking and live update of changes, in order to allow multiple users to access and update the same record at the same time, and to be able to see other people’s changes in realtime. This requires a concurrency manager to sit between the UI and the database.

I like the idea of “dashboard configs”. Ideally, I’d like to see them implemented as Javascript objects that can be manipulated in real-time, and generate or update the current page view using tools like D3.

I am working on gaining the financial support of a regional health system in order to advance development efforts for OpenMRS.

I would love to see OpenMRS in action. I’ve heard there is an installation somewhere in the United States, perhaps Maryland. Given time for planning and preparation, I hope to have the opportunity to meet some developers and discuss some ideas in person.

Cheers,

Jim

The work is done! Thanks to @SolDevelo for sponsoring @adamg and @tmarzeion to work on the sprint! Thanks to @ssmusoke and @darius for working on the specs!

We were able to implement all the widgets. Please see updated docs at https://wiki.openmrs.org/display/docs/Patient+Summary+Widget+Documentation

You can play around with the new widgets at http://qa-refapp.openmrs.org/openmrs/coreapps/clinicianfacing/patient.page?patientId=d9bdd3bc-3e43-49e5-93db-cccf9982593c

If you want to use them locally you need to make sure you update webservices.rest, coreapps and data integrity modules to the latest SNAPSHOT versions (soon to be released).

We put in place a new way for adding patient widgets, which doesn’t require writing any gsps! All widgets are implemented as pure AngularJS 1.x components. Eventually, we would like to move them out of coreapps code into a js library built with npm.

You can add and customize widgets by adding app definitions. They can be included in any custom patient dashboard by using a selected extension point. At some point we will want to migrate away from using an app definition for each widget to a single json config for the whole patient dashboard as discussed on this thread.

@jcapp, welcome! Thanks for sharing your point of view. Let us know, if we can assist you in any way going forward.

3 Likes

@raff, thank you! Can I get access to qa-refapp.openmrs.org to see the new widgets?

Hello @jcapp, You can log-in into http://qa-refapp.openmrs.org by using following credentials: Login: admin Password: Admin123

Special thanks again to @SolDevelo for getting my dreams of widgets in play … This is an excellent foundation by @adamg and @tmarzeion for the excellent job …

1 Like

Very fruitful sprint! Thanks @raff, @ssmusoke, @adamg, @tmarzeion and @SolDevelo for making this happen. :tropical_drink:

@ssmusoke if you could organise the remaining reference application 2.6 work and hand it over to such capable hands, we would have the release in the next month. :smile:

2 Likes

I’m trying to reproduce the version currently running on qa-refapp.openmrs.org. Can anyone tell me which branches to checkout for both openmrs-core and the reference app?

Thanks!

For openmrs-core, use this: https://github.com/openmrs/openmrs-core/tree/2.0.x You can get the reference application modules from here: https://ci.openmrs.org/browse/REFAPP-OMODDISTRO-5883/artifact

Thank you!

@raff I would like to be able to add age and location based filtering for the widgets similar to Displaying HTML entry forms based on login session in reference application

I wanted advice on how to get that implemented as I am JS handicapped - this is before I create a JIRA ticket.

I’m not quite sure I understand. Do you want to show/hide widgets based on a login location? Do you mean patient’s age?

@raff exactly - as there are some widgets we need to configure which are applicable to infants not adults, and vice versa. The location is also important as there is some information for an Mother to Child Clinic location which is not applicable in the general OPD or HIV clinic…

Okay. I see @darius implemented that feature for extensions. Do I read it right that the logic for extensions was not implemented in javascript rather it was made a part of an extension config through the require field and handled by appframework? Would it make sense to do the same for an app definition i.e. add the require field?

Actually, @ssmusoke, did you try adding

"require": "sessionLocation.uuid=='6351fcf4-e311-4a19-90f9-35667d99a8af'"

e.g. at line https://github.com/openmrs/openmrs-module-coreapps/blob/master/omod/src/main/resources/apps/dashboardWidgets_app.json#L18 ?