Ignore:
Timestamp:
03/05/14 22:44:48 (11 years ago)
Author:
hendrikvanantwerpen
Message:

Completed migration to API, without CouchDB proxy.

Move to API is now completed. The full API is password protected, a very
limited API is exposed for respondents, which works with secrets that
are passed in URLs.

Serverside the HTTPResult class was introduced, which is similar to
Promises, but specifically for HTTP. It carries a status code and
response and makes it easier to extract parts of async handling in
separate functions.

Fixed a bug in our schema (it seems optional attributes don't exist but
a required list does). Verification of our schema by grunt-tv4 didn't
work yet. Our schema is organized the wrong way (this is fixable),
but the json-schema schema has problems with simple types and $refs.

Location:
Dev/trunk/src/client/qed-client/model
Files:
4 added
2 deleted
5 edited
4 moved

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/client/qed-client/model/classes

    • Property svn:ignore set to

      ### begin grunt-svn-ignore managed ignores
      ### edits will be overwritten when grunt svn-ignore is run
      Question.js
      Response.js
      Survey.js
      SurveyRun.js
      ### end grunt-svn-ignore managed ignores
  • Dev/trunk/src/client/qed-client/model/classes/questions.js

    r486 r487  
    1 define(function(){
    2     return {
    3         create: function(){
    4             return { type:'Question' };
     1define([
     2    "./_Class",
     3    "dojo/_base/declare",
     4    "dojo/date/stamp"
     5], function(_Class, declare, stamp) {
     6
     7    var Questions = declare([_Class],{
     8        _collection: 'questions',
     9        _type: 'Question',
     10        create: function() {
     11            var obj = {
     12                type: this._type,
     13                categories: [],
     14                code: "",
     15                content: [],
     16                title: ""
     17            };
     18            return obj;
    519        },
    6         DisplayTitle: {
    7             get: function(q) {
    8                 return q.title || '';
     20        _deserialize: function(obj) {
     21            if (obj.publicationDate) {
     22                obj.publicationDate = stamp.fromISOString(obj.publicationDate);
    923            }
    1024        },
    11         Content: {
    12             get: function(q) {
    13                 return q.content || [];
    14             },
    15             set: function(q,content) {
    16                 q.content = content;
     25        _serialize: function(obj) {
     26            if (obj.publicationDate) {
     27                obj.publicationDate = stamp.toISOString(obj.publicationDate);
    1728            }
    1829        }
    19     };
     30    });
     31
     32    return new Questions();
     33
    2034});
  • Dev/trunk/src/client/qed-client/model/classes/responses.js

    r486 r487  
    1 define([],function(){
    2     var SurveyRun = {
    3         create: function(){
    4             return { type:'Response' };
     1define([
     2    "./_Class",
     3    "./surveyRuns",
     4    "dojo/Deferred",
     5    "dojo/_base/declare",
     6    "dojo/_base/json",
     7    "dojo/_base/lang",
     8    "dojo/_base/xhr",
     9    "dojo/date/stamp"
     10], function(_Class, surveyRuns, Deferred, declare, json, lang, xhr, stamp) {
     11
     12    var Responses = declare([_Class],{
     13        _collection: 'responses',
     14        _type: 'Response',
     15        create: function() {
     16            var obj = {
     17                type: this._type,
     18                answers: {},
     19                surveyRunId: null
     20            };
     21            return obj;
    522        },
    6         SurveyRun: {
    7             get: function(r) {
    8                 return r.surveyRunId || null;
    9             },
    10             set: function(r,sr) {
    11                 r.surveyRunId = sr;
    12                 return r;
     23        _deserialize: function(obj) {
     24            if (obj._surveyRun) {
     25                obj._surveyRun = surveyRuns._doDeserialize(obj._surveyRun);
    1326            }
     27            if (obj.publicationDate) {
     28                obj.publicationDate = stamp.fromISOString(obj.publicationDate);
     29            }
     30        },
     31        _serialize: function(obj) {
     32            if (obj._surveyRun) {
     33                obj._surveyRun = surveyRuns._doSerialize(obj._surveyRun);
     34            }
     35            if (obj.publicationDate) {
     36                obj.publicationDate = stamp.toISOString(obj.publicationDate);
     37            }
     38        },
     39        getWithSecret: function(id,secret) {
     40            var query = xhr.objectToQuery({secret:secret});
     41            return xhr('GET',{
     42                url: '/api/open/responses/' + id + '?' + query,
     43                handleAs: 'json',
     44                contentType: false
     45            }).then(lang.hitch(this,'_doDeserialize'),function(err){
     46                return new Deferred().reject(json.fromJson(err.responseText));
     47            });
     48        },
     49        postWithSecret: function(response,secret) {
     50            var query = xhr.objectToQuery({secret:secret});
     51            var body = json.toJson(this._doSerialize(response));
     52            return xhr('POST',{
     53                url: '/api/open/responses?' + query,
     54                handleAs: 'json',
     55                contentType: 'application/json',
     56                rawBody: body
     57            }).then(lang.hitch(this,'_doDeserialize'),function(err){
     58                return new Deferred().reject(json.fromJson(err.responseText));
     59            });
     60        },
     61        putWithSecret: function(response,secret) {
     62            var query = xhr.objectToQuery({secret:secret});
     63            var body = json.toJson(this._doSerialize(response));
     64            return xhr('PUT',{
     65                url: '/api/open/responses/' + this.getId(response) + '?' + query,
     66                handleAs: 'json',
     67                contentType: 'application/json',
     68                rawBody: body
     69            }).then(lang.hitch(this,'_doDeserialize'),function(err){
     70                return new Deferred().reject(json.fromJson(err.responseText));
     71            });
     72        },
     73        removeWithSecret: function(response,secret) {
     74            var query = xhr.objectToQuery({secret:secret});
     75            var rev = this.getRev(response);
     76            var body = json.toJson(this._doSerialize(response));
     77            var headers = {};
     78            if ( rev ) {
     79                headers['If-Match'] = '"'+rev+'"';
     80            }
     81            return xhr('DELETE',{
     82                url: '/api/open/responses/' + this.getId(response) + '?' + query,
     83                headers: headers,
     84                handleAs: 'json',
     85                contentType: 'application/json',
     86                rawBody: body
     87            });
    1488        }
    15     };
    16     return SurveyRun;
     89    });
     90
     91    return new Responses();
     92
    1793});
  • Dev/trunk/src/client/qed-client/model/classes/surveyRuns.js

    r486 r487  
    1 define(['dojo/_base/lang','dojo/date/locale','dojo/date/stamp'],function(lang,locale,stamp){
    2     var SurveyRun = {
    3         create: function(){
    4             return { type:'SurveyRun' };
     1define([
     2    "./_Class",
     3    "./surveys",
     4    "dojo/_base/declare",
     5    "dojo/date/stamp"
     6], function(_Class, surveys, declare, stamp) {
     7
     8    var SurveyRuns = declare([_Class],{
     9        _collection: 'surveyRuns',
     10        _type: 'SurveyRun',
     11        create: function() {
     12            var obj = {
     13                type: this._type,
     14                description: "",
     15                mode: "open",
     16                survey: null,
     17                title: ""
     18            };
     19            return obj;
    520        },
    6         StartDate: {
    7             get: function(sr) {
    8                 var d;
    9                 if ( sr.startDate ) {
    10                     d = lang.isString(sr.startDate) ? stamp.fromISOString(sr.startDate) : sr.startDate;
    11                 }
    12                 return d;
    13             },
    14             set: function(sr,d) {
    15                 if ( d ) {
    16                     sr.startDate = lang.isString(d) ? stamp.toISOString(d) : d;
    17                 }
     21        _deserialize: function(obj) {
     22            if (obj.endDate) {
     23                obj.endDate = stamp.fromISOString(obj.endDate);
     24            }
     25            if (obj.startDate) {
     26                obj.startDate = stamp.fromISOString(obj.startDate);
     27            }
     28            if (obj.survey) {
     29                obj.survey = surveys._doDeserialize(obj.survey);
    1830            }
    1931        },
    20         EndDate: {
    21             get: function(sr) {
    22                 var d;
    23                 if ( sr.endDate ) {
    24                     d = lang.isString(sr.endDate) ? stamp.fromISOString(sr.endDate) : sr.endDate;
    25                 }
    26                 return d;
    27             },
    28             set: function(sr,d) {
    29                 if ( d ) {
    30                     sr.endDate = lang.isString(d) ? stamp.toISOString(d) : d;
    31                 }
     32        _serialize: function(obj) {
     33            if (obj.endDate) {
     34                obj.endDate = stamp.toISOString(obj.endDate);
    3235            }
    33         },
    34         DisplayTitle: {
    35             get: function(sr) {
    36                 var t = "Run of '"+sr.survey.title+"'";
    37                 if ( sr.startDate ) {
    38                     t += " from "+locale.format(SurveyRun.StartDate.get(sr));
    39                 }
    40                 if ( sr.endDate ) {
    41                     t += " until "+locale.format(SurveyRun.EndDate.get(sr));
    42                 }
    43                 return t;
     36            if (obj.startDate) {
     37                obj.startDate = stamp.toISOString(obj.startDate);
    4438            }
    45         },
    46         Survey: {
    47             get: function(sr) {
    48                 return sr.survey || null;
    49             },
    50             set: function(sr,s) {
    51                 sr.survey = s;
    52                 return sr;
     39            if (obj.survey) {
     40                obj.survey = surveys._doSerialize(obj.survey);
    5341            }
    5442        }
    55     };
    56     return SurveyRun;
     43    });
     44
     45    return new SurveyRuns();
     46
    5747});
  • Dev/trunk/src/client/qed-client/model/classes/surveys.js

    r486 r487  
    1 define(function(){
    2     return {
    3         create: function(){
    4             return { type:'Survey' };
     1define([
     2    "./_Class",
     3    "dojo/_base/declare",
     4    "dojo/date/stamp",
     5    "dojo/store/JsonRest"
     6], function(_Class, declare, stamp, JsonRest) {
     7
     8    var Surveys = declare([_Class],{
     9        _collection: 'surveys',
     10        _type: 'Survey',
     11        create: function() {
     12            var obj = {
     13                type: this._type,
     14                questions: [],
     15                title: ""
     16            };
     17            return obj;
    518        },
    6         DisplayTitle: {
    7             get: function(s) {
    8                 return s.title || '';
     19        _deserialize: function(obj) {
     20            if (obj.publicationDate) {
     21                obj.publicationDate = stamp.fromISOString(obj.publicationDate);
    922            }
    1023        },
    11         Questions: {
    12             get: function(s) {
    13                 return s.questions || [];
    14             },
    15             set: function(s,questions) {
    16                 s.questions = questions;
     24        _serialize: function(obj) {
     25            if (obj.publicationDate) {
     26                obj.publicationDate = stamp.toISOString(obj.publicationDate);
    1727            }
    1828        }
    19     };
     29    });
     30
     31    return new Surveys();
     32
    2033});
  • Dev/trunk/src/client/qed-client/model/widgets/QuestionEditorToolkit.js

    r443 r487  
    11define([
    2     "../../store",
     2    "../classes/categories",
     3    "../classes/topics",
    34    "./CategoryListView",
    45    "dijit/_Container",
     
    1516    "require",
    1617    "dojo/text!./templates/QuestionEditorToolkit.html"
    17 ], function(store, CategoryListView, _Container, _TemplatedMixin, _WidgetBase, _WidgetsInTemplateMixin, Button, ComboBox, declare, lang, Source, domConstruct, Memory, require, template) {
     18], function(categories, topics, CategoryListView, _Container, _TemplatedMixin, _WidgetBase, _WidgetsInTemplateMixin, Button, ComboBox, declare, lang, Source, domConstruct, Memory, require, template) {
    1819    return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _Container], {
    1920
     
    107108            this.inherited(arguments);
    108109
    109             store.query("_design/questions/_view/all", {reduce:true, group:false, group_level:1})
    110             .forPairs(lang.hitch(this, function(value, key) {
    111                 this._categoryStore.put({ id: key[0] });
     110            categories.query().forEach(lang.hitch(this,function(cat){
     111                this._categoryStore.put({ id: cat });
    112112            }));
    113113
    114             store.query("_design/questions/_view/all_topics", {reduce:true, group:true})
    115             .forPairs(lang.hitch(this, function(value, key) {
    116                 this._topicStore.put({ id: key });
     114            topics.query().forEach(lang.hitch(this,function(topic){
     115                this._categoryStore.put({ id: topic });
    117116            }));
    118117        },
  • Dev/trunk/src/client/qed-client/model/widgets/SurveyRenderWidget.js

    r461 r487  
    11define([
    22    "../../widgets/_ComplexValueWidget",
    3     "../classes/Survey",
    43    "./questions/Factory",
    54    "dojo/_base/array",
     
    76    "dojo/dom-construct",
    87    "dojo/text!./templates/SurveyRenderWidget.html"
    9 ], function(_ComplexValueWidget, Survey, QuestionWidgetFactory, array, declare, domConstruct, template) {
     8], function(_ComplexValueWidget, QuestionWidgetFactory, array, declare, domConstruct, template) {
    109    return declare([_ComplexValueWidget],{
    1110        templateString: template,
     
    2221            this.survey = survey;
    2322            var f = new QuestionWidgetFactory();
    24             array.forEach(Survey.Questions.get(this.survey),function(question,question_index){
     23            array.forEach(this.survey.questions,function(question,question_index){
    2524                array.forEach(question.content || [], function(item,item_index){
    2625                    // The dot causes values to be grouped in an object!
  • Dev/trunk/src/client/qed-client/model/widgets/SurveySummary.js

    r457 r487  
    11define([
    2     "../../store",
    3     "../classes/Survey",
    42    "dijit/_TemplatedMixin",
    53    "dijit/_WidgetBase",
     
    75    "dojo/dom-attr",
    86    "dojo/text!./templates/SurveySummary.html"
    9 ], function(store, Survey, _TemplatedMixin, _WidgetBase, declare, domAttr, template) {
     7], function(_TemplatedMixin, _WidgetBase, declare, domAttr, template) {
    108    return declare([_WidgetBase,_TemplatedMixin],{
    119        templateString: template,
     
    1816        },
    1917        _setValueAttr: function(survey) {
    20             this.titleNode.innerHTML = Survey.DisplayTitle.get(survey);
    21             var id = store.getIdentity(survey);
    22             domAttr.set(this.titleNode, "href", id && ("#!/survey/"+id));
     18            this.titleNode.innerHTML = survey.title || "";
     19            domAttr.set(this.titleNode, "href", survey._id && ("#!/survey/"+survey._id));
    2320            this.descriptionNode.innerHTML = survey.description;
    24             this.questionsNode.innerHTML = (survey.questions || []).length;
     21            this.questionsNode.innerHTML = survey.questions.length;
    2522        }
    2623    });
  • Dev/trunk/src/client/qed-client/model/widgets/TabbedQuestionBrowser.js

    r477 r487  
    11define([
    2     'dojo/_base/declare',
    3     'dojo/_base/lang',
    4     'dojo/_base/window',
    5     'dijit/layout/ContentPane',
    6     'dijit/layout/TabContainer',
    7     'dojox/widget/Standby',
    8     '../../store',
    9     '../../widgets/Selector'
    10 ],function(declare,lang,win,ContentPane,TabContainer,Standby,store,Selector){
     2    "../../widgets/Selector",
     3    "../classes/categories",
     4    "../classes/questions",
     5    "../classes/topics",
     6    "dijit/layout/ContentPane",
     7    "dijit/layout/TabContainer",
     8    "dojo/_base/declare",
     9    "dojo/_base/lang",
     10    "dojo/_base/window",
     11    "dojox/widget/Standby"
     12], function(Selector, categories, questions, topics, ContentPane, TabContainer, declare, lang, win, Standby) {
    1113    return declare([TabContainer],{
    1214        tabPosition: 'left-h',
     
    3840                this._fillCategoryTab(newTab.__category);
    3941            }));
    40             store.query(this._query, {reduce:true,group:true,group_level:1})
    41             .forPairs(lang.hitch(this,function(value,key){
    42                 this._createCategoryTab(key[0],value);
     42            categories.query()
     43            .forEach(lang.hitch(this,function(cat){
     44                this._createCategoryTab(cat.name,cat.count);
    4345            }));
    4446        },
     
    6163                this._busy();
    6264                categoryMap._filled = true;
    63                 store.query(this._query, {reduce:true,group:true,group_level:2,startkey:[category],endkey:[category,{}]})
    64                 .forPairs(lang.hitch(this,function(value,key){
    65                     this._createTopicSelector(key[1],category,value);
     65                topics.query({category:category})
     66                .forEach(lang.hitch(this,function(topic){
     67                    this._createTopicSelector(topic.name,category,topic.count);
    6668                })).then(lang.hitch(this,function(){
    6769                    this._done();
     
    101103                topicMap._filled = true;
    102104                this._busy();
    103                 store.query(this._query, {
    104                     reduce:false,
    105                     include_docs:true,
    106                     key:[category,topic]
    107                 }).forEach(lang.hitch(this,function(value){
     105                questions.query({category:category,topic:topic})
     106                .forEach(lang.hitch(this,function(value){
    108107                    topicMap._widget.addItem(value);
    109108                })).then(lang.hitch(this,function(){
Note: See TracChangeset for help on using the changeset viewer.