[IMP] hr: add a standalone version of the avatar employee widget
This will be useful for special views like gantt, grid…
A StandaloneM2OAvatarEmployee widget will be available and would allow to
instantiate a Many2OneAvatarEmployee widget anywhere.
Usage:
const widget = new StandaloneM2OAvatarEmployee(<parent>, <value>);
widget.appendTo(<Node>);
Where:
<parent> the widget parent, if it is given
<value> {number|[number, char]} either the employee id or an array representing the employee: [id, display_name]. If only the id is passed, the widget will fetch the display_name through a name_get rpc.
<Node> any DOM Node object you want the widget to be appended to.
Examples:
const w1 = new StandaloneM2OAvatarEmployee(null, 3);
const w2 = new StandaloneM2OAvatarEmployee(null, [1, 'Mitchell Admin']);
w1.appendTo(document.body);
w2.appendTo(document.body);
closes odoo/odoo#54230
Taskid: 2272544
Taskid: 2272582
Related: odoo/enterprise#11412
Signed-off-by: Mathieu Duckerts-Antoine <Polymorphe57@users.noreply.github.com>
Co-authored-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
odoo.define('hr.StandaloneM2OAvatarEmployee', function (require) {
|
||||
'use strict';
|
||||
|
||||
const StandaloneFieldManagerMixin = require('web.StandaloneFieldManagerMixin');
|
||||
const Widget = require('web.Widget');
|
||||
|
||||
const { Many2OneAvatarEmployee } = require('hr.Many2OneAvatarEmployee');
|
||||
|
||||
const StandaloneM2OAvatarEmployee = Widget.extend(StandaloneFieldManagerMixin, {
|
||||
className: 'o_standalone_avatar_employee',
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init(parent, value) {
|
||||
this._super(...arguments);
|
||||
StandaloneFieldManagerMixin.init.call(this);
|
||||
this.value = value;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
willStart() {
|
||||
return Promise.all([this._super(...arguments), this._makeAvatarWidget()]);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start() {
|
||||
this.avatarWidget.$el.appendTo(this.$el);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a record, and initialize and start the avatar widget.
|
||||
*
|
||||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async _makeAvatarWidget() {
|
||||
const modelName = 'hr.employee';
|
||||
const fieldName = 'employee_id';
|
||||
const recordId = await this.model.makeRecord(modelName, [{
|
||||
name: fieldName,
|
||||
relation: modelName,
|
||||
type: 'many2one',
|
||||
value: this.value,
|
||||
}]);
|
||||
const state = this.model.get(recordId);
|
||||
this.avatarWidget = new Many2OneAvatarEmployee(this, fieldName, state);
|
||||
this._registerWidget(recordId, fieldName, this.avatarWidget);
|
||||
return this.avatarWidget.appendTo(document.createDocumentFragment());
|
||||
},
|
||||
});
|
||||
|
||||
return StandaloneM2OAvatarEmployee;
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
odoo.define('hr.StandaloneM2OEmployeeTests', function (require) {
|
||||
"use strict";
|
||||
|
||||
const { xml } = owl.tags;
|
||||
|
||||
const AbstractRendererOwl = require('web.AbstractRendererOwl');
|
||||
const BasicView = require("web.BasicView");
|
||||
const BasicRenderer = require("web.BasicRenderer");
|
||||
const RendererWrapper = require('web.RendererWrapper');
|
||||
const { createView } = require('web.test_utils');
|
||||
|
||||
const StandaloneM2OAvatarEmployee = require('hr.StandaloneM2OAvatarEmployee');
|
||||
|
||||
function getHtmlRenderer(html) {
|
||||
return BasicRenderer.extend({
|
||||
start: function () {
|
||||
this.$el.html(html);
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getOwlView(owlRenderer, viewType) {
|
||||
viewType = viewType || "test";
|
||||
return BasicView.extend({
|
||||
viewType: viewType,
|
||||
config: Object.assign({}, BasicView.prototype.config, {
|
||||
Renderer: owlRenderer,
|
||||
}),
|
||||
getRenderer() {
|
||||
return new RendererWrapper(null, this.config.Renderer, {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getHtmlView(html, viewType) {
|
||||
viewType = viewType || "test";
|
||||
return BasicView.extend({
|
||||
viewType: viewType,
|
||||
config: Object.assign({}, BasicView.prototype.config, {
|
||||
Renderer: getHtmlRenderer(html)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
QUnit.module('hr', {}, function () {
|
||||
QUnit.module('StandaloneM2OEmployeeTests', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
'foo': {
|
||||
fields: {
|
||||
employee_id: {string: "Employee", type: 'many2one', relation: 'hr.employee'},
|
||||
},
|
||||
records: [],
|
||||
},
|
||||
'hr.employee': {
|
||||
fields: {},
|
||||
records: [
|
||||
{id: 10, name: "Mario"},
|
||||
{id: 20, name: "Luigi"},
|
||||
{id: 30, name: "Yoshi"}
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
QUnit.test('standalone_m2o_avatar_employee: legacy view', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
const html = "<div class='coucou_test'></div>";
|
||||
const view = await createView({
|
||||
View: getHtmlView(html, "test"),
|
||||
data: this.data,
|
||||
model: "foo",
|
||||
arch: "<test/>"
|
||||
});
|
||||
|
||||
const avatar10 = new StandaloneM2OAvatarEmployee(view, 10);
|
||||
const avatar20 = new StandaloneM2OAvatarEmployee(view, 20);
|
||||
const avatar30 = new StandaloneM2OAvatarEmployee(view, [30, 'Bowser']);
|
||||
|
||||
await avatar10.appendTo(view.el.querySelector('.coucou_test'));
|
||||
await avatar20.appendTo(view.el.querySelector('.coucou_test'));
|
||||
await avatar30.appendTo(view.el.querySelector('.coucou_test'));
|
||||
|
||||
assert.deepEqual(
|
||||
[...view.el.querySelectorAll('.o_field_many2one_avatar span')].map(el => el.innerText),
|
||||
["Mario", "Luigi", "Bowser"]
|
||||
);
|
||||
|
||||
view.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('standalone_m2o_avatar_employee: Owl view', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
class Renderer extends AbstractRendererOwl { }
|
||||
Renderer.template = xml`<div class='coucou_test'></div>`;
|
||||
|
||||
const view = await createView({
|
||||
View: getOwlView(Renderer, "test"),
|
||||
data: this.data,
|
||||
model: "foo",
|
||||
arch: "<test/>"
|
||||
});
|
||||
|
||||
const avatar10 = new StandaloneM2OAvatarEmployee(view, 10);
|
||||
const avatar20 = new StandaloneM2OAvatarEmployee(view, 20);
|
||||
const avatar30 = new StandaloneM2OAvatarEmployee(view, [30, 'Bowser']);
|
||||
|
||||
await avatar10.appendTo(view.el.querySelector('.coucou_test'));
|
||||
await avatar20.appendTo(view.el.querySelector('.coucou_test'));
|
||||
await avatar30.appendTo(view.el.querySelector('.coucou_test'));
|
||||
|
||||
assert.deepEqual(
|
||||
[...view.el.querySelectorAll('.o_field_many2one_avatar span')].map(el => el.innerText),
|
||||
["Mario", "Luigi", "Bowser"]
|
||||
);
|
||||
|
||||
view.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -7,12 +7,14 @@
|
||||
<script type="text/javascript" src="/hr/static/src/js/chat.js"></script>
|
||||
<script type="text/javascript" src="/hr/static/src/js/language.js"></script>
|
||||
<script type="text/javascript" src="/hr/static/src/js/many2one_avatar_employee.js"></script>
|
||||
<script type="text/javascript" src="/hr/static/src/js/standalone_m2o_avatar_employee.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="qunit_suite" name="hr tests" inherit_id="web.qunit_suite_tests">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/hr/static/tests/many2one_avatar_employee_tests.js"></script>
|
||||
<script type="text/javascript" src="/hr/static/tests/standalone_m2o_avatar_employee_tests.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user