liquid_feedback_frontend

diff app/main/vote/list.lua @ 1045:701a5cf6b067

Imported LiquidFeedback Frontend 3.0 branch
author bsw
date Thu Jul 10 01:19:48 2014 +0200 (2014-07-10)
parents 37e31dd73e45
children 904f6807f7fa
line diff
     1.1 --- a/app/main/vote/list.lua	Thu Jul 10 01:02:43 2014 +0200
     1.2 +++ b/app/main/vote/list.lua	Thu Jul 10 01:19:48 2014 +0200
     1.3 @@ -21,69 +21,29 @@
     1.4    readonly = true
     1.5  end
     1.6  
     1.7 +if preview then
     1.8 +  readonly = true
     1.9 +end
    1.10 +
    1.11  local submit_button_text = _"Finish voting"
    1.12 +local edit_button_text = _"Edit again"
    1.13  
    1.14  if issue.closed then
    1.15 -  submit_button_text = _"Update voting comment"
    1.16 +  submit_button_text = _"Save voting comment"
    1.17 +  edit_button_text = _"Edit voting comment"
    1.18  end
    1.19  
    1.20 +execute.view {
    1.21 +  module = "issue", view = "_head", params = { issue = issue }
    1.22 +}
    1.23 +
    1.24  local direct_voter
    1.25  
    1.26  if member then
    1.27    direct_voter = DirectVoter:by_pk(issue.id, member.id)
    1.28 -  local str = _("Ballot of '#{member_name}' for issue ##{issue_id}",
    1.29 -                  {member_name = string.format('<a href="%s">%s</a>',
    1.30 -                                          encode.url{
    1.31 -                                            module    = "member",
    1.32 -                                            view      = "show",
    1.33 -                                            id        = member.id,
    1.34 -                                          },
    1.35 -                                          encode.html(member.name)),
    1.36 -                   issue_id = string.format('<a href="%s">%s</a>',
    1.37 -                                          encode.url{
    1.38 -                                            module    = "issue",
    1.39 -                                            view      = "show",
    1.40 -                                            id        = issue.id,
    1.41 -                                          },
    1.42 -                                          encode.html(tostring(issue.id)))
    1.43 -                  }
    1.44 -              )
    1.45 -  ui.raw_title(str)
    1.46  else
    1.47    member = app.session.member
    1.48 -
    1.49    direct_voter = DirectVoter:by_pk(issue.id, member.id)
    1.50 -
    1.51 -  ui.title(_"Voting")
    1.52 -
    1.53 -  ui.actions(function()
    1.54 -    ui.link{
    1.55 -      text = _"Cancel",
    1.56 -      module = "issue",
    1.57 -      view = "show",
    1.58 -      id = issue.id
    1.59 -    }
    1.60 -    if direct_voter then
    1.61 -      slot.put(" &middot; ")
    1.62 -      ui.link{
    1.63 -        text = _"Discard voting",
    1.64 -        module = "vote",
    1.65 -        action = "update",
    1.66 -        params = {
    1.67 -          issue_id = issue.id,
    1.68 -          discard = true
    1.69 -        },
    1.70 -        routing = {
    1.71 -          default = {
    1.72 -            mode = "redirect",
    1.73 -            module = "issue",
    1.74 -            view = "show",
    1.75 -            id = issue.id
    1.76 -          }
    1.77 -        }
    1.78 -      }
    1.79 -    end
    1.80 -  end)
    1.81  end
    1.82  
    1.83  
    1.84 @@ -144,10 +104,7 @@
    1.85    end
    1.86  end
    1.87  
    1.88 -
    1.89 -
    1.90  if not readonly then
    1.91 -  util.help("vote.list", _"Voting")
    1.92    slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>')
    1.93    slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>')
    1.94  end
    1.95 @@ -179,321 +136,436 @@
    1.96    end
    1.97  }
    1.98  
    1.99 -ui.form{
   1.100 -  record = direct_voter,
   1.101 -  attr = {
   1.102 -    id = "voting_form",
   1.103 -    class = readonly and "voting_form_readonly" or "voting_form_active"
   1.104 -  },
   1.105 -  module = "vote",
   1.106 -  action = "update",
   1.107 -  params = { issue_id = issue.id },
   1.108 -  content = function()
   1.109 -    if not readonly or preview then
   1.110 -      local scoring = param.get("scoring")
   1.111 -      if not scoring then
   1.112 -        for i, initiative in ipairs(initiatives) do
   1.113 -          local vote = initiative.vote
   1.114 -          if vote then
   1.115 -            tempvotings[initiative.id] = vote.grade
   1.116 -          else
   1.117 -            tempvotings[initiative.id] = 0
   1.118 -          end
   1.119 -        end
   1.120 -        local tempvotings_list = {}
   1.121 -        for key, val in pairs(tempvotings) do
   1.122 -          tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
   1.123 -        end
   1.124 -        if #tempvotings_list > 0 then
   1.125 -          scoring = table.concat(tempvotings_list, ";")
   1.126 -        else
   1.127 -          scoring = ""
   1.128 -        end
   1.129 -      end
   1.130 -      slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>')
   1.131 -      -- TODO abstrahieren
   1.132 -      ui.tag{
   1.133 -        tag = "input",
   1.134 -        attr = {
   1.135 -          type = "submit",
   1.136 -          class = "voting_done1",
   1.137 -          value = submit_button_text
   1.138 -        }
   1.139 +if issue.state == "finished_with_winner" 
   1.140 +  or issue.state == "finished_without_winner" 
   1.141 +then
   1.142 +
   1.143 +  local members_selector = Member:new_selector()
   1.144 +    :join("delegating_voter", nil, "delegating_voter.member_id = member.id")
   1.145 +    :add_where{ "delegating_voter.issue_id = ?", issue.id }
   1.146 +    :add_where{ "delegating_voter.delegate_member_ids[1] = ?", member.id }
   1.147 +    :add_field("delegating_voter.weight", "voter_weight")
   1.148 +    :join("issue", nil, "issue.id = delegating_voter.issue_id")
   1.149 +    
   1.150 +  ui.sidebar( "tab-members", function()
   1.151 +    ui.sidebarHead(function()
   1.152 +      ui.heading{ level = 2, content = _"Incoming delegations" }
   1.153 +    end)
   1.154 +    execute.view{
   1.155 +      module = "member",
   1.156 +      view = "_list",
   1.157 +      params = {
   1.158 +        members_selector = members_selector,
   1.159 +        trustee = member,
   1.160 +        issue = issue,
   1.161 +        initiative = initiative,
   1.162 +        for_votes = true, no_filter = true,
   1.163 +        member_class = "sidebarRow sidebarRowNarrow",
   1.164        }
   1.165 +    }
   1.166 +  end)
   1.167 +end
   1.168 +
   1.169 +
   1.170 +ui.section( function()
   1.171 +
   1.172 +  ui.sectionHead( function()
   1.173 +    if preview then
   1.174 +      ui.heading { level = 1, content = _"Preview of voting ballot" }
   1.175 +    elseif readonly then
   1.176 +      local str = _("Ballot of '#{member_name}'",
   1.177 +                      {member_name = string.format('<a href="%s">%s</a>',
   1.178 +                                              encode.url{
   1.179 +                                                module    = "member",
   1.180 +                                                view      = "show",
   1.181 +                                                id        = member.id,
   1.182 +                                              },
   1.183 +                                              encode.html(member.name))
   1.184 +                      }
   1.185 +                  )
   1.186 +      ui.heading { level = 1, content = function () slot.put ( str ) end }
   1.187 +    else
   1.188 +      ui.heading { level = 1, content = _"Voting" }
   1.189      end
   1.190 -    ui.container{
   1.191 -      attr = { id = "voting" },
   1.192 +  end )
   1.193 +  
   1.194 +  ui.sectionRow( function()
   1.195 +
   1.196 +    ui.form{
   1.197 +      record = direct_voter,
   1.198 +      attr = {
   1.199 +        id = "voting_form",
   1.200 +        class = readonly and "voting_form_readonly" or "voting_form_active"
   1.201 +      },
   1.202 +      module = "vote",
   1.203 +      action = "update",
   1.204 +      params = { issue_id = issue.id },
   1.205        content = function()
   1.206 -        local approval_index, disapproval_index = 0, 0
   1.207 -        for grade = max_grade, min_grade, -1 do 
   1.208 -          local entries = sections[grade]
   1.209 -          local class
   1.210 -          if grade > 0 then
   1.211 -            class = "approval"
   1.212 -          elseif grade < 0 then
   1.213 -            class = "disapproval"
   1.214 -          else
   1.215 -            class = "abstention"
   1.216 +        if not readonly or preview then
   1.217 +          local scoring = param.get("scoring")
   1.218 +          if not scoring then
   1.219 +            for i, initiative in ipairs(initiatives) do
   1.220 +              local vote = initiative.vote
   1.221 +              if vote then
   1.222 +                tempvotings[initiative.id] = vote.grade
   1.223 +              else
   1.224 +                tempvotings[initiative.id] = 0
   1.225 +              end
   1.226 +            end
   1.227 +            local tempvotings_list = {}
   1.228 +            for key, val in pairs(tempvotings) do
   1.229 +              tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
   1.230 +            end
   1.231 +            if #tempvotings_list > 0 then
   1.232 +              scoring = table.concat(tempvotings_list, ";")
   1.233 +            else
   1.234 +              scoring = ""
   1.235 +            end
   1.236            end
   1.237 -          if
   1.238 -            #entries > 0 or
   1.239 -            (grade == 1 and not approval_used) or
   1.240 -            (grade == -1 and not disapproval_used) or
   1.241 -            grade == 0
   1.242 -          then
   1.243 -            ui.container{
   1.244 -              attr = { class = class },
   1.245 -              content = function()
   1.246 -                local heading
   1.247 -                if class == "approval" then
   1.248 -                  approval_used = true
   1.249 -                  approval_index = approval_index + 1
   1.250 -                  if approval_count > 1 then
   1.251 -                    if approval_index == 1 then
   1.252 -                      if #entries == 1 then
   1.253 -                        heading = _"Approval (first preference) [single entry]"
   1.254 +          slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>')
   1.255 +        end
   1.256 +        if preview then
   1.257 +          ui.heading{ level = 2, content = _"Your choice" }
   1.258 +        elseif not readonly then
   1.259 +          ui.heading{ level = 2, content = _"Make your choice by placing the initiatives" }
   1.260 +        end
   1.261 +        
   1.262 +        ui.container{
   1.263 +          attr = { id = "voting" },
   1.264 +          content = function()
   1.265 +            local approval_index, disapproval_index = 0, 0
   1.266 +            for grade = max_grade, min_grade, -1 do 
   1.267 +              local entries = sections[grade]
   1.268 +              local class
   1.269 +              if grade > 0 then
   1.270 +                class = "approval"
   1.271 +              elseif grade < 0 then
   1.272 +                class = "disapproval"
   1.273 +              else
   1.274 +                class = "abstention"
   1.275 +              end
   1.276 +              if
   1.277 +                #entries > 0 or
   1.278 +                (grade == 1 and not approval_used) or
   1.279 +                (grade == -1 and not disapproval_used) or
   1.280 +                grade == 0
   1.281 +              then
   1.282 +                ui.container{
   1.283 +                  attr = { class = class },
   1.284 +                  content = function()
   1.285 +                    local heading
   1.286 +                    if class == "approval" then
   1.287 +                      approval_used = true
   1.288 +                      approval_index = approval_index + 1
   1.289 +                      if approval_count > 1 then
   1.290 +                        if approval_index == 1 then
   1.291 +                          if #entries == 1 then
   1.292 +                            heading = _"Approval (first preference) [single entry]"
   1.293 +                          else
   1.294 +                            heading = _"Approval (first preference) [many entries]"
   1.295 +                          end
   1.296 +                        elseif approval_index == 2 then
   1.297 +                          if #entries == 1 then
   1.298 +                            heading = _"Approval (second preference) [single entry]"
   1.299 +                          else
   1.300 +                            heading = _"Approval (second preference) [many entries]"
   1.301 +                          end
   1.302 +                        elseif approval_index == 3 then
   1.303 +                          if #entries == 1 then
   1.304 +                            heading = _"Approval (third preference) [single entry]"
   1.305 +                          else
   1.306 +                            heading = _"Approval (third preference) [many entries]"
   1.307 +                          end
   1.308 +                        else
   1.309 +                          if #entries == 1 then
   1.310 +                            heading = _"Approval (#th preference) [single entry]"
   1.311 +                          else
   1.312 +                            heading = _"Approval (#th preference) [many entries]"
   1.313 +                          end
   1.314 +                        end
   1.315                        else
   1.316 -                        heading = _"Approval (first preference) [many entries]"
   1.317 -                      end
   1.318 -                    elseif approval_index == 2 then
   1.319 -                      if #entries == 1 then
   1.320 -                        heading = _"Approval (second preference) [single entry]"
   1.321 -                      else
   1.322 -                        heading = _"Approval (second preference) [many entries]"
   1.323 +                        if #entries == 1 then
   1.324 +                          heading = _"Approval [single entry]"
   1.325 +                        else
   1.326 +                          heading = _"Approval [many entries]"
   1.327 +                        end
   1.328                        end
   1.329 -                    elseif approval_index == 3 then
   1.330 -                      if #entries == 1 then
   1.331 -                        heading = _"Approval (third preference) [single entry]"
   1.332 +                    elseif class == "abstention" then
   1.333 +                        if #entries == 1 then
   1.334 +                          heading = _"Abstention [single entry]"
   1.335 +                        else
   1.336 +                          heading = _"Abstention [many entries]"
   1.337 +                        end
   1.338 +                    elseif class == "disapproval" then
   1.339 +                      disapproval_used = true
   1.340 +                      disapproval_index = disapproval_index + 1
   1.341 +                      if disapproval_count > disapproval_index + 1 then
   1.342 +                        if #entries == 1 then
   1.343 +                          heading = _"Disapproval (prefer to lower blocks) [single entry]"
   1.344 +                        else
   1.345 +                          heading = _"Disapproval (prefer to lower blocks) [many entries]"
   1.346 +                        end
   1.347 +                      elseif disapproval_count == 2 and disapproval_index == 1 then
   1.348 +                        if #entries == 1 then
   1.349 +                          heading = _"Disapproval (prefer to lower block) [single entry]"
   1.350 +                        else
   1.351 +                          heading = _"Disapproval (prefer to lower block) [many entries]"
   1.352 +                        end
   1.353 +                      elseif disapproval_index == disapproval_count - 1 then
   1.354 +                        if #entries == 1 then
   1.355 +                          heading = _"Disapproval (prefer to last block) [single entry]"
   1.356 +                        else
   1.357 +                          heading = _"Disapproval (prefer to last block) [many entries]"
   1.358 +                        end
   1.359                        else
   1.360 -                        heading = _"Approval (third preference) [many entries]"
   1.361 -                      end
   1.362 -                    else
   1.363 -                      if #entries == 1 then
   1.364 -                        heading = _"Approval (#th preference) [single entry]"
   1.365 -                      else
   1.366 -                        heading = _"Approval (#th preference) [many entries]"
   1.367 +                        if #entries == 1 then
   1.368 +                          heading = _"Disapproval [single entry]"
   1.369 +                        else
   1.370 +                          heading = _"Disapproval [many entries]"
   1.371 +                        end
   1.372                        end
   1.373                      end
   1.374 -                  else
   1.375 -                    if #entries == 1 then
   1.376 -                      heading = _"Approval [single entry]"
   1.377 -                    else
   1.378 -                      heading = _"Approval [many entries]"
   1.379 -                    end
   1.380 -                  end
   1.381 -                elseif class == "abstention" then
   1.382 -                    if #entries == 1 then
   1.383 -                      heading = _"Abstention [single entry]"
   1.384 -                    else
   1.385 -                      heading = _"Abstention [many entries]"
   1.386 -                    end
   1.387 -                elseif class == "disapproval" then
   1.388 -                  disapproval_used = true
   1.389 -                  disapproval_index = disapproval_index + 1
   1.390 -                  if disapproval_count > disapproval_index + 1 then
   1.391 -                    if #entries == 1 then
   1.392 -                      heading = _"Disapproval (prefer to lower blocks) [single entry]"
   1.393 -                    else
   1.394 -                      heading = _"Disapproval (prefer to lower blocks) [many entries]"
   1.395 -                    end
   1.396 -                  elseif disapproval_count == 2 and disapproval_index == 1 then
   1.397 -                    if #entries == 1 then
   1.398 -                      heading = _"Disapproval (prefer to lower block) [single entry]"
   1.399 -                    else
   1.400 -                      heading = _"Disapproval (prefer to lower block) [many entries]"
   1.401 -                    end
   1.402 -                  elseif disapproval_index == disapproval_count - 1 then
   1.403 -                    if #entries == 1 then
   1.404 -                      heading = _"Disapproval (prefer to last block) [single entry]"
   1.405 -                    else
   1.406 -                      heading = _"Disapproval (prefer to last block) [many entries]"
   1.407 -                    end
   1.408 -                  else
   1.409 -                    if #entries == 1 then
   1.410 -                      heading = _"Disapproval [single entry]"
   1.411 -                    else
   1.412 -                      heading = _"Disapproval [many entries]"
   1.413 -                    end
   1.414 -                  end
   1.415 -                end
   1.416 -                ui.tag {
   1.417 -                  tag     = "div",
   1.418 -                  attr    = { class = "cathead" },
   1.419 -                  content = heading
   1.420 -                }
   1.421 -                for i, initiative in ipairs(entries) do
   1.422 -                  ui.container{
   1.423 -                    attr = {
   1.424 -                      class = "movable",
   1.425 -                      id = "entry_" .. tostring(initiative.id)
   1.426 -                    },
   1.427 -                    content = function()
   1.428 -                      local initiators_selector = initiative:get_reference_selector("initiating_members")
   1.429 -                        :add_where("accepted")
   1.430 -                      local initiators = initiators_selector:exec()
   1.431 -                      local initiator_names = {}
   1.432 -                      for i, initiator in ipairs(initiators) do
   1.433 -                        initiator_names[#initiator_names+1] = initiator.name
   1.434 -                      end
   1.435 -                      local initiator_names_string = table.concat(initiator_names, ", ")
   1.436 +                    ui.tag {
   1.437 +                      tag     = "div",
   1.438 +                      attr    = { class = "cathead" },
   1.439 +                      content = heading
   1.440 +                    }
   1.441 +                    for i, initiative in ipairs(entries) do
   1.442                        ui.container{
   1.443 -                        attr = { style = "float: right; position: relative;" },
   1.444 +                        attr = {
   1.445 +                          class = "movable",
   1.446 +                          id = "entry_" .. tostring(initiative.id)
   1.447 +                        },
   1.448                          content = function()
   1.449 -                          ui.link{
   1.450 -                            attr = { class = "clickable" },
   1.451 -                            content = _"Show",
   1.452 -                            module = "initiative",
   1.453 -                            view = "show",
   1.454 -                            id = initiative.id
   1.455 -                          }
   1.456 -                          slot.put(" ")
   1.457 -                          ui.link{
   1.458 -                            attr = { class = "clickable", target = "_blank" },
   1.459 -                            content = _"(new window)",
   1.460 -                            module = "initiative",
   1.461 -                            view = "show",
   1.462 -                            id = initiative.id
   1.463 +                          local initiators_selector = initiative:get_reference_selector("initiating_members")
   1.464 +                            :add_where("accepted")
   1.465 +                          local initiators = initiators_selector:exec()
   1.466 +                          local initiator_names = {}
   1.467 +                          for i, initiator in ipairs(initiators) do
   1.468 +                            initiator_names[#initiator_names+1] = initiator.name
   1.469 +                          end
   1.470 +                          local initiator_names_string = table.concat(initiator_names, ", ")
   1.471 +                          ui.container{
   1.472 +                            attr = { style = "float: right; position: relative;" },
   1.473 +                            content = function()
   1.474 +                              ui.link{
   1.475 +                                attr = { class = "clickable" },
   1.476 +                                content = _"Show",
   1.477 +                                module = "initiative",
   1.478 +                                view = "show",
   1.479 +                                id = initiative.id
   1.480 +                              }
   1.481 +                              slot.put(" ")
   1.482 +                              ui.link{
   1.483 +                                attr = { class = "clickable", target = "_blank" },
   1.484 +                                content = _"(new window)",
   1.485 +                                module = "initiative",
   1.486 +                                view = "show",
   1.487 +                                id = initiative.id
   1.488 +                              }
   1.489 +                              if not readonly then
   1.490 +                                slot.put(" ")
   1.491 +                                ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
   1.492 +                              end
   1.493 +                            end
   1.494                            }
   1.495                            if not readonly then
   1.496 -                            slot.put(" ")
   1.497 -                            ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
   1.498 -                          end
   1.499 -                        end
   1.500 -                      }
   1.501 -                      if not readonly then
   1.502 -                        ui.container{
   1.503 -                          attr = { style = "float: left; position: relative;" },
   1.504 -                          content = function()
   1.505 -                            ui.tag{
   1.506 -                              tag = "input",
   1.507 -                              attr = {
   1.508 -                                onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
   1.509 -                                name = "move_up_" .. tostring(initiative.id),
   1.510 -                                class = not disabled and "clickable" or nil,
   1.511 -                                type = "image",
   1.512 -                                src = encode.url{ static = "icons/move_up.png" },
   1.513 -                                alt = _"Move up"
   1.514 -                              }
   1.515 -                            }
   1.516 -                            slot.put("&nbsp;")
   1.517 -                            ui.tag{
   1.518 -                              tag = "input",
   1.519 -                              attr = {
   1.520 -                                onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
   1.521 -                                name = "move_down_" .. tostring(initiative.id),
   1.522 -                                class = not disabled and "clickable" or nil,
   1.523 -                                type = "image",
   1.524 -                                src = encode.url{ static = "icons/move_down.png" },
   1.525 -                                alt = _"Move down"
   1.526 -                              }
   1.527 -                            }
   1.528 -                            slot.put("&nbsp;")
   1.529 -                          end
   1.530 -                        }
   1.531 -                      end
   1.532 -                      ui.container{
   1.533 -                        content = function()
   1.534 -                          ui.tag{ content = "i" .. initiative.id .. ": " }
   1.535 -                          ui.tag{ content = initiative.shortened_name }
   1.536 -                          slot.put("<br />")
   1.537 -                          for i, initiator in ipairs(initiators) do
   1.538 -                            ui.link{
   1.539 -                              attr = { class = "clickable" },
   1.540 -                              content = function ()
   1.541 -                                execute.view{
   1.542 -                                  module = "member_image",
   1.543 -                                  view = "_show",
   1.544 -                                  params = {
   1.545 -                                    member = initiator,
   1.546 -                                    image_type = "avatar",
   1.547 -                                    show_dummy = true,
   1.548 -                                    class = "micro_avatar",
   1.549 -                                    popup_text = text
   1.550 +                            ui.container{
   1.551 +                              attr = { style = "float: left; position: relative;" },
   1.552 +                              content = function()
   1.553 +                                ui.tag{
   1.554 +                                  tag = "input",
   1.555 +                                  attr = {
   1.556 +                                    onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
   1.557 +                                    name = "move_up_" .. tostring(initiative.id),
   1.558 +                                    class = not disabled and "clickable" or nil,
   1.559 +                                    type = "image",
   1.560 +                                    src = encode.url{ static = "icons/move_up.png" },
   1.561 +                                    alt = _"Move up"
   1.562 +                                  }
   1.563 +                                }
   1.564 +                                slot.put("&nbsp;")
   1.565 +                                ui.tag{
   1.566 +                                  tag = "input",
   1.567 +                                  attr = {
   1.568 +                                    onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
   1.569 +                                    name = "move_down_" .. tostring(initiative.id),
   1.570 +                                    class = not disabled and "clickable" or nil,
   1.571 +                                    type = "image",
   1.572 +                                    src = encode.url{ static = "icons/move_down.png" },
   1.573 +                                    alt = _"Move down"
   1.574                                    }
   1.575                                  }
   1.576 -                              end,
   1.577 -                              module = "member", view = "show", id = initiator.id
   1.578 +                                slot.put("&nbsp;")
   1.579 +                              end
   1.580                              }
   1.581 -                            slot.put(" ")
   1.582 -                            ui.tag{ content = initiator.name }
   1.583 -                            slot.put(" ")
   1.584                            end
   1.585 +                          ui.container{
   1.586 +                            content = function()
   1.587 +                              ui.tag{ content = "i" .. initiative.id .. ": " }
   1.588 +                              ui.tag{ content = initiative.shortened_name }
   1.589 +                              slot.put("<br />")
   1.590 +                              for i, initiator in ipairs(initiators) do
   1.591 +                                ui.link{
   1.592 +                                  attr = { class = "clickable" },
   1.593 +                                  content = function ()
   1.594 +                                    execute.view{
   1.595 +                                      module = "member_image",
   1.596 +                                      view = "_show",
   1.597 +                                      params = {
   1.598 +                                        member = initiator,
   1.599 +                                        image_type = "avatar",
   1.600 +                                        show_dummy = true,
   1.601 +                                        class = "micro_avatar",
   1.602 +                                        popup_text = text
   1.603 +                                      }
   1.604 +                                    }
   1.605 +                                  end,
   1.606 +                                  module = "member", view = "show", id = initiator.id
   1.607 +                                }
   1.608 +                                slot.put(" ")
   1.609 +                                ui.tag{ content = initiator.name }
   1.610 +                                slot.put(" ")
   1.611 +                              end
   1.612 +                            end
   1.613 +                          }
   1.614                          end
   1.615                        }
   1.616                      end
   1.617 +                  end
   1.618 +                }
   1.619 +              end
   1.620 +            end
   1.621 +          end
   1.622 +        }
   1.623 +        if app.session.member_id and preview then
   1.624 +          local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine
   1.625 +          local comment = param.get("comment")
   1.626 +          if comment and #comment > 0 then
   1.627 +            local rendered_comment = format.wiki_text(comment, formatting_engine)
   1.628 +            ui.heading{ level = "2", content = _"Voting comment" }
   1.629 +            ui.container { attr = { class = "member_statement" }, content = function()
   1.630 +              slot.put(rendered_comment)
   1.631 +            end }
   1.632 +            slot.put("<br />")
   1.633 +          end
   1.634 +        end
   1.635 +        if (readonly or direct_voter and direct_voter.comment) and not preview and not (app.session.member_id == member.id) then
   1.636 +          local text
   1.637 +          if direct_voter and direct_voter.comment_changed then
   1.638 +            text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) })
   1.639 +          elseif direct_voter and direct_voter.comment then
   1.640 +            text = _"Voting comment"
   1.641 +          end
   1.642 +          if text then
   1.643 +            ui.heading{ level = "2", content = text }
   1.644 +          end
   1.645 +          if direct_voter and direct_voter.comment then
   1.646 +            local rendered_comment = direct_voter:get_content('html')
   1.647 +            ui.container { attr = { class = "member_statement" }, content = function()
   1.648 +              slot.put(rendered_comment)
   1.649 +            end }
   1.650 +            slot.put("<br />")
   1.651 +          end
   1.652 +        end
   1.653 +        if app.session.member_id and app.session.member_id == member.id then
   1.654 +          if (not readonly or direct_voter) and not preview then
   1.655 +            ui.container{ content = function()
   1.656 +              if not config.enforce_formatting_engine then
   1.657 +                ui.field.select{
   1.658 +                  label = _"Wiki engine for statement",
   1.659 +                  name = "formatting_engine",
   1.660 +                  foreign_records = config.formatting_engines,
   1.661 +                  attr = {id = "formatting_engine"},
   1.662 +                  foreign_id = "id",
   1.663 +                  foreign_name = "name",
   1.664 +                  value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine
   1.665 +                }
   1.666 +              end
   1.667 +              ui.heading { level = 2, content = _"Voting comment (optional)" }
   1.668 +              ui.field.text{
   1.669 +                name = "comment",
   1.670 +                multiline = true,
   1.671 +                value = param.get("comment") or direct_voter and direct_voter.comment,
   1.672 +                attr = { style = "height: 10ex; width: 100%;" },
   1.673 +              }
   1.674 +            end }
   1.675 +          end
   1.676 +
   1.677 +          if preview then
   1.678 +            if not config.enforce_formatting_engine then
   1.679 +              ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") }
   1.680 +            end
   1.681 +            ui.field.hidden{ name = "comment", value = param.get("comment") or direct_voter and direct_voter.comment }
   1.682 +          end
   1.683 +          
   1.684 +          if not readonly or direct_voter or preview then
   1.685 +            ui.container{ content = function()
   1.686 +              if preview  then
   1.687 +                slot.put(" ")
   1.688 +                ui.tag{
   1.689 +                  tag = "input",
   1.690 +                  attr = {
   1.691 +                    type = "submit",
   1.692 +                    class = "btn btn-default",
   1.693 +                    name = issue.closed and "update_comment" or nil,
   1.694 +                    value = submit_button_text -- finish voting / update comment
   1.695                    }
   1.696 -                end
   1.697 +                }
   1.698                end
   1.699 -            }
   1.700 +              if not preview then
   1.701 +                ui.tag{
   1.702 +                  tag = "input",
   1.703 +                  attr = {
   1.704 +                    type = "submit",
   1.705 +                    name = "preview",
   1.706 +                    class = "btn btn-default",
   1.707 +                    value = _"Preview",
   1.708 +                  }
   1.709 +                }
   1.710 +              else
   1.711 +                slot.put(" ")
   1.712 +                ui.tag{
   1.713 +                  tag = "input",
   1.714 +                  attr = {
   1.715 +                    type = "submit",
   1.716 +                    name = "edit",
   1.717 +                    class = "btn-link",
   1.718 +                    value = edit_button_text,
   1.719 +                  }
   1.720 +                }
   1.721 +              end
   1.722 +            end }
   1.723            end
   1.724          end
   1.725        end
   1.726      }
   1.727 -    if app.session.member_id and preview then
   1.728 -      local formatting_engine = param.get("formatting_engine")
   1.729 -      local comment = param.get("comment")
   1.730 -      local rendered_comment = format.wiki_text(comment, formatting_engine)
   1.731 -      slot.put(rendered_comment)
   1.732 -    end
   1.733 -    if (readonly or direct_voter and direct_voter.comment) and not preview then
   1.734 -      local text
   1.735 -      if direct_voter and direct_voter.comment_changed then
   1.736 -        text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) })
   1.737 -      elseif direct_voter and direct_voter.comment then
   1.738 -        text = _"Voting comment"
   1.739 -      end
   1.740 -      if text then
   1.741 -        ui.heading{ level = "2", content = text }
   1.742 -      end
   1.743 -      if direct_voter and direct_voter.comment then
   1.744 -        local rendered_comment = direct_voter:get_content('html')
   1.745 -        ui.container{ attr = { class = "member_statement" }, content = function()
   1.746 -          slot.put(rendered_comment)
   1.747 -        end }
   1.748 -        slot.put("<br />")
   1.749 -      end
   1.750 +    slot.put("<br />")
   1.751 +    ui.link{
   1.752 +      text = _"Cancel",
   1.753 +      module = "issue",
   1.754 +      view = "show",
   1.755 +      id = issue.id
   1.756 +    }
   1.757 +    if direct_voter then
   1.758 +      slot.put(" | ")
   1.759 +      ui.link {
   1.760 +        module = "vote", action = "update",
   1.761 +        params = {
   1.762 +          issue_id = issue.id,
   1.763 +          discard = true
   1.764 +        },
   1.765 +        routing = {
   1.766 +          default = {
   1.767 +            mode = "redirect",
   1.768 +            module = "issue",
   1.769 +            view = "show",
   1.770 +            id = issue.id
   1.771 +          }
   1.772 +        },
   1.773 +        text = _"Discard my vote"
   1.774 +      }
   1.775      end
   1.776 -    if app.session.member_id and app.session.member_id == member.id then
   1.777 -      if not readonly or direct_voter then
   1.778 -        ui.field.hidden{ name = "update_comment", value = param.get("update_comment") or issue.closed and "1" }
   1.779 -        ui.field.select{
   1.780 -          label = _"Wiki engine for statement",
   1.781 -          name = "formatting_engine",
   1.782 -          foreign_records = {
   1.783 -            { id = "rocketwiki", name = "RocketWiki" },
   1.784 -            { id = "compat", name = _"Traditional wiki syntax" }
   1.785 -          },
   1.786 -          attr = {id = "formatting_engine"},
   1.787 -          foreign_id = "id",
   1.788 -          foreign_name = "name",
   1.789 -          value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine
   1.790 -        }
   1.791 -        ui.field.text{
   1.792 -          label = _"Voting comment (optional)",
   1.793 -          name = "comment",
   1.794 -          multiline = true,
   1.795 -          value = param.get("comment") or direct_voter and direct_voter.comment,
   1.796 -          attr = { style = "height: 20ex;" },
   1.797 -        }
   1.798 -        ui.submit{
   1.799 -          name = "preview",
   1.800 -          value = _"Preview voting comment",
   1.801 -          attr = { class = "preview" }
   1.802 -        }
   1.803 -      end
   1.804 -      if not readonly or preview or direct_voter then
   1.805 -        slot.put(" ")
   1.806 -        ui.tag{
   1.807 -          tag = "input",
   1.808 -          attr = {
   1.809 -            type = "submit",
   1.810 -            class = "voting_done2",
   1.811 -            value = submit_button_text
   1.812 -          }
   1.813 -        }
   1.814 -      end
   1.815 -    end
   1.816 -  end
   1.817 -}
   1.818  
   1.819 -
   1.820 +  end )
   1.821 +end )
   1.822 \ No newline at end of file

Impressum / About Us