decidim-meetings 0.30.2 → 0.31.0.rc1

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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/meetings/cancel_registration_meeting_button/cancelation_modal.erb +7 -4
  3. data/app/cells/decidim/meetings/cancel_registration_meeting_button/show.erb +1 -1
  4. data/app/cells/decidim/meetings/cancel_registration_meeting_button_cell.rb +36 -0
  5. data/app/cells/decidim/meetings/dates_and_map_cell.rb +1 -1
  6. data/app/cells/decidim/meetings/join_meeting_button/registration_modal.erb +4 -5
  7. data/app/cells/decidim/meetings/join_meeting_button/show.erb +25 -28
  8. data/app/cells/decidim/meetings/join_meeting_button/waitlist_button.erb +22 -0
  9. data/app/cells/decidim/meetings/join_meeting_button_cell.rb +28 -0
  10. data/app/cells/decidim/meetings/question_responses/show.erb +7 -7
  11. data/app/cells/decidim/meetings/question_responses_cell.rb +28 -28
  12. data/app/commands/decidim/meetings/admin/copy_meeting.rb +5 -2
  13. data/app/commands/decidim/meetings/admin/create_agenda.rb +6 -2
  14. data/app/commands/decidim/meetings/admin/create_meeting.rb +7 -3
  15. data/app/commands/decidim/meetings/admin/mark_as_attendee.rb +44 -0
  16. data/app/commands/decidim/meetings/admin/publish_meeting.rb +2 -1
  17. data/app/commands/decidim/meetings/admin/update_agenda.rb +6 -2
  18. data/app/commands/decidim/meetings/admin/update_meeting.rb +15 -6
  19. data/app/commands/decidim/meetings/admin/update_questionnaire.rb +4 -4
  20. data/app/commands/decidim/meetings/admin/update_registrations.rb +19 -7
  21. data/app/commands/decidim/meetings/create_meeting.rb +2 -3
  22. data/app/commands/decidim/meetings/{create_answer.rb → create_response.rb} +11 -11
  23. data/app/commands/decidim/meetings/join_meeting.rb +4 -6
  24. data/app/commands/decidim/meetings/join_waitlist.rb +53 -0
  25. data/app/commands/decidim/meetings/leave_meeting.rb +14 -5
  26. data/app/commands/decidim/meetings/update_meeting.rb +1 -2
  27. data/app/controllers/concerns/decidim/meetings/admin/filterable.rb +1 -1
  28. data/app/controllers/decidim/meetings/admin/agenda_controller.rb +2 -2
  29. data/app/controllers/decidim/meetings/admin/invites_controller.rb +1 -1
  30. data/app/controllers/decidim/meetings/admin/meeting_closes_controller.rb +1 -1
  31. data/app/controllers/decidim/meetings/admin/meeting_copies_controller.rb +1 -1
  32. data/app/controllers/decidim/meetings/admin/meetings_controller.rb +4 -4
  33. data/app/controllers/decidim/meetings/admin/meetings_poll_controller.rb +10 -10
  34. data/app/controllers/decidim/meetings/admin/registrations_attendees_controller.rb +79 -0
  35. data/app/controllers/decidim/meetings/admin/registrations_controller.rb +1 -22
  36. data/app/controllers/decidim/meetings/meeting_closes_controller.rb +1 -1
  37. data/app/controllers/decidim/meetings/meetings_controller.rb +11 -11
  38. data/app/controllers/decidim/meetings/polls/{answers_controller.rb → responses_controller.rb} +7 -7
  39. data/app/controllers/decidim/meetings/registrations_controller.rb +39 -12
  40. data/app/events/decidim/meetings/registration_marked_as_attendee_event.rb +9 -0
  41. data/app/events/decidim/meetings/upcoming_meeting_event.rb +41 -0
  42. data/app/events/decidim/meetings/update_meeting_event.rb +25 -0
  43. data/app/forms/decidim/meetings/admin/close_meeting_form.rb +2 -1
  44. data/app/forms/decidim/meetings/admin/meeting_agenda_items_form.rb +4 -0
  45. data/app/forms/decidim/meetings/admin/meeting_form.rb +28 -3
  46. data/app/forms/decidim/meetings/admin/question_form.rb +3 -3
  47. data/app/forms/decidim/meetings/admin/{answer_option_form.rb → response_option_form.rb} +3 -3
  48. data/app/forms/decidim/meetings/admin/validate_registration_code_form.rb +1 -1
  49. data/app/forms/decidim/meetings/base_meeting_form.rb +0 -2
  50. data/app/forms/decidim/meetings/close_meeting_form.rb +2 -1
  51. data/app/forms/decidim/meetings/join_meeting_form.rb +0 -1
  52. data/app/forms/decidim/meetings/meeting_form.rb +3 -2
  53. data/app/forms/decidim/meetings/response_choice_form.rb +14 -0
  54. data/app/forms/decidim/meetings/{answer_form.rb → response_form.rb} +7 -7
  55. data/app/helpers/decidim/meetings/application_helper.rb +0 -1
  56. data/app/helpers/decidim/meetings/meetings_helper.rb +14 -5
  57. data/app/jobs/decidim/meetings/promote_from_waitlist_job.rb +63 -0
  58. data/app/jobs/decidim/meetings/upcoming_meeting_notification_job.rb +1 -1
  59. data/app/mailers/decidim/meetings/registration_mailer.rb +13 -0
  60. data/app/models/decidim/meetings/agenda_item.rb +5 -0
  61. data/app/models/decidim/meetings/meeting.rb +15 -12
  62. data/app/models/decidim/meetings/question.rb +12 -12
  63. data/app/models/decidim/meetings/questionnaire.rb +1 -1
  64. data/app/models/decidim/meetings/registration.rb +19 -7
  65. data/app/models/decidim/meetings/{answer.rb → response.rb} +6 -6
  66. data/app/models/decidim/meetings/response_choice.rb +15 -0
  67. data/app/models/decidim/meetings/{answer_option.rb → response_option.rb} +5 -5
  68. data/app/packs/src/decidim/meetings/admin/destroy_meeting_alert.js +1 -1
  69. data/app/packs/src/decidim/meetings/admin/meetings_components_form.js +1 -8
  70. data/app/packs/src/decidim/meetings/admin/meetings_form.js +1 -1
  71. data/app/packs/src/decidim/meetings/admin/registrations_form.js +1 -1
  72. data/app/packs/src/decidim/meetings/admin/registrations_invite_form.js +1 -1
  73. data/app/packs/src/decidim/meetings/meetings_form.js +1 -1
  74. data/app/packs/src/decidim/meetings/meetings_polls.js +1 -1
  75. data/app/packs/src/decidim/meetings/poll.component.js +5 -5
  76. data/app/packs/stylesheets/decidim/meetings/_item.scss +5 -1
  77. data/app/packs/stylesheets/decidim/meetings/meetings.scss +4 -4
  78. data/app/permissions/decidim/meetings/admin/agenda_permissions.rb +34 -0
  79. data/app/permissions/decidim/meetings/admin/meeting_permissions.rb +44 -0
  80. data/app/permissions/decidim/meetings/admin/permissions.rb +5 -66
  81. data/app/permissions/decidim/meetings/admin/questionnaire_permissions.rb +30 -0
  82. data/app/permissions/decidim/meetings/meeting_permissions.rb +90 -0
  83. data/app/permissions/decidim/meetings/permissions.rb +9 -105
  84. data/app/presenters/decidim/meetings/admin_log/value_types/meeting_title_description_presenter.rb +1 -1
  85. data/app/presenters/decidim/meetings/agenda_item_presenter.rb +29 -0
  86. data/app/presenters/decidim/meetings/meeting_presenter.rb +11 -15
  87. data/app/presenters/decidim/meetings/registration_presenter.rb +24 -0
  88. data/app/queries/decidim/meetings/{questionnaire_user_answers.rb → questionnaire_user_responses.rb} +5 -5
  89. data/app/serializers/decidim/meetings/registration_serializer.rb +5 -6
  90. data/app/services/decidim/meetings/diff_renderer.rb +0 -1
  91. data/app/views/decidim/meetings/_calendar_modal.html.erb +1 -0
  92. data/app/views/decidim/meetings/admin/agenda/_agenda_item_fields.html.erb +1 -1
  93. data/app/views/decidim/meetings/admin/invites/_form.html.erb +1 -1
  94. data/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +1 -1
  95. data/app/views/decidim/meetings/admin/meetings/_form.html.erb +3 -2
  96. data/app/views/decidim/meetings/admin/meetings/_linked_spaces.html.erb +1 -1
  97. data/app/views/decidim/meetings/admin/meetings/_meeting-tr.html.erb +11 -8
  98. data/app/views/decidim/meetings/admin/meetings/_meeting_actions.html.erb +200 -69
  99. data/app/views/decidim/meetings/admin/meetings/_reminders.html.erb +19 -0
  100. data/app/views/decidim/meetings/admin/meetings/_services.html.erb +1 -1
  101. data/app/views/decidim/meetings/admin/meetings/index.html.erb +7 -5
  102. data/app/views/decidim/meetings/admin/meetings/manage_trash.html.erb +2 -1
  103. data/app/views/decidim/meetings/admin/poll/_form.html.erb +6 -6
  104. data/app/views/decidim/meetings/admin/poll/_question.html.erb +13 -13
  105. data/app/views/decidim/meetings/admin/poll/_response_option.html.erb +35 -0
  106. data/app/views/decidim/meetings/admin/poll/_response_option_template.html.erb +7 -0
  107. data/app/views/decidim/meetings/admin/poll/edit.html.erb +3 -3
  108. data/app/views/decidim/meetings/admin/registration_form/edit_questions.html.erb +5 -5
  109. data/app/views/decidim/meetings/admin/registrations/edit.html.erb +19 -39
  110. data/app/views/decidim/meetings/admin/registrations_attendees/index.html.erb +126 -0
  111. data/app/views/decidim/meetings/layouts/live_event.html.erb +1 -1
  112. data/app/views/decidim/meetings/meeting_closes/_form.html.erb +2 -2
  113. data/app/views/decidim/meetings/meetings/_form.html.erb +2 -11
  114. data/app/views/decidim/meetings/meetings/_meeting.html.erb +2 -2
  115. data/app/views/decidim/meetings/meetings/_meeting_actions.html.erb +3 -3
  116. data/app/views/decidim/meetings/meetings/_meeting_agenda.html.erb +2 -2
  117. data/app/views/decidim/meetings/meetings/_meeting_aside.html.erb +11 -10
  118. data/app/views/decidim/meetings/meetings/_meeting_poll_actions.html.erb +3 -3
  119. data/app/views/decidim/meetings/meetings/_registration_code_modal.html.erb +16 -0
  120. data/app/views/decidim/meetings/polls/questions/_index_admin.html.erb +1 -1
  121. data/app/views/decidim/meetings/polls/questions/_published_question.html.erb +5 -5
  122. data/app/views/decidim/meetings/polls/responses/_multiple_option.html.erb +13 -0
  123. data/app/views/decidim/meetings/polls/responses/_single_option.html.erb +13 -0
  124. data/app/views/decidim/meetings/polls/{answers → responses}/admin.html.erb +4 -4
  125. data/app/views/decidim/meetings/polls/{answers → responses}/index.html.erb +4 -4
  126. data/app/views/decidim/meetings/registration_mailer/confirmation.html.erb +6 -1
  127. data/config/assets.rb +2 -2
  128. data/config/locales/ar.yml +1 -26
  129. data/config/locales/bg.yml +2 -32
  130. data/config/locales/ca-IT.yml +86 -40
  131. data/config/locales/ca.yml +86 -40
  132. data/config/locales/cs.yml +71 -43
  133. data/config/locales/de.yml +87 -41
  134. data/config/locales/el.yml +1 -25
  135. data/config/locales/en.yml +89 -43
  136. data/config/locales/es-MX.yml +87 -41
  137. data/config/locales/es-PY.yml +87 -41
  138. data/config/locales/es.yml +87 -41
  139. data/config/locales/eu.yml +86 -40
  140. data/config/locales/fi-plain.yml +86 -40
  141. data/config/locales/fi.yml +85 -39
  142. data/config/locales/fr-CA.yml +79 -38
  143. data/config/locales/fr.yml +79 -38
  144. data/config/locales/ga-IE.yml +1 -7
  145. data/config/locales/gl.yml +1 -19
  146. data/config/locales/hu.yml +1 -22
  147. data/config/locales/id-ID.yml +0 -16
  148. data/config/locales/is-IS.yml +0 -10
  149. data/config/locales/it.yml +1 -29
  150. data/config/locales/ja.yml +88 -42
  151. data/config/locales/lb.yml +1 -15
  152. data/config/locales/lt.yml +1 -28
  153. data/config/locales/lv.yml +0 -16
  154. data/config/locales/nl.yml +1 -26
  155. data/config/locales/no.yml +1 -28
  156. data/config/locales/pl.yml +2 -32
  157. data/config/locales/pt-BR.yml +1 -28
  158. data/config/locales/pt.yml +1 -28
  159. data/config/locales/ro-RO.yml +56 -29
  160. data/config/locales/ru.yml +0 -16
  161. data/config/locales/sk.yml +0 -16
  162. data/config/locales/sl.yml +0 -4
  163. data/config/locales/sv.yml +85 -39
  164. data/config/locales/tr-TR.yml +0 -20
  165. data/config/locales/uk.yml +0 -12
  166. data/config/locales/zh-CN.yml +0 -19
  167. data/config/locales/zh-TW.yml +1 -26
  168. data/db/migrate/20181107175558_add_questionnaire_to_existing_meetings.rb +8 -2
  169. data/db/migrate/20200827153856_add_commentable_counter_cache_to_meetings.rb +8 -2
  170. data/db/migrate/20201016065302_fix_meetings_registration_terms.rb +8 -2
  171. data/db/migrate/20210310120731_add_followable_counter_cache_to_meetings.rb +8 -2
  172. data/db/migrate/20250317103343_rename_answer_to_response_in_decidim_meetings.rb +18 -0
  173. data/db/migrate/20250403094034_add_reminder_customization_to_decidim_meetings.rb +9 -0
  174. data/db/migrate/20250408071941_add_status_to_registrations_to_decidim_meetings_registrations.rb +8 -0
  175. data/lib/decidim/api/agenda_item_type.rb +6 -2
  176. data/lib/decidim/api/agenda_type.rb +6 -2
  177. data/lib/decidim/api/linked_resources_interface.rb +1 -1
  178. data/lib/decidim/api/meeting_type.rb +20 -10
  179. data/lib/decidim/api/service_type.rb +3 -0
  180. data/lib/decidim/meetings/admin_engine.rb +9 -1
  181. data/lib/decidim/meetings/component.rb +29 -8
  182. data/lib/decidim/meetings/engine.rb +6 -21
  183. data/lib/decidim/meetings/meeting_serializer.rb +1 -2
  184. data/lib/decidim/meetings/schema_org_event_meeting_serializer.rb +0 -10
  185. data/lib/decidim/meetings/seeds.rb +4 -13
  186. data/lib/decidim/meetings/test/factories.rb +10 -16
  187. data/lib/decidim/meetings/user_responses_serializer.rb +47 -0
  188. data/lib/decidim/meetings/version.rb +1 -1
  189. data/lib/decidim/meetings.rb +7 -9
  190. metadata +49 -35
  191. data/app/cells/decidim/meetings/attending_organizations_list_cell.rb +0 -32
  192. data/app/forms/decidim/meetings/answer_choice_form.rb +0 -14
  193. data/app/models/decidim/meetings/answer_choice.rb +0 -15
  194. data/app/queries/decidim/meetings/metrics/meeting_followers_metric_measure.rb +0 -31
  195. data/app/queries/decidim/meetings/metrics/meetings_metric_manage.rb +0 -48
  196. data/app/views/decidim/meetings/admin/poll/_answer_option.html.erb +0 -35
  197. data/app/views/decidim/meetings/admin/poll/_answer_option_template.html.erb +0 -7
  198. data/app/views/decidim/meetings/polls/answers/_multiple_option.html.erb +0 -13
  199. data/app/views/decidim/meetings/polls/answers/_single_option.html.erb +0 -13
  200. data/lib/decidim/meetings/download_your_data_user_answers_serializer.rb +0 -39
  201. data/lib/decidim/meetings/user_answers_serializer.rb +0 -47
  202. /data/app/views/decidim/meetings/polls/{answers → responses}/create.js.erb +0 -0
