(
/**
* Contains the functionalities related to the new reservations page.
*
* @module new_reservation
* @author Joonas Konki
* @author Anu Koskela
* @author Mikko Kuhno
* @author Henrik Paananen
* @author Atte Räty
* @license BSD 3-clause, see LICENSE for more details.
* @copyright 2015 Kepler project authors
*/
function(){
var currentGroupSelection = -1;
var currentTimeSlot = null;
var unitList = null;
var units = null;
var unit = null;
var cal = null;
var groups = null;
var eventTimeSlot = null;
var savedTSColor = null;
/**
* Selects the clicked calendar timeslot event.
* @memberof module:new_reservation
* @param {object} timeslot - The selected timeslot.
*/
function selectCalendarTimeslot(timeslot) {
if (eventTimeSlot !== null) {
eventTimeSlot.k.selected = false;
}
eventTimeSlot = timeslot;
currentTimeSlot = eventTimeSlot.eventTimeSlot.id;
timeslot.k.selected = true;
cal.fullCalendar('rerenderEvents');
}
/**
* Gets the selected calendar timeslot event.
* @memberof module:new_reservation
* @param event - Contains the event information.
* @param element - Contains information what kind of
* element the clicked event is.
* @param view - Contains the view in which the element is shown.
*/
function calendarClick (event, element, view) {
if (event.eventTimeSlot !== undefined) {
selectCalendarTimeslot(event);
$("#makeReservationBtn").attr("disabled", false);
}
}
/**
* Shows information related to the FullCalendar event. The selection is
* highlighted if the event selection is active in the calendar view.
* @memberof module:new_reservation
* @param event - Contains the event information.
* @param element - Contains information what kind of
* element the clicked event is.
* @param view - Contains the view in which the element is shown.
* @param eventData - Contains the data that the event has.
*/
function calendarEventRender(event, element, view, eventData) {
if( event.eventTimeSlot !== undefined &&
event.eventTimeSlot.id == currentTimeSlot){
event.selected = true;
eventTimeSlot = event;
}
calUtil.defaultEventRender(event, element, view);
}
/**
* Initialises the calendar with the given custom attributes.
* @memberof module:new_reservation
*/
function initCalendar(){
function eventFilter(event) {
if (event.reservation === undefined) return true;
return (event.reservation.status === 'active_id');
}
cal = calUtil.initDefaultCal(calendarClick,
calendarEventRender,
eventFilter);
cal.fullCalendar('addEventSource',{
events: function(start, end, timezone, callback){
var params = {
'start_time': start.toISOString(),
'end_time': end.toISOString(),
'unit_type_id': unit.unit_type_id,
'unit_id': unit.id,
};
kepler.getTimeSlotEvents(params, function(data){
var events = [];
var content =
kepler.translate('calendar.time_slot.reservable');
// title += ': ' + unit.name;
for (var i = 0; i < data.time_slots.length; i++) {
var ts = data.time_slots[i];
event = calUtil.makeCalendarEvent(ts);
event.eventTimeSlot = ts;
event.k.pointer = true;
events.push(event);
}
eventTimeSlot = null;
callback(events);
});
},
});
}
/**
* Shows the calendar to pick a suitable time for the reservation
* after the work selection has been made.
* Initialises the calendar if it is null.
* @memberof module:new_reservation
*/
function showPickTimeArea(){
$("#pickTimeArea").show();
if (cal === null){
initCalendar();
}
}
/**
* Clears the calendar and refetches the events.
* @memberof module:new_reservation
*/
function updateCalendar(){
if (cal !== null) {
cal.fullCalendar('refetchEvents');
}
}
/**
* Shows a notification if the selected user group is bigger than the defined
* maximum number of participants for the unit group.
* @memberof module:new_reservation
* @param {object} groups - A list of all user groups.
*/
function checkGroupSize(groups){
if(unit !== null){
var maxSize = unit.max_user_group_size;
for (var i = 0; i < groups.length; i++){
if( (groups[i].id === currentGroupSelection) &&
(groups[i].members.length > maxSize) ){
var parag = $("<p>").addClass("bg-danger");
parag.text(kepler.translate(
'content.new_reservations_group_too_big') + ".");
$("#groupMembersWarning").empty();
$("#groupMembersWarning").append(parag);
}
else {
$("#groupMembersWarning").empty();
}
}
}
}
/**
* Creates a table row element for each available time slot.
* @memberof module:new_reservation
*/
function initList(){
$("#list").empty();
if (unit !== null) {
var listDiv = $('<table>').addClass('table table-striped');
listDiv.attr('id','shiftTable');
$("#list").append(listDiv);
var headerTh = $("<th>").addClass('header');
headerTh.text(kepler.translate(
'content.supervision_shifts_header') + ":");
var headerDiv = $("<tr>");
headerDiv.append(headerTh);
var tHead = $("<thead>").append(headerDiv);
$("#shiftTable").append(tHead);
$("#shiftTable").append($("<tbody>"));
var listDisplayArea = $("#shiftTable").find("tbody");
var params = {
'unit_type_id': unit.unit_type_id,
'unit_id': unit.id
};
kepler.getTimeSlotEvents(params, function(data){
for (var i = 0; i < data.time_slots.length; i++){
var ts = data.time_slots[i];
listDiv = $('<tr>').addClass('reservableShift');
var listRadioButton = $("<input>").attr('type', 'radio');
listRadioButton.attr('name', 'shiftSelector').val(ts.id);
listRadioButton.css('cursor', 'pointer');
var shiftInfo = " "+kepler.datetimeIntervalString(ts.start_time,
ts.end_time);
shiftInfo += ", " +ts.unit_type_name;
var label = $("<label>");
label.append(listRadioButton);
label.append(shiftInfo);
var td = $('<td>').append(label);
listDiv.append(td);
listDisplayArea.append(listDiv);
}
//Should check if some selection is defined to filter things
if (currentTimeSlot !== null){
$('input:radio[name=shiftSelector]').filter(
'[value=' + currentTimeSlot +']').attr('checked', true);
}
});
}
else {
var heading = $("<h4>").addClass("bg-info");
heading.text(kepler.translate(
'content.new_reservations_pick_experiment') + "!");
$("#list").append(heading);
}
}
/**
* Pastes the unit group, identified and name of the unit together into one
* string for better readability.
* @param {object} unit - The selected unit.
* @returns {string} - The names of the unit group, qualifier and unit.
* @memberof module:new_reservation
*/
function unitDisplayName(unit) {
return unit.unit_group + "/" + unit.qualifier + ", " + unit.name;
}
/**
* Sets the unit's name and other information to the corresponding areas.
* @memberof module:new_reservation
*/
function displayUnitDescription() {
var unitNameDiv = $("#selectedUnitName");
var unitDescDiv = $("#selectedUnitDesc");
var maxGroupSizeDiv = $("#selectedUnitGroupMaxSize");
var divNameLabel = $("<div>").addClass("selected-unit-label");
divNameLabel.text(kepler.translate('content.unit_name'));
var divNameValue = $("<div>").addClass("selected-unit-value");
divNameValue.text(unitDisplayName(unit));
unitNameDiv.empty();
unitNameDiv.append(divNameLabel);
unitNameDiv.append(divNameValue);
var divDescLabel = $("<div>").addClass("selected-unit-label");
divDescLabel.text(kepler.translate('content.unit_desc'));
var divDescValue = $("<div>").addClass("selected-unit-value");
divDescValue.text(unit.description ? unit.description : "-");
unitDescDiv.empty();
unitDescDiv.append(divDescLabel);
unitDescDiv.append(divDescValue);
var divGroup = $("<div>").addClass("selected-unit-label");
divGroup.text(kepler.translate('content.unit_user_group_max_size'));
maxGroupSizeDiv.empty();
maxGroupSizeDiv.append(divGroup);
var maxGroupSize = unit.max_user_group_size + " ";
if (unit.max_user_group_size == 1) {
maxGroupSize += kepler.translate('content.unit_user_group_member_1');
}
else {
maxGroupSize += kepler.translate('content.unit_user_group_member_N');
}
var maxUsers = $("<div>").addClass("selected-unit-value");
maxUsers.text(maxGroupSize);
maxGroupSizeDiv.append(maxUsers);
}
/**
* Fills the unitList with the units that match the given string.
* @memberof module:new_reservation
* @param {string} inputText - The string that has to be found in the name of
* each displayed unit.
*/
function updateUnitList(inputText){
$("#unitList").empty();
var filter = inputText.toLowerCase();
for (var i = 0; i < units.length; i++) {
var unit = units[i];
var displayName = unitDisplayName(unit);
var displayLower = displayName.toLowerCase();
if(displayLower.indexOf(filter) != -1) {
var option = $("<option>");
option.val(i);
// option.val(unit.id);
option.text(displayName);
$("#unitList").append(option);
}
}
}
/**
* Changes between the list and calendar views when the button is clicked.
* @function
* @name toggleViewButton click
* @memberof module:new_reservation
*/
$("#toggleViewButton").click(function(data){
if($("#viewList").is(":visible")){
$("#viewList").hide();
$("#viewCalendar").show();
updateCalendar();
if(currentTimeSlot !== null){
console.log(currentTimeSlot);
}
$("#toggleViewButton").text( kepler.translate(
'content.reservation_frame_button_list') );
} else {
initList();
$("#viewList").show();
$("#viewCalendar").hide();
$("#toggleViewButton").text( kepler.translate(
'content.reservation_frame_button_calendar') );
}
});
/**
* This is executed after the HTML page has been loaded.
* This is a common procedure of all of the client-side modules to
* initialise the page content.
* @memberof module:new_reservation
*/
function doc_ready() {
$("#navNewReservation").addClass("active");
$("#viewList").change(function() {
currentTimeSlot = $('#viewList').find(':checked').val();
$("#makeReservationBtn").attr("disabled",false);
});
kepler.getUserGroups(function (data) {
groups = data.groups;
currentGroupSelection = groups[0].id;
for (var i = 0; i < groups.length; i++){
var group = groups[i];
if (group.is_personal === false){
$("#newReservationSelectGroup").append("<option value='" +
group.id + "'> " + kepler.translate('label.group') + ": " +
group.name + "</option>");
}
else {
$("#newReservationSelectGroup").
append("<option value='" + group.id + "'>" +
group.members[0].first_names + " " +
group.members[0].last_name + "</option>");
}
}
});
/**
* Displays the members of the selected user group and calls the function
* checkGroupSize.
*
* @function
* @name newReservationSelectGroup change
* @inner
* @memberof module:new_reservation
*/
$("#newReservationSelectGroup").change(function(v){
$("#groupMembersArea").empty();
currentGroupSelection = parseInt(v.target.value);
for (var i = 0; i < groups.length; i++){
var group = groups[i];
if ((group.id === currentGroupSelection) &&
(group.is_personal === false)) {
$("#groupMembersArea").empty();
var memberslist = "";
for (var k = 0; k < groups[i].members.length; k++){
if(k > 0) memberslist += ",";
if (groups[i].members[k].call_name !== null)
memberslist += " " + groups[i].members[k].call_name +
" " + groups[i].members[k].last_name;
else
memberslist += " " + groups[i].members[k].first_names +
" " + groups[i].members[k].last_name;
}
var mTitle = $("<b>").text(kepler.translate(
'content.new_reservations_group_members') + ":");
var pMembers = $("<p>").append(mTitle);
pMembers.append(memberslist);
$("#groupMembersArea").append(pMembers);
}
}
checkGroupSize(groups);
});
$("#searchField").on("input", function(v){
var inputText = v.target.value;
updateUnitList(inputText);
});
unitList = kepler.createLoadElement("#unitList", function (element) {
call = kepler.getUnits(function (data) {
units = data.units;
updateUnitList("");
});
return call;
});
unitList.load();
var selectedUnit = null;
/**
* Displays the unit's description, check the size of the selected user
* group and updates the available time slots shown in the calendar or the
* list view.
*
* @function
* @name unitList change
* @inner
* @memberof module:new_reservation
*/
$('#unitList').change(function(v) {
if (selectedUnit !== v.target.value && v.target.value !== "") {
selectedUnit = v.target.value;
var index = parseInt(selectedUnit);
unit = units[index];
displayUnitDescription();
checkGroupSize(groups);
showPickTimeArea();
// Check which view is open and update that
if(cal.is(":visible")) {
updateCalendar();
} else {
initList();
}
}
});
$("#pickTimeArea").hide();
//Functions to disable and enable makeReservationButton
if (eventTimeSlot !== null){
$("#makeReservationBtn").attr("disabled",false);
}else {
$("#makeReservationBtn").attr("disabled",true);
}
/**
* Gets the additional information from the extraInfo field and calls the
* function addReservation at kepler.js to save the reservation with the
* provided parameters.
*
* @function
* @name makeReservationBtn click
* @inner
* @memberof module:new_reservation
*/
$("#makeReservationBtn").click(function(){
var addInfo = $("#extraInfo").val();
if ( cal !== null && cal.is(":visible") ) {
if(eventTimeSlot !== null) {
console.log(eventTimeSlot.eventTimeSlot.id);
var params = {
'time_slot_id': eventTimeSlot.eventTimeSlot.id,
'unit_id': unit.id,
'unit_group_id': unit.unit_group_id,
'user_group_id': currentGroupSelection,
'note': addInfo,
};
console.log (params);
kepler.addReservation(params, function (data) {
if (data.result.success === true) {
$('#extraInfo').val("");
}
kepler.showResult(data.result, "#notification");
updateCalendar();
});
} else {
// TODO(henrik): This should be cleaned-up: no alert
alert(kepler.translate('content.new_reservations_picktime')+
'!');
}
} else {
var params = {
'time_slot_id': currentTimeSlot,
'unit_id': unit.id,
'unit_group_id': unit.unit_group_id,
'user_group_id': currentGroupSelection,
'note': addInfo,
};
console.log (params);
kepler.addReservation(params, function (data) {
if (data.result.success === true) {
$('#extraInfo').val("");
}
kepler.showResult(data.result, "#notification");
currentTimeSlot = null;
if(cal.is(":visible")){
updateCalendar();
} else {
initList();
}
});
}
});
}
$(document).ready(doc_ready);
}());