authors can retire proposals now
This commit is contained in:
@@ -35,6 +35,17 @@ class ProposalsController < ApplicationController
|
||||
set_proposal_votes(@proposal)
|
||||
end
|
||||
|
||||
def retire
|
||||
if valid_retired_params? && @proposal.update(retired_params.merge(retired_at: Time.now))
|
||||
redirect_to proposal_path(@proposal), notice: t('proposals.notice.retired')
|
||||
else
|
||||
render action: :retire_form
|
||||
end
|
||||
end
|
||||
|
||||
def retire_form
|
||||
end
|
||||
|
||||
def vote_featured
|
||||
@proposal.register_vote(current_user, 'yes')
|
||||
set_featured_proposal_votes(@proposal)
|
||||
@@ -51,6 +62,16 @@ class ProposalsController < ApplicationController
|
||||
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url, :responsible_name, :tag_list, :terms_of_service, :captcha, :captcha_key, :geozone_id)
|
||||
end
|
||||
|
||||
def retired_params
|
||||
params.require(:proposal).permit(:retired_reason, :retired_explanation)
|
||||
end
|
||||
|
||||
def valid_retired_params?
|
||||
@proposal.errors.add(:retired_reason, I18n.t('errors.messages.blank')) if params[:proposal][:retired_reason].blank?
|
||||
@proposal.errors.add(:retired_explanation, I18n.t('errors.messages.blank')) if params[:proposal][:retired_explanation].blank?
|
||||
@proposal.errors.empty?
|
||||
end
|
||||
|
||||
def resource_model
|
||||
Proposal
|
||||
end
|
||||
|
||||
@@ -28,4 +28,8 @@ module ProposalsHelper
|
||||
end
|
||||
end
|
||||
|
||||
def retire_proposals_options
|
||||
Proposal::RETIRE_OPTIONS.collect { |option| [ t("proposals.retire_options.#{option}"), option ] }
|
||||
end
|
||||
|
||||
end
|
||||
@@ -16,6 +16,7 @@ module Abilities
|
||||
can :update, Proposal do |proposal|
|
||||
proposal.editable_by?(user)
|
||||
end
|
||||
can [:retire_form, :retire], Proposal, author_id: user.id
|
||||
|
||||
can :read, SpendingProposal
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ class Proposal < ActiveRecord::Base
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
RETIRE_OPTIONS = %w(duplicated started unfeasible done other)
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
belongs_to :geozone
|
||||
has_many :comments, as: :commentable
|
||||
@@ -26,6 +28,7 @@ class Proposal < ActiveRecord::Base
|
||||
validates :description, length: { maximum: Proposal.description_max_length }
|
||||
validates :question, length: { in: 10..Proposal.question_max_length }
|
||||
validates :responsible_name, length: { in: 6..Proposal.responsible_name_max_length }
|
||||
validates :retired_reason, inclusion: {in: RETIRE_OPTIONS, allow_nil: true}
|
||||
|
||||
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
|
||||
|
||||
|
||||
37
app/views/proposals/retire_form.html.erb
Normal file
37
app/views/proposals/retire_form.html.erb
Normal file
@@ -0,0 +1,37 @@
|
||||
<div class="proposal-edit row">
|
||||
|
||||
<div class="small-12 column">
|
||||
|
||||
<div class="float-right">
|
||||
<%= link_to @proposal.title, @proposal %>
|
||||
</div>
|
||||
|
||||
<h1><%= t("proposals.retire_form.title") %></h1>
|
||||
|
||||
<div data-alert class="callout primary">
|
||||
<%= t("proposals.retire_form.warning") %>
|
||||
</div>
|
||||
|
||||
<%= form_for(@proposal, url: retire_proposal_path(@proposal)) do |f| %>
|
||||
<%= render 'shared/errors', resource: @proposal %>
|
||||
<div class="row">
|
||||
|
||||
<div class="small-12 medium-6 column">
|
||||
<%= f.label :retired_reason, t("proposals.retire_form.retired_reason_label") %>
|
||||
<%= f.select :retired_reason, retire_proposals_options, {include_blank: t("proposals.retire_form.retired_reason_blank"), label: false} %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :retired_explanation, t("proposals.retire_form.retired_explanation_label") %>
|
||||
<%= f.text_area :retired_explanation, rows: 4, maxlength: 500, label: false,
|
||||
placeholder: t('proposals.retire_form.retired_explanation_placeholder') %>
|
||||
</div>
|
||||
|
||||
<div class="actions small-12 column">
|
||||
<%= f.submit(class: "button", value: t("proposals.retire_form.submit_button")) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -22,7 +22,11 @@
|
||||
<% end %>
|
||||
|
||||
<h1><%= @proposal.title %></h1>
|
||||
<% if @proposal.conflictive? %>
|
||||
<% if @proposal.retired? %>
|
||||
<div data-alert class="callout alert margin-top">
|
||||
<strong><%= t("proposals.show.retired_warning") %></strong>
|
||||
</div>
|
||||
<% elsif @proposal.conflictive? %>
|
||||
<div data-alert class="callout alert margin-top">
|
||||
<strong><%= t("proposals.show.flag") %></strong>
|
||||
</div>
|
||||
@@ -74,6 +78,11 @@
|
||||
|
||||
<h4><%= @proposal.question %></h4>
|
||||
|
||||
<% if @proposal.retired? %>
|
||||
<h2><%= t('proposals.show.retired') %>: <%= t("proposals.retire_options.#{@proposal.retired_reason}") unless @proposal.retired_reason == 'other' %></h2>
|
||||
<%= simple_format text_with_links(@proposal.retired_explanation), {}, sanitize: false %>
|
||||
<% end %>
|
||||
|
||||
<%= render 'shared/tags', taggable: @proposal %>
|
||||
|
||||
<%= render 'shared/geozone', geozonable: @proposal %>
|
||||
|
||||
@@ -2,10 +2,19 @@
|
||||
<% @proposals.each do |proposal| %>
|
||||
<tr id="proposal_<%= proposal.id %>">
|
||||
<td>
|
||||
<%= link_to proposal.title, proposal %>
|
||||
<%= link_to proposal.title, proposal, proposal.retired? ? {class: 'delete'} : {} %>
|
||||
<br>
|
||||
<%= proposal.summary %>
|
||||
</td>
|
||||
<td>
|
||||
<% if proposal.retired? %>
|
||||
<%= t('users.show.retired') %>
|
||||
<% else %>
|
||||
<%= link_to t('users.show.retire'),
|
||||
retire_form_proposal_path(proposal),
|
||||
class: 'delete' %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
@@ -254,6 +254,20 @@ en:
|
||||
form:
|
||||
submit_button: Save changes
|
||||
show_link: View proposal
|
||||
retire_form:
|
||||
title: Retire proposal
|
||||
warning: "If you retire the proposal it would still accept supports, but will be removed from the main list and a message will be visible to all users stating that the author considers the proposal should not be supported anymore"
|
||||
retired_reason_label: Reason to retire the proposal
|
||||
retired_reason_blank: Choose an option
|
||||
retired_explanation_label: Explanation
|
||||
retired_explanation_placeholder: Explain shortly why you think this proposal should not receive more supports
|
||||
submit_button: Retire proposal
|
||||
retire_options:
|
||||
duplicated: Duplicated
|
||||
started: Already underway
|
||||
unfeasible: Unfeasible
|
||||
done: Done
|
||||
other: Other
|
||||
form:
|
||||
geozone: Scope of operation
|
||||
proposal_external_url: Link to additional documentation
|
||||
@@ -305,6 +319,8 @@ en:
|
||||
recommendation_two: Any proposal or comment suggesting illegal action will be deleted, as well as those intending to sabotage the debate spaces. Anything else is allowed.
|
||||
recommendations_title: Recommendations for creating a proposal
|
||||
start_new: Create new proposal
|
||||
notice:
|
||||
retired: Proposal retired
|
||||
proposal:
|
||||
already_supported: You have already supported this proposal. Share it!
|
||||
comments:
|
||||
@@ -333,6 +349,8 @@ en:
|
||||
edit_proposal_link: Edit
|
||||
flag: This proposal has been flagged as inappropriate by several users.
|
||||
login_to_comment: You must %{signin} or %{signup} to leave a comment.
|
||||
retired_warning: "The author considers this proposal should not receive more supports. check the explanation before voting for it."
|
||||
retired: Proposal retired by the author
|
||||
share: Share
|
||||
update:
|
||||
form:
|
||||
@@ -489,6 +507,8 @@ en:
|
||||
other: "%{count} Spending proposals"
|
||||
no_activity: User has no public activity
|
||||
private_activity: This user decided to keep the activity list private
|
||||
retire: Retire
|
||||
retired: Retired
|
||||
votes:
|
||||
agree: I agree
|
||||
anonymous: Too many anonymous votes to admit vote %{verify_account}.
|
||||
|
||||
@@ -254,6 +254,20 @@ es:
|
||||
form:
|
||||
submit_button: Guardar cambios
|
||||
show_link: Ver propuesta
|
||||
retire_form:
|
||||
title: Retirar propuesta
|
||||
warning: "Si sigues adelante tu propuesta podrá seguir recibiendo apoyos, pero dejará de ser listada en la lista principal, y aparecerá un mensaje para todos los usuarios avisándoles de que el autor considera que esta propuesta no debe seguir recogiendo apoyos."
|
||||
retired_reason_label: Razón por la que se retira la propuesta
|
||||
retired_reason_blank: Selecciona una opción
|
||||
retired_explanation_label: Explicación
|
||||
retired_explanation_placeholder: Explica brevemente por que consideras que esta propuesta no debe recoger más apoyos
|
||||
submit_button: Retirar propuesta
|
||||
retire_options:
|
||||
duplicated: Duplicada
|
||||
started: Ejecutándose
|
||||
unfeasible: Inviable
|
||||
done: Hecha
|
||||
other: Otra
|
||||
form:
|
||||
geozone: "Ámbito de actuación"
|
||||
proposal_external_url: Enlace a documentación adicional
|
||||
@@ -305,6 +319,8 @@ es:
|
||||
recommendation_two: Cualquier propuesta o comentario que implique una acción ilegal será eliminada, también las que tengan la intención de sabotear los espacios de propuesta, todo lo demás está permitido.
|
||||
recommendations_title: Recomendaciones para crear una propuesta
|
||||
start_new: Crear una propuesta
|
||||
notice:
|
||||
retired: Propuesta retirada
|
||||
proposal:
|
||||
already_supported: "¡Ya has apoyado esta propuesta, compártela!"
|
||||
comments:
|
||||
@@ -333,6 +349,8 @@ es:
|
||||
edit_proposal_link: Editar propuesta
|
||||
flag: Esta propuesta ha sido marcada como inapropiada por varios usuarios.
|
||||
login_to_comment: Necesitas %{signin} o %{signup} para comentar.
|
||||
retired_warning: "El autor de esta propuesta considera que ya no debe seguir recogiendo apoyos. Revisa su explicación antes de apoyarla."
|
||||
retired: Propuesta retirada por el autor
|
||||
share: Compartir
|
||||
update:
|
||||
form:
|
||||
@@ -489,6 +507,8 @@ es:
|
||||
other: "%{count} Propuestas de inversión"
|
||||
no_activity: Usuario sin actividad pública
|
||||
private_activity: Este usuario ha decidido mantener en privado su lista de actividades
|
||||
retire: Retirar
|
||||
retired: Retirada
|
||||
votes:
|
||||
agree: Estoy de acuerdo
|
||||
anonymous: Demasiados votos anónimos, para poder votar %{verify_account}.
|
||||
|
||||
@@ -49,6 +49,8 @@ Rails.application.routes.draw do
|
||||
post :vote_featured
|
||||
put :flag
|
||||
put :unflag
|
||||
get :retire_form
|
||||
patch :retire
|
||||
end
|
||||
collection do
|
||||
get :map
|
||||
|
||||
@@ -375,7 +375,7 @@ feature 'Proposals' do
|
||||
end
|
||||
end
|
||||
|
||||
context "Geozones" do
|
||||
context 'Geozones' do
|
||||
|
||||
scenario "Default whole city" do
|
||||
author = create(:user)
|
||||
@@ -430,6 +430,44 @@ feature 'Proposals' do
|
||||
|
||||
end
|
||||
|
||||
context 'Retire a proposal' do
|
||||
scenario 'Retire' do
|
||||
proposal = create(:proposal)
|
||||
login_as(proposal.author)
|
||||
|
||||
visit user_path(proposal.author)
|
||||
within("#proposal_#{proposal.id}") do
|
||||
click_link 'Retire'
|
||||
end
|
||||
expect(current_path).to eq(retire_form_proposal_path(proposal))
|
||||
|
||||
select 'Duplicated', from: 'proposal_retired_reason'
|
||||
fill_in 'proposal_retired_explanation', with: 'There are three other better proposals with the same subject'
|
||||
click_button "Retire proposal"
|
||||
|
||||
expect(page).to have_content "Proposal retired"
|
||||
|
||||
visit proposal_path(proposal)
|
||||
|
||||
expect(page).to have_content proposal.title
|
||||
expect(page).to have_content 'Proposal retired by the author'
|
||||
expect(page).to have_content 'Duplicated'
|
||||
expect(page).to have_content 'There are three other better proposals with the same subject'
|
||||
end
|
||||
|
||||
scenario 'Fields are mandatory' do
|
||||
proposal = create(:proposal)
|
||||
login_as(proposal.author)
|
||||
|
||||
visit retire_form_proposal_path(proposal)
|
||||
|
||||
click_button 'Retire proposal'
|
||||
|
||||
expect(page).to_not have_content 'Proposal retired'
|
||||
expect(page).to have_content "can't be blank", count: 2
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Update should not be posible if logged user is not the author' do
|
||||
proposal = create(:proposal)
|
||||
expect(proposal).to be_editable
|
||||
|
||||
Reference in New Issue
Block a user