liquid_feedback_frontend

diff app/main/initiative/show.lua @ 1045:701a5cf6b067

Imported LiquidFeedback Frontend 3.0 branch
author bsw
date Thu Jul 10 01:19:48 2014 +0200 (2014-07-10)
parents 344e5fdce8c9
children 7188f8a45b3d
line diff
     1.1 --- a/app/main/initiative/show.lua	Thu Jul 10 01:02:43 2014 +0200
     1.2 +++ b/app/main/initiative/show.lua	Thu Jul 10 01:19:48 2014 +0200
     1.3 @@ -1,7 +1,541 @@
     1.4 -local initiative = Initiative:by_id(param.get_id())
     1.5 +local initiative = Initiative:by_id ( param.get_id() )
     1.6 +local member = app.session.member
     1.7 +
     1.8 +if not initiative then
     1.9 +  execute.view { module = "index", view = "404" }
    1.10 +  request.set_status("404 Not Found")
    1.11 +  return
    1.12 +end
    1.13 +
    1.14 +local issue_info
    1.15 +
    1.16 +if member then
    1.17 +  initiative:load_everything_for_member_id(member.id)
    1.18 +  initiative.issue:load_everything_for_member_id(member.id)
    1.19 +  issue_info = initiative.issue.member_info
    1.20 +end
    1.21 +
    1.22 +execute.view {
    1.23 +  module = "issue", view = "_head", 
    1.24 +  params = {
    1.25 +    issue = initiative.issue,
    1.26 +    initiative = initiative,
    1.27 +    member = app.session.member
    1.28 +  }
    1.29 +}
    1.30 +
    1.31 +if app.session.member_id then
    1.32 +  direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
    1.33 +end
    1.34  
    1.35 -execute.view{
    1.36 -  module = "initiative", view = "_show", params = {
    1.37 -    initiative = initiative
    1.38 +ui.script { script = [[
    1.39 +  function showTab(tabId) {
    1.40 +    $('.tab').hide();
    1.41 +    $('.main').hide();
    1.42 +    $('.main, .slot_extra .section').hide();
    1.43 +    $('.' + tabId).show();
    1.44 +    if (tabId == "main") $('.slot_extra .section').show();
    1.45 +  };
    1.46 +  showTab('main');
    1.47 +]]}
    1.48 +
    1.49 +execute.view{ module = "issue", view = "_sidebar_state", params = {
    1.50 +  initiative = initiative
    1.51 +} }
    1.52 +
    1.53 +execute.view { 
    1.54 +  module = "issue", view = "_sidebar_issue", 
    1.55 +  params = {
    1.56 +    issue = initiative.issue,
    1.57 +    highlight_initiative_id = initiative.id
    1.58 +  }
    1.59 +}
    1.60 +
    1.61 +execute.view {
    1.62 +  module = "issue", view = "_sidebar_whatcanido",
    1.63 +  params = { initiative = initiative }
    1.64 +}
    1.65 +
    1.66 +execute.view { 
    1.67 +  module = "issue", view = "_sidebar_members", params = {
    1.68 +    issue = initiative.issue, initiative = initiative
    1.69    }
    1.70  }
    1.71 +
    1.72 +ui.section( function ()
    1.73 +  execute.view{
    1.74 +    module = "initiative", view = "_head", params = {
    1.75 +      initiative = initiative
    1.76 +    }
    1.77 +  }
    1.78 +
    1.79 +  if direct_supporter and not initiative.issue.closed then
    1.80 +    local supporter = app.session.member:get_reference_selector("supporters")
    1.81 +      :add_where{ "initiative_id = ?", initiative.id }
    1.82 +      :optional_object_mode()
    1.83 +      :exec()
    1.84 +      
    1.85 +    if supporter then
    1.86 +
    1.87 +      local old_draft_id = supporter.draft_id
    1.88 +      local new_draft_id = initiative.current_draft.id
    1.89 +      
    1.90 +      if old_draft_id ~= new_draft_id then
    1.91 +        ui.sectionRow( "draft_updated_info", function ()
    1.92 +          ui.container{ 
    1.93 +            attr = { class = "info" },
    1.94 +            content = _"The draft of this initiative has been updated!"
    1.95 +          }
    1.96 +          slot.put(" ")
    1.97 +          ui.link{
    1.98 +            content = _"show differences",
    1.99 +            module = "draft",
   1.100 +            view = "diff",
   1.101 +            params = {
   1.102 +              old_draft_id = old_draft_id,
   1.103 +              new_draft_id = new_draft_id
   1.104 +            }
   1.105 +          }
   1.106 +          if not initiative.revoked then
   1.107 +            slot.put(" | ")
   1.108 +            ui.link{
   1.109 +              text   = _"refresh my support",
   1.110 +              module = "initiative",
   1.111 +              action = "add_support",
   1.112 +              id     = initiative.id,
   1.113 +              params = { draft_id = initiative.current_draft.id },
   1.114 +              routing = {
   1.115 +                default = {
   1.116 +                  mode = "redirect",
   1.117 +                  module = "initiative",
   1.118 +                  view = "show",
   1.119 +                  id = initiative.id
   1.120 +                }
   1.121 +              }
   1.122 +            }
   1.123 +            slot.put(" | ")
   1.124 +          end
   1.125 +
   1.126 +          ui.link{
   1.127 +            text   = _"remove my support",
   1.128 +            module = "initiative",
   1.129 +            action = "remove_support",
   1.130 +            id     = initiative.id,
   1.131 +            routing = {
   1.132 +              default = {
   1.133 +                mode = "redirect",
   1.134 +                module = "initiative",
   1.135 +                view = "show",
   1.136 +                id = initiative.id
   1.137 +              }
   1.138 +            }
   1.139 +          }
   1.140 +
   1.141 +        end )
   1.142 +      end
   1.143 +    end
   1.144 +  end
   1.145 +  
   1.146 +
   1.147 +  ui.sectionRow( function ()
   1.148 +    ui.container {
   1.149 +      attr = { class = "draft" },
   1.150 +      content = function ()
   1.151 +        slot.put ( initiative.current_draft:get_content ( "html" ) )
   1.152 +      end
   1.153 +    }
   1.154 +  end )
   1.155 +
   1.156 +end)
   1.157 +
   1.158 +ui.link { attr = { name = "suggestions" }, text = "" }
   1.159 +
   1.160 +
   1.161 +ui.container {
   1.162 +  attr = { class = "section suggestions" },
   1.163 +  content = function ()
   1.164 +
   1.165 +    if # ( initiative.suggestions ) > 0 then
   1.166 +  
   1.167 +      ui.sectionHead( function ()
   1.168 +        ui.heading { 
   1.169 +          level = 1, 
   1.170 +          content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } ) 
   1.171 +        }
   1.172 +        ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
   1.173 +      end )
   1.174 +      
   1.175 +      for i, suggestion in ipairs(initiative.suggestions) do
   1.176 +        
   1.177 +        local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
   1.178 +
   1.179 +        local class = "sectionRow suggestion"
   1.180 +        if suggestion.id == param.get("suggestion_id", atom.number) then
   1.181 +          class = class .. " highlighted"
   1.182 +        end
   1.183 +        if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
   1.184 +          class = class .. " rateable"
   1.185 +        end
   1.186 +      
   1.187 +        
   1.188 +        ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
   1.189 +
   1.190 +          if opinion then
   1.191 +            
   1.192 +            ui.container { attr = { class = "opinion"}, content = function()
   1.193 +              local class = ""
   1.194 +              local text = ""
   1.195 +              
   1.196 +              if opinion.degree == 2 then
   1.197 +                class = "must"
   1.198 +                text = _"must"
   1.199 +              elseif opinion.degree == 1 then
   1.200 +                class = "should"
   1.201 +                text = _"should"
   1.202 +              elseif opinion.degree == 0 then
   1.203 +                class = "neutral"
   1.204 +                text = _"neutral"
   1.205 +              elseif opinion.degree == -1 then
   1.206 +                class = "shouldnot"
   1.207 +                text = _"should not"
   1.208 +              elseif opinion.degree == -2 then
   1.209 +                class = "mustnot"
   1.210 +                text = _"must not"
   1.211 +              end
   1.212 +              
   1.213 +              ui.tag { 
   1.214 +                attr = { class = class }, 
   1.215 +                content = text 
   1.216 +              }
   1.217 +              
   1.218 +              slot.put ( " " )
   1.219 +              
   1.220 +              if 
   1.221 +                (opinion.degree > 0 and not opinion.fulfilled)
   1.222 +                or (opinion.degree < 0 and opinion.fulfilled)
   1.223 +              then
   1.224 +                ui.tag{ content = _"but" }
   1.225 +              else
   1.226 +                ui.tag{ content = _"and" }
   1.227 +              end
   1.228 +                
   1.229 +              slot.put ( " " )
   1.230 +              
   1.231 +              local class = ""
   1.232 +              local text = ""
   1.233 +              
   1.234 +              if opinion.fulfilled then
   1.235 +                class = "implemented"
   1.236 +                text = _"is implemented"
   1.237 +              else
   1.238 +                class = "notimplemented"
   1.239 +                text = _"is not implemented"
   1.240 +              end
   1.241 +
   1.242 +              ui.tag { 
   1.243 +                attr = { class = class }, 
   1.244 +                content = text
   1.245 +              }
   1.246 +
   1.247 +              if 
   1.248 +                (opinion.degree > 0 and not opinion.fulfilled)
   1.249 +                or (opinion.degree < 0 and opinion.fulfilled)
   1.250 +              then
   1.251 +                if math.abs(opinion.degree) > 1 then
   1.252 +                  slot.put(" !!")
   1.253 +                else
   1.254 +                  slot.put(" !")
   1.255 +                end
   1.256 +              else
   1.257 +                slot.put(" ✓")
   1.258 +              end
   1.259 +
   1.260 +            end }
   1.261 +
   1.262 +          end
   1.263 +          
   1.264 +          
   1.265 +          ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
   1.266 +          ui.heading { level = 2, 
   1.267 +            attr = { class = "suggestionHead" },
   1.268 +            content = format.string(suggestion.name, {
   1.269 +            truncate_at = 160, truncate_suffix = true
   1.270 +          }) }
   1.271 +  
   1.272 +
   1.273 +            local plus2  = (suggestion.plus2_unfulfilled_count or 0)
   1.274 +                            + (suggestion.plus2_fulfilled_count or 0)
   1.275 +            local plus1  = (suggestion.plus1_unfulfilled_count  or 0)
   1.276 +                            + (suggestion.plus1_fulfilled_count or 0)
   1.277 +            local minus1 = (suggestion.minus1_unfulfilled_count  or 0)
   1.278 +                            + (suggestion.minus1_fulfilled_count or 0)
   1.279 +            local minus2 = (suggestion.minus2_unfulfilled_count  or 0)
   1.280 +                            + (suggestion.minus2_fulfilled_count or 0)
   1.281 +            
   1.282 +            local with_opinion = plus2 + plus1 + minus1 + minus2
   1.283 +
   1.284 +            local neutral = (suggestion.initiative.supporter_count or 0)
   1.285 +                            - with_opinion
   1.286 +
   1.287 +            local neutral2 = with_opinion 
   1.288 +                              - (suggestion.plus2_fulfilled_count or 0)
   1.289 +                              - (suggestion.plus1_fulfilled_count or 0)
   1.290 +                              - (suggestion.minus1_fulfilled_count or 0)
   1.291 +                              - (suggestion.minus2_fulfilled_count or 0)
   1.292 +            
   1.293 +            ui.container { 
   1.294 +            attr = { class = "suggestionInfo" },
   1.295 +            content = function ()
   1.296 +              
   1.297 +              if with_opinion > 0 then
   1.298 +                ui.container { attr = { class = "suggestion-rating" }, content = function ()
   1.299 +                  ui.tag { content = _"collective rating:" }
   1.300 +                  slot.put("&nbsp;")
   1.301 +                  ui.bargraph{
   1.302 +                    max_value = suggestion.initiative.supporter_count,
   1.303 +                    width = 100,
   1.304 +                    bars = {
   1.305 +                      { color = "#0a0", value = plus2 },
   1.306 +                      { color = "#8a8", value = plus1 },
   1.307 +                      { color = "#eee", value = neutral },
   1.308 +                      { color = "#a88", value = minus1 },
   1.309 +                      { color = "#a00", value = minus2 },
   1.310 +                    }
   1.311 +                  }
   1.312 +                  slot.put(" | ")
   1.313 +                  ui.tag { content = _"implemented:" }
   1.314 +                  slot.put ( "&nbsp;" )
   1.315 +                  ui.bargraph{
   1.316 +                    max_value = with_opinion,
   1.317 +                    width = 100,
   1.318 +                    bars = {
   1.319 +                      { color = "#0a0", value = suggestion.plus2_fulfilled_count },
   1.320 +                      { color = "#8a8", value = suggestion.plus1_fulfilled_count },
   1.321 +                      { color = "#eee", value = neutral2 },
   1.322 +                      { color = "#a88", value = suggestion.minus1_fulfilled_count },
   1.323 +                      { color = "#a00", value = suggestion.minus2_fulfilled_count },
   1.324 +                    }
   1.325 +                  }
   1.326 +                end }
   1.327 +              end
   1.328 +
   1.329 +              if app.session:has_access("authors_pseudonymous") then
   1.330 +                util.micro_avatar ( suggestion.author )
   1.331 +              else
   1.332 +                slot.put("<br />")
   1.333 +              end
   1.334 +              
   1.335 +              ui.container {
   1.336 +                attr = { class = "suggestion-text" },
   1.337 +                content = function ()
   1.338 +                  slot.put ( suggestion:get_content( "html" ) )
   1.339 +
   1.340 +              if direct_supporter then
   1.341 +                
   1.342 +                ui.container {
   1.343 +                  attr = { class = "rating" },
   1.344 +                  content = function ()
   1.345 +
   1.346 +                    if not opinion then
   1.347 +                      opinion = {}
   1.348 +                    end
   1.349 +                    ui.form { 
   1.350 +                      module = "opinion", action = "update", params = {
   1.351 +                        suggestion_id = suggestion.id
   1.352 +                      },
   1.353 +                      routing = { default = {
   1.354 +                        mode = "redirect", 
   1.355 +                        module = "initiative", view = "show", id = suggestion.initiative_id,
   1.356 +                        params = { suggestion_id = suggestion.id },
   1.357 +                        anchor = "s" .. suggestion.id -- TODO webmcp
   1.358 +                      } },
   1.359 +                      content = function ()
   1.360 +                      
   1.361 +                        
   1.362 +                        ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" }
   1.363 +                        ui.container { content = function ()
   1.364 +                        
   1.365 +                          local active = opinion.degree == 2
   1.366 +                          ui.tag { tag = "input", attr = {
   1.367 +                            type = "radio", name = "degree", value = 2, 
   1.368 +                            id = "s" .. suggestion.id .. "_degree2",
   1.369 +                            checked = active and "checked" or nil
   1.370 +                          } }
   1.371 +                          ui.tag { 
   1.372 +                            tag = "label", 
   1.373 +                            attr = {
   1.374 +                              ["for"] = "s" .. suggestion.id .. "_degree2",
   1.375 +                              class = active and "active-plus2" or nil,
   1.376 +                            },
   1.377 +                            content = _"must"
   1.378 +                          }
   1.379 +                          
   1.380 +                          local active = opinion.degree == 1
   1.381 +                          ui.tag { tag = "input", attr = {
   1.382 +                            type = "radio", name = "degree", value = 1,
   1.383 +                            id = "s" .. suggestion.id .. "_degree1",
   1.384 +                            checked = active and "checked" or nil
   1.385 +                          } }
   1.386 +                          ui.tag { 
   1.387 +                            tag = "label", 
   1.388 +                            attr = {
   1.389 +                              ["for"] = "s" .. suggestion.id .. "_degree1",
   1.390 +                              class = active and "active-plus1" or nil,
   1.391 +                            },
   1.392 +                            content = _"should"
   1.393 +                          }
   1.394 +
   1.395 +                          local active = not opinion.member_id
   1.396 +                          ui.tag { tag = "input", attr = {
   1.397 +                            type = "radio", name = "degree", value = 0,
   1.398 +                            id = "s" .. suggestion.id .. "_degree0",
   1.399 +                            checked = active and "checked" or nil
   1.400 +                          } }
   1.401 +                          ui.tag { 
   1.402 +                            tag = "label", 
   1.403 +                            attr = {
   1.404 +                              ["for"] = "s" .. suggestion.id .. "_degree0",
   1.405 +                              class = active and "active-neutral" or nil,
   1.406 +                            },
   1.407 +                            content = _"neutral"
   1.408 +                          }
   1.409 +
   1.410 +                          local active = opinion.degree == -1
   1.411 +                          ui.tag { tag = "input", attr = {
   1.412 +                            type = "radio", name = "degree", value = -1,
   1.413 +                            id = "s" .. suggestion.id .. "_degree-1",
   1.414 +                            checked = active and "checked" or nil
   1.415 +                          } }
   1.416 +                          ui.tag { 
   1.417 +                            tag = "label", 
   1.418 +                            attr = {
   1.419 +                              ["for"] = "s" .. suggestion.id .. "_degree-1",
   1.420 +                              class = active and "active-minus1" or nil,
   1.421 +                            },
   1.422 +                            content = _"should not"
   1.423 +                          }
   1.424 +
   1.425 +                          local active = opinion.degree == -2
   1.426 +                          ui.tag { tag = "input", attr = {
   1.427 +                            type = "radio", name = "degree", value = -2,
   1.428 +                            id = "s" .. suggestion.id .. "_degree-2",
   1.429 +                            checked = active and "checked" or nil
   1.430 +                          } }
   1.431 +                          ui.tag { 
   1.432 +                            tag = "label", 
   1.433 +                            attr = {
   1.434 +                              ["for"] = "s" .. suggestion.id .. "_degree-2",
   1.435 +                              class = active and "active-minus2" or nil,
   1.436 +                            },
   1.437 +                            content = _"must not"
   1.438 +                          }
   1.439 +                        end }
   1.440 +                        
   1.441 +                        slot.put("<br />")
   1.442 +
   1.443 +                        ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" }
   1.444 +                        ui.container { content = function ()
   1.445 +                          local active = opinion.fulfilled == false
   1.446 +                          ui.tag { tag = "input", attr = {
   1.447 +                            type = "radio", name = "fulfilled", value = "false",
   1.448 +                            id = "s" .. suggestion.id .. "_notfulfilled",
   1.449 +                            checked = active and "checked" or nil
   1.450 +                          } }
   1.451 +                          ui.tag { 
   1.452 +                            tag = "label", 
   1.453 +                            attr = {
   1.454 +                              ["for"] = "s" .. suggestion.id .. "_notfulfilled",
   1.455 +                              class = active and "active-notfulfilled" or nil,
   1.456 +                            },
   1.457 +                            content = _"No (not yet)"
   1.458 +                          }
   1.459 +
   1.460 +                          local active = opinion.fulfilled
   1.461 +                          ui.tag { tag = "input", attr = {
   1.462 +                            type = "radio", name = "fulfilled", value = "true",
   1.463 +                            id = "s" .. suggestion.id .. "_fulfilled",
   1.464 +                            checked = active and "checked" or nil
   1.465 +                          } }
   1.466 +                          ui.tag { 
   1.467 +                            tag = "label", 
   1.468 +                            attr = {
   1.469 +                              ["for"] = "s" .. suggestion.id .. "_fulfilled",
   1.470 +                              class = active and "active-fulfilled" or nil,
   1.471 +                            },
   1.472 +                            content = _"Yes, it's implemented"
   1.473 +                          }
   1.474 +                        end }
   1.475 +                        slot.put("<br />")
   1.476 +                        
   1.477 +                        ui.tag{
   1.478 +                          tag = "input",
   1.479 +                          attr = {
   1.480 +                            type = "submit",
   1.481 +                            class = "btn btn-default",
   1.482 +                            value = _"publish my rating"
   1.483 +                          },
   1.484 +                          content = ""
   1.485 +                        }
   1.486 +                        
   1.487 +                      end 
   1.488 +                    }
   1.489 +
   1.490 +                  end -- if not issue,fully_frozen or closed
   1.491 +                }
   1.492 +              end 
   1.493 +                
   1.494 +                local text = _"Read more"
   1.495 +                
   1.496 +                if direct_supporter then
   1.497 +                  text = _"Show more and rate this"
   1.498 +                end
   1.499 +                  
   1.500 +                ui.link { 
   1.501 +                  attr = { 
   1.502 +                    class = "suggestion-more",
   1.503 +                    onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;"
   1.504 +                  },
   1.505 +                  text = text
   1.506 +                }
   1.507 +                
   1.508 +                ui.link { 
   1.509 +                  attr = { 
   1.510 +                    class = "suggestion-less",
   1.511 +                    onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;"
   1.512 +                  },
   1.513 +                  text = _"Show less"
   1.514 +                }
   1.515 +                end
   1.516 +              }
   1.517 +              
   1.518 +              ui.script{ script = [[
   1.519 +                var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text');
   1.520 +                var height = textEl.height();
   1.521 +                if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded');
   1.522 +              ]] }
   1.523 +               
   1.524 +            end
   1.525 +          } -- ui.paragraph
   1.526 +          
   1.527 +              
   1.528 +
   1.529 +        end } -- ui.tag "li"
   1.530 +        
   1.531 +      end -- for i, suggestion
   1.532 +      
   1.533 +    else -- if #initiative.suggestions > 0
   1.534 +      
   1.535 +      local text
   1.536 +      if initiative.issue.closed then
   1.537 +        text = "No suggestions"
   1.538 +      else
   1.539 +        text = "No suggestions (yet)"
   1.540 +      end
   1.541 +      ui.sectionHead( function()
   1.542 +        ui.heading { level = 1, content = text }
   1.543 +      end)
   1.544 +      
   1.545 +    end -- if #initiative.suggestions > 0
   1.546 +    
   1.547 +  end
   1.548 +}

Impressum / About Us