mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Add schedule interval as attribute of a program
Also, the part of the schedule event is deleted and the length of the event types changes to the nearest suitable after changing the length of the interval. This closes #1220
This commit is contained in:
parent
d1bf19867c
commit
f6e74461ba
19 changed files with 104 additions and 35 deletions
|
|
@ -12,13 +12,15 @@ module Admin
|
|||
@program = @conference.program
|
||||
@program.assign_attributes(program_params)
|
||||
send_mail_on_schedule_public = @program.notify_on_schedule_public?
|
||||
event_schedules_count_was = @program.event_schedules.count
|
||||
|
||||
if @program.update_attributes(program_params)
|
||||
ConferenceScheduleUpdateMailJob.perform_later(@conference) if send_mail_on_schedule_public
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to admin_conference_program_path(@conference.short_title),
|
||||
notice: 'The program was successfully updated.'
|
||||
notice = 'The program was successfully updated.'
|
||||
notice += ' You changed schedule interval and some events were unscheduled.' if @program.event_schedules.count != event_schedules_count_was
|
||||
redirect_to admin_conference_program_path(@conference.short_title), notice: notice
|
||||
end
|
||||
format.js { render json: {} }
|
||||
end
|
||||
|
|
@ -36,7 +38,7 @@ module Admin
|
|||
private
|
||||
|
||||
def program_params
|
||||
params.require(:program).permit(:rating, :schedule_public, :schedule_fluid, :languages, :blind_voting, :voting_start_date, :voting_end_date, :selected_schedule_id)
|
||||
params.require(:program).permit(:rating, :schedule_public, :schedule_interval, :schedule_fluid, :languages, :blind_voting, :voting_start_date, :voting_end_date, :selected_schedule_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class SchedulesController < ApplicationController
|
|||
|
||||
@events_xml = schedules.map(&:event).group_by{ |event| event.time.to_date } if schedules
|
||||
@dates = @conference.start_date..@conference.end_date
|
||||
@step_minutes = EventType::LENGTH_STEP.minutes
|
||||
@step_minutes = @program.schedule_interval.minutes
|
||||
@conf_start = @conference.start_hour
|
||||
@conf_period = @conference.end_hour - @conf_start
|
||||
|
||||
|
|
|
|||
|
|
@ -15,17 +15,13 @@ class EventType < ActiveRecord::Base
|
|||
|
||||
alias_attribute :name, :title
|
||||
|
||||
# If LENGTH_STEP must be divisor of 60, otherwise the schedule wont be displayed properly
|
||||
|
||||
LENGTH_STEP = defined?(SCHEDULE_CELL_SIZE) ? SCHEDULE_CELL_SIZE : 15
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Check if length is multiple of LENGTH_STEP. Used as validation.
|
||||
# Check if length is a divisor of program schedule cell size. Used as validation.
|
||||
#
|
||||
def length_step
|
||||
errors.add(:length, "must be multiple of #{LENGTH_STEP}") if length % LENGTH_STEP != 0
|
||||
errors.add(:length, "must be a divisor of #{program.schedule_interval}") if program && length % program.schedule_interval != 0
|
||||
end
|
||||
|
||||
def capitalize_color
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class Program < ActiveRecord::Base
|
|||
where(state: :confirmed, is_highlight: true)
|
||||
end
|
||||
end
|
||||
has_many :event_schedules, through: :events
|
||||
|
||||
has_many :event_users, through: :events
|
||||
has_many :speakers, -> { distinct }, through: :event_users, source: :user do
|
||||
|
|
@ -52,11 +53,15 @@ class Program < ActiveRecord::Base
|
|||
|
||||
# validates :conference_id, presence: true, uniqueness: true
|
||||
validates :rating, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 10, only_integer: true }
|
||||
validates :schedule_interval, numericality: { greater_than_or_equal_to: 5, less_than_or_equal_to: 60 }, presence: true
|
||||
validate :schedule_interval_divisor_60
|
||||
validate :voting_start_date_before_end_date
|
||||
validate :voting_dates_exist
|
||||
|
||||
after_create :create_event_types
|
||||
after_create :create_difficulty_levels
|
||||
after_save :unschedule_unfit_events, if: :schedule_interval_changed?
|
||||
after_save :normalize_event_types_length, if: :schedule_interval_changed?
|
||||
validate :check_languages_format
|
||||
|
||||
# Returns all event_schedules for the selected schedule ordered by start_time
|
||||
|
|
@ -199,4 +204,31 @@ class Program < ActiveRecord::Base
|
|||
# We check if every language is a valid ISO 639-1 language
|
||||
errors.add(:languages, 'must be ISO 639-1 valid codes') unless languages_array.select{ |x| ISO_639.find(x).nil? }.empty?
|
||||
end
|
||||
|
||||
##
|
||||
# Check if schedule_interval is a divisor of 60 minutes
|
||||
#
|
||||
def schedule_interval_divisor_60
|
||||
errors.add(:schedule_interval, 'must be a divisor of 60') if schedule_interval > 0 && 60 % schedule_interval > 0
|
||||
end
|
||||
|
||||
##
|
||||
# Unschedule all the events which don't fit
|
||||
#
|
||||
def unschedule_unfit_events
|
||||
unfit_schedules = event_schedules.select do |event_schedule|
|
||||
event_schedule.start_time.min % schedule_interval > 0
|
||||
end
|
||||
EventSchedule.where(id: unfit_schedules.map(&:id)).destroy_all
|
||||
end
|
||||
|
||||
##
|
||||
# Change event type length according schedule interval
|
||||
#
|
||||
def normalize_event_types_length
|
||||
event_types.each do |event_type|
|
||||
new_length = event_type.length > schedule_interval ? event_type.length - (event_type.length % schedule_interval) : schedule_interval
|
||||
event_type.update_attributes length: new_length
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,6 +26,6 @@ class EventSerializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def length
|
||||
object.event_type.try(:length) || EventType::LENGTH_STEP
|
||||
object.event_type.try(:length) || object.event_type.program.schedule_interval
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
.col-md-12
|
||||
= semantic_form_for(@event_type, url: (@event_type.new_record? ? admin_conference_program_event_types_path : admin_conference_program_event_type_path(@conference.short_title, @event_type))) do |f|
|
||||
= f.input :title
|
||||
= f.input :length, input_html: {size: 3, type: 'number', step: EventType::LENGTH_STEP, min: EventType::LENGTH_STEP}
|
||||
= f.input :length, input_html: {size: 3, type: 'number', step: @event_type.program.schedule_interval, min: @event_type.program.schedule_interval}
|
||||
= f.input :description
|
||||
= f.input :minimum_abstract_length, input_html: {size: 3}
|
||||
= f.input :maximum_abstract_length, input_html: {size: 3}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
= f.input :schedule_fluid, label: 'Allow submitters to change their event after it is scheduled'
|
||||
= f.input :rating, hint: 'Enter the number of different rating levels you want to have for voting on proposals. Enter 0 if you do not want to vote on proposals.'
|
||||
= f.input :languages, hint: "Enter the languages allowed for events as values of #{link_to('ISO 639-1', 'http://www.loc.gov/standards/iso639-2/php/code_list.php', target: "_blank")} language codes separated with commas. The first language would be the default language. Leave it blank if you do not want to specify languages.".html_safe
|
||||
= f.input :schedule_interval, hint: "It is the minimal time interval of your schedule. The value should be 5, 6, 10, 12, 15, 20, 30 or 60. Warning! Some events could be unscheduled when changing this value."
|
||||
= f.input :blind_voting, hint: 'Enable this feature if you do not want to show voting results and voters prior to user submitting a vote. For the feature to work you need to set the voting dates below as well'
|
||||
= f.input :voting_start_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_start_date.to_formatted_s(:db_without_seconds) unless f.object.voting_start_date.nil?) }
|
||||
= f.input :voting_end_date, as: :string, input_html: { id: 'datetimepicker-voting_start_date', readonly: true, value: (f.object.voting_end_date.to_formatted_s(:db_without_seconds) unless f.object.voting_end_date.nil?) }
|
||||
|
|
|
|||
|
|
@ -49,6 +49,11 @@
|
|||
Yes
|
||||
- else
|
||||
No
|
||||
%dt
|
||||
Schedule interval
|
||||
%dd
|
||||
= @program.schedule_interval
|
||||
minutes
|
||||
|
||||
%h3 Voting Options
|
||||
%hr
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
- compact_grid = EventType::LENGTH_STEP < 15
|
||||
- cells_per_hour = 60 / EventType::LENGTH_STEP
|
||||
- compact_grid = @program.schedule_interval < 15
|
||||
- cells_per_hour = 60 / @program.schedule_interval
|
||||
/ use smaller cell heights for more compact grids
|
||||
- cell_height = compact_grid ? 32 : 58
|
||||
- date_event_schedules = @event_schedules.select{ |e| e.start_time.to_date.eql? date }
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
= room.name
|
||||
- (@conference.start_hour * cells_per_hour..@conference.end_hour * cells_per_hour).each do |slot|
|
||||
- hour = slot / cells_per_hour
|
||||
- minutes = (EventType::LENGTH_STEP * (slot % cells_per_hour)).to_s.rjust(2, '0')
|
||||
- minutes = (@program.schedule_interval * (slot % cells_per_hour)).to_s.rjust(2, '0')
|
||||
- time = "#{hour}:#{minutes}"
|
||||
.schedule-room-slot{ id: "schedule-room-#{room.guid}-#{hour}-#{minutes}", |
|
||||
room_id: room.id, |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
- cells_length = event.event_type.length / EventType::LENGTH_STEP
|
||||
- cells_length = event.event_type.length / @program.schedule_interval
|
||||
/ this height fits the room cells
|
||||
- compact_grid = EventType::LENGTH_STEP < 15
|
||||
- compact_grid = @program.schedule_interval < 15
|
||||
- single_cell_height = compact_grid ? 32 : 58
|
||||
- height = (cells_length * single_cell_height)
|
||||
- height -= 23 unless compact_grid
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- intervals = hrs_per_slide * 60 / EventType::LENGTH_STEP + 1
|
||||
- intervals = hrs_per_slide * 60 / @conference.program.schedule_interval + 1
|
||||
- width = 85 / intervals
|
||||
- carousel_number = (@conf_period / hrs_per_slide.to_f).ceil
|
||||
.carousel.slide{ id: "carousel-#{ date }-#{ hrs_per_slide }", |
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
- if event_schedule
|
||||
/ There is an event, calculate the span and show it
|
||||
- event_span = (event_schedule.end_time.to_i - start_room_time.to_i) / 60 / EventType::LENGTH_STEP
|
||||
- event_span = (event_schedule.end_time.to_i - start_room_time.to_i) / 60 / @conference.program.schedule_interval
|
||||
- span = ((event_span + i - 1 ) > intervals ? intervals + 1 - i : event_span)
|
||||
= render partial: 'schedule_item', locals: {event: event_schedule.event, event_schedule: event_schedule, span: span, width: width}
|
||||
- else
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
%start= @conference.start_date
|
||||
%end= @conference.end_date
|
||||
%days= (@conference.end_date - @conference.start_date).to_i + 1
|
||||
%timeslot_duration= length_timestamp(EventType::LENGTH_STEP)
|
||||
%timeslot_duration= length_timestamp(@conference.program.schedule_interval)
|
||||
|
||||
- if @events_xml.any?
|
||||
- @events_xml.keys.each.with_index(1) do |day, index|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue