decidim-conferences 0.23.3 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/conferences/conference_speaker/show.erb +1 -1
  3. data/app/cells/decidim/conferences/media_link/show.erb +1 -1
  4. data/app/cells/decidim/conferences/media_link_cell.rb +1 -0
  5. data/app/commands/decidim/conferences/admin/create_conference_speaker.rb +40 -18
  6. data/app/commands/decidim/conferences/admin/create_partner.rb +33 -14
  7. data/app/commands/decidim/conferences/admin/invite_user_to_join_conference.rb +1 -1
  8. data/app/commands/decidim/conferences/admin/update_conference_speaker.rb +41 -17
  9. data/app/commands/decidim/conferences/admin/update_partner.rb +30 -10
  10. data/app/controllers/decidim/conferences/admin/imports_controller.rb +14 -0
  11. data/app/controllers/decidim/conferences/admin/moderations/reports_controller.rb +14 -0
  12. data/app/events/decidim/conferences/conference_role_assigned_event.rb +1 -1
  13. data/app/forms/decidim/conferences/admin/conference_form.rb +3 -2
  14. data/app/forms/decidim/conferences/admin/conference_speaker_form.rb +1 -1
  15. data/app/forms/decidim/conferences/admin/media_link_form.rb +1 -1
  16. data/app/forms/decidim/conferences/admin/partner_form.rb +2 -1
  17. data/app/models/decidim/conference_meeting.rb +1 -1
  18. data/app/models/decidim/conference_speaker.rb +1 -1
  19. data/app/models/decidim/conference_speaker_conference_meeting.rb +2 -2
  20. data/app/models/decidim/conferences/conference_meeting_registration_type.rb +2 -2
  21. data/app/models/decidim/conferences/registration_type.rb +1 -1
  22. data/app/permissions/decidim/conferences/permissions.rb +1 -1
  23. data/app/presenters/decidim/conferences/conference_stats_presenter.rb +1 -1
  24. data/app/views/decidim/conferences/admin/conference_invites/index.html.erb +1 -1
  25. data/app/views/decidim/conferences/admin/conference_registrations/index.html.erb +1 -1
  26. data/app/views/decidim/conferences/admin/partners/_form.html.erb +1 -1
  27. data/app/views/layouts/decidim/admin/conference.html.erb +2 -1
  28. data/config/locales/ar.yml +6 -4
  29. data/config/locales/ca.yml +50 -3
  30. data/config/locales/cs.yml +51 -4
  31. data/config/locales/de.yml +16 -3
  32. data/config/locales/el.yml +6 -4
  33. data/config/locales/en.yml +50 -3
  34. data/config/locales/es-MX.yml +16 -3
  35. data/config/locales/es-PY.yml +16 -3
  36. data/config/locales/es.yml +17 -4
  37. data/config/locales/eu.yml +6 -4
  38. data/config/locales/fi-plain.yml +51 -4
  39. data/config/locales/fi.yml +51 -4
  40. data/config/locales/fr-CA.yml +16 -3
  41. data/config/locales/fr.yml +16 -3
  42. data/config/locales/gl.yml +35 -4
  43. data/config/locales/hu.yml +6 -4
  44. data/config/locales/id-ID.yml +6 -4
  45. data/config/locales/it.yml +7 -5
  46. data/config/locales/ja.yml +12 -4
  47. data/config/locales/lv.yml +6 -4
  48. data/config/locales/nl.yml +176 -129
  49. data/config/locales/no.yml +6 -4
  50. data/config/locales/pl.yml +20 -7
  51. data/config/locales/pt-BR.yml +6 -4
  52. data/config/locales/pt.yml +6 -4
  53. data/config/locales/ro-RO.yml +66 -3
  54. data/config/locales/sk.yml +6 -4
  55. data/config/locales/sv.yml +50 -3
  56. data/config/locales/tr-TR.yml +13 -4
  57. data/config/locales/zh-CN.yml +6 -4
  58. data/db/migrate/20210310134942_add_followable_counter_cache_to_conferences.rb +16 -0
  59. data/lib/decidim/api/conference_media_link_type.rb +18 -0
  60. data/lib/decidim/api/conference_partner_type.rb +19 -0
  61. data/lib/decidim/api/conference_speaker_type.rb +23 -0
  62. data/lib/decidim/api/conference_type.rb +42 -0
  63. data/lib/decidim/conferences.rb +1 -0
  64. data/lib/decidim/conferences/admin_engine.rb +3 -1
  65. data/lib/decidim/conferences/api.rb +10 -0
  66. data/lib/decidim/conferences/engine.rb +7 -1
  67. data/lib/decidim/conferences/participatory_space.rb +25 -25
  68. data/lib/decidim/conferences/query_extensions.rb +43 -0
  69. data/lib/decidim/conferences/test/factories.rb +6 -6
  70. data/lib/decidim/conferences/version.rb +1 -1
  71. metadata +21 -16
  72. data/app/types/decidim/conferences/conference_media_link_type.rb +0 -19
  73. data/app/types/decidim/conferences/conference_partner_type.rb +0 -20
  74. data/app/types/decidim/conferences/conference_speaker_type.rb +0 -24
  75. data/app/types/decidim/conferences/conference_type.rb +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76e05e50396ac0d639819e9355e1dd1c08519aabeed44643ae6b20f116e1539e
