Organisations are now also displayed on the map. Refs #71

This commit is contained in:
echarp 2016-04-16 23:08:03 +02:00
parent 94afdadef3
commit f02c0b10f2
25 changed files with 88698 additions and 90 deletions

View File

@ -152,7 +152,7 @@ GEM
formtastic (3.1.4) formtastic (3.1.4)
actionpack (>= 3.2.13) actionpack (>= 3.2.13)
formtastic_i18n (0.6.0) formtastic_i18n (0.6.0)
geocoder (1.3.3) geocoder (1.3.4)
globalid (0.3.6) globalid (0.3.6)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
guard (2.13.0) guard (2.13.0)

View File

@ -1,32 +1,38 @@
# Setting up OpenStreeMap from a generic #map element # Setting up OpenStreeMap from a generic #map element
$(document).ready -> $(document).ready ->
$('#map.events, #map.orgas').each -> $('#map.list').each ->
map = L.map 'map' map = L.map 'map'
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a>' attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a>'
).addTo map ).addTo map
url = $(this).data 'url' controls = L.control.layers(null, null).addTo map
if location.search && url.indexOf('?') >= 0
url += '&' + location.search.substr 1
else
url += location.search
$.getJSON url, (json) -> $('li a', this).each ->
layer = L.geoJson json, url = $(this).attr 'href'
onEachFeature: (feature, layer) -> text = $(this).html()
# Does this feature have a property named popupContent? if location.search && url.indexOf('?') >= 0
if (feature.properties && feature.properties.popupContent) url += '&' + location.search.substr 1
layer.bindPopup feature.properties.popupContent
map.addLayer L.markerClusterGroup( maxClusterRadius: 30 ).addLayer layer
if (layer.getBounds()._northEast && layer.getBounds()._southWest)
# Automatic focus to all displayed events
map.fitBounds layer.getBounds()
else else
$('#map.events, #map.orgas').remove() url += location.search
$.getJSON url, (json) ->
if json
count = 0
layer = L.markerClusterGroup(maxClusterRadius: 30).addLayer L.geoJson json,
onEachFeature: (feature, layer) ->
# Does this feature have a property named popupContent?
if (feature.properties && feature.properties.popupContent)
layer.bindPopup feature.properties.popupContent
count++
map.addLayer layer
controls.addOverlay layer, text + ' - ' + count
if (url.contains('maps.json') && layer.getBounds()._northEast && layer.getBounds()._southWest)
# Automatic focus to all displayed events
map.fitBounds layer.getBounds()
$('#map.event, #map.orga').each -> $('#map.event, #map.orga').each ->
coord = [$(this).data('latitude'), $(this).data('longitude')] coord = [$(this).data('latitude'), $(this).data('longitude')]
@ -44,12 +50,12 @@ $(document).ready ->
url += location.search url += location.search
$.getJSON url, (json) -> $.getJSON url, (json) ->
layer = L.geoJson json, layer = L.markerClusterGroup(maxClusterRadius: 30).addLayer L.geoJson json,
onEachFeature: (feature, layer) -> onEachFeature: (feature, layer) ->
# Does this feature have a property named popupContent? # Does this feature have a property named popupContent?
if (feature.properties && feature.properties.popupContent) if (feature.properties && feature.properties.popupContent)
layer.bindPopup(feature.properties.popupContent) layer.bindPopup(feature.properties.popupContent)
map.addLayer L.markerClusterGroup( maxClusterRadius: 30 ).addLayer layer map.addLayer layer
marker = L.marker([coord[0], coord[1]]).addTo map marker = L.marker([coord[0], coord[1]]).addTo map

View File

@ -20,6 +20,10 @@
margin: 1.6em 2% margin: 1.6em 2%
+inline-block() +inline-block()
// Left align the map controls place in the top right corner
form.leaflet-control-layers-list label
text-align: left
html.iframe #map html.iframe #map
width: 100% width: 100%
max-width: 100% max-width: 100%

View File

@ -17,7 +17,7 @@ class EventsController < ApplicationController
format.json { @events = @events.future } format.json { @events = @events.future }
format.rss { @events = @events.future.order('id desc').limit 20 } format.rss { @events = @events.future.order('id desc').limit 20 }
format.ics { @events = @events.last_year } format.ics { @events = @events.last_year }
format.xml { @events = @events } format.xml
end end
end end

View File

@ -13,4 +13,12 @@ class MapsController < ApplicationController
format.json { render json: apply_scopes(Event.moderated.geo) } format.json { render json: apply_scopes(Event.moderated.geo) }
end end
end end
def show
kind = Kind.find_by_name params[:id]
orgas = apply_scopes(Orga.moderated.geo).joins(:kind).find_by(kind: kind)
respond_to do |format|
format.json { render json: orgas }
end
end
end end

