Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Wed, Oct 15, 1:38 PM
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index a148d45..48357d0 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -1,49 +1,89 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery.min
//= require jquery_ujs
//= require bootstrap.min
//= require_tree .
//= require highcharts
//= require jobs
//= require filesets
$(document).ready(function() {
- $(".schedule_run_form_plus").click(function() {
- addScheduleRun();
- });
- $(".schedule_run_form_remove").click(function() {
- removeScheduleRun();
- });
+ if ($('.schedule_run_form_plus').size() > 0) {
+ $(".schedule_run_form_plus").click(function() {
+ addScheduleRun();
+ return false;
+ });
+ };
+ if ($('.schedule_run_form_remove').size() > 0) {
+ $(".schedule_run_form_remove").click(function() {
+ removeScheduleRun();
+ return false;
+ });
+ };
+ if ($('.schedule_run_form').size() > 1) {
+ $('.schedule_run_form_remove').show();
+ };
});
function addScheduleRun() {
- var scheduleRun = $('.schedule_run_form:last').clone();
- scheduleRun.insertAfter('.schedule_run_form:last');
- $('.schedule_run_form:last input').val('');
- if ($('.schedule_run_form').size() > 1) {
- $(".schedule_run_form_remove").show();
- };
+ var count = $('.schedule_run_form').size();
+ var scheduleRun = $('.schedule_run_form:last').clone();
+
+ $(scheduleRun).find('label').each(function() {
+ var newLabel, oldLabel;
+ oldLabel = $(this).attr('for');
+ newLabel = oldLabel.replace(new RegExp(/_[0-9]+_/), "_" + count + "_");
+ $(this).attr('for', newLabel);
+ });
+
+ $(scheduleRun).find('select, input').each(function() {
+ var newId, oldId, newName, oldName;
+ oldId = $(this).attr('id');
+ newId = oldId.replace(new RegExp(/_[0-9]+_/), "_" + count + "_");
+ $(this).attr('id', newId);
+
+ oldName = $(this).attr('name');
+ newName = oldName.replace(new RegExp(/[0-9]+/), "[" + count + "]");
+ $(this).attr('name', newName);
+ });
+
+ scheduleRun.insertAfter('.schedule_run_form:last');
+ $('.schedule_run_form:last input').val('');
+ if (count > 0) {
+ $(".schedule_run_form_remove").show();
+ };
+ $('.destroyer:last').remove();
}
function removeScheduleRun() {
- if ($('.schedule_run_form').size() > 1) {
- $('.schedule_run_form:last').remove();
- if ($('.schedule_run_form').size() == 1) {
- $(".schedule_run_form_remove").hide();
- };
- }
- else {
- alert('nothing to remove');
- };
+ var count = $('.schedule_run_form').size();
+ if (count > 1) {
+ var last_id = count - 1;
+ $('<input>').attr({
+ type: 'hidden',
+ class: 'destroyer',
+ id: 'schedule_schedule_runs_attributes_' + last_id + '__destroy',
+ name: 'schedule[schedule_runs_attributes][' + last_id + '][_destroy]',
+ value: '1'
+ }).appendTo('form');
+
+ $('.schedule_run_form:last').remove();
+ if ($('.schedule_run_form').size() == 1) {
+ $(".schedule_run_form_remove").hide();
+ };
+ }
+ else {
+ alert('nothing to remove');
+ };
}
diff --git a/app/controllers/schedules_controller.rb b/app/controllers/schedules_controller.rb
index 5345ba4..f213ea1 100644
--- a/app/controllers/schedules_controller.rb
+++ b/app/controllers/schedules_controller.rb
@@ -1,72 +1,78 @@
class SchedulesController < ApplicationController
before_action :require_logged_in
before_action :fetch_host, only: [:new, :create, :show, :edit, :update]
before_action :fetch_job_id, only: [:new, :create, :show, :edit, :update]
before_action :fetch_schedule, only: [:show, :edit, :update]
def new
@schedule = @host.schedules.new
@schedule.schedule_runs.build
end
def show
respond_to do |format|
format.js {}
end
end
def edit
end
def update
if @schedule.update(fetch_params)
flash[:success] = 'Schedule updated successfully'
+ participating_hosts = @schedule.participating_hosts
+ if participating_hosts.size.nonzero?
+ participating_hosts.each(&:recalculate)
+ flash[:alert] = "You will need to redeploy the afffected clients: " +
+ participating_hosts.map(&:name).join(', ')
+ end
if @job_id
redirect_to edit_host_job_path(@host, @job_id, schedule_id: @schedule.id)
else
redirect_to new_host_job_path(@host, schedule_id: @schedule.id)
end
else
render :edit
end
end
def create
@schedule = @host.schedules.new(fetch_params)
@schedule.runtime = params[:schedule][:runtime] if params[:schedule][:runtime]
if @schedule.save
flash[:success] = 'Schedule created successfully'
if @job_id.present?
redirect_to edit_host_job_path(@host, @job_id, schedule_id: @schedule.id)
else
redirect_to new_host_job_path(@host, schedule_id: @schedule.id)
end
else
render :new
end
end
def destroy
end
private
def fetch_schedule
@schedule = @host.schedules.find(params[:id])
end
def fetch_host
@host = current_user.hosts.find(params[:host_id])
end
def fetch_job_id
@job_id = @host.job_templates.find(params[:job_id]).id if params[:job_id].present?
end
def fetch_params
params.require(:schedule).
- permit(:name, { schedule_runs_attributes: [[:id, :level, :month, :day, :time]] })
+ permit(:name, { schedule_runs_attributes: [[:id, :level, :month, :day, :time, :_destroy]] })
end
end
diff --git a/app/models/schedule.rb b/app/models/schedule.rb
index 77afffc..f382c49 100644
--- a/app/models/schedule.rb
+++ b/app/models/schedule.rb
@@ -1,33 +1,41 @@
# Schedule model is the application representation of Bacula's Schedule.
# It has references to a host and multiple schedule run in order to provide
# the desired Bacula configuration
class Schedule < ActiveRecord::Base
has_many :schedule_runs
belongs_to :host
+ has_many :job_templates
validates :name, presence: true
validates :name, uniqueness: { scope: :host }
validates_with NameValidator
- accepts_nested_attributes_for :schedule_runs
+ accepts_nested_attributes_for :schedule_runs, allow_destroy: true
# Constructs an array where each element is a line for the Schedule's bacula config
#
# @return [Array]
def to_bacula_config_array
['Schedule {'] +
[" Name = \"#{name_for_config}\""] +
schedule_runs.map {|r| " Run = #{r.schedule_line}" } +
['}']
end
# Generates a name that will be used for the configuration file.
# It is the name that will be sent to Bacula through the configuration
# files.
#
# @return [String]
def name_for_config
[host.name, name].join(' ')
end
+
+ # Returns the hosts that have enabled jobs that use this schedule
+ #
+ # @return [ActiveRecord::Colletion] the participating hosts
+ def participating_hosts
+ Host.joins(:job_templates).where(job_templates: { enabled: true, schedule_id: id }).uniq
+ end
end
diff --git a/app/views/schedules/_form.html.erb b/app/views/schedules/_form.html.erb
index 5926f30..2e9f830 100644
--- a/app/views/schedules/_form.html.erb
+++ b/app/views/schedules/_form.html.erb
@@ -1,49 +1,49 @@
<%= bootstrap_form_for(@schedule, url: url, method: method, layout: :horizontal,
label_col: 'col-xs-3', control_col: 'col-xs-8') do |f| %>
<%= f.text_field :name, required: true %>
<hr />
<% if ['schedule_runs.day','schedule_runs.month','scheduled_runs.time'] - @schedule.errors.keys %>
<div id="error_explanation" class="has-error">
<ul>
<% @schedule.errors.full_messages.each do |message| %>
<li><span class="help-block"><%= message %></span></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.fields_for :schedule_runs, @schedule.schedule_runs do |r| %>
<div class="schedule_run_form">
<%= r.select :level, options_for_select(ScheduleRun.options_for_select, r.object.level) %>
<%= r.text_field :month, placeholder: '[month | month-range]' %>
<p class="col-xs-10 col-xs-offset-1 help-block text-right">eg: jan-mar, feb, monthly</p>
<%= r.text_field :day, placeholder: '[week | week-range] day | day-range',
required: true %>
<p class="col-xs-10 col-xs-offset-1 help-block text-right">
eg: first sun, second-fifth mon, mon-sat
</p>
<%= r.text_field :time, placeholder: 'HH:MM', required: true %>
+ <hr />
</div>
- <hr />
<% end %>
<div class="col-xs-1 col-xs-offset-10">
<%= link_to '#', class: 'schedule_run_form_remove', style: 'display:none;' do %>
<span class="glyphicon glyphicon-remove text-danger"></span>
<% end %>
</div>
<div class="col-xs-1 col-xs-offset-10">
<%= link_to '#', class: 'schedule_run_form_plus' do %>
<span class="glyphicon glyphicon-plus text-success"></span>
<% end %>
</div>
<%= (hidden_field_tag :job_id, @job_id) if @job_id %>
<div class="form-group">
<div class="col-xs-offset-3 col-xs-8">
<%= f.submit class: 'btn btn-success' %>
</div>
</div>
<% end %>
diff --git a/app/views/schedules/edit.html.erb b/app/views/schedules/edit.html.erb
index 2f16826..b46f26b 100644
--- a/app/views/schedules/edit.html.erb
+++ b/app/views/schedules/edit.html.erb
@@ -1,9 +1,17 @@
<h1>Edit Schedule: <%= @schedule.name %></h1>
-<div class="container graybox">
- <%= render partial: 'form',
- locals: { url: host_schedule_path(@host, @schedule.id, job_id: @job_id), method: :patch } %>
+<div class="col-xs-5">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <h4>Edit Schedule</h4>
+ </div>
+
+ <br />
+
+ <%= render partial: 'form',
+ locals: { url: host_schedule_path(@host, @schedule.id, job_id: @job_id), method: :patch } %>
+ </div>
</div>
<%= link_to 'Back to job',
@job_id.present? ? edit_host_job_path(@host, @job_id) : new_host_job_path(@host) %>

Event Timeline