spina-admin-conferences 1.3.7 → 2.0.0

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 (117) 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/20210315164409_add_json_attributes_to_spina_conferences_presentations.rb +7 -0
  89. data/db/migrate/20210315164410_add_json_attributes_to_spina_conferences_conferences.rb +7 -0
  90. data/db/migrate/20210315164411_convert_partables_to_json.rb +407 -0
  91. data/lib/spina/admin/conferences.rb +2 -0
  92. data/lib/spina/admin/conferences/engine.rb +7 -0
  93. data/lib/spina/admin/conferences/version.rb +1 -1
  94. data/lib/tasks/spina/admin/conferences_tasks.rake +11 -1
  95. metadata +85 -61
  96. data/app/assets/javascripts/spina/admin/conferences/application.es6 +0 -20
  97. data/app/helpers/spina/admin/conferences/conferences_helper.rb +0 -44
  98. data/app/models/spina/admin/conferences/date_part.rb +0 -15
  99. data/app/models/spina/admin/conferences/email_address_part.rb +0 -21
  100. data/app/models/spina/admin/conferences/part.rb +0 -20
  101. data/app/models/spina/admin/conferences/time_part.rb +0 -53
  102. data/app/models/spina/admin/conferences/url_part.rb +0 -21
  103. data/app/views/spina/admin/conferences/application/_errors.js.erb +0 -2
  104. data/app/views/spina/admin/conferences/conferences/_form_presentations.html.haml +0 -12
  105. data/app/views/spina/admin/conferences/delegates/_form_presentations.html.haml +0 -12
  106. data/app/views/spina/admin/conferences/dietary_requirements/_form_delegates.html.haml +0 -12
  107. data/app/views/spina/admin/conferences/institutions/_form_delegates.html.haml +0 -12
  108. data/app/views/spina/admin/conferences/institutions/_form_rooms.html.haml +0 -12
  109. data/app/views/spina/admin/conferences/presentation_types/_form_presentations.html.haml +0 -12
  110. data/app/views/spina/admin/conferences/presentations/_form_presenters.html.haml +0 -12
  111. data/app/views/spina/admin/conferences/sessions/_form_presentations.html.haml +0 -12
  112. data/app/views/spina/admin/partables/admin/conferences/date_parts/_form.html.haml +0 -5
  113. data/app/views/spina/admin/partables/admin/conferences/email_address_parts/_form.html.haml +0 -5
  114. data/app/views/spina/admin/partables/admin/conferences/time_parts/_form.html.haml +0 -7
  115. data/app/views/spina/admin/partables/admin/conferences/url_parts/_form.html.haml +0 -5
  116. data/config/initializers/types.rb +0 -13
  117. data/lib/spina/admin/conferences/types/interval_type.rb +0 -29
@@ -9,15 +9,4 @@
9
9
  = icon 'plus'
10
10
  = t '.new'
11
11
 
12
- .well
13
- .table-container
14
- %table.table
15
- %thead
16
- %tr
17
- %th= Spina::Admin::Conferences::Presentation.human_attribute_name :conference
18
- %th= Spina::Admin::Conferences::Presentation.human_attribute_name :title
19
- %th= Spina::Admin::Conferences::Presentation.human_attribute_name :presenters
20
- %th
21
-
22
- %tbody
23
- = render @presentations.any? ? @presentations : 'empty_list', message: t('.no_presentations')
12
+ = render partial: 'presentations', object: @presentations
@@ -2,7 +2,7 @@
2
2
  - content_for :notifications do
3
3
  = render 'errors', errors: @room.errors
4
4
 
5
- = form_for @room, remote: true, html: { autocomplete: 'off' } do |f|
5
+ = form_for [:admin_conferences, @room], html: { autocomplete: 'off' } do |f|
6
6
  %header#header
7
7
  = render partial: 'spina/admin/shared/breadcrumbs'
8
8
 
@@ -19,5 +19,5 @@
19
19
  %li{ class: ('active'if i == 0)}
20
20
  = link_to t(".#{tab}"), "##{tab}"
21
21
 
