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/pages
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/client/qed-client/pages/previewSurvey.js

    r443 r487  
    11define([
    22    "../app/Page",
    3     "../store",
     3    "../model/classes/surveys",
    44    "dojo/_base/array",
    55    "dojo/_base/declare",
     
    88    "require",
    99    "dojo/text!./templates/previewSurvey.html"
    10 ], function(Page, store, array, declare, lang, when, require, template) {
     10], function(Page, surveys, array, declare, lang, when, require, template) {
    1111    return declare([Page],{
    1212        contextRequire: require,
     
    1616            this.inherited(arguments);
    1717            if ( this.surveyId ) {
    18                 when(store.get(this.surveyId))
     18                when(surveys.load(this.surveyId))
    1919                .then(lang.hitch(this,function(survey){
    20                     this.titleNode.innerHTML = survey.title;
     20                    this.titleNode.innerHTML = survey.title || "";
    2121                    this.surveyWidget.set('survey',survey);
    2222                }));
  • Dev/trunk/src/client/qed-client/pages/question.js

    r443 r487  
    33    "../app/Page",
    44    "../app/Router",
    5     "../model/classes/Question",
     5    "../model/classes/questions",
    66    "../model/widgets/QuestionEditorPreview",
    77    "../model/widgets/QuestionEditorToolkit",
    8     "../store",
    98    "../widgets/_ComplexValueMixin",
    109    "dojo/_base/declare",
     
    1312    "dojo/when",
    1413    "dojo/text!./templates/question.html"
    15 ], function(Content, Page, Router, Question, QuestionEditorPreview, QuestionEditorToolkit, store, _ComplexValueMixin, declare, event, lang, when, template) {
     14], function(Content, Page, Router, questions, QuestionEditorPreview, QuestionEditorToolkit, _ComplexValueMixin, declare, event, lang, when, template) {
    1615    return declare([Page,_ComplexValueMixin], {
    1716        templateString: template,
     
    4342            }
    4443            if (this.questionId === "new") {
    45                 this.set('value', Question.create());
     44                this.set('value', questions.create());
    4645            } else {
    47                 when(store.get(this.questionId))
     46                when(questions.load(this.questionId))
    4847                .then(lang.hitch(this, function(value) {
    4948                    this.set('value', value);
     
    5453            this.value = value;
    5554            this.inherited(arguments);
    56             this.titleNode.innerHTML = Question.DisplayTitle.get(value);
     55            this.titleNode.innerHTML = value.title || "";
    5756        },
    5857        _getValueAttr: function() {
     
    6362        _onSave: function(evt) {
    6463            if ( this.validate() ) {
    65                 var value = this.get('value');
    66                 store.put(value)
     64                questions.save(this.get('value'))
    6765                .then(function() {
    6866                    Router.go('/questions');
  • Dev/trunk/src/client/qed-client/pages/questions.js

    r443 r487  
    11define([
    2     'dojo/_base/declare',
    3     'dojo/_base/Deferred',
    4     'dojo/_base/event',
    5     'dojo/_base/lang',
    6     '../store',
    7     '../app/Content',
    8     '../app/Router',
    9     '../app/Page',
    10     '../model/widgets/TabbedQuestionBrowser',
    11     'dojo/text!./templates/questions.html'
    12 ],function(declare,Deferred,event,lang,store,Content,Router,Page,TabbedQuestionBrowser,template) {
     2    "../app/Content",
     3    "../app/Page",
     4    "../app/Router",
     5    "../model/classes/questions",
     6    "../model/widgets/TabbedQuestionBrowser",
     7    "dojo/_base/Deferred",
     8    "dojo/_base/declare",
     9    "dojo/_base/event",
     10    "dojo/_base/lang",
     11    "dojo/text!./templates/questions.html"
     12], function(Content, Page, Router, questions, TabbedQuestionBrowser, Deferred, declare, event, lang, template) {
    1313    return declare([Page],{
    1414        templateString: template,
     
    4444        },
    4545        onDeleteQuestion: function(question) {
    46             store.remove(store.getIdentity(question),store.getRevision(question))
     46            questions.remove(question)
    4747            .then(function(){
    4848                Content.notify("Question deleted.");
     
    5555        },
    5656        onPublishQuestion: function(question) {
    57             question.publicationDate = store.timestamp();
    58             store.put(question)
     57            question.publicationDate = new Date();
     58            questions.save(question)
    5959            .then(function(){
    6060                Content.notify("Question published.");
  • Dev/trunk/src/client/qed-client/pages/response.js

    r478 r487  
    33    "../app/Page",
    44    "../lib/async",
    5     "../model/classes/Response",
    6     "../model/classes/Survey",
    7     "../model/classes/SurveyRun",
    8     "../store",
     5    "../model/classes/responses",
    96    "dojo/_base/declare",
    107    "dojo/_base/event",
     
    1613    "require",
    1714    "dojo/text!./templates/response.html"
    18 ], function(Content, Page, async, Response, Survey, SurveyRun, store, declare, event, json, lang, all, request, when, require, template) {
     15], function(Content, Page, async, responses, declare, event, json, lang, all, request, when, require, template) {
    1916    return declare([Page],{
    2017        contextRequire: require,
     
    2825            this.inherited(arguments);
    2926            this._disableSubmit();
    30             var surveyRunId = this.surveyRunId;
    31             var responseId = this.options && this.options.id;
    32             if ( surveyRunId && responseId ) {
    33                 this._loadSurveyAndResponse(surveyRunId,responseId)
    34                 .then(lang.hitch(this, function() {
    35                     if ( this.response.publicationDate ) {
    36                         this._showInfo("<div>You already submitted your survey and cannot change it anymore. You can still view your answers here.</div>");
    37                         this._disableSubmit();
    38                     } else {
    39                         this._enableSubmit();
    40                     }
    41                 }), lang.hitch(this,function() {
    42                     this._showInfo("<div>The url seems to be incorrect, no survey found.</div>");
    43                 }));
     27            if ( !this.response ) {
     28                this._showInfo("<div>The url seems to be incorrect, no response found.</div>");
    4429            } else {
    45                 throw new Error("No valid uid or survey passed!");
     30                this.titleNode.innerHTML = this.response._surveyRun.survey.title || "";
     31                this.surveyWidget.set('survey', this.response._surveyRun.survey);
     32                this.surveyWidget.set('value', this.response.answers || {});
     33                if ( this.response.publicationDate ) {
     34                    this._showInfo("<div>You already submitted your survey and cannot change it anymore. You can still view your answers here.</div>");
     35                    this._disableSubmit();
     36                } else {
     37                    this._enableSubmit();
     38                }
    4639            }
    47         },
    48         _loadSurveyAndResponse: function(surveyRunId,responseId){
    49             return all([request.get('/api/surveyRuns/'+surveyRunId,{handleAs:'json'}),
    50                         request.get('/api/responses/'+responseId,{handleAs:'json'})])
    51             .then(lang.hitch(this,function(surveyAndResponse){
    52                 var surveyRun = surveyAndResponse[0];
    53                 this.response = surveyAndResponse[1];
    54                 if ( this.response.surveyRunId !== surveyRunId ) {
    55                     throw "Survey does not match the response...";
    56                 }
    57                 this.titleNode.innerHTML = Survey.DisplayTitle.get(surveyRun.survey);
    58                 this.surveyWidget.set('survey', surveyRun.survey);
    59                 this.surveyWidget.set('value', this.response.answers || {});
    60             }));
    6140        },
    6241        _enableSubmit: function() {
     
    7857            var answers = this.surveyWidget.get('value');
    7958            this.response.answers = answers;
    80             return request.put('/api/responses/'+store.getIdentity(this.response),{
    81                 handleAs:'json',
    82                 data:json.toJson(this.response),
    83                 headers:{"Content-Type": "application/json"}
    84             }).then(lang.hitch(this,function(res){
    85                 this.response._rev = res.rev;
     59            return responses.putWithSecret(this.response,this.response.secret)
     60            .then(lang.hitch(this,function(response){
     61                this.response = response;
    8662                Content.notify("Your response is saved.");
    8763            }), function(err){
     
    9066        },
    9167        _onSubmit: function(e) {
    92             this.response.publicationDate = store.timestamp();
     68            this.response.publicationDate = new Date();
    9369            this._getAnswersAndSaveResponse()
    9470            .then(lang.hitch(this,function(){
     
    11086            this._disableSubmit();
    11187            this.surveyWidget.destroy();
    112             request('/api/responses/'+store.getIdentity(this.response)+'?rev='+store.getRevision(this.response),{
    113                 method: 'DELETE',
    114                 handleAs:'json',
    115                 data:json.toJson(this.response),
    116                 headers:{"Content-Type": "application/json"}
    117             }).then(lang.hitch(this,function(res){
     88            responses.removeWithSecret(this.response,this.response.secret)
     89            .then(lang.hitch(this,function(res){
    11890                this._showInfo("<div>Your response has been deleted, no answers have been saved.</div>");
    11991                Content.notify("Your response is deleted.");
  • Dev/trunk/src/client/qed-client/pages/session.js

    r443 r487  
    11define([
    2     'dojo/_base/array',
     2    /*'dojo/_base/array',
    33    'dojo/_base/declare',
    44    'dojo/_base/event',
     
    1212    '../model/classes/SessionTemplate',
    1313    '../model/widgets/AccountListView',
    14     'dojo/text!./templates/session.html'
     14    'dojo/text!./templates/session.html'*/
    1515],function(array,declare,event,lang,when,search,store,Page,Router,ThresholdFilteringSelect,SessionTemplate,AccountListView,template){
    16     return declare([Page],{
     16    /*return declare([Page],{
    1717        templateString: template,
    1818        session: null,
     
    9292
    9393
    94     });
     94    });*/
    9595});
    9696
  • Dev/trunk/src/client/qed-client/pages/sessions.js

    r443 r487  
    11define([
    2     'dojo/_base/declare',
     2    /*'dojo/_base/declare',
    33    'dojo/_base/lang',
    44    'dojo/date/stamp',
     
    77    '../app/Page',
    88    '../widgets/ObjectBox',
    9     'dojo/text!./templates/sessions.html'
     9    'dojo/text!./templates/sessions.html'*/
    1010],function(declare,lang,dateStamp,store,Router,Page,ObjectBox,template){
    11     return declare([Page],{
     11    /*return declare([Page],{
    1212        templateString: template,
    1313        templateActions: null,
     
    1818            this.templateActions = {
    1919                "Edit": function(obj){
    20                     Router.go('/session/'+store.getIdentity(obj));
     20                    Router.go('/session/'+obj.get('id'));
    2121                },
    2222                "Delete": lang.hitch(this,function(obj){
    23                     store.remove(store.getIdentity(obj),store.getRevision(obj))
     23                    obj.remove()
    2424                    .then(lang.hitch(this,function(){
    2525                        this._refresh();
     
    3030            this.sessionActions = {
    3131                "Facilitate": function(obj){
    32                     Router.go('run',{uid:store.getIdentity(obj)});
     32                    Router.go('run',{uid: obj.get('id')});
    3333                },
    3434                "Delete": lang.hitch(this,function(obj){
    35                     store.remove(store.getIdentity(obj),store.getRevision(obj))
     35                    obj.remove()
    3636                    .then(lang.hitch(this,function(){
    3737                        this._refresh();
     
    4848        },
    4949        _refreshByType: function(type,container,actions) {
     50            // FIXME
    5051            store.query("_design/default/_view/by_type",{key:type})
    5152            .forEach(lang.hitch(this,function(obj){
     
    6162        },
    6263        _publishSession: function(sessionTemplate) {
     64            // FIXME
    6365            var session = lang.clone(sessionTemplate);
    6466            delete session[store.idProperty];
     
    7375            }));
    7476        }
    75     });
     77    });*/
    7678});
  • Dev/trunk/src/client/qed-client/pages/survey.js

    r443 r487  
    22    "../app/Page",
    33    "../app/Router",
    4     "../model/classes/Survey",
     4    "../model/classes/surveys",
    55    "../model/widgets/QuestionListView",
    66    "../model/widgets/TabbedQuestionBrowser",
    7     "../store",
    87    "dojo/_base/array",
    98    "dojo/_base/declare",
     
    1312    "require",
    1413    "dojo/text!./templates/survey.html"
    15 ], function(Page, Router, Survey, QuestionListView, TabbedQuestionBrowser, store, array, declare, event, lang, when, require, template) {
     14], function(Page, Router, surveys, QuestionListView, TabbedQuestionBrowser, array, declare, event, lang, when, require, template) {
    1615    return declare([Page],{
    1716        contextRequire: require,
     
    6362        _loadSurvey: function() {
    6463            if ( this.surveyId === "new" ) {
    65                 this.survey = Survey.create();
     64                this.survey = surveys.create();
    6665                this.refresh();
    6766            } else {
    68                 when(store.get(this.surveyId))
     67                when(surveys.load(this.surveyId))
    6968                .then(lang.hitch(this,function(survey){
    7069                    this.survey = survey;
    7170                    this.questionList.set('value',
    72                                           Survey.Questions.get(this.survey));
     71                                          this.survey.questions);
    7372                    this.refresh();
    7473                }));
     
    7978        },
    8079        refresh: function() {
    81             this.titleNode.innerHTML = Survey.DisplayTitle.get(this.survey) || "(set title in properties)";
     80            this.titleNode.innerHTML = this.survey.title || "(set title in properties)";
    8281            this.propertiesDialog.set('value',this.survey);
    8382        },
     
    10099        _onSave: function(evt) {
    101100            this.survey.questions = this.questionList.get('value');
    102             store.put(this.survey)
     101            surveys.save(this.survey)
    103102            .then(function() {
    104103                Router.go('/surveys');
     
    111110        },
    112111        _onShowPreview: function() {
    113             Router.go('/previewSurvey/'+store.getIdentity(this.survey),{
     112            Router.go('/previewSurvey/'+this.survey._id,{
    114113                preview: true
    115114            });
  • Dev/trunk/src/client/qed-client/pages/surveyRun.js

    r466 r487  
    44    "../app/Router",
    55    "../lib/func",
    6     "../model/classes/SurveyRun",
    7     "../store",
     6    "../model/classes/responses",
     7    "../model/classes/surveyRuns",
    88    "../widgets/LineWithActionsWidget",
     9    "dojo/_base/array",
    910    "dojo/_base/declare",
    1011    "dojo/_base/event",
     
    1314    "require",
    1415    "dojo/text!./templates/surveyRun.html"
    15 ], function(Content, Page, Router, func, SurveyRun, store, LineWithActionsWidget, declare, event, lang, when, require, template) {
     16], function(Content, Page, Router, func, responses, surveyRuns, LineWithActionsWidget, array, declare, event, lang, when, require, template) {
    1617    return declare([Page],{
    1718        contextRequire: require,
     
    2425            if ( this.surveyRunId ) {
    2526                this._loadSurveyRun();
    26                 this._loadResponses();
    2727            } else {
    2828                throw "No valid uid or survey passed!";
     
    3030        },
    3131        _loadSurveyRun: function() {
    32             when(store.get(this.surveyRunId))
     32            when(surveyRuns.load(this.surveyRunId))
    3333            .then(lang.hitch(this,function(surveyRun){
    3434                this.surveyRun = surveyRun;
    3535                this.refreshSurveyRun();
     36                this._loadResponses();
    3637            }));
    3738        },
    3839        refreshSurveyRun: function() {
    39             this.titleNode.innerHTML = SurveyRun.DisplayTitle.get(this.surveyRun);
    40             this.surveySummaryWidget.set('value',SurveyRun.Survey.get(this.surveyRun));
     40            this.titleNode.innerHTML = this.surveyRun.title || "";
     41            this.surveySummaryWidget.set('value',this.surveyRun.survey);
    4142            this.surveyRunWidget.set('value',this.surveyRun);
    4243            this._onPropChange();
    4344        },
    4445        _loadResponses: function() {
    45             when(store.query("_design/responses/_view/by_surveyrun",{key:this.surveyRunId}))
    46             .forEach(lang.hitch(this,function(response){
    47                 var actions = {
    48                     view: {
    49                         callback: function(){},
    50                         properties: {
    51                             title: "View response"
    52                         }
    53                     }
    54                 };
    55                 if ( !response.publicationDate ) {
    56                     actions.remove = {
    57                         callback: function(){},
    58                         properties: {
    59                             title: "Remove response"
     46            responses.query({surveyRunId:surveyRuns.getId(this.surveyRun)})
     47            .then(lang.hitch(this,function(allResponses){
     48                array.forEach(allResponses, function(response){
     49                    var actions = {
     50                        view: {
     51                            callback: function(){},
     52                            properties: {
     53                                title: "View response"
     54                            }
    6055                        }
    6156                    };
    62                 }
    63                 var w = new LineWithActionsWidget({
    64                     actions: actions
    65                 });
    66                 var responseId = store.getIdentity(response);
    67                 w.set('title',this._link(this._getResponseURL(this.surveyRunId,responseId),responseId));
    68                 w.placeAt(this.responsesNode);
     57                    if ( !response.publicationDate ) {
     58                        actions.remove = {
     59                            callback: function(){},
     60                            properties: {
     61                                title: "Remove response"
     62                            }
     63                        };
     64                    }
     65                    var w = new LineWithActionsWidget({
     66                        actions: actions
     67                    });
     68                    var rid = responses.getId(response);
     69                    w.set('title',this._link(this._buildResponseURL(response),rid),rid);
     70                    w.placeAt(this.responsesNode);
     71                }, this);
    6972            }));
    7073        },
     
    7376            if ( surveyRun.mode === "open" ) {
    7477                this.runURLNode.innerHTML =
    75                     this._link(this._getGeneralURL(store.getIdentity(this.surveyRun)));
     78                    this._link(this._buildGeneralURL(this.surveyRun));
    7679            } else {
    7780                this.runURLNode.innerHTML =
     
    7982            }
    8083        },
    81         _getGeneralURL: function(surveyRunId) {
    82             return 'response.html#!/'+surveyRunId;
     84        _buildGeneralURL: function(surveyRun) {
     85            return 'response.html#!/surveyRuns/'+surveyRuns.getId(surveyRun)+'!secret='+surveyRun.secret;
    8386        },
    84         _getResponseURL: function(surveyRunId,responseId) {
    85             return 'response.html#!/'+surveyRunId+'!id='+responseId;
     87        _buildResponseURL: function(response) {
     88            return 'response.html#!/responses/'+responses.getId(response)+'!secret='+response.secret;
    8689        },
    8790        _link: function(url,label) {
     
    9295                lang.mixin(this.surveyRun,this.surveyRunWidget.get('value'));
    9396
    94                 var SD = SurveyRun.StartDate;
    95                 var ED = SurveyRun.EndDate;
    96                 SD.set(this.surveyRun, SD.get(this.surveyRun));
    97                 ED.set(this.surveyRun, ED.get(this.surveyRun));
    98 
    99                 store.put(this.surveyRun)
     97                surveyRuns.save(this.surveyRun)
    10098                .then(function() {
    10199                    Router.go('/surveys');
  • Dev/trunk/src/client/qed-client/pages/surveys.js

    r443 r487  
    11define([
    2     'dojo/_base/array',
    3     'dojo/_base/declare',
    4     'dojo/_base/lang',
    5     'dojo/when',
    6     '../store',
    7     '../app/Content',
    8     '../app/Page',
    9     '../app/Router',
    10     '../model/classes/Survey',
    11     '../model/classes/SurveyRun',
    12     '../widgets/LineWithActionsWidget',
    13     'dojo/text!./templates/surveys.html'
    14 ],function(array,declare,lang,when,store,Content,Page,Router,Survey,SurveyRun,LineWithActionsWidget,template){
     2    "../app/Content",
     3    "../app/Page",
     4    "../app/Router",
     5    "../model/classes/surveys",
     6    "../model/classes/surveyRuns",
     7    "../widgets/LineWithActionsWidget",
     8    "dojo/_base/array",
     9    "dojo/_base/declare",
     10    "dojo/_base/lang",
     11    "dojo/when",
     12    "dojo/text!./templates/surveys.html"
     13], function(Content, Page, Router, surveys, surveyRuns, LineWithActionsWidget, array, declare, lang, when, template) {
    1514    return declare([Page],{
    1615        templateString: template,
     
    2524        _onPublishSurvey:function(survey){
    2625            var self = this;
    27             survey.publicationDate = store.timestamp();
    28             store.put(survey).then(function(){
     26            survey.publicationDate = new Date();
     27            surveys.save(survey)
     28            .then(function(){
    2929                self.refreshDrafts();
    3030                self.refreshPublished();
     
    3535        _onDeleteSurvey:function(survey){
    3636            var self = this;
    37             store.remove(store.getIdentity(survey),store.getRevision(survey))
     37            surveys.remove(survey)
    3838            .then(function(){
    3939                self.refreshDrafts();
     
    4343        },
    4444        _onEditSurvey:function(survey){
    45             Router.go('/survey/'+store.getIdentity(survey));
     45            Router.go('/survey/'+survey._id);
    4646        },
    4747        _onPreviewSurvey:function(survey){
    48             Router.go('/previewSurvey/'+store.getIdentity(survey));
     48            Router.go('/previewSurvey/'+survey._id);
    4949        },
    5050        _onRunSurvey:function(survey){
    51             var surveyRun = SurveyRun.create();
    52             SurveyRun.Survey.set(surveyRun,survey);
    53             store.put(surveyRun)
     51            var surveyRun = surveyRuns.create();
     52            surveyRun.survey = survey;
     53            surveyRuns.save(surveyRun)
    5454            .then(lang.hitch(this,function(surveyRun){
    5555                this._onRunDetails(surveyRun);
     
    5959        },
    6060        _onRunDetails: function(surveyRun) {
    61             Router.go('/surveyRun/'+store.getIdentity(surveyRun));
     61            Router.go('/surveyRun/'+surveyRun._id);
    6262        },
    6363        refresh: function() {
     
    6868        refreshDrafts: function() {
    6969            this.draftsContainer.set('content','');
    70             when(store.query("_design/surveys/_view/drafts"),
    71                     lang.hitch(this,function(surveys) {
     70            when(surveys.query({drafts:true}), lang.hitch(this,function(surveys) {
    7271                this.draftsTab.set('title','Drafts ('+surveys.length+')');
    7372                array.forEach(surveys,function(survey){
    7473                    var w = new LineWithActionsWidget({
    75                         title: Survey.DisplayTitle.get(survey) || '(unnamed)',
     74                        title: survey.title || '(unnamed)',
    7675                        actions: [{
    7776                            callback: lang.hitch(this,'_onPublishSurvey',survey),
     
    110109        refreshPublished: function() {
    111110            this.publishedContainer.set('content','');
    112             when(store.query("_design/surveys/_view/published"),
    113                     lang.hitch(this, function(surveys) {
     111            when(surveys.query({published:true}), lang.hitch(this, function(surveys) {
    114112                this.publishedTab.set('title','Published ('+surveys.length+')');
    115113                array.forEach(surveys,function(survey){
    116114                    var w = new LineWithActionsWidget({
    117                         title: Survey.DisplayTitle.get(survey),
     115                        title: survey.title || "",
    118116                        actions:[{
    119117                            callback: lang.hitch(this,'_onPreviewSurvey',survey),
     
    138136        refreshRuns: function() {
    139137            this.runsContainer.set('content','');
    140             when(store.query("_design/default/_view/by_type",{key:'SurveyRun'}),
    141                     lang.hitch(this,function(surveyRuns){
     138            when(surveyRuns.query(), lang.hitch(this,function(surveyRuns){
    142139                this.runsTab.set('title','Runs ('+surveyRuns.length+')');
    143140                array.forEach(surveyRuns,function(surveyRun){
    144141                    var w = new LineWithActionsWidget({
    145                         title: SurveyRun.DisplayTitle.get(surveyRun),
     142                        title: surveyRun.title || "",
    146143                        actions:[{
    147144                            callback: lang.hitch(this,'_onRunDetails',surveyRun),
Note: See TracChangeset for help on using the changeset viewer.