Skip to content
This repository has been archived by the owner on Jul 24, 2020. It is now read-only.

Commit

Permalink
Add modular reservations calendar
Browse files Browse the repository at this point in the history
Resolves #1360
- Add Calendarable controller concern to generate HTML, JSON, and
  iCalendar representations of all the reservations for a given
  resource
- Add calendarable routing concern and clean up config/routes.rb
- Add Reservation#end_date to find the last day for a reservation,
  status-dependent (with model specs)
- Add the associated controller specs as a shared example as well
  as feature specs for equipment models
- Add calendars for categories, equipment models, equipment items,
  and users
- Fix routing issue with jQuery-UI-Bootstrap assets
  • Loading branch information
orenyk committed Feb 16, 2016
1 parent 840868f commit 1763385
Show file tree
Hide file tree
Showing 34 changed files with 644 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ script:
# - jshint --reporter=node_modules/jshint-stylish/stylish.js .
# rubocop Ruby / Rails linter
- bundle exec rubocop -D
- bundle exec rake
- xvfb-run -a bundle exec rake

# From Travis CI Support: This will route jobs to our beta build environment,
# which has much faster boot times, making it easier to debug via Travis.
Expand Down
9 changes: 8 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ruby '2.2.3' # Version in .ruby-version must match
gem 'rails', '~> 4.2.5'
gem 'mysql2', '~> 0.4.2'
gem 'rake', '~> 10.4.2'
gem 'rdoc', '~> 4.2.1'
gem 'jbuilder', '~> 2.4.0'

# simulate environment variables
gem 'dotenv-rails', '~> 2.0.2', :require => 'dotenv/rails-now'
Expand Down Expand Up @@ -38,6 +38,9 @@ gem 'nilify_blanks', '~> 1.2.1'
# ui
gem 'jquery-rails', '~> 4.0.5'
gem 'jquery-ui-rails', '~> 5.0.5'
gem 'jquery-datatables-rails', '~> 3.3.0'
gem 'fullcalendar-rails', '~> 2.5.0.0'
gem 'momentjs-rails', '~> 2.10.6'
gem 'rails4-autocomplete', '~> 1.1.1'
gem 'select2-rails', '~> 4.0.1'
gem 'kaminari', '~> 0.16.3'
Expand All @@ -49,6 +52,9 @@ gem 'simple_form', '~> 3.2.1'
gem 'cocoon', '~> 1.2.6'
gem 'redcarpet', '~> 3.3.4'

# iCalendar export
gem 'icalendar', '~> 2.3.0'