4
- data.tar.gz: 052d02f80f30d28808ce7b9c3b3017f418ffb49b5d969deec9c75becc93a0bbe
3
+ metadata.gz: c4c1c21bb65f6cf0dc134a4ddd55aecec244edd7f20d962524a7c52b71b0b39e
4
+ data.tar.gz: 59fd333279eb8c43a37a67683b127230aed6e6124aea4c7798194e7435f8e9b9
5
5
  SHA512:
6
- metadata.gz: f98072cd1897a9e4c5e824665c0d39fe7745ec41a88bf85239babd0510d4f51da2e416170ef9b3930941c03d827d53cf7a91a90428b3cff11b480ca74f9bdd5d
7
- data.tar.gz: a1868c81d78d0407e67a0ca4fabaf60cc2102f50490b63cb3945f77d3e69f1a8ea552071cd827a093e253fe43e406d81c18de7167f67679892241eb1a0f55a44
6
+ metadata.gz: 6a9efa55c1626f4951a69122e3e877210d4bc475fe080b77f7cae6cdb7ecdbe54be8f5136d3d40cc0909b0252bfffe3382f78f8e131e4cffc013036ad8285e87
7
+ data.tar.gz: c4e939496320108ae90d1927f6a225beb14c3349824c4c20225d457c9895f10aa4e5be090bf5e6511b2995f7aec7f23c4694d493fde27ebf1613c1b003531200
@@ -70,7 +70,7 @@
70
70
  <hr class="reset mt-none mb-s">
71
71
  <div class="row">
72
72
  <div class="column medium-12">
73
- <div class="bio-acts">Speaking at</div>
73
+ <div class="bio-acts"><%= t("conferences.conference_speaker.show.speaking_at", scope: "decidim") %></div>
74
74
 
75
75
  <ul class="list-reset">
76
76
  <% meetings.each do |meeting| %>
@@ -2,7 +2,7 @@
2
2
  <%= icon "external-link", role: "img", "aria-hidden": true %>
3
3
  <div>
4
4
  <%= link_to model.link, target: "_blank" do %>
5
- <strong><%= translated_attribute(model.title) %> </strong>
5
+ <strong><%= decidim_html_escape translated_attribute(model.title) %> </strong>
6
6
  <% end %>
7
7
  <div class="text-small"><%= l(model.date, format: :decidim_short_with_month_name_short) %> · <%= model.link %></div>
8
8
  </div>
@@ -5,6 +5,7 @@ module Decidim
5
5
  # This cell renders the media link card for an instance of a MediaLink
6
6
  class MediaLinkCell < Decidim::ViewModel
7
7
  include Decidim::LayoutHelper
8
+ include Decidim::SanitizeHelper
8
9
 
9
10
  def show
10
11
  render
@@ -25,18 +25,52 @@ module Decidim
25
25
  def call
26
26
  return broadcast(:invalid) if form.invalid?
27
27
 
28
- transaction do
29
- create_conference_speaker!
30
- link_meetings(@conference_speaker)
31
- end
28
+ # We are going to assign the attributes only to handle the validation of the avatar before accessing
29
+ # `create_conference_speaker!` which uses `create!`, and this will render an ActiveRecord::RecordInvalid error
30
+ # After we assign and check if the object is valid, we will not save the model to let it be handled the old way
31
+ # If there is an error we add the error to the form
32
+ # We are using this method to assign the conference because if we are trying to assign all at once, there will be thrown a
33
+ # Delegation error
34
+
35
+ if conference_speaker_with_attributes.valid?
32
36
 
