spina-admin-conferences 1.3.10 → 2.2.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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/spina/admin/conferences/application.sass +0 -15
  3. data/app/controllers/spina/admin/conferences/application_controller.rb +6 -3
  4. data/app/controllers/spina/admin/conferences/conferences_controller.rb +19 -28
  5. data/app/controllers/spina/admin/conferences/delegates_controller.rb +3 -5
  6. data/app/controllers/spina/admin/conferences/dietary_requirements_controller.rb +2 -2
  7. data/app/controllers/spina/admin/conferences/institutions_controller.rb +2 -2
  8. data/app/controllers/spina/admin/conferences/presentation_attachment_types_controller.rb +2 -2
  9. data/app/controllers/spina/admin/conferences/presentation_types_controller.rb +2 -2
  10. data/app/controllers/spina/admin/conferences/presentations_controller.rb +5 -6
  11. data/app/controllers/spina/admin/conferences/rooms_controller.rb +2 -2
  12. data/app/controllers/spina/admin/conferences/sessions_controller.rb +2 -2
  13. data/app/jobs/spina/admin/conferences/presentation_import_job.rb +2 -3
  14. data/app/models/spina/admin/conferences/conference.rb +132 -15
  15. data/app/models/spina/admin/conferences/event.rb +30 -65
  16. data/app/models/spina/admin/conferences/presentation.rb +29 -38
  17. data/app/models/spina/parts/admin/conferences/date.rb +14 -0
  18. data/app/models/spina/parts/admin/conferences/email_address.rb +20 -0
  19. data/app/models/spina/parts/admin/conferences/time.rb +14 -0
  20. data/app/models/spina/parts/admin/conferences/url.rb +20 -0
  21. data/app/views/spina/admin/conferences/{delegates/_form_conferences.html.haml → application/_conferences.html.haml} +2 -4
  22. data/app/views/spina/admin/conferences/{conferences/_form_delegates.html.haml → application/_delegates.html.haml} +2 -3
  23. data/app/views/spina/admin/conferences/application/_dietary_requirements.html.haml +9 -0
  24. data/app/views/spina/admin/conferences/application/_institutions.html.haml +10 -0
  25. data/app/views/spina/admin/conferences/application/_presentation_attachment_types.html.haml +10 -0
  26. data/app/views/spina/admin/conferences/{conferences/_form_presentation_types.html.haml → application/_presentation_types.html.haml} +2 -3
  27. data/app/views/spina/admin/conferences/{rooms/_form_presentations.html.haml → application/_presentations.html.haml} +2 -3
  28. data/app/views/spina/admin/conferences/{conferences/_form_rooms.html.haml → application/_rooms.html.haml} +2 -3
  29. data/app/views/spina/admin/conferences/{presentation_types/_form_sessions.html.haml → application/_sessions.html.haml} +2 -3
  30. data/app/views/spina/admin/conferences/conferences/_event_fields.html.haml +14 -21
  31. data/app/views/spina/admin/conferences/conferences/_form.html.haml +7 -3
  32. data/app/views/spina/admin/conferences/conferences/_form_conference_details.html.haml +22 -24
  33. data/app/views/spina/admin/conferences/conferences/_form_parts.html.haml +7 -14
  34. data/app/views/spina/admin/conferences/conferences/index.html.haml +2 -13
  35. data/app/views/spina/admin/conferences/delegates/_form.html.haml +4 -3
  36. data/app/views/spina/admin/conferences/delegates/_form_delegate_details.html.haml +47 -32
  37. data/app/views/spina/admin/conferences/delegates/index.html.haml +2 -12
  38. data/app/views/spina/admin/conferences/dietary_requirements/_form.html.haml +3 -3
  39. data/app/views/spina/admin/conferences/dietary_requirements/_form_dietary_requirement_details.html.haml +7 -8
  40. data/app/views/spina/admin/conferences/dietary_requirements/index.html.haml +2 -10
  41. data/app/views/spina/admin/conferences/institutions/_form.html.haml +4 -3
  42. data/app/views/spina/admin/conferences/institutions/_form_institution_details.html.haml +29 -35
  43. data/app/views/spina/admin/conferences/institutions/index.html.haml +2 -11
  44. data/app/views/spina/admin/conferences/presentation_attachment_types/_form.html.haml +2 -2
  45. data/app/views/spina/admin/conferences/presentation_attachment_types/index.html.haml +2 -10
  46. data/app/views/spina/admin/conferences/presentation_types/_form.html.haml +4 -3
  47. data/app/views/spina/admin/conferences/presentation_types/_form_presentation_type_details.html.haml +13 -17
  48. data/app/views/spina/admin/conferences/presentation_types/index.html.haml +2 -12
  49. data/app/views/spina/admin/conferences/presentations/_attachment_fields.html.haml +6 -15
  50. data/app/views/spina/admin/conferences/presentations/_form.html.haml +3 -3
  51. data/app/views/spina/admin/conferences/presentations/_form_presentation_details.html.haml +55 -55
  52. data/app/views/spina/admin/conferences/presentations/index.html.haml +2 -12
  53. data/app/views/spina/admin/conferences/rooms/_form.html.haml +3 -3
  54. data/app/views/spina/admin/conferences/rooms/_form_room_details.html.haml +13 -15
  55. data/app/views/spina/admin/conferences/rooms/index.html.haml +2 -12
  56. data/app/views/spina/admin/conferences/sessions/_form.html.haml +3 -3
  57. data/app/views/spina/admin/conferences/sessions/_form_session_details.html.haml +18 -20
  58. data/app/views/spina/admin/conferences/sessions/_session.html.haml +1 -1
  59. data/app/views/spina/admin/conferences/sessions/index.html.haml +2 -12
  60. data/app/views/spina/admin/hooks/conferences/_primary_navigation.html.haml +4 -4
  61. data/app/views/spina/admin/hooks/conferences/_settings_secondary_navigation.html.haml +2 -2
  62. data/app/views/spina/admin/parts/admin/conferences/dates/_form.html.haml +2 -0
  63. data/app/views/spina/admin/parts/admin/conferences/email_addresses/_form.html.haml +2 -0
  64. data/app/views/spina/admin/parts/admin/conferences/times/_form.html.haml +2 -0
  65. data/app/views/spina/admin/parts/admin/conferences/urls/_form.html.haml +2 -0
  66. data/config/locales/en.yml +26 -29
  67. data/db/migrate/20210315164409_add_json_attributes_to_spina_conferences_presentations.rb +7 -0
  68. data/db/migrate/20210315164410_add_json_attributes_to_spina_conferences_conferences.rb +7 -0
  69. data/db/migrate/20210315164411_convert_partables_to_json.rb +407 -0
  70. data/db/migrate/20210417102513_add_locale_to_action_text_rich_texts.rb +11 -0
  71. data/db/migrate/20210417102514_move_texts_to_action_text_rich_texts.rb +82 -0
  72. data/lib/spina/admin/conferences.rb +1 -0
  73. data/lib/spina/admin/conferences/engine.rb +10 -5
  74. data/lib/spina/admin/conferences/version.rb +1 -1
  75. data/lib/tasks/spina/admin/conferences_tasks.rake +11 -1
  76. metadata +47 -46
  77. data/app/helpers/spina/admin/conferences/conferences_helper.rb +0 -44
  78. data/app/models/spina/admin/conferences/date_part.rb +0 -15
  79. data/app/models/spina/admin/conferences/email_address_part.rb +0 -21
  80. data/app/models/spina/admin/conferences/part.rb +0 -20
  81. data/app/models/spina/admin/conferences/time_part.rb +0 -53
  82. data/app/models/spina/admin/conferences/url_part.rb +0 -21
  83. data/app/views/spina/admin/conferences/conferences/_form_presentations.html.haml +0 -12
  84. data/app/views/spina/admin/conferences/delegates/_form_presentations.html.haml +0 -12
  85. data/app/views/spina/admin/conferences/dietary_requirements/_form_delegates.html.haml +0 -12
  86. data/app/views/spina/admin/conferences/institutions/_form_delegates.html.haml +0 -12
  87. data/app/views/spina/admin/conferences/institutions/_form_rooms.html.haml +0 -12
  88. data/app/views/spina/admin/conferences/presentation_types/_form_presentations.html.haml +0 -12
  89. data/app/views/spina/admin/conferences/presentations/_form_presenters.html.haml +0 -12
  90. data/app/views/spina/admin/conferences/sessions/_form_presentations.html.haml +0 -12
  91. data/app/views/spina/admin/partables/admin/conferences/date_parts/_form.html.haml +0 -5
  92. data/app/views/spina/admin/partables/admin/conferences/email_address_parts/_form.html.haml +0 -5
  93. data/app/views/spina/admin/partables/admin/conferences/time_parts/_form.html.haml +0 -7
  94. data/app/views/spina/admin/partables/admin/conferences/url_parts/_form.html.haml +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36fb99cebe29eb7c87ade649d55edb3de239e7f9c6394ffb9f566a3c72102f81
