decidim-meetings 0.13.1 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_meetings_manifest.js +1 -0
  3. data/app/assets/javascripts/decidim/meetings/admin/registrations_invite_form.es6 +25 -0
  4. data/app/cells/decidim/meetings/join_meeting_button/show.erb +2 -0
  5. data/app/cells/decidim/meetings/meeting_cell.rb +1 -1
  6. data/app/commands/decidim/meetings/admin/invite_user_to_join_meeting.rb +57 -8
  7. data/app/commands/decidim/meetings/admin/validate_registration_code.rb +51 -0
  8. data/app/commands/decidim/meetings/decline_invitation.rb +45 -0
  9. data/app/commands/decidim/meetings/join_meeting.rb +8 -3
  10. data/app/controllers/decidim/meetings/admin/attachment_collections_controller.rb +0 -4
  11. data/app/controllers/decidim/meetings/admin/attachments_controller.rb +0 -4
  12. data/app/controllers/decidim/meetings/admin/invites_controller.rb +14 -5
  13. data/app/controllers/decidim/meetings/admin/registrations_controller.rb +20 -0
  14. data/app/controllers/decidim/meetings/registrations_controller.rb +16 -0
  15. data/app/events/decidim/meetings/registration_code_validated_event.rb +15 -0
  16. data/app/forms/decidim/meetings/admin/close_meeting_form.rb +1 -1
  17. data/app/forms/decidim/meetings/admin/meeting_registration_invite_form.rb +9 -2
  18. data/app/forms/decidim/meetings/admin/validate_registration_code_form.rb +33 -0
  19. data/app/mailers/decidim/meetings/registration_mailer.rb +2 -1
  20. data/app/models/decidim/meetings/invite.rb +38 -0
  21. data/app/models/decidim/meetings/meeting.rb +6 -0
  22. data/app/models/decidim/meetings/registration.rb +18 -0
  23. data/app/permissions/decidim/meetings/admin/permissions.rb +2 -2
  24. data/app/permissions/decidim/meetings/permissions.rb +8 -1
  25. data/app/presenters/decidim/meetings/admin_log/invite_presenter.rb +35 -0
  26. data/app/presenters/decidim/meetings/invite_presenter.rb +26 -0
  27. data/app/queries/decidim/meetings/admin/invites.rb +59 -0
  28. data/app/serializers/decidim/meetings/data_portability_invite_serializer.rb +35 -0
  29. data/app/serializers/decidim/meetings/data_portability_registration_serializer.rb +1 -0
  30. data/app/serializers/decidim/meetings/registration_serializer.rb +1 -0
  31. data/app/views/decidim/meetings/admin/invite_join_meeting_mailer/invite.html.erb +1 -0
  32. data/app/views/decidim/meetings/admin/invites/_form.html.erb +34 -5
  33. data/app/views/decidim/meetings/admin/invites/index.html.erb +99 -0
  34. data/app/views/decidim/meetings/admin/meeting_copies/new.html.erb +1 -1
  35. data/app/views/decidim/meetings/admin/meetings/_form.html.erb +2 -3
  36. data/app/views/decidim/meetings/admin/meetings/index.html.erb +2 -0
  37. data/app/views/decidim/meetings/admin/registrations/_form.html.erb +1 -1
  38. data/app/views/decidim/meetings/admin/registrations/edit.html.erb +24 -0
  39. data/app/views/decidim/meetings/meetings/_meetings.html.erb +1 -1
  40. data/app/views/decidim/meetings/meetings/index.js.erb +0 -1
  41. data/app/views/decidim/meetings/meetings/show.html.erb +9 -0
  42. data/app/views/decidim/meetings/registration_mailer/confirmation.html.erb +2 -0
  43. data/app/views/decidim/participatory_spaces/_meeting.html.erb +1 -1
  44. data/app/views/devise/mailer/join_meeting.html.erb +1 -0
  45. data/app/views/devise/mailer/join_meeting.text.erb +4 -0
  46. data/config/locales/ca.yml +53 -5
  47. data/config/locales/en.yml +53 -5
  48. data/config/locales/es-PY.yml +52 -4
  49. data/config/locales/es.yml +53 -5
  50. data/config/locales/eu.yml +52 -4
  51. data/config/locales/fi.yml +164 -116
  52. data/config/locales/fr.yml +53 -5
  53. data/config/locales/gl.yml +52 -4
  54. data/config/locales/hu.yml +391 -0
  55. data/config/locales/it.yml +52 -4
  56. data/config/locales/nl.yml +52 -4
  57. data/config/locales/pl.yml +52 -4
  58. data/config/locales/pt-BR.yml +56 -8
  59. data/config/locales/pt.yml +52 -4
  60. data/config/locales/ru.yml +57 -9
  61. data/config/locales/sv.yml +135 -87
  62. data/config/locales/uk.yml +56 -8
  63. data/db/migrate/20180607142020_create_decidim_meetings_invites.rb +15 -0
  64. data/db/migrate/20180615160839_add_code_to_decidim_meetings_registrations.rb +7 -0
  65. data/db/migrate/20180711111023_add_validated_at_to_decidim_meetings_registrations.rb +7 -0
  66. data/lib/decidim/meetings.rb +1 -0
  67. data/lib/decidim/meetings/admin_engine.rb +3 -1
  68. data/lib/decidim/meetings/component.rb +2 -0
  69. data/lib/decidim/meetings/engine.rb +1 -0
  70. data/lib/decidim/meetings/registrations.rb +14 -0
  71. data/lib/decidim/meetings/registrations/code_generator.rb +39 -0
  72. data/lib/decidim/meetings/test/factories.rb +20 -4
  73. data/lib/decidim/meetings/version.rb +1 -1
  74. metadata +30 -14
  75. data/app/views/decidim/meetings/admin/invites/new.html.erb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 335c7c37ff53d307c70692c3818be204327a00fa07eddd813a5c8c6595c6afb2
