decidim-conferences 0.29.2 → 0.30.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/conferences/content_blocks/highlighted_conferences_settings_form/show.erb +1 -1
  3. data/app/commands/decidim/conferences/admin/copy_conference.rb +2 -12
  4. data/app/commands/decidim/conferences/admin/create_conference.rb +1 -1
  5. data/app/commands/decidim/conferences/admin/update_conference.rb +1 -1
  6. data/app/controllers/decidim/conferences/admin/component_share_tokens_controller.rb +18 -0
  7. data/app/controllers/decidim/conferences/admin/concerns/conference_admin.rb +1 -1
  8. data/app/controllers/decidim/conferences/admin/conference_share_tokens_controller.rb +18 -0
  9. data/app/controllers/decidim/conferences/admin/conferences_controller.rb +17 -4
  10. data/app/forms/decidim/conferences/admin/conference_copy_form.rb +0 -1
  11. data/app/forms/decidim/conferences/admin/conference_form.rb +3 -8
  12. data/app/helpers/decidim/conferences/conference_program_helper.rb +4 -2
  13. data/app/mailers/decidim/conferences/admin/send_conference_diploma_mailer.rb +1 -11
  14. data/app/models/decidim/conference.rb +19 -0
  15. data/app/models/decidim/conferences/conference_invite.rb +10 -0
  16. data/app/permissions/decidim/conferences/permissions.rb +11 -4
  17. data/app/presenters/decidim/conferences/admin_log/conference_presenter.rb +1 -1
  18. data/app/presenters/decidim/conferences/conference_presenter.rb +19 -0
  19. data/app/serializers/decidim/conferences/conference_serializer.rb +24 -0
  20. data/app/serializers/decidim/conferences/download_your_data_conference_invite_serializer.rb +3 -4
  21. data/app/serializers/decidim/conferences/download_your_data_conference_registration_serializer.rb +4 -4
  22. data/app/serializers/decidim/conferences/open_data_conference_serializer.rb +30 -0
  23. data/app/views/decidim/conferences/admin/conference_copies/_form.html.erb +0 -3
  24. data/app/views/decidim/conferences/admin/conferences/_actions.html.erb +35 -0
  25. data/app/views/decidim/conferences/admin/conferences/_conference_row.html.erb +28 -0
  26. data/app/views/decidim/conferences/admin/conferences/_conferences_thead.html.erb +8 -0
  27. data/app/views/decidim/conferences/admin/conferences/_form.html.erb +27 -8
  28. data/app/views/decidim/conferences/admin/conferences/index.html.erb +14 -52
  29. data/app/views/decidim/conferences/admin/conferences/manage_trash.html.erb +20 -0
  30. data/app/views/decidim/conferences/admin/send_conference_diploma_mailer/diploma_user.html.erb +3 -1
  31. data/app/views/decidim/conferences/conference_program/show.html.erb +3 -1
  32. data/app/views/decidim/conferences/conference_speakers/index.html.erb +4 -1
  33. data/app/views/decidim/conferences/conferences/index.html.erb +3 -2
  34. data/app/views/decidim/conferences/conferences/show.html.erb +6 -6
  35. data/app/views/decidim/conferences/media/index.html.erb +3 -1
  36. data/app/views/decidim/conferences/registration_types/index.html.erb +3 -1
  37. data/app/views/layouts/decidim/admin/conference.html.erb +1 -1
  38. data/config/locales/ar.yml +12 -3
  39. data/config/locales/bg.yml +0 -3
  40. data/config/locales/ca.yml +63 -3
  41. data/config/locales/cs.yml +63 -3
  42. data/config/locales/de.yml +63 -3
  43. data/config/locales/el.yml +0 -3
  44. data/config/locales/en.yml +63 -3
  45. data/config/locales/es-MX.yml +63 -3
  46. data/config/locales/es-PY.yml +63 -3
  47. data/config/locales/es.yml +63 -3
  48. data/config/locales/eu.yml +63 -3
  49. data/config/locales/fi-plain.yml +63 -3
  50. data/config/locales/fi.yml +63 -3
  51. data/config/locales/fr-CA.yml +22 -3
  52. data/config/locales/fr.yml +22 -3
  53. data/config/locales/ga-IE.yml +0 -2
  54. data/config/locales/gl.yml +0 -3
  55. data/config/locales/hu.yml +0 -3
  56. data/config/locales/id-ID.yml +0 -3
  57. data/config/locales/it.yml +0 -3
  58. data/config/locales/ja.yml +65 -3
  59. data/config/locales/lb.yml +0 -3
  60. data/config/locales/lt.yml +0 -3
  61. data/config/locales/lv.yml +0 -3
  62. data/config/locales/nl.yml +0 -3
  63. data/config/locales/no.yml +0 -3
  64. data/config/locales/pl.yml +0 -3
  65. data/config/locales/pt-BR.yml +0 -3
  66. data/config/locales/pt.yml +0 -3
  67. data/config/locales/ro-RO.yml +0 -3
  68. data/config/locales/sk.yml +0 -3
  69. data/config/locales/sv.yml +65 -3
  70. data/config/locales/tr-TR.yml +0 -3
  71. data/config/locales/zh-CN.yml +0 -3
  72. data/config/locales/zh-TW.yml +0 -3
  73. data/db/migrate/20210310134942_add_followable_counter_cache_to_conferences.rb +1 -1
  74. data/db/migrate/20240822161330_add_deleted_at_to_decidim_conferences.rb +8 -0
  75. data/decidim-conferences.gemspec +1 -2
  76. data/lib/decidim/api/conference_media_link_type.rb +4 -4
  77. data/lib/decidim/api/conference_partner_type.rb +4 -4
  78. data/lib/decidim/api/conference_speaker_type.rb +7 -8
  79. data/lib/decidim/api/conference_type.rb +17 -19
  80. data/lib/decidim/conferences/admin_engine.rb +87 -58
  81. data/lib/decidim/conferences/conference_diploma_pdf.rb +242 -0
  82. data/lib/decidim/conferences/engine.rb +6 -1
  83. data/lib/decidim/conferences/menu.rb +23 -9
  84. data/lib/decidim/conferences/participatory_space.rb +13 -0
  85. data/lib/decidim/conferences/seeds.rb +134 -115
  86. data/lib/decidim/conferences/test/factories.rb +10 -9
  87. data/lib/decidim/conferences/version.rb +1 -1
  88. data/lib/decidim/conferences.rb +1 -0
  89. metadata +23 -28
  90. data/app/controllers/decidim/conferences/admin/categories_controller.rb +0 -13
  91. data/config/initializers/wicked_pdf.rb +0 -22
