spina-admin-conferences 1.3.6 → 2.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -10
  3. data/app/assets/config/spina_admin_conferences_manifest.js +2 -2
  4. data/app/assets/javascripts/{spina/admin/conferences/controllers/conference_events_form_controller.es6 → controllers/spina/admin/conferences/conference_events_form_controller.js} +3 -4
  5. data/app/assets/javascripts/{spina/admin/conferences/controllers/presentation_attachments_form_controller.es6 → controllers/spina/admin/conferences/presentation_attachments_form_controller.js} +3 -4
  6. data/app/assets/javascripts/{spina/admin/conferences/controllers/select_options_controller.es6 → controllers/spina/admin/conferences/select_options_controller.js} +8 -9
  7. data/app/assets/javascripts/importmap.json.erb +6 -0
  8. data/app/assets/javascripts/spina/admin/conferences/application.js +4 -0
  9. data/app/assets/stylesheets/spina/admin/conferences/application.sass +3 -14
  10. data/app/controllers/spina/admin/conferences/application_controller.rb +6 -3
  11. data/app/controllers/spina/admin/conferences/conferences_controller.rb +21 -30
  12. data/app/controllers/spina/admin/conferences/delegates_controller.rb +5 -7
  13. data/app/controllers/spina/admin/conferences/dietary_requirements_controller.rb +4 -4
  14. data/app/controllers/spina/admin/conferences/institutions_controller.rb +4 -4
  15. data/app/controllers/spina/admin/conferences/presentation_attachment_types_controller.rb +4 -4
  16. data/app/controllers/spina/admin/conferences/presentation_types_controller.rb +4 -4
  17. data/app/controllers/spina/admin/conferences/presentations_controller.rb +7 -8
  18. data/app/controllers/spina/admin/conferences/rooms_controller.rb +4 -4
  19. data/app/controllers/spina/admin/conferences/sessions_controller.rb +4 -4
  20. data/app/jobs/spina/admin/conferences/presentation_import_job.rb +2 -3
  21. data/app/models/spina/admin/conferences/conference.rb +4 -7
  22. data/app/models/spina/admin/conferences/event.rb +21 -58
  23. data/app/models/spina/admin/conferences/presentation.rb +15 -33
  24. data/app/models/spina/parts/admin/conferences/date.rb +14 -0
  25. data/app/models/spina/parts/admin/conferences/email_address.rb +20 -0
  26. data/app/models/spina/parts/admin/conferences/time.rb +14 -0
  27. data/app/models/spina/parts/admin/conferences/url.rb +20 -0
  28. data/app/views/layouts/spina/admin/conferences/application.html.haml +6 -0
  29. data/app/views/layouts/spina/admin/conferences/conferences.html.haml +2 -4
  30. data/app/views/layouts/spina/admin/conferences/delegates.html.haml +2 -4
  31. data/app/views/layouts/spina/admin/conferences/dietary_requirements.html.haml +2 -4
  32. data/app/views/layouts/spina/admin/conferences/institutions.html.haml +2 -4
  33. data/app/views/layouts/spina/admin/conferences/presentation_attachment_types.html.haml +2 -4
  34. data/app/views/layouts/spina/admin/conferences/presentations.html.haml +2 -4
  35. data/app/views/spina/admin/conferences/{delegates/_form_conferences.html.haml → application/_conferences.html.haml} +2 -4
  36. data/app/views/spina/admin/conferences/{conferences/_form_delegates.html.haml → application/_delegates.html.haml} +2 -3
  37. data/app/views/spina/admin/conferences/application/_dietary_requirements.html.haml +9 -0
  38. data/app/views/spina/admin/conferences/application/_errors.turbo_stream.haml +1 -0
  39. data/app/views/spina/admin/conferences/application/_institutions.html.haml +10 -0
  40. data/app/views/spina/admin/conferences/application/_presentation_attachment_types.html.haml +10 -0
  41. data/app/views/spina/admin/conferences/{conferences/_form_presentation_types.html.haml → application/_presentation_types.html.haml} +2 -3
  42. data/app/views/spina/admin/conferences/{rooms/_form_presentations.html.haml → application/_presentations.html.haml} +2 -3
  43. data/app/views/spina/admin/conferences/{conferences/_form_rooms.html.haml → application/_rooms.html.haml} +2 -3
  44. data/app/views/spina/admin/conferences/{presentation_types/_form_sessions.html.haml → application/_sessions.html.haml} +2 -3
  45. data/app/views/spina/admin/conferences/conferences/_event_fields.html.haml +18 -25
  46. data/app/views/spina/admin/conferences/conferences/_event_row.html.haml +2 -2
  47. data/app/views/spina/admin/conferences/conferences/_form.html.haml +7 -3
  48. data/app/views/spina/admin/conferences/conferences/_form_conference_details.html.haml +22 -24
  49. data/app/views/spina/admin/conferences/conferences/_form_parts.html.haml +7 -14
  50. data/app/views/spina/admin/conferences/conferences/index.html.haml +1 -13
  51. data/app/views/spina/admin/conferences/delegates/_form.html.haml +4 -3
  52. data/app/views/spina/admin/conferences/delegates/_form_delegate_details.html.haml +47 -32
  53. data/app/views/spina/admin/conferences/delegates/index.html.haml +1 -12
  54. data/app/views/spina/admin/conferences/dietary_requirements/_form.html.haml +3 -3
  55. data/app/views/spina/admin/conferences/dietary_requirements/_form_dietary_requirement_details.html.haml +7 -8
  56. data/app/views/spina/admin/conferences/dietary_requirements/index.html.haml +1 -10
  57. data/app/views/spina/admin/conferences/events/new.js.erb +3 -9
  58. data/app/views/spina/admin/conferences/institutions/_form.html.haml +4 -3
  59. data/app/views/spina/admin/conferences/institutions/_form_institution_details.html.haml +29 -35
  60. data/app/views/spina/admin/conferences/institutions/index.html.haml +1 -11
  61. data/app/views/spina/admin/conferences/presentation_attachment_types/_form.html.haml +3 -3
  62. data/app/views/spina/admin/conferences/presentation_attachment_types/index.html.haml +1 -10
  63. data/app/views/spina/admin/conferences/presentation_attachments/new.js.erb +3 -3
  64. data/app/views/spina/admin/conferences/presentation_types/_form.html.haml +4 -3
  65. data/app/views/spina/admin/conferences/presentation_types/_form_presentation_type_details.html.haml +13 -17
  66. data/app/views/spina/admin/conferences/presentation_types/index.html.haml +1 -12
  67. data/app/views/spina/admin/conferences/presentations/_attachment_fields.html.haml +10 -19
  68. data/app/views/spina/admin/conferences/presentations/_attachment_row.html.haml +2 -2
  69. data/app/views/spina/admin/conferences/presentations/_form.html.haml +3 -3
  70. data/app/views/spina/admin/conferences/presentations/_form_presentation_details.html.haml +56 -55
  71. data/app/views/spina/admin/conferences/presentations/index.html.haml +1 -12
  72. data/app/views/spina/admin/conferences/rooms/_form.html.haml +3 -3
  73. data/app/views/spina/admin/conferences/rooms/_form_room_details.html.haml +13 -15
  74. data/app/views/spina/admin/conferences/rooms/index.html.haml +1 -12
  75. data/app/views/spina/admin/conferences/sessions/_form.html.haml +3 -3
  76. data/app/views/spina/admin/conferences/sessions/_form_session_details.html.haml +18 -20
  77. data/app/views/spina/admin/conferences/sessions/_session.html.haml +1 -1
  78. data/app/views/spina/admin/conferences/sessions/index.html.haml +1 -12
  79. data/app/views/spina/admin/hooks/conferences/_head.html.haml +5 -0
  80. data/app/views/spina/admin/hooks/conferences/_primary_navigation.html.haml +15 -14
  81. data/app/views/spina/admin/hooks/conferences/_settings_secondary_navigation.html.haml +4 -2
  82. data/app/views/spina/admin/parts/admin/conferences/dates/_form.html.haml +2 -0
  83. data/app/views/spina/admin/parts/admin/conferences/email_addresses/_form.html.haml +2 -0
  84. data/app/views/spina/admin/parts/admin/conferences/times/_form.html.haml +2 -0
  85. data/app/views/spina/admin/parts/admin/conferences/urls/_form.html.haml +2 -0
  86. data/config/initializers/assets.rb +1 -1
  87. data/config/locales/en.yml +26 -29
  88. data/db/migrate/20200911161739_move_conference_parts.rb +10 -8
  89. data/db/migrate/20201007125625_add_timestamps_to_spina_conferences_parts.rb +4 -3
  90. data/db/migrate/20210315164409_add_json_attributes_to_spina_conferences_presentations.rb +7 -0
  91. data/db/migrate/20210315164410_add_json_attributes_to_spina_conferences_conferences.rb +7 -0
  92. data/db/migrate/20210315164411_convert_partables_to_json.rb +407 -0
  93. data/lib/spina/admin/conferences.rb +2 -0
  94. data/lib/spina/admin/conferences/engine.rb +7 -0
  95. data/lib/spina/admin/conferences/version.rb +1 -1
  96. data/lib/tasks/spina/admin/conferences_tasks.rake +11 -1
  97. metadata +87 -63
  98. data/app/assets/javascripts/spina/admin/conferences/application.es6 +0 -20
  99. data/app/helpers/spina/admin/conferences/conferences_helper.rb +0 -44
  100. data/app/models/spina/admin/conferences/date_part.rb +0 -15
  101. data/app/models/spina/admin/conferences/email_address_part.rb +0 -21
  102. data/app/models/spina/admin/conferences/part.rb +0 -20
  103. data/app/models/spina/admin/conferences/time_part.rb +0 -53
  104. data/app/models/spina/admin/conferences/url_part.rb +0 -21
  105. data/app/views/spina/admin/conferences/application/_errors.js.erb +0 -2
  106. data/app/views/spina/admin/conferences/conferences/_form_presentations.html.haml +0 -12
  107. data/app/views/spina/admin/conferences/delegates/_form_presentations.html.haml +0 -12
  108. data/app/views/spina/admin/conferences/dietary_requirements/_form_delegates.html.haml +0 -12
  109. data/app/views/spina/admin/conferences/institutions/_form_delegates.html.haml +0 -12
  110. data/app/views/spina/admin/conferences/institutions/_form_rooms.html.haml +0 -12
  111. data/app/views/spina/admin/conferences/presentation_types/_form_presentations.html.haml +0 -12
  112. data/app/views/spina/admin/conferences/presentations/_form_presenters.html.haml +0 -12
  113. data/app/views/spina/admin/conferences/sessions/_form_presentations.html.haml +0 -12
  114. data/app/views/spina/admin/partables/admin/conferences/date_parts/_form.html.haml +0 -5
  115. data/app/views/spina/admin/partables/admin/conferences/email_address_parts/_form.html.haml +0 -5
  116. data/app/views/spina/admin/partables/admin/conferences/time_parts/_form.html.haml +0 -7
  117. data/app/views/spina/admin/partables/admin/conferences/url_parts/_form.html.haml +0 -5
  118. data/config/initializers/types.rb +0 -13
  119. data/lib/spina/admin/conferences/types/interval_type.rb +0 -29
