liquid_feedback_frontend
changeset 127:4fb486bce608
add pageinator to issue view.
this "paginator" shows links to the prev/area/next issues that have the same
state then the current one. This helps a lot when inspecting new issues or voting.
The voting filter works a little bit different, as he also activtes the not_voted subfilter
because it is most likely only not voted issues are interessting to the user
this "paginator" shows links to the prev/area/next issues that have the same
state then the current one. This helps a lot when inspecting new issues or voting.
The voting filter works a little bit different, as he also activtes the not_voted subfilter
because it is most likely only not voted issues are interessting to the user
author | Daniel Poelzleithner <poelzi@poelzi.org> |
---|---|
date | Tue Oct 05 04:44:06 2010 +0200 (2010-10-05) |
parents | 36aedac3e4bf |
children | 082450e65aa8 |
files | app/main/_layout/default.html app/main/issue/_filters.lua app/main/issue/_list.lua app/main/issue/_show_head.lua static/style.css |
line diff
1.1 --- a/app/main/_layout/default.html Mon Oct 04 15:52:22 2010 +0200 1.2 +++ b/app/main/_layout/default.html Tue Oct 05 04:44:06 2010 +0200 1.3 @@ -63,6 +63,9 @@ 1.4 <div style="clear: left;"></div> 1.5 </div> 1.6 </div> 1.7 + <div class="content_navigation" id="content_navigation"> 1.8 + <!-- WEBMCP SLOT content_navigation --> 1.9 + </div> 1.10 <div class="main" id="default"> 1.11 <!-- WEBMCP SLOT default --> 1.12 </div>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/app/main/issue/_filters.lua Tue Oct 05 04:44:06 2010 +0200 2.3 @@ -0,0 +1,186 @@ 2.4 +local filters = {} 2.5 + 2.6 +-- FIXME: the filter should be named like the corresponding issue.state value 2.7 + 2.8 +filters[#filters+1] = { 2.9 + label = _"Filter", 2.10 + name = "filter", 2.11 + { 2.12 + name = "open", 2.13 + label = _"Open", 2.14 + selector_modifier = function(selector) 2.15 + selector:add_where("issue.closed ISNULL") 2.16 + end 2.17 + }, 2.18 + { 2.19 + name = "new", 2.20 + label = _"New", 2.21 + selector_modifier = function(selector) 2.22 + selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") 2.23 + end 2.24 + }, 2.25 + { 2.26 + name = "accepted", 2.27 + label = _"In discussion", 2.28 + selector_modifier = function(selector) 2.29 + selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") 2.30 + end 2.31 + }, 2.32 + { 2.33 + name = "half_frozen", 2.34 + label = _"Frozen", 2.35 + selector_modifier = function(selector) 2.36 + selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") 2.37 + end 2.38 + }, 2.39 + { 2.40 + name = "frozen", 2.41 + label = _"Voting", 2.42 + selector_modifier = function(selector) 2.43 + selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") 2.44 + filter_voting = true 2.45 + end 2.46 + }, 2.47 + { 2.48 + name = "finished", 2.49 + label = _"Finished", 2.50 + selector_modifier = function(selector) 2.51 + selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") 2.52 + end 2.53 + }, 2.54 + { 2.55 + name = "cancelled", 2.56 + label = _"Cancelled", 2.57 + selector_modifier = function(selector) 2.58 + selector:add_where("issue.closed NOTNULL AND issue.fully_frozen ISNULL") 2.59 + end 2.60 + }, 2.61 + { 2.62 + name = "any", 2.63 + label = _"Any", 2.64 + selector_modifier = function(selector) end 2.65 + }, 2.66 +} 2.67 + 2.68 + 2.69 +if app.session.member and param.get("filter") == "frozen" then 2.70 + filters[#filters+1] = { 2.71 + label = _"Filter", 2.72 + name = "filter_voting", 2.73 + { 2.74 + name = "any", 2.75 + label = _"Any", 2.76 + selector_modifier = function() end 2.77 + }, 2.78 + { 2.79 + name = "not_voted", 2.80 + label = _"Not voted", 2.81 + selector_modifier = function(selector) 2.82 + selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 2.83 + selector:add_where("direct_voter.member_id ISNULL") 2.84 + end 2.85 + }, 2.86 + { 2.87 + name = "voted", 2.88 + label = _"Voted", 2.89 + selector_modifier = function(selector) 2.90 + selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 2.91 + end 2.92 + }, 2.93 + } 2.94 +end 2.95 + 2.96 + 2.97 +filters[#filters+1] = { 2.98 + label = _"Filter", 2.99 + name = "filter_interest", 2.100 + { 2.101 + name = "any", 2.102 + label = _"Any", 2.103 + selector_modifier = function() end 2.104 + }, 2.105 + { 2.106 + name = "my", 2.107 + label = _"Interested", 2.108 + selector_modifier = function(selector) 2.109 + selector:join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", app.session.member.id }) 2.110 + end 2.111 + }, 2.112 + { 2.113 + name = "supported", 2.114 + label = _"Supported", 2.115 + selector_modifier = function(selector) 2.116 + 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 }) 2.117 + end 2.118 + }, 2.119 + { 2.120 + name = "potentially_supported", 2.121 + label = _"Potential supported", 2.122 + selector_modifier = function(selector) 2.123 + 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 }) 2.124 + end 2.125 + }, 2.126 + { 2.127 + name = "initiated", 2.128 + label = _"Initiated", 2.129 + selector_modifier = function(selector) 2.130 + 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 }) 2.131 + end 2.132 + }, 2.133 +} 2.134 + 2.135 +if not param.get("no_sort", atom.boolean) then 2.136 + filters[#filters+1] = { 2.137 + label = _"Order by", 2.138 + name = "issue_list", 2.139 + { 2.140 + name = "max_potential_support", 2.141 + label = _"Max potential support", 2.142 + selector_modifier = function(selector) 2.143 + selector:add_order_by("(SELECT max(supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 2.144 + end 2.145 + }, 2.146 + { 2.147 + name = "max_support", 2.148 + label = _"Max support", 2.149 + selector_modifier = function(selector) 2.150 + selector:add_order_by("(SELECT max(satisfied_supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 2.151 + end 2.152 + }, 2.153 + { 2.154 + name = "population", 2.155 + label = _"Population", 2.156 + selector_modifier = function(selector) 2.157 + selector:add_order_by("issue.population DESC") 2.158 + end 2.159 + }, 2.160 + { 2.161 + name = "newest", 2.162 + label = _"Newest", 2.163 + selector_modifier = function(selector) 2.164 + selector:add_order_by("issue.created DESC") 2.165 + end 2.166 + }, 2.167 + { 2.168 + name = "oldest", 2.169 + label = _"Oldest", 2.170 + selector_modifier = function(selector) 2.171 + selector:add_order_by("issue.created") 2.172 + end 2.173 + } 2.174 + } 2.175 +end 2.176 + 2.177 +function filters:get_filter(group, name) 2.178 + for i,grp in ipairs(self) do 2.179 + if grp.name == group then 2.180 + for i,entry in ipairs(grp) do 2.181 + if entry.name == name then 2.182 + return entry 2.183 + end 2.184 + end 2.185 + end 2.186 + end 2.187 +end 2.188 + 2.189 +return filters 2.190 \ No newline at end of file
3.1 --- a/app/main/issue/_list.lua Mon Oct 04 15:52:22 2010 +0200 3.2 +++ b/app/main/issue/_list.lua Tue Oct 05 04:44:06 2010 +0200 3.3 @@ -14,175 +14,7 @@ 3.4 "issue_list" 3.5 } 3.6 3.7 -local filters = {} 3.8 - 3.9 -filters[#filters+1] = { 3.10 - label = _"Filter", 3.11 - { 3.12 - name = "open", 3.13 - label = _"Open", 3.14 - selector_modifier = function(selector) 3.15 - selector:add_where("issue.closed ISNULL") 3.16 - end 3.17 - }, 3.18 - { 3.19 - name = "new", 3.20 - label = _"New", 3.21 - selector_modifier = function(selector) 3.22 - selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") 3.23 - end 3.24 - }, 3.25 - { 3.26 - name = "accepted", 3.27 - label = _"In discussion", 3.28 - selector_modifier = function(selector) 3.29 - selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") 3.30 - end 3.31 - }, 3.32 - { 3.33 - name = "half_frozen", 3.34 - label = _"Frozen", 3.35 - selector_modifier = function(selector) 3.36 - selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") 3.37 - end 3.38 - }, 3.39 - { 3.40 - name = "frozen", 3.41 - label = _"Voting", 3.42 - selector_modifier = function(selector) 3.43 - selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") 3.44 - filter_voting = true 3.45 - end 3.46 - }, 3.47 - { 3.48 - name = "finished", 3.49 - label = _"Finished", 3.50 - selector_modifier = function(selector) 3.51 - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") 3.52 - end 3.53 - }, 3.54 - { 3.55 - name = "cancelled", 3.56 - label = _"Cancelled", 3.57 - selector_modifier = function(selector) 3.58 - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen ISNULL") 3.59 - end 3.60 - }, 3.61 - { 3.62 - name = "any", 3.63 - label = _"Any", 3.64 - selector_modifier = function(selector) end 3.65 - }, 3.66 -} 3.67 - 3.68 - 3.69 -if app.session.member and param.get("filter") == "frozen" then 3.70 - filters[#filters+1] = { 3.71 - label = _"Filter", 3.72 - name = "filter_voting", 3.73 - { 3.74 - name = "any", 3.75 - label = _"Any", 3.76 - selector_modifier = function() end 3.77 - }, 3.78 - { 3.79 - name = "not_voted", 3.80 - label = _"Not voted", 3.81 - selector_modifier = function(selector) 3.82 - selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 3.83 - selector:add_where("direct_voter.member_id ISNULL") 3.84 - end 3.85 - }, 3.86 - { 3.87 - name = "voted", 3.88 - label = _"Voted", 3.89 - selector_modifier = function(selector) 3.90 - selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 3.91 - end 3.92 - }, 3.93 - } 3.94 -end 3.95 - 3.96 - 3.97 -filters[#filters+1] = { 3.98 - label = _"Filter", 3.99 - name = "filter_interest", 3.100 - { 3.101 - name = "any", 3.102 - label = _"Any", 3.103 - selector_modifier = function() end 3.104 - }, 3.105 - { 3.106 - name = "my", 3.107 - label = _"Interested", 3.108 - selector_modifier = function(selector) 3.109 - selector:join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", app.session.member.id }) 3.110 - end 3.111 - }, 3.112 - { 3.113 - name = "supported", 3.114 - label = _"Supported", 3.115 - selector_modifier = function(selector) 3.116 - 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 }) 3.117 - end 3.118 - }, 3.119 - { 3.120 - name = "potentially_supported", 3.121 - label = _"Potential supported", 3.122 - selector_modifier = function(selector) 3.123 - 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 }) 3.124 - end 3.125 - }, 3.126 - { 3.127 - name = "initiated", 3.128 - label = _"Initiated", 3.129 - selector_modifier = function(selector) 3.130 - 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 }) 3.131 - end 3.132 - }, 3.133 -} 3.134 - 3.135 -if not param.get("no_sort", atom.boolean) then 3.136 - filters[#filters+1] = { 3.137 - label = _"Order by", 3.138 - name = "issue_list", 3.139 - { 3.140 - name = "max_potential_support", 3.141 - label = _"Max potential support", 3.142 - selector_modifier = function(selector) 3.143 - selector:add_order_by("(SELECT max(supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 3.144 - end 3.145 - }, 3.146 - { 3.147 - name = "max_support", 3.148 - label = _"Max support", 3.149 - selector_modifier = function(selector) 3.150 - selector:add_order_by("(SELECT max(satisfied_supporter_count) FROM initiative WHERE initiative.issue_id = issue.id) DESC") 3.151 - end 3.152 - }, 3.153 - { 3.154 - name = "population", 3.155 - label = _"Population", 3.156 - selector_modifier = function(selector) 3.157 - selector:add_order_by("issue.population DESC") 3.158 - end 3.159 - }, 3.160 - { 3.161 - name = "newest", 3.162 - label = _"Newest", 3.163 - selector_modifier = function(selector) 3.164 - selector:add_order_by("issue.created DESC") 3.165 - end 3.166 - }, 3.167 - { 3.168 - name = "oldest", 3.169 - label = _"Oldest", 3.170 - selector_modifier = function(selector) 3.171 - selector:add_order_by("issue.created") 3.172 - end 3.173 - } 3.174 - } 3.175 -end 3.176 +local filters = execute.load_chunk{module="issue", chunk="_filters.lua"} 3.177 3.178 filters.content = function() 3.179 local ui_paginate = ui.paginate
4.1 --- a/app/main/issue/_show_head.lua Mon Oct 04 15:52:22 2010 +0200 4.2 +++ b/app/main/issue/_show_head.lua Tue Oct 05 04:44:06 2010 +0200 4.3 @@ -37,6 +37,111 @@ 4.4 end) 4.5 4.6 4.7 +slot.select("content_navigation", function() 4.8 + 4.9 + if app.session.member_id then 4.10 + 4.11 + local this = 0 4.12 + local issues_selector = Issue:new_selector() 4.13 + 4.14 + -- FIXME: !DRY 4.15 + local issue_filter_map = { 4.16 + new = "new.png", 4.17 + accepted = "comments.png", 4.18 + half_frozen = "lock.png", 4.19 + frozen ="email_open.png", 4.20 + finished = "tick.png", 4.21 + cancelled = "cross.png", 4.22 + } 4.23 + 4.24 + 4.25 + local mk_link = function(index, text, icon, ltr) 4.26 + content = function() 4.27 + if ltr then 4.28 + slot.put(text) 4.29 + ui.image{ static = "icons/16/"..icon } 4.30 + else 4.31 + ui.image{ static = "icons/16/"..icon } 4.32 + slot.put(text) 4.33 + end 4.34 + end 4.35 + if records[this+index] then 4.36 + ui.link{ 4.37 + content = content, 4.38 + module = "issue", 4.39 + view = "show", 4.40 + id = records[this+index].id, 4.41 + } 4.42 + else 4.43 + ui.container{ 4.44 + content = content, 4.45 + } 4.46 + end 4.47 + end 4.48 + 4.49 + issues_selector 4.50 + :add_where{"issue.area_id = ?", issue.area.id} 4.51 + 4.52 + local filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = {filter = "frozen"}} 4.53 + 4.54 + local state = issue.state 4.55 + 4.56 + -- FIXME: fix filter names to reflect issue.state values 4.57 + if state == "voting" then 4.58 + state = "frozen" 4.59 + elseif state == "frozen" then 4.60 + state = "half_frozen" 4.61 + end 4.62 + 4.63 + filter = filters:get_filter("filter", state) 4.64 + if filter then 4.65 + filter.selector_modifier(issues_selector) 4.66 + 4.67 + -- add subfilter to voting pager, so only not voted entries will be shown 4.68 + -- as this seems the most usefull exception 4.69 + if filter.name == "frozen" then 4.70 + filter_voting_name = "not_voted" 4.71 + local vfilter = filters:get_filter("filter_voting", "not_voted") 4.72 + if vfilter then 4.73 + vfilter.selector_modifier(issues_selector) 4.74 + end 4.75 + end 4.76 + end 4.77 + 4.78 + records = issues_selector:exec() 4.79 + 4.80 + for i,cissue in ipairs(records) do 4.81 + if cissue.id == issue.id then 4.82 + this = i 4.83 + break 4.84 + end 4.85 + end 4.86 + 4.87 + mk_link(-1, "Previous", "resultset_previous.png") 4.88 + if issue.area then 4.89 + ui.link{ 4.90 + content = function() 4.91 + if issue_filter_map[state] then 4.92 + ui.image{ static = "icons/16/"..issue_filter_map[state] } 4.93 + end 4.94 + slot.put(issue.area.name) 4.95 + end, 4.96 + module = "area", 4.97 + view = "show", 4.98 + id = issue.area.id, 4.99 + params = { 4.100 + filter = filter and filter.name or nil, 4.101 + filter_voting = filter_voting_name, 4.102 + tab = "issues" 4.103 + } 4.104 + } 4.105 + end 4.106 + mk_link(1, "Next", "resultset_next.png", 1) 4.107 + end 4.108 +end 4.109 + 4.110 +) 4.111 + 4.112 slot.select("actions", function() 4.113 4.114 if app.session.member_id then
5.1 --- a/static/style.css Mon Oct 04 15:52:22 2010 +0200 5.2 +++ b/static/style.css Tue Oct 05 04:44:06 2010 +0200 5.3 @@ -182,7 +182,6 @@ 5.4 5.5 .title_bar { 5.6 border-bottom: 1px solid #777; 5.7 - margin-bottom: 2ex; 5.8 padding-top: 1ex; 5.9 padding-bottom: 0.5ex; 5.10 } 5.11 @@ -250,6 +249,21 @@ 5.12 vertical-align: middle; 5.13 } 5.14 5.15 +.content_navigation { 5.16 + font-size: 75%; 5.17 + background-color: #eee; 5.18 + margin-bottom: 2ex; 5.19 + padding-left: 1em; 5.20 +} 5.21 + 5.22 +.content_navigation div, 5.23 +.content_navigation a { 5.24 + display: inline-block; 5.25 + padding: 3px 0.5em 3px 0.0em; 5.26 + margin-right: 1em; 5.27 + vertical-align: middle; 5.28 +} 5.29 + 5.30 .actions a:hover { 5.31 background-color: #d7d7d7; 5.32 } 5.33 @@ -265,6 +279,9 @@ 5.34 margin-right: 1em; 5.35 } 5.36 5.37 + 5.38 + 5.39 + 5.40 /************************************************************************* 5.41 * vote info / delegation 5.42 */