liquid_feedback_frontend
view app/main/initiative/show.lua @ 1060:d6ab5f231178
Fixed error when displaying initiatives in polling mode, made inline help for phases available
author | bsw |
---|---|
date | Wed Jul 16 21:50:26 2014 +0200 (2014-07-16) |
parents | 701a5cf6b067 |
children | 7188f8a45b3d |
line source
1 local initiative = Initiative:by_id ( param.get_id() )
2 local member = app.session.member
4 if not initiative then
5 execute.view { module = "index", view = "404" }
6 request.set_status("404 Not Found")
7 return
8 end
10 local issue_info
12 if member then
13 initiative:load_everything_for_member_id(member.id)
14 initiative.issue:load_everything_for_member_id(member.id)
15 issue_info = initiative.issue.member_info
16 end
18 execute.view {
19 module = "issue", view = "_head",
20 params = {
21 issue = initiative.issue,
22 initiative = initiative,
23 member = app.session.member
24 }
25 }
27 if app.session.member_id then
28 direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
29 end
31 ui.script { script = [[
32 function showTab(tabId) {
33 $('.tab').hide();
34 $('.main').hide();
35 $('.main, .slot_extra .section').hide();
36 $('.' + tabId).show();
37 if (tabId == "main") $('.slot_extra .section').show();
38 };
39 showTab('main');
40 ]]}
42 execute.view{ module = "issue", view = "_sidebar_state", params = {
43 initiative = initiative
44 } }
46 execute.view {
47 module = "issue", view = "_sidebar_issue",
48 params = {
49 issue = initiative.issue,
50 highlight_initiative_id = initiative.id
51 }
52 }
54 execute.view {
55 module = "issue", view = "_sidebar_whatcanido",
56 params = { initiative = initiative }
57 }
59 execute.view {
60 module = "issue", view = "_sidebar_members", params = {
61 issue = initiative.issue, initiative = initiative
62 }
63 }
65 ui.section( function ()
66 execute.view{
67 module = "initiative", view = "_head", params = {
68 initiative = initiative
69 }
70 }
72 if direct_supporter and not initiative.issue.closed then
73 local supporter = app.session.member:get_reference_selector("supporters")
74 :add_where{ "initiative_id = ?", initiative.id }
75 :optional_object_mode()
76 :exec()
78 if supporter then
80 local old_draft_id = supporter.draft_id
81 local new_draft_id = initiative.current_draft.id
83 if old_draft_id ~= new_draft_id then
84 ui.sectionRow( "draft_updated_info", function ()
85 ui.container{
86 attr = { class = "info" },
87 content = _"The draft of this initiative has been updated!"
88 }
89 slot.put(" ")
90 ui.link{
91 content = _"show differences",
92 module = "draft",
93 view = "diff",
94 params = {
95 old_draft_id = old_draft_id,
96 new_draft_id = new_draft_id
97 }
98 }
99 if not initiative.revoked then
100 slot.put(" | ")
101 ui.link{
102 text = _"refresh my support",
103 module = "initiative",
104 action = "add_support",
105 id = initiative.id,
106 params = { draft_id = initiative.current_draft.id },
107 routing = {
108 default = {
109 mode = "redirect",
110 module = "initiative",
111 view = "show",
112 id = initiative.id
113 }
114 }
115 }
116 slot.put(" | ")
117 end
119 ui.link{
120 text = _"remove my support",
121 module = "initiative",
122 action = "remove_support",
123 id = initiative.id,
124 routing = {
125 default = {
126 mode = "redirect",
127 module = "initiative",
128 view = "show",
129 id = initiative.id
130 }
131 }
132 }
134 end )
135 end
136 end
137 end
140 ui.sectionRow( function ()
141 ui.container {
142 attr = { class = "draft" },
143 content = function ()
144 slot.put ( initiative.current_draft:get_content ( "html" ) )
145 end
146 }
147 end )
149 end)
151 ui.link { attr = { name = "suggestions" }, text = "" }
154 ui.container {
155 attr = { class = "section suggestions" },
156 content = function ()
158 if # ( initiative.suggestions ) > 0 then
160 ui.sectionHead( function ()
161 ui.heading {
162 level = 1,
163 content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } )
164 }
165 ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
166 end )
168 for i, suggestion in ipairs(initiative.suggestions) do
170 local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
172 local class = "sectionRow suggestion"
173 if suggestion.id == param.get("suggestion_id", atom.number) then
174 class = class .. " highlighted"
175 end
176 if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
177 class = class .. " rateable"
178 end
181 ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
183 if opinion then
185 ui.container { attr = { class = "opinion"}, content = function()
186 local class = ""
187 local text = ""
189 if opinion.degree == 2 then
190 class = "must"
191 text = _"must"
192 elseif opinion.degree == 1 then
193 class = "should"
194 text = _"should"
195 elseif opinion.degree == 0 then
196 class = "neutral"
197 text = _"neutral"
198 elseif opinion.degree == -1 then
199 class = "shouldnot"
200 text = _"should not"
201 elseif opinion.degree == -2 then
202 class = "mustnot"
203 text = _"must not"
204 end
206 ui.tag {
207 attr = { class = class },
208 content = text
209 }
211 slot.put ( " " )
213 if
214 (opinion.degree > 0 and not opinion.fulfilled)
215 or (opinion.degree < 0 and opinion.fulfilled)
216 then
217 ui.tag{ content = _"but" }
218 else
219 ui.tag{ content = _"and" }
220 end
222 slot.put ( " " )
224 local class = ""
225 local text = ""
227 if opinion.fulfilled then
228 class = "implemented"
229 text = _"is implemented"
230 else
231 class = "notimplemented"
232 text = _"is not implemented"
233 end
235 ui.tag {
236 attr = { class = class },
237 content = text
238 }
240 if
241 (opinion.degree > 0 and not opinion.fulfilled)
242 or (opinion.degree < 0 and opinion.fulfilled)
243 then
244 if math.abs(opinion.degree) > 1 then
245 slot.put(" !!")
246 else
247 slot.put(" !")
248 end
249 else
250 slot.put(" ✓")
251 end
253 end }
255 end
258 ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
259 ui.heading { level = 2,
260 attr = { class = "suggestionHead" },
261 content = format.string(suggestion.name, {
262 truncate_at = 160, truncate_suffix = true
263 }) }
266 local plus2 = (suggestion.plus2_unfulfilled_count or 0)
267 + (suggestion.plus2_fulfilled_count or 0)
268 local plus1 = (suggestion.plus1_unfulfilled_count or 0)
269 + (suggestion.plus1_fulfilled_count or 0)
270 local minus1 = (suggestion.minus1_unfulfilled_count or 0)
271 + (suggestion.minus1_fulfilled_count or 0)
272 local minus2 = (suggestion.minus2_unfulfilled_count or 0)
273 + (suggestion.minus2_fulfilled_count or 0)
275 local with_opinion = plus2 + plus1 + minus1 + minus2
277 local neutral = (suggestion.initiative.supporter_count or 0)
278 - with_opinion
280 local neutral2 = with_opinion
281 - (suggestion.plus2_fulfilled_count or 0)
282 - (suggestion.plus1_fulfilled_count or 0)
283 - (suggestion.minus1_fulfilled_count or 0)
284 - (suggestion.minus2_fulfilled_count or 0)
286 ui.container {
287 attr = { class = "suggestionInfo" },
288 content = function ()
290 if with_opinion > 0 then
291 ui.container { attr = { class = "suggestion-rating" }, content = function ()
292 ui.tag { content = _"collective rating:" }
293 slot.put(" ")
294 ui.bargraph{
295 max_value = suggestion.initiative.supporter_count,
296 width = 100,
297 bars = {
298 { color = "#0a0", value = plus2 },
299 { color = "#8a8", value = plus1 },
300 { color = "#eee", value = neutral },
301 { color = "#a88", value = minus1 },
302 { color = "#a00", value = minus2 },
303 }
304 }
305 slot.put(" | ")
306 ui.tag { content = _"implemented:" }
307 slot.put ( " " )
308 ui.bargraph{
309 max_value = with_opinion,
310 width = 100,
311 bars = {
312 { color = "#0a0", value = suggestion.plus2_fulfilled_count },
313 { color = "#8a8", value = suggestion.plus1_fulfilled_count },
314 { color = "#eee", value = neutral2 },
315 { color = "#a88", value = suggestion.minus1_fulfilled_count },
316 { color = "#a00", value = suggestion.minus2_fulfilled_count },
317 }
318 }
319 end }
320 end
322 if app.session:has_access("authors_pseudonymous") then
323 util.micro_avatar ( suggestion.author )
324 else
325 slot.put("<br />")
326 end
328 ui.container {
329 attr = { class = "suggestion-text" },
330 content = function ()
331 slot.put ( suggestion:get_content( "html" ) )
333 if direct_supporter then
335 ui.container {
336 attr = { class = "rating" },
337 content = function ()
339 if not opinion then
340 opinion = {}
341 end
342 ui.form {
343 module = "opinion", action = "update", params = {
344 suggestion_id = suggestion.id
345 },
346 routing = { default = {
347 mode = "redirect",
348 module = "initiative", view = "show", id = suggestion.initiative_id,
349 params = { suggestion_id = suggestion.id },
350 anchor = "s" .. suggestion.id -- TODO webmcp
351 } },
352 content = function ()
355 ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" }
356 ui.container { content = function ()
358 local active = opinion.degree == 2
359 ui.tag { tag = "input", attr = {
360 type = "radio", name = "degree", value = 2,
361 id = "s" .. suggestion.id .. "_degree2",
362 checked = active and "checked" or nil
363 } }
364 ui.tag {
365 tag = "label",
366 attr = {
367 ["for"] = "s" .. suggestion.id .. "_degree2",
368 class = active and "active-plus2" or nil,
369 },
370 content = _"must"
371 }
373 local active = opinion.degree == 1
374 ui.tag { tag = "input", attr = {
375 type = "radio", name = "degree", value = 1,
376 id = "s" .. suggestion.id .. "_degree1",
377 checked = active and "checked" or nil
378 } }
379 ui.tag {
380 tag = "label",
381 attr = {
382 ["for"] = "s" .. suggestion.id .. "_degree1",
383 class = active and "active-plus1" or nil,
384 },
385 content = _"should"
386 }
388 local active = not opinion.member_id
389 ui.tag { tag = "input", attr = {
390 type = "radio", name = "degree", value = 0,
391 id = "s" .. suggestion.id .. "_degree0",
392 checked = active and "checked" or nil
393 } }
394 ui.tag {
395 tag = "label",
396 attr = {
397 ["for"] = "s" .. suggestion.id .. "_degree0",
398 class = active and "active-neutral" or nil,
399 },
400 content = _"neutral"
401 }
403 local active = opinion.degree == -1
404 ui.tag { tag = "input", attr = {
405 type = "radio", name = "degree", value = -1,
406 id = "s" .. suggestion.id .. "_degree-1",
407 checked = active and "checked" or nil
408 } }
409 ui.tag {
410 tag = "label",
411 attr = {
412 ["for"] = "s" .. suggestion.id .. "_degree-1",
413 class = active and "active-minus1" or nil,
414 },
415 content = _"should not"
416 }
418 local active = opinion.degree == -2
419 ui.tag { tag = "input", attr = {
420 type = "radio", name = "degree", value = -2,
421 id = "s" .. suggestion.id .. "_degree-2",
422 checked = active and "checked" or nil
423 } }
424 ui.tag {
425 tag = "label",
426 attr = {
427 ["for"] = "s" .. suggestion.id .. "_degree-2",
428 class = active and "active-minus2" or nil,
429 },
430 content = _"must not"
431 }
432 end }
434 slot.put("<br />")
436 ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" }
437 ui.container { content = function ()
438 local active = opinion.fulfilled == false
439 ui.tag { tag = "input", attr = {
440 type = "radio", name = "fulfilled", value = "false",
441 id = "s" .. suggestion.id .. "_notfulfilled",
442 checked = active and "checked" or nil
443 } }
444 ui.tag {
445 tag = "label",
446 attr = {
447 ["for"] = "s" .. suggestion.id .. "_notfulfilled",
448 class = active and "active-notfulfilled" or nil,
449 },
450 content = _"No (not yet)"
451 }
453 local active = opinion.fulfilled
454 ui.tag { tag = "input", attr = {
455 type = "radio", name = "fulfilled", value = "true",
456 id = "s" .. suggestion.id .. "_fulfilled",
457 checked = active and "checked" or nil
458 } }
459 ui.tag {
460 tag = "label",
461 attr = {
462 ["for"] = "s" .. suggestion.id .. "_fulfilled",
463 class = active and "active-fulfilled" or nil,
464 },
465 content = _"Yes, it's implemented"
466 }
467 end }
468 slot.put("<br />")
470 ui.tag{
471 tag = "input",
472 attr = {
473 type = "submit",
474 class = "btn btn-default",
475 value = _"publish my rating"
476 },
477 content = ""
478 }
480 end
481 }
483 end -- if not issue,fully_frozen or closed
484 }
485 end
487 local text = _"Read more"
489 if direct_supporter then
490 text = _"Show more and rate this"
491 end
493 ui.link {
494 attr = {
495 class = "suggestion-more",
496 onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;"
497 },
498 text = text
499 }
501 ui.link {
502 attr = {
503 class = "suggestion-less",
504 onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;"
505 },
506 text = _"Show less"
507 }
508 end
509 }
511 ui.script{ script = [[
512 var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text');
513 var height = textEl.height();
514 if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded');
515 ]] }
517 end
518 } -- ui.paragraph
522 end } -- ui.tag "li"
524 end -- for i, suggestion
526 else -- if #initiative.suggestions > 0
528 local text
529 if initiative.issue.closed then
530 text = "No suggestions"
531 else
532 text = "No suggestions (yet)"
533 end
534 ui.sectionHead( function()
535 ui.heading { level = 1, content = text }
536 end)
538 end -- if #initiative.suggestions > 0
540 end
541 }