@@ -51,10 +51,10 @@ module Decidim
51
51
  has_many :meeting_links, dependent: :destroy, class_name: "Decidim::Meetings::MeetingLink", foreign_key: "decidim_meeting_id"
52
52
  has_many :components, through: :meeting_links, class_name: "Decidim::Component", foreign_key: "decidim_component_id"
53
53
 
54
- enum iframe_access_level: [:all, :signed_in, :registered], _prefix: true
55
- enum iframe_embed_type: [:none, :embed_in_meeting_page, :open_in_live_event_page, :open_in_new_tab], _prefix: true
56
- enum type_of_meeting: TYPE_OF_MEETING
57
- enum registration_type: REGISTRATION_TYPES, _scopes: false
54
+ enum :iframe_access_level, [:all, :signed_in, :registered], prefix: true
55
+ enum :iframe_embed_type, [:none, :embed_in_meeting_page, :open_in_live_event_page, :open_in_new_tab], prefix: true
56
+ enum :type_of_meeting, TYPE_OF_MEETING
57
+ enum :registration_type, REGISTRATION_TYPES, scopes: false
58
58
 
59
59
  component_manifest_name "meetings"
60
60
 
@@ -165,11 +165,6 @@ module Decidim
165
165
  iframe_embed_types.except(:open_in_live_event_page)
