[FIX] microsoft_calendar: Badge when sync is active
Add a cron to sync events in Microsoft calendar In Google and Microsoft calendar: remove 'sync with ...' button when the synchronization is already activated, and replace it by a badge. closes odoo/odoo#58197 Taskid: 2329313 X-original-commit: 255eb91dd5e9fb39a7625064d1ba8e0b492bfb85 Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com> Signed-off-by: jbm-odoo <jbm-odoo@users.noreply.github.com>
This commit is contained in:
@@ -20,7 +20,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
module_google_calendar = fields.Boolean(
|
||||
string='Allow the users to synchronize their calendar with Google Calendar')
|
||||
module_microsoft_calendar = fields.Boolean(
|
||||
string='Allow the users to synchronize their calendar with Office 365 Calendar')
|
||||
string='Allow the users to synchronize their calendar with Outlook Calendar')
|
||||
module_google_drive = fields.Boolean("Attach Google documents to any record")
|
||||
module_google_spreadsheet = fields.Boolean("Google Spreadsheet")
|
||||
module_auth_oauth = fields.Boolean("Use external authentication providers (OAuth)")
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
<field name="module_microsoft_calendar" />
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Office 365 Calendar" for="module_microsoft_calendar"/>
|
||||
<label string="Outlook Calendar" for="module_microsoft_calendar"/>
|
||||
<div class="text-muted">
|
||||
Synchronize your calendar with Outlook
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,24 @@ var _t = core._t;
|
||||
|
||||
const GoogleCalendarModel = CalendarModel.include({
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.google_is_sync = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
__get: function () {
|
||||
var result = this._super.apply(this, arguments);
|
||||
result.google_is_sync = this.google_is_sync;
|
||||
return result;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @returns {Promise}
|
||||
@@ -35,6 +53,7 @@ const GoogleCalendarModel = CalendarModel.include({
|
||||
},
|
||||
|
||||
_syncGoogleCalendar(shadow = false) {
|
||||
var self = this;
|
||||
var context = this.getSession().user_context;
|
||||
return this._rpc({
|
||||
route: '/google_calendar/sync_data',
|
||||
@@ -43,7 +62,14 @@ const GoogleCalendarModel = CalendarModel.include({
|
||||
fromurl: window.location.href,
|
||||
local_context: context, // LUL TODO remove this local_context
|
||||
}
|
||||
}, {shadow});
|
||||
}, {shadow}).then(function (result) {
|
||||
if (result.status === "need_config_from_admin" || result.status === "need_auth") {
|
||||
self.google_is_sync = false;
|
||||
} else if (result.status === "no_new_event_from_google" || result.status === "need_refresh") {
|
||||
self.google_is_sync = true;
|
||||
}
|
||||
return result
|
||||
});
|
||||
},
|
||||
})
|
||||
|
||||
@@ -115,12 +141,16 @@ const GoogleCalendarRenderer = CalendarRenderer.include({
|
||||
this._super.apply(this, arguments);
|
||||
this.$googleButton = $();
|
||||
if (this.model === "calendar.event") {
|
||||
this.$googleButton = $('<button/>', {type: 'button', html: _t("Sync with <b>Google</b>")})
|
||||
.addClass('o_google_sync_button oe_button btn btn-secondary')
|
||||
.prepend($('<img/>', {
|
||||
src: "/google_calendar/static/src/img/calendar_32.png",
|
||||
}))
|
||||
if (this.state.google_is_sync) {
|
||||
this.$googleButton = $('<span/>', {html: _t("Synched with Google")})
|
||||
.addClass('o_google_sync badge badge-pill badge-success')
|
||||
.prepend($('<i/>', {class: "fa mr-2 fa-check"}))
|
||||
.appendTo(self.$sidebar);
|
||||
} else {
|
||||
this.$googleButton = $('<button/>', {type: 'button', html: _t("Sync with <b>Google</b>")})
|
||||
.addClass('o_google_sync_button oe_button btn btn-secondary')
|
||||
.appendTo(self.$sidebar);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.o_google_sync_button {
|
||||
display: block;
|
||||
margin: auto;
|
||||
> img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.o_google_sync.badge {
|
||||
border: none;
|
||||
}
|
||||
|
||||
img.calendar_img_tuto {
|
||||
margin: 0 0 10px 50px;
|
||||
|
||||
@@ -70,7 +70,7 @@ QUnit.module('Google Calendar', {
|
||||
}, function () {
|
||||
|
||||
QUnit.test('sync google calendar', async function (assert) {
|
||||
assert.expect(8);
|
||||
assert.expect(9);
|
||||
|
||||
var calendar = await createCalendarView({
|
||||
View: GoogleCalendarView,
|
||||
@@ -105,12 +105,14 @@ QUnit.module('Google Calendar', {
|
||||
|
||||
assert.containsN(calendar, '.fc-event', 3, "should display 3 events on the month");
|
||||
|
||||
await testUtils.dom.click(calendar.$('.o_google_sync_button'));
|
||||
await testUtils.dom.click(calendar.$('.o_calendar_button_next'));
|
||||
await testUtils.dom.click(calendar.$('.o_calendar_button_prev'));
|
||||
|
||||
assert.verifySteps([
|
||||
'/google_calendar/sync_data',
|
||||
'/web/dataset/call_kw/calendar.event/search_read',
|
||||
'/google_calendar/sync_data',
|
||||
'/web/dataset/call_kw/calendar.event/search_read',
|
||||
'/google_calendar/sync_data',
|
||||
'/web/dataset/call_kw/calendar.event/search_read',
|
||||
], 'should do a search_read before and after the call to sync_data');
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
'depends': ['microsoft_account', 'calendar'],
|
||||
'qweb': ['static/src/xml/*.xml'],
|
||||
'data': [
|
||||
'data/microsoft_calendar_data.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/reset_account_views.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record forcecreate="True" id="ir_cron_sync_all_cals" model="ir.cron">
|
||||
<field name="name">Outlook: synchronization</field>
|
||||
<field name="model_id" ref="model_res_users"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
model._sync_all_microsoft_calendar()
|
||||
</field>
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
<field name="interval_number">12</field>
|
||||
<field name="interval_type">hours</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -112,7 +112,7 @@ class MicrosoftSync(models.AbstractModel):
|
||||
synced.write({self._active_name: False})
|
||||
self = self - synced
|
||||
elif synced:
|
||||
raise UserError(_("You cannot delete a record synchronized with Microsoft Calendar, archive it instead."))
|
||||
raise UserError(_("You cannot delete a record synchronized with Outlook Calendar, archive it instead."))
|
||||
return super().unlink()
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -39,7 +39,7 @@ class User(models.Model):
|
||||
client_secret = get_param('microsoft_calendar_client_secret')
|
||||
|
||||
if not client_id or not client_secret:
|
||||
raise UserError(_("The account for the Microsoft Calendar service is not configured."))
|
||||
raise UserError(_("The account for the Outlook Calendar service is not configured."))
|
||||
|
||||
headers = {"content-type": "application/x-www-form-urlencoded"}
|
||||
data = {
|
||||
|
||||
@@ -14,6 +14,23 @@ var _t = core._t;
|
||||
|
||||
const MicrosoftCalendarModel = CalendarModel.include({
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.microsoft_is_sync = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
__get: function () {
|
||||
var result = this._super.apply(this, arguments);
|
||||
result.microsoft_is_sync = this.microsoft_is_sync;
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @returns {Promise}
|
||||
@@ -29,19 +46,27 @@ const MicrosoftCalendarModel = CalendarModel.include({
|
||||
if (error.event) {
|
||||
error.event.preventDefault();
|
||||
}
|
||||
console.error("Could not synchronize Microsoft events now.", error);
|
||||
console.error("Could not synchronize Outlook events now.", error);
|
||||
}
|
||||
return _super(...arguments);
|
||||
},
|
||||
|
||||
_syncMicrosoftCalendar(shadow = false) {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
route: '/microsoft_calendar/sync_data',
|
||||
params: {
|
||||
model: this.modelName,
|
||||
fromurl: window.location.href,
|
||||
}
|
||||
}, {shadow});
|
||||
}, {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;
|
||||
}
|
||||
return result
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -68,7 +93,7 @@ const MicrosoftCalendarController = CalendarController.include({
|
||||
|
||||
return this.model._syncMicrosoftCalendar().then(function (o) {
|
||||
if (o.status === "need_auth") {
|
||||
Dialog.alert(self, _t("You will be redirected to Microsoft to authorize the access to your calendar."), {
|
||||
Dialog.alert(self, _t("You will be redirected to Outlook to authorize the access to your calendar."), {
|
||||
confirm_callback: function() {
|
||||
framework.redirect(o.url);
|
||||
},
|
||||
@@ -76,14 +101,14 @@ const MicrosoftCalendarController = CalendarController.include({
|
||||
});
|
||||
} else if (o.status === "need_config_from_admin") {
|
||||
if (!_.isUndefined(o.action) && parseInt(o.action)) {
|
||||
Dialog.confirm(self, _t("The Microsoft Synchronization needs to be configured before you can use it, do you want to do it now?"), {
|
||||
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 Microsoft Synchronization before you can use it!"), {
|
||||
Dialog.alert(self, _t("An administrator needs to configure Outlook Synchronization before you can use it!"), {
|
||||
title: _t('Configuration'),
|
||||
});
|
||||
}
|
||||
@@ -104,7 +129,7 @@ const MicrosoftCalendarRenderer = CalendarRenderer.include({
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Adds the Sync with Microsoft button in the sidebar
|
||||
* Adds the Sync with Outlook button in the sidebar
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
@@ -113,12 +138,16 @@ const MicrosoftCalendarRenderer = CalendarRenderer.include({
|
||||
this._super.apply(this, arguments);
|
||||
this.$microsoftButton = $();
|
||||
if (this.model === "calendar.event") {
|
||||
this.$microsoftButton = $('<button/>', {type: 'button', html: _t("Sync with <b>Microsoft</b>")})
|
||||
.addClass('o_microsoft_sync_button oe_button btn btn-secondary')
|
||||
.prepend($('<img/>', {
|
||||
src: "/microsoft_calendar/static/src/img/calendar_outlook_32.png",
|
||||
}))
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.o_microsoft_sync_button {
|
||||
display: block;
|
||||
margin: auto;
|
||||
> img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.o_microsoft_sync.badge {
|
||||
border: none;
|
||||
}
|
||||
|
||||
img.calendar_img_tuto {
|
||||
margin: 0 0 10px 50px;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<field name="model">microsoft.calendar.account.reset</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<h1>Reset Microsoft Calendar Account</h1>
|
||||
<h1>Reset Outlook Calendar Account</h1>
|
||||
<group>
|
||||
<field name="delete_policy" widget="radio"/>
|
||||
<field name="sync_policy" widget="radio"/>
|
||||
|
||||
Reference in New Issue
Block a user