22
- - @tabs.each do |tab|
23
- = render "form_#{tab}", f: f
22
+ #room_details.tab-content.active= render 'form_room_details', f: f
23
+ #presentations.tab-content= render partial: 'presentations', object: @room.presentations
@@ -1,18 +1,16 @@
1
- #room_details.tab-content.active
2
- .well
3
- .horizontal-form
4
- .horizontal-form-group
5
- .horizontal-form-label= Spina::Admin::Conferences::Room.human_attribute_name :institution
6
- .horizontal-form-content
7
- .select-dropdown= f.collection_select :institution_id, Spina::Admin::Conferences::Institution.all, :id, :name, {}, required: true
1
+ .page-form
2
+ .page-form-group
3
+ .page-form-label= Spina::Admin::Conferences::Room.human_attribute_name :institution
4
+ .page-form-control
5
+ .select-dropdown= f.collection_select :institution_id, Spina::Admin::Conferences::Institution.all, :id, :name, {}, required: true
8
6
 
9
- .horizontal-form-group
10
- .horizontal-form-label= Spina::Admin::Conferences::Room.human_attribute_name :building
11
- .horizontal-form-content= f.text_field :building, placeholder: Spina::Admin::Conferences::Room.human_attribute_name(:building), required: true
7
+ .page-form-group
8
+ .page-form-label= Spina::Admin::Conferences::Room.human_attribute_name :building
9
+ .page-form-control= f.text_field :building, placeholder: Spina::Admin::Conferences::Room.human_attribute_name(:building), required: true
12
10
 
13
- .horizontal-form-group
14
- .horizontal-form-label= Spina::Admin::Conferences::Room.human_attribute_name :number
15
- .horizontal-form-content= f.text_field :number, placeholder: Spina::Admin::Conferences::Room.human_attribute_name(:number), required: true
11
+ .page-form-group
12
+ .page-form-label= Spina::Admin::Conferences::Room.human_attribute_name :number
13
+ .page-form-control= f.text_field :number, placeholder: Spina::Admin::Conferences::Room.human_attribute_name(:number), required: true
16
14
 
17
- - unless @room.new_record?
18
- .pull-right= link_to t('spina.permanently_delete'), admin_conferences_room_path(@room), method: :delete, remote: true, data: { confirm: t('.delete_confirmation', room: @room.name) }, class: %w[button button-link button-danger]
15
+ - unless @room.new_record?
16
+ .pull-right= link_to t('spina.permanently_delete'), admin_conferences_room_path(@room), method: :delete, data: { confirm: t('.delete_confirmation', room: @room.name) }, class: %w[button button-link button-danger]
@@ -3,15 +3,4 @@
3
3
  = icon 'plus'
4
4
  = t '.new'
5
5
 
6
- .well
7
- .table-container
8
- %table.table
9
- %thead
10
- %tr
11
- %th= Spina::Admin::Conferences::Room.human_attribute_name :institution
12
- %th= Spina::Admin::Conferences::Room.human_attribute_name :building
13
- %th= Spina::Admin::Conferences::Room.human_attribute_name :number
14
- %th
15
-
16
- %tbody
17
- = render @rooms.any? ? @rooms : 'empty_list', message: t('.no_rooms')
6
+ = render partial: 'rooms', object: @rooms
@@ -2,7 +2,7 @@
2
2
  - content_for :notifications do
3
3
  = render 'errors', errors: @session.errors
4
4
 
5
- = form_for @session, remote: true, html: { autocomplete: 'off' } do |f|
5
+ = form_for [:admin_conferences, @session], html: { autocomplete: 'off' } do |f|
6
6
  %header#header
7
7
  = render partial: 'spina/admin/shared/breadcrumbs'
8
8
 
@@ -19,5 +19,5 @@
19
19
  %li{ class: ('active'if i == 0)}
20
20
  = link_to t(".#{tab}"), "##{tab}"
21
21
 
22
- - @tabs.each do |tab|
23
- = render "form_#{tab}", f: f
22
+ #session_details.tab-content.active= render 'form_session_details', f: f
23
+ #presentations.tab-content= render partial: 'presentations', object: @session.presentations
@@ -1,23 +1,21 @@
1
- #session_details.tab-content.active
2
- .well
3
- .horizontal-form
4
- .horizontal-form-group
5
- .horizontal-form-label= Spina::Admin::Conferences::Session.human_attribute_name :name
6
- .horizontal-form-content= f.text_field :name, placeholder: Spina::Admin::Conferences::Session.human_attribute_name(:name), required: true
1
+ .page-form
2
+ .page-form-group
3
+ .page-form-label= Spina::Admin::Conferences::Session.human_attribute_name :name
4
+ .page-form-control= f.text_field :name, placeholder: Spina::Admin::Conferences::Session.human_attribute_name(:name), required: true
7
5
 