4
- data.tar.gz: 869aa43467a8accd77e2746e7c1f9747bf3cc5fb2915da3388c3f126420d4a7e
3
+ metadata.gz: c64616247b31ffd1405c24a6e8c56c8065c7aa1fae0743def8af0333b3b4da15
4
+ data.tar.gz: d6b43e8bdd7380ef7dd3792ecfbc84365be458a2c628a47f1cd6faffb78bd22b
5
5
  SHA512:
6
- metadata.gz: 28095530192cf6a10caf09f4d0e98f7c47354f3d2fe8fc0aae26b65bc8d488bebb76b0b89a0bde1b1867a63180da553e990e8043faa123c78d7e3da5c34258c5
7
- data.tar.gz: 6f5848cde2cbc5023166384ddb6e24fc0ecccf22bdf5d81eba74fb7a516c5b658d6ac8865a400ca8226120723bfdf6b65f6887492e24cc980835207a384608ea
6
+ metadata.gz: ed37f8900387246afe83d3f81106b744853191def0dcb67d1dfb687cb484cc375bca8f76205658072d5d8d2f627fbde5887d25a9dfe53a2527f57e8234ae2865
7
+ data.tar.gz: db26443e184c8fb5e7f05c8b66b97c0bc8a0497f4f33462b560642b8217db72b498c897120973c923096ed8d9473b761a509978057729cca65513a6e76350457
@@ -1,18 +1,3 @@
1
- input::-webkit-calendar-picker-indicator
2
- display: none
3
- input[type="date"]::-webkit-outer-spin-button, input[type="date"]::-webkit-inner-spin-button, input[type="time"]::-webkit-inner-spin-button, input[type="time"]::-webkit-inner-spin-button
4
- display: none
5
- input[type="date"]
6
- padding-right: 30px
7
-
8
- .multiple.select-dropdown
9
- z-index: 0
10
- &:before
11
- content: none
12
- select
13
- padding: 11px 10px
14
- width: 100%
15
-
16
1
  .turbo-progress-bar
