Add/update/delete events

pull/1/head
yflory 4 years ago
parent bbd35d0307
commit 9f4144703c

@ -39,18 +39,98 @@ define([
)
{
var APP = window.APP = {
calendars: {}
};
console.log(Calendar);
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) {
console.log(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 = {
@ -68,34 +148,14 @@ Messages.calendar = "Calendar"; // XXX
h('div#cp-calendar')
]);
var cal = new Calendar('#cp-calendar', {
var cal = APP.calendar = new Calendar('#cp-calendar', {
defaultView: 'week', // weekly view option
useCreationPopup: true,
useDetailPopup: true,
usageStatistics: false,
calendars: [{
id: '1',
name: 'My Calendar',
color: '#ffffff',
bgColor: '#9e5fff',
dragBgColor: '#9e5fff',
borderColor: '#9e5fff'
}, {
id: '2',
name: 'Company',
color: '#00a9ff',
bgColor: '#00a9ff',
dragBgColor: '#00a9ff',
borderColor: '#00a9ff'
}]
calendars: getCalendars(),
});
cal.on('beforeCreateSchedule', function(event) {
var startTime = event.start;
var endTime = event.end;
var isAllDay = event.isAllDay;
var guide = event.guide;
var triggerEventName = event.triggerEventName;
// 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)
@ -110,23 +170,49 @@ Messages.calendar = "Calendar"; // XXX
category: "time",
location: Util.fixHTML(event.location),
start: event.start,
isAllDay: event.isAllDay,
end: event.end,
};
/*
if (triggerEventName === 'click') {
// open writing simple schedule popup
schedule = {
};
} else if (triggerEventName === 'dblclick') {
// open writing detail schedule popup
schedule = {
};
}
*/
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;
cal.createSchedules([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 () {
@ -161,6 +247,10 @@ Messages.calendar = "Calendar"; // XXX
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;
@ -193,7 +283,6 @@ Messages.calendar = "Calendar"; // XXX
$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();
console.log(el);
};
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
@ -214,16 +303,26 @@ Messages.calendar = "Calendar"; // XXX
APP.module = common.makeUniversal('calendar', {
onEvent: onEvent
});
APP.module.execCommand('SUBSCRIBE', null, function () {
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();
});
var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
APP.origin = privateData.origin;

@ -25,22 +25,16 @@ define([
* Own drive
{
calendars: {
own: calendar,
extra: {
uid: calendar,
uid: calendar
}
uid: calendar,
uid: calendar
}
}
* Team drive
{
calendars: {
own: calendar,
extra: {
uid: calendar,
uid: calendar
}
uid: calendar,
uid: calendar
}
}
@ -85,10 +79,11 @@ ctx.calendars[channel] = {
var initializeCalendars = function (ctx, cb) {
var proxy = ctx.store.proxy;
var calendars = proxy.calendars = proxy.calendars || {};
if (!calendars.own) {
/*if (!calendars.own) {
var own = calendars.own = makeCalendar(true);
own.color = ctx.Store.getUserColor();
}
*/
setTimeout(cb);
// XXX for each team, if we have edit rights, create the team calendar?
// XXX or maybe do it from the team app?
@ -99,11 +94,12 @@ ctx.calendars[channel] = {
teams: c.stores,
id: c.channel,
readOnly: c.readOnly,
data: Util.clone(c.proxy)
content: Util.clone(c.proxy)
}, ctx.clients);
};
var openChannel = function (ctx, cfg) {
var openChannel = function (ctx, cfg, _cb) {
var cb = Util.once(Util.mkAsync(_cb || function () {}));
var teamId = cfg.storeId;
var data = cfg.data;
var channel = data.channel;
@ -165,34 +161,36 @@ ctx.calendars[channel] = {
console.error(channel, config);
var lm = Listmap.create(config);
c.lm = lm;
c.proxy = lm.proxy;
var proxy = c.proxy = lm.proxy;
lm.proxy.on('ready', function () {
c.ready = true;
console.warn('READY', channel);
if (!proxy.metadata) {
proxy.metadata = {
color: data.color,
title: data.title
};
}
setTimeout(update);
if (cb) { cb(null, lm.proxy); }
}).on('change', [], function () {
setTimeout(update);
}).on('error', function (info) {
if (info && info.error) { cb(info); }
});
};
var openChannels = function (ctx) {
var findFromStore = function (store) {
var c = store.proxy.calendars;
if (!c) { return; }
if (c.own) {
Object.keys(c).forEach(function (channel) {
console.log(c[channel]);
openChannel(ctx, {
storeId: store.id || 1,
data: c.own
data: c[channel]
});
}
if (c.extra) {
Object.keys(c.extra).forEach(function (channel) {
openChannel(ctx, {
storeId: store.id || 1,
data: c.extra[channel]
});
});
}
});
};
// Personal drive
@ -206,7 +204,9 @@ ctx.calendars[channel] = {
if (idx === -1) {
ctx.clients.push(cId);
}
cb();
cb({
empty: !Object.keys(ctx.calendars).length
});
Object.keys(ctx.calendars).forEach(function (channel) {
var c = ctx.calendars[channel] || {};
console.log(channel, c);
@ -215,6 +215,76 @@ ctx.calendars[channel] = {
});
};
var getStore = function (ctx, id) {
if (!id || id === 1) {
return ctx.store;
}
var m = ctx.store.modules && ctx.store.modules.team;
if (!m) { return; }
return m.getTeam(id);
};
var createCalendar = function (ctx, data, cId, cb) {
console.error(data);
var store = getStore(ctx, data.teamId);
if (!store) { return void cb({error: "NO_STORE"}); }
// Check team edit rights: viewers in teams don't have rpc
if (!store.rpc) { return void cb({error: "EFORBIDDEN"}); }
var c = store.proxy.calendars = store.proxy.calendars || {};
var cal = makeCalendar();
cal.color = data.color;
cal.title = data.title;
openChannel(ctx, {
storeId: store.id || 1,
data: cal
}, function (err, proxy) {
if (err) {
// Can't open this channel, don't store it
console.error(err);
return void cb({error: err.error})
}
// Add the calendar and call back
c[cal.channel] = cal;
ctx.Store.onSync(store.id, cb);
});
};
var createEvent = function (ctx, data, cId, cb) {
var id = data.calendarId;
var c = ctx.calendars[id];
if (!c) { return void cb({error: "ENOENT"}); }
c.proxy.content = c.proxy.content || {};
c.proxy.content[data.id] = data;
Realtime.whenRealtimeSyncs(c.lm.realtime, cb);
};
var updateEvent = function (ctx, data, cId, cb) {
if (!data || !data.ev) { return void cb({error: 'EINVAL'}); }
var id = data.ev.calendarId;
var c = ctx.calendars[id];
if (!c || !c.proxy || !c.proxy.content) { return void cb({error: "ENOENT"}); }
// Find the event
var ev = c.proxy.content[data.ev.id];
if (!ev) { return void cb({error: "EINVAL"}); }
// update the event
var changes = data.changes || {};
Object.keys(changes).forEach(function (key) {
ev[key] = changes[key];
});
Realtime.whenRealtimeSyncs(c.lm.realtime, cb);
};
var deleteEvent = function (ctx, data, cId, cb) {
var id = data.calendarId;
var c = ctx.calendars[id];
if (!c) { return void cb({error: "ENOENT"}); }
c.proxy.content = c.proxy.content || {};
delete c.proxy.content[data.id];
Realtime.whenRealtimeSyncs(c.lm.realtime, cb);
};
var removeClient = function (ctx, cId) {
var idx = ctx.clients.indexOf(cId);
ctx.clients.splice(idx, 1);
@ -249,6 +319,18 @@ ctx.calendars[channel] = {
if (cmd === 'SUBSCRIBE') {
return void subscribe(ctx, data, clientId, cb);
}
if (cmd === 'CREATE') {
return void createCalendar(ctx, data, clientId, cb);
}
if (cmd === 'CREATE_EVENT') {
return void createEvent(ctx, data, clientId, cb);
}
if (cmd === 'UPDATE_EVENT') {
return void updateEvent(ctx, data, clientId, cb);
}
if (cmd === 'DELETE_EVENT') {
return void deleteEvent(ctx, data, clientId, cb);
}
};
return calendar;

@ -7,8 +7,6 @@ define([
var createRangePicker = function (cfg) {
var start = cfg.startpicker;
var end = cfg.endpicker;
console.log(cfg);
console.error(start, end);
var e = $(end.input)[0];
var endPickr = Flatpickr(e, {

Loading…
Cancel
Save