decidim-meetings 0.26.2 → 0.27.0.rc1
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_cell.rb +1 -1
- data/app/cells/decidim/meetings/content_blocks/upcoming_meetings/show.erb +1 -1
- data/app/cells/decidim/meetings/content_blocks/upcoming_meetings_cell.rb +2 -2
- data/app/cells/decidim/meetings/highlighted_meetings_for_component_cell.rb +10 -1
- data/app/commands/decidim/meetings/admin/close_meeting.rb +1 -1
- data/app/commands/decidim/meetings/admin/copy_meeting.rb +1 -1
- data/app/commands/decidim/meetings/admin/create_agenda.rb +1 -1
- data/app/commands/decidim/meetings/admin/create_meeting.rb +1 -4
- data/app/commands/decidim/meetings/admin/destroy_meeting.rb +1 -1
- data/app/commands/decidim/meetings/admin/export_meeting_registrations.rb +1 -1
- data/app/commands/decidim/meetings/admin/invite_user_to_join_meeting.rb +9 -11
- data/app/commands/decidim/meetings/admin/publish_meeting.rb +1 -1
- data/app/commands/decidim/meetings/admin/unpublish_meeting.rb +1 -1
- data/app/commands/decidim/meetings/admin/update_agenda.rb +1 -1
- data/app/commands/decidim/meetings/admin/update_meeting.rb +1 -4
- data/app/commands/decidim/meetings/admin/update_question_status.rb +1 -1
- data/app/commands/decidim/meetings/admin/update_questionnaire.rb +10 -7
- data/app/commands/decidim/meetings/admin/update_registrations.rb +5 -3
- data/app/commands/decidim/meetings/admin/validate_registration_code.rb +1 -1
- data/app/commands/decidim/meetings/close_meeting.rb +1 -1
- data/app/commands/decidim/meetings/create_answer.rb +1 -1
- data/app/commands/decidim/meetings/create_meeting.rb +1 -1
- data/app/commands/decidim/meetings/decline_invitation.rb +1 -1
- data/app/commands/decidim/meetings/join_meeting.rb +15 -7
- data/app/commands/decidim/meetings/leave_meeting.rb +3 -3
- data/app/commands/decidim/meetings/update_meeting.rb +1 -1
- data/app/commands/decidim/meetings/withdraw_meeting.rb +1 -1
- data/app/controllers/concerns/decidim/meetings/admin/filterable.rb +4 -4
- data/app/controllers/concerns/decidim/meetings/filterable.rb +1 -7
- data/app/controllers/decidim/meetings/calendars_controller.rb +1 -1
- data/app/controllers/decidim/meetings/directory/meetings_controller.rb +17 -15
- data/app/controllers/decidim/meetings/meetings_controller.rb +21 -14
- data/app/events/decidim/meetings/meeting_registration_notification_event.rb +1 -1
- data/app/forms/decidim/meetings/admin/close_meeting_form.rb +1 -1
- data/app/forms/decidim/meetings/admin/meeting_form.rb +2 -5
- data/app/forms/decidim/meetings/admin/meeting_registration_invite_form.rb +1 -1
- data/app/forms/decidim/meetings/admin/meeting_registrations_form.rb +3 -0
- data/app/forms/decidim/meetings/answer_form.rb +0 -1
- data/app/forms/decidim/meetings/close_meeting_form.rb +1 -1
- data/app/forms/decidim/meetings/meeting_form.rb +2 -2
- data/app/helpers/decidim/meetings/application_helper.rb +1 -1
- data/app/helpers/decidim/meetings/directory/application_helper.rb +1 -1
- data/app/helpers/decidim/meetings/meetings_helper.rb +1 -3
- data/app/jobs/decidim/meetings/send_close_meeting_reminder_job.rb +17 -0
- data/app/mailers/decidim/meetings/close_meeting_reminder_mailer.rb +43 -0
- data/app/models/decidim/meetings/answer.rb +2 -2
- data/app/models/decidim/meetings/invite.rb +2 -2
- data/app/models/decidim/meetings/meeting.rb +34 -16
- data/app/models/decidim/meetings/questionnaire.rb +6 -0
- data/app/models/decidim/meetings/registration.rb +2 -2
- data/app/packs/src/decidim/meetings/admin/meetings_form.js +0 -4
- data/app/packs/src/decidim/meetings/admin/registrations_form.js +2 -0
- data/app/presenters/decidim/meetings/admin_log/questionnaire_presenter.rb +39 -0
- data/app/queries/decidim/meetings/admin/invites.rb +1 -1
- data/app/queries/decidim/meetings/filtered_meetings.rb +1 -1
- data/app/queries/decidim/meetings/questionnaire_user_answers.rb +1 -1
- data/app/serializers/decidim/meetings/{data_portability_invite_serializer.rb → download_your_data_invite_serializer.rb} +2 -2
- data/app/serializers/decidim/meetings/{data_portability_registration_serializer.rb → download_your_data_registration_serializer.rb} +2 -2
- data/app/services/decidim/meetings/calendar/base_calendar.rb +4 -3
- data/app/services/decidim/meetings/calendar/component_calendar.rb +7 -9
- data/app/services/decidim/meetings/calendar/organization_calendar.rb +1 -1
- data/app/services/decidim/meetings/calendar_renderer.rb +4 -4
- data/app/services/decidim/meetings/close_meeting_reminder_generator.rb +68 -0
- data/app/services/decidim/meetings/meeting_iframe_embedder.rb +10 -6
- data/app/services/decidim/meetings/meeting_search.rb +7 -53
- data/app/views/decidim/meetings/_calendar_modal.html.erb +19 -2
- data/app/views/decidim/meetings/admin/meetings/_form.html.erb +4 -16
- data/app/views/decidim/meetings/admin/registrations/_form.html.erb +9 -0
- data/app/views/decidim/meetings/close_meeting_reminder_mailer/close_meeting_reminder.html.erb +5 -0
- data/app/views/decidim/meetings/directory/meetings/_filters.html.erb +7 -7
- data/app/views/decidim/meetings/directory/meetings/_meetings.html.erb +6 -1
- data/app/views/decidim/meetings/directory/meetings/index.html.erb +1 -1
- data/app/views/decidim/meetings/directory/meetings/index.js.erb +7 -1
- data/app/views/decidim/meetings/layouts/live_event.html.erb +6 -2
- data/app/views/decidim/meetings/meetings/_count.html.erb +1 -1
- data/app/views/decidim/meetings/meetings/_filters.html.erb +7 -7
- data/app/views/decidim/meetings/meetings/_form.html.erb +4 -2
- data/app/views/decidim/meetings/meetings/_meetings.html.erb +11 -6
- data/app/views/decidim/meetings/meetings/index.html.erb +2 -2
- data/app/views/decidim/meetings/meetings/index.js.erb +7 -1
- data/config/locales/am-ET.yml +1 -0
- data/config/locales/ar.yml +4 -7
- data/config/locales/bg.yml +1 -0
- data/config/locales/ca.yml +24 -10
- data/config/locales/cs.yml +24 -10
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +10 -13
- data/config/locales/el.yml +1 -0
- data/config/locales/en.yml +23 -10
- data/config/locales/eo.yml +1 -0
- data/config/locales/es-MX.yml +25 -11
- data/config/locales/es-PY.yml +25 -11
- data/config/locales/es.yml +25 -11
- data/config/locales/et.yml +1 -0
- data/config/locales/eu.yml +10 -11
- data/config/locales/fi-plain.yml +24 -10
- data/config/locales/fi.yml +24 -10
- data/config/locales/fr-CA.yml +22 -10
- data/config/locales/fr.yml +22 -10
- data/config/locales/ga-IE.yml +1 -9
- data/config/locales/gl.yml +14 -2
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +16 -8
- data/config/locales/id-ID.yml +1 -0
- data/config/locales/is-IS.yml +2 -1
- data/config/locales/it.yml +7 -11
- data/config/locales/ja.yml +26 -12
- data/config/locales/ko.yml +1 -0
- data/config/locales/lb.yml +6 -6
- data/config/locales/lt.yml +1 -0
- data/config/locales/lv.yml +1 -0
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +7 -11
- data/config/locales/no.yml +7 -12
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +2 -10
- data/config/locales/pt-BR.yml +3 -13
- data/config/locales/pt.yml +6 -11
- data/config/locales/ro-RO.yml +8 -8
- data/config/locales/ru.yml +1 -0
- data/config/locales/si-LK.yml +1 -0
- data/config/locales/sk.yml +1 -0
- data/config/locales/sl.yml +1 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sr-CS.yml +1 -0
- data/config/locales/sv.yml +15 -11
- data/config/locales/sw-KE.yml +1 -0
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +1 -11
- data/config/locales/uk.yml +1 -0
- data/config/locales/val-ES.yml +1 -0
- data/config/locales/vi.yml +1 -0
- data/config/locales/zh-CN.yml +1 -7
- data/config/locales/zh-TW.yml +1 -0
- data/db/migrate/20210512100333_drop_decidim_meetings_minutes_table.rb +2 -2
- data/db/migrate/20210518133236_merge_minutes_with_closing_report_in_meetings_table.rb +1 -1
- data/db/migrate/20211105115625_remove_not_null_on_customize_registration_email.rb +7 -0
- data/lib/decidim/api/meeting_type.rb +1 -1
- data/lib/decidim/meetings/component.rb +5 -5
- data/lib/decidim/meetings/{data_portability_user_answers_serializer.rb → download_your_data_user_answers_serializer.rb} +2 -2
- data/lib/decidim/meetings/engine.rb +14 -0
- data/lib/decidim/meetings/test/factories.rb +3 -1
- data/lib/decidim/meetings/test/notifications_handling.rb +1 -1
- data/lib/decidim/meetings/test/translated_event.rb +2 -2
- data/lib/decidim/meetings/version.rb +1 -1
- data/lib/decidim/meetings.rb +5 -1
- metadata +27 -22
- data/app/services/decidim/meetings/directory/meeting_search.rb +0 -53
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
attribute :attending_organizations, String
|
17
17
|
attribute :proposal_ids, Array[Integer]
|
18
18
|
attribute :proposals
|
19
|
-
attribute :closed_at, Decidim::Attributes::TimeWithZone, default: ->
|
19
|
+
attribute :closed_at, Decidim::Attributes::TimeWithZone, default: -> { Time.current }
|
20
20
|
|
21
21
|
validates :closing_report, translatable_presence: true
|
22
22
|
validates :attendees_count, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 999, only_integer: true }
|
@@ -14,7 +14,6 @@ module Decidim
|
|
14
14
|
attribute :transparent, Boolean
|
15
15
|
attribute :registration_type, String
|
16
16
|
attribute :registration_url, String
|
17
|
-
attribute :available_slots, Integer, default: 0
|
18
17
|
attribute :customize_registration_email, Boolean
|
19
18
|
attribute :iframe_embed_type, String, default: "none"
|
20
19
|
attribute :comments_enabled, Boolean, default: true
|
@@ -26,13 +25,11 @@ module Decidim
|
|
26
25
|
translatable_attribute :description, String
|
27
26
|
translatable_attribute :location, String
|
28
27
|
translatable_attribute :location_hints, String
|
29
|
-
translatable_attribute :registration_email_custom_content, String
|
30
28
|
|
31
29
|
validates :iframe_embed_type, inclusion: { in: Decidim::Meetings::Meeting.iframe_embed_types }
|
32
30
|
validates :title, translatable_presence: true
|
33
31
|
validates :description, translatable_presence: true
|
34
32
|
validates :registration_type, presence: true
|
35
|
-
validates :available_slots, numericality: { greater_than_or_equal_to: 0 }, presence: true, if: ->(form) { form.on_this_platform? }
|
36
33
|
validates :registration_url, presence: true, url: true, if: ->(form) { form.on_different_platform? }
|
37
34
|
validates :type_of_meeting, presence: true
|
38
35
|
validates :location, translatable_presence: true, if: ->(form) { form.in_person_meeting? || form.hybrid_meeting? }
|
@@ -75,14 +72,14 @@ module Decidim
|
|
75
72
|
#
|
76
73
|
# Returns a Decidim::Scope
|
77
74
|
def scope
|
78
|
-
@scope ||= @decidim_scope_id ? current_component.scopes.find_by(id: @decidim_scope_id) : current_component.scope
|
75
|
+
@scope ||= @attributes["decidim_scope_id"].value ? current_component.scopes.find_by(id: @attributes["decidim_scope_id"].value) : current_component.scope
|
79
76
|
end
|
80
77
|
|
81
78
|
# Scope identifier
|
82
79
|
#
|
83
80
|
# Returns the scope identifier related to the meeting
|
84
81
|
def decidim_scope_id
|
85
|
-
|
82
|
+
super || scope&.id
|
86
83
|
end
|
87
84
|
|
88
85
|
def category
|
@@ -12,7 +12,7 @@ module Decidim
|
|
12
12
|
attribute :existing_user, Boolean, default: false
|
13
13
|
|
14
14
|
validates :name, presence: true, unless: proc { |object| object.existing_user }
|
15
|
-
validates :email, presence: true,
|
15
|
+
validates :email, presence: true, "valid_email_2/email": { disposable: true }, unless: proc { |object| object.existing_user }
|
16
16
|
validates :user, presence: true, if: proc { |object| object.existing_user }
|
17
17
|
|
18
18
|
def user
|
@@ -11,9 +11,12 @@ module Decidim
|
|
11
11
|
|
12
12
|
attribute :registrations_enabled, Boolean
|
13
13
|
attribute :registration_form_enabled, Boolean
|
14
|
+
attribute :customize_registration_email, Boolean
|
14
15
|
attribute :available_slots, Integer
|
15
16
|
attribute :reserved_slots, Integer
|
17
|
+
|
16
18
|
translatable_attribute :registration_terms, String
|
19
|
+
translatable_attribute :registration_email_custom_content, String
|
17
20
|
|
18
21
|
validates :registration_terms, translatable_presence: true, if: ->(form) { form.registrations_enabled? }
|
19
22
|
validates :available_slots, :reserved_slots, presence: true, if: ->(form) { form.registrations_enabled? }
|
@@ -10,7 +10,6 @@ module Decidim
|
|
10
10
|
attribute :body, String
|
11
11
|
attribute :choices, Array[AnswerChoiceForm]
|
12
12
|
attribute :current_user, Decidim::User
|
13
|
-
attribute :answer, Decidim::Meetings::Answer
|
14
13
|
|
15
14
|
validates :selected_choices, presence: true
|
16
15
|
validate :max_choices, if: -> { question.max_choices }
|
@@ -7,7 +7,7 @@ module Decidim
|
|
7
7
|
attribute :closing_report, String
|
8
8
|
attribute :proposal_ids, Array[Integer]
|
9
9
|
attribute :proposals
|
10
|
-
attribute :closed_at, Decidim::Attributes::TimeWithZone, default: ->
|
10
|
+
attribute :closed_at, Decidim::Attributes::TimeWithZone, default: -> { Time.current }
|
11
11
|
attribute :attendees_count, Integer, default: 0
|
12
12
|
|
13
13
|
validates :closing_report, presence: true
|
@@ -60,14 +60,14 @@ module Decidim
|
|
60
60
|
#
|
61
61
|
# Returns a Decidim::Scope
|
62
62
|
def scope
|
63
|
-
@scope ||= @decidim_scope_id ? current_component.scopes.find_by(id: @decidim_scope_id) : current_component.scope
|
63
|
+
@scope ||= @attributes["decidim_scope_id"].value ? current_component.scopes.find_by(id: @attributes["decidim_scope_id"].value) : current_component.scope
|
64
64
|
end
|
65
65
|
|
66
66
|
# Scope identifier
|
67
67
|
#
|
68
68
|
# Returns the scope identifier related to the meeting
|
69
69
|
def decidim_scope_id
|
70
|
-
|
70
|
+
super || scope&.id
|
71
71
|
end
|
72
72
|
|
73
73
|
def category
|
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
def filter_origin_values
|
17
17
|
origin_values = []
|
18
18
|
origin_values << TreePoint.new("official", t("decidim.meetings.meetings.filters.origin_values.official"))
|
19
|
-
origin_values << TreePoint.new("
|
19
|
+
origin_values << TreePoint.new("participants", t("decidim.meetings.meetings.filters.origin_values.participants")) # todo
|
20
20
|
if current_organization.user_groups_enabled?
|
21
21
|
origin_values << TreePoint.new("user_group", t("decidim.meetings.meetings.filters.origin_values.user_groups")) # todo
|
22
22
|
end
|
@@ -109,7 +109,7 @@ module Decidim
|
|
109
109
|
def directory_filter_origin_values
|
110
110
|
origin_values = []
|
111
111
|
origin_values << TreePoint.new("official", t("decidim.meetings.meetings.filters.origin_values.official"))
|
112
|
-
origin_values << TreePoint.new("
|
112
|
+
origin_values << TreePoint.new("participants", t("decidim.meetings.meetings.filters.origin_values.participants"))
|
113
113
|
origin_values << TreePoint.new("user_group", t("decidim.meetings.meetings.filters.origin_values.user_groups")) if current_organization.user_groups_enabled?
|
114
114
|
|
115
115
|
TreeNode.new(
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
class SendCloseMeetingReminderJob < ApplicationJob
|
6
|
+
queue_as :close_meeting_reminder
|
7
|
+
|
8
|
+
def perform(record)
|
9
|
+
return if record.remindable.closed?
|
10
|
+
|
11
|
+
::Decidim::ReminderDelivery.create(reminder: record.reminder)
|
12
|
+
::Decidim::Meetings::CloseMeetingReminderMailer.close_meeting_reminder(record).deliver_now
|
13
|
+
record.update(state: "completed")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
# A custom mailer for sending notifications for overdue meetings
|
6
|
+
class CloseMeetingReminderMailer < Decidim::ApplicationMailer
|
7
|
+
include Decidim::TranslationsHelper
|
8
|
+
include ActionView::Helpers::SanitizeHelper
|
9
|
+
include Decidim::ApplicationHelper
|
10
|
+
|
11
|
+
helper Decidim::ResourceHelper
|
12
|
+
helper Decidim::TranslationsHelper
|
13
|
+
helper Decidim::ApplicationHelper
|
14
|
+
|
15
|
+
helper_method :routes
|
16
|
+
|
17
|
+
# Send the user an email reminder to close the meetings
|
18
|
+
#
|
19
|
+
# record - the reminder record specific to a past meeting.
|
20
|
+
def close_meeting_reminder(record)
|
21
|
+
@reminder = record.reminder
|
22
|
+
@user = record.reminder.user
|
23
|
+
with_user(@user) do
|
24
|
+
@meeting = record.remindable
|
25
|
+
@organization = @user.organization
|
26
|
+
mail(
|
27
|
+
to: @user.email,
|
28
|
+
subject: I18n.t(
|
29
|
+
"decidim.meetings.close_meeting_reminder_mailer.close_meeting_reminder.subject",
|
30
|
+
organization_name: @organization.name
|
31
|
+
)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def routes
|
39
|
+
@routes ||= Decidim::EngineRouter.main_proxy(@reminder.component)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -4,7 +4,7 @@ module Decidim
|
|
4
4
|
module Meetings
|
5
5
|
# The data store for an Answer in the Decidim::Meetings
|
6
6
|
class Answer < Meetings::ApplicationRecord
|
7
|
-
include Decidim::
|
7
|
+
include Decidim::DownloadYourData
|
8
8
|
|
9
9
|
belongs_to :user, class_name: "Decidim::User", foreign_key: "decidim_user_id", optional: true
|
10
10
|
belongs_to :questionnaire, class_name: "Decidim::Meetings::Questionnaire", foreign_key: "decidim_questionnaire_id"
|
@@ -24,7 +24,7 @@ module Decidim
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.export_serializer
|
27
|
-
Decidim::Meetings::
|
27
|
+
Decidim::Meetings::DownloadYourDataUserAnswersSerializer
|
28
28
|
end
|
29
29
|
|
30
30
|
def organization
|
@@ -6,7 +6,7 @@ module Decidim
|
|
6
6
|
class Invite < Meetings::ApplicationRecord
|
7
7
|
include Decidim::Traceable
|
8
8
|
include Decidim::Loggable
|
9
|
-
include Decidim::
|
9
|
+
include Decidim::DownloadYourData
|
10
10
|
|
11
11
|
belongs_to :meeting, foreign_key: "decidim_meeting_id", class_name: "Decidim::Meetings::Meeting"
|
12
12
|
belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
|
@@ -14,7 +14,7 @@ module Decidim
|
|
14
14
|
validates :user, uniqueness: { scope: :meeting }
|
15
15
|
|
16
16
|
def self.export_serializer
|
17
|
-
Decidim::Meetings::
|
17
|
+
Decidim::Meetings::DownloadYourDataInviteSerializer
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.log_presenter_class_for(_log)
|
@@ -25,6 +25,7 @@ module Decidim
|
|
25
25
|
include Decidim::Authorable
|
26
26
|
include Decidim::TranslatableResource
|
27
27
|
include Decidim::Publicable
|
28
|
+
include Decidim::FilterableResource
|
28
29
|
|
29
30
|
TYPE_OF_MEETING = %w(in_person online hybrid).freeze
|
30
31
|
REGISTRATION_TYPE = %w(registration_disabled on_this_platform on_different_platform).freeze
|
@@ -59,8 +60,26 @@ module Decidim
|
|
59
60
|
scope :upcoming, -> { where(arel_table[:end_time].gteq(Time.current)) }
|
60
61
|
scope :withdrawn, -> { where(state: "withdrawn") }
|
61
62
|
scope :except_withdrawn, -> { where.not(state: "withdrawn").or(where(state: nil)) }
|
63
|
+
scope :with_availability, lambda { |state_key|
|
64
|
+
case state_key
|
65
|
+
when "withdrawn"
|
66
|
+
withdrawn
|
67
|
+
else
|
68
|
+
except_withdrawn
|
69
|
+
end
|
70
|
+
}
|
71
|
+
scope_search_multi :with_any_date, [:upcoming, :past]
|
72
|
+
scope :with_any_space, lambda { |*target_space|
|
73
|
+
target_spaces = target_space.compact.compact_blank
|
74
|
+
|
75
|
+
return self if target_spaces.blank? || target_spaces.include?("all")
|
62
76
|
|
63
|
-
|
77
|
+
joins(:component).where(
|
78
|
+
decidim_components: { participatory_space_type: target_spaces.map(&:classify) }
|
79
|
+
)
|
80
|
+
}
|
81
|
+
|
82
|
+
scope :visible_for, lambda { |user|
|
64
83
|
(all.distinct if user&.admin?) ||
|
65
84
|
if user.present?
|
66
85
|
spaces = Decidim.participatory_space_registry.manifests.map do |manifest|
|
@@ -109,6 +128,10 @@ module Decidim
|
|
109
128
|
|
110
129
|
scope :visible, -> { where("decidim_meetings_meetings.private_meeting != ? OR decidim_meetings_meetings.transparent = ?", true, true) }
|
111
130
|
|
131
|
+
scope :authored_by, ->(author) { where(decidim_author_id: author) }
|
132
|
+
|
133
|
+
scope_search_multi :with_any_type, TYPE_OF_MEETING.map(&:to_sym)
|
134
|
+
|
112
135
|
TYPE_OF_MEETING.each do |type|
|
113
136
|
scope type.to_sym, -> { where(type_of_meeting: type.to_sym) }
|
114
137
|
scope "not_#{type}".to_sym, -> { where.not(type_of_meeting: type.to_sym) }
|
@@ -215,7 +238,7 @@ module Decidim
|
|
215
238
|
end
|
216
239
|
|
217
240
|
def current_user_can_visit_meeting?(user)
|
218
|
-
Decidim::Meetings::Meeting.
|
241
|
+
Decidim::Meetings::Meeting.visible_for(user).exists?(id: id)
|
219
242
|
end
|
220
243
|
|
221
244
|
def iframe_access_level_allowed_for_user?(user)
|
@@ -342,13 +365,9 @@ module Decidim
|
|
342
365
|
order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("DESC")))
|
343
366
|
end
|
344
367
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
ransacker :title do
|
350
|
-
Arel.sql(%{cast("decidim_meetings_meetings"."title" as text)})
|
351
|
-
end
|
368
|
+
# Create i18n ransackers for :title and :description.
|
369
|
+
# Create the :search_text ransacker alias for searching from both of these.
|
370
|
+
ransacker_i18n_multi :search_text, [:title, :description]
|
352
371
|
|
353
372
|
ransacker :id_string do
|
354
373
|
Arel.sql(%{cast("decidim_meetings_meetings"."id" as text)})
|
@@ -358,13 +377,12 @@ module Decidim
|
|
358
377
|
Arel.sql("(start_time > NOW())")
|
359
378
|
end
|
360
379
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
")
|
380
|
+
def self.ransackable_scopes(_auth_object = nil)
|
381
|
+
[:with_any_type, :with_any_date, :with_any_space, :with_any_origin, :with_any_scope, :with_any_category, :with_any_global_category]
|
382
|
+
end
|
383
|
+
|
384
|
+
def self.ransack(params = {}, options = {})
|
385
|
+
MeetingSearch.new(self, params, options)
|
368
386
|
end
|
369
387
|
|
370
388
|
private
|
@@ -4,6 +4,8 @@ module Decidim
|
|
4
4
|
module Meetings
|
5
5
|
# The data store for a Questionnaire in the Decidim::Meetings component.
|
6
6
|
class Questionnaire < Meetings::ApplicationRecord
|
7
|
+
include Decidim::Traceable
|
8
|
+
|
7
9
|
belongs_to :questionnaire_for, polymorphic: true
|
8
10
|
|
9
11
|
has_many :questions, -> { order(:position) }, class_name: "Question", foreign_key: "decidim_questionnaire_id", dependent: :destroy
|
@@ -18,6 +20,10 @@ module Decidim
|
|
18
20
|
def all_questions_unpublished?
|
19
21
|
questions.all?(&:unpublished?)
|
20
22
|
end
|
23
|
+
|
24
|
+
def self.log_presenter_class_for(_log)
|
25
|
+
Decidim::Meetings::AdminLog::QuestionnairePresenter
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
@@ -4,7 +4,7 @@ module Decidim
|
|
4
4
|
module Meetings
|
5
5
|
# The data store for a Registration in the Decidim::Meetings component.
|
6
6
|
class Registration < Meetings::ApplicationRecord
|
7
|
-
include Decidim::
|
7
|
+
include Decidim::DownloadYourData
|
8
8
|
|
9
9
|
belongs_to :meeting, foreign_key: "decidim_meeting_id", class_name: "Decidim::Meetings::Meeting"
|
10
10
|
belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
|
@@ -23,7 +23,7 @@ module Decidim
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.export_serializer
|
26
|
-
Decidim::Meetings::
|
26
|
+
Decidim::Meetings::DownloadYourDataRegistrationSerializer
|
27
27
|
end
|
28
28
|
|
29
29
|
# Pluck all Decidim::UserGroup ID's
|
@@ -102,9 +102,7 @@ $(() => {
|
|
102
102
|
attachGeocoding($form.find("#meeting_address"));
|
103
103
|
|
104
104
|
const $meetingRegistrationType = $form.find("#meeting_registration_type");
|
105
|
-
const $meetingRegistrationTerms = $form.find("#meeting_registration_terms");
|
106
105
|
const $meetingRegistrationUrl = $form.find("#meeting_registration_url");
|
107
|
-
const $meetingAvailableSlots = $form.find("#meeting_available_slots");
|
108
106
|
|
109
107
|
const toggleDependsOnSelect = ($target, $showDiv, type) => {
|
110
108
|
const value = $target.val();
|
@@ -113,8 +111,6 @@ $(() => {
|
|
113
111
|
|
114
112
|
$meetingRegistrationType.on("change", (ev) => {
|
115
113
|
const $target = $(ev.target);
|
116
|
-
toggleDependsOnSelect($target, $meetingAvailableSlots, "on_this_platform");
|
117
|
-
toggleDependsOnSelect($target, $meetingRegistrationTerms, "on_this_platform");
|
118
114
|
toggleDependsOnSelect($target, $meetingRegistrationUrl, "on_different_platform");
|
119
115
|
});
|
120
116
|
|
@@ -5,11 +5,13 @@ $(() => {
|
|
5
5
|
const $registrationsEnabled = $form.find("#meeting_registrations_enabled");
|
6
6
|
const $availableSlots = $form.find("#meeting_available_slots");
|
7
7
|
const $reservedSlots = $form.find("#meeting_reserved_slots");
|
8
|
+
const $customizeRegistrationEmail = $form.find("#meeting_customize_registration_email");
|
8
9
|
|
9
10
|
const toggleDisabledFields = () => {
|
10
11
|
const enabled = $registrationsEnabled.prop("checked");
|
11
12
|
$availableSlots.attr("disabled", !enabled);
|
12
13
|
$reservedSlots.attr("disabled", !enabled);
|
14
|
+
$customizeRegistrationEmail.attr("disabled", !enabled);
|
13
15
|
|
14
16
|
$form.find(".editor-container").each((idx, node) => {
|
15
17
|
const quill = Quill.find(node);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
module AdminLog
|
6
|
+
# This class holds the logic to present a `Decidim::Meetings::Questionnaire`
|
7
|
+
# for the `AdminLog` log.
|
8
|
+
#
|
9
|
+
# Usage should be automatic and you shouldn't need to call this class
|
10
|
+
# directly, but here's an example:
|
11
|
+
#
|
12
|
+
# action_log = Decidim::ActionLog.last
|
13
|
+
# view_helpers # => this comes from the views
|
14
|
+
# QuestionnairePresenter.new(action_log, view_helpers).present
|
15
|
+
class QuestionnairePresenter < Decidim::Log::BasePresenter
|
16
|
+
private
|
17
|
+
|
18
|
+
def action_string
|
19
|
+
case action
|
20
|
+
when "update"
|
21
|
+
"decidim.meetings.admin_log.questionnaire.#{action}"
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_presenter
|
28
|
+
@resource_presenter ||= Decidim::Log::ResourcePresenter.new(action_log.resource.questionnaire_for.meeting, h, action_log.resource.questionnaire_for.meeting)
|
29
|
+
end
|
30
|
+
|
31
|
+
def i18n_params
|
32
|
+
super.merge(
|
33
|
+
meeting_name: resource_presenter.try(:present)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -4,7 +4,7 @@ module Decidim
|
|
4
4
|
module Meetings
|
5
5
|
module Admin
|
6
6
|
# A class used to find the Invites by their status status.
|
7
|
-
class Invites <
|
7
|
+
class Invites < Decidim::Query
|
8
8
|
# Syntactic sugar to initialize the class and return the queried objects.
|
9
9
|
#
|
10
10
|
# invites - the initial Invites relation that needs to be filtered.
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
5
|
# A class used to find meetings filtered by components and a date range
|
6
|
-
class FilteredMeetings <
|
6
|
+
class FilteredMeetings < Decidim::Query
|
7
7
|
# Syntactic sugar to initialize the class and return the queried objects.
|
8
8
|
#
|
9
9
|
# components - An array of Decidim::Component
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
5
|
# A class used to collect user answers for a questionnaire
|
6
|
-
class QuestionnaireUserAnswers <
|
6
|
+
class QuestionnaireUserAnswers < Decidim::Query
|
7
7
|
# Syntactic sugar to initialize the class and return the queried objects.
|
8
8
|
#
|
9
9
|
# questionnaire - a Questionnaire object
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
|
-
class
|
6
|
-
# Serializes an invite for data
|
5
|
+
class DownloadYourDataInviteSerializer < Decidim::Exporters::Serializer
|
6
|
+
# Serializes an invite for download your data
|
7
7
|
def serialize
|
8
8
|
{
|
9
9
|
id: resource.id,
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
|
-
class
|
6
|
-
# Serializes a registration for data
|
5
|
+
class DownloadYourDataRegistrationSerializer < Decidim::Exporters::Serializer
|
6
|
+
# Serializes a registration for download your data
|
7
7
|
def serialize
|
8
8
|
{
|
9
9
|
id: resource.id,
|
@@ -14,15 +14,16 @@ module Decidim
|
|
14
14
|
# resource - a resource that has meetings.
|
15
15
|
#
|
16
16
|
# Returns a String.
|
17
|
-
def self.for(resource)
|
18
|
-
new(resource).calendar
|
17
|
+
def self.for(resource, filters = nil)
|
18
|
+
new(resource, filters).calendar
|
19
19
|
end
|
20
20
|
|
21
21
|
# Initializes the class.
|
22
22
|
#
|
23
23
|
# resource - a resource that has meetings.
|
24
|
-
def initialize(resource)
|
24
|
+
def initialize(resource, filters = nil)
|
25
25
|
@resource = resource
|
26
|
+
@filters = filters
|
26
27
|
end
|
27
28
|
|
28
29
|
# Converts the resource meetings to the ICalendar format.
|
@@ -11,11 +11,9 @@ module Decidim
|
|
11
11
|
#
|
12
12
|
# Returns a String.
|
13
13
|
def events
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end.compact.join
|
18
|
-
end
|
14
|
+
filtered_meetings.map do |meeting|
|
15
|
+
MeetingCalendar.new(meeting).events
|
16
|
+
end.compact.join
|
19
17
|
end
|
20
18
|
|
21
19
|
private
|
@@ -29,11 +27,11 @@ module Decidim
|
|
29
27
|
Decidim::Meetings::Meeting.where(component: component)
|
30
28
|
end
|
31
29
|
|
32
|
-
#
|
30
|
+
# Finds the component meetings.
|
33
31
|
#
|
34
|
-
# Returns a
|
35
|
-
def
|
36
|
-
|
32
|
+
# Returns a collection of Meetings filtered based on provided params.
|
33
|
+
def filtered_meetings
|
34
|
+
meetings.not_hidden.published.except_withdrawn.ransack(@filters).result
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
@@ -3,14 +3,14 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
5
|
class CalendarRenderer
|
6
|
-
def self.for(resource)
|
6
|
+
def self.for(resource, filters = nil)
|
7
7
|
case resource
|
8
8
|
when Decidim::Organization
|
9
|
-
Calendar::OrganizationCalendar.for(resource)
|
9
|
+
Calendar::OrganizationCalendar.for(resource, filters)
|
10
10
|
when Decidim::Component
|
11
|
-
Calendar::ComponentCalendar.for(resource)
|
11
|
+
Calendar::ComponentCalendar.for(resource, filters)
|
12
12
|
when Decidim::Meetings::Meeting
|
13
|
-
Calendar::MeetingCalendar.for(resource)
|
13
|
+
Calendar::MeetingCalendar.for(resource, filters)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|