@@ -2,8 +2,9 @@
2
2
 
3
3
  class AddTimestampsToSpinaConferencesParts < ActiveRecord::Migration[6.0]
4
4
  def change
5
- add_timestamps :spina_conferences_parts, default: Time.now
6
- change_column_default :spina_conferences_parts, :created_at, nil
7
- change_column_default :spina_conferences_parts, :updated_at, nil
5
+ default = Time.now
6
+ add_timestamps :spina_conferences_parts, default: default
7
+ change_column_default :spina_conferences_parts, :created_at, from: default, to: nil
8
+ change_column_default :spina_conferences_parts, :updated_at, from: default, to: nil
8
9
  end
9
10
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddJsonAttributesToSpinaConferencesPresentations < ActiveRecord::Migration[6.1] # :nodoc:
4
+ def change
5
+ add_column :spina_conferences_presentations, :json_attributes, :jsonb
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddJsonAttributesToSpinaConferencesConferences < ActiveRecord::Migration[6.1] # :nodoc:
4
+ def change
5
+ add_column :spina_conferences_conferences, :json_attributes, :jsonb
6
+ end
7
+ end
@@ -0,0 +1,407 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Reregistering parts necessary due to deserialization from JSON, where class instances from registration used
4
+ Spina::Part.all.delete_if { |part| Spina::Parts::Admin::Conferences.constants.include? :"#{part.name.demodulize}" }
5
+ Spina::Part.register(Spina::Parts::Admin::Conferences::Date)
6
+ Spina::Part.register(Spina::Parts::Admin::Conferences::EmailAddress)
7
+ Spina::Part.register(Spina::Parts::Admin::Conferences::Time)
8
+ Spina::Part.register(Spina::Parts::Admin::Conferences::Url)
9
+
10
+ # This migration converts table-based partables from Spina v1 to the new JSON-based parts in Spina v2.
11
+ # If you have custom partables you must modify this migration to ensure the conversion of your partables is handled appropriately
12
+ # by implementing <tt>convert_to_json!</tt> for your partables.
13
+ class ConvertPartablesToJson < ActiveRecord::Migration[6.1]
14
+ def up # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
15
+ announce 'converting partables to JSON parts'
16
+ Spina.config.locales.each do |locale|
17
+ I18n.with_locale(locale) do
18
+ say_with_time "Migrating content in locale #{I18n.locale}..." do
19
+ Spina::Page.in_batches.each_record do |page|
20
+ say "Migrating page parts for \"#{page.title}\"...", true
21
+ page.convert_page_parts_to_json!
22
+ end
23
+ Spina::Account.in_batches.each_record do |account|
24
+ say "Migrating layout parts for \"#{account.name}\"...", true
25
+ account.convert_layout_parts_to_json!
26
+ end
27
+ Spina::Admin::Conferences::Conference.in_batches.each_record do |conference|
28
+ say "Migrating parts for \"#{conference.name}\"...", true
29
+ conference.convert_parts_to_json!
30
+ end
31
+ Spina::Admin::Conferences::Presentation.in_batches.each_record do |presentation|
32
+ say "Migrating parts for \"#{presentation.title}\"...", true
33
+ presentation.convert_parts_to_json!
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def down # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
41
+ announce 'converting JSON parts to partables'
42
+ Spina.config.locales.each do |locale|
43
+ I18n.with_locale(locale) do
44
+ say_with_time "Migrating content in locale #{I18n.locale}..." do
45
+ Spina::Page.in_batches.each_record do |page|
46
+ say "Migrating JSON parts for \"#{page.title}\"...", true
47
+ page.convert_json_to_parts!
48
+ end
49
+ Spina::Account.in_batches.each_record do |account|
50
+ say "Migrating JSON parts for \"#{account.name}\"...", true
51
+ account.convert_json_to_parts!
52
+ end
53
+ Spina::Admin::Conferences::Conference.in_batches.each_record do |conference|
54
+ say "Migrating JSON parts for \"#{conference.name}\"...", true
55
+ conference.convert_json_to_parts!
56
+ end
57
+ Spina::Admin::Conferences::Presentation.in_batches.each_record do |presentation|
58
+ say "Migrating JSON parts for \"#{presentation.title}\"...", true
59
+ presentation.convert_json_to_parts!
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ module Spina # :nodoc: all
68
+ class ImageCollectionsImage < Spina::ApplicationRecord
69
+ belongs_to :image
70
+ belongs_to :image_collection
71
+ end
72
+
73
+ class AttachmentCollectionsAttachment < Spina::ApplicationRecord
74
+ belongs_to :attachment
75
+ belongs_to :attachment_collection
76
+ end
77
+
78
+ class Attachment < ApplicationRecord
79
+ def convert_to_json!
80
+ Parts::Attachment.new(attachment_id: id, signed_blob_id: file.blob.signed_id, filename: file.blob.filename)
81
+ end
82
+ end
83
+
84
+ class AttachmentCollection < ApplicationRecord
85
+ has_many :attachment_collection_attachments
86
+ has_many :attachments, through: :attachment_collection_attachments
87
+
88
+ def convert_to_json!
89
+ Parts::Repeater.new(content: attachments.collect(&:convert_to_json!)
90
+ .collect { |attachment| RepeaterContent.new(parts: [attachment]) })
91
+ end
92
+ end
93
+
94
+ class Image < ApplicationRecord
95
+ def convert_to_json!
96
+ Parts::Image.new(image_id: id, signed_blob_id: file.blob.signed_id, filename: file.blob.filename)
97
+ end
98
+ end
99
+
100
+ class ImageCollection < ApplicationRecord
101
+ has_many :image_collections_images
102
+ has_many :images, through: :image_collections_images
103
+
104
+ def convert_to_json!
105
+ Parts::ImageCollection.new(images: images.order(:position).collect(&:convert_to_json!))
106
+ end
107
+ end
108
+
109
+ class Line < ApplicationRecord
110
+ extend Mobility
111
+ translates :content, fallbacks: true
112
+
113
+ def convert_to_json!
114
+ Parts::Line.new(content: content)
115
+ end
116
+ end
117
+
118
+ class Option < ApplicationRecord
119
+ def convert_to_json!
120
+ Parts::Option.new(content: content)
121
+ end
122
+
123
+ private
124
+
125
+ def content
126
+ I18n.t(['options', part.name, value].compact.join('.'))
127
+ end
128
+
129
+ def part
130
+ page_part || layout_part || structure_part
131
+ end
132
+ end
133
+
134
+ class Structure < ApplicationRecord
135
+ has_many :structure_items
136
+ has_one :page_part, as: :page_partable
137
+ has_one :layout_part, as: :layout_partable
138
+ has_one :part, as: :partable, class_name: 'Spina::Admin::Conferences::Part'
139
+
140
+ def convert_to_json!
141
+ Parts::Repeater.new(content: structure_items.order(:position)
142
+ .collect(&:convert_to_json!)
143
+ .each { |structure_item| structure_item.name = present_part.name })
144
+ end
145
+
146
+ def present_part
147
+ page_part || layout_part || part
148
+ end
149
+ end
150
+
151
+ class Text < ApplicationRecord
152
+ extend Mobility
153
+ translates :content, fallbacks: true
154
+
155
+ def convert_to_json!
156
+ Parts::Text.new(content: content)
157
+ end
158
+ end
159
+
160
+ class LayoutPart < ::Spina::ApplicationRecord
161
+ belongs_to :account
162
+ belongs_to :layout_partable, polymorphic: true
163
+
164
+ def convert_to_json!
165
+ raise <<~MESSAGE unless layout_partable.respond_to? :convert_to_json!
166
+ Cannot convert an instance of #{layout_partable_type} to JSON.
167
+ You need to modify #{__FILE__} and implement `convert_to_json!` for this partable.
168
+ MESSAGE
169
+
170
+ layout_partable.convert_to_json!.tap { |layout_partable| layout_partable.name = name }
171
+ end
172
+ end
173
+
174
+ class PagePart < ::Spina::ApplicationRecord
175
+ belongs_to :page
176
+ belongs_to :page_partable, polymorphic: true
177
+
178
+ def convert_to_json!
179
+ raise <<~MESSAGE unless page_partable.respond_to? :convert_to_json!
180
+ Cannot convert an instance of #{page_partable_type} to JSON.
181
+ You need to modify #{__FILE__} and implement `convert_to_json!` for this partable.
182
+ MESSAGE
183
+
184
+ page_partable.convert_to_json!.tap { |page_partable| page_partable.name = name }
185
+ end
186
+ end
187
+
188
+ class StructurePart < ::Spina::ApplicationRecord
189
+ belongs_to :structure_item
190
+ belongs_to :structure_partable, polymorphic: true
191
+
192
+ def convert_to_json!
193
+ raise <<~MESSAGE unless structure_partable.respond_to? :convert_to_json!
194
+ Cannot convert an instance of #{structure_partable_type} to JSON.
195
+ You need to modify #{__FILE__} and implement `convert_to_json!` for this partable.
196
+ MESSAGE
197
+
198
+ structure_partable.convert_to_json!.tap { |structure_partable| structure_partable.name = name }
199
+ end
200
+ end
201
+
202
+ class Page < Spina::ApplicationRecord
203
+ has_many :page_parts
204
+
205
+ def convert_page_parts_to_json!
206
+ page_parts.reject { |page_part| page_part.page_partable.nil? }
207
+ .collect(&:convert_to_json!)
208
+ .compact
209
+ .then { |parts| send(:"#{I18n.locale}_content").union(parts) }
210
+ .then { |parts| update("#{I18n.locale}_content": parts) }
211
+ end
212
+
213
+ def convert_json_to_parts!
214
+ update(page_parts: send(:"#{I18n.locale}_content").collect(&:convert_to_partable!)
215
+ .compact
216
+ .collect { |partable| PagePart.new(page_partable: partable) })
217
+ end
218
+ end
219
+
220
+ class Account < Spina::ApplicationRecord
221
+ has_many :layout_parts
222
+
223
+ def convert_layout_parts_to_json!
224
+ layout_parts.reject { |layout_part| layout_part.layout_partable.nil? }
225
+ .collect(&:convert_to_json!)
226
+ .compact
227
+ .then { |parts| send(:"#{I18n.locale}_content").union(parts) }
228
+ .then { |parts| update("#{I18n.locale}_content": parts) }
229
+ end
230
+
231
+ def convert_json_to_parts!
232
+ update(layout_parts: send(:"#{I18n.locale}_content")
233
+ .collect(&:convert_to_partable!)
234
+ .compact
235
+ .collect { |partable| LayoutPart.new(layout_partable: partable) })
236
+ end
237
+ end
238
+
239
+ class StructureItem < Spina::ApplicationRecord
240
+ belongs_to :structure
241
+ has_many :structure_parts
242
+
243
+ def convert_to_json!
244
+ Parts::RepeaterContent.new(parts: structure_parts.reject { |structure_part| structure_part.structure_partable.nil? }
245
+ .collect(&:convert_to_json!)
246
+ .compact)
247
+ end
248
+ end
249
+
250
+ module Parts # :nodoc: all
251
+ class Attachment < Base
252
+ def convert_to_partable!
253
+ Spina::Attachment.find(attachment_id)
254
+ end
255
+ end
256
+
257
+ class Image < Base
258
+ def convert_to_partable!
259
+ Spina::Image.find(image_id)
260
+ end
261
+ end
262
+
263
+ class ImageCollection < Base
264
+ def convert_to_partable!
265
+ Spina::ImageCollection.new(images: images.collect(&:convert_to_partable!))
266
+ end
267
+ end
268
+
269
+ class Line < Base
270
+ def convert_to_partable!
271
+ Spina::Line.new(content: content)
272
+ end
273
+ end
274
+
275
+ class MultiLine < Base
276
+ def convert_to_partable!
277
+ Spina::Text.new(content: content)
278
+ end
279
+ end
280
+
281
+ class Text < Base
282
+ def convert_to_partable!
283
+ Spina::Text.new(content: content)
284
+ end
285
+ end
286
+
287
+ class Option < Base
288
+ def convert_to_partable!
289
+ Spina::Option.new(content: content)
290
+ end
291
+ end
292
+
293
+ class Repeater < Base
294
+ def convert_to_partable!
295
+ Spina::Structure.new(structure_items: content.collect(&:convert_to_structure_item!))
296
+ end
297
+ end
298
+
299
+ class RepeaterContent < Base
300
+ def convert_to_structure_item!
301
+ Spina::StructureItem.new(structure_parts: parts.collect(&:convert_to_partable!)
302
+ .compact
303
+ .collect { |partable| StructurePart.new(structure_partable: partable) })
304
+ end
305
+ end
306
+
307
+ module Admin
308
+ module Conferences
309
+ class Date < Spina::Parts::Base
310
+ def convert_to_partable!
311
+ Spina::Admin::Conferences::DatePart.new(content: content)
312
+ end
313
+ end
314
+
315
+ class EmailAddress < Spina::Parts::Base
316
+ def convert_to_partable!
317
+ Spina::Admin::Conferences::EmailAddressPart.new(content: content)
318
+ end
319
+ end
320
+
321
+ class Time < Spina::Parts::Base
322
+ def convert_to_partable!
323
+ Spina::Admin::Conferences::TimePart.new(content: content)
324
+ end
325
+ end
326
+
327
+ class Url < Spina::Parts::Base
328
+ def convert_to_partable!
329
+ Spina::Admin::Conferences::UrlPart.new(content: content)
330
+ end
331
+ end
332
+ end
333
+ end
334
+ end
335
+
336
+ module Admin
337
+ module Conferences
338
+ class DatePart < ApplicationRecord
339
+ def convert_to_json!
340
+ Spina::Parts::Admin::Conferences::Date.new(content: content)
341
+ end
342
+ end
343
+
344
+ class EmailAddressPart < ApplicationRecord
345
+ def convert_to_json!
346
+ Spina::Parts::Admin::Conferences::EmailAddress.new(content: content)
347
+ end
348
+ end
349
+
350
+ class TimePart < ApplicationRecord
351
+ def convert_to_json!
352
+ Spina::Parts::Admin::Conferences::Time.new(content: content)
353
+ end
354
+ end
355
+
356
+ class UrlPart < ApplicationRecord
357
+ def convert_to_json!
358
+ Spina::Parts::Admin::Conferences::Url.new(content: content)
359
+ end
360
+ end
361
+
362
+ class Part < ApplicationRecord
363
+ belongs_to :pageable, polymorphic: true
364
+ belongs_to :partable, polymorphic: true
365
+
366
+ def convert_to_json!
367
+ raise <<~MESSAGE unless partable.respond_to? :convert_to_json!
368
+ Cannot convert an instance of #{partable_type} to JSON.
369
+ You need to modify #{__FILE__} and implement `convert_to_json!` for this partable.
370
+ MESSAGE
371
+
372
+ partable.convert_to_json!.tap { |partable| partable.name = name }
373
+ end
374
+ end
375
+
376
+ module Pageable
377
+ extend ActiveSupport::Concern
378
+
379
+ included do
380
+ has_many :parts, as: :pageable
381
+
382
+ def convert_parts_to_json!
383
+ parts.reject { |part| part.partable.nil? }
384
+ .collect(&:convert_to_json!)
385
+ .compact
386
+ .then { |parts| send(:"#{I18n.locale}_content").union(parts) }
387
+ .then { |parts| update("#{I18n.locale}_content": parts) }
388
+ end
389
+
390
+ def convert_json_to_parts!
391
+ update(parts: send(:"#{I18n.locale}_content").collect(&:convert_to_partable!)
392
+ .compact
393
+ .collect { |partable| Part.new(partable: partable) })
394
+ end
395
+ end
396
+ end
397
+
398
+ class Conference < ApplicationRecord
399
+ include Pageable
400
+ end
401
+
402
+ class Presentation < ApplicationRecord
403
+ include Pageable
404
+ end
405
+ end
406
+ end
407
+ end
@@ -4,6 +4,8 @@ require 'spina'
4
4
  require 'spina/admin/conferences/engine'
