Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve budget header #4501

Merged
merged 5 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/assets/stylesheets/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,11 @@ $table-header: #ecf1f6;
}
}

.form-label {
font-weight: bold;
margin-bottom: 0;
}

.menu.simple {
margin-bottom: $line-height / 2;

Expand Down
31 changes: 30 additions & 1 deletion app/assets/stylesheets/participation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1132,8 +1132,28 @@
.budget-header {
@extend %brand-background;
margin-top: -$line-height;
min-height: $line-height * 25;
padding-bottom: $line-height;
padding-top: $line-height;
padding-top: $line-height * 4;

.budget-title {
font-weight: bold;
text-transform: uppercase;

&::after {
border-bottom: 2px solid #fff;
content: "";
margin: 0 auto;
padding-top: $line-height / 2;
display: block;
width: 20%;
}
}

h1 {
font-size: rem-calc(60);
padding: $line-height * 2 0 $line-height;
}

h1,
h2,
Expand Down Expand Up @@ -1162,6 +1182,15 @@
text-transform: uppercase;
}
}

.main-link {
@include regular-button($color: rgba(0, 0, 0, 0.5));

font-size: 1.25rem;
margin-bottom: $line-height * 2;
min-width: 30%;
text-decoration: none;
}
}

.jumbo-budget {
Expand Down
33 changes: 25 additions & 8 deletions app/components/admin/budgets/form_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,36 @@
<%= render "shared/errors", resource: budget %>

<%= f.translatable_fields do |translations_form| %>
<div class="small-12 medium-9 large-6 column end">
<%= translations_form.text_field :name,
maxlength: Budget.title_max_length,
hint: t("admin.budgets.edit.name_description") %>
<div class="row expanded">
<div class="small-12 medium-9 large-6 column end">
<%= translations_form.text_field :name,
maxlength: Budget.title_max_length,
hint: t("admin.budgets.edit.name_description") %>
</div>
</div>
<div class="row expanded">
<div class="small-12 medium-9 large-6 column end">
<p class="form-label"><%= t("admin.budgets.edit.main_call_to_action") %></p>
<p class="help-text"> <%= t("admin.budgets.edit.main_call_to_action_description") %></p>
<%= translations_form.text_field :main_link_text %>
</div>
</div>
<% end %>

<div class="small-12 medium-4 column">
<%= f.select :voting_style, voting_styles_select_options %>
<div class="row expanded">
<div class="small-12 medium-9 large-6 column end">
<%= f.text_field :main_link_url, placeholder: t("admin.shared.example_url") %>
</div>
</div>

<div class="small-12 medium-2 column end">
<%= f.select :currency_symbol, currency_symbol_select_options %>
<div class="row expanded">
<div class="small-12 medium-4 column">
<%= f.select :voting_style, voting_styles_select_options %>
</div>

<div class="small-12 medium-2 column end">
<%= f.select :currency_symbol, currency_symbol_select_options %>
</div>
</div>
</fieldset>

Expand Down
10 changes: 6 additions & 4 deletions app/components/budgets/budget_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<div class="budget-header">
<div class="row">
<div class="small-12 column">
<div class="small-12 column text-center">
<span class="budget-title"><%= t("budgets.index.title") %></span>
<h1><%= budget.name %></h1>
<div class="description">
<%= auto_link_already_sanitized_html wysiwyg(budget.description) %>
</div>

<% if budget.main_link_text.present? && budget.main_link_url.present? %>
<%= link_to budget.main_link_text, budget.main_link_url, class: "main-link" %>
<% end %>

<p>
<%= link_to t("budgets.index.section_header.help"), "#section_help" %>
Expand Down
1 change: 1 addition & 0 deletions app/controllers/admin/budgets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def budget_params
valid_attributes = [:phase,
:currency_symbol,
:voting_style,
:main_link_url,
administrator_ids: [],
valuator_ids: []
] + descriptions
Expand Down
3 changes: 2 additions & 1 deletion app/models/budget.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Budget < ApplicationRecord
include StatsVersionable
include Reportable

translates :name, touch: true
translates :name, :main_link_text, touch: true
include Globalizable

class Translation
Expand All @@ -27,6 +27,7 @@ def name_uniqueness_by_budget
validates :currency_symbol, presence: true
validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/
validates :voting_style, inclusion: { in: VOTING_STYLES }
validates :main_link_url, presence: true, if: -> { main_link_text.present? }

has_many :investments, dependent: :destroy
has_many :ballots, dependent: :destroy
Expand Down
2 changes: 2 additions & 0 deletions config/locales/en/activerecord.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ en:
voting_style: "Final voting style"
voting_style_knapsack: "Knapsack"
voting_style_approval: "Approval"
main_link_url: "The link takes you to (add a link)"
budget/translation:
main_link_text: "Text on the link"
name: "Name"
budget/investment:
heading_id: "Heading"
Expand Down
3 changes: 3 additions & 0 deletions config/locales/en/admin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ en:
empty_administrators: "There are no administrators"
empty_valuators: "There are no valuators"
name_description: "This is the name of the participatory budget used on the header and cards whenever it is active"
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 and encourages your user to perform a specific action like creating a proposal, voting for existing ones, or learn more about the process."
info:
budget_settings: "General participatory budget settings"
phases_settings: "Phases settings"
Expand Down Expand Up @@ -1350,6 +1352,7 @@ en:
color_help: Hexadecimal format
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"
geozones:
index:
title: Geozone
Expand Down
2 changes: 2 additions & 0 deletions config/locales/es/activerecord.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ es:
voting_style: "Estilo de la votación final"
voting_style_knapsack: Bolsa de dinero
voting_style_approval: Por aprobación
main_link_url: "El enlace te lleva a (añade un enlace)"
budget/translation:
main_link_text: "Texto del enlace"
name: "Nombre"
budget/investment:
heading_id: "Partida presupuestaria"
Expand Down
3 changes: 3 additions & 0 deletions config/locales/es/admin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ es:
empty_administrators: "No hay administradores"
empty_valuators: "No hay evaluadores"
name_description: "Este es el nombre del presupuesto participativo usado en la cabecera y tarjetas cuando éste está activo"
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 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."
info:
budget_settings: "Configuración genérica del presupuesto participativo"
phases_settings: "Configuración de las fases"
Expand Down Expand Up @@ -1349,6 +1351,7 @@ es:
color_help: Formato hexadecimal
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"
geozones:
index:
title: Zonas
Expand Down
6 changes: 6 additions & 0 deletions db/migrate/20200213163214_add_main_link_to_budgets.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddMainLinkToBudgets < ActiveRecord::Migration[5.2]
def change
add_column :budgets, :main_link_url, :string
add_column :budget_translations, :main_link_text, :string
end
end
2 changes: 2 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "main_link_text"
t.index ["budget_id"], name: "index_budget_translations_on_budget_id"
t.index ["locale"], name: "index_budget_translations_on_locale"
end
Expand Down Expand Up @@ -362,6 +363,7 @@
t.text "description_informing"
t.string "voting_style", default: "knapsack"
t.boolean "published"
t.string "main_link_url"
end

create_table "campaigns", id: :serial, force: :cascade do |t|
Expand Down
131 changes: 131 additions & 0 deletions spec/components/budgets/budget_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
require "rails_helper"

describe Budgets::BudgetComponent, type: :component do
let(:budget) { create(:budget) }
let(:heading) { create(:budget_heading, budget: budget) }
let(:user) { create(:user) }

before do
allow(controller).to receive(:current_user).and_return(user)
end

describe "budget header" do
it "shows budget name and link to help" do
budget.update!(phase: "informing")

render_inline Budgets::BudgetComponent.new(budget)

within(".budget-header") do
expect(page).to have_content("PARTICIPATORY BUDGETS")
expect(page).to have_content(budget.name)
expect(page).to have_link("Help with participatory budgets")
end
end

it "shows budget main link when defined" do
render_inline Budgets::BudgetComponent.new(budget)

within(".budget-header") do
expect(page).not_to have_css("a.main-link")
end

budget.update!(main_link_text: "Partitipate now!", main_link_url: "https://consulproject.org")

render_inline Budgets::BudgetComponent.new(budget)

within(".budget-header") do
expect(page).to have_css("a.main-link", text: "Participate now!", href: "https://consulproject.org")
end
end
end

describe "map" do
before do
Setting["feature.map"] = true
end

it "displays investment's map location markers" do
investment1 = create(:budget_investment, heading: heading)
investment2 = create(:budget_investment, heading: heading)
investment3 = create(:budget_investment, heading: heading)

create(:map_location, longitude: 40.1234, latitude: -3.634, investment: investment1)
create(:map_location, longitude: 40.1235, latitude: -3.635, investment: investment2)
create(:map_location, longitude: 40.1236, latitude: -3.636, investment: investment3)

render_inline Budgets::BudgetComponent.new(budget)

within ".map_location" do
expect(page).to have_css(".map-icon", count: 3)
end
end

it "displays all investment's map location if there are no selected" do
budget.update!(phase: :publishing_prices)

investment1 = create(:budget_investment, heading: heading)
investment2 = create(:budget_investment, heading: heading)
investment3 = create(:budget_investment, heading: heading)
investment4 = create(:budget_investment, heading: heading)

investment1.create_map_location(longitude: 40.1234, latitude: 3.1234, zoom: 10)
investment2.create_map_location(longitude: 40.1235, latitude: 3.1235, zoom: 10)
investment3.create_map_location(longitude: 40.1236, latitude: 3.1236, zoom: 10)
investment4.create_map_location(longitude: 40.1240, latitude: 3.1240, zoom: 10)

render_inline Budgets::BudgetComponent.new(budget)

within ".map_location" do
expect(page).to have_css(".map-icon", count: 4)
end
end

it "displays only selected investment's map location from publishing prices phase" do
budget.update!(phase: :publishing_prices)

investment1 = create(:budget_investment, :selected, heading: heading)
investment2 = create(:budget_investment, :selected, heading: heading)
investment3 = create(:budget_investment, heading: heading)
investment4 = create(:budget_investment, heading: heading)

investment1.create_map_location(longitude: 40.1234, latitude: 3.1234, zoom: 10)
investment2.create_map_location(longitude: 40.1235, latitude: 3.1235, zoom: 10)
investment3.create_map_location(longitude: 40.1236, latitude: 3.1236, zoom: 10)
investment4.create_map_location(longitude: 40.1240, latitude: 3.1240, zoom: 10)

render_inline Budgets::BudgetComponent.new(budget)

within ".map_location" do
expect(page).to have_css(".map-icon", count: 2)
end
end

scenario "skips invalid map markers" do
map_locations = []

investment = create(:budget_investment, heading: heading)

map_locations << { longitude: 40.123456789, latitude: 3.12345678 }
map_locations << { longitude: 40.123456789, latitude: "********" }
map_locations << { longitude: "**********", latitude: 3.12345678 }

coordinates = map_locations.map do |map_location|
{
lat: map_location[:latitude],
long: map_location[:longitude],
investment_title: investment.title,
investment_id: investment.id,
budget_id: budget.id
}
end

allow_any_instance_of(Budgets::BudgetComponent).to receive(:coordinates).and_return(coordinates)

render_inline Budgets::BudgetComponent.new(budget)

within ".map_location" do
expect(page).to have_css(".map-icon", count: 1)
end
end
end
end
Loading