Difference between revisions of "Uncharted"

From mn/ifi/inf5750
Jump to: navigation, search
(Documented learning during project)
(Add Alternative release info)
 
(18 intermediate revisions by 2 users not shown)
Line 15: Line 15:
  
 
== Summary of requirements ==
 
== Summary of requirements ==
Architecture/ components:
+
A "one-page webapp" to view and manage health facilities
* React
+
(OrgUnits) in the DHIS2 system.
* Google Maps or LeafletJS
 
* Material UI
 
  
React (main) components:
+
=== Main functionality / Use-cases ===
* App
 
* Search/ Filter box
 
* Breadcrumbs
 
* Info box/ List box
 
* Map
 
* Page header
 
  
Use cases:
+
==== Search / View ====
* User enters facility name in search box. System zooms map to area level, displays marker on map and info box with facility data.
+
* User can enter facility name in search box. System zooms map to area level, displays marker on map and info box with facility data.
* User enters area name in search box. System zooms to area, displays lower level items as markers/ polygons and info box with area information and list of underlying items (facilities or sub-areas).
+
* User can enter area name in search box. System zooms to area, displays lower level items as markers/polygons and info box with area information and list of underlying items (facilities or sub-areas).
* User enters search string that does not match anything in database. System displays info box that no result was found. (Edge case: User searches for an actual facility but it does not match the chosen filter settings. System should inform about that.)
+
* If there are no matching OrgUnits, the system notifies the user about this.
* User can navigate upwards in the hierarchy using the breadcrumbs. Info box shows related data on the current level.
+
* User can navigate upwards in the hierarchy using the breadcrumbs.  
* User taps/clicks on the map, and the next level of organisational units within the “tapped” area is shown to the user.
+
The list of OrgUnits that match the query are displayed in a list (in addition to being displayed on the map).
* User clicks “hamburger” menu in search box. System displays box with search filter options.
+
 
* Search results (filtered) show up on the map as markers, and also in the Info box (name, …?)
+
In addition to the basic free-text search, there is an option to further narrow the query by specifying Groups and/or Programs that an OrgUnit must have.
* User can click a button to find nearest facility (to user location), based on current filters.
+
 
* User can switch to edit mode (clicks “add unit” in menu), then when clicking on the map the Info box changes to editor mode so that User can add a new facility.
+
==== Add / Edit ====
* User can click “Edit” in the Info box to edit the currently selected Facility. Info box turns into and editor mode.
+
* User can click “Edit” in the Info box to edit the currently selected Facility. Info box turns into editor mode.
 +
* User can add a new OrgUnit under the currently selected Level 3 OrgUnit.
 +
 
 +
== Architecture and implementation ==
 +
The system will consist of ''component''s which are responsible for a well-defined functionality.
 +
 
 +
=== Components ===
 +
 
 +
==== App ====
 +
This is the root component. Contains all other components, and controls them via ''props''.
 +
 
 +
Responsible for querying the API, maintaining a list of OrgUnits and other data, and providing these to the other components.
 +
 
 +
==== Filtering ====
 +
Responsible for providing the search UI and constructing the query details (executed by the App component).
 +
 
 +
Contains an always visible toolbar with the free-text input.
 +
 
 +
Can be expanded to show advanced controls: Group multi-selector, Program multi-selector.
 +
 
 +
==== ListBox ====
 +
Responsible for displaying the search results in a list. OrgUnits in the list can be selected, which notifies the App component.
 +
 
 +
Can be collapsed to a toolbar to improve visibility of the map.
 +
 
 +
==== InfoBox ====
 +
Responsible for displaying the details of an OrgUnit.
 +
 
 +
Provides UI to switch to editing mode for the selected OrgUnit.
 +
 
 +
==== InfoBoxEditable ====
 +
Responsible for editing the details of an OrgUnit and for filling out the details of a new OrgUnit.
 +
 
 +
==== MapController and Map ====
 +
Two tightly connected components, responsible for displaying and manipulating the map and the OrgUnits on it.
 +
 
 +
==== Breadcrumbs ====
 +
Responsible for displaying the ancestors of the selected OrgUnit.
 +
 
 +
==== Header ====
 +
An app-wide toolbar for displaying a title and function buttons.
 +
 
 +
=== Technologies ===
 +
