spina-conferences-primer_theme 0.1.9 → 0.1.14

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/spina_conferences_primer_theme_manifest.js +1 -0
  3. data/app/controllers/spina/conferences/primer_theme/presentations_controller.rb +1 -6
  4. data/app/helpers/spina/conferences/primer_theme/application_helper.rb +6 -25
  5. data/app/helpers/spina/conferences/primer_theme/asset_helper.rb +9 -11
  6. data/app/views/conferences_primer_theme/pages/about.html.haml +3 -0
  7. data/app/views/conferences_primer_theme/pages/events.html.haml +12 -0
  8. data/app/views/conferences_primer_theme/pages/homepage.html.haml +4 -5
  9. data/app/views/layouts/conferences_primer_theme/application.html.haml +3 -1
  10. data/app/views/layouts/spina/conferences/primer_theme/application.html.haml +3 -2
  11. data/app/views/layouts/spina/conferences/primer_theme/conferences.html.haml +3 -2
  12. data/app/views/layouts/spina/conferences/primer_theme/presentations.html.haml +4 -2
  13. data/app/views/spina/admin/layout_partables/texts/_form.html.haml +4 -0
  14. data/app/views/spina/application/_current_conference_alert.html.haml +1 -1
  15. data/app/views/spina/application/_list_item.html.haml +1 -1
  16. data/app/views/spina/application/_mobile_navigation_item.html.haml +11 -2
  17. data/app/views/spina/application/_navigation_item.html.haml +12 -1
  18. data/app/views/spina/conferences/primer_theme/conferences/index.html.haml +1 -0
  19. data/app/views/spina/conferences/primer_theme/conferences/show.html.haml +3 -3
  20. data/app/views/spina/pages/_committee_bio.html.haml +11 -8
  21. data/app/views/spina/pages/_committee_bios.html.haml +1 -0
  22. data/app/views/spina/pages/_document.html.haml +15 -0
  23. data/app/views/spina/pages/_documents.html.haml +7 -0
  24. data/app/views/spina/pages/_event.html.haml +17 -0
  25. data/app/views/spina/pages/_events_list.html.haml +19 -0
  26. data/app/views/spina/pages/_minutes_entry.html.haml +1 -1
  27. data/app/views/spina/pages/_partner_societies.html.haml +1 -1
  28. data/app/views/spina/pages/_partner_society.html.haml +1 -1
  29. data/config/initializers/themes/conferences_primer_theme.rb +54 -2
  30. data/config/locales/en.rb +16 -0
  31. data/config/locales/en.yml +16 -0
  32. data/db/migrate/20210206170704_change_current_conference_alert_to_text.rb +29 -0
  33. data/lib/spina/conferences/primer_theme/version.rb +1 -1
  34. metadata +29 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 665965738e060bd5c6c9f90e5452f9cd84f92456a6e04e6de2fe85b594ecc397
4
- data.tar.gz: b3a31fb3bb0f867801f9f8fff03265ad9d33ec4cc8bb6acfdbe4b72ec8e8ff8f
3
+ metadata.gz: 747d8e4bd24f28e085f7f25e067975bded223945166f790a946344366c698604
4
+ data.tar.gz: d048d050d8b62c38bc33b831d4fbf6f3426b50b32123bc1d9ec423abdbb26eea
5
5
  SHA512:
6
- metadata.gz: 3e149a65b5ef03f743d3d9249a7cbe6e1b463090d10e1af8f833dbf49cebf416cc97e899d5c1340afc12cc67101a2b202a697d719c4a2ef11c35051d8079d03c
7
- data.tar.gz: 2fb6e336499d4b36b4cfba6521bd3dace00bc325668a618e97e55e2ac4c79de7f4fac45a3d8baf94ca9291488c5867ff49e2b5e6da77970bde371b1d8e6cd5cc
6
+ metadata.gz: a095e0ddfb8342743f321c5e1b3b79c342e4c6a106a91957d0a94559e13d0e4d1fb587d1c36f6080b012027f194d59ba2e8f9cd19ff739b87cf74dd310f636ad
7
+ data.tar.gz: d6f67677691a3183b7b870031552fc7c0c4a9c98a7be245f9997d8f58d7168dfaa41275cf4766d63b8a4de0147c7019bca03310a9928d0c331a80cca2f2701ce
@@ -6,3 +6,4 @@
6
6
  //= link @github/include-fragment-element/dist/index.js
7
7
  //= link @github/tab-container-element/dist/index.js
8
8
  //= link @github/filter-input-element/dist/index.js
9
+ //= link @github/details-menu-element/dist/index.js
@@ -5,7 +5,7 @@ module Spina
5
5
  module PrimerTheme
6
6
  # User-facing controller for presentations, serving both html and ics
7
7
  class PresentationsController < ApplicationController
8
- before_action :set_presentation, :set_conference, :set_breadcrumb, :set_metadata
8
+ before_action :set_presentation, :set_conference, :set_breadcrumb
9
9
 
10
10
  def show
11
11
  add_breadcrumb @presentation.name
