- Timestamp:
- 03/10/14 17:10:16 (11 years ago)
- Location:
- Dev/trunk/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
Dev/trunk/src/client/qed-client/model/widgets/TabbedQuestionBrowser.js
r495 r501 13 13 dndType: "question", 14 14 getCategories: function(){ 15 return categories.query(); 15 var opts = {}; 16 if ( this.include ) { opts[this.include] = true; } 17 return categories.query(opts); 16 18 }, 17 19 getCategoryName: function(category){ return category.name; }, 18 20 getCategoryCount: function(category){ return category.count; }, 19 21 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); 21 25 }, 22 26 getTopicName: function(topic){ return topic.name; }, 23 27 getTopicCount: function(topic){ return topic.count; }, 24 28 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); 33 32 }, 34 33 getItemName: function(item) { -
Dev/trunk/src/client/qed-client/widgets/ListWidget.js
r500 r501 9 9 "dojo/dnd/common", 10 10 "dojo/dom-construct", 11 "dojo/_base/event", 11 12 "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) { 13 14 return declare([_WidgetBase,_Container],{ 14 15 name: "", … … 58 59 lang.hitch(this,'_handleChange'))); 59 60 }, 61 create: function() { 62 this.inherited(arguments); 63 this._onChangeActive = true; 64 }, 60 65 creator: function(item, hint) { 61 66 var id = dnd.getUniqueId(); … … 74 79 } 75 80 } 76 this.own(on(nodeOrWidget,'change',lang.hitch(this,'_handleChange')));81 //this.own(on(nodeOrWidget,'change',lang.hitch(this,'_handleChange'))); 77 82 var node = nodeOrWidget.domNode ? nodeOrWidget.domNode : nodeOrWidget; 78 83 if ( hint !== "avatar" && node.id !== id ) { … … 122 127 appendItems: function(items,forceEvent) { 123 128 this.source.insertNodes(false,items); 124 if ( forceEvent ) { this._handle Change(); }129 if ( forceEvent ) { this._handleDrop(); } 125 130 }, 126 131 appendItem: function(item,forceEvent) { 127 132 this.source.insertNodes(false,[item]); 128 if ( forceEvent ) { this._handle Change(); }133 if ( forceEvent ) { this._handleDrop(); } 129 134 }, 130 135 removeItem: function(key,forceEvent) { … … 133 138 }), lang.hitch(this, "_destroyNodeOrWidget")); 134 139 this.source.delItem(key); 135 if ( forceEvent ) { this._handle Change(); }140 if ( forceEvent ) { this._handleDrop(); } 136 141 }, 137 142 getChildren: function() { … … 144 149 lang.hitch(this, "_destroyNodeOrWidget")); 145 150 this.source.clearItems(); 146 if ( forceEvent ) { this._handle Change(); }151 if ( forceEvent ) { this._handleDrop(); } 147 152 }, 148 153 _destroyNodeOrWidget: function(node) { -
Dev/trunk/src/server/app.js
r499 r501 136 136 } 137 137 138 function identity(obj) { return obj; } 138 139 function stripAndReturnPrivates(obj) { 139 140 var priv = {}; … … 146 147 return priv; 147 148 } 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 150 162 function handleUnknownResponse(status,error) { 151 163 return new HTTPResult(500,{error: error.reason}); … … 342 354 343 355 // 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'; 346 358 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}; 347 369 return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response, 348 370 handleUnknownError) … … 362 384 }); 363 385 } 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'; 366 388 var query = {reduce:false,include_docs:true,key:topic}; 367 389 return HTTPResult.fromResponsePromise(couch.get(url,{query:query}).response, … … 372 394 }); 373 395 } 374 function getQuestionsWithCategoryAndTopic(category,topic ) {396 function getQuestionsWithCategoryAndTopic(category,topic,sub) { 375 397 var hasTopic = typeof topic !== 'undefined'; 376 var url = '_design/questions/_view/ all';398 var url = '_design/questions/_view/'+(sub||'all'); 377 399 var query = {reduce:false,include_docs:true, 378 400 startkey:hasTopic?[category,topic]:[category], … … 389 411 ensureMIME(JSON_MIME), 390 412 function(req,res) { 413 var sub = 'published' in req.query && 'published'; 391 414 var hr; 392 415 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); 394 418 } else if ( 'topic' in req.query ) { 395 hr = getQuestionsWithTopic(req.query.topic );419 hr = getQuestionsWithTopic(req.query.topic,sub); 396 420 } 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); 398 424 } 399 425 hr.handle(res.send.bind(res)); … … 444 470 makeDocDel_id('Question')); 445 471 446 447 472 // 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'); 450 499 return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:2,startkey:[category],endkey:[category,{}]}}).response, 451 500 handleUnknownError) … … 461 510 ensureMIME(JSON_MIME), 462 511 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) 474 514 .handle(res.send.bind(res)); 475 515 }); … … 479 519 function(req,res) { 480 520 var category = req.params.category; 481 getTopicsWithCategory(category) 521 var sub = 'published' in req.query && 'published'; 522 getTopicsWithCategory(category,sub) 482 523 .handle(res.send.bind(res)); 483 524 }); … … 486 527 ensureMIME(JSON_MIME), 487 528 function(req,res) { 488 var url = '_design/questions/_view/all_topics';529 var sub = 'published' in req.query && 'published'; 489 530 var hr; 490 531 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); 501 535 } 502 536 hr.handle(res.send.bind(res)); … … 504 538 505 539 // 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 }512 540 app.get('/api/surveys', 513 541 ensureAuthenticated, … … 538 566 var doc = req.body; 539 567 var hr; 540 if ( !are SurveyQuestionsUnique(doc) ) {568 if ( !areDocsUnique(doc.questions) ) { 541 569 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."}); 542 572 } else { 543 573 hr = postDocument('Survey',doc); … … 557 587 var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); 558 588 var hr; 559 if ( !are SurveyQuestionsUnique(doc) ) {589 if ( !areDocsUnique(doc.questions) ) { 560 590 new HTTPResult(400,{error:"Survey contains duplicate questions."}) 561 591 .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."}); 562 594 } else { 563 595 putDocument(id,rev,'Survey',doc) … … 587 619 function(req,res) { 588 620 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)); 597 634 }); 598 635 app.get('/api/surveyRuns/:id', … … 608 645 var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); 609 646 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' ) { 611 650 hr = randomToken() 612 651 .handle({ -
Dev/trunk/src/server/config/couchdb-design-docs.js
r492 r501 96 96 reduce: function(key, values, rereduce) { return sum(values); } 97 97 }, 98 by_code: {98 all_by_code: { 99 99 map: function(doc){ 100 100 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; } 101 107 emit(doc.code,doc); 102 108 }
Note: See TracChangeset
for help on using the changeset viewer.