diff --git a/addons/hr/__manifest__.py b/addons/hr/__manifest__.py
index bbc8f6ace05..608d4bf85c8 100644
--- a/addons/hr/__manifest__.py
+++ b/addons/hr/__manifest__.py
@@ -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': [
diff --git a/addons/hr/static/src/js/chat_mixin.js b/addons/hr/static/src/js/chat_mixin.js
deleted file mode 100644
index 58523e85fc3..00000000000
--- a/addons/hr/static/src/js/chat_mixin.js
+++ /dev/null
@@ -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;
-});
diff --git a/addons/hr/static/src/js/hr_employee.js b/addons/hr/static/src/js/hr_employee.js
deleted file mode 100644
index dd91c35754e..00000000000
--- a/addons/hr/static/src/js/hr_employee.js
+++ /dev/null
@@ -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);
-});
diff --git a/addons/hr/static/src/js/language.js b/addons/hr/static/src/js/language.js
deleted file mode 100644
index 17346f9cd90..00000000000
--- a/addons/hr/static/src/js/language.js
+++ /dev/null
@@ -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;
diff --git a/addons/hr/static/src/mixins/archive_employee_mixin.js b/addons/hr/static/src/mixins/archive_employee_mixin.js
new file mode 100644
index 00000000000..351777d23bd
--- /dev/null
+++ b/addons/hr/static/src/mixins/archive_employee_mixin.js
@@ -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,
+ }
+ }
+ }
+};
diff --git a/addons/hr/static/src/js/user_menu.js b/addons/hr/static/src/user_menu/my_profile.js
similarity index 100%
rename from addons/hr/static/src/js/user_menu.js
rename to addons/hr/static/src/user_menu/my_profile.js
diff --git a/addons/hr/static/src/views/form_view.js b/addons/hr/static/src/views/form_view.js
new file mode 100644
index 00000000000..43d4c344973
--- /dev/null
+++ b/addons/hr/static/src/views/form_view.js
@@ -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,
+});
diff --git a/addons/hr/static/src/views/list_view.js b/addons/hr/static/src/views/list_view.js
new file mode 100644
index 00000000000..a0bea74c2c6
--- /dev/null
+++ b/addons/hr/static/src/views/list_view.js
@@ -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,
+});
diff --git a/addons/hr/static/src/views/profile_form_view.js b/addons/hr/static/src/views/profile_form_view.js
new file mode 100644
index 00000000000..d4caf92af17
--- /dev/null
+++ b/addons/hr/static/src/views/profile_form_view.js
@@ -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,
+});
diff --git a/addons/hr/views/hr_employee_public_views.xml b/addons/hr/views/hr_employee_public_views.xml
index 26a2002b90a..640e1d692f3 100644
--- a/addons/hr/views/hr_employee_public_views.xml
+++ b/addons/hr/views/hr_employee_public_views.xml
@@ -34,7 +34,7 @@
hr.employee.public.form
hr.employee.public
-