@@ -0,0 +1,242 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hexapdf"
4
+ require "open-uri"
5
+
6
+ module Decidim
7
+ module Conferences
8
+ class ConferenceDiplomaPDF
9
+ include ActionView::Helpers::AssetUrlHelper
10
+ include Shakapacker::Helper
11
+ include Decidim::TranslatableAttributes
12
+ include Decidim::SanitizeHelper
13
+
14
+ def initialize(conference, user)
15
+ @conference = conference
16
+ @user = user
17
+ end
18
+
19
+ def render
20
+ composer.styles(**styles)
21
+
22
+ create_border
23
+ add_logo
24
+
25
+ add_text
26
+
27
+ add_hr_line
28
+ add_verified_by_text
29
+ add_signature_picture
30
+ add_verified_by_signature
31
+
32
+ document.write_to_string
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :conference
38
+
39
+ delegate :document, to: :composer
40
+
41
+ def page_orientation = :landscape
42
+
43
+ def page = document.pages.first
44
+
45
+ def page_width = page.box(:media).width
46
+
47
+ def page_height = page.box(:media).height
48
+
49
+ def layout = document.layout
50
+
51
+ def box_width = page_width * 0.9
52
+
53
+ def box_height = page_height * 0.7
54
+
55
+ def styles
56
+ {
57
+ h1: { font: bold_font, text_align: :center, font_size: 18 },
58
+ h2: { font: bold_font, text_align: :center, font_size: 15 },
59
+ text: { font:, text_align: :center, font_size: 10 },
60
+ verified: { font:, text_align: :center, font_size: 8 },
61
+ bold: { font: bold_font, text_align: :center, font_size: 10 }
62
+ }
63
+ end
64
+
65
+ def composer
66
+ @composer ||= ::HexaPDF::Composer.new(page_orientation:)
67
+ end
68
+
69
+ def add_text
70
+ width = 710
71
+
72
+ composer.text(translated_attribute(conference.title), style: :h1, position: [30, box_height - 130], width:)
73
+ composer.text(I18n.t("decidim.conferences.admin.send_conference_diploma_mailer.diploma_user.certificate_of_attendance"),
74
+ style: :h2, position: [30, box_height - 160], width:)
75
+
76
+ text = I18n.t("decidim.conferences.admin.send_conference_diploma_mailer.diploma_user.certificate_of_attendance_description",
77
+ user: @user.name,
78
+ title: translated_attribute(@conference.title),
79
+ location: @conference.location,
80
+ start: I18n.l(@conference.start_date, format: :decidim_short),
81
+ end: I18n.l(@conference.end_date, format: :decidim_short))
82
+
83
+ texts_to_bold = [
84
+ @user.name,
85
+ translated_attribute(@conference.title),
86
+ I18n.l(@conference.start_date, format: :decidim_short),
87
+ I18n.l(@conference.end_date, format: :decidim_short)
88
+ ]
89
+
90
+ texts_to_bold = texts_to_bold.map { |bold| decidim_sanitize(bold, strip_tags: true) }
91
+
92
+ text = decidim_sanitize(text, strip_tags: true)
93
+ text_fragments = create_text_fragments(text, texts_to_bold)
94
+
95
+ result = HexaPDF::Layout::TextLayouter.new.fit(text_fragments, 710, 30)
96
+
97
+ x_width = (page_width - result.lines.first.width) / 2
98
+
99
+ result.draw(composer.canvas, x_width, 260)
100
+ end
101
+
102
+ # Function to create text fragments with bold parts
103
+ def create_text_fragments(text, texts_to_bold)
104
+ fragments = []
105
+ current_position = 0
106
+
107
+ texts_to_bold.sort_by! { |bold_text| text.index(bold_text) }
108
+
109
+ texts_to_bold.each do |bold_text|
110
+ bold_position = text.index(bold_text, current_position)
111
+
112
+ if bold_position > current_position
113
+ part = text[current_position...bold_position]
114
+ fragments << HexaPDF::Layout::TextFragment.create(part, styles[:text])
115
+ end
116
+
117
+ fragments << HexaPDF::Layout::TextFragment.create(bold_text, styles[:bold])
118
+
119
+ current_position = bold_position + bold_text.length
120
+ end
121
+
122
+ if current_position < text.length
123
+ part = text[current_position..-1]
124
+ fragments << HexaPDF::Layout::TextFragment.create(part, font: styles[:text])
125
+ end
126
+
127
+ fragments
128
+ end
129
+
130
+ def compute_dimensions(attached_image, max_width, max_height)
131
+ # Retrieve the image metadata
132
+ metadata = attached_image.blob.metadata
133
+
134
+ # If metadata does not contain width and height, return the max dimensions
135
+ return max_height, max_width unless metadata.has_key?(:width) && metadata.has_key?(:height)
136
+
137
+ # Calculate the aspect ratio of the image
138
+ aspect_ratio = metadata[:width].to_f / metadata[:height]
139
+
140
+ # Adjust the width based on the max height while preserving the aspect ratio
141
+ adjusted_width = (max_height * aspect_ratio).round
142
+
143
+ # Return the max height and the adjusted width
144
+ return max_height, adjusted_width
145
+ end
146
+
147
+ def font
148
+ @font ||= load_font("source-sans-pro-v21-cyrillic_cyrillic-ext_greek_greek-ext_latin_latin-ext_vietnamese-regular.ttf")
149
+ end
150
+
151
+ def bold_font
152
+ @bold_font ||= load_font("source-sans-pro-v21-cyrillic_cyrillic-ext_greek_greek-ext_latin_latin-ext_vietnamese-700.ttf")
153
+ end
154
+
155
+ def load_font(path)
156
+ document.fonts.add(Decidim::Core::Engine.root.join("app/packs/fonts/decidim/").join(path))
157
+ end
158
+
159
+ def add_verified_by_text
160
+ composer.text(I18n.t("decidim.conferences.admin.send_conference_diploma_mailer.diploma_user.attendance_verified_by"),
161
+ style: :bold, position: [30, 160], width: 710)
162
+ end
163
+
164
+ def add_signature_picture
165
+ attached_image = conference.attached_uploader(:signature).variant(:original)
166
+ logo = document.images.add(StringIO.new(attached_image.download))
167
+ max_height, max_width = compute_dimensions(attached_image, 80, 40)
168
+
169
+ box_x = (page_width - max_width) / 2
170
+ box_y = 150
171
+ frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, 80, 40)
172
+
173
+ box = document.layout.box do |canvas, _box|
174
+ canvas.image(logo, at: [0, 0], width: max_width, height: max_height)
175
+ end
176
+
177
+ result = frame.fit(box)
178
+ frame.draw(page.canvas, result)
179
+ end
180
+
181
+ def add_hr_line
182
+ frame = ::HexaPDF::Layout::Frame.new(66, 210, 710, 10)
183
+
184
+ box = document.layout.box do |canvas, _box|
185
+ canvas.line_width = 0.5
186
+ canvas.stroke_color(0, 0, 0)
187
+ canvas.line(0, 10, 710, 10).stroke
188
+ end
189
+ result = frame.fit(box)
190
+ frame.draw(page.canvas, result)
191
+ end
192
+
193
+ def add_verified_by_signature
194
+ composer.text([
195
+ I18n.l(conference.sign_date, format: :decidim_short),
196
+ conference.signature_name
197
+ ].join(", "), style: :verified, position: [30, 95], width: 710)
198
+ end
199
+
200
+ def add_logo
201
+ attached_image = conference.attached_uploader(:main_logo).variant(:original)
202
+ logo = document.images.add(StringIO.new(attached_image.download))
203
+ max_height, max_width = compute_dimensions(attached_image, 160, 80)
204
+
205
+ box_x = (page_width - max_width) / 2
206
+ box_y = page_height - 220
207
+ frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, 160, 80)
208
+
209
+ box = document.layout.box do |canvas, _box|
210
+ canvas.image(logo, at: [0, 0], width: max_width, height: max_height)
211
+ end
212
+
213
+ result = frame.fit(box)
214
+ frame.draw(page.canvas, result)
215
+ end
216
+
217
+ def create_border
218
+ background_image = StringIO.new(Rails.root.join("public/#{image_pack_path("media/images/pattern.png")}").read)
219
+
220
+ box_x = (page_width - box_width) / 2
221
+ box_y = (page_height - box_height) / 2
222
+
223
+ frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, box_width, box_height)
224
+
225
+ box = document.layout.image_box(background_image, width: box_width, height: box_height)
226
+ result = frame.fit(box)
227
+ frame.draw(page.canvas, result)
228
+
229
+ frame = ::HexaPDF::Layout::Frame.new(box_x, box_y, box_width, box_height)
230
+
231
+ box = document.layout.box do |canvas, _box|
232
+ canvas.fill_color("FFFFFF")
233
+ canvas.rectangle(10, 10, box_width - 20, box_height - 20)
234
+ canvas.fill
235
+ end
236
+
237
+ result = frame.fit(box)
238
+ frame.draw(page.canvas, result)
239
+ end
240
+ end
241
+ end
242
+ end
@@ -3,7 +3,6 @@
3
3
  require "rails"
