liquid_feedback_frontend
diff app/main/initiative/show_tab.lua @ 19:00d1004545f1
Dynamic interface using XMLHttpRequests, and many other changes
Bugfixes:
- Only allow voting on admitted initiatives
- Repaired issue search
- Don't display delegations for closed issues on member page
- Don't show revoke link in initiative, when issue is already half_frozen
- Localization for voting JavaScript
- Display author of suggestions
Disclosure of voting data after voting is finished:
- Possibility to inspect every ballot including preferences
- Show number of voters preferring one initiative to another initiative
Interface behaviour changes:
- Reversed default order of drafts
- Default order of suggestions changed
- Show new drafts of initiatives only once per day in timeline
Accessibility:
- Barrier-free voting implemented
- POST links are now accessible without JavaScript
- Changed gray for unsatisfied supporters in bar graph to a lighter gray
Other interface improvements:
- Optical enhancements
- Dynamic interface using XMLHttpRequests
- Show usage terms in about section
- Show own membership in area listing
- Show uninformed supporters greyed out and marked with yellow question mark
- Warning box in non-admitted initiatives
- When voted, don't display voting notice and change label of voting link
- Show object counts in more tabulator heads
- Enlarged member statement input field
Miscellaneous:
- Code cleanup
- Added README file containing installation instructions
- Use new WebMCP function ui.filters{...} instead of own ui.filter and ui.order functions
Bugfixes:
- Only allow voting on admitted initiatives
- Repaired issue search
- Don't display delegations for closed issues on member page
- Don't show revoke link in initiative, when issue is already half_frozen
- Localization for voting JavaScript
- Display author of suggestions
Disclosure of voting data after voting is finished:
- Possibility to inspect every ballot including preferences
- Show number of voters preferring one initiative to another initiative
Interface behaviour changes:
- Reversed default order of drafts
- Default order of suggestions changed
- Show new drafts of initiatives only once per day in timeline
Accessibility:
- Barrier-free voting implemented
- POST links are now accessible without JavaScript
- Changed gray for unsatisfied supporters in bar graph to a lighter gray
Other interface improvements:
- Optical enhancements
- Dynamic interface using XMLHttpRequests
- Show usage terms in about section
- Show own membership in area listing
- Show uninformed supporters greyed out and marked with yellow question mark
- Warning box in non-admitted initiatives
- When voted, don't display voting notice and change label of voting link
- Show object counts in more tabulator heads
- Enlarged member statement input field
Miscellaneous:
- Code cleanup
- Added README file containing installation instructions
- Use new WebMCP function ui.filters{...} instead of own ui.filter and ui.order functions
author | bsw/jbe |
---|---|
date | Sat Feb 20 22:10:31 2010 +0100 (2010-02-20) |
parents | |
children | 0849be391140 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/app/main/initiative/show_tab.lua Sat Feb 20 22:10:31 2010 +0100 1.3 @@ -0,0 +1,175 @@ 1.4 +local initiative = param.get("initiative", "table") 1.5 +local initiator = param.get("initiator", "table") 1.6 + 1.7 +if not initiative then 1.8 + initiative = Initiative:by_id(param.get("initiative_id", atom.number)) 1.9 +end 1.10 + 1.11 +if not initiator then 1.12 + initiator = Initiator:by_pk(initiative.id, app.session.member.id) 1.13 +end 1.14 + 1.15 +local current_draft_name = _"Current draft" 1.16 +if initiative.issue.half_frozen then 1.17 + current_draft_name = _"Voting proposal" 1.18 +end 1.19 + 1.20 +if initiative.issue.state == "finished" then 1.21 + current_draft_name = _"Voted proposal" 1.22 +end 1.23 + 1.24 +local tabs = { 1.25 + { 1.26 + name = "current_draft", 1.27 + label = current_draft_name, 1.28 + icon = { static = "icons/16/script.png" }, 1.29 + module = "initiative", 1.30 + view = "_current_draft", 1.31 + params = { 1.32 + initiative = initiative, 1.33 + initiator = initiator 1.34 + } 1.35 + } 1.36 +} 1.37 + 1.38 +if initiative.issue.ranks_available then 1.39 + tabs[#tabs+1] = { 1.40 + name = "voting", 1.41 + label = _"Voting details", 1.42 + icon = { static = "icons/16/email_open.png" }, 1.43 + module = "initiative", 1.44 + view = "_show_voting", 1.45 + params = { 1.46 + initiative = initiative 1.47 + } 1.48 + } 1.49 +end 1.50 + 1.51 +local suggestion_count = initiative:get_reference_selector("suggestions"):count() 1.52 + 1.53 +tabs[#tabs+1] = { 1.54 + name = "suggestions", 1.55 + label = _"Suggestions" .. " (" .. tostring(suggestion_count) .. ")", 1.56 + icon = { static = "icons/16/comments.png" }, 1.57 + module = "initiative", 1.58 + view = "_suggestions", 1.59 + params = { 1.60 + initiative = initiative 1.61 + } 1.62 +} 1.63 + 1.64 +local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 1.65 + :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 1.66 + :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.67 + :add_field("direct_interest_snapshot.weight") 1.68 + :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 1.69 + :add_where("direct_supporter_snapshot.satisfied") 1.70 + :add_field("direct_supporter_snapshot.informed", "is_informed") 1.71 + 1.72 +local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") 1.73 +local direct_satisfied_supporter_count = tmp.count 1.74 +local indirect_satisfied_supporter_count = (tmp.weight or 0) - tmp.count 1.75 + 1.76 +local count_string 1.77 +if indirect_satisfied_supporter_count > 0 then 1.78 + count_string = "(" .. tostring(direct_satisfied_supporter_count) .. "+" .. tostring(indirect_satisfied_supporter_count) .. ")" 1.79 +else 1.80 + count_string = "(" .. tostring(direct_satisfied_supporter_count) .. ")" 1.81 +end 1.82 + 1.83 +tabs[#tabs+1] = { 1.84 + name = "satisfied_supporter", 1.85 + label = _"Supporter" .. " " .. count_string, 1.86 + icon = { static = "icons/16/thumb_up_green.png" }, 1.87 + module = "member", 1.88 + view = "_list", 1.89 + params = { 1.90 + initiative = initiative, 1.91 + members_selector = members_selector 1.92 + } 1.93 +} 1.94 + 1.95 +local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 1.96 + :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 1.97 + :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.98 + :add_field("direct_interest_snapshot.weight") 1.99 + :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 1.100 + :add_where("NOT direct_supporter_snapshot.satisfied") 1.101 + :add_field("direct_supporter_snapshot.informed", "is_informed") 1.102 + 1.103 +local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") 1.104 +local direct_potential_supporter_count = tmp.count 1.105 +local indirect_potential_supporter_count = (tmp.weight or 0) - tmp.count 1.106 + 1.107 +local count_string 1.108 +if indirect_potential_supporter_count > 0 then 1.109 + count_string = "(" .. tostring(direct_potential_supporter_count) .. "+" .. tostring(indirect_potential_supporter_count) .. ")" 1.110 +else 1.111 + count_string = "(" .. tostring(direct_potential_supporter_count) .. ")" 1.112 +end 1.113 + 1.114 +tabs[#tabs+1] = { 1.115 + name = "supporter", 1.116 + label = _"Potential supporter" .. " " .. count_string, 1.117 + icon = { static = "icons/16/thumb_up.png" }, 1.118 + module = "member", 1.119 + view = "_list", 1.120 + params = { 1.121 + initiative = initiative, 1.122 + members_selector = members_selector 1.123 + } 1.124 +} 1.125 + 1.126 +local initiators_members_selector = initiative:get_reference_selector("initiating_members") 1.127 + :add_field("initiator.accepted", "accepted") 1.128 + 1.129 +if not (initiator and initiator.accepted) then 1.130 + initiators_members_selector:add_where("initiator.accepted") 1.131 +end 1.132 + 1.133 +local initiator_count = initiators_members_selector:count() 1.134 + 1.135 +tabs[#tabs+1] = { 1.136 + name = "initiators", 1.137 + label = _"Initiators" .. " (" .. tostring(initiator_count) .. ")", 1.138 + icon = { static = "icons/16/user_edit.png" }, 1.139 + module = "initiative", 1.140 + view = "_initiators", 1.141 + params = { 1.142 + initiative = initiative, 1.143 + initiator = initiator, 1.144 + initiators_members_selector = initiators_members_selector 1.145 + } 1.146 +} 1.147 + 1.148 +local drafts_count = initiative:get_reference_selector("drafts"):count() 1.149 + 1.150 +tabs[#tabs+1] = { 1.151 + name = "drafts", 1.152 + label = _"Draft history" .. " (" .. tostring(drafts_count) .. ")", 1.153 + icon = { static = "icons/16/script.png" }, 1.154 + module = "draft", 1.155 + view = "_list", 1.156 + params = { drafts = initiative.drafts } 1.157 +} 1.158 + 1.159 +tabs[#tabs+1] = { 1.160 + name = "details", 1.161 + label = _"Details", 1.162 + icon = { static = "icons/16/magnifier.png" }, 1.163 + module = "initiative", 1.164 + view = "_details", 1.165 + params = { 1.166 + initiative = initiative, 1.167 + members_selector = members_selector 1.168 + } 1.169 +} 1.170 + 1.171 +tabs.module = "initiative" 1.172 +tabs.view = "show_tab" 1.173 +tabs.static_params = { 1.174 + initiative_id = initiative.id 1.175 +} 1.176 + 1.177 +ui.tabs(tabs) 1.178 +