166
166
  end
167
167
 
168
- # Return registrations of a particular meeting made by users representing a group
169
- def user_group_registrations
170
- registrations.where.not(decidim_user_group_id: nil)
171
- end
172
-
173
168
  # Returns the presenter for this author, to be used in the views.
174
169
  # Required by ActsAsAuthor.
175
170
  def presenter
@@ -205,20 +200,28 @@ module Decidim
205
200
  false
206
201
  end
207
202
 
203
+ def waitlist_enabled?
204
+ Decidim::Meetings.waiting_list_enabled
205
+ end
206
+
208
207
  def has_available_slots?
209
208
  return true if available_slots.zero?
210
209
 
211
- (available_slots - reserved_slots) > registrations.count
210
+ (available_slots - reserved_slots) > registrations.registered.count
212
211
  end
213
212
 
214
213
  def remaining_slots
215
- available_slots - reserved_slots - registrations.count
214
+ available_slots - reserved_slots - registrations.registered.count
216
215
  end
217
216
 
218
217
  def has_registration_for?(user)
219
218
  registrations.where(user:).any?
220
219
  end
221
220
 
221
+ def pending_location?
222
+ !online? && location.except("machine_translations").values.all?(&:blank?)
223
+ end
224
+
222
225
  def maps_enabled?
223
226
  component.settings.maps_enabled?
224
227
  end
@@ -315,7 +318,7 @@ module Decidim
315
318
  end
316
319
 
317
320
  def authored_proposals
318
- return [] unless Decidim::Meetings.enable_proposal_linking
321
+ return [] unless Decidim.module_installed?(:proposals)
319
322
 
320
323
  Decidim::Proposals::Proposal
321
324
  .joins(:coauthorships)
@@ -9,18 +9,18 @@ module Decidim
9
9
  QUESTION_TYPES = %w(single_option multiple_option).freeze
10
10
 
11
11
  translatable_fields :body
12
- enum status: { unpublished: 0, published: 1, closed: 2 }
12
+ enum :status, { unpublished: 0, published: 1, closed: 2 }
13
13
 
14
14
  belongs_to :questionnaire, class_name: "Decidim::Meetings::Questionnaire", foreign_key: "decidim_questionnaire_id"
15
15
 
16
- has_many :answers,
17
- class_name: "Decidim::Meetings::Answer",
16
+ has_many :responses,
17
+ class_name: "Decidim::Meetings::Response",
18
18
  foreign_key: "decidim_question_id",
19
19
  dependent: :destroy,
20
20
  inverse_of: :question
21
21
 
22
- has_many :answer_options,
23
- class_name: "Decidim::Meetings::AnswerOption",
22
+ has_many :response_options,
23
+ class_name: "Decidim::Meetings::ResponseOption",
24
24
  foreign_key: "decidim_question_id",
