From c9416328532772fcad28dd18ba5a3ca2870332e3 Mon Sep 17 00:00:00 2001 From: Matheus Miranda Date: Thu, 8 Nov 2018 09:27:03 -0200 Subject: [PATCH 01/10] Add map to sidebar on Heading's page Signed-off-by: Matheus Miranda --- app/assets/stylesheets/layout.scss | 1 + .../admin/budget_headings_controller.rb | 2 +- .../budgets/investments_controller.rb | 24 +- app/models/budget/heading.rb | 4 + .../admin/budgets/_heading_form.html.erb | 37 +-- app/views/budgets/index.html.erb | 2 +- app/views/budgets/investments/_map.html.erb | 8 + .../budgets/investments/_sidebar.html.erb | 1 + config/locales/en/admin.yml | 2 + config/routes/budget.rb | 1 + db/dev_seeds/budgets.rb | 44 ++-- ...20181109111037_add_location_to_headings.rb | 6 + db/schema.rb | 2 + ...grate_spending_proposals_to_investments.rb | 4 +- spec/factories/budgets.rb | 2 + spec/features/admin/budgets_spec.rb | 2 + spec/features/budgets/investments_spec.rb | 84 ++++++- spec/features/tags/budget_investments_spec.rb | 2 +- spec/models/budget/heading_spec.rb | 210 ++++++++++++++++++ 19 files changed, 398 insertions(+), 40 deletions(-) create mode 100644 app/views/budgets/investments/_map.html.erb create mode 100644 db/migrate/20181109111037_add_location_to_headings.rb diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 92a5d5211d4..9f101725c00 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -859,6 +859,7 @@ footer { .categories a, .geozone a, .sidebar-links a, +.sidebar-map a, .tags span { background: #ececec; border-radius: rem-calc(6); diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb index efe718556fc..39493d86c90 100644 --- a/app/controllers/admin/budget_headings_controller.rb +++ b/app/controllers/admin/budget_headings_controller.rb @@ -27,7 +27,7 @@ def destroy private def budget_heading_params - params.require(:budget_heading).permit(:name, :price, :population) + params.require(:budget_heading).permit(:name, :price, :population, :latitude, :longitude) end def load_budget diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 257b7497f57..60421ff3ceb 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -1,5 +1,7 @@ module Budgets class InvestmentsController < ApplicationController + OSM_DISTRICT_LEVEL_ZOOM = 12 + include FeatureFlags include CommentableActions include FlagActions @@ -34,13 +36,17 @@ class InvestmentsController < ApplicationController respond_to :html, :js def index - if @budget.finished? - @investments = investments.winners.page(params[:page]).per(10).for_render - else - @investments = investments.page(params[:page]).per(10).for_render - end + all_investments = if @budget.finished? + investments.winners + else + investments + end + + @investments = all_investments.page(params[:page]).per(10).for_render @investment_ids = @investments.pluck(:id) + @investments_map_coordinates = MapLocation.where(investment_id: all_investments).map { |l| l.json_data } + load_investment_votes(@investments) end @@ -163,6 +169,7 @@ def load_heading load_heading_from_slug load_assigned_heading set_heading_id_from_slug + load_map end end @@ -205,5 +212,12 @@ def investments end end + def load_map + @map_location = MapLocation.new + @map_location.zoom = OSM_DISTRICT_LEVEL_ZOOM + @map_location.latitude = @heading.latitude.to_f + @map_location.longitude = @heading.longitude.to_f + end + end end diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb index 1cfb840aa27..b1e0c6b796d 100644 --- a/app/models/budget/heading.rb +++ b/app/models/budget/heading.rb @@ -11,6 +11,10 @@ class Heading < ActiveRecord::Base validates :price, presence: true validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/ validates :population, numericality: { greater_than: 0 }, allow_nil: true + validates :latitude, length: { maximum: 22, minimum: 1 }, presence: true, \ + format: /\A(-|\+)?([1-8]?\d(?:\.\d{1,})?|90(?:\.0{1,6})?)\z/ + validates :longitude, length: { maximum: 22, minimum: 1}, presence: true, \ + format: /\A(-|\+)?((?:1[0-7]|[1-9])?\d(?:\.\d{1,})?|180(?:\.0{1,})?)\z/ delegate :budget, :budget_id, to: :group, allow_nil: true diff --git a/app/views/admin/budgets/_heading_form.html.erb b/app/views/admin/budgets/_heading_form.html.erb index 935e69323f3..a02de44f723 100644 --- a/app/views/admin/budgets/_heading_form.html.erb +++ b/app/views/admin/budgets/_heading_form.html.erb @@ -1,30 +1,25 @@ <%= form_for [:admin, budget, group, heading], remote: true do |f| %> <%= render 'shared/errors', resource: heading %> -
-
- - <%= f.text_field :name, - label: false, - maxlength: 50, - placeholder: t("admin.budgets.form.heading") %> -
+ <%= f.text_field :name, + label: t("admin.budgets.form.heading"), + maxlength: 50, + placeholder: t("admin.budgets.form.heading") %> -
- +
+
<%= f.text_field :price, - label: false, + label: t("admin.budgets.form.amount"), maxlength: 8, placeholder: t("admin.budgets.form.amount") %>
-

<%= t("admin.budgets.form.population_help_text") %>

<%= f.text_field :population, - label: false, + label: t("admin.budgets.form.population"), maxlength: 8, placeholder: t("admin.budgets.form.population"), aria: {describedby: "budgets-population-help-text"} %> @@ -36,6 +31,22 @@
+
+
+ <%= f.text_field :latitude, + label: t("admin.budgets.form.latitude"), + maxlength: 22, + placeholder: "latitude" %> +
+
+
+
+ <%= f.text_field :longitude, + label: t("admin.budgets.form.longitude"), + maxlength: 22, + placeholder: "longitude" %> +
+
diff --git a/app/views/budgets/index.html.erb b/app/views/budgets/index.html.erb index bc236377f6a..9b0dd66f918 100644 --- a/app/views/budgets/index.html.erb +++ b/app/views/budgets/index.html.erb @@ -88,7 +88,7 @@
<% unless current_budget.informing? %> -
+

<%= t("budgets.index.map") %>

<%= render_map(nil, "budgets", false, nil, @budgets_coordinates) %>
diff --git a/app/views/budgets/investments/_map.html.erb b/app/views/budgets/investments/_map.html.erb new file mode 100644 index 00000000000..af04ef639a3 --- /dev/null +++ b/app/views/budgets/investments/_map.html.erb @@ -0,0 +1,8 @@ + +
+ + diff --git a/app/views/budgets/investments/_sidebar.html.erb b/app/views/budgets/investments/_sidebar.html.erb index 15632aa2b6c..99249a51661 100644 --- a/app/views/budgets/investments/_sidebar.html.erb +++ b/app/views/budgets/investments/_sidebar.html.erb @@ -23,6 +23,7 @@

