spina-conferences-primer_theme 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +33 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/config/spina_conferences_primer_theme_manifest.js +8 -0
  6. data/app/assets/javascripts/spina/conferences/primer_theme/application.js +8 -0
  7. data/app/assets/javascripts/spina/conferences/primer_theme/controllers/slideshow_controller.es6 +68 -0
  8. data/app/assets/stylesheets/spina/conferences/primer_theme/_admin.sass +4 -0
  9. data/app/assets/stylesheets/spina/conferences/primer_theme/_custom.sass +0 -0
  10. data/app/assets/stylesheets/spina/conferences/primer_theme/_github.sass +2 -0
  11. data/app/assets/stylesheets/spina/conferences/primer_theme/_primer.sass +4 -0
  12. data/app/assets/stylesheets/spina/conferences/primer_theme/_turbolinks.sass +3 -0
  13. data/app/assets/stylesheets/spina/conferences/primer_theme/application.sass +13 -0
  14. data/app/controllers/spina/conferences/primer_theme/application_controller.rb +14 -0
  15. data/app/controllers/spina/conferences/primer_theme/conferences_controller.rb +55 -0
  16. data/app/controllers/spina/conferences/primer_theme/presentations_controller.rb +39 -0
  17. data/app/helpers/spina/conferences/primer_theme/application_helper.rb +64 -0
  18. data/app/helpers/spina/conferences/primer_theme/asset_helper.rb +48 -0
  19. data/app/helpers/spina/conferences/primer_theme/navigations_helper.rb +24 -0
  20. data/app/views/conferences_primer_theme/pages/about.html.haml +17 -0
  21. data/app/views/conferences_primer_theme/pages/committee.html.haml +9 -0
  22. data/app/views/conferences_primer_theme/pages/homepage.html.haml +6 -0
  23. data/app/views/conferences_primer_theme/pages/information.html.haml +6 -0
  24. data/app/views/conferences_primer_theme/pages/show.html.haml +2 -0
  25. data/app/views/layouts/conferences_primer_theme/application.html.haml +5 -0
  26. data/app/views/layouts/spina/conferences/primer_theme/application.html.haml +36 -0
  27. data/app/views/layouts/spina/conferences/primer_theme/conferences.html.haml +4 -0
  28. data/app/views/layouts/spina/conferences/primer_theme/presentations.html.haml +4 -0
  29. data/app/views/spina/application/_cookies.html.haml +14 -0
  30. data/app/views/spina/application/_current_conference_alert.html.haml +4 -0
  31. data/app/views/spina/application/_footer.html.haml +24 -0
  32. data/app/views/spina/application/_image_collection.html.haml +19 -0
  33. data/app/views/spina/application/_list_item.html.haml +1 -0
  34. data/app/views/spina/application/_logo.html.haml +1 -0
  35. data/app/views/spina/application/_mobile_navigation_item.html.haml +2 -0
  36. data/app/views/spina/application/_navigation.html.haml +12 -0
  37. data/app/views/spina/application/_navigation_item.html.haml +1 -0
  38. data/app/views/spina/application/_text.html.haml +1 -0
  39. data/app/views/spina/conferences/primer_theme/conferences/_conference.html.haml +16 -0
  40. data/app/views/spina/conferences/primer_theme/conferences/_conference.ics.erb +3 -0
  41. data/app/views/spina/conferences/primer_theme/conferences/_event.html.haml +12 -0
  42. data/app/views/spina/conferences/primer_theme/conferences/_event.ics.erb +3 -0
  43. data/app/views/spina/conferences/primer_theme/conferences/_events.html.haml +15 -0
  44. data/app/views/spina/conferences/primer_theme/conferences/_information.html.haml +4 -0
  45. data/app/views/spina/conferences/primer_theme/conferences/_institution.html.haml +6 -0
  46. data/app/views/spina/conferences/primer_theme/conferences/_institution_logo.html.haml +3 -0
  47. data/app/views/spina/conferences/primer_theme/conferences/_presentation.html.haml +14 -0
  48. data/app/views/spina/conferences/primer_theme/conferences/_presentation.ics.erb +3 -0
  49. data/app/views/spina/conferences/primer_theme/conferences/_presentation_type.html.haml +6 -0
  50. data/app/views/spina/conferences/primer_theme/conferences/_presentations.html.haml +29 -0
  51. data/app/views/spina/conferences/primer_theme/conferences/_sponsor.html.haml +9 -0
  52. data/app/views/spina/conferences/primer_theme/conferences/_sponsors.html.haml +6 -0
  53. data/app/views/spina/conferences/primer_theme/conferences/_tab.html.haml +1 -0
  54. data/app/views/spina/conferences/primer_theme/conferences/index.html.haml +21 -0
  55. data/app/views/spina/conferences/primer_theme/conferences/index.ics.erb +3 -0
  56. data/app/views/spina/conferences/primer_theme/conferences/show.html.haml +67 -0
  57. data/app/views/spina/conferences/primer_theme/conferences/show.ics.erb +5 -0
  58. data/app/views/spina/conferences/primer_theme/presentations/_abstract.html.haml +1 -0
  59. data/app/views/spina/conferences/primer_theme/presentations/_attachment.html.haml +6 -0
  60. data/app/views/spina/conferences/primer_theme/presentations/_attachments.html.haml +4 -0
  61. data/app/views/spina/conferences/primer_theme/presentations/show.html.haml +16 -0
  62. data/app/views/spina/pages/_committee_bio.html.haml +29 -0
  63. data/app/views/spina/pages/_committee_bios.html.haml +5 -0
  64. data/app/views/spina/pages/_constitution.html.haml +11 -0
  65. data/app/views/spina/pages/_contact.html.haml +4 -0
  66. data/app/views/spina/pages/_homepage_content.html.haml +15 -0
  67. data/app/views/spina/pages/_jumbotron.html.haml +2 -0
  68. data/app/views/spina/pages/_minutes.html.haml +8 -0
  69. data/app/views/spina/pages/_minutes_entry.html.haml +11 -0
  70. data/app/views/spina/pages/_partner_societies.html.haml +9 -0
  71. data/app/views/spina/pages/_partner_society.html.haml +25 -0
  72. data/config/initializers/assets.rb +13 -0
  73. data/config/initializers/themes/conferences_primer_theme.rb +247 -0
  74. data/config/locales/en.yml +149 -0
  75. data/config/routes.rb +11 -0
  76. data/lib/spina/conferences/primer_theme.rb +17 -0
  77. data/lib/spina/conferences/primer_theme/breadcrumbs/builder.rb +34 -0
  78. data/lib/spina/conferences/primer_theme/engine.rb +13 -0
  79. data/lib/spina/conferences/primer_theme/version.rb +9 -0
  80. data/lib/tasks/spina/conferences/primer_theme_tasks.rake +6 -0
  81. metadata +388 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ca72fb8eca3889c55b4744e661876a775eaedd0184ae7ecae35c0e96236ffc98