View File

@ -1,7 +1,8 @@
# Organisations related to this agenda # Organisations related to this agenda
class Orga < ActiveRecord::Base class Orga < ActiveRecord::Base
strip_attributes strip_attributes
has_paper_trail ignore: [:last_updated, :secret, :submitter] has_paper_trail ignore: [:last_updated, :secret, :submitter, :decision_time,
:lock_version, :latitude, :longitude]
belongs_to :region belongs_to :region
belongs_to :kind belongs_to :kind
@ -23,7 +24,15 @@ class Orga < ActiveRecord::Base
scope :moderated, -> { where moderated: true } scope :moderated, -> { where moderated: true }
scope :unmoderated, -> { where moderated: false } scope :unmoderated, -> { where moderated: false }
# Only present to simplify maps_controller, to have the same scopes as events
scope :locality, -> {}
scope :daylimit, -> {}
scope :future, -> {}
scope :period, ->(year, week) {}
scope :region, ->(region) { where region: region unless region == 'all' } scope :region, ->(region) { where region: region unless region == 'all' }
scope :tag, ->(tag) { where 'tags like ?', "%#{tag}%" }
scope :geo, -> { where 'latitude is not null and longitude is not null' }
before_validation do before_validation do
unless submitter.blank? unless submitter.blank?
@ -60,6 +69,15 @@ class Orga < ActiveRecord::Base
name.gsub(/\AL'/, '').gsub(/[\s\*']/, '-').delete ':' name.gsub(/\AL'/, '').gsub(/[\s\*']/, '-').delete ':'
end end
def as_json(_options = {})
{ type: 'Feature', properties: {
id: id, name: name,
place_name: place_name, address: address, city: city,
tags: tags,
popupContent: "<a href=\"/orgas/#{id}\">#{self}</a>"
}, geometry: { type: 'Point', coordinates: [longitude, latitude] } }
end
def full_address def full_address
[address, city, region.try(:name)].compact.join ', ' [address, city, region.try(:name)].compact.join ', '
end end

View File

@ -1,8 +1,6 @@
json.array!(@events) do |event| json.array!(@events) do |event|
json.extract! event, :id, :title, :description, :start_time, :end_time, json.extract! event, :id, :title, :description, :start_time, :end_time,
:place_name, :address, :city, :region_id, :locality, :url, :place_name, :address, :city, :region_id, :locality, :url,
:contact, :submitter, :moderated, :tags, :secret, :contact, :tags
:decision_time, :submission_time, :moderator_mail_id,
:submitter_mail_id
json.url event_url(event, format: :json) json.url event_url(event, format: :json)
end end

View File

@ -1,4 +1,3 @@
json.extract! @event, :id, :title, :description, :start_time, :end_time, json.extract! @event, :id, :title, :description, :start_time, :end_time,
:place_name, :address, :city, :region, :locality, :url, :contact, :place_name, :address, :city, :region, :locality, :url, :contact,
:contact, :submitter, :moderated, :tags, :secret, :decision_time, :tags
:submission_time, :moderator_mail_id, :submitter_mail_id

View File

@ -6,17 +6,13 @@
%em= params[:tag] %em= params[:tag]
» »
#map.events(data-url="#{maps_path format: :json}") %ul#map.list
%li
%nav = link_to maps_path format: :json do
= link_to events_path format: :rss, tag: params[:tag] do %em.fa.fa-calendar
%em.fa.fa-rss = Event.model_name.human.pluralize
RSS - Kind.all.each do |kind|
\/ %li
= link_to events_path format: :ics, tag: params[:tag] do = link_to map_path kind.name, format: :json do
%em.fa.fa-th-list %em.fa{ class: "fa-#{kind.icon}" }
iCal = Kind.human_attribute_name("name_#{kind.name}")
\/
= link_to maps_path format: :json, tag: params[:tag] do
%em.fa.fa-dot-circle-o
GeoJSON

View File

@ -0,0 +1,6 @@
json.array!(@orgas) do |orga|
json.extract! orga, :id, :name, :description,
:place_name, :address, :city, :region_id, :url,
:contact, :tags
json.url orga_url(orga, format: :json)
end

View File

@ -0,0 +1,2 @@
json.extract! @orga, :id, :name, :description,
:place_name, :address, :city, :region, :url, :contact, :tags

View File

@ -226,7 +226,7 @@ description."
ko: Moderation ko: Moderation
maps: maps:
index: index:
title: Events map title: Events and organisations map
events: Events events: Events
orgas: Organiser orgas: Organiser
users: users:

