[IMP] hr: migrate widgets/views to Owl

This commit is contained in:
Kevin Baptiste
2022-08-24 09:23:01 +02:00
committed by Yannick Tivisse
parent 30f520a494
commit 6d9ec56bd1
11 changed files with 149 additions and 205 deletions
+1 -4
View File
@@ -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': [
-36
View File
@@ -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;
});
-136
View File
@@ -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);
});
-25
View File
@@ -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,
}
}
}
};
+50
View File
@@ -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,
});
+47
View File
@@ -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,
});
+3 -3
View File
@@ -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">
+1 -1
View File
@@ -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" />