4
+ data.tar.gz: 0040d9889b8d5166cdb5858c566e4420e9e55665cece9770ba35d96eff6f68b6
5
+ SHA512:
6
+ metadata.gz: f5bf423f7fc4053c9fa212af9c5ad90a1ce49d502d199d62028bfe2dc24b80f0c5cd639df5b89ee53c89e271f9bc512e7bd99c7740b24d13634adc55f4f6f88a
7
+ data.tar.gz: 55730ad62896d1d75a0cb55e9f1e182b5f3a650b81b3f5ce60c380f9ea260621b656af9fc7ac174cccd19b04934a98e8692940721264693eb784f863dd9768d0
@@ -0,0 +1,20 @@
1
+ Copyright 2019 Justin Malčić
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ # PrimerTheme
2
+ A plugin for `Spina` that provides a frontend for `Spina::Admin::Conferences` using components from `Primer::ViewComponents`.
3
+
4
+ ## Usage
5
+ See the README for `Spina::Admin::Conferences`. Also make sure to ensure compilation of the assets for this gem by adding the following line to your
6
+ `manifest.js` file.
7
+
8
+ ```js
9
+ //= link spina_conferences_primer_theme_manifest.js
10
+ ```
11
+
12
+ ## Installation
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'spina-conferences-primer_theme'
17
+ ```
18
+
19
+ And then execute:
20
+ ```bash
21
+ $ bundle
22
+ ```
23
+
24
+ Or install it yourself as:
25
+ ```bash
26
+ $ gem install spina-conferences-primer_theme
27
+ ```
28
+
29
+ ## Contributing
30
+ Contributions welcome, open an issue first please.
31
+
32
+ ## License
33
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'Spina::Conferences::PrimerTheme'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ APP_RAKEFILE = File.expand_path('test/dummy/Rakefile', __dir__)
20
+ load 'rails/tasks/engine.rake'
21
+
22
+ load 'rails/tasks/statistics.rake'
23
+
24
+ require 'bundler/gem_tasks'
25
+
26
+ require 'rake/testtask'
27
+
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.libs << 'test'
30
+ t.pattern = 'test/**/*_test.rb'
31
+ t.verbose = false
32
+ t.warning = false
33
+ t.ruby_opts = %w[-W:no-deprecated]
34
+ end
35
+
36
+ task default: :test
@@ -0,0 +1,8 @@
1
+ //= link_directory ../stylesheets/spina/conferences/primer_theme .css
2
+ //= link_directory ../javascripts/spina/conferences/primer_theme .js
3
+ //= link spina_admin_conferences_manifest.js
4
+
5
+ //= link @github/details-dialog-element/dist/index.js
6
+ //= link @github/include-fragment-element/dist/index.js
7
+ //= link @github/tab-container-element/dist/index.js
8
+ //= link @github/filter-input-element/dist/index.js
@@ -0,0 +1,8 @@
1
+ //= require stimulus
2
+ //= require_directory ./controllers
3
+ //= require turbolinks
4
+
5
+ // eslint-disable-next-line no-undef
6
+ const application = Stimulus.Application.start()
7
+ // eslint-disable-next-line no-undef
8
+ application.register('slideshow', SlideshowController)
@@ -0,0 +1,68 @@
1
+ // eslint-disable-next-line no-unused-vars,no-undef
2
+ class SlideshowController extends Stimulus.Controller {
3
+ static get targets() {
4
+ return [
5
+ /**
6
+ * @private
7
+ * @property {HTMLElement[]} slideTargets - The slide elements.
8
+ */
9
+ 'slide'
10
+ ]
11
+ }
12
+
13
+ /**
14
+ * Returns the incrementer.
15
+ * @private
16
+ * @return {Number} The value for the incrementer.
17
+ */
18
+ get incrementer() {
19
+ return Number.parseInt(this.data.get('incrementer'))
20
+ }
21
+
22
+ /**
23
+ * Sets the incrementer.
24
+ * @private
25
+ * @param value {Number} The new value for the incrementer.
26
+ */
27
+ set incrementer(value) {
28
+ this.data.set('incrementer', value.toString())
29
+ this.showSlide()
30
+ }
31
+
32
+ /**
33
+ * Hook to start advancing the slides if necessary.
34
+ * @private
35
+ */
36
+ connect() {
37
+ this.showSlide()
38
+ if (this.data.has('advance')) {
39
+ setInterval(() => this.next(), 10000)
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Shows the slide that corresponds to the incrementer and hides all others.
45
+ * @private
46
+ */
47
+ showSlide() {
48
+ this.slideTargets.forEach((target, index) => target.hidden = index !== this.incrementer)
49
+ }
50
+
51
+ /**
52
+ * Increases the incrementer if there are more slides, or sets it to 0 if showing the last slide.
53
+ * @private
54
+ */
55
+ next() {
56
+ const incrementer = this.incrementer
57
+ this.incrementer = incrementer === this.slideTargets.length - 1 ? 0 : incrementer + 1
58
+ }
59
+
60
+ /**
61
+ * Decreases the incrementer if there are more slides, or sets it to 0 if showing the first slide.
62
+ * @private
63
+ */
64
+ previous() {
65
+ const incrementer = this.incrementer
66
+ this.incrementer = incrementer === 0 ? this.slideTargets.length - 1 : incrementer - 1
67
+ }
68
+ }
@@ -0,0 +1,4 @@
1
+ .admin
2
+ @import spina/admin_editing
3
+ #admin_bar
4
+ font-family: 'Metropolis', sans-serif
@@ -0,0 +1,2 @@
1
+ //noinspection CssUnknownTarget
2
+ @import @github/details-dialog-element/dist
@@ -0,0 +1,4 @@
1
+ //noinspection CssUnknownTarget
2
+ @import @primer/css
3
+ //noinspection CssUnknownTarget
4
+ @import @primer/octicons
@@ -0,0 +1,3 @@
1
+ //noinspection CssUnusedSymbol
2
+ .turbolinks-progress-bar
3
+ background-color: white
@@ -0,0 +1,13 @@
1
+ @import spina/conferences/primer_theme/custom
2
+
3
+ @import primer
4
+ @import github
5
+ @import turbolinks
6
+ @import admin
7
+
8
+ img
9
+ max-width: 100%
10
+ object-fit: cover
11
+ object-position: top left
12
+ address
13
+ font-style: normal
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Conferences
5
+ module PrimerTheme
6
+ # Base class from which controllers inherit
7
+ class ApplicationController < Spina::ApplicationController
8
+ def cookies_info
9
+ render partial: 'cookies'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Conferences
5
+ module PrimerTheme
6
+ # User-facing controller for conferences, serving both html and ics
7
+ class ConferencesController < ApplicationController
8
+ before_action :set_conference, :set_tab, :set_presentation_type, :set_breadcrumb, only: :show
9
+ before_action :set_metadata
10
+
11
+ def index
12
+ @conferences = Admin::Conferences::Conference.sorted.includes(institutions: [:logo])
13
+ respond_to :html, :ics
14
+ end
15
+
16
+ def show
17
+ add_breadcrumb @conference.name
18
+ respond_to :html, :ics
19
+ end
20
+
21
+ private
22
+
23
+ def set_conference
24
+ @conference = Admin::Conferences::Conference.includes(:events, :institutions,
25
+ presentation_types: [:translations],
26
+ presentations: [session: [:room], presenters: [:institution]])
27
+ .find(params[:id])
28
+ end
29
+
30
+ def set_tab
31
+ @tab = params[:tab] || 'information'
32
+ end
33
+
34
+ def set_presentation_type
35
+ @presentation_type = if params[:presentation_type].present?
36
+ @conference.presentation_types
37
+ .includes(presentations: [session: [:room], presenters: [:institution]])
38
+ .find(params[:presentation_type])
39
+ else
40
+ @conference
41
+ end
42
+ end
43
+
44
+ def set_breadcrumb
45
+ add_breadcrumb Admin::Conferences::Conference.model_name.human.pluralize, frontend_conferences_path
46
+ end
47
+
48
+ def set_metadata
49
+ @title = @conference.present? ? @conference.name : Admin::Conferences::Conference.model_name.human(count: 0)
50
+ @description = @conference.present? && @conference.has_content?(:text) ? helpers.strip_tags(@conference.content(:text)) : ''
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Conferences
5
+ module PrimerTheme
6
+ # User-facing controller for presentations, serving both html and ics
7
+ class PresentationsController < ApplicationController
8
+ before_action :set_presentation, :set_conference, :set_breadcrumb, :set_metadata
9
+
10
+ def show
11
+ add_breadcrumb @presentation.name
12
+ end
13
+
14
+ private
15
+
16
+ def set_presentation
17
+ @presentation = Admin::Conferences::Presentation.includes(:presenters, attachments: [attachment_type: [:translations]])
18
+ .find(params[:id])
19
+ end
20
+
21
+ def set_conference
22
+ @conference = Admin::Conferences::Conference.find(params[:conference_id]) if params[:conference_id].present?
23
+ end
24
+
25
+ def set_breadcrumb
26
+ return if @conference.blank?
27
+
28
+ add_breadcrumb Admin::Conferences::Conference.model_name.human.pluralize, frontend_conferences_path
29
+ add_breadcrumb @conference.name, frontend_conference_path(@conference)
30
+ end
31
+
32
+ def set_metadata
33
+ @title = @presentation.present? ? @presentation.name : Admin::Conferences::Presentation.model_name.human(count: 0)
34
+ @description = @presentation.present? ? helpers.strip_tags(@presentation.abstract) : ''
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Conferences
5
+ module PrimerTheme
6
+ # Base helper
7
+ module ApplicationHelper
8
+ def latest_conference
9
+ Spina::Admin::Conferences::Conference.sorted.first
10
+ end
11
+
12
+ def breadcrumbs(options = {}, &block)
13
+ render_breadcrumbs(builder: Breadcrumbs::Builder, **options, &block)
14
+ end
15
+
16
+ def ancestors
17
+ return [] if current_page.blank?
18
+
19
+ render Primer::BreadcrumbComponent.new(mb: 4) do
20
+ current_page.ancestors.each do |ancestor|
21
+ component.slot(:item, href: 'ancestor.materialized_path') { ancestor.menu_title }
22
+ end
23
+ component.slot(:item, selected: true) { menu_title }
24
+ end
25
+ end
26
+
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
+ def partable_for(*parts, parent: current_page)
46
+ association = case parent
47
+ when Spina::Page then :page_partable
48
+ when Spina::StructureItem then :structure_partable
49
+ when Spina::Account then :layout_partable
50
+ else :partable
51
+ end
52
+ part = parent.parts.find_by(name: parts)
53
+ [part, part.try(association)]
54
+ end
55
+
56
+ def calendar(name:, &block)
57
+ # noinspection SpellCheckingInspection
58
+ Icalendar::Calendar.new.tap { |calendar| calendar.x_wr_calname = name }
59
+ .then(&:to_ical).then { |calendar| calendar.insert(calendar.index('END:VCALENDAR'), capture(&block)) }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Conferences
5
+ module PrimerTheme
6
+ # Helper for computing asset sources
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 srcset(image, **options)
12
+ return if image.blank?
13
+
14
+ options = options.symbolize_keys
15
+ variant_options = options.delete(:variant)
16
+ factors = options.delete(:factors) || DEFAULT_FACTORS
17
+ variants_for image, variant_options: variant_options, factors: factors
18
+ end
19
+
20
+ def src(image, **options)
21
+ main_app.url_for(image.variant(**options))
22
+ end
23
+
24
+ private
25
+
26
+ def variants_for(image, variant_options:, factors:)
27
+ factors.inject({}) { |srcset, factor| srcset.update(variant_url(image, variant_options, factor) => "#{factor}x") }
28
+ end
29
+
30
+ def variant_url(image, variant_options, factor)
31
+ main_app.url_for(image.variant(resize_options(variant_options, factor)))
32
+ end
33
+
34
+ def resize_options(variant_options, factor)
35
+ variant_options.to_h { |key, value| [key, resize_dimensions_for_key(key, factor, value)] }
36
+ end
37
+
38
+ def resize_dimensions_for_key(key, factor, dimensions)
39
+ dimensions.collect { |dimension| resize_dimension(dimension, factor) } if METHODS_TO_RESIZE.include? key
40
+ end
41
+
42
+ def resize_dimension(dimension = 0, factor = 0)
43
+ factor * dimension
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end