Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Info
titleIn Progress

This is a working document. If you are looking for documentation about the OpenLMIS-UI, refer to docs.openlmis.org.

No information on this page should be considered final or correct.

Table of Contents

UI Application Architecture

NOTE: In the OpenLMIS-UI development, we have never had a formal architecture — rather we just pointed the ui.router and said "URL Driven". We are well past the point where we need a formal and documented architeture because (1) we have non-DRY code (2) patterns are not shared well across developers (3) architecture makes maintenance easier.

This is a working document — please comment, add, and change.

UI Overview

The OpenLMIS-UI is a progressive web application that is URL Driven. Our application architecture stresses modular Javascript and DRY HTML markup, so implementers can customize logic and workflows to meet their needs. An extendable codebase is a maintainable codebase.

We aim to support "the last mile" which means we do our best to:

  • OfflineFirst
  • Minimize HTTP Requests
  • Display meaningful application state

That said, these are goals and not mandates — we all have deadlines and do our best to support the communities that use OpenLMIS — get people the tools they need first, and make it better second.

Build Process

→ See the current build process documentation

HTML & CSS

→ Keep it simple, semantic, and shallow — fancy things are hard, and avoid complex designs → I'll add more here later

Javascript Application Architecture

Modules

In the OpenLMIS-UI we consider a module a directory that contains a single feature. There are three buckets of modules:

  • Model Modules which bring data into the application, store application state, and/or process data
    • I expect this bucket to be most of our application code
  • View Modules which are CSS styles, UI Components, and other pieces that make views simpler
  • Controller Modules which are controllers, HTML, and configuration to make a screen show up
    • These should be skinny and ideally look very simple to an implementer

Note: I wanted to call these things Data, View, and Pretty modules - but making up new terms is usually a bad idea

No module should ever fit in more than one of these buckets. 

Moderator: The routeProvider

Since the OpenLMIS-UI is URL-Driven, every screen and modal should be directly accessible by a URL. AngularJS and ui.router provide a great start for an application, but we are hitting the limits of what we can do with this initial framework without it turning into a writing nightmare that is hard to document and test.

The routeProvider is a facade pattern that will essentially wrap ui-router. This will help us divide layout issues from application logic, and provides logical places for extension.

Routes will be created with configuration objects with "strong defaults", not specialized methods, so implementers can drop or change functionality without needing to worry about breaking the application architecture.

We are using the name "routeProvider" because other libraries are nice enough to leave us this namespace — since all application logic should point here, it should have the most obvious name.

NOTE: Using ui.router and existing conventions is fine for now, we will be moving towards a routeProvider based infrastructure and clean up existing ui.router code ... eventually.

Events: eventService

Events are great for decoupling modules and providing extension points. AngularJS has an event system built in — but we have different patterns of using it and are not even using all of the features provided.

We will be adding an eventService which will only pass events at the top-level of our application architecture. Technically, this means we are only exposing $rootScope.$emit and $rootScope.$on — with slightly different names. Only model modules should be aware of the event service.

NOTE: UI Components should also use events, but since they rely on the AngularJS architecture, they will use $rootScope for communication. I'll try to add specifics for UI Components when we revise the conventions and documentation for them.

Main Application Data Services

These are the primary services that are used through the OpenLMIS-UI application. The services could be put behind the routeProvider facade, but since they are primary, its best if other modules depend on them directly.

  • authorizationService keeps track of the current user, and what rights/permissions that user has
  • messageService handles internationalizing strings. Behind this service are other services that maintain the current state and other internationaliztion preferences
  • offlineService keeps track of if the OpenLMIS-UI is currently offline, and will emit events as that state changes
  • openlmisUrlService keeps track of where the OpenLMIS services live.
    • I'd like feedback if this should be extended so it actually does HTTP requests, which would make some markup cleaner
  • loadingService keeps track of if the UI is loading data, so url state transitions can be orchestrated
    • This could be hidden inside the routeProvider — I'd like feedback on this


HTML Conventions: 2017-09-21

QuestionResolutionJIRA Ticket



HTML Markup Guidelines

Less markup is better markup, and semantic markup is the best.

...