From a8bc3095b4864cfe7495201a7eaf505ee6728ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Wed, 20 Apr 2016 13:14:55 +0200 Subject: [PATCH 1/9] improves activity styles --- app/assets/stylesheets/layout.scss | 11 ++++++++--- app/views/users/_spending_proposals.html.erb | 7 ++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 24a433285..fdaf2dd30 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1743,19 +1743,24 @@ table { } } - &.activity-comments td:before { + &.activity-comments td:first-child:before { content: "e"; top: 18px; } - &.activity-debates td:before { + &.activity-debates td:first-child:before { content: "i"; top: 14px; } - &.activity-proposals td:before { + &.activity-proposals td:first-child:before { content: "h"; top: 18px; } + + &.activity-investment-projects td:first-child:before { + content: "\53"; + top: 10px; + } } } diff --git a/app/views/users/_spending_proposals.html.erb b/app/views/users/_spending_proposals.html.erb index 04bfa7867..40fd8d70d 100644 --- a/app/views/users/_spending_proposals.html.erb +++ b/app/views/users/_spending_proposals.html.erb @@ -1,15 +1,16 @@ - +
<% @spending_proposals.each do |spending_proposal| %> + From 69d2c14b4920bc72397d6db4062c7ba9442d79f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Wed, 20 Apr 2016 13:28:12 +0200 Subject: [PATCH 2/9] adds retired_at to proposals --- db/migrate/20160420105023_add_retired_to_proposals.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160420105023_add_retired_to_proposals.rb diff --git a/db/migrate/20160420105023_add_retired_to_proposals.rb b/db/migrate/20160420105023_add_retired_to_proposals.rb new file mode 100644 index 000000000..f818a9169 --- /dev/null +++ b/db/migrate/20160420105023_add_retired_to_proposals.rb @@ -0,0 +1,5 @@ +class AddRetiredToProposals < ActiveRecord::Migration + def change + add_column :proposals, :retired_at, :datetime, default: nil + end +end diff --git a/db/schema.rb b/db/schema.rb index 49f0011f2..aee822784 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160418172919) do +ActiveRecord::Schema.define(version: 20160420105023) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -260,6 +260,7 @@ ActiveRecord::Schema.define(version: 20160418172919) do t.integer "physical_votes", default: 0 t.tsvector "tsv" t.integer "geozone_id" + t.datetime "retired_at" end add_index "proposals", ["author_id", "hidden_at"], name: "index_proposals_on_author_id_and_hidden_at", using: :btree From f36f0ca8c8d34c946b5cf2ad9e6202f94d2ffa24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Wed, 20 Apr 2016 13:51:53 +0200 Subject: [PATCH 3/9] adds scope & boolean method for retired proposals --- app/models/proposal.rb | 5 +++++ spec/models/proposal_spec.rb | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/app/models/proposal.rb b/app/models/proposal.rb index f437fa134..c6c7e6398 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -42,6 +42,7 @@ class Proposal < ActiveRecord::Base scope :sort_by_relevance, -> { all } scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)} + scope :retired, -> { where.not(retired_at: nil) } def to_param "#{id}-#{title}".parameterize @@ -105,6 +106,10 @@ class Proposal < ActiveRecord::Base user && user.level_two_or_three_verified? end + def retired? + retired_at.present? + end + def register_vote(user, vote_value) if votable_by?(user) vote_by(voter: user, vote: vote_value) diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb index eae4d4fbd..dddab0fbc 100644 --- a/spec/models/proposal_spec.rb +++ b/spec/models/proposal_spec.rb @@ -741,4 +741,23 @@ describe Proposal do end end + describe "retired" do + before(:all) do + @proposal1 = create(:proposal) + @proposal2 = create(:proposal, retired_at: Time.now) + end + + it "retired? is true" do + expect(@proposal1.retired?).to eq false + expect(@proposal2.retired?).to eq true + end + + it "scope retired" do + retired = Proposal.retired + + expect(retired.size).to eq(1) + expect(retired.first).to eq(@proposal2) + end + end + end From be011a10dc8a2b5817a079b342300162779d5069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 22 Apr 2016 11:49:20 +0200 Subject: [PATCH 4/9] adds retired reason & explanation to proposals --- ...22094733_add_retired_texts_to_proposals.rb | 6 +++++ db/schema.rb | 24 ++++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 db/migrate/20160422094733_add_retired_texts_to_proposals.rb diff --git a/db/migrate/20160422094733_add_retired_texts_to_proposals.rb b/db/migrate/20160422094733_add_retired_texts_to_proposals.rb new file mode 100644 index 000000000..3c044477d --- /dev/null +++ b/db/migrate/20160422094733_add_retired_texts_to_proposals.rb @@ -0,0 +1,6 @@ +class AddRetiredTextsToProposals < ActiveRecord::Migration + def change + add_column :proposals, :retired_reason, :string, default: nil + add_column :proposals, :retired_explanation, :text, default: nil + end +end diff --git a/db/schema.rb b/db/schema.rb index aee822784..7e83ab7cc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160420105023) do +ActiveRecord::Schema.define(version: 20160422094733) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -239,28 +239,30 @@ ActiveRecord::Schema.define(version: 20160420105023) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree create_table "proposals", force: :cascade do |t| - t.string "title", limit: 80 + t.string "title", limit: 80 t.text "description" t.string "question" t.string "external_url" t.integer "author_id" t.datetime "hidden_at" - t.integer "flags_count", default: 0 + t.integer "flags_count", default: 0 t.datetime "ignored_flag_at" - t.integer "cached_votes_up", default: 0 - t.integer "comments_count", default: 0 + t.integer "cached_votes_up", default: 0 + t.integer "comments_count", default: 0 t.datetime "confirmed_hide_at" - t.integer "hot_score", limit: 8, default: 0 - t.integer "confidence_score", default: 0 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "responsible_name", limit: 60 + t.integer "hot_score", limit: 8, default: 0 + t.integer "confidence_score", default: 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "responsible_name", limit: 60 t.text "summary" t.string "video_url" - t.integer "physical_votes", default: 0 + t.integer "physical_votes", default: 0 t.tsvector "tsv" t.integer "geozone_id" t.datetime "retired_at" + t.string "retired_reason" + t.text "retired_explanation" end add_index "proposals", ["author_id", "hidden_at"], name: "index_proposals_on_author_id_and_hidden_at", using: :btree From 58a5e2a283733817228baf514de21f55ec35faae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 22 Apr 2016 14:42:49 +0200 Subject: [PATCH 5/9] authors can retire proposals now --- app/controllers/proposals_controller.rb | 21 +++++++++ app/helpers/proposals_helper.rb | 4 ++ app/models/abilities/common.rb | 1 + app/models/proposal.rb | 3 ++ app/views/proposals/retire_form.html.erb | 37 ++++++++++++++++ app/views/proposals/show.html.erb | 11 ++++- app/views/users/_proposals.html.erb | 11 ++++- config/locales/en.yml | 20 +++++++++ config/locales/es.yml | 20 +++++++++ config/routes.rb | 2 + spec/features/proposals_spec.rb | 54 ++++++++++++++++++++---- 11 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 app/views/proposals/retire_form.html.erb diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index add59a7cb..cbf2af121 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -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 diff --git a/app/helpers/proposals_helper.rb b/app/helpers/proposals_helper.rb index f01abc053..9eaa88549 100644 --- a/app/helpers/proposals_helper.rb +++ b/app/helpers/proposals_helper.rb @@ -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 \ No newline at end of file diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 5bb43725b..6dd36d5b0 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -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 diff --git a/app/models/proposal.rb b/app/models/proposal.rb index c6c7e6398..be08b5654 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -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 diff --git a/app/views/proposals/retire_form.html.erb b/app/views/proposals/retire_form.html.erb new file mode 100644 index 000000000..293e523bb --- /dev/null +++ b/app/views/proposals/retire_form.html.erb @@ -0,0 +1,37 @@ +
+ +
+ +
+ <%= link_to @proposal.title, @proposal %> +
+ +