8
- .horizontal-form-group
9
- .horizontal-form-label= Spina::Admin::Conferences::Session.human_attribute_name :presentation_type
10
- .horizontal-form-content
11
- .input-group{ data: { controller: 'select-options', select_options: { record_values: @conferences } } }
12
- .select-dropdown= select_tag :admin_conferences_conference_id, options_from_collection_for_select(Spina::Admin::Conferences::Conference.all, :id, :name, (@session.conference.id unless @session.conference.blank?)), include_blank: true, required: true, data: { action: 'select-options#setVisibility', select_options_target: 'select', text_key: 'name' }
13
- .select-dropdown= f.collection_select :presentation_type_id, @session.conference.present? ? @session.conference.presentation_types : Spina::Admin::Conferences::Conference.first.presentation_types, :id, :name, { include_blank: true }, required: true, data: { select_options_target: 'select', text_key: 'name', key_path: 'presentation_types' }
6
+ .page-form-group
7
+ .page-form-label= Spina::Admin::Conferences::Session.human_attribute_name :presentation_type
8
+ .page-form-control
9
+ .input-group{ data: { controller: 'spina--admin--conferences--select-options', 'spina--admin--conferences--select_options': { record_value: @conferences } } }
10
+ .select-dropdown= select_tag :conference_id, options_from_collection_for_select(Spina::Admin::Conferences::Conference.all, :id, :name, (@session.conference.id unless @session.conference.blank?)), include_blank: true, required: true, data: { action: 'spina--admin--conferences--select-options#setVisibility','spina--admin--conferences--select_options_target': 'select', text_key: 'name' }
11
+ .select-dropdown= f.collection_select :presentation_type_id, @session.conference.present? ? @session.conference.presentation_types : Spina::Admin::Conferences::Conference.first.presentation_types, :id, :name, { include_blank: true }, required: true, data: {'spina--admin--conferences--select_options_target': 'select', text_key: 'name', key_path: 'presentation_types' }
14
12
 
15
- .horizontal-form-group
16
- .horizontal-form-label= Spina::Admin::Conferences::Session.human_attribute_name :room
17
- .horizontal-form-content
18
- .input-group{ data: { controller: 'select-options', select_options: { record_values: @institutions } } }
19
- .select-dropdown= select_tag :admin_conferences_institution_id, options_from_collection_for_select(Spina::Admin::Conferences::Institution.all, :id, :name, (@session.institution.id unless @session.institution.blank?)), include_blank: true, required: true, data: { action: 'select-options#setVisibility', select_options_target: 'select', text_key: 'name' }
20
- .select-dropdown= f.collection_select :room_id, @session.institution.present? ? @session.institution.rooms : Spina::Admin::Conferences::Institution.first.rooms, :id, :name, { include_blank: true }, required: true, data: { select_options_target: 'select', text_key: 'name', key_path: 'rooms' }
13
+ .page-form-group
14
+ .page-form-label= Spina::Admin::Conferences::Session.human_attribute_name :room
15
+ .page-form-control
16
+ .input-group{ data: { controller: 'spina--admin--conferences--select-options', 'spina--admin--conferences--select_options': { record_value: @institutions } } }
17
+ .select-dropdown= select_tag :institution_id, options_from_collection_for_select(Spina::Admin::Conferences::Institution.all, :id, :name, (@session.institution.id unless @session.institution.blank?)), include_blank: true, required: true, data: { action: 'spina--admin--conferences--select-options#setVisibility','spina--admin--conferences--select_options_target': 'select', text_key: 'name' }
18
+ .select-dropdown= f.collection_select :room_id, @session.institution.present? ? @session.institution.rooms : Spina::Admin::Conferences::Institution.first.rooms, :id, :name, { include_blank: true }, required: true, data: {'spina--admin--conferences--select_options_target': 'select', text_key: 'name', key_path: 'rooms' }
21
19
 
22
- - unless @session.new_record?
23
- .pull-right= link_to t('spina.permanently_delete'), admin_conferences_session_path(@session), method: :delete, remote: true, data: { confirm: t('.delete_confirmation', session: @session.name) }, class: %w[button button-link button-danger]
20
+ - unless @session.new_record?
21
+ .pull-right= link_to t('spina.permanently_delete'), admin_conferences_session_path(@session), method: :delete, data: { confirm: t('.delete_confirmation', session: @session.name) }, class: %w[button button-link button-danger]
@@ -1,5 +1,5 @@
1
1
  %tr{ data: { session_id: session.id } }
