Merge pull request #2950 from consul/backport-improve_index_legislation_proposals
Allow select winner legislation proposals
This commit is contained in:
@@ -887,6 +887,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.legislation-proposals {
|
||||
|
||||
.votes {
|
||||
min-height: $line-height * 8;
|
||||
}
|
||||
}
|
||||
|
||||
.proposal-show .votes,
|
||||
.debate-show .votes {
|
||||
border: 0;
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
class Admin::Legislation::ProposalsController < Admin::Legislation::BaseController
|
||||
|
||||
has_orders %w[id title supports], only: :index
|
||||
|
||||
load_and_authorize_resource :process, class: "Legislation::Process"
|
||||
load_and_authorize_resource :proposal, class: "Legislation::Proposal", through: :process
|
||||
|
||||
def index
|
||||
@proposals = @proposals.send("sort_by_#{@current_order}").page(params[:page])
|
||||
end
|
||||
|
||||
def toggle_selection
|
||||
@proposal.toggle :selected
|
||||
@proposal.save!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class Legislation::ProcessesController < Legislation::BaseController
|
||||
has_filters %w{open next past}, only: :index
|
||||
has_filters %w[open next past], only: :index
|
||||
has_filters %w[random winners], only: :proposals
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
before_action :set_random_seed, only: :proposals
|
||||
@@ -91,7 +93,9 @@ class Legislation::ProcessesController < Legislation::BaseController
|
||||
|
||||
@proposals = ::Legislation::Proposal.where(process: @process)
|
||||
@proposals = @proposals.search(params[:search]) if params[:search].present?
|
||||
@proposals = @proposals.order('random()').page(params[:page])
|
||||
|
||||
@current_filter = "winners" if params[:filter].blank? && @proposals.winners.any?
|
||||
@proposals = @proposals.send(@current_filter).page(params[:page])
|
||||
|
||||
if @process.proposals_phase.started? || (current_user && current_user.administrator?)
|
||||
legislation_proposal_votes(@proposals)
|
||||
|
||||
@@ -10,4 +10,20 @@ module LegislationHelper
|
||||
def new_legislation_proposal_link_text(process)
|
||||
t("proposals.index.start_proposal")
|
||||
end
|
||||
|
||||
def link_to_toggle_legislation_proposal_selection(proposal)
|
||||
if proposal.selected?
|
||||
button_text = t("admin.legislation.proposals.index.selected")
|
||||
html_class = 'button expanded'
|
||||
else
|
||||
button_text = t("admin.legislation.proposals.index.select")
|
||||
html_class = 'button hollow expanded'
|
||||
end
|
||||
|
||||
link_to button_text,
|
||||
toggle_selection_admin_legislation_process_proposal_path(proposal.process, proposal),
|
||||
remote: true,
|
||||
method: :patch,
|
||||
class: html_class
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,9 +45,15 @@ class Legislation::Proposal < ActiveRecord::Base
|
||||
scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc) }
|
||||
scope :sort_by_created_at, -> { reorder(created_at: :desc) }
|
||||
scope :sort_by_most_commented, -> { reorder(comments_count: :desc) }
|
||||
scope :sort_by_title, -> { reorder(title: :asc) }
|
||||
scope :sort_by_id, -> { reorder(id: :asc) }
|
||||
scope :sort_by_supports, -> { reorder(cached_votes_up: :desc) }
|
||||
scope :sort_by_random, -> { reorder("RANDOM()") }
|
||||
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
|
||||
scope :selected, -> { where(selected: true) }
|
||||
scope :random, -> { sort_by_random }
|
||||
scope :winners, -> { selected.sort_by_confidence_score }
|
||||
|
||||
def to_param
|
||||
"#{id}-#{title}".parameterize
|
||||
|
||||
29
app/views/admin/legislation/proposals/_proposals.html.erb
Normal file
29
app/views/admin/legislation/proposals/_proposals.html.erb
Normal file
@@ -0,0 +1,29 @@
|
||||
<% if proposals.any? %>
|
||||
<h3><%= page_entries_info proposals %></h3>
|
||||
|
||||
<%= render 'shared/wide_order_selector', i18n_namespace: "admin.legislation.processes.proposals" %>
|
||||
|
||||
<table class="stack" id="legislation_proposals_list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"><%= t("admin.legislation.proposals.index.id") %></th>
|
||||
<th><%= t("admin.legislation.proposals.index.title") %></th>
|
||||
<th class="text-center"><%= t("admin.legislation.proposals.index.supports") %></th>
|
||||
<th><%= t("admin.legislation.proposals.index.selected") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% proposals.each do |proposal| %>
|
||||
<tr id="<%= dom_id(proposal) %>" class="legislation_proposal">
|
||||
<td class="text-center"><%= proposal.id %></td>
|
||||
<td><%= proposal.title %></td>
|
||||
<td class="text-center"><%= proposal.cached_votes_up %></td>
|
||||
<td class="select"><%= render "select_proposal", proposal: proposal %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate proposals %>
|
||||
<% end %>
|
||||
@@ -0,0 +1 @@
|
||||
<%= link_to_toggle_legislation_proposal_selection(proposal) %>
|
||||
@@ -11,4 +11,5 @@
|
||||
<%= render 'admin/legislation/processes/subnav', process: @process, active: 'proposals' %>
|
||||
|
||||
<%= render 'form' %>
|
||||
<%= render 'proposals', proposals: @proposals %>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
$("#<%= dom_id(@proposal) %> .select").html('<%= j render("select_proposal", proposal: @proposal) %>');
|
||||
@@ -3,6 +3,7 @@
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="legislation-proposals">
|
||||
<%= render 'shared/filter_subnav', i18n_namespace: "legislation.processes.proposals" %>
|
||||
<% if proposals.empty? %>
|
||||
<div class="callout primary">
|
||||
<p><%= t("legislation.processes.proposals.empty_proposals") %></p>
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<p><%= t("legislation.proposals.closed") %></p>
|
||||
<% end %>
|
||||
|
||||
<span class="total-votes">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#
|
||||
# i18n_namespace: for example "moderation.debates.index"
|
||||
%>
|
||||
|
||||
<% if @valid_orders.present? && @valid_orders.count > 1 %>
|
||||
<div class="wide-order-selector small-12 medium-8">
|
||||
<form>
|
||||
|
||||
@@ -139,6 +139,8 @@ ignore_unused:
|
||||
- 'admin.activity.show.filter*'
|
||||
- 'admin.legislation.processes.index.filter*'
|
||||
- 'admin.legislation.processes.*.submit_button'
|
||||
- 'admin.legislation.processes.proposals.orders.*'
|
||||
- 'admin.legislation.processes.proposals.select_order'
|
||||
- 'admin.legislation.draft_versions.*.submit_button'
|
||||
- 'admin.legislation.questions.*.submit_button'
|
||||
- 'admin.comments.index.hidden_*'
|
||||
@@ -176,6 +178,7 @@ ignore_unused:
|
||||
- 'notifications.notification.action.*'
|
||||
- 'legislation.processes.index.filter*'
|
||||
- 'legislation.processes.index.section_header.*'
|
||||
- 'legislation.processes.proposals.filters.*'
|
||||
- 'helpers.page_entries_info.*' # kaminari
|
||||
- 'views.pagination.*' # kaminari
|
||||
- 'shared.suggest.*'
|
||||
|
||||
@@ -76,6 +76,9 @@ en:
|
||||
legislation/process:
|
||||
one: "Process"
|
||||
other: "Processes"
|
||||
legislation/proposal:
|
||||
one: "Proposal"
|
||||
other: "Proposals"
|
||||
legislation/draft_versions:
|
||||
one: "Draft version"
|
||||
other: "Draft versions"
|
||||
|
||||
@@ -394,6 +394,12 @@ en:
|
||||
back: Back
|
||||
title: Create new collaborative legislation process
|
||||
submit_button: Create process
|
||||
proposals:
|
||||
select_order: Sort by
|
||||
orders:
|
||||
id: Id
|
||||
title: Title
|
||||
supports: Supports
|
||||
process:
|
||||
title: Process
|
||||
comments: Comments
|
||||
@@ -411,6 +417,11 @@ en:
|
||||
index:
|
||||
title: Proposals
|
||||
back: Back
|
||||
id: Id
|
||||
title: Title
|
||||
supports: Supports
|
||||
select: Select
|
||||
selected: Selected
|
||||
form:
|
||||
custom_categories: Categories
|
||||
custom_categories_description: Categories that users can select creating the proposal.
|
||||
|
||||
@@ -52,6 +52,9 @@ en:
|
||||
more_info: More information and context
|
||||
proposals:
|
||||
empty_proposals: There are no proposals
|
||||
filters:
|
||||
random: Random
|
||||
winners: Selected
|
||||
debate:
|
||||
empty_questions: There aren't any questions
|
||||
participate: Participate in the debate
|
||||
@@ -120,4 +123,3 @@ en:
|
||||
form:
|
||||
tags_label: "Categories"
|
||||
not_verified: "For vote proposals %{verify_account}."
|
||||
closed: "This process has been closed and can not receive votes."
|
||||
@@ -76,6 +76,9 @@ es:
|
||||
legislation/process:
|
||||
one: "Proceso"
|
||||
other: "Procesos"
|
||||
legislation/proposal:
|
||||
one: "Propuesta"
|
||||
other: "Propuestas"
|
||||
legislation/draft_versions:
|
||||
one: "Versión borrador"
|
||||
other: "Versiones borrador"
|
||||
|
||||
@@ -395,6 +395,12 @@ es:
|
||||
back: Volver
|
||||
title: Crear nuevo proceso de legislación colaborativa
|
||||
submit_button: Crear proceso
|
||||
proposals:
|
||||
select_order: Ordenar por
|
||||
orders:
|
||||
id: Id
|
||||
title: Título
|
||||
supports: Apoyos
|
||||
process:
|
||||
title: Proceso
|
||||
comments: Comentarios
|
||||
@@ -412,6 +418,11 @@ es:
|
||||
index:
|
||||
title: Propuestas
|
||||
back: Volver
|
||||
id: Id
|
||||
title: Título
|
||||
supports: Apoyos
|
||||
select: Seleccionar
|
||||
selected: Seleccionado
|
||||
form:
|
||||
custom_categories: Categorías
|
||||
custom_categories_description: Categorías que el usuario puede seleccionar al crear la propuesta.
|
||||
|
||||
@@ -52,6 +52,9 @@ es:
|
||||
more_info: Más información y contexto
|
||||
proposals:
|
||||
empty_proposals: No hay propuestas
|
||||
filters:
|
||||
random: Aleatorias
|
||||
winners: Seleccionadas
|
||||
debate:
|
||||
empty_questions: No hay preguntas
|
||||
participate: Realiza tus aportaciones al debate previo participando en los siguientes temas.
|
||||
@@ -120,4 +123,3 @@ es:
|
||||
form:
|
||||
tags_label: "Categorías"
|
||||
not_verified: "Para votar propuestas %{verify_account}."
|
||||
closed: "Este proceso se ha cerrado y ya no puede recoger votos."
|
||||
|
||||
@@ -194,7 +194,9 @@ namespace :admin do
|
||||
namespace :legislation do
|
||||
resources :processes do
|
||||
resources :questions
|
||||
resources :proposals
|
||||
resources :proposals do
|
||||
member { patch :toggle_selection }
|
||||
end
|
||||
resources :draft_versions
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ section "Creating legislation proposals" do
|
||||
summary: Faker::Lorem.paragraph,
|
||||
author: User.all.sample,
|
||||
process: Legislation::Process.all.sample,
|
||||
terms_of_service: '1')
|
||||
terms_of_service: '1',
|
||||
selected: rand <= 1.0 / 3)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddSelectedToLegislationProposals < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :legislation_proposals, :selected, :boolean
|
||||
end
|
||||
end
|
||||
@@ -687,6 +687,7 @@ ActiveRecord::Schema.define(version: 20180924071722) do
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "cached_votes_total", default: 0
|
||||
t.integer "cached_votes_down", default: 0
|
||||
t.boolean "selected"
|
||||
end
|
||||
|
||||
add_index "legislation_proposals", ["legislation_process_id"], name: "index_legislation_proposals_on_legislation_process_id", using: :btree
|
||||
|
||||
85
spec/features/admin/legislation/proposals_spec.rb
Normal file
85
spec/features/admin/legislation/proposals_spec.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature 'Admin legislation processes' do
|
||||
|
||||
background do
|
||||
admin = create(:administrator)
|
||||
login_as(admin.user)
|
||||
end
|
||||
|
||||
context "Index" do
|
||||
|
||||
scenario 'Displaying legislation proposals' do
|
||||
proposal = create(:legislation_proposal, cached_votes_up: 10)
|
||||
|
||||
visit admin_legislation_process_proposals_path(proposal.legislation_process_id)
|
||||
|
||||
within "#legislation_proposal_#{proposal.id}" do
|
||||
expect(page).to have_content(proposal.title)
|
||||
expect(page).to have_content(proposal.id)
|
||||
expect(page).to have_content(proposal.cached_votes_up)
|
||||
expect(page).to have_content('Select')
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Selecting legislation proposals', :js do
|
||||
proposal = create(:legislation_proposal, cached_votes_up: 10)
|
||||
|
||||
visit admin_legislation_process_proposals_path(proposal.legislation_process_id)
|
||||
click_link 'Select'
|
||||
|
||||
within "#legislation_proposal_#{proposal.id}" do
|
||||
expect(page).to have_content('Selected')
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Sorting legislation proposals by title', js: true do
|
||||
process = create(:legislation_process)
|
||||
create(:legislation_proposal, title: 'bbbb', legislation_process_id: process.id)
|
||||
create(:legislation_proposal, title: 'aaaa', legislation_process_id: process.id)
|
||||
create(:legislation_proposal, title: 'cccc', legislation_process_id: process.id)
|
||||
|
||||
visit admin_legislation_process_proposals_path(process.id)
|
||||
select "Title", from: "order-selector-participation"
|
||||
|
||||
within('#legislation_proposals_list') do
|
||||
within all('.legislation_proposal')[0] { expect(page).to have_content('aaaa') }
|
||||
within all('.legislation_proposal')[1] { expect(page).to have_content('bbbb') }
|
||||
within all('.legislation_proposal')[2] { expect(page).to have_content('cccc') }
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Sorting legislation proposals by supports', js: true do
|
||||
process = create(:legislation_process)
|
||||
create(:legislation_proposal, cached_votes_up: 10, legislation_process_id: process.id)
|
||||
create(:legislation_proposal, cached_votes_up: 30, legislation_process_id: process.id)
|
||||
create(:legislation_proposal, cached_votes_up: 20, legislation_process_id: process.id)
|
||||
|
||||
visit admin_legislation_process_proposals_path(process.id)
|
||||
select "Supports", from: "order-selector-participation"
|
||||
|
||||
within('#legislation_proposals_list') do
|
||||
within all('.legislation_proposal')[0] { expect(page).to have_content('30') }
|
||||
within all('.legislation_proposal')[1] { expect(page).to have_content('20') }
|
||||
within all('.legislation_proposal')[2] { expect(page).to have_content('10') }
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Sorting legislation proposals by Id', js: true do
|
||||
process = create(:legislation_process)
|
||||
proposal1 = create(:legislation_proposal, title: 'bbbb', legislation_process_id: process.id)
|
||||
proposal2 = create(:legislation_proposal, title: 'aaaa', legislation_process_id: process.id)
|
||||
proposal3 = create(:legislation_proposal, title: 'cccc', legislation_process_id: process.id)
|
||||
|
||||
visit admin_legislation_process_proposals_path(process.id, order: :title)
|
||||
select "Id", from: "order-selector-participation"
|
||||
|
||||
within('#legislation_proposals_list') do
|
||||
within all('.legislation_proposal')[0] { expect(page).to have_content(proposal1.id) }
|
||||
within all('.legislation_proposal')[1] { expect(page).to have_content(proposal2.id) }
|
||||
within all('.legislation_proposal')[2] { expect(page).to have_content(proposal3.id) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -64,6 +64,49 @@ feature 'Legislation Proposals' do
|
||||
expect(legislation_proposals_order).to eq(first_page_proposals_order)
|
||||
end
|
||||
|
||||
context 'Selected filter' do
|
||||
scenario 'apperars even if there are not any selected poposals' do
|
||||
create(:legislation_proposal, legislation_process_id: process.id)
|
||||
|
||||
visit legislation_process_proposals_path(process)
|
||||
|
||||
expect(page).to have_content('Selected')
|
||||
end
|
||||
|
||||
scenario 'defaults to winners if there are selected proposals' do
|
||||
create(:legislation_proposal, legislation_process_id: process.id)
|
||||
create(:legislation_proposal, legislation_process_id: process.id, selected: true)
|
||||
|
||||
visit legislation_process_proposals_path(process)
|
||||
|
||||
expect(page).to have_link('Random')
|
||||
expect(page).not_to have_link('Selected')
|
||||
expect(page).to have_content('Selected')
|
||||
end
|
||||
|
||||
scenario 'defaults to random if the current process does not have selected proposals' do
|
||||
create(:legislation_proposal, legislation_process_id: process.id)
|
||||
create(:legislation_proposal, selected: true)
|
||||
|
||||
visit legislation_process_proposals_path(process)
|
||||
|
||||
expect(page).to have_link('Selected')
|
||||
expect(page).not_to have_link('Random')
|
||||
expect(page).to have_content('Random')
|
||||
end
|
||||
|
||||
scenario 'filters correctly' do
|
||||
proposal1 = create(:legislation_proposal, legislation_process_id: process.id)
|
||||
proposal2 = create(:legislation_proposal, legislation_process_id: process.id, selected: true)
|
||||
|
||||
visit legislation_process_proposals_path(process, filter: "random")
|
||||
click_link 'Selected'
|
||||
|
||||
expect(page).to have_css("div#legislation_proposal_#{proposal2.id}")
|
||||
expect(page).not_to have_css("div#legislation_proposal_#{proposal1.id}")
|
||||
end
|
||||
end
|
||||
|
||||
def legislation_proposals_order
|
||||
all("[id^='legislation_proposal_']").collect { |e| e[:id] }
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user