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.
- checksums.yaml +4 -4
- data/app/assets/config/admin/decidim_meetings_manifest.js +1 -0
- data/app/assets/javascripts/decidim/meetings/admin/registrations_invite_form.es6 +25 -0
- data/app/cells/decidim/meetings/join_meeting_button/show.erb +2 -0
- data/app/cells/decidim/meetings/meeting_cell.rb +1 -1
- data/app/commands/decidim/meetings/admin/invite_user_to_join_meeting.rb +57 -8
- data/app/commands/decidim/meetings/admin/validate_registration_code.rb +51 -0
- data/app/commands/decidim/meetings/decline_invitation.rb +45 -0
- data/app/commands/decidim/meetings/join_meeting.rb +8 -3
- data/app/controllers/decidim/meetings/admin/attachment_collections_controller.rb +0 -4
- data/app/controllers/decidim/meetings/admin/attachments_controller.rb +0 -4
- data/app/controllers/decidim/meetings/admin/invites_controller.rb +14 -5
- data/app/controllers/decidim/meetings/admin/registrations_controller.rb +20 -0
- data/app/controllers/decidim/meetings/registrations_controller.rb +16 -0
- data/app/events/decidim/meetings/registration_code_validated_event.rb +15 -0
- data/app/forms/decidim/meetings/admin/close_meeting_form.rb +1 -1
- data/app/forms/decidim/meetings/admin/meeting_registration_invite_form.rb +9 -2
- data/app/forms/decidim/meetings/admin/validate_registration_code_form.rb +33 -0
- data/app/mailers/decidim/meetings/registration_mailer.rb +2 -1
- data/app/models/decidim/meetings/invite.rb +38 -0
- data/app/models/decidim/meetings/meeting.rb +6 -0
- data/app/models/decidim/meetings/registration.rb +18 -0
- data/app/permissions/decidim/meetings/admin/permissions.rb +2 -2
- data/app/permissions/decidim/meetings/permissions.rb +8 -1
- data/app/presenters/decidim/meetings/admin_log/invite_presenter.rb +35 -0
- data/app/presenters/decidim/meetings/invite_presenter.rb +26 -0
- data/app/queries/decidim/meetings/admin/invites.rb +59 -0
- data/app/serializers/decidim/meetings/data_portability_invite_serializer.rb +35 -0
- data/app/serializers/decidim/meetings/data_portability_registration_serializer.rb +1 -0
- data/app/serializers/decidim/meetings/registration_serializer.rb +1 -0
- data/app/views/decidim/meetings/admin/invite_join_meeting_mailer/invite.html.erb +1 -0
- data/app/views/decidim/meetings/admin/invites/_form.html.erb +34 -5
- data/app/views/decidim/meetings/admin/invites/index.html.erb +99 -0
- data/app/views/decidim/meetings/admin/meeting_copies/new.html.erb +1 -1
- data/app/views/decidim/meetings/admin/meetings/_form.html.erb +2 -3
- data/app/views/decidim/meetings/admin/meetings/index.html.erb +2 -0
- data/app/views/decidim/meetings/admin/registrations/_form.html.erb +1 -1
- data/app/views/decidim/meetings/admin/registrations/edit.html.erb +24 -0
- data/app/views/decidim/meetings/meetings/_meetings.html.erb +1 -1
- data/app/views/decidim/meetings/meetings/index.js.erb +0 -1
- data/app/views/decidim/meetings/meetings/show.html.erb +9 -0
- data/app/views/decidim/meetings/registration_mailer/confirmation.html.erb +2 -0
- data/app/views/decidim/participatory_spaces/_meeting.html.erb +1 -1
- data/app/views/devise/mailer/join_meeting.html.erb +1 -0
- data/app/views/devise/mailer/join_meeting.text.erb +4 -0
- data/config/locales/ca.yml +53 -5
- data/config/locales/en.yml +53 -5
- data/config/locales/es-PY.yml +52 -4
- data/config/locales/es.yml +53 -5
- data/config/locales/eu.yml +52 -4
- data/config/locales/fi.yml +164 -116
- data/config/locales/fr.yml +53 -5
- data/config/locales/gl.yml +52 -4
- data/config/locales/hu.yml +391 -0
- data/config/locales/it.yml +52 -4
- data/config/locales/nl.yml +52 -4
- data/config/locales/pl.yml +52 -4
- data/config/locales/pt-BR.yml +56 -8
- data/config/locales/pt.yml +52 -4
- data/config/locales/ru.yml +57 -9
- data/config/locales/sv.yml +135 -87
- data/config/locales/uk.yml +56 -8
- data/db/migrate/20180607142020_create_decidim_meetings_invites.rb +15 -0
- data/db/migrate/20180615160839_add_code_to_decidim_meetings_registrations.rb +7 -0
- data/db/migrate/20180711111023_add_validated_at_to_decidim_meetings_registrations.rb +7 -0
- data/lib/decidim/meetings.rb +1 -0
- data/lib/decidim/meetings/admin_engine.rb +3 -1
- data/lib/decidim/meetings/component.rb +2 -0
- data/lib/decidim/meetings/engine.rb +1 -0
- data/lib/decidim/meetings/registrations.rb +14 -0
- data/lib/decidim/meetings/registrations/code_generator.rb +39 -0
- data/lib/decidim/meetings/test/factories.rb +20 -4
- data/lib/decidim/meetings/version.rb +1 -1
- metadata +30 -14
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 143339c8a41808d05f02ab73f1fdca0af63fc60ea551919cc9517a32f751bbaf
|
4
|
+
data.tar.gz: ff671495cc3183f10369a19ecf2f7a61579763ec38ba8c805be4ff4ce05f2cae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '028d85237ce58717b6f5323da6fb8c12aab1fa52e67564b34962f314b7cc3dc2a6fe0a91f5799ae9f847e27fedb0ff0de7e7caf3a1ccbfbfcceb0065e18e5652'
|
7
|
+
data.tar.gz: 509abcb9e65fa3e5eedb5808e3dca0a87f8a9d51607a157511fb258460dd1ea3b8d227b72db6a04ff7a2ed95d47fd78742d6de83a4f6471812ee8c9a87bd97cd
|
@@ -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" }
|
@@ -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
|
-
|
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
|
-
|
45
|
-
|
82
|
+
invite_user_to_sign_up
|
83
|
+
create_invitation!
|
46
84
|
end
|
47
85
|
end
|
48
86
|
|
49
87
|
def user
|
50
|
-
@user ||=
|
51
|
-
|
52
|
-
|
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
|
@@ -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
|
-
|
12
|
-
|
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 :
|
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
|
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 :
|
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,
|
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 }
|