4
4
  require "active_support/all"
5
5
  require "decidim/core"
6
- require "wicked_pdf"
7
6
 
8
7
  require "decidim/conferences/query_extensions"
9
8
  require "decidim/conferences/content_blocks/registry_manager"
@@ -51,6 +50,12 @@ module Decidim
51
50
  end
52
51
  end
53
52
 
53
+ initializer "decidim_conferences.mount_routes" do
54
+ Decidim::Core::Engine.routes do
55
+ mount Decidim::Conferences::Engine, at: "/", as: "decidim_conferences"
56
+ end
57
+ end
58
+
54
59
  initializer "decidim_conferences.register_icons" do
55
60
  Decidim.icons.register(name: "Decidim::Conference", icon: "mic-line", description: "Conference", category: "activity", engine: :conferences)
56
61
  Decidim.icons.register(name: "conference_speaker", icon: "user-voice-line", description: "Speaker", category: "conferences", engine: :conferences)
@@ -48,6 +48,7 @@ module Decidim
48
48
  active: is_active_link?(manage_component_path(component)) ||
49
49
  is_active_link?(decidim_admin_conferences.edit_component_path(current_participatory_space, component)) ||
50
50
  is_active_link?(decidim_admin_conferences.edit_component_permissions_path(current_participatory_space, component)) ||
