[IMP] hr: migrate widgets/views to Owl
This commit is contained in:
committed by
Yannick Tivisse
parent
30f520a494
commit
6d9ec56bd1
@@ -56,13 +56,10 @@
|
||||
'hr/static/src/views/**/*.js',
|
||||
'hr/static/src/components/**/*.js',
|
||||
'hr/static/src/components/**/*.scss',
|
||||
'hr/static/src/user_menu/*.js',
|
||||
'hr/static/src/scss/hr.scss',
|
||||
'hr/static/src/js/chat_mixin.js',
|
||||
'hr/static/src/js/hr_employee.js',
|
||||
'hr/static/src/js/language.js',
|
||||
'hr/static/src/js/m2x_avatar_employee.js',
|
||||
'hr/static/src/js/standalone_m2o_avatar_employee.js',
|
||||
'hr/static/src/js/user_menu.js',
|
||||
'hr/static/src/js/work_permit_upload.js',
|
||||
],
|
||||
'web.assets_qweb': [
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
odoo.define('hr.chat_mixin', function (require) {
|
||||
"use strict";
|
||||
|
||||
const { Component } = owl;
|
||||
|
||||
// CHAT MIXIN
|
||||
const ChatMixin = {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_render: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
var $chat_button = self.$el.find('.o_employee_chat_btn');
|
||||
$chat_button.off('click').on('click', self._onOpenChat.bind(self));
|
||||
});
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
if (this.$el) {
|
||||
this.$el.find('.o_employee_chat_btn').off('click');
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
|
||||
async _onOpenChat(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopImmediatePropagation();
|
||||
const messaging = await Component.env.services.messaging.get();
|
||||
messaging.openChat({ employeeId: this.state.data.id });
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
return ChatMixin;
|
||||
});
|
||||
@@ -1,136 +0,0 @@
|
||||
odoo.define('hr.employee_chat', function (require) {
|
||||
'use strict';
|
||||
var viewRegistry = require('web.view_registry');
|
||||
|
||||
var FormController = require('web.FormController');
|
||||
var FormView = require('web.FormView');
|
||||
var FormRenderer = require('web.FormRenderer');
|
||||
|
||||
const ListController = require('web.ListController');
|
||||
const ListView = require('web.ListView');
|
||||
|
||||
const ChatMixin = require('hr.chat_mixin');
|
||||
|
||||
|
||||
const core = require('web.core');
|
||||
const _t = core._t;
|
||||
|
||||
// USAGE OF CHAT MIXIN IN FORM VIEWS
|
||||
var EmployeeFormRenderer = FormRenderer.extend(ChatMixin);
|
||||
|
||||
const EmployeeArchiveMixin = {
|
||||
_getArchiveAction: function (id) {
|
||||
return {
|
||||
type: 'ir.actions.act_window',
|
||||
name: _t('Employee Termination'),
|
||||
res_model: 'hr.departure.wizard',
|
||||
views: [[false, 'form']],
|
||||
view_mode: 'form',
|
||||
target: 'new',
|
||||
context: {
|
||||
'active_id': id,
|
||||
'toggle_active': true,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const EmployeeFormController = FormController.extend(EmployeeArchiveMixin, {
|
||||
/**
|
||||
* Override the archive action to directly open the departure wizard
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_getActionMenuItems: function (state) {
|
||||
let self = this;
|
||||
let actionMenuItems = this._super(...arguments);
|
||||
const activeField = this.model.getActiveField(state);
|
||||
if (actionMenuItems != null && this.archiveEnabled && activeField in state.data) {
|
||||
//This might break in future version, don't see a better way however
|
||||
let archiveString = _t("Archive");
|
||||
let archiveMenuItem = actionMenuItems.items.other.find(item => {return (item.description === archiveString)});
|
||||
if (archiveMenuItem) {
|
||||
archiveMenuItem.callback = () => {self.do_action(
|
||||
self._getArchiveAction(self.model.localIdsToResIds([this.handle])[0]), {
|
||||
on_close: function () {
|
||||
self.update({}, {reload: true});
|
||||
}
|
||||
})}
|
||||
}
|
||||
}
|
||||
return actionMenuItems;
|
||||
}
|
||||
})
|
||||
|
||||
var EmployeeFormView = FormView.extend({
|
||||
config: _.extend({}, FormView.prototype.config, {
|
||||
Controller: EmployeeFormController,
|
||||
Renderer: EmployeeFormRenderer
|
||||
}),
|
||||
});
|
||||
|
||||
viewRegistry.add('hr_employee_form', EmployeeFormView);
|
||||
|
||||
const EmployeeListController = ListController.extend(EmployeeArchiveMixin, {
|
||||
/**
|
||||
* Override the archive action to directly open the departure wizard
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_getActionMenuItems: function (state) {
|
||||
let self = this;
|
||||
let actionMenuItems = this._super(...arguments);
|
||||
if (actionMenuItems != null && this.archiveEnabled) {
|
||||
//This might break in future version, don't see a better way however
|
||||
let archiveString = _t("Archive");
|
||||
let archiveMenuItem = actionMenuItems.items.other.find(item => {return (item.description === archiveString)});
|
||||
if (archiveMenuItem) {
|
||||
//On this one we want the default action when multiple are selected
|
||||
let originalCallback = archiveMenuItem.callback;
|
||||
archiveMenuItem.callback = () => {
|
||||
let records = self.getSelectedRecords()
|
||||
if (records.length == 1 && records[0].data.active === true) {
|
||||
self.do_action(
|
||||
self._getArchiveAction(records[0].res_id), {
|
||||
on_close: function () {
|
||||
self.update({}, {reload: true});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
originalCallback();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return actionMenuItems;
|
||||
},
|
||||
|
||||
/**
|
||||
* When we run Launch Plan list action, in case if we close the
|
||||
* wizzard, the originally selected employees stay selected.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
async _executeButtonAction(actionData, recordData) {
|
||||
const prom = new Promise((resolve, reject) => {
|
||||
this.trigger_up('execute_action', {
|
||||
action_data: actionData,
|
||||
env: recordData,
|
||||
on_closed: () => this.isDestroyed() || actionData.context['action_plan'] ? Promise.resolve() : this.reload(),
|
||||
on_success: resolve,
|
||||
on_fail: () => this.update({}, { keepSelection: true, reload: false }).then(reject).guardedCatch(reject)
|
||||
});
|
||||
});
|
||||
return this.alive(prom);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const EmployeeListView = ListView.extend({
|
||||
config: _.extend({}, ListView.prototype.config, {
|
||||
Controller: EmployeeListController,
|
||||
})
|
||||
})
|
||||
|
||||
viewRegistry.add('hr_employee_list', EmployeeListView);
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import FormController from 'web.FormController';
|
||||
import FormView from 'web.FormView';
|
||||
import viewRegistry from 'web.view_registry';
|
||||
|
||||
var EmployeeFormController = FormController.extend({
|
||||
saveRecord: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
if (arguments[0].indexOf('lang') >= 0) {
|
||||
self.do_action('reload_context');
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
var EmployeeProfileFormView = FormView.extend({
|
||||
config: _.extend({}, FormView.prototype.config, {
|
||||
Controller: EmployeeFormController,
|
||||
}),
|
||||
});
|
||||
|
||||
viewRegistry.add('hr_employee_profile_form', EmployeeProfileFormView);
|
||||
export default EmployeeProfileFormView;
|
||||
@@ -0,0 +1,18 @@
|
||||
/** @odoo-module */
|
||||
|
||||
export const ArchiveEmployeeMixin = {
|
||||
_openArchiveEmployee(id) {
|
||||
return {
|
||||
type: 'ir.actions.act_window',
|
||||
name: this.env._t('Employee Termination'),
|
||||
res_model: 'hr.departure.wizard',
|
||||
views: [[false, 'form']],
|
||||
view_mode: 'form',
|
||||
target: 'new',
|
||||
context: {
|
||||
'active_id': id,
|
||||
'toggle_active': true,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
|
||||
import { formView } from '@web/views/form/form_view';
|
||||
import { FormController } from '@web/views/form/form_controller';
|
||||
import { FormRenderer } from '@web/views/form/form_renderer';
|
||||
|
||||
import { ArchiveEmployeeMixin } from '../mixins/archive_employee_mixin';
|
||||
import { EmployeeChatMixin } from '../mixins/chat_mixin';
|
||||
|
||||
export class EmployeeFormController extends FormController {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.actionService = useService('action');
|
||||
}
|
||||
|
||||
getActionMenuItems() {
|
||||
const menuItems = super.getActionMenuItems();
|
||||
if (!this.archiveEnabled || !this.model.root.isActive) {
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
const archiveAction = menuItems.other.find((item) => item.key === "archive");
|
||||
if (archiveAction) {
|
||||
archiveAction.callback = () => {
|
||||
const archiveAction = this._openArchiveEmployee(this.model.root.resId);
|
||||
this.actionService.doAction(archiveAction, {
|
||||
onClose: async () => {
|
||||
await this.model.load();
|
||||
this.model.notify();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
return menuItems;
|
||||
}
|
||||
}
|
||||
patch(EmployeeFormController.prototype, 'employee_form_controller_archive_mixin', ArchiveEmployeeMixin);
|
||||
|
||||
export class EmployeeFormRenderer extends FormRenderer {}
|
||||
patch(EmployeeFormRenderer.prototype, 'employee_form_renderer_mixin', EmployeeChatMixin);
|
||||
|
||||
registry.category('views').add('hr_employee_form', {
|
||||
...formView,
|
||||
Controller: EmployeeFormController,
|
||||
Renderer: EmployeeFormRenderer,
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
|
||||
import { listView } from '@web/views/list/list_view';
|
||||
import { ListController } from '@web/views/list/list_controller';
|
||||
|
||||
import { ArchiveEmployeeMixin } from '../mixins/archive_employee_mixin';
|
||||
|
||||
export class EmployeeListController extends ListController {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.actionService = useService('action');
|
||||
}
|
||||
|
||||
getActionMenuItems() {
|
||||
const menuItems = super.getActionMenuItems();
|
||||
const selectedRecords = this.model.root.selection;
|
||||
|
||||
// Only override the Archive action when only 1 record is selected.
|
||||
if (!this.archiveEnabled || selectedRecords.length > 1 || !selectedRecords[0].data.active) {
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
const archiveAction = menuItems.other.find((item) => item.key === "archive");
|
||||
if (archiveAction) {
|
||||
archiveAction.callback = () => {
|
||||
const archiveAction = this._openArchiveEmployee(this.model.root.resId);
|
||||
this.actionService.doAction(archiveAction, {
|
||||
onClose: async () => {
|
||||
await this.model.load();
|
||||
this.model.notify();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
return menuItems;
|
||||
}
|
||||
}
|
||||
patch(EmployeeListController.prototype, 'employee_list_controller_archive_mixin', ArchiveEmployeeMixin);
|
||||
|
||||
registry.category('views').add('hr_employee_list', {
|
||||
...listView,
|
||||
Controller: EmployeeListController,
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from '@web/core/registry';
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
import { formView } from '@web/views/form/form_view';
|
||||
import { FormController } from '@web/views/form/form_controller';
|
||||
|
||||
|
||||
export class EmployeeProfileFormController extends FormController {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.action = useService('action');
|
||||
}
|
||||
|
||||
async save(params = {}) {
|
||||
const dirtyFields = this.model.root.dirtyFields.map((f) => f.name);
|
||||
super.save(params);
|
||||
|
||||
if (dirtyFields.includes('lang')) {
|
||||
this.action.doAction("reload_context");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registry.category('views').add('hr_employee_profile_form', {
|
||||
...formView,
|
||||
Controller: EmployeeProfileFormController,
|
||||
});
|
||||
@@ -34,7 +34,7 @@
|
||||
<field name="name">hr.employee.public.form</field>
|
||||
<field name="model">hr.employee.public</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Employee" create="0" write="0" js_class="hr_employee_form">
|
||||
<form string="Employee" create="0" write="0" js_class="hr_employee_form" class="o_employee_form">
|
||||
<field name="image_128" invisible="1" />
|
||||
<header/>
|
||||
<sheet>
|
||||
@@ -50,7 +50,7 @@
|
||||
<label for="name" string="Employee Name"/>
|
||||
<h1>
|
||||
<field name="name" placeholder="e.g. John Doe" required="True"/>
|
||||
<a title="Chat" icon="fa-comments" href="#" class="ml8 o_employee_chat_btn" invisible="not context.get('chat_icon')" attrs="{'invisible': [('user_id','=', False)]}" role="button"><i class="fa fa-comments"/></a>
|
||||
<a title="Chat" icon="fa-comments" t-on-click.prevent="() => openChat(props.record.resId)" href="#" class="ml8" invisible="not context.get('chat_icon')" attrs="{'invisible': [('user_id','=', False)]}" role="button"><i class="fa fa-comments"/></a>
|
||||
</h1>
|
||||
<h2>
|
||||
<field name="job_title" placeholder="Job Title" />
|
||||
@@ -196,7 +196,7 @@
|
||||
<field name="res_model">hr.employee.public</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="domain">[]</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="context">{'chat_icon': True}</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="search_view_id" ref="hr_employee_public_view_search"/>
|
||||
<field name="help" type="html">
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<div role="img" class="fa fa-2xs fa-fw fa-circle text-warning o_button_icon hr_presence" attrs="{'invisible': [('hr_presence_state', '!=', 'to_define')]}" aria-label="Away" title="Away"/>
|
||||
<div role="img" class="fa fa-2xs fa-fw fa-circle text-danger o_button_icon hr_presence" attrs="{'invisible': [('hr_presence_state', '!=', 'absent')]}" aria-label="Not available" title="Not available"/>
|
||||
</div>
|
||||
<a title="Chat" icon="fa-comments" href="#" class="ml8 o_employee_chat_btn" invisible="not context.get('chat_icon')" attrs="{'invisible': [('user_id','=', False)]}" role="button"><i class="fa fa-comments"/></a>
|
||||
<a title="Chat" icon="fa-comments" t-on-click.prevent="() => openChat(props.record.resId)" href="#" class="ml8" invisible="not context.get('chat_icon')" attrs="{'invisible': [('user_id','=', False)]}" role="button"><i class="fa fa-comments"/></a>
|
||||
</h1>
|
||||
<h2>
|
||||
<field name="job_title" placeholder="Job Position" />
|
||||
|
||||
Reference in New Issue
Block a user