decidim-meetings 0.25.0 → 0.26.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/cells/decidim/meetings/content_blocks/highlighted_meetings/heading.erb +1 -1
- data/app/cells/decidim/meetings/content_blocks/highlighted_meetings_cell.rb +1 -1
- data/app/cells/decidim/meetings/content_blocks/{upcoming_events → upcoming_meetings}/show.erb +6 -6
- data/app/cells/decidim/meetings/content_blocks/{upcoming_events_cell.rb → upcoming_meetings_cell.rb} +11 -10
- data/app/cells/decidim/meetings/highlighted_meetings_for_component_cell.rb +1 -1
- data/app/cells/decidim/meetings/join_meeting_button_cell.rb +1 -1
- data/app/cells/decidim/meetings/meeting_list_item_cell.rb +10 -0
- data/app/cells/decidim/meetings/meeting_m_cell.rb +48 -0
- data/app/cells/decidim/meetings/meeting_s_cell.rb +22 -0
- data/app/cells/decidim/meetings/meetings_map_cell.rb +6 -0
- data/app/cells/decidim/meetings/online_meeting_cell.rb +23 -8
- data/app/cells/decidim/meetings/online_meeting_link/show.erb +2 -2
- data/app/cells/decidim/meetings/online_meeting_link_cell.rb +1 -5
- data/app/cells/decidim/meetings/public_participants_list_cell.rb +1 -0
- data/app/cells/decidim/meetings/question_responses_cell.rb +1 -1
- data/app/commands/decidim/meetings/admin/create_meeting.rb +11 -1
- data/app/commands/decidim/meetings/admin/publish_meeting.rb +3 -1
- data/app/commands/decidim/meetings/admin/update_meeting.rb +8 -2
- data/app/commands/decidim/meetings/create_meeting.rb +14 -2
- data/app/commands/decidim/meetings/update_meeting.rb +5 -2
- data/app/commands/decidim/meetings/withdraw_meeting.rb +39 -0
- data/app/controllers/concerns/decidim/meetings/filterable.rb +33 -0
- data/app/controllers/decidim/meetings/directory/application_controller.rb +16 -0
- data/app/controllers/decidim/meetings/directory/meetings_controller.rb +31 -20
- data/app/controllers/decidim/meetings/live_events_controller.rb +7 -1
- data/app/controllers/decidim/meetings/meetings_controller.rb +19 -17
- data/app/events/decidim/meetings/close_meeting_event.rb +1 -3
- data/app/events/decidim/meetings/create_meeting_event.rb +2 -4
- data/app/events/decidim/meetings/meeting_event.rb +37 -0
- data/app/events/decidim/meetings/meeting_registrations_enabled_event.rb +1 -3
- data/app/events/decidim/meetings/meeting_registrations_over_percentage_event.rb +2 -4
- data/app/events/decidim/meetings/registration_code_validated_event.rb +2 -4
- data/app/events/decidim/meetings/upcoming_meeting_event.rb +1 -3
- data/app/events/decidim/meetings/update_meeting_event.rb +1 -3
- data/app/forms/decidim/meetings/admin/close_meeting_form.rb +1 -1
- data/app/forms/decidim/meetings/admin/meeting_copy_form.rb +4 -13
- data/app/forms/decidim/meetings/admin/meeting_form.rb +34 -46
- data/app/forms/decidim/meetings/base_meeting_form.rb +59 -0
- data/app/forms/decidim/meetings/close_meeting_form.rb +6 -6
- data/app/forms/decidim/meetings/meeting_form.rb +30 -46
- data/app/helpers/decidim/meetings/application_helper.rb +13 -1
- data/app/helpers/decidim/meetings/directory/application_helper.rb +150 -0
- data/app/helpers/decidim/meetings/meeting_cells_helper.rb +4 -1
- data/app/helpers/decidim/meetings/meetings_helper.rb +3 -0
- data/app/models/decidim/meetings/meeting.rb +54 -2
- data/app/packs/src/decidim/meetings/admin/meetings_form.js +27 -11
- data/app/packs/src/decidim/meetings/meetings_form.js +19 -0
- data/app/packs/src/decidim/meetings/meetings_polls.js +31 -26
- data/app/permissions/decidim/meetings/permissions.rb +9 -1
- data/app/presenters/decidim/meetings/meeting_edition_presenter.rb +14 -0
- data/app/presenters/decidim/meetings/meeting_presenter.rb +13 -6
- data/app/services/decidim/meetings/directory/meeting_search.rb +53 -0
- data/app/services/decidim/meetings/meeting_iframe_embedder.rb +1 -1
- data/app/services/decidim/meetings/meeting_search.rb +15 -2
- data/app/views/decidim/meetings/admin/meeting_copies/_form.html.erb +16 -1
- data/app/views/decidim/meetings/admin/meeting_copies/new.html.erb +1 -1
- data/app/views/decidim/meetings/admin/meetings/_form.html.erb +15 -3
- data/app/views/decidim/meetings/directory/meetings/_filters.html.erb +34 -0
- data/app/views/decidim/meetings/directory/meetings/index.html.erb +1 -18
- data/app/views/decidim/meetings/meetings/_filters.html.erb +2 -0
- data/app/views/decidim/meetings/meetings/_filters_small_view.html.erb +3 -3
- data/app/views/decidim/meetings/meetings/_form.html.erb +14 -3
- data/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
- data/app/views/decidim/meetings/meetings/_meetings.html.erb +18 -0
- data/app/views/decidim/meetings/meetings/index.html.erb +1 -0
- data/app/views/decidim/meetings/meetings/show.html.erb +12 -13
- data/config/locales/ar.yml +2 -9
- data/config/locales/ca.yml +44 -16
- data/config/locales/cs.yml +41 -13
- data/config/locales/de.yml +56 -9
- data/config/locales/el.yml +2 -9
- data/config/locales/en.yml +41 -13
- data/config/locales/es-MX.yml +40 -12
- data/config/locales/es-PY.yml +41 -13
- data/config/locales/es.yml +41 -13
- data/config/locales/eu.yml +27 -13
- data/config/locales/fi-plain.yml +41 -13
- data/config/locales/fi.yml +41 -13
- data/config/locales/fr-CA.yml +48 -13
- data/config/locales/fr.yml +70 -35
- data/config/locales/ga-IE.yml +2 -7
- data/config/locales/gl.yml +28 -9
- data/config/locales/hu.yml +2 -9
- data/config/locales/id-ID.yml +2 -9
- data/config/locales/it.yml +4 -16
- data/config/locales/ja.yml +45 -17
- data/config/locales/lb-LU.yml +210 -0
- data/config/locales/lb.yml +2 -11
- data/config/locales/lv.yml +2 -9
- data/config/locales/nl.yml +33 -9
- data/config/locales/no.yml +2 -9
- data/config/locales/pl.yml +17 -12
- data/config/locales/pt-BR.yml +3 -10
- data/config/locales/pt.yml +2 -15
- data/config/locales/ro-RO.yml +194 -100
- data/config/locales/ru.yml +0 -8
- data/config/locales/sk.yml +2 -9
- data/config/locales/sl.yml +0 -3
- data/config/locales/sv.yml +83 -9
- data/config/locales/tr-TR.yml +3 -10
- data/config/locales/val-ES.yml +1 -0
- data/config/locales/zh-CN.yml +2 -9
- data/db/migrate/20210519133705_add_comments_availability_columns_to_meetings_table.rb +14 -0
- data/db/migrate/20210727085318_add_state_field_to_meeting.rb +7 -0
- data/db/migrate/20210903143040_add_iframe_access_level_to_decidim_meetings.rb +7 -0
- data/db/migrate/20210922140454_transform_show_embedded_iframe_column.rb +15 -0
- data/db/migrate/20210928095036_rename_upcoming_events_content_block_to_upcoming_meetings.rb +13 -0
- data/lib/decidim/api/meeting_type.rb +2 -1
- data/lib/decidim/meetings/component.rb +15 -6
- data/lib/decidim/meetings/directory_engine.rb +3 -3
- data/lib/decidim/meetings/engine.rb +8 -1
- data/lib/decidim/meetings/meeting_serializer.rb +2 -2
- data/lib/decidim/meetings/test/factories.rb +24 -3
- data/lib/decidim/meetings/test/notifications_handling.rb +39 -0
- data/lib/decidim/meetings/test/translated_event.rb +22 -0
- data/lib/decidim/meetings/version.rb +1 -1
- data/lib/decidim/meetings.rb +5 -0
- metadata +39 -22
@@ -4,10 +4,11 @@ module Decidim
|
|
4
4
|
module Meetings
|
5
5
|
module Directory
|
6
6
|
# Exposes the meeting resource so users can view them
|
7
|
-
class MeetingsController < Decidim::ApplicationController
|
7
|
+
class MeetingsController < Decidim::Meetings::Directory::ApplicationController
|
8
8
|
layout "layouts/decidim/application"
|
9
9
|
|
10
10
|
include FilterResource
|
11
|
+
include Filterable
|
11
12
|
include Paginable
|
12
13
|
|
13
14
|
helper Decidim::WidgetUrlsHelper
|
@@ -17,17 +18,6 @@ module Decidim
|
|
17
18
|
|
18
19
|
helper_method :meetings, :search
|
19
20
|
|
20
|
-
def index
|
21
|
-
@meeting_spaces = search.results.map do |meeting|
|
22
|
-
klass = meeting.component.participatory_space.class
|
23
|
-
[klass.model_name.name.underscore, klass.model_name.human(count: 2)]
|
24
|
-
end.uniq
|
25
|
-
@meeting_spaces = @meeting_spaces.sort_by do |_param, name|
|
26
|
-
name
|
27
|
-
end
|
28
|
-
@meeting_spaces.prepend(["all", t(".all")])
|
29
|
-
end
|
30
|
-
|
31
21
|
def calendar
|
32
22
|
render plain: CalendarRenderer.for(current_organization), content_type: "type/calendar"
|
33
23
|
end
|
@@ -39,26 +29,47 @@ module Decidim
|
|
39
29
|
end
|
40
30
|
|
41
31
|
def search_klass
|
42
|
-
MeetingSearch
|
32
|
+
::Decidim::Meetings::Directory::MeetingSearch
|
43
33
|
end
|
44
34
|
|
45
35
|
def default_filter_params
|
46
36
|
{
|
47
37
|
date: "upcoming",
|
48
38
|
search_text: "",
|
49
|
-
|
50
|
-
|
39
|
+
activity: "all",
|
40
|
+
scope_id: default_filter_scope_params,
|
41
|
+
space: default_filter_space_params,
|
42
|
+
type: default_filter_type_params,
|
43
|
+
origin: default_filter_origin_params,
|
44
|
+
category_id: default_filter_category_params
|
51
45
|
}
|
52
46
|
end
|
53
47
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
48
|
+
def default_filter_category_params
|
49
|
+
participatory_spaces = current_organization.public_participatory_spaces
|
50
|
+
list_of_ps = []
|
51
|
+
participatory_spaces.flat_map do |current_participatory_space|
|
52
|
+
next unless current_participatory_space.respond_to?(:categories)
|
53
|
+
|
54
|
+
key_point = current_participatory_space.class.name.gsub("::", "__") + current_participatory_space.id.to_s
|
55
|
+
|
56
|
+
list_of_ps.push(key_point)
|
57
|
+
list_of_ps += current_participatory_space.categories.pluck(:id).map(&:to_s)
|
58
|
+
end
|
59
|
+
|
60
|
+
["all"] + list_of_ps
|
61
|
+
end
|
62
|
+
|
63
|
+
def default_filter_space_params
|
64
|
+
%w(all) + current_organization.public_participatory_spaces.collect(&:model_name).uniq.collect(&:name).collect(&:underscore)
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_filter_scope_params
|
68
|
+
%w(all global) + current_organization.scopes.pluck(:id).map(&:to_s)
|
58
69
|
end
|
59
70
|
|
60
71
|
def context_params
|
61
|
-
{ component: meeting_components, organization: current_organization }
|
72
|
+
{ component: meeting_components, organization: current_organization, current_user: current_user }
|
62
73
|
end
|
63
74
|
|
64
75
|
def meeting_components
|
@@ -13,7 +13,7 @@ module Decidim
|
|
13
13
|
def show
|
14
14
|
raise ActionController::RoutingError, "Not Found" unless meeting
|
15
15
|
|
16
|
-
return if
|
16
|
+
return if allowed_for_current_user?
|
17
17
|
|
18
18
|
flash[:alert] = I18n.t("meeting.not_allowed", scope: "decidim.meetings")
|
19
19
|
redirect_to(ResourceLocatorPresenter.new(meeting).index)
|
@@ -21,6 +21,12 @@ module Decidim
|
|
21
21
|
|
22
22
|
private
|
23
23
|
|
24
|
+
def allowed_for_current_user?
|
25
|
+
meeting.current_user_can_visit_meeting?(current_user) &&
|
26
|
+
meeting.iframe_access_level_allowed_for_user?(current_user) &&
|
27
|
+
meeting.live?
|
28
|
+
end
|
29
|
+
|
24
30
|
def live_meeting_embed_code
|
25
31
|
MeetingIframeEmbedder.new(meeting.online_meeting_url).embed_code(request.host)
|
26
32
|
end
|
@@ -5,9 +5,12 @@ module Decidim
|
|
5
5
|
# Exposes the meeting resource so users can view them
|
6
6
|
class MeetingsController < Decidim::Meetings::ApplicationController
|
7
7
|
include FilterResource
|
8
|
+
include Filterable
|
8
9
|
include Flaggable
|
10
|
+
include Withdrawable
|
9
11
|
include FormFactory
|
10
12
|
include Paginable
|
13
|
+
|
11
14
|
helper Decidim::WidgetUrlsHelper
|
12
15
|
helper Decidim::ResourceVersionsHelper
|
13
16
|
|
@@ -83,6 +86,21 @@ module Decidim
|
|
83
86
|
end
|
84
87
|
end
|
85
88
|
|
89
|
+
def withdraw
|
90
|
+
enforce_permission_to :withdraw, :meeting, meeting: meeting
|
91
|
+
|
92
|
+
WithdrawMeeting.call(@meeting, current_user) do
|
93
|
+
on(:ok) do
|
94
|
+
flash[:notice] = I18n.t("meetings.withdraw.success", scope: "decidim")
|
95
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(@meeting).path
|
96
|
+
end
|
97
|
+
on(:invalid) do
|
98
|
+
flash[:alert] = I18n.t("meetings.withdraw.error", scope: "decidim")
|
99
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(@meeting).path
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
86
104
|
private
|
87
105
|
|
88
106
|
def meeting
|
@@ -112,27 +130,11 @@ module Decidim
|
|
112
130
|
activity: "all",
|
113
131
|
scope_id: default_filter_scope_params,
|
114
132
|
category_id: default_filter_category_params,
|
133
|
+
state: nil,
|
115
134
|
origin: default_filter_origin_params,
|
116
135
|
type: default_filter_type_params
|
117
136
|
}
|
118
137
|
end
|
119
|
-
|
120
|
-
def default_filter_origin_params
|
121
|
-
filter_origin_params = %w(citizens)
|
122
|
-
filter_origin_params << "official"
|
123
|
-
filter_origin_params << "user_group" if current_organization.user_groups_enabled?
|
124
|
-
filter_origin_params
|
125
|
-
end
|
126
|
-
|
127
|
-
def default_filter_type_params
|
128
|
-
%w(all) + Decidim::Meetings::Meeting::TYPE_OF_MEETING
|
129
|
-
end
|
130
|
-
|
131
|
-
def default_search_params
|
132
|
-
{
|
133
|
-
scope: Meeting.not_hidden.visible_meeting_for(current_user)
|
134
|
-
}
|
135
|
-
end
|
136
138
|
end
|
137
139
|
end
|
138
140
|
end
|
@@ -3,11 +3,9 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
5
|
class CreateMeetingEvent < Decidim::Events::SimpleEvent
|
6
|
-
|
6
|
+
include Decidim::Meetings::MeetingEvent
|
7
7
|
|
8
|
-
|
9
|
-
translated_attribute(resource.description)
|
10
|
-
end
|
8
|
+
delegate :organization, to: :user, prefix: false
|
11
9
|
|
12
10
|
def button_text
|
13
11
|
I18n.t("meeting_created.button_text", scope: "decidim.events.meetings") if resource.can_be_joined_by?(user)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
# This module is used to be included in events triggered by comments.
|
6
|
+
#
|
7
|
+
module MeetingEvent
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
include Decidim::Events::MachineTranslatedEvent
|
10
|
+
|
11
|
+
included do
|
12
|
+
def resource_text
|
13
|
+
translated_attribute(resource.description)
|
14
|
+
end
|
15
|
+
|
16
|
+
def translatable_resource
|
17
|
+
resource
|
18
|
+
end
|
19
|
+
|
20
|
+
def translatable_text
|
21
|
+
resource.description
|
22
|
+
end
|
23
|
+
|
24
|
+
def safe_resource_text
|
25
|
+
locale = resource.respond_to?(:content_original_language) ? resource.content_original_language : I18n.locale
|
26
|
+
I18n.with_locale(locale) { translated_attribute(resource.description).to_s.html_safe }
|
27
|
+
end
|
28
|
+
|
29
|
+
def safe_resource_translated_text
|
30
|
+
return safe_resource_text unless perform_translation?
|
31
|
+
|
32
|
+
I18n.with_locale(I18n.locale) { translated_attribute(resource.description, nil, true).to_s.html_safe }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -3,11 +3,9 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
5
|
class MeetingRegistrationsOverPercentageEvent < Decidim::Events::SimpleEvent
|
6
|
-
|
6
|
+
include Decidim::Meetings::MeetingEvent
|
7
7
|
|
8
|
-
|
9
|
-
translated_attribute(resource.description)
|
10
|
-
end
|
8
|
+
i18n_attributes :percentage
|
11
9
|
|
12
10
|
def percentage
|
13
11
|
extra["percentage"] * 100
|
@@ -3,11 +3,9 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
5
|
class RegistrationCodeValidatedEvent < Decidim::Events::SimpleEvent
|
6
|
-
|
6
|
+
include Decidim::Meetings::MeetingEvent
|
7
7
|
|
8
|
-
|
9
|
-
translated_attribute(resource.description)
|
10
|
-
end
|
8
|
+
i18n_attributes :registration_code
|
11
9
|
|
12
10
|
private
|
13
11
|
|
@@ -19,7 +19,7 @@ module Decidim
|
|
19
19
|
attribute :closed_at, Decidim::Attributes::TimeWithZone, default: ->(_form, _attribute) { Time.current }
|
20
20
|
|
21
21
|
validates :closing_report, translatable_presence: true
|
22
|
-
validates :attendees_count, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
22
|
+
validates :attendees_count, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 999, only_integer: true }
|
23
23
|
validates :contributions_count, numericality: true, allow_blank: true
|
24
24
|
|
25
25
|
# Private: Gets the proposals from the meeting and injects them to the form.
|
@@ -6,7 +6,7 @@ module Decidim
|
|
6
6
|
# A form object used to copy a meeting from the admin
|
7
7
|
# dashboard.
|
8
8
|
#
|
9
|
-
class MeetingCopyForm <
|
9
|
+
class MeetingCopyForm < ::Decidim::Meetings::BaseMeetingForm
|
10
10
|
include TranslatableAttributes
|
11
11
|
|
12
12
|
translatable_attribute :title, String
|
@@ -14,26 +14,17 @@ module Decidim
|
|
14
14
|
translatable_attribute :location, String
|
15
15
|
translatable_attribute :location_hints, String
|
16
16
|
|
17
|
-
attribute :
|
18
|
-
attribute :latitude, Float
|
19
|
-
attribute :longitude, Float
|
20
|
-
attribute :start_time, Decidim::Attributes::TimeWithZone
|
21
|
-
attribute :end_time, Decidim::Attributes::TimeWithZone
|
17
|
+
attribute :show_embedded_iframe, Boolean, default: false
|
22
18
|
attribute :private_meeting, Boolean
|
23
19
|
attribute :transparent, Boolean
|
24
20
|
attribute :services, Array[MeetingServiceForm]
|
25
21
|
|
26
22
|
mimic :meeting
|
27
23
|
|
28
|
-
validates :
|
29
|
-
|
24
|
+
validates :online_meeting_url, url: true, if: ->(form) { form.online_meeting? || form.hybrid_meeting? }
|
30
25
|
validates :title, translatable_presence: true
|
31
26
|
validates :description, translatable_presence: true
|
32
|
-
validates :location, translatable_presence: true
|
33
|
-
validates :address, presence: true
|
34
|
-
validates :address, geocoding: true, if: -> { Decidim::Map.available?(:geocoding) }
|
35
|
-
validates :start_time, presence: true, date: { before: :end_time }
|
36
|
-
validates :end_time, presence: true, date: { after: :start_time }
|
27
|
+
validates :location, translatable_presence: true, if: ->(form) { form.in_person_meeting? || form.hybrid_meeting? }
|
37
28
|
|
38
29
|
def map_model(model)
|
39
30
|
self.services = model.services.map do |service|
|
@@ -4,26 +4,23 @@ module Decidim
|
|
4
4
|
module Meetings
|
5
5
|
module Admin
|
6
6
|
# This class holds a Form to create/update translatable meetings from Decidim's admin panel.
|
7
|
-
class MeetingForm < Decidim::
|
7
|
+
class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
|
8
8
|
include TranslatableAttributes
|
9
9
|
|
10
|
-
attribute :address, String
|
11
|
-
attribute :latitude, Float
|
12
|
-
attribute :longitude, Float
|
13
|
-
attribute :start_time, Decidim::Attributes::TimeWithZone
|
14
|
-
attribute :end_time, Decidim::Attributes::TimeWithZone
|
15
10
|
attribute :services, Array[MeetingServiceForm]
|
16
11
|
attribute :decidim_scope_id, Integer
|
17
12
|
attribute :decidim_category_id, Integer
|
18
13
|
attribute :private_meeting, Boolean
|
19
14
|
attribute :transparent, Boolean
|
20
|
-
attribute :online_meeting_url, String
|
21
|
-
attribute :type_of_meeting, String
|
22
15
|
attribute :registration_type, String
|
23
16
|
attribute :registration_url, String
|
24
17
|
attribute :available_slots, Integer, default: 0
|
25
18
|
attribute :customize_registration_email, Boolean
|
26
|
-
attribute :
|
19
|
+
attribute :iframe_embed_type, String, default: "none"
|
20
|
+
attribute :comments_enabled, Boolean, default: true
|
21
|
+
attribute :comments_start_time, Decidim::Attributes::TimeWithZone
|
22
|
+
attribute :comments_end_time, Decidim::Attributes::TimeWithZone
|
23
|
+
attribute :iframe_access_level, String
|
27
24
|
|
28
25
|
translatable_attribute :title, String
|
29
26
|
translatable_attribute :description, String
|
@@ -31,6 +28,7 @@ module Decidim
|
|
31
28
|
translatable_attribute :location_hints, String
|
32
29
|
translatable_attribute :registration_email_custom_content, String
|
33
30
|
|
31
|
+
validates :iframe_embed_type, inclusion: { in: Decidim::Meetings::Meeting.iframe_embed_types }
|
34
32
|
validates :title, translatable_presence: true
|
35
33
|
validates :description, translatable_presence: true
|
36
34
|
validates :registration_type, presence: true
|
@@ -38,18 +36,18 @@ module Decidim
|
|
38
36
|
validates :registration_url, presence: true, url: true, if: ->(form) { form.on_different_platform? }
|
39
37
|
validates :type_of_meeting, presence: true
|
40
38
|
validates :location, translatable_presence: true, if: ->(form) { form.in_person_meeting? || form.hybrid_meeting? }
|
41
|
-
|
42
|
-
validates :address, presence: true, if: ->(form) { form.needs_address? }
|
43
|
-
validates :address, geocoding: true, if: ->(form) { form.has_address? && !form.geocoded? && form.needs_address? }
|
44
39
|
validates :online_meeting_url, url: true, if: ->(form) { form.online_meeting? || form.hybrid_meeting? }
|
45
|
-
validates :
|
46
|
-
validates :
|
47
|
-
|
48
|
-
validates :current_component, presence: true
|
40
|
+
validates :comments_start_time, date: { before: :comments_end_time, allow_blank: true, if: proc { |obj| obj.comments_end_time.present? } }
|
41
|
+
validates :comments_end_time, date: { after: :comments_start_time, allow_blank: true, if: proc { |obj| obj.comments_start_time.present? } }
|
49
42
|
validates :category, presence: true, if: ->(form) { form.decidim_category_id.present? }
|
50
43
|
validates :scope, presence: true, if: ->(form) { form.decidim_scope_id.present? }
|
51
44
|
validates :decidim_scope_id, scope_belongs_to_component: true, if: ->(form) { form.decidim_scope_id.present? }
|
52
45
|
validates :clean_type_of_meeting, presence: true
|
46
|
+
validates(
|
47
|
+
:iframe_access_level,
|
48
|
+
inclusion: { in: Decidim::Meetings::Meeting.iframe_access_levels },
|
49
|
+
if: ->(form) { %w(embed_in_meeting_page open_in_live_event_page open_in_new_tab).include?(form.iframe_embed_type) }
|
50
|
+
)
|
53
51
|
validate :embeddable_meeting_url
|
54
52
|
|
55
53
|
delegate :categories, to: :current_component
|
@@ -97,34 +95,6 @@ module Decidim
|
|
97
95
|
@category ||= categories.find_by(id: decidim_category_id)
|
98
96
|
end
|
99
97
|
|
100
|
-
def geocoding_enabled?
|
101
|
-
Decidim::Map.available?(:geocoding)
|
102
|
-
end
|
103
|
-
|
104
|
-
def has_address?
|
105
|
-
geocoding_enabled? && address.present?
|
106
|
-
end
|
107
|
-
|
108
|
-
def needs_address?
|
109
|
-
in_person_meeting? || hybrid_meeting?
|
110
|
-
end
|
111
|
-
|
112
|
-
def geocoded?
|
113
|
-
latitude.present? && longitude.present?
|
114
|
-
end
|
115
|
-
|
116
|
-
def online_meeting?
|
117
|
-
type_of_meeting == "online"
|
118
|
-
end
|
119
|
-
|
120
|
-
def in_person_meeting?
|
121
|
-
type_of_meeting == "in_person"
|
122
|
-
end
|
123
|
-
|
124
|
-
def hybrid_meeting?
|
125
|
-
type_of_meeting == "hybrid"
|
126
|
-
end
|
127
|
-
|
128
98
|
def clean_type_of_meeting
|
129
99
|
type_of_meeting.presence
|
130
100
|
end
|
@@ -138,6 +108,24 @@ module Decidim
|
|
138
108
|
end
|
139
109
|
end
|
140
110
|
|
111
|
+
def iframe_access_level_select
|
112
|
+
Decidim::Meetings::Meeting.iframe_access_levels.map do |level, _value|
|
113
|
+
[
|
114
|
+
I18n.t("iframe_access_level.#{level}", scope: "decidim.meetings"),
|
115
|
+
level
|
116
|
+
]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def iframe_embed_type_select
|
121
|
+
Decidim::Meetings::Meeting.iframe_embed_types.map do |type, _value|
|
122
|
+
[
|
123
|
+
I18n.t("iframe_embed_type.#{type}", scope: "decidim.meetings"),
|
124
|
+
type
|
125
|
+
]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
141
129
|
def on_this_platform?
|
142
130
|
registration_type == "on_this_platform"
|
143
131
|
end
|
@@ -156,9 +144,9 @@ module Decidim
|
|
156
144
|
end
|
157
145
|
|
158
146
|
def embeddable_meeting_url
|
159
|
-
if online_meeting_url.present? &&
|
147
|
+
if online_meeting_url.present? && %w(embed_in_meeting_page open_in_live_event_page).include?(iframe_embed_type)
|
160
148
|
embedder_service = Decidim::Meetings::MeetingIframeEmbedder.new(online_meeting_url)
|
161
|
-
errors.add(:
|
149
|
+
errors.add(:iframe_embed_type, :not_embeddable) unless embedder_service.embeddable?
|
162
150
|
end
|
163
151
|
end
|
164
152
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
class BaseMeetingForm < Decidim::Form
|
6
|
+
attribute :address, String
|
7
|
+
attribute :latitude, Float
|
8
|
+
attribute :longitude, Float
|
9
|
+
attribute :online_meeting_url, String
|
10
|
+
attribute :type_of_meeting, String
|
11
|
+
attribute :start_time, Decidim::Attributes::TimeWithZone
|
12
|
+
attribute :end_time, Decidim::Attributes::TimeWithZone
|
13
|
+
|
14
|
+
validates :current_component, presence: true
|
15
|
+
|
16
|
+
validates :address, presence: true, if: ->(form) { form.needs_address? }
|
17
|
+
validates :address, geocoding: true, if: ->(form) { form.has_address? && !form.geocoded? && form.needs_address? }
|
18
|
+
validates :start_time, presence: true, date: { before: :end_time }
|
19
|
+
validates :end_time, presence: true, date: { after: :start_time }
|
20
|
+
|
21
|
+
def type_of_meeting_select
|
22
|
+
Decidim::Meetings::Meeting::TYPE_OF_MEETING.map do |type|
|
23
|
+
[
|
24
|
+
I18n.t("type_of_meeting.#{type}", scope: "decidim.meetings"),
|
25
|
+
type
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def geocoding_enabled?
|
31
|
+
Decidim::Map.available?(:geocoding)
|
32
|
+
end
|
33
|
+
|
34
|
+
def geocoded?
|
35
|
+
latitude.present? && longitude.present?
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_address?
|
39
|
+
geocoding_enabled? && address.present?
|
40
|
+
end
|
41
|
+
|
42
|
+
def needs_address?
|
43
|
+
in_person_meeting? || hybrid_meeting?
|
44
|
+
end
|
45
|
+
|
46
|
+
def online_meeting?
|
47
|
+
type_of_meeting == "online"
|
48
|
+
end
|
49
|
+
|
50
|
+
def in_person_meeting?
|
51
|
+
type_of_meeting == "in_person"
|
52
|
+
end
|
53
|
+
|
54
|
+
def hybrid_meeting?
|
55
|
+
type_of_meeting == "hybrid"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -13,22 +13,22 @@ module Decidim
|
|
13
13
|
validates :closing_report, presence: true
|
14
14
|
validates :attendees_count,
|
15
15
|
presence: true,
|
16
|
-
numericality: { greater_than_or_equal_to: 0, only_integer: true }
|
16
|
+
numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 999, only_integer: true }
|
17
17
|
|
18
18
|
# Private: Gets the proposals from the meeting and injects them to the form.
|
19
19
|
#
|
20
20
|
# Returns nothing.
|
21
21
|
def map_model(model)
|
22
22
|
self.proposal_ids = model.linked_resources(:proposals, "proposals_from_meeting").pluck(:id)
|
23
|
-
presenter =
|
23
|
+
presenter = MeetingEditionPresenter.new(model)
|
24
24
|
self.closing_report = presenter.closing_report(all_locales: false)
|
25
25
|
end
|
26
26
|
|
27
27
|
def proposals
|
28
|
-
@proposals
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
@proposals = Decidim.find_resource_manifest(:proposals)
|
29
|
+
.try(:resource_scope, current_component)
|
30
|
+
&.where(id: proposal_ids)
|
31
|
+
&.order(title: :asc)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|