* '''React:''' [https://facebook.github.io/react/ React] is used as the main framework for the application.
 +
* '''LeafletJS:''' [http://leafletjs.com/ Leaflet] is used as the map engine, for displaying the map, showing and grouping markers.
 +
* '''Material-UI:''' [http://material-ui.com/ Material-UI] is responsible for consistently styled components and widgets.
 +
* '''Webpack:''' [https://webpack.github.io/ Webpack] is the packaging framework, that creates a single file of all our scripts.
 +
* '''Babel:''' [https://babeljs.io/ Babel] is responsible for transpiling all the advanced JavaScript features that most browsers don't support yet.
 +
 
 +
==== Alternative release ====
 +
We tried a new approach to querying the API: incremental loading of results. This means, that two queries are issued simultaneously:
 +
# For Level 2 and Level 3 units, that match the free-text criteria (ignoring other criteria)
 +
# For Level 4 units, using all criteria, requesting only the first ''N'' results (pagination). Then if there are more pages, those are subsequently fetched.
 +
Upon each query response, the results are ''added'' to the global list, which results in a smoother user experience by showing results as early as possible.
 +
 
 +
Due to a bug(?) in earlier DHIS2 servers (see [https://piazza.com/class/isfwaws3kkj5js?cid=223 Piazza discussion]), adding a filter on Programs to an OrgUnit query results in returning ''all'' OrgUnits stored in the system. This breaks this new approach to querying, so we created an alternative release, while keeping the main release stable on all servers. See ''Repository and downloads'' section.
  
 
== Time schedule ==
 
== Time schedule ==
Line 62: Line 109:
 
|}
 
|}
  
== Dividing tasks within the group ==
+
== Dividing tasks within the group and organizing work ==
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 78: Line 125:
 
|}
 
|}
  
Each member works on their own branch. Conflicts are discussed and resolved at weekly meetings.
+
In the beginning, each member works on their own branch. Conflicts are discussed and resolved at weekly meetings.
 +
 
 +
Later, we switch to issue-based branches and create pull-requests which are reviewed and merged into the master branch.
  
 
==Screenshots and screen flows ==
 
==Screenshots and screen flows ==
  
Mockups of the app: https://github.com/tobiasgm/inf5750-uncharted/tree/master/wireframes (private)
+
Mockups of the app from the planning stage can be found here: https://github.com/tobiasgm/inf5750-uncharted/tree/master/wireframes (private)
  
 
== Documented learning during project ==
 
== Documented learning during project ==
Line 90: Line 139:
 
* Working together on a non trivial project:  We all knew about pull requests, branches and issue managers, but none of us has used them in real. In this project, using a trial-and-error approach, we learned how to organize work around issue-specific branches and corresponding pull requests. There is still room for improvement, but probably this is the most important take-away from this project.
 
* Working together on a non trivial project:  We all knew about pull requests, branches and issue managers, but none of us has used them in real. In this project, using a trial-and-error approach, we learned how to organize work around issue-specific branches and corresponding pull requests. There is still room for improvement, but probably this is the most important take-away from this project.
 
* React:  React was completely unknown for most of us. During the project we learned some best practices, got to know some libraries (e.g. Material-UI, Leaflet) and noticed some quirks of React, which we had to find a workaround for.
 
* React:  React was completely unknown for most of us. During the project we learned some best practices, got to know some libraries (e.g. Material-UI, Leaflet) and noticed some quirks of React, which we had to find a workaround for.
 +
* Modern Javascript: Some of us had little experience with Javascript, let alone ES6. There was a steep learning curve but all of us got a good overview of the basics of the language.
 +
* On the background of our limited experience with React and JS we decided to keep the framework count of our project as low as possible. The project could probably have benefitted from us incorporating stuff like redux or react-router, but we wanted to get a good basic understanding of the tools (still we ended up feeling a bit like the person in this article: https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f#.z8e65whw2 ).
  
 
== Suggested improvements to APIs etc ==
 
== Suggested improvements to APIs etc ==
* Documentation (or usability thereof): Getting started was a lot more difficult than I'd have expected. Since Postman is free and widely used and recommended, maybe it would be worth creating one or more collections, showing the usage of the API (it could even test it!).
+
* '''Documentation (or usability thereof):''' Getting started was a lot more difficult than I'd have expected. Since Postman is free and widely used and recommended, maybe it would be worth creating one or more collections, showing the usage of the API (it could even test it!).
* Speed? Maybe it is the nature of such huge APIs, or it stems from the high degree of genericity of the DHIS2 system, but most queries, even if they are returning only a handful of results, take a significant time to load. Looking at the Timeline in the Chrome Developer tools, we see that most of this time is spent waiting for the response from the server.
+
* '''Speed?''' Maybe it is the nature of such huge APIs, or it stems from the high degree of genericity of the DHIS2 system, but most queries, even if they are returning only a handful of results, take a significant time to load. Looking at the Timeline in the Chrome Developer tools, we see that most of this time is spent waiting for the response from the server.
 +
* '''Some quirks:''' When doing a patch request we receive a 200 response with empty body. Shouldn`t this be a 204-no content or return something? We had also some trouble with the sample data using wrong annotations for multi-polygons and polygons (all objects where actually multi-polygons).
 +
* '''This wiki:''' Increase the auto-logout timeout, as most of the edits I did I couldn't save, because clicking save in the dialog just waited, and then didn't do anything. After a full page reload, and redoing the changes (luckily I had them copied), it worked.
  
== Link to repository ==
+
== Repository and downloads ==
 +
Link to the repository: https://github.com/tobiasgm/inf5750-uncharted (private)
  
https://github.com/tobiasgm/inf5750-uncharted (private)
+
The stable release of the app can be downloaded from https://github.com/tobiasgm/inf5750-uncharted/releases/tag/v1.1 (private)
  
== Download link to sample web app ==
+
There is also an alternative release, see ''Architecture and implementation -> Alternative release''. Available from https://github.com/tobiasgm/inf5750-uncharted/releases/tag/v1.1-alt (private)

Latest revision as of 21:53, 30 November 2016

List of group members

  • Morten K. Dybo
  • Tobias Messenbrink
  • Ákos Pap

Task

E Health Facility Registry

App providing an interface to the health facilities in a country (e.g. the Sierra Leone or Trainingland demo databases). The add should make it possible to search and list organisation units and see these in a map, along with relevant details regarding each facility such as type, the district it belongs to etc.

Some inspiration can be found in the Kenya Master Health Facility List

Place names with coordinates for the whole world can be found using MapZen

Summary of requirements

A "one-page webapp" to view and manage health facilities (OrgUnits) in the DHIS2 system.

Main functionality / Use-cases

Search / View

  • User can enter facility name in search box. System zooms map to area level, displays marker on map and info box with facility data.
  • User can enter area name in search box. System zooms to area, displays lower level items as markers/polygons and info box with area information and list of underlying items (facilities or sub-areas).
  • If there are no matching OrgUnits, the system notifies the user about this.
  • User can navigate upwards in the hierarchy using the breadcrumbs.

The list of OrgUnits that match the query are displayed in a list (in addition to being displayed on the map).

In addition to the basic free-text search, there is an option to further narrow the query by specifying Groups and/or Programs that an OrgUnit must have.

Add / Edit

  • User can click “Edit” in the Info box to edit the currently selected Facility. Info box turns into editor mode.
  • User can add a new OrgUnit under the currently selected Level 3 OrgUnit.

Architecture and implementation

The system will consist of components which are responsible for a well-defined functionality.

Components

App

This is the root component. Contains all other components, and controls them via props.

Responsible for querying the API, maintaining a list of OrgUnits and other data, and providing these to the other components.

Filtering

Responsible for providing the search UI and constructing the query details (executed by the App component).

Contains an always visible toolbar with the free-text input.

Can be expanded to show advanced controls: Group multi-selector, Program multi-selector.

ListBox

Responsible for displaying the search results in a list. OrgUnits in the list can be selected, which notifies the App component.

Can be collapsed to a toolbar to improve visibility of the map.

InfoBox

Responsible for displaying the details of an OrgUnit.

Provides UI to switch to editing mode for the selected OrgUnit.

InfoBoxEditable

Responsible for editing the details of an OrgUnit and for filling out the details of a new OrgUnit.

MapController and Map

Two tightly connected components, responsible for displaying and manipulating the map and the OrgUnits on it.

Breadcrumbs

Responsible for displaying the ancestors of the selected OrgUnit.

Header

An app-wide toolbar for displaying a title and function buttons.

Technologies

  • React: React is used as the main framework for the application.
  • LeafletJS: Leaflet is used as the map engine, for displaying the map, showing and grouping markers.
  • Material-UI: Material-UI is responsible for consistently styled components and widgets.
  • Webpack: Webpack is the packaging framework, that creates a single file of all our scripts.
  • Babel: Babel is responsible for transpiling all the advanced JavaScript features that most browsers don't support yet.

Alternative release

We tried a new approach to querying the API: incremental loading of results. This means, that two queries are issued simultaneously:

  1. For Level 2 and Level 3 units, that match the free-text criteria (ignoring other criteria)
  2. For Level 4 units, using all criteria, requesting only the first N results (pagination). Then if there are more pages, those are subsequently fetched.

Upon each query response, the results are added to the global list, which results in a smoother user experience by showing results as early as possible.

Due to a bug(?) in earlier DHIS2 servers (see Piazza discussion), adding a filter on Programs to an OrgUnit query results in returning all OrgUnits stored in the system. This breaks this new approach to querying, so we created an alternative release, while keeping the main release stable on all servers. See Repository and downloads section.

Time schedule

Due Date Task
October 28 Update project Wiki
October 28 - November 27 Development
November 4 Working prototype of main app components
November 27 App final delivery
December 7-9 Group presentation

Dividing tasks within the group and organizing work

Name Responsibility
Morten K. Dybo React developer (Listbox, Infobox)
Tobias Messenbrink React developer (Map, Header, Footer), Design/ HTML,CSS
Ákos Pap React developer (Main app, Filtering)

In the beginning, each member works on their own branch. Conflicts are discussed and resolved at weekly meetings.

Later, we switch to issue-based branches and create pull-requests which are reviewed and merged into the master branch.

Screenshots and screen flows

Mockups of the app from the planning stage can be found here: https://github.com/tobiasgm/inf5750-uncharted/tree/master/wireframes (private)

Documented learning during project

The project uses the "Issues" and "Wiki" functionality on Github for detailed documentation during development. Please refer to those pages in the project repo to view the current state of the project as well as reasoning for some choices we made.

What we have learned so far:

  • Working together on a non trivial project: We all knew about pull requests, branches and issue managers, but none of us has used them in real. In this project, using a trial-and-error approach, we learned how to organize work around issue-specific branches and corresponding pull requests. There is still room for improvement, but probably this is the most important take-away from this project.
  • React: React was completely unknown for most of us. During the project we learned some best practices, got to know some libraries (e.g. Material-UI, Leaflet) and noticed some quirks of React, which we had to find a workaround for.
  • Modern Javascript: Some of us had little experience with Javascript, let alone ES6. There was a steep learning curve but all of us got a good overview of the basics of the language.
  • On the background of our limited experience with React and JS we decided to keep the framework count of our project as low as possible. The project could probably have benefitted from us incorporating stuff like redux or react-router, but we wanted to get a good basic understanding of the tools (still we ended up feeling a bit like the person in this article: https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f#.z8e65whw2 ).

Suggested improvements to APIs etc

  • Documentation (or usability thereof): Getting started was a lot more difficult than I'd have expected. Since Postman is free and widely used and recommended, maybe it would be worth creating one or more collections, showing the usage of the API (it could even test it!).
  • Speed? Maybe it is the nature of such huge APIs, or it stems from the high degree of genericity of the DHIS2 system, but most queries, even if they are returning only a handful of results, take a significant time to load. Looking at the Timeline in the Chrome Developer tools, we see that most of this time is spent waiting for the response from the server.
  • Some quirks: When doing a patch request we receive a 200 response with empty body. Shouldn`t this be a 204-no content or return something? We had also some trouble with the sample data using wrong annotations for multi-polygons and polygons (all objects where actually multi-polygons).
  • This wiki: Increase the auto-logout timeout, as most of the edits I did I couldn't save, because clicking save in the dialog just waited, and then didn't do anything. After a full page reload, and redoing the changes (luckily I had them copied), it worked.

Repository and downloads

Link to the repository: https://github.com/tobiasgm/inf5750-uncharted (private)

The stable release of the app can be downloaded from https://github.com/tobiasgm/inf5750-uncharted/releases/tag/v1.1 (private)

There is also an alternative release, see Architecture and implementation -> Alternative release. Available from https://github.com/tobiasgm/inf5750-uncharted/releases/tag/v1.1-alt (private)