2
- %td= session.name
2
+ %td= link_to session.name, edit_admin_conferences_session_path(session)
3
3
  %td= session.presentation_type_name
4
4
  %td= session.room_name
5
5
  %td.align-right
@@ -3,15 +3,4 @@
3
3
  = icon 'plus'
4
4
  = t '.new'
5
5
 
6
- .well
7
- .table-container
8
- %table.table
9
- %thead
10
- %tr
11
- %th= Spina::Admin::Conferences::Session.human_attribute_name :name
12
- %th= Spina::Admin::Conferences::Session.human_attribute_name :presentation_type
13
- %th= Spina::Admin::Conferences::Session.human_attribute_name :room
14
- %th
15
-
16
- %tbody
17
- = render @sessions.any? ? @sessions : 'empty_list', message: t('.no_sessions')
6
+ = render partial: 'sessions', object: @sessions
@@ -1,2 +1,7 @@
1
+ %meta{ name: 'turbo-root', content: '/admin/conferences' }
2
+ %meta{name: 'turbo-cache-control', content: 'no-preview'}
1
3
  = stylesheet_link_tag 'spina/admin/conferences/application', media: 'all', data: { turbolinks_track: true }
4
+ = stimulus_include_tags
5
+ = javascript_include_tag 'turbo', type: 'module-shim'
2
6
  = javascript_include_tag 'spina/admin/conferences/application'
7
+ = yield :head
@@ -1,20 +1,21 @@
1
- %li{ class: ('active' if %w[conferences delegates presentations dietary_requirements presentation_types institutions rooms].include? controller_name) }
1
+ %li#conferences-primary-navigation{ data: { turbolinks: 'false', turbo: 'permanent' },
2
+ class: ('active' if %w[conferences delegates presentations presentation_types institutions rooms].include? controller_name) }
2
3
  = link_to admin_conferences_presentations_path do
3
4
  = icon('comment')
4
5
  = t("spina.admin.conferences.title")
5
6
  = icon('caret-right')
6
7
 
7
- %ul
8
- %li{ class: ('active' if %w[institutions rooms].include? controller_name) }
9
- = link_to Spina::Admin::Conferences::Institution.model_name.human(count: 0), spina.admin_conferences_institutions_path
10
- %li{ class: ('active' if %w[conferences presentation_types sessions].include? controller_name) }
11
- = link_to Spina::Admin::Conferences::Conference.model_name.human(count: 0), spina.admin_conferences_conferences_path
12
- %li{ class: ('active' if %w[delegates dietary_requirements].include? controller_name) }
13
- = link_to Spina::Admin::Conferences::Delegate.model_name.human(count: 0), spina.admin_conferences_delegates_path
14
- %li{ class: ('active' if %w[presentations].include? controller_name) }
15
- = link_to Spina::Admin::Conferences::Presentation.model_name.human(count: 0), spina.admin_conferences_presentations_path
8
+ %ul
9
+ %li{ class: ('active' if %w[institutions rooms].include? controller_name) }
10
+ = link_to Spina::Admin::Conferences::Institution.model_name.human(count: 0), admin_conferences_institutions_path
11
+ %li{ class: ('active' if %w[conferences presentation_types sessions].include? controller_name) }
12
+ = link_to Spina::Admin::Conferences::Conference.model_name.human(count: 0), admin_conferences_conferences_path
13
+ %li{ class: ('active' if %w[delegates].include? controller_name) }
14
+ = link_to Spina::Admin::Conferences::Delegate.model_name.human(count: 0), admin_conferences_delegates_path
15
+ %li{ class: ('active' if %w[presentations].include? controller_name) }
16
+ = link_to Spina::Admin::Conferences::Presentation.model_name.human(count: 0), admin_conferences_presentations_path
16
17
 
17
- %li
18
- = link_to '#', class: 'back-to-main-menu' do
19
- = icon('caret-left')
20
- =t 'spina.main_menu'
18
+ %li
19
+ = link_to '#', class: 'back-to-main-menu' do
20
+ = icon('caret-left')
21
+ =t 'spina.main_menu'
@@ -1,4 +1,6 @@
1
1
  %li{ class: ('active' if %w[dietary_requirements].include? controller_name) }