View File

@ -227,7 +227,7 @@ description plus complète."
ko: Modération ko: Modération
maps: maps:
index: index:
title: Carte des événements title: Carte des événements et organisations
events: Événements events: Événements
orgas: Orga orgas: Orga
users: users:

View File

@ -21,7 +21,7 @@ Rails.application.routes.draw do
resources :regions, only: [:index] resources :regions, only: [:index]
get 'tags/orgas', to: 'tags#orgas' get 'tags/orgas', to: 'tags#orgas'
resources :tags, only: [:index, :show] resources :tags, only: [:index, :show]
resources :maps, only: [:index] resources :maps, only: [:index, :show]
resources :orgas do resources :orgas do
get :cancel, :validate, :refuse, on: :member get :cancel, :validate, :refuse, on: :member
put :accept, on: :member put :accept, on: :member

View File

@ -24,9 +24,9 @@ ActiveRecord::Schema.define(version: 20160409131029) do
t.datetime "updated_at" t.datetime "updated_at"
end end
add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id" add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree
add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace" add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree
add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id" add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree
create_table "admin_users", force: :cascade do |t| create_table "admin_users", force: :cascade do |t|
t.string "email", limit: 255, default: "", null: false t.string "email", limit: 255, default: "", null: false
@ -43,8 +43,8 @@ ActiveRecord::Schema.define(version: 20160409131029) do
t.datetime "updated_at" t.datetime "updated_at"
end end
add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true, using: :btree
add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true, using: :btree
create_table "cities", force: :cascade do |t| create_table "cities", force: :cascade do |t|
t.string "name", limit: 255, default: "", null: false t.string "name", limit: 255, default: "", null: false
@ -56,7 +56,7 @@ ActiveRecord::Schema.define(version: 20160409131029) do
t.float "longitude", limit: 24 t.float "longitude", limit: 24
end end
add_index "cities", ["name"], name: "cities_name" add_index "cities", ["name"], name: "cities_name", using: :btree
create_table "events", force: :cascade do |t| create_table "events", force: :cascade do |t|
t.string "title", limit: 255, default: "", null: false t.string "title", limit: 255, default: "", null: false
@ -72,8 +72,8 @@ ActiveRecord::Schema.define(version: 20160409131029) do
t.integer "moderated", limit: 4, default: 0, null: false t.integer "moderated", limit: 4, default: 0, null: false
t.string "tags", limit: 255, default: "", null: false t.string "tags", limit: 255, default: "", null: false
t.string "secret", limit: 255, default: "", null: false t.string "secret", limit: 255, default: "", null: false
t.datetime "decision_time" t.datetime "decision_time", null: false
t.datetime "submission_time" t.datetime "submission_time", null: false
t.string "moderator_mail_id", limit: 32 t.string "moderator_mail_id", limit: 32
t.string "submitter_mail_id", limit: 32 t.string "submitter_mail_id", limit: 32
t.text "address", limit: 65535 t.text "address", limit: 65535
@ -83,7 +83,7 @@ ActiveRecord::Schema.define(version: 20160409131029) do
t.string "place_name", limit: 255 t.string "place_name", limit: 255
end end
add_index "events", ["start_time", "end_time"], name: "events_date" add_index "events", ["start_time", "end_time"], name: "events_date", using: :btree
create_table "kinds", force: :cascade do |t| create_table "kinds", force: :cascade do |t|
t.string "name", limit: 255, null: false t.string "name", limit: 255, null: false
@ -100,66 +100,64 @@ ActiveRecord::Schema.define(version: 20160409131029) do
end end
create_table "orgas", force: :cascade do |t| create_table "orgas", force: :cascade do |t|
t.integer "region_id", limit: 4, default: 0, null: false t.integer "region_id", limit: 4, default: 0, null: false
t.string "department", limit: 4, default: "0", null: false t.string "department", limit: 255
t.string "name", limit: 255, default: "", null: false t.string "name", limit: 255, default: "", null: false
t.string "url", limit: 255, default: "", null: false t.string "url", limit: 255, default: "", null: false
t.string "city", limit: 255, default: "" t.string "city", limit: 255, default: ""
t.integer "kind_id", limit: 4 t.integer "kind_id", limit: 4
t.string "feed", limit: 255 t.string "feed", limit: 255
t.string "contact", limit: 255 t.string "contact", limit: 255
t.string "submitter", limit: 255 t.string "submitter", limit: 255
t.boolean "moderated", limit: 1, default: false t.boolean "moderated", default: false
t.datetime "submission_time" t.datetime "submission_time"
t.datetime "decision_time" t.datetime "decision_time"
t.string "secret", limit: 255 t.string "secret", limit: 255
t.boolean "deleted", limit: 1, default: false, null: false t.boolean "deleted", default: false, null: false
t.boolean "active", default: true, null: false t.boolean "active", default: true, null: false
t.text "description" t.text "description", limit: 65535
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.text "tag" t.string "tags", limit: 255, default: ""
t.text "tags", default: "" t.text "diaspora", limit: 65535
t.text "diaspora" t.text "place_name", limit: 65535
t.text "object_changes" t.text "address", limit: 65535
t.text "place_name" t.float "latitude", limit: 24
t.text "address" t.float "longitude", limit: 24
t.float "latitude"
t.float "longitude"
end end
add_index "orgas", ["kind_id"], name: "index_orgas_on_kind_id" add_index "orgas", ["kind_id"], name: "index_orgas_on_kind_id", using: :btree
create_table "regions", force: :cascade do |t| create_table "regions", force: :cascade do |t|
t.string "name", limit: 255, default: "", null: false t.string "name", limit: 255, default: "", null: false
end end
create_table "taggings", force: :cascade do |t| create_table "taggings", force: :cascade do |t|
t.integer "tag_id" t.integer "tag_id", limit: 4
t.integer "taggable_id" t.integer "taggable_id", limit: 4
t.string "taggable_type", limit: 255 t.string "taggable_type", limit: 255
t.integer "tagger_id" t.integer "tagger_id", limit: 4
t.string "tagger_type", limit: 255 t.string "tagger_type", limit: 255
t.string "context", limit: 128 t.string "context", limit: 128
t.datetime "created_at" t.datetime "created_at"
end end
add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true add_index "taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true, using: :btree
add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
create_table "tags", force: :cascade do |t| create_table "tags", force: :cascade do |t|
t.string "name", limit: 255 t.string "name", limit: 255
t.integer "taggings_count", default: 0 t.integer "taggings_count", limit: 4, default: 0
end end
add_index "tags", ["name"], name: "index_tags_on_name", unique: true add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
create_table "translations", force: :cascade do |t| create_table "translations", force: :cascade do |t|
t.string "locale", limit: 255 t.string "locale", limit: 255
t.string "key", limit: 255 t.string "key", limit: 255
t.text "value", limit: 65535 t.text "value", limit: 65535
t.text "interpolations", limit: 65535 t.text "interpolations", limit: 65535
t.boolean "is_proc", limit: 1, default: false t.boolean "is_proc", default: false
end end
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
@ -171,15 +169,15 @@ ActiveRecord::Schema.define(version: 20160409131029) do
end end
create_table "versions", force: :cascade do |t| create_table "versions", force: :cascade do |t|
t.string "item_type", null: false t.string "item_type", limit: 255, null: false
t.integer "item_id", null: false t.integer "item_id", limit: 4, null: false
t.string "event", null: false t.string "event", limit: 255, null: false
t.string "whodunnit" t.string "whodunnit", limit: 255
t.text "object" t.text "object", limit: 65535
t.datetime "created_at" t.datetime "created_at"
t.text "object_changes", limit: 1073741823 t.text "object_changes", limit: 4294967295
end end
add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree
end end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,21 @@
(function() {
$(document).ready(function() {
return tinyMCE.init({
schema: 'html5',
menubar: false,
language: 'fr_FR',
selector: 'textarea.description',
content_css: '/assets/application-e08384d7ca80213e0d6c24b1b649a0b64d6e7281a61f79c0002ca9ebfd248fc7.css',
entity_encoding: 'raw',
add_unload_trigger: true,
browser_spellcheck: true,
toolbar: [' bold italic strikethrough | bullist numlist outdent indent | alignleft aligncenter alignright alignjustify | link image media insertdatetime charmap table | undo redo | searchreplace | code visualblocks preview fullscreen'],
plugins: 'lists, advlist, autolink, link, image, charmap, paste, print, preview, table, fullscreen, searchreplace, media, insertdatetime, visualblocks, visualchars, wordcount, contextmenu, code'
});
});
$(document).on('page:receive', function() {
return tinymce.remove();
});
}).call(this);

View File

@ -118,6 +118,6 @@ class EventTest < ActiveSupport::TestCase
@event.city = 'world' @event.city = 'world'
# Region is no longer used for geocoding..; # Region is no longer used for geocoding..;
# @event.region.name = 'all' # @event.region.name = 'all'
assert_equal 'hello, world', @event.full_address assert_equal 'hello, world, Alsace', @event.full_address
end end
end end