DRY and all these new ReactJS OWAs...

@darius any idea the difference between https://github.com/openmrs/openmrs-web-style-referenceapplication and https://github.com/openmrs/openmrs-contrib-uicommons

I am JS handicapped - any recommendations on how we can remove any duplication if any

web-style-referenceapplication is pure styling (scss/css) and has no components, whereas contrib-uicommons has AngularJS (1.x) specific components like header, breadcrumbs, etc. The goal was to make contrib-uicommons depend on web-style-referenceapplication.

I’d recommend to use web-style-referenceapplication when building react components.

1 Like

thank you @raff for the recommendation, I am wondering if there is any documentation for the web-style-referenceapplication ?

Is it needfull for your request ?

https://demo.openmrs.org/openmrs/uicommons/styleGuide.page

Sorry if this is a dumb question, but I’d love to hear from the Javascript gurus and learn if the state of Javascript today is such that we do really need to re-invent / re-write every component, every time we decide we want to leverage a new major framework.

Is it possible to take an existing investment in Angular components, and use them within React code (in an OWA or otherwise), or to take React components and to use them within existing Angular code? Is there some way we could write this header component, for example, such that we could maintain one version that is used across the application, regardless of whether a particular page is built with Angular or React?

A quick google search brings up libraries like react2angular and angular2react. Are there efforts like these that are worth investigating and pursuing?

After long experience investing in various Javascript and other UI frameworks for OpenMRS that are now being replaced, it would be great to know that investments today in React and Angular can build upon each other, and that they can work with whatever new great framework inevitably comes along to replace them soon.

Thoughts out there?

Thanks, Mike

1 Like

My recommendation is:

  • build two react libraries to be published to npm:
    1. openmrs-web-reactcomponents: contains lower-level components (autocomplete, formatted table, tabs); only build these components as-needed, i.e. don’t replicate the entire style guide
    2. openmrs-web-reactrefappcomponents: depends on (1) and the web-style-referenceapplication and it implements the higher-level shared code that’s more specific to the Reference Application look and feel, like the header
    • If it’s too much of a pain to separate this way, I can live with those being a single library.
  • keep in mind that we want to modify the style guide to be based on bootstrap 4’s CSS, and to make the design responsive. I’m not sure if there’s anything actionable about this for you now, but eventually it points to us refactoring openmrs-web-style-referenceapplication.

I’m not a JS guru, but I’ll try to answer this…

It’s possible to combine frameworks together in some interesting ways. e.g. Bahmni’s new forms engine is built in React but it’s included in the existing Angular 1.x UI using ngReact.

But our existing investment in Angular is in Angular 1.x, and things have moved beyond this now. Further, our real big investment is actually in an unholy mess of server-side gsp, Angular 1.x, with some knockout and underscore templates. Adding to this mix seems like a mistake to me.

While it’s true that every few years another better JS framework comes along and catches people’s attention, the reason it’s better tends to be that it takes a different approach and allows a new and different style of writing code. So, trying to mix this in with an older framework tends to negate these advantages. Also “every few years” is not actually that often, and as long as we’re only rewriting a bunch of stuff once per framework, it doesn’t bother me very much.

So, as long as we have this…

  • good REST endpoints that we continually improve
  • a single shared CSS library that’s independent of any particular JS framework
  • only one shared library for most things in Angular 1.x, only one for React, only one for Angular 2+, etc
  • one standard approach for things like i18n within each framework
  • a reference application that’s built around the idea that each “app” can be written in a different tech stack, but they can link seamlessly together (with the cost of having to do a page load if you move from a GSP screen to an Angular screen, to a React screen)

…then I think this is the best balance we can have between reusability and the ability to take advantage of new things.

(Ultimately, though, I believe that supporting new approaches without requiring every new dev who shows up to understand a bulky, non-standard, tech stack rich in “historical artifacts” means that new devs will be able to show up and be productive faster. And if this means that an Andela team can come along and built an order entry feature (in React) in few months, which we never actually got done in the old way, then that’s an argument for prioritizing the new ways.)

I agree with all what Darius pointed out.

