decidim-navigation_maps 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +144 -0
- data/Rakefile +40 -0
- data/app/assets/config/admin/decidim_navigation_maps_manifest.css +3 -0
- data/app/assets/config/admin/decidim_navigation_maps_manifest.js +3 -0
- data/app/assets/config/decidim_navigation_maps_manifest.css +3 -0
- data/app/assets/config/decidim_navigation_maps_manifest.js +1 -0
- data/app/assets/images/decidim/navigation_maps/icon.svg +1 -0
- data/app/assets/javascripts/decidim/navigation_maps/admin/map_editor.js +88 -0
- data/app/assets/javascripts/decidim/navigation_maps/admin/navigation_maps.js +143 -0
- data/app/assets/javascripts/decidim/navigation_maps/map_view.js +123 -0
- data/app/assets/javascripts/decidim/navigation_maps/navigation_maps.js +44 -0
- data/app/assets/stylesheets/decidim/navigation_maps/_variables.scss +3 -0
- data/app/assets/stylesheets/decidim/navigation_maps/admin/navigation_maps.scss +102 -0
- data/app/assets/stylesheets/decidim/navigation_maps/navigation_maps.scss +58 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map/_styles.erb +18 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map/_tabs.erb +5 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map/_tabs_content.erb +8 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map/_template.erb +13 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map/show.erb +21 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_cell.rb +22 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_settings_form/_form.erb +36 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_settings_form/_modal.erb +12 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_settings_form/_tabs.erb +6 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_settings_form/_tabs_content.erb +11 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_settings_form/show.erb +35 -0
- data/app/cells/decidim/navigation_maps/content_blocks/navigation_map_settings_form_cell.rb +32 -0
- data/app/commands/decidim/navigation_maps/save_area.rb +58 -0
- data/app/commands/decidim/navigation_maps/save_blueprints.rb +72 -0
- data/app/controllers/decidim/navigation_maps/admin/application_controller.rb +13 -0
- data/app/controllers/decidim/navigation_maps/admin/areas_controller.rb +94 -0
- data/app/controllers/decidim/navigation_maps/admin/blueprints_controller.rb +64 -0
- data/app/forms/decidim/navigation_maps/area_form.rb +37 -0
- data/app/forms/decidim/navigation_maps/blueprint_form.rb +39 -0
- data/app/forms/decidim/navigation_maps/blueprint_forms.rb +9 -0
- data/app/models/decidim/navigation_maps/application_record.rb +10 -0
- data/app/models/decidim/navigation_maps/blueprint.rb +27 -0
- data/app/models/decidim/navigation_maps/blueprint_area.rb +32 -0
- data/app/queries/decidim/navigation_maps/organization_blueprints.rb +20 -0
- data/app/uploaders/decidim/navigation_maps/blueprint_uploader.rb +22 -0
- data/app/views/decidim/navigation_maps/admin/areas/_form.html.erb +39 -0
- data/app/views/decidim/navigation_maps/admin/areas/new.html.erb +17 -0
- data/app/views/decidim/navigation_maps/admin/areas/show.html.erb +14 -0
- data/config/i18n-tasks.yml +10 -0
- data/config/locales/ca.yml +45 -0
- data/config/locales/cs.yml +45 -0
- data/config/locales/en.yml +46 -0
- data/config/locales/es.yml +45 -0
- data/db/migrate/20191022092624_create_decidim_navigation_maps_blueprints.rb +13 -0
- data/db/migrate/20191120185739_add_title_to_navigation_maps_blueprints.rb +10 -0
- data/db/migrate/20191125142751_create_decidim_navigation_maps_blueprint_areas.rb +18 -0
- data/db/migrate/20191126045831_add_link_type_to_decidim_navigation_maps_blueprint_areas.rb +8 -0
- data/db/migrate/20191126154019_add_area_id_to_decidim_navigation_maps_blueprint_areas.rb +16 -0
- data/db/migrate/20191127093746_add_color_to_navigation_maps_blueprint_areas.rb +7 -0
- data/lib/decidim/navigation_maps.rb +13 -0
- data/lib/decidim/navigation_maps/admin.rb +10 -0
- data/lib/decidim/navigation_maps/admin_engine.rb +34 -0
- data/lib/decidim/navigation_maps/engine.rb +34 -0
- data/lib/decidim/navigation_maps/navigation_map_cell_helpers.rb +28 -0
- data/lib/decidim/navigation_maps/test/factories.rb +29 -0
- data/lib/decidim/navigation_maps/version.rb +9 -0
- data/vendor/assets/images/draw/layers-2x.png +0 -0
- data/vendor/assets/images/draw/layers.png +0 -0
- data/vendor/assets/images/draw/marker-icon-2x.png +0 -0
- data/vendor/assets/images/draw/marker-icon.png +0 -0
- data/vendor/assets/images/draw/marker-shadow.png +0 -0
- data/vendor/assets/images/draw/spritesheet-2x.png +0 -0
- data/vendor/assets/images/draw/spritesheet.png +0 -0
- data/vendor/assets/images/draw/spritesheet.svg +156 -0
- data/vendor/assets/images/images/layers-2x.png +0 -0
- data/vendor/assets/images/images/layers.png +0 -0
- data/vendor/assets/images/images/marker-icon-2x.png +0 -0
- data/vendor/assets/images/images/marker-icon.png +0 -0
- data/vendor/assets/images/images/marker-shadow.png +0 -0
- data/vendor/assets/javascripts/jquery.form.js +1277 -0
- data/vendor/assets/javascripts/jsrender.min.js +4 -0
- data/vendor/assets/javascripts/jsrender.min.js.map +1 -0
- data/vendor/assets/javascripts/leaflet-geoman.min.js +1 -0
- data/vendor/assets/javascripts/leaflet.js +5 -0
- data/vendor/assets/stylesheets/leaflet-geoman.css +164 -0
- metadata +183 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
# This command creates or updates areas for a blueprints
|
6
|
+
class SaveArea < Rectify::Command
|
7
|
+
# Creates or updates an area for a blueprint.
|
8
|
+
#
|
9
|
+
# form - The form with the data.
|
10
|
+
def initialize(form)
|
11
|
+
@form = form
|
12
|
+
end
|
13
|
+
|
14
|
+
# Executes the command. Broadcasts these events:
|
15
|
+
#
|
16
|
+
# - :ok when everything is valid
|
17
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
18
|
+
#
|
19
|
+
# Returns nothing.
|
20
|
+
def call
|
21
|
+
return broadcast(:invalid, form.errors.full_messages.join(", ")) if form.invalid?
|
22
|
+
|
23
|
+
initialize_area
|
24
|
+
update_area
|
25
|
+
save_area!
|
26
|
+
|
27
|
+
broadcast(:ok, @area)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :form, :current_blueprint
|
33
|
+
|
34
|
+
def initialize_area
|
35
|
+
@area = BlueprintArea.find_or_initialize_by(area_id: form.area_id, blueprint: @form.context.current_blueprint)
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_area
|
39
|
+
@area.link_type = link_type
|
40
|
+
@area.link = form.link
|
41
|
+
@area.title = form.title unless form.no_popup
|
42
|
+
@area.description = form.description unless form.no_popup
|
43
|
+
@area.color = form.color
|
44
|
+
@area.area_id = form.area_id if form.area_id
|
45
|
+
@area.area = form.area if form.area
|
46
|
+
@area.area_type = form.area_type if form.area_type
|
47
|
+
end
|
48
|
+
|
49
|
+
def save_area!
|
50
|
+
@area.save!
|
51
|
+
end
|
52
|
+
|
53
|
+
def link_type
|
54
|
+
form.no_popup ? "direct" : "link"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
# This command creates or updates the blueprints for the organization.
|
6
|
+
class SaveBlueprints < Rectify::Command
|
7
|
+
# Creates a blueprint.
|
8
|
+
#
|
9
|
+
# forms - The form with the data.
|
10
|
+
def initialize(forms)
|
11
|
+
@forms = forms
|
12
|
+
@blueprints = forms.blueprints || {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# Executes the command. Broadcasts these events:
|
16
|
+
#
|
17
|
+
# - :ok when everything is valid
|
18
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
def call
|
22
|
+
@blueprints.each do |form|
|
23
|
+
next if form.invalid?
|
24
|
+
|
25
|
+
initialize_blueprint(form)
|
26
|
+
if form.remove
|
27
|
+
destroy_blueprint!(form)
|
28
|
+
else
|
29
|
+
create_areas(form.blueprint) if form.blueprint
|
30
|
+
destroy_areas_except(form.blueprint.keys) if form.blueprint
|
31
|
+
update_blueprint!(form)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
broadcast(:ok)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :forms
|
41
|
+
|
42
|
+
def initialize_blueprint(form)
|
43
|
+
@blueprint = Blueprint.find_or_initialize_by(id: form.id) do |blueprint|
|
44
|
+
blueprint.organization = @forms.current_organization
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_blueprint!(form)
|
49
|
+
@blueprint.image = form.image if form.image.present?
|
50
|
+
@blueprint.title = form.title
|
51
|
+
@blueprint.description = form.description
|
52
|
+
@blueprint.save!
|
53
|
+
end
|
54
|
+
|
55
|
+
def destroy_blueprint!(form)
|
56
|
+
@blueprint.destroy! if form.id
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy_areas_except(except)
|
60
|
+
@blueprint.areas.where.not(area_id: except).destroy_all
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_areas(blueprint)
|
64
|
+
blueprint.each do |key, area|
|
65
|
+
a = BlueprintArea.find_or_initialize_by(area_id: key, blueprint: @blueprint)
|
66
|
+
a.area = area[:geometry]
|
67
|
+
a.area_type = area[:type]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
module Admin
|
6
|
+
# This controller is the abstract class from which all other controllers of
|
7
|
+
# this engine inherit.
|
8
|
+
#
|
9
|
+
class ApplicationController < ::Decidim::Admin::ApplicationController
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
module Admin
|
6
|
+
class AreasController < ::Decidim::NavigationMaps::Admin::ApplicationController
|
7
|
+
layout false
|
8
|
+
helper_method :link_suggestions
|
9
|
+
|
10
|
+
before_action do
|
11
|
+
enforce_permission_to :update, :organization, organization: current_organization
|
12
|
+
end
|
13
|
+
|
14
|
+
def index
|
15
|
+
render json: blueprint.areas
|
16
|
+
end
|
17
|
+
|
18
|
+
def new
|
19
|
+
@form = form(AreaForm).instance(current_blueprint: blueprint)
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
parse_areas
|
24
|
+
@form = form(AreaForm).from_params(params, current_blueprint: blueprint)
|
25
|
+
|
26
|
+
SaveArea.call(@form) do
|
27
|
+
on(:ok) do |area|
|
28
|
+
render json: { message: I18n.t("navigation_maps.admin.areas.create.success", scope: "decidim"),
|
29
|
+
area_id: area.area_id,
|
30
|
+
blueprint_id: area.blueprint.id,
|
31
|
+
area: area.to_geoson }
|
32
|
+
end
|
33
|
+
|
34
|
+
on(:invalid) do |message|
|
35
|
+
render json: { message: I18n.t("navigation_maps.admin.areas.create.error", scope: "decidim"), error: message }, status: :unprocessable_entity
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def show
|
41
|
+
@form = form(AreaForm).from_model(area)
|
42
|
+
end
|
43
|
+
|
44
|
+
def update
|
45
|
+
@form = form(AreaForm).from_params(params, current_blueprint: blueprint)
|
46
|
+
SaveArea.call(@form) do
|
47
|
+
on(:ok) do |area|
|
48
|
+
render json: { message: I18n.t("navigation_maps.admin.areas.update.success", scope: "decidim"),
|
49
|
+
area_id: area.area_id,
|
50
|
+
blueprint_id: area.blueprint.id,
|
51
|
+
area: area.to_geoson }
|
52
|
+
end
|
53
|
+
|
54
|
+
on(:invalid) do |message|
|
55
|
+
render json: { message: I18n.t("navigation_maps.admin.areas.update.error", scope: "decidim"), error: message }, status: :unprocessable_entity
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def link_suggestions
|
63
|
+
return if blueprints_count.zero?
|
64
|
+
|
65
|
+
maps = blueprints_count.times.collect do |n|
|
66
|
+
"<a href=\"#map#{n}\">#map#{n}</a>"
|
67
|
+
end
|
68
|
+
t("link_suggestions", scope: "decidim.navigation_maps.admin.areas.show", map: maps.join(",")).html_safe
|
69
|
+
end
|
70
|
+
|
71
|
+
def parse_areas
|
72
|
+
return unless params[:blueprint_area]
|
73
|
+
return if params[:blueprint_area][:area].blank?
|
74
|
+
|
75
|
+
feature = JSON.parse params[:blueprint_area][:area]
|
76
|
+
params[:blueprint_area][:area] = feature["geometry"] if feature["geometry"]
|
77
|
+
params[:blueprint_area][:area_type] = feature["type"] if feature["type"]
|
78
|
+
end
|
79
|
+
|
80
|
+
def blueprint
|
81
|
+
@blueprint ||= Blueprint.find(params[:blueprint_id])
|
82
|
+
end
|
83
|
+
|
84
|
+
def area
|
85
|
+
@area ||= BlueprintArea.find_by(area_id: params[:area_id], blueprint: blueprint)
|
86
|
+
end
|
87
|
+
|
88
|
+
def blueprints_count
|
89
|
+
@blueprints_count ||= Blueprint.where(organization: current_organization).count
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
module Admin
|
6
|
+
class BlueprintsController < ::Decidim::NavigationMaps::Admin::ApplicationController
|
7
|
+
before_action do
|
8
|
+
enforce_permission_to :update, :organization, organization: current_organization
|
9
|
+
end
|
10
|
+
|
11
|
+
def index
|
12
|
+
render json: organization_blueprints
|
13
|
+
end
|
14
|
+
|
15
|
+
def show
|
16
|
+
render json: organization_blueprints.find(params[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
save_settings
|
21
|
+
parse_blueprints
|
22
|
+
@form = form(BlueprintForms).from_params(params).with_context(current_organization: current_organization)
|
23
|
+
SaveBlueprints.call(@form) do
|
24
|
+
on(:ok) do
|
25
|
+
render plain: I18n.t("navigation_maps.create.success", scope: "decidim")
|
26
|
+
end
|
27
|
+
|
28
|
+
on(:invalid) do
|
29
|
+
render plain: I18n.t("navigation_maps.create.error", scope: "decidim"), status: :unprocessable_entity
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Manually save original settings if the settings array is present
|
37
|
+
def save_settings
|
38
|
+
return unless params[:content_block]
|
39
|
+
return unless params[:content_block][:settings]
|
40
|
+
|
41
|
+
@form = form(Decidim::Admin::ContentBlockForm).from_params(params)
|
42
|
+
Decidim::Admin::UpdateContentBlock.call(@form, content_block, :homepage)
|
43
|
+
end
|
44
|
+
|
45
|
+
def content_block
|
46
|
+
@content_block ||= Decidim::ContentBlock.for_scope(:homepage, organization: current_organization).find_by(manifest_name: :navigation_map)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Convert blueprint data to an object
|
50
|
+
def parse_blueprints
|
51
|
+
return unless params[:blueprints]
|
52
|
+
|
53
|
+
params[:blueprints].each do |_key, data|
|
54
|
+
data[:blueprint] = JSON.parse data[:blueprint] if data[:blueprint].present?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def organization_blueprints
|
59
|
+
@organization_blueprints ||= OrganizationBlueprints.new(current_organization).query
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
# A form object used to configure the blueprint content block from the admin panel.
|
6
|
+
#
|
7
|
+
class AreaForm < Decidim::Form
|
8
|
+
include TranslatableAttributes
|
9
|
+
|
10
|
+
mimic :blueprint_area
|
11
|
+
|
12
|
+
attribute :area, Object
|
13
|
+
attribute :area_type, String
|
14
|
+
attribute :area_id, String
|
15
|
+
attribute :link, String
|
16
|
+
attribute :link_type, String
|
17
|
+
attribute :no_popup, String
|
18
|
+
attribute :color, String
|
19
|
+
translatable_attribute :title, String
|
20
|
+
translatable_attribute :description, String
|
21
|
+
|
22
|
+
def no_popup
|
23
|
+
return link_type == "direct" unless super
|
24
|
+
|
25
|
+
super.to_i.nonzero?
|
26
|
+
end
|
27
|
+
|
28
|
+
def color
|
29
|
+
return "#2262cc" if super.blank?
|
30
|
+
|
31
|
+
return "#" + super unless super.match?(/^#/)
|
32
|
+
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
# A form object used to configure the blueprint content block from the admin panel.
|
6
|
+
#
|
7
|
+
class BlueprintForm < Decidim::Form
|
8
|
+
include TranslatableAttributes
|
9
|
+
|
10
|
+
mimic :blueprint
|
11
|
+
|
12
|
+
attribute :blueprint, Object
|
13
|
+
attribute :id, Integer
|
14
|
+
attribute :remove, Boolean
|
15
|
+
attribute :image
|
16
|
+
translatable_attribute :title, String
|
17
|
+
translatable_attribute :description, String
|
18
|
+
|
19
|
+
# validate :check_image_or_blueprint
|
20
|
+
validates :title, translatable_presence: true
|
21
|
+
|
22
|
+
# def check_image_or_blueprint
|
23
|
+
# return if image.present? || blueprint.present?
|
24
|
+
|
25
|
+
# errors.add(:image, "no image") unless image.present?
|
26
|
+
# errors.add(:blueprint, "no blueprint") unless blueprint.present?
|
27
|
+
# end
|
28
|
+
|
29
|
+
def ident
|
30
|
+
id || "_"
|
31
|
+
end
|
32
|
+
|
33
|
+
def image?
|
34
|
+
return unless image && image.respond_to?(:url)
|
35
|
+
return image.content_type.start_with? "image" if image.content_type.present?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
# Abstract class from which all models in this engine inherit.
|
6
|
+
class Blueprint < ApplicationRecord
|
7
|
+
self.table_name = "decidim_navigation_maps_blueprints"
|
8
|
+
|
9
|
+
belongs_to :organization, foreign_key: :decidim_organization_id, class_name: "Decidim::Organization"
|
10
|
+
has_many :areas,
|
11
|
+
foreign_key: "decidim_navigation_maps_blueprint_id",
|
12
|
+
class_name: "Decidim::NavigationMaps::BlueprintArea",
|
13
|
+
dependent: :destroy
|
14
|
+
|
15
|
+
validates :organization, presence: true
|
16
|
+
validates :image,
|
17
|
+
file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
|
18
|
+
file_content_type: { allow: ["image/jpeg", "image/png", "image/svg+xml"] }
|
19
|
+
|
20
|
+
mount_uploader :image, Decidim::NavigationMaps::BlueprintUploader
|
21
|
+
|
22
|
+
def blueprint
|
23
|
+
areas.map { |area| [area.area_id.to_s, area.to_geoson] }.to_h
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module NavigationMaps
|
5
|
+
# Abstract class from which all models in this engine inherit.
|
6
|
+
class BlueprintArea < ApplicationRecord
|
7
|
+
include Decidim::TranslatableAttributes
|
8
|
+
|
9
|
+
self.table_name = "decidim_navigation_maps_blueprint_areas"
|
10
|
+
|
11
|
+
belongs_to :blueprint, foreign_key: :decidim_navigation_maps_blueprint_id, class_name: "Decidim::NavigationMaps::Blueprint"
|
12
|
+
|
13
|
+
attribute :link_type, :string, default: "link"
|
14
|
+
|
15
|
+
validates :blueprint, presence: true
|
16
|
+
|
17
|
+
def to_geoson
|
18
|
+
{
|
19
|
+
type: area_type,
|
20
|
+
geometry: area,
|
21
|
+
properties: {
|
22
|
+
link: link,
|
23
|
+
popup: link_type == "direct",
|
24
|
+
color: color,
|
25
|
+
title: translated_attribute(title),
|
26
|
+
description: translated_attribute(description)
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|