diff --git a/addons/web/static/src/js/views/calendar/calendar_controller.js b/addons/web/static/src/js/views/calendar/calendar_controller.js index e496734ed5d..73a83fd26e2 100644 --- a/addons/web/static/src/js/views/calendar/calendar_controller.js +++ b/addons/web/static/src/js/views/calendar/calendar_controller.js @@ -10,6 +10,7 @@ odoo.define('web.CalendarController', function (require) { */ var AbstractController = require('web.AbstractController'); +var config = require('web.config'); var core = require('web.core'); var Dialog = require('web.Dialog'); var dialogs = require('web.view_dialogs'); @@ -23,8 +24,10 @@ var CalendarController = AbstractController.extend({ changeDate: '_onChangeDate', changeFilter: '_onChangeFilter', dropRecord: '_onDropRecord', + next: '_onNext', openCreate: '_onOpenCreate', openEvent: '_onOpenEvent', + prev: '_onPrev', quickCreate: '_onQuickCreate', toggleFullWidth: '_onToggleFullWidth', updateRecord: '_onUpdateRecord', @@ -73,15 +76,16 @@ var CalendarController = AbstractController.extend({ */ renderButtons: function ($node) { var self = this; - this.$buttons = $(QWeb.render("CalendarView.buttons", {'widget': this})); + this.$buttons = $(QWeb.render('CalendarView.buttons', { + isMobile: config.device.isMobile, + })); this.$buttons.on('click', 'button.o_calendar_button_new', function () { self.trigger_up('switch_view', {view_type: 'form'}); }); _.each(['prev', 'today', 'next'], function (action) { self.$buttons.on('click', '.o_calendar_button_' + action, function () { - self.model[action](); - self.reload(); + self._move(action); }); }); _.each(['day', 'week', 'month'], function (scale) { @@ -105,6 +109,18 @@ var CalendarController = AbstractController.extend({ //-------------------------------------------------------------------------- /** + * Move to the requested direction and reload the view + * + * @private + * @param {string} to either 'prev', 'next' or 'today' + * @returns {Deferred} + */ + _move: function (to) { + this.model[to](); + return this.reload(); + }, + /** + * @private * @param {Object} record * @param {integer} record.id * @returns {Deferred} @@ -156,6 +172,14 @@ var CalendarController = AbstractController.extend({ _onDropRecord: function (event) { this._updateRecord(event.data); }, + /** + * @private + * @param {OdooEvent} event + */ + _onNext: function (event) { + event.stopPropagation(); + this._move('next'); + }, /** * @private * @param {OdooEvent} event @@ -305,6 +329,15 @@ var CalendarController = AbstractController.extend({ }; open_dialog(true); }, + /** + * @private + * @param {OdooEvent} event + */ + _onPrev: function () { + event.stopPropagation(); + this._move('prev'); + }, + /** * Handles saving data coming from quick create box * @@ -364,8 +397,7 @@ var CalendarController = AbstractController.extend({ this.$buttons.find('.active').removeClass('active'); this.$buttons.find('.o_calendar_button_' + this.mode).addClass('active'); } - var subtitle = (this.mode === 'week' ? _t('Week ') : '') + event.data.title; - this.set({title: this.displayName + ' (' + subtitle + ')'}); + this.set({title: this.displayName + ' (' + event.data.title + ')'}); }, }); diff --git a/addons/web/static/src/js/views/calendar/calendar_model.js b/addons/web/static/src/js/views/calendar/calendar_model.js index 102407e533d..ca28e90713f 100644 --- a/addons/web/static/src/js/views/calendar/calendar_model.js +++ b/addons/web/static/src/js/views/calendar/calendar_model.js @@ -6,7 +6,6 @@ var Context = require('web.Context'); var core = require('web.core'); var fieldUtils = require('web.field_utils'); var session = require('web.session'); -var time = require('web.time'); var _t = core._t; @@ -400,12 +399,6 @@ return AbstractModel.extend({ weekNumbers: true, weekNumberTitle: _t("W"), allDayText: _t("All day"), - views: { - week: { - columnFormat: 'ddd ' + time.getLangDateFormat(), - titleFormat: time.getLangTimeFormat(), - } - }, monthNames: moment.months(), monthNamesShort: moment.monthsShort(), dayNames: moment.weekdays(), diff --git a/addons/web/static/src/js/views/calendar/calendar_renderer.js b/addons/web/static/src/js/views/calendar/calendar_renderer.js index b07ea293619..469130c723a 100644 --- a/addons/web/static/src/js/views/calendar/calendar_renderer.js +++ b/addons/web/static/src/js/views/calendar/calendar_renderer.js @@ -2,6 +2,7 @@ odoo.define('web.CalendarRenderer', function (require) { "use strict"; var AbstractRenderer = require('web.AbstractRenderer'); +var config = require('web.config'); var core = require('web.core'); var Dialog = require('web.Dialog'); var field_utils = require('web.field_utils'); @@ -192,6 +193,9 @@ return AbstractRenderer.extend({ start: function () { this._initSidebar(); this._initCalendar(); + if (config.device.isMobile) { + this._bindSwipe(); + } return this._super(); }, /** @@ -289,6 +293,27 @@ return AbstractRenderer.extend({ /** * @private + * Bind handlers to enable swipe navigation + * + * @private + */ + _bindSwipe: function () { + var self = this; + var touchStartX; + var touchEndX; + this.$calendar.on('touchstart', function (event) { + touchStartX = event.originalEvent.touches[0].pageX; + }); + this.$calendar.on('touchend', function (event) { + touchEndX = event.originalEvent.changedTouches[0].pageX; + if (touchStartX - touchEndX > 100) { + self.trigger_up('next'); + } else if (touchStartX - touchEndX < -100) { + self.trigger_up('prev'); + } + }); + }, + /** * @param {any} event * @returns {string} the html for the rendered event */ @@ -297,6 +322,7 @@ return AbstractRenderer.extend({ event: event, fields: this.state.fields, format: this._format.bind(this), + isMobile: config.device.isMobile, read_only_mode: this.read_only_mode, record: event.record, user_context: session.user_context, @@ -376,11 +402,9 @@ return AbstractRenderer.extend({ viewRender: function (view) { // compute mode from view.name which is either 'month', 'agendaWeek' or 'agendaDay' var mode = view.name === 'month' ? 'month' : (view.name === 'agendaWeek' ? 'week' : 'day'); - // compute title: in week mode, display the week number - var title = mode === 'week' ? view.intervalStart.week() : view.title; self.trigger_up('viewUpdated', { mode: mode, - title: title, + title: view.title, }); }, height: 'parent', diff --git a/addons/web/static/src/less/web_calendar.less b/addons/web/static/src/less/web_calendar.less index d6aab5e0e38..05c9a5d6b4a 100644 --- a/addons/web/static/src/less/web_calendar.less +++ b/addons/web/static/src/less/web_calendar.less @@ -66,9 +66,6 @@ } .fc-view { overflow-x: auto; - > table { - min-width: 600px; - } } } @@ -202,12 +199,6 @@ } } -@media only screen and (max-width: 768px) { - .o_calendar_container { - padding: 0; - } -} - .modal { .o_attendee_head { width: 32px; @@ -220,3 +211,31 @@ display: none; } } + +// Mobile rules +@media only screen and (max-width: 768px) { + .o_calendar_container { + padding: 0; + } +} +@media (max-width: @screen-xs-max) { + .o_control_panel { + .o_cp_left { + width: 100%; + .o_cp_buttons { + width: 100%; + .o_calendar_button_today { + float: right; + > .o_calendar_text { + margin-top: 3px; + } + } + } + } + } + .o_calendar_view { + .fc-day-header { + word-spacing: 1000px; // force line break in week mode + } + } +} diff --git a/addons/web/static/src/xml/web_calendar.xml b/addons/web/static/src/xml/web_calendar.xml index 6573a51ca4e..ae9250d79e9 100644 --- a/addons/web/static/src/xml/web_calendar.xml +++ b/addons/web/static/src/xml/web_calendar.xml @@ -20,9 +20,9 @@
- : + :
- + +
@@ -63,10 +63,17 @@
- - - - + + + + + + + + + + +
diff --git a/addons/web/static/tests/views/calendar_mobile_tests.js b/addons/web/static/tests/views/calendar_mobile_tests.js new file mode 100644 index 00000000000..8e973688107 --- /dev/null +++ b/addons/web/static/tests/views/calendar_mobile_tests.js @@ -0,0 +1,62 @@ +odoo.define('web.calendar_mobile_tests', function (require) { +"use strict"; + +var CalendarView = require('web.CalendarView'); +var testUtils = require('web.test_utils'); + +var createView = testUtils.createView; + +var initialDate = new Date(2016, 11, 12, 8, 0, 0); +initialDate = new Date(initialDate.getTime() - initialDate.getTimezoneOffset()*60*1000); + + +QUnit.module('Views', { + beforeEach: function () { + this.data = { + event: { + fields: { + id: {string: "ID", type: "integer"}, + name: {string: "name", type: "char"}, + start: {string: "start datetime", type: "datetime"}, + stop: {string: "stop datetime", type: "datetime"}, + }, + records: [ + {id: 1, name: "event 1", start: "2016-12-11 00:00:00", stop: "2016-12-11 00:00:00"}, + ], + check_access_rights: function () { + return $.when(true); + } + }, + }; + } +}, function () { + + QUnit.module('CalendarView Mobile'); + + QUnit.test('simple calendar rendering in mobile', function (assert) { + assert.expect(3); + + var calendar = createView({ + View: CalendarView, + model: 'event', + data: this.data, + arch: '' + + '' + + '', + viewOptions: { + initialDate: initialDate, + }, + }); + + assert.notOk(calendar.$buttons.find('.o_calendar_button_prev').is(':visible'), + "prev button should be hidden"); + assert.notOk(calendar.$buttons.find('.o_calendar_button_next').is(':visible'), + "next button should be hidden"); + assert.ok(calendar.$buttons.find('.o_calendar_button_today').is(':visible'), + "today button should be visible"); + + calendar.destroy(); + }); +}); + +}); diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js index d6af7b93f3f..604b8b5bcee 100644 --- a/addons/web/static/tests/views/calendar_tests.js +++ b/addons/web/static/tests/views/calendar_tests.js @@ -234,7 +234,7 @@ QUnit.module('Views', { // displays month mode by default assert.strictEqual(actionManager.controlPanel.$('.breadcrumb li').text(), - 'Meetings Test (Week 51)', "should display the current week"); + 'Meetings Test (Dec 11 – 17, 2016)', "should display the current week"); // switch to day mode actionManager.controlPanel.$('.o_calendar_button_day').click(); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index e81606f6608..9e713c51b36 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -543,6 +543,7 @@ +