25
25
  dependent: :destroy,
26
26
  inverse_of: :question
@@ -28,27 +28,27 @@ module Decidim
28
28
  validates :question_type, inclusion: { in: QUESTION_TYPES }
29
29
 
30
30
  scope :visible, -> { where(status: [:published, :closed]) }
31
- scope :unanswered, -> { where.missing(:answers) }
31
+ scope :unanswered, -> { where.missing(:responses) }
32
32
 
33
33
  def multiple_choice?
34
34
  %w(single_option multiple_option).include?(question_type)
35
35
  end
36
36
 
37
- # Public: returns whether the questionnaire is answered by the user or not.
38
- def answered_by?(user)
39
- questionnaire.answers.where({ user:, question: self }).any? if questionnaire.questions.present? && user.present?
37
+ # Public: returns whether the questionnaire is responded by the user or not.
38
+ def responded_by?(user)
39
+ questionnaire.responses.where({ user:, question: self }).any? if questionnaire.questions.present? && user.present?
40
40
  end
41
41
 
42
42
  def number_of_options
43
- answer_options.size
43
+ response_options.size
44
44
  end
45
45
 
46
46
  def translated_body
47
47
  Decidim::Forms::QuestionPresenter.new(self).translated_body
48
48
  end
49
49
 
50
- def answers_count
51
- questionnaire.answers.where(question: self).count
50
+ def responses_count
51
+ questionnaire.responses.where(question: self).count
52
52
  end
53
53
  end
54
54
  end
@@ -9,7 +9,7 @@ module Decidim
9
9
  belongs_to :questionnaire_for, polymorphic: true
10
10
 
11
11
  has_many :questions, -> { order(:position) }, class_name: "Question", foreign_key: "decidim_questionnaire_id", dependent: :destroy
12
- has_many :answers, class_name: "Answer", foreign_key: "decidim_questionnaire_id", dependent: :destroy
12
+ has_many :responses, class_name: "Response", foreign_key: "decidim_questionnaire_id", dependent: :destroy
13
13
 
14
14
  def all_questions_unpublished?
15
15
  questions.all?(&:unpublished?)
@@ -8,7 +8,6 @@ module Decidim
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"
11
- belongs_to :user_group, foreign_key: "decidim_user_group_id", class_name: "Decidim::UserGroup", optional: true
12
11
 
13
12
  validates :user, uniqueness: { scope: :meeting }
14
13
  validates :code, uniqueness: { allow_blank: true, scope: :meeting }
@@ -16,7 +15,12 @@ module Decidim
16
15
 
17
16
  before_validation :generate_code, on: :create
18
17
 
19
- scope :public_participant, -> { where(decidim_user_group_id: nil, public_participation: true) }
18
+ enum :status, { registered: "registered", waiting_list: "waiting_list" }
19
+
20
+ scope :on_waiting_list, -> { waiting_list.order(:created_at) }
21
+ scope :public_participant, -> { where(public_participation: true) }
22
+
23
+ delegate :component, :organization, to: :meeting
20
24
 
21
25
  def self.user_collection(user)
22
26
  where(decidim_user_id: user.id)
@@ -26,11 +30,6 @@ module Decidim
26
30
  Decidim::Meetings::DownloadYourDataRegistrationSerializer
27
31
  end
28
32
 
29
- # Pluck all Decidim::UserGroup ID's
30
- def self.user_group_ids
31
- pluck(:decidim_user_group_id)
32
- end
33
-
34
33
  # Public: Checks if the registration has been validated.
35
34
  #
36
35
  # Returns Boolean.
@@ -38,6 +37,19 @@ module Decidim
38
37
  validated_at?
39
38
  end
40
39
 
40
+ def presenter
41
+ Decidim::Meetings::RegistrationPresenter.new(self)
42
+ end
43
+
44
+ def validation_code_short_link
45
+ Decidim::ShortLink.to(
46
+ self,
47
+ meeting.component.mounted_admin_engine,
48
+ route_name: :qr_mark_as_attendee_meeting_registrations_attendee,
49
+ params: { meeting_id: meeting.id, id: code }
50
+ )
51
+ end
52
+
41
53
  private