51
+ is_active_link?(decidim_admin_conferences.component_share_tokens_path(current_participatory_space, component)) ||
51
52
  participatory_space_active_link?(component),
52
53
  if: component.manifest.admin_engine && user_role_config.component_is_accessible?(component.manifest_name)
53
54
  end
@@ -100,8 +101,8 @@ module Decidim
100
101
  end
101
102
  end
102
103
 
103
- def self.register_conferences_admin_menu!
104
- Decidim.menu :conferences_admin_menu do |menu|
104
+ def self.register_conference_admin_menu!
105
+ Decidim.menu :conference_admin_menu do |menu|
105
106
  menu.add_item :edit_conference,
106
107
  I18n.t("info", scope: "decidim.admin.menu.conferences_submenu"),
107
108
  decidim_admin_conferences.edit_conference_path(current_participatory_space),
@@ -118,12 +119,6 @@ module Decidim
118
119
  ["decidim/conferences/admin/components", %w(index new edit)]),
119
120
  submenu: { target_menu: :admin_conferences_components_menu }
120
121
 
121
- menu.add_item :categories,
122
- I18n.t("categories", scope: "decidim.admin.menu.conferences_submenu"),
123
- decidim_admin_conferences.categories_path(current_participatory_space),
124
- icon_name: "price-tag-3-line",
125
- if: allowed_to?(:read, :category, conference: current_participatory_space)
126
-
127
122
  menu.add_item :attachments,
