bsw/jbe@19: local issue = Issue:by_id(param.get("issue_id"), atom.integer)
bsw/jbe@19: 
bsw/jbe@1309: -- TODO patch for project voting
bsw/jbe@1309: if not issue.closed and config.alternative_voting and config.alternative_voting[tostring(issue.policy.id)] then
bsw/jbe@1309:   local voting_config = config.alternative_voting[tostring(issue.policy.id)]
bsw/jbe@1309:   
bsw/jbe@1309:   local url = encode.url {
bsw/jbe@1309:     module = voting_config.module,
bsw/jbe@1309:     view = voting_config.view,
bsw/jbe@1309:     params = { issue_id = issue.id }
bsw/jbe@1309:   }
bsw/jbe@1309:   
bsw/jbe@1309:   return request.redirect{ external = url }
bsw/jbe@1309: end
bsw/jbe@1309: 
bsw/jbe@1309: if not issue then
bsw/jbe@1309:   execute.view { module = "index", view = "404" }
bsw/jbe@1309:   return
bsw/jbe@1309: end
bsw/jbe@1309: 
bsw/jbe@19: local member_id = param.get("member_id", atom.integer)
bsw/jbe@19: local member
jbe@945: local readonly = false
bsw/jbe@19: 
jbe@950: local preview = param.get("preview") and true or false
poelzi@156: 
bsw/jbe@19: if member_id then
bsw/jbe@1309:   if not issue.closed then 
bsw/jbe@1309:     execute.view{ module = "index", view = "403" }
bsw/jbe@1309:     return
bsw/jbe@19:   end
bsw/jbe@19:   member = Member:by_id(member_id)
bsw/jbe@19:   readonly = true
bsw/jbe@19: end
bsw/jbe@19: 
poelzi@138: if issue.closed then
poelzi@156:   if not member then
poelzi@158:     member = app.session.member
poelzi@158:   end
poelzi@156:   readonly = true
poelzi@138: end
poelzi@138: 
bsw@1045: if preview then
bsw@1045:   readonly = true
bsw@1045: end
bsw@1045: 
bsw@879: local submit_button_text = _"Finish voting"
bsw@1045: local edit_button_text = _"Edit again"
bsw@879: 
bsw@879: if issue.closed then
bsw@1045:   submit_button_text = _"Save voting comment"
bsw@1045:   edit_button_text = _"Edit voting comment"
bsw@879: end
bsw@879: 
bsw@1045: execute.view {
bsw@1045:   module = "issue", view = "_head", params = { issue = issue }
bsw@1045: }
bsw@1045: 
bsw@879: local direct_voter
bsw@879: 
bsw/jbe@19: if member then
bsw@879:   direct_voter = DirectVoter:by_pk(issue.id, member.id)
bsw/jbe@19: else
bsw/jbe@19:   member = app.session.member
bsw@879:   direct_voter = DirectVoter:by_pk(issue.id, member.id)
bsw/jbe@19: end
bsw/jbe@19: 
bsw/jbe@19: 
bsw@879: 
bsw/jbe@19: local tempvoting_string = param.get("scoring")
bsw/jbe@19: 
bsw/jbe@19: local tempvotings = {}
bsw/jbe@19: if tempvoting_string then
bsw/jbe@19:   for match in tempvoting_string:gmatch("([^;]+)") do
bsw/jbe@19:     for initiative_id, grade in match:gmatch("([^:;]+):([^:;]+)") do
bsw/jbe@19:       tempvotings[tonumber(initiative_id)] = tonumber(grade)
bsw/jbe@19:     end
bsw/jbe@5:   end
bsw/jbe@19: end
bsw/jbe@5: 
bsw@95: local initiatives = issue:get_reference_selector("initiatives"):add_where("initiative.admitted"):add_order_by("initiative.satisfied_supporter_count DESC"):exec()
bsw/jbe@5: 
bsw/jbe@5: local min_grade = -1;
bsw/jbe@5: local max_grade = 1;
bsw/jbe@5: 
bsw/jbe@5: for i, initiative in ipairs(initiatives) do
bsw/jbe@5:   -- TODO performance
bsw/jbe@19:   initiative.vote = Vote:by_pk(initiative.id, member.id)
bsw/jbe@19:   if tempvotings[initiative.id] then
bsw/jbe@19:     initiative.vote = {}
bsw/jbe@19:     initiative.vote.grade = tempvotings[initiative.id]
bsw/jbe@19:   end
bsw/jbe@5:   if initiative.vote then
bsw/jbe@5:     if initiative.vote.grade > max_grade then
bsw/jbe@5:       max_grade = initiative.vote.grade
bsw/jbe@5:     end
bsw/jbe@5:     if initiative.vote.grade < min_grade then
bsw/jbe@5:       min_grade = initiative.vote.grade
bsw/jbe@5:     end
bsw/jbe@5:   end
bsw/jbe@5: end
bsw/jbe@5: 
bsw/jbe@5: local sections = {}
bsw/jbe@5: for i = min_grade, max_grade do
bsw/jbe@5:   sections[i] = {}
bsw/jbe@5:   for j, initiative in ipairs(initiatives) do
bsw/jbe@5:     if (initiative.vote and initiative.vote.grade == i) or (not initiative.vote and i == 0) then
bsw/jbe@5:       sections[i][#(sections[i])+1] = initiative
bsw/jbe@5:     end
bsw/jbe@5:   end
bsw/jbe@5: end
bsw/jbe@5: 
bsw/jbe@19: local approval_count, disapproval_count = 0, 0
bsw/jbe@19: for i = min_grade, -1 do
bsw/jbe@19:   if #sections[i] > 0 then
bsw/jbe@19:     disapproval_count = disapproval_count + 1
bsw/jbe@19:   end
bsw/jbe@19: end
bsw/jbe@19: local approval_count = 0
bsw/jbe@19: for i = 1, max_grade do
bsw/jbe@19:   if #sections[i] > 0 then
bsw/jbe@19:     approval_count = approval_count + 1
bsw/jbe@19:   end
bsw/jbe@19: end
bsw/jbe@5: 
bsw/jbe@19: if not readonly then
bsw/jbe@19:   slot.put('')
bsw/jbe@19:   slot.put('')
bsw/jbe@19: end
bsw/jbe@19: 
bsw/jbe@19: ui.script{
bsw/jbe@19:   script = function()
bsw/jbe@19:     slot.put(
bsw/jbe@19:       "voting_text_approval_single               = ", encode.json(_"Approval [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_approval_multi                = ", encode.json(_"Approval [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_first_preference_single       = ", encode.json(_"Approval (first preference) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_first_preference_multi        = ", encode.json(_"Approval (first preference) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_second_preference_single      = ", encode.json(_"Approval (second preference) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_second_preference_multi       = ", encode.json(_"Approval (second preference) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_third_preference_single       = ", encode.json(_"Approval (third preference) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_third_preference_multi        = ", encode.json(_"Approval (third preference) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_numeric_preference_single     = ", encode.json(_"Approval (#th preference) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_numeric_preference_multi      = ", encode.json(_"Approval (#th preference) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_abstention_single             = ", encode.json(_"Abstention [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_abstention_multi              = ", encode.json(_"Abstention [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_above_one_single  = ", encode.json(_"Disapproval (prefer to lower block) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_above_one_multi   = ", encode.json(_"Disapproval (prefer to lower block) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_above_many_single = ", encode.json(_"Disapproval (prefer to lower blocks) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_above_many_multi  = ", encode.json(_"Disapproval (prefer to lower blocks) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_above_last_single = ", encode.json(_"Disapproval (prefer to last block) [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_above_last_multi  = ", encode.json(_"Disapproval (prefer to last block) [many entries]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_single            = ", encode.json(_"Disapproval [single entry]"), ";\n",
bsw/jbe@19:       "voting_text_disapproval_multi             = ", encode.json(_"Disapproval [many entries]"), ";\n"
bsw/jbe@19:     )
bsw/jbe@19:   end
bsw/jbe@19: }
bsw/jbe@5: 
bsw@1045: if issue.state == "finished_with_winner" 
bsw@1045:   or issue.state == "finished_without_winner" 
bsw@1045: then
bsw@1045: 
bsw@1045:   local members_selector = Member:new_selector()
bsw@1045:     :join("delegating_voter", nil, "delegating_voter.member_id = member.id")
bsw@1045:     :add_where{ "delegating_voter.issue_id = ?", issue.id }
bsw@1045:     :add_where{ "delegating_voter.delegate_member_ids[1] = ?", member.id }
bsw@1045:     :add_field("delegating_voter.weight", "voter_weight")
bsw@1045:     :join("issue", nil, "issue.id = delegating_voter.issue_id")
bsw@1045:     
bsw@1045:   ui.sidebar( "tab-members", function()
bsw@1045:     ui.sidebarHead(function()
bsw/jbe@1309:       ui.heading{ level = 4, content = _"Incoming delegations" }
bsw@1045:     end)
bsw@1045:     execute.view{
bsw@1045:       module = "member",
bsw@1045:       view = "_list",
bsw@1045:       params = {
bsw@1045:         members_selector = members_selector,
bsw@1045:         trustee = member,
bsw@1045:         issue = issue,
bsw@1045:         initiative = initiative,
bsw@1045:         for_votes = true, no_filter = true,
bsw@1045:         member_class = "sidebarRow sidebarRowNarrow",
bsw/jbe@5:       }
bsw@1045:     }
bsw@1045:   end)
bsw@1045: end
bsw@1045: 
bsw/jbe@1309: ui.container{ attr = { class = "mdl-grid" }, content = function()
bsw/jbe@1309:   ui.container{ attr = { class = "mdl-cell mdl-cell--12-col" }, content = function()
bsw@1045: 
bsw/jbe@1309:     ui.container{ attr = { class = "mdl-card mdl-card__fullwidth mdl-shadow--2dp" }, content = function()
bsw/jbe@1309:       ui.container{ attr = { class = "mdl-card__title mdl-card--border" }, content = function()
bsw/jbe@1309:         ui.heading { attr = { class = "mdl-card__title-text" }, level = 2, content = function()
bsw/jbe@1309:           if preview then
bsw/jbe@1309:             ui.tag{ content = _"Preview of voting ballot" }
bsw/jbe@1309:           elseif readonly then
bsw/jbe@1309:             local str = _("Ballot of '#{member_name}'", { member_name = string.format(
bsw/jbe@1309:               '%s', 
bsw/jbe@1309:               encode.url{ module = "member", view = "show", id = member.id },
bsw/jbe@1309:               encode.html(member.name)
bsw/jbe@1309:             ) })
bsw/jbe@1309:             ui.tag{ content = function () slot.put ( str ) end }
bsw/jbe@1309:           else
bsw/jbe@1309:             ui.tag{ content = _"Voting" }
bsw/jbe@5:           end
bsw/jbe@1309:         end }
bsw/jbe@1309:       end }
bsw/jbe@1309: 
bsw/jbe@1309:       ui.container{ attr = { class = "mdl-card__content" }, content = function()
bsw/jbe@1309: 
bsw/jbe@1309:         ui.form{
bsw/jbe@1309:           record = direct_voter,
bsw/jbe@1309:           attr = {
bsw/jbe@1309:             id = "voting_form",
bsw/jbe@1309:             class = readonly and "voting_form_readonly" or "voting_form_active"
bsw/jbe@1309:           },
bsw/jbe@1309:           module = "vote",
bsw/jbe@1309:           action = "update",
bsw/jbe@1309:           params = { issue_id = issue.id },
bsw@1045:           content = function()
bsw/jbe@1309:             if not readonly or preview then
bsw/jbe@1309:               local scoring = param.get("scoring")
bsw/jbe@1309:               if not scoring then
bsw/jbe@1309:                 for i, initiative in ipairs(initiatives) do
bsw/jbe@1309:                   local vote = initiative.vote
bsw/jbe@1309:                   if vote then
bsw/jbe@1309:                     tempvotings[initiative.id] = vote.grade
bsw/jbe@1309:                   else
bsw/jbe@1309:                     tempvotings[initiative.id] = 0
bsw/jbe@1309:                   end
bsw/jbe@1309:                 end
bsw/jbe@1309:                 local tempvotings_list = {}
bsw/jbe@1309:                 for key, val in pairs(tempvotings) do
bsw/jbe@1309:                   tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
bsw/jbe@1309:                 end
bsw/jbe@1309:                 if #tempvotings_list > 0 then
bsw/jbe@1309:                   scoring = table.concat(tempvotings_list, ";")
bsw/jbe@1309:                 else
bsw/jbe@1309:                   scoring = ""
bsw/jbe@1309:                 end
bsw@1045:               end
bsw/jbe@1309:               slot.put('')
bsw/jbe@1309:             end
bsw/jbe@1309:             if preview then
bsw/jbe@1309:               ui.container{ content = _"Your choice" }
bsw/jbe@1309:             elseif not readonly then
bsw/jbe@1309:               ui.container{ content = _"Make your choice by placing the initiatives" }
bsw/jbe@1309:             end
bsw/jbe@1309:             
bsw/jbe@1309:             ui.container{
bsw/jbe@1309:               attr = { id = "voting" },
bsw/jbe@1309:               content = function()
bsw/jbe@1309:                 local approval_index, disapproval_index = 0, 0
bsw/jbe@1309:                 local approval_used, disapproval_used
bsw/jbe@1309:                 for grade = max_grade, min_grade, -1 do 
bsw/jbe@1309:                   local entries = sections[grade]
bsw/jbe@1309:                   local class
bsw/jbe@1309:                   if grade > 0 then
bsw/jbe@1309:                     class = "approval"
bsw/jbe@1309:                   elseif grade < 0 then
bsw/jbe@1309:                     class = "disapproval"
bsw/jbe@1309:                   else
bsw/jbe@1309:                     class = "abstention"
bsw/jbe@1309:                   end
bsw/jbe@1309:                   if
bsw/jbe@1309:                     #entries > 0 or
bsw/jbe@1309:                     (grade == 1 and not approval_used) or
bsw/jbe@1309:                     (grade == -1 and not disapproval_used) or
bsw/jbe@1309:                     grade == 0
bsw/jbe@1309:                   then
bsw/jbe@1309:                     ui.container{
bsw/jbe@1309:                       attr = { class = class },
bsw/jbe@1309:                       content = function()
bsw/jbe@1309:                         local heading
bsw/jbe@1309:                         if class == "approval" then
bsw/jbe@1309:                           approval_used = true
bsw/jbe@1309:                           approval_index = approval_index + 1
bsw/jbe@1309:                           if approval_count > 1 then
bsw/jbe@1309:                             if approval_index == 1 then
bsw/jbe@1309:                               if #entries == 1 then
bsw/jbe@1309:                                 heading = _"Approval (first preference) [single entry]"
bsw/jbe@1309:                               else
bsw/jbe@1309:                                 heading = _"Approval (first preference) [many entries]"
bsw/jbe@1309:                               end
bsw/jbe@1309:                             elseif approval_index == 2 then
bsw/jbe@1309:                               if #entries == 1 then
bsw/jbe@1309:                                 heading = _"Approval (second preference) [single entry]"
bsw/jbe@1309:                               else
bsw/jbe@1309:                                 heading = _"Approval (second preference) [many entries]"
bsw/jbe@1309:                               end
bsw/jbe@1309:                             elseif approval_index == 3 then
bsw/jbe@1309:                               if #entries == 1 then
bsw/jbe@1309:                                 heading = _"Approval (third preference) [single entry]"
bsw/jbe@1309:                               else
bsw/jbe@1309:                                 heading = _"Approval (third preference) [many entries]"
bsw/jbe@1309:                               end
bsw/jbe@1309:                             else
bsw/jbe@1309:                               if #entries == 1 then
bsw/jbe@1309:                                 heading = _"Approval (#th preference) [single entry]"
bsw/jbe@1309:                               else
bsw/jbe@1309:                                 heading = _"Approval (#th preference) [many entries]"
bsw/jbe@1309:                               end
bsw/jbe@1309:                             end
bsw@1045:                           else
bsw/jbe@1309:                             if #entries == 1 then
bsw/jbe@1309:                               heading = _"Approval [single entry]"
bsw/jbe@1309:                             else
bsw/jbe@1309:                               heading = _"Approval [many entries]"
bsw/jbe@1309:                             end
bsw@1045:                           end
bsw/jbe@1309:                         elseif class == "abstention" then
bsw/jbe@1309:                             if #entries == 1 then
bsw/jbe@1309:                               heading = _"Abstention [single entry]"
bsw/jbe@1309:                             else
bsw/jbe@1309:                               heading = _"Abstention [many entries]"
bsw/jbe@1309:                             end
bsw/jbe@1309:                         elseif class == "disapproval" then
bsw/jbe@1309:                           disapproval_used = true
bsw/jbe@1309:                           disapproval_index = disapproval_index + 1
bsw/jbe@1309:                           if disapproval_count > disapproval_index + 1 then
bsw/jbe@1309:                             if #entries == 1 then
bsw/jbe@1309:                               heading = _"Disapproval (prefer to lower blocks) [single entry]"
bsw/jbe@1309:                             else
bsw/jbe@1309:                               heading = _"Disapproval (prefer to lower blocks) [many entries]"
bsw/jbe@1309:                             end
bsw/jbe@1309:                           elseif disapproval_count == 2 and disapproval_index == 1 then
bsw/jbe@1309:                             if #entries == 1 then
bsw/jbe@1309:                               heading = _"Disapproval (prefer to lower block) [single entry]"
bsw/jbe@1309:                             else
bsw/jbe@1309:                               heading = _"Disapproval (prefer to lower block) [many entries]"
bsw/jbe@1309:                             end
bsw/jbe@1309:                           elseif disapproval_index == disapproval_count - 1 then
bsw/jbe@1309:                             if #entries == 1 then
bsw/jbe@1309:                               heading = _"Disapproval (prefer to last block) [single entry]"
bsw/jbe@1309:                             else
bsw/jbe@1309:                               heading = _"Disapproval (prefer to last block) [many entries]"
bsw/jbe@1309:                             end
bsw@1045:                           else
bsw/jbe@1309:                             if #entries == 1 then
bsw/jbe@1309:                               heading = _"Disapproval [single entry]"
bsw/jbe@1309:                             else
bsw/jbe@1309:                               heading = _"Disapproval [many entries]"
bsw/jbe@1309:                             end
bsw@1045:                           end
bsw@1045:                         end
bsw/jbe@1309:                         ui.tag {
bsw/jbe@1309:                           tag     = "div",
bsw/jbe@1309:                           attr    = { class = "cathead " },
bsw/jbe@1309:                           content = heading
bsw/jbe@1309:                         }
bsw/jbe@1309:                         for i, initiative in ipairs(entries) do
bsw@1045:                           ui.container{
bsw/jbe@1309:                             attr = {
bsw/jbe@1309:                               class = "movable",
bsw/jbe@1309:                               id = "entry_" .. tostring(initiative.id)
bsw/jbe@1309:                             },
bsw@1045:                             content = function()
bsw/jbe@1309:                               local initiators_selector = initiative:get_reference_selector("initiating_members")
bsw/jbe@1309:                                 :add_where("accepted")
bsw/jbe@1309:                               local initiators = initiators_selector:exec()
bsw/jbe@1309:                               local initiator_names = {}
bsw/jbe@1309:                               for i, initiator in ipairs(initiators) do
bsw/jbe@1309:                                 initiator_names[#initiator_names+1] = initiator.name
bsw/jbe@1309:                               end
bsw/jbe@1309:                               local initiator_names_string = table.concat(initiator_names, ", ")
bsw/jbe@1309:                               ui.container{
bsw/jbe@1309:                                 attr = { style = "float: right; position: relative;" },
bsw/jbe@1309:                                 content = function()
bsw/jbe@1309:                                   ui.link{
bsw/jbe@1309:                                     attr = { class = "clickable" },
bsw/jbe@1309:                                     content = _"Show",
bsw/jbe@1309:                                     module = "initiative",
bsw/jbe@1309:                                     view = "show",
bsw/jbe@1309:                                     id = initiative.id
bsw/jbe@1309:                                   }
bsw/jbe@1309:                                   slot.put(" ")
bsw/jbe@1309:                                   ui.link{
bsw/jbe@1309:                                     attr = { class = "clickable", target = "_blank" },
bsw/jbe@1309:                                     content = _"(new window)",
bsw/jbe@1309:                                     module = "initiative",
bsw/jbe@1309:                                     view = "show",
bsw/jbe@1309:                                     id = initiative.id
bsw/jbe@1309:                                   }
bsw/jbe@1309:                                   if not readonly then
bsw/jbe@1309:                                     slot.put(" ")
bsw/jbe@1309:                                     ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
bsw/jbe@1309:                                   end
bsw/jbe@1309:                                 end
bsw@1045:                               }
bsw@1045:                               if not readonly then
bsw/jbe@1309:                                 ui.container{
bsw/jbe@1309:                                   attr = { style = "float: left; position: relative;" },
bsw/jbe@1309:                                   content = function()
bsw/jbe@1309:                                     ui.tag{
bsw/jbe@1309:                                       tag = "button",
bsw/jbe@1309:                                       attr = {
bsw/jbe@1309:                                         onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
bsw/jbe@1309:                                         name = "move_up_" .. tostring(initiative.id),
bsw/jbe@1309:                                         class = "clickable mdl-button mdl-js-button mdl-button--icon",
bsw/jbe@1309:                                         alt = _"Move up",
bsw/jbe@1309:                                       },
bsw/jbe@1309:                                       content = function()
bsw/jbe@1309:                                         ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "arrow_upward" }
bsw/jbe@1309:                                       end
bsw/jbe@1309:                                     }
bsw/jbe@1309:                                     ui.tag{
bsw/jbe@1309:                                       tag = "button",
bsw/jbe@1309:                                       attr = {
bsw/jbe@1309:                                         onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
bsw/jbe@1309:                                         name = "move_down_" .. tostring(initiative.id),
bsw/jbe@1309:                                         class = "clickable mdl-button mdl-js-button mdl-button--icon",
bsw/jbe@1309:                                         alt = _"Move down"
bsw/jbe@1309:                                       },
bsw/jbe@1309:                                       content = function()
bsw/jbe@1309:                                         ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "arrow_downward" }
bsw/jbe@1309:                                       end
bsw/jbe@1309:                                     }
bsw/jbe@1309:                                     slot.put(" ")
bsw/jbe@1309:                                   end
bsw@286:                                 }
bsw@1045:                               end
bsw/jbe@1309:                               ui.container{
bsw/jbe@1309:                                 content = function()
bsw/jbe@1309:                                   ui.tag{ attr = { class = "initiative_name" }, content = function()
bsw/jbe@1309:                                     ui.tag{ content = "i" .. initiative.id .. ": " }
bsw/jbe@1309:                                     ui.tag{ content = initiative.shortened_name }
bsw/jbe@1309:                                   end }
bsw/jbe@1309:                                   slot.put("
")
bsw/jbe@1309:                                   for i, initiator in ipairs(initiators) do
bsw/jbe@1309:                                     ui.link{
bsw/jbe@1309:                                       attr = { class = "clickable" },
bsw/jbe@1309:                                       content = function ()
bsw/jbe@1309:                                         execute.view{
bsw/jbe@1309:                                           module = "member_image",
bsw/jbe@1309:                                           view = "_show",
bsw/jbe@1309:                                           params = {
bsw/jbe@1309:                                             member = initiator,
bsw/jbe@1309:                                             image_type = "avatar",
bsw/jbe@1309:                                             show_dummy = true,
bsw/jbe@1309:                                             class = "micro_avatar",
bsw/jbe@1309:                                             popup_text = text
bsw/jbe@1309:                                           }
bsw/jbe@1309:                                         }
bsw/jbe@1309:                                       end,
bsw/jbe@1309:                                       module = "member", view = "show", id = initiator.id
bsw@1045:                                     }
bsw/jbe@1309:                                     slot.put(" ")
bsw/jbe@1309:                                     ui.tag{ content = initiator.name }
bsw/jbe@1309:                                     slot.put(" ")
bsw/jbe@1309:                                   end
bsw/jbe@1309:                                 end
bsw/jbe@1309:                               }
bsw@1045:                             end
bsw@1045:                           }
bsw/jbe@19:                         end
bsw/jbe@1309:                       end
bsw/jbe@1309:                     }
bsw/jbe@1309:                   end
bsw/jbe@1309:                 end
bsw/jbe@1309:               end
bsw/jbe@1309:             }
bsw/jbe@1309:             if app.session.member_id and preview then
bsw/jbe@1309:               local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine
bsw/jbe@1309:               local comment = param.get("comment")
bsw/jbe@1309:               if comment and #comment > 0 then
bsw/jbe@1309:                 local rendered_comment = format.wiki_text(comment, formatting_engine)
bsw/jbe@1309:                 ui.container{ content = _"Voting comment" }
bsw/jbe@1309:                 ui.container { attr = { class = "member_statement" }, content = function()
bsw/jbe@1309:                   slot.put(rendered_comment)
bsw/jbe@1309:                 end }
bsw/jbe@1309:                 slot.put("
")
bsw/jbe@1309:               end
bsw/jbe@1309:             end
bsw/jbe@1309:             if (readonly or direct_voter and direct_voter.comment) and not preview and not (app.session.member_id == member.id) then
bsw/jbe@1309:               local text
bsw/jbe@1309:               if direct_voter and direct_voter.comment_changed then
bsw/jbe@1309:                 text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) })
bsw/jbe@1309:               elseif direct_voter and direct_voter.comment then
bsw/jbe@1309:                 text = _"Voting comment"
bsw/jbe@1309:               end
bsw/jbe@1309:               if text then
bsw/jbe@1309:                 ui.container{ content = text }
bsw/jbe@1309:               end
bsw/jbe@1309:               if direct_voter and direct_voter.comment then
bsw/jbe@1309:                 local rendered_comment = direct_voter:get_content('html')
bsw/jbe@1309:                 ui.container { attr = { class = "member_statement" }, content = function()
bsw/jbe@1309:                   slot.put(rendered_comment)
bsw/jbe@1309:                 end }
bsw/jbe@1309:                 slot.put("
")
bsw/jbe@1309:               end
bsw/jbe@1309:             end
bsw/jbe@1309:             if app.session.member_id and app.session.member_id == member.id then
bsw/jbe@1309:               if (not readonly or direct_voter) and not preview then
bsw/jbe@1309:                 ui.container{ content = function()
bsw/jbe@1309:                   if not config.enforce_formatting_engine then
bsw/jbe@1309:                     ui.field.select{
bsw/jbe@1309:                       label = _"Wiki engine for statement",
bsw/jbe@1309:                       name = "formatting_engine",
bsw/jbe@1309:                       foreign_records = config.formatting_engines,
bsw/jbe@1309:                       attr = {id = "formatting_engine"},
bsw/jbe@1309:                       foreign_id = "id",
bsw/jbe@1309:                       foreign_name = "name",
bsw/jbe@1309:                       value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine
bsw/jbe@1309:                     }
bsw@1045:                   end
bsw/jbe@1309:                   ui.container{ content = _"Voting comment (optional)" }
bsw/jbe@1309:                   ui.field.text{
bsw/jbe@1309:                     name = "comment",
bsw/jbe@1309:                     multiline = true,
bsw/jbe@1309:                     value = param.get("comment") or direct_voter and direct_voter.comment,
bsw/jbe@1309:                     attr = { style = "height: 10ex; width: 100%;" },
bsw/jbe@1309:                   }
bsw/jbe@1309:                 end }
bsw/jbe@1309:               end
bsw/jbe@1309: 
bsw/jbe@1309:               if preview then
bsw/jbe@1309:                 if not config.enforce_formatting_engine then
bsw/jbe@1309:                   ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") }
bsw/jbe@1309:                 end
bsw/jbe@1309:                 ui.field.hidden{ name = "comment", value = param.get("comment") or direct_voter and direct_voter.comment }
bsw/jbe@1309:               end
bsw/jbe@1309:               
bsw/jbe@1309:               if not readonly or direct_voter or preview then
bsw/jbe@1309:                 if preview  then
bsw/jbe@1309:                   slot.put(" ")
bsw/jbe@1309:                   ui.tag{
bsw/jbe@1309:                     tag = "input",
bsw/jbe@1309:                     attr = {
bsw/jbe@1309:                       type = "submit",
bsw/jbe@1309:                       class = "mdl-button mdl-js-button mdl-button--raised mdl-button--colored",
bsw/jbe@1309:                       name = issue.closed and "update_comment" or nil,
bsw/jbe@1309:                       value = submit_button_text -- finish voting / update comment
bsw/jbe@1309:                     }
bsw/jbe@1309:                   }
bsw/jbe@1309:                 end
bsw/jbe@1309:                 if not preview then
bsw/jbe@1309:                   ui.tag{
bsw/jbe@1309:                     tag = "input",
bsw/jbe@1309:                     attr = {
bsw/jbe@1309:                       type = "submit",
bsw/jbe@1309:                       name = "preview",
bsw/jbe@1309:                       class = "mdl-button mdl-js-button mdl-button--raised mdl-button--colored",
bsw/jbe@1309:                       value = _"Preview",
bsw/jbe@1309:                     }
bsw/jbe@1309:                   }
bsw/jbe@1309:                 else
bsw/jbe@1309:                   slot.put("   ")
bsw/jbe@1309:                   ui.tag{
bsw/jbe@1309:                     tag = "input",
bsw/jbe@1309:                     attr = {
bsw/jbe@1309:                       type = "submit",
bsw/jbe@1309:                       name = "edit",
bsw/jbe@1309:                       class = "mdl-button mdl-js-button mdl-button--raised",
bsw/jbe@1309:                       value = edit_button_text,
bsw/jbe@1309:                     }
bsw/jbe@1309:                   }
bsw/jbe@1309:                 end
bsw@1045:               end
bsw@1045:             end
bsw@1045:           end
bsw@1045:         }
bsw/jbe@1309:         slot.put("
")
bsw/jbe@1309:         ui.link{
bsw/jbe@1309:           attr = { class = "mdl-button mdl-js-button mdl-button--raised" },
bsw/jbe@1309:           text = _"Cancel",
bsw/jbe@1309:           module = "issue",
bsw/jbe@1309:           view = "show",
bsw/jbe@1309:           id = issue.id
bsw/jbe@1309:         }
bsw/jbe@1309:         if direct_voter then
bsw/jbe@1309:           slot.put("   ")
bsw/jbe@1309:           ui.link {
bsw/jbe@1309:             attr = { class = "mdl-button mdl-js-button mdl-button--raised" },
bsw/jbe@1309:             module = "vote", action = "update",
bsw/jbe@1309:             params = {
bsw/jbe@1309:               issue_id = issue.id,
bsw/jbe@1309:               discard = true
bsw/jbe@1309:             },
bsw/jbe@1309:             routing = {
bsw/jbe@1309:               default = {
bsw/jbe@1309:                 mode = "redirect",
bsw/jbe@1309:                 module = "issue",
bsw/jbe@1309:                 view = "show",
bsw/jbe@1309:                 id = issue.id
bsw@1045:               }
bsw/jbe@1309:             },
bsw/jbe@1309:             text = _"Discard my vote"
bsw/jbe@1309:           }
bsw/jbe@5:         end
bsw/jbe@1309:         
bsw/jbe@1309:       end }
bsw/jbe@1309:     end }
bsw/jbe@1309:   end }
bsw/jbe@1309: end }