<% end %> +<%= render 'budgets/investments/map' %> <%= render 'budgets/investments/categories' %> <% if @heading && can?(:show, @ballot) %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index b44c8d89895..47ccc6899ab 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -134,6 +134,8 @@ en: max_supportable_headings: "Maximum number of headings in which a user can support" max_votable_headings: "Maximum number of headings in which a user can vote" current_of_max_headings: "%{current} of %{max}" + latitude: Latitude + longitude: Longitude winners: calculate: Calculate Winner Investments calculated: Winners being calculated, it may take a minute. diff --git a/config/routes/budget.rb b/config/routes/budget.rb index 475d5496a1a..0159b946a37 100644 --- a/config/routes/budget.rb +++ b/config/routes/budget.rb @@ -25,3 +25,4 @@ end get 'investments/:id/json_data', action: :json_data, controller: 'budgets/investments' +get '/budgets/:budget_id/investments/:id/json_data', action: :json_data, controller: 'budgets/investments' diff --git a/db/dev_seeds/budgets.rb b/db/dev_seeds/budgets.rb index 949b9e8747d..0558263bb4b 100644 --- a/db/dev_seeds/budgets.rb +++ b/db/dev_seeds/budgets.rb @@ -37,21 +37,35 @@ def add_image_to(imageable) phase: 'accepting' ) - (1..([1, 2, 3].sample)).each do |i| - finished_group = finished_budget.groups.create!(name: "#{Faker::StarWars.planet} #{i}") - accepting_group = accepting_budget.groups.create!(name: "#{Faker::StarWars.planet} #{i}") - - geozones = Geozone.reorder("RANDOM()").limit([2, 5, 6, 7].sample) - geozones.each do |geozone| - finished_group.headings << finished_group.headings.create!(name: "#{geozone.name} #{i}", - price: rand(1..100) * 100000, - population: rand(1..50) * 10000) - - accepting_group.headings << accepting_group.headings.create!(name: "#{geozone.name} #{i}", - price: rand(1..100) * 100000, - population: rand(1..50) * 10000) - - end + Budget.all.each do |budget| + city_group = budget.groups.create!(name: I18n.t('seeds.budgets.groups.all_city')) + city_group.headings.create!(name: I18n.t('seeds.budgets.groups.all_city'), + price: 1000000, + population: 1000000, + latitude: '-40.123241', + longitude: '25.123249') + + districts_group = budget.groups.create!(name: I18n.t('seeds.budgets.groups.districts')) + districts_group.headings.create!(name: I18n.t('seeds.geozones.north_district'), + price: rand(5..10) * 100000, + population: 350000, + latitude: '15.234521', + longitude: '-15.234234') + districts_group.headings.create!(name: I18n.t('seeds.geozones.west_district'), + price: rand(5..10) * 100000, + population: 300000, + latitude: '14.125125', + longitude: '65.123124') + districts_group.headings.create!(name: I18n.t('seeds.geozones.east_district'), + price: rand(5..10) * 100000, + population: 200000, + latitude: '23.234234', + longitude: '-47.134124') + districts_group.headings.create!(name: I18n.t('seeds.geozones.central_district'), + price: rand(5..10) * 100000, + population: 150000, + latitude: '-26.133213', + longitude: '-10.123231') end end diff --git a/db/migrate/20181109111037_add_location_to_headings.rb b/db/migrate/20181109111037_add_location_to_headings.rb new file mode 100644 index 00000000000..973cdf38eb7 --- /dev/null +++ b/db/migrate/20181109111037_add_location_to_headings.rb @@ -0,0 +1,6 @@ +class AddLocationToHeadings < ActiveRecord::Migration + def change + add_column :budget_headings, :latitude, :text + add_column :budget_headings, :longitude, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index 679559cd0bd..fcf82283f44 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -190,6 +190,8 @@ t.integer "price", limit: 8 t.string "slug" t.integer "population" + t.text "latitude" + t.text "longitude" end add_index "budget_headings", ["group_id"], name: "index_budget_headings_on_group_id", using: :btree diff --git a/lib/migrate_spending_proposals_to_investments.rb b/lib/migrate_spending_proposals_to_investments.rb index 76fbf897a80..d555e4a0978 100644 --- a/lib/migrate_spending_proposals_to_investments.rb +++ b/lib/migrate_spending_proposals_to_investments.rb @@ -9,10 +9,10 @@ def import(sp) if sp.geozone_id.present? group = budget.groups.find_or_create_by!(name: "Distritos") - heading = group.headings.find_or_create_by!(name: sp.geozone.name, price: 10000000) + heading = group.headings.find_or_create_by!(name: sp.geozone.name, price: 10000000, latitude: '40.416775', longitude: '-3.703790') else group = budget.groups.find_or_create_by!(name: "Toda la ciudad") - heading = group.headings.find_or_create_by!(name: "Toda la ciudad", price: 10000000) + heading = group.headings.find_or_create_by!(name: "Toda la ciudad", price: 10000000, latitude: '40.416775', longitude: '-3.703790') end feasibility = case sp.feasible diff --git a/spec/factories/budgets.rb b/spec/factories/budgets.rb index d0e965e73df..b91ca26614b 100644 --- a/spec/factories/budgets.rb +++ b/spec/factories/budgets.rb @@ -94,6 +94,8 @@ sequence(:name) { |n| "Heading #{n}" } price 1000000 population 1234 + latitude '-25.172741' + longitude '40.127241' trait :drafting_budget do association :group, factory: [:budget_group, :drafting_budget] diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 39f72110dcf..441744548df 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -285,6 +285,8 @@ fill_in 'budget_heading_name', with: 'District 9 reconstruction' fill_in 'budget_heading_price', with: '6785' fill_in 'budget_heading_population', with: '100500' + fill_in 'budget_heading_latitude', with: '40.416775' + fill_in 'budget_heading_longitude', with: '-3.703790' click_button 'Save heading' end diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index a03ee86d7b8..21dbaaaa71a 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -1424,10 +1424,10 @@ def investments_order user = create(:user, :level_two) global_group = create(:budget_group, budget: budget, name: 'Global Group') - global_heading = create(:budget_heading, group: global_group, name: 'Global Heading') + global_heading = create(:budget_heading, group: global_group, name: 'Global Heading', latitude: -43.145412, longitude: 12.009423) carabanchel_heading = create(:budget_heading, group: group, name: "Carabanchel") - new_york_heading = create(:budget_heading, group: group, name: "New York") + new_york_heading = create(:budget_heading, group: group, name: "New York", latitude: -43.223412, longitude: 12.009423) sp1 = create(:budget_investment, :selected, price: 1, heading: global_heading) sp2 = create(:budget_investment, :selected, price: 10, heading: global_heading) @@ -1732,4 +1732,84 @@ def investments_order expect(Flag.flagged?(user, investment)).not_to be end + context 'sidebar map' do + scenario "Display 6 investment's markers on sidebar map", :js do + investment1 = create(:budget_investment, heading: heading) + investment2 = create(:budget_investment, heading: heading) + investment3 = create(:budget_investment, heading: heading) + investment4 = create(:budget_investment, heading: heading) + investment5 = create(:budget_investment, heading: heading) + investment6 = create(:budget_investment, heading: heading) + + create(:map_location, longitude: 40.1231, latitude: -3.636, investment: investment1) + create(:map_location, longitude: 40.1232, latitude: -3.635, investment: investment2) + create(:map_location, longitude: 40.1233, latitude: -3.634, investment: investment3) + create(:map_location, longitude: 40.1234, latitude: -3.633, investment: investment4) + create(:map_location, longitude: 40.1235, latitude: -3.632, investment: investment5) + create(:map_location, longitude: 40.1236, latitude: -3.631, investment: investment6) + + visit budget_investments_path(budget, heading_id: heading.id) + + within ".map_location" do + expect(page).to have_css(".map-icon", count: 6, visible: false) + end + end + + scenario "Display 2 investment's markers on sidebar map", :js do + investment1 = create(:budget_investment, heading: heading) + investment2 = create(:budget_investment, heading: heading) + + create(:map_location, longitude: 40.1281, latitude: -3.656, investment: investment1) + create(:map_location, longitude: 40.1292, latitude: -3.665, investment: investment2) + + visit budget_investments_path(budget, heading_id: heading.id) + + within ".map_location" do + expect(page).to have_css(".map-icon", count: 2, visible: false) + end + end + + scenario "Display only investment's related to the current heading", :js do + heading_2 = create(:budget_heading, name: "Madrid", group: group) + + investment1 = create(:budget_investment, heading: heading) + investment2 = create(:budget_investment, heading: heading) + investment3 = create(:budget_investment, heading: heading) + investment4 = create(:budget_investment, heading: heading) + investment5 = create(:budget_investment, heading: heading_2) + investment6 = create(:budget_investment, heading: heading_2) + + create(:map_location, longitude: 40.1231, latitude: -3.636, investment: investment1) + create(:map_location, longitude: 40.1232, latitude: -3.685, investment: investment2) + create(:map_location, longitude: 40.1233, latitude: -3.664, investment: investment3) + create(:map_location, longitude: 40.1234, latitude: -3.673, investment: investment4) + create(:map_location, longitude: 40.1235, latitude: -3.672, investment: investment5) + create(:map_location, longitude: 40.1236, latitude: -3.621, investment: investment6) + + visit budget_investments_path(budget, heading_id: heading.id) + + within ".map_location" do + expect(page).to have_css(".map-icon", count: 4, visible: false) + end + end + + scenario "Do not display investment's, since they're all related to other heading", :js do + heading_2 = create(:budget_heading, name: "Madrid", group: group) + + investment1 = create(:budget_investment, heading: heading_2) + investment2 = create(:budget_investment, heading: heading_2) + investment3 = create(:budget_investment, heading: heading_2) + + create(:map_location, longitude: 40.1255, latitude: -3.644, investment: investment1) + create(:map_location, longitude: 40.1258, latitude: -3.637, investment: investment2) + create(:map_location, longitude: 40.1251, latitude: -3.649, investment: investment3) + + visit budget_investments_path(budget, heading_id: heading.id) + + within ".map_location" do + expect(page).to have_css(".map-icon", count: 0, visible: false) + end + end + end + end diff --git a/spec/features/tags/budget_investments_spec.rb b/spec/features/tags/budget_investments_spec.rb index 53a4184f7ba..8f044ff2242 100644 --- a/spec/features/tags/budget_investments_spec.rb +++ b/spec/features/tags/budget_investments_spec.rb @@ -5,7 +5,7 @@ let(:author) { create(:user, :level_two, username: 'Isabel') } let(:budget) { create(:budget, name: "Big Budget") } let(:group) { create(:budget_group, name: "Health", budget: budget) } - let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) } + let!(:heading) { create(:budget_heading, name: "More hospitals", group: group, latitude: '40.416775', longitude: '-3.703790') } let!(:tag_medio_ambiente) { create(:tag, :category, name: 'Medio Ambiente') } let!(:tag_economia) { create(:tag, :category, name: 'Economía') } let(:admin) { create(:administrator).user } diff --git a/spec/models/budget/heading_spec.rb b/spec/models/budget/heading_spec.rb index b2a09cb55ce..edd96a8b840 100644 --- a/spec/models/budget/heading_spec.rb +++ b/spec/models/budget/heading_spec.rb @@ -44,6 +44,216 @@ end end + describe "save latitude" do + it "Doesn't allow latitude == nil" do + expect(build(:budget_heading, group: group, name: 'Latitude is nil', population: 12412512, latitude: nil, longitude: '12.123412')).not_to be_valid + end + + it "Doesn't allow latitude == ''" do + expect(build(:budget_heading, group: group, name: 'Latitude is an empty string', population: 12412512, latitude: '', longitude: '12.123412')).not_to be_valid + end + + it "Doesn't allow latitude < -90" do + heading = create(:budget_heading, group: group, name: 'Latitude is < -90') + + heading.latitude = '-90.127491' + expect(heading).not_to be_valid + + heading.latitude = '-91.723491' + expect(heading).not_to be_valid + + heading.latitude = '-108.127412' + expect(heading).not_to be_valid + + heading.latitude = '-1100.888491' + expect(heading).not_to be_valid + end + + it "Doesn't allow latitude > 90" do + heading = create(:budget_heading, group: group, name: 'Latitude is > 90') + + heading.latitude = '90.127491' + expect(heading).not_to be_valid + + heading.latitude = '97.723491' + expect(heading).not_to be_valid + + heading.latitude = '119.127412' + expect(heading).not_to be_valid + + heading.latitude = '1200.888491' + expect(heading).not_to be_valid + + heading.latitude = '+128.888491' + expect(heading).not_to be_valid + + heading.latitude = '+255.888491' + expect(heading).not_to be_valid + end + + it "Doesn't allow latitude length > 22" do + heading = create(:budget_heading, group: group, name: 'Latitude length is > 22') + + heading.latitude = '10.12749112312418238128213' + expect(heading).not_to be_valid + + heading.latitude = '7.7234941211121231231241' + expect(heading).not_to be_valid + + heading.latitude = '9.1274124111241248688995' + expect(heading).not_to be_valid + + heading.latitude = '+12.8884911231238684445311' + expect(heading).not_to be_valid + end + + it "Allows latitude inside [-90,90] interval" do + heading = create(:budget_heading, group: group, name: 'Latitude is inside [-90,90] interval') + + heading.latitude = '90' + expect(heading).to be_valid + + heading.latitude = '-90' + expect(heading).to be_valid + + heading.latitude = '-90.000' + expect(heading).to be_valid + + heading.latitude = '-90.00000' + expect(heading).to be_valid + + heading.latitude = '90.000' + expect(heading).to be_valid + + heading.latitude = '90.00000' + expect(heading).to be_valid + + heading.latitude = '-80.123451' + expect(heading).to be_valid + + heading.latitude = '+65.888491' + expect(heading).to be_valid + + heading.latitude = '80.144812' + expect(heading).to be_valid + + heading.latitude = '17.417412' + expect(heading).to be_valid + + heading.latitude = '-21.000054' + expect(heading).to be_valid + + heading.latitude = '+80.888491' + expect(heading).to be_valid + end + end + + + describe "save longitude" do + it "Doesn't allow longitude == nil" do + expect(build(:budget_heading, group: group, name: 'Longitude is nil', population: 12412512, latitude: '12.123412', longitude: nil)).not_to be_valid + end + + it "Doesn't allow longitude == ''" do + expect(build(:budget_heading, group: group, name: 'Longitude is an empty string', population: 12412512, latitude: '12.127412', longitude: '')).not_to be_valid + end + + it "Doesn't allow longitude < -180" do + heading = create(:budget_heading, group: group, name: 'Longitude is < -180') + + heading.longitude = '-180.127491' + expect(heading).not_to be_valid + + heading.longitude = '-181.723491' + expect(heading).not_to be_valid + + heading.longitude = '-188.127412' + expect(heading).not_to be_valid + + heading.longitude = '-1100.888491' + expect(heading).not_to be_valid + end + + it "Doesn't allow longitude > 180" do + heading = create(:budget_heading, group: group, name: 'Longitude is > 180') + + heading.longitude = '190.127491' + expect(heading).not_to be_valid + + heading.longitude = '197.723491' + expect(heading).not_to be_valid + + heading.longitude = '+207.723491' + expect(heading).not_to be_valid + + heading.longitude = '300.723491' + expect(heading).not_to be_valid + + heading.longitude = '189.127412' + expect(heading).not_to be_valid + + heading.longitude = '1200.888491' + expect(heading).not_to be_valid + end + + it "Doesn't allow longitude length > 23" do + heading = create(:budget_heading, group: group, name: 'Longitude length is > 23') + + heading.longitude = '50.1274911123124112312418238128213' + expect(heading).not_to be_valid + + heading.longitude = '53.73412349178811231241' + expect(heading).not_to be_valid + + heading.longitude = '+20.1274124124124123121435' + expect(heading).not_to be_valid + + heading.longitude = '10.88849112312312311232123311' + expect(heading).not_to be_valid + end + + it "Allows longitude inside [-180,180] interval" do + heading = create(:budget_heading, group: group, name: 'Longitude is inside [-180,180] interval') + + heading.longitude = '180' + expect(heading).to be_valid + + heading.longitude = '-180' + expect(heading).to be_valid + + heading.longitude = '-180.000' + expect(heading).to be_valid + + heading.longitude = '-180.00000' + expect(heading).to be_valid + + heading.longitude = '180.000' + expect(heading).to be_valid + + heading.longitude = '180.00000' + expect(heading).to be_valid + + heading.longitude = '+75.00000' + expect(heading).to be_valid + + heading.longitude = '+15.023321' + expect(heading).to be_valid + + heading.longitude = '-80.123451' + expect(heading).to be_valid + + heading.longitude = '80.144812' + expect(heading).to be_valid + + heading.longitude = '17.417412' + expect(heading).to be_valid + + heading.longitude = '-21.000054' + expect(heading).to be_valid + end + end + + describe "heading" do it "can be deleted if no budget's investments associated" do heading1 = create(:budget_heading, group: group, name: 'name') From ce453cbc89597262efcdac827a472f8df5c54f92 Mon Sep 17 00:00:00 2001 From: Milber Champutiz Burbano Date: Tue, 27 Nov 2018 09:37:35 -0500 Subject: [PATCH 02/10] Added feature to add content block to headings in sidebar --- .../admin/budget_headings_controller.rb | 2 +- .../content_blocks_controller.rb | 85 ++++++++++++++++++- .../budgets/investments_controller.rb | 5 ++ app/helpers/content_blocks_helper.rb | 9 ++ app/models/budget/content_block.rb | 9 ++ app/models/budget/heading.rb | 2 + app/views/admin/budgets/_group.html.erb | 35 +++----- app/views/admin/budgets/_heading.html.erb | 3 + .../admin/budgets/_heading_form.html.erb | 8 +- .../content_blocks/_form.html.erb | 38 +-------- .../_form_content_block.html.erb | 35 ++++++++ .../_form_heading_content_block.html.erb | 29 +++++++ .../content_blocks/edit.html.erb | 4 +- .../content_blocks/index.html.erb | 15 +++- .../investments/_content_blocks.html.erb | 9 ++ .../budgets/investments/_sidebar.html.erb | 4 + config/locales/en/admin.yml | 6 ++ config/locales/es/admin.yml | 5 ++ config/routes/admin.rb | 3 + ...11_add_allow_custom_content_to_headings.rb | 5 ++ ...108142513_create_heading_content_blocks.rb | 10 +++ db/schema.rb | 11 +++ spec/factories/budgets.rb | 6 ++ .../site_customization/content_blocks_spec.rb | 3 + .../budget/heading_content_block_spec.rb | 20 +++++ 25 files changed, 294 insertions(+), 67 deletions(-) create mode 100644 app/helpers/content_blocks_helper.rb create mode 100644 app/models/budget/content_block.rb create mode 100644 app/views/admin/site_customization/content_blocks/_form_content_block.html.erb create mode 100644 app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb create mode 100644 app/views/budgets/investments/_content_blocks.html.erb create mode 100644 db/migrate/20181108103111_add_allow_custom_content_to_headings.rb create mode 100644 db/migrate/20181108142513_create_heading_content_blocks.rb create mode 100644 spec/models/budget/heading_content_block_spec.rb diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb index 39493d86c90..b0c8db3947d 100644 --- a/app/controllers/admin/budget_headings_controller.rb +++ b/app/controllers/admin/budget_headings_controller.rb @@ -27,7 +27,7 @@ def destroy private def budget_heading_params - params.require(:budget_heading).permit(:name, :price, :population, :latitude, :longitude) + params.require(:budget_heading).permit(:name, :price, :population, :allow_custom_content, :latitude, :longitude) end def load_budget diff --git a/app/controllers/admin/site_customization/content_blocks_controller.rb b/app/controllers/admin/site_customization/content_blocks_controller.rb index 1697cb76f97..2fb38c01835 100644 --- a/app/controllers/admin/site_customization/content_blocks_controller.rb +++ b/app/controllers/admin/site_customization/content_blocks_controller.rb @@ -1,12 +1,23 @@ class Admin::SiteCustomization::ContentBlocksController < Admin::SiteCustomization::BaseController - load_and_authorize_resource :content_block, class: "SiteCustomization::ContentBlock" + load_and_authorize_resource :content_block, class: "SiteCustomization::ContentBlock", + except: [:delete_heading_content_block, :edit_heading_content_block, :update_heading_content_block] def index @content_blocks = SiteCustomization::ContentBlock.order(:name, :locale) + @headings_content_blocks = Budget::ContentBlock.all end def create - if @content_block.save + if is_heading_content_block?(@content_block.name) + heading_content_block = new_heading_content_block + if heading_content_block.save + notice = t('admin.site_customization.content_blocks.create.notice') + redirect_to admin_site_customization_content_blocks_path, notice: notice + else + flash.now[:error] = t('admin.site_customization.content_blocks.create.error') + render :new + end + elsif @content_block.save notice = t('admin.site_customization.content_blocks.create.notice') redirect_to admin_site_customization_content_blocks_path, notice: notice else @@ -15,8 +26,22 @@ def create end end + def edit + @selected_content_block = (@content_block.is_a? SiteCustomization::ContentBlock) ? @content_block.name : "hcb_#{ @content_block.heading_id }" + end + def update - if @content_block.update(content_block_params) + if is_heading_content_block?(params[:site_customization_content_block][:name]) + heading_content_block = new_heading_content_block + if heading_content_block.save + @content_block.destroy + notice = t('admin.site_customization.content_blocks.create.notice') + redirect_to admin_site_customization_content_blocks_path, notice: notice + else + flash.now[:error] = t('admin.site_customization.content_blocks.create.error') + render :new + end + elsif @content_block.update(content_block_params) notice = t('admin.site_customization.content_blocks.update.notice') redirect_to admin_site_customization_content_blocks_path, notice: notice else @@ -31,6 +56,48 @@ def destroy redirect_to admin_site_customization_content_blocks_path, notice: notice end + def delete_heading_content_block + heading_content_block = Budget::ContentBlock.find(params[:id]) + heading_content_block.destroy if heading_content_block + notice = t('admin.site_customization.content_blocks.destroy.notice') + redirect_to admin_site_customization_content_blocks_path, notice: notice + end + + def edit_heading_content_block + @content_block = Budget::ContentBlock.find(params[:id]) + @selected_content_block = (@content_block.is_a? Budget::ContentBlock) ? "hcb_#{ @content_block.heading_id }" : @content_block.heading.name + @is_heading_content_block = true + render :edit + end + + def update_heading_content_block + heading_content_block = Budget::ContentBlock.find(params[:id]) + if is_heading_content_block?(params[:name]) + heading_content_block.locale = params[:locale] + heading_content_block.body = params[:body] + if heading_content_block.save + notice = t('admin.site_customization.content_blocks.update.notice') + redirect_to admin_site_customization_content_blocks_path, notice: notice + else + flash.now[:error] = t('admin.site_customization.content_blocks.update.error') + render :edit + end + else + @content_block = SiteCustomization::ContentBlock.new + @content_block.name = params[:name] + @content_block.locale = params[:locale] + @content_block.body = params[:body] + if @content_block.save + heading_content_block.destroy + notice = t('admin.site_customization.content_blocks.update.notice') + redirect_to admin_site_customization_content_blocks_path, notice: notice + else + flash.now[:error] = t('admin.site_customization.content_blocks.update.error') + render :edit + end + end + end + private def content_block_params @@ -40,4 +107,16 @@ def content_block_params :body ) end + + def is_heading_content_block?(name) + name.start_with?('hcb_') + end + + def new_heading_content_block + heading_content_block = Budget::ContentBlock.new + heading_content_block.body = params[:site_customization_content_block][:body] + heading_content_block.locale = params[:site_customization_content_block][:locale] + heading_content_block.heading_id = params[:site_customization_content_block][:name].sub('hcb_', '').to_i + heading_content_block + end end diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 60421ff3ceb..e0da9ce6cb2 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -21,6 +21,7 @@ class InvestmentsController < ApplicationController before_action :load_categories, only: [:index, :new, :create] before_action :set_default_budget_filter, only: :index before_action :set_view, only: :index + before_action :load_content_blocks, only: :index skip_authorization_check only: :json_data @@ -189,6 +190,10 @@ def load_categories @categories = ActsAsTaggableOn::Tag.category.order(:name) end + def load_content_blocks + @heading_content_blocks = @heading.content_blocks.where(locale: I18n.locale) if @heading + end + def tag_cloud TagCloud.new(Budget::Investment, params[:search]) end diff --git a/app/helpers/content_blocks_helper.rb b/app/helpers/content_blocks_helper.rb new file mode 100644 index 00000000000..a2e968c08a4 --- /dev/null +++ b/app/helpers/content_blocks_helper.rb @@ -0,0 +1,9 @@ +module ContentBlocksHelper + def valid_blocks + options = SiteCustomization::ContentBlock::VALID_BLOCKS.map { |key| [t("admin.site_customization.content_blocks.content_block.names.#{key}"), key] } + Budget::Heading.allow_custom_content.each do |heading| + options.push([heading.name, "hcb_#{heading.id}"]) + end + options + end +end diff --git a/app/models/budget/content_block.rb b/app/models/budget/content_block.rb new file mode 100644 index 00000000000..bba830cec3a --- /dev/null +++ b/app/models/budget/content_block.rb @@ -0,0 +1,9 @@ +class Budget + class ContentBlock < ActiveRecord::Base + validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } + validates :heading, presence: true + validates_uniqueness_of :heading, scope: :locale + + belongs_to :heading + end +end diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb index b1e0c6b796d..8f8da50d782 100644 --- a/app/models/budget/heading.rb +++ b/app/models/budget/heading.rb @@ -5,6 +5,7 @@ class Heading < ActiveRecord::Base belongs_to :group has_many :investments + has_many :content_blocks validates :group_id, presence: true validates :name, presence: true, uniqueness: { if: :name_exists_in_budget_headings } @@ -21,6 +22,7 @@ class Heading < ActiveRecord::Base scope :order_by_group_name, -> do includes(:group).order('budget_groups.name DESC', 'budget_headings.name') end + scope :allow_custom_content, -> { where(allow_custom_content: true).order(:name) } def name_scoped_by_group group.single_heading_group? ? name : "#{group.name}: #{name}" diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb index 9987261edc8..c25f4b7d715 100644 --- a/app/views/admin/budgets/_group.html.erb +++ b/app/views/admin/budgets/_group.html.erb @@ -1,7 +1,7 @@ - - - - - - - - - - - - <% end %> + <% if headings.present? %> + + + + + + + + <% end %> + <% if headings.blank? %> - - diff --git a/app/views/admin/budgets/_heading.html.erb b/app/views/admin/budgets/_heading.html.erb index 6cef11c9e32..e06bb96d100 100644 --- a/app/views/admin/budgets/_heading.html.erb +++ b/app/views/admin/budgets/_heading.html.erb @@ -8,6 +8,9 @@ + "); diff --git a/app/views/admin/budget_headings/update.js.erb b/app/views/admin/budget_headings/update.js.erb deleted file mode 100644 index 6466959cde8..00000000000 --- a/app/views/admin/budget_headings/update.js.erb +++ /dev/null @@ -1 +0,0 @@ -$("#<%= dom_id(@budget_group) %>").html('<%= j render("admin/budgets/group", group: @budget_group, headings: @budget_group.headings) %>'); diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb deleted file mode 100644 index c25f4b7d715..00000000000 --- a/app/views/admin/budgets/_group.html.erb +++ /dev/null @@ -1,54 +0,0 @@ -
+ <%= content_tag(:span, group.name, class:"group-toggle-#{group.id}", id:"group-name-#{group.id}") %> <%= render 'admin/budgets/group_form', budget: @budget, group: group, id: "group-form-#{group.id}", button_title: t("admin.budgets.form.submit"), css_class: "group-toggle-#{group.id}" %> @@ -18,31 +18,22 @@ class:"small group-toggle-#{group.id}", id:"max-supportable-heading-label-#{group.id}") %> -
- <%= content_tag(:span, (render 'admin/budgets/max_votable_headings_label', - current: group.max_votable_headings, - max: group.headings.count, - group: group if group.max_votable_headings), - class:"small group-toggle-#{group.id}", - id:"max-votable-heading-label-#{group.id}") %> -
<%= t("admin.budgets.form.table_heading") %><%= t("admin.budgets.form.table_amount") %><%= t("admin.budgets.form.table_population") %><%= t("admin.actions.actions") %>
<%= t("admin.budgets.form.table_heading") %><%= t("admin.budgets.form.table_amount") %><%= t("admin.budgets.form.table_population") %><%= t("admin.budgets.form.table_allow_custom_contents") %><%= t("admin.actions.actions") %>
+
<%= t("admin.budgets.form.no_heading") %>
@@ -51,7 +42,7 @@ <% end %>
<%= heading.population %> + <%= heading.allow_custom_content ? t("true_value") : t("false_value") %> + <%= link_to t("admin.actions.edit"), edit_admin_budget_budget_group_budget_heading_path(budget_id: group.budget.id, budget_group_id: group.id, id: heading.id), diff --git a/app/views/admin/budgets/_heading_form.html.erb b/app/views/admin/budgets/_heading_form.html.erb index a02de44f723..1e6c1af7a26 100644 --- a/app/views/admin/budgets/_heading_form.html.erb +++ b/app/views/admin/budgets/_heading_form.html.erb @@ -48,9 +48,11 @@ -
-
- <%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %> +
+
+ <%= f.check_box :allow_custom_content, label: t('admin.budgets.form.allow_content_block') %>
+ + <%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %> <% end %> diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb index 1286884bcb4..7f7799d2c1c 100644 --- a/app/views/admin/site_customization/content_blocks/_form.html.erb +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -1,35 +1,5 @@ -<%= form_for [:admin, @content_block], html: {class: "edit_page", data: {watch_changes: true}} do |f| %> - - <% if @content_block.errors.any? %> - -
- - - - <%= @content_block.errors.count %> - <%= t("admin.site_customization.content_blocks.errors.form.error", count: @content_block.errors.count) %> - -
- - <% end %> - -
- <%= f.label :name %> - <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS.map { |key| [t("admin.site_customization.content_blocks.content_block.names.#{key}"), key] }, label: false %> -
-
- <%= f.label :locale %> - <%= f.select :locale, I18n.available_locales, label: false %> -
- -
- <%= f.label :body %> - <%= f.text_area :body, label: false, rows: 10 %> -
- <%= f.submit class: "button success expanded" %> -
-
- +<% if @is_heading_content_block %> + <%= render 'form_heading_content_block' %> +<% else %> + <%= render 'form_content_block' %> <% end %> diff --git a/app/views/admin/site_customization/content_blocks/_form_content_block.html.erb b/app/views/admin/site_customization/content_blocks/_form_content_block.html.erb new file mode 100644 index 00000000000..b54861dcac7 --- /dev/null +++ b/app/views/admin/site_customization/content_blocks/_form_content_block.html.erb @@ -0,0 +1,35 @@ +<%= form_for [:admin, @content_block], html: {class: "edit_page", data: {watch_changes: true}} do |f| %> + + <% if @content_block.errors.any? %> + +
+ + + + <%= @content_block.errors.count %> + <%= t("admin.site_customization.content_blocks.errors.form.error", count: @content_block.errors.count) %> + +
+ + <% end %> + +
+ <%= f.label :name %> + <%= f.select :name, options_for_select(valid_blocks, @selected_content_block), label: false %> +
+
+ <%= f.label :locale %> + <%= f.select :locale, I18n.available_locales, label: false %> +
+ +
+ <%= f.label :body %> + <%= f.text_area :body, label: false, rows: 10 %> +
+ <%= f.submit class: "button success expanded" %> +
+
+ +<% end %> diff --git a/app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb b/app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb new file mode 100644 index 00000000000..2d14cd0c9d2 --- /dev/null +++ b/app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb @@ -0,0 +1,29 @@ +<%= form_tag(admin_site_customization_update_heading_content_block_path(@content_block.id), method: "put") do %> + <% if @content_block.errors.any? %> +
+ + + <%= @content_block.errors.count %> + <%= t("admin.site_customization.content_blocks.errors.form.error", count: @content_block.errors.count) %> + +
+ <% end %> + +
+ <%= label_tag :name %> + <%= select_tag :name, options_for_select(valid_blocks, @selected_content_block), label: false %> +
+
+ <%= label_tag :locale %> + <%= select_tag :locale, options_for_select(I18n.available_locales, @content_block.locale.to_sym), label: false %> +
+
+ <%= label_tag :body %> + <%= text_area_tag :body, @content_block.body, rows: 10 %> +
+ <%= button_tag t("admin.menu.site_customization.buttons.content_block.update"), class: "button success expanded" %> +
+
+<% end %> diff --git a/app/views/admin/site_customization/content_blocks/edit.html.erb b/app/views/admin/site_customization/content_blocks/edit.html.erb index d01e4a01b3b..c81a0d11ce9 100644 --- a/app/views/admin/site_customization/content_blocks/edit.html.erb +++ b/app/views/admin/site_customization/content_blocks/edit.html.erb @@ -1,11 +1,11 @@ <% provide :title do %> - <%= t("admin.header.title") %> - <%= t("admin.menu.site_customization.content_blocks") %> - <%= @content_block.name %> (<%= @content_block.locale %>) + <%= t("admin.header.title") %> - <%= t("admin.menu.site_customization.content_blocks") %> - <%= @content_block.try(:name) || @content_block.heading.try(:name) %> (<%= @content_block.locale %>) <% end %> <%= back_link_to admin_site_customization_content_blocks_path %> <%= link_to t("admin.site_customization.content_blocks.index.delete"), - admin_site_customization_content_block_path(@content_block), + (@is_heading_content_block ? admin_site_customization_delete_heading_content_block_path(@content_block.id) : admin_site_customization_content_block_path(@content_block)), method: :delete, class: "delete float-right" %> diff --git a/app/views/admin/site_customization/content_blocks/index.html.erb b/app/views/admin/site_customization/content_blocks/index.html.erb index 66cf5f24100..d779b130c84 100644 --- a/app/views/admin/site_customization/content_blocks/index.html.erb +++ b/app/views/admin/site_customization/content_blocks/index.html.erb @@ -17,7 +17,7 @@