group :development, :test do
gem 'pry', '~> 0.10.3'
gem 'pry-rails', '~> 0.3.4'
Expand All @@ -61,6 +67,7 @@ group :development, :test do
gem 'rspec-rails', '~> 3.4.0'
gem 'shoulda-matchers', '~> 3.0.1'
gem 'capybara', '~> 2.5.0'
gem 'capybara-webkit', '~> 1.7.1'
gem 'guard-rspec', '~> 4.6.4'
gem 'spring', '~> 1.6.2'
gem 'spring-commands-rspec', '~> 1.0.4'
Expand Down
27 changes: 24 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ GEM
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
capybara-webkit (1.7.1)
capybara (>= 2.3.0, < 2.6.0)
json
chronic (0.10.2)
climate_control (0.0.3)
activesupport (>= 3.0)
Expand Down Expand Up @@ -135,6 +138,10 @@ GEM
font-awesome-rails (4.5.0.0)
railties (>= 3.2, < 5.0)
formatador (0.2.5)
fullcalendar-rails (2.5.0.0)
jquery-rails (>= 4.0.5, < 5.0.0)
jquery-ui-rails (>= 5.0.2)
momentjs-rails (>= 2.9.0)
fuubar (2.0.0)
rspec (~> 3.0)
ruby-progressbar (~> 1.4)
Expand Down Expand Up @@ -164,10 +171,19 @@ GEM
highline (1.7.8)
http_parser.rb (0.6.0)
i18n (0.7.0)
icalendar (2.3.0)
inline_svg (0.6.1)
activesupport (>= 4.0.4)
loofah (>= 2.0)
nokogiri (~> 1.6)
jbuilder (2.4.1)
activesupport (>= 3.0.0, < 5.1)
multi_json (~> 1.2)
jquery-datatables-rails (3.3.0)
actionpack (>= 3.1)
jquery-rails
railties (>= 3.1)
sass-rails
jquery-rails (4.0.5)
rails-dom-testing (~> 1.0)
railties (>= 4.2.0)
Expand Down Expand Up @@ -201,6 +217,8 @@ GEM
mimemagic (0.3.0)
mini_portile2 (2.0.0)
minitest (5.8.3)
momentjs-rails (2.10.6)
railties (>= 3.1)
multi_json (1.11.2)
multipart-post (2.0.0)
mysql2 (0.4.2)
Expand Down Expand Up @@ -311,8 +329,6 @@ GEM
rb-fsevent (0.9.7)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rdoc (4.2.1)
json (~> 1.4)
redcarpet (3.3.4)
ref (2.0.0)
remotipart (1.2.1)
Expand Down Expand Up @@ -430,6 +446,7 @@ DEPENDENCIES
capistrano-rails (~> 1.1.5)
capistrano-rvm (~> 0.1.2)
capybara (~> 2.5.0)
capybara-webkit (~> 1.7.1)
cocoon (~> 1.2.6)
codeclimate-test-reporter (~> 0.4.8)
coffee-rails (~> 4.1.1)
Expand All @@ -441,16 +458,21 @@ DEPENDENCIES
factory_girl_rails (~> 4.5.0)
ffaker (~> 2.1.0)
font-awesome-rails (~> 4.5.0)
fullcalendar-rails (~> 2.5.0.0)
fuubar (~> 2.0.0)
guard-livereload (~> 2.5.1)
guard-rspec (~> 4.6.4)
highline (~> 1.7.8)
icalendar (~> 2.3.0)
inline_svg (~> 0.6.1)
jbuilder (~> 2.4.0)
jquery-datatables-rails (~> 3.3.0)
jquery-rails (~> 4.0.5)
jquery-ui-rails (~> 5.0.5)
kaminari (~> 0.16.3)
letter_opener (~> 1.4.1)
letter_opener_web (~> 1.3.0)
momentjs-rails (~> 2.10.6)
mysql2 (~> 0.4.2)
net-ldap (~> 0.13.0)
nilify_blanks (~> 1.2.1)
Expand All @@ -470,7 +492,6 @@ DEPENDENCIES
rails_12factor (~> 0.0.3)
rails_admin (~> 0.8.1)
rake (~> 10.4.2)
rdoc (~> 4.2.1)
redcarpet (~> 3.3.4)
rspec-rails (~> 3.4.0)
rubocop (~> 0.35.1)
Expand Down
13 changes: 13 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
//= require select2
//= require jquery.sticky.js
//= require jquery.dotdotdot.js
//= require moment
//= require fullcalendar
//= require_tree
//= require_self