2
- = link_to Spina::Admin::Conferences::DietaryRequirement.model_name.human(count: 0), spina.admin_conferences_dietary_requirements_path
2
+ = link_to Spina::Admin::Conferences::DietaryRequirement.model_name.human(count: 0), admin_conferences_dietary_requirements_path,
3
+ data: { turbolinks: 'false' }
3
4
  %li{ class: ('active' if %w[presentation_attachment_types].include? controller_name) }
4
- = link_to Spina::Admin::Conferences::PresentationAttachmentType.model_name.human(count: 0), spina.admin_conferences_presentation_attachment_types_path
5
+ = link_to Spina::Admin::Conferences::PresentationAttachmentType.model_name.human(count: 0), admin_conferences_presentation_attachment_types_path,
6
+ data: { turbolinks: 'false' }
@@ -0,0 +1,2 @@
1
+ .page-form-label= f.object.title
2
+ .page-form-control= f.date_field :content, placeholder: f.object.title
@@ -0,0 +1,2 @@
1
+ .page-form-label= f.object.title
2
+ .page-form-control= f.email_field :content, placeholder: f.object.title
@@ -0,0 +1,2 @@
1
+ .page-form-label= f.object.title
2
+ .page-form-control= f.datetime_field :content, placeholder: f.object.title
@@ -0,0 +1,2 @@
1
+ .page-form-label= f.object.title
2
+ .page-form-control= f.url_field :content, placeholder: f.object.title
@@ -5,7 +5,7 @@
5
5
  # Add additional assets to the asset load path.
6
6
  # Rails.application.config.assets.paths << Emoji.images_path
7
7
  # Add Yarn node_modules folder to the asset load path.
8
- Rails.application.config.assets.paths << Spina::Admin::Conferences::Engine.root.join('node_modules')
8
+ # Rails.application.config.assets.paths << Spina::Admin::Conferences::Engine.root.join('node_modules')
9
9
 
10
10
  # Precompile additional assets.
11
11
  # application.js, application.css, and all non-JS/CSS in the app/assets
@@ -39,13 +39,13 @@ en:
39
39
  images: Images # This translation is apparently not provided by Spina for some reason
40
40
  images:
41
41
  delete: Delete # Ditto
42
+ choose: Choose
42
43
  admin:
43
44
  conferences:
44
45
  title: Conferences
45
46
  conferences:
46
47
  index:
47
48
  new: New conference
48
- no_conferences: There are no conferences
49
49
  import: Import CSV
50
50
  new:
51
51
  new: New conference
@@ -67,13 +67,9 @@ en:
67
67
  form_conference_details:
68
68
  delete_confirmation:
69
69
  "Are you sure you want to delete the conference <strong>%{name}</strong>?"
70
- multiple_rooms_selection_instructions_html:
71
- "Select multiple rooms by holding <kbd>⇧</kbd> for a continuous selection, or, for a discontinous
72
- selection, <kbd>⌘</kbd> on Mac, or <kbd>Ctrl</kbd> on Windows and Linux"
73
70
  delegates:
74
71
  index:
75
72
  new: New delegate
76
- no_delegates: There are no delegates
77
73
  import: Import CSV
78
74
  new:
79
75
  new: New delegate
@@ -91,12 +87,6 @@ en:
91
87
  presentations: Presentations
92
88
  form_delegate_details:
93
89
  delete_confirmation: "Are you sure you want to delete the delegate <strong>%{delegate}</strong>?"
94
- multiple_dietary_requirements_selection_instructions_html:
95
- "Select multiple dietary requirements with <kbd>⌘</kbd> and <kbd>⇧</kbd> on Mac, or <kbd>⌃</kbd> and
96
- <kbd>⇧</kbd> on Windows and Linux"
97
- multiple_conferences_selection_instructions_html:
98
- "Select multiple conferences with <kbd>⌘</kbd> and <kbd>⇧</kbd> on Mac, or <kbd>⌃</kbd> and <kbd>⇧</kbd>
99
- on Windows and Linux"
100
90
  presenters:
101
91
  new: New presenter
102
92
  save: Save presenter
@@ -108,7 +98,6 @@ en:
108
98
  presentations:
109
99
  index:
110
100
  new: New presentation
111
- no_presentations: There are no presentations
112
101
  import: Import CSV
113
102
  new:
