decidim-meetings 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_meetings_manifest.js +2 -0
  3. data/app/assets/javascripts/decidim/meetings/map.js.es6.erb +92 -0
  4. data/app/assets/stylesheets/decidim/meetings/map.css +1 -0
  5. data/app/commands/decidim/meetings/admin/close_meeting.rb +53 -0
  6. data/app/commands/decidim/meetings/admin/create_meeting.rb +15 -3
  7. data/app/commands/decidim/meetings/admin/update_meeting.rb +15 -3
  8. data/app/controllers/decidim/meetings/admin/application_controller.rb +9 -0
  9. data/app/controllers/decidim/meetings/admin/attachments_controller.rb +29 -0
  10. data/app/controllers/decidim/meetings/admin/meeting_closes_controller.rb +38 -0
  11. data/app/controllers/decidim/meetings/admin/meetings_controller.rb +0 -12
  12. data/app/controllers/decidim/meetings/meetings_controller.rb +11 -9
  13. data/app/forms/decidim/meetings/admin/close_meeting_form.rb +31 -0
  14. data/app/forms/decidim/meetings/admin/meeting_form.rb +0 -2
  15. data/app/helpers/decidim/meetings/admin/application_helper.rb +12 -0
  16. data/app/helpers/decidim/meetings/application_helper.rb +1 -0
  17. data/app/helpers/decidim/meetings/map_helper.rb +46 -0
  18. data/app/models/decidim/meetings/meeting.rb +11 -15
  19. data/app/services/decidim/meetings/meeting_search.rb +0 -1
  20. data/app/services/decidim/meetings/static_map_generator.rb +50 -0
  21. data/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +23 -0
  22. data/app/views/decidim/meetings/admin/meeting_closes/edit.html.erb +9 -0
  23. data/app/views/decidim/meetings/admin/meetings/_form.html.erb +2 -6
  24. data/app/views/decidim/meetings/admin/meetings/index.html.erb +14 -0
  25. data/app/views/decidim/meetings/meetings/_datetime.html.erb +8 -0
  26. data/app/views/decidim/meetings/meetings/_filters.html.erb +2 -2
  27. data/app/views/decidim/meetings/meetings/_filters_small_view.html.erb +18 -0
  28. data/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +22 -0
  29. data/app/views/decidim/meetings/meetings/_meetings.html.erb +3 -10
  30. data/app/views/decidim/meetings/meetings/index.html.erb +42 -0
  31. data/app/views/decidim/meetings/meetings/index.js.erb +6 -0
  32. data/app/views/decidim/meetings/meetings/show.html.erb +33 -7
  33. data/config/i18n-tasks.yml +2 -0
  34. data/config/locales/ca.yml +37 -4
  35. data/config/locales/en.yml +34 -1
  36. data/config/locales/es.yml +36 -3
  37. data/db/migrate/20170110142105_close_a_meeting.rb +9 -0
  38. data/db/migrate/20170123151650_add_latitude_and_longitude_to_meetings.rb +6 -0
  39. data/db/migrate/20170129153716_remove_short_description_from_meetings.rb +5 -0
  40. data/lib/decidim/meetings/admin_engine.rb +31 -1
  41. data/lib/decidim/meetings/feature.rb +20 -6
  42. data/lib/decidim/meetings/list_engine.rb +10 -1
  43. data/lib/decidim/meetings/seeds/Exampledocument.pdf +0 -0
  44. data/lib/decidim/meetings/seeds/city.jpeg +0 -0
  45. data/lib/decidim/meetings/test/factories.rb +23 -0
  46. metadata +125 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e19fd2bced64fedffeeb7e466c5afcbcad2b814
4
- data.tar.gz: 8fadc5f684e7324c085da6f956923b66eb7c1818
3
+ metadata.gz: 39ecff3ff25e1f270d3bcd1b057d2f6035179297
4
+ data.tar.gz: a9796345f56085b0bf6613ec26b83823fb8e1652
5
5
  SHA512:
