diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb
index 7998f29a2..5b9ea9d7b 100644
--- a/app/controllers/admin/poll/booth_assignments_controller.rb
+++ b/app/controllers/admin/poll/booth_assignments_controller.rb
@@ -23,18 +23,24 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController
end
def create
- @booth_assignment = ::Poll::BoothAssignment.new(poll_id: booth_assignment_params[:poll_id],
- booth_id: booth_assignment_params[:booth_id])
+ @poll = Poll.find(booth_assignment_params[:poll_id])
+ @booth = Poll::Booth.find(booth_assignment_params[:booth_id])
+ @booth_assignment = ::Poll::BoothAssignment.new(poll: @poll,
+ booth: @booth)
if @booth_assignment.save
notice = t("admin.poll_booth_assignments.flash.create")
else
notice = t("admin.poll_booth_assignments.flash.error_create")
end
- redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice
+ respond_to do |format|
+ format.js { render layout: false }
+ end
end
def destroy
+ @poll = Poll.find(booth_assignment_params[:poll_id])
+ @booth = Poll::Booth.find(booth_assignment_params[:booth_id])
@booth_assignment = ::Poll::BoothAssignment.find(params[:id])
if @booth_assignment.destroy
@@ -42,7 +48,14 @@ class Admin::Poll::BoothAssignmentsController < Admin::Poll::BaseController
else
notice = t("admin.poll_booth_assignments.flash.error_destroy")
end
- redirect_to admin_poll_booth_assignments_path(@booth_assignment.poll_id), notice: notice
+ respond_to do |format|
+ format.js { render layout: false }
+ end
+ end
+
+ def manage
+ @booths = ::Poll::Booth.all
+ @poll = Poll.find(params[:poll_id])
end
private
diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb
index 5103275fb..8ba6e934e 100644
--- a/app/controllers/admin/poll/polls_controller.rb
+++ b/app/controllers/admin/poll/polls_controller.rb
@@ -47,6 +47,10 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController
redirect_to admin_poll_path(@poll), notice: notice
end
+ def booth_assignments
+ @polls = Poll.current_or_incoming
+ end
+
private
def load_geozones
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 1bc8d5e0c..704f9be24 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -56,10 +56,10 @@ module Abilities
can [:index, :create, :edit, :update, :destroy], Geozone
- can [:read, :create, :update, :destroy, :add_question, :search_booths, :search_officers], Poll
+ can [:read, :create, :update, :destroy, :add_question, :search_booths, :search_officers, :booth_assignments], Poll
can [:read, :create, :update, :destroy, :available], Poll::Booth
can [:search, :create, :index, :destroy], ::Poll::Officer
- can [:create, :destroy], ::Poll::BoothAssignment
+ can [:create, :destroy, :manage], ::Poll::BoothAssignment
can [:create, :destroy], ::Poll::OfficerAssignment
can [:read, :create, :update], Poll::Question
can :destroy, Poll::Question # , comments_count: 0, votes_up: 0
diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb
index 04f9d3dea..07e7d2456 100644
--- a/app/models/poll/booth.rb
+++ b/app/models/poll/booth.rb
@@ -15,5 +15,8 @@ class Poll
where(polls: { id: Poll.current_or_incoming }).includes(:polls)
end
+ def assignment_on_poll(poll)
+ booth_assignments.where(poll: poll).first
+ end
end
-end
\ No newline at end of file
+end
diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb
index f2af2c116..0518aa0e3 100644
--- a/app/views/admin/_menu.html.erb
+++ b/app/views/admin/_menu.html.erb
@@ -60,7 +60,8 @@
<%= t("admin.menu.title_polls") %>
<% end %>
diff --git a/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb
new file mode 100644
index 000000000..d78f7be8b
--- /dev/null
+++ b/app/views/admin/poll/booth_assignments/_booth_assignment.html.erb
@@ -0,0 +1,31 @@
+
+ <%= link_to booth.name, admin_booth_path(booth) %>
+ |
+
+ <%= booth.location || t("admin.booths.index.no_location") %>
+ |
+<% if booth_assignment.present? %>
+
+ <%= t("admin.booth_assignments.manage.status.assigned") %>
+ |
+
+ <%= link_to t("admin.booth_assignments.manage.actions.unassign"),
+ admin_poll_booth_assignment_path(@poll, booth_assignment, booth_id: booth.id),
+ method: :delete,
+ remote: true,
+ title: t("admin.booth_assignments.manage.actions.unassign"),
+ class: "button hollow alert" %>
+ |
+<% else %>
+
+ <%= t("admin.booth_assignments.manage.status.unassigned") %>
+ |
+
+ <%= link_to t("admin.booth_assignments.manage.actions.assign"),
+ admin_poll_booth_assignments_path(@poll, booth_id: booth.id),
+ method: :post,
+ remote: true,
+ title: t("admin.booth_assignments.manage.actions.assign"),
+ class: "button" %>
+ |
+<% end %>
diff --git a/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb b/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb
index 3fa7fc080..cebde154c 100644
--- a/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb
+++ b/app/views/admin/poll/booth_assignments/_search_booths_results.html.erb
@@ -12,7 +12,6 @@
| <%= t("admin.poll_booth_assignments.index.table_name") %> |
<%= t("admin.poll_booth_assignments.index.table_location") %> |
- <%= t("admin.poll_booth_assignments.index.table_assignment") %> |
@@ -24,14 +23,6 @@
<%= booth.location %>
|
-
- <% unless @poll.booth_ids.include?(booth.id) %>
- <%= link_to t("admin.poll_booth_assignments.index.add_booth"),
- admin_poll_booth_assignments_path(@poll, booth_id: booth.id),
- method: :post,
- class: "button hollow" %>
- <% end %>
- |
<% end %>
diff --git a/app/views/admin/poll/booth_assignments/create.js.erb b/app/views/admin/poll/booth_assignments/create.js.erb
new file mode 100644
index 000000000..8b278f7b3
--- /dev/null
+++ b/app/views/admin/poll/booth_assignments/create.js.erb
@@ -0,0 +1 @@
+$("#<%= dom_id(@booth) %>").html('<%= j render("booth_assignment", booth: @booth, booth_assignment: @booth.assignment_on_poll(@poll)) %>');
diff --git a/app/views/admin/poll/booth_assignments/destroy.js.erb b/app/views/admin/poll/booth_assignments/destroy.js.erb
new file mode 100644
index 000000000..8b278f7b3
--- /dev/null
+++ b/app/views/admin/poll/booth_assignments/destroy.js.erb
@@ -0,0 +1 @@
+$("#<%= dom_id(@booth) %>").html('<%= j render("booth_assignment", booth: @booth, booth_assignment: @booth.assignment_on_poll(@poll)) %>');
diff --git a/app/views/admin/poll/booth_assignments/index.html.erb b/app/views/admin/poll/booth_assignments/index.html.erb
index f14e59ef1..75cbe889f 100644
--- a/app/views/admin/poll/booth_assignments/index.html.erb
+++ b/app/views/admin/poll/booth_assignments/index.html.erb
@@ -1,10 +1,15 @@
<%= render "/admin/poll/polls/poll_header" %>
+
<%= render "/admin/poll/polls/subnav" %>
<%= render "search_booths" %>
<%= t("admin.poll_booth_assignments.index.booths_title") %>
+ <%= link_to t("admin.booth_assignments.manage_assignments"),
+ manage_admin_poll_booth_assignments_path(@poll),
+ class: "button hollow float-right" %>
+
<% if @booth_assignments.empty? %>
<%= t("admin.poll_booth_assignments.index.no_booths") %>
@@ -14,7 +19,6 @@
<%= t("admin.poll_booth_assignments.index.table_name") %> |
<%= t("admin.poll_booth_assignments.index.table_location") %> |
- <%= t("admin.poll_booth_assignments.index.table_assignment") %> |
<% @booth_assignments.each do |booth_assignment| %>
@@ -25,13 +29,7 @@
- <%= booth_assignment.booth.location %>
- |
-
- <%= link_to t("admin.poll_booth_assignments.index.remove_booth"),
- admin_poll_booth_assignment_path(@poll, booth_assignment),
- method: :delete,
- class: "button hollow alert" %>
+ <%= booth_assignment.booth.location || t("admin.booths.index.no_location") %>
|
<% end %>
diff --git a/app/views/admin/poll/booth_assignments/manage.html.erb b/app/views/admin/poll/booth_assignments/manage.html.erb
new file mode 100644
index 000000000..a24fac478
--- /dev/null
+++ b/app/views/admin/poll/booth_assignments/manage.html.erb
@@ -0,0 +1,28 @@
+<%= link_to booth_assignments_admin_polls_path do %>
+ <%= t("shared.back") %>
+<% end %>
+
+
+<%= t("admin.booth_assignments.manage.assignments_list", poll: @poll.name) %>
+
+<% if @booths.empty? %>
+
+ <%= t("admin.booths.index.no_booths") %>
+
+<% else %>
+
+
+ | <%= t("admin.booths.index.name") %> |
+ <%= t("admin.booths.index.location") %> |
+ <%= t("admin.booth_assignments.manage.status.assign_status") %> |
+ <%= t("admin.actions.actions") %> |
+
+
+ <% @booths.each do |booth| %>
+
+ <%= render partial: "booth_assignment", locals: { booth: booth, booth_assignment: booth.assignment_on_poll(@poll) } %>
+
+ <% end %>
+
+
+<% end %>
diff --git a/app/views/admin/poll/polls/booth_assignments.html.erb b/app/views/admin/poll/polls/booth_assignments.html.erb
new file mode 100644
index 000000000..ad5dc6211
--- /dev/null
+++ b/app/views/admin/poll/polls/booth_assignments.html.erb
@@ -0,0 +1,32 @@
+<%= t("admin.polls.index.title") %>
+
+<% if @polls.any? %>
+
+
+ | <%= t("admin.polls.index.name") %> |
+ <%= t("admin.polls.index.dates") %> |
+ <%= t("admin.actions.actions") %> |
+
+
+ <% @polls.each do |poll| %>
+
+ |
+ <%= link_to poll.name, admin_poll_path(poll) %>
+ |
+
+ <%= l poll.starts_at.to_date %> - <%= l poll.ends_at.to_date %>
+ |
+
+ <%= link_to t("admin.booth_assignments.manage_assignments"),
+ manage_admin_poll_booth_assignments_path(poll),
+ class: "button hollow" %>
+ |
+
+ <% end %>
+
+
+<% else %>
+
+ <%= t("admin.polls.index.no_polls") %>
+
+<% end %>
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml
index 38abe6f56..aa0fc0f8a 100644
--- a/config/locales/en/admin.yml
+++ b/config/locales/en/admin.yml
@@ -409,6 +409,7 @@ en:
poll_officers: Poll officers
polls: Polls
poll_booths: Booths location
+ poll_booth_assignments: Booths Assignments
poll_shifts: Manage shifts
officials: Officials
organizations: Organisations
@@ -524,6 +525,17 @@ en:
date_missing: "A date must be selected"
vote_collection: Collect Votes
recount_scrutiny: Recount & Scrutiny
+ booth_assignments:
+ manage_assignments: Manage assignments
+ manage:
+ assignments_list: "Assignments for poll '%{poll}'"
+ status:
+ assign_status: Assignment
+ assigned: Assigned
+ unassigned: Unassigned
+ actions:
+ assign: Assign booth
+ unassign: Unassign booth
poll_booth_assignments:
flash:
destroy: "Booth not assigned anymore"
@@ -547,9 +559,6 @@ en:
no_booths: "There are no booths assigned to this poll."
table_name: "Name"
table_location: "Location"
- table_assignment: "Assignment"
- remove_booth: "Remove booth from poll"
- add_booth: "Assign booth"
polls:
index:
title: "List of polls"
@@ -666,6 +675,7 @@ en:
add_booth: "Add booth"
name: "Name"
location: "Location"
+ no_location: "No Location"
new:
title: "New booth"
name: "Name"
diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml
index 3336cdc5b..2ff4449ec 100644
--- a/config/locales/es/admin.yml
+++ b/config/locales/es/admin.yml
@@ -420,6 +420,7 @@ es:
poll_officers: Presidentes de mesa
polls: Votaciones
poll_booths: Ubicación de urnas
+ poll_booth_assignments: Asignación de urnas
poll_shifts: Asignar turnos
officials: Cargos públicos
organizations: Organizaciones
@@ -524,6 +525,17 @@ es:
date_missing: "Debe seleccionarse una fecha"
vote_collection: Recoger Votos
recount_scrutiny: Recuento & Escrutinio
+ booth_assignments:
+ manage_assignments: Gestionar asignaciones
+ manage:
+ assignments_list: "Asignaciones para la votación '%{poll}'"
+ status:
+ assign_status: Asignación
+ assigned: Asignada
+ unassigned: No asignada
+ actions:
+ assign: Assign booth
+ unassign: Unassign booth
poll_booth_assignments:
flash:
destroy: "Urna desasignada"
@@ -547,9 +559,6 @@ es:
no_booths: "No hay urnas asignadas a esta votación."
table_name: "Nombre"
table_location: "Ubicación"
- table_assignment: "Asignación"
- remove_booth: "Desasignar urna"
- add_booth: "Asignar urna"
polls:
index:
title: "Listado de votaciones"
@@ -668,6 +677,7 @@ es:
add_booth: "Añadir urna"
name: "Nombre"
location: "Ubicación"
+ no_location: "Sin Ubicación"
new:
title: "Nueva urna"
name: "Nombre"
diff --git a/config/routes.rb b/config/routes.rb
index ae4f7280c..6f94594a3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -111,7 +111,7 @@ Rails.application.routes.draw do
resources :annotations do
get :search, on: :collection
end
-
+
resources :polls, only: [:show, :index] do
resources :questions, controller: 'polls/questions', shallow: true do
post :answer, on: :member
@@ -273,10 +273,12 @@ Rails.application.routes.draw do
scope module: :poll do
resources :polls do
+ get :booth_assignments, on: :collection
patch :add_question, on: :member
resources :booth_assignments, only: [:index, :show, :create, :destroy] do
get :search_booths, on: :collection
+ get :manage, on: :collection
end
resources :officer_assignments, only: [:index, :create, :destroy] do
diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb
index 5813e2dac..cceec1a3e 100644
--- a/spec/features/admin/poll/booth_assigments_spec.rb
+++ b/spec/features/admin/poll/booth_assigments_spec.rb
@@ -7,66 +7,109 @@ feature 'Admin booths assignments' do
login_as(admin.user)
end
- scenario 'Assign booth to poll', :js do
- poll = create(:poll)
- booth = create(:poll_booth)
+ feature 'Admin Booth Assignment management' do
- visit admin_poll_path(poll)
- within('#poll-resources') do
- click_link 'Booths (0)'
+ let!(:poll) { create(:poll) }
+ let!(:booth) { create(:poll_booth) }
+
+ scenario 'List Polls and Booths to manage', :js do
+ second_poll = create(:poll)
+ second_booth = create(:poll_booth)
+
+ visit booth_assignments_admin_polls_path
+
+ expect(page).to have_content(poll.name)
+ expect(page).to have_content(second_poll.name)
+
+ within("#poll_#{second_poll.id}") do
+ click_link 'Manage assignments'
+ end
+
+ expect(page).to have_content "Assignments for poll '#{second_poll.name}'"
+
+ expect(page).to have_content(booth.name)
+ expect(page).to have_content(second_booth.name)
end
- expect(page).to have_content 'There are no booths assigned to this poll.'
+ scenario 'Assign booth to poll', :js do
+ visit admin_poll_path(poll)
+ within('#poll-resources') do
+ click_link 'Booths (0)'
+ end
- fill_in 'search-booths', with: booth.name
- click_button 'Search'
- expect(page).to have_content(booth.name)
+ expect(page).to have_content 'There are no booths assigned to this poll.'
+ expect(page).to_not have_content booth.name
- within('#search-booths-results') do
- click_link 'Assign booth'
+ fill_in 'search-booths', with: booth.name
+ click_button 'Search'
+ expect(page).to have_content(booth.name)
+
+ visit manage_admin_poll_booth_assignments_path(poll)
+
+ expect(page).to have_content "Assignments for poll '#{poll.name}'"
+
+ within("#poll_booth_#{booth.id}") do
+ expect(page).to have_content(booth.name)
+ expect(page).to have_content "Unassigned"
+
+ click_link 'Assign booth'
+
+ expect(page).not_to have_content "Unassigned"
+ expect(page).to have_content "Assigned"
+ expect(page).to have_link "Unassign booth"
+ end
+
+ visit admin_poll_path(poll)
+ within('#poll-resources') do
+ click_link 'Booths (1)'
+ end
+
+ expect(page).to_not have_content 'There are no booths assigned to this poll.'
+ expect(page).to have_content booth.name
end
- expect(page).to have_content 'Booth assigned'
+ scenario 'Unassign booth from poll', :js do
+ assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
- visit admin_poll_path(poll)
- within('#poll-resources') do
- click_link 'Booths (1)'
+ visit admin_poll_path(poll)
+ within('#poll-resources') do
+ click_link 'Booths (1)'
+ end
+
+ expect(page).not_to have_content 'There are no booths assigned to this poll.'
+ expect(page).to have_content booth.name
+
+ fill_in 'search-booths', with: booth.name
+ click_button 'Search'
+ expect(page).to have_content(booth.name)
+
+ visit manage_admin_poll_booth_assignments_path(poll)
+
+ expect(page).to have_content "Assignments for poll '#{poll.name}'"
+
+ within("#poll_booth_#{booth.id}") do
+ expect(page).to have_content(booth.name)
+ expect(page).to have_content "Assigned"
+
+ click_link 'Unassign booth'
+
+ expect(page).to have_content "Unassigned"
+ expect(page).not_to have_content "Assigned"
+ expect(page).to have_link "Assign booth"
+ end
+
+ visit admin_poll_path(poll)
+ within('#poll-resources') do
+ click_link 'Booths (0)'
+ end
+
+ expect(page).to have_content 'There are no booths assigned to this poll.'
+ expect(page).not_to have_content booth.name
end
-
- expect(page).to_not have_content 'There are no booths assigned to this poll.'
- expect(page).to have_content booth.name
- end
-
- scenario 'Remove booth from poll', :js do
- poll = create(:poll)
- booth = create(:poll_booth)
- assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
-
- visit admin_poll_path(poll)
- within('#poll-resources') do
- click_link 'Booths (1)'
- end
-
- expect(page).to_not have_content 'There are no booths assigned to this poll.'
- expect(page).to have_content booth.name
-
- within("#poll_booth_assignment_#{assignment.id}") do
- click_link 'Remove booth from poll'
- end
-
- expect(page).to have_content 'Booth not assigned anymore'
-
- visit admin_poll_path(poll)
- within('#poll-resources') do
- click_link 'Booths (0)'
- end
-
- expect(page).to have_content 'There are no booths assigned to this poll.'
- expect(page).to_not have_content booth.name
end
feature 'Show' do
- scenario 'Lists all assigned poll oficers' do
+ scenario 'Lists all assigned poll officers' do
poll = create(:poll)
booth = create(:poll_booth)
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)