From db9ac79e05f730e54feead26ddc9e47fceef0e6c Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Mon, 16 Mar 2020 12:54:00 +0100 Subject: [PATCH] Add main link to each phase of the budget Co-authored-by: decabeza --- app/assets/stylesheets/budgets/phases.scss | 5 ++++ .../budget_phases/form_component.html.erb | 10 ++++++++ .../budgets/phases_component.html.erb | 4 ++++ .../concerns/admin/budget_phases_actions.rb | 3 ++- app/models/budget/phase.rb | 2 ++ config/locales/en/activerecord.yml | 2 ++ config/locales/en/admin.yml | 3 +++ config/locales/es/activerecord.yml | 2 ++ config/locales/es/admin.yml | 3 +++ ...09112812_add_main_link_to_budget_phases.rb | 6 +++++ db/schema.rb | 2 ++ .../budgets/phases_component_spec.rb | 17 ++++++++++++++ spec/models/budget/phase_spec.rb | 23 +++++++++++++++++++ spec/models/concerns/globalizable.rb | 2 +- spec/system/admin/budget_phases_spec.rb | 16 +++++++++++++ spec/system/admin/translatable_spec.rb | 1 + 16 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20200309112812_add_main_link_to_budget_phases.rb create mode 100644 spec/components/budgets/phases_component_spec.rb diff --git a/app/assets/stylesheets/budgets/phases.scss b/app/assets/stylesheets/budgets/phases.scss index 93b27f496..9fee6e5d3 100644 --- a/app/assets/stylesheets/budgets/phases.scss +++ b/app/assets/stylesheets/budgets/phases.scss @@ -191,5 +191,10 @@ text-align: center; } } + + .main-link { + @include regular-button; + font-size: 1.1rem; + } } } diff --git a/app/components/admin/budget_phases/form_component.html.erb b/app/components/admin/budget_phases/form_component.html.erb index b0e8a3af1..e8e0822c0 100644 --- a/app/components/admin/budget_phases/form_component.html.erb +++ b/app/components/admin/budget_phases/form_component.html.erb @@ -41,8 +41,18 @@ class: "html-area", hint: t("admin.budget_phases.edit.description_help_text") %> + +
+

<%= t("admin.budget_phases.edit.main_call_to_action") %>

+

<%= t("admin.budget_phases.edit.main_call_to_action_description") %>

+ <%= translations_form.text_field :main_link_text %> +
<% end %> +
+ <%= f.text_field :main_link_url, placeholder: t("admin.shared.example_url") %> +
+ <% if feature?(:allow_images) %>
<%= render "images/nested_image", imageable: @phase, f: f %> diff --git a/app/components/budgets/phases_component.html.erb b/app/components/budgets/phases_component.html.erb index ee58ae171..6e4b66bf0 100644 --- a/app/components/budgets/phases_component.html.erb +++ b/app/components/budgets/phases_component.html.erb @@ -47,6 +47,10 @@

<%= phase.name %>

<%= start_date(phase) %> - <%= end_date(phase) %>

