Changeset 501


Ignore:
Timestamp:
03/10/14 17:10:16 (11 years ago)
Author:
hendrikvanantwerpen
Message:
Location:
Dev/trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/src/client/qed-client/model/widgets/TabbedQuestionBrowser.js

    r495 r501  
    1313        dndType: "question",
    1414        getCategories: function(){
    15             return categories.query();
     15            var opts = {};
     16            if ( this.include ) { opts[this.include] = true; }
     17            return categories.query(opts);
    1618        },
    1719        getCategoryName: function(category){ return category.name; },
    1820        getCategoryCount: function(category){ return category.count; },
    1921        getTopics: function(category) {
    20             return topics.query({category:category.name});
     22            var opts = {category:category.name};
     23            if ( this.include ) { opts[this.include] = true; }
     24            return topics.query(opts);
    2125        },
    2226        getTopicName: function(topic){ return topic.name; },
    2327        getTopicCount: function(topic){ return topic.count; },
    2428        getItems: function(category,topic) {
    25             return questions.query({category:category.name,topic:topic.name})
    26             .then(lang.hitch(this,function(items){
    27                 return array.filter(items, function(item){
    28                     return (this.include === 'published' && item.publicationDate) ||
    29                            (this.include === 'drafts' && !item.publicationDate) ||
    30                            true;
    31                 }, this);
    32             }));
     29            var opts = {category:category.name,topic:topic.name};
     30            if ( this.include ) { opts[this.include] = true; }
     31            return questions.query(opts);
    3332        },
    3433        getItemName: function(item) {
  • Dev/trunk/src/client/qed-client/widgets/ListWidget.js

    r500 r501  
    99    "dojo/dnd/common",
    1010    "dojo/dom-construct",
     11    "dojo/_base/event",
    1112    "dojo/on"
    12 ], function(_Container, _WidgetBase, registry, array, declare, lang, Source, dnd, domConstruct, on) {
     13], function(_Container, _WidgetBase, registry, array, declare, lang, Source, dnd, domConstruct, event, on) {
    1314    return declare([_WidgetBase,_Container],{
    1415        name: "",
     
    5859                        lang.hitch(this,'_handleChange')));
    5960        },
     61        create: function() {
     62            this.inherited(arguments);
     63            this._onChangeActive = true;
     64        },
    6065        creator: function(item, hint) {
    6166            var id = dnd.getUniqueId();
     
    7479                }
    7580            }
    76             this.own(on(nodeOrWidget,'change',lang.hitch(this,'_handleChange')));
     81            //this.own(on(nodeOrWidget,'change',lang.hitch(this,'_handleChange')));
    7782            var node = nodeOrWidget.domNode ? nodeOrWidget.domNode : nodeOrWidget;
    7883            if ( hint !== "avatar" && node.id !== id ) {
     
    122127        appendItems: function(items,forceEvent) {
    123128            this.source.insertNodes(false,items);
    124             if ( forceEvent ) { this._handleChange(); }
     129            if ( forceEvent ) { this._handleDrop(); }
    125130        },
    126131        appendItem: function(item,forceEvent) {
    127132            this.source.insertNodes(false,[item]);
    128             if ( forceEvent ) { this._handleChange(); }
     133            if ( forceEvent ) { this._handleDrop(); }
    129134        },
    130135        removeItem: function(key,forceEvent) {
     
    133138            }), lang.hitch(this, "_destroyNodeOrWidget"));
    134139            this.source.delItem(key);
    135             if ( forceEvent ) { this._handleChange(); }
     140            if ( forceEvent ) { this._handleDrop(); }
    136141        },
    137142        getChildren: function() {
     
    144149                          lang.hitch(this, "_destroyNodeOrWidget"));
    145150            this.source.clearItems();
    146             if ( forceEvent ) { this._handleChange(); }
     151            if ( forceEvent ) { this._handleDrop(); }
    147152        },
    148153        _destroyNodeOrWidget: function(node) {
  • Dev/trunk/src/server/app.js

    r499 r501  
    136136    }
    137137   
     138    function identity(obj) { return obj; }
    138139    function stripAndReturnPrivates(obj) {
    139140        var priv = {};
     
    146147        return priv;
    147148    }
    148 
    149     function identity(obj) { return obj; }
     149    function areDocsUnique(docs) {
     150        return _.chain(docs)
     151                .map(function(doc){ return doc._id; })
     152                .uniq()
     153                .value().length === docs.length;
     154    }
     155    function areDocsPublished(docs) {
     156        return _.every(docs,isDocPublished);
     157    }
     158    function isDocPublished(doc) {
     159        return doc.publicationDate;
     160    }
     161
    150162    function handleUnknownResponse(status,error) {
    151163        return new HTTPResult(500,{error: error.reason});
     
    342354
    343355    // Questions
    344     function getQuestionsWithCode(code) {
    345         var url = '_design/questions/_view/by_code';
     356    function getQuestionsWithCode(code,sub) {
     357        var url = '_design/questions/_view/'+(sub||'all')+'_by_code';
    346358        var query = {include_docs:true,key:code};
     359        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
     360                                              handleUnknownError)
     361        .handle({
     362            200: handleRowDocs,
     363            default: handleUnknownResponse
     364        });
     365    }
     366    function getQuestions(sub) {
     367        var url = '_design/questions/_view/'+(sub||'all');
     368        var query = {include_docs:true};
    347369        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
    348370                                              handleUnknownError)
     
    362384        });
    363385    }
    364     function getQuestionsWithTopic(topic) {
    365         var url = '_design/questions/_view/all_topics';
     386    function getQuestionsWithTopic(topic,sub) {
     387        var url = '_design/questions/_view/'+(sub||'all')+'_topics';
    366388        var query = {reduce:false,include_docs:true,key:topic};
    367389        return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response,
     
    372394        });
    373395    }
    374     function getQuestionsWithCategoryAndTopic(category,topic) {
     396    function getQuestionsWithCategoryAndTopic(category,topic,sub) {
    375397        var hasTopic = typeof topic !== 'undefined';
    376         var url = '_design/questions/_view/all';
     398        var url = '_design/questions/_view/'+(sub||'all');
    377399        var query = {reduce:false,include_docs:true,
    378400                     startkey:hasTopic?[category,topic]:[category],
     
    389411        ensureMIME(JSON_MIME),
    390412        function(req,res) {
     413            var sub = 'published' in req.query && 'published';
    391414            var hr;
    392415            if ( 'category' in req.query ) {
    393                 hr = getQuestionsWithCategoryAndTopic(req.query.category,req.query.topic);
     416                hr = getQuestionsWithCategoryAndTopic(req.query.category,
     417                                                      req.query.topic,sub);
    394418            } else if ( 'topic' in req.query ) {
    395                 hr = getQuestionsWithTopic(req.query.topic);
     419                hr = getQuestionsWithTopic(req.query.topic,sub);
    396420            } else if ( 'code' in req.query ) {
    397                 hr = getQuestionsWithCode(req.query.code);
     421                hr = getQuestionsWithCode(req.query.code,sub);
     422            } else {
     423                hr = getQuestions(sub);
    398424            }
    399425            hr.handle(res.send.bind(res));
     
    444470        makeDocDel_id('Question'));
    445471
    446 
    447472    // Categories and topics
    448     function getTopicsWithCategory(category) {
    449         var url = '_design/questions/_view/all';
     473    function getTopics(sub) {
     474        var url = '_design/questions/_view/'+(sub||'all')+'_topics';
     475        return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true}}).response,
     476                                            handleUnknownError)
     477        .handle({
     478            200: function(result) {
     479                return _.map(result.rows, function(item) { return {name:item.key, count:item.value}; });
     480            },
     481            default: handleUnknownResponse
     482        });
     483    }
     484    function getCategories(sub) {
     485        var url = '_design/questions/_view/'+(sub||'all');
     486        return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:1}}).response,
     487                                       handleUnknownError)
     488        .handle({
     489            200: function(result) {
     490                return _.map(result.rows, function(item) {
     491                    return { name:item.key[0], count:item.value };
     492                });
     493            },
     494            default: handleUnknownResponse
     495        });
     496    }
     497    function getTopicsWithCategory(category,sub) {
     498        var url = '_design/questions/_view/'+(sub||'all');
    450499        return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:2,startkey:[category],endkey:[category,{}]}}).response,
    451500                                       handleUnknownError)
     
    461510        ensureMIME(JSON_MIME),
    462511        function(req,res) {
    463             var url = '_design/questions/_view/all';
    464             HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:1}}).response,
    465                                            handleUnknownError)
    466             .handle({
    467                 200: function(result) {
    468                     return _.map(result.rows, function(item) {
    469                         return { name:item.key[0], count:item.value };
    470                     });
    471                 },
    472                 default: handleUnknownResponse
    473             })
     512            var sub = 'published' in req.query && 'published';
     513            getCategories(sub)
    474514            .handle(res.send.bind(res));
    475515        });
     
    479519        function(req,res) {
    480520            var category = req.params.category;
    481             getTopicsWithCategory(category)
     521            var sub = 'published' in req.query && 'published';
     522            getTopicsWithCategory(category,sub)
    482523            .handle(res.send.bind(res));
    483524        });
     
    486527        ensureMIME(JSON_MIME),
    487528        function(req,res) {
    488             var url = '_design/questions/_view/all_topics';
     529            var sub = 'published' in req.query && 'published';
    489530            var hr;
    490531            if ( 'category' in req.query ) {
    491                 hr = getTopicsWithCategory(req.query.category);
    492             } else {
    493                 hr = HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true}}).response,
    494                                                     handleUnknownError)
    495                 .handle({
    496                     200: function(result) {
    497                         return _.map(result.rows, function(item) { return {name:item.key, count:item.value}; });
    498                     },
    499                     default: handleUnknownResponse
    500                 });
     532                hr = getTopicsWithCategory(req.query.category,sub);
     533            } else {
     534                hr = getTopics(sub);
    501535            }
    502536            hr.handle(res.send.bind(res));
     
    504538
    505539    // Surveys
    506     function areSurveyQuestionsUnique(survey) {
    507         return _.chain(survey.questions)
    508                 .map(function(q){ return q.code; })
    509                 .uniq()
    510                 .value().length === survey.questions.length;
    511     }
    512540    app.get('/api/surveys',
    513541        ensureAuthenticated,
     
    538566            var doc = req.body;
    539567            var hr;
    540             if ( !areSurveyQuestionsUnique(doc) ) {
     568            if ( !areDocsUnique(doc.questions) ) {
    541569                hr = new HTTPResult(400,{error:"Survey contains duplicate questions."});
     570            } else if ( !areDocsPublished(doc.questions) || isDocPublished(doc) ) {
     571                hr = new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."});
    542572            } else {
    543573                hr = postDocument('Survey',doc);
     
    557587            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
    558588            var hr;
    559             if ( !areSurveyQuestionsUnique(doc) ) {
     589            if ( !areDocsUnique(doc.questions) ) {
    560590                new HTTPResult(400,{error:"Survey contains duplicate questions."})
    561591                .handle(res.send.bind(res));
     592            } else if ( !areDocsPublished(doc.questions) || isDocPublished(doc) ) {
     593                hr = new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."});
    562594            } else {
    563595                putDocument(id,rev,'Survey',doc)
     
    587619        function(req,res) {
    588620            var doc = req.body;
    589             randomToken()
    590             .handle({
    591                 201: function(token) {
    592                     doc.secret = token;
    593                     return postDocument('SurveyRun',doc);
    594                 }
    595             })
    596             .handle(res.send.bind(res));
     621            var hr;
     622            if ( !isDocPublished(doc.survey) ) {
     623                hr = new HTTPResult(400,{error:"Cannot run unpublished survey."});
     624            } else {
     625                hr = randomToken()
     626                .handle({
     627                    201: function(token) {
     628                        doc.secret = token;
     629                        return postDocument('SurveyRun',doc);
     630                    }
     631                });
     632            }
     633            hr.handle(res.send.bind(res));
    597634        });
    598635    app.get('/api/surveyRuns/:id',
     
    608645            var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev);
    609646            var hr;
    610             if ( typeof doc.secret === 'undefined' ) {
     647            if ( !isDocPublished(doc.survey) ) {
     648                hr = new HTTPResult(400,{error:"Cannot run unpublished survey."});
     649            } else if ( typeof doc.secret === 'undefined' ) {
    611650                hr = randomToken()
    612651                .handle({
  • Dev/trunk/src/server/config/couchdb-design-docs.js

    r492 r501  
    9696                reduce: function(key, values, rereduce) { return sum(values); }
    9797            },
    98             by_code: {
     98            all_by_code: {
    9999                map: function(doc){
    100100                    if ( doc.type !== 'Question' ) { return; }
     101                    emit(doc.code,doc);
     102                }
     103            },
     104            published_by_code: {
     105                map: function(doc){
     106                    if ( doc.type !== 'Question' || !doc.publicationDate ) { return; }
    101107                    emit(doc.code,doc);
    102108                }
Note: See TracChangeset for help on using the changeset viewer.