42
54
 
43
55
  def generate_code
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Decidim
4
4
  module Meetings
5
- # The data store for an Answer in the Decidim::Meetings
6
- class Answer < Meetings::ApplicationRecord
5
+ # The data store for an Response in the Decidim::Meetings
6
+ class Response < Meetings::ApplicationRecord
7
7
  include Decidim::DownloadYourData
8
8
 
9
9
  belongs_to :user, class_name: "Decidim::User", foreign_key: "decidim_user_id", optional: true
@@ -11,10 +11,10 @@ module Decidim
11
11
  belongs_to :question, class_name: "Question", foreign_key: "decidim_question_id"
12
12
 
13
13
  has_many :choices,
14
- class_name: "AnswerChoice",
15
- foreign_key: "decidim_answer_id",
14
+ class_name: "ResponseChoice",
15
+ foreign_key: "decidim_response_id",
16
16
  dependent: :destroy,
17
- inverse_of: :answer
17
+ inverse_of: :response
18
18
 
19
19
  validate :user_questionnaire_same_organization
20
20
  validate :question_belongs_to_questionnaire
@@ -24,7 +24,7 @@ module Decidim
24
24
  end
25
25
 
26
26
  def self.export_serializer
27
- Decidim::Meetings::DownloadYourDataUserAnswersSerializer
27
+ Decidim::Forms::DownloadYourDataUserResponsesSerializer
28
28
  end
29
29
 
30
30
  def organization
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ class ResponseChoice < Meetings::ApplicationRecord
6
+ belongs_to :response,
7
+ class_name: "Decidim::Meetings::Response",
8
+ foreign_key: "decidim_response_id"
9
+
10
+ belongs_to :response_option,
11
+ class_name: "Decidim::Meetings::ResponseOption",
12
+ foreign_key: "decidim_response_option_id"
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Meetings
5
- class AnswerOption < Meetings::ApplicationRecord
5
+ class ResponseOption < Meetings::ApplicationRecord
6
6
  include Decidim::TranslatableResource
7
7
 
8
8
  default_scope { order(arel_table[:id].asc) }
@@ -11,13 +11,13 @@ module Decidim
11
11
 
12
12
  belongs_to :question, class_name: "Decidim::Meetings::Question", foreign_key: "decidim_question_id"
13
13
  has_many :choices,
14
- class_name: "AnswerChoice",
15
- foreign_key: "decidim_answer_option_id",
14
+ class_name: "ResponseChoice",
15
+ foreign_key: "decidim_response_option_id",
16
16
  dependent: :destroy,
17
- inverse_of: :answer_option
17
+ inverse_of: :response_option
18
18
 
19
19
  def translated_body
20
- Decidim::Forms::AnswerOptionPresenter.new(self).translated_body
20
+ Decidim::Forms::ResponseOptionPresenter.new(self).translated_body
21
21
  end
22
22
  end
23
23
  end
@@ -2,7 +2,7 @@ const removeNewlineAdjacentSpaces = (text) => {
2
2
  return text.replace(/\n\s/g, "\n");
3
3
  }
4
4
 
