mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Do not use JS to initialize the schedule
- Only use JS for the drag&drop functionality and to the set/alter the time and rooms of the EventSchedule object. - Introduce has_many :events, through: :event_schedules association to get unscheduled event easily
This commit is contained in:
parent
71dab6b79c
commit
a394293500
12 changed files with 66 additions and 125 deletions
|
|
@ -1,76 +1,14 @@
|
|||
var conference; // Should be initialize in Schedule.loadEvents
|
||||
var schedule_id; // Should be initialize in Schedule.loadEvents
|
||||
var conference; // Should be initialize in Schedule.initialize
|
||||
var schedule_id; // Should be initialize in Schedule.initialize
|
||||
|
||||
var Schedule = {
|
||||
loadEvents: function(conference_param, schedule_id_param) {
|
||||
initialize: function(conference_param, schedule_id_param) {
|
||||
conference = conference_param;
|
||||
schedule_id = schedule_id_param;
|
||||
var url = '/admin/conference/' + conference + '/program/events';
|
||||
var callback = function(data) {
|
||||
$.each(data, function(key, val) {
|
||||
Schedule.newEvent(val);
|
||||
});
|
||||
};
|
||||
$.getJSON(url, callback);
|
||||
},
|
||||
newEvent: function(vars) {
|
||||
var height = (vars["length"] / 15 * 58) - 23; // this height fits the room cells
|
||||
var lines = Math.floor((height - 7) / 23); // subtracting the padding before calculate the number of lines
|
||||
var newEvent = $('<div class="schedule-event">'
|
||||
+ '<div class="schedule-event-text" style="-webkit-line-clamp: '+ lines + '; height: ' + (lines * 23) + 'px;">'
|
||||
+ '<span onclick="Schedule.remove(\'event-' + vars["guid"] + '\', \'' + conference +'\');" class="schedule-event-delete-button">X</span>'
|
||||
+ vars["title"] + '</div></div>');
|
||||
newEvent.attr("id", "event-" + vars["guid"]);
|
||||
newEvent.attr("guid", vars["guid"]);
|
||||
newEvent.css("height", height);
|
||||
newEvent.css('background-color',vars["track_color"]);
|
||||
newEvent.css('color',vars["track_text_color"]);
|
||||
var date = "none";
|
||||
var room = "none"
|
||||
var time = "none";
|
||||
for (i = 0; i < vars["event_schedules"].length; i++) {
|
||||
event_schedule = vars["event_schedules"][i];
|
||||
if(event_schedule["schedule_id"] == schedule_id){
|
||||
room = event_schedule["room_guid"];
|
||||
var d = new Date(event_schedule["start_time"]);
|
||||
date = d.getUTCFullYear() + "-"
|
||||
+ ('0' + (d.getUTCMonth() +1)).slice(-2) + '-'
|
||||
+ ('0' + d.getUTCDate()).slice(-2);
|
||||
minutes = d.getUTCMinutes();
|
||||
time = d.getUTCHours() + ':' + (minutes == 0 ? '00' : minutes);
|
||||
console.log("date: " + d);
|
||||
newEvent.attr("room", room);
|
||||
newEvent.attr("date", date);
|
||||
newEvent.attr("hour", time);
|
||||
}
|
||||
}
|
||||
newEvent.draggable({
|
||||
snap: '.schedule-room-slot',
|
||||
revertDuration: 200,
|
||||
revert: function (event, ui) {
|
||||
console.log(event.attr);
|
||||
return !event;
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
this._originalPosition = this._originalPosition || ui.originalPosition;
|
||||
ui.helper.animate( this._originalPosition );
|
||||
},
|
||||
opacity: 0.7,
|
||||
snapMode: "inner",
|
||||
zIndex: 2
|
||||
});
|
||||
if (date == "none" || room == "none") {
|
||||
newEvent.find(".schedule-event-delete-button").hide();
|
||||
$('.unscheduled-events').append(newEvent);
|
||||
} else {
|
||||
var element = "[date='" + date +"'][hour='" + time + "'][room-guid='" + room + "']";
|
||||
$(element).append(newEvent);
|
||||
}
|
||||
},
|
||||
remove: function(element) {
|
||||
var e = $("#" + element);
|
||||
var unscheduled = $(".unscheduled-events");
|
||||
|
||||
var url = '/admin/conference/' + conference + '/schedule/' + schedule_id;
|
||||
var params = {
|
||||
event: e.attr("guid"),
|
||||
|
|
@ -92,7 +30,7 @@ var Schedule = {
|
|||
dataType : 'json'
|
||||
});
|
||||
},
|
||||
save: function (event_id, room_id, date, time) {
|
||||
add: function (event_id, room_id, date, time) {
|
||||
var url = '/admin/conference/' + conference + '/schedule/' + schedule_id;
|
||||
var params = {
|
||||
event: event_id,
|
||||
|
|
@ -116,6 +54,27 @@ var Schedule = {
|
|||
};
|
||||
|
||||
$(document).ready( function() {
|
||||
// hide the remove button for unscheduled events
|
||||
$('.unscheduled-events .schedule-event-delete-button').hide();
|
||||
|
||||
// set events as draggable
|
||||
$('.schedule-event').draggable({
|
||||
snap: '.schedule-room-slot',
|
||||
revertDuration: 200,
|
||||
revert: function (event, ui) {
|
||||
console.log(event.attr);
|
||||
return !event;
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
this._originalPosition = this._originalPosition || ui.originalPosition;
|
||||
ui.helper.animate( this._originalPosition );
|
||||
},
|
||||
opacity: 0.7,
|
||||
snapMode: "inner",
|
||||
zIndex: 2
|
||||
});
|
||||
|
||||
// set room cells as droppable
|
||||
$('.schedule-room-slot').droppable({
|
||||
accept: '.schedule-event',
|
||||
tolerance: "pointer",
|
||||
|
|
@ -128,7 +87,7 @@ $(document).ready( function() {
|
|||
$(ui.draggable).css("left", 0);
|
||||
$(ui.draggable).css("top", 0);
|
||||
$(this).css("background-color", "#ffffff");
|
||||
Schedule.save(myId, myRoom, myDate, myTime);
|
||||
Schedule.add(myId, myRoom, myDate, myTime);
|
||||
},
|
||||
over: function(event, ui) {
|
||||
$(this).css("background-color", "#009ED8");
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ module Admin
|
|||
|
||||
def show
|
||||
@schedule_id = params[:id].to_i
|
||||
schedule = Schedule.find(@schedule_id)
|
||||
@event_schedules = schedule.event_schedules
|
||||
@unscheduled_events = @program.events.confirmed - schedule.events
|
||||
@selected_schedule_id = @conference.program.selected_schedule.try(:id)
|
||||
@dates = @conference.start_date..@conference.end_date
|
||||
@rooms = (@venue && @venue.rooms.any?) ? @venue.rooms : [Room.new(name: 'No Rooms!', size: 0)]
|
||||
|
|
@ -44,7 +47,7 @@ module Admin
|
|||
error_message = "Could not find event GUID: #{params[:event]}"
|
||||
end
|
||||
|
||||
event_schedule = event.event_schedule(params[:schedule])
|
||||
event_schedule = event.event_schedules.find_by(schedule_id: params[:schedule])
|
||||
|
||||
if params[:date] == 'none'
|
||||
event_schedule.destroy if event_schedule.present?
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ class SchedulesController < ApplicationController
|
|||
|
||||
def show
|
||||
@rooms = @conference.venue.rooms if @conference.venue
|
||||
unless @program.selected_schedule.present? && @program.events.scheduled(@program.selected_schedule.id).any?
|
||||
schedules = @program.selected_event_schedules
|
||||
unless schedules
|
||||
redirect_to events_conference_schedule_path(@conference.short_title)
|
||||
end
|
||||
|
||||
schedules = @program.selected_event_schedules
|
||||
@events_xml = schedules.map(&:event).group_by{ |event| event.scheduled_start_time.to_date } if schedules
|
||||
@dates = @conference.start_date..@conference.end_date
|
||||
@step_minutes = EventType::LENGTH_STEP.minutes
|
||||
|
|
@ -32,7 +32,11 @@ class SchedulesController < ApplicationController
|
|||
@events_schedules = @program.selected_event_schedules
|
||||
@events_schedules = [] unless @events_schedules
|
||||
|
||||
@unscheduled_events = @program.events.unscheduled(@program.selected_schedule.id)
|
||||
@unscheduled_events = if @program.selected_schedule
|
||||
@program.events.confirmed - @program.selected_schedule.events
|
||||
else
|
||||
@program.events.confirmed
|
||||
end
|
||||
|
||||
day = @conference.current_conference_day
|
||||
@tag = day.strftime('%Y-%m-%d') if day
|
||||
|
|
|
|||
|
|
@ -78,15 +78,6 @@ class Event < ActiveRecord::Base
|
|||
selected_event_schedule.present?
|
||||
end
|
||||
|
||||
##
|
||||
# Checkes if the event has a start_time and a room for the given schedule
|
||||
# (given by its id) or for the selected one if there is any.
|
||||
# ====Returns
|
||||
# * +true+ or +false+
|
||||
def unscheduled?(schedule_id)
|
||||
state == 'confirmed' && !event_schedule(schedule_id).present?
|
||||
end
|
||||
|
||||
def registration_possible?
|
||||
return false unless require_registration && state == 'confirmed'
|
||||
return true if max_attendees.nil?
|
||||
|
|
@ -138,15 +129,6 @@ class Event < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def as_json(options={})
|
||||
json = super({ include: { event_schedules: { methods: [:room_guid] } } }.merge(options))
|
||||
json[:track_color] = track.try(:color) || '#FFFFFF'
|
||||
json[:track_text_color] = ApplicationController.helpers.contrast_color(json[:track_color])
|
||||
json[:length] = event_type.try(:length) || EventType::LENGTH_STEP
|
||||
|
||||
json
|
||||
end
|
||||
|
||||
def transition_possible?(transition)
|
||||
self.class.state_machine.events_for(current_state).include?(transition)
|
||||
end
|
||||
|
|
@ -263,11 +245,6 @@ class Event < ActiveRecord::Base
|
|||
selected_event_schedule.try(:start_time)
|
||||
end
|
||||
|
||||
# returns the event_schedule for this event and the schedule given in case that it exists
|
||||
def event_schedule(schedule_id)
|
||||
event_schedules.find_by(schedule_id: schedule_id)
|
||||
end
|
||||
|
||||
# returns the event_schedule for this event and for the selected_schedule
|
||||
def selected_event_schedule
|
||||
event_schedules.find_by(schedule_id: program.try(:selected_schedule_id))
|
||||
|
|
|
|||
|
|
@ -32,10 +32,6 @@ class Program < ActiveRecord::Base
|
|||
joins(:event_schedules).where('event_schedules.schedule_id = ?', schedule_id)
|
||||
end
|
||||
|
||||
def unscheduled(schedule_id)
|
||||
select{ |e| e.unscheduled?(schedule_id) }
|
||||
end
|
||||
|
||||
def highlights
|
||||
where(state: :confirmed, is_highlight: true)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
class Schedule < ActiveRecord::Base
|
||||
belongs_to :program
|
||||
has_many :event_schedules, dependent: :destroy
|
||||
has_many :events, through: :event_schedules
|
||||
end
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class EventSerializer < ActiveModel::Serializer
|
|||
end
|
||||
end
|
||||
|
||||
# FIXME: duplicated logic from Event#as_json
|
||||
def length
|
||||
object.event_type.try(:length) || EventType::LENGTH_STEP
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,20 @@
|
|||
- date_event_schedules = @event_schedules.select{ |e| e.start_time.to_date.eql? date }
|
||||
.row
|
||||
- @rooms.each do |room|
|
||||
.col-md-2.col-xs-6
|
||||
.room-name
|
||||
- room_date_event_schedules = date_event_schedules.select{ |e| e.room == room }
|
||||
= room.name
|
||||
- (9*4..18*4).each do |slot|
|
||||
- hour = slot / 4
|
||||
- time = (15 * (slot % 4) == 0) ? '00' : 15 * (slot % 4)
|
||||
.schedule-room-slot{ id: "schedule-room-#{room.guid}-#{hour}-#{time}", |
|
||||
- minutes = (15 * (slot % 4) == 0) ? '00' : 15 * (slot % 4)
|
||||
- time = "#{hour}:#{minutes}"
|
||||
.schedule-room-slot{ id: "schedule-room-#{room.guid}-#{hour}-#{minutes}", |
|
||||
"room-guid" => room.guid, |
|
||||
hour: "#{hour}:#{time}", |
|
||||
hour: time, |
|
||||
date: date}
|
||||
= "#{hour}:#{time}"
|
||||
.div
|
||||
= time
|
||||
- event_schedules = room_date_event_schedules.select{ |e| (e.start_time.hour.to_s + e.start_time.strftime(':%M')).eql? time }
|
||||
- if event_schedules.any?
|
||||
= render partial: 'event', locals: { event: event_schedules.first.event }
|
||||
|
|
|
|||
13
app/views/admin/schedule/_event.html.haml
Normal file
13
app/views/admin/schedule/_event.html.haml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
- cells_length = event.event_type.length / EventType::LENGTH_STEP
|
||||
/ this height fits the room cells
|
||||
- height = (cells_length * 58) - 23
|
||||
/ subtracting the padding before calculate the number of lines
|
||||
- lines = (height - 7) / 23
|
||||
- color = event.track.try(:color).present? ? event.track.try(:color) : 'FFFFFF'
|
||||
.schedule-event{ style: "height: #{height}px; background-color: #{color}; color: #{contrast_color(color)}", |
|
||||
id: "event-#{event.guid}", |
|
||||
guid: event.guid, |
|
||||
length: cells_length }
|
||||
.schedule-event-text{ style: "-webkit-line-clamp: #{lines}; height: #{lines * 23}px;"}
|
||||
%span.schedule-event-delete-button{ onclick: "Schedule.remove(\'event-#{event.guid}\');" } X
|
||||
= event.title
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
.h4
|
||||
Unscheduled events
|
||||
.unscheduled-events
|
||||
- @unscheduled_events.each do |e|
|
||||
= render partial: 'event', locals: { event: e }
|
||||
.col-md-10
|
||||
%ul.nav.nav-tabs
|
||||
- @dates.each do |date|
|
||||
|
|
@ -30,5 +32,5 @@
|
|||
|
||||
:javascript
|
||||
$(document).ready( function() {
|
||||
Schedule.loadEvents("#{@conference.short_title}", "#{@schedule_id}");
|
||||
Schedule.initialize("#{@conference.short_title}", "#{@schedule_id}");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -259,27 +259,6 @@ describe Event do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#as_json' do
|
||||
it 'adds the event\'s track_color, track_text_color and length' do
|
||||
create(:event_schedule, event: event)
|
||||
event.track = create(:track, color: '#efefef')
|
||||
json_hash = event.as_json
|
||||
|
||||
expect(json_hash[:track_color]).to eq('#EFEFEF')
|
||||
expect(json_hash[:track_text_color]).to eq('black')
|
||||
expect(json_hash[:length]).to eq(30)
|
||||
end
|
||||
|
||||
it 'uses correct default values for track_color, track_text_color and length' do
|
||||
event.event_type = nil
|
||||
json_hash = event.as_json
|
||||
|
||||
expect(json_hash[:track_color]).to eq('#FFFFFF')
|
||||
expect(json_hash[:track_text_color]).to eq('black')
|
||||
expect(json_hash[:length]).to eq(15)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#transition_possible?(transition)' do
|
||||
shared_examples 'transition_possible?(transition)' do |state, transition, expected|
|
||||
it "returns #{expected} for #{transition} transition, when the event is #{state}}" do
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ describe Schedule do
|
|||
describe 'association' do
|
||||
it { should belong_to(:program) }
|
||||
it { should have_many(:event_schedules).dependent(:destroy) }
|
||||
it { should have_many(:events).through(:event_schedules) }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue