Changeset 495
- Timestamp:
- 03/10/14 00:47:38 (11 years ago)
- Location:
- Dev/trunk/src
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
Dev/trunk/src/client/qed-client/model/widgets/TabbedQuestionBrowser.js
r490 r495 1 1 define([ 2 "../../widgets/ Selector",2 "../../widgets/TabbedBrowser", 3 3 "../classes/categories", 4 4 "../classes/questions", 5 5 "../classes/topics", 6 "dijit/layout/ContentPane", 7 "dijit/layout/TabContainer", 6 "dojo/_base/array", 8 7 "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) { 13 return declare([TabContainer],{ 8 "dojo/_base/lang" 9 ], function(TabbedBrowser, categories, questions, topics, array, declare, lang) { 10 return declare([TabbedBrowser],{ 14 11 tabPosition: 'left-h', 15 include: 'all', 16 17 selectedActions: null, 18 itemActions: null, 12 include: null, 19 13 dndType: "question", 20 21 _dataMap: null, 22 _busyCount: 0, 23 constructor: function(){ 24 this.inherited(arguments); 25 this._dataMap = {}; 14 getCategories: function(){ 15 return categories.query(); 26 16 }, 27 startup: function() { 28 if ( this._started ){ return; } 29 this.inherited(arguments); 30 this._busyWidget = new Standby({ 31 target: this.domNode, 32 duration: 200 33 }).placeAt(win.body()); 34 this._busyWidget.startup(); 35 this.watch("selectedChildWidget",lang.hitch(this,function(name,oldTab,newTab){ 36 this._fillCategoryTab(newTab.__category); 37 })); 38 categories.query() 39 .forEach(lang.hitch(this,function(cat){ 40 this._createCategoryTab(cat.name,cat.count); 17 getCategoryName: function(category){ return category.name; }, 18 getCategoryCount: function(category){ return category.count; }, 19 getTopics: function(category) { 20 return topics.query({category:category.name}); 21 }, 22 getTopicName: function(topic){ return topic.name; }, 23 getTopicCount: function(topic){ return topic.count; }, 24 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); 41 32 })); 42 33 }, 43 _createCategoryTab: function(category,count) { 44 if (this._dataMap[category] === undefined) { 45 var categoryTab = new ContentPane({ 46 __category: category, 47 title: (category || '[No category]')+" ("+count+")" 48 }); 49 categoryTab.startup(); 50 this._dataMap[category] = { 51 _widget: categoryTab 52 }; 53 this.addChild(categoryTab); 54 } 55 }, 56 _fillCategoryTab: function(category) { 57 var categoryMap = this._dataMap[category]; 58 if (!categoryMap._filled) { 59 this._busy(); 60 categoryMap._filled = true; 61 topics.query({category:category}) 62 .forEach(lang.hitch(this,function(topic){ 63 this._createTopicSelector(topic.name,category,topic.count); 64 })).then(lang.hitch(this,function(){ 65 this._done(); 66 })); 67 } 68 }, 69 _createTopicSelector: function(topic,category,count){ 70 var categoryMap = this._dataMap[category]; 71 if (categoryMap[topic] === undefined) { 72 var w = new Selector({ 73 __category: category, 74 __topic: topic, 75 dndType: this.dndType, 76 title: (topic || '[No topic]')+" ("+count+")", 77 selectedActions: this.selectedActions, 78 itemActions: this.itemActions, 79 itemTitle: this._itemTitle 80 }).placeAt(categoryMap._widget.containerNode); 81 w.startup(); 82 categoryMap[topic] = { 83 _widget: w 84 }; 85 this._fillTopicSelector(topic,category); 86 } 87 }, 88 _itemTitle: function(item) { 34 getItemName: function(item) { 89 35 var title = '['+item.code+']'+item.title; 90 if ( this.include === 'all') {91 title += (item.publicationDate ?' (published on '+item.publicationDate+')':' (unpublished)');36 if ( !this.include ) { 37 title += (item.publicationDate ?' (published on '+item.publicationDate+')':' (unpublished)'); 92 38 } 93 39 return title; 94 40 }, 95 _fillTopicSelector: function(topic,category) { 96 var categoryMap = this._dataMap[category]; 97 var topicMap = categoryMap[topic]; 98 if (!topicMap._filled) { 99 topicMap._filled = true; 100 this._busy(); 101 questions.query({category:category,topic:topic}) 102 .forEach(lang.hitch(this,function(value){ 103 topicMap._widget.addItem(value); 104 })).then(lang.hitch(this,function(){ 105 this._done(); 106 })); 107 } 108 }, 109 _busy: function() { 110 if ( this._busyCount === 0 ) { 111 this._busyWidget.show(); 112 } 113 this._busyCount++; 114 }, 115 _done: function() { 116 if ( this._busyCount > 0 ) { 117 this._busyCount--; 118 if ( this._busyCount === 0 ) { 119 this._busyWidget.hide(); 120 } 121 } else { 122 console.warn('_done() was called more times than _busy().'); 123 } 124 }, 125 destroy: function() { 126 this._busyWidget.destroyRecursive(); 127 this.inherited(arguments); 41 areItemsEqual: function(i1,i2) { 42 return questions.getId(i1) === questions.getId(i2); 128 43 } 129 44 }); -
Dev/trunk/src/client/qed-client/model/widgets/questions/MultipleChoiceInputWidget.js
r462 r495 35 35 return value; 36 36 } else { 37 return value.choice ;37 return value.choice.length > 0; 38 38 } 39 39 }, … … 43 43 inherited.call(this,value); 44 44 } else { 45 inherited.call(this,{choice:value });45 inherited.call(this,{choice:value ? ["on"] : []}); 46 46 } 47 47 } -
Dev/trunk/src/client/qed-client/pages/questions.js
r490 r495 19 19 'class': 'orange', 20 20 dndType: null, 21 itemActions: { 22 Delete: { 23 callback: lang.hitch(this,"onDeleteQuestion"), 24 icon: 'Delete', 25 description: 'Delete question' 26 }, 27 Edit: { 28 callback: lang.hitch(this,"onEditQuestion"), 29 icon: 'Edit', 30 description: 'Edit question' 31 }, 32 Publish: { 33 callback: lang.hitch(this,"onPublishQuestion"), 34 icon: 'Publish', 35 description: 'Publish question' 21 getItemActions: lang.hitch(this,function(item) { 22 var actions = { 23 Edit: { 24 callback: lang.hitch(this,"onEditQuestion"), 25 icon: 'Edit', 26 description: 'Edit question' 27 } 28 }; 29 if ( !item.publicationDate ) { 30 lang.mixin(actions,{ 31 Delete: { 32 callback: lang.hitch(this,"onDeleteQuestion"), 33 icon: 'Delete', 34 description: 'Delete question' 35 }, 36 Publish: { 37 callback: lang.hitch(this,"onPublishQuestion"), 38 icon: 'Publish', 39 description: 'Publish question' 40 } 41 }); 36 42 } 37 } 43 return actions; 44 }) 38 45 },this.questionBrowser); 39 46 this.questionBrowser.startup(); … … 45 52 questions.remove(question) 46 53 .then(lang.hitch(this,function(){ 54 this.questionBrowser.removeItem(question); 47 55 this.notify("Question deleted."); 48 56 }),lang.hitch(this,function(err){ -
Dev/trunk/src/client/qed-client/pages/survey.js
r494 r495 31 31 'class': 'blue', 32 32 include: 'published', 33 selectedActions: { 34 "Include": { 35 callback: lang.hitch(this,this._includeQuestion), 36 icon: "Accept", 37 description: "Include in survey" 38 } 39 }, 40 itemActions: { 41 "Info": { 42 callback: function(item){ 43 if ( item.description ) { alert(item.description); } 44 }, 45 icon: "Inspect", 46 description: "Show item description" 47 } 48 } 33 getSelectedItemActions: lang.hitch(this,function() { 34 return { 35 "Include": { 36 callback: lang.hitch(this,this._includeQuestion), 37 icon: "Accept", 38 description: "Include in survey" 39 } 40 }; 41 }), 42 getItemActions: lang.hitch(this,function(item) { 43 return { 44 "Info": { 45 callback: lang.hitch(this,function(item){ 46 if ( item.description ) { alert(item.description); } 47 }), 48 icon: "Inspect", 49 description: "Show item description" 50 } 51 }; 52 }) 49 53 },this.questionBrowser); 50 54 this.questionBrowser.startup(); -
Dev/trunk/src/client/qed-client/widgets/Selector.js
r494 r495 64 64 var actions = {}; 65 65 var action = null; 66 if ( this.selectedActions !== null ) { 67 for (var actionName in this.selectedActions) { 68 if ( this.selectedActions.hasOwnProperty(actionName) ) { 69 action = this.selectedActions[actionName]; 66 var userActions = 67 lang.isFunction(this.selectedActions) ? 68 this.selectedActions() : 69 this.selectedActions; 70 if ( userActions ) { 71 for (var actionName in userActions) { 72 if ( userActions.hasOwnProperty(actionName) ) { 73 action = userActions[actionName]; 70 74 actions[actionName] = { 71 75 callback: action.callback && 72 lang.hitch(this,this._onSelectedAction,73 action.callback),76 lang.hitch(this,this._onSelectedAction, 77 action.callback), 74 78 properties: { 75 79 blockButton: true, … … 135 139 _onSelectedAction: function(callback) { 136 140 if (this._selectedItem && callback) { 137 callback(this._selectedItem );141 callback(this._selectedItem,this); 138 142 } 139 143 }, … … 171 175 } 172 176 }, 177 removeItem: function(item) { 178 var nodes = this._source ? 179 this._source.getAllNodes() : 180 this.optionsNode.childNodes; 181 baseArray.forEach(nodes, function(node) { 182 var widget = registry.byNode(node); 183 if ( widget && this.itemEquals ? 184 this.itemEquals(widget.__item,item) : 185 widget.__item === item ) { 186 widget.destroyRecursive(); 187 if ( this._source ) { this._source.delItem(widget.id); } 188 } 189 }, this); 190 }, 173 191 _createNode: function(item, hint) { 174 192 var node = hint === "avatar" ? … … 188 206 _createLineNode: function(item) { 189 207 var actions = {}; 190 var action; 191 if (this.itemActions) { 192 for (var actionName in this.itemActions) { 193 if ( this.itemActions.hasOwnProperty(actionName) ) { 194 action = this.itemActions[actionName]; 208 var userActions = 209 lang.isFunction(this.itemActions) ? 210 this.itemActions(item) : 211 this.itemActions; 212 if (userActions) { 213 for (var actionName in userActions) { 214 if ( userActions.hasOwnProperty(actionName) ) { 215 var action = userActions[actionName]; 195 216 actions[actionName] = { 196 callback: action.callback && lang.partial(action.callback,item), 217 callback: action.callback && 218 lang.partial(action.callback,item,this), 197 219 properties: { 198 220 blockButton: false, … … 207 229 var w = new LineWithActionsWidget({ 208 230 title: get(this.itemTitle,item), 209 actions: actions 231 actions: actions, 232 __item: item 210 233 }); 211 234 w.startup(); … … 214 237 }, 215 238 216 onSelect: function(/*item*/) {} 239 onSelect: function(/*item*/) {}, 240 241 destroy: function() { 242 if ( this._source ) { this._source.destroy(); } 243 this.inherited(arguments); 244 } 217 245 }); 218 246 }); -
Dev/trunk/src/server/app.js
r492 r495 148 148 149 149 function identity(obj) { return obj; } 150 function handleUnknownResponse(status,error) {150 function handleUnknownResponse(status,error) { 151 151 return new HTTPResult(500,{error: error.reason}); 152 152 } … … 444 444 445 445 // Categories and topics 446 function getTopicsWithCategory(category) { 447 var url = '_design/questions/_view/all'; 448 return HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:2,startkey:[category],endkey:[category,{}]}}).response, 449 handleUnknownError) 450 .handle({ 451 200: function(result) { 452 return _.map(result.rows, function(item) { return { name:item.key[1], count:item.value }; }); 453 }, 454 default: handleUnknownResponse 455 }); 456 } 446 457 app.get('/api/categories', 447 458 ensureAuthenticated, … … 466 477 function(req,res) { 467 478 var category = req.params.category; 468 var url = '_design/questions/_view/all'; 469 HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true,group_level:2,startkey:[category],endkey:[category,{}]}}).response, 470 handleUnknownError) 471 .handle({ 472 200: function(result) { 473 return _.map(result.rows, function(item) { return { name:item.key[1], count:item.value }; }); 474 }, 475 default: handleUnknownResponse 476 }) 479 getTopicsWithCategory(category) 477 480 .handle(res.send.bind(res)); 478 481 }); … … 482 485 function(req,res) { 483 486 var url = '_design/questions/_view/all_topics'; 484 HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true}}).response, 485 handleUnknownError) 486 .handle({ 487 200: function(result) { 488 return _.map(result.rows, function(item) { return {name:item.key, count:item.value}; }); 489 }, 490 default: handleUnknownResponse 491 }) 492 .handle(res.send.bind(res)); 487 var hr; 488 if ( 'category' in req.query ) { 489 hr = getTopicsWithCategory(req.query.category); 490 } else { 491 hr = HTTPResult.fromResponsePromise(couch.get(url,{query:{reduce:true,group:true}}).response, 492 handleUnknownError) 493 .handle({ 494 200: function(result) { 495 return _.map(result.rows, function(item) { return {name:item.key, count:item.value}; }); 496 }, 497 default: handleUnknownResponse 498 }); 499 } 500 hr.handle(res.send.bind(res)); 493 501 }); 494 502
Note: See TracChangeset
for help on using the changeset viewer.