Schedule divisions and workshops table
This commit is contained in:
parent
c1f9b5db82
commit
ad3136a5cb
1
app/assets/images/admin/workshops.svg
Normal file
1
app/assets/images/admin/workshops.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 26.25"><path d="M0 21h24V0H0v21zM19 1h4v3h-4V1zm0 4h4v3h-4V5zm0 4h4v3h-4V9zm0 4h4v3h-4v-3zm0 4h4v3h-4v-3zM14 1h4v3h-4V1zm0 4h4v3h-4V5zm0 4h4v3h-4V9zm0 4h4v3h-4v-3zm0 4h4v3h-4v-3zM9 1h4v3H9V1zm0 4h4v3H9V5zm0 4h4v3H9V9zm0 4h4v3H9v-3zm0 4h4v3H9v-3zM1 1h7v3H1V1zm0 4h7v3H1V5zm0 4h7v3H1V9zm0 4h7v3H1v-3zm0 4h7v3H1v-3z"/></svg>
|
After Width: | Height: | Size: 377 B |
@ -1,114 +1,114 @@
|
|||||||
(function() {
|
(function() {
|
||||||
function closeWorkshopSelector() {
|
function closeWorkshopSelector() {
|
||||||
document.getElementById('workshop-selector').classList.remove('open');
|
document.getElementById('workshop-selector').classList.remove('open');
|
||||||
document.body.classList.remove('modal-open');
|
document.body.classList.remove('modal-open');
|
||||||
}
|
}
|
||||||
document.getElementById('workshop-selector').addEventListener('click', function(event) {
|
document.getElementById('workshop-selector').addEventListener('click', function(event) {
|
||||||
if (event.target.id == 'workshop-selector') {
|
if (event.target.id == 'workshop-selector') {
|
||||||
closeWorkshopSelector();
|
closeWorkshopSelector();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
function _post(form, params, f) {
|
function _post(form, params, f) {
|
||||||
var request = new XMLHttpRequest();
|
var request = new XMLHttpRequest();
|
||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
if (request.readyState == 4) {
|
if (request.readyState == 4) {
|
||||||
if (request.status == 200) {
|
if (request.status == 200) {
|
||||||
f(request.responseText);
|
f(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request.open('POST', form.getAttribute('action'), true);
|
request.open('POST', form.getAttribute('action'), true);
|
||||||
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
params['authenticity_token'] = form.querySelector('[name="authenticity_token"]').value;
|
params['authenticity_token'] = form.querySelector('[name="authenticity_token"]').value;
|
||||||
var data = [];
|
var data = [];
|
||||||
for (var key in params) {
|
for (var key in params) {
|
||||||
data.push(key + '=' + params[key]);
|
data.push(key + '=' + params[key]);
|
||||||
}
|
}
|
||||||
request.send(data.join('&'));
|
request.send(data.join('&'));
|
||||||
}
|
}
|
||||||
function selectorMatches(el, selector) {
|
function selectorMatches(el, selector) {
|
||||||
var p = Element.prototype;
|
var p = Element.prototype;
|
||||||
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
|
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) {
|
||||||
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
|
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
|
||||||
};
|
};
|
||||||
return f.call(el, selector);
|
return f.call(el, selector);
|
||||||
}
|
}
|
||||||
function updateSchedule(html) {
|
function updateSchedule(html) {
|
||||||
var schedule = document.getElementById('schedule-preview');
|
var schedule = document.getElementById('schedule-preview');
|
||||||
var s = document.createElement('div');
|
var s = document.createElement('div');
|
||||||
s.innerHTML = html;
|
s.innerHTML = html;
|
||||||
schedule.innerHTML = s.children[0].innerHTML;
|
schedule.innerHTML = s.children[0].innerHTML;
|
||||||
schedule.classList.remove('requesting');
|
schedule.classList.remove('requesting');
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.addEventListener('submit', function (event) {
|
document.body.addEventListener('submit', function (event) {
|
||||||
if (event.target.classList.contains('deschedule-workshop')) {
|
if (event.target.classList.contains('deschedule-workshop')) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var schedule = document.getElementById('schedule-preview');
|
var schedule = document.getElementById('schedule-preview');
|
||||||
var form = event.target;
|
var form = event.target;
|
||||||
schedule.classList.add('requesting');
|
schedule.classList.add('requesting');
|
||||||
_post(
|
_post(
|
||||||
form,
|
form,
|
||||||
{
|
{
|
||||||
id: form.querySelector('[name="id"]').value,
|
id: form.querySelector('[name="id"]').value,
|
||||||
button: 'deschedule_workshop'
|
button: 'deschedule_workshop'
|
||||||
},
|
},
|
||||||
updateSchedule
|
updateSchedule
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.body.addEventListener('click', function (event) {
|
document.body.addEventListener('click', function (event) {
|
||||||
//console.log(event.target);
|
|
||||||
|
if (selectorMatches(event.target, 'td.workshop.open, td.workshop.open *')) {
|
||||||
if (selectorMatches(event.target, 'td.workshop.open, td.workshop.open *')) {
|
var button = event.target;
|
||||||
//event.stopPropagation();
|
while (button && button.tagName && button.tagName !== 'TD') {
|
||||||
var button = event.target;
|
button = button.parentElement;
|
||||||
while (button && button.tagName && button.tagName !== 'TD') {
|
}
|
||||||
button = button.parentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('workshop-selector').classList.add('open');
|
document.getElementById('workshop-selector').classList.add('open');
|
||||||
var table = document.getElementById('table');
|
var table = document.getElementById('table');
|
||||||
table.classList.add('loading');
|
table.classList.add('loading');
|
||||||
document.body.classList.add('modal-open');
|
document.body.classList.add('modal-open');
|
||||||
|
|
||||||
var block = button.getAttribute('data-block');
|
var block = button.getAttribute('data-block');
|
||||||
var day = button.getAttribute('data-day');
|
var day = button.getAttribute('data-day');
|
||||||
var location = button.getAttribute('data-location');
|
var location = button.getAttribute('data-location');
|
||||||
|
var division = button.getAttribute('data-division');
|
||||||
_post(
|
|
||||||
document.getElementById('workshop-table-form'),
|
_post(
|
||||||
{
|
document.getElementById('workshop-table-form'),
|
||||||
block: block,
|
{
|
||||||
day: day,
|
block: block,
|
||||||
location: location,
|
day: day,
|
||||||
button: 'get-workshop-list'
|
location: location,
|
||||||
},
|
division: division,
|
||||||
function (response) {
|
button: 'get-workshop-list'
|
||||||
var table = document.getElementById('table');
|
},
|
||||||
table.innerHTML = response;
|
function (response) {
|
||||||
table.classList.remove('loading');
|
var table = document.getElementById('table');
|
||||||
forEachElement('tr.selectable', function(row) {
|
table.innerHTML = response;
|
||||||
row.addEventListener('click', function(event) {
|
table.classList.remove('loading');
|
||||||
var schedule = document.getElementById('schedule-preview');
|
forEachElement('tr.selectable', function(row) {
|
||||||
schedule.classList.add('requesting');
|
row.addEventListener('click', function(event) {
|
||||||
closeWorkshopSelector();
|
var schedule = document.getElementById('schedule-preview');
|
||||||
var form = document.getElementById('workshop-table-form');
|
schedule.classList.add('requesting');
|
||||||
_post(
|
closeWorkshopSelector();
|
||||||
form,
|
var form = document.getElementById('workshop-table-form');
|
||||||
{
|
_post(
|
||||||
workshop: row.getAttribute('data-workshop'),
|
form,
|
||||||
block: block,
|
{
|
||||||
day: day,
|
workshop: row.getAttribute('data-workshop'),
|
||||||
location: form.querySelector('#event_location').value,
|
block: block,
|
||||||
button: 'set-workshop'
|
day: day,
|
||||||
},
|
location: form.querySelector('#event_location').value,
|
||||||
updateSchedule
|
button: 'set-workshop'
|
||||||
);
|
},
|
||||||
});
|
updateSchedule
|
||||||
}, table);
|
);
|
||||||
}
|
});
|
||||||
);
|
}, table);
|
||||||
}
|
}
|
||||||
}, true);
|
);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
})();
|
})();
|
||||||
|
@ -1370,7 +1370,6 @@ nav.sub-menu {
|
|||||||
.event-detail-link {
|
.event-detail-link {
|
||||||
width: auto;
|
width: auto;
|
||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
|
|
||||||
}
|
}
|
||||||
.event-detail-link, .details, .title {
|
.event-detail-link, .details, .title {
|
||||||
display: inline;
|
display: inline;
|
||||||
@ -1403,6 +1402,10 @@ nav.sub-menu {
|
|||||||
width: 15em;
|
width: 15em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
+ .event-detail-link {
|
+ .event-detail-link {
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class ApplicationController < BaseController
|
class ApplicationController < BaseController
|
||||||
protect_from_forgery with: :exception, :except => [:do_confirm, :js_error, :admin_update]
|
protect_from_forgery with: :exception, except: [:do_confirm, :js_error, :admin_update]
|
||||||
|
|
||||||
before_filter :application_setup
|
before_filter :application_setup
|
||||||
after_filter :capture_page_info
|
after_filter :capture_page_info
|
||||||
@ -392,13 +392,13 @@ class ApplicationController < BaseController
|
|||||||
def get_scheule_data(do_analyze = true)
|
def get_scheule_data(do_analyze = true)
|
||||||
conference = @this_conference || @conference
|
conference = @this_conference || @conference
|
||||||
@meals = Hash[(conference.meals || {}).map{ |k, v| [k.to_i, v] }].sort.to_h
|
@meals = Hash[(conference.meals || {}).map{ |k, v| [k.to_i, v] }].sort.to_h
|
||||||
@events = Event.where(:conference_id => conference.id).order(start_time: :asc)
|
@events = Event.where(conference_id: conference.id).order(start_time: :asc)
|
||||||
@workshops = Workshop.where(:conference_id => conference.id).order(start_time: :asc)
|
@workshops = Workshop.where(conference_id: conference.id).order(start_time: :asc)
|
||||||
@locations = {}
|
@locations = {}
|
||||||
|
|
||||||
get_block_data
|
get_block_data
|
||||||
|
|
||||||
@schedule = {}
|
schedule = {}
|
||||||
day_1 = conference.start_date.wday
|
day_1 = conference.start_date.wday
|
||||||
|
|
||||||
@workshop_blocks.each_with_index do |info, block|
|
@workshop_blocks.each_with_index do |info, block|
|
||||||
@ -407,11 +407,11 @@ class ApplicationController < BaseController
|
|||||||
day_diff += 7 if day_diff < 0
|
day_diff += 7 if day_diff < 0
|
||||||
day = (conference.start_date + day_diff.days).to_date
|
day = (conference.start_date + day_diff.days).to_date
|
||||||
time = info['time'].to_f
|
time = info['time'].to_f
|
||||||
@schedule[day] ||= { times: {}, locations: {} }
|
schedule[day] ||= { times: {}, locations: {} }
|
||||||
@schedule[day][:times][time] ||= {}
|
schedule[day][:times][time] ||= {}
|
||||||
@schedule[day][:times][time][:type] = :workshop
|
schedule[day][:times][time][:type] = :workshop
|
||||||
@schedule[day][:times][time][:length] = info['length'].to_f
|
schedule[day][:times][time][:length] = info['length'].to_f
|
||||||
@schedule[day][:times][time][:item] = { block: block, workshops: {} }
|
schedule[day][:times][time][:item] = { block: block, workshops: {} }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -423,9 +423,9 @@ class ApplicationController < BaseController
|
|||||||
day_diff += 7 if day_diff < 0
|
day_diff += 7 if day_diff < 0
|
||||||
day = (conference.start_date + day_diff.days).to_date
|
day = (conference.start_date + day_diff.days).to_date
|
||||||
|
|
||||||
if block.present? && @schedule[day].present? && @schedule[day][:times].present? && @schedule[day][:times][block['time'].to_f].present?
|
if block.present? && schedule[day].present? && schedule[day][:times].present? && schedule[day][:times][block['time'].to_f].present?
|
||||||
@schedule[day][:times][block['time'].to_f][:item][:workshops][workshop.event_location_id] = { workshop: workshop, status: { errors: [], warnings: [], conflict_score: nil } }
|
schedule[day][:times][block['time'].to_f][:item][:workshops][workshop.event_location_id] = { workshop: workshop, status: { errors: [], warnings: [], conflict_score: nil } }
|
||||||
@schedule[day][:locations][workshop.event_location_id] ||= workshop.event_location if workshop.event_location.present?
|
schedule[day][:locations][workshop.event_location_id] ||= workshop.event_location if workshop.event_location.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -433,50 +433,50 @@ class ApplicationController < BaseController
|
|||||||
@meals.each do |time, meal|
|
@meals.each do |time, meal|
|
||||||
day = meal['day'].to_date
|
day = meal['day'].to_date
|
||||||
time = meal['time'].to_f
|
time = meal['time'].to_f
|
||||||
@schedule[day] ||= {}
|
schedule[day] ||= {}
|
||||||
@schedule[day][:times] ||= {}
|
schedule[day][:times] ||= {}
|
||||||
@schedule[day][:times][time] ||= {}
|
schedule[day][:times][time] ||= {}
|
||||||
@schedule[day][:times][time][:type] = :meal
|
schedule[day][:times][time][:type] = :meal
|
||||||
@schedule[day][:times][time][:length] = (meal['length'] || 1.0).to_f
|
schedule[day][:times][time][:length] = (meal['length'] || 1.0).to_f
|
||||||
@schedule[day][:times][time][:item] = meal
|
schedule[day][:times][time][:item] = meal
|
||||||
end
|
end
|
||||||
|
|
||||||
@events.each do |event|
|
@events.each do |event|
|
||||||
if event.present? && event.start_time.present? && event.end_time.present?
|
if event.present? && event.start_time.present? && event.end_time.present?
|
||||||
day = event.start_time.midnight.to_date
|
day = event.start_time.midnight.to_date
|
||||||
time = event.start_time.hour.to_f + (event.start_time.min / 60.0)
|
time = event.start_time.hour.to_f + (event.start_time.min / 60.0)
|
||||||
@schedule[day] ||= {}
|
schedule[day] ||= {}
|
||||||
@schedule[day][:times] ||= {}
|
schedule[day][:times] ||= {}
|
||||||
@schedule[day][:times][time] ||= {}
|
schedule[day][:times][time] ||= {}
|
||||||
@schedule[day][:times][time][:type] = :event
|
schedule[day][:times][time][:type] = :event
|
||||||
@schedule[day][:times][time][:length] = (event.end_time - event.start_time) / 3600.0
|
schedule[day][:times][time][:length] = (event.end_time - event.start_time) / 3600.0
|
||||||
@schedule[day][:times][time][:item] = event
|
schedule[day][:times][time][:item] = event
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@schedule = @schedule.sort.to_h
|
schedule = schedule.sort.to_h
|
||||||
@schedule.each do |day, data|
|
schedule.each do |day, data|
|
||||||
@schedule[day][:times] = data[:times].sort.to_h
|
schedule[day][:times] = data[:times].sort.to_h
|
||||||
end
|
end
|
||||||
|
|
||||||
@schedule.each do |day, data|
|
schedule.each do |day, data|
|
||||||
last_event = nil
|
last_event = nil
|
||||||
data[:times].each do |time, time_data|
|
data[:times].each do |time, time_data|
|
||||||
if last_event.present?
|
if last_event.present?
|
||||||
@schedule[day][:times][last_event][:next_event] = time
|
schedule[day][:times][last_event][:next_event] = time
|
||||||
end
|
end
|
||||||
last_event = time
|
last_event = time
|
||||||
end
|
end
|
||||||
@schedule[day][:num_locations] = (data[:locations] || []).size
|
schedule[day][:num_locations] = (data[:locations] || []).size
|
||||||
end
|
end
|
||||||
|
|
||||||
@schedule.deep_dup.each do |day, data|
|
schedule.deep_dup.each do |day, data|
|
||||||
data[:times].each do |time, time_data|
|
data[:times].each do |time, time_data|
|
||||||
if time_data[:next_event].present? || time_data[:length] > @this_conference.schedule_interval
|
if time_data[:next_event].present? || time_data[:length] > @this_conference.schedule_interval
|
||||||
span = @this_conference.schedule_interval
|
span = @this_conference.schedule_interval
|
||||||
length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length]
|
length = time_data[:next_event].present? ? time_data[:next_event] - time : time_data[:length]
|
||||||
while span < length
|
while span < length
|
||||||
@schedule[day][:times][time + span] ||= {
|
schedule[day][:times][time + span] ||= {
|
||||||
type: (span >= time_data[:length] ? :empty : :nil),
|
type: (span >= time_data[:length] ? :empty : :nil),
|
||||||
length: @this_conference.schedule_interval
|
length: @this_conference.schedule_interval
|
||||||
}
|
}
|
||||||
@ -486,16 +486,20 @@ class ApplicationController < BaseController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@schedule = @schedule.sort.to_h
|
# schedule = schedule.sort.to_h
|
||||||
|
|
||||||
@schedule.each do |day, data|
|
schedule.each do |day, data|
|
||||||
@schedule[day][:times] = data[:times].sort.to_h
|
# @schedule[day] = [{}]
|
||||||
@schedule[day][:locations] ||= {}
|
# division = 0
|
||||||
|
# schedule[day][:num_locations] = schedule[day][:num_locations]
|
||||||
|
# schedule[day][:times] = data[:times].sort.to_h
|
||||||
|
schedule[day][:times] = data[:times].sort.to_h
|
||||||
|
schedule[day][:locations] ||= {}
|
||||||
|
# # sort the locations by name
|
||||||
|
schedule[day][:locations] = schedule[day][:locations].sort_by { |event_id, event| event.present? ? event.title.downcase : '' }.to_h
|
||||||
|
|
||||||
# sort the locations by name
|
# # add an empty block if no workshops are scheduled on this day yet
|
||||||
@schedule[day][:locations] = @schedule[day][:locations].sort_by { |event_id, event| event.present? ? event.title.downcase : '' }.to_h
|
# schedule[day][:locations][0] = :add if do_analyze || schedule[day][:locations].empty?
|
||||||
# add an empty block if no workshops are scheduled on this day yet
|
|
||||||
@schedule[day][:locations][0] = :add if do_analyze || @schedule[day][:locations].empty?
|
|
||||||
|
|
||||||
if do_analyze
|
if do_analyze
|
||||||
data[:times].each do |time, time_data|
|
data[:times].each do |time, time_data|
|
||||||
@ -512,8 +516,8 @@ class ApplicationController < BaseController
|
|||||||
workshop_i.active_facilitators.each do |facilitator_i|
|
workshop_i.active_facilitators.each do |facilitator_i|
|
||||||
workshop_j.active_facilitators.each do |facilitator_j|
|
workshop_j.active_facilitators.each do |facilitator_j|
|
||||||
if facilitator_i.id == facilitator_j.id
|
if facilitator_i.id == facilitator_j.id
|
||||||
@schedule[day][:times][time][:status] ||= {}
|
schedule[day][:times][time][:status] ||= {}
|
||||||
@schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << {
|
schedule[day][:times][time][:item][:workshops][ids[j]][:status][:errors] << {
|
||||||
name: :common_facilitator,
|
name: :common_facilitator,
|
||||||
facilitator: facilitator_i,
|
facilitator: facilitator_i,
|
||||||
workshop: workshop_i,
|
workshop: workshop_i,
|
||||||
@ -533,7 +537,7 @@ class ApplicationController < BaseController
|
|||||||
amenities = JSON.parse(location.amenities || '[]').map &:to_sym
|
amenities = JSON.parse(location.amenities || '[]').map &:to_sym
|
||||||
|
|
||||||
needs.each do |need|
|
needs.each do |need|
|
||||||
@schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << {
|
schedule[day][:times][time][:item][:workshops][ids[i]][:status][:errors] << {
|
||||||
name: :need_not_available,
|
name: :need_not_available,
|
||||||
need: need,
|
need: need,
|
||||||
location: location,
|
location: location,
|
||||||
@ -555,13 +559,55 @@ class ApplicationController < BaseController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@schedule[day][:times][time][:item][:workshops][ids[i]][:status][:conflict_score] = (interests & (workshop_i.interested.map { | u | u.user_id })).length
|
schedule[day][:times][time][:item][:workshops][ids[i]][:status][:conflict_score] = (interests & (workshop_i.interested.map { | u | u.user_id })).length
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@schedule = {}
|
||||||
|
schedule.sort.to_h.each do |day, data|
|
||||||
|
@schedule[day] = []
|
||||||
|
division = 0
|
||||||
|
# @schedule[day][division] = data
|
||||||
|
locations = nil
|
||||||
|
@schedule[day][division] = {}
|
||||||
|
@schedule[day][division][:times] = {}
|
||||||
|
# @schedule[day][division][:times] = data[:times]
|
||||||
|
|
||||||
|
# # sort the locations by name
|
||||||
|
# @schedule[day][:locations] = schedule[day][:locations].sort_by { |event_id, event| event.present? ? event.title.downcase : '' }.to_h
|
||||||
|
|
||||||
|
# # add an empty block if no workshops are scheduled on this day yet
|
||||||
|
# schedule[day][:locations][0] = :add if do_analyze || schedule[day][:locations].empty?
|
||||||
|
|
||||||
|
# last_time_data = nil
|
||||||
|
data[:times].each do |time, time_data|
|
||||||
|
if time_data[:type] == :workshop && time_data[:item].present? && time_data[:item][:workshops].present?
|
||||||
|
if !locations.nil? && ((locations.keys - time_data[:item][:workshops].keys) | (time_data[:item][:workshops].keys - locations.keys)).length > 0
|
||||||
|
# data[:locations]
|
||||||
|
# xxx
|
||||||
|
@schedule[day][division][:locations] = locations.deep_dup
|
||||||
|
@schedule[day][division][:locations][0] = :add if do_analyze || locations.empty?
|
||||||
|
locations = data[:locations].select { |id, l| time_data[:item][:workshops][id].present? }
|
||||||
|
|
||||||
|
division += 1
|
||||||
|
@schedule[day][division] = {}
|
||||||
|
@schedule[day][division][:times] = {}
|
||||||
|
else
|
||||||
|
locations = data[:locations].select { |id, l| time_data[:item][:workshops][id].present? }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# last_time_data = time_data
|
||||||
|
@schedule[day][division][:times][time] = time_data
|
||||||
|
end
|
||||||
|
locations ||= data[:locations]
|
||||||
|
@schedule[day][division][:locations] = locations
|
||||||
|
@schedule[day][division][:locations][0] = :add if do_analyze || locations.empty?
|
||||||
|
@schedule[day][division][:num_locations] = locations.length
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -253,46 +253,7 @@ class ConferenceAdministrationController < ApplicationController
|
|||||||
format.xlsx { render xlsx: '../conferences/stats', filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" }
|
format.xlsx { render xlsx: '../conferences/stats', filename: "stats-#{DateTime.now.strftime('%Y-%m-%d')}" }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if params[:sort_column]
|
sort_data(params[:sort_column], params[:sort_dir], :name)
|
||||||
col = params[:sort_column].to_sym
|
|
||||||
@excel_data[:data].sort_by! do |row|
|
|
||||||
value = row[col]
|
|
||||||
|
|
||||||
if row[:raw_values].key?(col)
|
|
||||||
value = if row[:raw_values][col].is_a?(TrueClass)
|
|
||||||
't'
|
|
||||||
elsif row[:raw_values][col].is_a?(FalseClass)
|
|
||||||
''
|
|
||||||
else
|
|
||||||
row[:raw_values][col]
|
|
||||||
end
|
|
||||||
elsif value.is_a?(City)
|
|
||||||
value = value.sortable_string
|
|
||||||
end
|
|
||||||
|
|
||||||
if value.nil?
|
|
||||||
case @excel_data[:column_types][col]
|
|
||||||
when :datetime, [:date, :day]
|
|
||||||
value = Date.new
|
|
||||||
when :money
|
|
||||||
value = 0
|
|
||||||
else
|
|
||||||
value = ''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
value
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:sort_dir] == 'up'
|
|
||||||
@sort_dir = :up
|
|
||||||
@excel_data[:data].reverse!
|
|
||||||
end
|
|
||||||
|
|
||||||
@sort_column = col
|
|
||||||
else
|
|
||||||
@sort_column = :name
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@registration_count = @registrations.size
|
@registration_count = @registrations.size
|
||||||
@ -324,6 +285,22 @@ class ConferenceAdministrationController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def administrate_workshops
|
||||||
|
get_workshops(true)
|
||||||
|
if request.format.xlsx?
|
||||||
|
logger.info "Generating stats.xls"
|
||||||
|
return respond_to do |format|
|
||||||
|
format.xlsx { render xlsx: '../conferences/stats', filename: "workshops-#{DateTime.now.strftime('%Y-%m-%d')}" }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
sort_data(params[:sort_column], params[:sort_dir], :name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if request.xhr?
|
||||||
|
render html: view_context.html_table(@excel_data, view_context.registrations_table_options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def administrate_check_in
|
def administrate_check_in
|
||||||
sort_weight = {
|
sort_weight = {
|
||||||
checked_in: 5,
|
checked_in: 5,
|
||||||
@ -769,6 +746,179 @@ class ConferenceAdministrationController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_workshops(html_format = false, id = nil, conference = @this_conference)
|
||||||
|
@workshops = conference.workshops.sort_by { |w| w.title.downcase }
|
||||||
|
@excel_data = {
|
||||||
|
columns: [
|
||||||
|
:title,
|
||||||
|
:owner,
|
||||||
|
:locale,
|
||||||
|
:date,
|
||||||
|
:info,
|
||||||
|
:notes,
|
||||||
|
:facilitators
|
||||||
|
] + User.AVAILABLE_LANGUAGES.map { |l| "language_#{l}".to_sym } +
|
||||||
|
Workshop.all_needs.map { |n| "need_#{n}".to_sym } + [
|
||||||
|
:theme,
|
||||||
|
:space
|
||||||
|
] + (User.AVAILABLE_LANGUAGES - [I18n.locale]).map { |l| "title_#{l}".to_sym } +
|
||||||
|
(User.AVAILABLE_LANGUAGES - [I18n.locale]).map { |l| "info_#{l}".to_sym },
|
||||||
|
column_types: {
|
||||||
|
title: :bold,
|
||||||
|
date: :datetime,
|
||||||
|
info: :text,
|
||||||
|
notes: :text,
|
||||||
|
owner: :email
|
||||||
|
},
|
||||||
|
keys: {
|
||||||
|
title: 'forms.labels.generic.title',
|
||||||
|
owner: 'roles.workshops.facilitator.creator',
|
||||||
|
locale: 'articles.conference_registration.terms.Preferred_Languages',
|
||||||
|
info: 'forms.labels.generic.info',
|
||||||
|
date: 'workshop.created_at',
|
||||||
|
notes: 'forms.labels.generic.notes',
|
||||||
|
facilitators: 'roles.workshops.facilitator.facilitator',
|
||||||
|
theme: 'articles.workshops.headings.theme',
|
||||||
|
space: 'articles.workshops.headings.space'
|
||||||
|
},
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
@excel_data[:key_vars] = {}
|
||||||
|
User.AVAILABLE_LANGUAGES.each do |l|
|
||||||
|
@excel_data[:keys]["language_#{l}".to_sym] = "languages.#{l}"
|
||||||
|
if l != I18n.locale
|
||||||
|
@excel_data[:keys]["title_#{l}".to_sym] = 'translate.content.item_translation'
|
||||||
|
@excel_data[:key_vars]["title_#{l}".to_sym] = { language: view_context.language_name(l), item: I18n.t('forms.labels.generic.title') }
|
||||||
|
|
||||||
|
@excel_data[:keys]["info_#{l}".to_sym] = 'translate.content.item_translation'
|
||||||
|
@excel_data[:key_vars]["info_#{l}".to_sym] = { language: view_context.language_name(l), item: I18n.t('forms.labels.generic.info') }
|
||||||
|
@excel_data[:column_types]["info_#{l}".to_sym] = :text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Workshop.all_needs.each do |n|
|
||||||
|
@excel_data[:keys]["need_#{n}".to_sym] = "workshop.options.needs.#{n}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@workshops.each do |w|
|
||||||
|
if w.present?
|
||||||
|
if id.nil? || id == w.id
|
||||||
|
owner = User.find(w.creator)
|
||||||
|
facilitators = w.collaborators.map { |f| User.find(f) }
|
||||||
|
data = {
|
||||||
|
id: w.id,
|
||||||
|
title: w.title,
|
||||||
|
info: view_context.strip_tags(w.info),
|
||||||
|
notes: view_context.strip_tags(w.notes),
|
||||||
|
owner: owner.name,
|
||||||
|
locale: w.locale.present? ? (view_context.language_name w.locale) : '',
|
||||||
|
date: w.created_at ? w.created_at.strftime("%F %T") : '',
|
||||||
|
facilitators: facilitators.map { |f| f.name }.join(', '),
|
||||||
|
theme: w.theme && Workshop.all_themes.include?(w.theme.to_sym) ? I18n.t("workshop.options.theme.#{w.theme}") : w.theme,
|
||||||
|
space: w.space && Workshop.all_spaces.include?(w.space.to_sym) ? I18n.t("workshop.options.space.#{w.space}") : '',
|
||||||
|
raw_values: {
|
||||||
|
info: w.info,
|
||||||
|
owner: owner.email,
|
||||||
|
notes: w.notes,
|
||||||
|
locale: w.locale,
|
||||||
|
facilitators: facilitators.map { |f| f.email }.join(', '),
|
||||||
|
theme: w.theme,
|
||||||
|
space: w.space
|
||||||
|
},
|
||||||
|
html_values: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
languages = JSON.parse(w.languages || '[]').map &:to_sym
|
||||||
|
User.AVAILABLE_LANGUAGES.each do |l|
|
||||||
|
in_language = ((languages || []).include? l.to_sym)
|
||||||
|
data["language_#{l}".to_sym] = (in_language ? I18n.t('articles.conference_registration.questions.bike.yes') : '')
|
||||||
|
data[:raw_values]["language_#{l}".to_sym] = in_language
|
||||||
|
|
||||||
|
if l != I18n.locale
|
||||||
|
data["title_#{l}".to_sym] = w.get_column_for_locale!(:title, l, false)
|
||||||
|
data["info_#{l}".to_sym] = view_context.strip_tags(w.get_column_for_locale!(:info, l, false))
|
||||||
|
data[:raw_values]["info_#{l}".to_sym] = w.get_column_for_locale!(:info, l, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
needs = JSON.parse(w.needs || '[]').map &:to_sym
|
||||||
|
Workshop.all_needs.each do |n|
|
||||||
|
in_need = ((needs || []).include? n.to_sym)
|
||||||
|
data["need_#{n}".to_sym] = (in_need ? I18n.t('articles.conference_registration.questions.bike.yes') : '')
|
||||||
|
data[:raw_values]["need_#{n}".to_sym] = in_need
|
||||||
|
end
|
||||||
|
|
||||||
|
@excel_data[:data] << data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if html_format
|
||||||
|
@column_options = {
|
||||||
|
locale: I18n.backend.enabled_locales.map { |l| [(view_context.language_name l), l] },
|
||||||
|
theme: Workshop.all_themes.map { |t| [I18n.t("workshop.options.theme.#{t}"), t] },
|
||||||
|
space: Workshop.all_spaces.map { |s| [I18n.t("workshop.options.space.#{s}"), s] }
|
||||||
|
}
|
||||||
|
@column_options[:theme] += ((conference.workshops.map { |w| w.theme }) - Workshop.all_themes.map(&:to_s)).uniq.map { |t| [t, t] }
|
||||||
|
User.AVAILABLE_LANGUAGES.each do |l|
|
||||||
|
@column_options["language_#{l}".to_sym] = [
|
||||||
|
[I18n.t("articles.conference_registration.questions.bike.yes"), true]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
Workshop.all_needs.each do |n|
|
||||||
|
@column_options["need_#{n}".to_sym] = [
|
||||||
|
[I18n.t("articles.conference_registration.questions.bike.yes"), true]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sort_data(col, sort_dir, default_col)
|
||||||
|
if col
|
||||||
|
col = col.to_sym
|
||||||
|
@excel_data[:data].sort_by! do |row|
|
||||||
|
value = row[col]
|
||||||
|
|
||||||
|
if row[:raw_values].key?(col)
|
||||||
|
value = if row[:raw_values][col].is_a?(TrueClass)
|
||||||
|
't'
|
||||||
|
elsif row[:raw_values][col].is_a?(FalseClass)
|
||||||
|
''
|
||||||
|
elsif @excel_data[:column_types][col] == :text
|
||||||
|
view_context.strip_tags(row[:raw_values][col] || '').downcase
|
||||||
|
else
|
||||||
|
row[:raw_values][col]
|
||||||
|
end
|
||||||
|
elsif value.is_a?(City)
|
||||||
|
value = value.sortable_string
|
||||||
|
end
|
||||||
|
|
||||||
|
if value.nil?
|
||||||
|
case @excel_data[:column_types][col]
|
||||||
|
when :datetime, [:date, :day]
|
||||||
|
value = Date.new
|
||||||
|
when :money
|
||||||
|
value = 0
|
||||||
|
else
|
||||||
|
value = ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
value
|
||||||
|
end
|
||||||
|
|
||||||
|
if sort_dir == 'up'
|
||||||
|
@sort_dir = :up
|
||||||
|
@excel_data[:data].reverse!
|
||||||
|
end
|
||||||
|
|
||||||
|
@sort_column = col
|
||||||
|
else
|
||||||
|
@sort_column = default_col
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def get_housing_data
|
def get_housing_data
|
||||||
@hosts = {}
|
@hosts = {}
|
||||||
@guests = {}
|
@guests = {}
|
||||||
@ -1255,6 +1405,85 @@ class ConferenceAdministrationController < ApplicationController
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def admin_update_workshops
|
||||||
|
if params[:button] == 'update'
|
||||||
|
workshop = Workshop.where(
|
||||||
|
id: params[:key].to_i,
|
||||||
|
conference_id: @this_conference.id
|
||||||
|
).limit(1).first
|
||||||
|
|
||||||
|
params.each do |key, value|
|
||||||
|
case key.to_sym
|
||||||
|
when :owner
|
||||||
|
user = User.get(value.strip)
|
||||||
|
user_role = WorkshopFacilitator.where(user_id: user.id, workshop_id: workshop.id).first || WorkshopFacilitator.new(user_id: user.id, workshop_id: workshop.id)
|
||||||
|
owner_role = WorkshopFacilitator.where(role: :creator, workshop_id: workshop.id).first
|
||||||
|
if !owner_role || owner_role.user_id != user.id
|
||||||
|
owner_role.role = :collaborator
|
||||||
|
user_role.role = :creator
|
||||||
|
owner_role.save!
|
||||||
|
user_role.save!
|
||||||
|
end
|
||||||
|
when :facilitators
|
||||||
|
ids = []
|
||||||
|
value.split(/[\s,;]+/).each do |email|
|
||||||
|
user = User.get(email)
|
||||||
|
ids << user.id
|
||||||
|
user_role = WorkshopFacilitator.where(user_id: user.id, workshop_id: workshop.id).first || WorkshopFacilitator.new(user_id: user.id, workshop_id: workshop.id)
|
||||||
|
unless user_role.role == 'creator' || user_role.role == 'collaborator'
|
||||||
|
user_role.role = 'collaborator'
|
||||||
|
user_role.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
WorkshopFacilitator.where("workshop_id = ? AND role = ? AND user_id NOT IN (?)", workshop.id, 'collaborator', ids).destroy_all
|
||||||
|
when :title, :locale, :date, :info, :notes, :theme, :space
|
||||||
|
workshop.send("#{key}=", value.present? ? value : nil)
|
||||||
|
else
|
||||||
|
if key.start_with?('language_')
|
||||||
|
l = key.split('_').last.to_sym
|
||||||
|
languages = JSON.parse(workshop.languages || '[]').map &:to_sym
|
||||||
|
if User.AVAILABLE_LANGUAGES.include? l
|
||||||
|
if value.present?
|
||||||
|
languages |= [l]
|
||||||
|
else
|
||||||
|
languages -= [l]
|
||||||
|
end
|
||||||
|
workshop.languages = languages.to_json
|
||||||
|
end
|
||||||
|
elsif key.start_with?('need_')
|
||||||
|
n = key.split('_').last.to_sym
|
||||||
|
needs = JSON.parse(workshop.needs || '[]').map &:to_sym
|
||||||
|
if Workshop.all_needs.include? n
|
||||||
|
if value.present?
|
||||||
|
needs |= [n]
|
||||||
|
else
|
||||||
|
needs -= [n]
|
||||||
|
end
|
||||||
|
workshop.needs = needs.to_json
|
||||||
|
end
|
||||||
|
elsif key.start_with?('title_')
|
||||||
|
l = key.split('_').last.to_sym
|
||||||
|
workshop.set_column_for_locale(:title, l, value)
|
||||||
|
elsif key.start_with?('info_')
|
||||||
|
l = key.split('_').last.to_sym
|
||||||
|
workshop.set_column_for_locale(:info, l, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
workshop.save!
|
||||||
|
|
||||||
|
get_workshops(true, params[:key].to_i)
|
||||||
|
options = view_context.workshops_table_options
|
||||||
|
options[:html] = true
|
||||||
|
|
||||||
|
render html: view_context.excel_rows(@excel_data, {}, options)
|
||||||
|
else
|
||||||
|
do_404
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
def admin_update_check_in
|
def admin_update_check_in
|
||||||
unless params[:button] == 'cancel'
|
unless params[:button] == 'cancel'
|
||||||
user_id = params[:user_id]
|
user_id = params[:user_id]
|
||||||
@ -1478,7 +1707,7 @@ class ConferenceAdministrationController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
(params[:title] || {}).each do |locale, value|
|
(params[:title] || {}).each do |locale, value|
|
||||||
event.set_column_for_locale(:title, locale, html_value(value), current_user.id) if value != event._title(locale) && view_context.strip_tags(value).strip.present?
|
event.set_column_for_locale(:title, locale, html_value(value), current_user.id) if value != event._title(locale) && view_context.strip.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
event.save
|
event.save
|
||||||
@ -1555,8 +1784,18 @@ class ConferenceAdministrationController < ApplicationController
|
|||||||
@time = @workshop_blocks[@block]['time'].to_f
|
@time = @workshop_blocks[@block]['time'].to_f
|
||||||
@day = (Date.parse params[:day])
|
@day = (Date.parse params[:day])
|
||||||
@location = params[:location]
|
@location = params[:location]
|
||||||
|
@division = params[:division].to_i
|
||||||
@event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil
|
@event_location = @location.present? && @location.to_i > 0 ? EventLocation.find(@location.to_i) : nil
|
||||||
|
|
||||||
|
@schedule ||= {}
|
||||||
|
@schedule[@day] ||= {}
|
||||||
|
@schedule[@day][@division] ||= []
|
||||||
|
@schedule[@day][@division][:times] ||= {}
|
||||||
|
@schedule[@day][@division][:times][@time] ||= {}
|
||||||
|
@schedule[@day][@division][:times][@time][:item] ||= {}
|
||||||
|
@schedule[@day][@division][:times][@time][:item][:workshops] || {}
|
||||||
|
@invalid_locations = @schedule[@day][@division.to_i][:times][@time][:item][:workshops].keys
|
||||||
|
|
||||||
@workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do |workshop|
|
@workshops.sort { |a, b| a.title.downcase <=> b.title.downcase }.each do |workshop|
|
||||||
@ordered_workshops[workshop.id] = workshop
|
@ordered_workshops[workshop.id] = workshop
|
||||||
end
|
end
|
||||||
|
@ -38,7 +38,8 @@ module AdminHelper
|
|||||||
events: [
|
events: [
|
||||||
:locations,
|
:locations,
|
||||||
:meals,
|
:meals,
|
||||||
:events
|
:events,
|
||||||
|
:workshops
|
||||||
],
|
],
|
||||||
schedule: [
|
schedule: [
|
||||||
:workshop_times,
|
:workshop_times,
|
||||||
@ -177,8 +178,8 @@ module AdminHelper
|
|||||||
def available_dates_match?(host, guest)
|
def available_dates_match?(host, guest)
|
||||||
return false unless host.housing_data['availability'].present? && host.housing_data['availability'][1].present?
|
return false unless host.housing_data['availability'].present? && host.housing_data['availability'][1].present?
|
||||||
return false unless guest.arrival.present? && guest.departure.present?
|
return false unless guest.arrival.present? && guest.departure.present?
|
||||||
if host.housing_data['availability'][0] <= guest.arrival &&
|
if host.housing_data['availability'][0].to_date <= guest.arrival.to_date &&
|
||||||
host.housing_data['availability'][1] >= guest.departure
|
host.housing_data['availability'][1].to_date >= guest.departure.to_date
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -11,13 +11,15 @@ module FormHelper
|
|||||||
# set the selected locale
|
# set the selected locale
|
||||||
selected_locale = (options[:locale] || object.locale || I18n.locale).to_sym
|
selected_locale = (options[:locale] || object.locale || I18n.locale).to_sym
|
||||||
|
|
||||||
I18n.backend.enabled_locales.each do |locale|
|
locales = I18n.backend.enabled_locales.map { |l| [l, _("languages.#{l}")] }.sort_by { |l| l.last.downcase }.to_h
|
||||||
|
|
||||||
|
locales.each do |locale, locale_name|
|
||||||
# ses if this should b the selected field
|
# ses if this should b the selected field
|
||||||
class_name = selected_locale == locale.to_sym ? 'selected' : nil
|
class_name = selected_locale == locale.to_sym ? 'selected' : nil
|
||||||
|
|
||||||
# add the locale to the nav
|
# add the locale to the nav
|
||||||
nav += content_tag(:li,
|
nav += content_tag(:li,
|
||||||
content_tag(:a, _("languages.#{locale}"), href: 'javascript:void(0)'),
|
content_tag(:a, locale_name, href: 'javascript:void(0)'),
|
||||||
class: class_name, data: { locale: locale }).html_safe
|
class: class_name, data: { locale: locale }).html_safe
|
||||||
|
|
||||||
fields = ''
|
fields = ''
|
||||||
|
@ -16,7 +16,7 @@ module TableHelper
|
|||||||
headers = ''
|
headers = ''
|
||||||
options[:column_names].each do |header_name, columns|
|
options[:column_names].each do |header_name, columns|
|
||||||
column_names[header_name] ||= []
|
column_names[header_name] ||= []
|
||||||
headers += content_tag(:th, excel_data[:keys][header_name].present? ? _(excel_data[:keys][header_name]) : '', colspan: 2)
|
headers += content_tag(:th, excel_data[:keys][header_name].present? ? I18n.t(excel_data[:keys][header_name], (excel_data[:key_vars] || {})[header_name]) : '', colspan: 2)
|
||||||
row_count = columns.size
|
row_count = columns.size
|
||||||
columns.each do |column|
|
columns.each do |column|
|
||||||
column_names[header_name] << column
|
column_names[header_name] << column
|
||||||
@ -43,7 +43,7 @@ module TableHelper
|
|||||||
attributes[:rowspan] = options[:row_spans][column]
|
attributes[:rowspan] = options[:row_spans][column]
|
||||||
end
|
end
|
||||||
|
|
||||||
column_text = excel_data[:keys][column].present? ? _(excel_data[:keys][column]) : ''
|
column_text = excel_data[:keys][column].present? ? I18n.t(excel_data[:keys][column], (excel_data[:key_vars] || {})[header_name]) : ''
|
||||||
|
|
||||||
columns_html += content_tag(:th, column_text.html_safe, rowspan: attributes[:rowspan]) +
|
columns_html += content_tag(:th, column_text.html_safe, rowspan: attributes[:rowspan]) +
|
||||||
edit_column(nil, column, nil, attributes, excel_data, options)
|
edit_column(nil, column, nil, attributes, excel_data, options)
|
||||||
@ -64,7 +64,7 @@ module TableHelper
|
|||||||
if (excel_data[:column_types] || {})[column] != :table && ((options[:column_names] || []).include? column)
|
if (excel_data[:column_types] || {})[column] != :table && ((options[:column_names] || []).include? column)
|
||||||
rows += content_tag(:tr, { class: 'always-edit', data: { key: '' } }) do
|
rows += content_tag(:tr, { class: 'always-edit', data: { key: '' } }) do
|
||||||
attributes = { class: [excel_data[:column_types][column]], data: { 'column-id' => column } }
|
attributes = { class: [excel_data[:column_types][column]], data: { 'column-id' => column } }
|
||||||
column_text = excel_data[:keys][column].present? ? _(excel_data[:keys][column]) : ''
|
column_text = excel_data[:keys][column].present? ? I18n.t(excel_data[:keys][column], (excel_data[:key_vars] || {})[header_name]) : ''
|
||||||
|
|
||||||
columns = content_tag(:th, column_text.html_safe) + edit_column(nil, column, nil, attributes, excel_data, options)
|
columns = content_tag(:th, column_text.html_safe) + edit_column(nil, column, nil, attributes, excel_data, options)
|
||||||
end
|
end
|
||||||
@ -124,7 +124,7 @@ module TableHelper
|
|||||||
|
|
||||||
data[:columns].each do |column|
|
data[:columns].each do |column|
|
||||||
unless data[:column_types].present? && data[:column_types][column] == :table
|
unless data[:column_types].present? && data[:column_types][column] == :table
|
||||||
column_text = data[:keys][column].present? ? _(data[:keys][column]) : ''
|
column_text = data[:keys][column].present? ? I18n.t(data[:keys][column], (data[:key_vars] || {})[column]) : ''
|
||||||
attrs = { class: class_name }
|
attrs = { class: class_name }
|
||||||
|
|
||||||
unless @sort_column.nil?
|
unless @sort_column.nil?
|
||||||
@ -400,4 +400,29 @@ module TableHelper
|
|||||||
column_options: @column_options
|
column_options: @column_options
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def workshops_table_options
|
||||||
|
{
|
||||||
|
id: 'search-table',
|
||||||
|
class: ['registrations', 'admin-edit'],
|
||||||
|
primary_key: :id,
|
||||||
|
column_names: [
|
||||||
|
:title,
|
||||||
|
:owner,
|
||||||
|
:info,
|
||||||
|
:notes,
|
||||||
|
:locale,
|
||||||
|
:facilitators
|
||||||
|
] +
|
||||||
|
User.AVAILABLE_LANGUAGES.map { |l| "language_#{l}".to_sym } +
|
||||||
|
(User.AVAILABLE_LANGUAGES - [I18n.locale]).map { |l| "title_#{l}".to_sym } +
|
||||||
|
Workshop.all_needs.map { |n| "need_#{n}".to_sym } + [
|
||||||
|
:theme,
|
||||||
|
:space
|
||||||
|
],
|
||||||
|
editable: administration_update_path(@this_conference.slug, @admin_step),
|
||||||
|
sortable: administration_step_path(@this_conference.slug, @admin_step),
|
||||||
|
column_options: @column_options
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
= day_select @day, small: true, format: :weekday
|
= day_select @day, small: true, format: :weekday
|
||||||
= hour_select @time, small: true
|
= hour_select @time, small: true
|
||||||
= length_select @length, small: true
|
= length_select @length, small: true
|
||||||
= translate_fields @event, { title: { type: :textfield, big: true, label: 'forms.labels.generic.title' }, info: { type: :textarea, label: 'forms.labels.generic.info', edit_on: :focus } }
|
= translate_fields @event, { title: { type: :textfield, big: true }, info: { type: :textarea, label: 'forms.labels.generic.info', edit_on: :focus } }
|
||||||
.actions.next-prev
|
.actions.next-prev
|
||||||
= button :save, value: :save
|
= button :save, value: :save
|
||||||
= button :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present?
|
= button :cancel, value: :cancel, class: :subdued, formnovalidate: true if @event.id.present?
|
||||||
|
@ -6,81 +6,82 @@
|
|||||||
- else
|
- else
|
||||||
- add_inline_script :schedule if @entire_page
|
- add_inline_script :schedule if @entire_page
|
||||||
#schedule-preview
|
#schedule-preview
|
||||||
- @schedule.each do |day, data|
|
- @schedule.each do |day, data_array|
|
||||||
%h4=date(day, :weekday).html_safe
|
%h4=date(day, :weekday).html_safe
|
||||||
%table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]}
|
- data_array.each_with_index do |data, division|
|
||||||
- if data[:locations].present? && data[:locations].values.first != :add
|
%table.schedule{class: [data[:locations].present? ? 'has-locations' : 'no-locations', "locations-#{data[:num_locations]}"]}
|
||||||
%thead
|
- if data[:locations].present? && data[:locations].values.first != :add
|
||||||
%tr
|
%thead
|
||||||
%th.corner
|
%tr
|
||||||
- data[:locations].each do |id, location|
|
%th.corner
|
||||||
%th=location.is_a?(Symbol) ? '' : _!(location.title)
|
|
||||||
%tbody
|
|
||||||
- data[:times].each do |time, time_data|
|
|
||||||
%tr{class: "row-type-#{time_data[:type] || 'nil'}"}
|
|
||||||
- rowspan = (time_data[:length] * (1 / @this_conference.schedule_interval)).to_i
|
|
||||||
%th=time(time).html_safe
|
|
||||||
- if time_data[:type] == :workshop
|
|
||||||
- data[:locations].each do |id, location|
|
- data[:locations].each do |id, location|
|
||||||
- if time_data[:item][:workshops][id].present?
|
%th=location.is_a?(Symbol) ? '' : _!(location.title)
|
||||||
- workshop = time_data[:item][:workshops][id][:workshop]
|
%tbody
|
||||||
- status = time_data[:item][:workshops][id][:status]
|
- data[:times].each do |time, time_data|
|
||||||
- else
|
%tr{class: "row-type-#{time_data[:type] || 'nil'}"}
|
||||||
- workshop = status = nil
|
- rowspan = (time_data[:length] * (1 / @this_conference.schedule_interval)).to_i
|
||||||
%td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id }}
|
%th=time(time).html_safe
|
||||||
- if workshop.present? && workshop.event_location.present?
|
- if time_data[:type] == :workshop
|
||||||
.workshop-container
|
- data[:locations].each do |id, location|
|
||||||
- if @can_edit
|
- if time_data[:item][:workshops][id].present?
|
||||||
-if strip_tags(workshop.notes).strip.present?
|
- workshop = time_data[:item][:workshops][id][:workshop]
|
||||||
= admin_notes(workshop.notes)
|
- status = time_data[:item][:workshops][id][:status]
|
||||||
- if status[:errors].present?
|
- else
|
||||||
= admin_status content_tag(:ul, (status[:errors].collect { |error| (_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars])}.join).html_safe).html_safe
|
- workshop = status = nil
|
||||||
= link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do
|
%td{class: [time_data[:type], workshop.present? ? :filled : :open], rowspan: rowspan, data: workshop.present? ? nil : { block: time_data[:item][:block], day: day, location: id, division: division }}
|
||||||
.details
|
- if workshop.present? && workshop.event_location.present?
|
||||||
.title=_!workshop.title
|
.workshop-container
|
||||||
%template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }}
|
- if @can_edit
|
||||||
%h1.title=_!workshop.title
|
-if strip_tags(workshop.notes).strip.present?
|
||||||
%p.address
|
= admin_notes(workshop.notes)
|
||||||
= _!("#{workshop.event_location.title}:")
|
- if status[:errors].present?
|
||||||
= location_link workshop.event_location
|
= admin_status content_tag(:ul, (status[:errors].collect { |error| "<li>#{(_"errors.messages.schedule.#{error[:name].to_s}", vars: error[:i18nVars])}</li>"}.join).html_safe).html_safe
|
||||||
.workshop-description= richtext workshop.info, 1
|
= link_to view_workshop_path(@conference.slug, workshop.id), class: 'event-detail-link' do
|
||||||
- if @can_edit
|
.details
|
||||||
= form_tag administration_update_path(conference.slug, @admin_step), class: 'deschedule-workshop' do
|
.title=_!workshop.title
|
||||||
.status
|
%template.event-details{data: { href: view_workshop_path(@conference.slug, workshop.id) }}
|
||||||
.conflict-score
|
%h1.title=_!workshop.title
|
||||||
%span.title Conflicts:
|
%p.address
|
||||||
%span.value="#{status[:conflict_score]} / #{workshop.interested.size}"
|
= _!("#{workshop.event_location.title}:")
|
||||||
= hidden_field_tag :id, workshop.id
|
= location_link workshop.event_location
|
||||||
= button :deschedule, value: :deschedule_workshop, class: [:delete, :small]
|
.workshop-description= richtext workshop.info, 1
|
||||||
- elsif @can_edit
|
- if @can_edit
|
||||||
.title="Block #{time_data[:item][:block] + 1}"
|
= form_tag administration_update_path(conference.slug, @admin_step), class: 'deschedule-workshop' do
|
||||||
- elsif time_data[:type] != :nil
|
.status
|
||||||
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1}
|
.conflict-score
|
||||||
- case time_data[:type]
|
%span.title Conflicts:
|
||||||
- when :meal
|
%span.value="#{status[:conflict_score]} / #{workshop.interested.size}"
|
||||||
- location = EventLocation.where(id: time_data[:item]['location'].to_i).first
|
= hidden_field_tag :id, workshop.id
|
||||||
- if location.present?
|
= button :deschedule, value: :deschedule_workshop, class: [:delete, :small]
|
||||||
%a.event-detail-link
|
- elsif @can_edit
|
||||||
.details
|
.title="Block #{time_data[:item][:block] + 1}"
|
||||||
.title=_!(time_data[:item]['title'])
|
- elsif time_data[:type] != :nil
|
||||||
.location=_!location.title
|
%td{class: time_data[:type], rowspan: rowspan, colspan: data[:locations].present? ? data[:locations].size : 1}
|
||||||
%template.event-details
|
- case time_data[:type]
|
||||||
%h1.title=_!(time_data[:item]['title'])
|
- when :meal
|
||||||
%p.address
|
- location = EventLocation.where(id: time_data[:item]['location'].to_i).first
|
||||||
= _!("#{location.title}:")
|
- if location.present?
|
||||||
= location_link location
|
%a.event-detail-link
|
||||||
- when :event
|
.details
|
||||||
- if time_data[:item].event_location.present?
|
.title=_!(time_data[:item]['title'])
|
||||||
%a.event-detail-link
|
.location=_!location.title
|
||||||
.details
|
%template.event-details
|
||||||
.title=_!(time_data[:item][:title]) if time_data[:item][:title]
|
%h1.title=_!(time_data[:item]['title'])
|
||||||
.location=_!(time_data[:item].event_location.title)
|
%p.address
|
||||||
%template.event-details
|
= _!("#{location.title}:")
|
||||||
%h1.title=_!(time_data[:item][:title]) if time_data[:item][:title]
|
= location_link location
|
||||||
%p.address
|
- when :event
|
||||||
= _!("#{time_data[:item].event_location.title}:")
|
- if time_data[:item].event_location.present?
|
||||||
= location_link time_data[:item].event_location
|
%a.event-detail-link
|
||||||
= richtext time_data[:item][:info], 1
|
.details
|
||||||
|
.title=_!(time_data[:item][:title]) if time_data[:item][:title]
|
||||||
|
.location=_!(time_data[:item].event_location.title)
|
||||||
|
%template.event-details
|
||||||
|
%h1.title=_!(time_data[:item][:title]) if time_data[:item][:title]
|
||||||
|
%p.address
|
||||||
|
= _!("#{time_data[:item].event_location.title}:")
|
||||||
|
= location_link time_data[:item].event_location
|
||||||
|
= richtext time_data[:item][:info], 1
|
||||||
- if @entire_page
|
- if @entire_page
|
||||||
#workshop-selector
|
#workshop-selector
|
||||||
= form_tag administration_update_path(@this_conference.slug, @admin_step), class: 'workshop-dlg', id: 'workshop-table-form' do
|
= form_tag administration_update_path(@this_conference.slug, @admin_step), class: 'workshop-dlg', id: 'workshop-table-form' do
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
= @event_location.title
|
= @event_location.title
|
||||||
= hidden_field_tag :event_location, @location
|
= hidden_field_tag :event_location, @location
|
||||||
- else
|
- else
|
||||||
= location_select(nil, inline_label: true, small: true, invalid_locations: (((((@schedule[@day] || {})[:times] || {})[@time] || {})[:item] || {})[:workshops] || {}).keys, label: false)
|
= location_select(nil, inline_label: true, small: true, invalid_locations: @invalid_locations, label: false)
|
||||||
- if @event_location.present?
|
- if @event_location.present?
|
||||||
.host-field
|
.host-field
|
||||||
%h4.inline=_'articles.admin.locations.headings.amenities'
|
%h4.inline=_'articles.admin.locations.headings.amenities'
|
||||||
@ -38,7 +38,7 @@
|
|||||||
%td=(workshop.active_facilitators.map { |x| x.named_email }).join(', ')
|
%td=(workshop.active_facilitators.map { |x| x.named_email }).join(', ')
|
||||||
%td=workshop.interested_count
|
%td=workshop.interested_count
|
||||||
%td
|
%td
|
||||||
.text=workshop.notes
|
.text=strip_tags(workshop.notes)
|
||||||
|
|
||||||
.legend
|
.legend
|
||||||
%h4 Legend
|
%h4 Legend
|
||||||
|
12
app/views/conference_administration/_workshops.html.haml
Normal file
12
app/views/conference_administration/_workshops.html.haml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
- add_inline_script :registrations
|
||||||
|
= columns(medium: 12) do
|
||||||
|
.goes-fullscreen#registrations-table
|
||||||
|
.flex-column
|
||||||
|
= searchfield :search, nil, big: true, stretch: true
|
||||||
|
%a.button{data: { expands: 'registrations-table' }}='expand'
|
||||||
|
%a.button.delete{data: { contracts: 'registrations-table' }}='close'
|
||||||
|
.table-scroller#registrations
|
||||||
|
= html_table(@excel_data, workshops_table_options)
|
||||||
|
= columns(medium: 12) do
|
||||||
|
.actions.center
|
||||||
|
= link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :workshops, format: :xlsx), class: [:button, :download]
|
@ -1427,6 +1427,7 @@ en:
|
|||||||
locations: Locations
|
locations: Locations
|
||||||
meals: Meals
|
meals: Meals
|
||||||
events: Events
|
events: Events
|
||||||
|
workshops: Workshops
|
||||||
descriptions:
|
descriptions:
|
||||||
locations: Create the list of locations that you will be using for events,
|
locations: Create the list of locations that you will be using for events,
|
||||||
meals, and workshops.
|
meals, and workshops.
|
||||||
@ -1435,6 +1436,7 @@ en:
|
|||||||
events: Create event details. These events should be any type of event other
|
events: Create event details. These events should be any type of event other
|
||||||
than meals and workshops such as meeting, rides, and parties. The events
|
than meals and workshops such as meeting, rides, and parties. The events
|
||||||
will be added to your schedule.
|
will be added to your schedule.
|
||||||
|
workshops: View and modify all workshops created by registered users.
|
||||||
schedule:
|
schedule:
|
||||||
description: On this page you can schedule workshops and publish your schedule
|
description: On this page you can schedule workshops and publish your schedule
|
||||||
to the front page.
|
to the front page.
|
||||||
@ -2625,6 +2627,7 @@ en:
|
|||||||
unregistered: Unregistered
|
unregistered: Unregistered
|
||||||
facilitator: Facilitator
|
facilitator: Facilitator
|
||||||
workshop:
|
workshop:
|
||||||
|
created_at: Creation Date
|
||||||
options:
|
options:
|
||||||
needs:
|
needs:
|
||||||
projector: Projector
|
projector: Projector
|
||||||
@ -2718,6 +2721,7 @@ en:
|
|||||||
content:
|
content:
|
||||||
change_locale: Read in %{language}
|
change_locale: Read in %{language}
|
||||||
Translation_of: Translation of
|
Translation_of: Translation of
|
||||||
|
item_translation: "%{item} in %{language}"
|
||||||
number:
|
number:
|
||||||
currency:
|
currency:
|
||||||
format:
|
format:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user