Skip to content

Commit

Permalink
Merge pull request #1180 from medic/rc
Browse files Browse the repository at this point in the history
v0.4.9
  • Loading branch information
mandric committed Aug 26, 2015
2 parents 31d7b12 + 56e6d39 commit d97cc39
Show file tree
Hide file tree
Showing 32 changed files with 532 additions and 160 deletions.
17 changes: 17 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Medic Mobile Release Notes

## 0.4.9

### TBD

- Fixed bug on node 0.12 in felix-couchdb. #1145

- Improved error handling when notifications (start/stop) configs are
misconfigured. #1144

- Fixed bug in `exists` validation where it fails on some unicode characters.
#1147

- Fixed Reporting Rates interface that was neglected and broken. #1030

- Fixed bug in exporting data by date, it's now inclusive. #1104


## 0.4.8

### Jul 14, 2015
Expand Down
2 changes: 1 addition & 1 deletion api
Submodule api updated 1 files
+1 −1 package.json
2 changes: 1 addition & 1 deletion kanso.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "medic",
"display_name": "Medic Mobile",
"version": "0.4.8",
"version": "0.4.9",
"description": "SMS data collection designed for rural environments.",
"long_description" : "Medic Mobile is a web based SMS data collection and analytics tool focused on community health care workers in rural environments. We help large health organizations collect and analyze data sent from health care workers using ordinary mobile phones.",
"url": "https://github.com/medic/medic-webapp",
Expand Down
8 changes: 4 additions & 4 deletions lib/shows.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ function onExportFormsSubmit(ev) {
startkey = JSON.parse(params.startkey),
endkey = JSON.parse(params.endkey),
// moment doesn't like dates of '' or null
startDate = moment(startVal || undefined),
endDate = moment(endVal || undefined);
startDate = moment.utc(startVal || undefined),
endDate = moment.utc(endVal || undefined);

// flip dates if both have values and startDate's after endDate
if (startVal !== '' && startDate > endDate) {
endDate = startDate;
startDate = moment(endVal || undefined);
startDate = moment.utc(endVal || undefined);
}

// optionally filter by date
Expand All @@ -69,7 +69,7 @@ function onExportFormsSubmit(ev) {
}
if (endVal !== '') {
// update startkey for enddate as view is descending
startkey.push(endDate.valueOf());
startkey.push(endDate.add(1, 'days').valueOf());
} else {
startkey.push({});
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "medic",
"version": "0.4.8",
"version": "0.4.9",
"repository": {
"type": "git",
"url": "git://github.com/medic/medic-webapp.git"
Expand Down
16 changes: 13 additions & 3 deletions packages/kujua-reporting/css/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,17 @@
font-size: 1.12em;
font-weight: normal;
margin: 0.7em 1em 0 0;
i {
margin: 0 0.7em 0 0;
}
}
.row {
margin: 0 10px;
text-align: center;
}
.nav {
display: inline-block;
width: 75%;
}
.btn-group {
margin: 3px;
Expand Down Expand Up @@ -130,7 +134,8 @@
.mini-pie {
font-size: 2em;
margin-top: 5px;
&.fa-times {
&.fa-times,
&.fa-warning {
color: @red;
}
&.fa-check {
Expand Down Expand Up @@ -341,9 +346,9 @@
#reporting-district-choice {
padding-bottom: 40px;
padding-top: 20px;
text-align: center;
.form-name {
padding: 20px;
text-align: center;
}
.district-name {
padding: 10px 0 10px 20px;
Expand Down Expand Up @@ -393,4 +398,9 @@
padding-top: 1.5em;
}
}
}
#date-nav {
.nav {
width: 100%;
}
}
}
271 changes: 271 additions & 0 deletions packages/kujua-reporting/kujua-reporting/dust-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
var dust = require('dust-core'),
appinfo = require('views/lib/appinfo'),
_ = require('underscore');

var info;
var initInfo = function() {
if (!info || !info.translate) {
info = appinfo.getAppInfo();
}
};

// add helpers
_.extend(dust.helpers, {
// Stolen from: https://github.com/linkedin/dustjs-helpers/blob/master/dist/dust-helpers.js
tap: function(input, chunk, context) {
// return given input if there is no dust reference to resolve
// dust compiles a string/reference such as {foo} to a function
if (typeof input !== "function") {
return input;
}

var dustBodyOutput = '',
returnValue;

//use chunk render to evaluate output. For simple functions result will be returned from render call,
//for dust body functions result will be output via callback function
returnValue = chunk.tap(function(data) {
dustBodyOutput += data;
return '';
}).render(input, context);

chunk.untap();

//assume it's a simple function call if return result is not a chunk
if (returnValue.constructor !== chunk.constructor) {
//use returnValue as a result of tap
return returnValue;
} else if (dustBodyOutput === '') {
return false;
} else {
return dustBodyOutput;
}
},
translate: function(chunk, context, bodies, params) {
initInfo();
var value = dust.helpers.tap(params.value, chunk, context);
return chunk.write(info.translate(value));
},
formatDate: function(chunk, context, bodies, params) {
var timestamp = Number(dust.helpers.tap(params.timestamp, chunk, context)),
format = dust.helpers.tap(params.format, chunk, context);

if (_.isNaN(timestamp)) {
timestamp = dust.helpers.tap(params.timestamp, chunk, context);
}

// todo use data_format setting if format is not passed in
format = format || 'DD, MMM YYYY, HH:mm:ss ZZ';

return chunk.write(moment(timestamp).format(format));
},
formName: function(chunk, context, bodies, params) {
var form = dust.helpers.tap(params.form, chunk, context);

return chunk.write(sms_utils.getFormTitle(form));
},
contact: function(chunk, context, bodies, params) {
initInfo();
var entities = dust.helpers.tapObject(params.entities, chunk, context),
to = dust.helpers.tap(params.to, chunk, context),
verbose = dust.helpers.tap(params.verbose, chunk, context),
from = dust.helpers.tap(params.from, chunk, context),
contact,
clinic;

if (!contact && entities) {
contact = objectpath.get(
entities,
info.contact_display_short
);
if (!contact) {
contact = entities.clinic && entities.clinic.name;
}
if (!contact && entities.contact && entities.contact.name) {
contact = entities.contact.name;
}
}

if (!contact) {
contact = from;
}
if (!contact) {
contact = to;
}
if (!contact) {
contact = '<i class="fa fa-question-circle" title="Unknown"></i>';
}

if (verbose && entities) {
var names = [],
sep = '&raquo;',
str = '';
/*
* Supports the following structures:
*
* <entities>
* {clinic: <entities>}
* {health_center: <entities>}
*
*/
if (entities.clinic) {
entities = entities.clinic;
} else if (entities.health_center) {
entities = entities.health_center;
}
str = objectpath.get(entities, 'parent.parent.name');
if (str) {
names = names.concat(str, sep);
}
str = objectpath.get(entities, 'parent.name');
if (str) {
names = names.concat(str, sep);
}
if (entities.name) {
names = names.concat(entities.name, sep);
}
str = objectpath.get(entities, 'contact.rc_code');
names = str ? names.concat('['+str+']') : names;
str = objectpath.get(entities, 'contact.name');
names = str ? names.concat(str) : names;
if (to) {
names.push(to);
} else {
str = objectpath.get(entities, 'contact.phone');
names = str ? names.concat(str) : names;
}
contact = names.length ? names.join(' ') : contact;
}

return chunk.write(contact);
},
tasksByState: function(chunk, context, bodies, params) {
var array = dust.helpers.tapArray(params.array, chunk, context),
state = dust.helpers.tap(params.state, chunk, context),
matches;

matches = _.filter(array, function(item) {
return item.state === state;
});

return bodies.block(chunk, context.push(matches));
},
ifHasState: function(chunk, context, bodies, params) {
var array = dust.helpers.tapArray(params.array, chunk, context),
state = dust.helpers.tap(params.state, chunk, context),
body = bodies.block,
skip = bodies['else'],
cond;

cond = _.find(array, function(item) {
return item && item.state === state;
});


if (cond) {
return chunk.render( bodies.block, context );
} else if (skip) {
return chunk.render( bodies['else'], context );
} else {
return chunk;
}
},
countByState: function(chunk, context, bodies, params) {
var array1 = dust.helpers.tapArray(params.array1, chunk, context),
state = dust.helpers.tap(params.state, chunk, context),
matches,
array = [];

if (params.array2) {
array1 = array1.concat(
dust.helpers.tapArray(params.array2, chunk, context)
);
}

matches = _.filter(array1, function(item) {
return item && item.state === state;
});

return chunk.write(matches.length);
},
isAdmin: function(chunk, context, bodies, params) {
var body = bodies.block,
skip = bodies['else'];

if (data_records.isAdmin) {
return chunk.render(bodies.block, context);
} else if (skip) {
return chunk.render(skip, context);
} else {
return chunk;
}
},
hasPermission: function(chunk, context, bodies, params) {
var body = bodies.block,
skip = bodies['else'],
permission = dust.helpers.tap(params.permission, chunk, context);

if (utils.hasPerm(data_records.userCtx, permission)) {
return chunk.render(bodies.block, context);
} else if (skip) {
return chunk.render(skip, context);
} else {
return chunk;
}
},
idx: function(chunk, context, bodies) {
if (bodies.block) {
return bodies.block(chunk, context.push(context.stack.index));
}
else {
return chunk;
}
},
if: function(chunk, context, bodies, params) {
var body = bodies.block,
skip = bodies['else'];

if( params && params.cond){
var cond = params.cond;

cond = dust.helpers.tap(cond, chunk, context);

// strip all new line characters as they break eval
if (cond) {
cond = cond.replace(/\r?\n/g, '');
}

// eval expressions with given dust references
if(eval(cond)){
if(body) {
return chunk.render( bodies.block, context );
}
else {
_console.log( "Missing body block in the if helper!" );
return chunk;
}
}
if(skip){
return chunk.render( bodies['else'], context );
}
}
// no condition
else {
_console.log( "No condition given in the if helper!" );
}
return chunk;
},
eq: function(chunk, context, bodies, params) {
var actual = context.get(params.key) + '';
var expected = params.value;
if (actual === expected) {
return chunk.render(bodies.block, context);
} else if (bodies['else']) {
return chunk.render(bodies['else'], context);
} else {
return chunk;
}
}
});

module.exports = dust;
Loading

0 comments on commit d97cc39

Please sign in to comment.