liquid_feedback_frontend

annotate app/main/initiative/show.lua @ 1061:7188f8a45b3d

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

Impressum / About Us