diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index caf81b40b..f08d14fda 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -284,10 +284,6 @@ $sidebar-active: #f4fcd0; .proposal-form { padding-top: 0; } - - .proposal-show { - padding-top: rem-calc(54); - } } .is-featured { diff --git a/app/controllers/admin/proposal_milestones_controller.rb b/app/controllers/admin/proposal_milestones_controller.rb new file mode 100644 index 000000000..3dec8463b --- /dev/null +++ b/app/controllers/admin/proposal_milestones_controller.rb @@ -0,0 +1,8 @@ +class Admin::ProposalMilestonesController < Admin::MilestonesController + + private + + def milestoneable + Proposal.find(params[:proposal_id]) + end +end diff --git a/app/controllers/admin/proposals_controller.rb b/app/controllers/admin/proposals_controller.rb new file mode 100644 index 000000000..e76efce21 --- /dev/null +++ b/app/controllers/admin/proposals_controller.rb @@ -0,0 +1,18 @@ +class Admin::ProposalsController < Admin::BaseController + include HasOrders + include CommentableActions + include FeatureFlags + feature_flag :proposals + + has_orders %w[created_at] + + def show + @proposal = Proposal.find(params[:id]) + end + + private + + def resource_model + Proposal + end +end diff --git a/app/models/proposal.rb b/app/models/proposal.rb index fff616626..aa54827c6 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -20,6 +20,7 @@ class Proposal < ActiveRecord::Base accepted_content_types: [ "application/pdf" ] include EmbedVideosHelper include Relationable + include Milestoneable acts_as_votable acts_as_paranoid column: :hidden_at diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 5344c06f8..6e393e805 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -79,6 +79,15 @@ <% end %> + <% if feature?(:proposals) %> +
  • + <%= link_to admin_proposals_path do %> + + <%= t("admin.menu.proposals") %> + <% end %> +
  • + <% end %> + <% messages_sections = %w(newsletters emails_download admin_notifications system_emails) %> <% messages_menu_active = messages_sections.include?(controller_name) %>
  • > diff --git a/app/views/admin/proposals/index.html.erb b/app/views/admin/proposals/index.html.erb new file mode 100644 index 000000000..8a8372713 --- /dev/null +++ b/app/views/admin/proposals/index.html.erb @@ -0,0 +1,39 @@ +<% provide(:title) do %> + <%= t("admin.header.title") %> - <%= t("admin.proposals.index.title") %> +<% end %> + +

    <%= t("admin.proposals.index.title") %>

    + +<% if @proposals.any? %> + <%= render "/admin/shared/proposal_search", url: admin_proposals_path %> + +

    <%= page_entries_info @proposals %>

    + + + + + + + + + + + + + <% @proposals.each do |proposal| %> + + + + + + + <% end %> + +
    <%= t("admin.proposals.index.id") %><%= t("admin.proposals.index.title") %><%= t("admin.proposals.index.author") %><%= t("admin.proposals.index.milestones") %>
    <%= proposal.id %><%= link_to proposal.title, admin_proposal_path(proposal) %><%= proposal.author.username %><%= proposal.milestones.count %>
    + + <%= paginate @proposals %> +<% else %> +
    + <%= t("admin.proposals.index.no_proposals") %> +
    +<% end %> diff --git a/app/views/admin/proposals/show.html.erb b/app/views/admin/proposals/show.html.erb new file mode 100644 index 000000000..762c65592 --- /dev/null +++ b/app/views/admin/proposals/show.html.erb @@ -0,0 +1,11 @@ +<% provide :title do %> + <%= t("admin.header.title") %> - <%= t("admin.menu.proposals") %> - <%= @proposal.title %> +<% end %> + +
    +

    <%= @proposal.title %>

    + + <%= render "proposals/info", proposal: @proposal %> +
    + +<%= render "admin/milestones/milestones", milestoneable: @proposal %> diff --git a/app/views/proposals/_filter_subnav.html.erb b/app/views/proposals/_filter_subnav.html.erb index 47709c8aa..642d21535 100644 --- a/app/views/proposals/_filter_subnav.html.erb +++ b/app/views/proposals/_filter_subnav.html.erb @@ -21,4 +21,12 @@ <% end %>
  • +
  • + <%= link_to "#tab-milestones" do %> +

    + <%= t("proposals.show.milestones_tab") %> + (<%= @proposal.milestones.count %>) +

    + <% end %> +
  • diff --git a/app/views/proposals/_info.html.erb b/app/views/proposals/_info.html.erb new file mode 100644 index 000000000..44d5b76f3 --- /dev/null +++ b/app/views/proposals/_info.html.erb @@ -0,0 +1,84 @@ +
    + <%= render '/shared/author_info', resource: @proposal %> + +  •  + <%= l @proposal.created_at.to_date %> +  •  +   + <%= link_to t("proposals.show.comments", count: @proposal.comments_count), "#comments" %> + + <% if current_user %> +  •  + + <%= render 'proposals/flag_actions', proposal: @proposal %> + + <% end %> + +
    + +<%= render_image(@proposal.image, :large, true) if @proposal.image.present? %> + +
    +

    + <%= t("proposals.show.code") %> + <%= @proposal.code %> +

    + +
    <%= @proposal.summary %>
    + +<% if @proposal.video_url.present? %> +
    +
    +
    +
    +
    +<% end %> + +<%= safe_html_with_links @proposal.description %> + +<% if feature?(:map) && map_location_available?(@proposal.map_location) %> +
    + <%= render_map(@proposal.map_location, "proposal", false, nil) %> +
    +<% end %> + +<% if @proposal.external_url.present? %> + +<% end %> + +<% if @proposal.video_url.present? %> + + +<% end %> + +

    <%= @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 %> + +<% if feature?(:allow_attached_documents) %> + <%= render 'documents/documents', + documents: @proposal.documents, + max_documents_allowed: Proposal.max_documents_allowed %> +<% end %> + +<%= render 'shared/tags', taggable: @proposal %> diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 2c40a7075..cd9ba74f0 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -37,93 +37,8 @@ <% end %> -
    - <%= render '/shared/author_info', resource: @proposal %> - -  •  - <%= l @proposal.created_at.to_date %> -  •  -   - <%= link_to t("proposals.show.comments", count: @proposal.comments_count), "#comments" %> - - <% if current_user %> -  •  - - <%= render 'proposals/flag_actions', proposal: @proposal %> - - <% end %> - -
    - - <%= render_image(@proposal.image, :large, true) if @proposal.image.present? %> - -
    -

    - <%= t("proposals.show.code") %> - <%= @proposal.code %> -

    - -
    <%= @proposal.summary %>
    - - <% if @proposal.video_url.present? %> -
    -
    -
    -
    -
    - <% end %> - - <%= safe_html_with_links @proposal.description %> - - <% if feature?(:map) && map_location_available?(@proposal.map_location) %> -
    - <%= render_map(@proposal.map_location, "proposal", false, nil) %> -
    - <% end %> - - <% if @proposal.external_url.present? %> - - <% end %> - - <% if @proposal.video_url.present? %> - - - <% end %> - -

    <%= @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 %> - - <% if feature?(:allow_attached_documents) %> - <%= render 'documents/documents', - documents: @proposal.documents, - max_documents_allowed: Proposal.max_documents_allowed %> - <% end %> - - <%= render 'shared/tags', taggable: @proposal %> - + <%= render "proposals/info", proposal: @proposal %> <%= render 'shared/geozone', geozonable: @proposal %> - <%= render 'relationable/related_content', relationable: @proposal %>
    @@ -225,4 +140,5 @@
    <%= render "proposals/notifications" %> + <%= render "milestones/milestones", milestoneable: @proposal %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 0fd2a0d56..cd99283ce 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -536,6 +536,7 @@ en: admin: Admin menu banner: Manage banners poll_questions: Questions + proposals: Proposals proposals_topics: Proposals topics budgets: Participatory budgets geozones: Manage geozones @@ -1040,6 +1041,13 @@ en: search: title: Search Organisations no_results: No organizations found. + proposals: + index: + title: Proposals + id: ID + author: Author + milestones: Milestones + no_proposals: There are no proposals. hidden_proposals: index: filter: Filter diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 25136eecb..20f843999 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -437,6 +437,7 @@ en: flag: This proposal has been flagged as inappropriate by several users. login_to_comment: You must %{signin} or %{signup} to leave a comment. notifications_tab: Notifications + milestones_tab: Milestones 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 diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 5798dd0b1..cc0d99b7e 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -532,6 +532,7 @@ es: admin: Menú de administración banner: Gestionar banners poll_questions: Preguntas + proposals: Propuestas proposals_topics: Temas de propuestas budgets: Presupuestos participativos geozones: Gestionar distritos @@ -1036,6 +1037,13 @@ es: search: title: Buscar Organizaciones no_results: No se han encontrado organizaciones. + proposals: + index: + title: Propuestas + id: ID + author: Autor + milestones: Hitos + no_proposals: No hay propuestas. hidden_proposals: index: filter: Filtro diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 8c2212dae..52308497b 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -437,6 +437,7 @@ es: flag: Esta propuesta ha sido marcada como inapropiada por varios usuarios. login_to_comment: Necesitas %{signin} o %{signup} para comentar. notifications_tab: Notificaciones + milestones_tab: Seguimiento 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 diff --git a/config/locales/val/general.yml b/config/locales/val/general.yml index aa35f48d5..bc014d401 100644 --- a/config/locales/val/general.yml +++ b/config/locales/val/general.yml @@ -434,6 +434,7 @@ val: flag: Esta proposta ha sigut marcada com inapropiada per diversos usuaris. login_to_comment: Necessites %{signin} o %{signup} per a comentar. notifications_tab: Notificacions + milestones_tab: Seguiments retired_warning: "L'autor d'esta proposta considera que ja no ha de seguir recollint avals." retired_warning_link_to_explanation: Revisa la seua explicació abans d'avalar-la. retired: Proposta retirada per l'autor diff --git a/config/routes/admin.rb b/config/routes/admin.rb index a6ccf2de3..b37714f47 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -29,6 +29,10 @@ namespace :admin do end end + resources :proposals, only: [:index, :show] do + resources :milestones, controller: "proposal_milestones" + end + resources :hidden_proposals, only: :index do member do put :restore diff --git a/db/dev_seeds/milestones.rb b/db/dev_seeds/milestones.rb index d3e2ced68..41b3f40ab 100644 --- a/db/dev_seeds/milestones.rb +++ b/db/dev_seeds/milestones.rb @@ -6,17 +6,20 @@ section "Creating default Milestone Statuses" do end section "Creating investment milestones" do - Budget::Investment.find_each do |investment| - rand(1..5).times do - milestone = investment.milestones.build( - publication_date: rand(Date.tomorrow..(Date.current + 3.weeks)), - status_id: Milestone::Status.all.sample - ) - I18n.available_locales.map do |locale| - Globalize.with_locale(locale) do - milestone.description = "Description for locale #{locale}" - milestone.title = I18n.l(Time.current, format: :datetime) - milestone.save! + [Budget::Investment, Proposal].each do |model| + model.find_each do |record| + rand(1..5).times do + milestone = record.milestones.build( + publication_date: Date.tomorrow, + status_id: Milestone::Status.all.sample + ) + + I18n.available_locales.map do |locale| + Globalize.with_locale(locale) do + milestone.description = "Description for locale #{locale}" + milestone.title = I18n.l(Time.current, format: :datetime) + milestone.save! + end end end end diff --git a/spec/features/admin/proposals_spec.rb b/spec/features/admin/proposals_spec.rb new file mode 100644 index 000000000..ddad53d9c --- /dev/null +++ b/spec/features/admin/proposals_spec.rb @@ -0,0 +1,39 @@ +require "rails_helper" + +feature "Admin proposals" do + background do + login_as create(:administrator).user + end + + it_behaves_like "admin_milestoneable", + :proposal, + "admin_proposal_path" + + context "Index" do + scenario "Search" do + create(:proposal, title: "Make Pluto a planet again") + create(:proposal, title: "Build a monument to honour CONSUL developers") + + visit admin_root_path + within("#side_menu") { click_link "Proposals" } + + expect(page).to have_content "Make Pluto a planet again" + expect(page).to have_content "Build a monument" + + fill_in "search", with: "Pluto" + click_button "Search" + + expect(page).to have_content "Make Pluto a planet again" + expect(page).not_to have_content "Build a monument" + end + end + + scenario "Show" do + create(:proposal, title: "Create a chaotic future", summary: "Chaos isn't controlled") + + visit admin_proposals_path + click_link "Create a chaotic future" + + expect(page).to have_content "Chaos isn't controlled" + end +end diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index 454a83526..83e4edb9a 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -21,7 +21,7 @@ feature "Admin custom information texts" do click_link 'Community' expect(page).to have_content 'Access the community' - click_link 'Proposals' + within("#information-texts-tabs") { click_link "Proposals" } expect(page).to have_content 'Create proposal' within "#information-texts-tabs" do @@ -49,7 +49,7 @@ feature "Admin custom information texts" do scenario 'check that tabs are highlight when click it' do visit admin_site_customization_information_texts_path - click_link 'Proposals' + within("#information-texts-tabs") { click_link "Proposals" } expect(find("a[href=\"/admin/site_customization/information_texts?tab=proposals\"].is-active")) .to have_content "Proposals" end diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index eb8b5c0de..8beb35549 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -3,6 +3,10 @@ require 'rails_helper' feature 'Proposals' do + it_behaves_like "milestoneable", + :proposal, + "proposal_path" + scenario 'Disabled with a feature flag' do Setting['feature.proposals'] = nil expect{ visit proposals_path }.to raise_exception(FeatureFlags::FeatureDisabled)