114
103
  new: New presentation
@@ -125,14 +114,9 @@ en:
125
114
  presenters: Presenters
126
115
  form_presentation_details:
127
116
  delete_confirmation: "Are you sure you want to delete the presentation <strong>%{presentation}</strong>?"
128
- start_time_instructions: Enter in 24-hour format using a colon as the divider
129
- multiple_presenters_selection_instructions_html:
130
- "Select multiple presenters by holding <kbd>⇧</kbd> for a continuous selection, or, for a discontinous
131
- selection, <kbd>⌘</kbd> on Mac, or <kbd>Ctrl</kbd> on Windows and Linux"
132
117
  presentation_types:
133
118
  index:
134
119
  new: New presentation type
135
- no_presentation_types: There are no presentation types
136
120
  import: Import CSV
137
121
  new:
138
122
  new: New presentation type
@@ -151,11 +135,9 @@ en:
151
135
  form_presentation_type_details:
152
136
  delete_confirmation:
153
137
  "Are you sure you want to delete the presentation type <strong>%{presentation_type}</strong>?"
154
- duration_instructions: Enter in minutes
155
138
  dietary_requirements:
156
139
  index:
157
140
  new: New dietary requirement
158
- no_dietary_requirements: There are no dietary requirements
159
141
  import: Import CSV
160
142
  new:
161
143
  new: New dietary requirement
@@ -176,7 +158,6 @@ en:
176
158
  presentation_attachment_types:
177
159
  index:
178
160
  new: New presentation attachment type
179
- no_presentation_attachment_types: There are no presentation attachment types
180
161
  new:
181
162
  new: New presentation attachment type
182
163
  create:
@@ -194,7 +175,6 @@ en:
194
175
  institutions:
195
176
  index:
196
177
  new: New institution
197
- no_institutions: There are no institutions
198
178
  import: Import CSV
199
179
  new:
200
180
  new: New institution
@@ -216,7 +196,6 @@ en:
216
196
  rooms:
217
197
  index:
218
198
  new: New room
219
- no_rooms: There are no rooms
220
199
  import: Import CSV
221
200
  new:
222
201
  new: New room
@@ -236,7 +215,6 @@ en:
236
215
  sessions:
237
216
  index:
238
217
  new: New session
239
- no_sessions: There are no sessions
240
218
  new:
241
219
  new: New session
242
220
  create:
@@ -252,6 +230,25 @@ en:
252
230
  presentations: Presentations
253
231
  form_session_details:
254
232
  delete_confirmation: "Are you sure you want to delete the session <strong>%{session}</strong>?"
233
+ application:
234
+ conferences:
235
+ no_conferences: There are no conferences
236
+ delegates:
237
+ no_delegates: There are no delegates
238
+ dietary_requirements:
239
+ no_dietary_requirements: There are no dietary requirements
240
+ institutions:
241
+ no_institutions: There are no institutions
242
+ presentation_types:
243
+ no_presentation_types: There are no presentation types
244
+ presentations:
245
+ no_presentations: There are no presentations
246
+ presentation_attachment_types:
247
+ no_presentation_attachment_types: There are no presentation attachment types
248
+ rooms:
249
+ no_rooms: There are no rooms
250
+ sessions:
251
+ no_sessions: There are no sessions
255
252
  activerecord:
256
253
  models:
257
254
  spina/admin/conferences/conference:
@@ -290,14 +287,15 @@ en:
290
287
  attributes:
291
288
  spina/admin/conferences/conference:
292
289
  name: Name
293
- start_date: Start date
294
- finish_date: Finish date
290
+ year: Year
291
+ start_datetime: Start time
292
+ finish_datetime: Finish time
295
293
  events: Events
296
294
  spina/admin/conferences/event:
297
295
  name: Name
298
296
  location: Location
299
- start_time: Start time
300
- finish_time: Finish time
297
+ start_datetime: Start time
298
+ finish_datetime: Finish time
301
299
  description: Description
302
300
  spina/admin/conferences/delegate:
303
301
  first_name: First name
@@ -313,8 +311,7 @@ en:
313
311
  dietary_requirements: Dietary requirements
314
312
  spina/admin/conferences/presentation:
315
313
  title: Title
316
- date: Date
317
- start_time: Start time
314
+ start_datetime: Start time
318
315
  abstract: Abstract
319
316
  room_type: Type
320
317
  presenters: Presenters
@@ -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