<%= t("proposals.retire_form.title") %>

+ +
+ <%= t("proposals.retire_form.warning") %> +
+ + <%= form_for(@proposal, url: retire_proposal_path(@proposal)) do |f| %> + <%= render 'shared/errors', resource: @proposal %> +
+ +
+ <%= 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} %> +
+ +
+ <%= 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') %> +
+ +
+ <%= f.submit(class: "button", value: t("proposals.retire_form.submit_button")) %> +
+
+ <% end %> + +
+
\ No newline at end of file diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 0a5b35c0c..7d1c23e59 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -22,7 +22,11 @@ <% end %>

<%= @proposal.title %>

- <% if @proposal.conflictive? %> + <% if @proposal.retired? %> +
+ <%= t("proposals.show.retired_warning") %> +
+ <% elsif @proposal.conflictive? %>
<%= t("proposals.show.flag") %>
@@ -74,6 +78,11 @@

<%= @proposal.question %>

+ <% if @proposal.retired? %> +

<%= t('proposals.show.retired') %>: <%= t("proposals.retire_options.#{@proposal.retired_reason}") unless @proposal.retired_reason == 'other' %>

+ <%= simple_format text_with_links(@proposal.retired_explanation), {}, sanitize: false %> + <% end %> + <%= render 'shared/tags', taggable: @proposal %> <%= render 'shared/geozone', geozonable: @proposal %> diff --git a/app/views/users/_proposals.html.erb b/app/views/users/_proposals.html.erb index a8ec5061e..c3aa55ed1 100644 --- a/app/views/users/_proposals.html.erb +++ b/app/views/users/_proposals.html.erb @@ -2,10 +2,19 @@ <% @proposals.each do |proposal| %>
+ <% end %>
<%= link_to spending_proposal.title, spending_proposal %> - + <% if can?(:destroy, spending_proposal) %> <%= link_to t("users.show.delete_spending_proposal"), spending_proposal, method: :delete, data: { confirm: t("users.show.confirm_deletion_spending_proposal") }, - class: 'button small warning' %> + class: 'delete' %> <% end %>
- <%= link_to proposal.title, proposal %> + <%= link_to proposal.title, proposal, proposal.retired? ? {class: 'delete'} : {} %>
<%= proposal.summary %>
+ <% if proposal.retired? %> + <%= t('users.show.retired') %> + <% else %> + <%= link_to t('users.show.retire'), + retire_form_proposal_path(proposal), + class: 'delete' %> + <% end %> +
diff --git a/config/locales/en.yml b/config/locales/en.yml index 27d375496..0df604469 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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}. diff --git a/config/locales/es.yml b/config/locales/es.yml index 26e10874c..c67136e9e 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -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}. diff --git a/config/routes.rb b/config/routes.rb index dd4281788..aaa37cdb5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index bde574935..adcaf486c 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -88,27 +88,27 @@ feature 'Proposals' do end context "Embedded video" do - scenario "Show YouTube video" do + scenario "Show YouTube video" do proposal = create(:proposal, video_url: "http://www.youtube.com/watch?v=a7UFm6ErMPU") visit proposal_path(proposal) expect(page).to have_selector("div[id='js-embedded-video']") expect(page.html).to include 'https://www.youtube.com/embed/a7UFm6ErMPU' end - - scenario "Show Vimeo video" do + + scenario "Show Vimeo video" do proposal = create(:proposal, video_url: "https://vimeo.com/7232823" ) visit proposal_path(proposal) expect(page).to have_selector("div[id='js-embedded-video']") expect(page.html).to include 'https://player.vimeo.com/video/7232823' end - - scenario "Dont show video" do + + scenario "Dont show video" do proposal = create(:proposal, video_url: nil) visit proposal_path(proposal) expect(page).to_not have_selector("div[id='js-embedded-video']") - end - end + end + end scenario 'Social Media Cards' do proposal = create(:proposal) @@ -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 From d63cf8b392419bb85860535956089437a8c65c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 22 Apr 2016 15:30:55 +0200 Subject: [PATCH 6/9] removes retired proposals from default index adds a sidebar link to retired proposals list --- app/controllers/proposals_controller.rb | 8 ++++++- app/models/proposal.rb | 1 + app/views/proposals/_retired.html.erb | 6 +++++ app/views/proposals/index.html.erb | 3 +++ config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ spec/features/proposals_spec.rb | 30 ++++++++++++++++++++++++- spec/models/proposal_spec.rb | 7 ++++++ 8 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 app/views/proposals/_retired.html.erb diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index cbf2af121..e91d20de9 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -23,7 +23,13 @@ class ProposalsController < ApplicationController end def index_customization - @featured_proposals = Proposal.all.sort_by_confidence_score.limit(3) if (!@advanced_search_terms && @search_terms.blank? && @tag_filter.blank?) + if params[:retired].present? + @resources = @resources.retired + else + @resources = @resources.not_retired + end + + @featured_proposals = Proposal.all.sort_by_confidence_score.limit(3) if (!@advanced_search_terms && @search_terms.blank? && @tag_filter.blank? && params[:retired].blank?) if @featured_proposals.present? set_featured_proposal_votes(@featured_proposals) @resources = @resources.where('proposals.id NOT IN (?)', @featured_proposals.map(&:id)) diff --git a/app/models/proposal.rb b/app/models/proposal.rb index be08b5654..e6071e052 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -46,6 +46,7 @@ class Proposal < ActiveRecord::Base scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)} scope :retired, -> { where.not(retired_at: nil) } + scope :not_retired, -> { where(retired_at: nil) } def to_param "#{id}-#{title}".parameterize diff --git a/app/views/proposals/_retired.html.erb b/app/views/proposals/_retired.html.erb new file mode 100644 index 000000000..73d8a7844 --- /dev/null +++ b/app/views/proposals/_retired.html.erb @@ -0,0 +1,6 @@ + + + +

