From 5956207a0070090ac3228a1e082cafb56d413af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sen=C3=A9n=20Rodero=20Rodr=C3=ADguez?= Date: Mon, 7 Aug 2017 11:10:38 +0200 Subject: [PATCH] Add map locations. Each map location can belongs to proposal or budget investment. --- app/assets/javascripts/map.js.coffee | 40 +++++++++++++------ .../budgets/investments_controller.rb | 3 +- app/controllers/proposals_controller.rb | 3 +- app/models/budget/investment.rb | 2 + app/models/map_location.rb | 6 +++ app/models/proposal.rb | 2 + app/views/admin/settings/_map_form.html.erb | 3 +- app/views/budgets/investments/_form.html.erb | 13 ++++++ app/views/map_locations/_form_fields.html.erb | 25 ++++++++++++ app/views/proposals/_form.html.erb | 13 ++++++ config/locales/en/general.yml | 2 + config/locales/es/general.yml | 2 + .../20170805132736_create_map_locations.rb | 11 +++++ db/schema.rb | 11 +++++ 14 files changed, 119 insertions(+), 17 deletions(-) create mode 100644 app/models/map_location.rb create mode 100644 app/views/map_locations/_form_fields.html.erb create mode 100644 db/migrate/20170805132736_create_map_locations.rb diff --git a/app/assets/javascripts/map.js.coffee b/app/assets/javascripts/map.js.coffee index c3821e338..8aca94bc7 100644 --- a/app/assets/javascripts/map.js.coffee +++ b/app/assets/javascripts/map.js.coffee @@ -16,20 +16,15 @@ App.Map = latitudeInputSelector = $(element).data('latitude-input-selector') longitudeInputSelector = $(element).data('longitude-input-selector') zoomInputSelector = $(element).data('zoom-input-selector') + removeMarkerSelector = $(element).data('remove-marker-selector') + attribution = $(mapAttributionSelector) + marker_icon = L.divIcon( + iconSize: null + html: '
') - latLng = new (L.LatLng)(latitude, longitude) - map = L.map(element.id).setView(latLng, zoom) - attribution = $(mapAttributionSelector) - L.tileLayer(mapTilesProvider, attribution: attribution.html()).addTo map - - marker_icon = L.divIcon( - iconSize: null - html: '
') - marker = L.marker(latLng, { icon: marker_icon, draggable: 'true' }) - marker.addTo(map) - - onMapClick = (e) -> + placeMarker = (e) -> marker.setLatLng(e.latlng) + marker.addTo(map) updateFormfields() return @@ -39,6 +34,25 @@ App.Map = $(zoomInputSelector).val map.getZoom() return + clearFormfields = -> + $(latitudeInputSelector).val '' + $(longitudeInputSelector).val '' + $(zoomInputSelector).val '' + return + + removeMarker = (e) -> + e.preventDefault() + map.removeLayer(marker) + clearFormfields() + return + + latLng = new (L.LatLng)(latitude, longitude) + map = L.map(element.id).setView(latLng, zoom) + marker = L.marker(latLng, { icon: marker_icon, draggable: 'true' }) + L.tileLayer(mapTilesProvider, attribution: attribution.html()).addTo map + marker.addTo(map) + + $(removeMarkerSelector).on 'click', removeMarker marker.on 'dragend', updateFormfields map.on 'zoomend', updateFormfields - map.on 'click', onMapClick \ No newline at end of file + map.on 'click', placeMarker \ No newline at end of file diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index fb82c51db..bb00f24af 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -107,7 +107,8 @@ module Budgets .permit(:title, :description, :external_url, :heading_id, :tag_list, :organization_name, :location, :terms_of_service, image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy], - documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]) + documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy], + map_location_attributes: [:latitude, :longitude, :zoom]) end def load_ballot diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index 9e6fc521d..d1db0e4a2 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -77,7 +77,8 @@ class ProposalsController < ApplicationController params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url, :responsible_name, :tag_list, :terms_of_service, :geozone_id, image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy], - documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy] ) + documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy], + map_location_attributes: [:latitude, :longitude, :zoom]) end def retired_params diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 857025375..af8feac1d 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -27,6 +27,8 @@ class Budget has_many :valuators, through: :valuator_assignments has_many :comments, as: :commentable has_many :milestones + has_one :map_location + accepts_nested_attributes_for :map_location validates :title, presence: true validates :author, presence: true diff --git a/app/models/map_location.rb b/app/models/map_location.rb new file mode 100644 index 000000000..61cb10893 --- /dev/null +++ b/app/models/map_location.rb @@ -0,0 +1,6 @@ +class MapLocation < ActiveRecord::Base + + belongs_to :proposal + belongs_to :investment + +end diff --git a/app/models/proposal.rb b/app/models/proposal.rb index 7a0abcb6e..7ad7a863b 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -25,6 +25,8 @@ class Proposal < ActiveRecord::Base belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :geozone + has_one :map_location + accepts_nested_attributes_for :map_location has_many :comments, as: :commentable has_many :proposal_notifications diff --git a/app/views/admin/settings/_map_form.html.erb b/app/views/admin/settings/_map_form.html.erb index 1187cfa96..53eb3d882 100644 --- a/app/views/admin/settings/_map_form.html.erb +++ b/app/views/admin/settings/_map_form.html.erb @@ -8,8 +8,7 @@ data-tiles-provider="//{s}.tile.osm.org/{z}/{x}/{y}.png" data-latitude-input-selector="#latitude" data-longitude-input-selector="#longitude" - data-zoom-input-selector="#zoom" - data-marker-selector="#admin-map-marker"> + data-zoom-input-selector="#zoom">
© OpenStreetMap contributors diff --git a/app/views/budgets/investments/_form.html.erb b/app/views/budgets/investments/_form.html.erb index 0d0bdd7f1..789d0f8a9 100644 --- a/app/views/budgets/investments/_form.html.erb +++ b/app/views/budgets/investments/_form.html.erb @@ -29,6 +29,19 @@ <%= render 'documents/nested_documents', documentable: @investment, f: f %>
+ <% if feature?(:map) %> +
+ + <%= render 'map_locations/form_fields', + form: f, + map_location: @investment.map_location || MapLocation.new, + label: t("proposals.form.map_location"), + help: t("proposals.form.map_location_instructions"), + parent_class: "budget_investment" %> + +
+ <% end %> +
<%= f.text_field :location %>
diff --git a/app/views/map_locations/_form_fields.html.erb b/app/views/map_locations/_form_fields.html.erb new file mode 100644 index 000000000..7c4a1785e --- /dev/null +++ b/app/views/map_locations/_form_fields.html.erb @@ -0,0 +1,25 @@ +<%= form.label :map_location, label %> +

<%= help %>

+
" + data-longitude="<%= map_location.present? && map_location.longitude.present? ? map_location.longitude : Setting["map.longitude"] %>" + data-zoom="<%= map_location.present? && map_location.zoom.present? ? map_location.zoom : Setting["map.zoom"] %>" + data-tiles-attribution-selector="#map-location-attribution" + data-tiles-provider="//{s}.tile.osm.org/{z}/{x}/{y}.png" + data-latitude-input-selector="#<%= parent_class %>_map_location_attributes_latitude" + data-longitude-input-selector="#<%= parent_class %>_map_location_attributes_longitude" + data-zoom-input-selector="#<%= parent_class %>_map_location_attributes_zoom" + data-remove-marker-selector=".location-map-remove-marker-button"> +
+ +
+ © OpenStreetMap contributors +
+ +Remove marker + +<%= form.fields_for :map_location, map_location do |map_location_fields| %> + <%= map_location_fields.hidden_field :latitude, value: map_location.latitude, id: "#{parent_class}_map_location_attributes_latitude" %> + <%= map_location_fields.hidden_field :longitude, value: map_location.longitude, id: "#{parent_class}_map_location_attributes_longitude" %> + <%= map_location_fields.hidden_field :zoom, value: map_location.zoom, id: "#{parent_class}_map_location_attributes_zoom" %> +<% end %> \ No newline at end of file diff --git a/app/views/proposals/_form.html.erb b/app/views/proposals/_form.html.erb index df1e096e9..72feba9c3 100644 --- a/app/views/proposals/_form.html.erb +++ b/app/views/proposals/_form.html.erb @@ -59,6 +59,19 @@ <%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %> + <% if feature?(:map) %> +
+ + <%= render 'map_locations/form_fields', + form: f, + map_location: @proposal.map_location || MapLocation.new, + label: t("proposals.form.map_location"), + help: t("proposals.form.map_location_instructions"), + parent_class: "proposal" %> + +
+ <% end %> +
<%= f.label :tag_list, t("proposals.form.tags_label") %>

<%= t("proposals.form.tags_instructions") %>

diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 6312a9a5c..c118db367 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -333,6 +333,8 @@ en: tags_instructions: "Tag this proposal. You can choose from proposed categories or add your own" tags_label: Tags tags_placeholder: "Enter the tags you would like to use, separated by commas (',')" + map_location: "Map location" + map_location_instructions: "Navigate the map to the location and place the marker." index: featured_proposals: Featured filter_topic: diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 4b1ebe2ba..46664e2ae 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -333,6 +333,8 @@ es: tags_label: Temas tag_category_label: "Categorías" tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')" + map_location: "Ubicación en el mapa" + map_location_instructions: "Navega por el mapa hasta la ubicación y coloca el marcador." index: featured_proposals: Destacadas filter_topic: diff --git a/db/migrate/20170805132736_create_map_locations.rb b/db/migrate/20170805132736_create_map_locations.rb new file mode 100644 index 000000000..a75820d54 --- /dev/null +++ b/db/migrate/20170805132736_create_map_locations.rb @@ -0,0 +1,11 @@ +class CreateMapLocations < ActiveRecord::Migration + def change + create_table :map_locations do |t| + t.float :latitude + t.float :longitude + t.integer :zoom + t.integer :proposal_id, index: true + t.integer :investment_id, index: true + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 41063df03..86d22f3b2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -549,6 +549,17 @@ ActiveRecord::Schema.define(version: 20170918231410) do add_index "managers", ["user_id"], name: "index_managers_on_user_id", using: :btree + create_table "map_locations", force: :cascade do |t| + t.float "latitude" + t.float "longitude" + t.integer "zoom" + t.integer "proposal_id" + t.integer "investment_id" + end + + add_index "map_locations", ["investment_id"], name: "index_map_locations_on_investment_id", using: :btree + add_index "map_locations", ["proposal_id"], name: "index_map_locations_on_proposal_id", using: :btree + create_table "moderators", force: :cascade do |t| t.integer "user_id" end