[REF] hr_holidays: refactor js code for time_off_calendar.*.js
task- 2643692 required customizing the calendar view to display a calendar from the employee form via the Time Off smart button. As the changes took place after the freeze of the saas-14.5 branch, it was not possible to split the time_off_calendar.js file into its different components to have them being re-used in time_off_calendar_employee.js file. Subsequently, some code duplication exists between the two files and makes it hard to maintain. This commit is for making the custom calendar components more modular and more maintainable. task-2661142 closes odoo/odoo#77767 Signed-off-by: Kevin Baptiste <kba@odoo.com>
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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',
|
||||
};
|
||||
},
|
||||
|
||||
});
|
||||
+33
@@ -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;
|
||||
},
|
||||
|
||||
});
|
||||
+13
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
@@ -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 = '';
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
Reference in New Issue
Block a user