decidim-meetings 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/config/decidim_meetings_manifest.js +2 -0
- data/app/assets/javascripts/decidim/meetings/map.js.es6.erb +92 -0
- data/app/assets/stylesheets/decidim/meetings/map.css +1 -0
- data/app/commands/decidim/meetings/admin/close_meeting.rb +53 -0
- data/app/commands/decidim/meetings/admin/create_meeting.rb +15 -3
- data/app/commands/decidim/meetings/admin/update_meeting.rb +15 -3
- data/app/controllers/decidim/meetings/admin/application_controller.rb +9 -0
- data/app/controllers/decidim/meetings/admin/attachments_controller.rb +29 -0
- data/app/controllers/decidim/meetings/admin/meeting_closes_controller.rb +38 -0
- data/app/controllers/decidim/meetings/admin/meetings_controller.rb +0 -12
- data/app/controllers/decidim/meetings/meetings_controller.rb +11 -9
- data/app/forms/decidim/meetings/admin/close_meeting_form.rb +31 -0
- data/app/forms/decidim/meetings/admin/meeting_form.rb +0 -2
- data/app/helpers/decidim/meetings/admin/application_helper.rb +12 -0
- data/app/helpers/decidim/meetings/application_helper.rb +1 -0
- data/app/helpers/decidim/meetings/map_helper.rb +46 -0
- data/app/models/decidim/meetings/meeting.rb +11 -15
- data/app/services/decidim/meetings/meeting_search.rb +0 -1
- data/app/services/decidim/meetings/static_map_generator.rb +50 -0
- data/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +23 -0
- data/app/views/decidim/meetings/admin/meeting_closes/edit.html.erb +9 -0
- data/app/views/decidim/meetings/admin/meetings/_form.html.erb +2 -6
- data/app/views/decidim/meetings/admin/meetings/index.html.erb +14 -0
- data/app/views/decidim/meetings/meetings/_datetime.html.erb +8 -0
- data/app/views/decidim/meetings/meetings/_filters.html.erb +2 -2
- data/app/views/decidim/meetings/meetings/_filters_small_view.html.erb +18 -0
- data/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +22 -0
- data/app/views/decidim/meetings/meetings/_meetings.html.erb +3 -10
- data/app/views/decidim/meetings/meetings/index.html.erb +42 -0
- data/app/views/decidim/meetings/meetings/index.js.erb +6 -0
- data/app/views/decidim/meetings/meetings/show.html.erb +33 -7
- data/config/i18n-tasks.yml +2 -0
- data/config/locales/ca.yml +37 -4
- data/config/locales/en.yml +34 -1
- data/config/locales/es.yml +36 -3
- data/db/migrate/20170110142105_close_a_meeting.rb +9 -0
- data/db/migrate/20170123151650_add_latitude_and_longitude_to_meetings.rb +6 -0
- data/db/migrate/20170129153716_remove_short_description_from_meetings.rb +5 -0
- data/lib/decidim/meetings/admin_engine.rb +31 -1
- data/lib/decidim/meetings/feature.rb +20 -6
- data/lib/decidim/meetings/list_engine.rb +10 -1
- data/lib/decidim/meetings/seeds/Exampledocument.pdf +0 -0
- data/lib/decidim/meetings/seeds/city.jpeg +0 -0
- data/lib/decidim/meetings/test/factories.rb +23 -0
- metadata +125 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39ecff3ff25e1f270d3bcd1b057d2f6035179297
|
4
|
+
data.tar.gz: a9796345f56085b0bf6613ec26b83823fb8e1652
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23ab8448060b0e8b10c0f079a31ded9cda519842ca798c0e5c42a4fb17acd5b9b5ce73c9ce4a9d0b5c66dabc3899fe4e5a78065da5709b3698a7de383b3b1f5b
|
7
|
+
data.tar.gz: 37d206c6c7ff80a8d82416233c6a30a2c9f868c6acff8ab5d6a3b2f0a517ab394d9c56fc3b8ad50f3c53bb50ba70616e511051f41c8cd022c324f322607733b9
|
@@ -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
|
25
|
-
Meeting.
|
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
|
30
|
-
@meeting.
|
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,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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
include Decidim::Resourceable
|
9
|
+
include Decidim::HasAttachments
|
10
|
+
include Decidim::HasFeature
|
11
|
+
include Decidim::HasScope
|
12
|
+
include Decidim::HasCategory
|
12
13
|
|
13
|
-
|
14
|
-
validate :category_belongs_to_organization
|
14
|
+
feature_manifest_name "meetings"
|
15
15
|
|
16
|
-
|
16
|
+
validates :title, presence: true
|
17
17
|
|
18
|
-
|
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
|
24
|
-
|
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 %>
|
@@ -3,11 +3,11 @@
|
|
3
3
|
</div>
|
4
4
|
|
5
5
|
<div class="field" >
|
6
|
-
<%= form.translated :editor, :
|
6
|
+
<%= form.translated :editor, :description %>
|
7
7
|
</div>
|
8
8
|
|
9
9
|
<div class="field" >
|
10
|
-
<%= form.
|
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>
|