liquid_feedback_frontend

view app/main/vote/list.lua @ 520:f9b80c930456

Removed browser warning from login page
author bsw
date Mon Apr 16 23:28:58 2012 +0200 (2012-04-16)
parents 7492497005bd
children a930d2ab9e76
line source
1 local issue = Issue:by_id(param.get("issue_id"), atom.integer)
3 local member_id = param.get("member_id", atom.integer)
4 local member
6 local readonly = false
8 if member_id then
9 if not issue.closed then
10 error("access denied")
11 end
12 member = Member:by_id(member_id)
13 readonly = true
14 end
16 if issue.closed then
17 if not member then
18 slot.put_into("error", _"This issue is already closed.")
19 end
20 if not member then
21 member = app.session.member
22 end
23 readonly = true
24 end
26 if member then
27 local str = _("Ballot of '#{member_name}' for issue ##{issue_id}",
28 {member_name = string.format('<a href="%s">%s</a>',
29 encode.url{
30 module = "member",
31 view = "show",
32 id = member.id,
33 },
34 encode.html(member.name)),
35 issue_id = string.format('<a href="%s">%s</a>',
36 encode.url{
37 module = "issue",
38 view = "show",
39 id = issue.id,
40 },
41 encode.html(tostring(issue.id)))
42 }
43 )
44 slot.put_into("title", str)
45 else
46 member = app.session.member
47 slot.put_into("title", _"Voting")
49 slot.select("actions", function()
50 ui.link{
51 content = function()
52 ui.image{ static = "icons/16/cancel.png" }
53 slot.put(_"Cancel")
54 end,
55 module = "issue",
56 view = "show",
57 id = issue.id
58 }
59 ui.link{
60 text = _"Discard voting",
61 content = function()
62 ui.image{ static = "icons/16/email_delete.png" }
63 slot.put(_"Discard voting")
64 end,
65 module = "vote",
66 action = "update",
67 params = {
68 issue_id = issue.id,
69 discard = true
70 },
71 routing = {
72 default = {
73 mode = "redirect",
74 module = "issue",
75 view = "show",
76 id = issue.id
77 }
78 }
79 }
80 end)
81 end
84 local tempvoting_string = param.get("scoring")
86 local tempvotings = {}
87 if tempvoting_string then
88 for match in tempvoting_string:gmatch("([^;]+)") do
89 for initiative_id, grade in match:gmatch("([^:;]+):([^:;]+)") do
90 tempvotings[tonumber(initiative_id)] = tonumber(grade)
91 end
92 end
93 end
95 local initiatives = issue:get_reference_selector("initiatives"):add_where("initiative.admitted"):add_order_by("initiative.satisfied_supporter_count DESC"):exec()
97 local min_grade = -1;
98 local max_grade = 1;
100 for i, initiative in ipairs(initiatives) do
101 -- TODO performance
102 initiative.vote = Vote:by_pk(initiative.id, member.id)
103 if tempvotings[initiative.id] then
104 initiative.vote = {}
105 initiative.vote.grade = tempvotings[initiative.id]
106 end
107 if initiative.vote then
108 if initiative.vote.grade > max_grade then
109 max_grade = initiative.vote.grade
110 end
111 if initiative.vote.grade < min_grade then
112 min_grade = initiative.vote.grade
113 end
114 end
115 end
117 local sections = {}
118 for i = min_grade, max_grade do
119 sections[i] = {}
120 for j, initiative in ipairs(initiatives) do
121 if (initiative.vote and initiative.vote.grade == i) or (not initiative.vote and i == 0) then
122 sections[i][#(sections[i])+1] = initiative
123 end
124 end
125 end
127 local approval_count, disapproval_count = 0, 0
128 for i = min_grade, -1 do
129 if #sections[i] > 0 then
130 disapproval_count = disapproval_count + 1
131 end
132 end
133 local approval_count = 0
134 for i = 1, max_grade do
135 if #sections[i] > 0 then
136 approval_count = approval_count + 1
137 end
138 end
142 if not readonly then
143 util.help("vote.list", _"Voting")
144 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>')
145 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>')
146 end
148 ui.script{
149 script = function()
150 slot.put(
151 "voting_text_approval_single = ", encode.json(_"Approval [single entry]"), ";\n",
152 "voting_text_approval_multi = ", encode.json(_"Approval [many entries]"), ";\n",
153 "voting_text_first_preference_single = ", encode.json(_"Approval (first preference) [single entry]"), ";\n",
154 "voting_text_first_preference_multi = ", encode.json(_"Approval (first preference) [many entries]"), ";\n",
155 "voting_text_second_preference_single = ", encode.json(_"Approval (second preference) [single entry]"), ";\n",
156 "voting_text_second_preference_multi = ", encode.json(_"Approval (second preference) [many entries]"), ";\n",
157 "voting_text_third_preference_single = ", encode.json(_"Approval (third preference) [single entry]"), ";\n",
158 "voting_text_third_preference_multi = ", encode.json(_"Approval (third preference) [many entries]"), ";\n",
159 "voting_text_numeric_preference_single = ", encode.json(_"Approval (#th preference) [single entry]"), ";\n",
160 "voting_text_numeric_preference_multi = ", encode.json(_"Approval (#th preference) [many entries]"), ";\n",
161 "voting_text_abstention_single = ", encode.json(_"Abstention [single entry]"), ";\n",
162 "voting_text_abstention_multi = ", encode.json(_"Abstention [many entries]"), ";\n",
163 "voting_text_disapproval_above_one_single = ", encode.json(_"Disapproval (prefer to lower block) [single entry]"), ";\n",
164 "voting_text_disapproval_above_one_multi = ", encode.json(_"Disapproval (prefer to lower block) [many entries]"), ";\n",
165 "voting_text_disapproval_above_many_single = ", encode.json(_"Disapproval (prefer to lower blocks) [single entry]"), ";\n",
166 "voting_text_disapproval_above_many_multi = ", encode.json(_"Disapproval (prefer to lower blocks) [many entries]"), ";\n",
167 "voting_text_disapproval_above_last_single = ", encode.json(_"Disapproval (prefer to last block) [single entry]"), ";\n",
168 "voting_text_disapproval_above_last_multi = ", encode.json(_"Disapproval (prefer to last block) [many entries]"), ";\n",
169 "voting_text_disapproval_single = ", encode.json(_"Disapproval [single entry]"), ";\n",
170 "voting_text_disapproval_multi = ", encode.json(_"Disapproval [many entries]"), ";\n"
171 )
172 end
173 }
175 ui.form{
176 attr = {
177 id = "voting_form",
178 class = readonly and "voting_form_readonly" or "voting_form_active"
179 },
180 module = "vote",
181 action = "update",
182 params = { issue_id = issue.id },
183 routing = {
184 default = {
185 mode = "redirect",
186 module = "issue",
187 view = "show",
188 id = issue.id
189 }
190 },
191 content = function()
192 if not readonly then
193 local scoring = param.get("scoring")
194 if not scoring then
195 for i, initiative in ipairs(initiatives) do
196 local vote = initiative.vote
197 if vote then
198 tempvotings[initiative.id] = vote.grade
199 end
200 end
201 local tempvotings_list = {}
202 for key, val in pairs(tempvotings) do
203 tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
204 end
205 if #tempvotings_list > 0 then
206 scoring = table.concat(tempvotings_list, ";")
207 else
208 scoring = ""
209 end
210 end
211 slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>')
212 -- TODO abstrahieren
213 ui.tag{
214 tag = "input",
215 attr = {
216 type = "submit",
217 class = "voting_done",
218 value = _"Finish voting"
219 }
220 }
221 end
222 ui.container{
223 attr = { id = "voting" },
224 content = function()
225 local approval_index, disapproval_index = 0, 0
226 for grade = max_grade, min_grade, -1 do
227 local entries = sections[grade]
228 local class
229 if grade > 0 then
230 class = "approval"
231 elseif grade < 0 then
232 class = "disapproval"
233 else
234 class = "abstention"
235 end
236 if
237 #entries > 0 or
238 (grade == 1 and not approval_used) or
239 (grade == -1 and not disapproval_used) or
240 grade == 0
241 then
242 ui.container{
243 attr = { class = class },
244 content = function()
245 local heading
246 if class == "approval" then
247 approval_used = true
248 approval_index = approval_index + 1
249 if approval_count > 1 then
250 if approval_index == 1 then
251 if #entries == 1 then
252 heading = _"Approval (first preference) [single entry]"
253 else
254 heading = _"Approval (first preference) [many entries]"
255 end
256 elseif approval_index == 2 then
257 if #entries == 1 then
258 heading = _"Approval (second preference) [single entry]"
259 else
260 heading = _"Approval (second preference) [many entries]"
261 end
262 elseif approval_index == 3 then
263 if #entries == 1 then
264 heading = _"Approval (third preference) [single entry]"
265 else
266 heading = _"Approval (third preference) [many entries]"
267 end
268 else
269 if #entries == 1 then
270 heading = _"Approval (#th preference) [single entry]"
271 else
272 heading = _"Approval (#th preference) [many entries]"
273 end
274 end
275 else
276 if #entries == 1 then
277 heading = _"Approval [single entry]"
278 else
279 heading = _"Approval [many entries]"
280 end
281 end
282 elseif class == "abstention" then
283 if #entries == 1 then
284 heading = _"Abstention [single entry]"
285 else
286 heading = _"Abstention [many entries]"
287 end
288 elseif class == "disapproval" then
289 disapproval_used = true
290 disapproval_index = disapproval_index + 1
291 if disapproval_count > disapproval_index + 1 then
292 if #entries == 1 then
293 heading = _"Disapproval (prefer to lower blocks) [single entry]"
294 else
295 heading = _"Disapproval (prefer to lower blocks) [many entries]"
296 end
297 elseif disapproval_count == 2 and disapproval_index == 1 then
298 if #entries == 1 then
299 heading = _"Disapproval (prefer to lower block) [single entry]"
300 else
301 heading = _"Disapproval (prefer to lower block) [many entries]"
302 end
303 elseif disapproval_index == disapproval_count - 1 then
304 if #entries == 1 then
305 heading = _"Disapproval (prefer to last block) [single entry]"
306 else
307 heading = _"Disapproval (prefer to last block) [many entries]"
308 end
309 else
310 if #entries == 1 then
311 heading = _"Disapproval [single entry]"
312 else
313 heading = _"Disapproval [many entries]"
314 end
315 end
316 end
317 ui.tag {
318 tag = "div",
319 attr = { class = "cathead" },
320 content = heading
321 }
322 for i, initiative in ipairs(entries) do
323 ui.container{
324 attr = {
325 class = "movable",
326 id = "entry_" .. tostring(initiative.id)
327 },
328 content = function()
329 local initiators_selector = initiative:get_reference_selector("initiating_members")
330 :add_where("accepted")
331 local initiators = initiators_selector:exec()
332 local initiator_names = {}
333 for i, initiator in ipairs(initiators) do
334 initiator_names[#initiator_names+1] = initiator.name
335 end
336 local initiator_names_string = table.concat(initiator_names, ", ")
337 ui.container{
338 attr = { style = "float: right; position: relative;" },
339 content = function()
340 ui.link{
341 attr = { class = "clickable" },
342 content = _"Show",
343 module = "initiative",
344 view = "show",
345 id = initiative.id
346 }
347 slot.put(" ")
348 ui.link{
349 attr = { class = "clickable", target = "_blank" },
350 content = _"(new window)",
351 module = "initiative",
352 view = "show",
353 id = initiative.id
354 }
355 if not readonly then
356 slot.put(" ")
357 ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
358 end
359 end
360 }
361 if not readonly then
362 ui.container{
363 attr = { style = "float: left; position: relative;" },
364 content = function()
365 ui.tag{
366 tag = "input",
367 attr = {
368 onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
369 name = "move_up_" .. tostring(initiative.id),
370 class = not disabled and "clickable" or nil,
371 type = "image",
372 src = encode.url{ static = "icons/move_up.png" },
373 alt = _"Move up"
374 }
375 }
376 slot.put("&nbsp;")
377 ui.tag{
378 tag = "input",
379 attr = {
380 onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
381 name = "move_down_" .. tostring(initiative.id),
382 class = not disabled and "clickable" or nil,
383 type = "image",
384 src = encode.url{ static = "icons/move_down.png" },
385 alt = _"Move down"
386 }
387 }
388 slot.put("&nbsp;")
389 end
390 }
391 end
392 ui.container{
393 content = function()
394 ui.tag{ content = "i" .. initiative.id .. ": " }
395 ui.tag{ content = initiative.shortened_name }
396 slot.put("<br />")
397 for i, initiator in ipairs(initiators) do
398 ui.link{
399 attr = { class = "clickable" },
400 content = function ()
401 execute.view{
402 module = "member_image",
403 view = "_show",
404 params = {
405 member = initiator,
406 image_type = "avatar",
407 show_dummy = true,
408 class = "micro_avatar",
409 popup_text = text
410 }
411 }
412 end,
413 module = "member", view = "show", id = initiator.id
414 }
415 slot.put(" ")
416 ui.tag{ content = initiator.name }
417 slot.put(" ")
418 end
419 end
420 }
421 end
422 }
423 end
424 end
425 }
426 end
427 end
428 end
429 }
430 if not readonly then
431 ui.tag{
432 tag = "input",
433 attr = {
434 type = "submit",
435 class = "voting_done",
436 value = _"Finish voting"
437 }
438 }
439 end
440 end
441 }

Impressum / About Us