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@1557: :add_field("delegating_voter.ownweight", "ownweight") 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@1558: if direct_voter and not issue.closed 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 }