4
- data.tar.gz: 52848d0551a08d2b240c11bcbaaa519f9f46ec53f39eb63707c2e4445d8838fd
3
+ metadata.gz: 143339c8a41808d05f02ab73f1fdca0af63fc60ea551919cc9517a32f751bbaf
4
+ data.tar.gz: ff671495cc3183f10369a19ecf2f7a61579763ec38ba8c805be4ff4ce05f2cae
5
5
  SHA512:
6
- metadata.gz: 32caac25b60f8a284a41b80eb47b29b5e691871a73c13afc08862390a48de2589de5ff9881641d21d7d1d57dc333161bb7ea71f015a7eed63ad9969a3188c6b4
7
- data.tar.gz: a9b1a3e956e83d7d9e3c9a789e2dfd26239a835bb14371e3bb174c51051366b95f53a4d941bc8d684ac894af840118b914412992fafe723d8f0646fff441ac1f
6
+ metadata.gz: '028d85237ce58717b6f5323da6fb8c12aab1fa52e67564b34962f314b7cc3dc2a6fe0a91f5799ae9f847e27fedb0ff0de7e7caf3a1ccbfbfcceb0065e18e5652'
7
+ data.tar.gz: 509abcb9e65fa3e5eedb5808e3dca0a87f8a9d51607a157511fb258460dd1ea3b8d227b72db6a04ff7a2ed95d47fd78742d6de83a4f6471812ee8c9a87bd97cd
@@ -1,4 +1,5 @@
1
1
  //= link decidim/meetings/admin/meetings_form.js
2
2
  //= link decidim/meetings/admin/registrations_form.js
3
+ //= link decidim/meetings/admin/registrations_invite_form.js
3
4
  //= link decidim/meetings/admin/meetings_form.js
4
5
  //= link decidim/meetings/admin/agendas.js
