bsw/jbe@0: local issue = param.get("issue", "table") bsw/jbe@0: bsw/jbe@19: local initiatives_selector = param.get("initiatives_selector", "table") bsw@51: bsw@274: local highlight_initiative = param.get("highlight_initiative", "table") bsw@274: bsw@285: local for_member = param.get("for_member", "table") or app.session.member bsw@285: bsw@11: initiatives_selector bsw/jbe@19: :join("issue", nil, "issue.id = initiative.issue_id") bsw@11: bsw@51: if app.session.member_id then bsw@51: initiatives_selector bsw@285: :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ? AND _initiator.accepted", for_member.id } ) bsw@285: :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", for_member.id} ) bsw@285: :left_join("delegating_interest_snapshot", "_delegating_interest_snapshot", { "_delegating_interest_snapshot.issue_id = initiative.issue_id AND _delegating_interest_snapshot.member_id = ? AND _delegating_interest_snapshot.event = issue.latest_snapshot_event", for_member.id} ) bsw@285: :left_join("direct_supporter_snapshot", "_direct_supporter_snapshot", "_direct_supporter_snapshot.initiative_id = initiative.id AND _direct_supporter_snapshot.member_id = _delegating_interest_snapshot.delegate_member_ids[array_upper(_delegating_interest_snapshot.delegate_member_ids, 1)] AND _direct_supporter_snapshot.event = issue.latest_snapshot_event") bsw@285: bsw@51: :add_field("(_initiator.member_id NOTNULL)", "is_initiator") bsw@285: :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)))", for_member.id }, "is_supporter") bsw@285: :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)))", for_member.id }, "is_potential_supporter") bsw@285: bsw@285: :add_field("_direct_supporter_snapshot.member_id NOTNULL", "is_supporter_via_delegation") bsw@51: end bsw@11: bsw/jbe@19: local initiatives_count = initiatives_selector:count() bsw@11: bsw/jbe@19: local limit = param.get("limit", atom.number) bsw/jbe@19: local no_sort = param.get("no_sort", atom.boolean) bsw/jbe@19: bsw@345: local more_initiatives_count bsw@345: if limit then bsw@345: if initiatives_count > limit then bsw@345: more_initiatives_count = initiatives_count - limit bsw/jbe@19: end bsw@345: initiatives_selector:limit(limit) bsw/jbe@19: end bsw/jbe@19: bsw@345: local issue = param.get("issue", "table") bsw/jbe@19: bsw@345: local name = "initiative_list" bsw@345: if issue then bsw@345: name = "issue_" .. tostring(issue.id) .. "_initiative_list" bsw@345: end bsw@345: bsw@345: ui.add_partial_param_names{ name } bsw/jbe@19: bsw@345: local order_filter = { bsw@345: name = name, bsw@345: label = _"Order by" bsw@345: } bsw@345: bsw@345: if issue and issue.ranks_available then bsw@345: order_filter[#order_filter+1] = { bsw@345: name = "rank", bsw@345: label = _"Rank", bsw@345: 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 bsw@11: } bsw@11: end bsw/jbe@19: bsw@345: order_filter[#order_filter+1] = { bsw@345: name = "potential_support", bsw@345: label = _"Potential support", bsw@345: selector_modifier = function(selector) selector:add_order_by("CASE WHEN issue.population = 0 THEN 0 ELSE initiative.supporter_count::float / issue.population::float END DESC, initiative.id") end bsw@345: } bsw/jbe@19: bsw@345: order_filter[#order_filter+1] = { bsw@345: name = "support", bsw@345: label = _"Support", bsw@345: selector_modifier = function(selector) selector:add_order_by("initiative.satisfied_supporter_count::float / issue.population::float DESC, initiative.id") end bsw@345: } bsw/jbe@19: bsw@345: order_filter[#order_filter+1] = { bsw@345: name = "newest", bsw@345: label = _"Newest", bsw@345: selector_modifier = function(selector) selector:add_order_by("initiative.created DESC, initiative.id") end bsw@345: } bsw/jbe@19: bsw@345: order_filter[#order_filter+1] = { bsw@345: name = "oldest", bsw@345: label = _"Oldest", bsw@345: selector_modifier = function(selector) selector:add_order_by("initiative.created, initiative.id") end bsw@345: } bsw/jbe@19: bsw@345: ui_filters = ui.filters bsw/jbe@19: bsw@345: if no_sort then bsw@345: ui_filters = function(args) args.content() end bsw@345: if issue.ranks_available then bsw@345: initiatives_selector:add_order_by("initiative.rank, initiative.admitted DESC, vote_ratio(initiative.positive_votes, initiative.negative_votes) DESC, initiative.id") bsw@345: else bsw@345: initiatives_selector:add_order_by("CASE WHEN issue.population = 0 OR initiative.supporter_count = 0 OR initiative.supporter_count ISNULL THEN 0 ELSE initiative.supporter_count::float / issue.population::float END DESC, initiative.id") bsw/jbe@19: end bsw@345: end bsw/jbe@19: bsw@345: ui_filters{ bsw@345: label = _"Change order", bsw@345: order_filter, bsw@345: selector = initiatives_selector, bsw@345: content = function() bsw@345: ui.paginate{ bsw@345: name = issue and "issue_" .. tostring(issue.id) .. "_page" or nil, bsw@345: selector = initiatives_selector, bsw@345: per_page = param.get("per_page", atom.number) or limit, bsw@345: content = function() bsw@345: local initiatives = initiatives_selector:exec() bsw@345: if highlight_initiative then bsw@345: local highlight_initiative_found bsw@345: for i, initiative in ipairs(initiatives) do bsw@345: if initiative.id == highlight_initiative.id then bsw@345: highhighlight_initiative_found = true bsw@274: end bsw@274: end bsw@345: if not highhighlight_initiative_found then bsw@345: initiatives[#initiatives+1] = highlight_initiative bsw@345: if more_initiatives_count then bsw@345: more_initiatives_count = more_initiatives_count - 1 bsw@345: end bsw/jbe@19: end bsw/jbe@19: end bsw@345: for i, initiative in ipairs(initiatives) do bsw@345: execute.view{ bsw@345: module = "initiative", bsw@345: view = "_list_element", bsw@345: params = { bsw@345: initiative = initiative, bsw@345: selected = highlight_initiative and highlight_initiative.id == initiative.id or nil, bsw@345: } bsw@345: } bsw/jbe@19: end bsw/jbe@19: end bsw/jbe@19: } bsw/jbe@19: end bsw@345: } bsw/jbe@19: bsw@345: if more_initiatives_count and more_initiatives_count > 0 then bsw@345: local text bsw@345: if more_initiatives_count == 1 then bsw@345: text = _("and one more initiative") bsw@345: else bsw@345: text = _("and #{count} more initiatives", { count = more_initiatives_count }) bsw@345: end bsw@345: ui.link{ bsw@345: attr = { class = "more_initiatives_link" }, bsw@345: content = text, bsw@345: module = "issue", bsw@345: view = "show", bsw@345: id = issue.id, bsw@345: } bsw/jbe@19: end