<%= t("admin.site_customization.content_blocks.footer_html") %>

-<% if @content_blocks.any? %> +<% if @content_blocks.any? || @headings_content_blocks.any? %> @@ -38,10 +38,21 @@ <% end %> + <% @headings_content_blocks.each do |content_block| %> + + + + + + <% end %>
<%= link_to "#{content_block.heading.name} (#{content_block.locale})", admin_site_customization_edit_heading_content_block_path(content_block) %><%= content_block.body.html_safe %> + <%= link_to t("admin.site_customization.content_blocks.index.delete"), + admin_site_customization_delete_heading_content_block_path(content_block.id), + method: :delete, class: "button hollow alert" %> +
<% else %>
<%= t("admin.site_customization.content_blocks.no_blocks") %> -
+ <% end %> diff --git a/app/views/budgets/investments/_content_blocks.html.erb b/app/views/budgets/investments/_content_blocks.html.erb new file mode 100644 index 00000000000..b5996bf7a38 --- /dev/null +++ b/app/views/budgets/investments/_content_blocks.html.erb @@ -0,0 +1,9 @@ +<% if @heading.allow_custom_content %> +
+ +
    + <% @heading_content_blocks.each do |content_block| %> + <%= raw content_block.body %> + <% end %> +
+<% end %> diff --git a/app/views/budgets/investments/_sidebar.html.erb b/app/views/budgets/investments/_sidebar.html.erb index 99249a51661..ee402dbe4f3 100644 --- a/app/views/budgets/investments/_sidebar.html.erb +++ b/app/views/budgets/investments/_sidebar.html.erb @@ -23,9 +23,13 @@

