spina-admin-conferences 1.3.3

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 (212) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +101 -0
  4. data/Rakefile +40 -0
  5. data/app/assets/config/spina_admin_conferences_manifest.js +4 -0
  6. data/app/assets/javascripts/spina/admin/conferences/application.es6 +20 -0
  7. data/app/assets/javascripts/spina/admin/conferences/controllers/conference_events_form_controller.es6 +175 -0
  8. data/app/assets/javascripts/spina/admin/conferences/controllers/presentation_attachments_form_controller.es6 +175 -0
  9. data/app/assets/javascripts/spina/admin/conferences/controllers/select_options_controller.es6 +216 -0
  10. data/app/assets/stylesheets/spina/admin/conferences/application.sass +14 -0
  11. data/app/controllers/spina/admin/conferences/application_controller.rb +20 -0
  12. data/app/controllers/spina/admin/conferences/conferences_controller.rb +148 -0
  13. data/app/controllers/spina/admin/conferences/delegates_controller.rb +116 -0
  14. data/app/controllers/spina/admin/conferences/dietary_requirements_controller.rb +106 -0
  15. data/app/controllers/spina/admin/conferences/events_controller.rb +24 -0
  16. data/app/controllers/spina/admin/conferences/institutions_controller.rb +106 -0
  17. data/app/controllers/spina/admin/conferences/presentation_attachment_types_controller.rb +104 -0
  18. data/app/controllers/spina/admin/conferences/presentation_attachments_controller.rb +24 -0
  19. data/app/controllers/spina/admin/conferences/presentation_types_controller.rb +109 -0
  20. data/app/controllers/spina/admin/conferences/presentations_controller.rb +124 -0
  21. data/app/controllers/spina/admin/conferences/rooms_controller.rb +109 -0
  22. data/app/controllers/spina/admin/conferences/sessions_controller.rb +118 -0
  23. data/app/helpers/spina/admin/conferences/conferences_helper.rb +44 -0
  24. data/app/jobs/spina/admin/conferences/application_job.rb +11 -0
  25. data/app/jobs/spina/admin/conferences/delegate_import_job.rb +37 -0
  26. data/app/jobs/spina/admin/conferences/import_job.rb +26 -0
  27. data/app/jobs/spina/admin/conferences/presentation_import_job.rb +38 -0
  28. data/app/mailers/spina/admin/conferences/application_mailer.rb +13 -0
  29. data/app/models/spina/admin/conferences.rb +11 -0
  30. data/app/models/spina/admin/conferences/application_record.rb +14 -0
  31. data/app/models/spina/admin/conferences/conference.rb +152 -0
  32. data/app/models/spina/admin/conferences/date_part.rb +15 -0
  33. data/app/models/spina/admin/conferences/delegate.rb +89 -0
  34. data/app/models/spina/admin/conferences/dietary_requirement.rb +33 -0
  35. data/app/models/spina/admin/conferences/email_address_part.rb +21 -0
  36. data/app/models/spina/admin/conferences/event.rb +120 -0
  37. data/app/models/spina/admin/conferences/institution.rb +46 -0
  38. data/app/models/spina/admin/conferences/part.rb +20 -0
  39. data/app/models/spina/admin/conferences/presentation.rb +143 -0
  40. data/app/models/spina/admin/conferences/presentation_attachment.rb +27 -0
  41. data/app/models/spina/admin/conferences/presentation_attachment_type.rb +35 -0
  42. data/app/models/spina/admin/conferences/presentation_type.rb +60 -0
  43. data/app/models/spina/admin/conferences/room.rb +52 -0
  44. data/app/models/spina/admin/conferences/session.rb +56 -0
  45. data/app/models/spina/admin/conferences/time_part.rb +53 -0
  46. data/app/models/spina/admin/conferences/url_part.rb +21 -0
  47. data/app/validators/spina/admin/conferences/conference_date_validator.rb +20 -0
  48. data/app/validators/spina/admin/conferences/email_address_validator.rb +28 -0
  49. data/app/validators/spina/admin/conferences/finish_date_validator.rb +20 -0
  50. data/app/validators/spina/admin/conferences/finish_time_validator.rb +20 -0
  51. data/app/validators/spina/admin/conferences/http_url_validator.rb +28 -0
  52. data/app/views/layouts/spina/admin/conferences/conferences.html.haml +19 -0
  53. data/app/views/layouts/spina/admin/conferences/delegates.html.haml +10 -0
  54. data/app/views/layouts/spina/admin/conferences/dietary_requirements.html.haml +10 -0
  55. data/app/views/layouts/spina/admin/conferences/institutions.html.haml +17 -0
  56. data/app/views/layouts/spina/admin/conferences/presentation_attachment_types.html.haml +10 -0
  57. data/app/views/layouts/spina/admin/conferences/presentations.html.haml +10 -0
  58. data/app/views/spina/admin/conferences/application/_empty_list.html.haml +3 -0
  59. data/app/views/spina/admin/conferences/application/_errors.html.haml +11 -0
  60. data/app/views/spina/admin/conferences/application/_errors.js.erb +2 -0
  61. data/app/views/spina/admin/conferences/conferences/_conference.html.haml +9 -0
  62. data/app/views/spina/admin/conferences/conferences/_event_fields.html.haml +39 -0
  63. data/app/views/spina/admin/conferences/conferences/_event_row.html.haml +5 -0
  64. data/app/views/spina/admin/conferences/conferences/_form.html.haml +23 -0
  65. data/app/views/spina/admin/conferences/conferences/_form_conference_details.html.haml +29 -0
  66. data/app/views/spina/admin/conferences/conferences/_form_delegates.html.haml +12 -0
  67. data/app/views/spina/admin/conferences/conferences/_form_parts.html.haml +15 -0
  68. data/app/views/spina/admin/conferences/conferences/_form_presentation_types.html.haml +12 -0
  69. data/app/views/spina/admin/conferences/conferences/_form_presentations.html.haml +12 -0
  70. data/app/views/spina/admin/conferences/conferences/_form_rooms.html.haml +12 -0
  71. data/app/views/spina/admin/conferences/conferences/_form_structure.html.haml +19 -0
  72. data/app/views/spina/admin/conferences/conferences/_form_structure_item.html.haml +13 -0
  73. data/app/views/spina/admin/conferences/conferences/edit.html.haml +1 -0
  74. data/app/views/spina/admin/conferences/conferences/index.html.haml +18 -0
  75. data/app/views/spina/admin/conferences/conferences/new.html.haml +1 -0
  76. data/app/views/spina/admin/conferences/delegates/_delegate.html.haml +13 -0
  77. data/app/views/spina/admin/conferences/delegates/_form.html.haml +23 -0
  78. data/app/views/spina/admin/conferences/delegates/_form_conferences.html.haml +14 -0
  79. data/app/views/spina/admin/conferences/delegates/_form_delegate_details.html.haml +38 -0
  80. data/app/views/spina/admin/conferences/delegates/_form_presentations.html.haml +12 -0
  81. data/app/views/spina/admin/conferences/delegates/edit.html.haml +1 -0
  82. data/app/views/spina/admin/conferences/delegates/index.html.haml +23 -0
  83. data/app/views/spina/admin/conferences/delegates/new.html.haml +1 -0
  84. data/app/views/spina/admin/conferences/dietary_requirements/_dietary_requirement.html.haml +6 -0
  85. data/app/views/spina/admin/conferences/dietary_requirements/_form.html.haml +23 -0
  86. data/app/views/spina/admin/conferences/dietary_requirements/_form_delegates.html.haml +12 -0
  87. data/app/views/spina/admin/conferences/dietary_requirements/_form_dietary_requirement_details.html.haml +9 -0
  88. data/app/views/spina/admin/conferences/dietary_requirements/edit.html.haml +1 -0
  89. data/app/views/spina/admin/conferences/dietary_requirements/index.html.haml +15 -0
  90. data/app/views/spina/admin/conferences/dietary_requirements/new.html.haml +1 -0
  91. data/app/views/spina/admin/conferences/events/new.js.erb +27 -0
  92. data/app/views/spina/admin/conferences/institutions/_form.html.haml +23 -0
  93. data/app/views/spina/admin/conferences/institutions/_form_delegates.html.haml +12 -0
  94. data/app/views/spina/admin/conferences/institutions/_form_institution_details.html.haml +35 -0
  95. data/app/views/spina/admin/conferences/institutions/_form_rooms.html.haml +12 -0
  96. data/app/views/spina/admin/conferences/institutions/_institution.html.haml +7 -0
  97. data/app/views/spina/admin/conferences/institutions/edit.html.haml +1 -0
  98. data/app/views/spina/admin/conferences/institutions/index.html.haml +16 -0
  99. data/app/views/spina/admin/conferences/institutions/new.html.haml +1 -0
  100. data/app/views/spina/admin/conferences/presentation_attachment_types/_form.html.haml +23 -0
  101. data/app/views/spina/admin/conferences/presentation_attachment_types/_presentation_attachment_type.html.haml +6 -0
  102. data/app/views/spina/admin/conferences/presentation_attachment_types/edit.html.haml +1 -0
  103. data/app/views/spina/admin/conferences/presentation_attachment_types/index.html.haml +15 -0
  104. data/app/views/spina/admin/conferences/presentation_attachment_types/new.html.haml +1 -0
  105. data/app/views/spina/admin/conferences/presentation_attachments/new.js.erb +21 -0
  106. data/app/views/spina/admin/conferences/presentation_types/_form.html.haml +23 -0
  107. data/app/views/spina/admin/conferences/presentation_types/_form_presentation_type_details.html.haml +20 -0
  108. data/app/views/spina/admin/conferences/presentation_types/_form_presentations.html.haml +12 -0
  109. data/app/views/spina/admin/conferences/presentation_types/_form_sessions.html.haml +12 -0
  110. data/app/views/spina/admin/conferences/presentation_types/_presentation_type.html.haml +8 -0
  111. data/app/views/spina/admin/conferences/presentation_types/edit.html.haml +1 -0
  112. data/app/views/spina/admin/conferences/presentation_types/index.html.haml +17 -0
  113. data/app/views/spina/admin/conferences/presentation_types/new.html.haml +1 -0
  114. data/app/views/spina/admin/conferences/presentations/_attachment_fields.html.haml +27 -0
  115. data/app/views/spina/admin/conferences/presentations/_attachment_row.html.haml +2 -0
  116. data/app/views/spina/admin/conferences/presentations/_form.html.haml +23 -0
  117. data/app/views/spina/admin/conferences/presentations/_form_presentation_details.html.haml +55 -0
  118. data/app/views/spina/admin/conferences/presentations/_form_presenters.html.haml +12 -0
  119. data/app/views/spina/admin/conferences/presentations/_presentation.html.haml +11 -0
  120. data/app/views/spina/admin/conferences/presentations/edit.html.haml +1 -0
  121. data/app/views/spina/admin/conferences/presentations/index.html.haml +23 -0
  122. data/app/views/spina/admin/conferences/presentations/new.html.haml +1 -0
  123. data/app/views/spina/admin/conferences/rooms/_form.html.haml +23 -0
  124. data/app/views/spina/admin/conferences/rooms/_form_presentations.html.haml +12 -0
  125. data/app/views/spina/admin/conferences/rooms/_form_room_details.html.haml +18 -0
  126. data/app/views/spina/admin/conferences/rooms/_room.html.haml +8 -0
  127. data/app/views/spina/admin/conferences/rooms/edit.html.haml +1 -0
  128. data/app/views/spina/admin/conferences/rooms/index.html.haml +17 -0
  129. data/app/views/spina/admin/conferences/rooms/new.html.haml +1 -0
  130. data/app/views/spina/admin/conferences/sessions/_form.html.haml +23 -0
  131. data/app/views/spina/admin/conferences/sessions/_form_presentations.html.haml +12 -0
  132. data/app/views/spina/admin/conferences/sessions/_form_session_details.html.haml +23 -0
  133. data/app/views/spina/admin/conferences/sessions/_session.html.haml +8 -0
  134. data/app/views/spina/admin/conferences/sessions/edit.html.haml +1 -0
  135. data/app/views/spina/admin/conferences/sessions/index.html.haml +17 -0
  136. data/app/views/spina/admin/conferences/sessions/new.html.haml +1 -0
  137. data/app/views/spina/admin/hooks/conferences/_head.html.haml +2 -0
  138. data/app/views/spina/admin/hooks/conferences/_primary_navigation.html.haml +20 -0
  139. data/app/views/spina/admin/hooks/conferences/_settings_secondary_navigation.html.haml +4 -0
  140. data/app/views/spina/admin/partables/admin/conferences/date_parts/_form.html.haml +5 -0
  141. data/app/views/spina/admin/partables/admin/conferences/email_address_parts/_form.html.haml +5 -0
  142. data/app/views/spina/admin/partables/admin/conferences/time_parts/_form.html.haml +7 -0
  143. data/app/views/spina/admin/partables/admin/conferences/url_parts/_form.html.haml +5 -0
  144. data/config/initializers/assets.rb +13 -0
  145. data/config/initializers/types.rb +13 -0
  146. data/config/locales/en.yml +354 -0
  147. data/config/routes.rb +27 -0
  148. data/db/migrate/20180907141228_create_spina_dates.rb +11 -0
  149. data/db/migrate/20180907141229_create_spina_email_addresses.rb +11 -0
  150. data/db/migrate/20180907141230_create_spina_urls.rb +11 -0
  151. data/db/migrate/20180907141231_create_spina_conferences_institutions.rb +12 -0
  152. data/db/migrate/20180907141232_create_spina_conferences_delegates.rb +15 -0
  153. data/db/migrate/20180907141234_create_spina_conferences_dietary_requirements.rb +11 -0
  154. data/db/migrate/20180907141235_create_spina_conferences_conferences.rb +12 -0
  155. data/db/migrate/20180907141236_create_spina_conferences_presentation_types.rb +13 -0
  156. data/db/migrate/20180907141238_create_join_table_spina_conferences_conference_delegate.rb +7 -0
  157. data/db/migrate/20180907141239_create_join_table_spina_conferences_delegate_presentation.rb +7 -0
  158. data/db/migrate/20180907141240_create_join_table_spina_conferences_delegate_dietary_requirement.rb +7 -0
  159. data/db/migrate/20180907141242_add_type_to_spina_pages.rb +7 -0
  160. data/db/migrate/20180907141243_create_spina_conferences_conference_page_parts.rb +14 -0
  161. data/db/migrate/20180914121905_add_logo_ref_to_spina_conferences_institutions.rb +7 -0
  162. data/db/migrate/20180916135431_create_spina_conferences_rooms.rb +13 -0
  163. data/db/migrate/20180916135432_create_spina_conferences_room_possessions.rb +10 -0
  164. data/db/migrate/20180916135433_create_spina_conferences_room_uses.rb +10 -0
  165. data/db/migrate/20180916135434_create_spina_conferences_presentations.rb +15 -0
  166. data/db/migrate/20181009122503_create_spina_times.rb +11 -0
  167. data/db/migrate/20181009130631_rename_spina_page_parts.rb +10 -0
  168. data/db/migrate/20181012190811_rename_spina_conferences_page_parts.rb +10 -0
  169. data/db/migrate/20181012213049_change_start_time_in_spina_conferences_conferences.rb +15 -0
  170. data/db/migrate/20181012214813_rename_start_time_in_spina_conferences_conferences.rb +7 -0
  171. data/db/migrate/20181017155705_add_dependent_option_to_foreign_keys.rb +36 -0
  172. data/db/migrate/20190408131354_change_spina_resources.rb +56 -0
  173. data/db/migrate/20190622131423_create_spina_conferences_parts.rb +12 -0
  174. data/db/migrate/20190701174807_remove_spina_conference_pages.rb +199 -0
  175. data/db/migrate/20190704135524_add_constraints_to_columns.rb +24 -0
  176. data/db/migrate/20200126034441_create_spina_conferences_presentation_attachment_types.rb +11 -0
  177. data/db/migrate/20200126213718_create_spina_conferences_presentation_attachments.rb +19 -0
  178. data/db/migrate/20200420104603_create_spina_conferences_dietary_requirement_name_translations.rb +19 -0
  179. data/db/migrate/20200420104740_create_spina_conferences_institution_name_and_city_translations.rb +20 -0
  180. data/db/migrate/20200420105057_create_spina_conferences_presentation_title_and_abstract_translations.rb +20 -0
  181. data/db/migrate/20200420105144_create_spina_conferences_presentation_attachment_type_name_translations.rb +20 -0
  182. data/db/migrate/20200420105201_create_spina_conferences_presentation_type_name_translations.rb +19 -0
  183. data/db/migrate/20200420105458_create_spina_conferences_room_building_and_number_translations.rb +20 -0
  184. data/db/migrate/20200420110407_move_attributes_to_translation_tables.rb +161 -0
  185. data/db/migrate/20200420120706_remove_name_from_spina_conferences_dietary_requirements.rb +7 -0
  186. data/db/migrate/20200420120759_remove_name_and_city_from_spina_conferences_institutions.rb +8 -0
  187. data/db/migrate/20200420120946_remove_title_and_abstract_from_spina_conferences_presentations.rb +8 -0
  188. data/db/migrate/20200420121310_remove_name_from_spina_conferences_presentation_attachment_types.rb +7 -0
  189. data/db/migrate/20200420121321_remove_name_from_spina_conferences_presentation_types.rb +7 -0
  190. data/db/migrate/20200420121443_remove_building_and_number_from_spina_conferences_rooms.rb +8 -0
  191. data/db/migrate/20200502133408_create_spina_conferences_conference_name_translations.rb +19 -0
  192. data/db/migrate/20200502183409_set_name_for_spina_conferences_conferences.rb +47 -0
  193. data/db/migrate/20200502183410_remove_institution_from_spina_conferences_conferences.rb +8 -0
  194. data/db/migrate/20200502183719_remove_spina_conferences_room_possessions.rb +60 -0
  195. data/db/migrate/20200503230732_rename_spina_conferences_room_uses.rb +8 -0
  196. data/db/migrate/20200510125131_create_spina_conferences_session_name_translations.rb +19 -0
  197. data/db/migrate/20200802165242_create_spina_conferences_events.rb +13 -0
  198. data/db/migrate/20200802184921_create_spina_conferences_event_name_description_and_location_translations.rb +21 -0
  199. data/db/migrate/20200911161632_update_spina_conferences_parts.rb +23 -0
  200. data/db/migrate/20200911161651_update_spina_parts.rb +37 -0
  201. data/db/migrate/20200911161726_move_presentation_parts.rb +101 -0
  202. data/db/migrate/20200911161739_move_conference_parts.rb +219 -0
  203. data/db/migrate/20201002122517_remove_spina_conferences_conference_page_parts.rb +14 -0
  204. data/db/migrate/20201007125625_add_timestamps_to_spina_conferences_parts.rb +9 -0
  205. data/lib/spina/admin/conferences.rb +20 -0
  206. data/lib/spina/admin/conferences/engine.rb +26 -0
  207. data/lib/spina/admin/conferences/migration/renaming.rb +81 -0
  208. data/lib/spina/admin/conferences/railtie.rb +34 -0
  209. data/lib/spina/admin/conferences/types/interval_type.rb +29 -0
  210. data/lib/spina/admin/conferences/version.rb +10 -0
  211. data/lib/tasks/spina/admin/conferences_tasks.rake +4 -0
  212. metadata +561 -0
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # Time parts.
7
+ class TimePart < ApplicationRecord
8
+ has_many :page_parts, as: :page_partable
9
+ has_many :parts, as: :partable
10
+ has_many :layout_parts, as: :layout_partable
11
+ has_many :structure_parts, as: :structure_partable
12
+
13
+ # @return [Date, nil] the date of the time part. Nil if the time part has no date and time
14
+ def date
15
+ return if content.blank?
16
+
17
+ content.to_date
18
+ end
19
+
20
+ # Sets the date of the time part.
21
+ # @param date [Date] the new date
22
+ # @return [void]
23
+ def date=(date)
24
+ if date.blank? || date.to_date.blank?
25
+ self.content = nil
26
+ return
27
+ end
28
+
29
+ self.content = date.to_date + (content.try(:seconds_since_midnight) || 0).seconds
30
+ end
31
+
32
+ # @return [ActiveSupport::TimeWithZone, nil] the time of the time part. Nil if the time part has no date and time
33
+ def time
34
+ return if content.blank?
35
+
36
+ content
37
+ end
38
+
39
+ # Sets the start time of the time part.
40
+ # @param time [ActiveSupport::TimeWithZone] the new time
41
+ # @return [void]
42
+ def time=(time)
43
+ if time.blank?
44
+ self.content = nil
45
+ return
46
+ end
47
+
48
+ self.content = Time.parse(time, date).to_datetime.in_time_zone
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # URL parts. The format is validated.
7
+ #
8
+ # = Validators
9
+ # HTTP(S) URL (using {HttpUrlValidator}):: {#content}.
10
+ # @see HttpUrlValidator
11
+ class UrlPart < ApplicationRecord
12
+ has_many :page_parts, as: :page_partable
13
+ has_many :parts, as: :partable
14
+ has_many :layout_parts, as: :layout_partable
15
+ has_many :structure_parts, as: :structure_partable
16
+
17
+ validates :content, 'spina/admin/conferences/http_url': true, allow_blank: true
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # Validator for dates which should occur during the associated conference.
7
+ class ConferenceDateValidator < ActiveModel::EachValidator
8
+ # Performs validation on the supplied record.
9
+ # @param record [ActiveRecord::Base] the associated record
10
+ # @param attribute [Symbol] the attribute key
11
+ # @param value [Date] the attribute value
12
+ def validate_each(record, attribute, value)
13
+ return if value.blank? || record.conference&.dates&.cover?(value.to_date)
14
+
15
+ record.errors.add(attribute, :outside_conference)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # Validator for email addresses.
7
+ class EmailAddressValidator < ActiveModel::EachValidator
8
+ # Performs validation on the supplied record.
9
+ # @param record [ActiveRecord::Base] the associated record
10
+ # @param attribute [Symbol] the attribute key
11
+ # @param value [String] the attribute value
12
+ def validate_each(record, attribute, value)
13
+ return if value.blank?
14
+
15
+ record.errors.add(attribute, :invalid_email_address) unless parse(value)
16
+ end
17
+
18
+ private
19
+
20
+ def parse(value)
21
+ Mail::Address.new(value).then { |address| address.domain.present? && address.local.present? }
22
+ rescue Mail::Field::IncompleteParseError
23
+ false
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # Validator for dates which should occur after a +start_date+.
7
+ class FinishDateValidator < ActiveModel::EachValidator
8
+ # Performs validation on the supplied record.
9
+ # @param record [ActiveRecord::Base] the associated record
10
+ # @param attribute [Symbol] the attribute key
11
+ # @param value [Date] the attribute value
12
+ def validate_each(record, attribute, value)
13
+ return if value.blank? || record.start_date.blank? || value >= record.start_date
14
+
15
+ record.errors.add(attribute, :before_start_date)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # Validator for times which should occur after a +start_time+.
7
+ class FinishTimeValidator < ActiveModel::EachValidator
8
+ # Performs validation on the supplied record.
9
+ # @param record [ActiveRecord::Base] the associated record
10
+ # @param attribute [Symbol] the attribute key
11
+ # @param value [Time] the attribute value
12
+ def validate_each(record, attribute, value)
13
+ return if value.blank? || record.start_time.blank? || value >= record.start_time
14
+
15
+ record.errors.add(attribute, :before_start_time)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin
5
+ module Conferences
6
+ # Validator for HTTP(S) URLs.
7
+ class HttpUrlValidator < ActiveModel::EachValidator
8
+ # Performs validation on the supplied record.
9
+ # @param record [ActiveRecord::Base] the associated record
10
+ # @param attribute [Symbol] the attribute key
11
+ # @param value [String] the attribute value
12
+ def validate_each(record, attribute, value)
13
+ return if value.blank?
14
+
15
+ record.errors.add(attribute, :invalid_http_https_url) unless parse(value)
16
+ end
17
+
18
+ private
19
+
20
+ def parse(value)
21
+ URI.parse(value).then { |uri| uri.is_a?(URI::HTTP) && uri.host.present? }
22
+ rescue URI::InvalidURIError
23
+ false
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ - content_for :application do
2
+ %header#header
3
+ #header_actions
4
+ = yield(:header_actions)
5
+
6
+ = render partial: 'spina/admin/shared/breadcrumbs'
7
+
8
+ %nav#secondary.tabs
9
+ %ul
10
+ %li{class: ('active' if controller_name == 'conferences')}
11
+ = link_to Spina::Admin::Conferences::Conference.model_name.human(count: 0), admin_conferences_conferences_path
12
+ %li{class: ('active' if controller_name == 'presentation_types')}
13
+ = link_to Spina::Admin::Conferences::PresentationType.model_name.human(count: 0), admin_conferences_presentation_types_path
14
+ %li{class: ('active' if controller_name == 'sessions')}
15
+ = link_to Spina::Admin::Conferences::Session.model_name.human(count: 0), admin_conferences_sessions_path
16
+
17
+ = yield
18
+
19
+ = render template: 'layouts/spina/admin/admin'
@@ -0,0 +1,10 @@
1
+ - content_for :application do
2
+ %header#header
3
+ #header_actions
4
+ = yield(:header_actions)
5
+
6
+ = render partial: 'spina/admin/shared/breadcrumbs'
7
+
8
+ = yield
9
+
10
+ = render template: 'layouts/spina/admin/admin'
@@ -0,0 +1,10 @@
1
+ - content_for :application do
2
+ %header#header
3
+ #header_actions
4
+ = yield(:header_actions)
5
+
6
+ = render partial: 'spina/admin/shared/breadcrumbs'
7
+
8
+ = yield
9
+
10
+ = render template: 'layouts/spina/admin/admin'
@@ -0,0 +1,17 @@
1
+ - content_for :application do
2
+ %header#header
3
+ #header_actions
4
+ = yield(:header_actions)
5
+
6
+ = render partial: 'spina/admin/shared/breadcrumbs'
7
+
8
+ %nav#secondary.tabs
9
+ %ul
10
+ %li{class: ('active' if controller_name == 'institutions')}
11
+ = link_to Spina::Admin::Conferences::Institution.model_name.human(count: 0), admin_conferences_institutions_path
12
+ %li{class: ('active' if controller_name == 'rooms')}
13
+ = link_to Spina::Admin::Conferences::Room.model_name.human(count: 0), admin_conferences_rooms_path
14
+
15
+ = yield
16
+
17
+ = render template: 'layouts/spina/admin/admin'
@@ -0,0 +1,10 @@
1
+ - content_for :application do
2
+ %header#header
3
+ #header_actions
4
+ = yield(:header_actions)
5
+
6
+ = render partial: 'spina/admin/shared/breadcrumbs'
7
+
8
+ = yield
9
+
10
+ = render template: 'layouts/spina/admin/admin'
@@ -0,0 +1,10 @@
1
+ - content_for :application do
2
+ %header#header
3
+ #header_actions
4
+ = yield(:header_actions)
5
+
6
+ = render partial: 'spina/admin/shared/breadcrumbs'
7
+
8
+ = yield
9
+
10
+ = render template: 'layouts/spina/admin/admin'
@@ -0,0 +1,3 @@
1
+ %tr
2
+ %td.align-center{ colspan: 1000 }
3
+ %em= message
@@ -0,0 +1,11 @@
1
+ .notification.notification-danger.animated.fadeInRight
2
+ = icon 'exclamation'
3
+ .notification-message
4
+ = t 'spina.notifications.alert'
5
+ %small
6
+ - errors.full_messages.each do |message|
7
+ = message
8
+ - unless errors.full_messages[-1] == message
9
+ %br
10
+ = link_to '#', data: { close_notification: true } do
11
+ = icon('cross')
@@ -0,0 +1,2 @@
1
+ document.querySelector('aside#notifications')
2
+ .insertAdjacentHTML('beforeend', '<%= j(render partial: 'errors', formats: :html, locals: { errors: errors }) %>');
@@ -0,0 +1,9 @@
1
+ %tr{ data: { conference_id: conference.id } }
2
+ %td= link_to conference.name, edit_admin_conferences_conference_path(conference)
3
+ %td= conference.year
4
+ %td= time_tag conference.start_date, l(conference.start_date, format: :long)
5
+ %td= time_tag conference.finish_date, l(conference.finish_date, format: :long)
6
+ %td.align-right
7
+ = link_to edit_admin_conferences_conference_path(conference), class: %w[button button-small button-link] do
8
+ = icon 'pencil-outline'
9
+ = t 'spina.edit'
@@ -0,0 +1,39 @@
1
+ .structure-form-pane{ class: ('active' if (local_assigns[:active] == true) || (f.index == 0)), id: "structure_form_pane_#{f.index}",
2
+ data: { conference_events_form: { target: 'formPane' } } }
3
+ .structure-form-part
4
+ .horizontal-form-label= Spina::Admin::Conferences::Event.human_attribute_name :name
5
+ .horizontal-form-content= f.text_field :name, placeholder: Spina::Admin::Conferences::Event.human_attribute_name(:name), required: true
6
+
7
+ .structure-form-part
8
+ .horizontal-form-label= Spina::Admin::Conferences::Event.human_attribute_name :date
9
+ .horizontal-form-content= f.date_field :date, value: f.object.conference.start_date&.strftime("%Y-%m-%d"),
10
+ class: 'conference-datepicker',
11
+ placeholder: Spina::Admin::Conferences::Event.human_attribute_name(:date),
12
+ required: true
13
+
14
+ .structure-form-part
15
+ .horizontal-form-label= Spina::Admin::Conferences::Event.human_attribute_name :start_time
16
+ .horizontal-form-content= f.time_field :start_time,
17
+ value: (f.object.start_time.to_formatted_s(:time) unless f.object.start_time.blank?),
18
+ placeholder: Spina::Admin::Conferences::Event.human_attribute_name(:start_time), required: true
19
+
20
+ .structure-form-part
21
+ .horizontal-form-label= Spina::Admin::Conferences::Event.human_attribute_name :finish_time
22
+ .horizontal-form-content= f.time_field :finish_time,
23
+ value: (f.object.finish_time.to_formatted_s(:time) unless f.object.finish_time.blank?),
24
+ placeholder: Spina::Admin::Conferences::Event.human_attribute_name(:finish_time), required: true
25
+
26
+ .structure-form-part
27
+ .horizontal-form-label= Spina::Admin::Conferences::Event.human_attribute_name :location
28
+ .horizontal-form-content= f.text_field :location, placeholder: Spina::Admin::Conferences::Event.human_attribute_name(:location),
29
+ required: true
30
+
31
+ .structure-form-part
32
+ .horizontal-form-label= Spina::Admin::Conferences::Event.human_attribute_name :description
33
+ .horizontal-form-content= render 'spina/admin/shared/rich_text_field', f: f, field: :description
34
+
35
+ = f.hidden_field :id
36
+
37
+ = f.hidden_field :_destroy, data: { conference_events_form_target: 'destroyField' }
38
+ = button_tag t('spina.delete'), type: 'button', class: %w[button button-mini button-link pull-right],
39
+ data: { action: 'conference-events-form#removeForm' }
@@ -0,0 +1,5 @@
1
+ %li{ class: ('active' if (local_assigns[:active] == true) || (local_assigns[:index] == 0) || local_assigns[:event_iteration]&.first?),
2
+ data: { conference_events_form: { target: 'formLink' } } }
3
+ = link_to event&.name || '',
4
+ "#structure_form_pane_#{local_assigns[:index] || local_assigns[:event_iteration]&.index}",
5
+ data: { conference_events_form_target: 'formLinkLabel' }
@@ -0,0 +1,23 @@
1
+ - if @conference.errors.any?
2
+ - content_for :notifications do
3
+ = render 'errors', errors: @conference.errors
4
+
5
+ = form_for @conference, remote: true, html: { autocomplete: 'off' } do |f|
6
+ %header#header
7
+ = render partial: 'spina/admin/shared/breadcrumbs'
8
+
9
+ #header_actions
10
+ %button.button.button-primary{ type: 'submit' }
11
+ = icon('check')
12
+ = t '.save'
13
+
14
+ = link_to t('spina.cancel'), admin_conferences_conferences_path, class: 'button', style: 'margin-right: 0'
15
+
16
+ %nav#secondary.tabs
17
+ %ul
18
+ - @tabs.each_with_index do |tab, i|
19
+ %li{ class: ('active' if i == 0) }
20
+ = link_to t(".#{tab}"), "##{tab}"
21
+
22
+ - @tabs.each do |tab|
23
+ = render "form_#{tab}", f: f
@@ -0,0 +1,29 @@
1
+ #conference_details.tab-content.active
2
+ .well
3
+ .horizontal-form{ data: { controller: 'select-options', select_options: { config_value: '{ "admin_conferences_conference_institution_id": { "value": "id", "text": "name" }, "admin_conferences_conference_room_ids": { "trigger": "admin_conferences_conference_institution_id", "key": "rooms", "value": "id", "text": "name" } }', records_values: @institutions } } }
4
+ .horizontal-form-group
5
+ .horizontal-form-label= Spina::Admin::Conferences::Conference.human_attribute_name :name
6
+ .horizontal-form-content= f.text_field :name, placeholder: Spina::Admin::Conferences::Conference.human_attribute_name(:name), required: true
7
+
8
+ .horizontal-form-group
9
+ .horizontal-form-label= Spina::Admin::Conferences::Conference.human_attribute_name :start_date
10
+ .horizontal-form-content= f.date_field :start_date, value: (@conference.start_date.strftime("%Y-%m-%d") if @conference.start_date.present?), class: 'conference-datepicker', placeholder: Spina::Admin::Conferences::Conference.human_attribute_name(:start_date), required: true
11
+
12
+ .horizontal-form-group
13
+ .horizontal-form-label= Spina::Admin::Conferences::Conference.human_attribute_name :finish_date
14
+ .horizontal-form-content= f.date_field :finish_date, value: (@conference.finish_date.strftime("%Y-%m-%d") if @conference.finish_date.present?), class: 'conference-datepicker', placeholder: Spina::Admin::Conferences::Conference.human_attribute_name(:finish_date), required: true
15
+
16
+ .horizontal-form-group{ class: dom_class(@conference.events) }
17
+ .horizontal-form-content
18
+ .structure-form{ data: { controller: 'conference-events-form', conference_events_form: { active_class: 'active' } } }
19
+ .structure-form-menu
20
+ %label= Spina::Admin::Conferences::Conference.human_attribute_name :events
21
+ %ul= render partial: 'event_row', collection: f.object.events, as: :event
22
+ = link_to icon('plus'), @conference.new_record? ? new_admin_conferences_event_path : new_admin_conferences_conference_event_path(@conference, index: @conference.events.size), remote: true, class: %w[button button-link icon], data: { conference_events_form_target: 'addFormLink', disable_with: '&#xF12C;' }
23
+
24
+ .structure-form-content{ data: { action: 'conferenceEventFieldsAdded->conference-events-form#updateURL' } }
25
+ = f.fields_for :events do |event_fields|
26
+ = render 'event_fields', f: event_fields
27
+
28
+ - unless @conference.new_record?
29
+ .pull-right= link_to t('spina.permanently_delete'), admin_conferences_conference_path(@conference), method: :delete, remote: true, data: { confirm: t('.delete_confirmation', name: @conference.name) }, class: %w[button button-link button-danger]
@@ -0,0 +1,12 @@
1
+ #delegates.tab-content.well
2
+ .table-container
3
+ %table.table
4
+ %thead
5
+ %tr
6
+ %th= Spina::Admin::Conferences::Delegate.human_attribute_name :name
7
+ %th= Spina::Admin::Conferences::Delegate.human_attribute_name :email_address
8
+ %th= Spina::Admin::Conferences::Delegate.human_attribute_name :institution
9
+ %th
10
+
11
+ %tbody
12
+ = render @conference.delegates.any? ? @conference.delegates : 'empty_list', message: t('spina.admin.conferences.delegates.index.no_delegates')
@@ -0,0 +1,15 @@
1
+ #parts.tab-content
2
+ .well
3
+ .horizontal-form
4
+ = f.fields_for :parts do |ff|
5
+ = ff.hidden_field :id
6
+ = ff.hidden_field :title
7
+ = ff.hidden_field :partable_type
8
+ = ff.hidden_field :name
9
+
10
+ .horizontal-form-group.page-part{ data: { name: ff.object.name } }
11
+ - case ff.object.partable_type
12
+ - when 'Spina::Structure'
13
+ = render 'form_structure', f: ff
14
+ - else
15
+ = render "spina/admin/partables/#{partable_type_partial_namespace(ff.object.partable_type)}/form", f: ff