@@ -34,11 +34,6 @@ module Spina
34
34
  add_breadcrumb Admin::Conferences::Conference.model_name.human.pluralize, frontend_conferences_path
35
35
  add_breadcrumb @conference.name, frontend_conference_path(@conference)
36
36
  end
37
-
38
- def set_metadata
39
- @title = @presentation.present? ? @presentation.name : Admin::Conferences::Presentation.model_name.human(count: 0)
40
- @description = @presentation.present? ? helpers.strip_tags(@presentation.abstract) : ''
41
- end
42
37
  end
43
38
  end
44
39
  end
@@ -5,43 +5,23 @@ module Spina
5
5
  module PrimerTheme
6
6
  # Base helper
7
7
  module ApplicationHelper
8
+ include Spina::PagesHelper
9
+
8
10
  def latest_conference
9
11
  Spina::Admin::Conferences::Conference.sorted.first
10
12
  end
11
13
 
12
- def breadcrumbs(options = {}, &block)
13
- render_breadcrumbs(builder: Breadcrumbs::Builder, **options, &block)
14
- end
15
-
16
14
  def ancestors
17
15
  return [] if current_page.blank?
18
16
 
19
17
  render Primer::BreadcrumbComponent.new(mb: 4) do |component|
20
18
  current_page.ancestors.each do |ancestor|
21
- component.slot(:item, href: 'ancestor.materialized_path') { ancestor.menu_title }
19
+ component.slot(:item, href: ancestor.materialized_path) { ancestor.menu_title }
22
20
  end
23
21
  component.slot(:item, selected: true) { current_page.menu_title }
24
22
  end
25
23
  end
26
24
 
27
- def author
28
- current_account.name
29
- end
30
-
31
- def description
32
- current_page.present? ? current_page.description : @description # rubocop:disable Rails/HelperInstanceVariable
33
- end
34
-
35
- def title
36
- # noinspection RailsI18nInspection
37
- t :'.title', title: current_page.present? ? current_page.title : @title, suffix: current_account.name # rubocop:disable Rails/HelperInstanceVariable
38
- end
39
-
40
- def seo_title
41
- # noinspection RailsI18nInspection
42
- t :'.title', title: current_page.present? ? current_page.seo_title : @title, suffix: current_account.name # rubocop:disable Rails/HelperInstanceVariable
43
- end
44
-
45
25
  def partable_for(*part_names, parent: current_page)
46
26
  association = case parent
47
27
  when Spina::Page then :page_partable
@@ -50,12 +30,13 @@ module Spina
50
30
  else :partable
51
31
  end
52
32
  parts = parent.parts.where(name: part_names)
53
- part_parents = parts.collect { |part| part.try(association) }
54
- [*parts, *part_parents]
33
+ partables = parts.collect { |part| part.try(association) }
34
+ [*parts, *partables]
55
35
  end
56
36
 
57
37
  def calendar(name:, &block)
58
38
  # noinspection SpellCheckingInspection
39
+ block ||= proc { '' }
59
40
  Icalendar::Calendar.new.tap { |calendar| calendar.x_wr_calname = name }
60
41
  .then(&:to_ical).then { |calendar| calendar.insert(calendar.index('END:VCALENDAR'), capture(&block)) }
61
42
  end
@@ -5,29 +5,27 @@ module Spina
5
5
  module PrimerTheme
6
6
  # Helper for computing asset sources
7
7
  module AssetHelper
8
- METHODS_TO_RESIZE = %i[resize_to_limit resize_to_fit resize_to_fill resize_and_pad].freeze
9
- DEFAULT_FACTORS = [1, 2, 3, 4].freeze
10
-
11
- def concat_srcset(image, **options)
12
- srcset(image, **options).collect { |src_path, size| "#{src_path} #{size}" }
13
- .join ', '
14
- end
15
-
16
8
  def srcset(image, **options)
17
9
  return if image.blank?
18
10
 
19
11
  options = options.symbolize_keys
20
12
  variant_options = options.delete(:variant)
13
+ return if variant_options.blank?
14
+
21
15
  factors = options.delete(:factors) || DEFAULT_FACTORS
22
16
  variants_for image, variant_options: variant_options, factors: factors
23
17
  end
24
18
 
25
- def src(image, **options)
26
- main_app.url_for(image.variant(**options))
19
+ def srcset_string(image, **options)
20
+ srcset(image, **options).collect { |key, value| "#{key} #{value}" }
21
+ .join(', ')
27
22
  end
28
23
 
29
24
  private
30
25
 
26
+ METHODS_TO_RESIZE = %i[resize_to_limit resize_to_fit resize_to_fill resize_and_pad].freeze
27
+ DEFAULT_FACTORS = [1, 2, 3, 4].freeze
28
+
31
29
  def variants_for(image, variant_options:, factors:)
32
30
  factors.inject({}) { |srcset, factor| srcset.update(variant_url(image, variant_options, factor) => "#{factor}x") }
33
31
  end
@@ -41,7 +39,7 @@ module Spina
41
39
  end
42
40
 
43
41
  def resize_dimensions_for_key(key, factor, dimensions)