128
123
  I18n.t("attachments", scope: "decidim.admin.menu.conferences_submenu"),
129
124
  decidim_admin_conferences.conference_attachments_path(current_participatory_space),
@@ -172,6 +167,25 @@ module Decidim
172
167
  decidim_admin_conferences.moderations_path(current_participatory_space),
173
168
  icon_name: "flag-line",
174
169
  if: allowed_to?(:read, :moderation, conference: current_participatory_space)
170
+
171
+ menu.add_item :conference_share_tokens,
172
+ I18n.t("menu.share_tokens", scope: "decidim.admin"),
173
+ decidim_admin_conferences.conference_share_tokens_path(current_participatory_space),
174
+ active: is_active_link?(decidim_admin_conferences.conference_share_tokens_path(current_participatory_space)),
175
+ icon_name: "share-line",
176
+ if: allowed_to?(:read, :share_tokens, current_participatory_space:)
177
+ end
178
+ end
179
+
180
+ def self.register_conferences_admin_menu!
181
+ Decidim.menu :admin_conferences_menu do |menu|
182
+ menu.add_item :conferences,
183
+ I18n.t("menu.conferences", scope: "decidim.admin"),
184
+ decidim_admin_conferences.conferences_path,
185
+ position: 1,
186
+ active: is_active_link?(decidim_admin_conferences.conferences_path),
187
+ icon_name: "government-line",
188
+ if: allowed_to?(:read, :conference_list)
175
189
  end
176
190
  end
177
191
 
@@ -182,7 +196,7 @@ module Decidim
182
196
  decidim_admin_conferences.conferences_path,
183
197
  icon_name: "live-line",
184
198
  position: 2.8,
185
- active: :inclusive,
199
+ active: is_active_link?(decidim_admin_conferences.conferences_path, :inclusive),
186
200
  if: allowed_to?(:enter, :space_area, space_name: :conferences)
187
201
  end
