liquid_feedback_frontend
annotate model/issue.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 | 72c5e0ee7c98 |
children | 4b2af207cefa |
rev | line source |
---|---|
bsw/jbe@0 | 1 Issue = mondelefant.new_class() |
bsw/jbe@0 | 2 Issue.table = 'issue' |
bsw/jbe@0 | 3 |
bsw/jbe@0 | 4 Issue:add_reference{ |
bsw/jbe@0 | 5 mode = 'm1', |
bsw/jbe@0 | 6 to = "Area", |
bsw/jbe@0 | 7 this_key = 'area_id', |
bsw/jbe@0 | 8 that_key = 'id', |
bsw/jbe@0 | 9 ref = 'area', |
bsw/jbe@0 | 10 } |
bsw/jbe@0 | 11 |
bsw/jbe@0 | 12 Issue:add_reference{ |
bsw/jbe@0 | 13 mode = 'm1', |
bsw/jbe@0 | 14 to = "Policy", |
bsw/jbe@0 | 15 this_key = 'policy_id', |
bsw/jbe@0 | 16 that_key = 'id', |
bsw/jbe@0 | 17 ref = 'policy', |
bsw/jbe@0 | 18 } |
bsw/jbe@0 | 19 |
bsw/jbe@0 | 20 Issue:add_reference{ |
bsw/jbe@0 | 21 mode = '1m', |
bsw/jbe@0 | 22 to = "Initiative", |
bsw/jbe@0 | 23 this_key = 'id', |
bsw/jbe@0 | 24 that_key = 'issue_id', |
bsw/jbe@0 | 25 ref = 'initiatives', |
bsw/jbe@0 | 26 back_ref = 'issue' |
bsw/jbe@0 | 27 } |
bsw/jbe@0 | 28 |
bsw/jbe@0 | 29 Issue:add_reference{ |
bsw/jbe@0 | 30 mode = '1m', |
bsw/jbe@0 | 31 to = "Interest", |
bsw/jbe@0 | 32 this_key = 'id', |
bsw/jbe@0 | 33 that_key = 'issue_id', |
bsw/jbe@0 | 34 ref = 'interests', |
bsw/jbe@0 | 35 back_ref = 'issue', |
bsw/jbe@0 | 36 default_order = '"id"' |
bsw/jbe@0 | 37 } |
bsw/jbe@0 | 38 |
bsw/jbe@0 | 39 Issue:add_reference{ |
bsw/jbe@0 | 40 mode = '1m', |
bsw/jbe@0 | 41 to = "Supporter", |
bsw/jbe@0 | 42 this_key = 'id', |
bsw/jbe@0 | 43 that_key = 'issue_id', |
bsw/jbe@0 | 44 ref = 'supporters', |
bsw/jbe@0 | 45 back_ref = 'issue', |
bsw/jbe@0 | 46 default_order = '"id"' |
bsw/jbe@0 | 47 } |
bsw/jbe@0 | 48 |
bsw/jbe@0 | 49 Issue:add_reference{ |
bsw/jbe@0 | 50 mode = '1m', |
bsw/jbe@0 | 51 to = "DirectVoter", |
bsw/jbe@0 | 52 this_key = 'id', |
bsw/jbe@0 | 53 that_key = 'issue_id', |
bsw/jbe@0 | 54 ref = 'direct_voters', |
bsw/jbe@0 | 55 back_ref = 'issue', |
bsw/jbe@0 | 56 default_order = '"member_id"' |
bsw/jbe@0 | 57 } |
bsw/jbe@0 | 58 |
bsw/jbe@0 | 59 Issue:add_reference{ |
bsw/jbe@0 | 60 mode = '1m', |
bsw/jbe@0 | 61 to = "Vote", |
bsw/jbe@0 | 62 this_key = 'id', |
bsw/jbe@0 | 63 that_key = 'issue_id', |
bsw/jbe@0 | 64 ref = 'votes', |
bsw/jbe@0 | 65 back_ref = 'issue', |
bsw/jbe@0 | 66 default_order = '"member_id", "initiative_id"' |
bsw/jbe@0 | 67 } |
bsw/jbe@0 | 68 |
bsw/jbe@0 | 69 Issue:add_reference{ |
bsw@2 | 70 mode = '1m', |
bsw@2 | 71 to = "Delegation", |
bsw@2 | 72 this_key = 'id', |
bsw@2 | 73 that_key = 'issue_id', |
bsw@2 | 74 ref = 'delegations', |
bsw@2 | 75 back_ref = 'issue' |
bsw@2 | 76 } |
bsw@2 | 77 |
bsw@2 | 78 Issue:add_reference{ |
bsw/jbe@0 | 79 mode = 'mm', |
bsw/jbe@0 | 80 to = "Member", |
bsw/jbe@0 | 81 this_key = 'id', |
bsw/jbe@0 | 82 that_key = 'id', |
bsw/jbe@0 | 83 connected_by_table = 'interest', |
bsw/jbe@0 | 84 connected_by_this_key = 'issue_id', |
bsw/jbe@0 | 85 connected_by_that_key = 'member_id', |
bsw/jbe@0 | 86 ref = 'members' |
bsw/jbe@0 | 87 } |
bsw/jbe@0 | 88 |
bsw@3 | 89 Issue:add_reference{ |
bsw@3 | 90 mode = 'mm', |
bsw@3 | 91 to = "Member", |
bsw@3 | 92 this_key = 'id', |
bsw@3 | 93 that_key = 'id', |
bsw@3 | 94 connected_by_table = 'direct_interest_snapshot', |
bsw@3 | 95 connected_by_this_key = 'issue_id', |
bsw@3 | 96 connected_by_that_key = 'member_id', |
bsw@3 | 97 ref = 'interested_members_snapshot' |
bsw@3 | 98 } |
bsw@3 | 99 |
bsw/jbe@6 | 100 Issue:add_reference{ |
bsw/jbe@6 | 101 mode = 'mm', |
bsw/jbe@6 | 102 to = "Member", |
bsw/jbe@6 | 103 this_key = 'id', |
bsw/jbe@6 | 104 that_key = 'id', |
bsw/jbe@6 | 105 connected_by_table = 'direct_voter', |
bsw/jbe@6 | 106 connected_by_this_key = 'issue_id', |
bsw/jbe@6 | 107 connected_by_that_key = 'member_id', |
bsw/jbe@6 | 108 ref = 'direct_voters' |
bsw/jbe@6 | 109 } |
bsw/jbe@6 | 110 |
bsw/jbe@6 | 111 |
bsw/jbe@6 | 112 |
bsw/jbe@0 | 113 function Issue:get_state_name_for_state(value) |
bsw@2 | 114 local state_name_table = { |
bsw@2 | 115 new = _"New", |
bsw@3 | 116 accepted = _"Discussion", |
bsw@2 | 117 frozen = _"Frozen", |
bsw@2 | 118 voting = _"Voting", |
bsw@2 | 119 finished = _"Finished", |
bsw@2 | 120 cancelled = _"Cancelled" |
bsw@2 | 121 } |
bsw@10 | 122 return state_name_table[value] or value or '' |
bsw/jbe@0 | 123 end |
bsw/jbe@0 | 124 |
bsw@2 | 125 function Issue:get_search_selector(search_string) |
bsw/jbe@0 | 126 return self:new_selector() |
bsw/jbe@0 | 127 :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"') |
bsw/jbe@6 | 128 :join('"draft"', nil, '"draft"."initiative_id" = "initiative"."id"') |
bsw/jbe@6 | 129 :add_where{ '"initiative"."text_search_data" @@ "text_search_query"(?) OR "draft"."text_search_data" @@ "text_search_query"(?)', search_string, search_string } |
bsw/jbe@6 | 130 :add_group_by('"issue"."id"') |
bsw/jbe@6 | 131 :add_group_by('"issue"."area_id"') |
bsw/jbe@6 | 132 :add_group_by('"issue"."policy_id"') |
bsw/jbe@6 | 133 :add_group_by('"issue"."created"') |
bsw/jbe@6 | 134 :add_group_by('"issue"."accepted"') |
bsw/jbe@6 | 135 :add_group_by('"issue"."half_frozen"') |
bsw/jbe@6 | 136 :add_group_by('"issue"."fully_frozen"') |
bsw/jbe@6 | 137 :add_group_by('"issue"."closed"') |
bsw/jbe@6 | 138 :add_group_by('"issue"."ranks_available"') |
bsw/jbe@6 | 139 :add_group_by('"issue"."snapshot"') |
bsw/jbe@6 | 140 :add_group_by('"issue"."latest_snapshot_event"') |
bsw/jbe@6 | 141 :add_group_by('"issue"."population"') |
bsw/jbe@6 | 142 :add_group_by('"issue"."vote_now"') |
bsw/jbe@6 | 143 :add_group_by('"issue"."vote_later"') |
bsw/jbe@6 | 144 :add_group_by('"issue"."voter_count"') |
bsw/jbe@19 | 145 :add_group_by('"_interest"."member_id"') |
bsw/jbe@6 | 146 --:set_distinct() |
bsw/jbe@0 | 147 end |
bsw/jbe@0 | 148 |
bsw/jbe@0 | 149 function Issue.object_get:state() |
bsw/jbe@0 | 150 if self.accepted then |
bsw@3 | 151 if self.closed then |
bsw/jbe@5 | 152 return "finished" |
bsw@3 | 153 elseif self.fully_frozen then |
bsw@3 | 154 return "voting" |
bsw@3 | 155 elseif self.half_frozen then |
bsw@3 | 156 return "frozen" |
bsw/jbe@0 | 157 else |
bsw/jbe@0 | 158 return "accepted" |
bsw/jbe@0 | 159 end |
bsw/jbe@0 | 160 else |
bsw/jbe@0 | 161 if self.closed then |
bsw@2 | 162 return "cancelled" |
bsw/jbe@0 | 163 else |
bsw/jbe@0 | 164 return "new" |
bsw/jbe@0 | 165 end |
bsw/jbe@0 | 166 end |
bsw@2 | 167 end |
bsw@2 | 168 |
bsw@2 | 169 function Issue.object_get:state_name() |
bsw@2 | 170 return Issue:get_state_name_for_state(self.state) |
bsw@2 | 171 end |
bsw@2 | 172 |
bsw@2 | 173 function Issue.object_get:state_time_left() |
bsw@2 | 174 local state = self.state |
bsw@2 | 175 local last_event_time |
bsw@2 | 176 local duration |
bsw@2 | 177 if state == "new" then |
bsw@2 | 178 last_event_time = self.created |
bsw@2 | 179 duration = self.policy.admission_time |
bsw@2 | 180 elseif state == "accepted" then |
bsw@2 | 181 last_event_time = self.accepted |
bsw@2 | 182 duration = self.policy.discussion_time |
bsw@2 | 183 elseif state == "frozen" then |
bsw@2 | 184 last_event_time = self.half_frozen |
bsw@2 | 185 duration = self.policy.verification_time |
bsw@2 | 186 elseif state == "voting" then |
bsw@2 | 187 last_event_time = self.fully_frozen |
bsw@2 | 188 duration = self.policy.voting_time |
bsw@2 | 189 end |
bsw@2 | 190 return db:query{ "SELECT ?::timestamp + ?::interval - now() as time_left", last_event_time, duration }[1].time_left |
bsw@2 | 191 end |
bsw@2 | 192 |
bsw@2 | 193 function Issue.object_get:next_states() |
bsw@2 | 194 local state = self.state |
bsw@2 | 195 local next_states |
bsw@2 | 196 if state == "new" then |
bsw@2 | 197 next_states = { "accepted", "cancelled" } |
bsw@2 | 198 elseif state == "accepted" then |
bsw@2 | 199 next_states = { "frozen" } |
bsw@2 | 200 elseif state == "frozen" then |
bsw@2 | 201 next_states = { "voting" } |
bsw@2 | 202 elseif state == "voting" then |
bsw@2 | 203 next_states = { "finished" } |
bsw@2 | 204 end |
bsw@2 | 205 return next_states |
bsw@2 | 206 end |
bsw@2 | 207 |
bsw@2 | 208 function Issue.object_get:next_states_names() |
bsw@2 | 209 local next_states = self.next_states |
bsw@2 | 210 if not next_states then |
bsw@2 | 211 return |
bsw@2 | 212 end |
bsw@2 | 213 local state_names = {} |
bsw@2 | 214 for i, state in ipairs(self.next_states) do |
bsw@2 | 215 state_names[#state_names+1] = Issue:get_state_name_for_state(state) |
bsw@2 | 216 end |
bsw@2 | 217 return table.concat(state_names, ", ") |
bsw/jbe@0 | 218 end |