liquid_feedback_frontend

view app/main/initiative/show.lua @ 1209:fede09736f2b

Added support for external references
author bsw
date Sat Jul 18 16:20:30 2015 +0200 (2015-07-18)
parents 904f6807f7fa
children 32cc544d5a5b
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 local direct_supporter
29 if app.session.member_id then
30 direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
31 end
33 ui.script { script = [[
34 function showTab(tabId) {
35 $('.tab').hide();
36 $('.main').hide();
37 $('.main, .slot_extra .section').hide();
38 $('.' + tabId).show();
39 if (tabId == "main") $('.slot_extra .section').show();
40 };
41 showTab('main');
42 ]]}
44 execute.view{ module = "issue", view = "_sidebar_state", params = {
45 initiative = initiative
46 } }
48 execute.view {
49 module = "issue", view = "_sidebar_issue",
50 params = {
51 issue = initiative.issue,
52 highlight_initiative_id = initiative.id
53 }
54 }
56 execute.view {
57 module = "issue", view = "_sidebar_whatcanido",
58 params = { initiative = initiative }
59 }
61 execute.view {
62 module = "issue", view = "_sidebar_members", params = {
63 issue = initiative.issue, initiative = initiative
64 }
65 }
67 ui.section( function ()
68 execute.view{
69 module = "initiative", view = "_head", params = {
70 initiative = initiative
71 }
72 }
74 if direct_supporter and not initiative.issue.closed then
75 local supporter = app.session.member:get_reference_selector("supporters")
76 :add_where{ "initiative_id = ?", initiative.id }
77 :optional_object_mode()
78 :exec()
80 if supporter then
82 local old_draft_id = supporter.draft_id
83 local new_draft_id = initiative.current_draft.id
85 if old_draft_id ~= new_draft_id then
86 ui.sectionRow( "draft_updated_info", function ()
87 ui.container{
88 attr = { class = "info" },
89 content = _"The draft of this initiative has been updated!"
90 }
91 slot.put(" ")
92 ui.link{
93 content = _"show differences",
94 module = "draft",
95 view = "diff",
96 params = {
97 old_draft_id = old_draft_id,
98 new_draft_id = new_draft_id
99 }
100 }
101 if not initiative.revoked then
102 slot.put(" | ")
103 ui.link{
104 text = _"refresh my support",
105 module = "initiative",
106 action = "add_support",
107 id = initiative.id,
108 params = { draft_id = initiative.current_draft.id },
109 routing = {
110 default = {
111 mode = "redirect",
112 module = "initiative",
113 view = "show",
114 id = initiative.id
115 }
116 }
117 }
118 slot.put(" | ")
119 end
121 ui.link{
122 text = _"remove my support",
123 module = "initiative",
124 action = "remove_support",
125 id = initiative.id,
126 routing = {
127 default = {
128 mode = "redirect",
129 module = "initiative",
130 view = "show",
131 id = initiative.id
132 }
133 }
134 }
136 end )
137 end
138 end
139 end
141 if config.render_external_reference and config.render_external_reference.initiative then
142 config.render_external_reference.initiative(initiative, function (callback)
143 ui.sectionRow(callback)
144 end)
145 end
147 ui.sectionRow( function ()
148 ui.container {
149 attr = { class = "draft" },
150 content = function ()
151 slot.put ( initiative.current_draft:get_content ( "html" ) )
152 end
153 }
154 end )
156 end)
158 ui.link { attr = { name = "suggestions" }, text = "" }
161 ui.container {
162 attr = { class = "section suggestions" },
163 content = function ()
165 if # ( initiative.suggestions ) > 0 then
167 ui.sectionHead( function ()
168 ui.heading {
169 level = 1,
170 content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } )
171 }
172 ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
173 end )
175 for i, suggestion in ipairs(initiative.suggestions) do
177 local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
179 local class = "sectionRow suggestion"
180 if suggestion.id == param.get("suggestion_id", atom.number) then
181 class = class .. " highlighted"
182 end
183 if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
184 class = class .. " rateable"
185 end
188 ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
190 if opinion then
192 ui.container { attr = { class = "opinion"}, content = function()
193 local class = ""
194 local text = ""
196 if opinion.degree == 2 then
197 class = "must"
198 text = _"must"
199 elseif opinion.degree == 1 then
200 class = "should"
201 text = _"should"
202 elseif opinion.degree == 0 then
203 class = "neutral"
204 text = _"neutral"
205 elseif opinion.degree == -1 then
206 class = "shouldnot"
207 text = _"should not"
208 elseif opinion.degree == -2 then
209 class = "mustnot"
210 text = _"must not"
211 end
213 ui.tag {
214 attr = { class = class },
215 content = text
216 }
218 slot.put ( " " )
220 if
221 (opinion.degree > 0 and not opinion.fulfilled)
222 or (opinion.degree < 0 and opinion.fulfilled)
223 then
224 ui.tag{ content = _"but" }
225 else
226 ui.tag{ content = _"and" }
227 end
229 slot.put ( " " )
231 local class = ""
232 local text = ""
234 if opinion.fulfilled then
235 class = "implemented"
236 text = _"is implemented"
237 else
238 class = "notimplemented"
239 text = _"is not implemented"
240 end
242 ui.tag {
243 attr = { class = class },
244 content = text
245 }
247 if
248 (opinion.degree > 0 and not opinion.fulfilled)
249 or (opinion.degree < 0 and opinion.fulfilled)
250 then
251 if math.abs(opinion.degree) > 1 then
252 slot.put(" !!")
253 else
254 slot.put(" !")
255 end
256 else
257 slot.put(" ✓")
258 end
260 end }
262 end
265 ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
266 ui.heading { level = 2,
267 attr = { class = "suggestionHead" },
268 content = format.string(suggestion.name, {
269 truncate_at = 160, truncate_suffix = true
270 }) }
273 local plus2 = (suggestion.plus2_unfulfilled_count or 0)
274 + (suggestion.plus2_fulfilled_count or 0)
275 local plus1 = (suggestion.plus1_unfulfilled_count or 0)
276 + (suggestion.plus1_fulfilled_count or 0)
277 local minus1 = (suggestion.minus1_unfulfilled_count or 0)
278 + (suggestion.minus1_fulfilled_count or 0)
279 local minus2 = (suggestion.minus2_unfulfilled_count or 0)
280 + (suggestion.minus2_fulfilled_count or 0)
282 local with_opinion = plus2 + plus1 + minus1 + minus2
284 local neutral = (suggestion.initiative.supporter_count or 0)
285 - with_opinion
287 local neutral2 = with_opinion
288 - (suggestion.plus2_fulfilled_count or 0)
289 - (suggestion.plus1_fulfilled_count or 0)
290 - (suggestion.minus1_fulfilled_count or 0)
291 - (suggestion.minus2_fulfilled_count or 0)
293 ui.container {
294 attr = { class = "suggestionInfo" },
295 content = function ()
297 if with_opinion > 0 then
298 ui.container { attr = { class = "suggestion-rating" }, content = function ()
299 ui.tag { content = _"collective rating:" }
300 slot.put("&nbsp;")
301 ui.bargraph{
302 max_value = suggestion.initiative.supporter_count,
303 width = 100,
304 bars = {
305 { color = "#0a0", value = plus2 },
306 { color = "#8a8", value = plus1 },
307 { color = "#eee", value = neutral },
308 { color = "#a88", value = minus1 },
309 { color = "#a00", value = minus2 },
310 }
311 }
312 slot.put(" | ")
313 ui.tag { content = _"implemented:" }
314 slot.put ( "&nbsp;" )
315 ui.bargraph{
316 max_value = with_opinion,
317 width = 100,
318 bars = {
319 { color = "#0a0", value = suggestion.plus2_fulfilled_count },
320 { color = "#8a8", value = suggestion.plus1_fulfilled_count },
321 { color = "#eee", value = neutral2 },
322 { color = "#a88", value = suggestion.minus1_fulfilled_count },
323 { color = "#a00", value = suggestion.minus2_fulfilled_count },
324 }
325 }
326 end }
327 end
329 if app.session:has_access("authors_pseudonymous") then
330 util.micro_avatar ( suggestion.author )
331 else
332 slot.put("<br />")
333 end
335 ui.container {
336 attr = { class = "suggestion-text" },
337 content = function ()
338 slot.put ( suggestion:get_content( "html" ) )
341 if direct_supporter then
343 ui.container {
344 attr = { class = "rating" },
345 content = function ()
347 if not opinion then
348 opinion = {}
349 end
350 ui.form {
351 module = "opinion", action = "update", params = {
352 suggestion_id = suggestion.id
353 },
354 routing = { default = {
355 mode = "redirect",
356 module = "initiative", view = "show", id = suggestion.initiative_id,
357 params = { suggestion_id = suggestion.id },
358 anchor = "s" .. suggestion.id -- TODO webmcp
359 } },
360 content = function ()
363 ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" }
364 ui.container { content = function ()
366 local active = opinion.degree == 2
367 ui.tag { tag = "input", attr = {
368 type = "radio", name = "degree", value = 2,
369 id = "s" .. suggestion.id .. "_degree2",
370 checked = active and "checked" or nil
371 } }
372 ui.tag {
373 tag = "label",
374 attr = {
375 ["for"] = "s" .. suggestion.id .. "_degree2",
376 class = active and "active-plus2" or nil,
377 },
378 content = _"must"
379 }
381 local active = opinion.degree == 1
382 ui.tag { tag = "input", attr = {
383 type = "radio", name = "degree", value = 1,
384 id = "s" .. suggestion.id .. "_degree1",
385 checked = active and "checked" or nil
386 } }
387 ui.tag {
388 tag = "label",
389 attr = {
390 ["for"] = "s" .. suggestion.id .. "_degree1",
391 class = active and "active-plus1" or nil,
392 },
393 content = _"should"
394 }
396 local active = not opinion.member_id
397 ui.tag { tag = "input", attr = {
398 type = "radio", name = "degree", value = 0,
399 id = "s" .. suggestion.id .. "_degree0",
400 checked = active and "checked" or nil
401 } }
402 ui.tag {
403 tag = "label",
404 attr = {
405 ["for"] = "s" .. suggestion.id .. "_degree0",
406 class = active and "active-neutral" or nil,
407 },
408 content = _"neutral"
409 }
411 local active = opinion.degree == -1
412 ui.tag { tag = "input", attr = {
413 type = "radio", name = "degree", value = -1,
414 id = "s" .. suggestion.id .. "_degree-1",
415 checked = active and "checked" or nil
416 } }
417 ui.tag {
418 tag = "label",
419 attr = {
420 ["for"] = "s" .. suggestion.id .. "_degree-1",
421 class = active and "active-minus1" or nil,
422 },
423 content = _"should not"
424 }
426 local active = opinion.degree == -2
427 ui.tag { tag = "input", attr = {
428 type = "radio", name = "degree", value = -2,
429 id = "s" .. suggestion.id .. "_degree-2",
430 checked = active and "checked" or nil
431 } }
432 ui.tag {
433 tag = "label",
434 attr = {
435 ["for"] = "s" .. suggestion.id .. "_degree-2",
436 class = active and "active-minus2" or nil,
437 },
438 content = _"must not"
439 }
440 end }
442 slot.put("<br />")
444 ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" }
445 ui.container { content = function ()
446 local active = opinion.fulfilled == false
447 ui.tag { tag = "input", attr = {
448 type = "radio", name = "fulfilled", value = "false",
449 id = "s" .. suggestion.id .. "_notfulfilled",
450 checked = active and "checked" or nil
451 } }
452 ui.tag {
453 tag = "label",
454 attr = {
455 ["for"] = "s" .. suggestion.id .. "_notfulfilled",
456 class = active and "active-notfulfilled" or nil,
457 },
458 content = _"No (not yet)"
459 }
461 local active = opinion.fulfilled
462 ui.tag { tag = "input", attr = {
463 type = "radio", name = "fulfilled", value = "true",
464 id = "s" .. suggestion.id .. "_fulfilled",
465 checked = active and "checked" or nil
466 } }
467 ui.tag {
468 tag = "label",
469 attr = {
470 ["for"] = "s" .. suggestion.id .. "_fulfilled",
471 class = active and "active-fulfilled" or nil,
472 },
473 content = _"Yes, it's implemented"
474 }
475 end }
476 slot.put("<br />")
478 ui.tag{
479 tag = "input",
480 attr = {
481 type = "submit",
482 class = "btn btn-default",
483 value = _"publish my rating"
484 },
485 content = ""
486 }
488 end
489 }
491 end -- if not issue,fully_frozen or closed
492 }
493 end
495 local text = _"Read more"
497 if direct_supporter then
498 text = _"Show more and rate this"
499 end
501 ui.link{
502 attr = { class = "suggestion-details" },
503 content = _"Details",
504 module = "suggestion", view = "show", id = suggestion.id
505 }
507 ui.link {
508 attr = {
509 class = "suggestion-more",
510 onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;"
511 },
512 text = text
513 }
515 ui.link {
516 attr = {
517 class = "suggestion-less",
518 onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;"
519 },
520 text = _"Show less"
521 }
522 end
523 }
525 ui.script{ script = [[
526 var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text');
527 var height = textEl.height();
528 if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded');
529 ]] }
531 end
532 } -- ui.paragraph
536 end } -- ui.tag "li"
538 end -- for i, suggestion
540 else -- if #initiative.suggestions > 0
542 local text
543 if initiative.issue.closed then
544 text = _"No suggestions"
545 else
546 text = _"No suggestions yet"
547 end
548 ui.sectionHead( function()
549 ui.heading { level = 1, content = text }
550 end)
552 end -- if #initiative.suggestions > 0
554 end
555 }

Impressum / About Us