Get started with App development

Tech session 1:

Things to talk about

  • Webapp manifest
  • Authentication
  • Storage
  • Sql views
  • Browsing the Web API
  • D2 + D2-UI
  • Code?!

More API on Saturday :)

  • Reading data values
  • Filtering, sorting
  • Analytics and settings

When to app?

  • The core already has "Apps"
    • Event capture
    • Tracker capture
    • Pivot
    • GIS
    • Event reports
  • Any case where you need functionality that is not possible with the current apps or extending current functionality (Multiple entry form)

Managing apps

App Manager

  • Install apps
  • Remove apps
    • In the settings tab?!

What is a DHIS2 webapp?

  • Webapp manifest (Describes the app to the system)
  • HTML and CSS (Layout)
  • Javascript (Client side code, api communication)
  • Zip file containing the app files

Manifest

What is the manifest for?

  • Describes your application to DHIS2
  • What icon and name to use for the menu?
  • How to start up the app?
  • Locate the base url of the instance

Manifest

{
  "version": "0.0.1",
  "name": "tech-session1",
  "description": "The minimalist tech session 1 app!",
  "icons": {
    "48": "tech-session1.gif"
  },
  "developer": {
    "url": "",
    "name": "Mark"
  },
  "launch_path": "index.html",
  "default_locale": "en",
  "activities": {
    "dhis": {
      "href": "*"
    }
  }
}

Manifest

{
    "activities":{
        "dhis":{
            "href":"https://apps.dhis2.org/demo"
        }
}

Server modifies the special property

{
    "activities":{
        "dhis":{
            "href": "*"
        }
}

Manifest in app startup

  • App startup loads the manifest
  • Extract base url from the manifest to locate the api
  • Use base url to load any serverside assets
fetch('../manifest.webapp', {credentials: 'same-origin'})
  .then(function (response) { return response.json(); })
  .then(function (manifest) {
    var baseUrl = manifest.activities.dhis.href;
    var apiUrl = [baseUrl + 'api'].join('/');

    //Start your app here
    //Add the baseUrl to your app (Load any core assets if required)
    console.log(baseUrl);
  })
  .catch(function () {
    console.log('Failed to load manifest');
  });

Authentication

  • Basic authentication - (I.e. CURL requests)
  • OAuth2 - When building external apps (2.20)
  • When installing into the system the current user session will work for most cases
  • Apps can be served through the API

Depends on what kind of app (or script)

Storage

  • On the server
    • api/systemSettings
    • api/userSettings
    • General data store (Someday)
  • On the client machine
    • IndexDB
    • Session storage
    • Local storage

SQL Views

  • Useful is some cases where you need specific joins
  • Should be used with care (No ACL)
  • Could be used in combination with `normal` api requests to apply ACL

Browsing the web api

Chrome apps for JSON Views with style

/api/schemas.json?fields=name,href

A lot of endpoints can be found through

D2 + D2-UI

  • Available on Github and npm
  • Currently limited use
npm install d2
import d2 from 'd2';

//Initialise the library (Returns a `Promise`)
d2({baseUrl: '/demo/api/'})
    .then(function (d2) {
        //D2 is initialised
    });

D2 Model and ModelCollection

  • Model
    • Represents a database object (user, dataElement)
  • ModelCollection
    • Collection (Map) of models that also keeps track of paging if available

ModelDefinition

Not really visible directly but used under the hood to keep track of model state, properties, validations and more

Model

  • Won't save if no values
  • Will validate payload against schema
Save();
Validate();

d2.models.<schema>

List 

  • Returns a collection of models that keep track of paging
  • ModelCollection.pager.getNextPage();
  • ModelCollection.pager.getPreviousPage();
d2.models.user.list();
d2.models.dataElement.get(<uid>);
d2.models.user.filter().on(<property>).like(<value>)
d2.models.indicator.filter().on(<property>).equals(<value>)

Code stuff!

Copy of Tech Session 1

By markpolak

Copy of Tech Session 1

  • 257