Expand Down Expand Up @@ -98,6 +100,17 @@ $(document).ready(function() {
$("#res-history-future").DataTable().order([2, "asc"]).draw();
$("#res-history-overdue,#res-history-past,#res-history-past_overdue").DataTable().order([4, "desc"]).draw();

// For reservation calendars
$('.res-cal').fullCalendar({
events: $('.res-cal').attr('data-src'),
eventRender: function(event, element) {
element.attr('data-role', 'cal-item');
if(event.hasItem) {
$(element).tooltip({title: event.location});
}
},
buttonText: { today: 'Today' }
});

// ### REPORTS JS ### //

Expand Down
7 changes: 7 additions & 0 deletions app/assets/stylesheets/_jquery_overrides.scss.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
nicely with the asset pipeline in production [2015-12-30]
*/

/* Component containers
----------------------------------*/

.ui-widget-content {
background: #ffffff/*{bgColorContent}*/ url(<%= image_path("jquery-ui/ui-bg_flat_75_ffffff_40x100.png") %>)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/;
}

/* Icons
----------------------------------*/

Expand Down
3 changes: 3 additions & 0 deletions app/assets/stylesheets/application.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
@import "jquery-ui-1.10.3.theme";
@import "jquery_overrides";

// Calendar assets
@import "fullcalendar";

// Autocomplete CSS
// ============================
@import "autocomplete";
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/equipment_models/_show.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ $border-att: 1px solid darken($body-bg, 20%);
a { vertical-align: middle; }
}

section {
section ~ section {
padding-top: 86px;
}

Expand Down
11 changes: 11 additions & 0 deletions app/controllers/categories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class CategoriesController < ApplicationController

include ActivationHelper
include CsvExport
include Calendarable

# --------- before filter methods -------- #
def set_current_category
Expand Down Expand Up @@ -81,4 +82,14 @@ def category_params
:max_renewal_times, :max_renewal_length, :sort_order,
:renewal_days_before_due)
end

def generate_calendar_reservations
Reservation.for_cat(@category.id).includes(:equipment_item)
.overlaps_with_date_range(@start_date, @end_date).finalized + \
Reservation.for_cat(@category.id).includes(:equipment_item).overdue
end

def generate_calendar_resource
@category
end
end
80 changes: 80 additions & 0 deletions app/controllers/concerns/calendarable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
module Calendarable
extend ActiveSupport::Concern

included do
# before filters and such
end

def calendar # rubocop:disable AbcSize, MethodLength
prepare_calendar_vars

# extract calendar data
respond_to do |format|
format.html
format.json { @calendar_res = generate_calendar_reservations }
# generate iCal version
# see https://gorails.com/forum/multi-event-ics-file-generation
format.ics do
@calendar_res = generate_calendar_reservations
cal = Icalendar::Calendar.new

@calendar_res.each do |r|
event = Icalendar::Event.new
event.dtstart = Icalendar::Values::Date.new(r.start_date)
event.dtend = Icalendar::Values::Date.new(r.end_date + 1.day)
event.summary = r.reserver.name
event.location = r.equipment_item.name unless r.equipment_item.nil?
event.url = reservation_url(r, format: :html)
cal.add_event(event)
end
cal.publish

response.headers['Content-Type'] = 'text/calendar'
response.headers['Content-Disposition'] =
'attachment; filename=reservations.ics'
render text: cal.to_ical
end
end
end

private

def prepare_calendar_vars
@start_date = calendar_start_date
@end_date = calendar_end_date
@resource = generate_calendar_resource
@src_path = generate_source_path
end

def calendar_start_date
if params[:start]
Time.zone.parse(params[:start]).to_date
elsif params[:calendar] && params[:calendar][:start_date]
Time.zone.parse(params[:calendar][:start_date]).to_date
else
Time.zone.today - 6.months
end
end

def calendar_end_date
if params[:end]
Time.zone.parse(params[:end]).to_date
elsif params[:calendar] && params[:calendar][:end_date]
Time.zone.parse(params[:calendar][:end_date]).to_date
else
Time.zone.today + 6.months
end
end

def generate_calendar_reservations
fail NotImplementedError
end

def generate_calendar_resource
fail NotImplementedError
end

def generate_source_path
"calendar_#{@resource.class.to_s.underscore}_path".to_sym
end
end
12 changes: 12 additions & 0 deletions app/controllers/equipment_items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class EquipmentItemsController < ApplicationController
before_action :set_equipment_model_if_possible, only: [:index, :new]

include ActivationHelper
include Calendarable

# ---------- before filter methods ---------- #

Expand All @@ -31,6 +32,7 @@ def index
end

def show
prepare_calendar_vars
end

def new
Expand Down Expand Up @@ -110,4 +112,14 @@ def equipment_item_params
.permit(:name, :serial, :deleted_at, :equipment_model_id,
:deactivation_reason, :notes)
end

def generate_calendar_reservations
@equipment_item.reservations.includes(:equipment_item)
.overlaps_with_date_range(@start_date, @end_date).finalized + \
@equipment_item.reservations.includes(:equipment_item).overdue
end

def generate_calendar_resource
@equipment_item
end
end
12 changes: 12 additions & 0 deletions app/controllers/equipment_models_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class EquipmentModelsController < ApplicationController
before_action :set_category_if_possible, only: [:index, :new]

include ActivationHelper
include Calendarable

# --------- before filter methods --------- #
def set_equipment_model
Expand Down Expand Up @@ -192,4 +193,15 @@ def fix_content_type(filedata)
def type_from_file_command(file)
Paperclip::FileCommandContentTypeDetector.new(file).detect
end

def generate_calendar_reservations
Reservation.for_eq_model(@equipment_model.id).includes(:equipment_item)
.overlaps_with_date_range(@start_date, @end_date).finalized + \
Reservation.for_eq_model(@equipment_model.id).includes(:equipment_item)
.overdue
end

def generate_calendar_resource
@equipment_model
end
end
11 changes: 11 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class UsersController < ApplicationController
:edit, :update]

include Autocomplete
include Calendarable
include CsvExport

# ------------ before filter methods ------------ #
Expand Down Expand Up @@ -253,4 +254,14 @@ def user_params
p[:view_mode] = p[:role] if p[:role]
p
end

def generate_calendar_reservations
@user.reservations.includes(:equipment_item)
.overlaps_with_date_range(@start_date, @end_date).finalized + \
@user.reservations.includes(:equipment_item).overdue
end

def generate_calendar_resource
@user
end
end
Loading

0 comments on commit 1763385

Please sign in to comment.