5
- $(() => {
5
+ document.addEventListener("turbo:load", () => {
6
6
  const $confirmButton = $(".destroy-meeting-alert");
7
7
 
8
8
  if ($confirmButton.length > 0) {
@@ -1,5 +1,4 @@
1
1
  import TomSelect from "tom-select/dist/cjs/tom-select.popular";
2
- import createTooltip from "src/decidim/tooltips"
3
2
 
4
3
  /**
5
4
  * This module manages the Linked Spaces section from the
@@ -40,12 +39,6 @@ const handleAddButton = () => {
40
39
 
41
40
  body.appendChild(clone);
42
41
 
43
- const tooltips = body.querySelectorAll("[data-tooltip]")
44
-
45
- if (tooltips.length) {
46
- createTooltip(tooltips[tooltips.length - 1]);
47
- }
48
-
49
42
  select.value = "";
50
43
  table.classList.remove("hidden");
51
44
  };
@@ -65,7 +58,7 @@ const setupTomSelect = () => {
65
58
  return null;
66
59
  }
67
60
 
68
- document.addEventListener("DOMContentLoaded", () => {
61
+ document.addEventListener("turbo:load", () => {
69
62
  document.querySelectorAll(".js-remove-component").forEach(handleRemoveButton);
70
63
  const addButton = document.querySelector(".js-add-component")
71
64
 
@@ -5,7 +5,7 @@ import createDynamicFields from "src/decidim/admin/dynamic_fields.component"
5
5
  import createFieldDependentInputs from "src/decidim/admin/field_dependent_inputs.component"
6
6
  import attachGeocoding from "src/decidim/geocoding/attach_input"
7
7
 
8
- $(() => {
8
+ document.addEventListener("turbo:load", () => {
9
9
  const wrapperSelector = ".meeting-services";
10
10
  const fieldSelector = ".meeting-service";
11
11
 
@@ -1,4 +1,4 @@
1
- $(() => {
1
+ document.addEventListener("turbo:load", () => {
2
2
  const $form = $(".edit_meeting_registrations");
3
3
 
4
4
  if ($form.length > 0) {
@@ -1,6 +1,6 @@
1
1
  import createFieldDependentInputs from "src/decidim/admin/field_dependent_inputs.component"
2
2
 
3
- $(() => {
3
+ document.addEventListener("turbo:load", () => {
4
4
  const $attendeeType = $('[name="meeting_registration_invite[existing_user]"');
5
5
 
6
6
  createFieldDependentInputs({
@@ -1,7 +1,7 @@
1
1
  import attachGeocoding from "src/decidim/geocoding/attach_input"
2
2
  import createFieldDependentInputs from "src/decidim/admin/field_dependent_inputs.component"
3
3
 
4
- $(() => {
4
+ document.addEventListener("turbo:load", () => {
5
5
  // Adds the latitude/longitude inputs after the geocoding is done
6
6
  const $meetingAddress = $("#meeting_address");
7
7
  if ($meetingAddress.length > 0) {
@@ -1,7 +1,7 @@
1
1
  import MeetingsPollComponent from "src/decidim/meetings/poll.component"
2
2
  const OPEN_CLASS = "is-open";
3
3
 
4
- $(() => {
4
+ document.addEventListener("turbo:load", () => {
5
5
  // Mount polls component for users
6
6
  const $container = $("[data-decidim-meetings-poll]");
7
7
  const $counter = $("#visible-questions-count");
@@ -28,7 +28,7 @@ export default class PollComponent {
28
28
  this.mounted = false;
29
29
  this.questions = {};
30
30
  this.questionsStatuses = {};
31
- this.answersStatuses = {};
31
+ this.responsesStatuses = {};
32
32
  }
33
33
 
34
34
  /**
@@ -102,7 +102,7 @@ export default class PollComponent {
102
102
 
103
103
  this.questionsStatuses[questionId] = $el.data("status");
104
104
  if (elForm.length > 0) {
105
- this.answersStatuses[questionId] = Object.fromEntries(new FormData(elForm[0]));
105
+ this.responsesStatuses[questionId] = Object.fromEntries(new FormData(elForm[0]));
106
106
  }
107
107
  if ($el[0].open === true) {
108
108
  this.questions[questionId] = OPEN;
@@ -137,7 +137,7 @@ export default class PollComponent {
137
137
  // Current question state
138
138
  const state = this.questions[questionId];
139
139
  const questionStatus = this.questionsStatuses[questionId];
140
- const answersStatuses = this.answersStatuses[questionId];
140
+ const responsesStatuses = this.responsesStatuses[questionId];
141
141
 
142
142
  // New questions have a special class
143
143
  if (!state) {
@@ -151,8 +151,8 @@ export default class PollComponent {
151
151
  document.getElementById(`closed-announcement-${questionId}`).hidden = false;
152
152
  }
153
153
 
154
- if (answersStatuses) {
155
- for (const [key, value] of Object.entries(answersStatuses)) {
154
+ if (responsesStatuses) {
155
+ for (const [key, value] of Object.entries(responsesStatuses)) {
156
156
  if (key.includes("[choices]")) {
157
157
  $el.find(`[name='${key}'][value='${value}']`).prop("checked", true);
158
158
  }
@@ -148,6 +148,10 @@
148
148
  &__list {
149
149
  @apply ml-4 list-disc text-gray-2 text-sm;
150
150
  }
151
+
152
+ &__item {
153
+ @apply items-center gap-2;
154
+ }
151
155
  }
152
156
 
153
157
  &-actions {
@@ -228,7 +232,7 @@
228
232
  }
229
233
  }
230
234
 
231
- &__answer {
235
+ &__response {
232
236
  label {
233
237
  @apply block p-4 ring-4 ring-background rounded transition;
234
238
 
@@ -1,4 +1,4 @@
1
- @import "stylesheets/decidim/meetings/list.scss";
2
- @import "stylesheets/decidim/meetings/item.scss";
3
- @import "stylesheets/decidim/meetings/calendar.scss";
4
- @import "stylesheets/decidim/meetings/live_event.scss";
1
+ @use "stylesheets/decidim/meetings/list";
2
+ @use "stylesheets/decidim/meetings/item";
3
+ @use "stylesheets/decidim/meetings/calendar";
4
+ @use "stylesheets/decidim/meetings/live_event";
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ module Admin
6
+ class AgendaPermissions < Decidim::DefaultPermissions
7
+ def permissions
8
+ return permission_action unless user
9
+ return permission_action unless permission_action.scope == :admin
10
+ return permission_action unless subject == :agenda
11
+
12
+ case permission_action.action
13
+ when :create
14
+ toggle_allow(meeting.present?)
15
+ when :update
16
+ toggle_allow(agenda.present? && meeting.present?)
17
+ end
18
+
19
+ permission_action
20
+ end
21
+
22
+ private
23
+
24
+ def agenda
25
+ @agenda ||= context.fetch(:agenda, nil)
26
+ end
27
+
28
+ def meeting
29
+ @meeting ||= context.fetch(:meeting, nil)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ module Admin
6
+ class MeetingPermissions < Decidim::DefaultPermissions
7
+ def permissions # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
8
+ return permission_action unless user
9
+ return permission_action unless permission_action.scope == :admin
10
+ return permission_action unless subject == :meeting
11
+
12
+ if meeting && !meeting.official?
13
+ disallow!
14
+
15
+ return permission_action
16
+ end
17
+
18
+ case permission_action.action
19
+ when :close, :copy, :export_registrations, :update, :read_invites
20
+ toggle_allow(meeting.present?)
21
+ when :invite_attendee
22
+ toggle_allow(meeting.present? && meeting.registrations_enabled?)
23
+ when :validate_registration_code
24
+ toggle_allow(
25
+ meeting.present? &&
26
+ meeting.registrations_enabled? &&
27
+ meeting.component.settings.registration_code_enabled
28
+ )
29
+ when :create
30
+ allow!
31
+ end
32
+
33
+ permission_action
34
+ end
35
+
36
+ private
37
+
38
+ def meeting
39
+ @meeting ||= context.fetch(:meeting, nil)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -8,11 +8,11 @@ module Decidim
8
8
  return permission_action unless user
9
9
  return permission_action unless permission_action.scope == :admin
10
10
 
11
- allowed_registration_form_action?
12
- allowed_meeting_action?
13
- allowed_agenda_action?
14
- allowed_poll_action?
15
- allowed_export_answers?
11
+ return Decidim::Meetings::Admin::MeetingPermissions.new(user, permission_action, context).permissions if subject == :meeting
12
+ return Decidim::Meetings::Admin::QuestionnairePermissions.new(user, permission_action, context).permissions if subject == :questionnaire
13
+ return Decidim::Meetings::Admin::AgendaPermissions.new(user, permission_action, context).permissions if subject == :agenda
14
+
15
+ toggle_allow(poll.present? && meeting.present?) if subject == :poll && action == :update
16
16
 
17
17
  permission_action
18
18
  end
@@ -23,70 +23,9 @@ module Decidim
23
23
  @meeting ||= context.fetch(:meeting, nil)
24
24
  end
25
25
 
26
- def agenda
27
- @agenda ||= context.fetch(:agenda, nil)
28
- end
29
-
30
26
  def poll
31
27
  @poll ||= context.fetch(:poll, nil)
32
28
  end
33
-
34
- def registration_form
35
- @registration_form ||= context.fetch(:questionnaire, nil)
36
- end
37
-
38
- def allowed_meeting_action?
39
- return unless permission_action.subject == :meeting
40
-
41
- return disallow! if meeting && !meeting.official?
42
-
43
- case permission_action.action
44
- when :close, :copy, :export_registrations, :update, :read_invites
45
- toggle_allow(meeting.present?)
46
- when :invite_attendee
47
- toggle_allow(meeting.present? && meeting.registrations_enabled?)
48
- when :create
49
- allow!
50
- end
51
- end
52
-
53
- def allowed_registration_form_action?
54
- return unless permission_action.subject == :questionnaire
55
-
56
- case permission_action.action
57
- when :update
58
- toggle_allow(registration_form.present?)
59
- end
60
- end
61
-
62
- def allowed_agenda_action?
63
- return unless permission_action.subject == :agenda
64
-
65
- case permission_action.action
66
- when :create
67
- toggle_allow(meeting.present?)
68
- when :update
69
- toggle_allow(agenda.present? && meeting.present?)
70
- end
71
- end
72
-
73
- def allowed_poll_action?
74
- return unless permission_action.subject == :poll
75
-
76
- case permission_action.action
77
- when :update
78
- toggle_allow(poll.present? && meeting.present?)
79
- end
80
- end
81
-
82
- def allowed_export_answers?
83
- return unless permission_action.subject == :questionnaire
84
-
85
- case permission_action.action
86
- when :export_answers
87
- permission_action.allow!
88
- end
89
- end
90
29
  end
91
30
  end
92
31
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ module Admin
6
+ class QuestionnairePermissions < Decidim::DefaultPermissions
7
+ def permissions
8
+ return permission_action unless user
9
+ return permission_action unless permission_action.scope == :admin
10
+ return permission_action unless subject == :questionnaire
11
+
12
+ case permission_action.action
13
+ when :update
14
+ toggle_allow(registration_form.present?)
15
+ when :export_responses
16
+ allow!
17
+ end
18
+
19
+ permission_action
20
+ end
21
+
22
+ private
23
+
24
+ def registration_form
25
+ @registration_form ||= context.fetch(:questionnaire, nil)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end