liquid_feedback_frontend
annotate app/main/index/index.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 | a3ac899559de | 
| children | 53a45356c107 | 
| rev | line source | 
|---|---|
| bsw/jbe@0 | 1 slot.select("title", function() | 
| bsw@10 | 2 if app.session.member then | 
| bsw@10 | 3 execute.view{ | 
| bsw@10 | 4 module = "member_image", | 
| bsw@10 | 5 view = "_show", | 
| bsw@10 | 6 params = { | 
| bsw@10 | 7 member = app.session.member, | 
| bsw@10 | 8 image_type = "avatar" | 
| bsw@10 | 9 } | 
| bsw/jbe@4 | 10 } | 
| bsw@10 | 11 end | 
| bsw/jbe@0 | 12 end) | 
| bsw/jbe@0 | 13 | 
| bsw/jbe@0 | 14 slot.select("title", function() | 
| bsw/jbe@0 | 15 ui.container{ | 
| bsw/jbe@0 | 16 attr = { class = "lang_chooser" }, | 
| bsw/jbe@0 | 17 content = function() | 
| bsw@15 | 18 for i, lang in ipairs{"en", "de", "eo"} do | 
| bsw/jbe@0 | 19 ui.link{ | 
| bsw/jbe@0 | 20 content = function() | 
| bsw/jbe@0 | 21 ui.image{ | 
| bsw/jbe@0 | 22 static = "lang/" .. lang .. ".png", | 
| bsw/jbe@0 | 23 attr = { style = "margin-left: 0.5em;", alt = lang } | 
| bsw/jbe@0 | 24 } | 
| bsw/jbe@0 | 25 end, | 
| bsw/jbe@19 | 26 text = _('Select language "#{langcode}"', { langcode = lang }), | 
| bsw/jbe@0 | 27 module = "index", | 
| bsw/jbe@0 | 28 action = "set_lang", | 
| bsw/jbe@0 | 29 params = { lang = lang }, | 
| bsw/jbe@0 | 30 routing = { | 
| bsw/jbe@0 | 31 default = { | 
| bsw/jbe@0 | 32 mode = "redirect", | 
| bsw/jbe@0 | 33 module = request.get_module(), | 
| bsw/jbe@0 | 34 view = request.get_view(), | 
| bsw/jbe@0 | 35 id = param.get_id_cgi(), | 
| bsw/jbe@0 | 36 params = param.get_all_cgi() | 
| bsw/jbe@0 | 37 } | 
| bsw/jbe@0 | 38 } | 
| bsw/jbe@0 | 39 } | 
| bsw/jbe@0 | 40 end | 
| bsw/jbe@0 | 41 end | 
| bsw/jbe@0 | 42 } | 
| bsw/jbe@0 | 43 end) | 
| bsw/jbe@0 | 44 | 
| bsw/jbe@0 | 45 slot.put_into("title", encode.html(config.app_title)) | 
| bsw/jbe@0 | 46 | 
| bsw/jbe@0 | 47 slot.select("actions", function() | 
| bsw/jbe@4 | 48 | 
| bsw@10 | 49 if app.session.member then | 
| bsw@10 | 50 ui.link{ | 
| bsw@10 | 51 content = function() | 
| bsw@10 | 52 ui.image{ static = "icons/16/application_form.png" } | 
| bsw@10 | 53 slot.put(_"Edit my profile") | 
| bsw@10 | 54 end, | 
| bsw@10 | 55 module = "member", | 
| bsw@10 | 56 view = "edit" | 
| bsw@10 | 57 } | 
| bsw@10 | 58 | 
| bsw/jbe@6 | 59 ui.link{ | 
| bsw/jbe@6 | 60 content = function() | 
| bsw@10 | 61 ui.image{ static = "icons/16/user_gray.png" } | 
| bsw@10 | 62 slot.put(_"Upload images") | 
| bsw/jbe@6 | 63 end, | 
| bsw@10 | 64 module = "member", | 
| bsw@10 | 65 view = "edit_images" | 
| bsw@10 | 66 } | 
| bsw@10 | 67 | 
| bsw@10 | 68 execute.view{ | 
| bsw@10 | 69 module = "delegation", | 
| bsw@10 | 70 view = "_show_box" | 
| bsw/jbe@6 | 71 } | 
| bsw@10 | 72 | 
| bsw@10 | 73 ui.link{ | 
| bsw@10 | 74 content = function() | 
| bsw@10 | 75 ui.image{ static = "icons/16/wrench.png" } | 
| bsw@10 | 76 slot.put(_"Settings") | 
| bsw@10 | 77 end, | 
| bsw@10 | 78 module = "member", | 
| bsw@10 | 79 view = "settings" | 
| bsw@10 | 80 } | 
| bsw@10 | 81 | 
| bsw@10 | 82 if config.download_dir then | 
| bsw@10 | 83 ui.link{ | 
| bsw@10 | 84 content = function() | 
| bsw@10 | 85 ui.image{ static = "icons/16/database_save.png" } | 
| bsw@10 | 86 slot.put(_"Download") | 
| bsw@10 | 87 end, | 
| bsw@10 | 88 module = "index", | 
| bsw@10 | 89 view = "download" | 
| bsw@10 | 90 } | 
| bsw@10 | 91 end | 
| bsw@10 | 92 end | 
| bsw/jbe@0 | 93 end) | 
| bsw/jbe@0 | 94 | 
| bsw/jbe@4 | 95 local lang = locale.get("lang") | 
| bsw/jbe@4 | 96 local basepath = request.get_app_basepath() | 
| bsw/jbe@4 | 97 local file_name = basepath .. "/locale/motd/" .. lang .. ".txt" | 
| bsw/jbe@4 | 98 local file = io.open(file_name) | 
| bsw/jbe@4 | 99 if file ~= nil then | 
| bsw/jbe@4 | 100 local help_text = file:read("*a") | 
| bsw/jbe@4 | 101 if #help_text > 0 then | 
| bsw/jbe@4 | 102 ui.container{ | 
| bsw/jbe@4 | 103 attr = { class = "motd wiki" }, | 
| bsw/jbe@4 | 104 content = function() | 
| bsw/jbe@4 | 105 slot.put(format.wiki_text(help_text)) | 
| bsw/jbe@4 | 106 end | 
| bsw/jbe@4 | 107 } | 
| bsw/jbe@4 | 108 end | 
| bsw/jbe@4 | 109 end | 
| bsw/jbe@4 | 110 | 
| bsw/jbe@4 | 111 | 
| bsw/jbe@4 | 112 util.help("index.index", _"Home") | 
| bsw/jbe@4 | 113 | 
| bsw/jbe@5 | 114 local areas = {} | 
| bsw@10 | 115 if app.session.member then | 
| bsw@10 | 116 local selector = Area:new_selector() | 
| bsw@10 | 117 :reset_fields() | 
| bsw@10 | 118 :add_field("area.id", nil, { "grouped" }) | 
| bsw@10 | 119 :add_field("area.name", nil, { "grouped" }) | 
| bsw@10 | 120 :add_field("membership.member_id NOTNULL", "is_member", { "grouped" }) | 
| bsw@10 | 121 :add_field("count(issue.id)", "issues_to_vote_count") | 
| bsw@10 | 122 :add_field("count(interest.member_id)", "interested_issues_to_vote_count") | 
| bsw@10 | 123 :join("issue", nil, "issue.area_id = area.id AND issue.fully_frozen NOTNULL AND issue.closed ISNULL") | 
| bsw@10 | 124 :left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) | 
| bsw@10 | 125 :add_where{ "direct_voter.member_id ISNULL" } | 
| bsw@10 | 126 :left_join("interest", nil, { "interest.issue_id = issue.id AND interest.member_id = ?", app.session.member.id }) | 
| bsw@10 | 127 :left_join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ? ", app.session.member.id }) | 
| bsw@10 | 128 | 
| bsw@10 | 129 for i, area in ipairs(selector:exec()) do | 
| bsw@10 | 130 if area.is_member or area.interested_issues_to_vote_count > 0 then | 
| bsw@10 | 131 areas[#areas+1] = area | 
| bsw@10 | 132 end | 
| bsw/jbe@5 | 133 end | 
| bsw/jbe@5 | 134 end | 
| bsw/jbe@5 | 135 | 
| bsw/jbe@5 | 136 if #areas > 0 then | 
| bsw/jbe@5 | 137 ui.container{ | 
| bsw/jbe@5 | 138 attr = { style = "font-weight: bold;" }, | 
| bsw/jbe@5 | 139 content = _"Current votings in areas you are member of and issues you are interested in:" | 
| bsw/jbe@5 | 140 } | 
| bsw/jbe@5 | 141 | 
| bsw/jbe@5 | 142 ui.list{ | 
| bsw/jbe@5 | 143 records = areas, | 
| bsw/jbe@5 | 144 columns = { | 
| bsw/jbe@5 | 145 { | 
| bsw/jbe@5 | 146 name = "name" | 
| bsw/jbe@5 | 147 }, | 
| bsw/jbe@5 | 148 { | 
| bsw/jbe@5 | 149 content = function(record) | 
| bsw/jbe@5 | 150 if record.is_member and record.issues_to_vote_count > 0 then | 
| bsw/jbe@5 | 151 ui.link{ | 
| bsw/jbe@5 | 152 content = function() | 
| bsw/jbe@5 | 153 if record.issues_to_vote_count > 1 then | 
| bsw/jbe@5 | 154 slot.put(_("#{issues_to_vote_count} issue(s)", { issues_to_vote_count = record.issues_to_vote_count })) | 
| bsw/jbe@5 | 155 else | 
| bsw/jbe@5 | 156 slot.put(_("One issue")) | 
| bsw/jbe@5 | 157 end | 
| bsw/jbe@5 | 158 end, | 
| bsw/jbe@5 | 159 module = "area", | 
| bsw/jbe@5 | 160 view = "show", | 
| bsw/jbe@5 | 161 id = record.id, | 
| bsw/jbe@5 | 162 params = { | 
| bsw/jbe@5 | 163 filter = "frozen", | 
| bsw/jbe@5 | 164 filter_voting = "not_voted" | 
| bsw/jbe@5 | 165 } | 
| bsw/jbe@5 | 166 } | 
| bsw/jbe@5 | 167 else | 
| bsw/jbe@5 | 168 slot.put(_"Not a member") | 
| bsw/jbe@5 | 169 end | 
| bsw/jbe@5 | 170 end | 
| bsw/jbe@5 | 171 }, | 
| bsw/jbe@5 | 172 { | 
| bsw/jbe@5 | 173 content = function(record) | 
| bsw/jbe@5 | 174 if record.interested_issues_to_vote_count > 0 then | 
| bsw/jbe@5 | 175 ui.link{ | 
| bsw/jbe@5 | 176 content = function() | 
| bsw/jbe@5 | 177 if record.interested_issues_to_vote_count > 1 then | 
| bsw/jbe@5 | 178 slot.put(_("#{interested_issues_to_vote_count} issue(s) you are interested in", { interested_issues_to_vote_count = record.interested_issues_to_vote_count })) | 
| bsw/jbe@5 | 179 else | 
| bsw/jbe@5 | 180 slot.put(_"One issue you are interested in") | 
| bsw/jbe@5 | 181 end | 
| bsw/jbe@5 | 182 end, | 
| bsw/jbe@5 | 183 module = "area", | 
| bsw/jbe@5 | 184 view = "show", | 
| bsw/jbe@5 | 185 id = record.id, | 
| bsw/jbe@5 | 186 params = { | 
| bsw/jbe@5 | 187 filter = "frozen", | 
| bsw/jbe@5 | 188 filter_interest = "my", | 
| bsw/jbe@5 | 189 filter_voting = "not_voted" | 
| bsw/jbe@5 | 190 } | 
| bsw/jbe@5 | 191 } | 
| bsw/jbe@5 | 192 end | 
| bsw/jbe@5 | 193 end | 
| bsw/jbe@5 | 194 }, | 
| bsw/jbe@5 | 195 } | 
| bsw/jbe@5 | 196 } | 
| bsw/jbe@5 | 197 end | 
| bsw/jbe@5 | 198 | 
| bsw@10 | 199 local initiatives_selector = Initiative:new_selector() | 
| bsw@10 | 200 :join("initiator", nil, { "initiator.initiative_id = initiative.id AND initiator.member_id = ? AND initiator.accepted ISNULL", app.session.member.id }) | 
| bsw@10 | 201 | 
| bsw@10 | 202 if initiatives_selector:count() > 0 then | 
| bsw@10 | 203 ui.container{ | 
| bsw@10 | 204 attr = { style = "font-weight: bold;" }, | 
| bsw@10 | 205 content = _"Initiatives that invited you to become initiator:" | 
| bsw@10 | 206 } | 
| bsw/jbe@0 | 207 | 
| bsw@10 | 208 execute.view{ | 
| bsw@10 | 209 module = "initiative", | 
| bsw@10 | 210 view = "_list", | 
| bsw@10 | 211 params = { initiatives_selector = initiatives_selector } | 
| bsw@10 | 212 } | 
| bsw@10 | 213 end | 
| bsw@10 | 214 | 
| bsw@10 | 215 | 
| bsw@10 | 216 if app.session.member then | 
| bsw@10 | 217 execute.view{ | 
| bsw@10 | 218 module = "member", | 
| bsw@10 | 219 view = "_show", | 
| bsw@10 | 220 params = { member = app.session.member } | 
| bsw@10 | 221 } | 
| bsw@10 | 222 end |