188
202
  end
@@ -36,6 +36,19 @@ Decidim.register_participatory_space(:conferences) do |participatory_space|
36
36
  context.layout = "layouts/decidim/admin/conference"
37
37
  end
38
38
 
39
+ participatory_space.exports :conferences do |export|
40
+ export.collection do
41
+ Decidim::Conference
42
+ .public_spaces
43
+ .includes(:taxonomies, :attachment_collections)
44
+ end
45
+
46
+ export.include_in_open_data = true
47
+
48
+ export.serializer Decidim::Conferences::ConferenceSerializer
49
+ export.open_data_serializer Decidim::Conferences::OpenDataConferenceSerializer
50
+ end
51
+
39
52
  participatory_space.register_on_destroy_account do |user|
40
53
  Decidim::ConferenceUserRole.where(user:).destroy_all
41
54
  Decidim::ConferenceSpeaker.where(user:).destroy_all
@@ -6,145 +6,164 @@ module Decidim
6
6
  module Conferences
7
7
  class Seeds < Decidim::Seeds
8
8
  def call
9
- organization = Decidim::Organization.first
10
-
11
- Decidim::ContentBlock.create(
12
- organization:,
13
- weight: 33,
14
- scope_name: :homepage,
15
- manifest_name: :highlighted_conferences,
16
- published_at: Time.current
17
- )
9
+ create_content_block!
18
10
 
19
11
  2.times do |_n|
20
- params = {
21
- title: Decidim::Faker::Localized.sentence(word_count: 5),
22
- slogan: Decidim::Faker::Localized.sentence(word_count: 2),
23
- slug: Decidim::Faker::Internet.unique.slug(words: nil, glue: "-"),
24
- hashtag: "##{::Faker::Lorem.word}",
25
- short_description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
26
- Decidim::Faker::Localized.sentence(word_count: 3)
27
- end,
28
- description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
29
- Decidim::Faker::Localized.paragraph(sentence_count: 3)
30
- end,
31
- organization:,
32
- hero_image: ::Faker::Boolean.boolean(true_ratio: 0.5) ? hero_image : nil, # Keep after organization
33
- banner_image: ::Faker::Boolean.boolean(true_ratio: 0.5) ? banner_image : nil, # Keep after organization
34
- promoted: true,
35
- published_at: 2.weeks.ago,
36
- objectives: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
37
- Decidim::Faker::Localized.paragraph(sentence_count: 3)
38
- end,
39
- start_date: Time.current,
40
- end_date: 2.months.from_now.at_midnight,
41
- registrations_enabled: [true, false].sample,
42
- available_slots: (10..50).step(10).to_a.sample,
43
- registration_terms: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
44
- Decidim::Faker::Localized.paragraph(sentence_count: 3)
45
- end
46
- }
47
-
48
- conference = Decidim.traceability.perform_action!(
49
- "publish",
50
- Decidim::Conference,
51
- organization.users.first,
52
- visibility: "all"
53
- ) do
54
- Decidim::Conference.create!(params)
55
- end
56
- conference.add_to_index_as_search_resource
12
+ conference = create_conference!
57
13
 
58
- # Create users with specific roles
59
- Decidim::ConferenceUserRole::ROLES.each do |role|
60
- email = "conference_#{conference.id}_#{role}@example.org"
61
- user = find_or_initialize_user_by(email:)
14
+ create_conference_user_roles!(conference:)
62
15
 
63
- Decidim::ConferenceUserRole.find_or_create_by!(
64
- user:,
65
- conference:,
66
- role:
67
- )
68
- end
69
-
70
- attachment_collection = create_attachment_collection(collection_for: conference)
71
- create_attachment(attached_to: conference, filename: "Exampledocument.pdf", attachment_collection:)
72
- create_attachment(attached_to: conference, filename: "city.jpeg")
73
- create_attachment(attached_to: conference, filename: "Exampledocument.pdf")
74
-
75
- 2.times do
76
- Decidim::Category.create!(
77
- name: Decidim::Faker::Localized.sentence(word_count: 5),
78
- description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
79
- Decidim::Faker::Localized.paragraph(sentence_count: 3)
80
- end,
81
- participatory_space: conference
82
- )
83
- end
16
+ create_attachments!(attached_to: conference)
84
17
 