6
- metadata.gz: 7784edad8cef64c16f94fd8c94c175a23b61361beb7dafa50cf4b1ec8fc0aec0c86005578923baf7dce7c4bc2c13a55357375c21263926701a5c226fbe44fc1f
7
- data.tar.gz: 17e3efaa9f8d2e42642811a6b0336ae04409344f7e6b0ec19a12a18f3171b5e386432f884017674c8a30625bebce40e4b543c3b331728e6321cf4fc37ddca5dd
6
+ metadata.gz: 23ab8448060b0e8b10c0f079a31ded9cda519842ca798c0e5c42a4fb17acd5b9b5ce73c9ce4a9d0b5c66dabc3899fe4e5a78065da5709b3698a7de383b3b1f5b
7
+ data.tar.gz: 37d206c6c7ff80a8d82416233c6a30a2c9f868c6acff8ab5d6a3b2f0a517ab394d9c56fc3b8ad50f3c53bb50ba70616e511051f41c8cd022c324f322607733b9
@@ -0,0 +1,2 @@
1
+ //= link decidim/meetings/map.js
2
+ //= link decidim/meetings/map.css
@@ -0,0 +1,92 @@
1
+ // = require leaflet
2
+ // = require leaflet-tilelayer-here
3
+ // = require leaflet-svg-icon
4
+ // = require jquery-tmpl
5
+ // = require_self
6
+
7
+ /* globals L */
8
+
9
+ L.DivIcon.SVGIcon.DecidimIcon = L.DivIcon.SVGIcon.extend({
10
+ options: {
11
+ fillColor: '#ef604d',
12
+ opacity: 0
13
+ },
14
+ _createPathDescription: function() {
15
+ return 'M14 1.17a11.685 11.685 0 0 0-11.685 11.685c0 11.25 10.23 20.61 10.665 21a1.5 1.5 0 0 0 2.025 0c0.435-.435 10.665-9.81 10.665-21A11.685 11.685 0 0 0 14 1.17Zm0 17.415A5.085 5.085 0 1 1 19.085 13.5 5.085 5.085 0 0 1 14 18.585Z';
16
+ },
17
+ _createCircle: function() {
18
+ return ""
19
+ }
20
+ });
21
+
22
+ const popupTemplateId = 'meeting-popup';
23
+ $.template('meeting-popup', $(`#${popupTemplateId}`).html());
24
+
25
+ const addMarkers = (meetingsData, map) => {
26
+ const bounds = new L.LatLngBounds(meetingsData.map((meeting) => [meeting.latitude, meeting.longitude]));
27
+
28
+ meetingsData.forEach((meeting) => {
29
+ let marker = L.marker([meeting.latitude, meeting.longitude], {
30
+ icon: new L.DivIcon.SVGIcon.DecidimIcon()
31
+ }).addTo(map);
32
+ let node = document.createElement('div');
33
+
34
+ $.tmpl('meeting-popup', meeting).appendTo(node);
35
+
36
+ marker.bindPopup(node, {
37
+ maxwidth: 640,
38
+ minWidth: 500,
39
+ keepInView: true,
40
+ className: 'map-info'
41
+ }).openPopup();
42
+ });
43
+
44
+ map.fitBounds(bounds, { padding: [100, 100] });
45
+ };
46
+
47
+ const loadMap = (mapId, meetingsData) => {
48
+ const { hereAppId, hereAppCode } = window.DecidimMeetings.mapConfiguration;
49
+
50
+ if (window.DecidimMeetings.currentMap) {
51
+ window.DecidimMeetings.currentMap.remove();
52
+ window.DecidimMeetings.currentMap = null;
53
+ }
54
+
55
+ const map = L.map(mapId);
56
+
57
+ L.tileLayer.here({
58
+ appId: hereAppId,
59
+ appCode: hereAppCode,
60
+ }).addTo(map);
61
+
62
+ if (meetingsData.length > 0) {
63
+ addMarkers(meetingsData, map);
64
+ } else {
65
+ map.fitWorld();
66
+ }
67
+
68
+ map.scrollWheelZoom.disable();
69
+
70
+ return map;
71
+ };
72
+
73
+ window.DecidimMeetings = {
74
+ loadMap,
75
+ currentMap: null,
76
+ mapConfiguration: {}
77
+ };
78
+
79
+ $(() => {
80
+ const mapId = 'meetings-map';
81
+ const $map = $(`#${mapId}`);
82
+
83
+ const meetingsData = $map.data('meetings');
84
+ const hereAppId = $map.data('here-app-id');
85
+ const hereAppCode = $map.data('here-app-code');
86
+
87
+ window.DecidimMeetings.mapConfiguration = { hereAppId, hereAppCode };
88
+
89
+ if ($map.length > 0) {
90
+ window.DecidimMeetings.currentMap = loadMap(mapId, meetingsData);
91
+ }
92
+ });
@@ -0,0 +1 @@
1
+ /* = require leaflet */
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Meetings
4
+ module Admin
5
+ # This command is executed when the user closes a Meeting from the admin
6
+ # panel.
7
+ class CloseMeeting < Rectify::Command
8
+ # Initializes a CloseMeeting Command.
9
+ #
10
+ # form - The form from which to get the data.
11
+ # meeting - The current instance of the page to be closed.
12
+ def initialize(form, meeting)
13
+ @form = form
14
+ @meeting = meeting
15
+ end
16
+
17
+ # Closes the meeting if valid.
18
+ #
19
+ # Broadcasts :ok if successful, :invalid otherwise.
20
+ def call
21
+ return broadcast(:invalid) if @form.invalid?
22
+
23
+ transaction do
24
+ close_meeting
25
+ link_proposals
26
+ end
27
+
28
+ broadcast(:ok)
29
+ end
30
+
31
+ private
32
+
33
+ def close_meeting
34
+ @meeting.update_attributes!(
35
+ closing_report: @form.closing_report,
36
+ attendees_count: @form.attendees_count,
37
+ contributions_count: @form.contributions_count,
38
+ attending_organizations: @form.attending_organizations,
39
+ closed_at: @form.closed_at
40
+ )
41
+ end
42
+
43
+ def proposals
44
+ @meeting.sibling_scope(:proposals).where(id: @form.proposal_ids)
45
+ end
46
+
47
+ def link_proposals
48
+ @meeting.link_resources(proposals, "proposals_from_meeting")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -15,18 +15,20 @@ module Decidim
15
15
  def call
