Skip to content

Commit

Permalink
Merge pull request #8 from EyeSeeTea/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
ifoche authored Mar 10, 2021
2 parents c2ee2a3 + 8f212ca commit 6d95ec6
Show file tree
Hide file tree
Showing 22 changed files with 301 additions and 97 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ cypress/videos/

# Custom
bak
NOTES*
26 changes: 10 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
## Introduction

_d2-report_ provides the infrastructure to create DHIS2 reports with a React frontend.

Those reports developed an an standard webapp, and they can both be used as an standalone DHIS2 webapp or an standard HTML report (App: Reports).

Target DHIS2: 2.34.
_d2-reports_ than can be used as an standalone DHIS2 webapp or an standard HTML report (App: Reports). DHIS2 versions tested: 2.34.

## Reports

Expand All @@ -15,12 +11,10 @@ This report shows data values for data sets `NHWA Module ...`. There are two kin
1. Data values that have comments.
2. Data values related pairs (value/comment), which are rendered as a single row. The pairing criteria is:

- Comment data element: `NHWA_Comment of Abc`.
- Comment data element `NHWA_Comment of Abc`.
- Value data element: `NHWA_Abc`.

The API endpoint `/dataValueSets` does not provide all the features we need, so we use a custom SQL View instead. It will be included in the metadata.

We use the data element group to put data elements in the same sections together. Note that only data elements belonging to a data element group will be displayed.
The API endpoint `/dataValueSets` does not provide all the features we need, so we use a custom SQL View instead.

## Initial setup

Expand All @@ -30,24 +24,24 @@ $ yarn install

## Development

Start development server at `http://localhost:8082` using `https://play.dhis2.org/2.34` as backend:
Start the development server at `http://localhost:8082` using `https://play.dhis2.org/2.34` as a backend:

```
$ PORT=8082 REACT_APP_DHIS2_BASE_URL="https://play.dhis2.org/2.34" yarn start
```

## Deploy

Create standard report:
Create an standard report:

```
$ yarn build-report # Create dist/index.html
$ yarn build-metadata -u 'user:password' http://dhis2-server.org # Creates dist/metadata.json
$ yarn post-metadata -u 'user:password' http://dhis2-server.org # Posts dist/metadata.json
$ yarn build-report # Creates dist/index.html
$ yarn build-metadata -u 'user:pass' http://dhis2-server.org # Creates dist/metadata.json
$ yarn post-metadata -u 'user:pass' http://dhis2-server.org # Posts dist/metadata.json
```

Create web-app zip (`dist/d2-reports.zip`):
Create an standalone DHIS2 webapp app:

```
$ yarn build-webapp
$ yarn build-webapp # Creates dist/d2-reports.zip
```
19 changes: 17 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2020-11-18T10:58:48.575Z\n"
"PO-Revision-Date: 2020-11-18T10:58:48.575Z\n"
"POT-Creation-Date: 2021-03-05T08:55:57.149Z\n"
"PO-Revision-Date: 2021-03-05T08:55:57.149Z\n"

msgid "Periods"
msgstr ""
Expand All @@ -17,6 +17,9 @@ msgstr ""
msgid "Sections"
msgstr ""

msgid "NHWA Comments Report"
msgstr ""

msgid "Data set"
msgstr ""

Expand Down Expand Up @@ -47,6 +50,18 @@ msgstr ""
msgid "Stored by"
msgstr ""

msgid "Toggle filters"
msgstr ""

msgid "Loading..."
msgstr ""

msgid "Select parent organisation unit"
msgstr ""

msgid "Close"
msgstr ""

msgid "<No value>"
msgstr ""

Expand Down
17 changes: 16 additions & 1 deletion i18n/es.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
"POT-Creation-Date: 2020-11-18T10:58:48.575Z\n"
"POT-Creation-Date: 2021-03-05T08:55:57.149Z\n"
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand All @@ -17,6 +17,9 @@ msgstr ""
msgid "Sections"
msgstr ""

msgid "NHWA Comments Report"
msgstr ""

msgid "Data set"
msgstr ""

Expand Down Expand Up @@ -47,6 +50,18 @@ msgstr ""
msgid "Stored by"
msgstr ""

msgid "Toggle filters"
msgstr ""

