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.
- checksums.yaml +4 -4
- data/app/cells/decidim/meetings/cancel_registration_meeting_button/cancelation_modal.erb +7 -4
- data/app/cells/decidim/meetings/cancel_registration_meeting_button/show.erb +1 -1
- data/app/cells/decidim/meetings/cancel_registration_meeting_button_cell.rb +36 -0
- data/app/cells/decidim/meetings/dates_and_map_cell.rb +1 -1
- data/app/cells/decidim/meetings/join_meeting_button/registration_modal.erb +4 -5
- data/app/cells/decidim/meetings/join_meeting_button/show.erb +25 -28
- data/app/cells/decidim/meetings/join_meeting_button/waitlist_button.erb +22 -0
- data/app/cells/decidim/meetings/join_meeting_button_cell.rb +28 -0
- data/app/cells/decidim/meetings/question_responses/show.erb +7 -7
- data/app/cells/decidim/meetings/question_responses_cell.rb +28 -28
- data/app/commands/decidim/meetings/admin/copy_meeting.rb +5 -2
- data/app/commands/decidim/meetings/admin/create_agenda.rb +6 -2
- data/app/commands/decidim/meetings/admin/create_meeting.rb +7 -3
- data/app/commands/decidim/meetings/admin/mark_as_attendee.rb +44 -0
- data/app/commands/decidim/meetings/admin/publish_meeting.rb +2 -1
- data/app/commands/decidim/meetings/admin/update_agenda.rb +6 -2
- data/app/commands/decidim/meetings/admin/update_meeting.rb +15 -6
- data/app/commands/decidim/meetings/admin/update_questionnaire.rb +4 -4
- data/app/commands/decidim/meetings/admin/update_registrations.rb +19 -7
- data/app/commands/decidim/meetings/create_meeting.rb +2 -3
- data/app/commands/decidim/meetings/{create_answer.rb → create_response.rb} +11 -11
- data/app/commands/decidim/meetings/join_meeting.rb +4 -6
- data/app/commands/decidim/meetings/join_waitlist.rb +53 -0
- data/app/commands/decidim/meetings/leave_meeting.rb +14 -5
- data/app/commands/decidim/meetings/update_meeting.rb +1 -2
- data/app/controllers/concerns/decidim/meetings/admin/filterable.rb +1 -1
- data/app/controllers/decidim/meetings/admin/agenda_controller.rb +2 -2
- data/app/controllers/decidim/meetings/admin/invites_controller.rb +1 -1
- data/app/controllers/decidim/meetings/admin/meeting_closes_controller.rb +1 -1
- data/app/controllers/decidim/meetings/admin/meeting_copies_controller.rb +1 -1
- data/app/controllers/decidim/meetings/admin/meetings_controller.rb +4 -4
- data/app/controllers/decidim/meetings/admin/meetings_poll_controller.rb +10 -10
- data/app/controllers/decidim/meetings/admin/registrations_attendees_controller.rb +79 -0
- data/app/controllers/decidim/meetings/admin/registrations_controller.rb +1 -22
- data/app/controllers/decidim/meetings/meeting_closes_controller.rb +1 -1
- data/app/controllers/decidim/meetings/meetings_controller.rb +11 -11
- data/app/controllers/decidim/meetings/polls/{answers_controller.rb → responses_controller.rb} +7 -7
- data/app/controllers/decidim/meetings/registrations_controller.rb +39 -12
- data/app/events/decidim/meetings/registration_marked_as_attendee_event.rb +9 -0
- data/app/events/decidim/meetings/upcoming_meeting_event.rb +41 -0
- data/app/events/decidim/meetings/update_meeting_event.rb +25 -0
- data/app/forms/decidim/meetings/admin/close_meeting_form.rb +2 -1
- data/app/forms/decidim/meetings/admin/meeting_agenda_items_form.rb +4 -0
- data/app/forms/decidim/meetings/admin/meeting_form.rb +28 -3
- data/app/forms/decidim/meetings/admin/question_form.rb +3 -3
- data/app/forms/decidim/meetings/admin/{answer_option_form.rb → response_option_form.rb} +3 -3
- data/app/forms/decidim/meetings/admin/validate_registration_code_form.rb +1 -1
- data/app/forms/decidim/meetings/base_meeting_form.rb +0 -2
- data/app/forms/decidim/meetings/close_meeting_form.rb +2 -1
- data/app/forms/decidim/meetings/join_meeting_form.rb +0 -1
- data/app/forms/decidim/meetings/meeting_form.rb +3 -2
- data/app/forms/decidim/meetings/response_choice_form.rb +14 -0
- data/app/forms/decidim/meetings/{answer_form.rb → response_form.rb} +7 -7
- data/app/helpers/decidim/meetings/application_helper.rb +0 -1
- data/app/helpers/decidim/meetings/meetings_helper.rb +14 -5
- data/app/jobs/decidim/meetings/promote_from_waitlist_job.rb +63 -0
- data/app/jobs/decidim/meetings/upcoming_meeting_notification_job.rb +1 -1
- data/app/mailers/decidim/meetings/registration_mailer.rb +13 -0
- data/app/models/decidim/meetings/agenda_item.rb +5 -0
- data/app/models/decidim/meetings/meeting.rb +15 -12
- data/app/models/decidim/meetings/question.rb +12 -12
- data/app/models/decidim/meetings/questionnaire.rb +1 -1
- data/app/models/decidim/meetings/registration.rb +19 -7
- data/app/models/decidim/meetings/{answer.rb → response.rb} +6 -6
- data/app/models/decidim/meetings/response_choice.rb +15 -0
- data/app/models/decidim/meetings/{answer_option.rb → response_option.rb} +5 -5
- data/app/packs/src/decidim/meetings/admin/destroy_meeting_alert.js +1 -1
- data/app/packs/src/decidim/meetings/admin/meetings_components_form.js +1 -8
- data/app/packs/src/decidim/meetings/admin/meetings_form.js +1 -1
- data/app/packs/src/decidim/meetings/admin/registrations_form.js +1 -1
- data/app/packs/src/decidim/meetings/admin/registrations_invite_form.js +1 -1
- data/app/packs/src/decidim/meetings/meetings_form.js +1 -1
- data/app/packs/src/decidim/meetings/meetings_polls.js +1 -1
- data/app/packs/src/decidim/meetings/poll.component.js +5 -5
- data/app/packs/stylesheets/decidim/meetings/_item.scss +5 -1
- data/app/packs/stylesheets/decidim/meetings/meetings.scss +4 -4
- data/app/permissions/decidim/meetings/admin/agenda_permissions.rb +34 -0
- data/app/permissions/decidim/meetings/admin/meeting_permissions.rb +44 -0
- data/app/permissions/decidim/meetings/admin/permissions.rb +5 -66
- data/app/permissions/decidim/meetings/admin/questionnaire_permissions.rb +30 -0
- data/app/permissions/decidim/meetings/meeting_permissions.rb +90 -0
- data/app/permissions/decidim/meetings/permissions.rb +9 -105
- data/app/presenters/decidim/meetings/admin_log/value_types/meeting_title_description_presenter.rb +1 -1
- data/app/presenters/decidim/meetings/agenda_item_presenter.rb +29 -0
- data/app/presenters/decidim/meetings/meeting_presenter.rb +11 -15
- data/app/presenters/decidim/meetings/registration_presenter.rb +24 -0
- data/app/queries/decidim/meetings/{questionnaire_user_answers.rb → questionnaire_user_responses.rb} +5 -5
- data/app/serializers/decidim/meetings/registration_serializer.rb +5 -6
- data/app/services/decidim/meetings/diff_renderer.rb +0 -1
- data/app/views/decidim/meetings/_calendar_modal.html.erb +1 -0
- data/app/views/decidim/meetings/admin/agenda/_agenda_item_fields.html.erb +1 -1
- data/app/views/decidim/meetings/admin/invites/_form.html.erb +1 -1
- data/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +1 -1
- data/app/views/decidim/meetings/admin/meetings/_form.html.erb +3 -2
- data/app/views/decidim/meetings/admin/meetings/_linked_spaces.html.erb +1 -1
- data/app/views/decidim/meetings/admin/meetings/_meeting-tr.html.erb +11 -8
- data/app/views/decidim/meetings/admin/meetings/_meeting_actions.html.erb +200 -69
- data/app/views/decidim/meetings/admin/meetings/_reminders.html.erb +19 -0
- data/app/views/decidim/meetings/admin/meetings/_services.html.erb +1 -1
- data/app/views/decidim/meetings/admin/meetings/index.html.erb +7 -5
- data/app/views/decidim/meetings/admin/meetings/manage_trash.html.erb +2 -1
- data/app/views/decidim/meetings/admin/poll/_form.html.erb +6 -6
- data/app/views/decidim/meetings/admin/poll/_question.html.erb +13 -13
- data/app/views/decidim/meetings/admin/poll/_response_option.html.erb +35 -0
- data/app/views/decidim/meetings/admin/poll/_response_option_template.html.erb +7 -0
- data/app/views/decidim/meetings/admin/poll/edit.html.erb +3 -3
- data/app/views/decidim/meetings/admin/registration_form/edit_questions.html.erb +5 -5
- data/app/views/decidim/meetings/admin/registrations/edit.html.erb +19 -39
- data/app/views/decidim/meetings/admin/registrations_attendees/index.html.erb +126 -0
- data/app/views/decidim/meetings/layouts/live_event.html.erb +1 -1
- data/app/views/decidim/meetings/meeting_closes/_form.html.erb +2 -2
- data/app/views/decidim/meetings/meetings/_form.html.erb +2 -11
- data/app/views/decidim/meetings/meetings/_meeting.html.erb +2 -2
- data/app/views/decidim/meetings/meetings/_meeting_actions.html.erb +3 -3
- data/app/views/decidim/meetings/meetings/_meeting_agenda.html.erb +2 -2
- data/app/views/decidim/meetings/meetings/_meeting_aside.html.erb +11 -10
- data/app/views/decidim/meetings/meetings/_meeting_poll_actions.html.erb +3 -3
- data/app/views/decidim/meetings/meetings/_registration_code_modal.html.erb +16 -0
- data/app/views/decidim/meetings/polls/questions/_index_admin.html.erb +1 -1
- data/app/views/decidim/meetings/polls/questions/_published_question.html.erb +5 -5
- data/app/views/decidim/meetings/polls/responses/_multiple_option.html.erb +13 -0
- data/app/views/decidim/meetings/polls/responses/_single_option.html.erb +13 -0
- data/app/views/decidim/meetings/polls/{answers → responses}/admin.html.erb +4 -4
- data/app/views/decidim/meetings/polls/{answers → responses}/index.html.erb +4 -4
- data/app/views/decidim/meetings/registration_mailer/confirmation.html.erb +6 -1
- data/config/assets.rb +2 -2
- data/config/locales/ar.yml +1 -26
- data/config/locales/bg.yml +2 -32
- data/config/locales/ca-IT.yml +86 -40
- data/config/locales/ca.yml +86 -40
- data/config/locales/cs.yml +71 -43
- data/config/locales/de.yml +87 -41
- data/config/locales/el.yml +1 -25
- data/config/locales/en.yml +89 -43
- data/config/locales/es-MX.yml +87 -41
- data/config/locales/es-PY.yml +87 -41
- data/config/locales/es.yml +87 -41
- data/config/locales/eu.yml +86 -40
- data/config/locales/fi-plain.yml +86 -40
- data/config/locales/fi.yml +85 -39
- data/config/locales/fr-CA.yml +79 -38
- data/config/locales/fr.yml +79 -38
- data/config/locales/ga-IE.yml +1 -7
- data/config/locales/gl.yml +1 -19
- data/config/locales/hu.yml +1 -22
- data/config/locales/id-ID.yml +0 -16
- data/config/locales/is-IS.yml +0 -10
- data/config/locales/it.yml +1 -29
- data/config/locales/ja.yml +88 -42
- data/config/locales/lb.yml +1 -15
- data/config/locales/lt.yml +1 -28
- data/config/locales/lv.yml +0 -16
- data/config/locales/nl.yml +1 -26
- data/config/locales/no.yml +1 -28
- data/config/locales/pl.yml +2 -32
- data/config/locales/pt-BR.yml +1 -28
- data/config/locales/pt.yml +1 -28
- data/config/locales/ro-RO.yml +56 -29
- data/config/locales/ru.yml +0 -16
- data/config/locales/sk.yml +0 -16
- data/config/locales/sl.yml +0 -4
- data/config/locales/sv.yml +85 -39
- data/config/locales/tr-TR.yml +0 -20
- data/config/locales/uk.yml +0 -12
- data/config/locales/zh-CN.yml +0 -19
- data/config/locales/zh-TW.yml +1 -26
- data/db/migrate/20181107175558_add_questionnaire_to_existing_meetings.rb +8 -2
- data/db/migrate/20200827153856_add_commentable_counter_cache_to_meetings.rb +8 -2
- data/db/migrate/20201016065302_fix_meetings_registration_terms.rb +8 -2
- data/db/migrate/20210310120731_add_followable_counter_cache_to_meetings.rb +8 -2
- data/db/migrate/20250317103343_rename_answer_to_response_in_decidim_meetings.rb +18 -0
- data/db/migrate/20250403094034_add_reminder_customization_to_decidim_meetings.rb +9 -0
- data/db/migrate/20250408071941_add_status_to_registrations_to_decidim_meetings_registrations.rb +8 -0
- data/lib/decidim/api/agenda_item_type.rb +6 -2
- data/lib/decidim/api/agenda_type.rb +6 -2
- data/lib/decidim/api/linked_resources_interface.rb +1 -1
- data/lib/decidim/api/meeting_type.rb +20 -10
- data/lib/decidim/api/service_type.rb +3 -0
- data/lib/decidim/meetings/admin_engine.rb +9 -1
- data/lib/decidim/meetings/component.rb +29 -8
- data/lib/decidim/meetings/engine.rb +6 -21
- data/lib/decidim/meetings/meeting_serializer.rb +1 -2
- data/lib/decidim/meetings/schema_org_event_meeting_serializer.rb +0 -10
- data/lib/decidim/meetings/seeds.rb +4 -13
- data/lib/decidim/meetings/test/factories.rb +10 -16
- data/lib/decidim/meetings/user_responses_serializer.rb +47 -0
- data/lib/decidim/meetings/version.rb +1 -1
- data/lib/decidim/meetings.rb +7 -9
- metadata +49 -35
- data/app/cells/decidim/meetings/attending_organizations_list_cell.rb +0 -32
- data/app/forms/decidim/meetings/answer_choice_form.rb +0 -14
- data/app/models/decidim/meetings/answer_choice.rb +0 -15
- data/app/queries/decidim/meetings/metrics/meeting_followers_metric_measure.rb +0 -31
- data/app/queries/decidim/meetings/metrics/meetings_metric_manage.rb +0 -48
- data/app/views/decidim/meetings/admin/poll/_answer_option.html.erb +0 -35
- data/app/views/decidim/meetings/admin/poll/_answer_option_template.html.erb +0 -7
- data/app/views/decidim/meetings/polls/answers/_multiple_option.html.erb +0 -13
- data/app/views/decidim/meetings/polls/answers/_single_option.html.erb +0 -13
- data/lib/decidim/meetings/download_your_data_user_answers_serializer.rb +0 -39
- data/lib/decidim/meetings/user_answers_serializer.rb +0 -47
- /data/app/views/decidim/meetings/polls/{answers → responses}/create.js.erb +0 -0
@@ -8,14 +8,16 @@ module Decidim
|
|
8
8
|
fetch_form_attributes :registrations_enabled, :registration_form_enabled
|
9
9
|
|
10
10
|
def run_after_hooks
|
11
|
-
|
11
|
+
if resource.previous_changes["registrations_enabled"].present? && resource.registrations_enabled?
|
12
|
+
Decidim::EventsManager.publish(
|
13
|
+
event: "decidim.events.meetings.registrations_enabled",
|
14
|
+
event_class: Decidim::Meetings::MeetingRegistrationsEnabledEvent,
|
15
|
+
resource:,
|
16
|
+
followers: resource.followers
|
17
|
+
)
|
18
|
+
end
|
12
19
|
|
13
|
-
|
14
|
-
event: "decidim.events.meetings.registrations_enabled",
|
15
|
-
event_class: Decidim::Meetings::MeetingRegistrationsEnabledEvent,
|
16
|
-
resource:,
|
17
|
-
followers: resource.followers
|
18
|
-
)
|
20
|
+
promote_from_waitlist!
|
19
21
|
end
|
20
22
|
|
21
23
|
protected
|
@@ -33,6 +35,16 @@ module Decidim
|
|
33
35
|
end
|
34
36
|
super.merge(extra_params)
|
35
37
|
end
|
38
|
+
|
39
|
+
def promote_from_waitlist!
|
40
|
+
slot_changes = resource.previous_changes.keys & %w(available_slots reserved_slots)
|
41
|
+
return if slot_changes.empty?
|
42
|
+
return if resource.available_slots.zero?
|
43
|
+
return unless resource.remaining_slots.positive?
|
44
|
+
return unless resource.registrations.on_waiting_list.exists?
|
45
|
+
|
46
|
+
Decidim::Meetings::PromoteFromWaitlistJob.perform_later(resource.id)
|
47
|
+
end
|
36
48
|
end
|
37
49
|
end
|
38
50
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
|
-
# This command is executed when a participant
|
5
|
+
# This command is executed when a participant creates a Meeting from the public
|
6
6
|
# views.
|
7
7
|
class CreateMeeting < Decidim::Commands::CreateResource
|
8
8
|
fetch_form_attributes :end_time, :start_time, :address, :latitude, :longitude,
|
@@ -40,7 +40,7 @@ module Decidim
|
|
40
40
|
def resource_class = Decidim::Meetings::Meeting
|
41
41
|
|
42
42
|
def attributes
|
43
|
-
parsed_title = Decidim::ContentProcessor.
|
43
|
+
parsed_title = Decidim::ContentProcessor.parse(form.title, current_organization: form.current_organization).rewrite
|
44
44
|
parsed_description = Decidim::ContentProcessor.parse(form.description, current_organization: form.current_organization).rewrite
|
45
45
|
|
46
46
|
super.merge({
|
@@ -49,7 +49,6 @@ module Decidim
|
|
49
49
|
location: { I18n.locale => form.location },
|
50
50
|
location_hints: { I18n.locale => form.location_hints },
|
51
51
|
author: form.current_user,
|
52
|
-
decidim_user_group_id: form.user_group_id,
|
53
52
|
registration_terms: { I18n.locale => form.registration_terms },
|
54
53
|
type_of_meeting: form.clean_type_of_meeting,
|
55
54
|
published_at: Time.current
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Decidim
|
4
4
|
module Meetings
|
5
|
-
# This command is executed when the user creates an
|
6
|
-
class
|
5
|
+
# This command is executed when the user creates an Response in a meeting poll.
|
6
|
+
class CreateResponse < Decidim::Command
|
7
7
|
delegate :current_user, to: :form
|
8
8
|
|
9
9
|
def initialize(form, questionnaire)
|
@@ -11,14 +11,14 @@ module Decidim
|
|
11
11
|
@questionnaire = questionnaire
|
12
12
|
end
|
13
13
|
|
14
|
-
# Creates the
|
14
|
+
# Creates the response if valid.
|
15
15
|
#
|
16
16
|
# Broadcasts :ok if successful, :invalid otherwise.
|
17
17
|
def call
|
18
18
|
return broadcast(:invalid) if form.invalid?
|
19
19
|
|
20
20
|
transaction do
|
21
|
-
|
21
|
+
response_question
|
22
22
|
end
|
23
23
|
|
24
24
|
broadcast(:ok)
|
@@ -26,27 +26,27 @@ module Decidim
|
|
26
26
|
|
27
27
|
private
|
28
28
|
|
29
|
-
attr_reader :form, :
|
29
|
+
attr_reader :form, :response
|
30
30
|
|
31
31
|
def invalid?
|
32
32
|
form.invalid?
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
|
35
|
+
def response_question
|
36
|
+
response = Response.new(
|
37
37
|
user: current_user,
|
38
38
|
questionnaire: @questionnaire,
|
39
39
|
question: form.question
|
40
40
|
)
|
41
41
|
|
42
42
|
form.selected_choices.each do |choice|
|
43
|
-
|
44
|
-
body: choice.body || translated_attribute(
|
45
|
-
|
43
|
+
response.choices.build(
|
44
|
+
body: choice.body || translated_attribute(ResponseOption.find_by(id: choice.response_option_id)&.body),
|
45
|
+
decidim_response_option_id: choice.response_option_id
|
46
46
|
)
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
response.save!
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -11,7 +11,6 @@ module Decidim
|
|
11
11
|
# form - A form object with params; can be a questionnaire.
|
12
12
|
def initialize(meeting, form)
|
13
13
|
@meeting = meeting
|
14
|
-
@user_group = Decidim::UserGroup.find_by(id: form.user_group_id)
|
15
14
|
@form = form
|
16
15
|
end
|
17
16
|
|
@@ -22,7 +21,7 @@ module Decidim
|
|
22
21
|
def call
|
23
22
|
return broadcast(:invalid) unless can_join_meeting?
|
24
23
|
return broadcast(:invalid_form) unless form.valid?
|
25
|
-
return broadcast(:invalid) if
|
24
|
+
return broadcast(:invalid) if response_questionnaire == :invalid
|
26
25
|
|
27
26
|
meeting.with_lock do
|
28
27
|
create_registration
|
@@ -38,16 +37,16 @@ module Decidim
|
|
38
37
|
|
39
38
|
private
|
40
39
|
|
41
|
-
attr_reader :meeting, :
|
40
|
+
attr_reader :meeting, :registration, :form
|
42
41
|
|
43
42
|
def accept_invitation
|
44
43
|
meeting.invites.find_by(user: current_user)&.accept!
|
45
44
|
end
|
46
45
|
|
47
|
-
def
|
46
|
+
def response_questionnaire
|
48
47
|
return unless questionnaire?
|
49
48
|
|
50
|
-
Decidim::Forms::
|
49
|
+
Decidim::Forms::ResponseQuestionnaire.call(form, meeting.questionnaire) do
|
51
50
|
on(:ok) do
|
52
51
|
return :valid
|
53
52
|
end
|
@@ -62,7 +61,6 @@ module Decidim
|
|
62
61
|
@registration = Decidim::Meetings::Registration.create!(
|
63
62
|
meeting:,
|
64
63
|
user: current_user,
|
65
|
-
user_group:,
|
66
64
|
public_participation: form.public_participation
|
67
65
|
)
|
68
66
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
# This command is executed when the user joins a meeting waitlist.
|
6
|
+
class JoinWaitlist < Decidim::Command
|
7
|
+
delegate :current_user, to: :form
|
8
|
+
|
9
|
+
def initialize(meeting, form)
|
10
|
+
@meeting = meeting
|
11
|
+
@form = form
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
return broadcast(:invalid) unless can_join_waitlist?
|
16
|
+
return broadcast(:invalid_form) unless form.valid?
|
17
|
+
|
18
|
+
meeting.with_lock do
|
19
|
+
create_waitlist_entry
|
20
|
+
send_waitlist_notification
|
21
|
+
end
|
22
|
+
|
23
|
+
broadcast(:ok)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :meeting, :user_group, :form
|
29
|
+
|
30
|
+
def can_join_waitlist?
|
31
|
+
meeting.waitlist_enabled? && !meeting.registrations.exists?(user: current_user) && !meeting.has_available_slots?
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_waitlist_entry
|
35
|
+
@registration = Decidim::Meetings::Registration.create!(
|
36
|
+
meeting:,
|
37
|
+
user: current_user,
|
38
|
+
public_participation: form.public_participation,
|
39
|
+
status: :waiting_list
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def send_waitlist_notification
|
44
|
+
Decidim::EventsManager.publish(
|
45
|
+
event: "decidim.events.meetings.meeting_waitlist_added",
|
46
|
+
event_class: Decidim::Meetings::MeetingRegistrationNotificationEvent,
|
47
|
+
resource: meeting,
|
48
|
+
affected_users: [current_user]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -22,8 +22,9 @@ module Decidim
|
|
22
22
|
|
23
23
|
@meeting.with_lock do
|
24
24
|
destroy_registration
|
25
|
-
|
25
|
+
destroy_questionnaire_responses
|
26
26
|
decrement_score
|
27
|
+
promote_from_waitlist!
|
27
28
|
end
|
28
29
|
broadcast(:ok)
|
29
30
|
end
|
@@ -38,18 +39,26 @@ module Decidim
|
|
38
39
|
registration.destroy!
|
39
40
|
end
|
40
41
|
|
41
|
-
def
|
42
|
+
def questionnaire_responses
|
42
43
|
questionnaire = Decidim::Forms::Questionnaire.find_by(questionnaire_for_id: @meeting)
|
43
|
-
questionnaire.
|
44
|
+
questionnaire.responses.where(user: @user) if questionnaire.present?
|
44
45
|
end
|
45
46
|
|
46
|
-
def
|
47
|
-
|
47
|
+
def destroy_questionnaire_responses
|
48
|
+
questionnaire_responses.try(:destroy_all)
|
48
49
|
end
|
49
50
|
|
50
51
|
def decrement_score
|
51
52
|
Decidim::Gamification.decrement_score(@user, :attended_meetings)
|
52
53
|
end
|
54
|
+
|
55
|
+
def promote_from_waitlist!
|
56
|
+
return if @meeting.available_slots.zero?
|
57
|
+
return unless @meeting.remaining_slots.positive?
|
58
|
+
return unless @meeting.registrations.on_waiting_list.exists?
|
59
|
+
|
60
|
+
Decidim::Meetings::PromoteFromWaitlistJob.perform_later(@meeting.id)
|
61
|
+
end
|
53
62
|
end
|
54
63
|
end
|
55
64
|
end
|
@@ -45,7 +45,7 @@ module Decidim
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def update_meeting!
|
48
|
-
parsed_title = Decidim::ContentProcessor.
|
48
|
+
parsed_title = Decidim::ContentProcessor.parse(form.title, current_organization: form.current_organization).rewrite
|
49
49
|
parsed_description = Decidim::ContentProcessor.parse(form.description, current_organization: form.current_organization).rewrite
|
50
50
|
|
51
51
|
Decidim.traceability.update!(
|
@@ -62,7 +62,6 @@ module Decidim
|
|
62
62
|
location: { I18n.locale => form.location },
|
63
63
|
location_hints: { I18n.locale => form.location_hints },
|
64
64
|
author: current_user,
|
65
|
-
decidim_user_group_id: form.user_group_id,
|
66
65
|
registration_type: form.registration_type,
|
67
66
|
registration_url: form.registration_url,
|
68
67
|
available_slots: form.available_slots,
|
@@ -41,7 +41,7 @@ module Decidim
|
|
41
41
|
taxonomies_part_of_contains: taxonomy_ids_hash(available_root_taxonomies),
|
42
42
|
closed_at_present: %w(true false),
|
43
43
|
is_upcoming_true: %w(true false),
|
44
|
-
with_any_origin: %w(participants official
|
44
|
+
with_any_origin: %w(participants official)
|
45
45
|
}
|
46
46
|
end
|
47
47
|
|
@@ -27,7 +27,7 @@ module Decidim
|
|
27
27
|
|
28
28
|
on(:invalid) do
|
29
29
|
flash.now[:alert] = I18n.t("agenda.create.invalid", scope: "decidim.meetings.admin")
|
30
|
-
render action: "new"
|
30
|
+
render action: "new", status: :unprocessable_entity
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -51,7 +51,7 @@ module Decidim
|
|
51
51
|
|
52
52
|
on(:invalid) do
|
53
53
|
flash.now[:alert] = I18n.t("agenda.update.invalid", scope: "decidim.meetings.admin")
|
54
|
-
render action: "edit"
|
54
|
+
render action: "edit", status: :unprocessable_entity
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -29,7 +29,7 @@ module Decidim
|
|
29
29
|
|
30
30
|
on(:invalid) do
|
31
31
|
flash.now[:alert] = I18n.t("meetings.create.invalid", scope: "decidim.meetings.admin")
|
32
|
-
render action: "new"
|
32
|
+
render action: "new", status: :unprocessable_entity
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -53,7 +53,7 @@ module Decidim
|
|
53
53
|
|
54
54
|
on(:invalid) do
|
55
55
|
flash.now[:alert] = I18n.t("meetings.update.invalid", scope: "decidim.meetings.admin")
|
56
|
-
render action: "edit"
|
56
|
+
render action: "edit", status: :unprocessable_entity
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -69,7 +69,7 @@ module Decidim
|
|
69
69
|
|
70
70
|
on(:invalid) do
|
71
71
|
flash.now[:alert] = I18n.t("meetings.publish.invalid", scope: "decidim.meetings.admin")
|
72
|
-
render action: "index"
|
72
|
+
render action: "index", status: :unprocessable_entity
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
@@ -85,7 +85,7 @@ module Decidim
|
|
85
85
|
|
86
86
|
on(:invalid) do
|
87
87
|
flash.now[:alert] = I18n.t("meetings.unpublish.invalid", scope: "decidim.meetings.admin")
|
88
|
-
render action: "index"
|
88
|
+
render action: "index", status: :unprocessable_entity
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
@@ -6,8 +6,8 @@ module Decidim
|
|
6
6
|
class MeetingsPollController < Admin::ApplicationController
|
7
7
|
include Decidim::TranslatableAttributes
|
8
8
|
|
9
|
-
helper_method :questionnaire_for, :questionnaire, :blank_question, :
|
10
|
-
:question_types, :update_url, :
|
9
|
+
helper_method :questionnaire_for, :questionnaire, :blank_question, :blank_response_option,
|
10
|
+
:question_types, :update_url, :response_options_url, :edit_questionnaire_title,
|
11
11
|
:meeting, :poll
|
12
12
|
|
13
13
|
helper Decidim::Forms::Admin::ApplicationHelper
|
@@ -47,17 +47,17 @@ module Decidim
|
|
47
47
|
on(:invalid) do
|
48
48
|
# i18n-tasks-use t("decidim.forms.admin.questionnaires.update.invalid")
|
49
49
|
flash.now[:alert] = I18n.t("update.invalid", scope: "decidim.meetings.admin.meetings_poll")
|
50
|
-
render template: "decidim/meetings/admin/poll/edit"
|
50
|
+
render template: "decidim/meetings/admin/poll/edit", status: :unprocessable_entity
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
55
|
+
def response_options
|
56
56
|
respond_to do |format|
|
57
57
|
format.json do
|
58
58
|
question_id = params["id"]
|
59
59
|
question = Decidim::Meetings::Question.find_by(id: question_id)
|
60
|
-
render json: question.
|
60
|
+
render json: question.response_options.map { |response_option| ResponseOptionPresenter.new(response_option).as_json } if question.present?
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -66,10 +66,10 @@ module Decidim
|
|
66
66
|
poll
|
67
67
|
end
|
68
68
|
|
69
|
-
# Returns the url to get the
|
69
|
+
# Returns the url to get the response options json (for the display conditions form)
|
70
70
|
# for the question with id = params[:id]
|
71
|
-
def
|
72
|
-
url_for([questionnaire.questionnaire_for, { action: :
|
71
|
+
def response_options_url(params)
|
72
|
+
url_for([questionnaire.questionnaire_for, { action: :response_options, format: :json, **params }])
|
73
73
|
end
|
74
74
|
|
75
75
|
# Implement this method in your controller to set the title
|
@@ -88,8 +88,8 @@ module Decidim
|
|
88
88
|
@blank_question ||= Decidim::Meetings::Admin::QuestionForm.new
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
92
|
-
@
|
91
|
+
def blank_response_option
|
92
|
+
@blank_response_option ||= Decidim::Meetings::Admin::ResponseOptionForm.new
|
93
93
|
end
|
94
94
|
|
95
95
|
def question_types
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Meetings
|
5
|
+
module Admin
|
6
|
+
# This controller allows an admin to manage meeting registrations and
|
7
|
+
# attendances from a participatory space
|
8
|
+
class RegistrationsAttendeesController < Admin::ApplicationController
|
9
|
+
helper_method :registrations
|
10
|
+
|
11
|
+
before_action do
|
12
|
+
enforce_permission_to(:validate_registration_code, :meeting, meeting:)
|
13
|
+
end
|
14
|
+
|
15
|
+
def index
|
16
|
+
@validation_form = ValidateRegistrationCodeForm.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def qr_mark_as_attendee
|
20
|
+
registration = registrations.find_by!(code: params[:id])
|
21
|
+
|
22
|
+
MarkAsAttendee.call(registration) do
|
23
|
+
on(:ok) do
|
24
|
+
flash[:notice] = I18n.t("registrations_attendees.mark_attendee.success", scope: "decidim.meetings.admin")
|
25
|
+
end
|
26
|
+
|
27
|
+
on(:invalid) do
|
28
|
+
flash[:alert] = I18n.t("registrations_attendees.mark_attendee.invalid", scope: "decidim.meetings.admin")
|
29
|
+
end
|
30
|
+
|
31
|
+
redirect_to action: "index"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_registration_code
|
36
|
+
@validation_form = ValidateRegistrationCodeForm.from_params(params).with_context(current_organization: meeting.organization, meeting:)
|
37
|
+
|
38
|
+
ValidateRegistrationCode.call(@validation_form, meeting) do
|
39
|
+
on(:ok) do
|
40
|
+
flash[:notice] = I18n.t("registrations_attendees.validate_registration_code.success", scope: "decidim.meetings.admin")
|
41
|
+
redirect_to action: "index"
|
42
|
+
end
|
43
|
+
|
44
|
+
on(:invalid) do
|
45
|
+
flash.now[:alert] = I18n.t("registrations_attendees.validate_registration_code.invalid", scope: "decidim.meetings.admin")
|
46
|
+
render action: "index", status: :unprocessable_entity
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def mark_as_attendee
|
52
|
+
registration = registrations.find(params[:id])
|
53
|
+
|
54
|
+
MarkAsAttendee.call(registration) do
|
55
|
+
on(:ok) do
|
56
|
+
flash[:notice] = I18n.t("registrations_attendees.mark_attendee.success", scope: "decidim.meetings.admin")
|
57
|
+
redirect_to action: "index"
|
58
|
+
end
|
59
|
+
|
60
|
+
on(:invalid) do
|
61
|
+
flash.now[:alert] = I18n.t("registrations_attendees.mark_attendee.invalid", scope: "decidim.meetings.admin")
|
62
|
+
render action: "index", status: :unprocessable_entity
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def meeting
|
70
|
+
@meeting ||= Meeting.where(component: current_component).find(params[:meeting_id])
|
71
|
+
end
|
72
|
+
|
73
|
+
def registrations
|
74
|
+
meeting.registrations
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -9,14 +9,12 @@ module Decidim
|
|
9
9
|
enforce_permission_to(:update, :meeting, meeting:)
|
10
10
|
|
11
11
|
@form = MeetingRegistrationsForm.from_model(meeting)
|
12
|
-
@validation_form = ValidateRegistrationCodeForm.new
|
13
12
|
end
|
14
13
|
|
15
14
|
def update
|
16
15
|
enforce_permission_to(:update, :meeting, meeting:)
|
17
16
|
|
18
17
|
@form = MeetingRegistrationsForm.from_params(params).with_context(current_organization: meeting.organization, meeting:)
|
19
|
-
@validation_form = ValidateRegistrationCodeForm.new
|
20
18
|
|
21
19
|
UpdateRegistrations.call(@form, meeting) do
|
22
20
|
on(:ok) do
|
@@ -26,7 +24,7 @@ module Decidim
|
|
26
24
|
|
27
25
|
on(:invalid) do
|
28
26
|
flash.now[:alert] = I18n.t("registrations.update.invalid", scope: "decidim.meetings.admin")
|
29
|
-
render action: "edit"
|
27
|
+
render action: "edit", status: :unprocessable_entity
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
@@ -41,25 +39,6 @@ module Decidim
|
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
|
-
def validate_registration_code
|
45
|
-
enforce_permission_to(:update, :meeting, meeting:)
|
46
|
-
|
47
|
-
@form = MeetingRegistrationsForm.from_model(meeting)
|
48
|
-
@validation_form = ValidateRegistrationCodeForm.from_params(params).with_context(current_organization: meeting.organization, meeting:)
|
49
|
-
|
50
|
-
ValidateRegistrationCode.call(@validation_form, meeting) do
|
51
|
-
on(:ok) do
|
52
|
-
flash[:notice] = I18n.t("registrations.validate_registration_code.success", scope: "decidim.meetings.admin")
|
53
|
-
render action: "edit"
|
54
|
-
end
|
55
|
-
|
56
|
-
on(:invalid) do
|
57
|
-
flash.now[:alert] = I18n.t("registrations.validate_registration_code.invalid", scope: "decidim.meetings.admin")
|
58
|
-
render action: "edit"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
42
|
private
|
64
43
|
|
65
44
|
def meeting
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rqrcode"
|
4
|
+
|
3
5
|
module Decidim
|
4
6
|
module Meetings
|
5
7
|
# Exposes the meeting resource so users can view them
|
@@ -16,7 +18,7 @@ module Decidim
|
|
16
18
|
include Decidim::AttachmentsHelper
|
17
19
|
include Decidim::SanitizeHelper
|
18
20
|
|
19
|
-
helper_method :meetings, :meeting, :registration, :search, :tab_panel_items
|
21
|
+
helper_method :meetings, :meeting, :registration, :registration_qr_code_image, :search, :tab_panel_items
|
20
22
|
|
21
23
|
before_action :add_additional_csp_directives, only: [:show]
|
22
24
|
|
@@ -39,7 +41,7 @@ module Decidim
|
|
39
41
|
|
40
42
|
on(:invalid) do
|
41
43
|
flash.now[:alert] = I18n.t("meetings.create.invalid", scope: "decidim.meetings")
|
42
|
-
render action: "new"
|
44
|
+
render action: "new", status: :unprocessable_entity
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -86,7 +88,7 @@ module Decidim
|
|
86
88
|
|
87
89
|
on(:invalid) do
|
88
90
|
flash.now[:alert] = I18n.t("meetings.update.invalid", scope: "decidim.meetings")
|
89
|
-
render :edit
|
91
|
+
render :edit, status: :unprocessable_entity
|
90
92
|
end
|
91
93
|
end
|
92
94
|
end
|
@@ -121,6 +123,12 @@ module Decidim
|
|
121
123
|
@registration ||= meeting.registrations.find_by(user: current_user)
|
122
124
|
end
|
123
125
|
|
126
|
+
def registration_qr_code_image
|
127
|
+
Base64.encode64(
|
128
|
+
RQRCode::QRCode.new(registration.validation_code_short_link.short_url).as_png(size: 500).to_s
|
129
|
+
).gsub("\n", "")
|
130
|
+
end
|
131
|
+
|
124
132
|
def search_collection
|
125
133
|
Meeting
|
126
134
|
.where(component: current_component)
|
@@ -151,14 +159,6 @@ module Decidim
|
|
151
159
|
method: :cell,
|
152
160
|
args: ["decidim/meetings/public_participants_list", meeting]
|
153
161
|
},
|
154
|
-
{
|
155
|
-
enabled: !meeting.closed? && meeting.user_group_registrations.any?,
|
156
|
-
id: "organizations",
|
157
|
-
text: t("attending_organizations", scope: "decidim.meetings.public_participants_list"),
|
158
|
-
icon: "community-line",
|
159
|
-
method: :cell,
|
160
|
-
args: ["decidim/meetings/attending_organizations_list", meeting]
|
161
|
-
},
|
162
162
|
{
|
163
163
|
enabled: meeting.linked_resources(:proposals, "proposals_from_meeting").present?,
|
164
164
|
id: "included_proposals",
|