liquid_feedback_frontend
diff app/main/initiative/show.lua @ 718:cc64a4fc6ab6
Cleaned up initiative page
| author | bsw |
|---|---|
| date | Wed Jun 27 14:37:46 2012 +0200 (2012-06-27) |
| parents | a53b4485a3d3 |
| children | cdd0bcbbef8b |
line diff
1.1 --- a/app/main/initiative/show.lua Wed Jun 27 12:35:34 2012 +0200 1.2 +++ b/app/main/initiative/show.lua Wed Jun 27 14:37:46 2012 +0200 1.3 @@ -17,11 +17,447 @@ 1.4 } 1.5 end) 1.6 1.7 +local initiators_members_selector = initiative:get_reference_selector("initiating_members") 1.8 + :add_field("initiator.accepted", "accepted") 1.9 + :add_order_by("member.name") 1.10 +if initiator and initiator.accepted then 1.11 + initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted") 1.12 +else 1.13 + initiators_members_selector:add_where("initiator.accepted") 1.14 +end 1.15 + 1.16 +local initiators = initiators_members_selector:exec() 1.17 + 1.18 + 1.19 +local initiatives_selector = initiative.issue:get_reference_selector("initiatives") 1.20 +slot.select("head", function() 1.21 + execute.view{ 1.22 + module = "issue", 1.23 + view = "_show", 1.24 + params = { 1.25 + issue = initiative.issue, 1.26 + initiative_limit = 3, 1.27 + for_initiative = initiative 1.28 + } 1.29 + } 1.30 +end) 1.31 + 1.32 +util.help("initiative.show") 1.33 + 1.34 +ui.container{ attr = { class = "initiative_head" }, content = function() 1.35 + 1.36 + ui.container{ 1.37 + attr = { class = "title" }, 1.38 + content = _("Initiative i#{id}: #{name}", { id = initiative.id, name = initiative.name }) 1.39 + } 1.40 + 1.41 + ui.container{ attr = { class = "content" }, content = function() 1.42 + if app.session.member_id or config.public_access == "pseudonym" or config.public_access == "full" then 1.43 + ui.tag{ 1.44 + attr = { class = "initiator_names" }, 1.45 + content = function() 1.46 + for i, initiator in ipairs(initiators) do 1.47 + slot.put(" ") 1.48 + if app.session.member_id or config.public_access == "full" then 1.49 + ui.link{ 1.50 + content = function () 1.51 + execute.view{ 1.52 + module = "member_image", 1.53 + view = "_show", 1.54 + params = { 1.55 + member = initiator, 1.56 + image_type = "avatar", 1.57 + show_dummy = true, 1.58 + class = "micro_avatar", 1.59 + popup_text = text 1.60 + } 1.61 + } 1.62 + end, 1.63 + module = "member", view = "show", id = initiator.id 1.64 + } 1.65 + slot.put(" ") 1.66 + end 1.67 + ui.link{ 1.68 + text = initiator.name, 1.69 + module = "member", view = "show", id = initiator.id 1.70 + } 1.71 + if not initiator.accepted then 1.72 + ui.tag{ attr = { title = _"Not accepted yet" }, content = "?" } 1.73 + end 1.74 + end 1.75 + end 1.76 + } 1.77 + end 1.78 + 1.79 + if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 1.80 + slot.put(" · ") 1.81 + ui.link{ 1.82 + attr = { class = "action" }, 1.83 + content = function() 1.84 + slot.put(_"Invite initiator") 1.85 + end, 1.86 + module = "initiative", 1.87 + view = "add_initiator", 1.88 + params = { initiative_id = initiative.id } 1.89 + } 1.90 + if #initiators > 1 then 1.91 + slot.put(" · ") 1.92 + ui.link{ 1.93 + content = function() 1.94 + slot.put(_"Remove initiator") 1.95 + end, 1.96 + module = "initiative", 1.97 + view = "remove_initiator", 1.98 + params = { initiative_id = initiative.id } 1.99 + } 1.100 + end 1.101 + end 1.102 + if initiator and initiator.accepted == false then 1.103 + slot.put(" · ") 1.104 + ui.link{ 1.105 + text = _"Cancel refuse of invitation", 1.106 + module = "initiative", 1.107 + action = "remove_initiator", 1.108 + params = { 1.109 + initiative_id = initiative.id, 1.110 + member_id = app.session.member.id 1.111 + }, 1.112 + routing = { 1.113 + ok = { 1.114 + mode = "redirect", 1.115 + module = "initiative", 1.116 + view = "show", 1.117 + id = initiative.id 1.118 + } 1.119 + } 1.120 + } 1.121 + end 1.122 + end } 1.123 + ui.container{ attr = { class = "content" }, content = function() 1.124 + if app.session.member_id then 1.125 + execute.view{ 1.126 + module = "supporter", 1.127 + view = "_show_box", 1.128 + params = { 1.129 + initiative = initiative 1.130 + } 1.131 + } 1.132 + end 1.133 + 1.134 + end } 1.135 + 1.136 + 1.137 + -- voting results 1.138 + if initiative.issue.ranks_available and initiative.admitted then 1.139 + local class = initiative.winner and "admitted_info" or "not_admitted_info" 1.140 + ui.container{ 1.141 + attr = { class = class }, 1.142 + content = function() 1.143 + local max_value = initiative.issue.voter_count 1.144 + slot.put(" ") 1.145 + local positive_votes = initiative.positive_votes 1.146 + local negative_votes = initiative.negative_votes 1.147 + local sum_votes = initiative.positive_votes + initiative.negative_votes 1.148 + local function perc(votes, sum) 1.149 + if sum > 0 and votes > 0 then return " (" .. string.format( "%.f", votes * 100 / sum ) .. "%)" end 1.150 + return "" 1.151 + end 1.152 + slot.put(_"Yes" .. ": <b>" .. tostring(positive_votes) .. perc(positive_votes, sum_votes) .. "</b>") 1.153 + slot.put(" · ") 1.154 + slot.put(_"Abstention" .. ": <b>" .. tostring(max_value - initiative.negative_votes - initiative.positive_votes) .. "</b>") 1.155 + slot.put(" · ") 1.156 + slot.put(_"No" .. ": <b>" .. tostring(initiative.negative_votes) .. perc(negative_votes, sum_votes) .. "</b>") 1.157 + slot.put(" · ") 1.158 + slot.put("<b>") 1.159 + if initiative.winner then 1.160 + slot.put(_"Approved") 1.161 + elseif initiative.rank then 1.162 + slot.put(_("Not approved (rank #{rank})", { rank = initiative.rank })) 1.163 + else 1.164 + slot.put(_"Not approved") 1.165 + end 1.166 + slot.put("</b>") 1.167 + end 1.168 + } 1.169 + end 1.170 + 1.171 + ui.container{ attr = { class = "content" }, content = function() 1.172 + execute.view{ 1.173 + module = "initiative", 1.174 + view = "_battles", 1.175 + params = { initiative = initiative } 1.176 + } 1.177 + end } 1.178 + 1.179 + -- initiative not admitted info 1.180 + if initiative.admitted == false then 1.181 + local policy = initiative.issue.policy 1.182 + ui.container{ 1.183 + attr = { class = "not_admitted_info" }, 1.184 + content = _("This initiative has not been admitted! It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) }) 1.185 + } 1.186 + end 1.187 + 1.188 + -- initiative revoked info 1.189 + if initiative.revoked then 1.190 + ui.container{ 1.191 + attr = { class = "revoked_info" }, 1.192 + content = function() 1.193 + slot.put(_("This initiative has been revoked at #{revoked}", { revoked = format.timestamp(initiative.revoked) })) 1.194 + local suggested_initiative = initiative.suggested_initiative 1.195 + if suggested_initiative then 1.196 + slot.put("<br /><br />") 1.197 + slot.put(_("The initiators suggest to support the following initiative:")) 1.198 + slot.put(" ") 1.199 + ui.link{ 1.200 + content = _("Issue ##{id}", { id = suggested_initiative.issue.id } ) .. ": " .. encode.html(suggested_initiative.name), 1.201 + module = "initiative", 1.202 + view = "show", 1.203 + id = suggested_initiative.id 1.204 + } 1.205 + end 1.206 + end 1.207 + } 1.208 + end 1.209 + 1.210 + 1.211 + -- invited as initiator 1.212 + if initiator and initiator.accepted == nil and not initiative.issue.half_frozen and not initiative.issue.closed then 1.213 + ui.container{ 1.214 + attr = { class = "initiator_invite_info" }, 1.215 + content = function() 1.216 + slot.put(_"You are invited to become initiator of this initiative.") 1.217 + slot.put(" ") 1.218 + ui.link{ 1.219 + image = { static = "icons/16/tick.png" }, 1.220 + text = _"Accept invitation", 1.221 + module = "initiative", 1.222 + action = "accept_invitation", 1.223 + id = initiative.id, 1.224 + routing = { 1.225 + default = { 1.226 + mode = "redirect", 1.227 + module = request.get_module(), 1.228 + view = request.get_view(), 1.229 + id = param.get_id_cgi(), 1.230 + params = param.get_all_cgi() 1.231 + } 1.232 + } 1.233 + } 1.234 + slot.put(" ") 1.235 + ui.link{ 1.236 + image = { static = "icons/16/cross.png" }, 1.237 + text = _"Refuse invitation", 1.238 + module = "initiative", 1.239 + action = "reject_initiator_invitation", 1.240 + params = { 1.241 + initiative_id = initiative.id, 1.242 + member_id = app.session.member.id 1.243 + }, 1.244 + routing = { 1.245 + default = { 1.246 + mode = "redirect", 1.247 + module = request.get_module(), 1.248 + view = request.get_view(), 1.249 + id = param.get_id_cgi(), 1.250 + params = param.get_all_cgi() 1.251 + } 1.252 + } 1.253 + } 1.254 + end 1.255 + } 1.256 + end 1.257 + 1.258 + -- draft updated 1.259 + local supporter 1.260 + 1.261 + if app.session.member_id then 1.262 + supporter = app.session.member:get_reference_selector("supporters") 1.263 + :add_where{ "initiative_id = ?", initiative.id } 1.264 + :optional_object_mode() 1.265 + :exec() 1.266 + end 1.267 + 1.268 + if supporter and not initiative.issue.closed then 1.269 + local old_draft_id = supporter.draft_id 1.270 + local new_draft_id = initiative.current_draft.id 1.271 + if old_draft_id ~= new_draft_id then 1.272 + ui.container{ 1.273 + attr = { class = "draft_updated_info" }, 1.274 + content = function() 1.275 + slot.put(_"The draft of this initiative has been updated!") 1.276 + slot.put(" ") 1.277 + ui.link{ 1.278 + content = _"Show diff", 1.279 + module = "draft", 1.280 + view = "diff", 1.281 + params = { 1.282 + old_draft_id = old_draft_id, 1.283 + new_draft_id = new_draft_id 1.284 + } 1.285 + } 1.286 + if not initiative.revoked then 1.287 + slot.put(" ") 1.288 + ui.link{ 1.289 + text = _"Refresh support to current draft", 1.290 + module = "initiative", 1.291 + action = "add_support", 1.292 + id = initiative.id, 1.293 + routing = { 1.294 + default = { 1.295 + mode = "redirect", 1.296 + module = "initiative", 1.297 + view = "show", 1.298 + id = initiative.id 1.299 + } 1.300 + } 1.301 + } 1.302 + end 1.303 + end 1.304 + } 1.305 + end 1.306 + end 1.307 + 1.308 + 1.309 + execute.view{ 1.310 + module = "draft", 1.311 + view = "_show", 1.312 + params = { 1.313 + draft = initiative.current_draft 1.314 + } 1.315 + } 1.316 + 1.317 +end } 1.318 + 1.319 +execute.view{ 1.320 + module = "suggestion", 1.321 + view = "_list", 1.322 + params = { 1.323 + initiative = initiative, 1.324 + suggestions_selector = initiative:get_reference_selector("suggestions"), 1.325 + tab_id = param.get("tab_id") 1.326 + } 1.327 +} 1.328 + 1.329 + 1.330 +if config.public_access == "full" or app.session.member_id then 1.331 + if initiative.issue.ranks_available then 1.332 + local members_selector = initiative.issue:get_reference_selector("direct_voters") 1.333 + :left_join("vote", nil, { "vote.initiative_id = ? AND vote.member_id = member.id", initiative.id }) 1.334 + :add_field("direct_voter.weight as voter_weight") 1.335 + :add_field("coalesce(vote.grade, 0) as grade") 1.336 + :left_join("initiative", nil, "initiative.id = vote.initiative_id") 1.337 + :left_join("issue", nil, "issue.id = initiative.issue_id") 1.338 + 1.339 + ui.container{ attr = { class = "heading"}, content = _"Member voting" } 1.340 + 1.341 + execute.view{ 1.342 + module = "member", 1.343 + view = "_list", 1.344 + params = { 1.345 + initiative = initiative, 1.346 + for_votes = true, 1.347 + members_selector = members_selector 1.348 + } 1.349 + } 1.350 + end 1.351 + 1.352 + local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 1.353 + :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 1.354 + :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") 1.355 + :add_field("direct_interest_snapshot.weight") 1.356 + :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 1.357 + :add_where("direct_supporter_snapshot.satisfied") 1.358 + :add_field("direct_supporter_snapshot.informed", "is_informed") 1.359 + 1.360 + 1.361 + 1.362 + if members_selector:count() > 0 then 1.363 + if issue.fully_frozen then 1.364 + ui.container{ attr = { class = "heading"}, content = _"Supporters (before begin of voting)" } 1.365 + else 1.366 + ui.container{ attr = { class = "heading"}, content = _"Supporters" } 1.367 + end 1.368 + 1.369 + execute.view{ 1.370 + module = "member", 1.371 + view = "_list", 1.372 + params = { 1.373 + 1.374 + initiative = initiative, 1.375 + members_selector = members_selector 1.376 + } 1.377 + } 1.378 + else 1.379 + if issue.fully_frozen then 1.380 + ui.container{ attr = { class = "heading"}, content = _"No supporters (before begin of voting)" } 1.381 + else 1.382 + ui.container{ attr = { class = "heading"}, content = _"No supporters" } 1.383 + end 1.384 + slot.put("<br />") 1.385 + end 1.386 + 1.387 + local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 1.388 + :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 1.389 + :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") 1.390 + :add_field("direct_interest_snapshot.weight") 1.391 + :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 1.392 + :add_where("NOT direct_supporter_snapshot.satisfied") 1.393 + :add_field("direct_supporter_snapshot.informed", "is_informed") 1.394 + 1.395 + 1.396 + if members_selector:count() > 0 then 1.397 + if issue.fully_frozen then 1.398 + ui.container{ attr = { class = "heading"}, content = _"Potential supporters (before begin of voting" } 1.399 + else 1.400 + ui.container{ attr = { class = "heading"}, content = _"Potential supporters" } 1.401 + end 1.402 + 1.403 + execute.view{ 1.404 + module = "member", 1.405 + view = "_list", 1.406 + params = { 1.407 + 1.408 + initiative = initiative, 1.409 + members_selector = members_selector 1.410 + } 1.411 + } 1.412 + else 1.413 + if issue.fully_frozen then 1.414 + ui.container{ attr = { class = "heading"}, content = _"No potential supporters (before begin of voting)" } 1.415 + else 1.416 + ui.container{ attr = { class = "heading"}, content = _"No potential supporters" } 1.417 + end 1.418 + slot.put("<br />") 1.419 + end 1.420 + 1.421 + ui.container{ attr = { class = "heading"}, content = _"Details" } 1.422 + execute.view { 1.423 + module = "initiative", 1.424 + view = "_details", 1.425 + params = { 1.426 + initiative = initiative, 1.427 + members_selector = members_selector 1.428 + } 1.429 + } 1.430 + 1.431 +end 1.432 + 1.433 + 1.434 +--[[ 1.435 execute.view{ 1.436 module = "initiative", 1.437 - view = "_show", 1.438 + view = "show_tab", 1.439 params = { 1.440 initiative = initiative, 1.441 initiator = initiator 1.442 } 1.443 } 1.444 + 1.445 +if initiative.issue.snapshot then 1.446 + slot.put("<br />") 1.447 + ui.field.timestamp{ label = _"Last snapshot:", value = initiative.issue.snapshot } 1.448 +end 1.449 + 1.450 + 1.451 +--]]