<%= auto_link_already_sanitized_html(wysiwyg(phase.description)) %> + + <% if phase.main_link_text.present? && phase.main_link_url.present? %> + <%= link_to phase.main_link_text, phase.main_link_url, class: "main-link" %> + <% end %>
<% if phase.image.present? %> diff --git a/app/controllers/concerns/admin/budget_phases_actions.rb b/app/controllers/concerns/admin/budget_phases_actions.rb index 5d09ddee3..6d0434416 100644 --- a/app/controllers/concerns/admin/budget_phases_actions.rb +++ b/app/controllers/concerns/admin/budget_phases_actions.rb @@ -31,7 +31,8 @@ module Admin::BudgetPhasesActions end def budget_phase_params - valid_attributes = [:starts_at, :ends_at, :enabled, image_attributes: image_attributes] + valid_attributes = [:starts_at, :ends_at, :enabled, :main_link_url, + image_attributes: image_attributes] params.require(:budget_phase).permit(*valid_attributes, translation_params(Budget::Phase)) end end diff --git a/app/models/budget/phase.rb b/app/models/budget/phase.rb index 291386715..b6d4c64c5 100644 --- a/app/models/budget/phase.rb +++ b/app/models/budget/phase.rb @@ -8,6 +8,7 @@ class Budget translates :name, touch: true translates :summary, touch: true translates :description, touch: true + translates :main_link_text, touch: true include Globalizable include Sanitizable include Imageable @@ -20,6 +21,7 @@ class Budget validates_translation :description, length: { maximum: DESCRIPTION_MAX_LENGTH } validates :budget, presence: true validates :kind, presence: true, uniqueness: { scope: :budget }, inclusion: { in: ->(*) { PHASE_KINDS }} + validates :main_link_url, presence: true, if: -> { main_link_text.present? } validate :invalid_dates_range? validate :prev_phase_dates_valid? validate :next_phase_dates_valid? diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index cb49d44dd..5539f91b0 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -231,10 +231,12 @@ en: enabled: "Phase enabled" ends_at: "End date" starts_at: "Start date" + main_link_url: "The link takes you to (add a link)" budget/phase/translation: name: "Name" description: "Description" summary: "Summary" + main_link_text: "Text on the link" comment: body: "Comment" user: "User" diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 179f02192..b6d1329b3 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -201,6 +201,8 @@ en: duration_description: "The period of time this phase will be active." enabled_help_text: This phase will be public in the budget's phases timeline, as well as active for any other purpose image_description: "If an image is uplodaded it will be displayed next to the description of this phase." + main_call_to_action: "Main call to action (optional)" + main_call_to_action_description: "This link will appear on main banner of this participatory budget when this phase is enabled and encourages your user to perform a specific action like creating a proposal, voting for existing ones, or learn more about the process." name_help_text: "This is the title of the phase users will read on the header whenever this phase is active." save_changes: Save changes index: @@ -1352,6 +1354,7 @@ en: content: Content created_at: Created at color_help: Hexadecimal format + example_url: "https://consulproject.org" show_results_and_stats: "Show results and stats" results_and_stats_reminder: "Marking these checkboxes the results and/or stats will be publicly available and every user will see them." example_url: "https://consulproject.org" diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index 775cff009..d37a8a155 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -231,10 +231,12 @@ es: enabled: "Fase habilitada" ends_at: "Fecha de fin" starts_at: "Fecha de inicio" + main_link_url: "El enlace te lleva a (añade un enlace)" budget/phase/translation: name: "Nombre" description: "Descripción" summary: "Resumen" + main_link_text: "Texto del enlace" comment: body: "Comentario" user: "Usuario" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 6209bc245..a5d7fe170 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -200,6 +200,8 @@ es: duration_description: "El período de tiempo que esta fase estará activa." enabled_help_text: Esta fase será pública en el calendario de fases del presupuesto y estará activa para otros propósitos image_description: "Si se proporciona una imagen se mostrará junto a la descripción de esta fase." + main_call_to_action: "Enlace de acción principal (opcional)" + main_call_to_action_description: "Este enlace aparecerá en la cabecera de este presupuesto participativo cuando esta fase esté activa y permite al usuario ejecutar una acción específica como crear una nueva propuesta, votar las existentes, o leer más sobre el funcionamiento de los presupuestos participativos." name_help_text: "Este es el título de la fase que los usuarios leerán en el encabezado cuando la fase esté activa." save_changes: Guardar cambios title: "Editar fase" @@ -1351,6 +1353,7 @@ es: content: Contenido created_at: Fecha de creación color_help: Formato hexadecimal + example_url: "https://consulproject.org" show_results_and_stats: "Mostrar resultados y estadísticas" results_and_stats_reminder: "Si marcas estas casillas los resultados y/o estadísticas serán públicos y podrán verlos todos los usuarios." example_url: "https://consulproject.org" diff --git a/db/migrate/20200309112812_add_main_link_to_budget_phases.rb b/db/migrate/20200309112812_add_main_link_to_budget_phases.rb new file mode 100644 index 000000000..6813111b4 --- /dev/null +++ b/db/migrate/20200309112812_add_main_link_to_budget_phases.rb @@ -0,0 +1,6 @@ +class AddMainLinkToBudgetPhases < ActiveRecord::Migration[5.0] + def change + add_column :budget_phase_translations, :main_link_text, :string + add_column :budget_phases, :main_link_url, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index d13bbd02f..b69a16a90 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -287,6 +287,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_100638) do t.text "description" t.text "summary" t.string "name" + t.string "main_link_text" t.index ["budget_phase_id"], name: "index_budget_phase_translations_on_budget_phase_id" t.index ["locale"], name: "index_budget_phase_translations_on_locale" end @@ -298,6 +299,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_100638) do t.datetime "starts_at" t.datetime "ends_at" t.boolean "enabled", default: true + t.string "main_link_url" t.index ["ends_at"], name: "index_budget_phases_on_ends_at" t.index ["kind"], name: "index_budget_phases_on_kind" t.index ["next_phase_id"], name: "index_budget_phases_on_next_phase_id" diff --git a/spec/components/budgets/phases_component_spec.rb b/spec/components/budgets/phases_component_spec.rb new file mode 100644 index 000000000..c67e1eb24 --- /dev/null +++ b/spec/components/budgets/phases_component_spec.rb @@ -0,0 +1,17 @@ +require "rails_helper" + +describe Budgets::PhasesComponent, type: :component do + let(:budget) { create(:budget) } + + it "shows budget current phase main link when defined" do + render_inline Budgets::PhasesComponent.new(budget) + + expect(page).not_to have_css(".main-link") + + budget.current_phase.update!(main_link_text: "Phase link!", main_link_url: "https://consulproject.org") + render_inline Budgets::PhasesComponent.new(budget) + + expect(page).to have_css(".main-link") + expect(page).to have_link("Phase link!", href: "https://consulproject.org") + end +end diff --git a/spec/models/budget/phase_spec.rb b/spec/models/budget/phase_spec.rb index c5eccfaa2..58d70ca44 100644 --- a/spec/models/budget/phase_spec.rb +++ b/spec/models/budget/phase_spec.rb @@ -111,6 +111,29 @@ describe Budget::Phase do expect(informing_phase).to be_valid end end + + describe "main_link_url" do + it "is not required if main_link_text is not provided" do + valid_budget = build(:budget, main_link_text: nil) + + expect(valid_budget).to be_valid + end + + it "is required if main_link_text is provided" do + invalid_budget = build(:budget, main_link_text: "link text") + + expect(invalid_budget).not_to be_valid + expect(invalid_budget.errors.count).to be 1 + expect(invalid_budget.errors[:main_link_url].count).to be 1 + expect(invalid_budget.errors[:main_link_url].first).to eq "can't be blank" + end + + it "is valid if main_link_text and main_link_url are both provided" do + budget = build(:budget, main_link_text: "link text", main_link_url: "https://consulproject.org") + + expect(budget).to be_valid + end + end end describe "#save" do diff --git a/spec/models/concerns/globalizable.rb b/spec/models/concerns/globalizable.rb index 21f4bd556..9a55a0b42 100644 --- a/spec/models/concerns/globalizable.rb +++ b/spec/models/concerns/globalizable.rb @@ -13,7 +13,7 @@ shared_examples_for "globalizable" do |factory_name| let(:attribute) { required_fields.sample || fields.sample } before do - if factory_name == :budget + if factory_name == :budget || factory_name == :budget_phase record.main_link_url = "https://consulproject.org" end record.update!(attribute => "In English") diff --git a/spec/system/admin/budget_phases_spec.rb b/spec/system/admin/budget_phases_spec.rb index eda219810..5ecd061ca 100644 --- a/spec/system/admin/budget_phases_spec.rb +++ b/spec/system/admin/budget_phases_spec.rb @@ -55,5 +55,21 @@ describe "Admin budget phases" do expect(page).to have_content "Changes saved" end + + scenario "shows CTA link in public site if added" do + visit edit_admin_budget_budget_phase_path(budget, budget.current_phase) + + expect(page).to have_content "Main call to action (optional)" + + fill_in "Text on the link", with: "Link on the phase" + fill_in "The link takes you to (add a link)", with: "https://consulproject.org" + click_button "Save changes" + + expect(page).to have_content("Changes saved") + + visit budgets_path + + expect(page).to have_link("Link on the phase", href: "https://consulproject.org") + end end end diff --git a/spec/system/admin/translatable_spec.rb b/spec/system/admin/translatable_spec.rb index 4cf6868a8..ea4b18059 100644 --- a/spec/system/admin/translatable_spec.rb +++ b/spec/system/admin/translatable_spec.rb @@ -2,6 +2,7 @@ require "rails_helper" describe "Admin edit translatable records", :admin do before do + translatable.main_link_url = "https://consulproject.org" if translatable.is_a?(Budget::Phase) translatable.update!(attributes) end