diff --git a/addons/hr_holidays/__manifest__.py b/addons/hr_holidays/__manifest__.py index 76baca06f2d..584e0361868 100644 --- a/addons/hr_holidays/__manifest__.py +++ b/addons/hr_holidays/__manifest__.py @@ -65,8 +65,7 @@ A synchronization with an internal agenda (Meetings of the CRM module) is also p 'hr_holidays/static/src/models/*/*.js', ], 'web.assets_backend': [ - 'hr_holidays/static/src/js/time_off_calendar.js', - 'hr_holidays/static/src/js/time_off_calendar_employee.js', + 'hr_holidays/static/src/js/time_off_calendar/*.js', 'hr_holidays/static/src/js/radio_image.js', 'hr_holidays/static/src/js/leave_stats_widget.js', 'hr_holidays/static/src/models/*/*.js', diff --git a/addons/hr_holidays/static/src/js/time_off_calendar.js b/addons/hr_holidays/static/src/js/time_off_calendar.js deleted file mode 100644 index 967f893d72e..00000000000 --- a/addons/hr_holidays/static/src/js/time_off_calendar.js +++ /dev/null @@ -1,333 +0,0 @@ -odoo.define('hr_holidays.dashboard.view_custo', function(require) { - 'use strict'; - - var core = require('web.core'); - const config = require('web.config'); - var CalendarPopover = require('web.CalendarPopover'); - var CalendarController = require("web.CalendarController"); - var CalendarRenderer = require("web.CalendarRenderer"); - var CalendarModel = require("web.CalendarModel"); - var CalendarView = require("web.CalendarView"); - var dialogs = require('web.view_dialogs'); - var Dialog = require('web.Dialog'); - var viewRegistry = require('web.view_registry'); - - var _t = core._t; - var QWeb = core.qweb; - - var TimeOffCalendarPopover = CalendarPopover.extend({ - template: 'hr_holidays.calendar.popover', - - init: function (parent, eventInfo) { - this._super.apply(this, arguments); - const state = this.event.extendedProps.record.state; - this.canDelete = state && ['validate', 'refuse'].indexOf(state) === -1; - this.canEdit = state !== undefined; - this.displayFields = []; - - if (this.modelName === "hr.leave.report.calendar") { - const duration = this.event.extendedProps.record.display_name.split(':').slice(-1); - this.display_name = _.str.sprintf(_t("Time Off : %s"), duration); - } else { - this.display_name = this.event.extendedProps.record.display_name; - } - }, - }); - - var TimeOffCalendarController = CalendarController.extend({ - events: _.extend({}, CalendarController.prototype.events, { - 'click .btn-time-off': '_onNewTimeOff', - 'click .btn-allocation': '_onNewAllocation', - }), - - /** - * @override - */ - start: function () { - this.$el.addClass('o_timeoff_calendar'); - return this._super(...arguments); - }, - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - /** - * Render the buttons and add new button about - * time off and allocations request - * - * @override - */ - - renderButtons: function ($node) { - this._super.apply(this, arguments); - - $(QWeb.render('hr_holidays.dashboard.calendar.button', { - time_off: _t('New Time Off'), - request: _t('Allocation Request'), - })).appendTo(this.$buttons); - - if ($node) { - this.$buttons.appendTo($node); - } else { - this.$('.o_calendar_buttons').replaceWith(this.$buttons); - } - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - */ - _getFormDialogOptions(self, event) { - var options = this._super(self, event); - // Get the time off data from the event - var timeoffData = event.target.state.data.filter((timeOff) => timeOff.id === parseInt(event.data._id)); - // Take the record associated to the timeoffData and read its state to hide or not the Delete button - var timeoffState = timeoffData[0].record.state; - if(timeoffState && ['validate', 'refuse'].indexOf(timeoffState) === -1) { - options.deletable = true; - options.removeButtonText = _t("Delete"); - options.on_remove = function() { - Dialog.confirm(self, _t("Are you sure you want to delete this record ?"), { - confirm_callback: function () { - self.model.deleteRecords(self._getEventId(event), self.modelName).then(function () { - self.reload(); - }); - } - }); - }; - } - return options; - }, - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * Action: create a new time off request - * - * @private - */ - _onNewTimeOff: function () { - let self = this; - - let domain = [ - ['name', '=', 'hr.leave.view.form.dashboard.new.time.off'], - ['model', '=', 'hr.leave'] - ]; - - self._rpc({ - model: 'ir.ui.view', - method: 'search', - args: [domain], - }).then(function(ids) { - self.timeOffDialog = new dialogs.FormViewDialog(self, { - res_model: "hr.leave", - view_id: ids, - context: { - 'default_date_from': moment().format('YYYY-MM-DD'), - 'default_date_to': moment().add(1, 'days').format('YYYY-MM-DD'), - }, - title: _t("New time off"), - disable_multiple_selection: true, - on_saved: function() { - self.reload(); - }, - }); - self.timeOffDialog.open(); - }); - }, - - /** - * Action: create a new allocation request - * - * @private - */ - _onNewAllocation: function () { - let self = this; - - let domain = [ - ['name', '=', 'hr.leave.view.form.dashboard'], - ['model', '=', 'hr.leave.allocation'] - ]; - - self._rpc({ - model: 'ir.ui.view', - method: 'search', - args: [domain], - }).then(function(ids) { - self.allocationDialog = new dialogs.FormViewDialog(self, { - res_model: "hr.leave.allocation", - view_id: ids, - context: { - 'default_employee_ids': self.context.employee_id, - 'default_state': 'confirm', - }, - title: _t("New Allocation"), - disable_multiple_selection: true, - on_saved: function() { - self.reload(); - }, - }); - self.allocationDialog.open(); - }); - }, - - _onOpenCreate: function() { - var self = this; - this._super(...arguments); - if(this.previousOpen) { - this.previousOpen.on('closed', this, function(ev){ - // we reload as record can be created or modified (sent, unpublished, ...) - self.reload(); - }); - } - }, - - /** - * @override - */ - _setEventTitle: function () { - return _t('Time Off Request'); - }, - }); - - var TimeOffPopoverRenderer = CalendarRenderer.extend({ - template: "TimeOff.CalendarView.extend", - /** - * We're overriding this to display the weeknumbers on the year view - * - * @override - * @private - */ - _getFullCalendarOptions: function () { - const oldOptions = this._super(...arguments); - // Parameters - oldOptions.views.dayGridYear.weekNumbers = true; - oldOptions.views.dayGridYear.weekNumbersWithinDays = false; - return oldOptions; - }, - - config: _.extend({}, CalendarRenderer.prototype.config, { - CalendarPopover: TimeOffCalendarPopover, - }), - - _getPopoverParams: function (eventData) { - let params = this._super.apply(this, arguments); - let calendarIcon; - let state = eventData.extendedProps.record.state; - - if (state === 'validate') { - calendarIcon = 'fa-calendar-check-o'; - } else if (state === 'refuse') { - calendarIcon = 'fa-calendar-times-o'; - } else if(state) { - calendarIcon = 'fa-calendar-o'; - } - - params['title'] = eventData.extendedProps.record.display_name.split(':').slice(0, -1).join(':'); - params['template'] = QWeb.render('hr_holidays.calendar.popover.placeholder', {color: this.getColor(eventData.color_index), calendarIcon: calendarIcon}); - return params; - }, - - _render: function () { - var self = this; - return this._super.apply(this, arguments).then(function () { - self.$el.parent().find('.o_calendar_mini').hide(); - }); - }, - /** - * @override - * @private - */ - _renderCalendar: function() { - this._super.apply(this, arguments); - let weekNumbers = this.$el.find('.fc-week-number'); - weekNumbers.each( function() { - let weekRow = this.parentNode; - // By default, each month has 6 weeks displayed, hide the week number if there is no days for the week - if(!weekRow.children[1].classList.length && !weekRow.children[weekRow.children.length-1].classList.length) { - this.innerHTML = ''; - } - }); - }, - }); - - var TimeOffCalendarRenderer = TimeOffPopoverRenderer.extend({ - _render: function () { - var self = this; - return this._super.apply(this, arguments).then(function () { - return self._rpc({ - model: 'hr.leave.type', - method: 'get_days_all_request', - context: self.state.context, - }); - }).then(function (result) { - self.$el.parent().find('.o_calendar_mini').hide(); - self.$el.parent().find('.o_timeoff_container').remove(); - - // Do not display header if there is no element to display - if (result.length > 0) { - if (config.device.isMobile) { - result.forEach((data) => { - const elem = QWeb.render('hr_holidays.dashboard_calendar_header_mobile', { - timeoff: data, - }); - self.$el.find('.o_calendar_filter_item[data-value=' + data[4] + '] .o_cw_filter_title').append(elem); - }); - } else { - const elem = QWeb.render('hr_holidays.dashboard_calendar_header', { - timeoffs: result, - }); - self.$el.before(elem); - - //add popover to the information tags - _.each(self.$el.parent().find('.fa-question-circle-o'), function(popup){ - $(popup).popover({ - trigger: 'hover', - html: true, - delay: {show: 300, hide: 0}, - content: function () { - var data = { - allocated: popup.dataset.allocated, - approved: popup.dataset.approved, - planned: popup.dataset.planned, - left: popup.dataset.left - }; - var elem_popover = QWeb.render('hr_holidays.dashboard_calendar_header_leave_type_popover', { - data: data, - }); - return elem_popover - }, - }); - }); - } - } - }); - }, - }); - var TimeOffCalendarView = CalendarView.extend({ - config: _.extend({}, CalendarView.prototype.config, { - Controller: TimeOffCalendarController, - Renderer: TimeOffCalendarRenderer, - Model: CalendarModel, - }), - }); - - /** - * Calendar shown in the "Everyone" menu - */ - var TimeOffCalendarAllView = CalendarView.extend({ - config: _.extend({}, CalendarView.prototype.config, { - Controller: TimeOffCalendarController, - Renderer: TimeOffPopoverRenderer, - }), - }); - - viewRegistry.add('time_off_calendar', TimeOffCalendarView); - viewRegistry.add('time_off_calendar_all', TimeOffCalendarAllView); -}); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js new file mode 100644 index 00000000000..f80157c349d --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js @@ -0,0 +1,167 @@ +/** @odoo-module **/ + +import { _t, qweb as QWeb } from "web.core"; +import CalendarController from "web.CalendarController"; +import dialogs from "web.view_dialogs"; +import Dialog from "web.Dialog"; + +export const TimeOffCalendarController = CalendarController.extend({ + events: Object.assign({}, CalendarController.prototype.events, { + 'click .btn-time-off': '_onNewTimeOff', + 'click .btn-allocation': '_onNewAllocation', + }), + + /** + * @override + */ + start() { + this.$el.addClass('o_timeoff_calendar'); + return this._super(...arguments); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * Render the buttons and add new button about + * time off and allocations request + * + * @override + */ + renderButtons($node) { + this._super(...arguments); + + $(QWeb.render('hr_holidays.dashboard.calendar.button', { + time_off: _t('New Time Off'), + request: this._getAllocationButtonTitle(), + })).appendTo(this.$buttons); + + if ($node) { + this.$buttons.appendTo($node); + } else { + this.$('.o_calendar_buttons').replaceWith(this.$buttons); + } + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @override + */ + _getFormDialogOptions(self, event) { + const options = this._super(...arguments); + const eventId = parseInt(event.data._id) + // Get the time off data from the event + const timeoffData = event.target.state.data.find((timeOff) => timeOff.id === eventId); + // Take the record associated to the timeoffData and read its state to hide or not the Delete button + const timeoffState = timeoffData && timeoffData.record.state; + if(timeoffState && !['validate', 'refuse'].includes(timeoffState)) { + options.deletable = true; + options.removeButtonText = _t("Delete"); + options.on_remove = () => { + Dialog.confirm(self, _t("Are you sure you want to delete this record ?"), { + confirm_callback: () => { + self.model.deleteRecords(self._getEventId(event), self.modelName).then(() => { + self.reload(); + }); + } + }); + }; + } + return options; + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Action: create a new time off request + * + * @private + */ + async _onNewTimeOff() { + const viewId = await this._rpc({ + model: 'ir.ui.view', + method: 'get_view_id', + args: ['hr_holidays.hr_leave_view_form_dashboard_new_time_off'], + }); + + this.timeOffDialog = new dialogs.FormViewDialog(this, { + res_model: "hr.leave", + view_id: viewId, + context: this._getTimeOffContext(), + title: _t("New time off"), + disable_multiple_selection: true, + on_saved: () => this.reload() + }); + this.timeOffDialog.open(); + }, + + /** + * Action: create a new allocation request + * + * @private + */ + async _onNewAllocation() { + const viewXmlId = this._getFormViewId(); + + const viewId = await this._rpc({ + model: 'ir.ui.view', + method: 'get_view_id', + args: [viewXmlId], + }); + + this.allocationDialog = new dialogs.FormViewDialog(this, { + res_model: "hr.leave.allocation", + view_id: viewId, + context: this._getAllocationContext(), + title: _t("New Allocation"), + disable_multiple_selection: true, + on_saved: () => this.reload() + }); + this.allocationDialog.open(); + }, + + _onOpenCreate() { + this._super(...arguments); + if(this.previousOpen) { + this.previousOpen.on('closed', this, (ev) => { + // we reload as record can be created or modified (sent, unpublished, ...) + this.reload(); + }); + } + }, + + /** + * @override + */ + _setEventTitle() { + return _t('Time Off Request'); + }, + + _getAllocationButtonTitle() { + return _t('Allocation Request'); + }, + + _getFormViewId() { + return 'hr_holidays.hr_leave_allocation_view_form_dashboard'; + }, + + _getTimeOffContext() { + return { + 'default_date_from': moment().format('YYYY-MM-DD'), + 'default_date_to': moment().add(1, 'days').format('YYYY-MM-DD'), + }; + }, + + _getAllocationContext() { + return { + 'default_state': 'confirm', + }; + }, + +}); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_employee_controller.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_employee_controller.js new file mode 100644 index 00000000000..663d47959c3 --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_employee_controller.js @@ -0,0 +1,33 @@ +/** @odoo-module **/ + +import { _t } from "web.core"; +import { TimeOffCalendarController } from "./time_off_calendar_controller"; + +export const TimeOffCalendarEmployeeController = TimeOffCalendarController.extend({ + + _onOpenCreate() { + this.context['default_employee_id'] = this.context.employee_id[0]; + this._super(...arguments); + }, + + _getAllocationButtonTitle() { + return _t('New Allocation Request'); + }, + + _getFormViewId() { + return 'hr_holidays.hr_leave_allocation_view_form_manager_dashboard'; + }, + + _getTimeOffContext() { + const context = this._super(...arguments); + context.default_employee_id = this.context.employee_id[0]; + return context; + }, + + _getAllocationContext() { + const context = this._super(...arguments); + context.default_employee_ids = this.context.employee_id; + return context; + }, + +}); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_employee_views.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_employee_views.js new file mode 100644 index 00000000000..6eb95dcc328 --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_employee_views.js @@ -0,0 +1,13 @@ +/** @odoo-module **/ + +import { TimeOffCalendarEmployeeController } from "./time_off_calendar_employee_controller"; +import { TimeOffCalendarView } from "./time_off_calendar_views"; +import viewRegistry from 'web.view_registry'; + +export const TimeOffCalendarEmployeeView = TimeOffCalendarView.extend({ + config: Object.assign({}, TimeOffCalendarView.prototype.config, { + Controller: TimeOffCalendarEmployeeController, + }), +}); + +viewRegistry.add('time_off_employee_calendar', TimeOffCalendarEmployeeView); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_popover.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_popover.js new file mode 100644 index 00000000000..89d4082f8a3 --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_popover.js @@ -0,0 +1,23 @@ +/** @odoo-module **/ + +import { _t } from 'web.core'; +import CalendarPopover from 'web.CalendarPopover'; + +export const TimeOffCalendarPopover = CalendarPopover.extend({ + template: 'hr_holidays.calendar.popover', + + init(parent, eventInfo) { + this._super(...arguments); + const state = this.event.extendedProps.record.state; + this.canDelete = state && ['validate', 'refuse'].includes(state); + this.canEdit = state !== undefined; + this.displayFields = []; + + if (this.modelName === "hr.leave.report.calendar") { + const duration = this.event.extendedProps.record.display_name.split(':').slice(-1); + this.display_name = _.str.sprintf(_t("Time Off : %s"), duration); + } else { + this.display_name = this.event.extendedProps.record.display_name; + } + }, +}); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_renderer.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_renderer.js new file mode 100644 index 00000000000..cf1634bb338 --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_renderer.js @@ -0,0 +1,58 @@ +/** @odoo-module **/ + +import { qweb as QWeb } from 'web.core'; +import config from 'web.config'; + +import { TimeOffPopoverRenderer } from "./time_off_popover_renderer"; + +export const TimeOffCalendarRenderer = TimeOffPopoverRenderer.extend({ + async _render () { + await this._super(...arguments); + const result = await this._rpc({ + model: 'hr.leave.type', + method: 'get_days_all_request', + context: this.state.context, + }); + + this.$el.parent().find('.o_calendar_mini').hide(); + this.$el.parent().find('.o_timeoff_container').remove(); + + // Do not display header if there is no element to display + if (result.length > 0) { + if (config.device.isMobile) { + result.forEach((data) => { + const elem = QWeb.render('hr_holidays.dashboard_calendar_header_mobile', { + timeoff: data, + }); + this.$el.find('.o_calendar_filter_item[data-value=' + data[4] + '] .o_cw_filter_title').append(elem); + }); + } else { + const elem = QWeb.render('hr_holidays.dashboard_calendar_header', { + timeoffs: result, + }); + this.$el.before(elem); + + //add popover to the information tags + [...this.$el.parent().find('.fa-question-circle-o')].forEach((popup) => { + $(popup).popover({ + trigger: 'hover', + html: true, + delay: {show: 300, hide: 0}, + content() { + const data = { + allocated: popup.dataset.allocated, + approved: popup.dataset.approved, + planned: popup.dataset.planned, + left: popup.dataset.left + }; + const elem_popover = QWeb.render('hr_holidays.dashboard_calendar_header_leave_type_popover', { + data: data, + }); + return elem_popover + }, + }); + }); + } + } + }, +}); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_views.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_views.js new file mode 100644 index 00000000000..252ff02766c --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_views.js @@ -0,0 +1,27 @@ +/** @odoo-module **/ + +import CalendarView from "web.CalendarView"; +import { TimeOffCalendarController } from "./time_off_calendar_controller"; +import { TimeOffCalendarRenderer } from "./time_off_calendar_renderer"; +import { TimeOffPopoverRenderer } from "./time_off_popover_renderer"; +import viewRegistry from 'web.view_registry'; + +export const TimeOffCalendarView = CalendarView.extend({ + config: Object.assign({}, CalendarView.prototype.config, { + Controller: TimeOffCalendarController, + Renderer: TimeOffCalendarRenderer, + }), +}); + +/** + * Calendar shown in the "Everyone" menu + */ +export const TimeOffCalendarAllView = CalendarView.extend({ + config: Object.assign({}, CalendarView.prototype.config, { + Controller: TimeOffCalendarController, + Renderer: TimeOffPopoverRenderer, + }), +}); + +viewRegistry.add('time_off_calendar', TimeOffCalendarView); +viewRegistry.add('time_off_calendar_all', TimeOffCalendarAllView); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_popover_renderer.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_popover_renderer.js new file mode 100644 index 00000000000..1465ad4409d --- /dev/null +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_popover_renderer.js @@ -0,0 +1,70 @@ +/** @odoo-module **/ + +import { qweb as QWeb }from 'web.core'; +import config from 'web.config'; +import CalendarRenderer from "web.CalendarRenderer"; +import { TimeOffCalendarPopover } from "./time_off_calendar_popover"; + +export const TimeOffPopoverRenderer = CalendarRenderer.extend({ + template: "TimeOff.CalendarView.extend", + /** + * We're overriding this to display the weeknumbers on the year view + * + * @override + * @private + */ + _getFullCalendarOptions() { + const oldOptions = this._super(...arguments); + // Parameters + oldOptions.views.dayGridYear.weekNumbers = true; + oldOptions.views.dayGridYear.weekNumbersWithinDays = false; + return oldOptions; + }, + + config: Object.assign({}, CalendarRenderer.prototype.config, { + CalendarPopover: TimeOffCalendarPopover, + }), + + _getPopoverParams(eventData) { + const params = this._super(...arguments); + let calendarIcon; + const state = eventData.extendedProps.record.state; + + if (state === 'validate') { + calendarIcon = 'fa-calendar-check-o'; + } else if (state === 'refuse') { + calendarIcon = 'fa-calendar-times-o'; + } else if(state) { + calendarIcon = 'fa-calendar-o'; + } + + params.title = eventData.extendedProps.record.display_name.split(':').slice(0, -1).join(':'); + params.template = QWeb.render('hr_holidays.calendar.popover.placeholder', { + color: this.getColor(eventData.color_index), + calendarIcon: calendarIcon, + }); + return params; + }, + + _render() { + return this._super.apply(this, arguments).then(() => { + this.$el.parent().find('.o_calendar_mini').hide(); + }); + }, + /** + * @override + * @private + */ + _renderCalendar() { + this._super(...arguments); + const weekNumbers = this.$el.find('.fc-week-number'); + weekNumbers.each( function() { + const weekRow = this.parentNode; + // By default, each month has 6 weeks displayed, hide the week number if there is no days for the week + if (!weekRow.children[1].classList.length && + !weekRow.children[weekRow.children.length - 1].classList.length) { + this.innerHTML = ''; + } + }); + }, +}); diff --git a/addons/hr_holidays/static/src/js/time_off_calendar_employee.js b/addons/hr_holidays/static/src/js/time_off_calendar_employee.js deleted file mode 100644 index 3aa71c6c367..00000000000 --- a/addons/hr_holidays/static/src/js/time_off_calendar_employee.js +++ /dev/null @@ -1,266 +0,0 @@ -odoo.define('hr_holidays.employee.dashboard.views', function(require) { - 'use strict'; - - var core = require('web.core'); - const config = require('web.config'); - var CalendarController = require("web.CalendarController"); - var CalendarRenderer = require("web.CalendarRenderer"); - var CalendarPopover = require('web.CalendarPopover'); - var CalendarView = require("web.CalendarView"); - var dialogs = require('web.view_dialogs'); - var viewRegistry = require('web.view_registry'); - - var _t = core._t; - var QWeb = core.qweb; - - // TODO in master: Split the timeoff calendar components into several files to reuse or extend them here - - var TimeOffCalendarPopover = CalendarPopover.extend({ - template: 'hr_holidays.calendar.popover', - - init: function (parent, eventInfo) { - this._super.apply(this, arguments); - const state = this.event.extendedProps.record.state; - this.canDelete = state && ['validate', 'refuse'].indexOf(state) === -1; - this.canEdit = state !== undefined; - this.displayFields = []; - - if (this.modelName === "hr.leave.report.calendar") { - const duration = this.event.extendedProps.record.display_name.split(':').slice(-1); - this.display_name = _.str.sprintf(_t("Time Off : %s"), duration); - } else { - this.display_name = this.event.extendedProps.record.display_name; - } - }, - }); - - var TimeOffPopoverRenderer = CalendarRenderer.extend({ - template: "TimeOff.CalendarView.extend", - /** - * We're overriding this to display the weeknumbers on the year view - * - * @override - * @private - */ - _getFullCalendarOptions: function () { - const oldOptions = this._super(...arguments); - // Parameters - oldOptions.views.dayGridYear.weekNumbers = true; - oldOptions.views.dayGridYear.weekNumbersWithinDays = false; - return oldOptions; - }, - - config: _.extend({}, CalendarRenderer.prototype.config, { - CalendarPopover: TimeOffCalendarPopover, - }), - - _getPopoverParams: function (eventData) { - let params = this._super.apply(this, arguments); - let calendarIcon; - let state = eventData.extendedProps.record.state; - - if (state === 'validate') { - calendarIcon = 'fa-calendar-check-o'; - } else if (state === 'refuse') { - calendarIcon = 'fa-calendar-times-o'; - } else if(state) { - calendarIcon = 'fa-calendar-o'; - } - - params['title'] = eventData.extendedProps.record.display_name.split(':').slice(0, -1).join(':'); - params['template'] = QWeb.render('hr_holidays.calendar.popover.placeholder', {color: this.getColor(eventData.color_index), calendarIcon: calendarIcon}); - return params; - }, - - _render: function () { - var self = this; - return this._super.apply(this, arguments).then(function () { - self.$el.parent().find('.o_calendar_mini').hide(); - }); - }, - /** - * @override - * @private - */ - _renderCalendar: function() { - this._super.apply(this, arguments); - let weekNumbers = this.$el.find('.fc-week-number'); - weekNumbers.each( function() { - let weekRow = this.parentNode; - // By default, each month has 6 weeks displayed, hide the week number if there is no days for the week - if(!weekRow.children[1].classList.length && !weekRow.children[weekRow.children.length-1].classList.length) { - this.innerHTML = ''; - } - }); - }, - }); - - var TimeOffCalendarRenderer = TimeOffPopoverRenderer.extend({ - _render: function () { - var self = this; - return this._super.apply(this, arguments).then(function () { - return self._rpc({ - model: 'hr.leave.type', - method: 'get_days_all_request', - context: self.state.context, - }); - }).then(function (result) { - self.$el.parent().find('.o_calendar_mini').hide(); - self.$el.parent().find('.o_timeoff_container').remove(); - - // Do not display header if there is no element to display - if (result.length > 0) { - if (config.device.isMobile) { - result.forEach((data) => { - const elem = QWeb.render('hr_holidays.dashboard_calendar_header_mobile', { - timeoff: data, - }); - self.$el.find('.o_calendar_filter_item[data-value=' + data[4] + '] .o_cw_filter_title').append(elem); - }); - } else { - const elem = QWeb.render('hr_holidays.dashboard_calendar_header', { - timeoffs: result, - }); - self.$el.before(elem); - } - } - }); - }, - }); - - var TimeOffCalendarEmployeeController = CalendarController.extend({ - - events: _.extend({}, CalendarController.prototype.events, { - 'click .btn-time-off': '_onNewTimeOff', - 'click .btn-allocation': '_onNewAllocation', - }), - - /** - * @override - */ - start: function () { - this.$el.addClass('o_timeoff_calendar'); - return this._super(...arguments); - }, - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - /** - * Render the buttons and add new button about - * time off and allocations request - * - * @override - */ - - renderButtons: function ($node) { - this._super.apply(this, arguments); - - $(QWeb.render('hr_holidays.dashboard.calendar.button', { - time_off: _t('New Time Off'), - request: _t('New Allocation Request'), - })).appendTo(this.$buttons); - - if ($node) { - this.$buttons.appendTo($node); - } else { - this.$('.o_calendar_buttons').replaceWith(this.$buttons); - } - }, - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * Action: create a new time off request - * - * @private - */ - _onNewTimeOff: function () { - let self = this; - - let domain = [ - ['name', '=', 'hr.leave.view.form.dashboard.new.time.off'] - ]; - - self._rpc({ - model: 'ir.ui.view', - method: 'search', - args: [domain], - }).then(function(ids) { - self.timeOffDialog = new dialogs.FormViewDialog(self, { - res_model: "hr.leave", - view_id: ids, - context: { - 'default_employee_id': self.context.employee_id[0], - 'default_date_from': moment().format('YYYY-MM-DD'), - 'default_date_to': moment().add(1, 'days').format('YYYY-MM-DD'), - }, - title: _t("New time off"), - disable_multiple_selection: true, - on_saved: function() { - self.reload(); - }, - }); - self.timeOffDialog.open(); - }); - }, - - /** - * Action: create a new allocation request - * - * @private - */ - _onNewAllocation: function () { - let self = this; - - let domain = [ - ['name', '=', 'hr.leave.allocation.view.form.manager.dashboard'] - ]; - - self._rpc({ - model: 'ir.ui.view', - method: 'search', - args: [domain], - }).then(function(ids) { - self.allocationDialog = new dialogs.FormViewDialog(self, { - res_model: "hr.leave.allocation", - view_id: ids, - context: { - 'default_employee_ids': self.context.employee_id, - 'default_state': 'confirm', - }, - title: _t("New Allocation"), - disable_multiple_selection: true, - on_saved: function() { - self.reload(); - }, - }); - self.allocationDialog.open(); - }); - }, - - _onOpenCreate: function () { - this.context['default_employee_id'] = this.context.employee_id[0]; - this._super(...arguments); - }, - - /** - * @override - */ - _setEventTitle: function () { - return _t('Time Off Request'); - }, - }); - - var TimeOffCalendarEmployeeView = CalendarView.extend({ - config: _.extend({}, CalendarView.prototype.config, { - Controller: TimeOffCalendarEmployeeController, - Renderer: TimeOffCalendarRenderer, - }), - }); - - viewRegistry.add('time_off_employee_calendar', TimeOffCalendarEmployeeView); -});