|
|
|
|
define([
|
|
|
|
|
'jquery',
|
|
|
|
|
'/bower_components/chainpad-crypto/crypto.js',
|
|
|
|
|
'/common/toolbar.js',
|
|
|
|
|
'/bower_components/nthen/index.js',
|
|
|
|
|
'/common/sframe-common.js',
|
|
|
|
|
'/common/common-util.js',
|
|
|
|
|
'/common/common-hash.js',
|
|
|
|
|
'/common/common-interface.js',
|
|
|
|
|
'/common/common-ui-elements.js',
|
|
|
|
|
'/common/common-realtime.js',
|
|
|
|
|
'/common/clipboard.js',
|
|
|
|
|
'/common/inner/common-mediatag.js',
|
|
|
|
|
'/common/hyperscript.js',
|
|
|
|
|
'/customize/messages.js',
|
|
|
|
|
'/customize/application_config.js',
|
|
|
|
|
'/lib/calendar/tui-calendar.min.js',
|
|
|
|
|
|
|
|
|
|
'css!/lib/calendar/tui-calendar.min.css',
|
|
|
|
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
|
|
|
|
'less!/calendar/app-calendar.less',
|
|
|
|
|
], function (
|
|
|
|
|
$,
|
|
|
|
|
Crypto,
|
|
|
|
|
Toolbar,
|
|
|
|
|
nThen,
|
|
|
|
|
SFCommon,
|
|
|
|
|
Util,
|
|
|
|
|
Hash,
|
|
|
|
|
UI,
|
|
|
|
|
UIElements,
|
|
|
|
|
Realtime,
|
|
|
|
|
Clipboard,
|
|
|
|
|
MT,
|
|
|
|
|
h,
|
|
|
|
|
Messages,
|
|
|
|
|
AppConfig,
|
|
|
|
|
Calendar
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var APP = window.APP = {
|
|
|
|
|
calendars: {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var common;
|
|
|
|
|
var sframeChan;
|
|
|
|
|
|
|
|
|
|
Messages.calendar = "Calendar"; // XXX
|
|
|
|
|
Messages.calendar_default = "My calendar"; // XXX
|
|
|
|
|
|
|
|
|
|
var newCalendar = function (data, cb) {
|
|
|
|
|
APP.module.execCommand('CREATE', data, function (obj) {
|
|
|
|
|
if (obj && obj.error) { return void cb(obj.error); }
|
|
|
|
|
cb(null, obj);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var newEvent = function (data, cb) {
|
|
|
|
|
var start = data.start;
|
|
|
|
|
var end = data.end;
|
|
|
|
|
data.start = +new Date(start._date);
|
|
|
|
|
data.end = +new Date(end._date);
|
|
|
|
|
APP.module.execCommand('CREATE_EVENT', data, function (obj) {
|
|
|
|
|
if (obj && obj.error) { return void cb(obj.error); }
|
|
|
|
|
cb(null, obj);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var updateEvent = function (data, cb) {
|
|
|
|
|
APP.module.execCommand('UPDATE_EVENT', data, function (obj) {
|
|
|
|
|
if (obj && obj.error) { return void cb(obj.error); }
|
|
|
|
|
cb(null, obj);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var deleteEvent = function (data, cb) {
|
|
|
|
|
APP.module.execCommand('DELETE_EVENT', data, function (obj) {
|
|
|
|
|
if (obj && obj.error) { return void cb(obj.error); }
|
|
|
|
|
cb(null, obj);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var getContrast = function (color) {
|
|
|
|
|
var rgb = Util.hexToRGB(color);
|
|
|
|
|
// http://www.w3.org/TR/AERT#color-contrast
|
|
|
|
|
var brightness = Math.round(((parseInt(rgb[0]) * 299) +
|
|
|
|
|
(parseInt(rgb[1]) * 587) +
|
|
|
|
|
(parseInt(rgb[2]) * 114)) / 1000);
|
|
|
|
|
return (brightness > 125) ? 'black' : 'white';
|
|
|
|
|
};
|
|
|
|
|
var getCalendars = function () {
|
|
|
|
|
return Object.keys(APP.calendars).map(function (id) {
|
|
|
|
|
var c = APP.calendars[id];
|
|
|
|
|
var md = Util.find(c, ['content', 'metadata']);
|
|
|
|
|
if (!md) { return void console.error('Ignore calendar without metadata'); }
|
|
|
|
|
return {
|
|
|
|
|
id: id,
|
|
|
|
|
name: Util.fixHTML(md.title),
|
|
|
|
|
color: getContrast(md.color),
|
|
|
|
|
bgColor: md.color,
|
|
|
|
|
dragBgColor: md.color,
|
|
|
|
|
borderColor: md.color,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var getSchedules = function () {
|
|
|
|
|
var s = [];
|
|
|
|
|
Object.keys(APP.calendars).forEach(function (id) {
|
|
|
|
|
var c = APP.calendars[id];
|
|
|
|
|
var data = c.content || {};
|
|
|
|
|
Object.keys(data.content || {}).forEach(function (uid) {
|
|
|
|
|
var obj = data.content[uid];
|
|
|
|
|
obj.title = Util.fixHTML(obj.title || "");
|
|
|
|
|
obj.location = Util.fixHTML(obj.location || "");
|
|
|
|
|
s.push(data.content[uid]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
return s;
|
|
|
|
|
};
|
|
|
|
|
var updateCalendar = function (data) {
|
|
|
|
|
var cal = APP.calendar;
|
|
|
|
|
|
|
|
|
|
// Is it a new calendar?
|
|
|
|
|
var isNew = !APP.calendars[data.id];
|
|
|
|
|
|
|
|
|
|
// Update local data
|
|
|
|
|
APP.calendars[data.id] = data;
|
|
|
|
|
|
|
|
|
|
// If this calendar is new, add it
|
|
|
|
|
if (cal && isNew) { cal.setCalendars(getCalendars()); }
|
|
|
|
|
|
|
|
|
|
// If calendar if initialized, update it
|
|
|
|
|
if (!cal) { return; }
|
|
|
|
|
cal.clear();
|
|
|
|
|
cal.createSchedules(getSchedules(), true);
|
|
|
|
|
cal.render();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var templates = {
|
|
|
|
|
popupSave: function () {
|
|
|
|
|
return Messages.settings_save;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var makeCalendar = function (ctx) {
|
|
|
|
|
var $container = $('#cp-container');
|
|
|
|
|
$container.append([
|
|
|
|
|
h('div#menu', [
|
|
|
|
|
h('span#renderRange.render-range')
|
|
|
|
|
]),
|
|
|
|
|
h('div#cp-calendar')
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
var cal = APP.calendar = new Calendar('#cp-calendar', {
|
|
|
|
|
defaultView: 'week', // weekly view option
|
|
|
|
|
useCreationPopup: true,
|
|
|
|
|
useDetailPopup: true,
|
|
|
|
|
usageStatistics: false,
|
|
|
|
|
calendars: getCalendars(),
|
|
|
|
|
});
|
|
|
|
|
cal.on('beforeCreateSchedule', function(event) {
|
|
|
|
|
// XXX Recurrence (later)
|
|
|
|
|
// On creation, select a recurrence rule (daily / weekly / monthly / more weird rules)
|
|
|
|
|
// then mark it under recurrence rule with a uid (the same for all the recurring events)
|
|
|
|
|
// ie: recurrenceRule: DAILY|{uid}
|
|
|
|
|
// Use template to hide "recurrenceRule" from the detailPopup or at least to use
|
|
|
|
|
// a non technical value
|
|
|
|
|
|
|
|
|
|
var schedule = {
|
|
|
|
|
id: Util.uid(),
|
|
|
|
|
calendarId: event.calendarId,
|
|
|
|
|
title: Util.fixHTML(event.title),
|
|
|
|
|
category: "time",
|
|
|
|
|
location: Util.fixHTML(event.location),
|
|
|
|
|
start: event.start,
|
|
|
|
|
isAllDay: event.isAllDay,
|
|
|
|
|
end: event.end,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
newEvent(schedule, function (err) {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
return void UI.warn(err);
|
|
|
|
|
}
|
|
|
|
|
cal.createSchedules([schedule]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
cal.on('beforeUpdateSchedule', function(event) {
|
|
|
|
|
var changes = event.changes || {};
|
|
|
|
|
delete changes.state;
|
|
|
|
|
if (changes.end) { changes.end = +new Date(changes.end._date); }
|
|
|
|
|
if (changes.start) { changes.start = +new Date(changes.start._date); }
|
|
|
|
|
var old = event.schedule;
|
|
|
|
|
|
|
|
|
|
updateEvent({
|
|
|
|
|
ev: old,
|
|
|
|
|
changes: changes
|
|
|
|
|
}, function (err) {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
return void UI.warn(err);
|
|
|
|
|
}
|
|
|
|
|
cal.updateSchedule(old.id, old.calendarId, changes);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
cal.on('beforeDeleteSchedule', function(event) {
|
|
|
|
|
var data = event.schedule;
|
|
|
|
|
deleteEvent(event.schedule, function (err) {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
return void UI.warn(err);
|
|
|
|
|
}
|
|
|
|
|
cal.deleteSchedule(data.id, data.calendarId);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
cal.createSchedules(getSchedules(), true);
|
|
|
|
|
cal.render();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createToolbar = function () {
|
|
|
|
|
var displayed = ['useradmin', 'newpad', 'limit', 'pageTitle', 'notifications'];
|
|
|
|
|
var configTb = {
|
|
|
|
|
displayed: displayed,
|
|
|
|
|
sfCommon: common,
|
|
|
|
|
$container: APP.$toolbar,
|
|
|
|
|
pageTitle: Messages.calendar,
|
|
|
|
|
metadataMgr: common.getMetadataMgr(),
|
|
|
|
|
};
|
|
|
|
|
APP.toolbar = Toolbar.create(configTb);
|
|
|
|
|
APP.toolbar.$rightside.hide();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var onEvent = function (obj) {
|
|
|
|
|
var ev = obj.ev;
|
|
|
|
|
var data = obj.data;
|
|
|
|
|
if (ev === 'UPDATE') {
|
|
|
|
|
console.log('Update');
|
|
|
|
|
updateCalendar(data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
nThen(function (waitFor) {
|
|
|
|
|
$(waitFor(UI.addLoadingScreen));
|
|
|
|
|
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
|
|
|
|
|
}).nThen(function (waitFor) {
|
|
|
|
|
APP.$toolbar = $('#cp-toolbar');
|
|
|
|
|
sframeChan = common.getSframeChannel();
|
|
|
|
|
sframeChan.onReady(waitFor());
|
|
|
|
|
}).nThen(function (/*waitFor*/) {
|
|
|
|
|
createToolbar();
|
|
|
|
|
var metadataMgr = common.getMetadataMgr();
|
|
|
|
|
var privateData = metadataMgr.getPrivateData();
|
|
|
|
|
var user = metadataMgr.getUserData();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Fix flatpickr selection
|
|
|
|
|
var MutationObserver = window.MutationObserver;
|
|
|
|
|
var onFlatPickr = function (el) {
|
|
|
|
|
// Don't close event creation popup when clicking on flatpickr
|
|
|
|
|
$(el).mousedown(function (e) {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var observer = new MutationObserver(function(mutations) {
|
|
|
|
|
mutations.forEach(function(mutation) {
|
|
|
|
|
var node;
|
|
|
|
|
for (var i = 0; i < mutation.addedNodes.length; i++) {
|
|
|
|
|
var node = mutation.addedNodes[i];
|
|
|
|
|
if (node.classList && node.classList.contains('flatpickr-calendar')) {
|
|
|
|
|
onFlatPickr(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
observer.observe($('body')[0], {
|
|
|
|
|
childList: true,
|
|
|
|
|
subtree: false
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Customize creation/update popup
|
|
|
|
|
var onCalendarPopup = function (el) {
|
|
|
|
|
var $el = $(el);
|
|
|
|
|
$el.find('.tui-full-calendar-confirm').addClass('btn btn-primary');
|
|
|
|
|
$el.find('input').attr('autocomplete', 'off');
|
|
|
|
|
$el.find('.tui-full-calendar-dropdown-button').addClass('btn btn-secondary');
|
|
|
|
|
$el.find('.tui-full-calendar-popup-close').addClass('btn btn-cancel fa fa-times cp-calendar-close').empty();
|
|
|
|
|
};
|
|
|
|
|
var observer = new MutationObserver(function(mutations) {
|
|
|
|
|
mutations.forEach(function(mutation) {
|
|
|
|
|
var node;
|
|
|
|
|
for (var i = 0; i < mutation.addedNodes.length; i++) {
|
|
|
|
|
var node = mutation.addedNodes[i];
|
|
|
|
|
if (node.classList && node.classList.contains('tui-full-calendar-popup')) {
|
|
|
|
|
onCalendarPopup(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
observer.observe($('body')[0], {
|
|
|
|
|
childList: true,
|
|
|
|
|
subtree: true
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
APP.module = common.makeUniversal('calendar', {
|
|
|
|
|
onEvent: onEvent
|
|
|
|
|
});
|
|
|
|
|
APP.module.execCommand('SUBSCRIBE', null, function (obj) {
|
|
|
|
|
if (obj.empty) {
|
|
|
|
|
// No calendar yet, create one
|
|
|
|
|
newCalendar({
|
|
|
|
|
teamId: 1,
|
|
|
|
|
color: user.color,
|
|
|
|
|
title: Messages.calendar_default
|
|
|
|
|
}, function (err, obj) {
|
|
|
|
|
if (err) { return void UI.errorLoadingScreen(Messages.error); } // XXX
|
|
|
|
|
makeCalendar();
|
|
|
|
|
UI.removeLoadingScreen();
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
console.error('subscribed');
|
|
|
|
|
// XXX build UI
|
|
|
|
|
makeCalendar();
|
|
|
|
|
UI.removeLoadingScreen();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
APP.origin = privateData.origin;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
});
|