decidim-meetings 0.30.5 → 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/meeting_cell.rb +6 -1
- data/app/cells/decidim/meetings/meeting_s_cell.rb +15 -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 -44
- 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 +12 -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 +9 -14
- data/app/views/decidim/meetings/admin/meetings/_meeting_actions.html.erb +200 -69
- data/app/views/decidim/meetings/admin/meetings/_meetings-thead.html.erb +0 -3
- 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 +9 -9
- data/app/views/decidim/meetings/admin/poll/_question.html.erb +19 -9
- 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 +87 -44
- data/config/locales/ca.yml +87 -44
- data/config/locales/cs.yml +71 -46
- data/config/locales/de.yml +89 -46
- data/config/locales/el.yml +1 -25
- data/config/locales/en.yml +89 -46
- data/config/locales/es-MX.yml +87 -44
- data/config/locales/es-PY.yml +87 -44
- data/config/locales/es.yml +87 -44
- data/config/locales/eu.yml +114 -71
- data/config/locales/fi-plain.yml +86 -43
- data/config/locales/fi.yml +85 -42
- data/config/locales/fr-CA.yml +79 -41
- data/config/locales/fr.yml +79 -41
- data/config/locales/ga-IE.yml +1 -8
- data/config/locales/gl.yml +1 -19
- data/config/locales/hu.yml +1 -23
- data/config/locales/id-ID.yml +0 -16
- data/config/locales/is-IS.yml +0 -10
- data/config/locales/it.yml +1 -38
- data/config/locales/ja.yml +88 -45
- data/config/locales/lb.yml +1 -16
- 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 -29
- data/config/locales/pl.yml +2 -32
- data/config/locales/pt-BR.yml +13 -205
- data/config/locales/pt.yml +1 -29
- data/config/locales/ro-RO.yml +56 -32
- 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 +89 -46
- 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 -20
- 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 +50 -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
|
@@ -73,12 +73,12 @@ module Decidim
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
update_nested_model(form_question, question_attributes, @questionnaire.questions) do |question|
|
|
76
|
-
form_question.
|
|
77
|
-
|
|
78
|
-
body:
|
|
76
|
+
form_question.response_options.each do |form_response_option|
|
|
77
|
+
response_option_attributes = {
|
|
78
|
+
body: form_response_option.body
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
update_nested_model(
|
|
81
|
+
update_nested_model(form_response_option, response_option_attributes, question.response_options)
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
end
|
|
@@ -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
|