diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/admin/holidays.js | 23 | ||||
-rw-r--r-- | app/assets/stylesheets/admin.scss | 5 | ||||
-rw-r--r-- | app/controllers/admin_holiday_imports_controller.rb | 28 | ||||
-rw-r--r-- | app/controllers/admin_holidays_controller.rb | 2 | ||||
-rw-r--r-- | app/models/holiday_import.rb | 93 | ||||
-rw-r--r-- | app/views/admin_holiday_imports/new.html.erb | 81 | ||||
-rw-r--r-- | app/views/admin_holidays/_edit_form.html.erb | 2 | ||||
-rw-r--r-- | app/views/admin_holidays/_form.html.erb | 11 |
8 files changed, 236 insertions, 9 deletions
diff --git a/app/assets/javascripts/admin/holidays.js b/app/assets/javascripts/admin/holidays.js index 81f269c80..55eae9e2a 100644 --- a/app/assets/javascripts/admin/holidays.js +++ b/app/assets/javascripts/admin/holidays.js @@ -14,14 +14,33 @@ $(function() { $('.holiday').each(function(index){ var holiday_row = $(this); var edit_button = holiday_row.find('.edit-button'); - edit_button.click(function(){ var edit_call = $.ajax({ type: 'GET', url: holiday_row.data('target') }); - edit_call.done(function(response) { holiday_row.html(response); }); return false; }); }); + + // Remove button removes form div for holiday from an import set + $('.remove-holiday').each(function(index){ + $(this).click(function(){ + $(this).parents('.import-holiday-info').remove(); + return false; + }); + }); + + if ($('#holiday_import_source_suggestions').is(':checked')){ + $('#holiday_import_ical_feed_url').attr("disabled", "disabled"); + } + // Enable and disable the feed element when that is selected as the import source + $('#holiday_import_source_feed').click(function(){ + $('#holiday_import_ical_feed_url').removeAttr("disabled"); + }); + + $('#holiday_import_source_suggestions').click(function(){ + $('#holiday_import_ical_feed_url').attr("disabled", "disabled"); + }); + }); diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 69fce108c..469c3ed91 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -143,5 +143,10 @@ body.admin { width: 200px; text-align: right; } + + #import_start_year, #import_end_year { + width: 75px; + } + } diff --git a/app/controllers/admin_holiday_imports_controller.rb b/app/controllers/admin_holiday_imports_controller.rb new file mode 100644 index 000000000..8596936f0 --- /dev/null +++ b/app/controllers/admin_holiday_imports_controller.rb @@ -0,0 +1,28 @@ +class AdminHolidayImportsController < AdminController + + def new + @holiday_import = HolidayImport.new(holiday_import_params) + @holiday_import.populate if @holiday_import.valid? + end + + def create + @holiday_import = HolidayImport.new(holiday_import_params) + if @holiday_import.save + notice = "Holidays successfully imported" + redirect_to admin_holidays_path, :notice => notice + else + render :new + end + end + + private + + def holiday_import_params(key = :holiday_import) + if params[key] + params[key].slice(:holidays_attributes, :start_year, :end_year, :source, :ical_feed_url) + else + {} + end + end + +end diff --git a/app/controllers/admin_holidays_controller.rb b/app/controllers/admin_holidays_controller.rb index 3c4b37530..9177ebd44 100644 --- a/app/controllers/admin_holidays_controller.rb +++ b/app/controllers/admin_holidays_controller.rb @@ -7,7 +7,7 @@ class AdminHolidaysController < AdminController def new @holiday = Holiday.new if request.xhr? - render :partial => 'new_form' + render :partial => 'new_form', :locals => { :holiday => @holiday } else render :action => 'new' end diff --git a/app/models/holiday_import.rb b/app/models/holiday_import.rb new file mode 100644 index 000000000..c6019fac0 --- /dev/null +++ b/app/models/holiday_import.rb @@ -0,0 +1,93 @@ +class HolidayImport + + include ActiveModel::Validations + + attr_accessor :holidays, + :ical_feed_url, + :start_year, + :end_year, + :start_date, + :end_date, + :source, + :populated + + validate :all_holidays_valid + validates_inclusion_of :source, :in => %w( suggestions feed ) + validates_presence_of :ical_feed_url, + :if => proc { |holiday_import| holiday_import.source == 'feed' } + + def initialize(opts = {}) + @populated = false + @start_year = opts.fetch(:start_year, Time.now.year).to_i + @end_year = opts.fetch(:end_year, Time.now.year).to_i + @start_date = Date.civil(start_year, 1, 1) + @end_date = Date.civil(end_year, 12, 31) + @source = opts.fetch(:source, 'suggestions') + @ical_feed_url = opts.fetch(:ical_feed_url, nil) + @country_code = AlaveteliConfiguration::iso_country_code.downcase + self.holidays_attributes = opts.fetch(:holidays_attributes, []) + end + + def populate + source == 'suggestions' ? populate_from_suggestions : populate_from_ical_feed + @populated = true + end + + def suggestions_country_name + IsoCountryCodes.find(@country_code).name if @country_code + end + + def period + start_year == end_year ? "#{start_year}" : "#{start_year}-#{end_year}" + end + + def save + holidays.all?(&:save) + end + + def holidays_attributes=(incoming_data) + incoming_data.each{ |offset, incoming| self.holidays << Holiday.new(incoming) } + end + + def holidays + @holidays ||= [] + end + + private + + def all_holidays_valid + errors.add(:base, 'These holidays could not be imported') unless holidays.all?(&:valid?) + end + + def populate_from_ical_feed + begin + cal_file = open(ical_feed_url) + cals = Icalendar.parse(cal_file, strict=false) + cal = cals.first + cal.events.each{ |cal_event| populate_from_ical_event(cal_event) } + rescue Errno::ENOENT, Exception => e + if e.message == 'Invalid line in calendar string!' + errors.add(:ical_feed_url, "Sorry, there's a problem with the format of that feed.") + elsif e.message.starts_with 'No such file or directory' + errors.add(:ical_feed_url, "Sorry we couldn't find that feed.") + else + raise e + end + end + end + + def populate_from_ical_event(cal_event) + if cal_event.dtstart >= start_date and cal_event.dtstart <= end_date + holidays << Holiday.new(:description => cal_event.summary, + :day => cal_event.dtstart) + end + end + + def populate_from_suggestions + holiday_info = Holidays.between(start_date, end_date, @country_code.to_sym, :observed) + holiday_info.each do |holiday_info_hash| + holidays << Holiday.new(:description => holiday_info_hash[:name], + :day => holiday_info_hash[:date]) + end + end +end diff --git a/app/views/admin_holiday_imports/new.html.erb b/app/views/admin_holiday_imports/new.html.erb new file mode 100644 index 000000000..047f321f9 --- /dev/null +++ b/app/views/admin_holiday_imports/new.html.erb @@ -0,0 +1,81 @@ +<% @title = "Create holidays from suggestions or iCal feed" %> +<h1><%= @title %></h1> + +<%= form_for( @holiday_import, :as => 'holiday_import', :url => '', :method => 'get', :html => { :class => 'form-horizontal form-inline' }) do |f| %> + <% if @holiday_import.holidays.empty? %> + <%= error_messages_for 'holiday_import', :header_message => 'There was a problem with these import settings' %> + <% end %> + <legend>Import settings</legend> + <div> + <div class="control-group"> + <label class="control-label">Choose the years to import holidays for</label> + <div class="controls"> + <label for="import_start_year" class="inline">Start year:</label> + <%= f.select :start_year, (Time.now.year)..(Time.now.year + 5) %> + <label for="import_end_year" class="inline">End year:</label> + <%= f.select :end_year, (Time.now.year)..(Time.now.year + 5) %> + </div> + </div> + + <div class="control-group"> + <label class="control-label">Import from built-in suggestions or iCal feed</label> + <div class="controls"> + <label class="radio inline"> + <%= f.radio_button :source, "suggestions" %>Built-in suggestions + </label> + <label class="radio inline"> + <%= f.radio_button :source, "feed" %>iCal feed + </label> + </div> + </div> + + <div class="control-group"> + <label class="control-label">iCal feed URL:</label> + <div class="controls"> + <%= f.text_field 'ical_feed_url' %> + </div> + </div> + + <div class="control-group"> + <input type="submit" value="Show holidays" class="btn btn-primary"> + </div> + + </div> +<% end %> + +<% if @holiday_import.populated %> + <h2>Holidays to import</h2> + + <table class="table table-striped table-condensed"> + <tbody> + <tr> + <td> + <% if @holiday_import.holidays.empty? %> + <% if @holiday_import.source == 'suggestions' %> + Sorry, we don't have any built-in suggestions for holiday days in <%= @holiday_import.suggestions_country_name %>. + <% else %> + Sorry, we couldn't find any holidays in that iCal feed. + <% end %> + <% else %> + <%= form_for( @holiday_import, :as => 'holiday_import', :url => admin_holiday_imports_path, :html => { :class => 'form-inline' } ) do |f| -%> + <%= error_messages_for 'holiday_import' %> + <legend> + <% if @holiday_import.source == 'suggestions' %> + Suggested holidays for <%= @holiday_import.suggestions_country_name %> (<%= @holiday_import.period %>) + <% else %> + Holidays from feed (<%= @holiday_import.period %>) + <% end %> + </legend> + <%= f.fields_for :holidays do |holiday_fields| %> + <div class="import-holiday-info"> + <%= render :partial => 'admin_holidays/form', :locals => {:f => holiday_fields, :context => :import, :holiday => holiday_fields.object } %> + </div> + <% end%> + <%= f.submit "Import", :class => 'btn btn-warning' %> + <% end %> + <% end %> + </td> + </tr> + </tbody> + </table> +<% end %> diff --git a/app/views/admin_holidays/_edit_form.html.erb b/app/views/admin_holidays/_edit_form.html.erb index 1a4047890..b750dbf4c 100644 --- a/app/views/admin_holidays/_edit_form.html.erb +++ b/app/views/admin_holidays/_edit_form.html.erb @@ -1,6 +1,6 @@ <td> <%= form_for(@holiday, :url => admin_holiday_path(@holiday), :html => { :class => 'form-inline edit-holiday-form'}) do |f| -%> - <%= render :partial => 'form', :locals => { :f => f, :holiday => @holiday } %> + <%= render :partial => 'form', :locals => { :f => f, :holiday => @holiday, :context => :edit } %> <% end %> <div class="holiday-destroy "> diff --git a/app/views/admin_holidays/_form.html.erb b/app/views/admin_holidays/_form.html.erb index f61c5fc61..35370e5fc 100644 --- a/app/views/admin_holidays/_form.html.erb +++ b/app/views/admin_holidays/_form.html.erb @@ -11,11 +11,12 @@ <div class="holiday-day"> <%= f.date_select :day, { :use_month_numbers => true }, { :class => "day_select" } %> </div> - <div class="holiday-buttons"> - <%= link_to("Cancel", admin_holidays_path, :class => 'btn') %> - <%= f.submit "Save", :class => 'btn btn-warning' %> + <% if context == :import %> + <%= f.submit "Remove", :class => 'btn remove-holiday' %> + <% else %> + <%= link_to("Cancel", admin_holidays_path, :class => 'btn') %> + <%= f.submit "Save", :class => 'btn btn-warning' %> +<% end %> </div> - - |