+ <%= link_to t("proposals.index.retired_proposals_link"), proposals_path(retired: 1), class: "small" %>
+

diff --git a/app/views/proposals/index.html.erb b/app/views/proposals/index.html.erb index 970e1cb3e..065553cce 100644 --- a/app/views/proposals/index.html.erb +++ b/app/views/proposals/index.html.erb @@ -22,6 +22,8 @@ <%= page_entries_info @proposals %> <%= t("proposals.index.filter_topic", count: @proposals.size, topic: @tag_filter) %> + <% elsif params[:retired].present? %> +

<%= t("proposals.index.retired_proposals") %> <% end %> @@ -57,6 +59,7 @@ <%= render 'categories' %> <%= render 'geozones' %> <%= render 'popular' %> + <%= render 'retired' %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 0df604469..a79ceaca6 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -296,6 +296,8 @@ en: hot_score: most active most_commented: most commented relevance: relevance + retired_proposals: Retired proposals + retired_proposals_link: "Proposals retired by the author (duplicated, unfeasibles, done, etc.)" search_form: button: Search placeholder: Search proposals... diff --git a/config/locales/es.yml b/config/locales/es.yml index c67136e9e..38da0cb2c 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -296,6 +296,8 @@ es: hot_score: Más activas hoy most_commented: Más comentadas relevance: Más relevantes + retired_proposals: Propuestas retiradas + retired_proposals_link: "Propuestas retiradas por sus autores (realizadas, en ejecución, inviables, duplicadas, etc.)" search_form: button: Buscar placeholder: Buscar propuestas... diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index adcaf486c..d770f9d9a 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -430,7 +430,7 @@ feature 'Proposals' do end - context 'Retire a proposal' do + context 'Retired proposals' do scenario 'Retire' do proposal = create(:proposal) login_as(proposal.author) @@ -466,6 +466,34 @@ feature 'Proposals' do expect(page).to_not have_content 'Proposal retired' expect(page).to have_content "can't be blank", count: 2 end + + scenario 'Index do not list retired proposals by default' do + create_featured_proposals + not_retired = create(:proposal) + retired = create(:proposal, retired_at: Time.now) + + visit proposals_path + + expect(page).to have_selector('#proposals .proposal', count: 1) + within('#proposals') do + expect(page).to have_content not_retired.title + expect(page).to_not have_content retired.title + end + end + + scenario 'Index has a link to retired proposals list' do + create_featured_proposals + not_retired = create(:proposal) + retired = create(:proposal, retired_at: Time.now) + + visit proposals_path + + expect(page).to_not have_content retired.title + click_link 'Proposals retired by the author (duplicated, unfeasibles, done, etc.)' + + expect(page).to have_content retired.title + expect(page).to_not have_content not_retired.title + end end scenario 'Update should not be posible if logged user is not the author' do diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb index dddab0fbc..4958204ec 100644 --- a/spec/models/proposal_spec.rb +++ b/spec/models/proposal_spec.rb @@ -758,6 +758,13 @@ describe Proposal do expect(retired.size).to eq(1) expect(retired.first).to eq(@proposal2) end + + it "scope not_retired" do + not_retired = Proposal.not_retired + + expect(not_retired.size).to eq(1) + expect(not_retired.first).to eq(@proposal1) + end end end From ed0a4a85252c6e19a1a66ee55f93c29424cd9416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 22 Apr 2016 17:51:11 +0200 Subject: [PATCH 7/9] adds links to filter retired proposals by reason --- app/controllers/proposals_controller.rb | 1 + app/views/proposals/_retired.html.erb | 9 +++++++- app/views/proposals/index.html.erb | 14 +++++++----- config/locales/en.yml | 9 +++++++- config/locales/es.yml | 9 +++++++- spec/features/proposals_spec.rb | 30 ++++++++++++++++++++++++- 6 files changed, 62 insertions(+), 10 deletions(-) diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index e91d20de9..f778b2ca0 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -25,6 +25,7 @@ class ProposalsController < ApplicationController def index_customization if params[:retired].present? @resources = @resources.retired + @resources = @resources.where(retired_reason: params[:retired]) if Proposal::RETIRE_OPTIONS.include?(params[:retired]) else @resources = @resources.not_retired end diff --git a/app/views/proposals/_retired.html.erb b/app/views/proposals/_retired.html.erb index 73d8a7844..ddf1dc36d 100644 --- a/app/views/proposals/_retired.html.erb +++ b/app/views/proposals/_retired.html.erb @@ -2,5 +2,12 @@