@@ -0,0 +1,25 @@
1
+ ((exports) => {
2
+ const { createFieldDependentInputs } = exports.DecidimAdmin;
3
+
4
+ const $attendeeType = $('[name="meeting_registration_invite[existing_user]"');
5
+
6
+ createFieldDependentInputs({
7
+ controllerField: $attendeeType,
8
+ wrapperSelector: ".attendee-fields",
9
+ dependentFieldsSelector: ".attendee-fields--new-user",
10
+ dependentInputSelector: "input",
11
+ enablingCondition: () => {
12
+ return $("#meeting_registration_invite_existing_user_false").is(":checked")
13
+ }
14
+ });
15
+
16
+ createFieldDependentInputs({
17
+ controllerField: $attendeeType,
18
+ wrapperSelector: ".attendee-fields",
19
+ dependentFieldsSelector: ".attendee-fields--user-picker",
20
+ dependentInputSelector: "input",
21
+ enablingCondition: () => {
22
+ return $("#meeting_registration_invite_existing_user_true").is(":checked")
23
+ }
24
+ });
25
+ })(window);
@@ -3,6 +3,7 @@
3
3
  <%= action_authorized_button_to(
4
4
  :join,
5
5
  meeting_registration_path(model),
6
+ resource: model,
6
7
  method: :delete,
7
8
  class: "#{button_classes} secondary light",
8
9
  data: { disable: true }
@@ -16,6 +17,7 @@
16
17
  :join,
17
18
  i18n_join_text,
18
19
  "",
20
+ resource: model,
19
21
  class: button_classes,
20
22
  disabled: !model.has_available_slots?,
21
23
  data: { open: current_user.present? ? "meeting-registration-confirm-#{model.id}" : "loginModal" }
@@ -10,7 +10,7 @@ module Decidim
10
10
  include Cell::ViewModel::Partial
11
11
 
12
12
  def show
13
- cell card_size, model
13
+ cell card_size, model, options
14
14
  end
15
15
 
16
16
  private
@@ -24,7 +24,7 @@ module Decidim
24
24
  #
25
25
  # Returns nothing.
26
26
  def call
27
- return broadcast(:invalid) if form.invalid?
27
+ return broadcast(:invalid) if form.invalid? || already_invited?
28
28
 
29
29
  invite_user
30
30
 
@@ -35,22 +35,71 @@ module Decidim
35
35
 
36
36
  attr_reader :form, :invited_by, :meeting
37
37
 
38
+ def already_invited?
39
+ return false unless user.persisted?
40
+ return false unless meeting.invites.where(user: user).exists?
41
+
42
+ form.errors.add(:email, :already_invited)
43
+ true
44
+ end
45
+
46
+ def create_invitation!
47
+ log_info = {
48
+ resource: {
49
+ title: meeting.title
50
+ },
51
+ participatory_space: {
52
+ title: meeting.participatory_space.title
53
+ }
54
+ }
55
+
56
+ @invite = Decidim.traceability.create!(
57
+ Invite,
58
+ invited_by,
59
+ {
60
+ user: user,
61
+ meeting: meeting,
62
+ sent_at: Time.current
63
+ },
64
+ log_info
65
+ )
66
+ end
67
+
38
68
  def invite_user
39
69
  if user.persisted?
40
- InviteJoinMeetingMailer.invite(user, meeting, invited_by).deliver_later
70
+ create_invitation!
71
+
72
+ # The user has already been invited to sign up to another
73
+ # meeting or resource and has not yet accepted the invitation
74
+ if user.invited_to_sign_up?
75
+ invite_user_to_sign_up
76
+ else
77
+ InviteJoinMeetingMailer.invite(user, meeting, invited_by).deliver_later
78
+ end
41
79
  else
42
80
  user.name = form.name
43
81
  user.nickname = User.nicknamize(user.name, organization: user.organization)
44
- user.skip_reconfirmation!
45
- user.invite!(invited_by, invitation_instructions: "join_meeting", meeting: meeting)
82
+ invite_user_to_sign_up
83
+ create_invitation!
46
84
  end
47
85
  end
48
86
 
49
87
  def user
50
- @user ||= Decidim::User.find_or_initialize_by(
51
- organization: form.current_organization,
52
- email: form.email.downcase
53
- )
88
+ @user ||= begin
89
+ if form.existing_user
90
+ form.user
91
+ else
92
+ Decidim::User.find_or_initialize_by(
93
+ organization: form.current_organization,
94
+ email: form.email.downcase
95
+ )
96
+ end
97
+ end
98
+ end
99
+
100
+ def invite_user_to_sign_up
101
+ user.skip_reconfirmation!
102
+ user.invite!(invited_by, invitation_instructions: "join_meeting", meeting: meeting)
54
103
  end
55
104
  end
56
105
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ module Admin
6
+ # This command is executed when the admin validates a registration code in the admin panel.
7
+ class ValidateRegistrationCode < Rectify::Command
8
+ # Initializes a ValidateRegistrationCode Command.
9
+ #
10
+ # form - The form from which to get the data.
11
+ # meeting - The current instance of the meeting to be updated.
12
+ def initialize(form, meeting)
13
+ @form = form
14
+ @meeting = meeting
15
+ end
16
+
17
+ # Validates the registration code the meeting if valid.
18
+ #
19
+ # Broadcasts :ok if successful, :invalid otherwise.
20
+ def call
21
+ return broadcast(:invalid) if form.invalid?
22
+
23
+ validate_registration_code
24
+ send_notification
25
+
26
+ broadcast(:ok)
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :form, :meeting
32
+
33
+ def validate_registration_code
34
+ form.registration.update!(validated_at: Time.current)
35
+ end
36
+
37
+ def send_notification
38
+ Decidim::EventsManager.publish(
39
+ event: "decidim.events.meetings.registration_code_validated",
40
+ event_class: Decidim::Meetings::RegistrationCodeValidatedEvent,
41
+ resource: meeting,
42
+ recipient_ids: [form.registration.user.id],
43
+ extra: {
44
+ registration: form.registration
45
+ }
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ # This command is executed when the user declines an invite to the meeting.
6
+ class DeclineInvitation < Rectify::Command
7
+ # Initializes a DeclineInvitation Command.
8
+ #
9
+ # meeting - The current instance of the meeting where user has been invited.
10
+ # user - The user that declines their invitation
11
+ def initialize(meeting, user)
12
+ @meeting = meeting
13
+ @user = user
14
+ end
15
+
16
+ # Creates a meeting registration if the meeting has registrations enabled
17
+ # and there are available slots.
18
+ #
19
+ # Broadcasts :ok if successful, :invalid otherwise.
20
+ def call
21
+ return broadcast(:invalid) unless can_decline_invitation?
22
+
23
+ decline_invitation
24
+
25
+ broadcast(:ok)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :meeting, :user
31
+
32
+ def decline_invitation
33
+ invitation.decline!
34
+ end
35
+
36
+ def can_decline_invitation?
37
+ meeting.registrations_enabled? && invitation.present?
38
+ end
39
+
40
+ def invitation
41
+ @invitation ||= meeting.invites.find_by(user: user)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -21,6 +21,7 @@ module Decidim
21
21
  meeting.with_lock do
22
22
  return broadcast(:invalid) unless can_join_meeting?
23
23
  create_registration
24
+ accept_invitation
24
25
  send_email_confirmation
25
26
  send_notification
26
27
  end
@@ -29,10 +30,14 @@ module Decidim
29
30
 
30
31
  private
31
32
 
32
- attr_reader :meeting, :user
33
+ attr_reader :meeting, :user, :registration
34
+
35
+ def accept_invitation
36
+ meeting.invites.find_by(user: user)&.accept!
37
+ end
33
38
 
34
39
  def create_registration
35
- Decidim::Meetings::Registration.create!(meeting: meeting, user: user)
40
+ @registration = Decidim::Meetings::Registration.create!(meeting: meeting, user: user)
36
41
  end
37
42
 
38
43
  def can_join_meeting?
@@ -40,7 +45,7 @@ module Decidim
40
45
  end
41
46
 
42
47
  def send_email_confirmation
43
- Decidim::Meetings::RegistrationMailer.confirmation(user, meeting).deliver_later
48
+ Decidim::Meetings::RegistrationMailer.confirmation(user, meeting, registration).deliver_later
44
49
  end
45
50
 
46
51
  def participatory_space_admins
@@ -19,10 +19,6 @@ module Decidim
19
19
  def meeting
20
20
  @meeting ||= meetings.find(params[:meeting_id])
21
21
  end
22
-
23
- def authorization_object
24
- meeting.component
25
- end
26
22
  end
27
23
  end
28
24
  end
@@ -20,10 +20,6 @@ module Decidim
20
20
  def meeting
21
21
  @meeting ||= meetings.find(params[:meeting_id])
22
22
  end
23
-
24
- def authorization_object
25
- meeting.component
26
- end
27
23
  end
28
24
  end
29
25
  end
@@ -8,26 +8,31 @@ module Decidim
8
8
  # Controller that allows inviting users to join a meeting.
9
9
  #
10
10
  class InvitesController < Admin::ApplicationController
11
- def new
12
- enforce_permission_to :invite_user, :meeting, meeting: meeting
11
+ helper_method :invites
12
+
13
+ def index
14
+ enforce_permission_to :read_invites, :meeting, meeting: meeting
15
+
16
+ @query = params[:q]
17
+ @status = params[:status]
13
18
 
14
19
  @form = form(MeetingRegistrationInviteForm).instance
15
20
  end
16
21
 
17
22
  def create
18
- enforce_permission_to :invite_user, :meeting, meeting: meeting
23
+ enforce_permission_to :invite_attendee, :meeting, meeting: meeting
19
24
 
20
25
  @form = form(MeetingRegistrationInviteForm).from_params(params)
21
26
 
22
27
  InviteUserToJoinMeeting.call(@form, meeting, current_user) do
23
28
  on(:ok) do
24
29
  flash[:notice] = I18n.t("invites.create.success", scope: "decidim.meetings.admin")
25
- redirect_to edit_meeting_registrations_path(meeting)
30
+ redirect_to meeting_registrations_invites_path(meeting)
26
31
  end
27
32
 
28
33
  on(:invalid) do
29
34
  flash.now[:alert] = I18n.t("invites.create.error", scope: "decidim.meetings.admin")
30
- render :new
35
+ render :index
31
36
  end
32
37
  end
33
38
  end
@@ -37,6 +42,10 @@ module Decidim
37
42
  def meeting
38
43
  @meeting ||= Meeting.where(component: current_component).find(params[:meeting_id])
39
44
  end
45
+
46
+ def invites
47
+ @invites ||= Decidim::Meetings::Admin::Invites.for(meeting.invites, @query, @status).page(params[:page]).per(15)
48
+ end
40
49
  end
41
50
  end
42
51
  end
@@ -9,6 +9,7 @@ module Decidim
9
9
  enforce_permission_to :update, :meeting, meeting: meeting
10
10
 
11
11
  @form = MeetingRegistrationsForm.from_model(meeting)
12
+ @validation_form = ValidateRegistrationCodeForm.new
12
13
  end
13
14
 
14
15
  def update
@@ -39,6 +40,25 @@ module Decidim
39
40
  end
40
41
  end
41
42
 
43
+ def validate_registration_code
44
+ enforce_permission_to :update, :meeting, meeting: meeting
45
+
46
+ @form = MeetingRegistrationsForm.from_model(meeting)
47
+ @validation_form = ValidateRegistrationCodeForm.from_params(params).with_context(current_organization: meeting.organization, meeting: meeting)
48
+
49
+ ValidateRegistrationCode.call(@validation_form, meeting) do
50
+ on(:ok) do
51
+ flash[:notice] = I18n.t("registrations.validate_registration_code.success", scope: "decidim.meetings.admin")
52
+ render action: "edit"
53
+ end
54
+
55
+ on(:invalid) do
56
+ flash.now[:alert] = I18n.t("registrations.validate_registration_code.invalid", scope: "decidim.meetings.admin")
57
+ render action: "edit"
58
+ end
59
+ end
60
+ end
61
+
42
62
  private
43
63
 
44
64
  def meeting
@@ -36,6 +36,22 @@ module Decidim
36
36
  end
37
37
  end
38
38
 
39
+ def decline_invitation
40
+ enforce_permission_to :decline_invitation, :meeting, meeting: meeting
41
+
42
+ DeclineInvitation.call(meeting, current_user) do
43
+ on(:ok) do
44
+ flash[:notice] = I18n.t("registrations.decline_invitation.success", scope: "decidim.meetings")
45
+ redirect_after_path
46
+ end
47
+
48
+ on(:invalid) do
49
+ flash.now[:alert] = I18n.t("registrations.decline_invitation.invalid", scope: "decidim.meetings")
50
+ redirect_after_path
51
+ end
52
+ end
53
+ end
54
+
39
55
  private
40
56
 
41
57
  def meeting
@@ -0,0 +1,15 @@
1
+ # frozen-string_literal: true
2
+
3
+ module Decidim
4
+ module Meetings
5
+ class RegistrationCodeValidatedEvent < Decidim::Events::SimpleEvent
6
+ i18n_attributes :registration_code
7
+
8
+ private
9
+
10
+ def registration_code
11
+ extra["registration"]["code"]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -13,7 +13,7 @@ module Decidim
13
13
  attribute :attending_organizations, String
14
14
  attribute :proposal_ids, Array[Integer]
15
15
  attribute :proposals
16
- attribute :closed_at, DateTime, default: ->(_form, _attribute) { Time.current }
16
+ attribute :closed_at, Decidim::Attributes::TimeWithZone, default: ->(_form, _attribute) { Time.current }
17
17
 
18
18
  validates :closing_report, translatable_presence: true
19
19
  validates :attendees_count, presence: true, numericality: { greater_than_or_equal_to: 0 }