85
18
  5.times do
86
- Decidim::ConferenceSpeaker.create!(
87
- user: conference.organization.users.sample,
88
- full_name: ::Faker::Name.name,
89
- position: Decidim::Faker::Localized.word,
90
- affiliation: Decidim::Faker::Localized.sentence(word_count: 3),
91
- short_bio: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
92
- Decidim::Faker::Localized.paragraph(sentence_count: 3)
93
- end,
94
- twitter_handle: ::Faker::Twitter.unique.screen_name,
95
- personal_url: ::Faker::Internet.url,
96
- published_at: Time.current,
97
- conference:
98
- )
19
+ create_conference_speaker!(conference:)
99
20
  end
100
21
 
101
22
  Decidim::Conferences::Partner::TYPES.map do |type|
102
23
  4.times do
103
- Decidim::Conferences::Partner.create!(
104
- name: ::Faker::Name.name,
105
- weight: ::Faker::Number.between(from: 1, to: 10),
106
- link: ::Faker::Internet.url,
107
- partner_type: type,
108
- conference:,
109
- logo: create_blob!(seeds_file: "logo.png", filename: "logo.png", content_type: "image/png")
110
- )
24
+ create_conference_partner!(conference:, type:)
111
25
  end
112
26
  end
113
27
 
114
28
  5.times do
115
- Decidim::Conferences::MediaLink.create!(
116
- title: Decidim::Faker::Localized.sentence(word_count: 2),
117
- link: ::Faker::Internet.url,
118
- date: Date.current,
119
- weight: ::Faker::Number.between(from: 1, to: 10),
120
- conference:
121
- )
29
+ create_conference_media_link!(conference:)
122
30
  end
123
31
 
124
32
  5.times do
125
- Decidim::Conferences::RegistrationType.create!(
126
- title: Decidim::Faker::Localized.sentence(word_count: 2),
127
- description: Decidim::Faker::Localized.sentence(word_count: 5),
128
- weight: ::Faker::Number.between(from: 1, to: 10),
129
- price: ::Faker::Number.between(from: 1, to: 300),
130
- published_at: 2.weeks.ago,
131
- conference:
132
- )
33
+ create_conference_registration_type!(conference:)
133
34
  end
134
35
 
135
36
  Decidim.component_manifests.each do |manifest|
136
37
  manifest.seed!(conference.reload)
137
38
  end
138
39
 
139
- Decidim::ConferenceMeeting.where(component: conference.components).each do |conference_meeting|
140
- next unless ::Faker::Boolean.boolean(true_ratio: 0.5)
40
+ create_conference_meeting!(conference:)
41
+ end
42
+ end
141
43
 