- <%= link_to t("proposals.index.retired_proposals_link"), proposals_path(retired: 1), class: "small" %>
+<% if params[:retired].blank? %> + <%= link_to t("proposals.index.retired_proposals_link"), proposals_path(retired: 'all'), class: "small" %>
+<% else %> + <%= link_to t("proposals.index.retired_links.all"), proposals_path(retired: 'all'), ({class: "small"} unless params[:retired] == 'all') %>
+ <% Proposal::RETIRE_OPTIONS.each do |option| %> + <%= link_to t("proposals.index.retired_links.#{option}"), proposals_path(retired: option), ({class: "small"} unless params[:retired] == option) %>
+ <% end %> +<% end %>

diff --git a/app/views/proposals/index.html.erb b/app/views/proposals/index.html.erb index 065553cce..67ee98f67 100644 --- a/app/views/proposals/index.html.erb +++ b/app/views/proposals/index.html.erb @@ -40,7 +40,7 @@ <% end %> - <%= render "shared/advanced_search", search_path: proposals_path(page: 1)%> + <%= render("shared/advanced_search", search_path: proposals_path(page: 1)) unless params[:retired].present? %> <%= render 'shared/order_links', i18n_namespace: "proposals.index" %> @@ -55,11 +55,13 @@
diff --git a/config/locales/en.yml b/config/locales/en.yml index a79ceaca6..d797bef40 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -297,7 +297,14 @@ en: most_commented: most commented relevance: relevance retired_proposals: Retired proposals - retired_proposals_link: "Proposals retired by the author (duplicated, unfeasibles, done, etc.)" + retired_proposals_link: "Proposals retired by the author" + retired_links: + all: All + duplicated: Duplicated + started: Underway + unfeasible: Unfeasible + done: Done + other: Other search_form: button: Search placeholder: Search proposals... diff --git a/config/locales/es.yml b/config/locales/es.yml index 38da0cb2c..16982ed6c 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -297,7 +297,14 @@ es: most_commented: Más comentadas relevance: Más relevantes retired_proposals: Propuestas retiradas - retired_proposals_link: "Propuestas retiradas por sus autores (realizadas, en ejecución, inviables, duplicadas, etc.)" + retired_proposals_link: "Propuestas retiradas por sus autores" + retired_links: + all: Todas + duplicated: Duplicadas + started: Empezadas + unfeasible: Inviables + done: Hechas + other: Otras search_form: button: Buscar placeholder: Buscar propuestas... diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index d770f9d9a..4a3ea58a1 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -489,11 +489,39 @@ feature 'Proposals' do visit proposals_path expect(page).to_not have_content retired.title - click_link 'Proposals retired by the author (duplicated, unfeasibles, done, etc.)' + click_link 'Proposals retired by the author' expect(page).to have_content retired.title expect(page).to_not have_content not_retired.title end + + scenario 'Retired proposals index interface elements' do + visit proposals_path(retired: 'all') + + expect(page).to_not have_content 'Advanced search' + expect(page).to_not have_content 'Categories' + expect(page).to_not have_content 'Districts' + end + + scenario 'Retired proposals index has links to filter by retired_reason' do + unfeasible = create(:proposal, retired_at: Time.now, retired_reason: 'unfeasible') + duplicated = create(:proposal, retired_at: Time.now, retired_reason: 'duplicated') + + visit proposals_path(retired: 'all') + + expect(page).to have_content unfeasible.title + expect(page).to have_content duplicated.title + expect(page).to have_link 'Duplicated' + expect(page).to have_link 'Underway' + expect(page).to have_link 'Unfeasible' + expect(page).to have_link 'Done' + expect(page).to have_link 'Other' + + click_link 'Unfeasible' + + expect(page).to have_content unfeasible.title + expect(page).to_not have_content duplicated.title + end end scenario 'Update should not be posible if logged user is not the author' do From 5b4a7b8cf83d4286767a84f481e24dc54a419b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Fri, 22 Apr 2016 17:58:23 +0200 Subject: [PATCH 8/9] adds link to explanation --- app/views/proposals/show.html.erb | 3 ++- config/locales/en.yml | 3 ++- config/locales/es.yml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 7d1c23e59..8fc01b7b4 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -24,7 +24,7 @@