msgid "Loading..."
msgstr ""

msgid "Select parent organisation unit"
msgstr ""

msgid "Close"
msgstr ""

msgid "<No value>"
msgstr ""

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "d2-reports",
"description": "DHIS2 Reports",
"version": "0.0.2",
"version": "0.0.4",
"license": "GPL-3.0",
"author": "EyeSeeTea team",
"homepage": ".",
Expand Down
6 changes: 6 additions & 0 deletions src/compositionRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@ import { GetDataValuesUseCase } from "./domain/usecases/GetDataValuesUseCase";
import { GetConfig } from "./domain/usecases/GetConfig";
import { Dhis2ConfigRepository } from "./data/Dhis2ConfigRepository";
import { SaveDataValuesUseCase } from "./domain/usecases/SaveDataValuesCsvUseCase";
import { GetOrgUnitsUseCase } from "./domain/usecases/GetOrgUnitsUseCase";
import { Dhis2OrgUnitsRepository } from "./data/Dhis2OrgUnitsRepository";

export function getCompositionRoot(api: D2Api) {
const configRepository = new Dhis2ConfigRepository(api);
const dataValueRepository = new Dhis2DataValueRepository(api);
const orgUnitsRepository = new Dhis2OrgUnitsRepository(api);

return {
dataValues: {
get: new GetDataValuesUseCase(dataValueRepository),
save: new SaveDataValuesUseCase(dataValueRepository),
},
orgUnits: {
get: new GetOrgUnitsUseCase(orgUnitsRepository),
},
config: {
get: new GetConfig(configRepository),
},
Expand Down
10 changes: 1 addition & 9 deletions src/data/Dhis2ConfigRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@ import { User } from "../domain/entities/User";
const base = {
dataSets: { namePrefix: "NHWA", nameExcluded: /old$/ },
sqlViewName: "NHWA Data Comments",
sectionOrderAttributeCode: "SECTION_ORDER",
constantCode: "NHWA_COMMENTS",
};

export class Dhis2ConfigRepository implements ConfigRepository {
constructor(private api: D2Api) {}

async get(): Promise<Config> {
const { dataSets, constants, sqlViews, attributes } = await this.getMetadata();
const { dataSets, constants, sqlViews } = await this.getMetadata();
const filteredDataSets = getFilteredDataSets(dataSets);
const attributeCode = base.sectionOrderAttributeCode;
const getDataValuesSqlView = getFirst(sqlViews, `Missing sqlView: ${base.sqlViewName}`);
const sectionOrderAttribute = getFirst(attributes, `Missing attribute: ${attributeCode}`);
const constant = getFirst(constants, `Missing constant: ${base.constantCode}`);
const currentUser = await this.getCurrentUser();
const pairedDataElements = getPairedMapping(filteredDataSets);
Expand All @@ -32,7 +29,6 @@ export class Dhis2ConfigRepository implements ConfigRepository {
dataSets: keyById(filteredDataSets),
currentUser,
getDataValuesSqlView,
sectionOrderAttribute,
pairedDataElementsByDataSet: pairedDataElements,
sections: keyById(sections),
sectionsByDataSet,
Expand Down Expand Up @@ -60,10 +56,6 @@ export class Dhis2ConfigRepository implements ConfigRepository {
fields: { id: true },
filter: { name: { eq: base.sqlViewName } },
},
attributes: {
fields: { id: true },
filter: { code: { eq: base.sectionOrderAttributeCode } },
},
});

return metadata$.getData();
Expand Down
2 changes: 0 additions & 2 deletions src/data/Dhis2DataValueRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ interface Variables {
periods: string;
orderByColumn: SqlField;
orderByDirection: "asc" | "desc";
sectionOrderAttributeId: Id;
commentPairs: string;
}

Expand Down Expand Up @@ -75,7 +74,6 @@ export class Dhis2DataValueRepository implements DataValueRepository {
orderByColumn: fieldMapping[sorting.field],
orderByDirection: sorting.direction,
commentPairs,
sectionOrderAttributeId: config.sectionOrderAttribute.id,
},
paging
)
Expand Down
22 changes: 22 additions & 0 deletions src/data/Dhis2OrgUnitsRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { OrgUnitPath, OrgUnit, getOrgUnitIdsFromPaths } from "../domain/entities/OrgUnit";
import { OrgUnitsRepository } from "../domain/repositories/OrgUnitsRepository";
import { D2Api } from "../types/d2-api";

export class Dhis2OrgUnitsRepository implements OrgUnitsRepository {
constructor(private api: D2Api) {}

async getFromPaths(paths: OrgUnitPath[]): Promise<OrgUnit[]> {
const ids = getOrgUnitIdsFromPaths(paths);

const { organisationUnits } = await this.api.metadata
.get({
organisationUnits: {
filter: { id: { in: ids } },
fields: { id: true, path: true, name: true, level: true },
},
})
.getData();

return organisationUnits;
}
}
7 changes: 6 additions & 1 deletion src/domain/entities/Config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import _ from "lodash";
import { Id, NamedRef, Ref } from "./Base";
import { getPath } from "./OrgUnit";
import { User } from "./User";

export interface Config {
dataSets: Record<Id, NamedRef>;
sections: Record<Id, NamedRef>;
sectionOrderAttribute: Ref;
currentUser: User;
getDataValuesSqlView: Ref;
pairedDataElementsByDataSet: {
Expand All @@ -15,3 +16,7 @@ export interface Config {
};
years: string[];
}

export function getMainUserPaths(config: Config) {
return _.compact([getPath(config.currentUser.orgUnits)]);
}
18 changes: 12 additions & 6 deletions src/domain/entities/OrgUnit.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import _ from "lodash";
import { Id } from "./Base";

type Path = string;
export type OrgUnitPath = string;

export interface OrgUnit {
id: string;
path: Path;
id: Id;
path: OrgUnitPath;
name: string;
level: number;
}

const pathSeparator = "/";

export function getRoots(orgUnits: OrgUnit[]): OrgUnit[] {
const minLevel = _.min(orgUnits.map(ou => ou.level));
return _(orgUnits)
Expand All @@ -22,13 +24,17 @@ export function getRootIds(orgUnits: OrgUnit[]): Id[] {
return getRoots(orgUnits).map(ou => ou.id);
}

export function getPath(orgUnits: OrgUnit[]): Path | undefined {
export function getPath(orgUnits: OrgUnit[]): OrgUnitPath | undefined {
return getRoots(orgUnits).map(ou => ou.path)[0];
}

export function getOrgUnitIdsFromPaths(orgUnitPathsSelected: Path[]): Id[] {
export function getOrgUnitIdsFromPaths(orgUnitPathsSelected: OrgUnitPath[]): Id[] {
return _(orgUnitPathsSelected)
.map(path => _.last(path.split("/")))
.map(path => _.last(path.split(pathSeparator)))
.compact()
.value();
}

export function getOrgUnitParentPath(path: OrgUnitPath) {
return _(path).split(pathSeparator).initial().join(pathSeparator);
}
5 changes: 5 additions & 0 deletions src/domain/repositories/OrgUnitsRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { OrgUnit, OrgUnitPath } from "../entities/OrgUnit";

export interface OrgUnitsRepository {
getFromPaths(paths: OrgUnitPath[]): Promise<OrgUnit[]>;
}
10 changes: 10 additions & 0 deletions src/domain/usecases/GetOrgUnitsUseCase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { OrgUnit, OrgUnitPath } from "../entities/OrgUnit";
import { OrgUnitsRepository } from "../repositories/OrgUnitsRepository";

export class GetOrgUnitsUseCase {
constructor(private orgUnitsRepository: OrgUnitsRepository) {}

execute(options: { paths: OrgUnitPath[] }): Promise<OrgUnit[]> {
return this.orgUnitsRepository.getFromPaths(options.paths);
}
}
3 changes: 2 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ async function getBaseUrl() {
return baseUrl.replace(/\/*$/, "");
} else {
const { data: manifest } = await axios.get("manifest.webapp");
return manifest.activities.dhis.href;
const href = manifest.activities.dhis.href;
return href === "*" ? ".." : href;
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/webapp/components/app/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ body {
li {
line-height: 1.75;
}

table th,
table td {
border: none !important;
}
Loading

0 comments on commit 6d95ec6

Please sign in to comment.