Template language widget
[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 template = this.team.loadTemplate(this.config.template || "Results");
219   this.node.html(template({team: this.team.name()}));
220   this.autosearch();
221 });
222
223
224 mkws.registerWidgetType('Ranking', function() {
225   var output = {};
226   output.perPage = [];
227   output.sort = [];
228   output.team = this.team.name();
229   output.showSort = this.config.show_sort;
230   output.showPerPage = this.config.show_perpage;
231
232   var order = this.team.sortOrder();
233   this.log("making sort, sortOrder = '" + order + "'");
234   for (var i = 0; i < this.config.sort_options.length; i++) {
235     var cur = {};
236     var opt = this.config.sort_options[i];
237     cur.key = opt[0];
238     cur.label = opt.length == 1 ? opt[0] : opt[1];
239     if (order == cur.key || order == cur.label) cur.selected = true;
240     output.sort.push(cur);
241   }
242
243   var perpage = this.team.perpage();
244   this.log("making perpage, perpage = " + perpage);
245   for(var i = 0; i < this.config.perpage_options.length; i++) {
246     var cur = {};
247     cur.perPage = this.config.perpage_options[i];
248     if (cur.perPage == perpage) cur.selected = true;
249     output.perPage.push(cur);
250   }
251
252   var template = this.team.loadTemplate(this.config.template || "Ranking");
253   this.node.html(template(output));
254 });
255
256
257 mkws.registerWidgetType('Lang', function() {
258   // dynamic URL or static page? /path/foo?query=test
259   /* create locale language menu */
260   if (!this.config.show_lang) return;
261
262   var lang_default = "en";
263   var lang = this.config.lang || lang_default;
264   var list = [];
265
266   /* display a list of configured languages, or all */
267   var lang_options = this.config.lang_options || [];
268   var toBeIncluded = {};
269   for (var i = 0; i < lang_options.length; i++) {
270     toBeIncluded[lang_options[i]] = true;
271   }
272
273   for (var k in mkws.locale_lang) {
274     if (toBeIncluded[k] || lang_options.length == 0) {
275       cur = {};
276       if (lang === k) cur.selected = true;
277       cur.code = k;
278       cur.url = lang_url(k);
279       list.push(cur);
280     }
281   }
282
283   // add english link
284   if (lang_options.length == 0 || toBeIncluded[lang_default]) {
285       cur = {};
286       if (lang === lang_default) cur.selected = true;
287       cur.code = lang_default;
288       cur.url = lang_url(lang_default);
289       list.push(cur);
290   }
291
292   this.log("language menu: " + list.join(", "));
293
294   var template = this.team.loadTemplate(this.config.template || "Lang");
295   this.node.html(template({languages: list}));
296   this.hideWhenNarrow();
297
298   // set or re-set "lang" URL parameter
299   function lang_url(lang) {
300     var query = location.search;
301     // no query parameters? done
302     if (!query) {
303       return "?lang=" + lang;
304     }
305
306     // parameter does not exist
307     if (!query.match(/[\?&]lang=/)) {
308       return query + "&lang=" + lang;
309     }
310
311     // replace existing parameter
312     query = query.replace(/\?lang=([^&#;]*)/, "?lang=" + lang);
313     query = query.replace(/\&lang=([^&#;]*)/, "&lang=" + lang);
314     return query;
315   }
316 });
317
318
319 mkws.registerWidgetType('MOTD', function() {
320   var container = this.team.widget('MOTDContainer');
321   if (container) {
322     // Move the MOTD from the provided element down into the container
323     this.node.appendTo(container.node);
324   }
325 });
326
327
328 // This widget has no functionality of its own, but its configuration
329 // is copied up into its team, allowing it to affect other widgets in
330 // the team.
331 //
332 mkws.registerWidgetType('Config', function() {
333   var c = this.config;
334   for (var name in c) {
335     if (c.hasOwnProperty(name)) {
336       this.team.config[name] = c[name];
337       this.log(this + " copied property " + name + "='" + c[name] + "' up to team");
338     }
339   }
340 });
341
342
343 mkws.registerWidgetType('Progress', function() {
344   var that = this;
345
346   this.node.hide();
347   this.team.queue("stat").subscribe(function(data) {
348     var s = '<span class="mkwsDone">';
349     for (var i = 0; i < data.clients; i++) {
350       if (i == data.clients - data.activeclients) {
351         s += '</span>';
352         s += '<span class="mkwsWaiting">';
353       }
354       s += '&#x2588;';
355     }
356     s += '</span>';
357     that.node.html(s);
358     that.node.show();
359   });
360 });
361
362
363 // Some elements have mkws* classes that makes them appear as widgets
364 // -- for example, because we want to style them using CSS -- but have
365 // no actual functionality. We register these to prevent ignorable
366 // warnings when they occur.
367
368 mkws.registerWidgetType('Query', function() {});
369 mkws.registerWidgetType('MOTDContainer', function() {});
370 mkws.registerWidgetType('Button', function() {});
371
372