liquid_feedback_frontend
changeset 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
line diff
1.1 --- a/Makefile Tue Feb 02 00:31:06 2010 +0100 1.2 +++ b/Makefile Sat Feb 20 22:10:31 2010 +0100 1.3 @@ -1,14 +1,6 @@ 1.4 default: 1.5 1.6 1.7 -db: 1.8 - create_db liquid_feedback 1.9 - psql liquid_feedback -f db/core.sql 1.10 - 1.11 -demo-db: db 1.12 - psql liquid_feedback -f db/demo.sql 1.13 - 1.14 - 1.15 translations-de: 1.16 cd ../webmcp/framework/bin/ && ./langtool.lua ~/workspace/liquid_feedback/locale/translations.de.lua ~/workspace/liquid_feedback/app ~/workspace/liquid_feedback/locale/translations.de.lua 1.17
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/README Sat Feb 20 22:10:31 2010 +0100 2.3 @@ -0,0 +1,61 @@ 2.4 + 2.5 +################ 2.6 +# Installation # 2.7 +################ 2.8 + 2.9 + 2.10 +1. Choose a directory where to install the software, e.g. /opt : 2.11 + 2.12 +$ cd /opt 2.13 + 2.14 + 2.15 +2. Get the repositories of the core, the frondend and the web application 2.16 + framework WebMCP: 2.17 + 2.18 +$ hg clone http://www.public-software-group.org/mercurial/liquid_feedback_core 2.19 +$ hg clone http://www.public-software-group.org/mercurial/liquid_feedback_frontend 2.20 +$ hg clone http://www.public-software-group.org/mercurial/webmcp 2.21 + 2.22 + 2.23 +3. Install LiquidFeedback Core: 2.24 + 2.25 +$ cd /opt/liquid_feedback_core 2.26 +$ make 2.27 +$ createdb liquid_feedback 2.28 +$ psql -v ON_ERROR_STOP=1 -f core.sql liquid_feedback 2.29 + 2.30 +You should initiatize your database using the command 2.31 +"psql liquid_feedback" and the examples shown in file "init.sql". 2.32 + 2.33 + 2.34 +4. Compile WebMCP 2.35 + 2.36 +$ cd /opt/webmcp 2.37 +$ make 2.38 + 2.39 +If you experience trouble during compilation, you might want to edit the 2.40 +file "Makefile.options" (i.e. to add -fPIC to compiler options) and then 2.41 +retry: 2.42 + 2.43 +$ vi Makefile.options 2.44 +$ make clean 2.45 +$ make 2.46 + 2.47 + 2.48 +5. Install Wiki-to-HTML converters 2.49 + 2.50 +Download latest LiquidFeedback Edition of RocketWiki from 2.51 +http://www.public-software-group.org/pub/projects/rocketwiki/liquid_feedback_edition/ 2.52 + 2.53 +Compile the binaries by calling make, and copy them to a place of your 2.54 +choice, e.g. /opt/rocketwiki-lqfb/ 2.55 + 2.56 + 2.57 +6. Configure the webserver and the LiquidFeedback Frontend application: 2.58 + 2.59 +Edit the configuration files in /opt/liquid_feedback_frontend/config/ 2.60 + 2.61 +Use /opt/webmcp/doc/lighttpd.example.conf (or apache.sample.conf) to setup 2.62 +your webserver appropriatly. 2.63 + 2.64 +
3.1 --- a/app/main/_filter_view/30_navigation.lua Tue Feb 02 00:31:06 2010 +0100 3.2 +++ b/app/main/_filter_view/30_navigation.lua Sat Feb 20 22:10:31 2010 +0100 3.3 @@ -4,36 +4,28 @@ 3.4 if app.session.member == nil then 3.5 slot.select('navigation', function() 3.6 ui.link{ 3.7 - content = function() 3.8 - ui.image{ static = "icons/16/key.png" } 3.9 - slot.put(_"Login") 3.10 - end, 3.11 + image = { static = "icons/16/key.png" }, 3.12 + text = _"Login", 3.13 module = 'index', 3.14 - view = 'login' 3.15 + view = 'login' 3.16 } 3.17 ui.link{ 3.18 - content = function() 3.19 - ui.image{ static = "icons/16/book_edit.png" } 3.20 - slot.put(_"Registration") 3.21 - end, 3.22 + image = { static = "icons/16/book_edit.png" }, 3.23 + text = _"Registration", 3.24 module = 'index', 3.25 - view = 'register' 3.26 + view = 'register' 3.27 } 3.28 ui.link{ 3.29 - content = function() 3.30 - ui.image{ static = "icons/16/key_forgot.png" } 3.31 - slot.put(_"Reset password") 3.32 - end, 3.33 + image = { static = "icons/16/key_forgot.png" }, 3.34 + text = _"Reset password", 3.35 module = 'index', 3.36 - view = 'reset_password' 3.37 + view = 'reset_password' 3.38 } 3.39 ui.link{ 3.40 - content = function() 3.41 - ui.image{ static = "icons/16/information.png" } 3.42 - slot.put('About / Impressum') 3.43 - end, 3.44 + image = { static = "icons/16/information.png" }, 3.45 + text = _"About / Impressum", 3.46 module = 'index', 3.47 - view = 'about' 3.48 + view = 'about' 3.49 } 3.50 end) 3.51 execute.inner() 3.52 @@ -43,75 +35,46 @@ 3.53 slot.select('navigation', function() 3.54 3.55 ui.link{ 3.56 - content = function() 3.57 - ui.image{ static = "icons/16/house.png" } 3.58 - slot.put(_"Home") 3.59 - end, 3.60 + image = { static = "icons/16/house.png" }, 3.61 + text = _"Home", 3.62 module = 'index', 3.63 - view = 'index' 3.64 + view = 'index' 3.65 } 3.66 3.67 - local setting_key = "liquidfeedback_frontend_timeline_current_options" 3.68 - local setting = Setting:by_pk(app.session.member.id, setting_key) 3.69 - 3.70 - timeline_params = {} 3.71 - if setting then 3.72 - for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do 3.73 - timeline_params["option_" .. event_ident] = true 3.74 - if filter_idents ~= "*" then 3.75 - for filter_ident in filter_idents:gmatch("([^\|]+)") do 3.76 - timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true 3.77 - end 3.78 - end 3.79 - end 3.80 - end 3.81 - 3.82 - timeline_params.date = param.get("date") or today 3.83 - 3.84 ui.link{ 3.85 - content = function() 3.86 - ui.image{ static = "icons/16/time.png" } 3.87 - slot.put(_"Timeline") 3.88 - end, 3.89 + image = { static = "icons/16/time.png" }, 3.90 + text = _"Timeline", 3.91 module = "timeline", 3.92 - action = "update" 3.93 --- params = timeline_params 3.94 + view = "index" 3.95 } 3.96 3.97 ui.link{ 3.98 - content = function() 3.99 - ui.image{ static = "icons/16/package.png" } 3.100 - slot.put(_"Areas") 3.101 - end, 3.102 + image = { static = "icons/16/package.png" }, 3.103 + text = _"Areas", 3.104 module = 'area', 3.105 - view = 'list' 3.106 + view = 'list' 3.107 } 3.108 3.109 ui.link{ 3.110 - content = function() 3.111 - ui.image{ static = "icons/16/group.png" } 3.112 - slot.put(_"Members") 3.113 - end, 3.114 + image = { static = "icons/16/group.png" }, 3.115 + text = _"Members", 3.116 module = 'member', 3.117 - view = 'list' 3.118 + view = 'list', 3.119 + params = { member_list = "newest" } 3.120 } 3.121 3.122 ui.link{ 3.123 - content = function() 3.124 - ui.image{ static = "icons/16/book_edit.png" } 3.125 - slot.put(_"Contacts") 3.126 - end, 3.127 + image = { static = "icons/16/book_edit.png" }, 3.128 + text = _"Contacts", 3.129 module = 'contact', 3.130 - view = 'list' 3.131 + view = 'list' 3.132 } 3.133 3.134 ui.link{ 3.135 - content = function() 3.136 - ui.image{ static = "icons/16/information.png" } 3.137 - slot.put(_"About") 3.138 - end, 3.139 + image = { static = "icons/16/information.png" }, 3.140 + text = _"About", 3.141 module = 'index', 3.142 - view = 'about' 3.143 + view = 'about' 3.144 } 3.145 3.146 if app.session.member.admin then 3.147 @@ -119,13 +82,11 @@ 3.148 slot.put(" ") 3.149 3.150 ui.link{ 3.151 - attr = { class = { "admin_only" } }, 3.152 - content = function() 3.153 - ui.image{ static = "icons/16/cog.png" } 3.154 - slot.put(_'Admin') 3.155 - end, 3.156 + attr = { class = { "admin_only" } }, 3.157 + image = { static = "icons/16/cog.png" }, 3.158 + text = _"Admin", 3.159 module = 'admin', 3.160 - view = 'index' 3.161 + view = 'index' 3.162 } 3.163 3.164 end 3.165 @@ -139,5 +100,3 @@ 3.166 end 3.167 3.168 execute.inner() 3.169 - 3.170 -
4.1 --- a/app/main/_filter_view/31_logout_button.lua Tue Feb 02 00:31:06 2010 +0100 4.2 +++ b/app/main/_filter_view/31_logout_button.lua Sat Feb 20 22:10:31 2010 +0100 4.3 @@ -5,10 +5,8 @@ 4.4 4.5 slot.select('logout_button', function() 4.6 ui.link{ 4.7 - content = function() 4.8 - ui.image{ static = "icons/16/stop.png" } 4.9 - slot.put(_'Logout') 4.10 - end, 4.11 + image = { static = "icons/16/stop.png" }, 4.12 + text = _"Logout", 4.13 module = 'index', 4.14 action = 'logout' 4.15 }
5.1 --- a/app/main/_filter_view/33_help_hidden.lua Tue Feb 02 00:31:06 2010 +0100 5.2 +++ b/app/main/_filter_view/33_help_hidden.lua Sat Feb 20 22:10:31 2010 +0100 5.3 @@ -28,9 +28,9 @@ 5.4 attr = { class = "help_icon" }, 5.5 static = "icons/16/help.png" 5.6 } 5.7 - end 5.8 + end, 5.9 + text = _"Show help text" 5.10 } 5.11 end 5.12 end) 5.13 end 5.14 -
6.1 --- a/app/main/_filter_view/34_stylesheet.lua Tue Feb 02 00:31:06 2010 +0100 6.2 +++ b/app/main/_filter_view/34_stylesheet.lua Sat Feb 20 22:10:31 2010 +0100 6.3 @@ -11,4 +11,40 @@ 6.4 slot.put_into("stylesheet_url", config.absolute_base_url .. "static/style.css") 6.5 end 6.6 6.7 -execute.inner() 6.8 \ No newline at end of file 6.9 +if os.getenv("HTTP_USER_AGENT"):find("Android.*AppleWebKit.*Mobile Safari") then 6.10 + slot.select("html_head", function() 6.11 + ui.tag{ 6.12 + tag = "style", 6.13 + content = "body, td, th { font-size: 16px; };" 6.14 + } 6.15 + end) 6.16 +end 6.17 + 6.18 +if app.session.member then 6.19 + local tab_mode = app.session.member:get_setting_value("tab_mode") 6.20 + if tab_mode then 6.21 + config.user_tab_mode = tab_mode 6.22 + end 6.23 +end 6.24 + 6.25 +local web20 = config.user_tab_mode == "accordeon" 6.26 + or config.user_tab_mode == "accordeon_first_expanded" 6.27 + or config.user_tab_mode == "accordeon_all_expanded" 6.28 + 6.29 +if web20 then 6.30 + ui.enable_partial_loading() 6.31 +end 6.32 + 6.33 +if request.get_json_request_slots() then 6.34 + slot.set_layout("blank") 6.35 +end 6.36 + 6.37 + 6.38 +ui.container{ 6.39 + attr = { 6.40 + class = web20 and "web20" or "web10" 6.41 + }, 6.42 + content = function() 6.43 + execute.inner() 6.44 + end 6.45 +} 6.46 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/app/main/_layout/atom.html Sat Feb 20 22:10:31 2010 +0100 7.3 @@ -0,0 +1,12 @@ 7.4 +<?xml version="1.0" encoding="utf-8"?> 7.5 + 7.6 +<feed xmlns="http://www.w3.org/2005/Atom"> 7.7 + <author> 7.8 + <name>foo</name> 7.9 + </author> 7.10 + <title>LiquidFeedback</title> 7.11 + <subtitle>Initiatives</subtitle> 7.12 + <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id> 7.13 + <updated>2003-12-14T10:20:09Z</updated> 7.14 + <!-- WEBMCP SLOTNODIV default --> 7.15 +</feed>
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/app/main/_layout/blank.html Sat Feb 20 22:10:31 2010 +0100 8.3 @@ -0,0 +1,1 @@ 8.4 +<!-- WEBMCP SLOTNODIV default --> 8.5 \ No newline at end of file
9.1 --- a/app/main/_layout/default.html Tue Feb 02 00:31:06 2010 +0100 9.2 +++ b/app/main/_layout/default.html Sat Feb 20 22:10:31 2010 +0100 9.3 @@ -6,6 +6,8 @@ 9.4 <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" /> 9.5 <link rel="stylesheet" type="text/css" media="screen" href="<!-- WEBMCP SLOTNODIV stylesheet_url -->" /> 9.6 <!-- WEBMCP SLOTNODIV html_head --> 9.7 + <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script> 9.8 + <script type="text/javascript">var ui_tabs_active = {};</script> 9.9 </head> 9.10 <body> 9.11 <div class="topbar"> 9.12 @@ -67,7 +69,9 @@ 9.13 <div class="layout_trace" id="layout_trace" style="xdisplay: none"> 9.14 <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';">TRACE</div> 9.15 <div id="trace_content" style="display: none;"> 9.16 - <!-- WEBMCP SLOT trace --> 9.17 + <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt> 9.18 + <div id="trace"> </div><hr /> 9.19 + <!-- WEBMCP SLOT trace --> 9.20 <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';"> 9.21 close 9.22 </div>
10.1 --- a/app/main/_layout/system_error.html Tue Feb 02 00:31:06 2010 +0100 10.2 +++ b/app/main/_layout/system_error.html Sat Feb 20 22:10:31 2010 +0100 10.3 @@ -1,7 +1,7 @@ 10.4 <html> 10.5 <head> 10.6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 10.7 - <title>Liquid Democracy System Error</title> 10.8 + <title>LiquidFeedback Error</title> 10.9 <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" /> 10.10 <style> 10.11 body {
11.1 --- a/app/main/area/_list.lua Tue Feb 02 00:31:06 2010 +0100 11.2 +++ b/app/main/area/_list.lua Sat Feb 20 22:10:31 2010 +0100 11.3 @@ -13,38 +13,56 @@ 11.4 :add_field({ "(SELECT COUNT(*) FROM issue LEFT JOIN direct_voter ON direct_voter.issue_id = issue.id AND direct_voter.member_id = ? WHERE issue.area_id = area.id AND issue.fully_frozen NOTNULL AND issue.closed ISNULL AND direct_voter.member_id ISNULL)", app.session.member.id }, "issues_to_vote_count") 11.5 :add_field("(SELECT COUNT(*) FROM issue WHERE issue.area_id = area.id AND issue.fully_frozen NOTNULL AND issue.closed NOTNULL)", "issues_finished_count") 11.6 :add_field("(SELECT COUNT(*) FROM issue WHERE issue.area_id = area.id AND issue.fully_frozen ISNULL AND issue.closed NOTNULL)", "issues_cancelled_count") 11.7 + :left_join("membership", "_membership", { "_membership.area_id = area.id AND _membership.member_id = ?", app.session.member.id }) 11.8 + :add_field("_membership.member_id NOTNULL", "is_member", { "grouped" }) 11.9 11.10 -ui.order{ 11.11 - name = name, 11.12 +local label_attr = { style = "text-align: right; width: 4em;" } 11.13 +local field_attr = { style = "text-align: right; width: 4em;" } 11.14 + 11.15 +ui.filters{ 11.16 + label = _"Change order", 11.17 selector = areas_selector, 11.18 - options = { 11.19 + { 11.20 + label = _"Order by", 11.21 { 11.22 name = "member_weight", 11.23 label = _"Population", 11.24 - order_by = "area.member_weight DESC" 11.25 + selector_modifier = function(selector) selector:add_order_by("area.member_weight DESC") end 11.26 }, 11.27 { 11.28 name = "direct_member_count", 11.29 label = _"Direct member count", 11.30 - order_by = "area.direct_member_count DESC" 11.31 + selector_modifier = function(selector) selector:add_order_by("area.direct_member_count DESC") end 11.32 }, 11.33 { 11.34 name = "az", 11.35 label = _"A-Z", 11.36 - order_by = "area.name" 11.37 + selector_modifier = function(selector) selector:add_order_by("area.name") end 11.38 }, 11.39 { 11.40 name = "za", 11.41 label = _"Z-A", 11.42 - order_by = "area.name DESC" 11.43 + selector_modifier = function(selector) selector:add_order_by("area.name DESC") end 11.44 } 11.45 }, 11.46 content = function() 11.47 ui.list{ 11.48 + attr = { class = "area_list" }, 11.49 records = areas_selector:exec(), 11.50 columns = { 11.51 { 11.52 content = function(record) 11.53 + if record.is_member then 11.54 + local text = _"Member of area" 11.55 + ui.image{ 11.56 + attr = { title = text, alt = text, style = "vertical-align: middle;" }, 11.57 + static = "icons/16/user_gray.png", 11.58 + } 11.59 + end 11.60 + end 11.61 + }, 11.62 + { 11.63 + content = function(record) 11.64 if record.member_weight and record.direct_member_count then 11.65 local max_value = MemberCount:get() 11.66 ui.bargraph{ 11.67 @@ -70,97 +88,143 @@ 11.68 end 11.69 }, 11.70 { 11.71 - label = _"New", 11.72 - field_attr = { style = "text-align: right;" }, 11.73 + label = function() 11.74 + local title = _"New" 11.75 + ui.image{ 11.76 + attr = { title = title, alt = title }, 11.77 + static = "icons/16/new.png" 11.78 + } 11.79 + end, 11.80 + field_attr = field_attr, 11.81 + label_attr = label_attr, 11.82 content = function(record) 11.83 ui.link{ 11.84 text = tostring(record.issues_new_count), 11.85 module = "area", 11.86 view = "show", 11.87 id = record.id, 11.88 - params = { filter = "new" } 11.89 + params = { filter = "new", tab = "issues" } 11.90 } 11.91 end 11.92 }, 11.93 { 11.94 - label = _"Discussion", 11.95 - field_attr = { style = "text-align: right;" }, 11.96 + label = function() 11.97 + local title = _"Discussion" 11.98 + ui.image{ 11.99 + attr = { title = title, alt = title }, 11.100 + static = "icons/16/comments.png" 11.101 + } 11.102 + end, 11.103 + field_attr = field_attr, 11.104 + label_attr = label_attr, 11.105 content = function(record) 11.106 ui.link{ 11.107 text = tostring(record.issues_discussion_count), 11.108 module = "area", 11.109 view = "show", 11.110 id = record.id, 11.111 - params = { filter = "accepted" } 11.112 + params = { filter = "accepted", tab = "issues" } 11.113 } 11.114 end 11.115 }, 11.116 { 11.117 - label = _"Frozen", 11.118 - field_attr = { style = "text-align: right;" }, 11.119 + label = function() 11.120 + local title = _"Frozen" 11.121 + ui.image{ 11.122 + attr = { title = title, alt = title }, 11.123 + static = "icons/16/lock.png" 11.124 + } 11.125 + end, 11.126 + field_attr = field_attr, 11.127 + label_attr = label_attr, 11.128 content = function(record) 11.129 ui.link{ 11.130 text = tostring(record.issues_frozen_count), 11.131 module = "area", 11.132 view = "show", 11.133 id = record.id, 11.134 - params = { filter = "half_frozen" } 11.135 + params = { filter = "half_frozen", tab = "issues" } 11.136 } 11.137 end 11.138 }, 11.139 { 11.140 - label = _"Voting", 11.141 - field_attr = { style = "text-align: right;" }, 11.142 + label = function() 11.143 + local title = _"Voting" 11.144 + ui.image{ 11.145 + attr = { title = title, alt = title }, 11.146 + static = "icons/16/email_open.png" 11.147 + } 11.148 + end, 11.149 + field_attr = field_attr, 11.150 + label_attr = label_attr, 11.151 content = function(record) 11.152 ui.link{ 11.153 text = tostring(record.issues_voting_count), 11.154 module = "area", 11.155 view = "show", 11.156 id = record.id, 11.157 - params = { filter = "frozen" } 11.158 + params = { filter = "frozen", tab = "issues" } 11.159 } 11.160 end 11.161 }, 11.162 { 11.163 - label = _"Not yet voted", 11.164 - field_attr = { style = "text-align: right;" }, 11.165 - content = function(record) 11.166 - ui.link{ 11.167 - attr = { class = record.issues_to_vote_count > 0 and "not_voted" or nil }, 11.168 - text = tostring(record.issues_to_vote_count), 11.169 - module = "area", 11.170 - view = "show", 11.171 - id = record.id, 11.172 - params = { filter = "frozen", filter_voting = "not_voted" } 11.173 + label = function() 11.174 + local title = _"Finished" 11.175 + ui.image{ 11.176 + attr = { title = title, alt = title }, 11.177 + static = "icons/16/tick.png" 11.178 } 11.179 - end 11.180 - }, 11.181 - { 11.182 - label = _"Finished", 11.183 - field_attr = { style = "text-align: right;" }, 11.184 + end, 11.185 + field_attr = field_attr, 11.186 + label_attr = label_attr, 11.187 content = function(record) 11.188 ui.link{ 11.189 text = tostring(record.issues_finished_count), 11.190 module = "area", 11.191 view = "show", 11.192 id = record.id, 11.193 - params = { filter = "finished", issue_list = "newest" } 11.194 + params = { filter = "finished", issue_list = "newest", tab = "issues" } 11.195 } 11.196 end 11.197 }, 11.198 { 11.199 - label = _"Cancelled", 11.200 - field_attr = { style = "text-align: right;" }, 11.201 + label = function() 11.202 + local title = _"Cancelled" 11.203 + ui.image{ 11.204 + attr = { title = title, alt = title }, 11.205 + static = "icons/16/cross.png" 11.206 + } 11.207 + end, 11.208 + field_attr = field_attr, 11.209 + label_attr = label_attr, 11.210 content = function(record) 11.211 ui.link{ 11.212 text = tostring(record.issues_cancelled_count), 11.213 module = "area", 11.214 view = "show", 11.215 id = record.id, 11.216 - params = { filter = "cancelled", issue_list = "newest" } 11.217 + params = { filter = "cancelled", issue_list = "newest", tab = "issues" } 11.218 } 11.219 end 11.220 }, 11.221 + { 11.222 + content = function(record) 11.223 + if record.issues_to_vote_count > 0 then 11.224 + ui.link{ 11.225 + attr = { class = "not_voted" }, 11.226 + text = _"Not yet voted" .. ": " .. tostring(record.issues_to_vote_count), 11.227 + module = "area", 11.228 + view = "show", 11.229 + id = record.id, 11.230 + params = { 11.231 + filter = "frozen", 11.232 + filter_voting = "not_voted", 11.233 + tab = "issues" 11.234 + } 11.235 + } 11.236 + end 11.237 + end 11.238 + }, 11.239 } 11.240 } 11.241 end 11.242 @@ -175,3 +239,61 @@ 11.243 } 11.244 } 11.245 11.246 +slot.put("<br /> ") 11.247 + 11.248 + 11.249 +ui.image{ 11.250 + attr = { title = title, alt = title }, 11.251 + static = "icons/16/user_gray.png" 11.252 +} 11.253 +slot.put(" ") 11.254 +slot.put(_"Member of area") 11.255 +slot.put(" ") 11.256 + 11.257 +ui.image{ 11.258 + attr = { title = title, alt = title }, 11.259 + static = "icons/16/new.png" 11.260 +} 11.261 +slot.put(" ") 11.262 +slot.put(_"New") 11.263 +slot.put(" ") 11.264 + 11.265 +ui.image{ 11.266 + attr = { title = title, alt = title }, 11.267 + static = "icons/16/comments.png" 11.268 +} 11.269 +slot.put(" ") 11.270 +slot.put(_"Discussion") 11.271 +slot.put(" ") 11.272 + 11.273 +ui.image{ 11.274 + attr = { title = title, alt = title }, 11.275 + static = "icons/16/lock.png" 11.276 +} 11.277 +slot.put(" ") 11.278 +slot.put(_"Frozen") 11.279 +slot.put(" ") 11.280 + 11.281 +ui.image{ 11.282 + attr = { title = title, alt = title }, 11.283 + static = "icons/16/email_open.png" 11.284 +} 11.285 +slot.put(" ") 11.286 +slot.put(_"Voting") 11.287 +slot.put(" ") 11.288 + 11.289 +ui.image{ 11.290 + attr = { title = title, alt = title }, 11.291 + static = "icons/16/tick.png" 11.292 +} 11.293 +slot.put(" ") 11.294 +slot.put(_"Finished") 11.295 +slot.put(" ") 11.296 + 11.297 +ui.image{ 11.298 + attr = { title = title, alt = title }, 11.299 + static = "icons/16/cross.png" 11.300 +} 11.301 +slot.put(" ") 11.302 +slot.put(_"Cancelled") 11.303 +
12.1 --- a/app/main/area/show.lua Tue Feb 02 00:31:06 2010 +0100 12.2 +++ b/app/main/area/show.lua Sat Feb 20 22:10:31 2010 +0100 12.3 @@ -36,39 +36,104 @@ 12.4 params = { area_id = area.id } 12.5 } 12.6 12.7 -ui.tabs{ 12.8 - { 12.9 - name = "issues", 12.10 - label = _"Issues", 12.11 +--[[ 12.12 +for i, issue in ipairs(area.issues) do 12.13 + local head_name = "issue_head_content_" .. tostring(issue.id) 12.14 + local name = "issue_content_" .. tostring(issue.id) 12.15 + local icon_name = "issue_icon_" .. tostring(issue.id) 12.16 + ui.container{ 12.17 + attr = { class = "ui_tabs" }, 12.18 content = function() 12.19 - execute.view{ 12.20 - module = "issue", 12.21 - view = "_list", 12.22 - params = { issues_selector = area:get_reference_selector("issues"), for_area_list = true } 12.23 + local onclick = 12.24 + 'if (ui_tabs_active["' .. name .. '"]) {' .. 12.25 + 'el=document.getElementById("' .. name .. '");' .. 12.26 + 'el.innerHTML="";' .. 12.27 + 'el.style.display="none";' .. 12.28 + 'ui_tabs_active["' .. name .. '"]=false' .. 12.29 + '} else {' .. 12.30 + 'ui_tabs_active["' .. name .. '"]=true;' .. 12.31 + 'document.getElementById("' .. name .. '").style.display="block"; ' .. 12.32 + 'var hourglass_el = document.getElementById("' .. icon_name .. '");' .. 12.33 + 'var hourglass_src = hourglass_el.src;' .. 12.34 + 'hourglass_el.src = "' .. encode.url{ static = "icons/16/connect.png" } .. '";' .. 12.35 + 'partialMultiLoad(' .. 12.36 + '{ trace: "trace", system_error: "system_error", ' .. name .. '_title: "title", ' .. name .. '_actions: "actions", ' .. name .. '_content: "default" },' .. 12.37 + '{},' .. 12.38 + '"error",' .. 12.39 + '"' .. request.get_relative_baseurl() .. 'issue/show/' .. tostring(issue.id) .. '.html?&_webmcp_json_slots[]=title&_webmcp_json_slots[]=actions&_webmcp_json_slots[]=default&_webmcp_json_slots[]=trace&_webmcp_json_slots[]=system_error&dyn=1",' .. 12.40 + '{},' .. 12.41 + '{},' .. 12.42 + 'function() {' .. 12.43 + 'hourglass_el.src = hourglass_src;' .. 12.44 + '},' .. 12.45 + 'function() {' .. 12.46 + 'hourglass_el.src = hourglass_src;' .. 12.47 + '}' .. 12.48 + '); ' .. 12.49 + '}' .. 12.50 + 'return(false);' 12.51 + ui.link{ 12.52 + attr = { 12.53 + name = name, 12.54 + class = "ui_tabs_accordeon_head", 12.55 + id = head_name, 12.56 + onclick = onclick, 12.57 + }, 12.58 + module = "issue", 12.59 + view = "show", 12.60 + id = issue.id, 12.61 + params = params, 12.62 + anchor = name, 12.63 + content = function() 12.64 + ui.image{ 12.65 + attr = { id = icon_name }, 12.66 + static = "icons/16/script.png" 12.67 + } 12.68 + ui.container{ 12.69 + attr = { style = "float: right;" }, 12.70 + content = function() 12.71 + 12.72 + end 12.73 + } 12.74 + slot.put(tostring(issue.id)) 12.75 + end 12.76 } 12.77 end 12.78 - }, 12.79 - { 12.80 - name = "members", 12.81 - label = _"Members", 12.82 + } 12.83 + 12.84 + ui.container{ 12.85 + attr = { 12.86 + id = name, 12.87 + class = "ui_tabs_accordeon_content", 12.88 + }, 12.89 content = function() 12.90 - execute.view{ 12.91 - module = "member", 12.92 - view = "_list", 12.93 - params = { members_selector = area:get_reference_selector("members") } 12.94 - } 12.95 + ui.container{ attr = { id = name .. "_title", }, content = function() slot.put(" ") end } 12.96 + ui.container{ attr = { id = name .. "_actions", }, content = function() slot.put(" ") end } 12.97 + ui.container{ attr = { id = name .. "_content", }, content = function() 12.98 + execute.view{ 12.99 + module = "initiative", 12.100 + view = "_list", 12.101 + params = { 12.102 + issue = issue, 12.103 + initiatives_selector = issue:get_reference_selector("initiatives"), 12.104 + limit = 3, 12.105 + per_page = 3, 12.106 + no_sort = true, 12.107 + } 12.108 + } 12.109 + end } 12.110 end 12.111 - }, 12.112 - { 12.113 - name = "delegations", 12.114 - label = _"Delegations", 12.115 - content = function() 12.116 - execute.view{ 12.117 - module = "delegation", 12.118 - view = "_list", 12.119 - params = { delegations_selector = area:get_reference_selector("delegations") } 12.120 - } 12.121 - end 12.122 - }, 12.123 + } 12.124 + 12.125 + if config.user_tab_mode == "accordeon_all_expanded" then 12.126 + ui.script{ script = 'document.getElementById("' .. head_name .. '").onclick();' } 12.127 + end 12.128 +end 12.129 +--]] 12.130 + 12.131 +execute.view{ 12.132 + module = "area", 12.133 + view = "show_tab", 12.134 + params = { area = area } 12.135 } 12.136
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/app/main/area/show_tab.lua Sat Feb 20 22:10:31 2010 +0100 13.3 @@ -0,0 +1,40 @@ 13.4 +local area = param.get("area", "table") or Area:by_id(param.get("area_id", atom.integer)) 13.5 + 13.6 +local issues_selector = area:get_reference_selector("issues") 13.7 +local members_selector = area:get_reference_selector("members") 13.8 +local delegations_selector = area:get_reference_selector("delegations") 13.9 + 13.10 +ui.tabs{ 13.11 + module = "area", 13.12 + view = "show_tab", 13.13 + static_params = { area_id = area.id }, 13.14 + { 13.15 + name = "issues", 13.16 + label = _"Issues" .. " (" .. tostring(issues_selector:count()) .. ")", 13.17 + icon = { static = "icons/16/folder.png" }, 13.18 + module = "issue", 13.19 + view = "_list", 13.20 + params = { 13.21 + issues_selector = issues_selector, 13.22 + filter = cgi.params["filter"], 13.23 + filter_voting = param.get("filter_voting") 13.24 + } 13.25 + }, 13.26 + { 13.27 + name = "members", 13.28 + label = _"Members" .. " (" .. tostring(members_selector:count()) .. ")", 13.29 + icon = { static = "icons/16/group.png" }, 13.30 + module = "member", 13.31 + view = "_list", 13.32 + params = { members_selector = members_selector } 13.33 + }, 13.34 + { 13.35 + name = "delegations", 13.36 + label = _"Delegations" .. " (" .. tostring(delegations_selector:count()) .. ")", 13.37 + icon = { static = "icons/16/table_go.png" }, 13.38 + module = "delegation", 13.39 + view = "_list", 13.40 + params = { delegations_selector = delegations_selector } 13.41 + }, 13.42 +} 13.43 +
14.1 --- a/app/main/delegation/_show_box.lua Tue Feb 02 00:31:06 2010 +0100 14.2 +++ b/app/main/delegation/_show_box.lua Sat Feb 20 22:10:31 2010 +0100 14.3 @@ -1,43 +1,106 @@ 14.4 -slot.select("actions", function() 14.5 - 14.6 - local delegation 14.7 - local area_id 14.8 - local issue_id 14.9 - 14.10 - local scope = "global" 14.11 +function change_delegation(scope, area_id, issue, delegation) 14.12 + local image 14.13 + local text 14.14 + if scope == "global" and delegation then 14.15 + image = { static = "icons/16/table_go.png" } 14.16 + text = _"Change global delegation" 14.17 + elseif scope == "global" and not delegation then 14.18 + image = { static = "icons/16/table_go.png" } 14.19 + text = _"Set global delegation" 14.20 + elseif scope == "area" and delegation and delegation.area_id then 14.21 + image = { static = "icons/16/table_go.png" } 14.22 + text = _"Change area delegation" 14.23 + elseif scope == "area" and not (delegation and delegation.area_id) then 14.24 + image = { static = "icons/16/table_go.png" } 14.25 + text = _"Set area delegation" 14.26 + elseif scope == "issue" then 14.27 + if delegation and delegation.issue_id then 14.28 + image = { static = "icons/16/table_go.png" } 14.29 + text = _"Change issue delegation" 14.30 + elseif issue.state ~= "finished" and issue.state ~= "cancelled" then 14.31 + image = { static = "icons/16/table_go.png" } 14.32 + text = _"Set issue delegation" 14.33 + end 14.34 + end 14.35 + ui.container{ 14.36 + attr = { 14.37 + class = "change_delegation", 14.38 + }, 14.39 + content = function() 14.40 + ui.link{ 14.41 + image = image, 14.42 + text = text, 14.43 + module = "delegation", 14.44 + view = "new", 14.45 + params = { 14.46 + issue_id = issue and issue.id or nil, 14.47 + area_id = area_id 14.48 + }, 14.49 + } 14.50 + if delegation then 14.51 + ui.link{ 14.52 + image = { static = "icons/16/delete.png" }, 14.53 + text = _"Revoke", 14.54 + module = "delegation", 14.55 + action = "update", 14.56 + params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true }, 14.57 + routing = { 14.58 + default = { 14.59 + mode = "redirect", 14.60 + module = request.get_module(), 14.61 + view = request.get_view(), 14.62 + id = param.get_id_cgi(), 14.63 + params = param.get_all_cgi() 14.64 + } 14.65 + } 14.66 + } 14.67 + end 14.68 + end 14.69 + } 14.70 +end 14.71 14.72 - if param.get("initiative_id", atom.integer) then 14.73 - issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id 14.74 - scope = "issue" 14.75 - end 14.76 +local delegation 14.77 +local area_id 14.78 +local issue_id 14.79 + 14.80 +local scope = "global" 14.81 14.82 - if param.get("issue_id", atom.integer) then 14.83 - issue_id = param.get("issue_id", atom.integer) 14.84 - scope = "issue" 14.85 - end 14.86 +if param.get("initiative_id", atom.integer) then 14.87 + issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id 14.88 + scope = "issue" 14.89 +end 14.90 14.91 - if param.get("area_id", atom.integer) then 14.92 - area_id = param.get("area_id", atom.integer) 14.93 - scope = "area" 14.94 - end 14.95 +if param.get("issue_id", atom.integer) then 14.96 + issue_id = param.get("issue_id", atom.integer) 14.97 + scope = "issue" 14.98 +end 14.99 + 14.100 +if param.get("area_id", atom.integer) then 14.101 + area_id = param.get("area_id", atom.integer) 14.102 + scope = "area" 14.103 +end 14.104 14.105 14.106 14.107 - local delegation 14.108 - local issue 14.109 - if issue_id then 14.110 - issue = Issue:by_id(issue_id) 14.111 - delegation = Delegation:by_pk(app.session.member.id, nil, issue_id) 14.112 - if not delegation then 14.113 - delegation = Delegation:by_pk(app.session.member.id, issue.area_id) 14.114 - end 14.115 - elseif area_id then 14.116 - delegation = Delegation:by_pk(app.session.member.id, area_id) 14.117 +local delegation 14.118 +local issue 14.119 +if issue_id then 14.120 + issue = Issue:by_id(issue_id) 14.121 + delegation = Delegation:by_pk(app.session.member.id, nil, issue_id) 14.122 + if not delegation then 14.123 + delegation = Delegation:by_pk(app.session.member.id, issue.area_id) 14.124 end 14.125 +elseif area_id then 14.126 + delegation = Delegation:by_pk(app.session.member.id, area_id) 14.127 +end 14.128 14.129 - if not delegation then 14.130 - delegation = Delegation:by_pk(app.session.member.id) 14.131 - end 14.132 +if not delegation then 14.133 + delegation = Delegation:by_pk(app.session.member.id) 14.134 +end 14.135 + 14.136 + 14.137 +slot.select("actions", function() 14.138 + 14.139 if delegation then 14.140 ui.container{ 14.141 attr = { class = "delegation vote_info"}, 14.142 @@ -85,6 +148,10 @@ 14.143 :add_order_by("index") 14.144 :exec() 14.145 14.146 + if not issue or (issue.state ~= "finished" and issue.state ~= "cancelled") then 14.147 + change_delegation(scope, area_id, issue, delegation) 14.148 + end 14.149 + 14.150 for i, record in ipairs(delegation_chain) do 14.151 local style 14.152 local overridden = record.overridden 14.153 @@ -115,29 +182,6 @@ 14.154 end 14.155 end 14.156 } 14.157 - if i == 2 then 14.158 - if not issue or (issue.state ~= "finished" and issue.state ~= "cancelled") then 14.159 - ui.link{ 14.160 - attr = { class = "revoke" }, 14.161 - content = function() 14.162 - ui.image{ static = "icons/16/delete.png" } 14.163 - slot.put(_"Revoke") 14.164 - end, 14.165 - module = "delegation", 14.166 - action = "update", 14.167 - params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true }, 14.168 - routing = { 14.169 - default = { 14.170 - mode = "redirect", 14.171 - module = request.get_module(), 14.172 - view = request.get_view(), 14.173 - id = param.get_id_cgi(), 14.174 - params = param.get_all_cgi() 14.175 - } 14.176 - } 14.177 - } 14.178 - end 14.179 - end 14.180 end 14.181 } 14.182 end 14.183 @@ -155,7 +199,7 @@ 14.184 ui.container{ 14.185 attr = { class = "delegation_participation" }, 14.186 content = function() 14.187 - slot.put("<br /><br />-----> Participation<br />") 14.188 + slot.put(_"This member is participating, the rest of delegation chain is suspended while discussing") 14.189 end 14.190 } 14.191 end 14.192 @@ -165,38 +209,7 @@ 14.193 } 14.194 end 14.195 } 14.196 - 14.197 - 14.198 + else 14.199 + change_delegation(scope, area_id, issue) 14.200 end 14.201 - ui.link{ 14.202 - content = function() 14.203 - if scope == "global" and delegation then 14.204 - ui.image{ static = "icons/16/table_go.png" } 14.205 - slot.put(_"Change global delegation") 14.206 - elseif scope == "global" and not delegation then 14.207 - ui.image{ static = "icons/16/table_go.png" } 14.208 - slot.put(_"Set global delegation") 14.209 - elseif scope == "area" and delegation and delegation.area_id then 14.210 - ui.image{ static = "icons/16/table_go.png" } 14.211 - slot.put(_"Change area delegation") 14.212 - elseif scope == "area" and not (delegation and delegation.area_id) then 14.213 - ui.image{ static = "icons/16/table_go.png" } 14.214 - slot.put(_"Set area delegation") 14.215 - elseif scope == "issue" then 14.216 - if delegation and delegation.issue_id then 14.217 - ui.image{ static = "icons/16/table_go.png" } 14.218 - slot.put(_"Change issue delegation") 14.219 - elseif issue.state ~= "finished" and issue.state ~= "cancelled" then 14.220 - ui.image{ static = "icons/16/table_go.png" } 14.221 - slot.put(_"Set issue delegation") 14.222 - end 14.223 - end 14.224 - end, 14.225 - module = "delegation", 14.226 - view = "new", 14.227 - params = { 14.228 - area_id = area_id, 14.229 - issue_id = issue_id 14.230 - } 14.231 - } 14.232 end)
15.1 --- a/app/main/draft/_show.lua Tue Feb 02 00:31:06 2010 +0100 15.2 +++ b/app/main/draft/_show.lua Sat Feb 20 22:10:31 2010 +0100 15.3 @@ -6,8 +6,15 @@ 15.4 readonly = true, 15.5 content = function() 15.6 15.7 - ui.field.text{ label = _"Last author", name = "author_name" } 15.8 - ui.field.timestamp{ label = _"Created at", name = "created" } 15.9 + ui.field.text{ 15.10 + label = _"Last author", 15.11 + value = _( 15.12 + "#{author} at #{date}", { 15.13 + author = draft.author_name, 15.14 + date = format.timestamp(draft.created) 15.15 + } 15.16 + ) 15.17 + } 15.18 ui.container{ 15.19 attr = { class = "draft_content wiki" }, 15.20 content = function()
16.1 --- a/app/main/index/about.lua Tue Feb 02 00:31:06 2010 +0100 16.2 +++ b/app/main/index/about.lua Sat Feb 20 22:10:31 2010 +0100 16.3 @@ -1,5 +1,18 @@ 16.4 slot.put_into("title", encode.html(_"About LiquidFeedback")) 16.5 16.6 +if app.session.member_id then 16.7 + slot.select("actions", function() 16.8 + ui.link{ 16.9 + module = "index", 16.10 + view = "usage_terms", 16.11 + content = function() 16.12 + ui.image{ static = "icons/16/script.png" } 16.13 + slot.put(_"Terms of use") 16.14 + end 16.15 + } 16.16 + end) 16.17 +end 16.18 + 16.19 16.20 slot.put("<br />") 16.21 ui.field.text{ attr = { style = "font-weight: bold;" }, value = "Diensteanbieter:" }
17.1 --- a/app/main/index/index.lua Tue Feb 02 00:31:06 2010 +0100 17.2 +++ b/app/main/index/index.lua Sat Feb 20 22:10:31 2010 +0100 17.3 @@ -23,6 +23,7 @@ 17.4 attr = { style = "margin-left: 0.5em;", alt = lang } 17.5 } 17.6 end, 17.7 + text = _('Select language "#{langcode}"', { langcode = lang }), 17.8 module = "index", 17.9 action = "set_lang", 17.10 params = { lang = lang },
18.1 --- a/app/main/index/login.lua Tue Feb 02 00:31:06 2010 +0100 18.2 +++ b/app/main/index/login.lua Sat Feb 20 22:10:31 2010 +0100 18.3 @@ -24,6 +24,7 @@ 18.4 attr = { style = "margin-left: 0.5em;", alt = lang } 18.5 } 18.6 end, 18.7 + text = _('Select language "#{langcode}"', { langcode = lang }), 18.8 module = "index", 18.9 action = "set_lang", 18.10 params = { lang = lang },
19.1 --- a/app/main/index/search.lua Tue Feb 02 00:31:06 2010 +0100 19.2 +++ b/app/main/index/search.lua Sat Feb 20 22:10:31 2010 +0100 19.3 @@ -1,44 +1,41 @@ 19.4 -local search_for = param.get("search_for", atom.string) 19.5 +local search_for = param.get("search_for", atom.string) or "global" 19.6 local search_string = param.get("search", atom.string) 19.7 19.8 -search_for = search_for or "global" 19.9 - 19.10 slot.put_into("title", _("Search results for: '#{search}'", { search = search_string })) 19.11 19.12 + 19.13 if search_for == "global" or search_for == "member" then 19.14 - members_selector = Member:get_search_selector(search_string) 19.15 ---if #members > 0 then 19.16 + local members_selector = Member:get_search_selector(search_string) 19.17 ui.heading{ content = _"Members" } 19.18 execute.view{ 19.19 module = "member", 19.20 view = "_list", 19.21 params = { members_selector = members_selector }, 19.22 } 19.23 ---end 19.24 end 19.25 19.26 -if search_for == "global" or search_for == "issue" then 19.27 - issues_selector = Issue:get_search_selector(search_string) 19.28 ---if #issues > 0 then 19.29 - ui.heading{ content = _"Issues" } 19.30 - execute.view{ 19.31 - module = "issue", 19.32 - view = "_list", 19.33 - params = { issues_selector = issues_selector, highlight_string = search_string }, 19.34 - } 19.35 ---end 19.36 -end 19.37 - 19.38 -if search_for == "initiative" then 19.39 - initiatives_selector = Initiative:get_search_selector(search_string) 19.40 ---if #initiatives > 0 then 19.41 +if search_for == "global" or search_for == "initiative" then 19.42 + local initiatives_selector = Initiative:get_search_selector(search_string) 19.43 ui.heading{ content = _"Initiatives" } 19.44 execute.view{ 19.45 module = "initiative", 19.46 view = "_list", 19.47 params = { initiatives_selector = initiatives_selector }, 19.48 } 19.49 ---end 19.50 +end 19.51 + 19.52 +if search_for == "issue" then 19.53 + local issues_selector = Issue:get_search_selector(search_string) 19.54 + ui.heading{ content = _"Issues" } 19.55 + execute.view{ 19.56 + module = "issue", 19.57 + view = "_list", 19.58 + params = { 19.59 + issues_selector = issues_selector, 19.60 + highlight_string = search_string, 19.61 + no_filter = true 19.62 + }, 19.63 + } 19.64 end 19.65 19.66
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/app/main/index/usage_terms.lua Sat Feb 20 22:10:31 2010 +0100 20.3 @@ -0,0 +1,17 @@ 20.4 +slot.select("actions", function() 20.5 + ui.link{ 20.6 + module = "index", 20.7 + view = "about", 20.8 + content = function() 20.9 + ui.image{ static = "icons/16/cancel.png" } 20.10 + slot.put(_"Back") 20.11 + end 20.12 + } 20.13 +end) 20.14 + 20.15 +ui.container{ 20.16 + attr = { class = "wiki use_terms" }, 20.17 + content = function() 20.18 + slot.put(format.wiki_text(config.use_terms)) 20.19 + end 20.20 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/app/main/initiative/_current_draft.lua Sat Feb 20 22:10:31 2010 +0100 21.3 @@ -0,0 +1,16 @@ 21.4 +local initiator = param.get("initiator", "table") 21.5 +local initiative = param.get("initiative", "table") 21.6 + 21.7 +if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 21.8 + ui.link{ 21.9 + attr = { style = "float: right;" }, 21.10 + content = function() 21.11 + ui.image{ static = "icons/16/script_add.png" } 21.12 + slot.put(_"Edit draft") 21.13 + end, 21.14 + module = "draft", 21.15 + view = "new", 21.16 + params = { initiative_id = initiative.id } 21.17 + } 21.18 +end 21.19 +execute.view{ module = "draft", view = "_show", params = { draft = initiative.current_draft } }
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/app/main/initiative/_details.lua Sat Feb 20 22:10:31 2010 +0100 22.3 @@ -0,0 +1,20 @@ 22.4 +local initiative = param.get("initiative", "table") 22.5 + 22.6 +ui.form{ 22.7 + attr = { class = "vertical" }, 22.8 + record = initiative, 22.9 + readonly = true, 22.10 + content = function() 22.11 + ui.field.text{ label = _"Issue policy", value = initiative.issue.policy.name } 22.12 + ui.field.text{ 22.13 + label = _"Created at", 22.14 + value = tostring(initiative.created) 22.15 + } 22.16 + ui.field.text{ 22.17 + label = _"Created at", 22.18 + value = format.timestamp(initiative.created) 22.19 + } 22.20 + -- ui.field.date{ label = _"Revoked at", name = "revoked" } 22.21 + ui.field.boolean{ label = _"Admitted", name = "admitted" } 22.22 + end 22.23 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/app/main/initiative/_initiators.lua Sat Feb 20 22:10:31 2010 +0100 23.3 @@ -0,0 +1,58 @@ 23.4 +local initiative = param.get("initiative", "table") 23.5 +local initiator = param.get("initiator", "table") 23.6 +local initiators_members_selector = param.get("initiators_members_selector", "table") 23.7 + 23.8 +local initiator_count = initiators_members_selector:count() 23.9 + 23.10 +if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 23.11 + ui.link{ 23.12 + attr = { class = "action" }, 23.13 + content = function() 23.14 + ui.image{ static = "icons/16/user_add.png" } 23.15 + slot.put(_"Invite initiator") 23.16 + end, 23.17 + module = "initiative", 23.18 + view = "add_initiator", 23.19 + params = { initiative_id = initiative.id } 23.20 + } 23.21 + if initiator_count > 1 then 23.22 + ui.link{ 23.23 + content = function() 23.24 + ui.image{ static = "icons/16/user_delete.png" } 23.25 + slot.put(_"Remove initiator") 23.26 + end, 23.27 + module = "initiative", 23.28 + view = "remove_initiator", 23.29 + params = { initiative_id = initiative.id } 23.30 + } 23.31 + end 23.32 +end 23.33 +if initiator and initiator.accepted == false then 23.34 + ui.link{ 23.35 + image = { static = "icons/16/user_delete.png" }, 23.36 + text = _"Cancel refuse of invitation", 23.37 + module = "initiative", 23.38 + action = "remove_initiator", 23.39 + params = { 23.40 + initiative_id = initiative.id, 23.41 + member_id = app.session.member.id 23.42 + }, 23.43 + routing = { 23.44 + ok = { 23.45 + mode = "redirect", 23.46 + module = "initiative", 23.47 + view = "show", 23.48 + id = initiative.id 23.49 + } 23.50 + } 23.51 + } 23.52 +end 23.53 + 23.54 +execute.view{ 23.55 + module = "member", 23.56 + view = "_list", 23.57 + params = { 23.58 + members_selector = initiators_members_selector, 23.59 + initiator = initiator 23.60 + } 23.61 +}
24.1 --- a/app/main/initiative/_list.lua Tue Feb 02 00:31:06 2010 +0100 24.2 +++ b/app/main/initiative/_list.lua Sat Feb 20 22:10:31 2010 +0100 24.3 @@ -1,71 +1,10 @@ 24.4 -local initiatives_selector = param.get("initiatives_selector", "table") 24.5 -initiatives_selector:join("issue", nil, "issue.id = initiative.issue_id") 24.6 - 24.7 -local limit = param.get("limit", atom.number) 24.8 - 24.9 -local more_initiatives_count 24.10 -if limit then 24.11 - local initiatives_count = initiatives_selector:count() 24.12 - if initiatives_count > limit then 24.13 - more_initiatives_count = initiatives_count - limit 24.14 - end 24.15 - initiatives_selector:limit(limit) 24.16 -end 24.17 - 24.18 +ui.script{ script = "lf_initiative_expanded = {};" } 24.19 24.20 local issue = param.get("issue", "table") 24.21 24.22 -local order_options = {} 24.23 - 24.24 -if issue and issue.ranks_available then 24.25 - order_options[#order_options+1] = { 24.26 - name = "rank", 24.27 - label = _"Rank", 24.28 - order_by = "initiative.rank, initiative.admitted DESC, vote_ratio(initiative.positive_votes, initiative.negative_votes) DESC, initiative.id" 24.29 - } 24.30 -end 24.31 - 24.32 -order_options[#order_options+1] = { 24.33 - name = "potential_support", 24.34 - label = _"Potential support", 24.35 - order_by = "initiative.supporter_count::float / issue.population::float DESC, initiative.id" 24.36 -} 24.37 - 24.38 -order_options[#order_options+1] = { 24.39 - name = "support", 24.40 - label = _"Support", 24.41 - order_by = "initiative.satisfied_supporter_count::float / issue.population::float DESC, initiative.id" 24.42 -} 24.43 - 24.44 -order_options[#order_options+1] = { 24.45 - name = "newest", 24.46 - label = _"Newest", 24.47 - order_by = "initiative.created DESC, initiative.id" 24.48 -} 24.49 - 24.50 -order_options[#order_options+1] = { 24.51 - name = "oldest", 24.52 - label = _"Oldest", 24.53 - order_by = "initiative.created, initiative.id" 24.54 -} 24.55 - 24.56 -local name = "initiative_list" 24.57 -if issue then 24.58 - name = "issue_" .. tostring(issue.id) .. "_initiative_list" 24.59 -end 24.60 - 24.61 -ui_order = ui.order 24.62 - 24.63 -if param.get("no_sort", atom.boolean) then 24.64 - ui_order = function(args) args.content() end 24.65 - if issue.ranks_available then 24.66 - initiatives_selector:add_order_by("initiative.rank, initiative.admitted DESC, vote_ratio(initiative.positive_votes, initiative.negative_votes) DESC, initiative.id") 24.67 - else 24.68 - initiatives_selector:add_order_by("initiative.supporter_count::float / issue.population::float DESC, initiative.id") 24.69 - end 24.70 -end 24.71 - 24.72 +local initiatives_selector = param.get("initiatives_selector", "table") 24.73 initiatives_selector 24.74 + :join("issue", nil, "issue.id = initiative.issue_id") 24.75 :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ?", app.session.member.id} ) 24.76 :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", app.session.member.id} ) 24.77 24.78 @@ -73,128 +12,213 @@ 24.79 :add_field({"(_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT 1 FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)))", app.session.member.id }, "is_supporter") 24.80 :add_field({"EXISTS(SELECT 1 FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)))", app.session.member.id }, "is_potential_supporter") 24.81 24.82 +local initiatives_count = initiatives_selector:count() 24.83 24.84 -ui_order{ 24.85 - name = name, 24.86 - selector = initiatives_selector, 24.87 - options = order_options, 24.88 - content = function() 24.89 - ui.paginate{ 24.90 - name = issue and "issue_" .. tostring(issue.id) .. "_page" or nil, 24.91 - selector = initiatives_selector, 24.92 - per_page = param.get("per_page", atom.number), 24.93 +local limit = param.get("limit", atom.number) 24.94 +local no_sort = param.get("no_sort", atom.boolean) 24.95 + 24.96 +local show_for_issue = param.get("show_for_issue", atom.boolean) 24.97 + 24.98 +local show_for_initiative 24.99 + 24.100 +local show_for_initiative_id = param.get("for_initiative_id", atom.number) 24.101 + 24.102 +if show_for_initiative_id then 24.103 + show_for_initiative = Initiative:by_id(show_for_initiative_id) 24.104 + 24.105 +elseif not show_for_initiative_id and show_for_issue and issue and issue.ranks_available then 24.106 + winning_initiative = Initiative:new_selector() 24.107 + :add_where{ "issue_id = ?", issue.id } 24.108 + :add_where("rank = 1") 24.109 + :single_object_mode() 24.110 + :exec() 24.111 + if winning_initiative then 24.112 + show_for_initiative = winning_initiative 24.113 + ui.container{ 24.114 + attr = { class = "admitted_info" }, 24.115 + content = _"This issue has been finished with the following winning initiative:" 24.116 + } 24.117 + else 24.118 + ui.container{ 24.119 + attr = { class = "not_admitted_info" }, 24.120 + content = _"This issue has been finished without any winning initiative." 24.121 + } 24.122 + end 24.123 +end 24.124 + 24.125 + 24.126 +if show_for_initiative then 24.127 + ui.script{ script = "lf_initiative_expanded['initiative_content_" .. tostring(show_for_initiative.id) .. "'] = true;" } 24.128 + initiatives_selector:add_where{ "initiative.id != ?", show_for_initiative.id } 24.129 + 24.130 + execute.view{ 24.131 + module = "initiative", 24.132 + view = "_list_element", 24.133 + params = { 24.134 + initiative = show_for_initiative, 24.135 + expanded = true, 24.136 + expandable = true 24.137 + } 24.138 + } 24.139 + if show_for_issue then 24.140 + slot.put("<br />") 24.141 + ui.container{ 24.142 + attr = { style = "font-weight: bold;" }, 24.143 content = function() 24.144 - local initiatives = initiatives_selector:exec() 24.145 - local columns = {} 24.146 - columns[#columns+1] = { 24.147 - content = function(record) 24.148 - if record.issue.accepted and record.issue.closed and record.issue.ranks_available then 24.149 - ui.field.rank{ attr = { class = "rank" }, value = record.rank } 24.150 - end 24.151 - end 24.152 - } 24.153 - columns[#columns+1] = { 24.154 - content = function(record) 24.155 - if record.issue.accepted and record.issue.closed then 24.156 - if record.issue.ranks_available then 24.157 - if record.negative_votes and record.positive_votes then 24.158 - local max_value = record.issue.voter_count 24.159 - ui.bargraph{ 24.160 - max_value = max_value, 24.161 - width = 100, 24.162 - bars = { 24.163 - { color = "#0a0", value = record.positive_votes }, 24.164 - { color = "#aaa", value = max_value - record.negative_votes - record.positive_votes }, 24.165 - { color = "#a00", value = record.negative_votes }, 24.166 - } 24.167 - } 24.168 - end 24.169 - else 24.170 - slot.put(_"Counting of votes") 24.171 - end 24.172 - else 24.173 - local max_value = (record.issue.population or 0) 24.174 - ui.bargraph{ 24.175 - max_value = max_value, 24.176 - width = 100, 24.177 - bars = { 24.178 - { color = "#0a0", value = (record.satisfied_supporter_count or 0) }, 24.179 - { color = "#777", value = (record.supporter_count or 0) - (record.satisfied_supporter_count or 0) }, 24.180 - { color = "#ddd", value = max_value - (record.supporter_count or 0) }, 24.181 - } 24.182 - } 24.183 - end 24.184 - end 24.185 - } 24.186 - columns[#columns+1] = { 24.187 - content = function(record) 24.188 - local link_class 24.189 - if record.revoked then 24.190 - link_class = "revoked" 24.191 - end 24.192 - ui.link{ 24.193 - attr = { class = link_class }, 24.194 - content = function() 24.195 - local name 24.196 - if record.name_highlighted then 24.197 - name = encode.highlight(record.name_highlighted) 24.198 - else 24.199 - name = encode.html(record.name) 24.200 - end 24.201 - slot.put(name) 24.202 - end, 24.203 - module = "initiative", 24.204 - view = "show", 24.205 - id = record.id 24.206 - } 24.207 - if record.issue.state == "new" then 24.208 - ui.image{ 24.209 - static = "icons/16/new.png" 24.210 - } 24.211 - end 24.212 - if record.is_supporter then 24.213 - slot.put(" ") 24.214 - local label = _"You are supporting this initiative" 24.215 - ui.image{ 24.216 - attr = { alt = label, title = label }, 24.217 - static = "icons/16/thumb_up_green.png" 24.218 - } 24.219 - end 24.220 - if record.is_potential_supporter then 24.221 - slot.put(" ") 24.222 - local label = _"You are potential supporter of this initiative" 24.223 - ui.image{ 24.224 - attr = { alt = label, title = label }, 24.225 - static = "icons/16/thumb_up.png" 24.226 - } 24.227 - end 24.228 - if record.is_initiator then 24.229 - slot.put(" ") 24.230 - local label = _"You are iniator of this initiative" 24.231 - ui.image{ 24.232 - attr = { alt = label, title = label }, 24.233 - static = "icons/16/user_edit.png" 24.234 - } 24.235 - end 24.236 - end 24.237 - } 24.238 - 24.239 - ui.list{ 24.240 - attr = { class = "initiatives" }, 24.241 - records = initiatives, 24.242 - columns = columns 24.243 - } 24.244 + slot.put(_"Alternative initiatives") 24.245 end 24.246 } 24.247 end 24.248 -} 24.249 - 24.250 -if more_initiatives_count then 24.251 - ui.link{ 24.252 - attr = { style = "font-size: 75%; font-style: italic;" }, 24.253 - content = _("#{count} more initiatives", { count = more_initiatives_count }), 24.254 - module = "issue", 24.255 - view = "show", 24.256 - id = issue.id, 24.257 +elseif show_for_issue then 24.258 + ui.container{ 24.259 + attr = { style = "font-weight: bold;" }, 24.260 + content = function() 24.261 + slot.put(_"Alternative initiatives") 24.262 + end 24.263 } 24.264 end 24.265 + 24.266 +if not show_for_initiative or initiatives_count > 1 then 24.267 + 24.268 + 24.269 + local more_initiatives_count 24.270 + if limit then 24.271 + limit = limit - (show_for_initiative and 1 or 0) 24.272 + if initiatives_count > limit then 24.273 + more_initiatives_count = initiatives_count - limit 24.274 + end 24.275 + initiatives_selector:limit(limit) 24.276 + end 24.277 + 24.278 + local expandable = param.get("expandable", atom.boolean) 24.279 + 24.280 + local issue = param.get("issue", "table") 24.281 + 24.282 + local name = "initiative_list" 24.283 + if issue then 24.284 + name = "issue_" .. tostring(issue.id) .. "_initiative_list" 24.285 + end 24.286 + 24.287 + ui.add_partial_param_names{ name } 24.288 + 24.289 + local order_filter = { 24.290 + name = name, 24.291 + label = _"Order by" 24.292 + } 24.293 + 24.294 + if issue and issue.ranks_available then 24.295 + order_filter[#order_filter+1] = { 24.296 + name = "rank", 24.297 + label = _"Rank", 24.298 + selector_modifier = function(selector) selector:add_order_by("initiative.rank, initiative.admitted DESC, vote_ratio(initiative.positive_votes, initiative.negative_votes) DESC, initiative.id") end 24.299 + } 24.300 + end 24.301 + 24.302 + order_filter[#order_filter+1] = { 24.303 + name = "potential_support", 24.304 + label = _"Potential support", 24.305 + selector_modifier = function(selector) selector:add_order_by("initiative.supporter_count::float / issue.population::float DESC, initiative.id") end 24.306 + } 24.307 + 24.308 + order_filter[#order_filter+1] = { 24.309 + name = "support", 24.310 + label = _"Support", 24.311 + selector_modifier = function(selector) selector:add_order_by("initiative.satisfied_supporter_count::float / issue.population::float DESC, initiative.id") end 24.312 + } 24.313 + 24.314 + order_filter[#order_filter+1] = { 24.315 + name = "newest", 24.316 + label = _"Newest", 24.317 + selector_modifier = function(selector) selector:add_order_by("initiative.created DESC, initiative.id") end 24.318 + } 24.319 + 24.320 + order_filter[#order_filter+1] = { 24.321 + name = "oldest", 24.322 + label = _"Oldest", 24.323 + selector_modifier = function(selector) selector:add_order_by("initiative.created, initiative.id") end 24.324 + } 24.325 + 24.326 + ui_filters = ui.filters 24.327 + 24.328 + if no_sort then 24.329 + ui_filters = function(args) args.content() end 24.330 + if issue.ranks_available then 24.331 + initiatives_selector:add_order_by("initiative.rank, initiative.admitted DESC, vote_ratio(initiative.positive_votes, initiative.negative_votes) DESC, initiative.id") 24.332 + else 24.333 + initiatives_selector:add_order_by("initiative.supporter_count::float / issue.population::float DESC, initiative.id") 24.334 + end 24.335 + end 24.336 + 24.337 + ui_filters{ 24.338 + label = _"Change order", 24.339 + order_filter, 24.340 + selector = initiatives_selector, 24.341 + content = function() 24.342 + ui.paginate{ 24.343 + name = issue and "issue_" .. tostring(issue.id) .. "_page" or nil, 24.344 + selector = initiatives_selector, 24.345 + per_page = param.get("per_page", atom.number), 24.346 + content = function() 24.347 + local initiatives = initiatives_selector:exec() 24.348 + for i, initiative in ipairs(initiatives) do 24.349 + local expanded = config.user_tab_mode == "accordeon_all_expanded" and expandable or 24.350 + show_for_initiative and initiative.id == show_for_initiative.id 24.351 + if expanded then 24.352 + ui.script{ script = "lf_initiative_expanded['initiative_content_" .. tostring(initiative.id) .. "'] = true;" } 24.353 + end 24.354 + execute.view{ 24.355 + module = "initiative", 24.356 + view = "_list_element", 24.357 + params = { 24.358 + initiative = initiative, 24.359 + expanded = expanded, 24.360 + expandable = expandable 24.361 + } 24.362 + } 24.363 + end 24.364 + end 24.365 + } 24.366 + end 24.367 + } 24.368 + 24.369 + if more_initiatives_count then 24.370 + ui.link{ 24.371 + attr = { style = "font-size: 75%; font-style: italic;" }, 24.372 + content = _("and #{count} more initiatives", { count = more_initiatives_count }), 24.373 + module = "issue", 24.374 + view = "show", 24.375 + id = issue.id, 24.376 + } 24.377 + end 24.378 + 24.379 +end 24.380 + 24.381 +if show_for_issue then 24.382 + slot.put("<br />") 24.383 + 24.384 + if issue and initiatives_count == 1 then 24.385 + ui.container{ 24.386 + content = function() 24.387 + if issue.fully_frozen or issue.closed then 24.388 + slot.put(_"There were no more alternative initiatives.") 24.389 + else 24.390 + slot.put(_"There are no more alternative initiatives currently.") 24.391 + end 24.392 + end 24.393 + } 24.394 + end 24.395 + 24.396 + if not (issue.fully_frozen or issue.closed) then 24.397 + slot.put(" ") 24.398 + ui.link{ 24.399 + content = function() 24.400 + ui.image{ static = "icons/16/script_add.png" } 24.401 + slot.put(" ") 24.402 + slot.put(_"Create alternative initiative") 24.403 + end, 24.404 + module = "initiative", 24.405 + view = "new", 24.406 + params = { issue_id = issue.id } 24.407 + } 24.408 + end 24.409 +end
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/app/main/initiative/_list_element.lua Sat Feb 20 22:10:31 2010 +0100 25.3 @@ -0,0 +1,208 @@ 25.4 +local initiative = param.get("initiative", "table") 25.5 +local expanded = param.get("expanded", atom.boolean) 25.6 +local expandable = param.get("expandable", atom.boolean) 25.7 + 25.8 +local head_name = "initiative_head_" .. tostring(initiative.id) 25.9 +local link_name = "initiative_link_" .. tostring(initiative.id) 25.10 +local name = "initiative_content_" .. tostring(initiative.id) 25.11 +local icon_name = "initiative_icon_" .. tostring(initiative.id) 25.12 + 25.13 +ui.container{ 25.14 + attr = { class = "ui_tabs" .. (initiative.id == for_initiative_id and " active" or "") }, 25.15 + content = function() 25.16 + local web20 = config.user_tab_mode == "accordeon" 25.17 + or config.user_tab_mode == "accordeon_first_expanded" 25.18 + or config.user_tab_mode == "accordeon_all_expanded" 25.19 + local onclick 25.20 + if web20 then 25.21 + if expandable then 25.22 + onclick = 25.23 + 'if (lf_initiative_expanded["' .. name .. '"]) {' .. 25.24 + 'lf_initiative_expanded["' .. name .. '"]=false;' .. 25.25 + 'document.getElementById("' .. name .. '_content").innerHTML=" ";' .. 25.26 + 'document.getElementById("' .. name .. '").style.display="none";' .. 25.27 + '} else {' .. 25.28 + 'lf_initiative_expanded["' .. name .. '"] = true;' .. 25.29 + 'document.getElementById("' .. name .. '").style.display="block"; ' .. 25.30 + 'var hourglass_el = document.getElementById("' .. icon_name .. '");' .. 25.31 + 'var hourglass_src = hourglass_el.src;' .. 25.32 + 'hourglass_el.src = "' .. encode.url{ static = "icons/16/connect.png" } .. '";' .. 25.33 + 'partialMultiLoad(' .. 25.34 + '{ trace: "trace", system_error: "system_error", ' .. name .. '_content: "default" },' .. 25.35 + '{},' .. 25.36 + '"error",' .. 25.37 + '"' .. request.get_relative_baseurl() .. 'initiative/show_partial/' .. tostring(initiative.id) .. '.html?&_webmcp_json_slots[]=default&_webmcp_json_slots[]=support&_webmcp_json_slots[]=trace&_webmcp_json_slots[]=system_error",' .. 25.38 + '{},' .. 25.39 + '{},' .. 25.40 + 'function() {' .. 25.41 + 'hourglass_el.src = hourglass_src;' .. 25.42 + '},' .. 25.43 + 'function() {' .. 25.44 + 'hourglass_el.src = hourglass_src;' .. 25.45 + '}' .. 25.46 + '); ' .. 25.47 + '}' .. 25.48 + 'return(false);' 25.49 + else 25.50 + onclick = "document.location.href = document.getElementById('" .. link_name .. "').href;" 25.51 + end 25.52 + end 25.53 + local module = "initiative" 25.54 + local view = "show" 25.55 + local id = initiative.id 25.56 + local params = {} 25.57 + ui.container{ 25.58 + attr = { 25.59 + name = name, 25.60 + class = "ui_tabs_accordeon_head", 25.61 + id = head_name, 25.62 + onclick = onclick, 25.63 + }, 25.64 + content = function() 25.65 + 25.66 + ui.container{ 25.67 + attr = { style = "float: left; width: 4em;"}, 25.68 + content = function() 25.69 + if initiative.issue.accepted and initiative.issue.closed and initiative.issue.ranks_available or initiative.admitted == false then 25.70 + ui.field.rank{ image_attr = { id = icon_name }, attr = { class = "rank" }, value = initiative.rank } 25.71 + elseif web20 then 25.72 + ui.image{ 25.73 + attr = { 25.74 + width = 16, 25.75 + height = 16, 25.76 + id = icon_name, 25.77 + style = "float: left;" 25.78 + }, 25.79 + static = "icons/16/script.png" 25.80 + } 25.81 + else 25.82 + slot.put(" ") 25.83 + end 25.84 + end 25.85 + } 25.86 + 25.87 + ui.container{ 25.88 + attr = { style = "float: left; width: 110px;"}, 25.89 + content = function() 25.90 + if initiative.issue.accepted and initiative.issue.closed then 25.91 + if initiative.issue.ranks_available then 25.92 + if initiative.negative_votes and initiative.positive_votes then 25.93 + local max_value = initiative.issue.voter_count 25.94 + ui.bargraph{ 25.95 + max_value = max_value, 25.96 + width = 100, 25.97 + bars = { 25.98 + { color = "#0a0", value = initiative.positive_votes }, 25.99 + { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes }, 25.100 + { color = "#a00", value = initiative.negative_votes }, 25.101 + } 25.102 + } 25.103 + else 25.104 + slot.put(" ") 25.105 + end 25.106 + else 25.107 + slot.put(_"Counting of votes") 25.108 + end 25.109 + elseif initiative.issue.population then 25.110 + local max_value = initiative.issue.population 25.111 + ui.bargraph{ 25.112 + max_value = max_value, 25.113 + width = 100, 25.114 + bars = { 25.115 + { color = "#0a0", value = (initiative.satisfied_supporter_count or 0) }, 25.116 + { color = "#bbb", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) }, 25.117 + { color = "#eee", value = max_value - (initiative.supporter_count or 0) }, 25.118 + } 25.119 + } 25.120 + else 25.121 + slot.put(" ") 25.122 + end 25.123 + end 25.124 + } 25.125 + 25.126 + ui.container{ 25.127 + attr = { style = "float: left;"}, 25.128 + content = function() 25.129 + local link_class 25.130 + if initiative.revoked then 25.131 + link_class = "revoked" 25.132 + end 25.133 + ui.link{ 25.134 + attr = { id = link_name, class = link_class }, 25.135 + content = function() 25.136 + local name 25.137 + if initiative.name_highlighted then 25.138 + name = encode.highlight(initiative.name_highlighted) 25.139 + else 25.140 + name = encode.html(initiative.name) 25.141 + end 25.142 + slot.put(name) 25.143 + end, 25.144 + module = module, 25.145 + view = view, 25.146 + id = id, 25.147 + params = params, 25.148 + } 25.149 + end 25.150 + } 25.151 + 25.152 + if initiative.issue.state == "new" then 25.153 + ui.image{ 25.154 + static = "icons/16/new.png" 25.155 + } 25.156 + end 25.157 + if initiative.is_supporter then 25.158 + slot.put(" ") 25.159 + local label = _"You are supporting this initiative" 25.160 + ui.image{ 25.161 + attr = { alt = label, title = label }, 25.162 + static = "icons/16/thumb_up_green.png" 25.163 + } 25.164 + end 25.165 + if initiative.is_potential_supporter then 25.166 + slot.put(" ") 25.167 + local label = _"You are potential supporter of this initiative" 25.168 + ui.image{ 25.169 + attr = { alt = label, title = label }, 25.170 + static = "icons/16/thumb_up.png" 25.171 + } 25.172 + end 25.173 + if initiative.is_initiator then 25.174 + slot.put(" ") 25.175 + local label = _"You are iniator of this initiative" 25.176 + ui.image{ 25.177 + attr = { alt = label, title = label }, 25.178 + static = "icons/16/user_edit.png" 25.179 + } 25.180 + end 25.181 + 25.182 + slot.put("<br style='clear: left' />") 25.183 + end 25.184 + } 25.185 + end 25.186 +} 25.187 + 25.188 +if ui.is_partial_loading_enabled() then 25.189 + ui.container{ 25.190 + attr = { 25.191 + id = name, 25.192 + class = "ui_tabs_accordeon_content", 25.193 + style = not expanded and "display: none;" or nil 25.194 + }, 25.195 + content = function() 25.196 + ui.container{ 25.197 + attr = { id = name .. "_content", style = "clear: left;" }, 25.198 + content = function() 25.199 + execute.view{ 25.200 + module = "initiative", 25.201 + view = "show_partial", 25.202 + params = { 25.203 + initiative = initiative, 25.204 + expanded = expanded 25.205 + } 25.206 + } 25.207 + end 25.208 + } 25.209 + end 25.210 + } 25.211 +end 25.212 \ No newline at end of file
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/app/main/initiative/_show.lua Sat Feb 20 22:10:31 2010 +0100 26.3 @@ -0,0 +1,236 @@ 26.4 +local initiative = param.get("initiative", "table") 26.5 +local initiator = param.get("initiator", "table") 26.6 + 26.7 +util.help("initiative.show") 26.8 + 26.9 +if initiative.issue.ranks_available and initiative.admitted then 26.10 + local class = initiative.rank == 1 and "admitted_info" or "not_admitted_info" 26.11 + ui.container{ 26.12 + attr = { class = class }, 26.13 + content = function() 26.14 + local max_value = initiative.issue.voter_count 26.15 + slot.put(" ") 26.16 + local positive_votes = initiative.positive_votes 26.17 + local negative_votes = initiative.negative_votes 26.18 + slot.put(_"Yes" .. ": <b>" .. tostring(positive_votes) .. "</b>") 26.19 + slot.put(" · ") 26.20 + slot.put(_"Abstention" .. ": <b>" .. tostring(max_value - initiative.negative_votes - initiative.positive_votes) .. "</b>") 26.21 + slot.put(" · ") 26.22 + slot.put(_"No" .. ": <b>" .. tostring(initiative.negative_votes) .. "</b>") 26.23 + slot.put(" · ") 26.24 + slot.put("<b>") 26.25 + if initiative.rank == 1 then 26.26 + slot.put(_"Approved") 26.27 + elseif initiative.rank then 26.28 + slot.put(_("Not approved (rank #{rank})", { rank = initiative.rank })) 26.29 + end 26.30 + slot.put("</b>") 26.31 + end 26.32 + } 26.33 +end 26.34 + 26.35 +if initiative.admitted == false then 26.36 + local policy = initiative.issue.policy 26.37 + ui.container{ 26.38 + attr = { class = "not_admitted_info" }, 26.39 + content = _("This initiative has not been admitted! It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) }) 26.40 + } 26.41 +end 26.42 + 26.43 +local web20 = config.user_tab_mode == "accordeon" 26.44 + or config.user_tab_mode == "accordeon_first_expanded" 26.45 + or config.user_tab_mode == "accordeon_all_expanded" 26.46 + 26.47 +if not web20 and initiative.issue.state == "cancelled" then 26.48 + local policy = initiative.issue.policy 26.49 + ui.container{ 26.50 + attr = { class = "not_admitted_info" }, 26.51 + content = _("This issue has been cancelled. It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) }) 26.52 + } 26.53 +end 26.54 + 26.55 +if initiative.revoked then 26.56 + ui.container{ 26.57 + attr = { class = "revoked_info" }, 26.58 + content = function() 26.59 + slot.put(_("This initiative has been revoked at #{revoked}", { revoked = format.timestamp(initiative.revoked) })) 26.60 + local suggested_initiative = initiative.suggested_initiative 26.61 + if suggested_initiative then 26.62 + slot.put("<br /><br />") 26.63 + slot.put(_("The initiators suggest to support the following initiative:")) 26.64 + slot.put(" ") 26.65 + ui.link{ 26.66 + content = _("Issue ##{id}", { id = suggested_initiative.issue.id } ) .. ": " .. encode.html(suggested_initiative.name), 26.67 + module = "initiative", 26.68 + view = "show", 26.69 + id = suggested_initiative.id 26.70 + } 26.71 + end 26.72 + end 26.73 + } 26.74 +end 26.75 + 26.76 +if initiator and initiator.accepted == nil then 26.77 + ui.container{ 26.78 + attr = { class = "initiator_invite_info" }, 26.79 + content = function() 26.80 + slot.put(_"You are invited to become initiator of this initiative.") 26.81 + slot.put(" ") 26.82 + ui.link{ 26.83 + image = { static = "icons/16/tick.png" }, 26.84 + text = _"Accept invitation", 26.85 + module = "initiative", 26.86 + action = "accept_invitation", 26.87 + id = initiative.id, 26.88 + routing = { 26.89 + default = { 26.90 + mode = "redirect", 26.91 + module = request.get_module(), 26.92 + view = request.get_view(), 26.93 + id = param.get_id_cgi(), 26.94 + params = param.get_all_cgi() 26.95 + } 26.96 + } 26.97 + } 26.98 + slot.put(" ") 26.99 + ui.link{ 26.100 + image = { static = "icons/16/cross.png" }, 26.101 + text = _"Refuse invitation", 26.102 + module = "initiative", 26.103 + action = "reject_initiator_invitation", 26.104 + params = { 26.105 + initiative_id = initiative.id, 26.106 + member_id = app.session.member.id 26.107 + }, 26.108 + routing = { 26.109 + default = { 26.110 + mode = "redirect", 26.111 + module = request.get_module(), 26.112 + view = request.get_view(), 26.113 + id = param.get_id_cgi(), 26.114 + params = param.get_all_cgi() 26.115 + } 26.116 + } 26.117 + } 26.118 + end 26.119 + } 26.120 + slot.put("<br />") 26.121 +end 26.122 + 26.123 + 26.124 +local supporter = app.session.member:get_reference_selector("supporters") 26.125 + :add_where{ "initiative_id = ?", initiative.id } 26.126 + :optional_object_mode() 26.127 + :exec() 26.128 + 26.129 +if supporter and not initiative.issue.closed then 26.130 + local old_draft_id = supporter.draft_id 26.131 + local new_draft_id = initiative.current_draft.id 26.132 + if old_draft_id ~= new_draft_id then 26.133 + ui.container{ 26.134 + attr = { class = "draft_updated_info" }, 26.135 + content = function() 26.136 + slot.put(_"The draft of this initiative has been updated!") 26.137 + slot.put(" ") 26.138 + ui.link{ 26.139 + content = _"Show diff", 26.140 + module = "draft", 26.141 + view = "diff", 26.142 + params = { 26.143 + old_draft_id = old_draft_id, 26.144 + new_draft_id = new_draft_id 26.145 + } 26.146 + } 26.147 + slot.put(" ") 26.148 + ui.link{ 26.149 + text = _"Refresh support to current draft", 26.150 + module = "initiative", 26.151 + action = "add_support", 26.152 + id = initiative.id, 26.153 + routing = { 26.154 + default = { 26.155 + mode = "redirect", 26.156 + module = "initiative", 26.157 + view = "show", 26.158 + id = initiative.id 26.159 + } 26.160 + } 26.161 + } 26.162 + end 26.163 + } 26.164 + end 26.165 +end 26.166 + 26.167 + 26.168 + 26.169 +ui.container{ 26.170 + attr = { 26.171 + id = "initiative_" .. tostring(initiative.id) .. "_support" 26.172 + }, 26.173 + content = function() 26.174 + execute.view{ 26.175 + module = "initiative", 26.176 + view = "show_support", 26.177 + params = { 26.178 + initiative = initiative 26.179 + } 26.180 + } 26.181 + end 26.182 +} 26.183 + 26.184 +if (initiative.discussion_url and #initiative.discussion_url > 0) 26.185 + or (initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked) then 26.186 + ui.container{ 26.187 + attr = { class = "vertical" }, 26.188 + content = function() 26.189 + ui.container{ 26.190 + attr = { class = "ui_field_label" }, 26.191 + content = _"Discussion with initiators" 26.192 + } 26.193 + ui.tag{ 26.194 + tag = "span", 26.195 + content = function() 26.196 + if initiative.discussion_url:find("^https?://") then 26.197 + if initiative.discussion_url and #initiative.discussion_url > 0 then 26.198 + ui.link{ 26.199 + attr = { 26.200 + class = "actions", 26.201 + target = "_blank", 26.202 + title = initiative.discussion_url 26.203 + }, 26.204 + content = function() 26.205 + slot.put(encode.html(initiative.discussion_url)) 26.206 + end, 26.207 + external = initiative.discussion_url 26.208 + } 26.209 + end 26.210 + else 26.211 + slot.put(encode.html(initiative.discussion_url)) 26.212 + end 26.213 + slot.put(" ") 26.214 + if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 26.215 + ui.link{ 26.216 + attr = { class = "actions" }, 26.217 + text = _"(change URL)", 26.218 + module = "initiative", 26.219 + view = "edit", 26.220 + id = initiative.id 26.221 + } 26.222 + end 26.223 + end 26.224 + } 26.225 + end 26.226 + } 26.227 +end 26.228 + 26.229 + 26.230 + 26.231 +execute.view{ 26.232 + module = "initiative", 26.233 + view = "show_tab", 26.234 + params = { 26.235 + initiative = initiative, 26.236 + initiator = initiator 26.237 + } 26.238 +} 26.239 +
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/app/main/initiative/_show_voting.lua Sat Feb 20 22:10:31 2010 +0100 27.3 @@ -0,0 +1,112 @@ 27.4 +local initiative = param.get("initiative", "table") 27.5 + 27.6 + 27.7 +local battled_initiatives = Initiative:new_selector() 27.8 + :add_field("winning_battle.count", "winning_count") 27.9 + :add_field("losing_battle.count", "losing_count") 27.10 + :join("battle", "winning_battle", { "winning_battle.winning_initiative_id = ? AND winning_battle.losing_initiative_id = initiative.id", initiative.id }) 27.11 + :join("battle", "losing_battle", { "losing_battle.losing_initiative_id = ? AND losing_battle.winning_initiative_id = initiative.id", initiative.id }) 27.12 + :add_order_by("rank") 27.13 + :exec() 27.14 + 27.15 +local number_of_initiatives = Initiative:new_selector() 27.16 + :add_where{ "issue_id = ?", initiative.issue_id } 27.17 + :add_where("admitted") 27.18 + :count() 27.19 + 27.20 +if initiative.revoked then 27.21 + slot.put(_"Not voted (revoked from initiator)") 27.22 +elseif initiative.admitted == false then 27.23 + slot.put(_"Not voted (not admitted)") 27.24 +else 27.25 + if number_of_initiatives > 1 then 27.26 + ui.container{ 27.27 + attr = { class = "heading first" }, 27.28 + content = _"This initiative compared to alternative initiatives" 27.29 + } 27.30 + 27.31 + ui.list{ 27.32 + records = battled_initiatives, 27.33 + columns = { 27.34 + { 27.35 + content = function() 27.36 + slot.put(_"This initiative") 27.37 + end 27.38 + }, 27.39 + { 27.40 + content = function(record) 27.41 + local population = initiative.issue.voter_count 27.42 + local value = record.winning_count 27.43 + ui.bargraph{ 27.44 + class = "bargraph bargraph50", 27.45 + max_value = population, 27.46 + width = 50, 27.47 + bars = { 27.48 + { color = "#aaa", value = population - value }, 27.49 + { color = "#444", value = value }, 27.50 + } 27.51 + } 27.52 + end 27.53 + }, 27.54 + { 27.55 + content = function(record) 27.56 + slot.put(record.winning_count) 27.57 + end 27.58 + }, 27.59 + { 27.60 + content = function(record) 27.61 + if record.winning_count == record.losing_count then 27.62 + ui.image{ static = "icons/16/bullet_blue.png" } 27.63 + elseif record.winning_count > record.losing_count then 27.64 + ui.image{ static = "icons/16/resultset_previous.png" } 27.65 + else 27.66 + ui.image{ static = "icons/16/resultset_next.png" } 27.67 + end 27.68 + end 27.69 + }, 27.70 + { 27.71 + field_attr = { style = "text-align: right;" }, 27.72 + content = function(record) 27.73 + slot.put(record.losing_count) 27.74 + end 27.75 + }, 27.76 + { 27.77 + content = function(record) 27.78 + local population = initiative.issue.voter_count 27.79 + local value = record.losing_count 27.80 + ui.bargraph{ 27.81 + class = "bargraph bargraph50", 27.82 + max_value = population, 27.83 + width = 50, 27.84 + bars = { 27.85 + { color = "#444", value = value }, 27.86 + { color = "#aaa", value = population - value }, 27.87 + } 27.88 + } 27.89 + end 27.90 + }, 27.91 + { 27.92 + name = "name" 27.93 + } 27.94 + } 27.95 + } 27.96 + end 27.97 + 27.98 + ui.container{ 27.99 + attr = { class = "heading" }, 27.100 + content = _"Member voting" 27.101 + } 27.102 + 27.103 + execute.view{ 27.104 + module = "member", 27.105 + view = "_list", 27.106 + params = { 27.107 + initiative = initiative, 27.108 + members_selector = initiative.issue:get_reference_selector("direct_voters") 27.109 + :left_join("vote", nil, { "vote.initiative_id = ? AND vote.member_id = member.id", initiative.id }) 27.110 + :add_field("direct_voter.weight as voter_weight") 27.111 + :add_field("coalesce(vote.grade, 0) as grade") 27.112 + } 27.113 + } 27.114 + 27.115 +end
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/app/main/initiative/_suggestions.lua Sat Feb 20 22:10:31 2010 +0100 28.3 @@ -0,0 +1,26 @@ 28.4 +local initiative = param.get("initiative", "table") 28.5 + 28.6 +if not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 28.7 + ui.link{ 28.8 + content = function() 28.9 + ui.image{ static = "icons/16/comment_add.png" } 28.10 + slot.put(_"Add new suggestion") 28.11 + end, 28.12 + module = "suggestion", 28.13 + view = "new", 28.14 + params = { 28.15 + initiative_id = initiative.id 28.16 + } 28.17 + } 28.18 +end 28.19 + 28.20 +execute.view{ 28.21 + module = "suggestion", 28.22 + view = "_list", 28.23 + params = { 28.24 + initiative = initiative, 28.25 + suggestions_selector = initiative:get_reference_selector("suggestions"), 28.26 + tab_id = param.get("tab_id") 28.27 + } 28.28 +} 28.29 +
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/app/main/initiative/list_rss.lua Sat Feb 20 22:10:31 2010 +0100 29.3 @@ -0,0 +1,29 @@ 29.4 +slot.set_layout("atom") 29.5 + 29.6 +request.force_absolute_baseurl() 29.7 + 29.8 +local initiatives = Initiative:new_selector() 29.9 + :add_order_by("id DESC") 29.10 + :limit(25) 29.11 + :exec() 29.12 + 29.13 +for i, initiative in ipairs(initiatives) do 29.14 + ui.tag{ 29.15 + tag = "entry", 29.16 + content = function() 29.17 + ui.tag{ tag = "category", attr = { term = initiative.issue.area.name } } 29.18 + ui.tag{ tag = "author", content = initiative.current_draft.author.name } 29.19 + ui.tag{ tag = "title", content = initiative.name } 29.20 + ui.tag{ tag = "link", attr = { 29.21 + href = encode.url{ 29.22 + module = "initiative", 29.23 + view = "show", 29.24 + id = initiative.id 29.25 + } 29.26 + } } 29.27 + ui.tag{ tag = "id", content = "initiative_" .. tostring(initiative_id) } 29.28 + ui.tag{ tag = "updated", content = tostring(initiative.created) } 29.29 + ui.tag{ tag = "content", content = initiative.current_draft.draft } 29.30 + end 29.31 + } 29.32 +end 29.33 \ No newline at end of file
30.1 --- a/app/main/initiative/new.lua Tue Feb 02 00:31:06 2010 +0100 30.2 +++ b/app/main/initiative/new.lua Sat Feb 20 22:10:31 2010 +0100 30.3 @@ -12,7 +12,7 @@ 30.4 end 30.5 30.6 if issue_id then 30.7 - slot.put_into("title", _"Add new initiative to issue") 30.8 + slot.put_into("title", _"Add alternative initiative to issue") 30.9 else 30.10 slot.put_into("title", _"Create new issue") 30.11 end
31.1 --- a/app/main/initiative/show.lua Tue Feb 02 00:31:06 2010 +0100 31.2 +++ b/app/main/initiative/show.lua Sat Feb 20 22:10:31 2010 +0100 31.3 @@ -1,535 +1,36 @@ 31.4 -local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 31.5 - 31.6 -slot.select("actions", function() 31.7 - ui.link{ 31.8 - content = function() 31.9 - ui.image{ static = "icons/16/script.png" } 31.10 - slot.put(_"Show all initiatives") 31.11 - end, 31.12 - module = "issue", 31.13 - view = "show", 31.14 - id = initiative.issue.id 31.15 - } 31.16 -end) 31.17 - 31.18 -execute.view{ 31.19 - module = "issue", 31.20 - view = "_show_head", 31.21 - params = { issue = initiative.issue } 31.22 -} 31.23 - 31.24 -if initiative.revoked then 31.25 - ui.container{ 31.26 - attr = { class = "revoked_info" }, 31.27 - content = function() 31.28 - slot.put(_("This initiative has been revoked at #{revoked}", { revoked = format.timestamp(initiative.revoked) })) 31.29 - local suggested_initiative = initiative.suggested_initiative 31.30 - if suggested_initiative then 31.31 - slot.put("<br /><br />") 31.32 - slot.put(_("The initiators suggest to support the following initiative:")) 31.33 - slot.put("<br />") 31.34 - ui.link{ 31.35 - content = _("Issue ##{id}", { id = suggested_initiative.issue.id } ) .. ": " .. encode.html(suggested_initiative.name), 31.36 - module = "initiative", 31.37 - view = "show", 31.38 - id = suggested_initiative.id 31.39 - } 31.40 - end 31.41 - end 31.42 - } 31.43 -end 31.44 - 31.45 -local initiator = Initiator:by_pk(initiative.id, app.session.member.id) 31.46 - 31.47 ---slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(initiative.id) .. '.rss" />') 31.48 - 31.49 - 31.50 -slot.select("actions", function() 31.51 - if not initiative.issue.fully_frozen and not initiative.issue.closed then 31.52 - ui.link{ 31.53 - attr = { class = "action" }, 31.54 - content = function() 31.55 - ui.image{ static = "icons/16/script_add.png" } 31.56 - slot.put(_"Create alternative initiative") 31.57 - end, 31.58 - module = "initiative", 31.59 - view = "new", 31.60 - params = { issue_id = initiative.issue.id } 31.61 - } 31.62 - end 31.63 -end) 31.64 - 31.65 -slot.put_into("sub_title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) )) 31.66 - 31.67 -slot.select("support", function() 31.68 - ui.container{ 31.69 - attr = { class = "actions" }, 31.70 - content = function() 31.71 - execute.view{ 31.72 - module = "supporter", 31.73 - view = "_show_box", 31.74 - params = { initiative = initiative } 31.75 - } 31.76 - if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 31.77 - ui.link{ 31.78 - attr = { class = "action", style = "float: left;" }, 31.79 - content = function() 31.80 - ui.image{ static = "icons/16/script_delete.png" } 31.81 - slot.put(_"Revoke initiative") 31.82 - end, 31.83 - module = "initiative", 31.84 - view = "revoke", 31.85 - id = initiative.id 31.86 - } 31.87 - end 31.88 - end 31.89 - } 31.90 -end) 31.91 - 31.92 -util.help("initiative.show") 31.93 +local initiative = param.get("initiative", "table") 31.94 31.95 -if initiator and initiator.accepted == nil then 31.96 - ui.container{ 31.97 - attr = { class = "initiator_invite_info" }, 31.98 - content = function() 31.99 - slot.put(_"You are invited to become initiator of this initiative.") 31.100 - slot.put(" ") 31.101 - ui.link{ 31.102 - content = function() 31.103 - ui.image{ static = "icons/16/tick.png" } 31.104 - slot.put(_"Accept invitation") 31.105 - end, 31.106 - module = "initiative", 31.107 - action = "accept_invitation", 31.108 - id = initiative.id, 31.109 - routing = { 31.110 - default = { 31.111 - mode = "redirect", 31.112 - module = request.get_module(), 31.113 - view = request.get_view(), 31.114 - id = param.get_id_cgi(), 31.115 - params = param.get_all_cgi() 31.116 - } 31.117 - } 31.118 - } 31.119 - slot.put(" ") 31.120 - ui.link{ 31.121 - content = function() 31.122 - ui.image{ static = "icons/16/cross.png" } 31.123 - slot.put(_"Refuse invitation") 31.124 - end, 31.125 - module = "initiative", 31.126 - action = "reject_initiator_invitation", 31.127 - params = { 31.128 - initiative_id = initiative.id, 31.129 - member_id = app.session.member.id 31.130 - }, 31.131 - routing = { 31.132 - default = { 31.133 - mode = "redirect", 31.134 - module = request.get_module(), 31.135 - view = request.get_view(), 31.136 - id = param.get_id_cgi(), 31.137 - params = param.get_all_cgi() 31.138 - } 31.139 - } 31.140 - } 31.141 - end 31.142 - } 31.143 - slot.put("<br />") 31.144 -end 31.145 - 31.146 -if (initiative.discussion_url and #initiative.discussion_url > 0) 31.147 - or (initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked) then 31.148 - ui.container{ 31.149 - attr = { class = "vertical" }, 31.150 - content = function() 31.151 - ui.container{ 31.152 - attr = { class = "ui_field_label" }, 31.153 - content = _"Discussion with initiators" 31.154 - } 31.155 - ui.tag{ 31.156 - tag = "span", 31.157 - content = function() 31.158 - if initiative.discussion_url:find("^https?://") then 31.159 - if initiative.discussion_url and #initiative.discussion_url > 0 then 31.160 - ui.link{ 31.161 - attr = { 31.162 - class = "actions", 31.163 - target = "_blank", 31.164 - title = initiative.discussion_url 31.165 - }, 31.166 - content = function() 31.167 - slot.put(encode.html(initiative.discussion_url)) 31.168 - end, 31.169 - external = initiative.discussion_url 31.170 - } 31.171 - end 31.172 - else 31.173 - slot.put(encode.html(initiative.discussion_url)) 31.174 - end 31.175 - slot.put(" ") 31.176 - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 31.177 - ui.link{ 31.178 - attr = { class = "actions" }, 31.179 - content = _"(change URL)", 31.180 - module = "initiative", 31.181 - view = "edit", 31.182 - id = initiative.id 31.183 - } 31.184 - end 31.185 - end 31.186 - } 31.187 - end 31.188 - } 31.189 +if not initiative then 31.190 + initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 31.191 end 31.192 31.193 - 31.194 -ui.container{ 31.195 - attr = { id = "add_suggestion_form", class = "hidden_inline_form" }, 31.196 - content = function() 31.197 - 31.198 - ui.link{ 31.199 - content = _"Close", 31.200 - attr = { 31.201 - onclick = "document.getElementById('add_suggestion_form').style.display='none';return(false)", 31.202 - style = "float: right;" 31.203 - } 31.204 - } 31.205 - 31.206 - ui.field.text{ attr = { class = "head" }, value = _"Add new suggestion" } 31.207 - 31.208 - 31.209 - ui.form{ 31.210 - module = "suggestion", 31.211 - action = "add", 31.212 - params = { initiative_id = initiative.id }, 31.213 - routing = { 31.214 - default = { 31.215 - mode = "redirect", 31.216 - module = "initiative", 31.217 - view = "show", 31.218 - id = initiative.id, 31.219 - params = { tab = "suggestion" } 31.220 - } 31.221 - }, 31.222 - attr = { class = "vertical" }, 31.223 - content = function() 31.224 - local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false 31.225 - if not supported then 31.226 - ui.field.text{ 31.227 - attr = { class = "warning" }, 31.228 - value = _"You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter." 31.229 - } 31.230 - end 31.231 - ui.field.text{ label = _"Title (80 chars max)", name = "name" } 31.232 - ui.field.text{ label = _"Description", name = "description", multiline = true } 31.233 - ui.field.select{ 31.234 - label = _"Degree", 31.235 - name = "degree", 31.236 - foreign_records = { 31.237 - { id = 1, name = _"should"}, 31.238 - { id = 2, name = _"must"}, 31.239 - }, 31.240 - foreign_id = "id", 31.241 - foreign_name = "name" 31.242 - } 31.243 - ui.submit{ text = _"Commit suggestion" } 31.244 - end 31.245 - } 31.246 - end 31.247 -} 31.248 - 31.249 -local supporter = app.session.member:get_reference_selector("supporters") 31.250 - :add_where{ "initiative_id = ?", initiative.id } 31.251 - :optional_object_mode() 31.252 - :exec() 31.253 - 31.254 -if supporter then 31.255 - local old_draft_id = supporter.draft_id 31.256 - local new_draft_id = initiative.current_draft.id 31.257 - if old_draft_id ~= new_draft_id then 31.258 - ui.container{ 31.259 - attr = { class = "draft_updated_info" }, 31.260 - content = function() 31.261 - slot.put(_"The draft of this initiative has been updated!") 31.262 - slot.put(" ") 31.263 - ui.link{ 31.264 - content = _"Show diff", 31.265 - module = "draft", 31.266 - view = "diff", 31.267 - params = { 31.268 - old_draft_id = old_draft_id, 31.269 - new_draft_id = new_draft_id 31.270 - } 31.271 - } 31.272 - slot.put(" ") 31.273 - ui.link{ 31.274 - content = _"Refresh support to current draft", 31.275 - module = "initiative", 31.276 - action = "add_support", 31.277 - id = initiative.id, 31.278 - routing = { 31.279 - default = { 31.280 - mode = "redirect", 31.281 - module = "initiative", 31.282 - view = "show", 31.283 - id = initiative.id 31.284 - } 31.285 - } 31.286 - } 31.287 - end 31.288 - } 31.289 - end 31.290 -end 31.291 - 31.292 - 31.293 -local current_draft_name = _"Current draft" 31.294 -if initiative.issue.half_frozen then 31.295 - current_draft_name = _"Voting proposal" 31.296 -end 31.297 - 31.298 -if initiative.issue.state == "finished" then 31.299 - current_draft_name = _"Voted proposal" 31.300 -end 31.301 - 31.302 -local tabs = { 31.303 - { 31.304 - name = "current_draft", 31.305 - label = current_draft_name, 31.306 - content = function() 31.307 - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 31.308 - ui.link{ 31.309 - content = function() 31.310 - ui.image{ static = "icons/16/script_add.png" } 31.311 - slot.put(_"Edit draft") 31.312 - end, 31.313 - module = "draft", 31.314 - view = "new", 31.315 - params = { initiative_id = initiative.id } 31.316 - } 31.317 - end 31.318 - execute.view{ module = "draft", view = "_show", params = { draft = initiative.current_draft } } 31.319 - end 31.320 - } 31.321 -} 31.322 - 31.323 -if initiative.issue.ranks_available then 31.324 - tabs[#tabs+1] = { 31.325 - name = "voter", 31.326 - label = _"Voter", 31.327 - content = function() 31.328 - execute.view{ 31.329 - module = "member", 31.330 - view = "_list", 31.331 - params = { 31.332 - initiative = initiative, 31.333 - members_selector = initiative.issue:get_reference_selector("direct_voters") 31.334 - :left_join("vote", nil, { "vote.initiative_id = ? AND vote.member_id = member.id", initiative.id }) 31.335 - :add_field("direct_voter.weight as voter_weight") 31.336 - :add_field("coalesce(vote.grade, 0) as grade") 31.337 - } 31.338 - } 31.339 - end 31.340 - } 31.341 -end 31.342 - 31.343 -local suggestion_count = initiative:get_reference_selector("suggestions"):count() 31.344 - 31.345 -tabs[#tabs+1] = { 31.346 - name = "suggestion", 31.347 - label = _"Suggestions" .. " (" .. tostring(suggestion_count) .. ")", 31.348 - content = function() 31.349 - execute.view{ 31.350 - module = "suggestion", 31.351 - view = "_list", 31.352 - params = { 31.353 - initiative = initiative, 31.354 - suggestions_selector = initiative:get_reference_selector("suggestions") 31.355 - } 31.356 +if request.get_json_request_slots() then 31.357 + execute.view{ 31.358 + module = "initiative", 31.359 + view = "show_partial", 31.360 + params = { 31.361 + initiative = initiative 31.362 } 31.363 - slot.put("<br />") 31.364 - if not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 31.365 - ui.link{ 31.366 - content = function() 31.367 - ui.image{ static = "icons/16/comment_add.png" } 31.368 - slot.put(_"Add new suggestion") 31.369 - end, 31.370 - attr = { onclick = "document.getElementById('add_suggestion_form').style.display='block';return(false)" }, 31.371 - static = "#" 31.372 - } 31.373 - end 31.374 - end 31.375 -} 31.376 - 31.377 -local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 31.378 - :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 31.379 - :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") 31.380 - :add_field("direct_interest_snapshot.weight") 31.381 - :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 31.382 - :add_where("direct_supporter_snapshot.satisfied") 31.383 - 31.384 -local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") 31.385 -local direct_satisfied_supporter_count = tmp.count 31.386 -local indirect_satisfied_supporter_count = (tmp.weight or 0) - tmp.count 31.387 - 31.388 -local count_string 31.389 -if indirect_satisfied_supporter_count > 0 then 31.390 - count_string = "(" .. tostring(direct_satisfied_supporter_count) .. "+" .. tostring(indirect_satisfied_supporter_count) .. ")" 31.391 -else 31.392 - count_string = "(" .. tostring(direct_satisfied_supporter_count) .. ")" 31.393 -end 31.394 - 31.395 -tabs[#tabs+1] = { 31.396 - name = "satisfied_supporter", 31.397 - label = _"Supporter" .. " " .. count_string, 31.398 - content = function() 31.399 - execute.view{ 31.400 - module = "member", 31.401 - view = "_list", 31.402 - params = { 31.403 - initiative = initiative, 31.404 - members_selector = members_selector 31.405 - } 31.406 - } 31.407 - end 31.408 -} 31.409 - 31.410 -local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 31.411 - :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 31.412 - :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") 31.413 - :add_field("direct_interest_snapshot.weight") 31.414 - :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 31.415 - :add_where("NOT direct_supporter_snapshot.satisfied") 31.416 - 31.417 -local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") 31.418 -local direct_potential_supporter_count = tmp.count 31.419 -local indirect_potential_supporter_count = (tmp.weight or 0) - tmp.count 31.420 - 31.421 -local count_string 31.422 -if indirect_potential_supporter_count > 0 then 31.423 - count_string = "(" .. tostring(direct_potential_supporter_count) .. "+" .. tostring(indirect_potential_supporter_count) .. ")" 31.424 -else 31.425 - count_string = "(" .. tostring(direct_potential_supporter_count) .. ")" 31.426 -end 31.427 - 31.428 -tabs[#tabs+1] = { 31.429 - name = "supporter", 31.430 - label = _"Potential supporter" .. " " .. count_string, 31.431 - content = function() 31.432 - execute.view{ 31.433 - module = "member", 31.434 - view = "_list", 31.435 - params = { 31.436 - initiative = initiative, 31.437 - members_selector = members_selector 31.438 - } 31.439 + } 31.440 +elseif 31.441 + config.user_tab_mode == "accordeon" or 31.442 + config.user_tab_mode == "accordeon_first_expanded" or 31.443 + config.user_tab_mode == "accordeon_all_expanded" 31.444 +then 31.445 + execute.view{ 31.446 + module = "issue", 31.447 + view = "show", 31.448 + id = initiative.issue_id, 31.449 + params = { 31.450 + for_initiative_id = initiative.id 31.451 } 31.452 - end 31.453 -} 31.454 - 31.455 -local initiator_count = initiative:get_reference_selector("initiators"):add_where("accepted"):count() 31.456 - 31.457 -tabs[#tabs+1] = { 31.458 - name = "initiators", 31.459 - label = _"Initiators" .. " (" .. tostring(initiator_count) .. ")", 31.460 - content = function() 31.461 - if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 31.462 - ui.link{ 31.463 - attr = { class = "action" }, 31.464 - content = function() 31.465 - ui.image{ static = "icons/16/user_add.png" } 31.466 - slot.put(_"Invite initiator") 31.467 - end, 31.468 - module = "initiative", 31.469 - view = "add_initiator", 31.470 - params = { initiative_id = initiative.id } 31.471 - } 31.472 - if initiator_count > 1 then 31.473 - ui.link{ 31.474 - content = function() 31.475 - ui.image{ static = "icons/16/user_delete.png" } 31.476 - slot.put(_"Remove initiator") 31.477 - end, 31.478 - module = "initiative", 31.479 - view = "remove_initiator", 31.480 - params = { initiative_id = initiative.id } 31.481 - } 31.482 - end 31.483 - end 31.484 - if initiator and initiator.accepted == false then 31.485 - ui.link{ 31.486 - content = function() 31.487 - ui.image{ static = "icons/16/user_delete.png" } 31.488 - slot.put(_"Cancel refuse of invitation") 31.489 - end, 31.490 - module = "initiative", 31.491 - action = "remove_initiator", 31.492 - params = { 31.493 - initiative_id = initiative.id, 31.494 - member_id = app.session.member.id 31.495 - }, 31.496 - routing = { 31.497 - ok = { 31.498 - mode = "redirect", 31.499 - module = "initiative", 31.500 - view = "show", 31.501 - id = initiative.id 31.502 - } 31.503 - } 31.504 - } 31.505 - end 31.506 - local members_selector = initiative:get_reference_selector("initiating_members") 31.507 - :add_field("initiator.accepted", "accepted") 31.508 - if not (initiator and initiator.accepted) then 31.509 - members_selector:add_where("accepted") 31.510 - end 31.511 - execute.view{ 31.512 - module = "member", 31.513 - view = "_list", 31.514 - params = { 31.515 - members_selector = members_selector, 31.516 - initiator = initiator 31.517 - } 31.518 + } 31.519 +else 31.520 + execute.view{ 31.521 + module = "initiative", 31.522 + view = "show_static", 31.523 + params = { 31.524 + initiative = initiative 31.525 } 31.526 - end 31.527 -} 31.528 - 31.529 -local drafts_count = initiative:get_reference_selector("drafts"):count() 31.530 - 31.531 -tabs[#tabs+1] = { 31.532 - name = "drafts", 31.533 - label = _"Draft history" .. " (" .. tostring(drafts_count) .. ")", 31.534 - content = function() 31.535 - execute.view{ module = "draft", view = "_list", params = { drafts = initiative.drafts } } 31.536 - end 31.537 -} 31.538 - 31.539 -tabs[#tabs+1] = { 31.540 - name = "details", 31.541 - label = _"Details", 31.542 - content = function() 31.543 - ui.form{ 31.544 - attr = { class = "vertical" }, 31.545 - record = initiative, 31.546 - readonly = true, 31.547 - content = function() 31.548 - ui.field.text{ label = _"Issue policy", value = initiative.issue.policy.name } 31.549 - ui.field.text{ 31.550 - label = _"Created at", 31.551 - value = tostring(initiative.created) 31.552 - } 31.553 - ui.field.text{ 31.554 - label = _"Created at", 31.555 - value = format.timestamp(initiative.created) 31.556 - } 31.557 --- ui.field.date{ label = _"Revoked at", name = "revoked" } 31.558 - ui.field.boolean{ label = _"Admitted", name = "admitted" } 31.559 - end 31.560 - } 31.561 - end 31.562 -} 31.563 - 31.564 - 31.565 -ui.tabs(tabs) 31.566 - 31.567 + } 31.568 +end 31.569 \ No newline at end of file
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/app/main/initiative/show_partial.lua Sat Feb 20 22:10:31 2010 +0100 32.3 @@ -0,0 +1,31 @@ 32.4 +local initiative = param.get("initiative", "table") 32.5 +local expanded = param.get("expanded", atom.boolean) 32.6 + 32.7 +if not initiative then 32.8 + initiative = Initiative:by_id(param.get_id()) 32.9 + expanded = true 32.10 +end 32.11 + 32.12 +-- TODO performance 32.13 +local initiator = Initiator:by_pk(initiative.id, app.session.member.id) 32.14 + 32.15 +ui.partial{ 32.16 + module = "initiative", 32.17 + view = "show", 32.18 + id = initiative.id, 32.19 + target = "initiative_content_" .. tostring(initiative.id) .. "_content", 32.20 + content = function() 32.21 + if expanded then 32.22 + execute.view{ 32.23 + module = "initiative", 32.24 + view = "_show", 32.25 + params = { 32.26 + initiative = initiative, 32.27 + initiator = initiator 32.28 + } 32.29 + } 32.30 + else 32.31 + slot.put(" ") 32.32 + end 32.33 + end 32.34 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/app/main/initiative/show_static.lua Sat Feb 20 22:10:31 2010 +0100 33.3 @@ -0,0 +1,49 @@ 33.4 +local initiative = param.get("initiative", "table") 33.5 + 33.6 +if not initiative then 33.7 + initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 33.8 +end 33.9 + 33.10 +slot.select("actions", function() 33.11 + ui.link{ 33.12 + content = function() 33.13 + ui.image{ static = "icons/16/script.png" } 33.14 + slot.put(_"Show alternative initiatives") 33.15 + end, 33.16 + module = "issue", 33.17 + view = "show", 33.18 + id = initiative.issue.id 33.19 + } 33.20 +end) 33.21 + 33.22 +execute.view{ 33.23 + module = "issue", 33.24 + view = "_show_head", 33.25 + params = { issue = initiative.issue } 33.26 +} 33.27 + 33.28 +--slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(initiative.id) .. '.rss" />') 33.29 + 33.30 + 33.31 +slot.select("actions", function() 33.32 + if not initiative.issue.fully_frozen and not initiative.issue.closed then 33.33 + ui.link{ 33.34 + image = { static = "icons/16/script_add.png" }, 33.35 + attr = { class = "action" }, 33.36 + text = _"Create alternative initiative", 33.37 + module = "initiative", 33.38 + view = "new", 33.39 + params = { issue_id = initiative.issue.id } 33.40 + } 33.41 + end 33.42 +end) 33.43 + 33.44 +slot.put_into("sub_title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) )) 33.45 + 33.46 +execute.view{ 33.47 + module = "initiative", 33.48 + view = "show_partial", 33.49 + params = { 33.50 + initiative = initiative 33.51 + } 33.52 +} 33.53 \ No newline at end of file
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/app/main/initiative/show_support.lua Sat Feb 20 22:10:31 2010 +0100 34.3 @@ -0,0 +1,43 @@ 34.4 +local initiative = param.get("initiative", "table") or Initiative:by_id(param.get_id()) 34.5 + 34.6 +-- TODO performance 34.7 +local initiator = Initiator:by_pk(initiative.id, app.session.member.id) 34.8 + 34.9 +ui.partial{ 34.10 + module = "initiative", 34.11 + view = "show_support", 34.12 + id = initiative.id, 34.13 + target = "initiative_" .. tostring(initiative.id) .. "_support", 34.14 + content = function() 34.15 + ui.container{ 34.16 + attr = { 34.17 + class = "slot_support vote_info", 34.18 + }, 34.19 + content = function() 34.20 + ui.container{ 34.21 + attr = { class = "actions" }, 34.22 + content = function() 34.23 + execute.view{ 34.24 + module = "supporter", 34.25 + view = "_show_box", 34.26 + params = { initiative = initiative } 34.27 + } 34.28 + if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 34.29 + ui.link{ 34.30 + attr = { class = "action", style = "float: left;" }, 34.31 + content = function() 34.32 + ui.image{ static = "icons/16/script_delete.png" } 34.33 + slot.put(_"Revoke initiative") 34.34 + end, 34.35 + module = "initiative", 34.36 + view = "revoke", 34.37 + id = initiative.id 34.38 + } 34.39 + end 34.40 + end 34.41 + } 34.42 + end 34.43 + } 34.44 + slot.put("<div style='clear: left;'></div>") 34.45 + end 34.46 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/app/main/initiative/show_tab.lua Sat Feb 20 22:10:31 2010 +0100 35.3 @@ -0,0 +1,175 @@ 35.4 +local initiative = param.get("initiative", "table") 35.5 +local initiator = param.get("initiator", "table") 35.6 + 35.7 +if not initiative then 35.8 + initiative = Initiative:by_id(param.get("initiative_id", atom.number)) 35.9 +end 35.10 + 35.11 +if not initiator then 35.12 + initiator = Initiator:by_pk(initiative.id, app.session.member.id) 35.13 +end 35.14 + 35.15 +local current_draft_name = _"Current draft" 35.16 +if initiative.issue.half_frozen then 35.17 + current_draft_name = _"Voting proposal" 35.18 +end 35.19 + 35.20 +if initiative.issue.state == "finished" then 35.21 + current_draft_name = _"Voted proposal" 35.22 +end 35.23 + 35.24 +local tabs = { 35.25 + { 35.26 + name = "current_draft", 35.27 + label = current_draft_name, 35.28 + icon = { static = "icons/16/script.png" }, 35.29 + module = "initiative", 35.30 + view = "_current_draft", 35.31 + params = { 35.32 + initiative = initiative, 35.33 + initiator = initiator 35.34 + } 35.35 + } 35.36 +} 35.37 + 35.38 +if initiative.issue.ranks_available then 35.39 + tabs[#tabs+1] = { 35.40 + name = "voting", 35.41 + label = _"Voting details", 35.42 + icon = { static = "icons/16/email_open.png" }, 35.43 + module = "initiative", 35.44 + view = "_show_voting", 35.45 + params = { 35.46 + initiative = initiative 35.47 + } 35.48 + } 35.49 +end 35.50 + 35.51 +local suggestion_count = initiative:get_reference_selector("suggestions"):count() 35.52 + 35.53 +tabs[#tabs+1] = { 35.54 + name = "suggestions", 35.55 + label = _"Suggestions" .. " (" .. tostring(suggestion_count) .. ")", 35.56 + icon = { static = "icons/16/comments.png" }, 35.57 + module = "initiative", 35.58 + view = "_suggestions", 35.59 + params = { 35.60 + initiative = initiative 35.61 + } 35.62 +} 35.63 + 35.64 +local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 35.65 + :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 35.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") 35.67 + :add_field("direct_interest_snapshot.weight") 35.68 + :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 35.69 + :add_where("direct_supporter_snapshot.satisfied") 35.70 + :add_field("direct_supporter_snapshot.informed", "is_informed") 35.71 + 35.72 +local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") 35.73 +local direct_satisfied_supporter_count = tmp.count 35.74 +local indirect_satisfied_supporter_count = (tmp.weight or 0) - tmp.count 35.75 + 35.76 +local count_string 35.77 +if indirect_satisfied_supporter_count > 0 then 35.78 + count_string = "(" .. tostring(direct_satisfied_supporter_count) .. "+" .. tostring(indirect_satisfied_supporter_count) .. ")" 35.79 +else 35.80 + count_string = "(" .. tostring(direct_satisfied_supporter_count) .. ")" 35.81 +end 35.82 + 35.83 +tabs[#tabs+1] = { 35.84 + name = "satisfied_supporter", 35.85 + label = _"Supporter" .. " " .. count_string, 35.86 + icon = { static = "icons/16/thumb_up_green.png" }, 35.87 + module = "member", 35.88 + view = "_list", 35.89 + params = { 35.90 + initiative = initiative, 35.91 + members_selector = members_selector 35.92 + } 35.93 +} 35.94 + 35.95 +local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 35.96 + :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 35.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") 35.98 + :add_field("direct_interest_snapshot.weight") 35.99 + :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 35.100 + :add_where("NOT direct_supporter_snapshot.satisfied") 35.101 + :add_field("direct_supporter_snapshot.informed", "is_informed") 35.102 + 35.103 +local tmp = db:query("SELECT count(1) AS count, sum(weight) AS weight FROM (" .. tostring(members_selector) .. ") as subquery", "object") 35.104 +local direct_potential_supporter_count = tmp.count 35.105 +local indirect_potential_supporter_count = (tmp.weight or 0) - tmp.count 35.106 + 35.107 +local count_string 35.108 +if indirect_potential_supporter_count > 0 then 35.109 + count_string = "(" .. tostring(direct_potential_supporter_count) .. "+" .. tostring(indirect_potential_supporter_count) .. ")" 35.110 +else 35.111 + count_string = "(" .. tostring(direct_potential_supporter_count) .. ")" 35.112 +end 35.113 + 35.114 +tabs[#tabs+1] = { 35.115 + name = "supporter", 35.116 + label = _"Potential supporter" .. " " .. count_string, 35.117 + icon = { static = "icons/16/thumb_up.png" }, 35.118 + module = "member", 35.119 + view = "_list", 35.120 + params = { 35.121 + initiative = initiative, 35.122 + members_selector = members_selector 35.123 + } 35.124 +} 35.125 + 35.126 +local initiators_members_selector = initiative:get_reference_selector("initiating_members") 35.127 + :add_field("initiator.accepted", "accepted") 35.128 + 35.129 +if not (initiator and initiator.accepted) then 35.130 + initiators_members_selector:add_where("initiator.accepted") 35.131 +end 35.132 + 35.133 +local initiator_count = initiators_members_selector:count() 35.134 + 35.135 +tabs[#tabs+1] = { 35.136 + name = "initiators", 35.137 + label = _"Initiators" .. " (" .. tostring(initiator_count) .. ")", 35.138 + icon = { static = "icons/16/user_edit.png" }, 35.139 + module = "initiative", 35.140 + view = "_initiators", 35.141 + params = { 35.142 + initiative = initiative, 35.143 + initiator = initiator, 35.144 + initiators_members_selector = initiators_members_selector 35.145 + } 35.146 +} 35.147 + 35.148 +local drafts_count = initiative:get_reference_selector("drafts"):count() 35.149 + 35.150 +tabs[#tabs+1] = { 35.151 + name = "drafts", 35.152 + label = _"Draft history" .. " (" .. tostring(drafts_count) .. ")", 35.153 + icon = { static = "icons/16/script.png" }, 35.154 + module = "draft", 35.155 + view = "_list", 35.156 + params = { drafts = initiative.drafts } 35.157 +} 35.158 + 35.159 +tabs[#tabs+1] = { 35.160 + name = "details", 35.161 + label = _"Details", 35.162 + icon = { static = "icons/16/magnifier.png" }, 35.163 + module = "initiative", 35.164 + view = "_details", 35.165 + params = { 35.166 + initiative = initiative, 35.167 + members_selector = members_selector 35.168 + } 35.169 +} 35.170 + 35.171 +tabs.module = "initiative" 35.172 +tabs.view = "show_tab" 35.173 +tabs.static_params = { 35.174 + initiative_id = initiative.id 35.175 +} 35.176 + 35.177 +ui.tabs(tabs) 35.178 +
36.1 --- a/app/main/interest/_show_box.lua Tue Feb 02 00:31:06 2010 +0100 36.2 +++ b/app/main/interest/_show_box.lua Sat Feb 20 22:10:31 2010 +0100 36.3 @@ -11,7 +11,7 @@ 36.4 content = function() 36.5 ui.container{ 36.6 attr = { 36.7 - class = "head head_active", 36.8 + class = "head head_active" .. (interest.autoreject and " head_autoreject" or ""), 36.9 onclick = "document.getElementById('interest_content').style.display = 'block';" 36.10 }, 36.11 content = function() 36.12 @@ -19,6 +19,13 @@ 36.13 static = "icons/16/eye.png" 36.14 } 36.15 slot.put(_"Your are interested") 36.16 + 36.17 + if interest.autoreject then 36.18 + ui.image{ 36.19 + static = "icons/16/thumb_down_red.png" 36.20 + } 36.21 + end 36.22 + 36.23 ui.image{ 36.24 static = "icons/16/dropdown.png" 36.25 } 36.26 @@ -40,10 +47,10 @@ 36.27 } 36.28 if issue.state ~= "finished" and issue.state ~= "cancelled" and issue.state ~= "voting" then 36.29 ui.link{ 36.30 - content = _"Remove my interest", 36.31 - module = "interest", 36.32 - action = "update", 36.33 - params = { issue_id = issue.id, delete = true }, 36.34 + text = _"Remove my interest", 36.35 + module = "interest", 36.36 + action = "update", 36.37 + params = { issue_id = issue.id, delete = true }, 36.38 routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 36.39 } 36.40 slot.put("<br />") 36.41 @@ -53,10 +60,10 @@ 36.42 ui.field.text{ value = _"Autoreject is on." } 36.43 if issue.state ~= "finished" and issue.state ~= "cancelled" then 36.44 ui.link{ 36.45 - content = _"Remove autoreject", 36.46 - module = "interest", 36.47 - action = "update", 36.48 - params = { issue_id = issue.id, autoreject = false }, 36.49 + text = _"Remove autoreject", 36.50 + module = "interest", 36.51 + action = "update", 36.52 + params = { issue_id = issue.id, autoreject = false }, 36.53 routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 36.54 } 36.55 end 36.56 @@ -64,10 +71,10 @@ 36.57 ui.field.text{ value = _"Autoreject is off." } 36.58 if issue.state ~= "finished" and issue.state ~= "cancelled" then 36.59 ui.link{ 36.60 - content = _"Set autoreject", 36.61 - module = "interest", 36.62 - action = "update", 36.63 - params = { issue_id = issue.id, autoreject = true }, 36.64 + text = _"Set autoreject", 36.65 + module = "interest", 36.66 + action = "update", 36.67 + params = { issue_id = issue.id, autoreject = true }, 36.68 routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 36.69 } 36.70 end 36.71 @@ -80,13 +87,11 @@ 36.72 else 36.73 if not issue.closed and not issue.fully_frozen then 36.74 ui.link{ 36.75 - content = function() 36.76 - ui.image{ static = "icons/16/user_add.png" } 36.77 - slot.put(_"Add my interest") 36.78 - end, 36.79 - module = "interest", 36.80 - action = "update", 36.81 - params = { issue_id = issue.id }, 36.82 + image = { static = "icons/16/user_add.png" }, 36.83 + text = _"Add my interest", 36.84 + module = "interest", 36.85 + action = "update", 36.86 + params = { issue_id = issue.id }, 36.87 routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 36.88 } 36.89 end
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/app/main/issue/_details.lua Sat Feb 20 22:10:31 2010 +0100 37.3 @@ -0,0 +1,37 @@ 37.4 +local issue = param.get("issue", "table") 37.5 + 37.6 +local policy = issue.policy 37.7 +ui.form{ 37.8 + record = issue, 37.9 + readonly = true, 37.10 + attr = { class = "vertical" }, 37.11 + content = function() 37.12 + ui.field.text{ label = _"Population", name = "population" } 37.13 + ui.field.text{ label = _"State", name = "state" } 37.14 + ui.field.timestamp{ label = _"Created at", name = "created" } 37.15 + ui.field.text{ label = _"Admission time", value = policy.admission_time } 37.16 + ui.field.text{ 37.17 + label = _"Issue quorum", 37.18 + value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) 37.19 + } 37.20 + ui.field.timestamp{ label = _"Accepted at", name = "accepted" } 37.21 + ui.field.text{ label = _"Discussion time", value = policy.discussion_time } 37.22 + ui.field.vote_now{ label = _"Vote now", name = "vote_now" } 37.23 + ui.field.vote_later{ label = _"Vote later", name = "vote_later" } 37.24 + ui.field.timestamp{ label = _"Half frozen at", name = "half_frozen" } 37.25 + ui.field.text{ label = _"Verification time", value = policy.verification_time } 37.26 + ui.field.text{ 37.27 + label = _"Initiative quorum", 37.28 + value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) 37.29 + } 37.30 + ui.field.timestamp{ label = _"Fully frozen at", name = "fully_frozen" } 37.31 + ui.field.text{ label = _"Voting time", value = policy.voting_time } 37.32 + ui.field.timestamp{ label = _"Closed", name = "closed" } 37.33 + end 37.34 +} 37.35 +ui.form{ 37.36 + record = issue.policy, 37.37 + readonly = true, 37.38 + content = function() 37.39 + end 37.40 +}
38.1 --- a/app/main/issue/_list.lua Tue Feb 02 00:31:06 2010 +0100 38.2 +++ b/app/main/issue/_list.lua Sat Feb 20 22:10:31 2010 +0100 38.3 @@ -4,347 +4,310 @@ 38.4 :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id} ) 38.5 :add_field("(_interest.member_id NOTNULL)", "is_interested") 38.6 38.7 -local ui_filter = ui.filter 38.8 -if param.get("filter", atom.boolean) == false then 38.9 - ui_filter = function(args) args.content() end 38.10 -end 38.11 +ui.add_partial_param_names{ 38.12 + "filter", 38.13 + "filter_open", 38.14 + "filter_voting", 38.15 + "filter_interest", 38.16 + "issue_list" 38.17 +} 38.18 38.19 -if param.get("no_filter", atom.boolean) then 38.20 - ui_filter = function(args) args.content() end 38.21 -end 38.22 +local filters = {} 38.23 38.24 -local filter_voting = false 38.25 -ui_filter{ 38.26 - selector = issues_selector, 38.27 - filters = { 38.28 +filters[#filters+1] = { 38.29 + label = _"Filter", 38.30 + { 38.31 + name = "open", 38.32 + label = _"Open", 38.33 + selector_modifier = function(selector) 38.34 + selector:add_where("issue.closed ISNULL") 38.35 + end 38.36 + }, 38.37 + { 38.38 + name = "new", 38.39 + label = _"New", 38.40 + selector_modifier = function(selector) 38.41 + selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") 38.42 + end 38.43 + }, 38.44 + { 38.45 + name = "accepted", 38.46 + label = _"In discussion", 38.47 + selector_modifier = function(selector) 38.48 + selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") 38.49 + end 38.50 + }, 38.51 + { 38.52 + name = "half_frozen", 38.53 + label = _"Frozen", 38.54 + selector_modifier = function(selector) 38.55 + selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") 38.56 + end 38.57 + }, 38.58 + { 38.59 + name = "frozen", 38.60 + label = _"Voting", 38.61 + selector_modifier = function(selector) 38.62 + selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") 38.63 + filter_voting = true 38.64 + end 38.65 + }, 38.66 + { 38.67 + name = "finished", 38.68 + label = _"Finished", 38.69 + selector_modifier = function(selector) 38.70 + selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") 38.71 + end 38.72 + }, 38.73 + { 38.74 + name = "cancelled", 38.75 + label = _"Cancelled", 38.76 + selector_modifier = function(selector) 38.77 + selector:add_where("issue.closed NOTNULL AND issue.accepted ISNULL") 38.78 + end 38.79 + }, 38.80 + { 38.81 + name = "any", 38.82 + label = _"Any", 38.83 + selector_modifier = function(selector) end 38.84 + }, 38.85 +} 38.86 + 38.87 + 38.88 +if param.get("filter") == "frozen" then 38.89 + filters[#filters+1] = { 38.90 + label = _"Filter", 38.91 + name = "filter_voting", 38.92 { 38.93 - type = "boolean", 38.94 - name = "open", 38.95 - label = _"Open", 38.96 - selector_modifier = function(selector, value) 38.97 - if value then 38.98 - selector:add_where("issue.closed ISNULL") 38.99 - end 38.100 - end 38.101 + name = "any", 38.102 + label = _"Any", 38.103 + selector_modifier = function() end 38.104 }, 38.105 { 38.106 - type = "boolean", 38.107 - name = "new", 38.108 - label = _"New", 38.109 - selector_modifier = function(selector, value) 38.110 - if value then 38.111 - selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") 38.112 - end 38.113 + name = "not_voted", 38.114 + label = _"Not voted", 38.115 + selector_modifier = function(selector) 38.116 + selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 38.117 + selector:add_where("direct_voter.member_id ISNULL") 38.118 end 38.119 }, 38.120 { 38.121 - type = "boolean", 38.122 - name = "accepted", 38.123 - label = _"In discussion", 38.124 - selector_modifier = function(selector, value) 38.125 - if value then 38.126 - selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") 38.127 - end 38.128 - end 38.129 - }, 38.130 - { 38.131 - type = "boolean", 38.132 - name = "half_frozen", 38.133 - label = _"Frozen", 38.134 - selector_modifier = function(selector, value) 38.135 - if value then 38.136 - selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") 38.137 - end 38.138 + name = "voted", 38.139 + label = _"Voted", 38.140 + selector_modifier = function(selector) 38.141 + selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 38.142 end 38.143 }, 38.144 + } 38.145 +end 38.146 + 38.147 + 38.148 +filters[#filters+1] = { 38.149 + label = _"Filter", 38.150 + name = "filter_interest", 38.151 + { 38.152 + name = "any", 38.153 + label = _"Any", 38.154 + selector_modifier = function() end 38.155 + }, 38.156 + { 38.157 + name = "my", 38.158 + label = _"Interested", 38.159 + selector_modifier = function(selector) 38.160 + selector:join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", app.session.member.id }) 38.161 + end 38.162 + }, 38.163 + { 38.164 + name = "supported", 38.165 + label = _"Supported", 38.166 + selector_modifier = function(selector) 38.167 + selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN opinion ON opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) WHERE initiative.issue_id = issue.id AND opinion.member_id ISNULL LIMIT 1)", app.session.member.id, app.session.member.id }) 38.168 + end 38.169 + }, 38.170 + { 38.171 + name = "potentially_supported", 38.172 + label = _"Potential supported", 38.173 + selector_modifier = function(selector) 38.174 + selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? JOIN opinion ON opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) WHERE initiative.issue_id = issue.id LIMIT 1)", app.session.member.id, app.session.member.id }) 38.175 + end 38.176 + }, 38.177 + { 38.178 + name = "initiated", 38.179 + label = _"Initiated", 38.180 + selector_modifier = function(selector) 38.181 + selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN initiator ON initiator.initiative_id = initiative.id AND initiator.member_id = ? WHERE initiative.issue_id = issue.id)", app.session.member.id }) 38.182 + end 38.183 + }, 38.184 +} 38.185 + 38.186 +if not param.get("no_sort", atom.boolean) then 38.187 + filters[#filters+1] = { 38.188 + label = _"Order by", 38.189 + name = "issue_list", 38.190 { 38.191 - type = "boolean", 38.192 - name = "frozen", 38.193 - label = _"Voting", 38.194 - selector_modifier = function(selector, value) 38.195 - if value then 38.196 - selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") 38.197 - filter_voting = true 38.198 - end 38.199 - end 38.200 - }, 38.201 - { 38.202 - type = "boolean", 38.203 - name = "finished", 38.204 - label = _"Finished", 38.205 - selector_modifier = function(selector, value) 38.206 - if value then 38.207 - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") 38.208 - end 38.209 + name = "max_potential_support", 38.210 + label = _"Max potential support", 38.211 + selector_modifier = function(selector) 38.212 + selector:add_order_by("(SELECT max(supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 38.213 end 38.214 }, 38.215 { 38.216 - type = "boolean", 38.217 - name = "cancelled", 38.218 - label = _"Cancelled", 38.219 - selector_modifier = function(selector, value) 38.220 - if value then 38.221 - selector:add_where("issue.closed NOTNULL AND issue.accepted ISNULL") 38.222 - end 38.223 + name = "max_support", 38.224 + label = _"Max support", 38.225 + selector_modifier = function(selector) 38.226 + selector:add_order_by("(SELECT max(satisfied_supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 38.227 + end 38.228 + }, 38.229 + { 38.230 + name = "population", 38.231 + label = _"Population", 38.232 + selector_modifier = function(selector) 38.233 + selector:add_order_by("issue.population DESC") 38.234 + end 38.235 + }, 38.236 + { 38.237 + name = "newest", 38.238 + label = _"Newest", 38.239 + selector_modifier = function(selector) 38.240 + selector:add_order_by("issue.created DESC") 38.241 end 38.242 }, 38.243 - }, 38.244 - content = function() 38.245 - local ui_filter = ui.filter 38.246 - if not filter_voting then 38.247 - ui_filter = function(args) args.content() end 38.248 - end 38.249 - if param.get("no_filter", atom.boolean) then 38.250 - ui_filter = function(args) args.content() end 38.251 - end 38.252 - ui_filter{ 38.253 - selector = issues_selector, 38.254 - name = "filter_voting", 38.255 - filters = { 38.256 - { 38.257 - type = "boolean", 38.258 - name = "any", 38.259 - label = _"Any", 38.260 - selector_modifier = function() end 38.261 - }, 38.262 - { 38.263 - type = "boolean", 38.264 - name = "not_voted", 38.265 - label = _"Not voted", 38.266 - selector_modifier = function(selector, value) 38.267 - if value then 38.268 - selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 38.269 - selector:add_where("direct_voter.member_id ISNULL") 38.270 - end 38.271 - end 38.272 - }, 38.273 - { 38.274 - type = "boolean", 38.275 - name = "voted", 38.276 - label = _"Voted", 38.277 - selector_modifier = function(selector, value) 38.278 - if value then 38.279 - selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 38.280 - end 38.281 - end 38.282 - }, 38.283 - }, 38.284 - content = function() 38.285 - local ui_filter = ui.filter 38.286 - if param.get("filter", atom.boolean) == false then 38.287 - ui_filter = function(args) args.content() end 38.288 - end 38.289 - ui_filter{ 38.290 - selector = issues_selector, 38.291 - name = "filter_interest", 38.292 - filters = { 38.293 - { 38.294 - type = "boolean", 38.295 - name = "any", 38.296 - label = _"Any", 38.297 - selector_modifier = function() end 38.298 - }, 38.299 - { 38.300 - type = "boolean", 38.301 - name = "my", 38.302 - label = _"Interested", 38.303 - selector_modifier = function(selector, value) 38.304 - if value then 38.305 - selector:join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", app.session.member.id }) 38.306 - end 38.307 - end 38.308 - }, 38.309 - { 38.310 - type = "boolean", 38.311 - name = "supported", 38.312 - label = _"Supported", 38.313 - selector_modifier = function(selector, value) 38.314 - if value then 38.315 - selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN opinion ON opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) WHERE initiative.issue_id = issue.id AND opinion.member_id ISNULL LIMIT 1)", app.session.member.id, app.session.member.id }) 38.316 - end 38.317 - end 38.318 - }, 38.319 - { 38.320 - type = "boolean", 38.321 - name = "potentially_supported", 38.322 - label = _"Potential supported", 38.323 - selector_modifier = function(selector, value) 38.324 - if value then 38.325 - selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? JOIN opinion ON opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) WHERE initiative.issue_id = issue.id LIMIT 1)", app.session.member.id, app.session.member.id }) 38.326 - end 38.327 - end 38.328 - }, 38.329 - { 38.330 - type = "boolean", 38.331 - name = "initiated", 38.332 - label = _"Initiated", 38.333 - selector_modifier = function(selector, value) 38.334 - if value then 38.335 - selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN initiator ON initiator.initiative_id = initiative.id AND initiator.member_id = ? WHERE initiative.issue_id = issue.id)", app.session.member.id }) 38.336 - end 38.337 + { 38.338 + name = "oldest", 38.339 + label = _"Oldest", 38.340 + selector_modifier = function(selector) 38.341 + selector:add_order_by("issue.created") 38.342 + end 38.343 + } 38.344 + } 38.345 +end 38.346 + 38.347 +filters.content = function() 38.348 + local ui_paginate = ui.paginate 38.349 + if param.get("per_page") == "all" then 38.350 + ui_paginate = function(args) args.content() end 38.351 + end 38.352 + ui_paginate{ 38.353 + per_page = tonumber(param.get("per_page")), 38.354 + selector = issues_selector, 38.355 + content = function() 38.356 + local highlight_string = param.get("highlight_string", "string") 38.357 + local issues = issues or issues_selector:exec() 38.358 + -- issues:load(initiatives) 38.359 + ui.list{ 38.360 + attr = { class = "issues" }, 38.361 + records = issues, 38.362 + columns = { 38.363 + { 38.364 + label = _"Issue", 38.365 + content = function(record) 38.366 + if not param.get("for_area_list", atom.boolean) then 38.367 + ui.field.text{ 38.368 + value = record.area.name 38.369 + } 38.370 + slot.put("<br />") 38.371 end 38.372 - }, 38.373 - }, 38.374 - content = function() 38.375 - local ui_order = ui.order 38.376 - if param.get("no_sort", atom.boolean) then 38.377 - ui_order = function(args) args.content() end 38.378 - end 38.379 - ui_order{ 38.380 - name = "issue_list", 38.381 - selector = issues_selector, 38.382 - options = { 38.383 - { 38.384 - name = "max_potential_support", 38.385 - label = _"Max potential support", 38.386 - selector_modifier = function(selector) 38.387 - selector:add_order_by("(SELECT max(supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 38.388 - end 38.389 - }, 38.390 - { 38.391 - name = "max_support", 38.392 - label = _"Max support", 38.393 - selector_modifier = function(selector) 38.394 - selector:add_order_by("(SELECT max(satisfied_supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 38.395 - end 38.396 - }, 38.397 - { 38.398 - name = "population", 38.399 - label = _"Population", 38.400 - order_by = "issue.population DESC" 38.401 - }, 38.402 - { 38.403 - name = "newest", 38.404 - label = _"Newest", 38.405 - order_by = "issue.created DESC" 38.406 - }, 38.407 - { 38.408 - name = "oldest", 38.409 - label = _"Oldest", 38.410 - order_by = "issue.created" 38.411 + if record.is_interested then 38.412 + local label = _"You are interested in this issue", 38.413 + ui.image{ 38.414 + attr = { alt = label, title = label }, 38.415 + static = "icons/16/eye.png" 38.416 } 38.417 - }, 38.418 - content = function() 38.419 - local ui_paginate = ui.paginate 38.420 - if param.get("per_page") == "all" then 38.421 - ui_paginate = function(args) args.content() end 38.422 - end 38.423 - ui_paginate{ 38.424 - per_page = tonumber(param.get("per_page")), 38.425 - selector = issues_selector, 38.426 - content = function() 38.427 - local highlight_string = param.get("highlight_string", "string") 38.428 - local issues = issues or issues_selector:exec() 38.429 - -- issues:load(initiatives) 38.430 - ui.list{ 38.431 - attr = { class = "issues" }, 38.432 - records = issues, 38.433 - columns = { 38.434 - { 38.435 - label = _"Issue", 38.436 - content = function(record) 38.437 - if not param.get("for_area_list", atom.boolean) then 38.438 - ui.field.text{ 38.439 - value = record.area.name 38.440 - } 38.441 - slot.put("<br />") 38.442 - end 38.443 - if record.is_interested then 38.444 - local label = _"You are interested in this issue", 38.445 - ui.image{ 38.446 - attr = { alt = label, title = label }, 38.447 - static = "icons/16/eye.png" 38.448 - } 38.449 - slot.put(" ") 38.450 - end 38.451 - ui.link{ 38.452 - text = _("Issue ##{id}", { id = tostring(record.id) }), 38.453 - module = "issue", 38.454 - view = "show", 38.455 - id = record.id 38.456 - } 38.457 - if record.state == "new" then 38.458 - ui.image{ 38.459 - static = "icons/16/new.png" 38.460 - } 38.461 - end 38.462 - slot.put("<br />") 38.463 - slot.put("<br />") 38.464 - if record.old_state then 38.465 - ui.field.text{ value = format.time(record.sort) } 38.466 - ui.field.text{ value = Issue:get_state_name_for_state(record.old_state) .. " > " .. Issue:get_state_name_for_state(record.new_state) } 38.467 - else 38.468 - end 38.469 - end 38.470 - }, 38.471 - { 38.472 - label = _"State", 38.473 - content = function(record) 38.474 - if record.state == "voting" then 38.475 - ui.link{ 38.476 - content = _"Voting", 38.477 - module = "vote", 38.478 - view = "list", 38.479 - params = { issue_id = record.id } 38.480 - } 38.481 - else 38.482 - ui.field.issue_state{ value = record.state } 38.483 - end 38.484 - end 38.485 - }, 38.486 - { 38.487 - label = _"Initiatives", 38.488 - content = function(record) 38.489 - local initiatives_selector = record:get_reference_selector("initiatives") 38.490 - local highlight_string = param.get("highlight_string") 38.491 - if highlight_string then 38.492 - initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted") 38.493 - end 38.494 - execute.view{ 38.495 - module = "initiative", 38.496 - view = "_list", 38.497 - params = { 38.498 - issue = record, 38.499 - initiatives_selector = initiatives_selector, 38.500 - highlight_string = highlight_string, 38.501 - per_page = param.get("initiatives_per_page", atom.number), 38.502 - no_sort = param.get("initiatives_no_sort", atom.boolean) 38.503 - } 38.504 - } 38.505 - end 38.506 - }, 38.507 - } 38.508 - } 38.509 - end 38.510 + slot.put(" ") 38.511 + end 38.512 + ui.link{ 38.513 + text = _("Issue ##{id}", { id = tostring(record.id) }), 38.514 + module = "issue", 38.515 + view = "show", 38.516 + id = record.id 38.517 + } 38.518 + if record.state == "new" then 38.519 + ui.image{ 38.520 + static = "icons/16/new.png" 38.521 } 38.522 end 38.523 - } 38.524 - end 38.525 + slot.put("<br />") 38.526 + slot.put("<br />") 38.527 + if record.old_state then 38.528 + ui.field.text{ value = format.time(record.sort) } 38.529 + ui.field.text{ value = Issue:get_state_name_for_state(record.old_state) .. " > " .. Issue:get_state_name_for_state(record.new_state) } 38.530 + else 38.531 + end 38.532 + end 38.533 + }, 38.534 + { 38.535 + label = _"State", 38.536 + content = function(record) 38.537 + if record.state == "voting" then 38.538 + ui.link{ 38.539 + content = _"Voting", 38.540 + module = "vote", 38.541 + view = "list", 38.542 + params = { issue_id = record.id } 38.543 + } 38.544 + else 38.545 + ui.field.issue_state{ value = record.state } 38.546 + end 38.547 + end 38.548 + }, 38.549 + { 38.550 + label = _"Initiatives", 38.551 + content = function(record) 38.552 + local initiatives_selector = record:get_reference_selector("initiatives") 38.553 + local highlight_string = param.get("highlight_string") 38.554 + if highlight_string then 38.555 + initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted") 38.556 + end 38.557 + execute.view{ 38.558 + module = "initiative", 38.559 + view = "_list", 38.560 + params = { 38.561 + issue = record, 38.562 + initiatives_selector = initiatives_selector, 38.563 + highlight_string = highlight_string, 38.564 + per_page = tonumber(app.session.member:get_setting_value("initiatives_preview_limit") or 3), 38.565 + no_sort = true, 38.566 + limit = tonumber(app.session.member:get_setting_value("initiatives_preview_limit") or 3) 38.567 + } 38.568 + } 38.569 + end 38.570 + }, 38.571 } 38.572 - end 38.573 + } 38.574 + end 38.575 + } 38.576 +end 38.577 + 38.578 +filters.selector = issues_selector 38.579 +filters.label = _"Change filters and order" 38.580 + 38.581 +if param.get("no_filter", atom.boolean) then 38.582 + filters.content() 38.583 +else 38.584 + ui.filters(filters) 38.585 +end 38.586 + 38.587 +if param.get("legend", atom.boolean) ~= false then 38.588 + local filter = param.get_all_cgi().filter 38.589 + if not filter or filter == "any" or filter ~= "finished" then 38.590 + ui.bargraph_legend{ 38.591 + width = 25, 38.592 + bars = { 38.593 + { color = "#0a0", label = _"Supporter" }, 38.594 + { color = "#777", label = _"Potential supporter" }, 38.595 + { color = "#ddd", label = _"No support at all" }, 38.596 + } 38.597 } 38.598 - if param.get("legend", atom.boolean) ~= false then 38.599 - local filter = param.get_all_cgi().filter 38.600 - if not filter or filter == "any" or filter ~= "finished" then 38.601 - ui.bargraph_legend{ 38.602 - width = 25, 38.603 - bars = { 38.604 - { color = "#0a0", label = _"Supporter" }, 38.605 - { color = "#777", label = _"Potential supporter" }, 38.606 - { color = "#ddd", label = _"No support at all" }, 38.607 - } 38.608 - } 38.609 - end 38.610 - if not filter or filter == "any" or filter == "finished" then 38.611 - ui.bargraph_legend{ 38.612 - width = 25, 38.613 - bars = { 38.614 - { color = "#0a0", label = _"Yes" }, 38.615 - { color = "#aaa", label = _"Abstention" }, 38.616 - { color = "#a00", label = _"No" }, 38.617 - } 38.618 - } 38.619 - end 38.620 - end 38.621 end 38.622 -} 38.623 + if not filter or filter == "any" or filter == "finished" then 38.624 + ui.bargraph_legend{ 38.625 + width = 25, 38.626 + bars = { 38.627 + { color = "#0a0", label = _"Yes" }, 38.628 + { color = "#aaa", label = _"Abstention" }, 38.629 + { color = "#a00", label = _"No" }, 38.630 + } 38.631 + } 38.632 + end 38.633 +end 38.634 +
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/app/main/issue/_list_initiatives.lua Sat Feb 20 22:10:31 2010 +0100 39.3 @@ -0,0 +1,10 @@ 39.4 +local issue = param.get("issue", "table") 39.5 + 39.6 +execute.view{ 39.7 + module = "initiative", 39.8 + view = "_list", 39.9 + params = { 39.10 + issue = issue, 39.11 + initiatives_selector = issue:get_reference_selector("initiatives") 39.12 + } 39.13 +}
40.1 --- a/app/main/issue/_show_box.lua Tue Feb 02 00:31:06 2010 +0100 40.2 +++ b/app/main/issue/_show_box.lua Sat Feb 20 22:10:31 2010 +0100 40.3 @@ -2,6 +2,10 @@ 40.4 40.5 slot.select("issue_info", function() 40.6 ui.field.text{ 40.7 + label = _"Policy", 40.8 + value = issue.policy.name 40.9 + } 40.10 + ui.field.text{ 40.11 label = _"State", 40.12 value = issue.state_name 40.13 }
41.1 --- a/app/main/issue/_show_head.lua Tue Feb 02 00:31:06 2010 +0100 41.2 +++ b/app/main/issue/_show_head.lua Sat Feb 20 22:10:31 2010 +0100 41.3 @@ -1,33 +1,47 @@ 41.4 local issue = param.get("issue", "table") 41.5 41.6 +local direct_voter = DirectVoter:by_pk(issue.id, app.session.member.id) 41.7 + 41.8 slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(issue.id) .. '.rss" />') 41.9 41.10 slot.select("path", function() 41.11 +end) 41.12 + 41.13 +slot.select("title", function() 41.14 ui.link{ 41.15 - content = _"Area '#{name}'":gsub("#{name}", issue.area.name), 41.16 + content = issue.area.name, 41.17 module = "area", 41.18 view = "show", 41.19 id = issue.area.id 41.20 } 41.21 -end) 41.22 - 41.23 -slot.select("title", function() 41.24 + slot.put(" · ") 41.25 ui.link{ 41.26 - content = _"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name), 41.27 + content = _("Issue ##{id}", { id = issue.id }), 41.28 module = "issue", 41.29 view = "show", 41.30 id = issue.id 41.31 } 41.32 + slot.put(" · ") 41.33 + ui.tag{ 41.34 + tag = "span", 41.35 + content = issue.state_name, 41.36 + } 41.37 end) 41.38 41.39 41.40 slot.select("actions", function() 41.41 41.42 if issue.state == 'voting' then 41.43 + local text 41.44 + if not direct_voter then 41.45 + text = _"Vote now" 41.46 + else 41.47 + text = _"Change vote" 41.48 + end 41.49 ui.link{ 41.50 content = function() 41.51 ui.image{ static = "icons/16/email_open.png" } 41.52 - slot.put(_"Vote now") 41.53 + slot.put(text) 41.54 end, 41.55 module = "vote", 41.56 view = "list", 41.57 @@ -78,7 +92,7 @@ 41.58 -- ui.twitter("http://example.com/t" .. tostring(issue.id)) 41.59 41.60 41.61 -if issue.state == 'voting' then 41.62 +if issue.state == 'voting' and not direct_voter then 41.63 ui.container{ 41.64 attr = { class = "voting_active_info" }, 41.65 content = function()
42.1 --- a/app/main/issue/_show_vote_later_box.lua Tue Feb 02 00:31:06 2010 +0100 42.2 +++ b/app/main/issue/_show_vote_later_box.lua Sat Feb 20 22:10:31 2010 +0100 42.3 @@ -48,10 +48,10 @@ 42.4 end 42.5 } 42.6 ui.link{ 42.7 - content = _"Remove my request to vote later", 42.8 - module = "interest", 42.9 - action = "update_voting_requested", 42.10 - params = { issue_id = issue.id, voting_requested = nil }, 42.11 + text = _"Remove my request to vote later", 42.12 + module = "interest", 42.13 + action = "update_voting_requested", 42.14 + params = { issue_id = issue.id, voting_requested = nil }, 42.15 routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } 42.16 } 42.17 slot.put("<br />") 42.18 @@ -63,10 +63,8 @@ 42.19 else 42.20 if not issue.closed and not issue.half_frozen then 42.21 ui.link{ 42.22 - content = function() 42.23 - ui.image{ static = "icons/16/clock_play.png" } 42.24 - slot.put(_"Vote later") 42.25 - end, 42.26 + image = { static = "icons/16/clock_play.png" }, 42.27 + text = _"Vote later", 42.28 module = "interest", 42.29 action = "update_voting_requested", 42.30 params = {
43.1 --- a/app/main/issue/show.lua Tue Feb 02 00:31:06 2010 +0100 43.2 +++ b/app/main/issue/show.lua Sat Feb 20 22:10:31 2010 +0100 43.3 @@ -6,126 +6,59 @@ 43.4 params = { issue = issue } 43.5 } 43.6 43.7 +--[[ 43.8 +if not issue.fully_frozen and not issue.closed then 43.9 + slot.select("actions", function() 43.10 + ui.link{ 43.11 + content = function() 43.12 + ui.image{ static = "icons/16/script_add.png" } 43.13 + slot.put(_"Create alternative initiative") 43.14 + end, 43.15 + module = "initiative", 43.16 + view = "new", 43.17 + params = { issue_id = issue.id } 43.18 + } 43.19 + end) 43.20 +end 43.21 +--]] 43.22 + 43.23 util.help("issue.show") 43.24 43.25 -local voting_requested_percentage = 0 43.26 -if issue.vote_later and issue.population and issue.population > 0 then 43.27 - voting_requested_percentage = math.ceil(issue.vote_later / issue.population * 100) 43.28 +if issue.state == "cancelled" then 43.29 + local policy = issue.policy 43.30 + ui.container{ 43.31 + attr = { class = "not_admitted_info" }, 43.32 + content = _("This issue has been cancelled. It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) }) 43.33 + } 43.34 end 43.35 -local voting_requested_string = "(" .. tostring(voting_requested_percentage) .. "%)" 43.36 43.37 -ui.tabs{ 43.38 - { 43.39 - name = "initiatives", 43.40 - label = _"Initiatives", 43.41 - content = function() 43.42 - execute.view{ 43.43 - module = "initiative", 43.44 - view = "_list", 43.45 - params = { 43.46 - issue = issue, 43.47 - initiatives_selector = issue:get_reference_selector("initiatives") 43.48 - } 43.49 - } 43.50 - slot.put("<br />") 43.51 - if not issue.fully_frozen and not issue.closed then 43.52 - ui.link{ 43.53 - attr = { class = "action" }, 43.54 - content = function() 43.55 - ui.image{ static = "icons/16/script_add.png" } 43.56 - slot.put(_"Add new initiative to issue") 43.57 - end, 43.58 - module = "initiative", 43.59 - view = "new", 43.60 - params = { issue_id = issue.id } 43.61 - } 43.62 - end 43.63 - end 43.64 - }, 43.65 - { 43.66 - name = "interested_members", 43.67 - label = _"Interested members", 43.68 - content = function() 43.69 - execute.view{ 43.70 - module = "member", 43.71 - view = "_list", 43.72 - params = { 43.73 - issue = issue, 43.74 - members_selector = issue:get_reference_selector("interested_members_snapshot") 43.75 - :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id") 43.76 - :add_field("direct_interest_snapshot.weight") 43.77 - :add_where("direct_interest_snapshot.event = issue.latest_snapshot_event") 43.78 - } 43.79 +ui.container{ 43.80 + attr = { class = "issue_initiative_list" }, 43.81 + content = function() 43.82 + execute.view{ 43.83 + module = "initiative", 43.84 + view = "_list", 43.85 + params = { 43.86 + initiatives_selector = issue:get_reference_selector("initiatives"), 43.87 + issue = issue, 43.88 + expandable = true, 43.89 + for_initiative_id = param.get("for_initiative_id", atom.number), 43.90 + show_for_issue = true 43.91 } 43.92 - end 43.93 - }, 43.94 - { 43.95 - name = "delegations", 43.96 - label = _"Delegations", 43.97 - content = function() 43.98 - execute.view{ 43.99 - module = "delegation", 43.100 - view = "_list", 43.101 - params = { delegations_selector = issue:get_reference_selector("delegations") } 43.102 - } 43.103 - end 43.104 - }, 43.105 - { 43.106 - name = "voting_requests", 43.107 - label = _"Vote later requests" .. " " .. voting_requested_string, 43.108 - content = function() 43.109 - execute.view{ 43.110 - module = "member", 43.111 - view = "_list", 43.112 - params = { 43.113 - issue = issue, 43.114 - members_selector = issue:get_reference_selector("interested_members_snapshot") 43.115 - :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id") 43.116 - :add_where("direct_interest_snapshot.voting_requested = false") 43.117 - } 43.118 - } 43.119 - end 43.120 - }, 43.121 - { 43.122 - name = "details", 43.123 - label = _"Details", 43.124 - content = function() 43.125 - local policy = issue.policy 43.126 - ui.form{ 43.127 - record = issue, 43.128 - readonly = true, 43.129 - attr = { class = "vertical" }, 43.130 - content = function() 43.131 - ui.field.text{ label = _"State", name = "state" } 43.132 - ui.field.timestamp{ label = _"Created at", name = "created" } 43.133 - ui.field.text{ label = _"Admission time", value = policy.admission_time } 43.134 - ui.field.text{ 43.135 - label = _"Issue quorum", 43.136 - value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) 43.137 - } 43.138 - ui.field.timestamp{ label = _"Accepted at", name = "accepted" } 43.139 - ui.field.text{ label = _"Discussion time", value = policy.discussion_time } 43.140 - ui.field.vote_now{ label = _"Vote now", name = "vote_now" } 43.141 - ui.field.vote_later{ label = _"Vote later", name = "vote_later" } 43.142 - ui.field.timestamp{ label = _"Half frozen at", name = "half_frozen" } 43.143 - ui.field.text{ label = _"Verification time", value = policy.verification_time } 43.144 - ui.field.text{ 43.145 - label = _"Initiative quorum", 43.146 - value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) 43.147 - } 43.148 - ui.field.timestamp{ label = _"Fully frozen at", name = "fully_frozen" } 43.149 - ui.field.text{ label = _"Voting time", value = policy.voting_time } 43.150 - ui.field.timestamp{ label = _"Closed", name = "closed" } 43.151 - end 43.152 - } 43.153 - ui.form{ 43.154 - record = issue.policy, 43.155 - readonly = true, 43.156 - content = function() 43.157 - end 43.158 - } 43.159 - end 43.160 - }, 43.161 + } 43.162 + end 43.163 } 43.164 43.165 +slot.put("<br />") 43.166 43.167 +execute.view{ 43.168 + module = "issue", 43.169 + view = "show_tab", 43.170 + params = { issue = issue } 43.171 +} 43.172 + 43.173 +if issue.snapshot then 43.174 + slot.put("<br />") 43.175 + ui.field.timestamp{ label = _"Last snapshot:", value = issue.snapshot } 43.176 +end 43.177 +
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/app/main/issue/show_tab.lua Sat Feb 20 22:10:31 2010 +0100 44.3 @@ -0,0 +1,69 @@ 44.4 +local issue 44.5 +if request.get_json_request_slots() then 44.6 + issue = Issue:by_id(param.get("issue_id")) 44.7 +else 44.8 + issue = param.get("issue", "table") 44.9 +end 44.10 + 44.11 +local voting_requested_percentage = 0 44.12 +if issue.vote_later and issue.population and issue.population > 0 then 44.13 + voting_requested_percentage = math.ceil(issue.vote_later / issue.population * 100) 44.14 +end 44.15 + 44.16 +local interested_members_selector = issue:get_reference_selector("interested_members_snapshot") 44.17 + :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id") 44.18 + :add_field("direct_interest_snapshot.weight") 44.19 + :add_where("direct_interest_snapshot.event = issue.latest_snapshot_event") 44.20 + 44.21 +local voting_requests_selector = issue:get_reference_selector("interested_members_snapshot") 44.22 + :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id") 44.23 + :add_where("direct_interest_snapshot.voting_requested = false") 44.24 + 44.25 +local delegations_selector = issue:get_reference_selector("delegations") 44.26 + 44.27 + 44.28 +ui.tabs{ 44.29 + module = "issue", 44.30 + view = "show_tab", 44.31 + static_params = { issue_id = issue.id }, 44.32 + { 44.33 + name = "interested_members", 44.34 + label = _"Interested members" .. " (" .. tostring(interested_members_selector:count()) .. ")" , 44.35 + icon = { static = "icons/16/eye.png" }, 44.36 + module = "member", 44.37 + view = "_list", 44.38 + params = { 44.39 + issue = issue, 44.40 + members_selector = interested_members_selector 44.41 + } 44.42 + }, 44.43 + { 44.44 + name = "voting_requests", 44.45 + label = _"Vote later requests" .. " (" .. tostring(voting_requests_selector:count()) .. ") (" .. tostring(voting_requested_percentage) .. "%)", 44.46 + icon = { static = "icons/16/clock_play.png" }, 44.47 + module = "member", 44.48 + view = "_list", 44.49 + params = { 44.50 + issue = issue, 44.51 + members_selector = voting_requests_selector 44.52 + } 44.53 + }, 44.54 + { 44.55 + name = "delegations", 44.56 + label = _"Delegations" .. " (" .. tostring(delegations_selector:count()) .. ")" , 44.57 + icon = { static = "icons/16/table_go.png" }, 44.58 + module = "delegation", 44.59 + view = "_list", 44.60 + params = { delegations_selector = delegations_selector } 44.61 + }, 44.62 + { 44.63 + name = "details", 44.64 + label = _"Details", 44.65 + icon = { static = "icons/16/magnifier.png" }, 44.66 + module = "issue", 44.67 + view = "_details", 44.68 + params = { issue = issue } 44.69 + }, 44.70 +} 44.71 + 44.72 +
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/app/main/member/_action/update_display.lua Sat Feb 20 22:10:31 2010 +0100 45.3 @@ -0,0 +1,4 @@ 45.4 +app.session.member:set_setting("tab_mode", param.get("tab_mode")) 45.5 +app.session.member:set_setting("initiatives_preview_limit", param.get("initiatives_preview_limit", atom.number)) 45.6 + 45.7 +slot.put_into("notice", _"Your display settings have been updated") 45.8 \ No newline at end of file
46.1 --- a/app/main/member/_list.lua Tue Feb 02 00:31:06 2010 +0100 46.2 +++ b/app/main/member/_list.lua Sat Feb 20 22:10:31 2010 +0100 46.3 @@ -4,41 +4,45 @@ 46.4 local trustee = param.get("trustee", "table") 46.5 local initiator = param.get("initiator", "table") 46.6 46.7 -local options = { 46.8 +ui.add_partial_param_names{ "member_list" } 46.9 + 46.10 +local filter = { 46.11 + label = _"Order by", 46.12 + name = "member_list", 46.13 + { 46.14 + name = "name", 46.15 + label = _"A-Z", 46.16 + selector_modifier = function(selector) selector:add_order_by("name") end 46.17 + }, 46.18 + { 46.19 + name = "name_desc", 46.20 + label = _"Z-A", 46.21 + selector_modifier = function(selector) selector:add_order_by("name DESC") end 46.22 + }, 46.23 { 46.24 name = "newest", 46.25 label = _"Newest", 46.26 - order_by = "created DESC, id DESC" 46.27 + selector_modifier = function(selector) selector:add_order_by("created DESC, id DESC") end 46.28 }, 46.29 { 46.30 name = "oldest", 46.31 label = _"Oldest", 46.32 - order_by = "created, id" 46.33 - }, 46.34 - { 46.35 - name = "name", 46.36 - label = _"A-Z", 46.37 - order_by = "name" 46.38 - }, 46.39 - { 46.40 - name = "name_desc", 46.41 - label = _"Z-A", 46.42 - order_by = "name DESC" 46.43 + selector_modifier = function(selector) selector:add_order_by("created, id") end 46.44 }, 46.45 } 46.46 46.47 if initiative then 46.48 - options[#options+1] = { 46.49 + filter[#filter] = { 46.50 name = "delegations", 46.51 label = _"Delegations", 46.52 - order_by = "weight DESC" 46.53 + selector_modifier = function(selector) selector:add_order_by("weight DESC") end 46.54 } 46.55 end 46.56 46.57 -ui.order{ 46.58 - name = "member_list", 46.59 +ui.filters{ 46.60 + label = _"Change order", 46.61 selector = members_selector, 46.62 - options = options, 46.63 + filter, 46.64 content = function() 46.65 ui.paginate{ 46.66 selector = members_selector, 46.67 @@ -118,12 +122,6 @@ 46.68 } 46.69 end 46.70 46.71 ---[[ ui.list{ 46.72 - records = members, 46.73 - columns = columns 46.74 - } 46.75 ---]] 46.76 ----[[ 46.77 for i, member in ipairs(members) do 46.78 execute.view{ 46.79 module = "member", 46.80 @@ -137,17 +135,11 @@ 46.81 } 46.82 } 46.83 end 46.84 ----]] 46.85 + 46.86 end 46.87 } 46.88 slot.put('<br style="clear: left;" />') 46.89 - if issue then 46.90 - ui.field.timestamp{ label = _"Last snapshot:", value = issue.snapshot } 46.91 - end 46.92 - if initiative then 46.93 - ui.field.timestamp{ label = _"Last snapshot:", value = initiative.issue.snapshot } 46.94 - end 46.95 end 46.96 } 46.97 end 46.98 -} 46.99 \ No newline at end of file 46.100 +}
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/app/main/member/_profile.lua Sat Feb 20 22:10:31 2010 +0100 47.3 @@ -0,0 +1,114 @@ 47.4 +local member = param.get("member", "table") 47.5 + 47.6 +if not member then 47.7 + local member_id = param.get("member_id", atom.integer) 47.8 + if member_id then 47.9 + member = Member:by_id(member_id) 47.10 + end 47.11 +end 47.12 + 47.13 + 47.14 +ui.form{ 47.15 + attr = { class = "member vertical" }, 47.16 + record = member, 47.17 + readonly = true, 47.18 + content = function() 47.19 + 47.20 + ui.container{ 47.21 + attr = { class = "right" }, 47.22 + content = function() 47.23 + 47.24 + execute.view{ 47.25 + module = "member_image", 47.26 + view = "_show", 47.27 + params = { 47.28 + member = member, 47.29 + image_type = "photo" 47.30 + } 47.31 + } 47.32 + 47.33 + ui.container{ 47.34 + attr = { class = "contact_data" }, 47.35 + content = function() 47.36 + end 47.37 + } 47.38 + 47.39 + end 47.40 + } 47.41 + 47.42 + if member.admin then 47.43 + ui.field.boolean{ label = _"Admin?", name = "admin" } 47.44 + end 47.45 + if member.locked then 47.46 + ui.field.boolean{ label = _"Locked?", name = "locked" } 47.47 + end 47.48 + if member.ident_number then 47.49 + ui.field.text{ label = _"Ident number", name = "ident_number" } 47.50 + end 47.51 + ui.field.text{ label = _"Name", name = "name" } 47.52 + 47.53 + if member.realname and #member.realname > 0 then 47.54 + ui.field.text{ label = _"Real name", name = "realname" } 47.55 + end 47.56 + if member.email and #member.email > 0 then 47.57 + ui.field.text{ label = _"email", name = "email" } 47.58 + end 47.59 + if member.xmpp_address and #member.xmpp_address > 0 then 47.60 + ui.field.text{ label = _"xmpp", name = "xmpp_address" } 47.61 + end 47.62 + if member.website and #member.website > 0 then 47.63 + ui.field.text{ label = _"Website", name = "website" } 47.64 + end 47.65 + if member.phone and #member.phone > 0 then 47.66 + ui.field.text{ label = _"Phone", name = "phone" } 47.67 + end 47.68 + if member.mobile_phone and #member.mobile_phone > 0 then 47.69 + ui.field.text{ label = _"Mobile phone", name = "mobile_phone" } 47.70 + end 47.71 + if member.address and #member.address > 0 then 47.72 + ui.container{ 47.73 + content = function() 47.74 + ui.tag{ 47.75 + tag = "label", 47.76 + attr = { class = "ui_field_label" }, 47.77 + content = _"Address" 47.78 + } 47.79 + ui.tag{ 47.80 + tag = "span", 47.81 + content = function() 47.82 + slot.put(encode.html_newlines(encode.html(member.address))) 47.83 + end 47.84 + } 47.85 + end 47.86 + } 47.87 + end 47.88 + if member.profession and #member.profession > 0 then 47.89 + ui.field.text{ label = _"Profession", name = "profession" } 47.90 + end 47.91 + if member.birthday and #member.birthday > 0 then 47.92 + ui.field.text{ label = _"Birthday", name = "birthday" } 47.93 + end 47.94 + if member.organizational_unit and #member.organizational_unit > 0 then 47.95 + ui.field.text{ label = _"Organizational unit", name = "organizational_unit" } 47.96 + end 47.97 + if member.internal_posts and #member.internal_posts > 0 then 47.98 + ui.field.text{ label = _"Internal posts", name = "internal_posts" } 47.99 + end 47.100 + if member.external_memberships and #member.external_memberships > 0 then 47.101 + ui.field.text{ label = _"Memberships", name = "external_memberships", multiline = true } 47.102 + end 47.103 + if member.external_posts and #member.external_posts > 0 then 47.104 + ui.field.text{ label = _"Posts", name = "external_posts", multiline = true } 47.105 + end 47.106 + slot.put('<br style="clear: right;" />') 47.107 + 47.108 + end 47.109 +} 47.110 +if member.statement and #member.statement > 0 then 47.111 + ui.container{ 47.112 + attr = { class = "member_statement wiki" }, 47.113 + content = function() 47.114 + slot.put(format.wiki_text(member.statement)) 47.115 + end 47.116 + } 47.117 +end
48.1 --- a/app/main/member/_show.lua Tue Feb 02 00:31:06 2010 +0100 48.2 +++ b/app/main/member/_show.lua Sat Feb 20 22:10:31 2010 +0100 48.3 @@ -1,191 +1,7 @@ 48.4 -local member = param.get("member", "table") 48.5 - 48.6 -ui.tabs{ 48.7 - { 48.8 - name = "profile", 48.9 - label = _"Profile", 48.10 - content = function() 48.11 - ui.form{ 48.12 - attr = { class = "member vertical" }, 48.13 - record = member, 48.14 - readonly = true, 48.15 - content = function() 48.16 - 48.17 - ui.container{ 48.18 - attr = { class = "right" }, 48.19 - content = function() 48.20 - 48.21 - execute.view{ 48.22 - module = "member_image", 48.23 - view = "_show", 48.24 - params = { 48.25 - member = member, 48.26 - image_type = "photo" 48.27 - } 48.28 - } 48.29 - 48.30 - ui.container{ 48.31 - attr = { class = "contact_data" }, 48.32 - content = function() 48.33 - end 48.34 - } 48.35 - 48.36 - end 48.37 - } 48.38 - 48.39 - if member.admin then 48.40 - ui.field.boolean{ label = _"Admin?", name = "admin" } 48.41 - end 48.42 - if member.locked then 48.43 - ui.field.boolean{ label = _"Locked?", name = "locked" } 48.44 - end 48.45 - if member.ident_number then 48.46 - ui.field.text{ label = _"Ident number", name = "ident_number" } 48.47 - end 48.48 - ui.field.text{ label = _"Name", name = "name" } 48.49 - 48.50 - if member.realname and #member.realname > 0 then 48.51 - ui.field.text{ label = _"Real name", name = "realname" } 48.52 - end 48.53 - if member.email and #member.email > 0 then 48.54 - ui.field.text{ label = _"email", name = "email" } 48.55 - end 48.56 - if member.xmpp_address and #member.xmpp_address > 0 then 48.57 - ui.field.text{ label = _"xmpp", name = "xmpp_address" } 48.58 - end 48.59 - if member.website and #member.website > 0 then 48.60 - ui.field.text{ label = _"Website", name = "website" } 48.61 - end 48.62 - if member.phone and #member.phone > 0 then 48.63 - ui.field.text{ label = _"Phone", name = "phone" } 48.64 - end 48.65 - if member.mobile_phone and #member.mobile_phone > 0 then 48.66 - ui.field.text{ label = _"Mobile phone", name = "mobile_phone" } 48.67 - end 48.68 - if member.address and #member.address > 0 then 48.69 - ui.container{ 48.70 - content = function() 48.71 - ui.tag{ 48.72 - tag = "label", 48.73 - attr = { class = "ui_field_label" }, 48.74 - content = _"Address" 48.75 - } 48.76 - ui.tag{ 48.77 - tag = "span", 48.78 - content = function() 48.79 - slot.put(encode.html_newlines(encode.html(member.address))) 48.80 - end 48.81 - } 48.82 - end 48.83 - } 48.84 - end 48.85 - if member.profession and #member.profession > 0 then 48.86 - ui.field.text{ label = _"Profession", name = "profession" } 48.87 - end 48.88 - if member.birthday and #member.birthday > 0 then 48.89 - ui.field.text{ label = _"Birthday", name = "birthday" } 48.90 - end 48.91 - if member.organizational_unit and #member.organizational_unit > 0 then 48.92 - ui.field.text{ label = _"Organizational unit", name = "organizational_unit" } 48.93 - end 48.94 - if member.internal_posts and #member.internal_posts > 0 then 48.95 - ui.field.text{ label = _"Internal posts", name = "internal_posts" } 48.96 - end 48.97 - if member.external_memberships and #member.external_memberships > 0 then 48.98 - ui.field.text{ label = _"Memberships", name = "external_memberships", multiline = true } 48.99 - end 48.100 - if member.external_posts and #member.external_posts > 0 then 48.101 - ui.field.text{ label = _"Posts", name = "external_posts", multiline = true } 48.102 - end 48.103 - slot.put('<br style="clear: right;" />') 48.104 - 48.105 - end 48.106 - } 48.107 - if member.statement and #member.statement > 0 then 48.108 - ui.container{ 48.109 - attr = { class = "member_statement wiki" }, 48.110 - content = function() 48.111 - slot.put(format.wiki_text(member.statement)) 48.112 - end 48.113 - } 48.114 - end 48.115 - end 48.116 - }, 48.117 - { 48.118 - name = "areas", 48.119 - label = _"Areas", 48.120 - content = function() 48.121 - execute.view{ 48.122 - module = "area", 48.123 - view = "_list", 48.124 - params = { areas_selector = member:get_reference_selector("areas") } 48.125 - } 48.126 - end 48.127 - }, 48.128 - { 48.129 - name = "issues", 48.130 - label = _"Issues", 48.131 - content = function() 48.132 - execute.view{ 48.133 - module = "issue", 48.134 - view = "_list", 48.135 - params = { issues_selector = member:get_reference_selector("issues") } 48.136 - } 48.137 - end 48.138 - }, 48.139 - { 48.140 - name = "supported_initiatives", 48.141 - label = _"Supported initiatives", 48.142 - content = function() 48.143 - execute.view{ 48.144 - module = "initiative", 48.145 - view = "_list", 48.146 - params = { initiatives_selector = member:get_reference_selector("supported_initiatives") } 48.147 - } 48.148 - end 48.149 - }, 48.150 - { 48.151 - name = "initiatied_initiatives", 48.152 - label = _"Initiated initiatives", 48.153 - content = function() 48.154 - execute.view{ 48.155 - module = "initiative", 48.156 - view = "_list", 48.157 - params = { initiatives_selector = member:get_reference_selector("initiated_initiatives"):add_where("initiator.accepted = true") } 48.158 - } 48.159 - end 48.160 - }, 48.161 - { 48.162 - name = "incoming_delegations", 48.163 - label = _"Incoming delegations", 48.164 - content = function() 48.165 - execute.view{ 48.166 - module = "delegation", 48.167 - view = "_list", 48.168 - params = { delegations_selector = member:get_reference_selector("incoming_delegations"), incoming = true } 48.169 - } 48.170 - end 48.171 - }, 48.172 - { 48.173 - name = "Outgoing delegations", 48.174 - label = _"Outgoing delegations", 48.175 - content = function() 48.176 - execute.view{ 48.177 - module = "delegation", 48.178 - view = "_list", 48.179 - params = { delegations_selector = member:get_reference_selector("outgoing_delegations"), outgoing = true } 48.180 - } 48.181 - end 48.182 - }, 48.183 - { 48.184 - name = "contacts", 48.185 - label = _"Published contacts", 48.186 - content = function() 48.187 - execute.view{ 48.188 - module = "member", 48.189 - view = "_list", 48.190 - params = { members_selector = member:get_reference_selector("saved_members"):add_where("public") } 48.191 - } 48.192 - end 48.193 - }, 48.194 -} 48.195 +execute.view{ 48.196 + module = "member", 48.197 + view = "show_tab", 48.198 + params = { 48.199 + member = param.get("member", "table") 48.200 + } 48.201 +} 48.202 \ No newline at end of file
49.1 --- a/app/main/member/_show_thumb.lua Tue Feb 02 00:31:06 2010 +0100 49.2 +++ b/app/main/member/_show_thumb.lua Sat Feb 20 22:10:31 2010 +0100 49.3 @@ -17,12 +17,55 @@ 49.4 container_class = container_class .. " not_accepted" 49.5 end 49.6 49.7 +if member.is_informed == false then 49.8 + container_class = container_class .. " not_informed" 49.9 +end 49.10 + 49.11 ui.container{ 49.12 attr = { class = container_class }, 49.13 content = function() 49.14 ui.container{ 49.15 attr = { class = "flags" }, 49.16 content = function() 49.17 + 49.18 + if member.grade then 49.19 + ui.link{ 49.20 + module = "vote", 49.21 + view = "list", 49.22 + params = { 49.23 + issue_id = initiative.issue.id, 49.24 + member_id = member.id, 49.25 + }, 49.26 + content = function() 49.27 + if member.grade > 0 then 49.28 + ui.image{ 49.29 + attr = { 49.30 + alt = _"Voted yes", 49.31 + title = _"Voted yes" 49.32 + }, 49.33 + static = "icons/16/thumb_up_green.png" 49.34 + } 49.35 + elseif member.grade < 0 then 49.36 + ui.image{ 49.37 + attr = { 49.38 + alt = _"Voted no", 49.39 + title = _"Voted no" 49.40 + }, 49.41 + static = "icons/16/thumb_down_red.png" 49.42 + } 49.43 + else 49.44 + ui.image{ 49.45 + attr = { 49.46 + alt = _"Abstention", 49.47 + title = _"Abstention" 49.48 + }, 49.49 + static = "icons/16/bullet_yellow.png" 49.50 + } 49.51 + end 49.52 + end 49.53 + } 49.54 + end 49.55 + 49.56 local weight = 0 49.57 if member.weight then 49.58 weight = member.weight 49.59 @@ -52,9 +95,8 @@ 49.60 issue_id = issue and issue.id or nil 49.61 } 49.62 } 49.63 - else 49.64 - slot.put(" ") 49.65 end 49.66 + 49.67 if initiator and initiator.accepted then 49.68 if member.accepted == nil then 49.69 slot.put(_"Invited") 49.70 @@ -62,37 +104,15 @@ 49.71 slot.put(_"Rejected") 49.72 end 49.73 end 49.74 - if member.grade then 49.75 - ui.container{ 49.76 - content = function() 49.77 - if member.grade > 0 then 49.78 - ui.image{ 49.79 - attr = { 49.80 - alt = _"Voted yes", 49.81 - title = _"Voted yes" 49.82 - }, 49.83 - static = "icons/16/thumb_up_green.png" 49.84 - } 49.85 - elseif member.grade < 0 then 49.86 - ui.image{ 49.87 - attr = { 49.88 - alt = _"Voted no", 49.89 - title = _"Voted no" 49.90 - }, 49.91 - static = "icons/16/thumb_down_red.png" 49.92 - } 49.93 - else 49.94 - ui.image{ 49.95 - attr = { 49.96 - alt = _"Abstention", 49.97 - title = _"Abstention" 49.98 - }, 49.99 - static = "icons/16/bullet_yellow.png" 49.100 - } 49.101 - end 49.102 - end 49.103 + 49.104 + if member.is_informed == false then 49.105 + local text = _"Member has not approved latest draft" 49.106 + ui.image{ 49.107 + attr = { alt = text, title = text }, 49.108 + static = "icons/16/help_yellow.png" 49.109 } 49.110 end 49.111 + 49.112 if member.admin then 49.113 ui.image{ 49.114 attr = { 49.115 @@ -102,6 +122,7 @@ 49.116 static = "icons/16/cog.png" 49.117 } 49.118 end 49.119 + 49.120 -- TODO performance 49.121 local contact = Contact:by_pk(app.session.member.id, member.id) 49.122 if contact then
50.1 --- a/app/main/member/edit.lua Tue Feb 02 00:31:06 2010 +0100 50.2 +++ b/app/main/member/edit.lua Sat Feb 20 22:10:31 2010 +0100 50.3 @@ -39,7 +39,7 @@ 50.4 ui.field.text{ label = _"Profession", name = "profession" } 50.5 ui.field.text{ label = _"External memberships", name = "external_memberships", multiline = true } 50.6 ui.field.text{ label = _"External posts", name = "external_posts", multiline = true } 50.7 - ui.field.text{ label = _"Statement", name = "statement", multiline = true } 50.8 + ui.field.text{ label = _"Statement", name = "statement", multiline = true, attr = { style = "height: 10em;" } } 50.9 ui.submit{ value = _"Save" } 50.10 end 50.11 } 50.12 \ No newline at end of file
51.1 --- a/app/main/member/settings.lua Tue Feb 02 00:31:06 2010 +0100 51.2 +++ b/app/main/member/settings.lua Sat Feb 20 22:10:31 2010 +0100 51.3 @@ -26,6 +26,55 @@ 51.4 end 51.5 end) 51.6 51.7 +ui.heading{ content = _"Display settings" } 51.8 +util.help("member.settings.display", _"Display settings") 51.9 + 51.10 +ui.form{ 51.11 + attr = { class = "vertical" }, 51.12 + module = "member", 51.13 + action = "update_display", 51.14 + routing = { 51.15 + ok = { 51.16 + mode = "redirect", 51.17 + module = "index", 51.18 + view = "index" 51.19 + } 51.20 + }, 51.21 + content = function() 51.22 + ui.field.select{ 51.23 + label = _"Type of tabs", 51.24 + foreign_records = { 51.25 + { id = "tabs", name = _"Tabs" }, 51.26 + { id = "accordeon", name = _"Accordion (none expanded)" .. " === " .. _"EXPERIMENTAL FEATURE" .. " ===" }, 51.27 + { id = "accordeon_first_expanded", name = _"Accordion (first expanded)" .. " === " .. _"EXPERIMENTAL FEATURE" .. " ===" }, 51.28 +-- { id = "accordeon_all_expanded", name = _"Accordion (all expanded)" } 51.29 + }, 51.30 + foreign_id = "id", 51.31 + foreign_name = "name", 51.32 + name = "tab_mode", 51.33 + value = app.session.member:get_setting_value("tab_mode") 51.34 + } 51.35 + ui.field.select{ 51.36 + label = _"Number of initiatives to preview", 51.37 + foreign_records = { 51.38 + { id = 3, name = "3" }, 51.39 + { id = 4, name = "4" }, 51.40 + { id = 5, name = "5" }, 51.41 + { id = 6, name = "6" }, 51.42 + { id = 7, name = "7" }, 51.43 + { id = 8, name = "8" }, 51.44 + { id = 9, name = "9" }, 51.45 + { id = 10, name = "10" }, 51.46 + }, 51.47 + foreign_id = "id", 51.48 + foreign_name = "name", 51.49 + name = "initiatives_preview_limit", 51.50 + value = app.session.member:get_setting_value("initiatives_preview_limit") 51.51 + } 51.52 + ui.submit{ value = _"Change display settings" } 51.53 + end 51.54 +} 51.55 + 51.56 ui.heading{ content = _"Change your name" } 51.57 util.help("member.settings.name", _"Change name") 51.58
52.1 --- a/app/main/member/show.lua Tue Feb 02 00:31:06 2010 +0100 52.2 +++ b/app/main/member/show.lua Sat Feb 20 22:10:31 2010 +0100 52.3 @@ -23,13 +23,11 @@ 52.4 content = _"You have saved this member as contact." 52.5 } 52.6 ui.link{ 52.7 - content = function() 52.8 - ui.image{ static = "icons/16/book_delete.png" } 52.9 - slot.put(encode.html(_"Remove from contacts")) 52.10 - end, 52.11 + image = { static = "icons/16/book_delete.png" }, 52.12 + text = _"Remove from contacts", 52.13 module = "contact", 52.14 action = "remove_member", 52.15 - id = contact.other_member_id, 52.16 + id = contact.other_member_id, 52.17 routing = { 52.18 default = { 52.19 mode = "redirect", 52.20 @@ -44,10 +42,8 @@ 52.21 else 52.22 slot.select("actions", function() 52.23 ui.link{ 52.24 - content = function() 52.25 - ui.image{ static = "icons/16/book_add.png" } 52.26 - slot.put(encode.html(_"Add to my contacts")) 52.27 - end, 52.28 + image = { static = "icons/16/book_add.png" }, 52.29 + text = _"Add to my contacts", 52.30 module = "contact", 52.31 action = "add_member", 52.32 id = member.id,
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/app/main/member/show_tab.lua Sat Feb 20 22:10:31 2010 +0100 53.3 @@ -0,0 +1,89 @@ 53.4 +local member 53.5 + 53.6 +if request.get_json_request_slots() then 53.7 + member = Member:by_id(param.get("member_id")) 53.8 +else 53.9 + member = param.get("member", "table") 53.10 +end 53.11 + 53.12 +local areas_selector = member:get_reference_selector("areas") 53.13 +local issues_selector = member:get_reference_selector("issues") 53.14 +local supported_initiatives_selector = member:get_reference_selector("supported_initiatives") 53.15 +local initiated_initiatives_selector = member:get_reference_selector("initiated_initiatives"):add_where("initiator.accepted = true") 53.16 +local incoming_delegations_selector = member:get_reference_selector("incoming_delegations") 53.17 + :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") 53.18 + :add_where("_member_showtab_issue.closed ISNULL") 53.19 +local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations") 53.20 + :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") 53.21 + :add_where("_member_showtab_issue.closed ISNULL") 53.22 +local contacts_selector = member:get_reference_selector("saved_members"):add_where("public") 53.23 + 53.24 +ui.tabs{ 53.25 + module = "member", 53.26 + view = "show_tab", 53.27 + static_params = { member_id = member.id }, 53.28 + { 53.29 + name = "profile", 53.30 + label = _"Profile", 53.31 + icon = { static = "icons/16/application_form.png" }, 53.32 + module = "member", 53.33 + view = "_profile", 53.34 + params = { member = member }, 53.35 + }, 53.36 + { 53.37 + name = "areas", 53.38 + label = _"Areas" .. " (" .. tostring(areas_selector:count()) .. ")", 53.39 + icon = { static = "icons/16/package.png" }, 53.40 + module = "area", 53.41 + view = "_list", 53.42 + params = { areas_selector = areas_selector }, 53.43 + }, 53.44 + { 53.45 + name = "issues", 53.46 + label = _"Issues" .. " (" .. tostring(issues_selector:count()) .. ")", 53.47 + icon = { static = "icons/16/folder.png" }, 53.48 + module = "issue", 53.49 + view = "_list", 53.50 + params = { issues_selector = issues_selector }, 53.51 + }, 53.52 + { 53.53 + name = "supported_initiatives", 53.54 + label = _"Supported initiatives" .. " (" .. tostring(supported_initiatives_selector:count()) .. ")", 53.55 + icon = { static = "icons/16/thumb_up_green.png" }, 53.56 + module = "initiative", 53.57 + view = "_list", 53.58 + params = { initiatives_selector = supported_initiatives_selector }, 53.59 + }, 53.60 + { 53.61 + name = "initiatied_initiatives", 53.62 + label = _"Initiated initiatives" .. " (" .. tostring(initiated_initiatives_selector:count()) .. ")", 53.63 + icon = { static = "icons/16/user_edit.png" }, 53.64 + module = "initiative", 53.65 + view = "_list", 53.66 + params = { initiatives_selector = initiated_initiatives_selector }, 53.67 + }, 53.68 + { 53.69 + name = "incoming_delegations", 53.70 + label = _"Incoming delegations" .. " (" .. tostring(incoming_delegations_selector:count()) .. ")", 53.71 + icon = { static = "icons/16/table_go.png" }, 53.72 + module = "delegation", 53.73 + view = "_list", 53.74 + params = { delegations_selector = incoming_delegations_selector, incoming = true }, 53.75 + }, 53.76 + { 53.77 + name = "outgoing_delegations", 53.78 + label = _"Outgoing delegations" .. " (" .. tostring(outgoing_delegations_selector:count()) .. ")", 53.79 + icon = { static = "icons/16/table_go.png" }, 53.80 + module = "delegation", 53.81 + view = "_list", 53.82 + params = { delegations_selector = outgoing_delegations_selector }, 53.83 + }, 53.84 + { 53.85 + name = "contacts", 53.86 + label = _"Contacts" .. " (" .. tostring(contacts_selector:count()) .. ")", 53.87 + icon = { static = "icons/16/book_edit.png" }, 53.88 + module = "member", 53.89 + view = "_list", 53.90 + params = { members_selector = contacts_selector }, 53.91 + } 53.92 +}
54.1 --- a/app/main/membership/_show_box.lua Tue Feb 02 00:31:06 2010 +0100 54.2 +++ b/app/main/membership/_show_box.lua Sat Feb 20 22:10:31 2010 +0100 54.3 @@ -36,28 +36,28 @@ 54.4 end 54.5 } 54.6 ui.link{ 54.7 - content = _"Remove my membership", 54.8 - module = "membership", 54.9 - action = "update", 54.10 - params = { area_id = area.id, delete = true }, 54.11 + text = _"Remove my membership", 54.12 + module = "membership", 54.13 + action = "update", 54.14 + params = { area_id = area.id, delete = true }, 54.15 routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 54.16 } 54.17 if membership.autoreject then 54.18 ui.field.text{ value = _"Autoreject is on." } 54.19 ui.link{ 54.20 - content = _"Remove autoreject", 54.21 - module = "membership", 54.22 - action = "update", 54.23 - params = { area_id = area.id, autoreject = false }, 54.24 + text = _"Remove autoreject", 54.25 + module = "membership", 54.26 + action = "update", 54.27 + params = { area_id = area.id, autoreject = false }, 54.28 routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 54.29 } 54.30 else 54.31 ui.field.text{ value = _"Autoreject is off." } 54.32 ui.link{ 54.33 - content = _"Set autoreject", 54.34 - module = "membership", 54.35 - action = "update", 54.36 - params = { area_id = area.id, autoreject = true }, 54.37 + text = _"Set autoreject", 54.38 + module = "membership", 54.39 + action = "update", 54.40 + params = { area_id = area.id, autoreject = true }, 54.41 routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } 54.42 } 54.43 end 54.44 @@ -65,10 +65,8 @@ 54.45 } 54.46 else 54.47 ui.link{ 54.48 - content = function() 54.49 - ui.image{ static = "icons/16/user_add.png" } 54.50 - slot.put(_"Become a member") 54.51 - end, 54.52 + image = { static = "icons/16/user_add.png" }, 54.53 + text = _"Become a member", 54.54 module = "membership", 54.55 action = "update", 54.56 params = { area_id = area.id },
55.1 --- a/app/main/suggestion/_list.lua Tue Feb 02 00:31:06 2010 +0100 55.2 +++ b/app/main/suggestion/_list.lua Sat Feb 20 22:10:31 2010 +0100 55.3 @@ -1,61 +1,66 @@ 55.4 55.5 local initiative = param.get("initiative", "table") 55.6 local suggestions_selector = param.get("suggestions_selector", "table") 55.7 +local tab_id = param.get("tab_id") 55.8 +local show_name = param.get("show_name", atom.boolean) 55.9 +if show_name == nil then 55.10 + show_name = true 55.11 +end 55.12 +local show_filter = param.get("show_filter", atom.boolean) 55.13 +if show_filter == nil then 55.14 + show_filter = true 55.15 +end 55.16 55.17 -ui.order{ 55.18 - name = name, 55.19 +local partial = { 55.20 + routing = { 55.21 + default = { 55.22 + mode = "redirect", 55.23 + module = "initiative", 55.24 + view = "show_tab", 55.25 + params = { 55.26 + initiative_id = initiative.id, 55.27 + tab = "suggestions", 55.28 + tab_id = tab_id 55.29 + }, 55.30 + } 55.31 + } 55.32 +} 55.33 + 55.34 +local ui_filters = ui.filters 55.35 +if not show_filter then 55.36 + ui_filters = function(args) args.content() end 55.37 +end 55.38 + 55.39 +ui_filters{ 55.40 + label = _"Show filter", 55.41 selector = suggestions_selector, 55.42 - options = { 55.43 + { 55.44 + label = _"Order by", 55.45 { 55.46 - name = "all", 55.47 - label = _"all", 55.48 - order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id" 55.49 + name = "plus_unfulfilled", 55.50 + label = _"requested", 55.51 + selector_modifier = function(selector) selector:add_order_by("plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id") end 55.52 }, 55.53 { 55.54 name = "plus2", 55.55 label = _"must", 55.56 - order_by = "plus2_unfulfilled_count + plus2_fulfilled_count DESC, id" 55.57 + selector_modifier = function(selector) selector:add_order_by("plus2_unfulfilled_count + plus2_fulfilled_count DESC, id") end 55.58 }, 55.59 { 55.60 name = "plus", 55.61 label = _"must/should", 55.62 - order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id" 55.63 + selector_modifier = function(selector) selector:add_order_by("plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id") end 55.64 }, 55.65 { 55.66 name = "minus", 55.67 label = _"must/should not", 55.68 - order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count DESC, id" 55.69 + selector_modifier = function(selector) selector:add_order_by("minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count DESC, id") end 55.70 }, 55.71 { 55.72 name = "minus2", 55.73 label = _"must not", 55.74 - order_by = "minus2_unfulfilled_count + minus2_fulfilled_count DESC, id" 55.75 - }, 55.76 - { 55.77 - name = "unfulfilled", 55.78 - label = _"not implemented", 55.79 - order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id" 55.80 - }, 55.81 - { 55.82 - name = "plus2_unfulfilled", 55.83 - label = _"must", 55.84 - order_by = "plus2_unfulfilled_count DESC, id" 55.85 - }, 55.86 - { 55.87 - name = "plus_unfulfilled", 55.88 - label = _"must/should", 55.89 - order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id" 55.90 - }, 55.91 - { 55.92 - name = "minus_unfulfilled", 55.93 - label = _"must/should not", 55.94 - order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count DESC, id" 55.95 - }, 55.96 - { 55.97 - name = "minus2_unfulfilled", 55.98 - label = _"must not", 55.99 - order_by = "minus2_unfulfilled_count DESC, id" 55.100 - }, 55.101 + selector_modifier = function(selector) selector:add_order_by("minus2_unfulfilled_count + minus2_fulfilled_count DESC, id") end 55.102 + } 55.103 }, 55.104 content = function() 55.105 ui.paginate{ 55.106 @@ -66,14 +71,16 @@ 55.107 records = suggestions_selector:exec(), 55.108 columns = { 55.109 { 55.110 - label = _"Suggestion", 55.111 + label = show_name and _"Suggestion" or nil, 55.112 content = function(record) 55.113 - ui.link{ 55.114 - text = record.name, 55.115 - module = "suggestion", 55.116 - view = "show", 55.117 - id = record.id 55.118 - } 55.119 + if show_name then 55.120 + ui.link{ 55.121 + text = record.name, 55.122 + module = "suggestion", 55.123 + view = "show", 55.124 + id = record.id 55.125 + } 55.126 + end 55.127 end 55.128 }, 55.129 { 55.130 @@ -108,65 +115,98 @@ 55.131 ui.container{ 55.132 attr = { class = "suggestion_my_opinion" }, 55.133 content = function() 55.134 - ui.link{ 55.135 - attr = { class = "action" .. (degree == -2 and " active_red2" or "") }, 55.136 - text = _"must not", 55.137 - module = "opinion", 55.138 - action = "update", 55.139 - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.140 - params = { 55.141 - suggestion_id = record.id, 55.142 - degree = -2 55.143 + if initiative.issue.state == "voting" or initiative.issue.state == "closed" then 55.144 + ui.tag{ 55.145 + tag = "span", 55.146 + attr = { class = "action" .. (degree == -2 and " active_red2" or "") }, 55.147 + content = _"must not" 55.148 + } 55.149 + ui.tag{ 55.150 + tag = "span", 55.151 + attr = { class = "action" .. (degree == -1 and " active_red1" or "") }, 55.152 + content = _"should not" 55.153 + } 55.154 + ui.tag{ 55.155 + tag = "span", 55.156 + attr = { class = "action" .. (degree == nil and " active" or "") }, 55.157 + content = _"neutral" 55.158 } 55.159 - } 55.160 - slot.put(" ") 55.161 - ui.link{ 55.162 - attr = { class = "action" .. (degree == -1 and " active_red1" or "") }, 55.163 - text = _"should not", 55.164 - module = "opinion", 55.165 - action = "update", 55.166 - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.167 - params = { 55.168 - suggestion_id = record.id, 55.169 - degree = -1 55.170 + ui.tag{ 55.171 + tag = "span", 55.172 + attr = { class = "action" .. (degree == 1 and " active_green1" or "") }, 55.173 + content = _"should" 55.174 + } 55.175 + ui.tag{ 55.176 + tag = "span", 55.177 + attr = { class = "action" .. (degree == 2 and " active_green2" or "") }, 55.178 + content = _"must" 55.179 + } 55.180 + else 55.181 + ui.link{ 55.182 + attr = { class = "action" .. (degree == -2 and " active_red2" or "") }, 55.183 + text = _"must not", 55.184 + module = "opinion", 55.185 + action = "update", 55.186 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.187 + params = { 55.188 + suggestion_id = record.id, 55.189 + degree = -2 55.190 + }, 55.191 + partial = partial 55.192 } 55.193 - } 55.194 - slot.put(" ") 55.195 - ui.link{ 55.196 - attr = { class = "action" .. (degree == nil and " active" or "") }, 55.197 - text = _"neutral", 55.198 - module = "opinion", 55.199 - action = "update", 55.200 - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.201 - params = { 55.202 - suggestion_id = record.id, 55.203 - delete = true 55.204 + slot.put(" ") 55.205 + ui.link{ 55.206 + attr = { class = "action" .. (degree == -1 and " active_red1" or "") }, 55.207 + text = _"should not", 55.208 + module = "opinion", 55.209 + action = "update", 55.210 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.211 + params = { 55.212 + suggestion_id = record.id, 55.213 + degree = -1 55.214 + }, 55.215 + partial = partial 55.216 + } 55.217 + slot.put(" ") 55.218 + ui.link{ 55.219 + attr = { class = "action" .. (degree == nil and " active" or "") }, 55.220 + text = _"neutral", 55.221 + module = "opinion", 55.222 + action = "update", 55.223 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.224 + params = { 55.225 + suggestion_id = record.id, 55.226 + delete = true 55.227 + }, 55.228 + partial = partial 55.229 } 55.230 - } 55.231 - slot.put(" ") 55.232 - ui.link{ 55.233 - attr = { class = "action" .. (degree == 1 and " active_green1" or "") }, 55.234 - text = _"should", 55.235 - module = "opinion", 55.236 - action = "update", 55.237 - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.238 - params = { 55.239 - suggestion_id = record.id, 55.240 - degree = 1 55.241 + slot.put(" ") 55.242 + ui.link{ 55.243 + attr = { class = "action" .. (degree == 1 and " active_green1" or "") }, 55.244 + text = _"should", 55.245 + module = "opinion", 55.246 + action = "update", 55.247 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.248 + params = { 55.249 + suggestion_id = record.id, 55.250 + degree = 1 55.251 + }, 55.252 + partial = partial 55.253 } 55.254 - } 55.255 - slot.put(" ") 55.256 - ui.link{ 55.257 - attr = { class = "action" .. (degree == 2 and " active_green2" or "") }, 55.258 - text = _"must", 55.259 - module = "opinion", 55.260 - action = "update", 55.261 - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.262 - params = { 55.263 - suggestion_id = record.id, 55.264 - degree = 2 55.265 + slot.put(" ") 55.266 + ui.link{ 55.267 + attr = { class = "action" .. (degree == 2 and " active_green2" or "") }, 55.268 + text = _"must", 55.269 + module = "opinion", 55.270 + action = "update", 55.271 + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, 55.272 + params = { 55.273 + suggestion_id = record.id, 55.274 + degree = 2 55.275 + }, 55.276 + partial = partial 55.277 } 55.278 - } 55.279 + end 55.280 end 55.281 } 55.282 end 55.283 @@ -254,7 +294,8 @@ 55.284 params = { 55.285 suggestion_id = record.id, 55.286 fulfilled = true 55.287 - } 55.288 + }, 55.289 + partial = partial 55.290 } 55.291 else 55.292 if opinion.degree > 0 then 55.293 @@ -271,7 +312,8 @@ 55.294 params = { 55.295 suggestion_id = record.id, 55.296 fulfilled = false 55.297 - } 55.298 + }, 55.299 + partial = partial 55.300 } 55.301 end 55.302 end 55.303 @@ -295,7 +337,3 @@ 55.304 } 55.305 end 55.306 } 55.307 - 55.308 -if initiative then 55.309 - ui.field.timestamp{ label = _"Last snapshot:", value = initiative.issue.snapshot } 55.310 -end
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/app/main/suggestion/_opinions.lua Sat Feb 20 22:10:31 2010 +0100 56.3 @@ -0,0 +1,13 @@ 56.4 +local suggestion = param.get("suggestion", "table") 56.5 + 56.6 +execute.view{ 56.7 + module = "opinion", 56.8 + view = "_list", 56.9 + params = { 56.10 + opinions_selector = Opinion:new_selector() 56.11 + :add_field("member.name", "member_name") 56.12 + :add_where{ "suggestion_id = ?", suggestion.id } 56.13 + :join("member", nil, "member.id = opinion.member_id") 56.14 + :add_order_by("member.id DESC") 56.15 + } 56.16 +}
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/app/main/suggestion/_suggestion.lua Sat Feb 20 22:10:31 2010 +0100 57.3 @@ -0,0 +1,30 @@ 57.4 +local suggestion = param.get("suggestion", "table") 57.5 + 57.6 +ui.form{ 57.7 + attr = { class = "vertical" }, 57.8 + record = suggestion, 57.9 + readonly = true, 57.10 + content = function() 57.11 + ui.field.text{ label = _"Author", value = suggestion.author.name } 57.12 + ui.field.text{ label = _"Title", name = "name" } 57.13 + ui.container{ 57.14 + attr = { class = "suggestion_content wiki" }, 57.15 + content = function() 57.16 + ui.tag{ 57.17 + tag = "p", 57.18 + content = suggestion.description 57.19 + } 57.20 + end 57.21 + } 57.22 + end 57.23 +} 57.24 +execute.view{ 57.25 + module = "suggestion", 57.26 + view = "_list", 57.27 + params = { 57.28 + suggestions_selector = Suggestion:new_selector():add_where{ "id = ?", suggestion.id }, 57.29 + initiative = suggestion.initiative, 57.30 + show_name = false, 57.31 + show_filter = false 57.32 + } 57.33 +}
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/app/main/suggestion/new.lua Sat Feb 20 22:10:31 2010 +0100 58.3 @@ -0,0 +1,54 @@ 58.4 +local initiative_id = param.get("initiative_id") 58.5 + 58.6 +slot.put_into("title", _"Add new suggestion") 58.7 + 58.8 +slot.select("actions", function() 58.9 + ui.link{ 58.10 + content = function() 58.11 + ui.image{ static = "icons/16/cancel.png" } 58.12 + slot.put(_"Cancel") 58.13 + end, 58.14 + module = "initiative", 58.15 + view = "show", 58.16 + id = initiative_id, 58.17 + params = { tab = "suggestions" } 58.18 + } 58.19 +end) 58.20 + 58.21 +ui.form{ 58.22 + module = "suggestion", 58.23 + action = "add", 58.24 + params = { initiative_id = initiative_id }, 58.25 + routing = { 58.26 + default = { 58.27 + mode = "redirect", 58.28 + module = "initiative", 58.29 + view = "show", 58.30 + id = initiative_id, 58.31 + params = { tab = "suggestions" } 58.32 + } 58.33 + }, 58.34 + attr = { class = "vertical" }, 58.35 + content = function() 58.36 + local supported = Supporter:by_pk(initiative_id, app.session.member.id) and true or false 58.37 + if not supported then 58.38 + ui.field.text{ 58.39 + attr = { class = "warning" }, 58.40 + value = _"You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter." 58.41 + } 58.42 + end 58.43 + ui.field.text{ label = _"Title (80 chars max)", name = "name" } 58.44 + ui.field.text{ label = _"Description", name = "description", multiline = true } 58.45 + ui.field.select{ 58.46 + label = _"Degree", 58.47 + name = "degree", 58.48 + foreign_records = { 58.49 + { id = 1, name = _"should"}, 58.50 + { id = 2, name = _"must"}, 58.51 + }, 58.52 + foreign_id = "id", 58.53 + foreign_name = "name" 58.54 + } 58.55 + ui.submit{ text = _"Commit suggestion" } 58.56 + end 58.57 +}
59.1 --- a/app/main/suggestion/show.lua Tue Feb 02 00:31:06 2010 +0100 59.2 +++ b/app/main/suggestion/show.lua Sat Feb 20 22:10:31 2010 +0100 59.3 @@ -11,34 +11,14 @@ 59.4 module = "initiative", 59.5 view = "show", 59.6 id = suggestion.initiative.id, 59.7 - params = { tab = "suggestion" } 59.8 + params = { tab = "suggestions" } 59.9 } 59.10 end) 59.11 59.12 -ui.form{ 59.13 - attr = { class = "vertical" }, 59.14 - record = suggestion, 59.15 - readonly = true, 59.16 - content = function() 59.17 - ui.field.text{ label = _"Name", name = "name" } 59.18 - ui.field.text{ label = _"Description", name = "description" } 59.19 - end 59.20 -} 59.21 - 59.22 execute.view{ 59.23 module = "suggestion", 59.24 - view = "_list", 59.25 - params = { suggestions_selector = Suggestion:new_selector():add_where{ "id = ?", suggestion.id } } 59.26 -} 59.27 - 59.28 -execute.view{ 59.29 - module = "opinion", 59.30 - view = "_list", 59.31 - params = { 59.32 - opinions_selector = Opinion:new_selector() 59.33 - :add_field("member.name", "member_name") 59.34 - :add_where{ "suggestion_id = ?", suggestion.id } 59.35 - :join("member", nil, "member.id = opinion.member_id") 59.36 - :add_order_by("member.id DESC") 59.37 + view = "show_tab", 59.38 + params = { 59.39 + suggestion = suggestion 59.40 } 59.41 -} 59.42 +} 59.43 \ No newline at end of file
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/app/main/suggestion/show_tab.lua Sat Feb 20 22:10:31 2010 +0100 60.3 @@ -0,0 +1,28 @@ 60.4 +local suggestion = param.get("suggestion", "table") or Suggestion:by_id(param.get("suggestion_id")) 60.5 + 60.6 +ui.tabs{ 60.7 + module = "suggestion", 60.8 + view = "show_tab", 60.9 + static_params = { 60.10 + suggestion_id = suggestion.id 60.11 + }, 60.12 + { 60.13 + name = "description", 60.14 + label = _"Suggestion", 60.15 + module = "suggestion", 60.16 + view = "_suggestion", 60.17 + params = { 60.18 + suggestion = suggestion 60.19 + } 60.20 + }, 60.21 + { 60.22 + name = "opinions", 60.23 + label = _"Opinions", 60.24 + module = "suggestion", 60.25 + view = "_opinions", 60.26 + params = { 60.27 + suggestion = suggestion 60.28 + } 60.29 + } 60.30 +} 60.31 +
61.1 --- a/app/main/supporter/_show_box.lua Tue Feb 02 00:31:06 2010 +0100 61.2 +++ b/app/main/supporter/_show_box.lua Sat Feb 20 22:10:31 2010 +0100 61.3 @@ -1,103 +1,109 @@ 61.4 61.5 -slot.select("support", function() 61.6 - local initiative = param.get("initiative", "table") 61.7 - local supporter = Supporter:by_pk(initiative.id, app.session.member.id) 61.8 +local initiative = param.get("initiative", "table") 61.9 +local supporter = Supporter:by_pk(initiative.id, app.session.member.id) 61.10 + 61.11 +local unique_string = multirand.string(16, '0123456789abcdef') 61.12 + 61.13 + 61.14 +local partial = { 61.15 + routing = { 61.16 + default = { 61.17 + mode = "redirect", 61.18 + module = "initiative", 61.19 + view = "show_support", 61.20 + id = initiative.id 61.21 + } 61.22 + } 61.23 +} 61.24 61.25 - if not initiative.issue.fully_frozen and not initiative.issue.closed then 61.26 - if supporter then 61.27 - if not supporter:has_critical_opinion() then 61.28 - ui.container{ 61.29 - attr = { 61.30 - class = "head head_supporter", 61.31 - style = "cursor: pointer;", 61.32 - onclick = "document.getElementById('support_content').style.display = 'block';" 61.33 - }, 61.34 - content = function() 61.35 - ui.image{ 61.36 - static = "icons/16/thumb_up_green.png" 61.37 - } 61.38 - slot.put(_"Your are supporter") 61.39 - ui.image{ 61.40 - static = "icons/16/dropdown.png" 61.41 - } 61.42 - end 61.43 - } 61.44 - else 61.45 - ui.container{ 61.46 - attr = { 61.47 - class = "head head_potential_supporter", 61.48 - style = "cursor: pointer;", 61.49 - onclick = "document.getElementById('support_content').style.display = 'block';" 61.50 - }, 61.51 - content = function() 61.52 - ui.image{ 61.53 - static = "icons/16/thumb_up.png" 61.54 - } 61.55 - slot.put(_"Your are potential supporter") 61.56 - ui.image{ 61.57 - static = "icons/16/dropdown.png" 61.58 - } 61.59 - end 61.60 - } 61.61 - end 61.62 +local routing = { 61.63 + default = { 61.64 + mode = "redirect", 61.65 + module = request.get_module(), 61.66 + view = request.get_view(), 61.67 + id = param.get_id_cgi(), 61.68 + params = param.get_all_cgi() 61.69 + } 61.70 +} 61.71 + 61.72 +if not initiative.issue.fully_frozen and not initiative.issue.closed then 61.73 + if supporter then 61.74 + if not supporter:has_critical_opinion() then 61.75 ui.container{ 61.76 - attr = { class = "content", id = "support_content" }, 61.77 + attr = { 61.78 + class = "head head_supporter", 61.79 + style = "cursor: pointer;", 61.80 + onclick = "document.getElementById('support_content_" .. unique_string .. "').style.display = 'block';" 61.81 + }, 61.82 content = function() 61.83 - ui.container{ 61.84 - attr = { 61.85 - class = "close", 61.86 - style = "cursor: pointer;", 61.87 - onclick = "document.getElementById('support_content').style.display = 'none';" 61.88 - }, 61.89 - content = function() 61.90 - ui.image{ static = "icons/16/cross.png" } 61.91 - end 61.92 + ui.image{ 61.93 + static = "icons/16/thumb_up_green.png" 61.94 } 61.95 - if supporter then 61.96 - ui.link{ 61.97 - content = function() 61.98 - ui.image{ static = "icons/16/thumb_down_red.png" } 61.99 - slot.put(_"Remove my support from this initiative") 61.100 - end, 61.101 - module = "initiative", 61.102 - action = "remove_support", 61.103 - id = initiative.id, 61.104 - routing = { 61.105 - default = { 61.106 - mode = "redirect", 61.107 - module = request.get_module(), 61.108 - view = request.get_view(), 61.109 - id = param.get_id_cgi(), 61.110 - params = param.get_all_cgi() 61.111 - } 61.112 - } 61.113 - } 61.114 - else 61.115 - end 61.116 + slot.put(_"Your are supporter") 61.117 + ui.image{ 61.118 + static = "icons/16/dropdown.png" 61.119 + } 61.120 end 61.121 } 61.122 else 61.123 - if not initiative.revoked then 61.124 - ui.link{ 61.125 + ui.container{ 61.126 + attr = { 61.127 + class = "head head_potential_supporter", 61.128 + style = "cursor: pointer;", 61.129 + onclick = "document.getElementById('support_content_" .. unique_string .. "').style.display = 'block';" 61.130 + }, 61.131 + content = function() 61.132 + ui.image{ 61.133 + static = "icons/16/thumb_up.png" 61.134 + } 61.135 + slot.put(_"Your are potential supporter") 61.136 + ui.image{ 61.137 + static = "icons/16/dropdown.png" 61.138 + } 61.139 + end 61.140 + } 61.141 + end 61.142 + ui.container{ 61.143 + attr = { class = "content", id = "support_content_" .. unique_string .. "" }, 61.144 + content = function() 61.145 + ui.container{ 61.146 + attr = { 61.147 + class = "close", 61.148 + style = "cursor: pointer;", 61.149 + onclick = "document.getElementById('support_content_" .. unique_string .. "').style.display = 'none';" 61.150 + }, 61.151 content = function() 61.152 - ui.image{ static = "icons/16/thumb_up_green.png" } 61.153 - slot.put(_"Support this initiative") 61.154 - end, 61.155 - module = "initiative", 61.156 - action = "add_support", 61.157 - id = initiative.id, 61.158 - routing = { 61.159 - default = { 61.160 - mode = "redirect", 61.161 - module = request.get_module(), 61.162 - view = request.get_view(), 61.163 - id = param.get_id_cgi(), 61.164 - params = param.get_all_cgi() 61.165 - } 61.166 + ui.image{ static = "icons/16/cross.png" } 61.167 + end 61.168 + } 61.169 + if supporter then 61.170 + ui.link{ 61.171 + image = { static = "icons/16/thumb_down_red.png" }, 61.172 + text = _"Remove my support from this initiative", 61.173 + module = "initiative", 61.174 + action = "remove_support", 61.175 + id = initiative.id, 61.176 + routing = routing, 61.177 + partial = partial 61.178 } 61.179 - } 61.180 + else 61.181 + end 61.182 end 61.183 + } 61.184 + else 61.185 + if not initiative.revoked then 61.186 + local params = param.get_all_cgi() 61.187 + params.dyn = nil 61.188 + ui.link{ 61.189 + image = { static = "icons/16/thumb_up_green.png" }, 61.190 + text = _"Support this initiative", 61.191 + module = "initiative", 61.192 + action = "add_support", 61.193 + id = initiative.id, 61.194 + routing = routing, 61.195 + partial = partial 61.196 + } 61.197 end 61.198 end 61.199 +end 61.200 61.201 -end)
62.1 --- a/app/main/timeline/_action/update.lua Tue Feb 02 00:31:06 2010 +0100 62.2 +++ b/app/main/timeline/_action/update.lua Sat Feb 20 22:10:31 2010 +0100 62.3 @@ -48,6 +48,11 @@ 62.4 end 62.5 62.6 local date = param.get("date") 62.7 +trace.debug(param.get("search_from")) 62.8 + 62.9 +if param.get("search_from") == "last_24h" then 62.10 + date = "last_24h" 62.11 +end 62.12 62.13 if date and #date > 0 then 62.14 local setting_key = "liquidfeedback_frontend_timeline_current_date"
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/app/main/timeline/_filter/29_filter.lua Sat Feb 20 22:10:31 2010 +0100 63.3 @@ -0,0 +1,36 @@ 63.4 +if request.get_view() == "index" and not param.get("date") then 63.5 + local setting_key = "liquidfeedback_frontend_timeline_current_options" 63.6 + local setting = Setting:by_pk(app.session.member.id, setting_key) 63.7 + 63.8 + local timeline_params = {} 63.9 + if setting and setting.value then 63.10 + for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do 63.11 + timeline_params["option_" .. event_ident] = true 63.12 + if filter_idents ~= "*" then 63.13 + for filter_ident in filter_idents:gmatch("([^\|]+)") do 63.14 + timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true 63.15 + end 63.16 + end 63.17 + end 63.18 + end 63.19 + 63.20 + local setting_key = "liquidfeedback_frontend_timeline_current_date" 63.21 + local setting = Setting:by_pk(app.session.member.id, setting_key) 63.22 + 63.23 + if setting then 63.24 + timeline_params.date = setting.value 63.25 + else 63.26 + timeline_params.date = "last_24h" 63.27 + end 63.28 + 63.29 + timeline_params.show_options = param.get("show_options", atom.boolean) 63.30 + 63.31 + request.redirect{ 63.32 + module = "timeline", 63.33 + view = "index", 63.34 + params = timeline_params 63.35 + } 63.36 +else 63.37 + execute.inner() 63.38 +end 63.39 +
64.1 --- a/app/main/timeline/_list.lua Tue Feb 02 00:31:06 2010 +0100 64.2 +++ b/app/main/timeline/_list.lua Sat Feb 20 22:10:31 2010 +0100 64.3 @@ -21,10 +21,17 @@ 64.4 attr = { style = "font-size: 75%; font-weight: bold; background-color: #ccc; display: block; margin-bottom: 1ex;"}, 64.5 value = format.time(timeline.occurrence) 64.6 } 64.7 + 64.8 ui.field.text{ 64.9 attr = { style = "font-size: 75%; font-weight: bold;"}, 64.10 value = event_names[timeline.event] or timeline.event 64.11 } 64.12 + if timeline.event == "draft_created" and timeline.count > 1 then 64.13 + ui.field.text{ 64.14 + attr = { style = "font-size: 75%;"}, 64.15 + value = _("(#{more_count} duplicates removed)", { more_count = timeline.count - 1 }) 64.16 + } 64.17 + end 64.18 end 64.19 }, 64.20 {
65.1 --- a/app/main/timeline/index.lua Tue Feb 02 00:31:06 2010 +0100 65.2 +++ b/app/main/timeline/index.lua Sat Feb 20 22:10:31 2010 +0100 65.3 @@ -37,13 +37,10 @@ 65.4 if options_string == current_options then 65.5 active = true 65.6 end 65.7 - timeline_params.date = param.get("date") 65.8 ui.link{ 65.9 - attr = { class = active and "action_active" or nil }, 65.10 - content = function() 65.11 - ui.image{ static = "icons/16/time.png" } 65.12 - slot.put(encode.html(name)) 65.13 - end, 65.14 + image = { static = "icons/16/time.png" }, 65.15 + attr = { class = active and "action_active" or nil }, 65.16 + text = name, 65.17 module = 'timeline', 65.18 action = 'update', 65.19 params = { 65.20 @@ -81,68 +78,100 @@ 65.21 action = "update", 65.22 content = function() 65.23 65.24 + ui.container{ 65.25 65.26 - ui.tag{ 65.27 - tag = "label", 65.28 - attr = { style = "font-size: 130%;" }, 65.29 - content = _"Date" .. ":" 65.30 - } 65.31 - slot.put(" ") 65.32 - local date = param.get("date") 65.33 - if not date or #date == 0 then 65.34 - date = tostring(db:query("select now()::date as date")[1].date) 65.35 - end 65.36 - ui.tag{ 65.37 - tag = "input", 65.38 - attr = { 65.39 - type = "text", 65.40 - id = "timeline_search_date", 65.41 - style = "width: 10em;", 65.42 - onchange = "this.form.submit();", 65.43 - name = "date", 65.44 - value = date 65.45 - }, 65.46 - content = function() end 65.47 - } 65.48 - 65.49 - ui.script{ static = "gregor.js/gregor.js" } 65.50 - util.gregor("timeline_search_date", "document.getElementById('timeline_search_date').form.submit();") 65.51 - 65.52 - 65.53 - ui.link{ 65.54 - attr = { style = "margin-left: 1em; font-size: 130%; font-weight: bold;", onclick = "document.getElementById('timeline_search_date').form.submit();return(false);" }, 65.55 content = function() 65.56 - ui.image{ 65.57 - attr = { style = "margin-right: 0.25em;" }, 65.58 - static = "icons/16/magnifier.png" 65.59 + 65.60 + ui.tag{ 65.61 + tag = "input", 65.62 + attr = { 65.63 + type = "radio", 65.64 + id = "timeline_search_last_24h", 65.65 + name = "search_from", 65.66 + value = "last_24h", 65.67 + checked = param.get("date") == "last_24h" and "checked" or nil 65.68 + }, 65.69 } 65.70 - slot.put(_"Search") 65.71 - end, 65.72 - external = "#", 65.73 - } 65.74 - local show_options = param.get("show_options", atom.boolean) 65.75 - ui.link{ 65.76 - attr = { style = "margin-left: 1em; font-size: 130%;", onclick = "el=document.getElementById('timeline_show_options');el.checked=" .. tostring(not show_options) .. ";el.form.submit();return(false);" }, 65.77 - content = function() 65.78 - ui.image{ 65.79 - attr = { style = "margin-right: 0.25em;" }, 65.80 - static = "icons/16/text_list_bullets.png" 65.81 + 65.82 + ui.tag{ 65.83 + tag = "label", 65.84 + attr = { 65.85 + ["for"] = "timeline_search_last_24h" 65.86 + }, 65.87 + content = " " .. _"last 24 hours" .. " " 65.88 + } 65.89 + 65.90 + ui.tag{ 65.91 + tag = "input", 65.92 + attr = { 65.93 + type = "radio", 65.94 + id = "timeline_search_from_date", 65.95 + name = "search_from", 65.96 + value = "date", 65.97 + checked = not (param.get("date") == "last_24h") and "checked" or nil 65.98 + }, 65.99 } 65.100 - slot.put(not show_options and _"Show filter details" or _"Hide filter details") 65.101 - end, 65.102 - external = "#", 65.103 - } 65.104 65.105 - ui.field.boolean{ 65.106 - attr = { id = "timeline_show_options", style = "display: none;", onchange="this.form.submit();" }, 65.107 - name = "show_options", 65.108 - value = param.get("show_options", atom.boolean) 65.109 - } 65.110 + slot.put(" ") 65.111 + local current_date = param.get("date") 65.112 + if not current_date or #current_date == 0 or current_date == "last_24h" then 65.113 + current_date = tostring(db:query("select now()::date as date")[1].date) 65.114 + end 65.115 + ui.tag{ 65.116 + tag = "input", 65.117 + attr = { 65.118 + type = "text", 65.119 + id = "timeline_search_date", 65.120 + style = "width: 10em;", 65.121 + onchange = "this.form.submit();", 65.122 + onclick = "document.getElementById('timeline_search_from_date').checked = true;", 65.123 + name = "date", 65.124 + value = current_date 65.125 + }, 65.126 + content = function() end 65.127 + } 65.128 + 65.129 + ui.script{ static = "gregor.js/gregor.js" } 65.130 + util.gregor("timeline_search_date", "document.getElementById('timeline_search_date').form.submit();") 65.131 + 65.132 + 65.133 + ui.link{ 65.134 + attr = { style = "margin-left: 1em; font-weight: bold;", onclick = "document.getElementById('timeline_search_date').form.submit();return(false);" }, 65.135 + content = function() 65.136 + ui.image{ 65.137 + attr = { style = "margin-right: 0.25em;" }, 65.138 + static = "icons/16/magnifier.png" 65.139 + } 65.140 + slot.put(_"Search") 65.141 + end, 65.142 + external = "#", 65.143 + } 65.144 + local show_options = param.get("show_options", atom.boolean) 65.145 + ui.link{ 65.146 + attr = { style = "margin-left: 1em;", onclick = "el=document.getElementById('timeline_show_options');el.checked=" .. tostring(not show_options) .. ";el.form.submit();return(false);" }, 65.147 + content = function() 65.148 + ui.image{ 65.149 + attr = { style = "margin-right: 0.25em;" }, 65.150 + static = "icons/16/text_list_bullets.png" 65.151 + } 65.152 + slot.put(not show_options and _"Show filter details" or _"Hide filter details") 65.153 + end, 65.154 + external = "#", 65.155 + } 65.156 65.157 - ui.field.boolean{ 65.158 - attr = { id = "timeline_save", style = "display: none;", onchange="this.form.submit();" }, 65.159 - name = "save", 65.160 - value = false 65.161 + ui.field.boolean{ 65.162 + attr = { id = "timeline_show_options", style = "display: none;", onchange="this.form.submit();" }, 65.163 + name = "show_options", 65.164 + value = param.get("show_options", atom.boolean) 65.165 + } 65.166 + 65.167 + ui.field.boolean{ 65.168 + attr = { id = "timeline_save", style = "display: none;", onchange="this.form.submit();" }, 65.169 + name = "save", 65.170 + value = false 65.171 + } 65.172 + 65.173 + end 65.174 } 65.175 65.176 ui.container{ 65.177 @@ -219,8 +248,6 @@ 65.178 } 65.179 } 65.180 65.181 - slot.put("<br />") 65.182 - 65.183 slot.put("<table>") 65.184 65.185 for i_event_group, event_group in ipairs(event_groups) do 65.186 @@ -255,6 +282,7 @@ 65.187 } 65.188 65.189 local date = param.get("date") 65.190 + 65.191 if not date or #date == 0 then 65.192 date = "today" 65.193 end 65.194 @@ -266,24 +294,50 @@ 65.195 if param.get("option_" .. event, atom.boolean) then 65.196 65.197 local tmp = Timeline:new_selector() 65.198 - :add_where{ "occurrence::date = ?", date } 65.199 - 65.200 - :left_join("draft", nil, "draft.id = timeline.draft_id") 65.201 - :left_join("suggestion", nil, "suggestion.id = timeline.suggestion_id") 65.202 - :left_join("initiative", nil, "initiative.id = timeline.initiative_id or initiative.id = draft.initiative_id or initiative.id = suggestion.initiative_id") 65.203 - :left_join("issue", nil, "issue.id = timeline.issue_id or issue.id = initiative.issue_id") 65.204 - :left_join("area", nil, "area.id = issue.area_id") 65.205 + if event == "draft_created" then 65.206 + tmp 65.207 + :reset_fields() 65.208 + :add_field("max(timeline.occurrence)", "occurrence") 65.209 + :add_field("timeline.event", nil, { "grouped" }) 65.210 + :add_field("timeline.issue_id", nil, { "grouped" }) 65.211 + :add_field("timeline.initiative_id", nil, { "grouped" }) 65.212 + :add_field("max(timeline.draft_id)", "draft_id") 65.213 + :add_field("timeline.suggestion_id", nil, { "grouped" }) 65.214 + :add_field("COUNT(*)", "count") 65.215 + else 65.216 + tmp 65.217 + :add_field("1", "count") 65.218 + end 65.219 65.220 - :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id} ) 65.221 - :left_join("membership", "_membership", { "_membership.area_id = area.id AND _membership.member_id = ?", app.session.member.id} ) 65.222 - :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ?", app.session.member.id} ) 65.223 - :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", app.session.member.id} ) 65.224 + if date == "last_24h" then 65.225 + tmp:add_where{ "occurrence > now() - '24 hours'::interval" } 65.226 + else 65.227 + tmp:add_where{ "occurrence::date = ?::date", date } 65.228 + end 65.229 + tmp 65.230 + :left_join("draft", nil, "draft.id = timeline.draft_id") 65.231 + :left_join("suggestion", nil, "suggestion.id = timeline.suggestion_id") 65.232 + :left_join("initiative", nil, "initiative.id = timeline.initiative_id or initiative.id = draft.initiative_id or initiative.id = suggestion.initiative_id") 65.233 + :left_join("issue", nil, "issue.id = timeline.issue_id or issue.id = initiative.issue_id") 65.234 + :left_join("area", nil, "area.id = issue.area_id") 65.235 65.236 - :add_field("(_interest.member_id NOTNULL)", "is_interested") 65.237 - :add_field("(_initiator.member_id NOTNULL)", "is_initiator") 65.238 - :add_field({"(_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_supporter") 65.239 - :add_field({"EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_potential_supporter") 65.240 - -- :left_join("member", nil, "member.id = timeline.member_id") 65.241 + :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id} ) 65.242 + :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ?", app.session.member.id} ) 65.243 + :left_join("membership", "_membership", { "_membership.area_id = area.id AND _membership.member_id = ?", app.session.member.id} ) 65.244 + :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", app.session.member.id} ) 65.245 + 65.246 + local group 65.247 + if event == "draft_created" then 65.248 + group = { "grouped" } 65.249 + end 65.250 + 65.251 + tmp 65.252 + :add_field("(_interest.member_id NOTNULL)", "is_interested", group) 65.253 + :add_field("(_initiator.member_id NOTNULL)", "is_initiator", group) 65.254 + :add_field({"(_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_supporter", group) 65.255 + :add_field({"EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_potential_supporter", group) 65.256 + -- :left_join("member", nil, "member.id = timeline.member_id", group) 65.257 + 65.258 65.259 tmp:add_where{ "event = ?", event } 65.260 65.261 @@ -310,7 +364,7 @@ 65.262 65.263 if #filters > 0 then 65.264 local filter_string = "(" .. table.concat(filters, ") OR (") .. ")" 65.265 - tmp:add_where{ filter_string, app.session.member.id } 65.266 + tmp:add_where{ filter_string, app.session.member.id, app.session.member.id } 65.267 end 65.268 65.269 if not timeline_selector then 65.270 @@ -327,10 +381,11 @@ 65.271 65.272 local outer_timeline_selector = db:new_selector() 65.273 outer_timeline_selector._class = Timeline 65.274 - outer_timeline_selector:add_field{ "timeline.*" } 65.275 - outer_timeline_selector:from({"($)", { timeline_selector }}, "timeline" ) 65.276 - outer_timeline_selector:add_order_by("occurrence DESC") 65.277 - 65.278 + outer_timeline_selector 65.279 + :add_field{ "timeline.*" } 65.280 + :from({"($)", { timeline_selector }}, "timeline" ) 65.281 + :add_order_by("occurrence DESC") 65.282 + 65.283 slot.put("<br />") 65.284 execute.view{ 65.285 module = "timeline",
66.1 --- a/app/main/timeline/list_filter.lua Tue Feb 02 00:31:06 2010 +0100 66.2 +++ b/app/main/timeline/list_filter.lua Sat Feb 20 22:10:31 2010 +0100 66.3 @@ -2,10 +2,8 @@ 66.4 66.5 slot.select("actions", function() 66.6 ui.link{ 66.7 - content = function() 66.8 - ui.image{ static = "icons/16/cancel.png" } 66.9 - slot.put(_"Back to timeline") 66.10 - end, 66.11 + image = { static = "icons/16/cancel.png" }, 66.12 + text = _"Back to timeline", 66.13 module = "timeline", 66.14 action = "update" 66.15 } 66.16 @@ -22,10 +20,8 @@ 66.17 { 66.18 content = function(timeline_filter) 66.19 ui.link{ 66.20 - attr = { class = "action" }, 66.21 - content = function() 66.22 - slot.put(_"Delete filter") 66.23 - end, 66.24 + attr = { class = "action" }, 66.25 + text = _"Delete filter", 66.26 module = "timeline", 66.27 action = "delete_filter", 66.28 params = {
67.1 --- a/app/main/vote/_action/update.lua Tue Feb 02 00:31:06 2010 +0100 67.2 +++ b/app/main/vote/_action/update.lua Sat Feb 20 22:10:31 2010 +0100 67.3 @@ -10,38 +10,145 @@ 67.4 return false 67.5 end 67.6 67.7 -local direct_voter = DirectVoter:by_pk(issue.id, app.session.member_id) 67.8 +local move_up = param.get("move_up", atom.integer) 67.9 +local move_down = param.get("move_down", atom.integer) 67.10 + 67.11 +if not move_down and not move_up then 67.12 + local direct_voter = DirectVoter:by_pk(issue.id, app.session.member_id) 67.13 + 67.14 + if not direct_voter then 67.15 + direct_voter = DirectVoter:new() 67.16 + direct_voter.issue_id = issue.id 67.17 + direct_voter.member_id = app.session.member_id 67.18 + end 67.19 + 67.20 + direct_voter.autoreject = false 67.21 + direct_voter:save() 67.22 + 67.23 + local scoring = param.get("scoring") 67.24 67.25 -if not direct_voter then 67.26 - direct_voter = DirectVoter:new() 67.27 - direct_voter.issue_id = issue.id 67.28 - direct_voter.member_id = app.session.member_id 67.29 -end 67.30 + for initiative_id, grade in scoring:gmatch("([^:;]+):([^:;]+)") do 67.31 + local initiative_id = tonumber(initiative_id) 67.32 + local grade = tonumber(grade) 67.33 + local initiative = Initiative:by_id(initiative_id) 67.34 + if initiative.issue.id ~= issue.id then 67.35 + error("initiative from wrong issue") 67.36 + end 67.37 + local vote = Vote:by_pk(initiative_id, app.session.member.id) 67.38 + if not vote then 67.39 + vote = Vote:new() 67.40 + vote.issue_id = issue.id 67.41 + vote.initiative_id = initiative.id 67.42 + vote.member_id = app.session.member.id 67.43 + end 67.44 + vote.grade = grade 67.45 + vote:save() 67.46 + end 67.47 + 67.48 +else 67.49 + 67.50 + local tempvoting_string = param.get("scoring") 67.51 67.52 -direct_voter.autoreject = false 67.53 + local tempvotings = {} 67.54 + for match in tempvoting_string:gmatch("([^;]+)") do 67.55 + for initiative_id, grade in match:gmatch("([^:;]+):([^:;]+)") do 67.56 + tempvotings[tonumber(initiative_id)] = tonumber(grade) 67.57 + end 67.58 + end 67.59 + 67.60 + local current_initiative_id = move_up or move_down 67.61 67.62 -direct_voter:save() 67.63 + local current_grade = tempvotings[current_initiative_id] or 0 67.64 + local is_alone = true 67.65 + if current_grade == 0 then 67.66 + is_alone = false 67.67 + else 67.68 + for initiative_id, grade in pairs(tempvotings) do 67.69 + if current_initiative_id ~= initiative_id and grade == current_grade then 67.70 + is_alone = false 67.71 + break 67.72 + end 67.73 + end 67.74 + end 67.75 67.76 - 67.77 -local scoring = param.get("scoring") 67.78 + if move_up and current_grade >= 0 and is_alone then 67.79 + for initiative_id, grade in pairs(tempvotings) do 67.80 + if grade > current_grade then 67.81 + tempvotings[initiative_id] = grade - 1 67.82 + end 67.83 + end 67.84 67.85 -for initiative_id, grade in scoring:gmatch("([^:;]+):([^:;]+)") do 67.86 - local initiative_id = tonumber(initiative_id) 67.87 - local grade = tonumber(grade) 67.88 - local initiative = Initiative:by_id(initiative_id) 67.89 - if initiative.issue.id ~= issue.id then 67.90 - error("initiative from wrong issue") 67.91 + elseif move_up and current_grade >= 0 and not is_alone then 67.92 + for initiative_id, grade in pairs(tempvotings) do 67.93 + if grade > current_grade then 67.94 + tempvotings[initiative_id] = grade + 1 67.95 + end 67.96 + end 67.97 + tempvotings[current_initiative_id] = current_grade + 1 67.98 + 67.99 + elseif move_up and current_grade < 0 and is_alone then 67.100 + tempvotings[current_initiative_id] = current_grade + 1 67.101 + for initiative_id, grade in pairs(tempvotings) do 67.102 + if grade < current_grade then 67.103 + tempvotings[initiative_id] = grade + 1 67.104 + end 67.105 + end 67.106 + 67.107 + elseif move_up and current_grade < 0 and not is_alone then 67.108 + for initiative_id, grade in pairs(tempvotings) do 67.109 + if grade <= current_grade then 67.110 + tempvotings[initiative_id] = grade - 1 67.111 + end 67.112 + end 67.113 + tempvotings[current_initiative_id] = current_grade 67.114 + 67.115 + elseif move_down and current_grade <= 0 and is_alone then 67.116 + for initiative_id, grade in pairs(tempvotings) do 67.117 + if grade < current_grade then 67.118 + tempvotings[initiative_id] = grade + 1 67.119 + end 67.120 + end 67.121 + 67.122 + elseif move_down and current_grade <= 0 and not is_alone then 67.123 + for initiative_id, grade in pairs(tempvotings) do 67.124 + if grade < current_grade then 67.125 + tempvotings[initiative_id] = grade - 1 67.126 + end 67.127 + end 67.128 + tempvotings[current_initiative_id] = current_grade - 1 67.129 + 67.130 + elseif move_down and current_grade > 0 and is_alone then 67.131 + tempvotings[current_initiative_id] = current_grade - 1 67.132 + for initiative_id, grade in pairs(tempvotings) do 67.133 + if grade > current_grade then 67.134 + tempvotings[initiative_id] = grade - 1 67.135 + end 67.136 + end 67.137 + 67.138 + elseif move_down and current_grade > 0 and not is_alone then 67.139 + for initiative_id, grade in pairs(tempvotings) do 67.140 + if grade >= current_grade then 67.141 + tempvotings[initiative_id] = grade + 1 67.142 + end 67.143 + end 67.144 + tempvotings[current_initiative_id] = current_grade 67.145 + 67.146 end 67.147 - local vote = Vote:by_pk(initiative_id, app.session.member.id) 67.148 - if not vote then 67.149 - vote = Vote:new() 67.150 - vote.issue_id = issue.id 67.151 - vote.initiative_id = initiative.id 67.152 - vote.member_id = app.session.member.id 67.153 + 67.154 + local tempvotings_list = {} 67.155 + for key, val in pairs(tempvotings) do 67.156 + tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val) 67.157 end 67.158 - vote.grade = grade 67.159 - vote:save() 67.160 + 67.161 + tempvoting_string = table.concat(tempvotings_list, ";") 67.162 + 67.163 + request.redirect{ 67.164 + module = "vote", 67.165 + view = "list", 67.166 + params = { 67.167 + issue_id = issue.id, 67.168 + scoring = tempvoting_string 67.169 + } 67.170 + } 67.171 + 67.172 end 67.173 - 67.174 -trace.debug(scoring) 67.175 -
68.1 --- a/app/main/vote/list.lua Tue Feb 02 00:31:06 2010 +0100 68.2 +++ b/app/main/vote/list.lua Sat Feb 20 22:10:31 2010 +0100 68.3 @@ -1,26 +1,70 @@ 68.4 +local issue = Issue:by_id(param.get("issue_id"), atom.integer) 68.5 + 68.6 +local member_id = param.get("member_id", atom.integer) 68.7 +local member 68.8 + 68.9 +local readonly = false 68.10 +if member_id then 68.11 + if not issue.closed then 68.12 + error("access denied") 68.13 + end 68.14 + member = Member:by_id(member_id) 68.15 + readonly = true 68.16 +end 68.17 + 68.18 +if member then 68.19 + slot.put_into("title", _("Ballot of '#{member_name}' for issue ##{issue_id}", { 68.20 + member_name = member.name, 68.21 + issue_id = issue.id 68.22 + })) 68.23 +else 68.24 + member = app.session.member 68.25 + slot.put_into("title", _"Voting") 68.26 + 68.27 + slot.select("actions", function() 68.28 + ui.link{ 68.29 + content = function() 68.30 + ui.image{ static = "icons/16/cancel.png" } 68.31 + slot.put(_"Cancel") 68.32 + end, 68.33 + module = "issue", 68.34 + view = "show", 68.35 + id = issue.id 68.36 + } 68.37 + end) 68.38 + 68.39 +end 68.40 + 68.41 + 68.42 local warning_text = _"Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon." 68.43 68.44 ui.script{ static = "js/browser_warning.js" } 68.45 ui.script{ script = "checkBrowser(" .. encode.json(_"Your web browser is not fully supported yet." .. " " .. warning_text:gsub("\n", "\n\n")) .. ");" } 68.46 68.47 -ui.tag{ 68.48 - tag = "noscript", 68.49 - content = function() 68.50 - slot.put(_"JavaScript is disabled or not available." .. " " .. encode.html_newlines(warning_text)) 68.51 + 68.52 +local tempvoting_string = param.get("scoring") 68.53 + 68.54 +local tempvotings = {} 68.55 +if tempvoting_string then 68.56 + for match in tempvoting_string:gmatch("([^;]+)") do 68.57 + for initiative_id, grade in match:gmatch("([^:;]+):([^:;]+)") do 68.58 + tempvotings[tonumber(initiative_id)] = tonumber(grade) 68.59 + end 68.60 end 68.61 -} 68.62 - 68.63 +end 68.64 68.65 -local issue = Issue:by_id(param.get("issue_id"), atom.integer) 68.66 - 68.67 -local initiatives = issue.initiatives 68.68 +local initiatives = issue:get_reference_selector("initiatives"):add_where("initiative.admitted"):exec() 68.69 68.70 local min_grade = -1; 68.71 local max_grade = 1; 68.72 68.73 for i, initiative in ipairs(initiatives) do 68.74 -- TODO performance 68.75 - initiative.vote = Vote:by_pk(initiative.id, app.session.member.id) 68.76 + initiative.vote = Vote:by_pk(initiative.id, member.id) 68.77 + if tempvotings[initiative.id] then 68.78 + initiative.vote = {} 68.79 + initiative.vote.grade = tempvotings[initiative.id] 68.80 + end 68.81 if initiative.vote then 68.82 if initiative.vote.grade > max_grade then 68.83 max_grade = initiative.vote.grade 68.84 @@ -41,28 +85,59 @@ 68.85 end 68.86 end 68.87 68.88 -slot.put_into("title", _"Voting") 68.89 +local approval_count, disapproval_count = 0, 0 68.90 +for i = min_grade, -1 do 68.91 + if #sections[i] > 0 then 68.92 + disapproval_count = disapproval_count + 1 68.93 + end 68.94 +end 68.95 +local approval_count = 0 68.96 +for i = 1, max_grade do 68.97 + if #sections[i] > 0 then 68.98 + approval_count = approval_count + 1 68.99 + end 68.100 +end 68.101 68.102 -slot.select("actions", function() 68.103 - ui.link{ 68.104 - content = function() 68.105 - ui.image{ static = "icons/16/cancel.png" } 68.106 - slot.put(_"Cancel") 68.107 - end, 68.108 - module = "issue", 68.109 - view = "show", 68.110 - id = issue.id 68.111 - } 68.112 -end) 68.113 - 68.114 -util.help("vote.list", _"Voting") 68.115 68.116 68.117 -slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>') 68.118 -slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>') 68.119 +if not readonly then 68.120 + util.help("vote.list", _"Voting") 68.121 + slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>') 68.122 + slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>') 68.123 +end 68.124 + 68.125 +ui.script{ 68.126 + script = function() 68.127 + slot.put( 68.128 + "voting_text_approval_single = ", encode.json(_"Approval [single entry]"), ";\n", 68.129 + "voting_text_approval_multi = ", encode.json(_"Approval [many entries]"), ";\n", 68.130 + "voting_text_first_preference_single = ", encode.json(_"Approval (first preference) [single entry]"), ";\n", 68.131 + "voting_text_first_preference_multi = ", encode.json(_"Approval (first preference) [many entries]"), ";\n", 68.132 + "voting_text_second_preference_single = ", encode.json(_"Approval (second preference) [single entry]"), ";\n", 68.133 + "voting_text_second_preference_multi = ", encode.json(_"Approval (second preference) [many entries]"), ";\n", 68.134 + "voting_text_third_preference_single = ", encode.json(_"Approval (third preference) [single entry]"), ";\n", 68.135 + "voting_text_third_preference_multi = ", encode.json(_"Approval (third preference) [many entries]"), ";\n", 68.136 + "voting_text_numeric_preference_single = ", encode.json(_"Approval (#th preference) [single entry]"), ";\n", 68.137 + "voting_text_numeric_preference_multi = ", encode.json(_"Approval (#th preference) [many entries]"), ";\n", 68.138 + "voting_text_abstention_single = ", encode.json(_"Abstention [single entry]"), ";\n", 68.139 + "voting_text_abstention_multi = ", encode.json(_"Abstention [many entries]"), ";\n", 68.140 + "voting_text_disapproval_above_one_single = ", encode.json(_"Disapproval (prefer to lower block) [single entry]"), ";\n", 68.141 + "voting_text_disapproval_above_one_multi = ", encode.json(_"Disapproval (prefer to lower block) [many entries]"), ";\n", 68.142 + "voting_text_disapproval_above_many_single = ", encode.json(_"Disapproval (prefer to lower blocks) [single entry]"), ";\n", 68.143 + "voting_text_disapproval_above_many_multi = ", encode.json(_"Disapproval (prefer to lower blocks) [many entries]"), ";\n", 68.144 + "voting_text_disapproval_above_last_single = ", encode.json(_"Disapproval (prefer to last block) [single entry]"), ";\n", 68.145 + "voting_text_disapproval_above_last_multi = ", encode.json(_"Disapproval (prefer to last block) [many entries]"), ";\n", 68.146 + "voting_text_disapproval_single = ", encode.json(_"Disapproval [single entry]"), ";\n", 68.147 + "voting_text_disapproval_multi = ", encode.json(_"Disapproval [many entries]"), ";\n" 68.148 + ) 68.149 + end 68.150 +} 68.151 68.152 ui.form{ 68.153 - attr = { id = "voting_form" }, 68.154 + attr = { 68.155 + id = "voting_form", 68.156 + class = readonly and "voting_form_readonly" or "voting_form_active" 68.157 + }, 68.158 module = "vote", 68.159 action = "update", 68.160 params = { issue_id = issue.id }, 68.161 @@ -75,21 +150,42 @@ 68.162 } 68.163 }, 68.164 content = function() 68.165 - slot.put('<input type="hidden" name="scoring" value=""/>') 68.166 - -- TODO abstrahieren 68.167 - ui.tag{ 68.168 - tag = "input", 68.169 - attr = { 68.170 - type = "button", 68.171 - class = "voting_done", 68.172 - value = _"Finish voting" 68.173 + if not readonly then 68.174 + local scoring = param.get("scoring") 68.175 + if not scoring then 68.176 + for i, initiative in ipairs(initiatives) do 68.177 + local vote = initiative.vote 68.178 + if vote then 68.179 + tempvotings[initiative.id] = vote.grade 68.180 + end 68.181 + end 68.182 + local tempvotings_list = {} 68.183 + for key, val in pairs(tempvotings) do 68.184 + tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val) 68.185 + end 68.186 + if #tempvotings_list > 0 then 68.187 + scoring = table.concat(tempvotings_list, ";") 68.188 + else 68.189 + scoring = "" 68.190 + end 68.191 + end 68.192 + slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>') 68.193 + -- TODO abstrahieren 68.194 + ui.tag{ 68.195 + tag = "input", 68.196 + attr = { 68.197 + type = "button", 68.198 + class = "voting_done", 68.199 + value = _"Finish voting" 68.200 + } 68.201 } 68.202 - } 68.203 + end 68.204 ui.container{ 68.205 attr = { id = "voting" }, 68.206 content = function() 68.207 + local approval_index, disapproval_index = 0, 0 68.208 for grade = max_grade, min_grade, -1 do 68.209 - local section = sections[grade] 68.210 + local entries = sections[grade] 68.211 local class 68.212 if grade > 0 then 68.213 class = "approval" 68.214 @@ -98,75 +194,199 @@ 68.215 else 68.216 class = "abstention" 68.217 end 68.218 - ui.container{ 68.219 - attr = { class = class }, 68.220 - content = function() 68.221 - slot.put('<div class="cathead"></div>') 68.222 - for i, initiative in ipairs(section) do 68.223 - ui.container{ 68.224 - attr = { 68.225 - class = "movable", 68.226 - id = "entry_" .. tostring(initiative.id) 68.227 - }, 68.228 - content = function() 68.229 - local initiators_selector = initiative:get_reference_selector("initiating_members") 68.230 - :add_where("accepted") 68.231 - local initiators = initiators_selector:exec() 68.232 - local initiator_names = {} 68.233 - for i, initiator in ipairs(initiators) do 68.234 - initiator_names[#initiator_names+1] = initiator.name 68.235 + if 68.236 + #entries > 0 or 68.237 + (grade == 1 and not approval_used) or 68.238 + (grade == -1 and not disapproval_used) or 68.239 + grade == 0 68.240 + then 68.241 + ui.container{ 68.242 + attr = { class = class }, 68.243 + content = function() 68.244 + local heading 68.245 + if class == "approval" then 68.246 + approval_used = true 68.247 + approval_index = approval_index + 1 68.248 + if approval_count > 1 then 68.249 + if approval_index == 1 then 68.250 + if #entries == 1 then 68.251 + heading = _"Approval (first preference) [single entry]" 68.252 + else 68.253 + heading = _"Approval (first preference) [many entries]" 68.254 + end 68.255 + elseif approval_index == 2 then 68.256 + if #entries == 1 then 68.257 + heading = _"Approval (second preference) [single entry]" 68.258 + else 68.259 + heading = _"Approval (second preference) [many entries]" 68.260 + end 68.261 + elseif approval_index == 3 then 68.262 + if #entries == 1 then 68.263 + heading = _"Approval (third preference) [single entry]" 68.264 + else 68.265 + heading = _"Approval (third preference) [many entries]" 68.266 + end 68.267 + else 68.268 + if #entries == 1 then 68.269 + heading = _"Approval (#th preference) [single entry]" 68.270 + else 68.271 + heading = _"Approval (#th preference) [many entries]" 68.272 + end 68.273 + end 68.274 + else 68.275 + if #entries == 1 then 68.276 + heading = _"Approval [single entry]" 68.277 + else 68.278 + heading = _"Approval [many entries]" 68.279 + end 68.280 + end 68.281 + elseif class == "abstention" then 68.282 + if #entries == 1 then 68.283 + heading = _"Abstention [single entry]" 68.284 + else 68.285 + heading = _"Abstention [many entries]" 68.286 + end 68.287 + elseif class == "disapproval" then 68.288 + disapproval_used = true 68.289 + disapproval_index = disapproval_index + 1 68.290 + if disapproval_count > disapproval_index + 1 then 68.291 + if #entries == 1 then 68.292 + heading = _"Disapproval (prefer to lower blocks) [single entry]" 68.293 + else 68.294 + heading = _"Disapproval (prefer to lower blocks) [many entries]" 68.295 + end 68.296 + elseif disapproval_count == 2 and disapproval_index == 1 then 68.297 + if #entries == 1 then 68.298 + heading = _"Disapproval (prefer to lower block) [single entry]" 68.299 + else 68.300 + heading = _"Disapproval (prefer to lower block) [many entries]" 68.301 + end 68.302 + elseif disapproval_index == disapproval_count - 1 then 68.303 + if #entries == 1 then 68.304 + heading = _"Disapproval (prefer to last block) [single entry]" 68.305 + else 68.306 + heading = _"Disapproval (prefer to last block) [many entries]" 68.307 + end 68.308 + else 68.309 + if #entries == 1 then 68.310 + heading = _"Disapproval [single entry]" 68.311 + else 68.312 + heading = _"Disapproval [many entries]" 68.313 end 68.314 - local initiator_names_string = table.concat(initiator_names, ", ") 68.315 - ui.container{ 68.316 - attr = { style = "float: right;" }, 68.317 - content = function() 68.318 - ui.link{ 68.319 - attr = { class = "clickable" }, 68.320 - content = _"Show", 68.321 - module = "initiative", 68.322 - view = "show", 68.323 - id = initiative.id 68.324 + end 68.325 + end 68.326 + ui.tag { 68.327 + tag = "div", 68.328 + attr = { class = "cathead" }, 68.329 + content = heading 68.330 + } 68.331 + for i, initiative in ipairs(entries) do 68.332 + ui.container{ 68.333 + attr = { 68.334 + class = "movable", 68.335 + id = "entry_" .. tostring(initiative.id) 68.336 + }, 68.337 + content = function() 68.338 + local initiators_selector = initiative:get_reference_selector("initiating_members") 68.339 + :add_where("accepted") 68.340 + local initiators = initiators_selector:exec() 68.341 + local initiator_names = {} 68.342 + for i, initiator in ipairs(initiators) do 68.343 + initiator_names[#initiator_names+1] = initiator.name 68.344 + end 68.345 + local initiator_names_string = table.concat(initiator_names, ", ") 68.346 + ui.container{ 68.347 + attr = { style = "float: right;" }, 68.348 + content = function() 68.349 + ui.link{ 68.350 + attr = { class = "clickable" }, 68.351 + content = _"Show", 68.352 + module = "initiative", 68.353 + view = "show", 68.354 + id = initiative.id 68.355 + } 68.356 + slot.put(" ") 68.357 + ui.link{ 68.358 + attr = { class = "clickable", target = "_blank" }, 68.359 + content = _"(new window)", 68.360 + module = "initiative", 68.361 + view = "show", 68.362 + id = initiative.id 68.363 + } 68.364 + if not readonly then 68.365 + slot.put(" ") 68.366 + ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" } 68.367 + end 68.368 + end 68.369 + } 68.370 + if not readonly then 68.371 + ui.container{ 68.372 + attr = { style = "float: left;" }, 68.373 + content = function() 68.374 + ui.tag{ 68.375 + tag = "input", 68.376 + attr = { 68.377 + onclick = "voting_moveUp(this.parentNode.parentNode); return(false);", 68.378 + name = "move_up", 68.379 + value = initiative.id, 68.380 + class = not disabled and "clickable" or nil, 68.381 + type = "image", 68.382 + src = encode.url{ static = "icons/move_up.png" }, 68.383 + alt = _"Move up" 68.384 + } 68.385 + } 68.386 + slot.put(" ") 68.387 + ui.tag{ 68.388 + tag = "input", 68.389 + attr = { 68.390 + onclick = "voting_moveDown(this.parentNode.parentNode); return(false);", 68.391 + name = "move_down", 68.392 + value = initiative.id, 68.393 + class = not disabled and "clickable" or nil, 68.394 + type = "image", 68.395 + src = encode.url{ static = "icons/move_down.png" }, 68.396 + alt = _"Move down" 68.397 + } 68.398 + } 68.399 + slot.put(" ") 68.400 + end 68.401 } 68.402 - slot.put(" ") 68.403 - ui.link{ 68.404 - attr = { class = "clickable", target = "_blank" }, 68.405 - content = _"(new window)", 68.406 - module = "initiative", 68.407 - view = "show", 68.408 - id = initiative.id 68.409 - } 68.410 - slot.put(" ") 68.411 - ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" } 68.412 end 68.413 - } 68.414 - slot.put(encode.html(initiative.shortened_name)) 68.415 - if #initiators > 1 then 68.416 ui.container{ 68.417 - attr = { style = "font-size: 80%;" }, 68.418 - content = _"Initiators" .. ": " .. initiator_names_string 68.419 - } 68.420 - else 68.421 - ui.container{ 68.422 - attr = { style = "font-size: 80%;" }, 68.423 - content = _"Initiator" .. ": " .. initiator_names_string 68.424 + content = function() 68.425 + slot.put(encode.html(initiative.shortened_name)) 68.426 + if #initiators > 1 then 68.427 + ui.container{ 68.428 + attr = { style = "font-size: 80%;" }, 68.429 + content = _"Initiators" .. ": " .. initiator_names_string 68.430 + } 68.431 + else 68.432 + ui.container{ 68.433 + attr = { style = "font-size: 80%;" }, 68.434 + content = _"Initiator" .. ": " .. initiator_names_string 68.435 + } 68.436 + end 68.437 + end 68.438 } 68.439 end 68.440 - end 68.441 - } 68.442 + } 68.443 + end 68.444 end 68.445 - end 68.446 - } 68.447 + } 68.448 + end 68.449 end 68.450 end 68.451 } 68.452 - ui.tag{ 68.453 - tag = "input", 68.454 - attr = { 68.455 - type = "button", 68.456 - class = "voting_done", 68.457 - value = _"Finish voting" 68.458 + if not readonly then 68.459 + ui.tag{ 68.460 + tag = "input", 68.461 + attr = { 68.462 + type = "button", 68.463 + class = "voting_done", 68.464 + value = _"Finish voting" 68.465 + } 68.466 } 68.467 - } 68.468 + end 68.469 end 68.470 } 68.471
69.1 --- a/config/default.lua Tue Feb 02 00:31:06 2010 +0100 69.2 +++ b/config/default.lua Sat Feb 20 22:10:31 2010 +0100 69.3 @@ -1,5 +1,5 @@ 69.4 config.app_name = "LiquidFeedback" 69.5 -config.app_version = "beta9" 69.6 +config.app_version = "beta10" 69.7 69.8 config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)" 69.9 69.10 @@ -27,6 +27,11 @@ 69.11 69.12 config.download_use_terms = "=== Nutzungsbedingungen ===\nAlles ist verboten" 69.13 69.14 +request.set_allowed_json_request_slots{ "title", "actions", "support", "default", "trace", "system_error" } 69.15 + 69.16 +if request.get_json_request_slots() then 69.17 + request.force_absolute_baseurl() 69.18 +end 69.19 69.20 request.set_404_route{ module = 'index', view = '404' } 69.21
70.1 --- a/env/ui/bargraph.lua Tue Feb 02 00:31:06 2010 +0100 70.2 +++ b/env/ui/bargraph.lua Sat Feb 20 22:10:31 2010 +0100 70.3 @@ -1,21 +1,33 @@ 70.4 function ui.bargraph(args) 70.5 + local text = "" 70.6 + for i, bar in ipairs(args.bars) do 70.7 + if #text > 0 then 70.8 + text = text .. " / " 70.9 + end 70.10 + text = text .. tostring(bar.value) 70.11 + end 70.12 ui.container{ 70.13 attr = { 70.14 - class = "bargraph", 70.15 + class = args.class or "bargraph", 70.16 + title = tostring(text) 70.17 }, 70.18 content = function() 70.19 + local at_least_one_bar = false 70.20 for i, bar in ipairs(args.bars) do 70.21 if bar.value > 0 then 70.22 + at_least_one_bar = true 70.23 local value = bar.value * args.width / args.max_value 70.24 ui.container{ 70.25 attr = { 70.26 style = "width: " .. tostring(value) .. "px; background-color: " .. bar.color .. ";", 70.27 - title = tostring(bar.value) 70.28 }, 70.29 content = function() slot.put(" ") end 70.30 } 70.31 end 70.32 end 70.33 + if not at_least_one_bar then 70.34 + slot.put(" ") 70.35 + end 70.36 end 70.37 } 70.38 end
71.1 --- a/env/ui/field/rank.lua Tue Feb 02 00:31:06 2010 +0100 71.2 +++ b/env/ui/field/rank.lua Sat Feb 20 22:10:31 2010 +0100 71.3 @@ -5,11 +5,11 @@ 71.4 attr = { class = "rank" }, 71.5 content = function() 71.6 if value == 1 then 71.7 - ui.image{ static = "icons/16/award_star_gold_2.png" } 71.8 + ui.image{ attr = args.image_attr, static = "icons/16/award_star_gold_2.png" } 71.9 elseif value then 71.10 - ui.image{ static = "icons/16/award_star_silver_2.png" } 71.11 + ui.image{ attr = args.image_attr, static = "icons/16/award_star_silver_2.png" } 71.12 else 71.13 - ui.image{ static = "icons/16/cross.png" } 71.14 + ui.image{ attr = args.image_attr, static = "icons/16/cross.png" } 71.15 end 71.16 if value then 71.17 ui.tag{
72.1 --- a/env/ui/filter.lua Tue Feb 02 00:31:06 2010 +0100 72.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 72.3 @@ -1,40 +0,0 @@ 72.4 -function ui.filter(args) 72.5 - local name = args.name or "filter" 72.6 - local current_filter = atom.string:load(cgi.params[name]) or args.filters[1].name 72.7 - local id = param.get_id_cgi() 72.8 - local params = param.get_all_cgi() 72.9 - ui.container{ 72.10 - attr = { class = "ui_filter" }, 72.11 - content = function() 72.12 - ui.container{ 72.13 - attr = { class = "ui_filter_head" }, 72.14 - content = function() 72.15 - slot.put(_"Filter") 72.16 - slot.put(": ") 72.17 - for i, filter in ipairs(args.filters) do 72.18 - params[name] = filter.name 72.19 - local attr = {} 72.20 - if current_filter == filter.name then 72.21 - attr.class = "active" 72.22 - filter.selector_modifier(args.selector, true) 72.23 - end 72.24 - ui.link{ 72.25 - attr = attr, 72.26 - module = request.get_module(), 72.27 - view = request.get_view(), 72.28 - id = id, 72.29 - params = params, 72.30 - content = filter.label 72.31 - } 72.32 - end 72.33 - end 72.34 - } 72.35 - ui.container{ 72.36 - attr = { class = "ui_filter_content" }, 72.37 - content = function() 72.38 - args.content() 72.39 - end 72.40 - } 72.41 - end 72.42 - } 72.43 -end
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/env/ui/is_for_partial_load.lua Sat Feb 20 22:10:31 2010 +0100 73.3 @@ -0,0 +1,3 @@ 73.4 +function ui.is_for_partial_load() 73.5 + return ui._partial_load 73.6 +end 73.7 \ No newline at end of file
74.1 --- a/env/ui/order.lua Tue Feb 02 00:31:06 2010 +0100 74.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 74.3 @@ -1,44 +0,0 @@ 74.4 -function ui.order(args) 74.5 - local name = args.name or "order" 74.6 - local current_order = atom.string:load(cgi.params[name]) or args.options[1].name 74.7 - local id = param.get_id_cgi() 74.8 - local params = param.get_all_cgi() 74.9 - ui.container{ 74.10 - attr = { class = "ui_order" }, 74.11 - content = function() 74.12 - ui.container{ 74.13 - attr = { class = "ui_order_head" }, 74.14 - content = function() 74.15 - slot.put(_"Order by") 74.16 - slot.put(": ") 74.17 - for i, option in ipairs(args.options) do 74.18 - params[name] = option.name 74.19 - local attr = {} 74.20 - if current_order == option.name then 74.21 - attr.class = "active" 74.22 - if option.selector_modifier then 74.23 - option.selector_modifier(args.selector) 74.24 - else 74.25 - args.selector:add_order_by(option.order_by) 74.26 - end 74.27 - end 74.28 - ui.link{ 74.29 - attr = attr, 74.30 - module = request.get_module(), 74.31 - view = request.get_view(), 74.32 - id = id, 74.33 - params = params, 74.34 - content = option.label 74.35 - } 74.36 - end 74.37 - end 74.38 - } 74.39 - ui.container{ 74.40 - attr = { class = "ui_order_content" }, 74.41 - content = function() 74.42 - args.content() 74.43 - end 74.44 - } 74.45 - end 74.46 - } 74.47 -end
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/env/ui/partial_load.lua Sat Feb 20 22:10:31 2010 +0100 75.3 @@ -0,0 +1,55 @@ 75.4 +function ui.partial_load(args) 75.5 + local hourglass_target = ui._partial.hourglass_target 75.6 + local target = ui._partial.target 75.7 + local id = param.get_id_cgi() 75.8 + local module = ui._partial.module 75.9 + local view = ui._partial.view 75.10 + local cgi_params = cgi.params 75.11 + 75.12 + local params = { 75.13 + } 75.14 + 75.15 + if ui._partial and ui._partial.static_params then 75.16 + for key, value in pairs(ui._partial.static_params) do 75.17 + params[key] = value 75.18 + end 75.19 + end 75.20 + if ui._partial and ui._partial.params then 75.21 + for i, param_name in ipairs(ui._partial.params) do 75.22 + params[param_name] = cgi_params[param_name] 75.23 + end 75.24 + end 75.25 + if args.params then 75.26 + for key, value in pairs(args.params) do 75.27 + params[key] = value 75.28 + end 75.29 + end 75.30 + 75.31 + request.force_absolute_baseurl() 75.32 + 75.33 + return 75.34 + 'var hourglass_el = document.getElementById("' .. hourglass_target .. '");' .. 75.35 + 'var hourglass_src = hourglass_el.src;' .. 75.36 + 'hourglass_el.src = "' .. encode.url{ static = "icons/16/connect.png" } .. '";' .. 75.37 + 'partialMultiLoad(' .. 75.38 + '{ trace: "trace", system_error: "system_error", ' .. target .. ': "default" },' .. 75.39 + '{},' .. 75.40 + '"error",' .. 75.41 + '"' .. encode.url{ 75.42 + module = module, 75.43 + view = view, 75.44 + id = id, 75.45 + params = params 75.46 + } .. '&_webmcp_json_slots[]=default&_webmcp_json_slots[]=trace&_webmcp_json_slots[]=system_error",' .. 75.47 + '{},' .. 75.48 + '{},' .. 75.49 + 'function() {' .. 75.50 + 'hourglass_el.src = hourglass_src;' .. 75.51 + '},' .. 75.52 + 'function() {' .. 75.53 + 'hourglass_el.src = hourglass_src;' .. 75.54 + '}' .. 75.55 + '); ' .. 75.56 + 'return(false);' 75.57 +end 75.58 +
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/env/ui/partial_set_param_names.lua Sat Feb 20 22:10:31 2010 +0100 76.3 @@ -0,0 +1,6 @@ 76.4 +function ui.partial_set_param_names(args) 76.5 + if not ui._partial then 76.6 + ui._partial = {} 76.7 + end 76.8 + ui._partial.params = args 76.9 +end
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/env/ui/set_for_partial_load.lua Sat Feb 20 22:10:31 2010 +0100 77.3 @@ -0,0 +1,3 @@ 77.4 +function ui.set_for_partial_load() 77.5 + ui._partial_load = true 77.6 +end 77.7 \ No newline at end of file
78.1 --- a/env/ui/tabs.lua Tue Feb 02 00:31:06 2010 +0100 78.2 +++ b/env/ui/tabs.lua Sat Feb 20 22:10:31 2010 +0100 78.3 @@ -1,41 +1,239 @@ 78.4 -function ui.tabs(tabs) 78.5 - ui.container{ 78.6 - attr = { class = "ui_tabs" }, 78.7 - content = function() 78.8 +if config.user_tab_mode == "accordeon" or config.user_tab_mode == "accordeon_first_expanded" or config.user_tab_mode == "accordeon_all_expanded" then 78.9 + 78.10 + function ui.tabs(tabs) 78.11 + local params = param.get_all_cgi() 78.12 + local current_tabs_string = params["tab"] 78.13 + local current_tabs = {} 78.14 + if current_tabs_string then 78.15 + for current_tab in current_tabs_string:gmatch("([^%|]+)") do 78.16 + current_tabs[current_tab] = current_tab 78.17 + end 78.18 + end 78.19 + 78.20 + local unique_string = param.get("tab_id") or multirand.string(16, '0123456789abcdef') 78.21 + 78.22 + function render_tab(tab, first) 78.23 local params = param.get_all_cgi() 78.24 - local current_tab = params["tab"] 78.25 - ui.container{ 78.26 - attr = { class = "ui_tabs_links" }, 78.27 + local active = false 78.28 + for current_tab in pairs(current_tabs) do 78.29 + if tab.name == current_tab then 78.30 + active = true 78.31 + end 78.32 + end 78.33 + if config.user_tab_mode == "accordeon_first_expanded" then 78.34 + if first and current_tabs_string == nil then 78.35 + active = true 78.36 + end 78.37 + end 78.38 + local link_tabs = {} 78.39 + if config.user_tab_mode == "accordeon" 78.40 + or config.user_tab_mode == "accordeon_first_expanded" 78.41 + or config.user_tab_mode == "accordeon_all_expanded" and current_tabs_string 78.42 + then 78.43 + if not current_tabs_string and not first then 78.44 + link_tabs[tabs[1].name] = true 78.45 + end 78.46 + for current_tab in pairs(current_tabs) do 78.47 + if current_tab ~= tab.name then 78.48 + link_tabs[current_tab] = true 78.49 + end 78.50 + end 78.51 + elseif config.user_tab_mode == "accordeon_all_expanded" and not current_tabs_string then 78.52 + for i, current_tab in ipairs(tabs) do 78.53 + if current_tab.name ~= tab.name then 78.54 + link_tabs[current_tab.name] = true 78.55 + end 78.56 + end 78.57 + end 78.58 + if not active then 78.59 + link_tabs[tab.name] = true 78.60 + end 78.61 + local link_tab_string = "" 78.62 + for link_tab in pairs(link_tabs) do 78.63 + if #link_tab_string > 0 then 78.64 + link_tab_string = link_tab_string .. "|" 78.65 + end 78.66 + link_tab_string = link_tab_string .. link_tab 78.67 + end 78.68 + params["tab"] = link_tab_string 78.69 + local onclick 78.70 + if not tab.content then 78.71 + onclick = 78.72 + 'if (ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"]) {' .. 78.73 + 'el=document.getElementById("tab' .. unique_string .. '_content_' .. tab.name .. '");' .. 78.74 + 'el.innerHTML="";' .. 78.75 + 'el.style.display="none";' .. 78.76 + 'ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"]=false' .. 78.77 + '} else {' .. 78.78 + 'ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"]=true;' .. 78.79 + 'document.getElementById("tab' .. unique_string .. '_content_' .. tab.name .. '").style.display="block"; ' .. 78.80 + ui._partial_load_js{ 78.81 + params = { tab = tab.name } 78.82 + } .. 78.83 + '};' .. 78.84 + 'return(false);' 78.85 + end 78.86 + ui.link{ 78.87 + attr = { 78.88 + name = "tab_" .. tab.name, 78.89 + class = ( 78.90 + tab.name == current_tab and "ui_tabs_accordeon_head selected" or 78.91 + not current_tab and i == 1 and "ui_tabs_accordeon_head selected" or 78.92 + "ui_tabs_accordeon_head" 78.93 + ), 78.94 + id = "tab" .. unique_string .. "_head_" .. tab.name, 78.95 + onclick = onclick, 78.96 + }, 78.97 + module = request.get_module(), 78.98 + view = request.get_view(), 78.99 + id = param.get_id_cgi(), 78.100 + params = params, 78.101 + anchor = "tab" .. unique_string .. "_" .. tab.name, 78.102 content = function() 78.103 - for i, tab in ipairs(tabs) do 78.104 - params["tab"] = i > 1 and tab.name or nil 78.105 - ui.link{ 78.106 - attr = { 78.107 - class = ( 78.108 - tab.name == current_tab and "selected" or 78.109 - not current_tab and i == 1 and "selected" or 78.110 - "" 78.111 - ) 78.112 - }, 78.113 - module = request.get_module(), 78.114 - view = request.get_view(), 78.115 - id = param.get_id_cgi(), 78.116 - text = tab.label, 78.117 - params = params 78.118 + if tab.icon then 78.119 + if not tab.icon.attr then 78.120 + tab.icon.attr = {} 78.121 + end 78.122 + tab.icon.attr.id = "tab" .. unique_string .. "_icon_" .. tab.name 78.123 + tab.icon.attr.width = 16 78.124 + tab.icon.attr.height = 16 78.125 + ui.image(tab.icon) 78.126 + end 78.127 + slot.put(tab.label) 78.128 + end 78.129 + } 78.130 + local expanded = active or not request.get_json_request_slots() and config.user_tab_mode == "accordeon_all_expanded" and not current_tabs_string 78.131 + ui.container{ 78.132 + attr = { 78.133 + class = "ui_tabs_accordeon_content", 78.134 + style = not expanded and "display: none;" or nil, 78.135 + id = "tab" .. unique_string .. "_content_" .. tab.name 78.136 + }, 78.137 + content = function() 78.138 + if expanded then 78.139 + ui.script{ script = 'ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"] = true;' } 78.140 + execute.view{ 78.141 + module = tab.module, 78.142 + view = tab.view, 78.143 + id = tab.id, 78.144 + params = tab.params 78.145 } 78.146 - slot.put(" ") 78.147 + else 78.148 + slot.put(" ") 78.149 end 78.150 end 78.151 } 78.152 + end 78.153 + 78.154 + if not request.get_json_request_slots() or not current_tabs_string then 78.155 + ui.script{ script = "ui_tabs_active['" .. unique_string .. "'] = {};" } 78.156 + ui.container{ 78.157 + attr = { class = "ui_tabs" }, 78.158 + content = function() 78.159 + for i, tab in ipairs(tabs) do 78.160 + local static_params = tabs.static_params or {} 78.161 + static_params.tab = tab.name 78.162 + static_params.tab_id = unique_string 78.163 + ui.partial{ 78.164 + module = tabs.module, 78.165 + view = tabs.view, 78.166 + id = tabs.id, 78.167 + params = static_params, 78.168 + param_names = { "page" }, 78.169 + hourglass_target = "tab" .. unique_string .. "_icon_" .. tab.name, 78.170 + target = "tab" .. unique_string .. "_content_" .. tab.name, 78.171 + content = function() 78.172 + render_tab(tab, i == 1) 78.173 + end 78.174 + } 78.175 + end 78.176 + end 78.177 + } 78.178 + else 78.179 + local dyntab 78.180 for i, tab in ipairs(tabs) do 78.181 - if tab.name == current_tab or not current_tab and i == 1 then 78.182 - ui.container{ 78.183 - attr = { class = "ui_tabs_content" }, 78.184 - content = tab.content 78.185 - } 78.186 + if tab.name == current_tabs_string then 78.187 + dyntab = tab 78.188 end 78.189 end 78.190 + if dyntab then 78.191 + local static_params = tabs.static_params or {} 78.192 + static_params.tab = dyntab.name 78.193 + static_params.tab_id = unique_string 78.194 + dyntab.params.tab_id = unique_string 78.195 + ui.partial{ 78.196 + module = tabs.module, 78.197 + view = tabs.view, 78.198 + id = tabs.id, 78.199 + params = static_params, 78.200 + param_names = { "page" }, 78.201 + hourglass_target = "tab" .. unique_string .. "_icon_" .. dyntab.name, 78.202 + target = "tab" .. unique_string .. "_content_" .. dyntab.name, 78.203 + content = function() 78.204 + execute.view{ 78.205 + module = dyntab.module, 78.206 + view = dyntab.view, 78.207 + id = dyntab.id, 78.208 + params = dyntab.params, 78.209 + } 78.210 + end 78.211 + } 78.212 + end 78.213 end 78.214 - } 78.215 -end 78.216 + end 78.217 + 78.218 +else -- 'classic tab' 78.219 78.220 + function ui.tabs(tabs) 78.221 + ui.container{ 78.222 + attr = { class = "ui_tabs" }, 78.223 + content = function() 78.224 + local params = param.get_all_cgi() 78.225 + local current_tab = params["tab"] 78.226 + ui.container{ 78.227 + attr = { class = "ui_tabs_links" }, 78.228 + content = function() 78.229 + for i, tab in ipairs(tabs) do 78.230 + params["tab"] = i > 1 and tab.name or nil 78.231 + ui.link{ 78.232 + attr = { 78.233 + class = ( 78.234 + tab.name == current_tab and "selected" or 78.235 + not current_tab and i == 1 and "selected" or 78.236 + "" 78.237 + ) 78.238 + }, 78.239 + module = request.get_module(), 78.240 + view = request.get_view(), 78.241 + id = param.get_id_cgi(), 78.242 + content = tab.label, 78.243 + params = params 78.244 + } 78.245 + slot.put(" ") 78.246 + end 78.247 + end 78.248 + } 78.249 + for i, tab in ipairs(tabs) do 78.250 + if tab.name == current_tab or not current_tab and i == 1 then 78.251 + ui.container{ 78.252 + attr = { class = "ui_tabs_content" }, 78.253 + content = function() 78.254 + if tab.content then 78.255 + tab.content() 78.256 + else 78.257 + execute.view{ 78.258 + module = tab.module, 78.259 + view = tab.view, 78.260 + id = tab.id, 78.261 + params = tab.params, 78.262 + } 78.263 + end 78.264 + end 78.265 + } 78.266 + end 78.267 + end 78.268 + end 78.269 + } 78.270 + end 78.271 + 78.272 +end 78.273 \ No newline at end of file
79.1 --- a/env/util/help.lua Tue Feb 02 00:31:06 2010 +0100 79.2 +++ b/env/util/help.lua Sat Feb 20 22:10:31 2010 +0100 79.3 @@ -13,7 +13,7 @@ 79.4 attr = { class = "help_actions" }, 79.5 content = function() 79.6 ui.link{ 79.7 - content = _"Hide this help message", 79.8 + text = _"Hide this help message", 79.9 module = "help", 79.10 action = "update", 79.11 params = {
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/locale/help/member.settings.display.de.txt Sat Feb 20 22:10:31 2010 +0100 80.3 @@ -0,0 +1,1 @@ 80.4 +Hier kannst du persönliche Einstellungen in Bezug auf die optische Darstellung der Bedienoberfläche von LiquidFeedback tätigen.
81.1 --- a/locale/translations.de.lua Tue Feb 02 00:31:06 2010 +0100 81.2 +++ b/locale/translations.de.lua Sat Feb 20 22:10:31 2010 +0100 81.3 @@ -1,22 +1,28 @@ 81.4 #!/usr/bin/env lua 81.5 return { 81.6 -["#{count} more initiatives"] = "#{count} weitere Initiativen"; 81.7 ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = "#{interested_issues_to_vote_count} Themen, die Dich interessieren"; 81.8 ["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} Themen"; 81.9 ["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht"; 81.10 ["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert"; 81.11 +["(#{more_count} duplicates removed)"] = "(#{more_count} Duplikate entfernt)"; 81.12 ["(change URL)"] = "(URL ändern)"; 81.13 ["(new window)"] = "(neues Fenster)"; 81.14 ["+ #{weight}"] = "+ #{weight}"; 81.15 ["A-Z"] = "A-Z"; 81.16 ["About"] = "About"; 81.17 +["About / Impressum"] = false; 81.18 ["About LiquidFeedback"] = "Über LiquidFeedback"; 81.19 ["Abstention"] = "Enthaltung"; 81.20 +["Abstention [many entries]"] = "Enthaltung"; 81.21 +["Abstention [single entry]"] = "Enthaltung"; 81.22 ["Accept invitation"] = "Einladung annehmen"; 81.23 ["Accepted at"] = "Angenommen am/um"; 81.24 +["Accordion (all expanded)"] = "Akkordeon (alle offen)"; 81.25 +["Accordion (first expanded)"] = "Akkordeon (erstes offen)"; 81.26 +["Accordion (none expanded)"] = "Akkordeon (keins offen)"; 81.27 ["Active?"] = "Aktiv?"; 81.28 +["Add alternative initiative to issue"] = "Alternative Initiative zum Thema hinzufügen"; 81.29 ["Add my interest"] = "Mein Interesse anmelden"; 81.30 -["Add new initiative to issue"] = "Neue Initiative zum Thema hinzufügen"; 81.31 ["Add new suggestion"] = "Neue Anregung hinzufügen"; 81.32 ["Add to my contacts"] = "Zu meinen Kontakten hinzufügen"; 81.33 ["Address"] = "Anschrift"; 81.34 @@ -26,14 +32,26 @@ 81.35 ["Administrator"] = "Administrator"; 81.36 ["Admission time"] = "Zeit für die Zulassung"; 81.37 ["Admitted"] = "zugelassen"; 81.38 +["Alternative initiatives"] = "Alternative Initiativen"; 81.39 ["Any"] = "Alle"; 81.40 +["Approval (#th preference) [many entries]"] = "Zustimmung (#.-Wünsche)"; 81.41 +["Approval (#th preference) [single entry]"] = "Zustimmung (#.-Wunsch)"; 81.42 +["Approval (first preference) [many entries]"] = "Zustimmung (Erstwünsche)"; 81.43 +["Approval (first preference) [single entry]"] = "Zustimmung (Erstwunsch)"; 81.44 +["Approval (second preference) [many entries]"] = "Zustimmung (Zweitwünsche)"; 81.45 +["Approval (second preference) [single entry]"] = "Zustimmung (Zweitwunsch)"; 81.46 +["Approval (third preference) [many entries]"] = "Zustimmung (Drittwünsche)"; 81.47 +["Approval (third preference) [single entry]"] = "Zustimmung (Drittwunsch)"; 81.48 +["Approval [many entries]"] = "Zustimmung"; 81.49 +["Approval [single entry]"] = "Zustimmung"; 81.50 +["Approved"] = "Angenommen"; 81.51 ["Are you sure?"] = "Sicher?"; 81.52 ["Area"] = "Themenbereich"; 81.53 ["Area '#{name}'"] = "Themenbereich '#{name}'"; 81.54 -["Area delegation"] = "Area-Delegation"; 81.55 +["Area delegation"] = "Delegation für Themenbereich"; 81.56 ["Area list"] = "Liste der Themenbereiche"; 81.57 ["Area successfully updated"] = "Themenbereich erfolgreich aktualisiert"; 81.58 -["Area wide delegation active"] = "Delegation für Themengebiet aktiv"; 81.59 +["Area wide delegation active"] = "Delegation für Themenbereich aktiv"; 81.60 ["Areas"] = "Themenbereiche"; 81.61 ["Author"] = "Autor"; 81.62 ["Autoreject is off."] = "Auto-Ablehnen ist aus"; 81.63 @@ -41,6 +59,7 @@ 81.64 ["Avatar"] = "Avatar"; 81.65 ["Back"] = "Zurück"; 81.66 ["Back to timeline"] = "Zurück zur Zeitachse"; 81.67 +["Ballot of '#{member_name}' for issue ##{issue_id}"] = "Stimmzettel von '#{member_name}' für Thema ##{issue_id}"; 81.68 ["Become a member"] = "Mitglied werden"; 81.69 ["Birthday"] = "Geburtstag"; 81.70 ["Can't remove last initiator"] = "Der letzte Initiator kann nicht entfernt werden"; 81.71 @@ -50,19 +69,22 @@ 81.72 ["Cancel refuse of invitation"] = "Ablehnung der Einladung aufheben"; 81.73 ["Cancel registration"] = "Registration abbrechen"; 81.74 ["Cancelled"] = "Abgebrochen"; 81.75 -["Change area delegation"] = "Delegation für Themengebiet ändern"; 81.76 +["Change area delegation"] = "Delegation für Themenbereich ändern"; 81.77 +["Change display settings"] = "Anzeige-Einstellungen ändern"; 81.78 +["Change filters and order"] = "Filter und Sortierung ändern"; 81.79 ["Change global delegation"] = "Globale Delegation ändern"; 81.80 ["Change issue delegation"] = "Delegation für Thema ändern"; 81.81 ["Change login"] = "Login ändern"; 81.82 ["Change name"] = "Name ändern"; 81.83 +["Change order"] = "Sortierung ändern"; 81.84 ["Change password"] = "Kennwort ändern"; 81.85 +["Change vote"] = "Wahl ändern"; 81.86 ["Change your login"] = "Deinen Anmeldenamen ändern"; 81.87 ["Change your name"] = "Deinen Namen ändern"; 81.88 ["Change your password"] = "Dein Kennwort ändern"; 81.89 ["Choose initiator"] = "Initiator auswählen"; 81.90 ["Choose member"] = "Mitglied auswählen"; 81.91 ["Click for details"] = "Klicke für Details"; 81.92 -["Close"] = "Schließen"; 81.93 ["Closed"] = "geschlossen"; 81.94 ["Collective opinion"] = "Meinungsbild"; 81.95 ["Commit suggestion"] = "Anregung speichern"; 81.96 @@ -79,7 +101,6 @@ 81.97 ["Created at"] = "Erzeugt am/um"; 81.98 ["Current draft"] = "Aktueller Entwurf"; 81.99 ["Current votings in areas you are member of and issues you are interested in:"] = "Jetzt laufende Abstimmungen zu Themen aus Deinen Themenbereichen oder solchen an denen Du interessiert bist:"; 81.100 -["Date"] = "Datum"; 81.101 ["Degree"] = "Grad"; 81.102 ["Delegations"] = "Delegationen"; 81.103 ["Delete filter"] = "Filter löschen"; 81.104 @@ -89,15 +110,25 @@ 81.105 ["Diff"] = "Differenz"; 81.106 ["Direct member count"] = "Anzahl Direktmitglieder"; 81.107 ["Direct membership"] = "Direkte Mitgliedschaft"; 81.108 +["Disapproval (prefer to last block) [many entries]"] = "Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)"; 81.109 +["Disapproval (prefer to last block) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)"; 81.110 +["Disapproval (prefer to lower block) [many entries]"] = "Ablehnung (jedoch Bevorzugung gegenüber unterem Ablehnungsblock)"; 81.111 +["Disapproval (prefer to lower block) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber unterem Ablehnungsblock)"; 81.112 +["Disapproval (prefer to lower blocks) [many entries]"] = "Ablehnung (jedoch Bevorzugung gegenüber unteren Ablehnungsblöcken)"; 81.113 +["Disapproval (prefer to lower blocks) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber unteren Ablehnungsblöcken)"; 81.114 +["Disapproval [many entries]"] = "Ablehnung"; 81.115 +["Disapproval [single entry]"] = "Ablehnung"; 81.116 ["Discussion"] = "Diskussion"; 81.117 ["Discussion URL"] = "Diskussions-URL"; 81.118 ["Discussion on issue"] = "Diskussion zum Thema"; 81.119 ["Discussion time"] = "Zeit für die Diskussions"; 81.120 ["Discussion with initiators"] = "Diskussion mit den Initiatoren"; 81.121 +["Display settings"] = "Anzeige-Einstellungen"; 81.122 ["Download"] = "Download"; 81.123 ["Download database export"] = "Datenbankexport herunterladen"; 81.124 ["Draft"] = "Entwurf"; 81.125 ["Draft history"] = "Entwurfshistorie"; 81.126 +["EXPERIMENTAL FEATURE"] = "EXPERIMENTELLE FUNKTION"; 81.127 ["Edit"] = "Bearbeiten"; 81.128 ["Edit draft"] = "Entwurf bearbeiten"; 81.129 ["Edit initiative"] = "Initiative bearbeiten"; 81.130 @@ -161,7 +192,6 @@ 81.131 ["Invited"] = "Eingeladen"; 81.132 ["Issue"] = "Thema"; 81.133 ["Issue ##{id}"] = "Thema ##{id}"; 81.134 -["Issue ##{id} (#{policy_name})"] = "Thema ##{id} (#{policy_name})"; 81.135 ["Issue accepted"] = "Thema akzeptiert"; 81.136 ["Issue canceled"] = "Thema abgebrochen"; 81.137 ["Issue delegation"] = "Issue-Delegation"; 81.138 @@ -196,6 +226,7 @@ 81.139 ["Member '#{member}'"] = "Mitglied '#{member}'"; 81.140 ["Member has been removed from initiators"] = "Mitglied wurde von den Initiatoren entfernt"; 81.141 ["Member has been removed from your contacts"] = "Mitglied wurde aus Deinen Kontakten entfernt"; 81.142 +["Member has not approved latest draft"] = "Mitglied hat den letzten Entwurf noch nicht angenommen"; 81.143 ["Member is administrator"] = "Mitglied ist Administrator"; 81.144 ["Member is already saved in your contacts!"] = "Mitglied ist schon in Deinen Kontakten!"; 81.145 ["Member is now invited to be initiator"] = "Mitglied ist jetzt als Initiator eingeladen"; 81.146 @@ -206,6 +237,7 @@ 81.147 ["Member page"] = "Mitgliederseite"; 81.148 ["Member successfully registered"] = "Mitglied erfolgreich registriert"; 81.149 ["Member successfully updated"] = "Mitglied erfolgreich aktualisert"; 81.150 +["Member voting"] = false; 81.151 ["Member: '#{login}' (#{name})"] = "Mitlied: '#{login}' (#{name})"; 81.152 ["Members"] = "Mitglieder"; 81.153 ["Membership by delegation"] = "Mitgliedschaft durch Delegation"; 81.154 @@ -216,6 +248,8 @@ 81.155 ["Missing help text: #{id}.#{lang}.txt"] = "Fehlender Hilfe-Text: #{id}.#{lang}.txt"; 81.156 ["Mobile phone"] = "Mobiltelefon"; 81.157 ["Monday"] = "Montag"; 81.158 +["Move down"] = "Runter schieben"; 81.159 +["Move up"] = "Hoch schieben"; 81.160 ["My opinion"] = "Meine Meinung"; 81.161 ["Name"] = "Name"; 81.162 ["New"] = "Neu"; 81.163 @@ -237,9 +271,13 @@ 81.164 ["No membership at all"] = "Gar keine Mitgliedschaft"; 81.165 ["No support at all"] = "Gar keine Unterstützung"; 81.166 ["Not a member"] = "Kein Mitglied"; 81.167 +["Not approved (rank #{rank})"] = "Nicht angenommen (Rang #{rank})"; 81.168 ["Not voted"] = "Nicht abgestimmt"; 81.169 +["Not voted (not admitted)"] = "Nicht abgestimmt (nicht zugelassen)"; 81.170 +["Not voted (revoked from initiator)"] = "Nicht abgestimmt (durch Initiator zurückgezogen)"; 81.171 ["Not yet voted"] = "Noch abzustimmen"; 81.172 ["Number of incoming delegations, follow link to see more details"] = "Anzahl eingehender Delegationen, Link folgen für mehr Details"; 81.173 +["Number of initiatives to preview"] = "Anzahl der Initiativen in der Vorschau"; 81.174 ["OK"] = "OK"; 81.175 ["Old draft revision"] = "Alte Revision des Entwurfs"; 81.176 ["Old password"] = "Altes Kennwort"; 81.177 @@ -251,6 +289,7 @@ 81.178 ["One issue you are interested in"] = "Ein Thema, das Dich interessiert"; 81.179 ["One step back"] = "Ein Schritt zurück"; 81.180 ["Open"] = "Offen"; 81.181 +["Opinions"] = "Meinungen"; 81.182 ["Order by"] = "Sortieren nach"; 81.183 ["Organizational unit"] = "Organisationseinheit"; 81.184 ["Outgoing delegations"] = "Ausgehende Delegationen"; 81.185 @@ -285,7 +324,6 @@ 81.186 ["Profile"] = "Profil"; 81.187 ["Publish"] = "Veröffentlichen"; 81.188 ["Published"] = "veröffentlicht"; 81.189 -["Published contacts"] = "Veröffentlichte Kontakte"; 81.190 ["Rank"] = "Rang"; 81.191 ["Real name"] = "Realname"; 81.192 ["Refresh support to current draft"] = "Unterstützung auf aktuellen Entwurf aktualisieren"; 81.193 @@ -322,10 +360,11 @@ 81.194 ["Search issues"] = "Suche Themen"; 81.195 ["Search members"] = "Suche Mitglieder"; 81.196 ["Search results for: '#{search}'"] = "Suchergebnisse für: '#{search}'"; 81.197 +["Select language \"#{langcode}\""] = false; 81.198 ["Set URL"] = "URL setzen"; 81.199 -["Set area delegation"] = "Delegation für Themengebiet festlegen"; 81.200 +["Set area delegation"] = "Delegation für Themenbereich festlegen"; 81.201 ["Set autoreject"] = "Auto-Ablehnen anschalten"; 81.202 -["Set delegation for Area '#{name}'"] = "Delegation für Themengebiet '#{name}' festlegen"; 81.203 +["Set delegation for Area '#{name}'"] = "Delegation für Themenbereich '#{name}' festlegen"; 81.204 ["Set delegation for Issue ##{number} in Area '#{area_name}'"] = "Delegation für Thema ##{number} im Themenbereich '#{area_name}' festlegen"; 81.205 ["Set global delegation"] = "Globale Delegation festlegen"; 81.206 ["Set issue delegation"] = "Delegation für Thema festlegen"; 81.207 @@ -333,11 +372,13 @@ 81.208 ["Settings"] = "Einstellungen"; 81.209 ["Show"] = "Zeige"; 81.210 ["Show active members"] = "Zeige aktive Mitglieder"; 81.211 -["Show all initiatives"] = "Zeige alle Initiativen"; 81.212 +["Show alternative initiatives"] = "Zeige alternative Initiativen"; 81.213 ["Show areas in use"] = "Zeige verwendete Themenbereiche"; 81.214 ["Show areas not in use"] = "Zeige nicht verwendente Themenbereiche"; 81.215 ["Show diff"] = "Änderungen anzeigen"; 81.216 +["Show filter"] = "Zeige Filter"; 81.217 ["Show filter details"] = "Zeige Filter-Details"; 81.218 +["Show help text"] = "Zeige Hilfe-Text"; 81.219 ["Show locked members"] = "Zeige gesperrte Mitglieder"; 81.220 ["Show member"] = "Mitglied anzeigen"; 81.221 ["Show name history"] = "Namenshistorie zeigen"; 81.222 @@ -370,14 +411,24 @@ 81.223 ["Supported"] = "Unterstützt"; 81.224 ["Supported initiatives"] = "Unterstützte Initiativen"; 81.225 ["Supporter"] = "Unterstützer"; 81.226 +["Tabs"] = "Registerkarten"; 81.227 ["Terms accepted"] = "Bedingungen akzeptiert"; 81.228 +["Terms of use"] = "Nutzungsbedingungen"; 81.229 ["The code you've entered is invalid"] = "Der Code, den Du eingeben hast, ist nicht gültig!"; 81.230 ["The draft of this initiative has been updated!"] = "Der Entwurfstext der Initiative wurde aktualisiert!"; 81.231 ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht"; 81.232 ["The initiators suggest to support the following initiative:"] = "Die Initiatoren empfehlen folgende Initiative zu unterstützen:"; 81.233 +["There are no more alternative initiatives currently."] = "Es gibt zur Zeit keine weiteren alternative Initiative."; 81.234 +["There were no more alternative initiatives."] = "Es gab keine weiteren alternativen Initiativen."; 81.235 +["This initiative"] = "Diese Initiative"; 81.236 +["This initiative compared to alternative initiatives"] = "Diese Initiative im Vergleich zu alternativen Initiativen"; 81.237 ["This initiative has been revoked at #{revoked}"] = "Diese Initiative wurde am/um #{revoked} zurückgezogen"; 81.238 +["This initiative has not been admitted! It failed the quorum of #{quorum}."] = "Diese Initiative wurde nicht zugelassen. Sie hat das Quorum von #{quorum} nicht erreicht."; 81.239 ["This initiative is already revoked"] = "Diese Initiative ist schon zurückgezogen"; 81.240 ["This initiative is revoked"] = "Diese Initiative wurde zurückgezogen"; 81.241 +["This issue has been cancelled. It failed the quorum of #{quorum}."] = "Dieses Thema wurde abgebrochen. Es hat das Quorum von #{quorum} nicht erfüllt."; 81.242 +["This issue has been finished with the following winning initiative:"] = "Diese Thema wurde mit folgender Initiative als Gewinner abgeschlossen:"; 81.243 +["This issue has been finished without any winning initiative."] = "Das Thema wurde ohne Gewinner abgeschlossen."; 81.244 ["This issue is already closed."] = "Das Thema ist schon geschlossen."; 81.245 ["This issue is already frozen."] = "Das Thema ist schon eingefroren"; 81.246 ["This login is already taken, please choose another one!"] = "Dieser Anmeldename ist bereits vergeben, bitte wähle einen anderen!"; 81.247 @@ -386,6 +437,7 @@ 81.248 ["This member has rejected to become initiator of this initiative"] = "Dieses Mitglied hat die Einladung, Initiator zu werden, abgelehnt"; 81.249 ["This member is already initiator of this initiative"] = "Dieses Mitglied ist bereits Initiator dieser Initiative"; 81.250 ["This member is already invited to become initiator of this initiative"] = "Dieses Mitglied ist bereits eingeladen Initiator dieser Initiative zu werden"; 81.251 +["This member is participating, the rest of delegation chain is suspended while discussing"] = "Dieses Mitglied partizipiert, Rest der Delegationskette ausgesetzt."; 81.252 ["This name is already taken, please choose another one!"] = "Dieser Name ist bereits vergeben, bitte wähle einen anderen!"; 81.253 ["This name is really too short!"] = "Dieser Name ist wirklich zu kurz!"; 81.254 ["This name is too short!"] = "Dieser Name ist zu kurz!"; 81.255 @@ -395,10 +447,12 @@ 81.256 ["Thursday"] = "Donnerstag"; 81.257 ["Time left"] = "Restzeit"; 81.258 ["Timeline"] = "Zeitachse"; 81.259 -["Title (80 chars max)"] = "Title (max. 80 Zeichen)"; 81.260 -["Traditional wiki syntax"] = "Traditionaller Wiki-Syntax"; 81.261 +["Title"] = "Titel"; 81.262 +["Title (80 chars max)"] = "Titel (max. 80 Zeichen)"; 81.263 +["Traditional wiki syntax"] = "Traditionelle Wiki-Syntax"; 81.264 ["Trustee"] = "Bevollmächtigter"; 81.265 ["Tuesday"] = "Dienstag"; 81.266 +["Type of tabs"] = "Tabulatortyp"; 81.267 ["Unknown author"] = "Unbekannter Autor"; 81.268 ["Upload images"] = "Bilder hochladen"; 81.269 ["Used until"] = "Benutzt bis"; 81.270 @@ -411,8 +465,8 @@ 81.271 ["Voted no"] = "Mit Nein gestimmt"; 81.272 ["Voted proposal"] = "Abgestimmte Vorlage"; 81.273 ["Voted yes"] = "Mit Ja gestimmt"; 81.274 -["Voter"] = "Abstimmende"; 81.275 ["Voting"] = "Abstimmung"; 81.276 +["Voting details"] = "Abstimmdetails"; 81.277 ["Voting for this issue has already begun."] = "Die Abstimmung für dieses Thema hat schon begonnen."; 81.278 ["Voting for this issue is currently running!"] = "Über dieses Thema wird gerade abgestimmt!"; 81.279 ["Voting has not started yet."] = "Die Abstimmung hat noch nicht begonnen."; 81.280 @@ -447,10 +501,11 @@ 81.281 ["Your are interested"] = "Du bist interessiert"; 81.282 ["Your are potential supporter"] = "Du bist potentieller Unterstützer"; 81.283 ["Your are supporter"] = "Du bist Unterstützer"; 81.284 -["Your delegation for this area has been deleted."] = "Deine Delegation für dieses Themengebiet wurde gelöscht"; 81.285 -["Your delegation for this area has been updated."] = "Deine Delegation für dieses Themengebiet wurde geändert"; 81.286 +["Your delegation for this area has been deleted."] = "Deine Delegation für dieses Themenbereich wurde gelöscht"; 81.287 +["Your delegation for this area has been updated."] = "Deine Delegation für dieses Themenbereich wurde geändert"; 81.288 ["Your delegation for this issue has been deleted."] = "Deine Delegation für dieses Thema wurde gelöscht"; 81.289 ["Your delegation for this issue has been updated."] = "Deine Delegation für dieses Thema wurde geändert"; 81.290 +["Your display settings have been updated"] = "Deine Anzeige-Einstellungen wurden aktualisiert"; 81.291 ["Your global delegation has been deleted."] = "Deine globale Delegation wurde gelöscht"; 81.292 ["Your global delegation has been updated."] = "Deine globale Delegation wurde geändert"; 81.293 ["Your login has been changed to '#{login}'"] = "Dein Anmeldename wurde auf '#{login}' geändert"; 81.294 @@ -465,17 +520,18 @@ 81.295 ["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert"; 81.296 ["Your web browser is not fully supported yet."] = "Dein Web-Browser wird noch nicht vollständig unterstützt."; 81.297 ["Z-A"] = "Z-A"; 81.298 -["all"] = "Alle"; 81.299 +["and #{count} more initiatives"] = "und #{count} weitere Initiativen"; 81.300 ["continuing"] = "andauernd"; 81.301 ["delete<br /><br />"] = "löschen<br /><br />"; 81.302 ["email"] = "E-Mail"; 81.303 +["last 24 hours"] = "letzte 24 Stunden"; 81.304 ["login name"] = "Anmeldename"; 81.305 ["must"] = "muss"; 81.306 ["must not"] = "darf nicht"; 81.307 ["must/should"] = "muss/soll"; 81.308 ["must/should not"] = "muss/soll nicht"; 81.309 ["neutral"] = "neutral"; 81.310 -["not implemented"] = "nicht umgesetzt"; 81.311 +["requested"] = "angefragt"; 81.312 ["should"] = "soll"; 81.313 ["should not"] = "soll nicht"; 81.314 ["to reset your password please click on the following link:\n\n"] = "um Dein Kennwort zurückzusetzen klicke bitte den folgenden Link an:\n\n";
82.1 --- a/locale/translations.en.lua Tue Feb 02 00:31:06 2010 +0100 82.2 +++ b/locale/translations.en.lua Sat Feb 20 22:10:31 2010 +0100 82.3 @@ -1,15 +1,517 @@ 82.4 #!/usr/bin/env lua 82.5 return { 82.6 -["Error compile"] = false; 82.7 -["Error no file"] = false; 82.8 -["Error runtime"] = false; 82.9 +["#{interested_issues_to_vote_count} issue(s) you are interested in"] = false; 82.10 +["#{issues_to_vote_count} issue(s)"] = false; 82.11 +["#{number} Image(s) has been deleted"] = false; 82.12 +["#{number} Image(s) has been updated"] = false; 82.13 +["(#{more_count} duplicates removed)"] = false; 82.14 +["(change URL)"] = false; 82.15 +["(new window)"] = false; 82.16 +["+ #{weight}"] = false; 82.17 +["A-Z"] = false; 82.18 +["About"] = false; 82.19 +["About LiquidFeedback"] = false; 82.20 +["Abstention"] = false; 82.21 +["Abstention [many entries]"] = "Abstention"; 82.22 +["Abstention [single entry]"] = "Abstention"; 82.23 +["Accept invitation"] = false; 82.24 +["Accepted at"] = false; 82.25 +["Accordion (all expanded)"] = false; 82.26 +["Accordion (first expanded)"] = false; 82.27 +["Accordion (none expanded)"] = false; 82.28 +["Active?"] = false; 82.29 +["Add my interest"] = false; 82.30 +["Add new initiative"] = false; 82.31 +["Add new initiative to issue"] = false; 82.32 +["Add new suggestion"] = false; 82.33 +["Add to my contacts"] = false; 82.34 +["Address"] = false; 82.35 +["Admin"] = false; 82.36 +["Admin menu"] = false; 82.37 +["Admin?"] = false; 82.38 +["Administrator"] = false; 82.39 +["Admission time"] = false; 82.40 +["Admitted"] = false; 82.41 +["Any"] = false; 82.42 +["Approval (#th preference) [many entries]"] = "Approval (#th preference)"; 82.43 +["Approval (#th preference) [single entry]"] = "Approval (#th preference)"; 82.44 +["Approval (first preference) [many entries]"] = "Approval (first preference)"; 82.45 +["Approval (first preference) [single entry]"] = "Approval (first preference)"; 82.46 +["Approval (second preference) [many entries]"] = "Approval (second preference)"; 82.47 +["Approval (second preference) [single entry]"] = "Approval (second preference)"; 82.48 +["Approval (third preference) [many entries]"] = "Approval (third preference)"; 82.49 +["Approval (third preference) [single entry]"] = "Approval (third preference)"; 82.50 +["Approval [many entries]"] = "Approval"; 82.51 +["Approval [single entry]"] = "Approval"; 82.52 +["Are you sure?"] = false; 82.53 +["Area"] = false; 82.54 +["Area '#{name}'"] = false; 82.55 +["Area delegation"] = false; 82.56 +["Area list"] = false; 82.57 +["Area successfully updated"] = false; 82.58 +["Area wide delegation active"] = false; 82.59 +["Areas"] = false; 82.60 +["Author"] = false; 82.61 +["Autoreject is off."] = false; 82.62 +["Autoreject is on."] = false; 82.63 +["Avatar"] = false; 82.64 +["Back"] = false; 82.65 +["Back to timeline"] = false; 82.66 +["Become a member"] = false; 82.67 +["Birthday"] = false; 82.68 +["Can't remove last initiator"] = false; 82.69 +["Can't send confirmation email"] = false; 82.70 +["Cancel"] = false; 82.71 +["Cancel password reset"] = false; 82.72 +["Cancel refuse of invitation"] = false; 82.73 +["Cancel registration"] = false; 82.74 +["Cancelled"] = false; 82.75 +["Change area delegation"] = false; 82.76 +["Change display settings"] = false; 82.77 +["Change global delegation"] = false; 82.78 +["Change issue delegation"] = false; 82.79 +["Change login"] = false; 82.80 +["Change name"] = false; 82.81 +["Change password"] = false; 82.82 +["Change vote"] = false; 82.83 +["Change your login"] = false; 82.84 +["Change your name"] = false; 82.85 +["Change your password"] = false; 82.86 +["Choose initiator"] = false; 82.87 +["Choose member"] = false; 82.88 +["Click for details"] = false; 82.89 +["Close"] = false; 82.90 +["Closed"] = false; 82.91 +["Collective opinion"] = false; 82.92 +["Commit suggestion"] = false; 82.93 +["Compare"] = false; 82.94 +["Confirm"] = false; 82.95 +["Confirmation code"] = false; 82.96 +["Confirmation code invalid!"] = false; 82.97 +["Contacts"] = false; 82.98 +["Content"] = false; 82.99 +["Counting of votes"] = false; 82.100 +["Create alternative initiative"] = false; 82.101 +["Create new area"] = false; 82.102 +["Create new issue"] = false; 82.103 +["Created at"] = false; 82.104 +["Current draft"] = false; 82.105 +["Current votings in areas you are member of and issues you are interested in:"] = false; 82.106 +["Degree"] = false; 82.107 +["Delegations"] = false; 82.108 +["Delete filter"] = false; 82.109 +["Description"] = false; 82.110 +["Details"] = false; 82.111 +["Developer features"] = false; 82.112 +["Diff"] = false; 82.113 +["Direct member count"] = false; 82.114 +["Direct membership"] = false; 82.115 +["Disapproval (prefer to last block) [many entries]"] = "Disapproval (prefer to last block)"; 82.116 +["Disapproval (prefer to last block) [single entry]"] = "Disapproval (prefer to last block)"; 82.117 +["Disapproval (prefer to lower block) [many entries]"] = "Disapproval (prefer to lower block)"; 82.118 +["Disapproval (prefer to lower block) [single entry]"] = "Disapproval (prefer to lower block)"; 82.119 +["Disapproval (prefer to lower blocks) [many entries]"] = "Disapproval (prefer to lower blocks)"; 82.120 +["Disapproval (prefer to lower blocks) [single entry]"] = "Disapproval (prefer to lower blocks)"; 82.121 +["Disapproval [many entries]"] = "Disapproval"; 82.122 +["Disapproval [single entry]"] = "Disapproval"; 82.123 +["Discussion"] = false; 82.124 +["Discussion URL"] = false; 82.125 +["Discussion on issue"] = false; 82.126 +["Discussion time"] = false; 82.127 +["Discussion with initiators"] = false; 82.128 +["Display settings"] = false; 82.129 +["Display starting from"] = false; 82.130 +["Download"] = false; 82.131 +["Download database export"] = false; 82.132 +["Draft"] = false; 82.133 +["Draft history"] = false; 82.134 +["Edit"] = false; 82.135 +["Edit draft"] = false; 82.136 +["Edit initiative"] = false; 82.137 +["Edit my page"] = false; 82.138 +["Edit my profile"] = false; 82.139 +["Email address"] = false; 82.140 +["Email address confirmation"] = false; 82.141 +["Email address is confirmed now"] = false; 82.142 +["Email address too short!"] = false; 82.143 +["Email confirmation request"] = false; 82.144 +["Empty help text: #{id}.#{lang}.txt"] = false; 82.145 +["Error while updating member, database reported:<br /><br /> (#{errormessage})"] = false; 82.146 +["External memberships"] = false; 82.147 +["External posts"] = false; 82.148 +["Filter"] = false; 82.149 +["Finish voting"] = false; 82.150 +["Finished"] = false; 82.151 +["Friday"] = false; 82.152 +["Frozen"] = false; 82.153 +["Fully frozen at"] = false; 82.154 +["Global delegation"] = false; 82.155 +["Global delegation active"] = false; 82.156 +["Half frozen at"] = false; 82.157 +["Hello "] = false; 82.158 +["Help for: #{text}"] = false; 82.159 +["Hide"] = false; 82.160 +["Hide filter details"] = false; 82.161 +["Hide this help message"] = false; 82.162 ["Home"] = false; 82.163 +["I accept the terms of use by checking the following checkbox:"] = false; 82.164 +["Id"] = false; 82.165 +["Ident number"] = false; 82.166 +["If this link is not working, please open following url in your web browser:\n\n"] = false; 82.167 +["Images"] = false; 82.168 +["In discussion"] = false; 82.169 +["Incoming delegations"] = false; 82.170 +["Initiated"] = false; 82.171 +["Initiated initiatives"] = false; 82.172 +["Initiative events"] = false; 82.173 +["Initiative is revoked now"] = false; 82.174 +["Initiative quorum"] = false; 82.175 +["Initiative revoked"] = false; 82.176 +["Initiative successfully created"] = false; 82.177 +["Initiative successfully updated"] = false; 82.178 +["Initiative: '#{name}'"] = false; 82.179 +["Initiatives"] = false; 82.180 +["Initiatives that invited you to become initiator:"] = false; 82.181 +["Initiator"] = false; 82.182 +["Initiators"] = false; 82.183 +["Interest not existant"] = false; 82.184 +["Interest removed"] = false; 82.185 +["Interest updated"] = false; 82.186 +["Interested"] = false; 82.187 +["Interested members"] = false; 82.188 +["Internal posts"] = false; 82.189 ["Invalid username or password!"] = false; 82.190 +["Invitation has been refused"] = false; 82.191 +["Invite an initiator to initiative"] = false; 82.192 +["Invite code"] = false; 82.193 +["Invite initiator"] = false; 82.194 +["Invited"] = false; 82.195 +["Issue"] = false; 82.196 +["Issue ##{id}"] = false; 82.197 +["Issue ##{id} (#{policy_name})"] = false; 82.198 +["Issue accepted"] = false; 82.199 +["Issue canceled"] = false; 82.200 +["Issue delegation"] = false; 82.201 +["Issue delegation active"] = false; 82.202 +["Issue events"] = false; 82.203 +["Issue finished"] = false; 82.204 +["Issue finished without voting"] = false; 82.205 +["Issue frozen"] = false; 82.206 +["Issue policy"] = false; 82.207 +["Issue quorum"] = false; 82.208 +["Issues"] = false; 82.209 +["JavaScript is disabled or not available."] = false; 82.210 +["Last author"] = false; 82.211 +["Last snapshot:"] = false; 82.212 +["Legend:"] = false; 82.213 +["License"] = false; 82.214 +["Locked?"] = false; 82.215 ["Login"] = false; 82.216 +["Login name"] = false; 82.217 ["Login successful!"] = false; 82.218 ["Logout"] = false; 82.219 ["Logout successful"] = false; 82.220 +["Manage filter"] = false; 82.221 +["Manage timeline filters"] = false; 82.222 +["Mark suggestion as implemented and express dissatisfaction"] = false; 82.223 +["Mark suggestion as implemented and express satisfaction"] = false; 82.224 +["Mark suggestion as not implemented and express dissatisfaction"] = false; 82.225 +["Mark suggestion as not implemented and express satisfaction"] = false; 82.226 +["Max potential support"] = false; 82.227 +["Max support"] = false; 82.228 +["Member"] = false; 82.229 +["Member '#{member}'"] = false; 82.230 +["Member has been removed from initiators"] = false; 82.231 +["Member has been removed from your contacts"] = false; 82.232 +["Member is administrator"] = false; 82.233 +["Member is already saved in your contacts!"] = false; 82.234 +["Member is now invited to be initiator"] = false; 82.235 +["Member list"] = false; 82.236 +["Member name"] = false; 82.237 +["Member name history for '#{name}'"] = false; 82.238 +["Member of area"] = false; 82.239 +["Member page"] = false; 82.240 +["Member successfully registered"] = false; 82.241 +["Member successfully updated"] = false; 82.242 +["Member: '#{login}' (#{name})"] = false; 82.243 +["Members"] = false; 82.244 +["Membership by delegation"] = false; 82.245 +["Membership not existant"] = false; 82.246 +["Membership removed"] = false; 82.247 +["Membership updated"] = false; 82.248 +["Memberships"] = false; 82.249 +["Missing help text: #{id}.#{lang}.txt"] = false; 82.250 +["Mobile phone"] = false; 82.251 +["Monday"] = false; 82.252 +["My opinion"] = false; 82.253 +["Name"] = false; 82.254 +["New"] = false; 82.255 +["New draft"] = false; 82.256 +["New draft has been added to initiative"] = false; 82.257 +["New draft revision"] = false; 82.258 +["New initiative"] = false; 82.259 +["New issue"] = false; 82.260 +["New password"] = false; 82.261 +["New passwords does not match."] = false; 82.262 +["New passwords is too short."] = false; 82.263 +["New suggestion"] = false; 82.264 +["Newest"] = false; 82.265 +["Next state"] = false; 82.266 +["No"] = false; 82.267 +["No changes to your images were made"] = false; 82.268 +["No delegation"] = false; 82.269 +["No events selected to list"] = false; 82.270 +["No membership at all"] = false; 82.271 +["No support at all"] = false; 82.272 +["Not a member"] = false; 82.273 +["Not voted"] = false; 82.274 +["Not yet voted"] = false; 82.275 +["Number of incoming delegations, follow link to see more details"] = false; 82.276 +["Number of initiatives to preview"] = false; 82.277 +["OK"] = false; 82.278 +["Old draft revision"] = false; 82.279 +["Old password"] = false; 82.280 +["Old password is wrong"] = false; 82.281 +["Oldest"] = false; 82.282 +["On that page please enter the confirmation code:\n\n"] = false; 82.283 +["On that page please enter the reset code:\n\n"] = false; 82.284 +["One issue"] = false; 82.285 +["One issue you are interested in"] = false; 82.286 +["One step back"] = false; 82.287 +["Open"] = false; 82.288 +["Order by"] = false; 82.289 +["Organizational unit"] = false; 82.290 +["Outgoing delegations"] = false; 82.291 ["Password"] = false; 82.292 -["Password login"] = false; 82.293 -["Username"] = false; 82.294 +["Password (repeat)"] = false; 82.295 +["Password has been reset successfully"] = false; 82.296 +["Password reset request"] = false; 82.297 +["Passwords don't match!"] = false; 82.298 +["Passwords must consist of at least 8 characters!"] = false; 82.299 +["Phone"] = false; 82.300 +["Photo"] = false; 82.301 +["Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."] = false; 82.302 +["Please choose a member"] = false; 82.303 +["Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."] = false; 82.304 +["Please choose a password and enter it twice. The password is case sensitive."] = false; 82.305 +["Please choose a policy"] = false; 82.306 +["Please choose two different versions of the draft to compare"] = false; 82.307 +["Please choose two versions of the draft to compare"] = false; 82.308 +["Please confirm your email address by clicking the following link:\n\n"] = false; 82.309 +["Please enter the email reset code you have received:"] = false; 82.310 +["Please enter the invite code you've received."] = false; 82.311 +["Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link."] = false; 82.312 +["Please enter your login name. You will receive an email with a link to reset your password."] = false; 82.313 +["Please enter your new password twice."] = false; 82.314 +["Policy"] = false; 82.315 +["Population"] = false; 82.316 +["Posts"] = false; 82.317 +["Potential support"] = false; 82.318 +["Potential supported"] = false; 82.319 +["Potential supporter"] = false; 82.320 +["Profession"] = false; 82.321 +["Profile"] = false; 82.322 +["Publish"] = false; 82.323 +["Published"] = false; 82.324 +["Published contacts"] = false; 82.325 +["Rank"] = false; 82.326 +["Real name"] = false; 82.327 +["Refresh support to current draft"] = false; 82.328 +["Refuse invitation"] = false; 82.329 +["Register"] = false; 82.330 +["Register new member"] = false; 82.331 +["Registration"] = false; 82.332 +["Rejected"] = false; 82.333 +["Remove"] = false; 82.334 +["Remove autoreject"] = false; 82.335 +["Remove from contacts"] = false; 82.336 +["Remove initiator"] = false; 82.337 +["Remove initiator from initiative"] = false; 82.338 +["Remove my interest"] = false; 82.339 +["Remove my membership"] = false; 82.340 +["Remove my request to vote later"] = false; 82.341 +["Remove my support from this initiative"] = false; 82.342 +["Repeat new password"] = false; 82.343 +["Request password reset link"] = false; 82.344 +["Reset code"] = false; 82.345 +["Reset code is invalid!"] = false; 82.346 +["Reset link has been send for this member"] = false; 82.347 +["Reset password"] = false; 82.348 +["Revoke"] = false; 82.349 +["Revoke initiative"] = false; 82.350 +["Revoked at"] = false; 82.351 +["Saturday"] = false; 82.352 +["Save"] = false; 82.353 +["Save current filter"] = false; 82.354 +["Save timeline filters"] = false; 82.355 +["Saved as contact"] = false; 82.356 +["Search"] = false; 82.357 +["Search initiatives"] = false; 82.358 +["Search issues"] = false; 82.359 +["Search members"] = false; 82.360 +["Search results for: '#{search}'"] = false; 82.361 +["Set URL"] = false; 82.362 +["Set area delegation"] = false; 82.363 +["Set autoreject"] = false; 82.364 +["Set delegation for Area '#{name}'"] = false; 82.365 +["Set delegation for Issue ##{number} in Area '#{area_name}'"] = false; 82.366 +["Set global delegation"] = false; 82.367 +["Set issue delegation"] = false; 82.368 +["Set new password"] = false; 82.369 +["Settings"] = false; 82.370 +["Show"] = false; 82.371 +["Show active members"] = false; 82.372 +["Show all initiatives"] = false; 82.373 +["Show areas in use"] = false; 82.374 +["Show areas not in use"] = false; 82.375 +["Show diff"] = false; 82.376 +["Show filter details"] = false; 82.377 +["Show locked members"] = false; 82.378 +["Show member"] = false; 82.379 +["Show name history"] = false; 82.380 +["Show only events which match... (or associtated)"] = false; 82.381 +["Software"] = false; 82.382 +["Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."] = false; 82.383 +["Sorry, but there is not confirmed email address for your account. Please contact the administrator or support."] = false; 82.384 +["Sorry, but you are currently not invited"] = false; 82.385 +["Sorry, you have reached your personal flood limit. Please be slower..."] = false; 82.386 +["Sorry, your contingent for creating initiatives has been used up. Please try again later."] = false; 82.387 +["State"] = false; 82.388 +["Statement"] = false; 82.389 +["Step 1/5: Invite code"] = false; 82.390 +["Step 2/5: Email address"] = false; 82.391 +["Step 3/5: Username"] = false; 82.392 +["Step 4/5: Login name"] = false; 82.393 +["Step 5/5: Terms of use and password"] = false; 82.394 +["Stylesheet URL"] = false; 82.395 +["Stylesheet URL has been updated"] = false; 82.396 +["Suggest no initiative"] = false; 82.397 +["Suggested initiative"] = false; 82.398 +["Suggestion"] = false; 82.399 +["Suggestion currently implemented"] = false; 82.400 +["Suggestion currently not implemented"] = false; 82.401 +["Suggestion for initiative: '#{name}'"] = false; 82.402 +["Suggestions"] = false; 82.403 +["Sunday"] = false; 82.404 +["Support"] = false; 82.405 +["Support this initiative"] = false; 82.406 +["Supported"] = false; 82.407 +["Supported initiatives"] = false; 82.408 +["Supporter"] = false; 82.409 +["Tabs"] = false; 82.410 +["Terms accepted"] = false; 82.411 +["The code you've entered is invalid"] = false; 82.412 +["The draft of this initiative has been updated!"] = false; 82.413 +["The drafts do not differ"] = false; 82.414 +["The initiators suggest to support the following initiative:"] = false; 82.415 +["This initiative has been revoked at #{revoked}"] = false; 82.416 +["This initiative has not been admitted! It failed the quorum of #{quorum}."] = false; 82.417 +["This initiative is already revoked"] = false; 82.418 +["This initiative is revoked"] = false; 82.419 +["This issue is already closed."] = false; 82.420 +["This issue is already frozen."] = false; 82.421 +["This login is already taken, please choose another one!"] = false; 82.422 +["This login is too short!"] = false; 82.423 +["This member account has been created at #{created}"] = false; 82.424 +["This member has rejected to become initiator of this initiative"] = false; 82.425 +["This member is already initiator of this initiative"] = false; 82.426 +["This member is already invited to become initiator of this initiative"] = false; 82.427 +["This name is already taken, please choose another one!"] = false; 82.428 +["This name is really too short!"] = false; 82.429 +["This name is too short!"] = false; 82.430 +["This suggestion has been meanwhile deleted"] = false; 82.431 +["This title is really too short!"] = false; 82.432 +["This username is too short!"] = false; 82.433 +["Thursday"] = false; 82.434 +["Time left"] = false; 82.435 +["Timeline"] = false; 82.436 +["Title (80 chars max)"] = false; 82.437 +["Traditional wiki syntax"] = false; 82.438 +["Trustee"] = false; 82.439 +["Tuesday"] = false; 82.440 +["Type of tabs"] = false; 82.441 +["Unknown author"] = false; 82.442 +["Upload images"] = false; 82.443 +["Used until"] = false; 82.444 +["Verification time"] = false; 82.445 +["Version"] = false; 82.446 +["Vote later"] = false; 82.447 +["Vote later requests"] = false; 82.448 +["Vote now"] = false; 82.449 +["Voted"] = false; 82.450 +["Voted no"] = false; 82.451 +["Voted proposal"] = false; 82.452 +["Voted yes"] = false; 82.453 +["Voter"] = false; 82.454 +["Voting"] = false; 82.455 +["Voting for this issue has already begun."] = false; 82.456 +["Voting for this issue is currently running!"] = false; 82.457 +["Voting has not started yet."] = false; 82.458 +["Voting proposal"] = false; 82.459 +["Voting request updated"] = false; 82.460 +["Voting started"] = false; 82.461 +["Voting time"] = false; 82.462 +["Website"] = false; 82.463 +["Wednesday"] = false; 82.464 +["Wiki engine"] = false; 82.465 +["Yes"] = false; 82.466 +["You are already initator"] = false; 82.467 +["You are already not supporting this initiative"] = false; 82.468 +["You are already supporting the latest draft"] = false; 82.469 +["You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."] = false; 82.470 +["You are iniator of this initiative"] = false; 82.471 +["You are interested in this issue"] = false; 82.472 +["You are invited to become initiator of this initiative."] = false; 82.473 +["You are member"] = false; 82.474 +["You are now initiator of this initiative"] = false; 82.475 +["You are potential supporter of this initiative"] = false; 82.476 +["You are supporting this initiative"] = false; 82.477 +["You can't suggest the initiative you are revoking"] = false; 82.478 +["You didn't saved any member as contact yet."] = false; 82.479 +["You have saved this member as contact"] = false; 82.480 +["You have saved this member as contact."] = false; 82.481 +["You have to accept the terms of use to complete registration."] = false; 82.482 +["You have to mark 'Are you sure' to revoke!"] = false; 82.483 +["You need to be logged in, to use this system."] = false; 82.484 +["You want to vote later"] = false; 82.485 +["You've successfully registered and you can login now with your login and password!"] = false; 82.486 +["Your are interested"] = false; 82.487 +["Your are potential supporter"] = false; 82.488 +["Your are supporter"] = false; 82.489 +["Your delegation for this area has been deleted."] = false; 82.490 +["Your delegation for this area has been updated."] = false; 82.491 +["Your delegation for this issue has been deleted."] = false; 82.492 +["Your delegation for this issue has been updated."] = false; 82.493 +["Your display settings have been updated"] = false; 82.494 +["Your global delegation has been deleted."] = false; 82.495 +["Your global delegation has been updated."] = false; 82.496 +["Your login has been changed to '#{login}'"] = false; 82.497 +["Your name has been changed"] = false; 82.498 +["Your opinion has been deleted"] = false; 82.499 +["Your opinion has been updated"] = false; 82.500 +["Your page has been updated"] = false; 82.501 +["Your password has been updated successfully"] = false; 82.502 +["Your suggestion has been added"] = false; 82.503 +["Your support has been added to this initiative"] = false; 82.504 +["Your support has been removed from this initiative"] = false; 82.505 +["Your support has been updated to the latest draft"] = false; 82.506 +["Your web browser is not fully supported yet."] = false; 82.507 +["Z-A"] = false; 82.508 +["all"] = false; 82.509 +["and #{count} more initiatives"] = false; 82.510 +["continuing"] = false; 82.511 +["delete<br /><br />"] = false; 82.512 +["email"] = false; 82.513 +["login name"] = false; 82.514 +["must"] = false; 82.515 +["must not"] = false; 82.516 +["must/should"] = false; 82.517 +["must/should not"] = false; 82.518 +["neutral"] = false; 82.519 +["not implemented"] = false; 82.520 +["now"] = false; 82.521 +["should"] = false; 82.522 +["should not"] = false; 82.523 +["to reset your password please click on the following link:\n\n"] = false; 82.524 +["xmpp"] = false; 82.525 }
83.1 --- a/locale/translations.eo.lua Tue Feb 02 00:31:06 2010 +0100 83.2 +++ b/locale/translations.eo.lua Sat Feb 20 22:10:31 2010 +0100 83.3 @@ -4,18 +4,25 @@ 83.4 ["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} temoj"; 83.5 ["#{number} Image(s) has been deleted"] = "Estas viŝita(j) #{number} bildo(j)"; 83.6 ["#{number} Image(s) has been updated"] = "Estas ĝisdatigita(j) #{number} bildo(j)"; 83.7 +["(#{more_count} duplicates removed)"] = false; 83.8 ["(change URL)"] = "(ŝanĝi URL)"; 83.9 ["(new window)"] = "(nova fenestro)"; 83.10 ["+ #{weight}"] = "+ #{weight}"; 83.11 ["A-Z"] = "A-Z"; 83.12 ["About"] = "Pri"; 83.13 +["About / Impressum"] = false; 83.14 ["About LiquidFeedback"] = "Pri LiquidFeedback"; 83.15 ["Abstention"] = "Sindeteno"; 83.16 +["Abstention [many entries]"] = false; 83.17 +["Abstention [single entry]"] = false; 83.18 ["Accept invitation"] = "Akcepti inviton"; 83.19 ["Accepted at"] = "Akceptita je"; 83.20 +["Accordion (all expanded)"] = false; 83.21 +["Accordion (first expanded)"] = false; 83.22 +["Accordion (none expanded)"] = false; 83.23 ["Active?"] = "Ĉu aktiva?"; 83.24 +["Add alternative initiative to issue"] = false; 83.25 ["Add my interest"] = "Anonci mian intereson"; 83.26 -["Add new initiative to issue"] = "Aldoni novan iniciaton al la temon"; 83.27 ["Add new suggestion"] = "Aldoni novan sugeston"; 83.28 ["Add to my contacts"] = "Aldoni al miaj kontaktoj"; 83.29 ["Address"] = "Adreso"; 83.30 @@ -25,8 +32,19 @@ 83.31 ["Administrator"] = "Administranto"; 83.32 ["Admission time"] = "Aprobotempo"; 83.33 ["Admitted"] = "Aprobita"; 83.34 -["All"] = "Ĉiuj"; 83.35 +["Alternative initiatives"] = false; 83.36 ["Any"] = "Kelkaj"; 83.37 +["Approval (#th preference) [many entries]"] = false; 83.38 +["Approval (#th preference) [single entry]"] = false; 83.39 +["Approval (first preference) [many entries]"] = false; 83.40 +["Approval (first preference) [single entry]"] = false; 83.41 +["Approval (second preference) [many entries]"] = false; 83.42 +["Approval (second preference) [single entry]"] = false; 83.43 +["Approval (third preference) [many entries]"] = false; 83.44 +["Approval (third preference) [single entry]"] = false; 83.45 +["Approval [many entries]"] = false; 83.46 +["Approval [single entry]"] = false; 83.47 +["Approved"] = false; 83.48 ["Are you sure?"] = "Ĉu vi estas certa?"; 83.49 ["Area"] = "Temaro"; 83.50 ["Area '#{name}'"] = "Temaro '#{name}'"; 83.51 @@ -39,7 +57,9 @@ 83.52 ["Autoreject is off."] = "Aŭtomata rifuzo estas malŝaltita."; 83.53 ["Autoreject is on."] = "Aŭtomata rifuzo estas ŝaltita."; 83.54 ["Avatar"] = "Avataro"; 83.55 -["Back"] = "Reen"; 83.56 +["Back"] = "Reen"; 83.57 +["Back to timeline"] = false; 83.58 +["Ballot of '#{member_name}' for issue ##{issue_id}"] = false; 83.59 ["Become a member"] = "Iĝi membro"; 83.60 ["Birthday"] = "Naskiĝtago"; 83.61 ["Can't remove last initiator"] = "Ne povas forigi la lastan iniciatinton"; 83.62 @@ -50,18 +70,21 @@ 83.63 ["Cancel registration"] = "Nuligi registradon"; 83.64 ["Cancelled"] = "Abolita"; 83.65 ["Change area delegation"] = "Ŝanĝi delegacion por temaro"; 83.66 +["Change display settings"] = false; 83.67 +["Change filters and order"] = false; 83.68 ["Change global delegation"] = "Ŝanĝi ĝeneralan delegacion"; 83.69 ["Change issue delegation"] = "Ŝanĝi delegacion por la temo"; 83.70 ["Change login"] = "Ŝanĝi salutnomon"; 83.71 ["Change name"] = "Ŝanĝi nomon"; 83.72 +["Change order"] = false; 83.73 ["Change password"] = "Ŝanĝi pasvorton"; 83.74 +["Change vote"] = false; 83.75 ["Change your login"] = "Ŝanĝi vian salutnomon"; 83.76 ["Change your name"] = "Ŝanĝi vian nomon"; 83.77 ["Change your password"] = "Ŝanĝi vian pasvorton"; 83.78 ["Choose initiator"] = "Elekti iniciatanton"; 83.79 ["Choose member"] = "Elekti membron"; 83.80 ["Click for details"] = "Klaki por detaloj"; 83.81 -["Close"] = "Fermi"; 83.82 ["Closed"] = "Fermita"; 83.83 ["Collective opinion"] = "Opinioresumo"; 83.84 ["Commit suggestion"] = "Stori sugeston"; 83.85 @@ -80,21 +103,32 @@ 83.86 ["Current votings in areas you are member of and issues you are interested in:"] = "Aktualaj voĉdonoj pri temoj en kiuj vi membraa kaj kiuj vin interesas:"; 83.87 ["Degree"] = "Grado"; 83.88 ["Delegations"] = "Delegacioj"; 83.89 +["Delete filter"] = false; 83.90 ["Description"] = "Priskribo"; 83.91 ["Details"] = "Detaloj"; 83.92 -["Developer features"] = "Porprogramistaj funkcioj"; 83.93 +["Developer features"] = "Porprogramistaj funkcioj"; 83.94 ["Diff"] = "Diferenco"; 83.95 ["Direct member count"] = "Nombro de la rektaj membroj"; 83.96 ["Direct membership"] = "Rekta membreco"; 83.97 +["Disapproval (prefer to last block) [many entries]"] = false; 83.98 +["Disapproval (prefer to last block) [single entry]"] = false; 83.99 +["Disapproval (prefer to lower block) [many entries]"] = false; 83.100 +["Disapproval (prefer to lower block) [single entry]"] = false; 83.101 +["Disapproval (prefer to lower blocks) [many entries]"] = false; 83.102 +["Disapproval (prefer to lower blocks) [single entry]"] = false; 83.103 +["Disapproval [many entries]"] = false; 83.104 +["Disapproval [single entry]"] = false; 83.105 ["Discussion"] = "Diskuto"; 83.106 ["Discussion URL"] = "Diskuto-URL"; 83.107 ["Discussion on issue"] = "Diskuto pri la temo"; 83.108 ["Discussion time"] = "Tempo de la diskuto"; 83.109 ["Discussion with initiators"] = "Diskuto kun la iniciatintoj"; 83.110 +["Display settings"] = false; 83.111 ["Download"] = "Elŝuti"; 83.112 ["Download database export"] = "Elŝuti datumbazoeksporton"; 83.113 ["Draft"] = "Skizo"; 83.114 ["Draft history"] = "Skizohistorio"; 83.115 +["EXPERIMENTAL FEATURE"] = false; 83.116 ["Edit"] = "Redakti"; 83.117 ["Edit draft"] = "Redakti skizon"; 83.118 ["Edit initiative"] = "Redakti iniciaton"; 83.119 @@ -115,30 +149,32 @@ 83.120 ["Friday"] = "Vendredo"; 83.121 ["Frozen"] = "Ĝelita"; 83.122 ["Fully frozen at"] = "Tute ĝelita je"; 83.123 -["Global delegation"] = "Ĝenerala delegacio"; 83.124 -["Global delegation active"] = "Ĝenerala delegacio estas aktiva"; 83.125 -["Global timeline"] = "Ĝenerala tempolineo"; 83.126 +["Global delegation"] = "Ĝenerala delegacio"; 83.127 +["Global delegation active"] = "Ĝenerala delegacio estas aktiva"; 83.128 ["Half frozen at"] = "Duone ĝelita je"; 83.129 ["Hello "] = "Saluton "; 83.130 ["Help for: #{text}"] = "Helpo por: #{text}"; 83.131 ["Hide"] = "Kaŝi"; 83.132 +["Hide filter details"] = false; 83.133 ["Hide this help message"] = "Kaŝi tiun helpotekston"; 83.134 ["Home"] = "Ĉefpaĝo"; 83.135 ["I accept the terms of use by checking the following checkbox:"] = "Mi akceptas la uzokondiĉojn per la selekto de la sekva krucosignokesteto:"; 83.136 -["Id"] = "Identigilo"; 83.137 -["Ident number"] = "Identonumero"; 83.138 +["Id"] = "Identigilo"; 83.139 +["Ident number"] = "Identonumero"; 83.140 ["If this link is not working, please open following url in your web browser:\n\n"] = "Se tiu ligilo ne funkcias, bonvolu malfermi la sekvan URL per via retumilo:\n\n"; 83.141 ["Images"] = "Bildoj"; 83.142 ["In discussion"] = "En diskuton"; 83.143 ["Incoming delegations"] = "Alvenantaj delegacioj"; 83.144 -["Initiated initiatives"] = "Lanĉitaj iniciatoj "; 83.145 +["Initiated"] = false; 83.146 +["Initiated initiatives"] = "Lanĉitaj iniciatoj"; 83.147 +["Initiative events"] = false; 83.148 ["Initiative is revoked now"] = "Iniciato nun estas retirita"; 83.149 ["Initiative quorum"] = "Kvorumo de la iniciato"; 83.150 +["Initiative revoked"] = false; 83.151 ["Initiative successfully created"] = "Iniciato sukcese kreita"; 83.152 ["Initiative successfully updated"] = "Iniciato sukcese ĝisdatigita"; 83.153 ["Initiative: '#{name}'"] = "Iniciato: '#{name}'"; 83.154 ["Initiatives"] = "Iniciatoj"; 83.155 -["Initiatives per page"] = "Iniciatoj po paĝo"; 83.156 ["Initiatives that invited you to become initiator:"] = "Iniciatoj, kiuj vin invitis esti iniciatinto:"; 83.157 ["Initiator"] = "Iniciatinto"; 83.158 ["Initiators"] = "Iniciatintoj"; 83.159 @@ -154,16 +190,19 @@ 83.160 ["Invite code"] = "Invitokodo"; 83.161 ["Invite initiator"] = "Inviti iniciatanton"; 83.162 ["Invited"] = "Invitita"; 83.163 -["Inviting initiator"] = "Invitanta iniciatinto"; 83.164 ["Issue"] = "Temo"; 83.165 ["Issue ##{id}"] = "Temo ##{id}"; 83.166 -["Issue ##{id} (#{policy_name})"] = "Temo ##{id} (#{policy_name})"; 83.167 +["Issue accepted"] = false; 83.168 +["Issue canceled"] = false; 83.169 ["Issue delegation"] = "Temodelegacio"; 83.170 ["Issue delegation active"] = "Delegacio por temo aktiva"; 83.171 +["Issue events"] = false; 83.172 +["Issue finished"] = false; 83.173 +["Issue finished without voting"] = false; 83.174 +["Issue frozen"] = false; 83.175 ["Issue policy"] = "Regularo por temo"; 83.176 ["Issue quorum"] = "Kvorumo per temo"; 83.177 ["Issues"] = "Temoj"; 83.178 -["Issues per page"] = "Temoj po paĝo"; 83.179 ["JavaScript is disabled or not available."] = "JavaScript ne estas ŝaltita aŭ disponebla."; 83.180 ["Last author"] = "Lasta aŭtoro"; 83.181 ["Last snapshot:"] = "Lasta fulmrigardo:"; 83.182 @@ -175,6 +214,8 @@ 83.183 ["Login successful!"] = "Saluto sukcesa!"; 83.184 ["Logout"] = "Adiaŭi"; 83.185 ["Logout successful"] = "Adiaŭo sukcesa"; 83.186 +["Manage filter"] = false; 83.187 +["Manage timeline filters"] = false; 83.188 ["Mark suggestion as implemented and express dissatisfaction"] = "Marki sugeston kiel realigitan kaj esprimi malkontentecon"; 83.189 ["Mark suggestion as implemented and express satisfaction"] = "Marki sugeston kiel realigitan kaj esprimi kontentecon"; 83.190 ["Mark suggestion as not implemented and express dissatisfaction"] = "Marki sugeston kiel ne realigitan kaj esprimi malkontentecon"; 83.191 @@ -185,15 +226,18 @@ 83.192 ["Member '#{member}'"] = "Membro '#{member}'"; 83.193 ["Member has been removed from initiators"] = "La membro estas forigita de la iniciatantaro"; 83.194 ["Member has been removed from your contacts"] = "La membro estas forigita de viaj kontaktoj"; 83.195 +["Member has not approved latest draft"] = false; 83.196 ["Member is administrator"] = "La membro estas administranto"; 83.197 ["Member is already saved in your contacts!"] = "La membro estas jam konservita en viaj kontaktoj!"; 83.198 ["Member is now invited to be initiator"] = "La membro nun estas invitita kiel iniciatanto"; 83.199 ["Member list"] = "Membrolisto"; 83.200 ["Member name"] = "Membronomo"; 83.201 ["Member name history for '#{name}'"] = "Nomohistorio por '#{name}'"; 83.202 +["Member of area"] = false; 83.203 ["Member page"] = "Membropaĝo"; 83.204 ["Member successfully registered"] = "Membro sukcese registrita"; 83.205 ["Member successfully updated"] = "Membro sukcese ĝisdatigita"; 83.206 +["Member voting"] = false; 83.207 ["Member: '#{login}' (#{name})"] = "Membro: '#{login}' (#{name})"; 83.208 ["Members"] = "Membroj"; 83.209 ["Membership by delegation"] = "Membreco laŭ delegacio"; 83.210 @@ -204,25 +248,36 @@ 83.211 ["Missing help text: #{id}.#{lang}.txt"] = "Mankas helpoteksto: #{id}.#{lang}.txt"; 83.212 ["Mobile phone"] = "Poŝtelefono"; 83.213 ["Monday"] = "Lundo"; 83.214 +["Move down"] = false; 83.215 +["Move up"] = false; 83.216 ["My opinion"] = "Mia opinio"; 83.217 ["Name"] = "Nomo"; 83.218 ["New"] = "Nova"; 83.219 +["New draft"] = false; 83.220 ["New draft has been added to initiative"] = "La nova skizo estas aldonita al la iniciato"; 83.221 ["New draft revision"] = "Nova revizio de la skizon"; 83.222 +["New initiative"] = false; 83.223 +["New issue"] = false; 83.224 ["New password"] = "Nova pasvorto"; 83.225 ["New passwords does not match."] = "Vi ne enigis dufoje la saman pasvorton"; 83.226 ["New passwords is too short."] = "La nova pasvorto estas tro mallonga"; 83.227 +["New suggestion"] = false; 83.228 ["Newest"] = "Plej nova"; 83.229 ["Next state"] = "Sekva stato"; 83.230 ["No"] = "Ne"; 83.231 ["No changes to your images were made"] = "Viaj bildoj ne estas ŝanĝitaj"; 83.232 ["No delegation"] = "Neniu delegacio"; 83.233 +["No events selected to list"] = false; 83.234 ["No membership at all"] = "Tute sen membreco"; 83.235 ["No support at all"] = "Tute sen subteno"; 83.236 ["Not a member"] = "Ne estas membro"; 83.237 +["Not approved (rank #{rank})"] = false; 83.238 ["Not voted"] = "Ne balotinta"; 83.239 +["Not voted (not admitted)"] = false; 83.240 +["Not voted (revoked from initiator)"] = false; 83.241 ["Not yet voted"] = "Ankoraŭ ne balotinta"; 83.242 ["Number of incoming delegations, follow link to see more details"] = "Nombro de alvenantaj delegacioj, sekvi ligilon por pli da detaloj"; 83.243 +["Number of initiatives to preview"] = false; 83.244 ["OK"] = "Bone"; 83.245 ["Old draft revision"] = "Malnova revizio de la skizo"; 83.246 ["Old password"] = "Malnova pasvorto"; 83.247 @@ -234,6 +289,7 @@ 83.248 ["One issue you are interested in"] = "Unu temo, kiu vin interesas"; 83.249 ["One step back"] = "Unu paŝo reen"; 83.250 ["Open"] = "Malferma"; 83.251 +["Opinions"] = false; 83.252 ["Order by"] = "Ordigi laŭ"; 83.253 ["Organizational unit"] = "Organiza unuo"; 83.254 ["Outgoing delegations"] = "Elirantaj delegacioj"; 83.255 @@ -247,7 +303,7 @@ 83.256 ["Photo"] = "Foto"; 83.257 ["Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."] = "Bonvolu elekti salutonomon! Tiu nomo ne estas montrita al aliaj kaj nur vi uzas tiun nomon por la saluto. La uskleco (granda/malgranda) gravas"; 83.258 ["Please choose a member"] = "Bonvolu elekti membron"; 83.259 -["Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."] = "Bonvolu elekti nomon, ekzemple vian veran nomon aŭ kromnomon. Tiu nomo estas montrita al aliaj por vin identecigi."; 83.260 +["Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."] = "Bonvolu elekti nomon, ekzemple vian veran nomon aŭ kromnomon. Tiu nomo estas montrita al aliaj por vin identecigi."; 83.261 ["Please choose a password and enter it twice. The password is case sensitive."] = "Bonvolu elekti pasvorton kaj enigi tiun pasvorton dufoje! La uskleco (granda/malgranda) gravas."; 83.262 ["Please choose a policy"] = "Bonvolu elekti regularon"; 83.263 ["Please choose two different versions of the draft to compare"] = "Bonvolu elekti du malsamajn versiojn de la skizo por kompari ilin."; 83.264 @@ -260,14 +316,14 @@ 83.265 ["Please enter your new password twice."] = "Bonvolu enigi dufoje vian novan pasvorton:"; 83.266 ["Policy"] = "Regularo"; 83.267 ["Population"] = "Loĝantaro"; 83.268 -["Posts"] = "Postenoj"; -- im Sinne von Posten oder im Sinne von Einträge? Letzeres wäre "Enskriboj" 83.269 +["Posts"] = "Postenoj"; 83.270 ["Potential support"] = "Eventuala subteno"; 83.271 +["Potential supported"] = false; 83.272 ["Potential supporter"] = "Eventuala subtenanto"; 83.273 ["Profession"] = "Profesio"; 83.274 ["Profile"] = "Profilo"; 83.275 ["Publish"] = "Publikigi"; 83.276 ["Published"] = "Publikigita"; 83.277 -["Published contacts"] = "Kontaktoj publikigitaj"; 83.278 ["Rank"] = "Rango"; 83.279 ["Real name"] = "Vera nomo"; 83.280 ["Refresh support to current draft"] = "Refreŝigi subtenon por la aktuala skizo"; 83.281 @@ -283,6 +339,7 @@ 83.282 ["Remove initiator from initiative"] = "Ĉu forigi iniciatinton de la iniciato?"; 83.283 ["Remove my interest"] = "Forigi mian intereson"; 83.284 ["Remove my membership"] = "Forigi mian membrecon"; 83.285 +["Remove my request to vote later"] = false; 83.286 ["Remove my support from this initiative"] = "Forigi mian subtenon de la iniciato"; 83.287 ["Repeat new password"] = "Ripeti novan pasvorton"; 83.288 ["Request password reset link"] = "Demandi ligilon por remeti la pasvorton"; 83.289 @@ -295,12 +352,15 @@ 83.290 ["Revoked at"] = "Nuligita je"; 83.291 ["Saturday"] = "Sabato"; 83.292 ["Save"] = "Konservi"; 83.293 +["Save current filter"] = false; 83.294 +["Save timeline filters"] = false; 83.295 ["Saved as contact"] = "Konservi kiel kontakton"; 83.296 ["Search"] = "Serĉi"; 83.297 ["Search initiatives"] = "Serĉi iniciatojn"; 83.298 ["Search issues"] = "Serĉi temojn"; 83.299 ["Search members"] = "Serĉi membrojn"; 83.300 ["Search results for: '#{search}'"] = "Serĉorezultoj por: '#{search}'"; 83.301 +["Select language \"#{langcode}\""] = false; 83.302 ["Set URL"] = "Meti URL"; 83.303 ["Set area delegation"] = "Meti delegacion por temaro"; 83.304 ["Set autoreject"] = "Meti aŭtorifuzo"; 83.305 @@ -309,16 +369,20 @@ 83.306 ["Set global delegation"] = "Meti ĝeneralan delegacion"; 83.307 ["Set issue delegation"] = "Meti delegacion por temo"; 83.308 ["Set new password"] = "Meti novan pasvorton"; 83.309 -["Settings"] = "Agordoj"; 83.310 +["Settings"] = "Agordoj"; 83.311 ["Show"] = "Montri"; 83.312 ["Show active members"] = "Montri aktivajn membrojn"; 83.313 -["Show all initiatives"] = "Montri ĉiujn iniciatojn"; 83.314 +["Show alternative initiatives"] = false; 83.315 ["Show areas in use"] = "Montri uzatajn temarojn"; 83.316 ["Show areas not in use"] = "Montri ne uzatajn temarojn"; 83.317 ["Show diff"] = "Montri diferencojn"; 83.318 +["Show filter"] = false; 83.319 +["Show filter details"] = false; 83.320 +["Show help text"] = false; 83.321 ["Show locked members"] = "Montri blokitajn membrojn"; 83.322 ["Show member"] = "Montri membron"; 83.323 ["Show name history"] = "Montri nomohistorion"; 83.324 +["Show only events which match... (or associtated)"] = false; 83.325 ["Software"] = "Programaro"; 83.326 ["Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."] = "Kelkaj funkcioj bazitaj je JavaScript (precipe la voĉdono) ne funkcios.\nBonvolu, uzi por tiu betaversio aktualan version de Firefox, Safari, Opera(?), Konqueror aŭ alian (pli) normokonforman retumilon.\nAlternativa atingo sen JavaScript estos baldaŭ disponeble."; 83.327 ["Sorry, but there is not confirmed email address for your account. Please contact the administrator or support."] = "Pardonu, por tiu konto ne ekzistas konfirmita retadreson. Bonvolu vin turni al administranto aŭ al la helpantaro."; 83.328 @@ -344,15 +408,27 @@ 83.329 ["Sunday"] = "Dimanĉo"; 83.330 ["Support"] = "Subteno"; 83.331 ["Support this initiative"] = "Subteni tiun iniciaton"; 83.332 +["Supported"] = false; 83.333 ["Supported initiatives"] = "Iniciatoj subtenitaj"; 83.334 ["Supporter"] = "Subtenantoj"; 83.335 +["Tabs"] = false; 83.336 ["Terms accepted"] = "Kondiĉoj akceptitaj"; 83.337 +["Terms of use"] = false; 83.338 ["The code you've entered is invalid"] = "La kodo, kiun vi enigis ne estas valida!"; 83.339 +["The draft of this initiative has been updated!"] = false; 83.340 ["The drafts do not differ"] = "La skizoj ne estas malsamaj"; 83.341 ["The initiators suggest to support the following initiative:"] = "La iniciatantoj rekomendas subteni sekvan iniciaton:"; 83.342 +["There are no more alternative initiatives currently."] = false; 83.343 +["There were no more alternative initiatives."] = false; 83.344 +["This initiative"] = false; 83.345 +["This initiative compared to alternative initiatives"] = false; 83.346 ["This initiative has been revoked at #{revoked}"] = "Tiu iniciato estis nuligita je #{revoked}"; 83.347 +["This initiative has not been admitted! It failed the quorum of #{quorum}."] = false; 83.348 ["This initiative is already revoked"] = "Tiu iniciato estas jam nuligita"; 83.349 ["This initiative is revoked"] = "Tiu iniciato estas nuligita"; 83.350 +["This issue has been cancelled. It failed the quorum of #{quorum}."] = false; 83.351 +["This issue has been finished with the following winning initiative:"] = false; 83.352 +["This issue has been finished without any winning initiative."] = false; 83.353 ["This issue is already closed."] = "La temo estas jam fermita."; 83.354 ["This issue is already frozen."] = "La temo estas jam ĝelita"; 83.355 ["This login is already taken, please choose another one!"] = "Tiu salutnomo estas jam fordonita, bonvolu elekti alian!"; 83.356 @@ -361,6 +437,7 @@ 83.357 ["This member has rejected to become initiator of this initiative"] = "Tiu membro rifuzis inviton por esti iniciatanto"; 83.358 ["This member is already initiator of this initiative"] = "Tiu membro estas jam iniciatanto de tiu iniciato"; 83.359 ["This member is already invited to become initiator of this initiative"] = "Tiu membro estis jam invitita por esti iniciatanto de tiu iniciato"; 83.360 +["This member is participating, the rest of delegation chain is suspended while discussing"] = false; 83.361 ["This name is already taken, please choose another one!"] = "Tiu nomo estas jam fordonita, bonvolu elekti alian!"; 83.362 ["This name is really too short!"] = "Tiu nomo estas vere tro mallonga!"; 83.363 ["This name is too short!"] = "Tiu nomo estas tro mallonga!"; 83.364 @@ -369,43 +446,49 @@ 83.365 ["This username is too short!"] = "Tiu salutonomo estas tro mallonga!"; 83.366 ["Thursday"] = "Ĵaŭdo"; 83.367 ["Time left"] = "Restanta tempo"; 83.368 +["Timeline"] = false; 83.369 +["Title"] = false; 83.370 ["Title (80 chars max)"] = "Titolo (maksimume 80 literoj)"; 83.371 -["Today"] = "Hodiaŭ"; 83.372 ["Traditional wiki syntax"] = "Tradicia Viki-sintakso"; 83.373 -["Trustee"] = "Fidulo mastrumanta"; -- kommt stark auf den Sinn an, ist ohne Kontext schwierig 83.374 +["Trustee"] = "Fidulo mastrumanta"; 83.375 ["Tuesday"] = "Mardo"; 83.376 +["Type of tabs"] = false; 83.377 ["Unknown author"] = "Aŭtoro nekonata"; 83.378 ["Upload images"] = "Alŝuti bildojn"; 83.379 ["Used until"] = "Uzita ĝis"; 83.380 ["Verification time"] = "Tempo por la kontrolo"; 83.381 ["Version"] = "Versio"; 83.382 ["Vote later"] = "Baloti pli malfrue"; 83.383 +["Vote later requests"] = false; 83.384 ["Vote now"] = "Baloti nun"; 83.385 -["Vote now/later"] = "Baloti nun/pli malfrue"; 83.386 ["Voted"] = "Balotita"; 83.387 ["Voted no"] = "Balotita nee"; 83.388 ["Voted proposal"] = "Propono balotita"; 83.389 ["Voted yes"] = "Balotita jese"; 83.390 -["Voter"] = "Voĉdonantoj"; 83.391 ["Voting"] = "Voĉdono"; 83.392 +["Voting details"] = false; 83.393 ["Voting for this issue has already begun."] = "Voĉdono pri tiu temo jam komenciĝis."; 83.394 ["Voting for this issue is currently running!"] = "Voĉdono pri tiu temo okazas nun!"; 83.395 ["Voting has not started yet."] = "Voĉdono por tiu temo ankoraŭ ne komenciĝis."; 83.396 ["Voting proposal"] = "Privoĉdonendaj proponoj"; 83.397 -["Voting requests"] = "Voĉdonopetoj"; 83.398 +["Voting request updated"] = false; 83.399 +["Voting started"] = false; 83.400 ["Voting time"] = "Tempo por la voĉdono"; 83.401 ["Website"] = "Retpaĝo"; 83.402 ["Wednesday"] = "Merkredo"; 83.403 ["Wiki engine"] = "Viki-motoro"; 83.404 ["Yes"] = "Jes"; 83.405 -["Yesterday"] = "Hieraŭ"; 83.406 ["You are already initator"] = "Vi estas jam iniciatanto"; 83.407 ["You are already not supporting this initiative"] = "Vi jam ne subtenas tiun iniciaton"; 83.408 ["You are already supporting the latest draft"] = "Vi jam subtenas la plej novan skizon"; 83.409 ["You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."] = "Vi aktuale ne subtenas tiun iniciaton. Se vi aldonas sugeston al tiu iniciato vi estos aŭtomate eventuala subtenanto!"; 83.410 +["You are iniator of this initiative"] = false; 83.411 +["You are interested in this issue"] = false; 83.412 ["You are invited to become initiator of this initiative."] = "Vi estas invitita por esti iniciatanto de tiu iniciato."; 83.413 ["You are member"] = "Vi estas membro"; 83.414 ["You are now initiator of this initiative"] = "Vi nun estas iniciatanto de tiu iniciato"; 83.415 +["You are potential supporter of this initiative"] = false; 83.416 +["You are supporting this initiative"] = false; 83.417 ["You can't suggest the initiative you are revoking"] = "Vi ne povas rekomendi la iniciaton, kiun vi nuligas"; 83.418 ["You didn't saved any member as contact yet."] = "Vi ankoraŭ ne storis membron kiel kontakton!"; 83.419 ["You have saved this member as contact"] = "Vi storis membron kiel kontakton"; 83.420 @@ -413,6 +496,7 @@ 83.421 ["You have to accept the terms of use to complete registration."] = "Vi devas akcepti la uzokondiĉojn por fini la registradon."; 83.422 ["You have to mark 'Are you sure' to revoke!"] = "Por nuligi vi devas elekti 'Certa?'"; 83.423 ["You need to be logged in, to use this system."] = "Vi devas esti ensalutinta, por uzi la sistemon"; 83.424 +["You want to vote later"] = false; 83.425 ["You've successfully registered and you can login now with your login and password!"] = "Vi sukcese registriĝis kaj povas nun ensaluti per via salutnomo kaj pasvorto!"; 83.426 ["Your are interested"] = "Vi estas interesita"; 83.427 ["Your are potential supporter"] = "Vi estas eventuala subtenanto"; 83.428 @@ -421,6 +505,7 @@ 83.429 ["Your delegation for this area has been updated."] = "Via delegacio por tiu temaro estas ĝisdatigita"; 83.430 ["Your delegation for this issue has been deleted."] = "Via delegacio por tiu temaro estas viŝita"; 83.431 ["Your delegation for this issue has been updated."] = "Via delegacio por tiu temaro estas ĝisdatigita"; 83.432 +["Your display settings have been updated"] = false; 83.433 ["Your global delegation has been deleted."] = "Via ĝenerala delegacio estas viŝita"; 83.434 ["Your global delegation has been updated."] = "Via ĝenerala delegacio estas ĝisdatigita"; 83.435 ["Your login has been changed to '#{login}'"] = "Via salutnomo estas ĝisdatigita al '#{login}'"; 83.436 @@ -435,17 +520,18 @@ 83.437 ["Your support has been updated to the latest draft"] = "Via subteno estas ĝisdatigita al la plej nova skizo"; 83.438 ["Your web browser is not fully supported yet."] = "Via retumilo ne estas jam komplete subtenita."; 83.439 ["Z-A"] = "Z-A"; 83.440 -["all"] = "ĉiuj"; 83.441 +["and #{count} more initiatives"] = false; 83.442 ["continuing"] = "kontinue"; 83.443 ["delete<br /><br />"] = "forviŝi<br /><br />"; 83.444 ["email"] = "Retpoŝto"; 83.445 +["last 24 hours"] = false; 83.446 ["login name"] = "Salutnomo"; 83.447 ["must"] = "devas"; 83.448 ["must not"] = "ne rajtas"; 83.449 ["must/should"] = "devus"; 83.450 ["must/should not"] = "ne devus"; 83.451 ["neutral"] = "neŭtrala"; 83.452 -["not implemented"] = "ne realigita"; 83.453 +["requested"] = false; 83.454 ["should"] = "devus"; 83.455 ["should not"] = "ne devus"; 83.456 ["to reset your password please click on the following link:\n\n"] = "por remeti vian pasvorton bonvolu klaki sekvan ligilon:\n\n";
84.1 --- a/model/initiative.lua Tue Feb 02 00:31:06 2010 +0100 84.2 +++ b/model/initiative.lua Sat Feb 20 22:10:31 2010 +0100 84.3 @@ -16,7 +16,7 @@ 84.4 that_key = 'initiative_id', 84.5 ref = 'drafts', 84.6 back_ref = 'initiative', 84.7 - default_order = '"id"' 84.8 + default_order = '"id" DESC' 84.9 } 84.10 84.11 Initiative:add_reference{ 84.12 @@ -129,8 +129,11 @@ 84.13 :add_group_by('"initiative"."negative_votes"') 84.14 :add_group_by('"initiative"."agreed"') 84.15 :add_group_by('"initiative"."rank"') 84.16 + :add_group_by('"initiative"."suggested_initiative_id"') 84.17 :add_group_by('"initiative"."text_search_data"') 84.18 :add_group_by('"issue"."population"') 84.19 + :add_group_by("_initiator.member_id") 84.20 + :add_group_by("_supporter.member_id") 84.21 end 84.22 84.23 function Member:get_search_selector(search_string)
85.1 --- a/model/issue.lua Tue Feb 02 00:31:06 2010 +0100 85.2 +++ b/model/issue.lua Sat Feb 20 22:10:31 2010 +0100 85.3 @@ -142,6 +142,7 @@ 85.4 :add_group_by('"issue"."vote_now"') 85.5 :add_group_by('"issue"."vote_later"') 85.6 :add_group_by('"issue"."voter_count"') 85.7 + :add_group_by('"_interest"."member_id"') 85.8 --:set_distinct() 85.9 end 85.10
86.1 --- a/model/member.lua Tue Feb 02 00:31:06 2010 +0100 86.2 +++ b/model/member.lua Sat Feb 20 22:10:31 2010 +0100 86.3 @@ -311,10 +311,26 @@ 86.4 return success 86.5 end 86.6 86.7 -function Member.object:get_setting_by_key(key) 86.8 +function Member.object:get_setting(key) 86.9 + return Setting:by_pk(app.session.member.id, key) 86.10 +end 86.11 + 86.12 +function Member.object:get_setting_value(key) 86.13 + local setting = Setting:by_pk(app.session.member.id, key) 86.14 + if setting then 86.15 + return setting.value 86.16 + end 86.17 end 86.18 86.19 function Member.object:set_setting(key, value) 86.20 + local setting = self:get_setting(key) 86.21 + if not setting then 86.22 + setting = Setting:new() 86.23 + setting.member_id = app.session.member_id 86.24 + setting.key = key 86.25 + end 86.26 + setting.value = value 86.27 + setting:save() 86.28 end 86.29 86.30 function Member.object:get_setting_maps_by_key(key)
87.1 Binary file static/icons/16/bullet_blue.png has changed
88.1 Binary file static/icons/16/bullet_toggle_minus.png has changed
89.1 Binary file static/icons/16/bullet_toggle_plus.png has changed
90.1 Binary file static/icons/16/connect.png has changed
91.1 Binary file static/icons/16/help_yellow.png has changed
92.1 Binary file static/icons/16/lock.png has changed
93.1 Binary file static/icons/16/resultset_next.png has changed
94.1 Binary file static/icons/move_down.png has changed
95.1 Binary file static/icons/move_up.png has changed
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 96.2 +++ b/static/js/partialload.js Sat Feb 20 22:10:31 2010 +0100 96.3 @@ -0,0 +1,271 @@ 96.4 + 96.5 +partialload_queue = []; 96.6 +partialload_queueRPos = 0; 96.7 +partialload_queueWPos = 0; 96.8 + 96.9 +function partialload_getFormKeyValuePairs(form) { 96.10 + var result = {}; 96.11 + for (var i=0; i<form.elements.length; i++) { 96.12 + var inputElement = form.elements[i]; 96.13 + var key = inputElement.name; 96.14 + var value = inputElement.value; 96.15 + if (result[key] == null) result[key] = value; 96.16 + else if (typeof(result[key]) == "object") { 96.17 + result[key][result[key].length] = value; 96.18 + } else { 96.19 + result[key] = [result[key], value]; 96.20 + } 96.21 + } 96.22 + return result; 96.23 +} 96.24 + 96.25 +function partialload_encodeFormData(params) { 96.26 + var result = ""; 96.27 + for (var key in params) { 96.28 + var value = params[key]; 96.29 + if (typeof(value) == "string") { 96.30 + if (result != "") result += "&"; 96.31 + result += encodeURIComponent(key) + "=" + encodeURIComponent(value); 96.32 + } else if (typeof(value) == "object") { 96.33 + var i; 96.34 + for (i=0; i<value.length; i++) { 96.35 + if (result != "") result += "&"; 96.36 + result += encodeURIComponent(key) + "=" + encodeURIComponent(value[i]); 96.37 + } 96.38 + } 96.39 + } 96.40 + return result; 96.41 +} 96.42 + 96.43 +function partialload_addFormDataToUrl(url, params) { 96.44 + if (params != null && typeof(params) != "string") { 96.45 + params = partialload_encodeFormData(params); 96.46 + } 96.47 + if (params != null) { 96.48 + if (url.search(/\?/) >= 0) { 96.49 + if (url.search(/&$/) >= 0) { 96.50 + url = url + params; 96.51 + } else { 96.52 + url = url + "&" + params; 96.53 + } 96.54 + } else { 96.55 + url = url + "?" + params; 96.56 + } 96.57 + } 96.58 + return url; 96.59 +} 96.60 + 96.61 +function partialload_mergeEncodedFormData(data1, data2) { 96.62 + if (data2 == null || data2 == "") return data1; 96.63 + if (data1 == null || data1 == "") return data2; 96.64 + return data1 + "&" + data2; 96.65 +} 96.66 + 96.67 +function partialload_startNextRequest() { 96.68 + var entry = partialload_queue[partialload_queueRPos++]; 96.69 + var req = new XMLHttpRequest(); 96.70 + req.open(entry.method, entry.url, true); 96.71 + req.onreadystatechange = function() { 96.72 + if (req.readyState == 4) { 96.73 + if (req.status == 200) { 96.74 + if (entry.successHandler != null) entry.successHandler(req.responseText); 96.75 + } else { 96.76 + if (entry.failureHandler != null) entry.failureHandler(); 96.77 + } 96.78 + if (partialload_queue[partialload_queueRPos]) { 96.79 + partialload_startNextRequest(); 96.80 + } else { 96.81 + partialload_queue = []; 96.82 + partialload_queueRPos = 0; 96.83 + partialload_queueWPos = 0; 96.84 + } 96.85 + } 96.86 + } 96.87 + if (entry.data) { 96.88 + req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 96.89 + } 96.90 + req.send(entry.data); 96.91 +} 96.92 + 96.93 +function queuedHttpRequest( 96.94 + url_or_form, 96.95 + urlParams, 96.96 + postParams, 96.97 + successHandler, 96.98 + failureHandler 96.99 +) { 96.100 + var method; 96.101 + var data = null; 96.102 + if (typeof(postParams) == "string") { 96.103 + data = postParams; 96.104 + } else if (postParams != null) { 96.105 + data = partialload_encodeFormData(postParams); 96.106 + } 96.107 + var url; 96.108 + if (typeof(url_or_form) == "object") { 96.109 + // form element given 96.110 + var form = url_or_form; 96.111 + url = partialload_addFormDataToUrl(form.action, urlParams); 96.112 + var dataFromForm = partialload_encodeFormData( 96.113 + partialload_getFormKeyValuePairs(form) 96.114 + ); 96.115 + if (form.method != null && form.method.search(/^POST$/i) >= 0) { 96.116 + method = "POST"; 96.117 + data = partialload_mergeEncodedFormData(data, dataFromForm); 96.118 + } else { 96.119 + method = (postParams == NULL) ? "GET" : "POST"; 96.120 + url = partialload_addFormDataToUrl(url, dataFromForm); 96.121 + } 96.122 + } else { 96.123 + // URL given 96.124 + url = partialload_addFormDataToUrl(url_or_form, urlParams); 96.125 + if (postParams == null) { 96.126 + method = "GET"; 96.127 + } else { 96.128 + method = "POST"; 96.129 + if (typeof(postParams) == "string") { 96.130 + data = postParams; 96.131 + } else { 96.132 + data = partialload_encodeFormData(postParams); 96.133 + } 96.134 + } 96.135 + } 96.136 + partialload_queue[partialload_queueWPos++] = { 96.137 + method: method, 96.138 + url: url, 96.139 + data: data, 96.140 + successHandler: successHandler, 96.141 + failureHandler: failureHandler 96.142 + }; 96.143 + if (partialload_queueRPos == 0) { 96.144 + partialload_startNextRequest(); 96.145 + } 96.146 +} 96.147 + 96.148 +function setHtmlContent(node, htmlWithScripts) { 96.149 + var uniquePrefix = "placeholder" + Math.floor(Math.random()*10e16) + "_"; 96.150 + var i = 0; 96.151 + var scripts = []; 96.152 + var htmlWithPlaceholders = ""; 96.153 + // NOTE: This function can not handle CDATA blocks at random positions. 96.154 + htmlWithPlaceholders = htmlWithScripts.replace( 96.155 + /<script[^>]*>(.*?)<\/script>/ig, 96.156 + function(all, inside) { 96.157 + scripts[i] = inside; 96.158 + var placeholder = '<span id="' + uniquePrefix + i + '"></span>'; 96.159 + i++; 96.160 + return placeholder; 96.161 + } 96.162 + ) 96.163 + node.innerHTML = htmlWithPlaceholders; 96.164 + var documentWriteBackup = document.write; 96.165 + var documentWritelnBackup = document.writeln; 96.166 + var output; 96.167 + document.write = function(str) { output += str; } 96.168 + document.writeln = function(str) { output += str + "\n"; } 96.169 + for (i=0; i<scripts.length; i++) { 96.170 + var placeholderNode = document.getElementById(uniquePrefix + i); 96.171 + output = ""; 96.172 + eval(scripts[i]); 96.173 + if (output != "") { 96.174 + placeholderNode.innerHTML = output; 96.175 + while (placeholderNode.childNodes.length > 0) { 96.176 + var childNode = placeholderNode.childNodes[0]; 96.177 + placeholderNode.removeChild(childNode); 96.178 + placeholderNode.parentNode.insertBefore(childNode, placeholderNode); 96.179 + } 96.180 + } 96.181 + placeholderNode.parentNode.removeChild(placeholderNode); 96.182 + } 96.183 + document.write = documentWriteBackup; 96.184 + document.writeln = documentWritelnBackup; 96.185 +} 96.186 + 96.187 +function partialLoad( 96.188 + node, 96.189 + tempLoadingContent, 96.190 + failureContent, 96.191 + url_or_form, 96.192 + urlParams, 96.193 + postParams, 96.194 + successHandler, 96.195 + failureHandler 96.196 +) { 96.197 + if (typeof(node) == "string") node = document.getElementById(node); 96.198 + if (tempLoadingContent != null) setHtmlContent(node, tempLoadingContent); 96.199 + queuedHttpRequest( 96.200 + url_or_form, 96.201 + urlParams, 96.202 + postParams, 96.203 + function(response) { 96.204 + setHtmlContent(node, response); 96.205 + if (successHandler != null) successHandler(); 96.206 + }, 96.207 + function() { 96.208 + if (failureContent != null) setHtmlContent(node, failureContent); 96.209 + if (failureHandler != null) failureHandler(); 96.210 + } 96.211 + ); 96.212 +} 96.213 + 96.214 +function partialMultiLoad( 96.215 + mapping, 96.216 + tempLoadingContents, 96.217 + failureContents, 96.218 + url_or_form, 96.219 + urlParams, 96.220 + postParams, 96.221 + successHandler, 96.222 + failureHandler 96.223 +) { 96.224 + if (mapping instanceof Array) { 96.225 + var mappingHash = {} 96.226 + for (var i=0; i<mapping.length; i++) { 96.227 + mappingHash[mapping[i]] = mapping[i]; 96.228 + } 96.229 + mapping = mappingHash; 96.230 + } 96.231 + if (typeof(tempLoadingContents) == "string") { 96.232 + for (var key in mapping) { 96.233 + var node = key; 96.234 + if (typeof(node) == "string") node = document.getElementById(node); 96.235 + setHtmlContent(node, tempLoadingContents); 96.236 + } 96.237 + } else if (tempLoadingContents != null) { 96.238 + for (var key in tempLoadingContents) { 96.239 + var node = key; 96.240 + if (typeof(node) == "string") node = document.getElementById(node); 96.241 + setHtmlContent(node, tempLoadingContents[key]); 96.242 + } 96.243 + } 96.244 + queuedHttpRequest( 96.245 + url_or_form, 96.246 + urlParams, 96.247 + postParams, 96.248 + function(response) { 96.249 + var data = eval("(" + response + ")"); 96.250 + for (var key in mapping) { 96.251 + var node = key; 96.252 + if (typeof(node) == "string") node = document.getElementById(node); 96.253 + setHtmlContent(node, data[mapping[key]]); 96.254 + } 96.255 + if (successHandler != null) successHandler(); 96.256 + }, 96.257 + function() { 96.258 + if (typeof(failureContents) == "string") { 96.259 + for (var key in mapping) { 96.260 + var node = key; 96.261 + if (typeof(node) == "string") node = document.getElementById(node); 96.262 + setHtmlContent(node, failureContents); 96.263 + } 96.264 + } else if (failureContents != null) { 96.265 + for (var key in failureContents) { 96.266 + var node = key; 96.267 + if (typeof(node) == "string") node = document.getElementById(node); 96.268 + setHtmlContent(node, failureContents[key]); 96.269 + } 96.270 + } 96.271 + if (failureHandler != null) failureHandler(); 96.272 + } 96.273 + ); 96.274 +}
97.1 --- a/static/js/voting.js Tue Feb 02 00:31:06 2010 +0100 97.2 +++ b/static/js/voting.js Sat Feb 20 22:10:31 2010 +0100 97.3 @@ -1,4 +1,25 @@ 97.4 -function setCategoryHeadings() { 97.5 +voting_text_approval_single = "Approval" 97.6 +voting_text_approval_multi = "Approval" 97.7 +voting_text_first_preference_single = "Approval (first preference)" 97.8 +voting_text_first_preference_multi = "Approval (first preference)" 97.9 +voting_text_second_preference_single = "Approval (second preference)" 97.10 +voting_text_second_preference_multi = "Approval (second preference)" 97.11 +voting_text_third_preference_single = "Approval (third preference)" 97.12 +voting_text_third_preference_multi = "Approval (third preference)" 97.13 +voting_text_numeric_preference_single = "Approval (#th preference)" 97.14 +voting_text_numeric_preference_multi = "Approval (#th preference)" 97.15 +voting_text_abstention_single = "Abstention" 97.16 +voting_text_abstention_multi = "Abstention" 97.17 +voting_text_disapproval_above_one_single = "Disapproval (prefer to lower block)" 97.18 +voting_text_disapproval_above_one_multi = "Disapproval (prefer to lower block)" 97.19 +voting_text_disapproval_above_many_single = "Disapproval (prefer to lower blocks)" 97.20 +voting_text_disapproval_above_many_multi = "Disapproval (prefer to lower blocks)" 97.21 +voting_text_disapproval_above_last_single = "Disapproval (prefer to last block)" 97.22 +voting_text_disapproval_above_last_multi = "Disapproval (prefer to last block)" 97.23 +voting_text_disapproval_single = "Disapproval" 97.24 +voting_text_disapproval_multi = "Disapproval" 97.25 + 97.26 +function voting_setCategoryHeadings() { 97.27 var approvalCount = 0; 97.28 var disapprovalCount = 0; 97.29 var sections = document.getElementById("voting").childNodes; 97.30 @@ -34,42 +55,53 @@ 97.31 if (section.className == "approval") { 97.32 if (approvalCount > 1) { 97.33 if (approvalIndex == 0) { 97.34 - if (count == 1) setHeading("Zustimmung (Erstwunsch)"); 97.35 - else setHeading("Zustimmung (Erstwünsche)"); 97.36 + if (count == 1) setHeading(voting_text_first_preference_single); 97.37 + else setHeading(voting_text_first_preference_multi); 97.38 } else if (approvalIndex == 1) { 97.39 - if (count == 1) setHeading("Zustimmung (Zweitwunsch)"); 97.40 - else setHeading("Zustimmung (Zweitwünsche)"); 97.41 + if (count == 1) setHeading(voting_text_second_preference_single); 97.42 + else setHeading(voting_text_second_preference_multi); 97.43 } else if (approvalIndex == 2) { 97.44 - if (count == 1) setHeading("Zustimmung (Drittwunsch)"); 97.45 - else setHeading("Zustimmung (Drittwünsche)"); 97.46 + if (count == 1) setHeading(voting_text_third_preference_single); 97.47 + else setHeading(voting_text_third_preference_multi); 97.48 } else { 97.49 - if (count == 1) setHeading("Zustimmung (" + (approvalIndex+1) + ".-Wunsch)"); 97.50 - else setHeading("Zustimmung (" + (approvalIndex+1) + ".-Wünsche)"); 97.51 + var text; 97.52 + if (count == 1) text = voting_text_numeric_preference_single; 97.53 + else text = voting_text_numeric_preference_multi; 97.54 + text = text.replace(/#/, "" + (approvalIndex + 1)) 97.55 + setHeading(text); 97.56 } 97.57 } else { 97.58 - setHeading("Zustimmung"); 97.59 + if (count == 1) setHeading(voting_text_approval_single); 97.60 + else setHeading(voting_text_approval_multi); 97.61 } 97.62 approvalIndex++; 97.63 } else if (section.className == "abstention") { 97.64 - setHeading("Enthaltung"); 97.65 + if (count == 1) setHeading(voting_text_abstention_single); 97.66 + else setHeading(voting_text_abstention_multi); 97.67 } else if (section.className == "disapproval") { 97.68 if (disapprovalCount > disapprovalIndex + 2) { 97.69 - setHeading("Ablehnung (jedoch Bevorzugung gegenüber unteren Ablehnungsblöcken)") 97.70 + if (count == 1) setHeading(voting_text_disapproval_above_many_single); 97.71 + else setHeading(voting_text_disapproval_above_many_multi); 97.72 } else if (disapprovalCount == 2 && disapprovalIndex == 0) { 97.73 - setHeading("Ablehnung (jedoch Bevorzugung gegenüber unterem Ablehnungsblock)") 97.74 + if (count == 1) setHeading(voting_text_disapproval_above_one_single); 97.75 + else setHeading(voting_text_disapproval_above_one_multi); 97.76 } else if (disapprovalIndex == disapprovalCount - 2) { 97.77 - setHeading("Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)") 97.78 + if (count == 1) setHeading(voting_text_disapproval_above_last_single); 97.79 + else setHeading(voting_text_disapproval_above_last_multi); 97.80 } else { 97.81 - setHeading("Ablehnung"); 97.82 + if (count == 1) setHeading(voting_text_disapproval_single); 97.83 + else setHeading(voting_text_disapproval_multi); 97.84 } 97.85 disapprovalIndex++; 97.86 } 97.87 } 97.88 } 97.89 } 97.90 -function elementDropped(element, dropX, dropY) { 97.91 +function voting_move(element, up, dropX, dropY) { 97.92 + if (typeof(element) == "string") element = document.getElementById(element); 97.93 + var mouse = (up == null); 97.94 var oldParent = element.parentNode; 97.95 - var centerY = dropY + element.clientHeight / 2 97.96 + if (mouse) var centerY = dropY + element.clientHeight / 2; 97.97 var approvalCount = 0; 97.98 var disapprovalCount = 0; 97.99 var mainDiv = document.getElementById("voting"); 97.100 @@ -79,43 +111,7 @@ 97.101 if (section.className == "approval") approvalCount++; 97.102 if (section.className == "disapproval") disapprovalCount++; 97.103 } 97.104 - for (var i=0; i<sections.length; i++) { 97.105 - var section = sections[i]; 97.106 - if ( 97.107 - section.className == "approval" || 97.108 - section.className == "abstention" || 97.109 - section.className == "disapproval" 97.110 - ) { 97.111 - if ( 97.112 - centerY >= section.offsetTop && 97.113 - centerY < section.offsetTop + section.clientHeight 97.114 - ) { 97.115 - var entries = section.childNodes; 97.116 - for (var j=0; j<entries.length; j++) { 97.117 - var entry = entries[j]; 97.118 - if (entry.className == "movable") { 97.119 - if (centerY < entry.offsetTop + entry.clientHeight / 2) { 97.120 - if (element != entry) { 97.121 - oldParent.removeChild(element); 97.122 - section.insertBefore(element, entry); 97.123 - } 97.124 - break; 97.125 - } 97.126 - } 97.127 - } 97.128 - if (j == entries.length) { 97.129 - oldParent.removeChild(element); 97.130 - section.appendChild(element); 97.131 - } 97.132 - break; 97.133 - } 97.134 - } 97.135 - } 97.136 - if (i == sections.length) { 97.137 - var newSection = document.createElement("div"); 97.138 - var cathead = document.createElement("div"); 97.139 - cathead.setAttribute("class", "cathead"); 97.140 - newSection.appendChild(cathead); 97.141 + if (mouse) { 97.142 for (var i=0; i<sections.length; i++) { 97.143 var section = sections[i]; 97.144 if ( 97.145 @@ -123,28 +119,145 @@ 97.146 section.className == "abstention" || 97.147 section.className == "disapproval" 97.148 ) { 97.149 - if (centerY < section.offsetTop + section.clientHeight / 2) { 97.150 - if (section.className == "disapproval") { 97.151 - newSection.setAttribute("class", "disapproval"); 97.152 - disapprovalCount++; 97.153 - } else { 97.154 - newSection.setAttribute("class", "approval"); 97.155 - approvalCount++; 97.156 + if ( 97.157 + centerY >= section.offsetTop && 97.158 + centerY < section.offsetTop + section.clientHeight 97.159 + ) { 97.160 + var entries = section.childNodes; 97.161 + for (var j=0; j<entries.length; j++) { 97.162 + var entry = entries[j]; 97.163 + if (entry.className == "movable") { 97.164 + if (centerY < entry.offsetTop + entry.clientHeight / 2) { 97.165 + if (element != entry) { 97.166 + oldParent.removeChild(element); 97.167 + section.insertBefore(element, entry); 97.168 + } 97.169 + break; 97.170 + } 97.171 + } 97.172 } 97.173 - mainDiv.insertBefore(newSection, section); 97.174 + if (j == entries.length) { 97.175 + oldParent.removeChild(element); 97.176 + section.appendChild(element); 97.177 + } 97.178 break; 97.179 } 97.180 } 97.181 } 97.182 if (i == sections.length) { 97.183 - newSection.setAttribute("class", "disapproval"); 97.184 - disapprovalCount++; 97.185 - mainDiv.appendChild(newSection); 97.186 + var newSection = document.createElement("div"); 97.187 + var cathead = document.createElement("div"); 97.188 + cathead.setAttribute("class", "cathead"); 97.189 + newSection.appendChild(cathead); 97.190 + for (var i=0; i<sections.length; i++) { 97.191 + var section = sections[i]; 97.192 + if ( 97.193 + section.className == "approval" || 97.194 + section.className == "abstention" || 97.195 + section.className == "disapproval" 97.196 + ) { 97.197 + if (centerY < section.offsetTop + section.clientHeight / 2) { 97.198 + if (section.className == "disapproval") { 97.199 + newSection.setAttribute("class", "disapproval"); 97.200 + disapprovalCount++; 97.201 + } else { 97.202 + newSection.setAttribute("class", "approval"); 97.203 + approvalCount++; 97.204 + } 97.205 + mainDiv.insertBefore(newSection, section); 97.206 + break; 97.207 + } 97.208 + } 97.209 + } 97.210 + if (i == sections.length) { 97.211 + newSection.setAttribute("class", "disapproval"); 97.212 + disapprovalCount++; 97.213 + mainDiv.appendChild(newSection); 97.214 + } 97.215 + oldParent.removeChild(element); 97.216 + newSection.appendChild(element); 97.217 + } 97.218 + } else { 97.219 + var oldFound = false; 97.220 + var prevSection = null; 97.221 + var nextSection = null; 97.222 + for (var i=0; i<sections.length; i++) { 97.223 + var section = sections[i]; 97.224 + if ( 97.225 + section.className == "approval" || 97.226 + section.className == "abstention" || 97.227 + section.className == "disapproval" 97.228 + ) { 97.229 + if (oldFound) { 97.230 + nextSection = section; 97.231 + break; 97.232 + } else if (section == oldParent) { 97.233 + oldFound = true; 97.234 + } else { 97.235 + prevSection = section; 97.236 + } 97.237 + } 97.238 } 97.239 - oldParent.removeChild(element); 97.240 - newSection.appendChild(element); 97.241 + var create; 97.242 + if (oldParent.className == "abstention") { 97.243 + create = true; 97.244 + } else { 97.245 + create = false; 97.246 + for (var i=0; i<oldParent.childNodes.length; i++) { 97.247 + var entry = oldParent.childNodes[i]; 97.248 + if (entry.className == "movable") { 97.249 + if (entry != element) { 97.250 + create = true; 97.251 + break; 97.252 + } 97.253 + } 97.254 + } 97.255 + } 97.256 + var newSection; 97.257 + if (create) { 97.258 + newSection = document.createElement("div"); 97.259 + var cathead = document.createElement("div"); 97.260 + cathead.setAttribute("class", "cathead"); 97.261 + newSection.appendChild(cathead); 97.262 + if ( 97.263 + oldParent.className == "approval" || 97.264 + (oldParent.className == "abstention" && up) 97.265 + ) { 97.266 + newSection.setAttribute("class", "approval"); 97.267 + approvalCount++; 97.268 + } else { 97.269 + newSection.setAttribute("class", "disapproval"); 97.270 + disapprovalCount++; 97.271 + } 97.272 + if (up) { 97.273 + mainDiv.insertBefore(newSection, oldParent); 97.274 + } else { 97.275 + if (nextSection) mainDiv.insertBefore(newSection, nextSection); 97.276 + else mainDiv.appendChild(newSection); 97.277 + } 97.278 + } else { 97.279 + if (up) newSection = prevSection; 97.280 + else newSection = nextSection; 97.281 + } 97.282 + if (newSection) { 97.283 + oldParent.removeChild(element); 97.284 + if (create || up) { 97.285 + newSection.appendChild(element); 97.286 + } else { 97.287 + var inserted = false; 97.288 + for (var i=0; i<newSection.childNodes.length; i++) { 97.289 + var entry = newSection.childNodes[i]; 97.290 + if (entry.className == "movable") { 97.291 + newSection.insertBefore(element, entry); 97.292 + inserted = true; 97.293 + break; 97.294 + } 97.295 + } 97.296 + if (!inserted) newSection.appendChild(element); 97.297 + } 97.298 + } 97.299 } 97.300 - sections = mainDiv.childNodes; 97.301 + // sections = mainDiv.childNodes; 97.302 for (i=0; i<sections.length; i++) { 97.303 var section = sections[i]; 97.304 if ( 97.305 @@ -161,10 +274,13 @@ 97.306 } 97.307 } 97.308 } 97.309 - setCategoryHeadings(); 97.310 + voting_setCategoryHeadings(); 97.311 +} 97.312 +function elementDropped(element, dropX, dropY) { 97.313 + voting_move(element, null, dropX, dropY); 97.314 } 97.315 window.addEventListener("load", function(event) { 97.316 - setCategoryHeadings(); 97.317 + voting_setCategoryHeadings(); 97.318 var mainDiv = document.getElementById("voting"); 97.319 var form = document.getElementById("voting_form"); 97.320 var elements = document.getElementsByTagName("input"); 97.321 @@ -225,3 +341,9 @@ 97.322 } 97.323 } 97.324 }, false); 97.325 +function voting_moveUp(element) { 97.326 + return voting_move(element, true); 97.327 +} 97.328 +function voting_moveDown(element) { 97.329 + return voting_move(element, false); 97.330 +}
98.1 --- a/static/style.css Tue Feb 02 00:31:06 2010 +0100 98.2 +++ b/static/style.css Sat Feb 20 22:10:31 2010 +0100 98.3 @@ -4,11 +4,16 @@ 98.4 98.5 body, th, td { 98.6 font-family: sans-serif; 98.7 + font-size: 15px; 98.8 font-size: 14px; 98.9 padding: 0; 98.10 margin: 0; 98.11 } 98.12 98.13 +.area_list { 98.14 + line-height: 170%; 98.15 +} 98.16 + 98.17 body, a { 98.18 color: #000; 98.19 } 98.20 @@ -54,7 +59,7 @@ 98.21 } 98.22 98.23 a { 98.24 - vertical-align: middle; 98.25 + xvertical-align: middle; 98.26 } 98.27 98.28 h1 { 98.29 @@ -104,6 +109,8 @@ 98.30 background-color: #444; 98.31 color: #fff; 98.32 font-size: 75%; 98.33 + line-height: 140%; 98.34 + margin-bottom: 1.8ex; 98.35 } 98.36 98.37 .topbar a { 98.38 @@ -137,11 +144,16 @@ 98.39 } 98.40 98.41 .searchbox { 98.42 - padding: 0.5ex 1em 0ex 1em; 98.43 + margin: 0; 98.44 + padding: 0.1ex 1em 0ex 1em; 98.45 float: right; 98.46 line-height: 250%; 98.47 } 98.48 98.49 +.searchbox form { 98.50 + float: left; 98.51 +} 98.52 + 98.53 .searchbox div { 98.54 display: inline; 98.55 } 98.56 @@ -162,7 +174,6 @@ 98.57 98.58 .searchbox input[type=submit] { 98.59 font-size: 100%; 98.60 - width: 2.5em; 98.61 } 98.62 98.63 /************************************************************************* 98.64 @@ -264,6 +275,7 @@ 98.65 .voting_requested { 98.66 float: left; 98.67 position: relative; 98.68 + z-index: 1; 98.69 } 98.70 98.71 .interest img, 98.72 @@ -284,6 +296,11 @@ 98.73 border: 1px solid #b96; 98.74 } 98.75 98.76 +.interest .head_autoreject { 98.77 + background-color: #fdd; 98.78 + border: 1px solid #b77; 98.79 +} 98.80 + 98.81 .slot_support .head_supporter { 98.82 background-color: #dfc; 98.83 border: 1px solid #8b8; 98.84 @@ -299,6 +316,23 @@ 98.85 border: 1px solid #88b; 98.86 } 98.87 98.88 +.delegation .change_delegation { 98.89 + margin-bottom: 2ex; 98.90 +} 98.91 + 98.92 +.delegation .change_delegation a { 98.93 + display: inline; 98.94 + float: none; 98.95 + padding: 1ex; 98.96 +} 98.97 + 98.98 +.delegation .delegation_participation { 98.99 + margin-left: 20.5em; 98.100 + margin-top: 3ex; 98.101 + font-style: italic; 98.102 + font-size: 80%; 98.103 +} 98.104 + 98.105 .voting_requested .head_active { 98.106 background-color: #fdd; 98.107 border: 1px solid #b77; 98.108 @@ -322,7 +356,7 @@ 98.109 background-color: #fff; 98.110 border: 1px solid #999; 98.111 padding: 1em; 98.112 - width: 25em; 98.113 + width: 35em; 98.114 } 98.115 98.116 .vote_info .delegation_arrow { 98.117 @@ -365,7 +399,6 @@ 98.118 98.119 98.120 .sub_title div { 98.121 - border-top: 1px solid #444; 98.122 padding-top: 1ex; 98.123 margin-top: 1ex; 98.124 font-weight: bold; 98.125 @@ -415,27 +448,81 @@ 98.126 padding: 1ex 1ex 1ex 1ex; 98.127 } 98.128 98.129 +.web10 .ui_tabs_accordeon_head { 98.130 + margin-bottom: 1ex; 98.131 +} 98.132 + 98.133 +.web20 .ui_tabs_accordeon_head { 98.134 + font-size: 80%; 98.135 + font-weight: bold; 98.136 + display: block; 98.137 + background: #eee; 98.138 + border: 1px solid #bbb; 98.139 + color: #000; 98.140 + padding: 0.75ex; 98.141 + margin-top: 2ex; 98.142 + cursor: pointer; 98.143 +} 98.144 + 98.145 +.web20 .ui_tabs_accordeon_head img { 98.146 + vertical-align: middle; 98.147 + margin-right: 0.5em; 98.148 +} 98.149 + 98.150 +.web20 .ui_tabs_accordeon_head .bargraph { 98.151 + margin-right: 0.5em; 98.152 +} 98.153 + 98.154 +.web20 .ui_tabs_accordeon_content { 98.155 + border: 1px solid #aaa; 98.156 + border-top: none; 98.157 + padding: 2ex 1em 2ex 1em; 98.158 + margin-bottom: 3ex; 98.159 +} 98.160 + 98.161 +.web20 .issue_initiative_list .ui_tabs_accordeon_head { 98.162 + background-color: #e5e5ff; 98.163 +} 98.164 + 98.165 +.web20 .issue_initiative_list .ui_tabs_accordeon_head, 98.166 +.web20 .issue_initiative_list .ui_tabs_accordeon_content { 98.167 + border-color: #aad; 98.168 +} 98.169 + 98.170 +.web20 .issue_initiative_list .ui_tabs_accordeon_content .ui_tabs_accordeon_content { 98.171 + border-color: #bbb; 98.172 + border-width: 1px; 98.173 +} 98.174 + 98.175 +.web20 .issue_initiative_list .ui_tabs_accordeon_content .ui_tabs_accordeon_head { 98.176 + background-color: #eee; 98.177 + border: 1px solid #bbb; 98.178 +} 98.179 + 98.180 +.web20 .issue_initiative_list .ui_tabs_accordeon_head a { 98.181 + font-size: 125%; 98.182 +} 98.183 + 98.184 + 98.185 + 98.186 /************************************************************************* 98.187 - * ui.filter 98.188 - * ui.order 98.189 + * ui.filters 98.190 */ 98.191 98.192 -.ui_filter_head, 98.193 -.ui_order_head { 98.194 +.ui_filter_closed_head, 98.195 +.ui_filter_head { 98.196 color: #777; 98.197 margin-top: 1ex; 98.198 margin-bottom: 1.5ex; 98.199 font-size: 75%; 98.200 } 98.201 98.202 -.ui_filter_head a, 98.203 -.ui_order_head a { 98.204 +.ui_filter_head a { 98.205 color: #777; 98.206 padding: 0.5ex; 98.207 } 98.208 98.209 -.ui_filter_head a.active, 98.210 -.ui_order_head a.active { 98.211 +.ui_filter_head a.active { 98.212 color: #fff; 98.213 background-color: #777; 98.214 padding: 0.5ex; 98.215 @@ -462,7 +549,11 @@ 98.216 */ 98.217 98.218 .bargraph { 98.219 - width: 101px; 98.220 + width: 103px; 98.221 +} 98.222 + 98.223 +.bargraph50 { 98.224 + width: 52px; 98.225 } 98.226 98.227 .bargraph div { 98.228 @@ -627,6 +718,7 @@ 98.229 background-color: #fff; 98.230 left: 5em; 98.231 top: 5ex; 98.232 +z-index: 2; 98.233 } 98.234 98.235 .hidden_inline_form a { 98.236 @@ -673,7 +765,8 @@ 98.237 padding: 0.3ex 0.5em 0.3ex 0.5em; 98.238 } 98.239 98.240 -.suggestion_my_opinion a { 98.241 +.suggestion_my_opinion a, 98.242 +.suggestion_my_opinion span { 98.243 white-space: nowrap; 98.244 padding-left: 0.2ex !important; 98.245 padding-right: 0.2ex !important; 98.246 @@ -737,7 +830,7 @@ 98.247 98.248 .member_thumb { 98.249 text-decoration: none; 98.250 - width: 18em; 98.251 + width: 15.5em; 98.252 height: 48px; 98.253 display: block; 98.254 float: left; 98.255 @@ -781,13 +874,15 @@ 98.256 } 98.257 98.258 .member_thumb .flags { 98.259 - float: right; 98.260 + text-align: right; 98.261 font-size: 75%; 98.262 } 98.263 98.264 -.member_thumb .flags a{ 98.265 +.member_thumb .flags a, 98.266 +.member_thumb .flags img { 98.267 position: static; 98.268 float: right; 98.269 + margin-left: 0.5em; 98.270 } 98.271 98.272 98.273 @@ -795,12 +890,14 @@ 98.274 float: right; 98.275 } 98.276 98.277 -.member_thumb.not_accepted { 98.278 +.member_thumb.not_accepted, 98.279 +.member_thumb.not_informed { 98.280 opacity: 0.5; 98.281 } 98.282 98.283 +.member_statement, 98.284 .draft_content, 98.285 -.member_statement { 98.286 +.suggestion_content { 98.287 background-color: #eee; 98.288 border: 1px solid #ccc; 98.289 padding-left: 1ex; 98.290 @@ -842,14 +939,27 @@ 98.291 margin-right: 0.7em; 98.292 } 98.293 98.294 +.admitted_info { 98.295 + background-color: #dfd; 98.296 + padding: 1ex; 98.297 + margin-bottom: 2ex; 98.298 +} 98.299 + 98.300 +.not_admitted_info, 98.301 +.revoked_info { 98.302 + background-color: #fdd; 98.303 + padding: 1ex; 98.304 + margin-bottom: 2ex; 98.305 +} 98.306 + 98.307 .draft_updated_info, 98.308 .voting_active_info, 98.309 -.revoked_info, 98.310 .initiator_invite_info, 98.311 .motd { 98.312 background-color: #fec; 98.313 - border: 2px solid #b96; 98.314 + border: 1px solid #b96; 98.315 padding: 1ex; 98.316 + margin-bottom: 2ex; 98.317 } 98.318 98.319 .suggestion_fulfilled { 98.320 @@ -934,6 +1044,17 @@ 98.321 background-color: #fec; 98.322 } 98.323 98.324 +.heading { 98.325 + font-size: 120%; 98.326 + font-weight: bold; 98.327 + margin-top: 2ex; 98.328 + margin-bottom: 1ex; 98.329 +} 98.330 + 98.331 +.heading.first { 98.332 + margin-top: 0; 98.333 +} 98.334 + 98.335 /************************************************************************* 98.336 * Voting 98.337 */ 98.338 @@ -974,16 +1095,20 @@ 98.339 border: 1px black solid; 98.340 margin: 1ex; 98.341 padding: 0.5ex; 98.342 +} 98.343 +#voting .voting_form_active .movable { 98.344 cursor: pointer; 98.345 } 98.346 -#voting .clickable { 98.347 +#voting .voting_form_active .clickable { 98.348 cursor: auto; 98.349 } 98.350 -#voting a.clickable { 98.351 +#voting .voting_form_active a.clickable { 98.352 cursor: pointer; 98.353 } 98.354 98.355 #voting .grabber { 98.356 vertical-align: middle; 98.357 cursor: move; 98.358 -} 98.359 \ No newline at end of file 98.360 +} 98.361 + 98.362 +