summaryrefslogtreecommitdiff
path: root/addons/microsoft_calendar/static/src
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/microsoft_calendar/static/src
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/microsoft_calendar/static/src')
-rw-r--r--addons/microsoft_calendar/static/src/img/calendar_outlook_32.pngbin0 -> 450 bytes
-rw-r--r--addons/microsoft_calendar/static/src/js/microsoft_calendar.js219
-rw-r--r--addons/microsoft_calendar/static/src/js/microsoft_calendar_popover.js34
-rw-r--r--addons/microsoft_calendar/static/src/scss/microsoft_calendar.scss14
-rw-r--r--addons/microsoft_calendar/static/src/xml/microsoft_calendar_popover.xml8
5 files changed, 275 insertions, 0 deletions
diff --git a/addons/microsoft_calendar/static/src/img/calendar_outlook_32.png b/addons/microsoft_calendar/static/src/img/calendar_outlook_32.png
new file mode 100644
index 00000000..78553f07
--- /dev/null
+++ b/addons/microsoft_calendar/static/src/img/calendar_outlook_32.png
Binary files differ
diff --git a/addons/microsoft_calendar/static/src/js/microsoft_calendar.js b/addons/microsoft_calendar/static/src/js/microsoft_calendar.js
new file mode 100644
index 00000000..dab5def9
--- /dev/null
+++ b/addons/microsoft_calendar/static/src/js/microsoft_calendar.js
@@ -0,0 +1,219 @@
+odoo.define('microsoft_calendar.CalendarView', function (require) {
+"use strict";
+
+var core = require('web.core');
+var Dialog = require('web.Dialog');
+var framework = require('web.framework');
+const CalendarView = require('calendar.CalendarView');
+const CalendarRenderer = require('calendar.CalendarRenderer');
+const CalendarController = require('calendar.CalendarController');
+const CalendarModel = require('calendar.CalendarModel');
+const viewRegistry = require('web.view_registry');
+const session = require('web.session');
+
+var _t = core._t;
+
+const MicrosoftCalendarModel = CalendarModel.include({
+
+ /**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ this.microsoft_is_sync = true;
+ this.microsoft_pending_sync = false;
+ },
+
+ /**
+ * @override
+ */
+ __get: function () {
+ var result = this._super.apply(this, arguments);
+ result.microsoft_is_sync = this.microsoft_is_sync;
+ return result;
+ },
+
+ /**
+ * @override
+ * @returns {Promise}
+ */
+ async _loadCalendar() {
+ const _super = this._super.bind(this);
+ // When the calendar synchronization takes some time, prevents retriggering the sync while navigating the calendar.
+ if (this.microsoft_pending_sync) {
+ return _super(...arguments);
+ }
+ try {
+ await Promise.race([
+ new Promise(resolve => setTimeout(resolve, 1000)),
+ this._syncMicrosoftCalendar(true)
+ ]);
+ } catch (error) {
+ if (error.event) {
+ error.event.preventDefault();
+ }
+ console.error("Could not synchronize Outlook events now.", error);
+ this.microsoft_pending_sync = false;
+ }
+ return _super(...arguments);
+ },
+
+ _syncMicrosoftCalendar(shadow = false) {
+ var self = this;
+ this.microsoft_pending_sync = true;
+ return this._rpc({
+ route: '/microsoft_calendar/sync_data',
+ params: {
+ model: this.modelName,
+ fromurl: window.location.href,
+ }
+ }, {shadow}).then(function (result) {
+ if (result.status === "need_config_from_admin" || result.status === "need_auth") {
+ self.microsoft_is_sync = false;
+ } else if (result.status === "no_new_event_from_microsoft" || result.status === "need_refresh") {
+ self.microsoft_is_sync = true;
+ }
+ self.microsoft_pending_sync = false;
+ return result
+ });
+ },
+
+ archiveRecords: function (ids, model) {
+ return this._rpc({
+ model: model,
+ method: 'action_archive',
+ args: [ids],
+ context: session.user_context,
+ });
+ },
+});
+
+const MicrosoftCalendarController = CalendarController.include({
+ custom_events: _.extend({}, CalendarController.prototype.custom_events, {
+ syncMicrosoftCalendar: '_onSyncMicrosoftCalendar',
+ archiveRecord: '_onArchiveRecord',
+ }),
+
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Try to sync the calendar with Microsoft Calendar. According to the result
+ * from Microsoft API, this function may require an action of the user by the
+ * mean of a dialog.
+ *
+ * @private
+ * @returns {OdooEvent} event
+ */
+ _onSyncMicrosoftCalendar: function (event) {
+ var self = this;
+
+ return this.model._syncMicrosoftCalendar().then(function (o) {
+ if (o.status === "need_auth") {
+ Dialog.alert(self, _t("You will be redirected to Outlook to authorize the access to your calendar."), {
+ confirm_callback: function() {
+ framework.redirect(o.url);
+ },
+ title: _t('Redirection'),
+ });
+ } else if (o.status === "need_config_from_admin") {
+ if (!_.isUndefined(o.action) && parseInt(o.action)) {
+ Dialog.confirm(self, _t("The Outlook Synchronization needs to be configured before you can use it, do you want to do it now?"), {
+ confirm_callback: function() {
+ self.do_action(o.action);
+ },
+ title: _t('Configuration'),
+ });
+ } else {
+ Dialog.alert(self, _t("An administrator needs to configure Outlook Synchronization before you can use it!"), {
+ title: _t('Configuration'),
+ });
+ }
+ } else if (o.status === "need_refresh") {
+ self.reload();
+ }
+ }).then(event.data.on_always, event.data.on_always);
+ },
+
+ _onArchiveRecord: function (ev) {
+ var self = this;
+ Dialog.confirm(this, _t("Are you sure you want to archive this record ?"), {
+ confirm_callback: function () {
+ self.model.archiveRecords([ev.data.id], self.modelName).then(function () {
+ self.reload();
+ });
+ }
+ });
+ },
+});
+
+const MicrosoftCalendarRenderer = CalendarRenderer.include({
+ events: _.extend({}, CalendarRenderer.prototype.events, {
+ 'click .o_microsoft_sync_button': '_onSyncMicrosoftCalendar',
+ }),
+ custom_events: _.extend({}, CalendarRenderer.prototype.custom_events, {
+ archive_event: '_onArchiveEvent',
+ }),
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Adds the Sync with Outlook button in the sidebar
+ *
+ * @private
+ */
+ _initSidebar: function () {
+ var self = this;
+ this._super.apply(this, arguments);
+ this.$microsoftButton = $();
+ if (this.model === "calendar.event") {
+ if (this.state.microsoft_is_sync) {
+ this.$microsoftButton = $('<span/>', {html: _t("Synched with Outlook")})
+ .addClass('o_microsoft_sync badge badge-pill badge-success')
+ .prepend($('<i/>', {class: "fa mr-2 fa-check"}))
+ .appendTo(self.$sidebar);
+ } else {
+ this.$microsoftButton = $('<button/>', {type: 'button', html: _t("Sync with <b>Outlook</b>")})
+ .addClass('o_microsoft_sync_button oe_button btn btn-secondary')
+ .appendTo(self.$sidebar);
+ }
+ }
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Requests to sync the calendar with Microsoft Calendar
+ *
+ * @private
+ */
+ _onSyncMicrosoftCalendar: function () {
+ var self = this;
+ var context = this.getSession().user_context;
+ this.$microsoftButton.prop('disabled', true);
+ this.trigger_up('syncMicrosoftCalendar', {
+ on_always: function () {
+ self.$microsoftButton.prop('disabled', false);
+ },
+ });
+ },
+
+ _onArchiveEvent: function (ev) {
+ this._unselectEvent();
+ this.trigger_up('archiveRecord', {id: parseInt(ev.data.id, 10)});
+ },
+});
+
+return {
+ MicrosoftCalendarController,
+ MicrosoftCalendarModel,
+ MicrosoftCalendarRenderer,
+};
+
+});
diff --git a/addons/microsoft_calendar/static/src/js/microsoft_calendar_popover.js b/addons/microsoft_calendar/static/src/js/microsoft_calendar_popover.js
new file mode 100644
index 00000000..2699e0b3
--- /dev/null
+++ b/addons/microsoft_calendar/static/src/js/microsoft_calendar_popover.js
@@ -0,0 +1,34 @@
+odoo.define('microsoft_calendar.MicrosoftCalendarPopover', function(require) {
+ "use strict";
+
+ const CalendarPopover = require('web.CalendarPopover');
+
+ const MicrosoftCalendarPopover = CalendarPopover.include({
+ events: _.extend({}, CalendarPopover.prototype.events, {
+ 'click .o_cw_popover_archive_m': '_onClickPopoverArchive',
+ }),
+
+ /**
+ * We only want one 'Archive' button in the popover
+ * so if Google Sync is also active, it takes precedence
+ * over this popvoer.
+ */
+ isMEventSyncedAndArchivable() {
+ if (this.event.extendedProps.record.google_id === undefined) {
+ return this.event.extendedProps.record.microsoft_id;
+ }
+ return !this.event.extendedProps.record.google_id && this.event.extendedProps.record.microsoft_id
+ },
+
+ isEventDeletable() {
+ return !this.isMEventSyncedAndArchivable() && this._super();
+ },
+
+ _onClickPopoverArchive: function (ev) {
+ ev.preventDefault();
+ this.trigger_up('archive_event', {id: this.event.id});
+ },
+ });
+
+ return MicrosoftCalendarPopover;
+});
diff --git a/addons/microsoft_calendar/static/src/scss/microsoft_calendar.scss b/addons/microsoft_calendar/static/src/scss/microsoft_calendar.scss
new file mode 100644
index 00000000..2f1fa96b
--- /dev/null
+++ b/addons/microsoft_calendar/static/src/scss/microsoft_calendar.scss
@@ -0,0 +1,14 @@
+.o_microsoft_sync_button {
+ margin: auto;
+ > img {
+ margin-right: 10px;
+ }
+}
+.o_microsoft_sync.badge {
+ border: none;
+}
+
+img.calendar_img_tuto {
+ margin: 0 0 10px 50px;
+ border: 2px solid $o-brand-secondary;
+}
diff --git a/addons/microsoft_calendar/static/src/xml/microsoft_calendar_popover.xml b/addons/microsoft_calendar/static/src/xml/microsoft_calendar_popover.xml
new file mode 100644
index 00000000..aace2731
--- /dev/null
+++ b/addons/microsoft_calendar/static/src/xml/microsoft_calendar_popover.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates>
+ <t t-extend="Calendar.attendee.status.popover">
+ <t t-jquery=".o_cw_popover_edit" t-operation="after">
+ <a t-if="typeof widget.isMEventSyncedAndArchivable === 'function' and widget.isMEventSyncedAndArchivable() and widget.isEventDetailsVisible()" href="#" class="btn btn-secondary o_cw_popover_archive_m">Archive</a>
+ </t>
+ </t>
+</templates>