{% load i18n %} {% comment %} These Riot tags allow operations via a RESTful interface on the following objects ✓ = complete p = pending f = future / not planned yet Result ✓ ResultDescription ✓ ResultIndicator ✓ ResultIndicatorBaselineComment p ResultIndicatorDescription ✓ ResultIndicatorPeriod ✓ ResultIndicatorPeriodActualComment f ResultIndicatorPeriodActualDimension ✓ ResultIndicatorPeriodActualLocation f ResultIndicatorPeriodTargetComment f ResultIndicatorPeriodTargetDimension f ResultIndicatorPeriodTargetLocation f ResultIndicatorReference f ResultIndicatorTitle ✓ ResultIndicatorType ✓ ResultTitle ✓ {% endcomment %} {link.text || 'back'} var tag = this; tag.link = {}; tag.on('mount', function(){ tag.update({link: _.invoke(tag.parent, 'getBackLink')}) })
var tag = this; tag.item = {}; tag.cancel = tag.parent.cancel; tag.goBack = tag.parent.goBack; tag.save = tag.parent.save; tag.delete_item = tag.parent.delete_item; tag.edit = tag.parent.edit; tag.on('mount', function(){ tag.update({item: tag.parent.item}); }) tag.on('update', function(){ if (tag.item != tag.parent.item){ tag.update({item: tag.parent.item}); } })
{# EG resultindicatortitle/result_indicator/3 : the title(s) for result indicator 3 #}
/* manually call 'exec' to initiate this nested router */ this.on('mount', function(){route.exec('')})

{% trans 'Results' %}

Add a result
{% include "tags/tab-results.js" %}

{% trans 'There are no results' %}

var tag = this; var store = stores.resultsStore; var content_type = 'result'; function get_filter(){return {content_type:content_type}} function update_items(){tag.update({items: _.filter(store.getItems(get_filter())) })} tag.on('before-mount', function(){update_items()});

{% trans 'Add an indicator to your result' %}

{% trans 'Indicators' %}

{# #} {# #}
Indicator TypeVisible{# Actions #}
{item.title}Untitled {_.get(item, 'result_indicator_type.display')}{_.get(item, 'result_indicator_type.visible')} Add a value
{# #}

{% trans 'Creating the result, please wait' %}

{% trans 'Your result should be ready shortly' %}

var store = stores.resultsStore; var content_type = 'result'; function onRoute() { /* In order to save the narrative fields 'Title' and 'Description' we first need a result ID. For this, we'll show a "Please wait" screen while we post the server for a new RESULT. */ var request = store.make_request({ content_type: content_type, data: store.getTemplate(content_type)}) request.then(function(response){ route('results/'+response.id+'/edit') }) } this.on('route', onRoute());

Edit Result

{# #}

Add an indicator to your result

Edit an indicator

Report the Baseline:
{# #}
{name}
{# #}
Indicator Type
var tag = this; tag.item = {}; var store = stores.resultsStore; var content_type = 'resultindicatortype'; tag.object_id = undefined; function onMount() { if(tag.parent.item.id){ return tag.update({item: store.getItems({content_type: content_type, result_indicator: tag.parent.item.id}, true) }) } tag.update({item: store.getTemplate(content_type)}); } tag.on('mount', function(id){ onMount(); }) tag.save = function () { var data = _.clone(tag.item); var request; _.each(tag.refs, function (control, ref) { data[ref] = control.value; }); /* Ensure a result_indicator is set */ data.result_indicator = tag.parent.item.id; if (!data.result_indicator){throw new Error('Oops! No resultindicator')}; request = {content_type: content_type, data: data}; tag.update({item: undefined}); store.make_request(request) .then(function (response) { tag.update({item: response}) }) .fail(function (response) { tag.update({item: data}) }) }
{# #}

{item.title} No Title provided

{item.description} No Description

Profile page
var tag = this; tag.item = {}; tag.display = undefined; var store = stores.resultsStore; var content_type = 'resultindicator'; function onRoute(id){tag.update({item: store.getRichItem(content_type, parseInt(id)), profile_page: store.navigation_urls({content_type: 'resultindicator', id: parseInt(id), action: 'profile'})});} tag.on('route', function (id) {onRoute(id)}) tag.getBackLink = function(){return {url:'results/'+tag.item.result}} tag.edit = function(){route('results/indicator/'+tag.item.id+'/edit')}

{item.title} No title provided

{item.description} No description provided

Add an indicator
var tag = this; var store = stores.resultsStore; var content_type = 'result'; function onRoute(id){tag.update({item: store.getRichItem(content_type, parseInt(id))})} tag.on('route', function (id) {onRoute(id)}) tag.edit = function(){route('results/'+tag.item.id+'/edit')} tag.getBackLink = function(){return {url: 'results'}}

{narrative.content}

{% trans "Untitled" %}

this.mixin('NarrativeMixin')

{narrative.content}

this.mixin('NarrativeMixin')

{opts.narrative.content}

{# Ready for multilingual inputs #}
{# #}

{opts.narrative.content}


Indicator {index+1}

This result has no indicators

Add an indicator {# #}

Indicator Type

{# #}
Report the Baseline:
{# #}
Indicator Title:

{narrative.content}

this.mixin('NarrativeMixin')
this.mixin('NarrativeMixin') this.mixin('NarrativeMixin') {# Placeholders to be filled out #}

{opts.title || 'items'}

{JSON.stringify(opts.item)}

Indicator Periods
{# #}

{% trans 'There are no values' %}

{% trans 'Indicator Periods' %}

Date Target Actual
{item.period_end} {item.target} {item.actual} Edit
{# #}

{% trans "Add a value" %}

{% trans "Edit a value" %}

var tag = this; tag.item = {}; var store = stores.resultsStore; var content_type = 'resultindicatorperiod'; function getDatepickerOpts() { var datepicker_opts = $.extend({ orientation: 'top left', startView: 1, autoclose: true, format: 'yyyy-mm-dd', clearBtn: true }, tag.opts.datepicker_opts); if (tag.opts.validate_date_is_past) { tag.datepicker_opts.endDate = '0d'; } return datepicker_opts; } function intializeDatePicker(ref) { var selector = "[ref="+ref+"]" var element = $(selector, tag.root) if (!element[0]) { return; } var datepicker = element.datepicker(getDatepickerOpts()); datepicker.on('changeDate', function () { var date = $(this).datepicker('getUTCDate'); var iso_date = moment(date).format('YYYY-MM-DD'); tag.item.date = iso_date; tag.update(); }); datepicker.on('clearDate', function () { tag.item.date = ''; tag.update(); }); } function getData(){ var data = _.clone(tag.item); _.each(tag.refs, function (control, ref) { data[ref] = control.value }); // Drop blank values _.each(['period_start', 'period_end', 'actual', 'target'], function(date_field){ if(data[date_field] === ''){ data[date_field] = null } }) return data; } function onRoute() { intializeDatePicker('period_start'); intializeDatePicker('period_end'); if (tag.object_id) { tag.add_or_edit = 'Edit' tag.update({item: store.getRichItem(content_type, parseInt(tag.object_id))}); } else { tag.add_or_edit = 'Add' tag.update({item: store.getTemplate(content_type)}); } tag.query_params = route.query(); if (tag.query_params.result_indicator){ tag.item.result_indicator = _.toInteger(tag.query_params.result_indicator) }; } tag.on('route', function (id) { tag.object_id = id; onRoute() }); tag.save = function save(){ if (!tag.item){return} store.make_request({object_type: content_type, data: getData()}).done(function (response) { tag.update({item:store.getRichItem(content_type, response.id)}); _.invoke(tag.tags['dimension-form'], 'save') }); } tag.delete_item = function delete_item(){ if (!tag.item){return} store.make_request({method: 'DELETE', object_type: content_type, data: getData()}).done(function (response) { route(tag.getBackLink().url); }); } tag.getBackLink = function(){return {url: 'results/indicator/'+ (tag.query_params.result_indicator || tag.item.result_indicator)}}
{ col } {# Save #} {# Delete #} var tag = this; tag.cols = ['Period Start', 'Period End', 'Target', 'Actual', 'Dimension'] {# #}
{# #}
{# #}