16
16
  return broadcast(:invalid) if @form.invalid?
17
17
 
18
+ build_meeting
19
+ return broadcast(:invalid) if Decidim.geocoder.present? && !geocode_meeting
18
20
  create_meeting
21
+
19
22
  broadcast(:ok)
20
23
  end
21
24
 
22
25
  private
23
26
 
24
- def create_meeting
25
- Meeting.create!(
27
+ def build_meeting
28
+ @meeting = Meeting.new(
26
29
  scope: @form.scope,
27
30
  category: @form.category,
28
31
  title: @form.title,
29
- short_description: @form.short_description,
30
32
  description: @form.description,
31
33
  end_time: @form.end_time,
32
34
  start_time: @form.start_time,
@@ -36,6 +38,16 @@ module Decidim
36
38
  feature: @form.current_feature
37
39
  )
38
40
  end
41
+
42
+ def geocode_meeting
43
+ result = @meeting.geocode
44
+ @form.errors.add :address, :invalid unless result
45
+ result
46
+ end
47
+
48
+ def create_meeting
49
+ @meeting.save!
50
+ end
39
51
  end
40
52
  end
41
53
  end
@@ -20,18 +20,20 @@ module Decidim
20
20
  def call
21
21
  return broadcast(:invalid) if @form.invalid?
22
22
 
23
+ change_meeting
24
+ return broadcast(:invalid) if Decidim.geocoder.present? && @meeting.address_changed? && !geocode_meeting
23
25
  update_meeting
26
+
24
27
  broadcast(:ok)
25
28
  end
26
29
 
27
30
  private
28
31
 
29
- def update_meeting
30
- @meeting.update_attributes!(
32
+ def change_meeting
33
+ @meeting.assign_attributes(
31
34
  scope: @form.scope,
32
35
  category: @form.category,
33
36
  title: @form.title,
34
- short_description: @form.short_description,
35
37
  description: @form.description,
36
38
  end_time: @form.end_time,
37
39
  start_time: @form.start_time,
@@ -40,6 +42,16 @@ module Decidim
40
42
  location_hints: @form.location_hints
41
43
  )
42
44
  end
45
+
46
+ def geocode_meeting
47
+ result = @meeting.geocode
48
+ @form.errors.add :address, :invalid unless result
49
+ result
50
+ end
51
+
52
+ def update_meeting
53
+ @meeting.save!
54
+ end
43
55
  end
44
56
  end
45
57
  end
@@ -8,6 +8,15 @@ module Decidim
8
8
  # Note that it inherits from `Decidim::Features::BaseController`, which
9
9
  # override its layout and provide all kinds of useful methods.
10
10
  class ApplicationController < Decidim::Admin::Features::BaseController
11
+ helper_method :meetings, :meeting
12
+
13
+ def meetings
14
+ @meetings ||= Meeting.where(feature: current_feature)
15
+ end
16
+
17
+ def meeting
18
+ @meeting ||= meetings.find(params[:id])
19
+ end
11
20
  end
12
21
  end
13
22
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Meetings
4
+ module Admin
5
+ # Controller that allows managing all the attachments for a participatory
6
+ # process.
7
+ #
8
+ class AttachmentsController < Admin::ApplicationController
9
+ include Decidim::Admin::Concerns::HasAttachments
10
+
11
+ def after_destroy_path
12
+ meetings_path
13
+ end
14
+
15
+ def attached_to
16
+ meeting
17
+ end
18
+
19
+ def meeting
20
+ @meeting ||= meetings.find(params[:meeting_id])
21
+ end
22
+
23
+ def authorization_object
24
+ meeting.feature
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Meetings
4
+ module Admin
5
+ # This controller allows an admin to manage meetings from a Participatory Process
6
+ class MeetingClosesController < Admin::ApplicationController
7
+ helper ResourceHelper
8
+ helper_method :meeting
9
+
10
+ def edit
11
+ @form = form(CloseMeetingForm).from_model(meeting)
12
+ end
13
+
14
+ def update
15
+ @form = form(CloseMeetingForm).from_params(params.merge(proposals: meeting.sibling_scope(:proposals)))
16
+
17
+ CloseMeeting.call(@form, meeting) do
18
+ on(:ok) do
19
+ flash[:notice] = I18n.t("meetings.close.success", scope: "decidim.meetings.admin")
20
+ redirect_to meetings_path
21
+ end
22
+
23
+ on(:invalid) do
24
+ flash.now[:alert] = I18n.t("meetings.close.invalid", scope: "decidim.meetings.admin")
25
+ render action: "edit"
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def meeting
33
+ @meeting ||= Meeting.where(feature: current_feature).find(params[:id])
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -4,8 +4,6 @@ module Decidim
4
4
  module Admin
5
5
  # This controller allows an admin to manage meetings from a Participatory Process
6
6
  class MeetingsController < Admin::ApplicationController
7
- helper_method :meetings
8
-
9
7
  def new
10
8
  @form = form(MeetingForm).instance
11
9
  end
@@ -53,16 +51,6 @@ module Decidim
53
51
 
54
52
  redirect_to meetings_path
55
53
  end
56
-
57
- private
58
-
59
- def meetings
60
- @meetings ||= Meeting.where(feature: current_feature)
61
- end
62
-
63
- def meeting
64
- @meeting ||= meetings.find(params[:id])
65
- end
66
54
  end
67
55
  end
68
56
  end
@@ -6,14 +6,23 @@ module Decidim
6
6
  class MeetingsController < Decidim::Meetings::ApplicationController
7
7
  include FilterResource
8
8
 
9
- helper_method :meetings, :meeting
9
+ helper_method :meetings, :geocoded_meetings, :meeting
10
10
 
11
11
  def index; end
12
12
 
13
+ def static_map
14
+ @meeting = Meeting.where(feature: current_feature).find(params[:id])
15
+ send_data StaticMapGenerator.new(@meeting).data, type: "image/jpeg", disposition: "inline"
16
+ end
17
+
13
18
  private
14
19
 
15
20
  def meetings
16
- @meetings ||= search.results
21
+ @meetings ||= search.results.page(params[:page]).per(12)
22
+ end
23
+
24
+ def geocoded_meetings
25
+ @geocoded_meetings ||= search.results.select(&:geocoded?)
17
26
  end
18
27
 
19
28
  def meeting
@@ -24,13 +33,6 @@ module Decidim
24
33
  MeetingSearch
25
34
  end
26
35
 
27
- def default_search_params
28
- {
29
- page: params[:page],
30
- per_page: 12
31
- }
32
- end
33
-
34
36
  def default_filter_params
35
37
  {
36
38
  order_start_time: "asc",
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Meetings
4
+ module Admin
5
+ # This class holds a Form to close a meeting from Decidim's admin panel.
6
+ class CloseMeetingForm < Decidim::Form
7
+ include TranslatableAttributes
8
+
9
+ translatable_attribute :closing_report, String
10
+ attribute :attendees_count, Integer, default: 0
11
+ attribute :contributions_count, Integer, default: 0
12
+ attribute :attending_organizations, String
13
+ attribute :proposal_ids, Array[Integer]
14
+ attribute :proposals
15
+ attribute :closed_at, DateTime, default: ->(_form, _attribute) { Time.current }
16
+
17
+ validates :closing_report, translatable_presence: true
18
+ validates :attendees_count, :contributions_count, presence: true, numericality: { greater_than_or_equal_to: 0 }
19
+ validates :attending_organizations, presence: true
20
+
21
+ # Private: Gets the proposals from the meeting and injects them to the form.
22
+ #
23
+ # Returns nothing.
24
+ def map_model(model)
25
+ self.proposal_ids = model.linked_resources(:proposals, "proposals_from_meeting").pluck(:id)
26
+ self.proposals = model.sibling_scope(:proposals)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -7,7 +7,6 @@ module Decidim
7
7
  include TranslatableAttributes
8
8
 
9
9
  translatable_attribute :title, String
10
- translatable_attribute :short_description, String
11
10
  translatable_attribute :description, String
12
11
  translatable_attribute :location, String
13
12
  translatable_attribute :location_hints, String
@@ -18,7 +17,6 @@ module Decidim
18
17
  attribute :decidim_category_id, Integer
19
18
 
20
19
  validates :title, translatable_presence: true
21
- validates :short_description, translatable_presence: true
22
20
  validates :description, translatable_presence: true
23
21
  validates :location, translatable_presence: true
24
22
  validates :address, presence: true
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Meetings
4
+ module Admin
5
+ # Custom helpers, scoped to the meetings admin engine.
6
+ #
7
+ module ApplicationHelper
8
+ include MapHelper
9
+ end
10
+ end
11
+ end
12
+ end
@@ -5,6 +5,7 @@ module Decidim
5
5
  #
6
6
  module ApplicationHelper
7
7
  include PaginateHelper
8
+ include MapHelper
8
9
  end
9
10
  end
10
11
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ module Meetings
4
+ # This helper include some methods for rendering meetings static and dynamic maps.
5
+ module MapHelper
6
+ # Renders a link to openstreetmaps with the meeting latitude and longitude.
7
+ # The link's content is a static map image.
8
+ #
9
+ # meeting - A Decidim::Meetings::Meeting object
10
+ # options - An optional hash of options (default: { zoom: 17 })
11
+ # * zoom: A number to represent the zoom value of the map
12
+ def static_map_link(meeting, options = {})
13
+ if meeting.geocoded?
14
+ zoom = options[:zoom] || 17
15
+ latitude = meeting.latitude
16
+ longitude = meeting.longitude
17
+
18
+ map_url = "https://www.openstreetmap.org/?mlat=#{latitude}&mlon=#{longitude}#map=#{zoom}/#{latitude}/#{longitude}"
19
+
20
+ link_to map_url, target: "_blank" do
21
+ image_tag decidim_meetings.static_map_meeting_path(feature_id: meeting.feature,
22
+ participatory_process_id: meeting.feature.participatory_process,
23
+ id: meeting)
24
+ end
25
+ end
26
+ end
27
+
28
+ # Serialize a collection of geocoded meetings to be used by the dynamic map component
29
+ #
30
+ # geocoded_meetings - A collection of geocoded meetings
31
+ def meetings_data_for_map(geocoded_meetings)
32
+ geocoded_meetings.map do |meeting|
33
+ meeting.slice(:latitude, :longitude, :address).merge(title: translated_attribute(meeting.title),
34
+ description: translated_attribute(meeting.description),
35
+ startTimeDay: l(meeting.start_time, format: "%d"),
36
+ startTimeMonth: l(meeting.start_time, format: "%B"),
37
+ startTime: "#{meeting.start_time.strftime("%H:%M")} - #{meeting.end_time.strftime("%H:%M")}",
38
+ icon: icon("meetings", width: 40, height: 70, remove_icon_class: true),
39
+ location: translated_attribute(meeting.location),
40
+ locationHints: translated_attribute(meeting.location_hints),
41
+ link: meeting_path(meeting))
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,28 +1,24 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Meetings
4
5
  # The data store for a Meeting in the Decidim::Meetings component. It stores a
5
6
  # title, description and any other useful information to render a custom meeting.
6
7
  class Meeting < Meetings::ApplicationRecord
7
- belongs_to :feature, foreign_key: "decidim_feature_id", class_name: Decidim::Feature
8
- belongs_to :scope, foreign_key: "decidim_scope_id", class_name: Decidim::Scope
9
- belongs_to :category, foreign_key: "decidim_category_id", class_name: Decidim::Category
10
- has_one :organization, through: :feature
11
- validates :title, presence: true
8
+ include Decidim::Resourceable
9
+ include Decidim::HasAttachments
10
+ include Decidim::HasFeature
11
+ include Decidim::HasScope
12
+ include Decidim::HasCategory
12
13
 
13
- validate :scope_belongs_to_organization
14
- validate :category_belongs_to_organization
14
+ feature_manifest_name "meetings"
15
15
 
16
- private
16
+ validates :title, presence: true
17
17
 
18
- def scope_belongs_to_organization
19
- return unless scope
20
- errors.add(:scope, :invalid) unless feature.scopes.where(id: scope.id).exists?
21
- end
18
+ geocoded_by :address
22
19
 
23
- def category_belongs_to_organization
24
- return unless category
25
- errors.add(:category, :invalid) unless feature.categories.where(id: category.id).exists?
20
+ def closed?
21
+ closed_at.present?
26
22
  end
27
23
  end
28
24
  end
@@ -18,7 +18,6 @@ module Decidim
18
18
  query
19
19
  .where(localized_search_text_in(:title), text: "%#{search_text}%")
20
20
  .or(query.where(localized_search_text_in(:description), text: "%#{search_text}%"))
21
- .or(query.where(localized_search_text_in(:short_description), text: "%#{search_text}%"))
22
21
  end
23
22
 
24
23
  # Handle the order_start_time filter
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ require "httparty"
3
+
4
+ module Decidim
5
+ module Meetings
6
+ # This class generates a url to create a static map image for a geocoded meeting
7
+ class StaticMapGenerator
8
+ BASE_HOST = "image.maps.cit.api.here.com"
9
+ BASE_PATH = "/mia/1.6/mapview"
10
+
11
+ def initialize(meeting, options = {})
12
+ @meeting = meeting
13
+ @options = options
14
+
15
+ @options[:zoom] ||= 15
16
+ @options[:width] ||= 120
17
+ @options[:height] ||= 120
18
+ end
19
+
20
+ def data
21
+ return if Decidim.geocoder.nil?
22
+
23
+ Rails.cache.fetch(@meeting.cache_key) do
24
+ request = HTTParty.get(uri)
25
+ request.body
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def uri
32
+ params = {
33
+ c: "#{@meeting.latitude}, #{@meeting.longitude}",
34
+ z: @options[:zoom],
35
+ w: @options[:width],
36
+ h: @options[:height],
37
+ f: "1",
38
+ app_id: Decidim.geocoder&.fetch(:here_app_id),
39
+ app_code: Decidim.geocoder&.fetch(:here_app_code)
40
+ }
41
+
42
+ uri = URI.parse("https://#{BASE_HOST}#{BASE_PATH}").tap do |uri|
43
+ uri.query = URI.encode_www_form params
44
+ end
45
+
46
+ uri
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ <div class="field">
2
+ <%= form.translated :text_area, :closing_report, autofocus: true, rows: 15 %>
3
+ </div>
4
+
5
+ <div class="field">
6
+ <%= form.text_area :attending_organizations, rows: 5 %>
7
+ </div>
8
+
9
+ <div class="field">
10
+ <%= form.number_field :attendees_count, min: 0 %>
11
+ </div>
12
+
13
+ <div class="field">
14
+ <%= form.number_field :contributions_count, min: 0 %>
15
+ </div>
16
+
17
+ <% if @form.proposals %>
18
+ <%= form.select :proposal_ids,
19
+ @form.proposals.order("title ASC").pluck(:title, :id),
20
+ { include_blank: true },
21
+ { multiple: true, class: "chosen-select" }
22
+ %>
23
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <h3><%= t ".title" %></h3>
2
+
3
+ <%= form_for(@form, url: meeting_meeting_close_path(meeting, @form)) do |f| %>
4
+ <%= render partial: 'form', object: f %>
5
+
6
+ <div class="actions">
7
+ <%= f.submit t(".close") %>
8
+ </div>
9
+ <% end %>
@@ -3,11 +3,11 @@
3
3
  </div>
4
4
 
5
5
  <div class="field" >
6
- <%= form.translated :editor, :short_description %>
6
+ <%= form.translated :editor, :description %>
7
7
  </div>
8
8
 
9
9
  <div class="field" >
10
- <%= form.translated :editor, :description %>
10
+ <%= form.text_field :address %>
11
11
  </div>
12
12
 
13
13
  <div class="field" >
@@ -18,10 +18,6 @@
18
18
  <%= form.translated :text_area, :location_hints %>
19
19
  </div>
20
20
 
21
- <div class="field" >
22
- <%= form.text_field :address %>
23
- </div>
24
-
25
21
  <div class="field" >
26
22
  <%= form.datetime_field :start_time %>
27
23
  </div>