|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
define([
|
|
|
|
|
'jquery',
|
|
|
|
|
'json.sortify',
|
|
|
|
|
'/bower_components/chainpad-crypto/crypto.js',
|
|
|
|
|
'/common/toolbar.js',
|
|
|
|
|
'/bower_components/nthen/index.js',
|
|
|
|
@ -15,17 +16,20 @@ define([
|
|
|
|
|
'/customize/messages.js',
|
|
|
|
|
'/customize/application_config.js',
|
|
|
|
|
'/lib/calendar/tui-calendar.min.js',
|
|
|
|
|
'/calendar/export.js',
|
|
|
|
|
|
|
|
|
|
'/common/inner/share.js',
|
|
|
|
|
'/common/inner/access.js',
|
|
|
|
|
'/common/inner/properties.js',
|
|
|
|
|
|
|
|
|
|
'/common/jscolor.js',
|
|
|
|
|
'/bower_components/file-saver/FileSaver.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 (
|
|
|
|
|
$,
|
|
|
|
|
JSONSortify,
|
|
|
|
|
Crypto,
|
|
|
|
|
Toolbar,
|
|
|
|
|
nThen,
|
|
|
|
@ -41,9 +45,11 @@ define([
|
|
|
|
|
Messages,
|
|
|
|
|
AppConfig,
|
|
|
|
|
Calendar,
|
|
|
|
|
Export,
|
|
|
|
|
Share, Access, Properties
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var SaveAs = window.saveAs;
|
|
|
|
|
var APP = window.APP = {
|
|
|
|
|
calendars: {}
|
|
|
|
|
};
|
|
|
|
@ -77,6 +83,14 @@ Messages.calendar_loc = "Location";
|
|
|
|
|
Messages.calendar_location = "Location: {0}";
|
|
|
|
|
Messages.calendar_allDay = "All day";
|
|
|
|
|
|
|
|
|
|
Messages.calendar_minutes = "Minutes";
|
|
|
|
|
Messages.calendar_hours = "Hours";
|
|
|
|
|
Messages.calendar_days = "Days";
|
|
|
|
|
|
|
|
|
|
Messages.calendar_notifications = "Reminders";
|
|
|
|
|
Messages.calendar_addNotification = "Add reminder";
|
|
|
|
|
Messages.calendar_noNotification = "None";
|
|
|
|
|
|
|
|
|
|
var onCalendarsUpdate = Util.mkEvent();
|
|
|
|
|
|
|
|
|
|
var newCalendar = function (data, cb) {
|
|
|
|
@ -103,6 +117,12 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
cb(null, obj);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var importICSCalendar = function (data, cb) {
|
|
|
|
|
APP.module.execCommand('IMPORT_ICS', data, function (obj) {
|
|
|
|
|
if (obj && obj.error) { return void cb(obj.error); }
|
|
|
|
|
cb(null, obj);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var newEvent = function (data, cb) {
|
|
|
|
|
APP.module.execCommand('CREATE_EVENT', data, function (obj) {
|
|
|
|
|
if (obj && obj.error) { return void cb(obj.error); }
|
|
|
|
@ -230,11 +250,17 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
})()) { getTime = undefined; }
|
|
|
|
|
|
|
|
|
|
var templates = {
|
|
|
|
|
popupSave: function (obj) {
|
|
|
|
|
APP.editModalData = obj.data && obj.data.root;
|
|
|
|
|
return Messages.settings_save;
|
|
|
|
|
},
|
|
|
|
|
popupUpdate: function(obj) {
|
|
|
|
|
APP.editModalData = obj.data && obj.data.root;
|
|
|
|
|
return Messages.calendar_update;
|
|
|
|
|
},
|
|
|
|
|
monthGridHeaderExceed: function(hiddenSchedules) {
|
|
|
|
|
return '<span class="tui-full-calendar-weekday-grid-more-schedules">' + Messages._getKey('calendar_more', [hiddenSchedules]) + '</span>';
|
|
|
|
|
},
|
|
|
|
|
popupSave: function () { return Messages.settings_save; },
|
|
|
|
|
popupUpdate: function() { return Messages.calendar_update; },
|
|
|
|
|
popupEdit: function() { return Messages.poll_edit; },
|
|
|
|
|
popupDelete: function() { return Messages.kanban_delete; },
|
|
|
|
|
popupDetailLocation: function(schedule) {
|
|
|
|
@ -453,6 +479,79 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!data.readOnly) {
|
|
|
|
|
options.push({
|
|
|
|
|
tag: 'a',
|
|
|
|
|
attributes: {
|
|
|
|
|
'class': 'fa fa-upload',
|
|
|
|
|
},
|
|
|
|
|
content: h('span', Messages.importButton),
|
|
|
|
|
action: function (e) {
|
|
|
|
|
UIElements.importContent('text/calendar', function (res) {
|
|
|
|
|
Export.import(res, id, function (err, json) {
|
|
|
|
|
if (err) { return void UI.warn(Messages.importError); }
|
|
|
|
|
importICSCalendar({
|
|
|
|
|
id: id,
|
|
|
|
|
json: json
|
|
|
|
|
}, function (err) {
|
|
|
|
|
if (err) { return void UI.warn(Messages.error); }
|
|
|
|
|
UI.log(Messages.saved);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
}, {
|
|
|
|
|
accept: ['.ics']
|
|
|
|
|
})();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
options.push({
|
|
|
|
|
tag: 'a',
|
|
|
|
|
attributes: {
|
|
|
|
|
'class': 'fa fa-download',
|
|
|
|
|
},
|
|
|
|
|
content: h('span', Messages.exportButton),
|
|
|
|
|
action: function (e) {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
var cal = APP.calendars[id];
|
|
|
|
|
var suggestion = Util.find(cal, ['content', 'metadata', 'title']);
|
|
|
|
|
var types = [];
|
|
|
|
|
types.push({
|
|
|
|
|
tag: 'a',
|
|
|
|
|
attributes: {
|
|
|
|
|
'data-value': '.ics',
|
|
|
|
|
'href': '#'
|
|
|
|
|
},
|
|
|
|
|
content: '.ics'
|
|
|
|
|
});
|
|
|
|
|
var dropdownConfig = {
|
|
|
|
|
text: '.ics', // Button initial text
|
|
|
|
|
caretDown: true,
|
|
|
|
|
options: types, // Entries displayed in the menu
|
|
|
|
|
isSelect: true,
|
|
|
|
|
initialValue: '.ics',
|
|
|
|
|
common: common
|
|
|
|
|
};
|
|
|
|
|
var $select = UIElements.createDropdown(dropdownConfig);
|
|
|
|
|
UI.prompt(Messages.exportPrompt,
|
|
|
|
|
Util.fixFileName(suggestion), function (filename)
|
|
|
|
|
{
|
|
|
|
|
if (!(typeof(filename) === 'string' && filename)) { return; }
|
|
|
|
|
var ext = $select.getValue();
|
|
|
|
|
filename = filename + ext;
|
|
|
|
|
var blob = Export.main(cal.content);
|
|
|
|
|
SaveAs(blob, filename);
|
|
|
|
|
}, {
|
|
|
|
|
typeInput: $select[0]
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
options.push({
|
|
|
|
|
tag: 'a',
|
|
|
|
|
attributes: {
|
|
|
|
@ -498,7 +597,7 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
if (cal.owned) {
|
|
|
|
|
key += Messages.calendar_deleteOwned;
|
|
|
|
|
}
|
|
|
|
|
UI.confirm(Messages.calendar_deleteConfirm, function (yes) {
|
|
|
|
|
UI.confirm(key, function (yes) {
|
|
|
|
|
if (!yes) { return; }
|
|
|
|
|
deleteCalendar({
|
|
|
|
|
id: id,
|
|
|
|
@ -681,6 +780,7 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
// ie: recurrenceRule: DAILY|{uid}
|
|
|
|
|
// Use template to hide "recurrenceRule" from the detailPopup or at least to use
|
|
|
|
|
// a non technical value
|
|
|
|
|
var reminders = APP.notificationsEntries;
|
|
|
|
|
|
|
|
|
|
var startDate = event.start._date;
|
|
|
|
|
var endDate = event.end._date;
|
|
|
|
@ -694,6 +794,7 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
start: +startDate,
|
|
|
|
|
isAllDay: event.isAllDay,
|
|
|
|
|
end: +endDate,
|
|
|
|
|
reminders: reminders,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
newEvent(schedule, function (err) {
|
|
|
|
@ -711,6 +812,12 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
if (changes.start) { changes.start = +new Date(changes.start._date); }
|
|
|
|
|
var old = event.schedule;
|
|
|
|
|
|
|
|
|
|
var oldReminders = Util.find(APP.calendars, [old.calendarId, 'content', 'content', old.id, 'reminders']);
|
|
|
|
|
var reminders = APP.notificationsEntries;
|
|
|
|
|
if (JSONSortify(oldReminders || []) !== JSONSortify(reminders)) {
|
|
|
|
|
changes.reminders = reminders;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateEvent({
|
|
|
|
|
ev: old,
|
|
|
|
|
changes: changes
|
|
|
|
@ -811,6 +918,113 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var parseNotif = function (minutes) {
|
|
|
|
|
var res = {
|
|
|
|
|
unit: 'minutes',
|
|
|
|
|
value: minutes
|
|
|
|
|
};
|
|
|
|
|
var hours = minutes / 60;
|
|
|
|
|
if (!Number.isInteger(hours)) { return res; }
|
|
|
|
|
res.unit = 'hours';
|
|
|
|
|
res.value = hours;
|
|
|
|
|
var days = hours / 24;
|
|
|
|
|
if (!Number.isInteger(days)) { return res; }
|
|
|
|
|
res.unit = 'days';
|
|
|
|
|
res.value = days;
|
|
|
|
|
return res;
|
|
|
|
|
};
|
|
|
|
|
var getNotificationDropdown = function () {
|
|
|
|
|
var ev = APP.editModalData;
|
|
|
|
|
var calId = ev.selectedCal.id;
|
|
|
|
|
// XXX DEFAULT HERE [10] ==> 10 minutes before the event
|
|
|
|
|
var oldReminders = Util.find(APP.calendars, [calId, 'content', 'content', ev.id, 'reminders']) || [10];
|
|
|
|
|
APP.notificationsEntries = [];
|
|
|
|
|
var number = h('input.tui-full-calendar-content', {
|
|
|
|
|
type: "number",
|
|
|
|
|
value: 10,
|
|
|
|
|
min: 1,
|
|
|
|
|
max: 60
|
|
|
|
|
});
|
|
|
|
|
var $number = $(number);
|
|
|
|
|
var options = ['minutes', 'hours', 'days'].map(function (k) {
|
|
|
|
|
return {
|
|
|
|
|
tag: 'a',
|
|
|
|
|
attributes: {
|
|
|
|
|
'class': 'cp-calendar-reminder',
|
|
|
|
|
'data-value': k,
|
|
|
|
|
'href': '#',
|
|
|
|
|
},
|
|
|
|
|
content: Messages['calendar_'+k]
|
|
|
|
|
// Messages.calendar_minutes
|
|
|
|
|
// Messages.calendar_hours
|
|
|
|
|
// Messages.calendar_days
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
var dropdownConfig = {
|
|
|
|
|
text: Messages.calendar_minutes,
|
|
|
|
|
options: options, // Entries displayed in the menu
|
|
|
|
|
isSelect: true,
|
|
|
|
|
common: common,
|
|
|
|
|
buttonCls: 'btn btn-secondary',
|
|
|
|
|
caretDown: true,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var $block = UIElements.createDropdown(dropdownConfig);
|
|
|
|
|
$block.setValue('minutes');
|
|
|
|
|
var $types = $block.find('a');
|
|
|
|
|
$types.click(function () {
|
|
|
|
|
var mode = $(this).attr('data-value');
|
|
|
|
|
var max = mode === "minutes" ? 60 : 24;
|
|
|
|
|
$number.attr('max', max);
|
|
|
|
|
if ($number.val() > max) { $number.val(max); }
|
|
|
|
|
});
|
|
|
|
|
var addNotif = h('button.btn.btn-primary.fa.fa-plus');
|
|
|
|
|
var $list = $(h('div.cp-calendar-notif-list'));
|
|
|
|
|
var listContainer = h('div.cp-calendar-notif-list-container', [
|
|
|
|
|
h('span.cp-notif-label', Messages.calendar_notifications),
|
|
|
|
|
$list[0],
|
|
|
|
|
h('span.cp-notif-empty', Messages.calendar_noNotification)
|
|
|
|
|
]);
|
|
|
|
|
var addNotification = function (unit, value) {
|
|
|
|
|
var unitValue = (unit === "minutes") ? 1 : (unit === "hours" ? 60 : (60*24));
|
|
|
|
|
var del = h('button.btn.btn-danger.small.fa.fa-times');
|
|
|
|
|
var minutes = value * unitValue;
|
|
|
|
|
if ($list.find('[data-minutes="'+minutes+'"]').length) { return; }
|
|
|
|
|
var span = h('span.cp-notif-entry', {
|
|
|
|
|
'data-minutes': minutes
|
|
|
|
|
}, [
|
|
|
|
|
h('span', value),
|
|
|
|
|
h('span', Messages['calendar_'+unit]),
|
|
|
|
|
del
|
|
|
|
|
]);
|
|
|
|
|
$(del).click(function () {
|
|
|
|
|
$(span).remove();
|
|
|
|
|
var idx = APP.notificationsEntries.indexOf(minutes);
|
|
|
|
|
APP.notificationsEntries.splice(idx, 1);
|
|
|
|
|
});
|
|
|
|
|
$list.append(span);
|
|
|
|
|
APP.notificationsEntries.push(minutes);
|
|
|
|
|
};
|
|
|
|
|
$(addNotif).click(function () {
|
|
|
|
|
var unit = $block.getValue();
|
|
|
|
|
var value = $number.val();
|
|
|
|
|
addNotification(unit, value);
|
|
|
|
|
});
|
|
|
|
|
oldReminders.forEach(function (minutes) {
|
|
|
|
|
var p = parseNotif(minutes);
|
|
|
|
|
addNotification(p.unit, p.value);
|
|
|
|
|
});
|
|
|
|
|
return h('div.tui-full-calendar-popup-section.cp-calendar-add-notif', [
|
|
|
|
|
listContainer,
|
|
|
|
|
h('div.cp-calendar-notif-form', [
|
|
|
|
|
h('span.cp-notif-label', Messages.calendar_addNotification),
|
|
|
|
|
number,
|
|
|
|
|
$block[0],
|
|
|
|
|
addNotif
|
|
|
|
|
])
|
|
|
|
|
]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createToolbar = function () {
|
|
|
|
|
var displayed = ['useradmin', 'newpad', 'limit', 'pageTitle', 'notifications'];
|
|
|
|
|
var configTb = {
|
|
|
|
@ -900,6 +1114,10 @@ Messages.calendar_allDay = "All day";
|
|
|
|
|
var isUpdate = Boolean($el.find('#tui-full-calendar-schedule-title').val());
|
|
|
|
|
if (!isUpdate) { $el.find('.tui-full-calendar-dropdown-menu li').first().click(); }
|
|
|
|
|
|
|
|
|
|
var $button = $el.find('.tui-full-calendar-section-button-save');
|
|
|
|
|
var div = getNotificationDropdown();
|
|
|
|
|
$button.before(div);
|
|
|
|
|
|
|
|
|
|
var $cbox = $el.find('#tui-full-calendar-schedule-allday');
|
|
|
|
|
var $start = $el.find('.tui-full-calendar-section-start-date');
|
|
|
|
|
var $dash = $el.find('.tui-full-calendar-section-date-dash');
|
|
|
|
|