44
- dimensions.collect { |dimension| resize_dimension(dimension, factor) } if METHODS_TO_RESIZE.include? key
42
+ METHODS_TO_RESIZE.include?(key) ? dimensions.collect { |dimension| resize_dimension(dimension, factor) } : dimensions
45
43
  end
46
44
 
47
45
  def resize_dimension(dimension = 0, factor = 0)
@@ -13,6 +13,9 @@
13
13
  - cache [partable_for(:minutes), content(:minutes)&.structure_items,
14
14
  content(:minutes)&.structure_items&.collect_concat(&:structure_parts)&.collect(&:structure_partable)] do
15
15
  .mt-4.col-12.col-md-6.float-md-left= render partial: 'minutes', object: content(:minutes)
16
+ - cache [partable_for(:documents), content(:documents)&.structure_items,
17
+ content(:documents)&.structure_items&.collect_concat(&:structure_parts)&.collect(&:structure_partable)] do
18
+ .mt-4.col-12.col-md-12.float-md-left= render partial: 'documents', object: content(:documents)
16
19
  - cache [partable_for(:partner_societies), content(:partner_societies)&.structure_items,
17
20
  content(:partner_societies)&.structure_items&.collect_concat(&:structure_parts)&.collect(&:structure_partable)] do
18
21
  - if has_content?(:partner_societies) && content(:partner_societies).structure_items.any?
@@ -0,0 +1,12 @@
1
+ - cache current_page do
2
+ %h1= current_page.title
3
+
4
+ - cache partable_for(:text) do
5
+ - if has_content? :text
6
+ .mt-4= render partial: 'text', object: content(:text)
7
+ - cache [partable_for(:events_list), content(:events_list)&.structure_items,
8
+ content(:events_list)&.structure_items&.collect_concat(&:structure_parts)&.collect(&:structure_partable)] do
9
+ - if has_content?(:events_list) && content(:events_list).structure_items.any?
10
+ .mt-2= render partial: 'events_list', object: content(:events_list)
11
+ - else
12
+ = render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
@@ -1,6 +1,5 @@
1
1
  - content_for :hero do
2
- - cache current_page do
3
- - cache partable_for(:gallery) do
4
- = render partial: 'homepage_content',
5
- layout: has_content?(:gallery) && content(:gallery).images.any? ? 'image_collection' : 'jumbotron',
6
- locals: { conference: latest_conference, advance: true, image_collection: content(:gallery) }
2
+ - cache [current_page, partable_for(:gallery), latest_conference] do
3
+ = render partial: 'homepage_content',
4
+ layout: has_content?(:gallery) && content(:gallery).images.any? ? 'image_collection' : 'jumbotron',
5
+ locals: { conference: latest_conference, advance: true, image_collection: content(:gallery) }
@@ -2,4 +2,6 @@
2
2
  - if current_page.ancestors.any?
3
3
  = ancestors
4
4
 
5
- = render template: 'layouts/spina/conferences/primer_theme/application'
5
+ = render template: 'layouts/spina/conferences/primer_theme/application',
6
+ locals: { author: current_account.name, description: current_page.description,
7
+ seo_title: current_page.seo_title, title: current_page.title }
@@ -5,12 +5,12 @@
5
5
  %meta{ name: 'author', content: author }
6
6
  %meta{ name: 'description', content: description }
7
7
  %meta{ name: 'viewport', content: 'initial-scale=1.0' }
8
- %meta{ name: 'og:title', content: title }
8
+ %meta{ name: 'og:title', content: t(:'.title', title: title, suffix: current_account.name) }
9
9
  %meta{ name: 'og:description', content: description }
10
10
  %meta{ name: 'turbolinks-cache-control', content: 'no-preview' }
11
11
  %base{ target: '_blank' }
12
12
  = csrf_meta_tags
13
- %title= seo_title
13
+ %title= t(:'.title', title: seo_title, suffix: current_account.name)
14
14
  = render 'spina/shared/google_site_verification'
15
15
  = render 'spina/shared/analytics'
16
16
  = stylesheet_link_tag 'spina/conferences/primer_theme/application', media: 'all', data: { turbolinks_track: true }
@@ -19,6 +19,7 @@
19
19
  %script{ type: 'module', src: asset_path('@github/include-fragment-element/dist/index.js') }
20
20
  %script{ type: 'module', src: asset_path('@github/tab-container-element/dist/index.js') }
21
21
  %script{ type: 'module', src: asset_path('@github/filter-input-element/dist/index.js') }
22
+ %script{ type: 'module', src: asset_path('@github/details-menu-element/dist/index.js') }
22
23
  = yield :head
23
24
  %body
24
25
  .admin= render 'spina/shared/admin_bar'
@@ -1,4 +1,5 @@
1
1
  - content_for :breadcrumbs do
2
- = breadcrumbs
2
+ = render_breadcrumbs(builder: Spina::Conferences::PrimerTheme::Breadcrumbs::Builder)
3
3
 