<%= @proposal.title %>

<% if @proposal.retired? %>
- <%= t("proposals.show.retired_warning") %> + <%= t("proposals.show.retired_warning") %> <%= link_to t("proposals.show.retired_warning_link_to_explanation"), "#retired_explanation" %>
<% elsif @proposal.conflictive? %>
@@ -79,6 +79,7 @@

<%= @proposal.question %>

<% if @proposal.retired? %> +

<%= t('proposals.show.retired') %>: <%= t("proposals.retire_options.#{@proposal.retired_reason}") unless @proposal.retired_reason == 'other' %>

<%= simple_format text_with_links(@proposal.retired_explanation), {}, sanitize: false %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d797bef40..8d9b23541 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -358,7 +358,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_warning: "The author considers this proposal should not receive more supports." + retired_warning_link_to_explanation: Read the explanation before voting for it. retired: Proposal retired by the author share: Share update: diff --git a/config/locales/es.yml b/config/locales/es.yml index 16982ed6c..93e685326 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -358,7 +358,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_warning: "El autor de esta propuesta considera que ya no debe seguir recogiendo apoyos." + retired_warning_link_to_explanation: Revisa su explicación antes de apoyarla. retired: Propuesta retirada por el autor share: Compartir update: From f079bdac8a00a6c608d3c239e8b1496afaf42df2 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Sat, 23 Apr 2016 00:40:28 +0200 Subject: [PATCH 9/9] Improves styles for retire proposals --- app/assets/stylesheets/layout.scss | 22 ++++++++++++++++------ app/assets/stylesheets/participation.scss | 4 ++++ app/views/proposals/_retired.html.erb | 14 +++++++------- app/views/proposals/retire_form.html.erb | 21 +++++++++++---------- app/views/proposals/show.html.erb | 14 +++++++++----- app/views/users/_proposals.html.erb | 6 +++--- 6 files changed, 50 insertions(+), 31 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index fdaf2dd30..2040a02ce 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -545,7 +545,7 @@ footer { // 04. Tags // - - - - - - - - - - - - - - - - - - - - - - - - - -.tags a , .tag-cloud a, .categories a, .geozone a { +.tags a , .tag-cloud a, .categories a, .geozone a, .sidebar-links a { background: #ececec; border-radius: rem-calc(6); color: $text; @@ -1730,9 +1730,12 @@ table { border: 0; td { - padding-left: $line-height*1.5; position: relative; - word-break: break-all; + + &:first-child { + padding-left: $line-height*1.5; + width: 80%; + } &:before { color: $brand; @@ -1753,9 +1756,16 @@ table { top: 14px; } - &.activity-proposals td:first-child:before { - content: "h"; - top: 18px; + &.activity-proposals { + + td:first-child:before { + content: "h"; + top: 18px; + } + + .retired { + text-decoration: line-through; + } } &.activity-investment-projects td:first-child:before { diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 8ede20c2b..7ceaf7b99 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -343,6 +343,10 @@ word-wrap: break-word; } + .callout.proposal-retired { + font-size: $base-font-size; + } + .social-share-full .social-share-button { display:inline; } diff --git a/app/views/proposals/_retired.html.erb b/app/views/proposals/_retired.html.erb index ddf1dc36d..4ab1aba98 100644 --- a/app/views/proposals/_retired.html.erb +++ b/app/views/proposals/_retired.html.erb @@ -1,13 +1,13 @@ -

<% if params[:retired].blank? %> - <%= link_to t("proposals.index.retired_proposals_link"), proposals_path(retired: 'all'), class: "small" %>
+

<%= link_to t("proposals.index.retired_proposals_link"), proposals_path(retired: 'all'), class: "small" %>

<% else %> - <%= link_to t("proposals.index.retired_links.all"), proposals_path(retired: 'all'), ({class: "small"} unless params[:retired] == 'all') %>
- <% Proposal::RETIRE_OPTIONS.each do |option| %> - <%= link_to t("proposals.index.retired_links.#{option}"), proposals_path(retired: option), ({class: "small"} unless params[:retired] == option) %>
- <% end %> + <% end %> -

diff --git a/app/views/proposals/retire_form.html.erb b/app/views/proposals/retire_form.html.erb index 293e523bb..d56277cb3 100644 --- a/app/views/proposals/retire_form.html.erb +++ b/app/views/proposals/retire_form.html.erb @@ -2,33 +2,34 @@
-
- <%= link_to @proposal.title, @proposal %> -
+

<%= t("proposals.retire_form.title") %>

-

<%= t("proposals.retire_form.title") %>

+

<%= link_to @proposal.title, @proposal %>

-
+
<%= t("proposals.retire_form.warning") %>
<%= form_for(@proposal, url: retire_proposal_path(@proposal)) do |f| %> <%= render 'shared/errors', resource: @proposal %>
- -
+
<%= 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} %>
+
-
+
+
<%= 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') %>
+
-
- <%= f.submit(class: "button", value: t("proposals.retire_form.submit_button")) %> +
+
+ <%= f.submit(class: "button expanded", value: t("proposals.retire_form.submit_button")) %>
<% end %> diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 8fc01b7b4..c319c1409 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -23,8 +23,11 @@

