diff --git a/Gemfile b/Gemfile index d52faad1c..743ff4d78 100644 --- a/Gemfile +++ b/Gemfile @@ -17,6 +17,9 @@ gem 'jsonapi-resources' # CSS framework gem 'bootstrap-sass' +gem 'bootstrap', '4.1.1' +gem 'material-sass', '4.1.1' +gem 'material_icons' gem 'font-awesome-sass' gem 'uglifier' # JavaScript compressor diff --git a/Gemfile.lock b/Gemfile.lock index e00ef2345..a72188955 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,6 +66,10 @@ GEM bonsai-elasticsearch-rails (7.0.1) elasticsearch-model (< 8) elasticsearch-rails (< 8) + bootstrap (4.1.1) + autoprefixer-rails (>= 6.0.3) + popper_js (>= 1.12.9, < 2) + sass (>= 3.5.2) bootstrap-datepicker-rails (1.8.0.1) railties (>= 3.0) bootstrap-kaminari-views (0.0.5) @@ -280,6 +284,11 @@ GEM mini_mime (>= 0.1.1) marcel (0.3.3) mimemagic (~> 0.3.2) + material-sass (4.1.1) + autoprefixer-rails (>= 6.0.3) + sass (>= 3.5.2) + material_icons (2.2.1) + railties (>= 3.2) memcachier (0.0.2) method_source (0.9.2) mime-types (3.2.2) @@ -336,6 +345,7 @@ GEM capybara (>= 2.1, < 4) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) + popper_js (1.14.5) powerpack (0.1.2) public_suffix (3.0.3) puma (3.12.0) @@ -510,6 +520,7 @@ DEPENDENCIES better_errors bluecloth bonsai-elasticsearch-rails + bootstrap (= 4.1.1) bootstrap-datepicker-rails bootstrap-kaminari-views bootstrap-sass @@ -556,6 +567,8 @@ DEPENDENCIES letter_opener listen loofah (>= 2.2.1) + material-sass (= 4.1.1) + material_icons memcachier newrelic_rpm omniauth (~> 1.3) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 419c55d00..cd1924033 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -18,4 +18,8 @@ // = require jquery-ui/widgets/autocomplete // = require bootstrap-sprockets // = require bootstrap-datepicker +// = require jquery +// = require popper +// = require bootstrap +// = require material // = require_tree . diff --git a/app/assets/javascripts/jquery-roadmap.js b/app/assets/javascripts/jquery-roadmap.js new file mode 100644 index 000000000..cc8fd6a32 --- /dev/null +++ b/app/assets/javascripts/jquery-roadmap.js @@ -0,0 +1,212 @@ +;(function(factory) { + "use strict"; + + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (typeof exports !== 'undefined') { + module.exports = factory(require('jquery'), window, document); + } else { + factory(jQuery, window, document); + } + +}(function($, window, document, undefined ) { + + "use strict"; + + // undefined is used here as the undefined global variable in ECMAScript 3 is + // mutable (ie. it can be changed by someone else). undefined isn't really being + // passed in so we can ensure the value of it is truly undefined. In ES5, undefined + // can no longer be modified. + + // window and document are passed through as local variables rather than global + // as this (slightly) quickens the resolution process and can be more efficiently + // minified (especially when both are regularly referenced in your plugin). + + /** + * jQuery custom plugin implement the roadmap functionality + */ + $.fn.roadmap = function(events, opts) { + if ( !events instanceof Array ) { + events = []; + } + + var defaults = { + slide: 1, + eventsPerSlide: 6, + rootClass: 'roadmap', + prevArrow: 'prev', + nextArrow: 'next', + orientation: 'auto', + eventTemplate: '
' + + '
####DATE###
' + + '
####CONTENT###
' + + '
' + }; + + var settings = $.extend({}, defaults, opts); + + var buildEvent = function(event, key) { + var html = '
  • ' + settings.eventTemplate + '
  • '; + html = html.replace('####DATE###', event.date); + html = html.replace('####CONTENT###', event.content); + + var left = (100/(settings.eventsPerSlide-1))*key; + + return $(html).css('left', left + '%'); + } + + return this.each(function() { + var _this = this; + var $this = $(this); + var currentSlide = settings.slide - 1; + + /** + * Store events and settings + */ + $this.data({ + events: events, + settings: settings, + currentSlide: currentSlide + }).addClass(settings.rootClass); + + var clear = function() { + $this.removeClass(settings.rootClass + '--initialized'); + + $this.find('.' + settings.rootClass + '__events').remove(); + $this.find('.' + settings.rootClass + '__navigation').remove(); + } + + var buildEvents = function() { + var currentSlide = $this.data('currentSlide'); + var settings = $this.data('settings'); + var events = $this.data('events'); + + $('
      ', {class: settings.rootClass + '__events'}).append(events.slice((currentSlide*settings.eventsPerSlide), ((currentSlide+1)*settings.eventsPerSlide)).map(buildEvent)).appendTo(_this); + } + + var buildNavigation = function() { + var currentSlide = $this.data('currentSlide'); + + var buildNav = function(nav) { + switch (nav) { + case 'prev': + if ( currentSlide > 0 ) { + return $('
    1. ' + settings.prevArrow + '
    2. '); + } + break; + + case 'next': + if ( (currentSlide+1)*settings.eventsPerSlide < events.length ) { + return $('
    3. ' + settings.nextArrow + '
    4. '); + } + break; + } + + return $('
    5. '); + } + + $('