be2f588853c5686ccced5497910447246ea95e14
[mkws-moved-to-github.git] / src / mkws-widget-main.js
1 // Functions follow for promoting the regular widget object into
2 // widgets of specific types. These could be moved into their own
3 // source files.
4
5
6 mkws.registerWidgetType('Targets', function() {
7   if (!this.config.show_switch) return;
8   var that = this;
9
10   this.node.html('No information available yet.');
11   this.node.css("display", "none");
12
13   this.team.queue("targets").subscribe(function(data) {
14     // There is a bug in pz2.js wherein it makes each data object an array but
15     // simply assigns properties to it.
16     // TODO: remove this when PAZ-946 is addressed.
17     var cleandata = [];
18     for (var i = 0; i < data.length; i++) {
19       var cur = {};
20       cur.id = data[i].id;
21       cur.hits = data[i].hits;
22       cur.diagnostic = data[i].diagnostic;
23       cur.records = data[i].records;
24       cur.state = data[i].state;
25       cleandata.push(cur);
26     }
27
28     var template = that.team.loadTemplate(that.config.template || "Targets");
29     that.node.html(template({data: cleandata}));
30   });
31 });
32
33
34 mkws.registerWidgetType('Stat', function() {
35   var that = this;
36   this.team.queue("stat").subscribe(function(data) {
37     var template = that.team.loadTemplate(that.config.template || "Stat");
38     that.node.html(template(data));
39   });
40 });
41
42
43 mkws.registerWidgetType('Pager', function() {
44   var that = this;
45   var M = mkws.M;
46
47   this.team.queue("pager").subscribe(function(data) {
48     var teamName = that.team.name();
49     var output = {};
50     output.first = data.start + 1;
51     output.last = data.start + data.num;
52     output.count = data.merged;
53     output.found = data.total;
54
55     //client indexes pages from 1 but pz2 from 0
56     var onsides = 6;
57     var pages = Math.ceil(that.team.totalRecordCount() / that.team.perpage());
58     var currentPage = that.team.currentPage();
59
60     var firstClkbl = (currentPage - onsides > 0)
61       ? currentPage - onsides
62       : 1;
63     var lastClkbl = firstClkbl + 2*onsides < pages
64       ? firstClkbl + 2*onsides
65       : pages;
66
67     if (firstClkbl > 1) output.morePrev = true;
68     if (lastClkbl < pages) output.moreNext = true;
69
70     if (currentPage > 1) output.prevClick = "mkws.pagerPrev(\'" + teamName + "\');";
71
72     output.pages = [];
73     for(var i = firstClkbl; i <= lastClkbl; i++) {
74       var o = {};
75       o.number = i;
76       if (i !== currentPage) {
77         o.click = "mkws.showPage(\'" + teamName + "\', " + i + ");";
78       }
79       output.pages.push(o);
80     }
81
82     if (pages - currentPage > 0) output.nextClick = "mkws.pagerNext(\'" + teamName + "\')";
83
84     var template = that.team.loadTemplate(that.config.template || "Pager");
85     that.node.html(template(output));
86   });
87 });
88
89
90 mkws.registerWidgetType('Records', function() {
91   var that = this;
92   var team = this.team;
93
94   this.team.queue("records").subscribe(function(data) {
95     for (var i = 0; i < data.hits.length; i++) {
96       var hit = data.hits[i];
97       that.team.queue("record").publish(hit);
98       hit.detailLinkId = team.recordElementId(hit.recid[0]);
99       hit.detailClick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;"
100       hit.containerClass = "mkwsSummary mkwsTeam_" + team.name();
101       hit.containerClass += " " + hit.detailLinkId;
102       // ### At some point, we may be able to move the
103       // m_currentRecordId and m_currentRecordData members
104       // from the team object into this widget.
105       if (hit.recid == team.currentRecordId()) {
106         if (team.currentRecordData()) {
107           hit.renderedDetails = team.renderDetails(team.currentRecordData());
108           console.log(hit.renderedDetails); 
109         } 
110       }
111     }
112     var template = team.loadTemplate(that.config.template || "Records");
113     var targs = $.extend({}, {"hits": data.hits}, that.config.template_vars);
114     that.node.html(template(targs));
115   });
116
117   that.autosearch();
118 });
119
120
121 mkws.registerWidgetType('Navi', function() {
122   var that = this;
123   var teamName = this.team.name();
124   var M = mkws.M;
125
126   this.team.queue("navi").subscribe(function() {
127     var filters = that.team.filters();
128     var text = "";
129
130     filters.visitTargets(function(id, name) {
131       if (text) text += " | ";
132       text += M('source') + ': <a class="mkwsRemovable" href="#" onclick="mkws.delimitTarget(\'' + teamName +
133         "', '" + id + "'" + ');return false;">' + name + '</a>';
134     });
135
136     filters.visitFields(function(field, value) {
137       if (text) text += " | ";
138       text += M(field) + ': <a class="mkwsRemovable" href="#" onclick="mkws.delimitQuery(\'' + teamName +
139         "', '" + field + "', '" + value + "'" +
140         ');return false;">' + value + '</a>';
141     });
142
143     that.node.html(text);
144   });
145 });
146
147
148 // It seems this and the Perpage widget doen't need to subscribe to
149 // anything, since they produce events rather than consuming them.
150 //
151 mkws.registerWidgetType('Sort', function() {
152   var that = this;
153
154   this.node.change(function() {
155     that.team.set_sortOrder(that.node.val());
156     if (that.team.submitted()) {
157       that.team.reShow();
158     }
159     return false;
160   });
161 });
162
163
164 mkws.registerWidgetType('Perpage', function() {
165   var that = this;
166
167   this.node.change(function() {
168     that.team.set_perpage(that.node.val());
169     if (that.team.submitted()) {
170       that.team.reShow();
171     }
172     return false;
173   });
174 });
175
176
177 mkws.registerWidgetType('Done', function() {
178   var that = this;
179   this.team.queue("complete").subscribe(function(n) {
180     var template = that.team.loadTemplate(that.config.template || "Done");
181     that.node.html(template({count: n}));
182   });
183 });
184
185
186 mkws.registerWidgetType('Switch', function() {
187   if (!this.config.show_switch) return;
188   var tname = this.team.name();
189   var output = {};
190   output.recordClick = "mkws.switchView(\'" + tname + "\', \'records\')";
191   output.targetClick = "mkws.switchView(\'" + tname + "\', \'targets\')";
192   var template = this.team.loadTemplate(this.config.template || "Switch");
193   this.node.html(template(output));
194   this.hideWhenNarrow();
195 });
196
197
198 mkws.registerWidgetType('Search', function() {
199   var output = {};
200   output.team = this.team.name();
201   output.queryWidth = this.config.query_width;
202   var template = this.team.loadTemplate(this.config.template || "Search");
203   this.node.html(template(output));
204 });
205
206
207 mkws.registerWidgetType('SearchForm', function() {
208   var team = this.team;
209   this.node.submit(function() {
210     var val = team.widget('Query').value();
211     team.newSearch(val);
212     return false;
213   });
214 });
215
216
217 mkws.registerWidgetType('Results', function() {
218   var tname = this.team.name();
219
220   this.node.html('\
221 <table width="100%" border="0" cellpadding="6" cellspacing="0">\
222   <tr>\
223     <td class="mkwsTermlists-Container-wide mkwsTeam_' + tname + '" width="250" valign="top">\
224       <div class="mkwsTermlists mkwsTeam_' + tname + '"></div>\
225     </td>\
226     <td class="mkwsMOTDContainer mkwsTeam_' + tname + '" valign="top">\
227       <div class="mkwsRanking mkwsTeam_' + tname + '"></div>\
228       <div class="mkwsPager mkwsTeam_' + tname + '"></div>\
229       <div class="mkwsNavi mkwsTeam_' + tname + '"></div>\
230       <div class="mkwsRecords mkwsTeam_' + tname + '"></div>\
231     </td>\
232   </tr>\
233   <tr>\
234     <td colspan="2">\
235       <div class="mkwsTermlists-Container-narrow mkwsTeam_' + tname + '"></div>\
236     </td>\
237   </tr>\
238 </table>');
239
240   this.autosearch();
241 });
242
243
244 mkws.registerWidgetType('Ranking', function() {
245   var tname = this.team.name();
246   var that = this;
247   var M = mkws.M;
248
249   var s = '<form>';
250   if (this.config.show_sort) {
251     s +=  M('Sort by') + ' ' + mkwsHtmlSort() + ' ';
252   }
253   if (this.config.show_perpage) {
254     s += M('and show') + ' ' + mkwsHtmlPerpage() + ' ' + M('per page') + '.';
255   }
256   s += '</form>';
257
258   this.node.html(s);
259
260
261   function mkwsHtmlSort() {
262     var order = that.team.sortOrder();
263
264     that.log("making sort HTML, sortOrder = '" + order + "'");
265     var sort_html = '<select class="mkwsSort mkwsTeam_' + tname + '">';
266
267     for(var i = 0; i < that.config.sort_options.length; i++) {
268       var opt = that.config.sort_options[i];
269       var key = opt[0];
270       var val = opt.length == 1 ? opt[0] : opt[1];
271
272       sort_html += '<option value="' + key + '"';
273       if (order == key || order == val) {
274         sort_html += ' selected="selected"';
275       }
276       sort_html += '>' + M(val) + '</option>';
277     }
278     sort_html += '</select>';
279
280     return sort_html;
281   }
282
283   function mkwsHtmlPerpage() {
284     var perpage = that.team.perpage();
285
286     that.log("making perpage HTML, perpage = " + perpage);
287     var perpage_html = '<select class="mkwsPerpage mkwsTeam_' + tname + '">';
288
289     for(var i = 0; i < that.config.perpage_options.length; i++) {
290       var key = that.config.perpage_options[i];
291
292       perpage_html += '<option value="' + key + '"';
293       if (key == perpage) {
294         perpage_html += ' selected="selected"';
295       }
296       perpage_html += '>' + key + '</option>';
297     }
298     perpage_html += '</select>';
299
300     return perpage_html;
301   }
302 });
303
304
305 mkws.registerWidgetType('Lang', function() {
306   // dynamic URL or static page? /path/foo?query=test
307   /* create locale language menu */
308   if (!this.config.show_lang) return;
309
310   var lang_default = "en";
311   var lang = this.config.lang || lang_default;
312   var list = [];
313
314   /* display a list of configured languages, or all */
315   var lang_options = this.config.lang_options || [];
316   var toBeIncluded = {};
317   for (var i = 0; i < lang_options.length; i++) {
318     toBeIncluded[lang_options[i]] = true;
319   }
320
321   for (var k in mkws.locale_lang) {
322     if (toBeIncluded[k] || lang_options.length == 0)
323       list.push(k);
324   }
325
326   // add english link
327   if (lang_options.length == 0 || toBeIncluded[lang_default])
328     list.push(lang_default);
329
330   this.log("language menu: " + list.join(", "));
331
332   /* the HTML part */
333   var data = "";
334   for (var i = 0; i < list.length; i++) {
335     var l = list[i];
336     if (data)
337       data += ' | ';
338
339     if (lang == l) {
340       data += ' <span>' + l + '</span> ';
341     } else {
342       data += ' <a href="' + lang_url(l) + '">' + l + '</a> '
343     }
344   }
345
346   this.node.html(data);
347   this.hideWhenNarrow();
348
349
350   // set or re-set "lang" URL parameter
351   function lang_url(lang) {
352     var query = location.search;
353     // no query parameters? done
354     if (!query) {
355       return "?lang=" + lang;
356     }
357
358     // parameter does not exist
359     if (!query.match(/[\?&]lang=/)) {
360       return query + "&lang=" + lang;
361     }
362
363     // replace existing parameter
364     query = query.replace(/\?lang=([^&#;]*)/, "?lang=" + lang);
365     query = query.replace(/\&lang=([^&#;]*)/, "&lang=" + lang);
366     return query;
367   }
368 });
369
370
371 mkws.registerWidgetType('MOTD', function() {
372   var container = this.team.widget('MOTDContainer');
373   if (container) {
374     // Move the MOTD from the provided element down into the container
375     this.node.appendTo(container.node);
376   }
377 });
378
379
380 // This widget has no functionality of its own, but its configuration
381 // is copied up into its team, allowing it to affect other widgets in
382 // the team.
383 //
384 mkws.registerWidgetType('Config', function() {
385   var c = this.config;
386   for (var name in c) {
387     if (c.hasOwnProperty(name)) {
388       this.team.config[name] = c[name];
389       this.log(this + " copied property " + name + "='" + c[name] + "' up to team");
390     }
391   }
392 });
393
394
395 mkws.registerWidgetType('Progress', function() {
396   var that = this;
397
398   this.node.hide();
399   this.team.queue("stat").subscribe(function(data) {
400     var s = '<span class="mkwsDone">';
401     for (var i = 0; i < data.clients; i++) {
402       if (i == data.clients - data.activeclients) {
403         s += '</span>';
404         s += '<span class="mkwsWaiting">';
405       }
406       s += '&#x2588;';
407     }
408     s += '</span>';
409     that.node.html(s);
410     that.node.show();
411   });
412 });
413
414
415 // Some elements have mkws* classes that makes them appear as widgets
416 // -- for example, because we want to style them using CSS -- but have
417 // no actual functionality. We register these to prevent ignorable
418 // warnings when they occur.
419
420 mkws.registerWidgetType('Query', function() {});
421 mkws.registerWidgetType('MOTDContainer', function() {});
422 mkws.registerWidgetType('Button', function() {});
423
424