<%= @proposal.title %>

<% if @proposal.retired? %> -
- <%= t("proposals.show.retired_warning") %> <%= link_to t("proposals.show.retired_warning_link_to_explanation"), "#retired_explanation" %> +
+ + <%= t("proposals.show.retired_warning") %>
+ <%= link_to t("proposals.show.retired_warning_link_to_explanation"), "#retired_explanation" %> +
<% elsif @proposal.conflictive? %>
@@ -79,9 +82,10 @@

<%= @proposal.question %>

<% if @proposal.retired? %> - -

<%= t('proposals.show.retired') %>: <%= t("proposals.retire_options.#{@proposal.retired_reason}") unless @proposal.retired_reason == 'other' %>

- <%= simple_format text_with_links(@proposal.retired_explanation), {}, sanitize: false %> +
+

<%= t('proposals.show.retired') %>: <%= t("proposals.retire_options.#{@proposal.retired_reason}") unless @proposal.retired_reason == 'other' %>

+ <%= simple_format text_with_links(@proposal.retired_explanation), {}, sanitize: false %> +
<% end %> <%= render 'shared/tags', taggable: @proposal %> diff --git a/app/views/users/_proposals.html.erb b/app/views/users/_proposals.html.erb index c3aa55ed1..9ec1368bd 100644 --- a/app/views/users/_proposals.html.erb +++ b/app/views/users/_proposals.html.erb @@ -2,13 +2,13 @@ <% @proposals.each do |proposal| %> - <%= link_to proposal.title, proposal, proposal.retired? ? {class: 'delete'} : {} %> + <%= link_to proposal.title, proposal, proposal.retired? ? {class: 'retired'} : {} %>
<%= proposal.summary %> - + <% if proposal.retired? %> - <%= t('users.show.retired') %> + <%= t('users.show.retired') %> <% else %> <%= link_to t('users.show.retire'), retire_form_proposal_path(proposal),