4
- = render template: 'layouts/spina/conferences/primer_theme/application'
4
+ = render template: 'layouts/spina/conferences/primer_theme/application',
5
+ locals: { author: current_account.name, description: @description, title: @title, seo_title: @title }
@@ -1,4 +1,6 @@
1
1
  - content_for :breadcrumbs do
2
- = breadcrumbs
2
+ = render_breadcrumbs(builder: Spina::Conferences::PrimerTheme::Breadcrumbs::Builder)
3
3
 
4
- = render template: 'layouts/spina/conferences/primer_theme/application'
4
+ = render template: 'layouts/spina/conferences/primer_theme/application',
5
+ locals: { author: current_account.name, description: strip_tags(@presentation.abstract), title: @presentation.name,
6
+ seo_title: @presentation.name }
@@ -0,0 +1,4 @@
1
+ = f.fields_for :layout_partable, f.object.layout_partable do |ff|
2
+ - object_id = (ff.object.persisted? ? ff.object.object_id : "new_association_#{ff.object.object_id}").to_s + "_content"
3
+ = ff.hidden_field :content, id: "#{object_id}_input", value: ff.object.content(fallback: false, default: nil)
4
+ %trix-editor.text-input.trix-content{ input: "#{object_id}_input" }
@@ -1,4 +1,4 @@
1
1
  - content_for :flash do
2
2
  - cache partable_for(:current_conference_alert, parent: current_account) do
3
3
  - if current_account.has_content? :current_conference_alert
4
- = render(Primer::FlashComponent.new(full: true, variant: :warning)) { current_account.content(:current_conference_alert) }
4
+ = render(Primer::FlashComponent.new(full: true, variant: :warning)) { current_account.content(:current_conference_alert).html_safe }
@@ -1 +1 @@
1
- %li.list-style-none.py-4.border-bottom= yield
1
+ %li.list-style-none.py-4.border-bottom{ id: local_assigns[:list_item_id]&.call(local_assigns) }= yield
@@ -1,2 +1,11 @@
1
- = link_to mobile_navigation_item.menu_title, mobile_navigation_item.materialized_path,
2
- class: %w[d-block py-2 border-top border-white-fade text-white]
1
+ - if mobile_navigation_item.has_children?
2
+ %details.details-reset
3
+ %summary.btn-link.d-block.py-2.border-top.border-white-fade.text-white
4
+ = mobile_navigation_item.menu_title
5
+ = render Primer::OcticonComponent.new(icon: 'chevron-down')
6
+ %ul.list-style-none
7
+ - mobile_navigation_item.children.each do |child|
8
+ %li= link_to child.menu_title, child.materialized_path, class: %w[d-block py-2 pl-3 border-top border-white-fade text-white]
9
+ - elsif mobile_navigation_item.is_root?
10
+ = link_to mobile_navigation_item.menu_title, mobile_navigation_item.materialized_path,
11
+ class: %w[d-block py-2 border-top border-white-fade text-white]
@@ -1 +1,12 @@
1
- .Header-item.d-none.d-lg-flex= link_to navigation_item.menu_title, navigation_item.materialized_path, class: 'Header-link'
1
+ - if navigation_item.has_children?
2
+ .Header-item.d-none.d-lg-flex
3
+ %details.dropdown.details-reset.details-overlay
4
+ %summary.Header-link
5
+ = navigation_item.menu_title
6
+ %span.dropdown-caret
7
+ %details-menu.dropdown-menu.dropdown-menu-se.mt-3{ role: 'menu' }
8
+ - navigation_item.children.in_menu.sorted.each do |child|
9
+ %li= link_to child.menu_title, child.materialized_path, class: 'dropdown-item'
10
+ - elsif navigation_item.is_root?
11
+ .Header-item.d-none.d-lg-flex
12
+ = link_to navigation_item.menu_title, navigation_item.materialized_path, class: 'Header-link'
@@ -14,6 +14,7 @@
14
14
  - if @conferences.any?
15
15
  %ul{ class: dom_class(@conferences), data: { filter: { list: true } } }
16
16
  = render partial: 'conference', collection: @conferences, layout: 'list_item',
17
+ locals: { list_item_id: ->(local_assigns) { dom_id(local_assigns[:conference]) } },
17
18
  cached: -> conference { [conference, conference.institutions, conference.institutions.collect(&:logo)] }
18
19
  - else
19
20
  = render Primer::BlankslateComponent.new(title: t(:'.no_conferences'), icon: 'mortar-board')
@@ -1,15 +1,15 @@
1
1
  - if @conference.has_content?(:submission_date) && @conference.content(:submission_date) >= Date.today
2
2
  - content_for :flash do
3
3
  - cache partable_for(:submission_url, :submission_date, :submission_text, parent: @conference) do
4
- = render Primer::FlashComponent.new(variant: :warning, full: true) do
4
+ = render Primer::FlashComponent.new(variant: :warning, full: true, classes: dom_class(@conference)) do
5
5
  - cache partable_for(:submission_url, parent: @conference) do
6
6
  - if @conference.content(:submission_url).present?
7
7
  = link_to t(:'.submit_abstract'), @conference.content(:submission_url),
