liquid_feedback_frontend

diff app/main/vote/list.lua @ 1309:32cc544d5a5b

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

Impressum / About Us