<% end %> +<% if @heading && !@heading.content_blocks.where(locale: I18n.locale).empty? %> + <%= render 'budgets/investments/content_blocks' %> +<% end %> <%= render 'budgets/investments/map' %> <%= render 'budgets/investments/categories' %> + <% if @heading && can?(:show, @ballot) %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 47ccc6899ab..27a1cec3dd4 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1,4 +1,6 @@ en: + true_value: 'Yes' + false_value: 'No' admin: header: title: Administration @@ -130,12 +132,14 @@ en: table_heading: Heading table_amount: Amount table_population: Population + table_allow_custom_contents: Custom content allowed population_info: "Budget Heading population field is used for Statistic purposes at the end of the Budget to show for each Heading that represents an area with population what percentage voted. The field is optional so you can leave it empty if it doesn't apply." max_supportable_headings: "Maximum number of headings in which a user can support" max_votable_headings: "Maximum number of headings in which a user can vote" current_of_max_headings: "%{current} of %{max}" latitude: Latitude longitude: Longitude + allow_content_block: Allow content block winners: calculate: Calculate Winner Investments calculated: Winners being calculated, it may take a minute. @@ -607,6 +611,8 @@ en: welcome: "Welcome" buttons: save: "Save" + content_block: + update: "Update Block" title_moderated_content: Moderated content title_budgets: Budgets title_polls: Polls diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 78ef23e42c1..1786fefea31 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1,4 +1,6 @@ es: + true_value: 'Si' + false_value: 'No' admin: header: title: Administración @@ -134,6 +136,7 @@ es: max_supportable_headings: "Máximo número de partidas en que un usuario puede apoyar" max_votable_headings: "Máximo número de partidas en que un usuario puede votar" current_of_max_headings: "%{current} de %{max}" + allow_content_block: Permite bloque de contenidos winners: calculate: Calcular proyectos ganadores calculated: Calculando ganadores, puede tardar un minuto. @@ -604,6 +607,8 @@ es: welcome: "Bienvenido/a" buttons: save: "Guardar cambios" + content_block: + update: "Actualizar Bloque" title_moderated_content: Contenido moderado title_budgets: Presupuestos title_polls: Votaciones diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 03c2fe1dae8..f4a609b6f31 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -222,6 +222,9 @@ resources :pages, except: [:show] resources :images, only: [:index, :update, :destroy] resources :content_blocks, except: [:show] + delete '/heading_content_blocks/:id', to: 'content_blocks#delete_heading_content_block', as: 'delete_heading_content_block' + get '/edit_heading_content_blocks/:id', to: 'content_blocks#edit_heading_content_block', as: 'edit_heading_content_block' + put '/update_heading_content_blocks/:id', to: 'content_blocks#update_heading_content_block', as: 'update_heading_content_block' resources :information_texts, only: [:index] do post :update, on: :collection end diff --git a/db/migrate/20181108103111_add_allow_custom_content_to_headings.rb b/db/migrate/20181108103111_add_allow_custom_content_to_headings.rb new file mode 100644 index 00000000000..cf65b6fa317 --- /dev/null +++ b/db/migrate/20181108103111_add_allow_custom_content_to_headings.rb @@ -0,0 +1,5 @@ +class AddAllowCustomContentToHeadings < ActiveRecord::Migration + def change + add_column :budget_headings, :allow_custom_content, :boolean, default: false + end +end diff --git a/db/migrate/20181108142513_create_heading_content_blocks.rb b/db/migrate/20181108142513_create_heading_content_blocks.rb new file mode 100644 index 00000000000..17db70e8c4b --- /dev/null +++ b/db/migrate/20181108142513_create_heading_content_blocks.rb @@ -0,0 +1,10 @@ +class CreateHeadingContentBlocks < ActiveRecord::Migration + def change + create_table :budget_content_blocks do |t| + t.integer :heading_id, index: true, foreign_key: true + t.text :body + t.string :locale + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index fcf82283f44..3132fb44768 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -174,6 +174,16 @@ t.integer "poll_ballot_id" end + create_table "budget_content_blocks", force: :cascade do |t| + t.integer "heading_id" + t.text "body" + t.string "locale" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "budget_content_blocks", ["heading_id"], name: "index_budget_content_blocks_on_heading_id", using: :btree + create_table "budget_groups", force: :cascade do |t| t.integer "budget_id" t.string "name", limit: 50 @@ -190,6 +200,7 @@ t.integer "price", limit: 8 t.string "slug" t.integer "population" + t.boolean "allow_custom_content", default: false t.text "latitude" t.text "longitude" end diff --git a/spec/factories/budgets.rb b/spec/factories/budgets.rb index b91ca26614b..f1b10167d7e 100644 --- a/spec/factories/budgets.rb +++ b/spec/factories/budgets.rb @@ -237,4 +237,10 @@ factory :valuator_group, class: ValuatorGroup do sequence(:name) { |n| "Valuator Group #{n}" } end + + factory :heading_content_block, class: 'Budget::ContentBlock' do + association :heading, factory: :budget_heading + locale 'en' + body 'Some heading contents' + end end diff --git a/spec/features/admin/site_customization/content_blocks_spec.rb b/spec/features/admin/site_customization/content_blocks_spec.rb index 7bb15fdd02a..f54189049f0 100644 --- a/spec/features/admin/site_customization/content_blocks_spec.rb +++ b/spec/features/admin/site_customization/content_blocks_spec.rb @@ -9,10 +9,13 @@ scenario "Index" do block = create(:site_customization_content_block) + heading_block = create(:heading_content_block) visit admin_site_customization_content_blocks_path expect(page).to have_content(block.name) expect(page).to have_content(block.body) + expect(page).to have_content(heading_block.heading.name) + expect(page).to have_content(heading_block.body) end context "Create" do diff --git a/spec/models/budget/heading_content_block_spec.rb b/spec/models/budget/heading_content_block_spec.rb new file mode 100644 index 00000000000..7dd6c2f391a --- /dev/null +++ b/spec/models/budget/heading_content_block_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +RSpec.describe Budget::ContentBlock do + let(:block) { build(:heading_content_block) } + + it "is valid" do + expect(block).to be_valid + end + + it "Heading is unique per locale" do + heading_content_block_en = create(:heading_content_block, locale: "en") + invalid_block = build(:heading_content_block, heading: heading_content_block_en.heading, locale: "en") + + expect(invalid_block).to be_invalid + expect(invalid_block.errors.full_messages).to include("Heading has already been taken") + + valid_block = build(:heading_content_block, heading: heading_content_block_en.heading, locale: "es") + expect(valid_block).to be_valid + end +end From 16573819baed657ccd22e84bafdc0e4c45ca10a3 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Tue, 11 Dec 2018 18:21:14 +0100 Subject: [PATCH 03/10] apply missing requeriments in PR #3043 In this PR https://github.com/consul/consul/pull/3043 there were some change requests. In order to keep moving we decided to merge the PR and do the changes ourselves. --- .../site_customization/content_blocks/index.html.erb | 2 +- .../budgets/investments/_content_blocks.html.erb | 12 ++++++------ app/views/budgets/investments/_sidebar.html.erb | 1 - config/locales/en/admin.yml | 4 ++-- config/locales/es/admin.yml | 4 ++-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/views/admin/site_customization/content_blocks/index.html.erb b/app/views/admin/site_customization/content_blocks/index.html.erb index d779b130c84..ccc13bcf23b 100644 --- a/app/views/admin/site_customization/content_blocks/index.html.erb +++ b/app/views/admin/site_customization/content_blocks/index.html.erb @@ -54,5 +54,5 @@ <% else %>
<%= t("admin.site_customization.content_blocks.no_blocks") %> - +
<% end %> diff --git a/app/views/budgets/investments/_content_blocks.html.erb b/app/views/budgets/investments/_content_blocks.html.erb index b5996bf7a38..de86b50fe69 100644 --- a/app/views/budgets/investments/_content_blocks.html.erb +++ b/app/views/budgets/investments/_content_blocks.html.erb @@ -1,9 +1,9 @@ <% if @heading.allow_custom_content %> -
+
-
    - <% @heading_content_blocks.each do |content_block| %> - <%= raw content_block.body %> - <% end %> -
+
    + <% @heading_content_blocks.each do |content_block| %> + <%= raw content_block.body %> + <% end %> +