142
- conference.speakers.sample(3).each do |speaker|
143
- Decidim::ConferenceSpeakerConferenceMeeting.create!(
144
- conference_meeting:,
145
- conference_speaker: speaker
146
- )
147
- end
44
+ def create_content_block!
45
+ Decidim::ContentBlock.create(
46
+ organization:,
47
+ weight: 33,
48
+ scope_name: :homepage,
49
+ manifest_name: :highlighted_conferences,
50
+ published_at: Time.current
51
+ )
52
+ end
53
+
54
+ def create_conference!
55
+ params = {
56
+ title: Decidim::Faker::Localized.sentence(word_count: 5),
57
+ slogan: Decidim::Faker::Localized.sentence(word_count: 2),
58
+ slug: Decidim::Faker::Internet.unique.slug(words: nil, glue: "-"),
59
+ hashtag: "##{::Faker::Lorem.word}",
60
+ short_description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
61
+ Decidim::Faker::Localized.sentence(word_count: 3)
62
+ end,
63
+ description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
64
+ Decidim::Faker::Localized.paragraph(sentence_count: 3)
65
+ end,
66
+ organization:,
67
+ hero_image: ::Faker::Boolean.boolean(true_ratio: 0.5) ? hero_image : nil, # Keep after organization
68
+ banner_image: ::Faker::Boolean.boolean(true_ratio: 0.5) ? banner_image : nil, # Keep after organization
69
+ promoted: true,
70
+ published_at: 2.weeks.ago,
71
+ objectives: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
72
+ Decidim::Faker::Localized.paragraph(sentence_count: 3)
73
+ end,
74
+ start_date: Time.current,
75
+ end_date: 2.months.from_now.at_midnight,
76
+ registrations_enabled: [true, false].sample,
77
+ available_slots: (10..50).step(10).to_a.sample,
78
+ registration_terms: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
79
+ Decidim::Faker::Localized.paragraph(sentence_count: 3)
80
+ end
81
+ }
82
+
83
+ conference = Decidim.traceability.perform_action!(
84
+ "publish",
85
+ Decidim::Conference,
86
+ organization.users.first,
87
+ visibility: "all"
88
+ ) do
89
+ Decidim::Conference.create!(params)
90
+ end
91
+ conference.add_to_index_as_search_resource
92
+
93
+ conference
94
+ end
95
+
96
+ def create_conference_user_roles!(conference:)
97
+ # Create users with specific roles
98
+ Decidim::ConferenceUserRole::ROLES.each do |role|
99
+ email = "conference_#{conference.id}_#{role}@example.org"
100
+ user = find_or_initialize_user_by(email:)
101
+
102
+ Decidim::ConferenceUserRole.find_or_create_by!(
103
+ user:,
104
+ conference:,
105
+ role:
106
+ )
107
+ end
108
+ end
109
+
110
+ def create_conference_speaker!(conference:)
111
+ Decidim::ConferenceSpeaker.create!(
112
+ user: conference.organization.users.sample,
113
+ full_name: ::Faker::Name.name,
114
+ position: Decidim::Faker::Localized.word,
115
+ affiliation: Decidim::Faker::Localized.sentence(word_count: 3),
116
+ short_bio: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
117
+ Decidim::Faker::Localized.paragraph(sentence_count: 3)
118
+ end,
119
+ twitter_handle: ::Faker::Twitter.unique.screen_name,
120
+ personal_url: ::Faker::Internet.url,
121
+ published_at: Time.current,
122
+ conference:
123
+ )
124
+ end
125
+
126
+ def create_conference_partner!(conference:, type:)
127
+ Decidim::Conferences::Partner.create!(
128
+ name: ::Faker::Name.name,
129
+ weight: ::Faker::Number.between(from: 1, to: 10),
130
+ link: ::Faker::Internet.url,
131
+ partner_type: type,
132
+ conference:,
133
+ logo: create_blob!(seeds_file: "logo.png", filename: "logo.png", content_type: "image/png")
134
+ )
135
+ end
136
+
137
+ def create_conference_media_link!(conference:)
138
+ Decidim::Conferences::MediaLink.create!(
139
+ title: Decidim::Faker::Localized.sentence(word_count: 2),
140
+ link: ::Faker::Internet.url,
141
+ date: Date.current,
142
+ weight: ::Faker::Number.between(from: 1, to: 10),
143
+ conference:
144
+ )
145
+ end
146
+
147
+ def create_conference_registration_type!(conference:)
148
+ Decidim::Conferences::RegistrationType.create!(
149
+ title: Decidim::Faker::Localized.sentence(word_count: 2),
150
+ description: Decidim::Faker::Localized.sentence(word_count: 5),
151
+ weight: ::Faker::Number.between(from: 1, to: 10),
152
+ price: ::Faker::Number.between(from: 1, to: 300),
153
+ published_at: 2.weeks.ago,
154
+ conference:
155
+ )
156
+ end
157
+
158
+ def create_conference_meeting!(conference:)
159
+ Decidim::ConferenceMeeting.where(component: conference.components).each do |conference_meeting|
160
+ next unless ::Faker::Boolean.boolean(true_ratio: 0.5)
161
+
162
+ conference.speakers.sample(3).each do |speaker|
163
+ Decidim::ConferenceSpeakerConferenceMeeting.create!(
164
+ conference_meeting:,
165
+ conference_speaker: speaker
166
+ )
148
167
  end
149
168
  end
150
169
  end