Skip to content

Commit

Permalink
Move bundled nools code to a proper .js file
Browse files Browse the repository at this point in the history
  • Loading branch information
alxndrsn committed Jul 4, 2018
1 parent 2a43669 commit c0eb5ec
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 155 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## v1.17.5
* Move bundled nools code to a proper .js file

## v1.17.4
* Don't confuse jshint by talking about jshint
* Fix: first scheduled_task date is incorrect
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "medic-conf",
"version": "1.17.4",
"version": "1.17.5",
"description": "Configure Medic Mobile deployments",
"main": "index.js",
"scripts": {
Expand Down
155 changes: 2 additions & 153 deletions src/lib/compile-nools-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function compileWithDefaultLayout(projectDir) {
const targets = parseTargets.js(projectDir);
const tasks = fs.read(`${projectDir}/tasks.js`);
const supportCode = fs.read(`${projectDir}/nools-extras.js`);
const noolsLib = fs.read(`${__dirname}/../nools/lib.js`);

const jsCode = templatedJs.fromString(projectDir, `
var idx1, idx2, r, target;
Expand All @@ -26,159 +27,7 @@ function compileWithDefaultLayout(projectDir) {
var targets = ${jsToString(targets)};
var tasks = ${tasks};
if (c.contact && c.contact.type === 'person') {
for(idx1=0; idx1<targets.length; ++idx1) {
target = targets[idx1];
switch(target.appliesToType) {
case 'person':
emitPersonBasedTargetFor(c, target);
break;
case 'report':
for(idx2=0; idx2<c.reports.length; ++idx2) {
r = c.reports[idx2];
emitReportBasedTargetFor(c, r, target);
}
break;
default:
throw new Error('unrecognised target type: ' + target.type);
}
}
for(idx1=0; idx1<tasks.length; ++idx1) {
// TODO currently we assume all tasks are report-based
for(idx2=0; idx2<c.reports.length; ++idx2) {
r = c.reports[idx2];
emitTasksForSchedule(c, r, tasks[idx1]);
}
}
}
function emitTasksForSchedule(c, r, schedule) {
var i;
if(schedule.appliesToForms && schedule.appliesToForms.indexOf(r.form) === -1) {
return;
}
if(schedule.appliesIf && !schedule.appliesIf(c, r)) {
return;
}
if(schedule.appliesToScheduledTaskIf) {
if(!r.scheduled_tasks) {
return;
}
for (i = 0; i < r.scheduled_tasks.length; i++) {
if(schedule.appliesToScheduledTaskIf(r, i)) {
emitForEvents(i);
}
}
} else {
emitForEvents();
}
function emitForEvents(scheduledTaskIdx) {
var i, dueDate, event, priority, task;
for (i = 0; i < schedule.events.length; i++) {
event = schedule.events[i];
if(event.dueDate) {
dueDate = event.dueDate(r, event, scheduledTaskIdx);
} else if(scheduledTaskIdx !== undefined) {
dueDate = new Date(Utils.addDate(new Date(r.scheduled_tasks[scheduledTaskIdx].due), event.days));
} else {
dueDate = new Date(Utils.addDate(new Date(r.reported_date), event.days));
}
if (!Utils.isTimely(dueDate, event)) {
continue;
}
task = {
// One task instance for each event per form that triggers a task, not per contact
// Otherwise they collide when contact has multiple reports of the same form
_id: r._id + '-' + event.id,
deleted: !!((c.contact && c.contact.deleted) || r.deleted),
doc: c,
contact: c.contact,
icon: schedule.icon,
date: dueDate,
title: schedule.title,
resolved: schedule.resolvedIf(c, r, event, dueDate, scheduledTaskIdx),
actions: schedule.actions.map(initActions),
};
if(scheduledTaskIdx !== undefined) {
task._id += '-' + scheduledTaskIdx;
}
priority = schedule.priority;
if(typeof priority === 'function') {
priority = priority(c, r);
}
if(priority) {
task.priority = priority.level;
task.priorityLabel = priority.label;
}
emit('task', new Task(task));
}
}
function initActions(def) {
return {
type: 'report',
form: def.form,
label: def.label || 'Follow up',
content: {
source: 'task',
source_id: r._id,
contact: c.contact,
},
};
}
}
function emitPersonBasedTargetFor(c, targetConfig) {
if(targetConfig.appliesIf && !targetConfig.appliesIf(c)) return;
var pass = !targetConfig.passesIf || !!targetConfig.passesIf(c);
var instance = createTargetInstance(targetConfig.id, c.contact, pass);
instance.date = targetConfig.date ? targetConfig.date(c) : now.getTime(); emitTargetInstance(instance);
}
function emitReportBasedTargetFor(c, r, targetConf) {
var instance, pass;
if(targetConf.appliesIf && !targetConf.appliesIf(c, r)) return;
if(targetConf.emitCustom) {
targetConf.emitCustom(c, r);
return;
}
pass = !targetConf.passesIf || !!targetConf.passesIf(c, r);
instance = createTargetInstance(targetConf.id, r, pass);
instance._id = (targetConf.idType === 'report' ? r._id : c.contact._id) + '-' + targetConf.id;
emitTargetInstance(instance);
switch(targetConf.date) {
case 'now': instance.date = now.getTime(); break;
}
}
function createTargetInstance(type, doc, pass) {
return new Target({
_id: doc._id + '-' + type,
deleted: !!doc.deleted,
type: type,
pass: pass,
date: doc.reported_date
});
}
function emitTargetInstance(i) {
emit('target', i);
}
emit('_complete', { _id: true });
${noolsLib}
`);

lint(jsCode);
Expand Down
19 changes: 19 additions & 0 deletions src/nools/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"esversion": 5,
"globals": {
"c": true,
"emit": false,
"idx1": true,
"idx2": true,
"now": false,
"r": true,
"target": true,
"targets": false,
"tasks": false,
"Target": false,
"Task": false,
"Utils": false
},
"undef": true,
"unused": true
}
153 changes: 153 additions & 0 deletions src/nools/lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
if (c.contact && c.contact.type === 'person') {
for(idx1=0; idx1<targets.length; ++idx1) {
target = targets[idx1];
switch(target.appliesToType) {
case 'person':
emitPersonBasedTargetFor(c, target);
break;
case 'report':
for(idx2=0; idx2<c.reports.length; ++idx2) {
r = c.reports[idx2];
emitReportBasedTargetFor(c, r, target);
}
break;
default:
throw new Error('unrecognised target type: ' + target.type);
}
}
for(idx1=0; idx1<tasks.length; ++idx1) {
// TODO currently we assume all tasks are report-based
for(idx2=0; idx2<c.reports.length; ++idx2) {
r = c.reports[idx2];
emitTasksForSchedule(c, r, tasks[idx1]);
}
}
}

function emitTasksForSchedule(c, r, schedule) {
var i;

if(schedule.appliesToForms && schedule.appliesToForms.indexOf(r.form) === -1) {
return;
}
if(schedule.appliesIf && !schedule.appliesIf(c, r)) {
return;
}

if(schedule.appliesToScheduledTaskIf) {
if(!r.scheduled_tasks) {
return;
}
for (i = 0; i < r.scheduled_tasks.length; i++) {
if(schedule.appliesToScheduledTaskIf(r, i)) {
emitForEvents(i);
}
}
} else {
emitForEvents();
}

function emitForEvents(scheduledTaskIdx) {
var i, dueDate, event, priority, task;
for (i = 0; i < schedule.events.length; i++) {
event = schedule.events[i];

if(event.dueDate) {
dueDate = event.dueDate(r, event, scheduledTaskIdx);
} else if(scheduledTaskIdx !== undefined) {
dueDate = new Date(Utils.addDate(new Date(r.scheduled_tasks[scheduledTaskIdx].due), event.days));
} else {
dueDate = new Date(Utils.addDate(new Date(r.reported_date), event.days));
}

if (!Utils.isTimely(dueDate, event)) {
continue;
}

task = {
// One task instance for each event per form that triggers a task, not per contact
// Otherwise they collide when contact has multiple reports of the same form
_id: r._id + '-' + event.id,
deleted: !!((c.contact && c.contact.deleted) || r.deleted),
doc: c,
contact: c.contact,
icon: schedule.icon,
date: dueDate,
title: schedule.title,
resolved: schedule.resolvedIf(c, r, event, dueDate, scheduledTaskIdx),
actions: schedule.actions.map(initActions),
};

if(scheduledTaskIdx !== undefined) {
task._id += '-' + scheduledTaskIdx;
}

priority = schedule.priority;
if(typeof priority === 'function') {
priority = priority(c, r);
}
if(priority) {
task.priority = priority.level;
task.priorityLabel = priority.label;
}

emit('task', new Task(task));
}
}

function initActions(def) {
return {
type: 'report',
form: def.form,
label: def.label || 'Follow up',
content: {
source: 'task',
source_id: r._id,
contact: c.contact,
},
};
}
}

function emitPersonBasedTargetFor(c, targetConfig) {
if(targetConfig.appliesIf && !targetConfig.appliesIf(c)) return;

var pass = !targetConfig.passesIf || !!targetConfig.passesIf(c);

var instance = createTargetInstance(targetConfig.id, c.contact, pass);
instance.date = targetConfig.date ? targetConfig.date(c) : now.getTime(); emitTargetInstance(instance);
}

function emitReportBasedTargetFor(c, r, targetConf) {
var instance, pass;
if(targetConf.appliesIf && !targetConf.appliesIf(c, r)) return;

if(targetConf.emitCustom) {
targetConf.emitCustom(c, r);
return;
}

pass = !targetConf.passesIf || !!targetConf.passesIf(c, r);
instance = createTargetInstance(targetConf.id, r, pass);
instance._id = (targetConf.idType === 'report' ? r._id : c.contact._id) + '-' + targetConf.id;
emitTargetInstance(instance);
switch(targetConf.date) {
case 'now': instance.date = now.getTime(); break;
}
}

function createTargetInstance(type, doc, pass) {
return new Target({
_id: doc._id + '-' + type,
deleted: !!doc.deleted,
type: type,
pass: pass,
date: doc.reported_date
});
}

function emitTargetInstance(i) {
emit('target', i);
}

emit('_complete', { _id: true });

0 comments on commit c0eb5ec

Please sign in to comment.