One thing I would consider is building the header (including breadcrumbs) and the footer with plain jQuery, which is compatible with angular, react and other frameworks. That way we do not have to maintain these simple elements for every framework rather have them easily included with (almost) pure JS in every app. It would make it also much easier to overwrite these elements for a specific implementation to add branding or additional features like location selection for the whole system.

The project simply contains scss files, which are transpiled to css files (referenceapplication style guide) and resources (fonts/icons/images). I can release it to npm next week and add some info on how to import and use in any js project. It’s actually published at https://www.npmjs.com/package/@openmrs/style-referenceapplication already. If I have extra time, I’ll migrate openmrs-contrib-uicommons to use it, which should be straightforward.

2 Likes

I would even try to start with plain JS for simple things :slight_smile:

This is an interesting idea, but I fear these wouldn’t participate correctly with Angular scope or React state.

I think I’m okay with removing any state-affecting behavior from the header to mitigate this, e.g. we currently allow you to change the session location without reloading the page.

Can we use the callback functions(instead of building the actual plain jQuery functions) in the header for the events? then we can simply integrate those header click events from Angular or ReactJS.

I should further say: I think this is interesting, and I hope that someone pursues it at some point, but it takes us yet one step further away from actually building an app. So, I would recommend that the current Andela team working on the order entry app only go as far as making a reusable React library.

1 Like

fwiw, I’d started taking on the task of creating a reusable React header, I’ve got a discussion going about it here:

fyi, I created a new project in JIRA to start to tracking some of these issues and potential solutions, see this Talk post:

fyi, I created a “openmrs-contrib-reactcomponents” project in github and have begun to work on it:

Currently there is nothing in it except for a “Hello World” heading, but I plan to start building a reusable Ref App header by extracting some of the code int he Order Entry UI module.

Note that instead of creating two projects, “reactrefappcomponents” and “reactcomponents” I started with just a single project to keep things simple. (“reactrefappcomponents” is a bit of a mouthful as well). I put the header in a “refapp” subdirectory for now. I’ll continue to refactor as things get more complicated and I get a better sense of where things should live, but feel free to start weighing in now on structure… and feel free to start contributing as well!

Take care, Mark

1 Like

Nice work @mogoodrich. The current Andela team on OrderEntry OWA project have thinking along this line since we had to (re)implement the app header, patient dashboard and a couple of other components ourself. I (and hopefully, my other team members) will be on the look out for how we can help. Thanks

An architectural question with regard to OWAs - what is the scope:

  • Functional feature e.g., sysadmin, concept dictionary, order entry, cohort builder
  • Module: we are looking at them for Point of care
  • Screen - search widget?

What is the guidance with regard to scoping out how the OWAs grow

Thanks @larrystone! Feel free to start contributing to the reactcomponents project. And thanks for creating the tickets in RAUI project!

@ssmusoke are you how we want split things up between different OWAs? Good question… it seems like the are developing a model of OWA-per-functional feature. Instinctively, that seems about right to me, but interested in other ideas.

For reusable components, there’s a question of whether we should have a separate library per technology (React, Angular), which is the approach I’ve gone with my “reactcomponents” contrib, or whether it’s better to have everything in a shared “uicommons” contrib.

Take care, Mark

@mogoodrich I am Javascriptically challenged but I think its best to have owa reusable components in one project then have the react and angular components filed differently…

That way later when there is a new Vue.js need we just add a new folder… It also allows us to have a common folder for those that can be shared between frameworks, or probably a bridge that allows one to use any framework.

On splitting up the OWAs, I think feature wise is a good start, then we can learn as we move forward.

I think the theory would be we’d want to release a “openmrs-contrib-reactcomponents” package via npm and a “openmrs-contrib-angularcomponents” package via npm, and if that is the case, it would make sense for them to live in different repos. Interested in hearing others thoughts as well. It also looks like we may have a design call soon about this:

+1 to this.

It’s also fine to have an openmrs-contrib-jscommon (or whatever), but as a separate code repo, and the react and angular can import the latest version of this as part of their build process.