0358f33da1aa20a1be23abf4703a9cbd8c164ce0
[nit.git] / contrib / opportunity / src / templates / meetup.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License
14
15 # Shows a meetup and allows to modify its participants
16 module meetup is i18n
17
18 import opportunity_model
19 import boilerplate
20 import welcome
21 import template
22
23 # Shows a meetup and allows to modify its participants
24 class OpportunityMeetupPage
25 super OpportunityPage
26
27 # Meetup the page is supposed to show
28 var meetup: nullable Meetup = null
29 # Answer mode for the meetup
30 var mode = 0
31
32 init from_id(id: String) do
33 var db = new OpportunityDB.open("opportunity")
34 meetup = db.find_meetup_by_id(id)
35 db.close
36 if meetup != null then mode = meetup.answer_mode
37 init
38 end
39
40 init do
41 header.page_js = "mode = {mode};\n"
42 header.page_js += """
43 function update_scores(){
44 var anss = $('.answer');
45 var count = {};
46 var scores = {};
47 var answers = [];
48 var maxscore = 0;
49 for(i=0; i < anss.length; i++){
50 var incscore = 0;
51 var inccount = 0;
52 var idparts = anss[i].id.split("_");
53 var ansid = idparts[1];
54 var html = anss[i].innerHTML;
55 if(html === "<center>✔</center>"){
56 inccount = 1;
57 incscore = 2;
58 }else if(html === "<center>❓</center>"){
59 incscore = 1;
60 }
61 var intansid = parseInt(ansid)
62 if(answers.indexOf(intansid) == -1){
63 answers.push(intansid);
64 }
65 if(ansid in count){
66 count[ansid] += inccount;
67 }else{
68 count[ansid] = inccount;
69 }
70 if(ansid in scores){
71 scores[ansid] += incscore;
72 }else{
73 scores[ansid] = incscore;
74 }
75 if(scores[ansid] > maxscore){
76 maxscore = scores[ansid];
77 }
78 }
79 for(i=0; i < answers.length; i++){
80 var ansid = answers[i].toString();
81 var el = $('#total'+ansid)[0];
82 var ins = "<center>"+count[ansid];
83 if(scores[ansid] >= maxscore){
84 ins += "<br/><span style=\\"color:blue\\">★</span>";
85 }
86 ins += "</center>";
87 el.innerHTML = ins;
88 }
89 }
90 function change_answer(ele, id){
91 // modify only the currently selected entry
92 if (in_modification_id != id) return;
93
94 var e = document.getElementById(ele.id);
95 var i = e.innerHTML;
96 var ans = true;"""
97 if mode == 0 then
98 header.page_js += """
99 if(i === "<center>✔</center>"){
100 ans = 0;
101 e.innerHTML = "<center>✘</center>"
102 e.style.color = "red";
103 }else{
104 ans = 1;
105 e.innerHTML = "<center>✔</center>";
106 e.style.color = "green";
107 }"""
108
109 else
110 header.page_js += """
111 if(i === "<center>✔</center>"){
112 ans = 1;
113 e.innerHTML = "<center>❓</center>"
114 e.style.color = "#B8860B";
115 }else if(i === "<center>❓</center>"){
116 ans = 0;
117 e.innerHTML = "<center>✘</center>"
118 e.style.color = "red";
119 }else{
120 ans = 2;
121 e.innerHTML = "<center>✔</center>";
122 e.style.color = "green";
123 }"""
124 end
125 header.page_js += """
126 var a = ele.id.split('_')
127 var pid = a[1]
128 var aid = a[2]
129 update_scores();
130 $.ajax({
131 type: "POST",
132 url: "./rest/answer",
133 data: {
134 answer_id: aid,
135 pers_id: pid,
136 answer: ans
137 }
138 });
139 }
140 function change_temp_answer(ele){
141 var e = document.getElementById(ele.id);
142 var i = e.innerHTML;"""
143 if mode == 0 then
144 header.page_js += """
145 if(i === "<center>✔</center>"){
146 e.innerHTML = "<center>✘</center>"
147 e.style.color = "red";
148 }else{
149 e.innerHTML = "<center>✔</center>";
150 e.style.color = "green";
151 }
152 """
153 else
154 header.page_js += """
155 if(i === "<center>✔</center>"){
156 e.innerHTML = "<center>❓</center>";
157 e.style.color = "#B8860B";
158 }else if(i === "<center>❓</center>"){
159 e.innerHTML = "<center>✘</center>"
160 e.style.color = "red";
161 }else{
162 e.innerHTML = "<center>✔</center>";
163 e.style.color = "green";
164 }
165 """
166 end
167 header.page_js += """
168 update_scores();
169 }
170 function add_part(ele){
171 var e = document.getElementById(ele.id);
172 var pname = document.getElementById("new_name").value;
173 var arr = e.id.split("_");
174 var mid = arr[1];
175 var ans = $('#' + ele.id).parent().parent().parent().children(".answer");
176 ansmap = {};
177 for(i=0;i<ans.length;i++){
178 var curr = ans.eq(i)
179 """
180 if mode == 0 then
181 header.page_js += """
182 if(curr[0].innerHTML === "<center>✔</center>"){
183 ansmap[curr.attr('id')] = 1
184 }else{
185 ansmap[curr.attr('id')] = 0
186 }"""
187 else
188 header.page_js += """
189 if(curr[0].innerHTML === "<center>✔</center>"){
190 ansmap[curr.attr('id')] = 2
191 }else if(curr[0].innerHTML === "<center>❓</center>"){
192 ansmap[curr.attr('id')] = 1
193 }else{
194 ansmap[curr.attr('id')] = 0
195 }"""
196 end
197 header.page_js += """
198 }
199 $.ajax({
200 type: "POST",
201 url: "./rest/meetup/new_pers",
202 data: {
203 meetup_id: mid,
204 persname: pname,
205 answers: $.param(ansmap)
206 }
207 })
208 .done(function(data){
209 location.reload();
210 })
211 .fail(function(data){
212 //TODO: Notify of failure
213 });
214 }
215 function remove_people(ele){
216 var arr = ele.id.split("_")
217 var pid = arr[1]
218 $('#' + ele.id).parent().parent().parent().remove();
219 update_scores();
220 $.ajax({
221 type: "POST",
222 url: "./rest/people",
223 data: {
224 method: "DELETE",
225 p_id: pid
226 }
227 });
228 }
229 // ID of line currently open for modification
230 var in_modification_id = null;
231 function modify_people(ele, id){
232 if (in_modification_id != null) {
233 // reset to normal values
234 $('#modify_'+in_modification_id).text("{{{"Modify or delete"}}}");
235 $('#modify_'+in_modification_id).attr("class", "btn btn-xs btn-warning");
236 $('#line_'+in_modification_id).css("background-color", "");
237 $('#delete_'+in_modification_id).css("display", "none");
238 }
239 if (in_modification_id != id) {
240 // activate modifiable mode
241 $('#modify_'+id).text("{{{"Done"}}}");
242 $('#modify_'+id).attr("class", "btn btn-xs btn-success");
243 $('#line_'+id).css("background-color", "LightYellow");
244 $('#delete_'+id).show();
245
246 in_modification_id = id;
247 } else {
248 in_modification_id = null;
249 }
250 }
251 """
252 end
253
254 redef fun rendering do
255 if meetup == null then
256 add((new OpportunityHomePage).write_to_string)
257 return
258 end
259 add header
260 var db = new OpportunityDB.open("opportunity")
261 add meetup.to_html(db)
262 db.close
263 add footer
264 end
265 end
266
267 redef class Meetup
268 # Build the HTML for `self`
269 fun to_html(db: OpportunityDB): Writable do
270 var t = new Template
271 t.add """
272 <div class="container">
273 <div class="page-header">
274 <center><h1>{{{name}}}</h1></center>
275 """
276 if not date.is_empty then t.add """
277 <center><h4>{{{"When:"}}} {{{date}}}</h4></center>"""
278
279 if not place.is_empty then t.add """
280 <center><h4>{{{"Where:"}}} {{{place}}}</h4></center>"""
281
282 t.add """
283 </div>
284 <table class="table">
285 """
286 t.add "<th>{"Participant name"}</th>"
287 for i in answers(db) do
288 t.add "<th class=\"text-center\">"
289 t.add i.to_s
290 t.add "</th>"
291 end
292 t.add "<th></th>"
293 t.add "</tr>"
294 for i in participants(db) do
295 i.load_answers(db, self)
296 t.add "<tr id=\"line_{i.id}\">"
297 t.add "<td>"
298 t.add i.to_s
299 t.add "</td>"
300 for j, k in i.answers do
301 var color
302 if answer_mode == 0 then
303 if k == 1 then
304 color = "green"
305 else
306 color = "red"
307 end
308 else
309 if k == 2 then
310 color = "green"
311 else if k == 1 then
312 color = "#B8860B"
313 else
314 color = "red"
315 end
316 end
317 t.add """<td class="answer" onclick="change_answer(this, {{{i.id}}})" id="answer_{{{j.id}}}_{{{i.id}}}" style="color:{{{color}}}">"""
318 t.add "<center>"
319 if answer_mode == 0 then
320 if k == 1 then
321 t.add "✔"
322 else
323 t.add "✘"
324 end
325 else
326 if k == 2 then
327 t.add "✔"
328 else if k == 1 then
329 t.add "❓"
330 else
331 t.add "✘"
332 end
333 end
334 t.add "</center></td>"
335 end
336 t.add """<td class="opportunity-action"><center><button class="btn btn-xs btn-warning" type="button" onclick="modify_people(this, {{{i.id}}})" id="modify_{{{i.id}}}">{{{"Modify or delete"}}}</button>&nbsp;"""
337 t.add """<button class="btn btn-xs btn-danger" type="button" onclick="remove_people(this)" id="delete_{{{i.id}}}" style="display: none;">{{{"Delete"}}}</button></center></td>"""
338 t.add "</tr>"
339 end
340 t.add """
341 <tr id="newrow" style="background-color: LightYellow">
342 <td><input id="new_name" type="text" placeholder="{{{"Your name"}}}" class="input-large"></td>
343 """
344 for i in answers(db) do
345 t.add "<td class=\"answer\" id=\"newans_{i.id}\" onclick=\"change_temp_answer(this)\" style=\"color:red;\"><center>✘</center></td>"
346 end
347 t.add """
348 <td><center><span id="add_{{{id}}}" onclick="add_part(this)" style="color:green;" class="action"><button class="btn btn-xs btn-success" type="button">{{{"Done"}}}</button></span></center></td>"""
349 t.add "</tr>"
350 # Compute score for each answer
351 var scores = new HashMap[Int, Int]
352 var maxsc = 0
353 for i in answers(db) do
354 scores[i.id] = i.score(db)
355 if scores[i.id] > maxsc then maxsc = scores[i.id]
356 end
357 t.add """
358 <tr id="total">
359 <th>Total ({{{participants(db).length}}})</th>
360 """
361 for i in answers(db) do
362 t.add """<th id="total{{{i.id}}}"><center>{{{i.count(db)}}}"""
363 if scores.has_key(i.id) and scores[i.id] >= maxsc then
364 t.add """<br/><span style="color:blue">★</span>"""
365 end
366 t.add "</center></th>"
367 end
368 t.add "</th>"
369 t.add """
370 <th></th>
371 </tr>"""
372 t.add "</table>"
373 t.add "</div>"
374 return t
375 end
376 end