<% end %> diff --git a/app/views/budgets/investments/_sidebar.html.erb b/app/views/budgets/investments/_sidebar.html.erb index ee402dbe4f3..28a032e71fb 100644 --- a/app/views/budgets/investments/_sidebar.html.erb +++ b/app/views/budgets/investments/_sidebar.html.erb @@ -29,7 +29,6 @@ <%= render 'budgets/investments/map' %> <%= render 'budgets/investments/categories' %> - <% if @heading && can?(:show, @ballot) %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 27a1cec3dd4..118340378f8 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1,6 +1,4 @@ en: - true_value: 'Yes' - false_value: 'No' admin: header: title: Administration @@ -1149,6 +1147,8 @@ en: setting_value: Value no_description: "No description" shared: + true_value: "Yes" + false_value: "No" booths_search: button: Search placeholder: Search booth by name diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 1786fefea31..dcfb677e06f 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1,6 +1,4 @@ es: - true_value: 'Si' - false_value: 'No' admin: header: title: Administración @@ -1145,6 +1143,8 @@ es: setting_value: Valor no_description: "Sin descripción" shared: + true_value: "Sí" + false_value: "No" booths_search: button: Buscar placeholder: Buscar urna por nombre From 795fd1942e4c6e969f7e7dd7ee2ddbbf00598eef Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Wed, 12 Dec 2018 11:00:16 +0100 Subject: [PATCH 04/10] change coordinates to make the map to be centered in Madrid --- db/dev_seeds/budgets.rb | 20 ++++++++++---------- spec/factories/budgets.rb | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/db/dev_seeds/budgets.rb b/db/dev_seeds/budgets.rb index 0558263bb4b..1e2a92d391b 100644 --- a/db/dev_seeds/budgets.rb +++ b/db/dev_seeds/budgets.rb @@ -42,30 +42,30 @@ def add_image_to(imageable) city_group.headings.create!(name: I18n.t('seeds.budgets.groups.all_city'), price: 1000000, population: 1000000, - latitude: '-40.123241', - longitude: '25.123249') + latitude: '40.416775', + longitude: '-3.703790') districts_group = budget.groups.create!(name: I18n.t('seeds.budgets.groups.districts')) districts_group.headings.create!(name: I18n.t('seeds.geozones.north_district'), price: rand(5..10) * 100000, population: 350000, - latitude: '15.234521', - longitude: '-15.234234') + latitude: '40.416775', + longitude: '-3.703790') districts_group.headings.create!(name: I18n.t('seeds.geozones.west_district'), price: rand(5..10) * 100000, population: 300000, - latitude: '14.125125', - longitude: '65.123124') + latitude: '40.416775', + longitude: '-3.703790') districts_group.headings.create!(name: I18n.t('seeds.geozones.east_district'), price: rand(5..10) * 100000, population: 200000, - latitude: '23.234234', - longitude: '-47.134124') + latitude: '40.416775', + longitude: '-3.703790') districts_group.headings.create!(name: I18n.t('seeds.geozones.central_district'), price: rand(5..10) * 100000, population: 150000, - latitude: '-26.133213', - longitude: '-10.123231') + latitude: '40.416775', + longitude: '-3.703790') end end diff --git a/spec/factories/budgets.rb b/spec/factories/budgets.rb index f1b10167d7e..128e95f1daf 100644 --- a/spec/factories/budgets.rb +++ b/spec/factories/budgets.rb @@ -94,8 +94,8 @@ sequence(:name) { |n| "Heading #{n}" } price 1000000 population 1234 - latitude '-25.172741' - longitude '40.127241' + latitude '40.416775' + longitude '-3.703790' trait :drafting_budget do association :group, factory: [:budget_group, :drafting_budget] From 279feead6f83921b1cf4a8c17f0a9ca8cba2af68 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Thu, 13 Dec 2018 10:00:54 +0100 Subject: [PATCH 05/10] fix map rendering for budget headings --- app/assets/stylesheets/layout.scss | 7 +++++++ .../budgets/investments_controller.rb | 7 +------ app/models/budget/heading.rb | 6 ++++-- app/models/map_location.rb | 8 ++++++++ app/views/budgets/ballot/lines/create.js.erb | 2 ++ app/views/budgets/ballot/lines/destroy.js.erb | 2 ++ app/views/budgets/investments/_map.html.erb | 6 +++--- .../budgets/investments/_sidebar.html.erb | 4 +++- app/views/custom/budgets/index.html.erb | 2 +- spec/features/budgets/investments_spec.rb | 16 +++++++++++++++ spec/models/budget/heading_spec.rb | 20 ++++++------------- 11 files changed, 53 insertions(+), 27 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 9f101725c00..74e9180474f 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -887,6 +887,13 @@ footer { } } +.sidebar-map { + + .map { + z-index: -1; + } +} + .sidebar-title { border-top: 2px solid $brand; display: inline-block; diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index e0da9ce6cb2..40ba8abb19e 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -1,7 +1,5 @@ module Budgets class InvestmentsController < ApplicationController - OSM_DISTRICT_LEVEL_ZOOM = 12 - include FeatureFlags include CommentableActions include FlagActions @@ -218,10 +216,7 @@ def investments end def load_map - @map_location = MapLocation.new - @map_location.zoom = OSM_DISTRICT_LEVEL_ZOOM - @map_location.latitude = @heading.latitude.to_f - @map_location.longitude = @heading.longitude.to_f + @map_location = MapLocation.load_from_heading(@heading) end end diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb index 8f8da50d782..900ca029592 100644 --- a/app/models/budget/heading.rb +++ b/app/models/budget/heading.rb @@ -1,5 +1,7 @@ class Budget class Heading < ActiveRecord::Base + OSM_DISTRICT_LEVEL_ZOOM = 12.freeze + include Sluggable belongs_to :group @@ -12,9 +14,9 @@ class Heading < ActiveRecord::Base validates :price, presence: true validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/ validates :population, numericality: { greater_than: 0 }, allow_nil: true - validates :latitude, length: { maximum: 22, minimum: 1 }, presence: true, \ + validates :latitude, length: { maximum: 22 }, allow_blank: true, \ format: /\A(-|\+)?([1-8]?\d(?:\.\d{1,})?|90(?:\.0{1,6})?)\z/ - validates :longitude, length: { maximum: 22, minimum: 1}, presence: true, \ + validates :longitude, length: { maximum: 22 }, allow_blank: true, \ format: /\A(-|\+)?((?:1[0-7]|[1-9])?\d(?:\.\d{1,})?|180(?:\.0{1,})?)\z/ delegate :budget, :budget_id, to: :group, allow_nil: true diff --git a/app/models/map_location.rb b/app/models/map_location.rb index f66d71e349d..d141c167d45 100644 --- a/app/models/map_location.rb +++ b/app/models/map_location.rb @@ -18,4 +18,12 @@ def json_data } end + def self.load_from_heading(heading) + map = new + map.zoom = Budget::Heading::OSM_DISTRICT_LEVEL_ZOOM + map.latitude = heading.latitude.to_f if heading.latitude.present? + map.longitude = heading.longitude.to_f if heading.latitude.present? + map + end + end diff --git a/app/views/budgets/ballot/lines/create.js.erb b/app/views/budgets/ballot/lines/create.js.erb index b1c9f76bef2..6edf8a0f282 100644 --- a/app/views/budgets/ballot/lines/create.js.erb +++ b/app/views/budgets/ballot/lines/create.js.erb @@ -9,3 +9,5 @@ $("#<%= dom_id(@investment) %>_ballot").html('<%= j render("/budgets/investments investment: @investment, investment_ids: @investment_ids, ballot: @ballot %> + +App.Map.initialize(); diff --git a/app/views/budgets/ballot/lines/destroy.js.erb b/app/views/budgets/ballot/lines/destroy.js.erb index 82c3030471d..94120d3a9af 100644 --- a/app/views/budgets/ballot/lines/destroy.js.erb +++ b/app/views/budgets/ballot/lines/destroy.js.erb @@ -10,3 +10,5 @@ $("#<%= dom_id(@investment) %>_ballot").html('<%= j render("/budgets/investments investment: @investment, investment_ids: @investment_ids, ballot: @ballot %> + +App.Map.initialize(); diff --git a/app/views/budgets/investments/_map.html.erb b/app/views/budgets/investments/_map.html.erb index af04ef639a3..37aa50f6721 100644 --- a/app/views/budgets/investments/_map.html.erb +++ b/app/views/budgets/investments/_map.html.erb @@ -2,7 +2,7 @@
diff --git a/app/views/budgets/investments/_sidebar.html.erb b/app/views/budgets/investments/_sidebar.html.erb index 28a032e71fb..f215e3cd914 100644 --- a/app/views/budgets/investments/_sidebar.html.erb +++ b/app/views/budgets/investments/_sidebar.html.erb @@ -26,7 +26,9 @@ <% if @heading && !@heading.content_blocks.where(locale: I18n.locale).empty? %> <%= render 'budgets/investments/content_blocks' %> <% end %> -<%= render 'budgets/investments/map' %> +<% if @map_location&.available? %> + <%= render 'budgets/investments/map' %> +<% end %> <%= render 'budgets/investments/categories' %> <% if @heading && can?(:show, @ballot) %> diff --git a/app/views/custom/budgets/index.html.erb b/app/views/custom/budgets/index.html.erb index 2a07ef58321..3ab7902ebc7 100644 --- a/app/views/custom/budgets/index.html.erb +++ b/app/views/custom/budgets/index.html.erb @@ -100,7 +100,7 @@ <% unless current_budget.informing? %> <% cache [@budgets_coordinates] do %> -
+

<%= t("budgets.index.map") %>

<%= render_map(nil, "budgets", false, nil, @budgets_coordinates) %>
diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 21dbaaaa71a..361148e05cf 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -95,6 +95,22 @@ Setting['feature.allow_images'] = nil end + scenario 'Index should show a map if heading has coordinates defined', :js do + create(:budget_investment, heading: heading) + visit budget_investments_path(budget, heading_id: heading.id) + within("#sidebar") do + expect(page).to have_css(".map_location") + end + + unlocated_heading = create(:budget_heading, name: "No Map", price: 500, group: group, + longitude: nil, latitude: nil) + create(:budget_investment, heading: unlocated_heading) + visit budget_investments_path(budget, heading_id: unlocated_heading.id) + within("#sidebar") do + expect(page).not_to have_css(".map_location") + end + end + context("Search") do scenario 'Search by text' do diff --git a/spec/models/budget/heading_spec.rb b/spec/models/budget/heading_spec.rb index edd96a8b840..816d7507efb 100644 --- a/spec/models/budget/heading_spec.rb +++ b/spec/models/budget/heading_spec.rb @@ -7,6 +7,12 @@ it_behaves_like "sluggable", updatable_slug_trait: :drafting_budget + describe "::OSM_DISTRICT_LEVEL_ZOOM" do + it "should be defined" do + expect(Budget::Heading::OSM_DISTRICT_LEVEL_ZOOM).to be 12 + end + end + describe "name" do before do create(:budget_heading, group: group, name: 'object name') @@ -45,13 +51,6 @@ end describe "save latitude" do - it "Doesn't allow latitude == nil" do - expect(build(:budget_heading, group: group, name: 'Latitude is nil', population: 12412512, latitude: nil, longitude: '12.123412')).not_to be_valid - end - - it "Doesn't allow latitude == ''" do - expect(build(:budget_heading, group: group, name: 'Latitude is an empty string', population: 12412512, latitude: '', longitude: '12.123412')).not_to be_valid - end it "Doesn't allow latitude < -90" do heading = create(:budget_heading, group: group, name: 'Latitude is < -90') @@ -150,13 +149,6 @@ describe "save longitude" do - it "Doesn't allow longitude == nil" do - expect(build(:budget_heading, group: group, name: 'Longitude is nil', population: 12412512, latitude: '12.123412', longitude: nil)).not_to be_valid - end - - it "Doesn't allow longitude == ''" do - expect(build(:budget_heading, group: group, name: 'Longitude is an empty string', population: 12412512, latitude: '12.127412', longitude: '')).not_to be_valid - end it "Doesn't allow longitude < -180" do heading = create(:budget_heading, group: group, name: 'Longitude is < -180') From 8b57df6d4ec56b67d288cde0421b254a7a3ed62e Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Thu, 13 Dec 2018 10:03:30 +0100 Subject: [PATCH 06/10] cleanup (due to new CRUD for budget groups and headings) --- app/helpers/admin_helper.rb | 4 -- app/views/admin/budget_groups/create.js.erb | 2 - app/views/admin/budget_groups/update.js.erb | 8 --- .../admin/budget_headings/_errors.html.erb | 7 --- app/views/admin/budget_headings/create.js.erb | 2 - app/views/admin/budget_headings/edit.js.erb | 1 - app/views/admin/budget_headings/update.js.erb | 1 - app/views/admin/budgets/_group.html.erb | 54 ----------------- app/views/admin/budgets/_group_form.html.erb | 41 ------------- app/views/admin/budgets/_groups.html.erb | 21 ------- app/views/admin/budgets/_heading.html.erb | 27 --------- .../admin/budgets/_heading_form.html.erb | 58 ------------------- .../budgets/_max_headings_label.html.erb | 2 - .../_max_supportable_headings_label.html.erb | 3 - .../_max_votable_headings_label.html.erb | 3 - 15 files changed, 234 deletions(-) delete mode 100644 app/views/admin/budget_groups/create.js.erb delete mode 100644 app/views/admin/budget_groups/update.js.erb delete mode 100644 app/views/admin/budget_headings/_errors.html.erb delete mode 100644 app/views/admin/budget_headings/create.js.erb delete mode 100644 app/views/admin/budget_headings/edit.js.erb delete mode 100644 app/views/admin/budget_headings/update.js.erb delete mode 100644 app/views/admin/budgets/_group.html.erb delete mode 100644 app/views/admin/budgets/_group_form.html.erb delete mode 100644 app/views/admin/budgets/_groups.html.erb delete mode 100644 app/views/admin/budgets/_heading.html.erb delete mode 100644 app/views/admin/budgets/_heading_form.html.erb delete mode 100644 app/views/admin/budgets/_max_headings_label.html.erb delete mode 100644 app/views/admin/budgets/_max_supportable_headings_label.html.erb delete mode 100644 app/views/admin/budgets/_max_votable_headings_label.html.erb diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 5632ef2c7bc..cf673e1564d 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -90,10 +90,6 @@ def display_user_roles(user) user_roles(user).join(", ") end - def display_budget_goup_form(group) - group.errors.messages.size > 0 ? "" : "display:none" - end - private def namespace diff --git a/app/views/admin/budget_groups/create.js.erb b/app/views/admin/budget_groups/create.js.erb deleted file mode 100644 index cb926a7c677..00000000000 --- a/app/views/admin/budget_groups/create.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$("#<%= dom_id(@budget) %>_groups").html('<%= j render("admin/budgets/groups", groups: @groups) %>'); -App.Forms.toggleLink(); \ No newline at end of file diff --git a/app/views/admin/budget_groups/update.js.erb b/app/views/admin/budget_groups/update.js.erb deleted file mode 100644 index a2b66ac1b1d..00000000000 --- a/app/views/admin/budget_groups/update.js.erb +++ /dev/null @@ -1,8 +0,0 @@ -<% if @group.errors.any? %> - $("#group-form-<%= @group.id %>").html('<%= j render("admin/budgets/group_form", group: @group, budget: @group.budget, button_title: t("admin.budgets.form.submit"), id: "group-form-#{@group.id}", css_class: "group-toggle-#{@group.id}" ) %>'); -<% else %> - $("#group-name-<%= @group.id %>").html('<%= @group.name %>') - $("#max-supportable-heading-label-<%=@group.id%>").html('<%= j render("admin/budgets/max_supportable_headings_label", current: @group.max_supportable_headings, max: @group.headings.count, group: @group) %>') - $("#max-votable-heading-label-<%=@group.id%>").html('<%= j render("admin/budgets/max_votable_headings_label", current: @group.max_votable_headings, max: @group.headings.count, group: @group) %>') - $(".group-toggle-<%= @group.id %>").toggle() -<% end %> diff --git a/app/views/admin/budget_headings/_errors.html.erb b/app/views/admin/budget_headings/_errors.html.erb deleted file mode 100644 index bb3e5482edd..00000000000 --- a/app/views/admin/budget_headings/_errors.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -
-
    - <% errors.each do |error| %> -
  • <%= error %>
  • - <% end %> -
-
diff --git a/app/views/admin/budget_headings/create.js.erb b/app/views/admin/budget_headings/create.js.erb deleted file mode 100644 index 5d8eefb2d63..00000000000 --- a/app/views/admin/budget_headings/create.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$("#<%= dom_id(@budget_group) %>").html('<%= j render("admin/budgets/group", group: @budget_group, headings: @headings) %>'); -App.Forms.toggleLink(); \ No newline at end of file diff --git a/app/views/admin/budget_headings/edit.js.erb b/app/views/admin/budget_headings/edit.js.erb deleted file mode 100644 index 5f9ac48f89d..00000000000 --- a/app/views/admin/budget_headings/edit.js.erb +++ /dev/null @@ -1 +0,0 @@ -$("#heading-<%=@heading.id%>").html("
<%= j render("admin/budgets/heading_form", group: @budget_group, budget: @budget, heading: @heading) %>
- - - - - <% if headings.present? %> - - - - - - - - - <% end %> - - - - - <% if headings.blank? %> - - - - <% end %> - - - - - - <% headings.each do |heading| %> - <%= render "admin/budgets/heading", group: group, budget: @budget, heading: heading %> - <% end %> - -
- <%= content_tag(:span, group.name, class:"group-toggle-#{group.id}", id:"group-name-#{group.id}") %> - - <%= render 'admin/budgets/group_form', budget: @budget, group: group, id: "group-form-#{group.id}", button_title: t("admin.budgets.form.submit"), css_class: "group-toggle-#{group.id}" %> - <%= link_to t("admin.budgets.form.edit_group"), "#", class: "button float-right js-toggle-link hollow", data: { "toggle-selector" => ".group-toggle-#{group.id}" } %> - <%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %> -
- <%= content_tag(:span, (render 'admin/budgets/max_supportable_headings_label', - current: group.max_supportable_headings, - max: group.headings.count, group: group if group.max_supportable_headings), - class:"small group-toggle-#{group.id}", - id:"max-supportable-heading-label-#{group.id}") %> - - <% if headings.present? %> -
<%= t("admin.budgets.form.table_heading") %><%= t("admin.budgets.form.table_amount") %><%= t("admin.budgets.form.table_population") %><%= t("admin.budgets.form.table_allow_custom_contents") %><%= t("admin.actions.actions") %>
-
- <%= t("admin.budgets.form.no_heading") %> -
-
diff --git a/app/views/admin/budgets/_group_form.html.erb b/app/views/admin/budgets/_group_form.html.erb deleted file mode 100644 index 2f40258f24f..00000000000 --- a/app/views/admin/budgets/_group_form.html.erb +++ /dev/null @@ -1,41 +0,0 @@ -<%= form_for [:admin, budget, group], html: {id: id, style: display_budget_goup_form(group), class: css_class}, remote: true do |f| %> -
-
- <%= f.label :name, t("admin.budgets.form.group") %> - - <%= f.text_field :name, - label: false, - maxlength: 50, - placeholder: t("admin.budgets.form.group"), - class: "input-group-field" %> -
-
- <% if group.persisted? %> -
-
- <%= f.label :name, t("admin.budgets.form.max_supportable_headings") %> - - <%= f.select :max_supportable_headings, - (1..group.headings.count), - label: false, - placeholder: t("admin.budgets.form.max_supportable_headings"), - class: "input-group-field" %> -
- -
- <%= f.label :name, t("admin.budgets.form.max_votable_headings") %> - - <%= f.select :max_votable_headings, - (1..group.headings.count), - label: false, - placeholder: t("admin.budgets.form.max_votable_headings") %> -
-
- <% end %> - -
-
- <%= f.submit button_title, class: "button success" %> -
-
-<% end %> diff --git a/app/views/admin/budgets/_groups.html.erb b/app/views/admin/budgets/_groups.html.erb deleted file mode 100644 index dbee9576c7f..00000000000 --- a/app/views/admin/budgets/_groups.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -

<%= t('admin.budgets.show.groups', count: groups.count) %>

-<%= link_to t("admin.budgets.form.add_group"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#new-group-form" } %> - -<% if groups.blank? %> -
- <%= t("admin.budgets.form.no_groups") %> -
-<% end %> - -<%= render 'admin/budgets/group_form', - budget: @budget, - group: Budget::Group.new, - id: "new-group-form", - button_title: t("admin.budgets.form.create_group"), - css_class: '' %> - -<% groups.each do |group| %> -
- <%= render "admin/budgets/group", group: group, headings: group.headings.order(:id) %> -
-<% end %> diff --git a/app/views/admin/budgets/_heading.html.erb b/app/views/admin/budgets/_heading.html.erb deleted file mode 100644 index e06bb96d100..00000000000 --- a/app/views/admin/budgets/_heading.html.erb +++ /dev/null @@ -1,27 +0,0 @@ - - - <%= heading.name %> - - - <%= heading.budget.formatted_heading_price(heading) %> - - - <%= heading.population %> - - - <%= heading.allow_custom_content ? t("true_value") : t("false_value") %> - - - <%= link_to t("admin.actions.edit"), - edit_admin_budget_budget_group_budget_heading_path(budget_id: group.budget.id, budget_group_id: group.id, id: heading.id), - class: "button hollow", - remote: true %> - <% if heading.can_be_deleted? %> - <%= link_to t('admin.administrators.administrator.delete'), - #admin_budget_budget_group_budget_headings_path(group.budget.id, group.id), - [:admin, group.budget, group, heading], - method: :delete, - class: "button hollow alert" %> - <% end %> - - diff --git a/app/views/admin/budgets/_heading_form.html.erb b/app/views/admin/budgets/_heading_form.html.erb deleted file mode 100644 index 1e6c1af7a26..00000000000 --- a/app/views/admin/budgets/_heading_form.html.erb +++ /dev/null @@ -1,58 +0,0 @@ -<%= form_for [:admin, budget, group, heading], remote: true do |f| %> - <%= render 'shared/errors', resource: heading %> - <%= f.text_field :name, - label: t("admin.budgets.form.heading"), - maxlength: 50, - placeholder: t("admin.budgets.form.heading") %> - -
-
- <%= f.text_field :price, - label: t("admin.budgets.form.amount"), - maxlength: 8, - placeholder: t("admin.budgets.form.amount") %> -
-
-
-
-

- <%= t("admin.budgets.form.population_help_text") %> -

- <%= f.text_field :population, - label: t("admin.budgets.form.population"), - maxlength: 8, - placeholder: t("admin.budgets.form.population"), - aria: {describedby: "budgets-population-help-text"} %> -
- -
-
- <%= t("admin.budgets.form.population_info") %> -
-
-
-
-
- <%= f.text_field :latitude, - label: t("admin.budgets.form.latitude"), - maxlength: 22, - placeholder: "latitude" %> -
-
-
-
- <%= f.text_field :longitude, - label: t("admin.budgets.form.longitude"), - maxlength: 22, - placeholder: "longitude" %> -
-
- -
-
- <%= f.check_box :allow_custom_content, label: t('admin.budgets.form.allow_content_block') %> -
-
- - <%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %> -<% end %> diff --git a/app/views/admin/budgets/_max_headings_label.html.erb b/app/views/admin/budgets/_max_headings_label.html.erb deleted file mode 100644 index f2c438d4f1d..00000000000 --- a/app/views/admin/budgets/_max_headings_label.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<%= t("admin.budgets.form.max_votable_headings")%> -<%= t("admin.budgets.form.current_of_max_headings", current: current, max: max) %> diff --git a/app/views/admin/budgets/_max_supportable_headings_label.html.erb b/app/views/admin/budgets/_max_supportable_headings_label.html.erb deleted file mode 100644 index deac8eddfd1..00000000000 --- a/app/views/admin/budgets/_max_supportable_headings_label.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= t("admin.budgets.form.max_supportable_headings")%> -<%= content_tag(:strong, - t("admin.budgets.form.current_of_max_headings", current: current, max: max )) %> diff --git a/app/views/admin/budgets/_max_votable_headings_label.html.erb b/app/views/admin/budgets/_max_votable_headings_label.html.erb deleted file mode 100644 index 12d3e352973..00000000000 --- a/app/views/admin/budgets/_max_votable_headings_label.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= t("admin.budgets.form.max_votable_headings")%> -<%= content_tag(:strong, - t("admin.budgets.form.current_of_max_headings", current: current, max: max)) %> From d300dae9f9ed4b6db67315785a15a73f1b591cb3 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Thu, 13 Dec 2018 10:34:01 +0100 Subject: [PATCH 07/10] change CRUD for budget groups and headings To make it more consistent with the rest of the Admin panel, the CRUD for budget groups and headings has been changed from the old "all-in-one" form to a separate form for each resource. --- .../admin/budget_groups_controller.rb | 52 ++++- .../admin/budget_headings_controller.rb | 52 +++-- app/controllers/admin/budgets_controller.rb | 6 +- .../budgets/ballot/lines_controller.rb | 8 + app/views/admin/budget_groups/_form.html.erb | 18 ++ .../admin/budget_groups/_header.html.erb | 5 + app/views/admin/budget_groups/edit.html.erb | 3 + app/views/admin/budget_groups/index.html.erb | 44 ++++ app/views/admin/budget_groups/new.html.erb | 3 + .../admin/budget_headings/_form.html.erb | 40 ++++ .../admin/budget_headings/_header.html.erb | 5 + app/views/admin/budget_headings/edit.html.erb | 3 + .../admin/budget_headings/index.html.erb | 47 ++++ app/views/admin/budget_headings/new.html.erb | 3 + app/views/admin/budgets/index.html.erb | 4 +- app/views/admin/budgets/show.html.erb | 4 +- config/locales/en/admin.yml | 75 ++++--- config/locales/es/admin.yml | 72 +++--- config/routes/admin.rb | 4 +- spec/features/admin/budget_groups_spec.rb | 200 ++++++++++------- spec/features/admin/budget_headings_spec.rb | 208 ++++++++++++++++++ spec/features/admin/budgets_spec.rb | 103 --------- spec/features/budgets/ballots_spec.rb | 28 +++ 23 files changed, 719 insertions(+), 268 deletions(-) create mode 100644 app/views/admin/budget_groups/_form.html.erb create mode 100644 app/views/admin/budget_groups/_header.html.erb create mode 100644 app/views/admin/budget_groups/edit.html.erb create mode 100644 app/views/admin/budget_groups/index.html.erb create mode 100644 app/views/admin/budget_groups/new.html.erb create mode 100644 app/views/admin/budget_headings/_form.html.erb create mode 100644 app/views/admin/budget_headings/_header.html.erb create mode 100644 app/views/admin/budget_headings/edit.html.erb create mode 100644 app/views/admin/budget_headings/index.html.erb create mode 100644 app/views/admin/budget_headings/new.html.erb create mode 100644 spec/features/admin/budget_headings_spec.rb diff --git a/app/controllers/admin/budget_groups_controller.rb b/app/controllers/admin/budget_groups_controller.rb index d77d44f9dff..1e452934017 100644 --- a/app/controllers/admin/budget_groups_controller.rb +++ b/app/controllers/admin/budget_groups_controller.rb @@ -2,25 +2,61 @@ class Admin::BudgetGroupsController < Admin::BaseController include FeatureFlags feature_flag :budgets before_action :load_budget + before_action :load_group, except: [:index, :new, :create] + + def index + @groups = @budget.groups.order(:id) + end + + def new + @group = @budget.groups.new + end + + def edit + end def create - @budget.groups.create(budget_group_params) - @groups = @budget.groups.includes(:headings) + @group = @budget.groups.new(budget_group_params) + if @group.save + redirect_to groups_index, notice: t("admin.budget_groups.create.notice") + else + render :new + end end def update - @group = @budget.groups.by_slug(params[:id]).first - @group.update(budget_group_params) + if @group.update(budget_group_params) + redirect_to groups_index, notice: t("admin.budget_groups.update.notice") + else + render :edit + end end - private - - def budget_group_params - params.require(:budget_group).permit(:name, :max_votable_headings, :max_supportable_headings) + def destroy + if @group.headings.any? + redirect_to groups_index, alert: t("admin.budget_groups.destroy.unable_notice") + else + @group.destroy + redirect_to groups_index, notice: t("admin.budget_groups.destroy.success_notice") end + end + + private def load_budget @budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) end + def load_group + @group = @budget.groups.find_by(slug: params[:id]) || @budget.groups.find_by(id: params[:id]) + end + + def groups_index + admin_budget_groups_path(@budget) + end + + def budget_group_params + params.require(:budget_group).permit(:name, :max_votable_headings, :max_supportable_headings) + end + end diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb index b0c8db3947d..e5b5762dded 100644 --- a/app/controllers/admin/budget_headings_controller.rb +++ b/app/controllers/admin/budget_headings_controller.rb @@ -4,41 +4,65 @@ class Admin::BudgetHeadingsController < Admin::BaseController before_action :load_budget before_action :load_group - before_action :load_heading + before_action :load_heading, except: [:index, :new, :create] - def create - @budget_group.headings.create(budget_heading_params) - @headings = @budget_group.headings + def index + @headings = @group.headings.order(:id) + end + + def new + @heading = @group.headings.new end def edit end + def create + @heading = @group.headings.new(budget_heading_params) + if @heading.save + redirect_to headings_index, notice: t('admin.budget_headings.create.notice') + else + render :new + end + end + def update - @heading.assign_attributes(budget_heading_params) - render :edit unless @heading.save + if @heading.update(budget_heading_params) + redirect_to headings_index, notice: t('admin.budget_headings.update.notice') + else + render :edit + end end def destroy - @heading.destroy - redirect_to admin_budget_path(@budget) + if @heading.can_be_deleted? + @heading.destroy + redirect_to headings_index, notice: t('admin.budget_headings.destroy.success_notice') + else + redirect_to headings_index, alert: t('admin.budget_headings.destroy.unable_notice') + end end private - def budget_heading_params - params.require(:budget_heading).permit(:name, :price, :population, :allow_custom_content, :latitude, :longitude) - end - def load_budget @budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) end def load_group - @budget_group = @budget.groups.find_by(slug: params[:budget_group_id]) || @budget.groups.find_by(id: params[:budget_group_id]) + @group = @budget.groups.find_by(slug: params[:group_id]) || @budget.groups.find_by(id: params[:group_id]) end def load_heading - @heading = @budget_group.headings.find_by(slug: params[:id]) || @budget_group.headings.find_by(id: params[:id]) + @heading = @group.headings.find_by(slug: params[:id]) || @group.headings.find_by(id: params[:id]) + end + + def headings_index + admin_budget_group_headings_path(@budget, @group) end + + def budget_heading_params + params.require(:budget_heading).permit(:name, :price, :population, :allow_custom_content, :latitude, :longitude) + end + end diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb index 0b9ab2bb7ed..f31f877083a 100644 --- a/app/controllers/admin/budgets_controller.rb +++ b/app/controllers/admin/budgets_controller.rb @@ -14,9 +14,11 @@ def index def show end - def new; end + def new + end - def edit; end + def edit + end def calculate_winners return unless @budget.balloting_process? diff --git a/app/controllers/budgets/ballot/lines_controller.rb b/app/controllers/budgets/ballot/lines_controller.rb index 7d78c7aa76a..06eca5229fe 100644 --- a/app/controllers/budgets/ballot/lines_controller.rb +++ b/app/controllers/budgets/ballot/lines_controller.rb @@ -16,6 +16,7 @@ class LinesController < ApplicationController def create load_investment load_heading + load_map @ballot.add_investment(@investment) end @@ -23,6 +24,7 @@ def create def destroy @investment = @line.investment load_heading + load_map @line.destroy load_investments @@ -69,6 +71,12 @@ def load_ballot_referer @ballot_referer = session[:ballot_referer] end + def load_map + @investments ||= [] + @investments_map_coordinates = MapLocation.where(investment: @investments).map(&:json_data) + @map_location = MapLocation.load_from_heading(@heading) + end + end end end diff --git a/app/views/admin/budget_groups/_form.html.erb b/app/views/admin/budget_groups/_form.html.erb new file mode 100644 index 00000000000..5da9493d80b --- /dev/null +++ b/app/views/admin/budget_groups/_form.html.erb @@ -0,0 +1,18 @@ +
+ <%= form_for [:admin, @budget, @group], url: path do |f| %> + + <%= f.text_field :name, + label: t("admin.budget_groups.form.name"), + maxlength: 50, + placeholder: t("admin.budget_groups.form.name") %> + + <% if @group.persisted? %> + <%= f.select :max_votable_headings, + (1..@group.headings.count), + label: t("admin.budget_groups.max_votable_headings"), + placeholder: t("admin.budget_groups.max_votable_headings") %> + <% end %> + + <%= f.submit t("admin.budget_groups.form.#{action}"), class: "button success" %> + <% end %> +
diff --git a/app/views/admin/budget_groups/_header.html.erb b/app/views/admin/budget_groups/_header.html.erb new file mode 100644 index 00000000000..32962bd9325 --- /dev/null +++ b/app/views/admin/budget_groups/_header.html.erb @@ -0,0 +1,5 @@ +<%= back_link_to admin_budget_groups_path(@budget) %> + +

<%= @budget.name %>

+ +

<%= t("admin.budget_groups.form.#{action}") %>

diff --git a/app/views/admin/budget_groups/edit.html.erb b/app/views/admin/budget_groups/edit.html.erb new file mode 100644 index 00000000000..4ed1ad7f976 --- /dev/null +++ b/app/views/admin/budget_groups/edit.html.erb @@ -0,0 +1,3 @@ +<%= render "header", action: "edit" %> + +<%= render "form", path: admin_budget_group_path(@budget, @group), action: "edit" %> diff --git a/app/views/admin/budget_groups/index.html.erb b/app/views/admin/budget_groups/index.html.erb new file mode 100644 index 00000000000..44257d87d63 --- /dev/null +++ b/app/views/admin/budget_groups/index.html.erb @@ -0,0 +1,44 @@ +

<%= @budget.name %>

+ +<%= link_to t("admin.budget_groups.form.create"), + new_admin_budget_group_path, + class: "button float-right" %> + +<% if @groups.any? %> +

<%= t("admin.budget_groups.amount", count: @groups.count) %>

+ + + + + + + + + + + + <% @groups.each do |group| %> + + + + + + + + <% end %> + +
<%= t("admin.budget_groups.name") %><%= t("admin.budget_groups.max_votable_headings") %><%= t("admin.budget_groups.headings_name") %><%= t("admin.budget_groups.headings_edit") %><%= t("admin.actions.actions") %>
<%= link_to group.name, edit_admin_budget_group_path(@budget, group) %><%= group.max_votable_headings %><%= group.headings.count %><%= link_to t("admin.budget_groups.headings_manage"), + admin_budget_group_headings_path(@budget, group) %> + <%= link_to t("admin.actions.edit"), + edit_admin_budget_group_path(@budget, group), + class: "button hollow" %> + <%= link_to t("admin.actions.delete"), + admin_budget_group_path(@budget, group), + method: :delete, + class: "button hollow alert" %> +
+<% else %> +
+ <%= t("admin.budget_groups.no_groups") %> +
+<% end %> diff --git a/app/views/admin/budget_groups/new.html.erb b/app/views/admin/budget_groups/new.html.erb new file mode 100644 index 00000000000..461427d44ae --- /dev/null +++ b/app/views/admin/budget_groups/new.html.erb @@ -0,0 +1,3 @@ +<%= render "header", action: "create" %> + +<%= render "form", path: admin_budget_groups_path(@budget), action: "create" %> diff --git a/app/views/admin/budget_headings/_form.html.erb b/app/views/admin/budget_headings/_form.html.erb new file mode 100644 index 00000000000..ebc5aa2aecf --- /dev/null +++ b/app/views/admin/budget_headings/_form.html.erb @@ -0,0 +1,40 @@ +
+ + <%= form_for [:admin, @budget, @group, @heading], url: path do |f| %> + + <%= f.text_field :name, + label: t("admin.budget_headings.form.name"), + maxlength: 50, + placeholder: t("admin.budget_headings.form.name") %> + + <%= f.text_field :price, + label: t("admin.budget_headings.form.amount"), + maxlength: 8, + placeholder: t("admin.budget_headings.form.amount") %> + + <%= f.label :population, t("admin.budget_headings.form.population") %> +

+ <%= t("admin.budget_headings.form.population_info") %> +

+ <%= f.text_field :population, + label: false, + maxlength: 8, + placeholder: t("admin.budget_headings.form.population"), + data: {toggle_focus: "population-info"}, + aria: {describedby: "budgets-population-help-text"} %> + + <%= f.text_field :latitude, + label: t("admin.budget_headings.form.latitude"), + maxlength: 22, + placeholder: "latitude" %> + + <%= f.text_field :longitude, + label: t("admin.budget_headings.form.longitude"), + maxlength: 22, + placeholder: "longitude" %> + + <%= f.check_box :allow_custom_content, label: t("admin.budget_headings.form.allow_content_block") %> + + <%= f.submit t("admin.budget_headings.form.#{action}"), class: "button success" %> + <% end %> +
diff --git a/app/views/admin/budget_headings/_header.html.erb b/app/views/admin/budget_headings/_header.html.erb new file mode 100644 index 00000000000..dde0f14ec1a --- /dev/null +++ b/app/views/admin/budget_headings/_header.html.erb @@ -0,0 +1,5 @@ +<%= back_link_to admin_budget_group_headings_path(@budget, @group) %> + +

<%= "#{@budget.name} / #{@group.name}" %>

+ +

<%= t("admin.budget_headings.form.#{action}") %>

diff --git a/app/views/admin/budget_headings/edit.html.erb b/app/views/admin/budget_headings/edit.html.erb new file mode 100644 index 00000000000..a01fa70a420 --- /dev/null +++ b/app/views/admin/budget_headings/edit.html.erb @@ -0,0 +1,3 @@ +<%= render "header", action: "edit" %> + +<%= render "form", path: admin_budget_group_heading_path(@budget, @group, @heading), action: "edit" %> diff --git a/app/views/admin/budget_headings/index.html.erb b/app/views/admin/budget_headings/index.html.erb new file mode 100644 index 00000000000..a5a2a75aff9 --- /dev/null +++ b/app/views/admin/budget_headings/index.html.erb @@ -0,0 +1,47 @@ +<%= back_link_to admin_budget_groups_path(@budget) %> + +
+

<%= "#{@budget.name} / #{@group.name}" %>

+<%= link_to t("admin.budget_headings.form.create"), + new_admin_budget_group_heading_path, + class: "button float-right" %> + +<% if @headings.any? %> +

<%= t("admin.budget_headings.amount", count: @headings.count) %>

+ + + + + + + + + + + + <% @headings.each do |heading| %> + + + + + + + + <% end %> + +
<%= t("admin.budget_headings.name") %><%= t("admin.budget_headings.form.amount") %><%= t("admin.budget_headings.form.population") %><%= t("admin.budget_headings.form.allow_content_block") %><%= t("admin.actions.actions") %>
<%= link_to heading.name, edit_admin_budget_group_heading_path(@budget, @group, heading) %><%= @budget.formatted_heading_price(heading) %><%= heading.population %> + <%= heading.allow_custom_content ? t("admin.shared.true_value") : t("admin.shared.false_value") %> + + <%= link_to t("admin.actions.edit"), + edit_admin_budget_group_heading_path(@budget, @group, heading), + class: "button hollow" %> + <%= link_to t("admin.actions.delete"), + admin_budget_group_heading_path(@budget, @group, heading), + method: :delete, + class: "button hollow alert" %> +
+<% else %> +
+ <%= t("admin.budget_headings.no_headings") %> +
+<% end %> diff --git a/app/views/admin/budget_headings/new.html.erb b/app/views/admin/budget_headings/new.html.erb new file mode 100644 index 00000000000..0566a5a5e1a --- /dev/null +++ b/app/views/admin/budget_headings/new.html.erb @@ -0,0 +1,3 @@ +<%= render "header", action: "create" %> + +<%= render "form", path: admin_budget_group_headings_path(@budget, @group), action: "create" %> diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb index f4d43d87f90..f042f980091 100644 --- a/app/views/admin/budgets/index.html.erb +++ b/app/views/admin/budgets/index.html.erb @@ -24,7 +24,7 @@ <% @budgets.each do |budget| %> - <%= budget.name %> + <%= link_to budget.name, admin_budget_path(budget) %> <%= t("budgets.phase.#{budget.phase}") %> @@ -35,7 +35,7 @@ class: "button hollow medium" %> - <%= link_to t("admin.budgets.index.edit_groups"), admin_budget_path(budget) %> + <%= link_to t("admin.budgets.index.edit_groups"), admin_budget_groups_path(budget) %> <%= link_to t("admin.budgets.index.edit_budget"), edit_admin_budget_path(budget) %> diff --git a/app/views/admin/budgets/show.html.erb b/app/views/admin/budgets/show.html.erb index 063b025ea8b..2e46f79c86c 100644 --- a/app/views/admin/budgets/show.html.erb +++ b/app/views/admin/budgets/show.html.erb @@ -2,6 +2,4 @@

<%= @budget.name %>

-
- <%= render "groups", groups: @budget.groups.order(:id) %> -
+<%= render "form" %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 118340378f8..cad1f8d3708 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -109,39 +109,56 @@ en: unable_notice: You cannot destroy a Budget that has associated investments new: title: New participatory budget - show: - groups: - one: 1 Group of budget headings - other: "%{count} Groups of budget headings" - form: - group: Group name - no_groups: No groups created yet. Each user will be able to vote in only one heading per group. - add_group: Add new group - create_group: Create group - edit_group: Edit group - submit: Save group - heading: Heading name - add_heading: Add heading - amount: Amount - population: "Population (optional)" - population_help_text: "This data is used exclusively to calculate the participation statistics" - save_heading: Save heading - no_heading: This group has no assigned heading. - table_heading: Heading - table_amount: Amount - table_population: Population - table_allow_custom_contents: Custom content allowed - population_info: "Budget Heading population field is used for Statistic purposes at the end of the Budget to show for each Heading that represents an area with population what percentage voted. The field is optional so you can leave it empty if it doesn't apply." - max_supportable_headings: "Maximum number of headings in which a user can support" - max_votable_headings: "Maximum number of headings in which a user can vote" - current_of_max_headings: "%{current} of %{max}" - latitude: Latitude - longitude: Longitude - allow_content_block: Allow content block winners: calculate: Calculate Winner Investments calculated: Winners being calculated, it may take a minute. recalculate: Recalculate Winner Investments + budget_groups: + name: "Name" + headings_name: "Headings" + headings_edit: "Edit Headings" + headings_manage: "Manage headings" + max_votable_headings: "Maximum number of headings in which a user can vote" + no_groups: "No groups created yet. Each user will be able to vote in only one heading per group." + amount: + one: "There is 1 group" + other: "There are %{count} groups" + create: + notice: "Group created successfully!" + update: + notice: "Group updated successfully" + destroy: + success_notice: "Group deleted successfully" + unable_notice: "You cannot destroy a Group that has associated headings" + form: + create: "Create new group" + edit: "Edit group" + name: "Group name" + submit: "Save group" + budget_headings: + name: "Name" + no_headings: "No headings created yet. Each user will be able to vote in only one heading per group." + amount: + one: "There is 1 heading" + other: "There are %{count} headings" + create: + notice: "Heading created successfully!" + update: + notice: "Heading updated successfully" + destroy: + success_notice: "Heading deleted successfully" + unable_notice: "You cannot destroy a Heading that has associated investments" + form: + name: "Heading name" + amount: "Amount" + population: "Population (optional)" + population_info: "Budget Heading population field is used for Statistic purposes at the end of the Budget to show for each Heading that represents an area with population what percentage voted. The field is optional so you can leave it empty if it doesn't apply." + latitude: "Latitude" + longitude: "Longitude" + allow_content_block: "Allow content block" + create: "Create new heading" + edit: "Edit heading" + submit: "Save heading" budget_phases: edit: start_date: Start date diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index dcfb677e06f..55418b8e72a 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -109,36 +109,56 @@ es: unable_notice: No se puede eliminar un presupuesto con proyectos asociados new: title: Nuevo presupuesto ciudadano - show: - groups: - one: 1 Grupo de partidas presupuestarias - other: "%{count} Grupos de partidas presupuestarias" - form: - group: Nombre del grupo - no_groups: No hay grupos creados todavía. Cada usuario podrá votar en una sola partida de cada grupo. - add_group: Añadir nuevo grupo - create_group: Crear grupo - edit_group: Editar grupo - submit: Guardar grupo - heading: Nombre de la partida - add_heading: Añadir partida - amount: Cantidad - population: "Población (opcional)" - population_help_text: "Este dato se utiliza exclusivamente para calcular las estadísticas de participación" - save_heading: Guardar partida - no_heading: Este grupo no tiene ninguna partida asignada. - table_heading: Partida - table_amount: Cantidad - table_population: Población - population_info: "El campo población de las partidas presupuestarias se usa con fines estadísticos únicamente, con el objetivo de mostrar el porcentaje de votos habidos en cada partida que represente un área con población. Es un campo opcional, así que puedes dejarlo en blanco si no aplica." - max_supportable_headings: "Máximo número de partidas en que un usuario puede apoyar" - max_votable_headings: "Máximo número de partidas en que un usuario puede votar" - current_of_max_headings: "%{current} de %{max}" - allow_content_block: Permite bloque de contenidos winners: calculate: Calcular proyectos ganadores calculated: Calculando ganadores, puede tardar un minuto. recalculate: Recalcular propuestas ganadoras + budget_groups: + name: "Nombre" + headings_name: "Partidas" + headings_edit: "Editar Partidas" + headings_manage: "Gestionar partidas" + max_votable_headings: "Máximo número de partidas en que un usuario puede votar" + no_groups: "No hay grupos creados todavía. Cada usuario podrá votar en una sola partida de cada grupo." + amount: + one: "Hay 1 grupo de partidas presupuestarias" + other: "Hay %{count} grupos de partidas presupuestarias" + create: + notice: "¡Grupo creado con éxito!" + update: + notice: "Grupo actualizado" + destroy: + success_notice: "Grupo eliminado correctamente" + unable_notice: "No se puede eliminar un grupo con partidas asociadas" + form: + create: "Crear nuevo grupo" + edit: "Editar grupo" + name: "Nombre del grupo" + submit: "Guardar grupo" + budget_headings: + name: "Nombre" + no_headings: "No hay partidas creadas todavía. Cada usuario podrá votar en una sola partida de cada grupo." + amount: + one: "Hay 1 partida presupuestarias" + other: "Hay %{count} partidas presupuestarias" + create: + notice: "¡Partida presupuestaria creada con éxito!" + update: + notice: "Partida presupuestaria actualizada" + destroy: + success_notice: "Partida presupuestaria eliminada correctamente" + unable_notice: "No se puede eliminar una partida presupuestaria con proyectos asociados" + form: + name: "Nombre de la partida" + amount: "Cantidad" + population: "Población (opcional)" + population_info: "El campo población de las partidas presupuestarias se usa con fines estadísticos únicamente, con el objetivo de mostrar el porcentaje de votos habidos en cada partida que represente un área con población. Es un campo opcional, así que puedes dejarlo en blanco si no aplica." + latitude: "Latitud" + longitude: "Longitud" + allow_content_block: "Permitir bloque de contenidos" + create: "Crear nueva partida" + edit: "Editar partida" + submit: "Guardar partida" budget_phases: edit: start_date: Fecha de Inicio diff --git a/config/routes/admin.rb b/config/routes/admin.rb index f4a609b6f31..4e74d3a567e 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -67,8 +67,8 @@ put :calculate_winners end - resources :budget_groups do - resources :budget_headings + resources :groups, except: [:show], controller: "budget_groups" do + resources :headings, except: [:show], controller: "budget_headings" end resources :budget_investments, only: [:index, :show, :edit, :update] do diff --git a/spec/features/admin/budget_groups_spec.rb b/spec/features/admin/budget_groups_spec.rb index f9ea361fdc1..d501c081377 100644 --- a/spec/features/admin/budget_groups_spec.rb +++ b/spec/features/admin/budget_groups_spec.rb @@ -1,136 +1,178 @@ require 'rails_helper' -feature 'Admin can change the groups name' do +feature "Admin budget groups" do - let(:budget) { create(:budget, phase: 'drafting') } - let(:group) { create(:budget_group, budget: budget) } + let(:budget) { create(:budget, phase: "drafting") } background do admin = create(:administrator) login_as(admin.user) end - scenario "Show button" do - visit admin_budget_path(group.budget) + context "Feature flag" do - within("#budget_group_#{group.id}") do - expect(page).to have_content('Edit group') + background do + Setting["feature.budgets"] = nil end - end - scenario "Change name" do - group.update(name: 'Google') - expect(group.name).to eq('Google') - end + after do + Setting["feature.budgets"] = true + end - scenario "Can change name when the budget isn't drafting, but the slug remains" do - old_slug = group.slug - budget.update(phase: 'reviewing') - group.update(name: 'Google') + scenario "Disabled with a feature flag" do + expect { visit admin_budget_groups_path(budget) }.to raise_exception(FeatureFlags::FeatureDisabled) + end - expect(group.name).to eq('Google') - expect(group.slug).to eq old_slug end - scenario "Can't repeat names" do - budget.groups << create(:budget_group, name: 'group_name') - group.name = 'group_name' + context "Index" do - expect(group).not_to be_valid - expect(group.errors.size).to eq(1) - end - - context "Maximum votable headings" do + scenario "Displaying no groups for budget" do + visit admin_budget_groups_path(budget) - background do - 3.times { create(:budget_heading, group: group) } + expect(page).to have_content "No groups created yet. Each user will be able to vote in only one heading per group." end - scenario "Defaults to 1 heading per group", :js do - visit admin_budget_path(group.budget) + scenario "Displaying groups" do + group1 = create(:budget_group, budget: budget) - expect(page).to have_content('Maximum number of headings in which a user can vote 1 of 3') + group2 = create(:budget_group, budget: budget) + create(:budget_heading, group: group2) - within("#budget_group_#{group.id}") do - click_link 'Edit group' + group3 = create(:budget_group, budget: budget, max_votable_headings: 2) + 3.times { create(:budget_heading, group: group3) } - expect(page).to have_select('budget_group_max_votable_headings', selected: '1') - end - end + visit admin_budget_groups_path(budget) + expect(page).to have_content "There are 3 groups" - scenario "Update", :js do - visit admin_budget_path(group.budget) + within "#budget_group_#{group1.id}" do + expect(page).to have_content(group1.name) + expect(page).to have_content(group1.max_votable_headings) + expect(page).to have_content(group1.headings.count) + expect(page).to have_link "Manage headings", href: admin_budget_group_headings_path(budget, group1) + end - within("#budget_group_#{group.id}") do - click_link 'Edit group' + within "#budget_group_#{group2.id}" do + expect(page).to have_content(group2.name) + expect(page).to have_content(group2.max_votable_headings) + expect(page).to have_content(group2.headings.count) + expect(page).to have_link "Manage headings", href: admin_budget_group_headings_path(budget, group2) + end - select '2', from: 'budget_group_max_votable_headings' - click_button 'Save group' + within "#budget_group_#{group3.id}" do + expect(page).to have_content(group3.name) + expect(page).to have_content(group3.max_votable_headings) + expect(page).to have_content(group3.headings.count) + expect(page).to have_link "Manage headings", href: admin_budget_group_headings_path(budget, group3) end + end - expect(page).to have_content('Maximum number of headings in which a user can vote 2 of 3') + scenario "Delete a group without headings" do + group = create(:budget_group, budget: budget) - within("#budget_group_#{group.id}") do - click_link 'Edit group' + visit admin_budget_groups_path(budget) + within("#budget_group_#{group.id}") { click_link "Delete" } - expect(page).to have_select('budget_group_max_votable_headings', selected: '2') - end + expect(page).to have_content "Group deleted successfully" + expect(page).not_to have_selector "#budget_group_#{group.id}" end - scenario "Do not display maximum votable headings' select in new form", :js do - visit admin_budget_path(group.budget) + scenario "Try to delete a group with headings" do + group = create(:budget_group, budget: budget) + create(:budget_heading, group: group) - click_link 'Add new group' + visit admin_budget_groups_path(budget) + within("#budget_group_#{group.id}") { click_link "Delete" } - expect(page).to have_field('budget_group_name') - expect(page).not_to have_field('budget_group_max_votable_headings') + expect(page).to have_content "You cannot destroy a Group that has associated headings" + expect(page).to have_selector "#budget_group_#{group.id}" end + end - context "Maximum supportable headings" do + context "New" do - background do - 3.times { create(:budget_heading, group: group) } + scenario "Create group" do + visit admin_budget_groups_path(budget) + click_link "Create new group" + + fill_in "Group name", with: "All City" + + click_button "Create new group" + + expect(page).to have_content "Group created successfully!" + expect(page).to have_link "All City" end - scenario "Defaults to 1 heading per group", :js do - visit admin_budget_path(group.budget) + scenario "Maximum number of headings in which a user can vote is set to 1 by default" do + visit new_admin_budget_group_path(budget) + fill_in "Group name", with: "All City" - expect(page).to have_content('Maximum number of headings in which a user can support 1 of 3') + click_button "Create new group" - within("#budget_group_#{group.id}") do - click_link 'Edit group' + expect(page).to have_content "Group created successfully!" + expect(Budget::Group.first.max_votable_headings).to be 1 + end - expect(page).to have_select('budget_group_max_supportable_headings', selected: '1') - end + scenario "Group name is mandatory" do + visit new_admin_budget_group_path(budget) + click_button "Create new group" + + expect(page).not_to have_content "Group created successfully!" + expect(page).to have_css("label.error", text: "Group name") + expect(page).to have_content "can't be blank" end - scenario "Update", :js do - visit admin_budget_path(group.budget) + end - within("#budget_group_#{group.id}") do - click_link 'Edit group' + context "Edit" do - select '2', from: 'budget_group_max_supportable_headings' - click_button 'Save group' - end + scenario "Show group information" do + group = create(:budget_group, budget: budget, max_votable_headings: 2) + 2.times { create(:budget_heading, group: group) } - expect(page).to have_content('Maximum number of headings in which a user can support 2 of 3') + visit admin_budget_groups_path(budget) + within("#budget_group_#{group.id}") { click_link "Edit" } - within("#budget_group_#{group.id}") do - click_link 'Edit group' + expect(page).to have_field "Group name", with: group.name + expect(page).to have_field "Maximum number of headings in which a user can vote", with: "2" + end - expect(page).to have_select('budget_group_max_supportable_headings', selected: '2') - end + end + + context "Update" do + let!(:group) { create(:budget_group, budget: budget, name: "All City") } + + scenario "Updates group" do + 2.times { create(:budget_heading, group: group) } + + visit edit_admin_budget_group_path(budget, group) + expect(page).to have_field "Group name", with: "All City" + + fill_in "Group name", with: "Districts" + select "2", from: "Maximum number of headings in which a user can vote" + click_button "Edit group" + + expect(page).to have_content "Group updated successfully" + + visit edit_admin_budget_group_path(budget, group.reload) + expect(page).to have_field "Group name", with: "Districts" + expect(page).to have_field "Maximum number of headings in which a user can vote", with: "2" end - scenario "Do not display maximum supportable headings' select in new form", :js do - visit admin_budget_path(group.budget) + scenario "Group name is already used" do + create(:budget_group, budget: budget, name: "Districts") - click_link 'Add new group' + visit edit_admin_budget_group_path(budget, group) + expect(page).to have_field "Group name", with: "All City" - expect(page).to have_field('budget_group_name') - expect(page).not_to have_field('budget_group_max_supportable_headings') + fill_in "Group name", with: "Districts" + click_button "Edit group" + + expect(page).not_to have_content "Group updated successfully" + expect(page).to have_css("label.error", text: "Group name") + expect(page).to have_content "has already been taken" end end + end diff --git a/spec/features/admin/budget_headings_spec.rb b/spec/features/admin/budget_headings_spec.rb new file mode 100644 index 00000000000..834c6d1e59d --- /dev/null +++ b/spec/features/admin/budget_headings_spec.rb @@ -0,0 +1,208 @@ +require 'rails_helper' + +feature "Admin budget headings" do + + let(:budget) { create(:budget, phase: "drafting") } + let(:group) { create(:budget_group, budget: budget) } + + background do + admin = create(:administrator) + login_as(admin.user) + end + + context "Feature flag" do + + background do + Setting["feature.budgets"] = nil + end + + after do + Setting["feature.budgets"] = true + end + + scenario "Disabled with a feature flag" do + expect { visit admin_budget_group_headings_path(budget, group) }.to raise_exception(FeatureFlags::FeatureDisabled) + end + + end + + context "Index" do + + scenario "Displaying no headings for group" do + visit admin_budget_group_headings_path(budget, group) + + expect(page).to have_content "No headings created yet. Each user will be able to vote in only one heading per group." + end + + scenario "Displaying headings" do + heading1 = create(:budget_heading, group: group, price: 1000, allow_custom_content: true) + heading2 = create(:budget_heading, group: group, price: 2000, population: 10000) + heading3 = create(:budget_heading, group: group, price: 3000, population: 10000) + + visit admin_budget_group_headings_path(budget, group) + expect(page).to have_content "There are 3 headings" + + within "#budget_heading_#{heading1.id}" do + expect(page).to have_content(heading1.name) + expect(page).to have_content "€1,000" + expect(page).not_to have_content "10000" + expect(page).to have_content "Yes" + expect(page).to have_link "Edit", href: edit_admin_budget_group_heading_path(budget, group, heading1) + expect(page).to have_link "Delete", href: admin_budget_group_heading_path(budget, group, heading1) + end + + within "#budget_heading_#{heading2.id}" do + expect(page).to have_content(heading2.name) + expect(page).to have_content "€2,000" + expect(page).to have_content "10000" + expect(page).to have_content "No" + expect(page).to have_link "Edit", href: edit_admin_budget_group_heading_path(budget, group, heading2) + expect(page).to have_link "Delete", href: admin_budget_group_heading_path(budget, group, heading2) + end + + within "#budget_heading_#{heading3.id}" do + expect(page).to have_content(heading3.name) + expect(page).to have_content "€3,000" + expect(page).to have_content "10000" + expect(page).to have_content "No" + expect(page).to have_link "Edit", href: edit_admin_budget_group_heading_path(budget, group, heading3) + expect(page).to have_link "Delete", href: admin_budget_group_heading_path(budget, group, heading3) + end + end + + scenario "Delete a heading without investments" do + heading = create(:budget_heading, group: group) + + visit admin_budget_group_headings_path(budget, group) + within("#budget_heading_#{heading.id}") { click_link "Delete" } + + expect(page).to have_content "Heading deleted successfully" + expect(page).not_to have_selector "#budget_heading_#{heading.id}" + end + + scenario "Try to delete a heading with investments" do + heading = create(:budget_heading, group: group) + investment = create(:budget_investment, heading: heading) + + visit admin_budget_group_headings_path(budget, group) + within("#budget_heading_#{heading.id}") { click_link "Delete" } + + expect(page).to have_content "You cannot destroy a Heading that has associated investments" + expect(page).to have_selector "#budget_heading_#{heading.id}" + end + + end + + context "New" do + + scenario "Create heading" do + visit admin_budget_group_headings_path(budget, group) + click_link "Create new heading" + + fill_in "Heading name", with: "All City" + fill_in "Amount", with: "1000" + fill_in "Population (optional)", with: "10000" + check "Allow content block" + + click_button "Create new heading" + + expect(page).to have_content "Heading created successfully!" + expect(page).to have_link "All City" + expect(page).to have_content "€1,000" + expect(page).to have_content "10000" + expect(page).to have_content "Yes" + end + + scenario "Heading name is mandatory" do + visit new_admin_budget_group_heading_path(budget, group) + click_button "Create new heading" + + expect(page).not_to have_content "Heading created successfully!" + expect(page).to have_css("label.error", text: "Heading name") + expect(page).to have_content "can't be blank" + end + + scenario "Heading amount is mandatory" do + visit new_admin_budget_group_heading_path(budget, group) + click_button "Create new heading" + + expect(page).not_to have_content "Heading created successfully!" + expect(page).to have_css("label.error", text: "Amount") + expect(page).to have_content "can't be blank" + end + + end + + context "Edit" do + + scenario "Show heading information" do + heading = create(:budget_heading, group: group) + + visit admin_budget_group_headings_path(budget, group) + within("#budget_heading_#{heading.id}") { click_link "Edit" } + + expect(page).to have_field "Heading name", with: heading.name + expect(page).to have_field "Amount", with: heading.price + expect(page).to have_field "Population (optional)", with: heading.population + expect(page).to have_field "Longitude", with: heading.longitude + expect(page).to have_field "Latitude", with: heading.latitude + expect(find_field("Allow content block")).not_to be_checked + end + + end + + context "Update" do + let(:heading) { create(:budget_heading, + group: group, + name: "All City", + price: 1000, + population: 10000, + longitude: 20.50, + latitude: -10.50, + allow_custom_content: true) } + + scenario "Updates group" do + visit edit_admin_budget_group_heading_path(budget, group, heading) + + expect(page).to have_field "Heading name", with: "All City" + expect(page).to have_field "Amount", with: 1000 + expect(page).to have_field "Population (optional)", with: 10000 + expect(page).to have_field "Longitude", with: 20.50 + expect(page).to have_field "Latitude", with: -10.50 + expect(find_field("Allow content block")).to be_checked + + fill_in "Heading name", with: "Districts" + fill_in "Amount", with: "2000" + fill_in "Population (optional)", with: "20000" + fill_in "Longitude", with: "-40.47" + fill_in "Latitude", with: "25.25" + uncheck "Allow content block" + click_button "Edit heading" + + expect(page).to have_content "Heading updated successfully" + + visit edit_admin_budget_group_heading_path(budget, group, heading.reload) + expect(page).to have_field "Heading name", with: "Districts" + expect(page).to have_field "Amount", with: 2000 + expect(page).to have_field "Population (optional)", with: 20000 + expect(page).to have_field "Longitude", with: -40.47 + expect(page).to have_field "Latitude", with: 25.25 + expect(find_field("Allow content block")).not_to be_checked + end + + scenario "Heading name is already used" do + create(:budget_heading, group: group, name: "Districts") + + visit edit_admin_budget_group_heading_path(budget, group, heading) + expect(page).to have_field "Heading name", with: "All City" + + fill_in "Heading name", with: "Districts" + click_button "Edit heading" + + expect(page).not_to have_content "Heading updated successfully" + expect(page).to have_css("label.error", text: "Heading name") + expect(page).to have_content "has already been taken" + end + + end +end diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 441744548df..7d734d6d618 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -236,109 +236,6 @@ end end - - context 'Manage groups and headings' do - - scenario 'Create group', :js do - budget = create(:budget, name: 'Yearly budget') - - visit admin_budgets_path - - within("#budget_#{budget.id}") do - click_link 'Edit headings groups' - end - - expect(page).to have_content '0 Groups of budget headings' - expect(page).to have_content 'No groups created yet.' - - click_link 'Add new group' - - fill_in 'budget_group_name', with: 'Health' - click_button 'Create group' - - expect(page).to have_content '1 Group of budget headings' - expect(page).to have_content 'Health' - expect(page).to have_content 'Yearly budget' - expect(page).not_to have_content 'No groups created yet.' - - visit admin_budgets_path - within("#budget_#{budget.id}") do - click_link 'Edit headings groups' - end - - expect(page).to have_content '1 Group of budget headings' - expect(page).to have_content 'Health' - expect(page).to have_content 'Yearly budget' - expect(page).not_to have_content 'No groups created yet.' - end - - scenario 'Create heading', :js do - budget = create(:budget, name: 'Yearly budget') - group = create(:budget_group, budget: budget, name: 'Districts improvments') - - visit admin_budget_path(budget) - - within("#budget_group_#{group.id}") do - expect(page).to have_content 'This group has no assigned heading.' - click_link 'Add heading' - - fill_in 'budget_heading_name', with: 'District 9 reconstruction' - fill_in 'budget_heading_price', with: '6785' - fill_in 'budget_heading_population', with: '100500' - fill_in 'budget_heading_latitude', with: '40.416775' - fill_in 'budget_heading_longitude', with: '-3.703790' - click_button 'Save heading' - end - - visit admin_budget_path(budget) - - within("#budget_group_#{group.id}") do - expect(page).not_to have_content 'This group has no assigned heading.' - expect(page).to have_content 'District 9 reconstruction' - expect(page).to have_content '€6,785' - expect(page).to have_content '100500' - end - end - - scenario 'Update heading', :js do - budget = create(:budget, name: 'Yearly budget') - group = create(:budget_group, budget: budget, name: 'Districts improvments') - heading = create(:budget_heading, group: group, name: "District 1") - heading = create(:budget_heading, group: group, name: "District 3") - - visit admin_budget_path(budget) - - within("#heading-#{heading.id}") do - click_link 'Edit' - - fill_in 'budget_heading_name', with: 'District 2' - fill_in 'budget_heading_price', with: '10000' - fill_in 'budget_heading_population', with: '6000' - click_button 'Save heading' - end - - expect(page).to have_content 'District 2' - expect(page).to have_content '€10,000' - expect(page).to have_content '6000' - end - - scenario 'Delete heading', :js do - budget = create(:budget, name: 'Yearly budget') - group = create(:budget_group, budget: budget, name: 'Districts improvments') - heading = create(:budget_heading, group: group, name: "District 1") - - visit admin_budget_path(budget) - - expect(page).to have_content 'District 1' - - within("#heading-#{heading.id}") do - click_link 'Delete' - end - - expect(page).not_to have_content 'District 1' - end - - end end def translated_phase_name(phase_kind: kind) diff --git a/spec/features/budgets/ballots_spec.rb b/spec/features/budgets/ballots_spec.rb index 051fb51cd97..01e91edfb8e 100644 --- a/spec/features/budgets/ballots_spec.rb +++ b/spec/features/budgets/ballots_spec.rb @@ -161,6 +161,34 @@ end end + scenario "the Map shoud be visible before and after", :js do + investment = create(:budget_investment, :selected, heading: new_york, price: 10000) + + visit budget_path(budget) + click_link "States" + click_link "New York" + + within("#sidebar") do + expect(page).to have_content "OpenStreetMap" + end + + add_to_ballot(investment) + + within("#sidebar") do + expect(page).to have_content investment.title + expect(page).to have_content "OpenStreetMap" + end + + within("#budget_investment_#{investment.id}") do + click_link "Remove vote" + end + + within("#sidebar") do + expect(page).not_to have_content investment.title + expect(page).to have_content "OpenStreetMap" + end + end + end #Break up or simplify with helpers From bad9047f8ef6b388919039783a41f71d41a5fc7c Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Wed, 19 Dec 2018 13:22:43 +0100 Subject: [PATCH 08/10] improve rendering of map in the sidebar --- app/assets/stylesheets/layout.scss | 1 - app/views/budgets/investments/_map.html.erb | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 74e9180474f..7739d563b58 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -859,7 +859,6 @@ footer { .categories a, .geozone a, .sidebar-links a, -.sidebar-map a, .tags span { background: #ececec; border-radius: rem-calc(6); diff --git a/app/views/budgets/investments/_map.html.erb b/app/views/budgets/investments/_map.html.erb index 37aa50f6721..f22a5d7ee18 100644 --- a/app/views/budgets/investments/_map.html.erb +++ b/app/views/budgets/investments/_map.html.erb @@ -1,7 +1,4 @@ - -
- -