8
- class: %i[btn btn-sm flash-action d-none d-sm-inline-block]
8
+ class: %i[btn btn-primary flash-action]
9
9
  - cache partable_for(:submission_date, parent: @conference) do
10
10
  %p
11
11
  = octicon('clock')
12
- = t :'.submit_by_html', date: time_tag(@conference.content(:submission_date), format: :short)
12
+ = t :'.submit_by_html', date: time_tag(@conference.content(:submission_date), format: :full)
13
13
  - cache partable_for(:submission_text, parent: @conference) do
14
14
  - if @conference.content(:submission_text).present?
15
15
  %p= @conference.content(:submission_text).html_safe
@@ -1,20 +1,23 @@
1
1
  - cache [committee_bio, committee_bio.structure_parts.collect(&:structure_partable)] do
2
2
  .d-flex.flex-column.flex-md-row.flex-items-start
3
3
  - cache partable_for(:profile_picture, parent: committee_bio) do
4
- - if committee_bio.has_content?(:profile_picture) && committee_bio.content(:profile_picture).persisted?
4
+ - if committee_bio.has_content?(:profile_picture) && committee_bio.content(:profile_picture).persisted? && committee_bio.content(:profile_picture).file.present?
5
5
  .flex-shrink-0
6
- = render Primer::AvatarComponent.new(src: src(committee_bio.content(:profile_picture).file, resize_to_fill: [150, 150]),
7
- srcset: concat_srcset(committee_bio.content(:profile_picture).file,
6
+ = render Primer::AvatarComponent.new(src: main_app.url_for(committee_bio.content(:profile_picture).file.variant(resize_to_fill: [150, 150])),
7
+ srcset: srcset_string(committee_bio.content(:profile_picture).file,
8
8
  variant: { resize_to_limit: [150, 150] }),
9
9
  draggable: false, alt: committee_bio.content(:name), size: 150, mr: [nil, nil, 3, nil],
10
10
  mb: [3, nil, 0, nil])
11
11
  .flex-auto
12
12
  .d-flex.flex-column.flex-md-row.mb-1
13
- - cache partable_for(:name, :role, parent: committee_bio) do
14
- - if committee_bio.has_content?(:name) && committee_bio.has_content?(:role)
15
- %h3.flex-auto= t :'.name_and_role', name: committee_bio.content(:name), role: committee_bio.content(:role)
16
- - elsif committee_bio.has_content?(:name)
17
- %h3.flex-auto= committee_bio.content(:name)
13
+ - cache partable_for(:name, :role, :institution, parent: committee_bio) do
14
+ .flex-column
15
+ - if committee_bio.has_content?(:name) && committee_bio.has_content?(:role)
16
+ %h3.flex-auto= t :'.name_and_role', name: committee_bio.content(:name), role: committee_bio.content(:role)
17
+ - elsif committee_bio.has_content?(:name)
18
+ %h3.flex-auto= committee_bio.content(:name)
19
+ - if committee_bio.has_content?(:institution)
20
+ %h4.flex-auto= committee_bio.content(:institution)
18
21
  .BtnGroup.mt-1.mt-md-0.ml-md-1{ aria: { label: t(:'.contact_buttons') } }
19
22
  - cache partable_for(:twitter_profile, parent: committee_bio) do
20
23
  - if committee_bio.has_content?(:twitter_profile)
@@ -1,6 +1,7 @@
1
1
  - if committee_bios.structure_items.any?
2
2
  %ul{ class: dom_class(committee_bios), id: dom_id(committee_bios) }
3
3
  = render partial: 'committee_bio', collection: committee_bios.structure_items.sorted_by_structure, layout: 'list_item',
4
+ locals: { list_item_id: ->(local_assigns) { dom_id(local_assigns[:committee_bio]) } },
4
5
  cached: ->(committee_bio) { [committee_bio, committee_bio.structure_parts.collect(&:structure_partable)] }
5
6
  - else
6
7
  = render Primer::BlankslateComponent.new(title: t(:'.no_bios'), icon: 'file')
@@ -0,0 +1,15 @@
1
+ - cache [document, document.structure_parts.collect(&:structure_partable)] do
2
+ %li.list-style-none.py-1.d-flex.flex-items-center
3
+ - cache partable_for(:name, parent: document) do
4
+ - if(document.has_content?(:name))
5
+ %h3.flex-auto= document.content(:name)
6
+ - else
7
+ %h3.flex-auto= t :'.no_name'
8
+ - cache partable_for(:attachment, parent: document) do
9
+ - if document.has_content?(:attachment) && document.content(:attachment).persisted?
10
+ = render Primer::ButtonComponent.new(tag: :a, ml: 2,
11
+ href: main_app.rails_blob_path(document.content(:attachment), disposition: :attachment)) do
12
+ = render Primer::OcticonComponent.new(icon: 'desktop-download')
13
+ = t(:'.download')
14
+ - else
15
+ .text-small.text-gray= t :'.no_file'
@@ -0,0 +1,7 @@
1
+ - if documents.present? && documents.structure_items.any?
2
+ = render Primer::SubheadComponent.new do |component|
3
+ = component.slot(:heading) { t :'.title' }
4
+
5
+ %ul{ class: dom_class(documents), id: dom_id(documents) }
6
+ = render partial: 'document', collection: documents.structure_items.sorted_by_structure,
7
+ cached: ->(document) { [document, document.structure_parts.collect(&:structure_partable)] }
@@ -0,0 +1,17 @@
1
+ - cache [event, event.structure_parts.collect(&:structure_partable)] do
2
+ .d-flex.flex-column.flex-items-start
3
+ - cache partable_for(:name, parent: event) do
4
+ - if event.has_content?(:name)
5
+ %h3.flex-auto= event.content(:name)
6
+ - cache partable_for(:location, :start_time, parent: event) do
7
+ %h4.flex-auto= t(:'.time_and_place', time: event.has_content?(:start_time) ? time_tag(event.content(:start_time), format: :ordinal_datetime_with_year) : t('.time_tbc'),
8
+ place: event.has_content?(:location) ? event.content(:location) : t('.location_tbc')).try(:html_safe)
9
+ - cache partable_for(:description, parent: event) do
10
+ - if event.has_content?(:description)
11
+ .mt-1.text-gray-light= event.content(:description).try(:html_safe)
12
+ - cache partable_for(:url, parent: event) do
13
+ - if event.has_content?(:url)
14
+ .mt-2
15
+ = render Primer::ButtonComponent.new(tag: :a, href: event.content(:url)) do
16
+ = render Primer::OcticonComponent.new(icon: 'link-external')
17
+ = t :'.more_info'
@@ -0,0 +1,19 @@
1
+ %div{ class: dom_class(events_list), id: dom_id(events_list) }
2
+ = render Primer::SubheadComponent.new(mt: 4) do |component|
3
+ = component.slot(:heading) { t :'.upcoming' }
4
+ - events_list.structure_items.sorted_by_structure.filter { |item| item.has_content?(:start_time) && item.content(:start_time) >= Time.now }.then do |events|
5
+ - if events.any?
6
+ %ul
7
+ = render partial: 'event', layout: 'list_item', cached: ->(event) { [event, event.structure_parts.collect(&:structure_partable)] },
8
+ collection: events
9
+ - else
10
+ = render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
11
+ = render Primer::SubheadComponent.new(mt: 4) do |component|
12
+ = component.slot(:heading) { t :'.past' }
13
+ - events_list.structure_items.sorted_by_structure.filter { |item| item.has_content?(:start_time) && item.content(:start_time) < Time.now }.then do |events|
14
+ - if events.any?
15
+ %ul
16
+ = render partial: 'event', layout: 'list_item', cached: ->(event) { [event, event.structure_parts.collect(&:structure_partable)] },
17
+ collection: events
18
+ - else
19
+ = render Primer::BlankslateComponent.new(title: t(:'.no_events'), icon: 'calendar')
@@ -1,5 +1,5 @@
1
1
  - cache [minutes_entry, minutes_entry.structure_parts.collect(&:structure_partable)] do
2
- %li.list-style-none.py-1.d-flex.flex-items-center
2
+ %li.list-style-none.py-1.d-flex.flex-items-center{ id: dom_id(local_assigns[:minutes_entry]) }
3
3
  - cache partable_for(:date, parent: minutes_entry) do
4
4
  .flex-auto= minutes_entry.has_content?(:date) ? t(:'.minutes_html', date: time_tag(minutes_entry.content(:date))) : t(:'.no_date')
5
5
  - cache partable_for(:attachment, parent: minutes_entry) do
@@ -4,7 +4,7 @@
4
4
  - if partner_societies.structure_items.any?
5
5
  %ul{ class: dom_class(partner_societies), id: dom_id(partner_societies) }
6
6
  = render partial: 'partner_society', collection: partner_societies.structure_items.sorted_by_structure,
7
- layout: 'list_item',
7
+ layout: 'list_item', locals: { list_item_id: ->(local_assigns) { dom_id(local_assigns[:partner_society]) } },
8
8
  cached: ->(partner_society) { [partner_society, partner_society.structure_parts.collect(&:structure_partable)] }
9
9
  - else
10
10
  = render Primer::BlankslateComponent.new(title: t(:'.no_societies'), icon: 'organization')
@@ -20,7 +20,7 @@
20
20
  - if partner_society.has_content? :description
21
21
  .text-gray= render partial: 'text', object: partner_society.content(:description)
22
22
  - cache partable_for(:logo, parent: partner_society) do
23
- - if partner_society.has_content?(:logo) && partner_society.content(:logo).persisted?
23
+ - if partner_society.has_content?(:logo) && partner_society.content(:logo).persisted? && partner_society.content(:logo).file.present?
24
24
  = image_tag(main_app.url_for(partner_society.content(:logo).file.variant(resize_to_limit: [200, 150])),
25
25
  srcset: srcset(partner_society.content(:logo).file, variant: { resize_to_limit: [200, 150] }), size: nil,
26
26
  alt_description: partner_society.content(:name), draggable: false, class: %w[mt-4 mt-md-0 mr-md-4])
@@ -36,6 +36,10 @@
36
36
  name: 'minutes',
37
37
  title: 'Minutes',
38
38
  partable_type: 'Spina::Structure'
39
+ }, {
40
+ name: 'documents',
41
+ title: 'Documents',
42
+ partable_type: 'Spina::Structure'
39
43
  }, {
40
44
  name: 'contact',
41
45
  title: 'Contact',
@@ -68,12 +72,16 @@
68
72
  name: 'sponsors',
69
73
  title: 'Sponsors',
70
74
  partable_type: 'Spina::Structure'
75
+ }, {
76
+ name: 'events_list',
77
+ title: 'Events',
78
+ partable_type: 'Spina::Structure'
71
79
  }]