17
2
  @import spina/configuration
18
3
  background-color: $primary-color
@@ -5,14 +5,17 @@ module Spina
5
5
  module Conferences
6
6
  # @abstract Subclass to implement a custom controller.
7
7
  class ApplicationController < ::Spina::Admin::AdminController
8
+ helper ::Spina::Engine.routes.url_helpers
9
+
8
10
  add_flash_types :success
9
11
 
10
- layout :admin_layout, only: %i[new edit]
12
+ layout 'spina/admin/conferences/application', only: %i[new edit]
13
+ before_action :set_locale
11
14
 
12
15
  private
13
16
 
14
- def admin_layout
15
- 'spina/admin/conferences/application'
17
+ def set_locale
18
+ @locale = params[:locale] || I18n.default_locale
16
19
  end
17
20
  end
18
21
  end
@@ -6,16 +6,21 @@ module Spina
6
6
  # Controller for {Conference} objects.
7
7
  # @see Conference
8
8
  class ConferencesController < ApplicationController
9
- PARTS = [
10
- { name: 'text', title: 'Text', partable_type: 'Spina::Text' },
11
- { name: 'submission_url', title: 'Submission URL', partable_type: 'Spina::Admin::Conferences::UrlPart' },
12
- { name: 'submission_email_address', title: 'Submission email address',
13
- partable_type: 'Spina::Admin::Conferences::EmailAddressPart' },
14
- { name: 'submission_date', title: 'Submission date', partable_type: 'Spina::Admin::Conferences::DatePart' },
15
- { name: 'submission_text', title: 'Submission text', partable_type: 'Spina::Line' },
16
- { name: 'gallery', title: 'Gallery', partable_type: 'Spina::ImageCollection' },
17
- { name: 'sponsors', title: 'Sponsors', partable_type: 'Spina::Structure' }
9
+ PARTS_PARAMS = [
10
+ :name, :title, :type, :content, :filename, :signed_blob_id, :alt, :attachment_id, :image_id,
11
+ images_attributes: %i[filename signed_blob_id image_id alt],
12
+ content_attributes: [
13
+ :name, :title,
14
+ parts_attributes: [
15
+ :name, :title, :type, :content, :filename, :signed_blob_id, :alt, :attachment_id, :image_id,
16
+ images_attributes: %i[filename signed_blob_id image_id alt]
17
+ ]
18
+ ]
18
19
  ].freeze
20
+ CONTENT_PARAMS = Spina.config.locales.inject({}) { |params, locale| params.merge("#{locale}_content_attributes": [*PARTS_PARAMS]) }
21
+ PARAMS = [:start_date, :finish_date, :name, **CONTENT_PARAMS,
22
+ events_attributes: %i[id name start_datetime finish_datetime description location] ].freeze
23
+ PARTS = %w[text submission_url submission_email_address submission_date submission_text gallery sponsors].freeze
19
24
 
20
25
  before_action :set_conference, only: %i[edit update destroy]
21
26
  before_action :set_conferences_breadcrumb
@@ -28,7 +33,7 @@ module Spina
28
33
  # Renders a list of conferences.
29
34
  # @return [void]
30
35
  def index
31
- @conferences = Conference.sorted
36
+ @conferences = Conference.sorted.page(params[:page])
32
37
  end
33
38
 
34
39
  # Renders a form for a new conference.
@@ -116,31 +121,17 @@ module Spina
116
121
  end
117
122
 
118
123
  def set_parts_attributes
119
- @parts_attributes = PARTS
124
+ @parts_attributes = current_theme.parts.select { |part| PARTS.include? part[:name] }
120
125
  end
121
126
 
122
127
  def build_parts
123
128
  return unless @parts_attributes.is_a? Array
124
129
 
125
- @conference.parts = @parts_attributes.collect do |part_attributes|
126
- @conference.parts.where(name: part_attributes[:name]).first_or_initialize(**part_attributes)
127
- .tap { |part| part.partable ||= part.partable_type.constantize.new }
128
- end
130
+ @parts = @parts_attributes.collect { |part_attributes| @conference.part(part_attributes) }
129
131
  end
130
132
 
131
- def conference_params # rubocop:disable Metrics/MethodLength
132
- params.require(:admin_conferences_conference).permit(:start_date, :finish_date, :name,
133
- events_attributes:
134
- %i[id name date start_time finish_time description location],
135
- parts_attributes:
136
- [:id, :title, :name, :partable_type, :partable_id,
137
- { partable_attributes:
138
- [:id, :content, :image_tokens, :image_positions, :date, :time,
139
- { structure_items_attributes:
140
- [:id, :position, :_destroy,
141
- { structure_parts_attributes:
142
- [:id, :title, :structure_partable_type, :name, :partable_id,
143
- { partable_attributes: {} }] }] }] }])
133
+ def conference_params
134
+ params.require(:conference).permit(PARAMS)
144
135
  end
145
136
  end
146
137
  end
@@ -15,7 +15,7 @@ module Spina
15
15
  # Renders a list of delegates.
16
16
  # @return [void]
17
17
  def index
18
- @delegates = Delegate.sorted
18
+ @delegates = Delegate.sorted.page(params[:page])
19
19
  end
20
20
 
21
21
  # Renders a form for a new delegate.
@@ -105,10 +105,8 @@ module Spina
105
105
  end
106
106
 
107
107
  def delegate_params
108
- params.require(:admin_conferences_delegate).permit(:first_name, :last_name, :email_address, :url,
109
- :institution_id,
110
- conference_ids: [],
111
- dietary_requirement_ids: [])
108
+ params.require(:delegate).permit(:first_name, :last_name, :email_address, :url, :institution_id,
109
+ conference_ids: [], dietary_requirement_ids: [])
112
110
  end
113
111
  end
114
112
  end
@@ -15,7 +15,7 @@ module Spina
15
15
  # Renders a list of dietary requirements.
16
16
  # @return [void]
17
17
  def index
18
- @dietary_requirements = DietaryRequirement.sorted
18
+ @dietary_requirements = DietaryRequirement.sorted.page(params[:page])
19
19
  end
20
20
 
21
21
  # Renders a form for a new dietary requirement.
@@ -98,7 +98,7 @@ module Spina
98
98
  end
99
99
 
100
100
  def dietary_requirement_params
101
- params.require(:admin_conferences_dietary_requirement).permit(:name)
101
+ params.require(:dietary_requirement).permit(:name)
102
102
  end
103
103
  end
104
104
  end
@@ -15,7 +15,7 @@ module Spina
15
15
  # Renders a list of institutions.
16
16
  # @return [void]
17
17
  def index
18
- @institutions = Institution.sorted
18
+ @institutions = Institution.sorted.page(params[:page])
19
19
  end
20
20
 
21
21
  # Renders a form for a new institution.
@@ -98,7 +98,7 @@ module Spina
98
98
  end
99
99
 
100
100
  def conference_params
101
- params.require(:admin_conferences_institution).permit(:name, :city, :logo_id)
101
+ params.require(:institution).permit(:name, :city, :logo_id)
102
102
  end
103
103
  end
104
104
  end
@@ -14,7 +14,7 @@ module Spina
14
14
  # Renders a list of presentation attachment types.
15
15
  # @return [void]
16
16
  def index
17
- @presentation_attachment_types = PresentationAttachmentType.sorted
17
+ @presentation_attachment_types = PresentationAttachmentType.sorted.page(params[:page])
18
18
  end
19
19
 
20
20
  # Renders a form for a new presentation attachment type.
@@ -96,7 +96,7 @@ module Spina
96
96
 
97
97
  # noinspection RubyInstanceMethodNamingConvention
98
98
  def presentation_attachment_type_params
99
- params.require(:admin_conferences_presentation_attachment_type).permit(:name)
99
+ params.require(:presentation_attachment_type).permit(:name)
100
100
  end
101
101
  end
102
102
  end
@@ -17,7 +17,7 @@ module Spina
17
17
  # Renders a list of presentation types.
18
18
  # @return [void]
19
19
  def index
20
- @presentation_types = PresentationType.sorted
20
+ @presentation_types = PresentationType.sorted.page(params[:page])
21
21
  end
22
22
 
23
23
  # Renders a form for a new presentation type.
@@ -101,7 +101,7 @@ module Spina
101
101
  end
102
102
 
103
103
  def presentation_type_params
104
- params.require(:admin_conferences_presentation_type).permit(:name, :conference_id, :minutes)
104
+ params.require(:presentation_type).permit(:name, :conference_id, :minutes)
105
105
  end
106
106
  end
107
107
  end
@@ -16,7 +16,7 @@ module Spina
16
16
  # Renders a list of presentations.
17
17
  # @return [void]
18
18
  def index
19
- @presentations = Presentation.sorted
19
+ @presentations = Presentation.sorted.page(params[:page])
20
20
  end
21
21
 
22
22
  # Renders a form for a new presentation.
@@ -98,7 +98,7 @@ module Spina
98
98
  end
99
99
 
100
100
  def set_conferences
101
- @conferences = Conference.all.to_json methods: %i[name localized_dates],
101
+ @conferences = Conference.all.to_json methods: %i[name],
102
102
  include:
103
103
  { presentation_types:
104
104
  { methods: [:name], include: { sessions: { methods: [:name] } } } }
@@ -113,10 +113,9 @@ module Spina
113
113
  end
114
114
 
115
115
  def presentation_params
116
- params.require(:admin_conferences_presentation).permit(:title, :abstract, :session_id, :date, :start_time,
117
- presenter_ids: [],
118
- attachments_attributes:
119
- %i[id attachment_id attachment_type_id _destroy])
116
+ params.require(:presentation).permit(:title, :abstract, :session_id, :start_datetime,
117
+ presenter_ids: [],
118
+ attachments_attributes: %i[id attachment_id attachment_type_id _destroy])
120
119
  end
121
120
  end
122
121
  end
@@ -17,7 +17,7 @@ module Spina
17
17
  # Renders a list of rooms.
18
18
  # @return [void]
19
19
  def index
20
- @rooms = Room.sorted
20
+ @rooms = Room.sorted.page(params[:page])
21
21
  end
22
22
 
23
23
  # Renders a form for a new room.
@@ -101,7 +101,7 @@ module Spina
101
101
  end
102
102
 
103
103
  def room_params
104
- params.require(:admin_conferences_room).permit(:building, :number, :institution_id)
104
+ params.require(:room).permit(:building, :number, :institution_id)
105
105
  end
106
106
  end
107
107
  end
@@ -18,7 +18,7 @@ module Spina
18
18
  # Renders a list of sessions.
19
19
  # @return [void]
20
20
  def index
21
- @sessions = Session.all
21
+ @sessions = Session.all.page(params[:page])
22
22
  end
23
23
 
24
24
  # Renders a form for a new session.
@@ -110,7 +110,7 @@ module Spina
110
110
  end
111
111
 
112
112
  def session_params
113
- params.require(:admin_conferences_session).permit(:name, :presentation_type_id, :room_id)
113
+ params.require(:session).permit(:name, :presentation_type_id, :room_id)
114
114
  end
115
115
  end
116
116
  end
@@ -13,8 +13,7 @@ module Spina
13
13
  # == Columns
14
14
  # The CSV should has the following columns. Make sure to include the column names in the header row.
15
15
  # +session_id+:: The id of the associated session.
16
- # +date+:: The date of the presentation, in ISO 8601 format.
17
- # +start_time+:: The start time of the presentation, in HH:MM format.
16
+ # +start_datetime+:: The start time of the presentation, in ISO 8601 format.
18
17
  # +title+:: The title of the presentation for the default locale.
19
18
  # +abstract+:: The presentation's abstract.
20
19
  # +presenter_ids+:: The ids of the presenters.
@@ -30,7 +29,7 @@ module Spina
30
29
 
31
30
  def presentation_params(params)
32
31
  params = ActionController::Parameters.new(params)
33
- params.permit :title, :date, :start_time, :abstract, :session_id, presenter_ids: []
32
+ params.permit :title, :start_datetime, :abstract, :session_id, presenter_ids: []
34
33
  end
35
34
  end
36
35
  end
@@ -12,8 +12,11 @@ module Spina
12
12
  #
13
13
  # = Translations
14
14
  # - {#name}
15
- class Conference < ApplicationRecord
16
- include Partable
15
+ class Conference < ApplicationRecord # rubocop:disable Metrics/ClassLength
16
+ include AttrJson::Record
17
+ include AttrJson::NestedAttributes
18
+ include Spina::Partable
19
+ include Spina::TranslatedContent
17
20
 
18
21
  default_scope { includes(:translations) }
19
22
 
@@ -37,11 +40,6 @@ module Spina
37
40
  # @note Destroying a conference destroys dependent events.
38
41
  # @see Event
39
42
  has_many :events, -> { includes(:translations) }, inverse_of: :conference, dependent: :destroy
40
- # @!attribute [rw] events
41
- # @return [ActiveRecord::Relation] directly associated events
42
- # @note Destroying a conference destroys dependent events.
43
- # @see Event
44
- has_many :parts, as: :pageable, dependent: :destroy
45
43
  # @!attribute [rw] sessions
46
44
  # @return [ActiveRecord::Relation] Sessions associated with {#presentation_types}
47
45
  # @see Session
@@ -68,11 +66,71 @@ module Spina
68
66
  has_and_belongs_to_many :delegates, foreign_key: :spina_conferences_conference_id, # rubocop:disable Rails/HasAndBelongsToMany
69
67
  association_foreign_key: :spina_conferences_delegate_id
70
68
  accepts_nested_attributes_for :events, allow_destroy: true
71
- accepts_nested_attributes_for :parts, allow_destroy: true
72
69
 
73
70
  validates :name, :start_date, :finish_date, :year, presence: true
74
71
  validates :finish_date, 'spina/admin/conferences/finish_date': true, unless: proc { |conference| conference.start_date.blank? }
75
72
 
73
+ class << self
74
+ # @return [Array<TZInfo::TimezonePeriod>] the time zone periods for the conferences
75
+ def time_zone_periods
76
+ pluck(:dates).compact.collect(&:begin).collect(&:at_beginning_of_day).collect(&:period)
77
+ end
78
+
79
+ # @return [String] a set of conferences as an iCalendar
80
+ def to_ics
81
+ Rails.cache.fetch [all, 'calendar'] do
82
+ calendar = Icalendar::Calendar.new
83
+ calendar.x_wr_calname = (Current.account || Spina::Account.first).name
84
+ calendar.add_timezone(ical_timezone)
85
+ conference_events.each { |event| calendar.add_event(event) }
86
+ calendar.publish
87
+ calendar.to_ical
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def conference_events
94
+ Rails.cache.fetch [all, 'events'] do
95
+ all.in_batches.each_record.collect do |conference|
96
+ Rails.cache.fetch([conference, 'event']) { conference.to_event }
97
+ end
98
+ end
99
+ end
100
+
101
+ def ical_timezone
102
+ Rails.cache.fetch [self, 'time_zone'] do
103
+ Icalendar::Timezone.new do |timezone|
104
+ timezone.tzid = Time.zone.name
105
+ daylight_periods.each { |daylight_period| timezone.add_daylight(daylight_period) }
106
+ standard_periods.each { |standard_period| timezone.add_daylight(standard_period) }
107
+ end
108
+ end
109
+ end
110
+
111
+ def daylight_periods
112
+ time_zone_periods.select(&:dst?).each do |period|
113
+ Icalendar::Timezone::Daylight.new do |ical_period|
114
+ ical_period.tzoffsetfrom = period.offset.ical_offset
115
+ ical_period.tzoffsetto = period.offset.ical_offset
116
+ ical_period.tzname = period.abbreviation
117
+ ical_period.dtstart = period.starts_at.to_datetime
118
+ end
119
+ end
120
+ end
121
+
122
+ def standard_periods
123
+ time_zone_periods.reject(&:dst?).each do |period|
124
+ Icalendar::Timezone::Standard.new do |ical_period|
125
+ ical_period.tzoffsetfrom = period.offset.ical_offset
126
+ ical_period.tzoffsetto = period.offset.ical_offset
127
+ ical_period.tzname = period.abbreviation
128
+ ical_period.dtstart = period.starts_at.to_datetime
129
+ end
130
+ end
131
+ end
132
+ end
133
+
76
134
  # @return [Date, nil] the start date of the conference. Nil if the conference has no dates
77
135
  def start_date
78
136
  return if dates.blank?
@@ -130,10 +188,8 @@ module Spina
130
188
  event = Icalendar::Event.new
131
189
  return event if invalid?
132
190
 
133
- event.dtstart = start_date
134
- event.dtstart.ical_param(:value, 'DATE')
135
- event.dtend = finish_date
136
- event.dtend.ical_param(:value, 'DATE')
191
+ event.dtstart = Icalendar::Values::Date.new(dates.begin)
192
+ event.dtend = Icalendar::Values::Date.new(dates.exclude_end? ? dates.end : dates.end + 1.day)
137
193
  event.location = location
138
194
  event.contact = Spina::Account.first.email
139
195
  event.categories = Conference.model_name.human(count: 0)
@@ -141,10 +197,71 @@ module Spina
141
197
  event
142
198
  end
143
199
 
144
- # @param (see #to_event)
145
- # @deprecated Use {#to_event} instead
200
+ # @return [TZInfo::TimezonePeriod, nil] the time zone period for the conference event
201
+ def time_zone_period
202
+ return if start_date.blank?
203
+
204
+ start_date.at_beginning_of_day.period
205
+ end
206
+
207
+ # @return [String, nil] the conference as an iCalendar
146
208
  def to_ics
147
- to_event
209
+ Rails.cache.fetch [self, presentations, 'calendar'] do
210
+ calendar = Icalendar::Calendar.new
211
+ return if invalid?
212
+
213
+ calendar.x_wr_calname = name
214
+ calendar.add_timezone(ical_timezone)
215
+ eventables_events.each { |event| calendar.add_event(event) }
216
+ calendar.publish
217
+ calendar.to_ical
218
+ end
219
+ end
220
+
221
+ private
222
+
223
+ def eventables
224
+ [self, *events, *presentations]
225
+ end
226
+
227
+ def eventables_events
228
+ Rails.cache.fetch [self, *presentations, 'events'] do
229
+ eventables.collect do |eventable|
230
+ Rails.cache.fetch([eventable, 'event']) { eventable.to_event }
231
+ end
232
+ end
233
+ end
234
+
235
+ def ical_timezone
236
+ Rails.cache.fetch [self, presentations, 'time_zone'] do
237
+ Icalendar::Timezone.new do |timezone|
238
+ timezone.tzid = Time.zone.name
239
+ daylight_periods.each { |daylight_period| timezone.add_daylight(daylight_period) }
240
+ standard_periods.each { |standard_period| timezone.add_daylight(standard_period) }
241
+ end
242
+ end
243
+ end
244
+
245
+ def daylight_periods
246
+ time_zone_periods.select(&:dst?).each do |period|
247
+ Icalendar::Timezone::Daylight.new do |ical_period|
248
+ ical_period.tzoffsetfrom = period.offset.ical_offset
249
+ ical_period.tzoffsetto = period.offset.ical_offset
250
+ ical_period.tzname = period.abbreviation
251
+ ical_period.dtstart = period.starts_at.to_datetime
252
+ end
253
+ end
254
+ end
255
+
256
+ def standard_periods
257
+ time_zone_periods.reject(&:dst?).each do |period|
258
+ Icalendar::Timezone::Standard.new do |ical_period|
259
+ ical_period.tzoffsetfrom = period.offset.ical_offset
260
+ ical_period.tzoffsetto = period.offset.ical_offset
261
+ ical_period.tzname = period.abbreviation
262
+ ical_period.dtstart = period.starts_at.to_datetime
263
+ end
264
+ end
148
265
  end
149
266
  end
150
267
  end