33
- broadcast(:ok)
37
+ transaction do
38
+ create_conference_speaker!
39
+ link_meetings(@conference_speaker)
40
+ end
41
+ broadcast(:ok)
42
+ else
43
+ form.errors.add(:avatar, conference_speaker_with_attributes.errors[:avatar]) if conference_speaker_with_attributes.errors.include? :avatar
44
+
45
+ broadcast(:invalid)
46
+ end
34
47
  end
35
48
 
36
49
  private
37
50
 
38
51
  attr_reader :form, :conference, :current_user
39
52
 
53
+ def conference_speaker_with_attributes
54
+ attrs = form.attributes.slice(
55
+ :full_name,
56
+ :twitter_handle,
57
+ :personal_url,
58
+ :avatar,
59
+ :remove_avatar,
60
+ :position,
61
+ :affiliation,
62
+ :short_bio
63
+ ).merge(
64
+ decidim_conference_id: conference.id,
65
+ conference: conference,
66
+ user: form.user
67
+ )
68
+ conference_speaker = conference.speakers.build
69
+ conference_speaker.conference = conference
70
+ conference_speaker.assign_attributes(attrs)
71
+ conference_speaker
72
+ end
73
+
40
74
  def create_conference_speaker!
41
75
  log_info = {
42
76
  resource: {
@@ -50,19 +84,7 @@ module Decidim
50
84
  @conference_speaker = Decidim.traceability.create!(
51
85
  Decidim::ConferenceSpeaker,
52
86
  current_user,
53
- form.attributes.slice(
54
- :full_name,
55
- :position,
56
- :affiliation,
57
- :short_bio,
58
- :twitter_handle,
59
- :personal_url,
60
- :avatar,
61
- :remove_avatar
62
- ).merge(
63
- conference: conference,
64
- user: form.user
65
- ),
87
+ conference_speaker_with_attributes.attributes,
66
88
  log_info
67
89
  )
68
90
  end
@@ -25,11 +25,17 @@ module Decidim
25
25
  def call
26
26
  return broadcast(:invalid) if form.invalid?
27
27
 
28
- transaction do
29
- create_partner!
30
- end
28
+ if conference_partner.valid?
29
+ transaction do
30
+ create_partner!
31
+ end
32
+
33
+ broadcast(:ok)
34
+ else
35
+ form.errors.add(:logo, conference_partner.errors[:logo]) if conference_partner.errors.include? :logo
31
36
 
32
- broadcast(:ok)
37
+ broadcast(:invalid)
38
+ end
33
39
  end
34
40
 
35
41
  private
@@ -49,19 +55,32 @@ module Decidim
49
55
  @partner = Decidim.traceability.create!(
50
56
  Decidim::Conferences::Partner,
51
57
  form.current_user,
52
- { conference: conference }.merge(
53
- form.attributes.slice(
54
- :name,
55
- :weight,
56
- :link,
57
- :partner_type,
58
- :logo,
59
- :remove_avatar
60
- )
61
- ),
58
+ attributes,
62
59
  log_info
63
60
  )
64
61
  end
62
+
63
+ def conference_partner
64
+ return @conference_partner if defined?(@conference_partner)
65
+
66
+ @conference_partner = conference.partners.build
67
+ @conference_partner.conference = conference
68
+ @conference_partner.assign_attributes(attributes)
69
+ @conference_partner
70
+ end
71
+
72
+ def attributes
73
+ { conference: conference }.merge(
74
+ form.attributes.slice(
75
+ :name,
76
+ :weight,
77
+ :link,
78
+ :partner_type,
79
+ :logo,
80
+ :remove_avatar
81
+ )
82
+ )
83
+ end
65
84
  end
66
85
  end
67
86
  end
@@ -37,7 +37,7 @@ module Decidim
37
37
 
38
38
  def already_invited?
39
39
  return false unless user.persisted?
40
- return false unless conference.conference_invites.where(user: user).exists?
40
+ return false unless conference.conference_invites.exists?(user: user)
41
41
 
42
42
  form.errors.add(:email, :already_invited)
43
43
  true
@@ -11,6 +11,7 @@ module Decidim
11
11
  # form - A form object with the params.
12
12
  # conference_speaker - The ConferenceSpeaker to update
13
13
  def initialize(form, conference_speaker)
14
+ form.avatar = conference_speaker.avatar if form.avatar.blank?
14
15
  @form = form
15
16
  @conference_speaker = conference_speaker
16
17
  end
@@ -25,18 +26,52 @@ module Decidim
25
26
  return broadcast(:invalid) if form.invalid?
26
27
  return broadcast(:invalid) unless conference_speaker
27
28
 
28
- transaction do
29
- update_conference_speaker!
30
- link_meetings(@conference_speaker)
31
- end
29
+ # We are going to assign the attributes only to handle the validation of the avatar before accessing
30
+ # `update_conference_speaker!` which uses `update!`. Without this step, the image validation may render
31
+ # an ActiveRecord::RecordInvalid error
32
+ # After we assign and check if the object is valid, we reload the model to let it be handled the old way
33
+ # If there is an error we add the error to the form
34
+ conference_speaker.assign_attributes(attributes)
35
+
36
+ if conference_speaker.valid?
37
+ conference_speaker.reload
32
38
 
33
- broadcast(:ok)
39
+ transaction do
40
+ update_conference_speaker!
41
+ link_meetings(@conference_speaker)
42
+ end
43
+ broadcast(:ok)
44
+ else
45
+ form.errors.add(:avatar, conference_speaker.errors[:avatar]) if conference_speaker.errors.include? :avatar
46
+
47
+ broadcast(:invalid)
48
+ end
34
49
  end
35
50
 
36
51
  private
37
52
 
38
53
  attr_reader :form, :conference_speaker
39
54
 
55
+ def attributes
56
+ form.attributes.slice(
57
+ :full_name,
58
+ :twitter_handle,
59
+ :personal_url,
60
+ :position,
61
+ :affiliation,
62
+ :short_bio
63
+ ).merge(
64
+ user: form.user
65
+ ).merge(uploader_attributes)
66
+ end
67
+
68
+ def uploader_attributes
69
+ {
70
+ avatar: form.avatar,
71
+ remove_avatar: form.remove_avatar
72
+ }.delete_if { |_k, val| val.is_a?(Decidim::ApplicationUploader) }
73
+ end
74
+
40
75
  def update_conference_speaker!
41
76
  log_info = {
42
77
  resource: {
@@ -50,18 +85,7 @@ module Decidim
50
85
  Decidim.traceability.update!(
51
86
  conference_speaker,
52
87
  form.current_user,
53
- form.attributes.slice(
54
- :full_name,
55
- :position,
56
- :affiliation,
57
- :short_bio,
58
- :twitter_handle,
59
- :personal_url,
60
- :avatar,
61
- :remove_avatar
62
- ).merge(
63
- user: form.user
64
- ),
88
+ attributes,
65
89
  log_info
66
90
  )
67
91
  end
@@ -11,6 +11,8 @@ module Decidim
11
11
  # form - A form object with the params.
12
12
  # conference_partner - The ConferencePartner to update
13
13
  def initialize(form, conference_partner)
14
+ form.logo = conference_partner.logo if form.logo.blank?
15
+
14
16
  @form = form
15
17
  @conference_partner = conference_partner
16
18
  end
@@ -25,14 +27,39 @@ module Decidim
25
27
  return broadcast(:invalid) if form.invalid?
26
28
  return broadcast(:invalid) unless conference_partner
27
29
 
28
- update_conference_partner!
29
- broadcast(:ok)
30
+ # We are going to assign the attributes only to handle the validation of the avatar before accessing
31
+ # `update_conference_partner!` which uses `update!`. Without this step, the image validation may render
32
+ # an ActiveRecord::RecordInvalid error
33
+ # After we assign and check if the object is valid, we reload the model to let it be handled the old way
34
+ # If there is an error we add the error to the form
35
+ conference_partner.assign_attributes(attributes)
36
+ if conference_partner.valid?
37
+ conference_partner.reload
38
+
39
+ update_conference_partner!
40
+ broadcast(:ok)
41
+ else
42
+ form.errors.add(:logo, conference_partner.errors[:logo]) if conference_partner.errors.include? :logo
43
+
44
+ broadcast(:invalid)
45
+ end
30
46
  end
31
47
 
32
48
  private
33
49
 
34
50
  attr_reader :form, :conference_partner
35
51
 
52
+ def attributes
53
+ form.attributes.slice(
54
+ :name,
55
+ :weight,
56
+ :partner_type,
57
+ :link,
58
+ :logo,
59
+ :remove_logo
60
+ )
61
+ end
62
+
36
63
  def update_conference_partner!
37
64
  log_info = {
38
65
  resource: {
@@ -46,14 +73,7 @@ module Decidim
46
73
  Decidim.traceability.update!(
47
74
  conference_partner,
48
75
  form.current_user,
49
- form.attributes.slice(
50
- :name,
51
- :weight,
52
- :partner_type,
53
- :link,
54
- :logo,
55
- :remove_logo
56
- ),
76
+ attributes,
57
77
  log_info
58
78
  )
59
79
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Conferences
5
+ module Admin
6
+ # This controller allows importing things.
7
+ # It is targeted for customizations for importing things that lives under
8
+ # an conference.
9
+ class ImportsController < Decidim::Admin::ImportsController
10
+ include Concerns::ConferenceAdmin
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Conferences
5
+ module Admin
6
+ module Moderations
7
+ # This controller allows admins to manage moderation reports in an conference.
8
+ class ReportsController < Decidim::Admin::Moderations::ReportsController
9
+ include Concerns::ConferenceAdmin
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -11,7 +11,7 @@ module Decidim
11
11
  end
12
12
 
13
13
  def i18n_role
14
- I18n.t(extra["role"], "decidim.admin.models.conference_user_role.roles", default: extra["role"])
14
+ I18n.t(extra["role"], scope: "decidim.admin.models.conference_user_role.roles", default: extra["role"])
15
15
  end
16
16
 
17
17
  def i18n_options
@@ -43,12 +43,13 @@ module Decidim
43
43
 
44
44
  validate :slug_uniqueness
45
45
 
46
+ validates :available_slots, presence: true, if: ->(form) { form.registrations_enabled? }
47
+ validates :available_slots, numericality: { greater_than_or_equal_to: 0 }, if: ->(form) { form.registrations_enabled? && form.available_slots.present? }
46
48
  validates :registration_terms, translatable_presence: true, if: ->(form) { form.registrations_enabled? }
47
- validates :available_slots, numericality: { greater_than_or_equal_to: 0 }, if: ->(form) { form.registrations_enabled? }
48
49
 
49
50
  validates :hero_image, passthru: { to: Decidim::Conference }
50
51
  validates :banner_image, passthru: { to: Decidim::Conference }
51
- validate :available_slots_greater_than_or_equal_to_registrations_count, if: ->(form) { form.registrations_enabled? && form.available_slots.positive? }
52
+ validate :available_slots_greater_than_or_equal_to_registrations_count, if: ->(form) { form.registrations_enabled? && form.available_slots.try(:positive?) }
52
53
 
53
54
  validates :start_date, presence: true, date: { before_or_equal_to: :end_date }
54
55
  validates :end_date, presence: true, date: { after_or_equal_to: :start_date }
@@ -43,7 +43,7 @@ module Decidim
43
43
  def personal_url
44
44
  return if super.blank?
45
45
 
46
- return "http://" + super unless super.match?(%r{\A(http|https)://}i)
46
+ return "http://#{super}" unless super.match?(%r{\A(http|https)://}i)
47
47
 
48
48
  super
49
49
  end
@@ -21,7 +21,7 @@ module Decidim
21
21
  def link
22
22
  return if super.blank?
23
23
 
24
- return "http://" + super unless super.match?(%r{\A(http|https)://}i)
24
+ return "http://#{super}" unless super.match?(%r{\A(http|https)://}i)
25
25
 
26
26
  super
27
27
  end
@@ -17,6 +17,7 @@ module Decidim
17
17
  attribute :remove_logo
18
18
 
19
19
  validates :name, :partner_type, presence: true, if: ->(form) { form.logo.present? }
20
+ validates :logo, presence: true, unless: ->(form) { form.logo.present? }
20
21
  validates :logo, passthru: {
21
22
  to: Decidim::Conferences::Partner,
22
23
  with: {
@@ -38,7 +39,7 @@ module Decidim
38
39
  def link
39
40
  return if super.blank?
40
41
 
41
- return "http://" + super unless super.match?(%r{\A(http|https)://}i)
42
+ return "http://#{super}" unless super.match?(%r{\A(http|https)://}i)
42
43
 
43
44
  super
44
45
  end
@@ -4,7 +4,7 @@ module Decidim
4
4
  # It represents a meeting of the conference
5
5
  class ConferenceMeeting < Decidim::Meetings::Meeting
6
6
  has_many :conference_speaker_conference_meetings, dependent: :destroy
7
- has_many :conference_speakers, through: :conference_speaker_conference_meetings, foreign_key: "conference_meeting_id", class_name: "Decidim::ConferenceSpeaker"
7
+ has_many :conference_speakers, through: :conference_speaker_conference_meetings, class_name: "Decidim::ConferenceSpeaker"
8
8
  has_many :conference_meeting_registration_types, dependent: :destroy
9
9
  has_many :registration_types, through: :conference_meeting_registration_types, foreign_key: "registration_type_id", class_name: "Decidim::Conferences::RegistrationType"
10
10
  end