72
80
 
73
81
  theme.layout_parts = [{
74
82
  name: 'current_conference_alert',
75
83
  title: 'Alert',
76
- partable_type: 'Spina::Line'
84
+ partable_type: 'Spina::Text'
77
85
  }, {
78
86
  name: 'github_url',
79
87
  title: 'GitHub URL',
@@ -114,6 +122,17 @@
114
122
  title: 'Attachment',
115
123
  partable_type: 'Spina::Attachment'
116
124
  }]
125
+ }, {
126
+ name: 'documents',
127
+ structure_parts: [{
128
+ name: 'name',
129
+ title: 'Name',
130
+ partable_type: 'Spina::Line'
131
+ }, {
132
+ name: 'attachment',
133
+ title: 'Attachment',
134
+ partable_type: 'Spina::Attachment'
135
+ }]
117
136
  }, {
118
137
  name: 'socials',
119
138
  structure_parts: [{
@@ -158,6 +177,10 @@
158
177
  name: 'name',
159
178
  title: 'Name',
160
179
  partable_type: 'Spina::Line'
180
+ }, {
181
+ name: 'institution',
182
+ title: 'Institution',
183
+ partable_type: 'Spina::Line'
161
184
  }, {
162
185
  name: 'role',
163
186
  title: 'Role',
@@ -194,6 +217,30 @@
194
217
  title: 'Website',
195
218
  partable_type: 'Spina::Admin::Conferences::UrlPart'
196
219
  }]
220
+ }, {
221
+ name: 'events_list',
222
+ title: 'Events',
223
+ structure_parts: [{
224
+ name: 'name',
225
+ title: 'Name',
226
+ partable_type: 'Spina::Line'
227
+ }, {
228
+ name: 'start_time',
229
+ title: 'Time',
230
+ partable_type: 'Spina::Admin::Conferences::TimePart'
231
+ }, {
232
+ name: 'location',
233
+ title: 'Location',
234
+ partable_type: 'Spina::Line'
235
+ }, {
236
+ name: 'description',
237
+ title: 'Description',
238
+ partable_type: 'Spina::Text'
239
+ }, {
240
+ name: 'url',
241
+ title: 'Link',
242
+ partable_type: 'Spina::Admin::Conferences::UrlPart'
243
+ }]
197
244
  }]