5
5
  require 'spina/admin/conferences/railtie' if defined?(Rails::Railtie)
6
6
  require 'rails-i18n'
7
+ require 'stimulus-rails'
8
+ require 'turbo-rails'
7
9
  require 'icalendar'
8
10
 
9
11
  # Spina content management system.
@@ -6,6 +6,8 @@ module Spina
6
6
  # Engine class for the plugin. This is where the plugin is registered as a {Spina::Plugin} with {Spina}.
7
7
  # @note The +name+ and +namespace+ of the {Spina::Plugin} object is +'conferences'+ (for compatibility reasons).
8
8
  class Engine < ::Rails::Engine
9
+ isolate_namespace Spina::Admin::Conferences
10
+
9
11
  config.before_initialize do
10
12
  ::Spina::Plugin.register do |plugin|
11
13
  plugin.name = 'conferences'
@@ -14,6 +16,11 @@ module Spina
14
16
  end
15
17
 
16
18
  config.after_initialize do
19
+ Spina::Part.register(Spina::Parts::Admin::Conferences::Date)
20
+ Spina::Part.register(Spina::Parts::Admin::Conferences::EmailAddress)
21
+ Spina::Part.register(Spina::Parts::Admin::Conferences::Time)
22
+ Spina::Part.register(Spina::Parts::Admin::Conferences::Url)
23
+
17
24
  ActiveSupport::Deprecation
18
25
  .new('2.0', 'Spina::Admin::Conferences')
19
26
  .tap { |deprecator| deprecator.deprecate_methods(Conference, to_ics: :to_event) }