Merge branch 'master' into polls-persist-officer-data
This commit is contained in:
@@ -314,6 +314,7 @@
|
||||
|
||||
.debate-show,
|
||||
.proposal-show,
|
||||
.poll-question-show,
|
||||
.investment-project-show,
|
||||
.budget-investment-show,
|
||||
.polls-show,
|
||||
|
||||
@@ -30,6 +30,11 @@ class Admin::Poll::BoothsController < Admin::BaseController
|
||||
end
|
||||
end
|
||||
|
||||
def available
|
||||
@booths = Poll::Booth.available.order(name: :asc).page(params[:page])
|
||||
render :index
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def booth_params
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class Admin::Poll::QuestionsController < Admin::BaseController
|
||||
include CommentableActions
|
||||
|
||||
load_and_authorize_resource :poll
|
||||
load_and_authorize_resource :question, class: 'Poll::Question'
|
||||
|
||||
@@ -20,6 +22,7 @@ class Admin::Poll::QuestionsController < Admin::BaseController
|
||||
|
||||
def create
|
||||
@question.author = @question.proposal.try(:author) || current_user
|
||||
recover_documents_from_cache(@question)
|
||||
|
||||
if @question.save
|
||||
redirect_to admin_question_path(@question)
|
||||
@@ -29,6 +32,7 @@ class Admin::Poll::QuestionsController < Admin::BaseController
|
||||
end
|
||||
|
||||
def show
|
||||
@document = Document.new(documentable: @question)
|
||||
end
|
||||
|
||||
def edit
|
||||
@@ -54,7 +58,8 @@ class Admin::Poll::QuestionsController < Admin::BaseController
|
||||
private
|
||||
|
||||
def question_params
|
||||
params.require(:poll_question).permit(:poll_id, :title, :question, :description, :proposal_id, :valid_answers)
|
||||
params.require(:poll_question).permit(:poll_id, :title, :question, :description, :proposal_id, :valid_answers, :video_url,
|
||||
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
|
||||
end
|
||||
|
||||
def search_params
|
||||
|
||||
@@ -2,20 +2,21 @@ class Admin::Poll::ShiftsController < Admin::BaseController
|
||||
|
||||
before_action :load_booth
|
||||
before_action :load_polls
|
||||
before_action :load_officer
|
||||
|
||||
def new
|
||||
load_officers
|
||||
load_shifts
|
||||
@shift = ::Poll::Shift.new
|
||||
end
|
||||
|
||||
def create
|
||||
@shift = ::Poll::Shift.new(shift_params)
|
||||
@officer = @shift.officer
|
||||
|
||||
if @shift.save
|
||||
notice = t("admin.poll_shifts.flash.create")
|
||||
redirect_to new_admin_booth_shift_path(@shift.booth), notice: notice
|
||||
else
|
||||
load_officers
|
||||
load_shifts
|
||||
render :new
|
||||
end
|
||||
@@ -28,6 +29,10 @@ class Admin::Poll::ShiftsController < Admin::BaseController
|
||||
redirect_to new_admin_booth_shift_path(@booth), notice: notice
|
||||
end
|
||||
|
||||
def search_officers
|
||||
@officers = User.search(params[:search]).order(username: :asc)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_booth
|
||||
@@ -38,14 +43,16 @@ class Admin::Poll::ShiftsController < Admin::BaseController
|
||||
@polls = ::Poll.current_or_incoming
|
||||
end
|
||||
|
||||
def load_officers
|
||||
@officers = ::Poll::Officer.all
|
||||
end
|
||||
|
||||
def load_shifts
|
||||
@shifts = @booth.shifts
|
||||
end
|
||||
|
||||
def load_officer
|
||||
if params[:officer_id].present?
|
||||
@officer = ::Poll::Officer.find(params[:officer_id])
|
||||
end
|
||||
end
|
||||
|
||||
def shift_params
|
||||
params.require(:shift).permit(:booth_id, :officer_id, :date)
|
||||
end
|
||||
|
||||
@@ -10,6 +10,8 @@ class Polls::QuestionsController < ApplicationController
|
||||
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
||||
set_comment_flags(@comment_tree.comments)
|
||||
|
||||
@document = Document.new(documentable: @question)
|
||||
|
||||
question_answer = @question.answers.where(author_id: current_user.try(:id)).first
|
||||
@answers_by_question_id = {@question.id => question_answer.try(:answer)}
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ module AdminHelper
|
||||
end
|
||||
|
||||
def menu_polls?
|
||||
["polls", "questions", "officers", "booths", "officer_assignments", "booth_assignments", "recounts", "results"].include? controller_name
|
||||
["polls", "questions", "officers", "booths", "officer_assignments", "booth_assignments", "recounts", "results", "shifts"].include? controller_name
|
||||
end
|
||||
|
||||
def menu_profiles?
|
||||
|
||||
@@ -57,7 +57,7 @@ module Abilities
|
||||
can [:index, :create, :edit, :update, :destroy], Geozone
|
||||
|
||||
can [:read, :create, :update, :destroy, :add_question, :remove_question, :search_booths, :search_questions, :search_officers], Poll
|
||||
can [:read, :create, :update, :destroy], Poll::Booth
|
||||
can [:read, :create, :update, :destroy, :available], Poll::Booth
|
||||
can [:search, :create, :index, :destroy], ::Poll::Officer
|
||||
can [:create, :destroy], ::Poll::BoothAssignment
|
||||
can [:create, :destroy], ::Poll::OfficerAssignment
|
||||
|
||||
@@ -5,10 +5,15 @@ class Poll
|
||||
has_many :shifts
|
||||
|
||||
validates :name, presence: true, uniqueness: true
|
||||
|
||||
|
||||
def self.search(terms)
|
||||
return Booth.none if terms.blank?
|
||||
Booth.where("name ILIKE ? OR location ILIKE ?", "%#{terms}%", "%#{terms}%")
|
||||
end
|
||||
|
||||
def self.available
|
||||
where(polls: { id: Poll.current_or_incoming }).includes(:polls)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,11 @@
|
||||
class Poll::Question < ActiveRecord::Base
|
||||
include Measurable
|
||||
include Searchable
|
||||
include Documentable
|
||||
documentable max_documents_allowed: 1,
|
||||
max_file_size: 3.megabytes,
|
||||
accepted_content_types: [ "application/pdf" ]
|
||||
accepts_nested_attributes_for :documents, allow_destroy: true
|
||||
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
@@ -73,12 +73,15 @@
|
||||
<%= link_to t('admin.menu.poll_officers'), admin_officers_path %>
|
||||
</li>
|
||||
|
||||
<li <%# "class=active" if controller_name == "booths" %>>
|
||||
<li <%= "class=active" if controller_name == "booths" &&
|
||||
action_name != "available" %>>
|
||||
<%= link_to t('admin.menu.poll_booths'), admin_booths_path %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "booths" %>>
|
||||
<%= link_to t('admin.menu.poll_shifts'), admin_booths_path %>
|
||||
<li <%= "class=active" if controller_name == "shifts" ||
|
||||
controller_name == "booths" &&
|
||||
action_name == "available" %>>
|
||||
<%= link_to t('admin.menu.poll_shifts'), available_admin_booths_path %>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
<thead>
|
||||
<th><%= t("admin.booths.index.name") %></th>
|
||||
<th><%= t("admin.booths.index.location") %></th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th class="text-right"><%= t("admin.actions.actions") %></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @booths.each do |booth| %>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<thead>
|
||||
<th><%= t("admin.poll_officer_assignments.index.table_name") %></th>
|
||||
<th><%= t("admin.poll_officer_assignments.index.table_email") %></th>
|
||||
<th class="text-right"><%= t("admin.actions.actions") %></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @officers.each do |officer| %>
|
||||
@@ -28,11 +27,6 @@
|
||||
<td>
|
||||
<%= officer.email %>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<%= link_to t("admin.poll_officer_assignments.index.edit_officer_assignments"),
|
||||
by_officer_admin_poll_officer_assignments_path(@poll, officer_id: officer.id),
|
||||
class: "button hollow" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
@@ -40,4 +34,4 @@
|
||||
|
||||
<%= paginate @officers %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,17 @@
|
||||
ckeditor: { language: I18n.locale } %>
|
||||
</div>
|
||||
|
||||
<div class="documents small-12" data-max-documents="<%= Poll::Question.max_documents_allowed %>">
|
||||
<%= render 'documents/nested_documents', documentable: @question %>
|
||||
</div>
|
||||
|
||||
<div class="small-12">
|
||||
<%= f.label :video_url, t("proposals.form.proposal_video_url") %>
|
||||
<p class="help-text" id="video-url-help-text"><%= t("proposals.form.proposal_video_url_note") %></p>
|
||||
<%= f.text_field :video_url, placeholder: t("proposals.form.proposal_video_url"), label: false,
|
||||
aria: {describedby: "video-url-help-text"} %>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="actions small-12 medium-4 column margin-top">
|
||||
<%= f.submit(class: "button expanded", value: t("shared.save")) %>
|
||||
|
||||
@@ -40,6 +40,21 @@
|
||||
<%= @question.description %>
|
||||
</p>
|
||||
|
||||
<% if @question.video_url.present? %>
|
||||
<p>
|
||||
<strong><%= t("admin.questions.show.video_url") %></strong>
|
||||
<br>
|
||||
<a href="<%= @question.video_url %>"><%= @question.video_url %></a>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @question.documents.any? %>
|
||||
<p>
|
||||
<strong><%= t("admin.questions.show.documents") %></strong>
|
||||
<br>
|
||||
<a href="<%= @question.documents.first.attachment.url %>"><%= @question.documents.first.title %></a>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to t("admin.questions.show.preview"), question_path(@question) %>
|
||||
</div>
|
||||
|
||||
30
app/views/admin/poll/shifts/_form.html.erb
Normal file
30
app/views/admin/poll/shifts/_form.html.erb
Normal file
@@ -0,0 +1,30 @@
|
||||
<%= form_for @shift, as: :shift, url: admin_booth_shifts_path do |f| %>
|
||||
<%= render "shared/errors", resource: @shift %>
|
||||
|
||||
<fieldset class="fieldset">
|
||||
<legend>
|
||||
<%= t("admin.poll_shifts.new.new_shift") %>
|
||||
</legend>
|
||||
|
||||
<div class="small-12 medium-4 column highlight padding">
|
||||
<strong><%= t("admin.poll_shifts.new.officer") %></strong>
|
||||
<br><%= @officer.name %>
|
||||
<%= f.hidden_field :officer_id, value: @officer.id %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<label><%= t("admin.poll_shifts.new.date") %></label>
|
||||
<%= f.select :date,
|
||||
shift_dates_select_options(@polls),
|
||||
prompt: t("admin.poll_shifts.new.select_date"),
|
||||
label: false %>
|
||||
</div>
|
||||
|
||||
<%= f.hidden_field :booth_id, value: @booth.id %>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<%= f.submit t("admin.poll_shifts.new.add_shift"),
|
||||
class: "button expanded margin-top" %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
19
app/views/admin/poll/shifts/_search_officers.html.erb
Normal file
19
app/views/admin/poll/shifts/_search_officers.html.erb
Normal file
@@ -0,0 +1,19 @@
|
||||
<div class="row">
|
||||
<div class="small-12 medium-6 column">
|
||||
<%= form_tag search_officers_admin_booth_shifts_path,
|
||||
method: :get, remote: true do |f| %>
|
||||
<div class="input-group">
|
||||
<%= text_field_tag :search,
|
||||
@search,
|
||||
placeholder: t("admin.poll_shifts.new.search_officer_placeholder"),
|
||||
id: "search-officers" %>
|
||||
<div class="input-group-button">
|
||||
<%= submit_tag t("admin.poll_shifts.new.search_officer_button"),
|
||||
class: "button" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-officers-results"></div>
|
||||
@@ -0,0 +1,36 @@
|
||||
<% if @officers.blank? %>
|
||||
<div class="callout alert margin-bottom">
|
||||
<%= t('admin.shared.no_search_results') %>
|
||||
</div>
|
||||
<% else %>
|
||||
<h3><%= t('admin.shared.search_results') %></h3>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.poll_shifts.new.table_name") %></th>
|
||||
<th><%= t("admin.poll_shifts.new.table_email") %></th>
|
||||
<th class="text-right">
|
||||
<%= t("admin.poll_shifts.new.table_shift") %>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @officers.each do |user| %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= user.name %>
|
||||
</td>
|
||||
<td>
|
||||
<%= user.email %>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<%= link_to t("admin.poll_shifts.new.edit_shifts"),
|
||||
new_admin_booth_shift_path(officer_id: user.poll_officer.id),
|
||||
class: "button hollow" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
@@ -1,10 +1,10 @@
|
||||
<h3><%= t("admin.poll_shifts.new.assignments") %></h3>
|
||||
<h3><%= t("admin.poll_shifts.new.shifts") %></h3>
|
||||
<table class="fixed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.poll_shifts.new.date") %></th>
|
||||
<th><%= t("admin.poll_shifts.new.officer") %></th>
|
||||
<th class="text-right"><%= t("admin.poll_shifts.new.assignment") %></th>
|
||||
<th class="text-right"><%= t("admin.poll_shifts.new.shift") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -13,7 +13,7 @@
|
||||
<td><%= l(shift.date.to_date, format: :long) %></td>
|
||||
<td><%= shift.officer_name %></td>
|
||||
<td class="text-right">
|
||||
<%= link_to t("admin.poll_shifts.new.remove_assignment"),
|
||||
<%= link_to t("admin.poll_shifts.new.remove_shift"),
|
||||
admin_booth_shift_path(@booth, shift),
|
||||
method: :delete,
|
||||
class: "button hollow alert" %>
|
||||
|
||||
@@ -2,45 +2,21 @@
|
||||
|
||||
<h2><%= @booth.name %></h2>
|
||||
|
||||
<%= form_for @shift, as: :shift, url: admin_booth_shifts_path do |f| %>
|
||||
<%= render "shared/errors", resource: @shift %>
|
||||
|
||||
<fieldset class="fieldset">
|
||||
<legend>
|
||||
<%= t("admin.poll_shifts.new.new_assignment") %>
|
||||
</legend>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<label><%= t("admin.poll_shifts.new.date") %></label>
|
||||
<%= f.select :date,
|
||||
shift_dates_select_options(@polls),
|
||||
prompt: t("admin.poll_shifts.new.select_date"),
|
||||
label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<label><%= t("admin.poll_shifts.new.officer") %></label>
|
||||
<%= f.select :officer_id,
|
||||
officer_select_options(@officers),
|
||||
prompt: t("admin.poll_shifts.new.select_officer"),
|
||||
label: false %>
|
||||
</div>
|
||||
|
||||
<%= f.hidden_field :booth_id, value: @booth.id %>
|
||||
|
||||
<div class="small-12 medium-4 column">
|
||||
<%= f.submit t("admin.poll_shifts.new.add_assignment"),
|
||||
class: "button expanded hollow margin-top" %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% if @officer.blank? %>
|
||||
<p>
|
||||
<%= t("admin.poll_shifts.new.search_officer_text") %>
|
||||
</p>
|
||||
<%= render "search_officers" %>
|
||||
<% else %>
|
||||
<%= render "form" %>
|
||||
<% end %>
|
||||
|
||||
<div id="shifts">
|
||||
<% if @shifts.empty? %>
|
||||
<div class="callout primary margin-top">
|
||||
<%= t("admin.poll_shifts.new.no_assignments") %>
|
||||
<div class="callout primary">
|
||||
<%= t("admin.poll_shifts.new.no_shifts") %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render "shifts" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
1
app/views/admin/poll/shifts/search_officers.js.erb
Normal file
1
app/views/admin/poll/shifts/search_officers.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#search-officers-results").html("<%= j render 'search_officers_results' %>");
|
||||
22
app/views/polls/questions/_filter_subnav.html.erb
Normal file
22
app/views/polls/questions/_filter_subnav.html.erb
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<ul class="tabs" data-tabs id="questions-tabs">
|
||||
<li class="tabs-title is-active">
|
||||
<%= link_to "#tab-comments" do %>
|
||||
<h3>
|
||||
<%= t("proposals.show.comments_tab") %>
|
||||
<span class="js-comments-count">(<%= @question.comments_count %>)</span>
|
||||
</h3>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class="tabs-title">
|
||||
<%= link_to "#tab-documents" do %>
|
||||
<h3>
|
||||
<%= t("documents.tab") %>
|
||||
(<%= @question.documents.count %>)
|
||||
</h3>
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,6 +55,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if @question.video_url.present? %>
|
||||
<div class="row margin-top poll-question-show">
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="video-link">
|
||||
<p>
|
||||
<span class="icon-video"></span>
|
||||
<strong><%= t('proposals.show.title_video_url') %></strong>
|
||||
</p>
|
||||
<%= text_with_links @question.video_url %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<div class="row margin-top">
|
||||
<div class="small-12 medium-9 column">
|
||||
<h3><%= t('poll_questions.show.more_info') %></h3>
|
||||
@@ -62,4 +77,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render "comments" %>
|
||||
<div class="tabs-content" data-tabs-content="questions-tabs" role="tablist">
|
||||
<%= render "polls/questions/filter_subnav" %>
|
||||
|
||||
<div class="tabs-panel is-active" id="tab-comments">
|
||||
<%= render "polls/questions/comments" %>
|
||||
</div>
|
||||
|
||||
<div class="tabs-panel" id="tab-documents">
|
||||
<%= render 'documents/documents',
|
||||
documents: @question.documents,
|
||||
max_documents_allowed: Poll::Question.max_documents_allowed %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
<% end %>
|
||||
|
||||
<% if author_of?(@proposal, current_user) %>
|
||||
<%= link_to t("proposals.show.send_notification"), new_proposal_notification_path(proposal_id: @proposal.id),
|
||||
<%= link_to t("proposals.show.send_notification"),
|
||||
new_proposal_notification_path(proposal_id: @proposal.id),
|
||||
class: 'button hollow float-right' %>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
<% if show_admin_menu? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.administration_menu"), "#", rel: "nofollow" %>
|
||||
<ul class="menu">
|
||||
<% if current_user.administrator? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.administration"), admin_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.administration_menu"), "#", rel: "nofollow" %>
|
||||
<ul class="menu">
|
||||
<% if current_user.administrator? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.administration"), admin_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.administrator? || current_user.moderator? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.moderation"), moderation_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if current_user.administrator? || current_user.moderator? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.moderation"), moderation_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if (feature?(:spending_proposals) || feature?(:budgets)) &&
|
||||
(current_user.administrator? || current_user.valuator?) %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.valuation"), valuation_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if (feature?(:spending_proposals) || feature?(:budgets)) &&
|
||||
(current_user.administrator? || current_user.valuator?) %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.valuation"), valuation_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.administrator? || current_user.manager? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.management"), management_sign_in_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if current_user.administrator? || current_user.manager? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.management"), management_sign_in_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.administrator? || current_user.poll_officer? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.officing"), officing_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
<% if current_user.administrator? || current_user.poll_officer? %>
|
||||
<li>
|
||||
<%= link_to t("layouts.header.officing"), officing_root_path %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<li>
|
||||
<%= layout_menu_link_to t("layouts.header.poll_questions"),
|
||||
polls_path,
|
||||
controller_name == "polls",
|
||||
controller_name == "polls" || controller_name == "questions",
|
||||
accesskey: "3",
|
||||
title: t("shared.go_to_page") + t("layouts.header.poll_questions") %>
|
||||
</li>
|
||||
|
||||
@@ -498,16 +498,22 @@ en:
|
||||
final_recount: "Final recount (by officer)"
|
||||
poll_shifts:
|
||||
new:
|
||||
new_assignment: "New shift"
|
||||
add_shift: "Add shift"
|
||||
shift: "Assignment"
|
||||
shifts: "Shifts in this booth"
|
||||
date: "Date"
|
||||
edit_shifts: Edit shifts
|
||||
new_shift: "New shift"
|
||||
no_shifts: "This booth has no shifts"
|
||||
officer: "Officer"
|
||||
assignment: "Assignment"
|
||||
remove_shift: "Remove"
|
||||
search_officer_button: Search
|
||||
search_officer_placeholder: Search officer
|
||||
search_officer_text: Search for an officer to assign a new shift
|
||||
select_date: "Select day"
|
||||
select_officer: "Select officer"
|
||||
add_assignment: "Add shift"
|
||||
remove_assignment: "Remove"
|
||||
assignments: "Shifts in this booth"
|
||||
no_assignments: "This booth has no shifts"
|
||||
table_shift: "Shift"
|
||||
table_email: "Email"
|
||||
table_name: "Name"
|
||||
flash:
|
||||
create: "Shift added"
|
||||
destroy: "Shift removed"
|
||||
@@ -590,6 +596,8 @@ en:
|
||||
title: Title
|
||||
valid_answers: Valid answers
|
||||
description: Description
|
||||
video_url: External video
|
||||
documents: Documents
|
||||
preview: View on website
|
||||
recounts:
|
||||
index:
|
||||
|
||||
@@ -175,6 +175,7 @@ en:
|
||||
proposal_notification: "Notification"
|
||||
spending_proposal: Spending proposal
|
||||
budget/investment: Investment
|
||||
poll/shift: Shift
|
||||
user: Account
|
||||
verification/sms: phone
|
||||
signature_sheet: Signature sheet
|
||||
|
||||
@@ -63,9 +63,9 @@ en:
|
||||
text: |-
|
||||
Use it in your local government or help us to improve it, it is free software.
|
||||
|
||||
This Open Government Portal use the [CONSUL app](https://github.com/ayuntamientomadrid 'consul github') that is free software, with [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), that means in simple words that anyone can use the code freely, copy it, see it in detail, modify it and redistribute it to the word with the modifications he wants (allowing others to do the same). Because we think culture is better and richer when it is released.
|
||||
This Open Government Portal use the [CONSUL app](https://github.com/consul/consul 'consul github') that is free software, with [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), that means in simple words that anyone can use the code freely, copy it, see it in detail, modify it and redistribute it to the word with the modifications he wants (allowing others to do the same). Because we think culture is better and richer when it is released.
|
||||
|
||||
If you are a programmer, you can see the code and help us to improve it at [CONSUL app](https://github.com/ayuntamientomadrid 'consul github').
|
||||
If you are a programmer, you can see the code and help us to improve it at [CONSUL app](https://github.com/consul/consul 'consul github').
|
||||
titles:
|
||||
how_to_use: Use it in your local government
|
||||
privacy: Privacy Policy
|
||||
|
||||
@@ -498,18 +498,24 @@ es:
|
||||
final_recount: "Recuento final (presidente de mesa)"
|
||||
poll_shifts:
|
||||
new:
|
||||
new_assignment: "Nuevo turno"
|
||||
add_shift: "Añadir turno"
|
||||
shift: "Asignación"
|
||||
shifts: "Turnos en esta urna"
|
||||
date: "Fecha"
|
||||
edit_shifts: Asignar turno
|
||||
new_shift: "Nuevo turno"
|
||||
no_shifts: "Esta urna no tiene turnos asignados"
|
||||
officer: "Presidente de mesa"
|
||||
assignment: "Asignación"
|
||||
remove_shift: "Eliminar turno"
|
||||
search_officer_button: Buscar
|
||||
search_officer_placeholder: Buscar presidentes de mesa
|
||||
search_officer_text: Busca al presidente de mesa para asignar un turno
|
||||
select_date: "Seleccionar día"
|
||||
select_officer: "Seleccionar presidente de mesa"
|
||||
add_assignment: "Añadir turno"
|
||||
remove_assignment: "Eliminar turno"
|
||||
assignments: "Turnos en esta urna"
|
||||
no_assignments: "Esta urna no tiene turnos asignados"
|
||||
table_shift: "Turno"
|
||||
table_email: "Email"
|
||||
table_name: "Nombre"
|
||||
flash:
|
||||
create: "Añadido turno de presidente de mesa"
|
||||
create: "Añadido turno de presidente de mesa"
|
||||
destroy: "Eliminado turno de presidente de mesa"
|
||||
poll_booth_assignments:
|
||||
flash:
|
||||
@@ -590,6 +596,8 @@ es:
|
||||
title: Título
|
||||
valid_answers: Respuestas válidas
|
||||
description: Descripción
|
||||
video_url: Video externo
|
||||
documents: Documentos
|
||||
preview: Ver en la web
|
||||
recounts:
|
||||
index:
|
||||
|
||||
@@ -175,6 +175,7 @@ es:
|
||||
proposal_notification: "la notificación"
|
||||
spending_proposal: la propuesta de gasto
|
||||
budget/investment: la propuesta de inversión
|
||||
poll/shift: el turno
|
||||
user: la cuenta
|
||||
verification/sms: el teléfono
|
||||
signature_sheet: la hoja de firmas
|
||||
|
||||
@@ -63,9 +63,9 @@ es:
|
||||
text: |-
|
||||
Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre.
|
||||
|
||||
Este Portal de Gobierno Abierto usa la [aplicación CONSUL](https://github.com/ayuntamientomadrid 'github consul') que es software libre, con [licencia AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), esto significa en palabras sencillas, que cualquiera puede libremente usar el código, copiarlo, verlo en detalle, modificarlo, y redistribuirlo al mundo con las modificaciones que quiera (manteniendo el que otros puedan a su vez hacer lo mismo). Porque creemos que la cultura es mejor y más rica cuando se libera.
|
||||
Este Portal de Gobierno Abierto usa la [aplicación CONSUL](https://github.com/consul/consul 'github consul') que es software libre, con [licencia AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), esto significa en palabras sencillas, que cualquiera puede libremente usar el código, copiarlo, verlo en detalle, modificarlo, y redistribuirlo al mundo con las modificaciones que quiera (manteniendo el que otros puedan a su vez hacer lo mismo). Porque creemos que la cultura es mejor y más rica cuando se libera.
|
||||
|
||||
Si eres programador, puedes ver el código y ayudarnos a mejorarlo en [aplicación CONSUL](https://github.com/ayuntamientomadrid 'github consul').
|
||||
Si eres programador, puedes ver el código y ayudarnos a mejorarlo en [aplicación CONSUL](https://github.com/consul/consul 'github consul').
|
||||
titles:
|
||||
how_to_use: Utilízalo en tu municipio
|
||||
privacy: Política de Privacidad
|
||||
@@ -81,4 +81,4 @@ es:
|
||||
info_code: 'Ahora introduce el código que has recibido en tu carta:'
|
||||
password: Contraseña
|
||||
submit: Verificar mi cuenta
|
||||
title: Verifica tu cuenta
|
||||
title: Verifica tu cuenta
|
||||
|
||||
@@ -1196,7 +1196,7 @@ fr:
|
||||
how_to_use:
|
||||
text: "Utilisez cet outil dans votre collectivité ou aidez-nous àl'améliorer,
|
||||
c'est un logiciel libre.\r\n\r\nCe portail de gouvernement ouvert utilise
|
||||
cette [application Consul ](https://github.com/ayuntamientomadrid 'consul
|
||||
cette [application Consul ](https://github.com/consul/consul 'consul
|
||||
github') qui est un logiciel libre, avec une [license AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html
|
||||
'AGPLv3 gnu' ), ce qui signifie en fait que n'importe qui peut utiliser
|
||||
le code librement, le copier, l'étudier en détail, le modifier et le redistribuer
|
||||
@@ -1207,7 +1207,7 @@ fr:
|
||||
la Mairie de Madrid autant que possible pour le faire. Si vous êtes intéressé,
|
||||
n'hésitez pas à nous contacter : <a href='mailto:ag.gobiernoabierto@consul.dev'>ag.gobiernoabierto@consul.dev</a>\r\n\r\nSi
|
||||
vous êtes développeur, vous pouvez voir le code et nous aider à l'améliorer
|
||||
sur [Consul app](https://github.com/ayuntamientomadrid 'consul github '
|
||||
sur [Consul app](https://github.com/consul/consul 'consul github '
|
||||
)."
|
||||
titles:
|
||||
faq: Solution pour les problèmes techniques (FAQ)
|
||||
|
||||
@@ -59,9 +59,9 @@ fr:
|
||||
text: |-
|
||||
Utilisez le librement pour votre gouvernement ou aider nous à l'améliorer, c'est un logiciel libre.
|
||||
|
||||
Ce portail de Gouvernement Ouvert utilise l'[application Consul](https://github.com/ayuntamientomadrid 'consul github') qui est un logiciel libre, sous [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), ce qui, en quelques mots, signifie que tout le monde peut utiliser le code librement, le copier, le voir en détail, le modifier et le redistribuer avec ces modifications (permettant à d'autres d'en faire de même). Car nous pensons que la culture est meilleure et plus riche quand elle est libre.
|
||||
Ce portail de Gouvernement Ouvert utilise l'[application Consul](https://github.com/consul/consul 'consul github') qui est un logiciel libre, sous [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), ce qui, en quelques mots, signifie que tout le monde peut utiliser le code librement, le copier, le voir en détail, le modifier et le redistribuer avec ces modifications (permettant à d'autres d'en faire de même). Car nous pensons que la culture est meilleure et plus riche quand elle est libre.
|
||||
|
||||
Si vous êtes un développeur, vous pouvez voir le code et nous aider à l'améliorer en allant sur l'[applicationConsul](https://github.com/ayuntamientomadrid 'consul github').
|
||||
Si vous êtes un développeur, vous pouvez voir le code et nous aider à l'améliorer en allant sur l'[applicationConsul](https://github.com/consul/consul 'consul github').
|
||||
titles:
|
||||
how_to_use: Utilisez-le pour votre gouvernement
|
||||
privacy: Politique de confidentialité
|
||||
|
||||
@@ -60,9 +60,9 @@ nl:
|
||||
text: |-
|
||||
Gebruik het in uw gemeente en help ons het te verbeteren, het is gratis software.
|
||||
|
||||
Deze Open Overheid site gebruikt de [Consul web-app](https://github.com/ayuntamientomadrid 'consul github'). Gratis software, onder de [AGPLv3 Licentie](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ). Simpel gezegd betekend dit dat u de app kunt inspecteren, gebruiken, aanpassen en herdistribueren (onder voorwaarde dat anderen hetzelfde kunnen doen met uw versie).
|
||||
Deze Open Overheid site gebruikt de [Consul web-app](https://github.com/consul/consul 'consul github'). Gratis software, onder de [AGPLv3 Licentie](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ). Simpel gezegd betekend dit dat u de app kunt inspecteren, gebruiken, aanpassen en herdistribueren (onder voorwaarde dat anderen hetzelfde kunnen doen met uw versie).
|
||||
|
||||
Voor programmeurs: help ons het te verbeteren via [Consul app](https://github.com/ayuntamientomadrid 'consul github').
|
||||
Voor programmeurs: help ons het te verbeteren via [Consul app](https://github.com/consul/consul 'consul github').
|
||||
titles:
|
||||
how_to_use: Gebruik het in uw gemeente
|
||||
privacy: Privacy Verklaring
|
||||
@@ -78,4 +78,4 @@ nl:
|
||||
info_code: 'en de code die u heeft ontvangen:'
|
||||
password: Wachtwoord
|
||||
submit: Verifieer mijn account
|
||||
title: Verifieer uw account
|
||||
title: Verifieer uw account
|
||||
|
||||
@@ -1212,7 +1212,7 @@ pt-BR:
|
||||
how_to_use:
|
||||
text: "Use este programa em seu governo local ou nos ajude a melhorá-lo, ele
|
||||
é um software livre.\r\n\r\nEste Portal de Governo Aberto usa o [app Consul]
|
||||
(https://github.com/ayuntamientomadrid 'cônsul github'), que é um software
|
||||
(https://github.com/consul/consul 'cônsul github'), que é um software
|
||||
livre, com [licença AGPLv3] (http://www.gnu.org/licenses/agpl- 3.0.html
|
||||
'AGPLv3 gnu'), o que significa, em palavras simples que qualquer um pode
|
||||
usar o código livremente, copiá-lo, vê-lo em detalhes, modificá-lo e redistribuí-lo
|
||||
@@ -1223,7 +1223,7 @@ pt-BR:
|
||||
Madrid, o tanto quanto possível para fazê-lo, por isso, se você estiver
|
||||
interessado escreva-nos: <a href = \"mailto: ag.gobiernoabierto@consul.dev
|
||||
'> ag.gobiernoabierto@consul.dev </a>\r\n\r\nSe você é um programador, você
|
||||
pode ver o código e nos ajudar a melhorá-lo em [app Consul] (https://github.com/ayuntamientomadrid
|
||||
pode ver o código e nos ajudar a melhorá-lo em [app Consul] (https://github.com/consul/consul
|
||||
'cônsul github')."
|
||||
titles:
|
||||
faq: Solução para problemas técnicos (FAQ)
|
||||
|
||||
@@ -287,7 +287,11 @@ Rails.application.routes.draw do
|
||||
end
|
||||
|
||||
resources :booths do
|
||||
resources :shifts
|
||||
get :available, on: :collection
|
||||
|
||||
resources :shifts do
|
||||
get :search_officers, on: :collection
|
||||
end
|
||||
end
|
||||
|
||||
resources :questions
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddVideoUrlToPollQuestions < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :poll_questions, :video_url, :string
|
||||
end
|
||||
end
|
||||
@@ -669,6 +669,7 @@ ActiveRecord::Schema.define(version: 20170908175149) do
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.tsvector "tsv"
|
||||
t.string "video_url"
|
||||
end
|
||||
|
||||
add_index "poll_questions", ["author_id"], name: "index_poll_questions_on_author_id", using: :btree
|
||||
@@ -973,7 +974,7 @@ ActiveRecord::Schema.define(version: 20170908175149) do
|
||||
t.boolean "email_digest", default: true
|
||||
t.boolean "email_on_direct_message", default: true
|
||||
t.boolean "official_position_badge", default: false
|
||||
t.datetime "password_changed_at", default: '2017-08-07 11:14:09', null: false
|
||||
t.datetime "password_changed_at", default: '2017-09-06 18:19:39', null: false
|
||||
t.boolean "created_from_signature", default: false
|
||||
t.integer "failed_email_digests_count", default: 0
|
||||
t.text "former_users_data_log", default: ""
|
||||
|
||||
@@ -380,6 +380,10 @@ FactoryGirl.define do
|
||||
trait :budget_investment_document do
|
||||
association :documentable, factory: :budget_investment
|
||||
end
|
||||
|
||||
trait :poll_question_document do
|
||||
association :documentable, factory: :poll_question
|
||||
end
|
||||
end
|
||||
|
||||
factory :comment do
|
||||
|
||||
@@ -36,6 +36,32 @@ feature 'Admin booths' do
|
||||
expect(page).to_not have_content "There are no booths"
|
||||
end
|
||||
|
||||
scenario "Available" do
|
||||
booth_for_current_poll = create(:poll_booth)
|
||||
booth_for_incoming_poll = create(:poll_booth)
|
||||
booth_for_expired_poll = create(:poll_booth)
|
||||
|
||||
current_poll = create(:poll, :current)
|
||||
incoming_poll = create(:poll, :incoming)
|
||||
expired_poll = create(:poll, :expired)
|
||||
|
||||
create(:poll_booth_assignment, poll: current_poll, booth: booth_for_current_poll)
|
||||
create(:poll_booth_assignment, poll: incoming_poll, booth: booth_for_incoming_poll)
|
||||
create(:poll_booth_assignment, poll: expired_poll, booth: booth_for_expired_poll)
|
||||
|
||||
visit admin_root_path
|
||||
|
||||
within('#side_menu') do
|
||||
click_link "Manage shifts"
|
||||
end
|
||||
|
||||
expect(page).to have_css(".booth", count: 2)
|
||||
|
||||
expect(page).to have_content booth_for_current_poll.name
|
||||
expect(page).to have_content booth_for_incoming_poll.name
|
||||
expect(page).to_not have_content booth_for_expired_poll.name
|
||||
end
|
||||
|
||||
scenario 'Show' do
|
||||
booth = create(:poll_booth)
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ feature 'Admin poll questions' do
|
||||
Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her
|
||||
people and restore freedom to the galaxy....
|
||||
}
|
||||
video_url = "https://puppyvideos.com"
|
||||
|
||||
visit admin_questions_path
|
||||
click_link "Create question"
|
||||
@@ -45,11 +46,13 @@ feature 'Admin poll questions' do
|
||||
select 'Movies', from: 'poll_question_poll_id'
|
||||
fill_in 'poll_question_title', with: title
|
||||
fill_in 'poll_question_description', with: description
|
||||
fill_in 'poll_question_video_url', with: video_url
|
||||
|
||||
click_button 'Save'
|
||||
|
||||
expect(page).to have_content(title)
|
||||
expect(page).to have_content(description)
|
||||
expect(page).to have_content(video_url)
|
||||
end
|
||||
|
||||
scenario 'Create from successful proposal index' do
|
||||
|
||||
@@ -30,7 +30,7 @@ feature 'Admin shifts' do
|
||||
expect(page).to have_content officer.name
|
||||
end
|
||||
|
||||
scenario "Create" do
|
||||
scenario "Create", :js do
|
||||
poll = create(:poll)
|
||||
booth = create(:poll_booth)
|
||||
officer = create(:poll_officer)
|
||||
@@ -41,10 +41,13 @@ feature 'Admin shifts' do
|
||||
click_link "Manage shifts"
|
||||
end
|
||||
|
||||
select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date'
|
||||
select officer.name, from: 'shift_officer_id'
|
||||
click_button "Add shift"
|
||||
fill_in "search", with: officer.email
|
||||
click_button "Search"
|
||||
click_link "Edit shifts"
|
||||
|
||||
select I18n.l(poll.starts_at.to_date, format: :long), from: 'shift_date'
|
||||
click_button "Add shift"
|
||||
|
||||
expect(page).to have_content "Shift added"
|
||||
|
||||
within("#shifts") do
|
||||
@@ -54,6 +57,25 @@ feature 'Admin shifts' do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Erros on create", :js do
|
||||
poll = create(:poll)
|
||||
booth = create(:poll_booth)
|
||||
officer = create(:poll_officer)
|
||||
|
||||
visit admin_booths_path
|
||||
|
||||
within("#booth_#{booth.id}") do
|
||||
click_link "Manage shifts"
|
||||
end
|
||||
|
||||
fill_in "search", with: officer.email
|
||||
click_button "Search"
|
||||
click_link "Edit shifts"
|
||||
click_button "Add shift"
|
||||
|
||||
expect(page).to have_content "can't be blank"
|
||||
end
|
||||
|
||||
scenario "Destroy" do
|
||||
poll = create(:poll)
|
||||
booth = create(:poll_booth)
|
||||
|
||||
@@ -25,6 +25,25 @@ feature 'Poll Questions' do
|
||||
expect(page).to have_content(question_with_author_visible_name.author_visible_name)
|
||||
end
|
||||
|
||||
scenario '#show view has video_url present' do
|
||||
poll = create(:poll)
|
||||
normal_question = create(:poll_question, poll: poll, video_url: "https://puppyvideos.com")
|
||||
|
||||
visit question_path(normal_question)
|
||||
|
||||
expect(page).to have_link(normal_question.video_url)
|
||||
end
|
||||
|
||||
scenario '#show view has document present' do
|
||||
poll = create(:poll)
|
||||
normal_question = create(:poll_question, poll: poll)
|
||||
document = create(:document, documentable: normal_question)
|
||||
|
||||
visit question_path(normal_question)
|
||||
|
||||
expect(page).to have_content(document.title)
|
||||
end
|
||||
|
||||
context 'Answering' do
|
||||
let(:geozone) { create(:geozone) }
|
||||
let(:poll) { create(:poll, geozone_restricted: true, geozone_ids: [geozone.id]) }
|
||||
|
||||
@@ -14,9 +14,11 @@ describe "Abilities::Administrator" do
|
||||
let(:proposal) { create(:proposal) }
|
||||
let(:budget_investment) { create(:budget_investment) }
|
||||
let(:legislation_question) { create(:legislation_question) }
|
||||
let(:poll_question) { create(:poll_question) }
|
||||
|
||||
let(:proposal_document) { build(:document, documentable: proposal) }
|
||||
let(:budget_investment_document) { build(:document, documentable: budget_investment) }
|
||||
let(:poll_question_document) { build(:document, documentable: poll_question) }
|
||||
|
||||
let(:hidden_debate) { create(:debate, :hidden) }
|
||||
let(:hidden_comment) { create(:comment, :hidden) }
|
||||
@@ -83,4 +85,8 @@ describe "Abilities::Administrator" do
|
||||
it { should be_able_to(:new, budget_investment_document) }
|
||||
it { should be_able_to(:create, budget_investment_document) }
|
||||
it { should be_able_to(:destroy, budget_investment_document) }
|
||||
|
||||
it { should be_able_to(:new, poll_question_document) }
|
||||
it { should be_able_to(:create, poll_question_document) }
|
||||
it { should be_able_to(:destroy, poll_question_document) }
|
||||
end
|
||||
|
||||
@@ -24,4 +24,25 @@ describe :booth do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#available" do
|
||||
|
||||
it "returns booths associated to current or incoming polls" do
|
||||
booth_for_current_poll = create(:poll_booth)
|
||||
booth_for_incoming_poll = create(:poll_booth)
|
||||
booth_for_expired_poll = create(:poll_booth)
|
||||
|
||||
current_poll = create(:poll, :current)
|
||||
incoming_poll = create(:poll, :incoming)
|
||||
expired_poll = create(:poll, :expired)
|
||||
|
||||
create(:poll_booth_assignment, poll: current_poll, booth: booth_for_current_poll)
|
||||
create(:poll_booth_assignment, poll: incoming_poll, booth: booth_for_incoming_poll)
|
||||
create(:poll_booth_assignment, poll: expired_poll, booth: booth_for_expired_poll)
|
||||
|
||||
expect(Poll::Booth.available).to include(booth_for_current_poll)
|
||||
expect(Poll::Booth.available).to include(booth_for_incoming_poll)
|
||||
expect(Poll::Booth.available).to_not include(booth_for_expired_poll)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user