198
245
 
199
246
  theme.view_templates = [{
@@ -214,7 +261,12 @@
214
261
  name: 'about',
215
262
  title: 'About',
216
263
  description: 'Contains information about the society',
217
- page_parts: %w[text constitution minutes partner_societies contact]
264
+ page_parts: %w[text constitution minutes documents partner_societies contact]
265
+ }, {
266
+ name: 'events',
267
+ title: 'Events',
268
+ description: 'Contains details of past and upcoming events',
269
+ page_parts: %w[text events_list]
218
270
  }, {
219
271
  name: 'show',
220
272
  title: 'Blank',
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ {
4
+ en: {
5
+ date: {
6
+ formats: {
7
+ full: ->(time, _) { "%A, #{time.day.ordinalize} %B %Y" }
8
+ }
9
+ },
10
+ time: {
11
+ formats: {
12
+ ordinal_datetime_with_year: ->(time, _) { "#{time.day.ordinalize} %b %Y, %R" }
13
+ }
14
+ }
15
+ }
16
+ }
@@ -82,6 +82,11 @@ en:
82
82
  download: Download
83
83
  no_file: No file uploaded.
84
84
  no_date: No date specified.
85
+ documents:
86
+ title: Documents
87
+ download: Download
88
+ no_file: No file uploaded.
89
+ no_name: No name.
85
90
  partner_societies:
86
91
  title: Partner societies
87
92
  no_societies: No societies added.
@@ -89,6 +94,17 @@ en:
89
94
  website: Website
90
95
  email: Email
91
96
  contact_buttons: Contact buttons
97
+ events:
98
+ no_events: No events.
99
+ events_list:
100
+ upcoming: Upcoming events
101
+ past: Past events
102
+ no_events: No events.
103
+ event:
104
+ time_and_place: "%{place}, %{time}"
105
+ time_tbc: Time TBC
106
+ location_tbc: Location TBC
107
+ more_info: More information
92
108
 
93
109
  conferences:
94
110
  primer_theme:
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ChangeCurrentConferenceAlertToText < ActiveRecord::Migration[6.0]
4
+ def up
5
+ Spina::LayoutPart.where(name: 'current_conference_alert', layout_partable_type: 'Spina::Line').each do |layout_part|
6
+ if layout_part.partable.present?
7
+ Spina::Text.create(content: layout_part.partable.content).then do |text|
8
+ layout_part.partable.destroy
9
+ layout_part.update(partable: text)
10
+ end
11
+ else
12
+ layout_part.update(partable_type: 'Spina::Text')
13
+ end
14
+ end
15
+ end
16
+
17
+ def down
18
+ Spina::LayoutPart.where(name: 'current_conference_alert', layout_partable_type: 'Spina::Text').each do |layout_part|
19
+ if layout_part.partable.present?
20
+ Spina::Line.create(content: layout_part.partable.content).then do |line|
21
+ layout_part.partable.destroy
22
+ layout_part.update(partable: line)
23
+ end
24
+ else
25
+ layout_part.update(partable_type: 'Spina::Line')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,7 +3,7 @@
3
3
  module Spina
4
4
  module Conferences
5
5
  module PrimerTheme
6
- VERSION = '0.1.9'
6
+ VERSION = '0.1.14'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spina-conferences-primer_theme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Malčić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-23 00:00:00.000000000 Z
11
+ date: 2021-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: babel-transpiler
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.0.10
61
+ version: 0.0.19
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.0.10
68
+ version: 0.0.19
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rails
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 6.0.2
75
+ version: '6.0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 6.0.2
82
+ version: '6.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: spina
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '2.7'
139
- - !ruby/object:Gem::Dependency
140
- name: minitest-rails
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '6.0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '6.0'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: minitest-reporters
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -248,6 +234,20 @@ dependencies:
248
234
  - - "~>"
249
235
  - !ruby/object:Gem::Version
250
236
  version: '0.19'
237
+ - !ruby/object:Gem::Dependency
238
+ name: simplecov-lcov
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '0.8'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '0.8'
251
251
  - !ruby/object:Gem::Dependency
252
252
  name: web-console
253
253
  requirement: !ruby/object:Gem::Requirement
@@ -303,6 +303,7 @@ files:
303
303
  - app/helpers/spina/conferences/primer_theme/navigations_helper.rb
304
304
  - app/views/conferences_primer_theme/pages/about.html.haml
305
305
  - app/views/conferences_primer_theme/pages/committee.html.haml
306
+ - app/views/conferences_primer_theme/pages/events.html.haml
306
307
  - app/views/conferences_primer_theme/pages/homepage.html.haml
307
308
  - app/views/conferences_primer_theme/pages/information.html.haml
308
309
  - app/views/conferences_primer_theme/pages/show.html.haml
@@ -310,6 +311,7 @@ files:
310
311
  - app/views/layouts/spina/conferences/primer_theme/application.html.haml
311
312
  - app/views/layouts/spina/conferences/primer_theme/conferences.html.haml
312
313
  - app/views/layouts/spina/conferences/primer_theme/presentations.html.haml
314
+ - app/views/spina/admin/layout_partables/texts/_form.html.haml
313
315
  - app/views/spina/application/_cookies.html.haml
314
316
  - app/views/spina/application/_current_conference_alert.html.haml
315
317
  - app/views/spina/application/_footer.html.haml
@@ -347,6 +349,10 @@ files:
347
349
  - app/views/spina/pages/_committee_bios.html.haml
348
350
  - app/views/spina/pages/_constitution.html.haml
349
351
  - app/views/spina/pages/_contact.html.haml
352
+ - app/views/spina/pages/_document.html.haml
353
+ - app/views/spina/pages/_documents.html.haml
354
+ - app/views/spina/pages/_event.html.haml
355
+ - app/views/spina/pages/_events_list.html.haml
350
356
  - app/views/spina/pages/_homepage_content.html.haml
351
357
  - app/views/spina/pages/_jumbotron.html.haml
352
358
  - app/views/spina/pages/_minutes.html.haml
@@ -355,8 +361,10 @@ files:
355
361
  - app/views/spina/pages/_partner_society.html.haml
356
362
  - config/initializers/assets.rb
357
363
  - config/initializers/themes/conferences_primer_theme.rb
364
+ - config/locales/en.rb
358
365
  - config/locales/en.yml
359
366
  - config/routes.rb
367
+ - db/migrate/20210206170704_change_current_conference_alert_to_text.rb
360
368
  - lib/spina/conferences/primer_theme.rb
361
369
  - lib/spina/conferences/primer_theme/breadcrumbs/builder.rb
362
370
  - lib/spina/conferences/primer_theme/engine.rb
@@ -381,7 +389,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
381
389
  - !ruby/object:Gem::Version
382
390
  version: '0'
383
391
  requirements: []
384
- rubygems_version: 3.0.3
392
+ rubygems_version: 3.1.4
385
393
  signing_key:
386
394
  specification_version: 4
387
395
  summary: Spina::Admin::Conferences frontend theme.