[IMP] base_import,*: move Import button to Favorite menu

*account,crm_iap_lead,hr_expense

Part of task 2234547

Co-authored-by: Mohammed Shekha <msh@odoo.com>
Co-authored-by: Aaron Bohy <aab@odoo.com>
This commit is contained in:
pka-odoo
2020-05-04 14:31:11 +00:00
committed by Aaron Bohy
co-authored by Mohammed Shekha Aaron Bohy
parent 93c01a231a
commit 470fa48686
9 changed files with 179 additions and 303 deletions
@@ -15,11 +15,6 @@
<t t-extend="ListView.buttons" t-name="BillsListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<t t-js="ctx">
if (window.odoo._modules.indexOf("base_import") >= 0) {
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
};
</t>
<button type="button" class="btn btn-secondary o_button_upload_bill">
Upload
</button>
@@ -1,123 +0,0 @@
odoo.define('base_import.import_buttons', function (require) {
"use strict";
var config = require('web.config');
var KanbanController = require('web.KanbanController');
var KanbanView = require('web.KanbanView');
var ListController = require('web.ListController');
var ListView = require('web.ListView');
// Mixins that enable the 'Import' feature
var ImportViewMixin = {
/**
* @override
* @param {Object} params
* @param {boolean} [params.import_enabled=true] set to false to disable
* the Import feature (no 'Import' button in the control panel). Can also
* be disabled with 'import' attrs set to '0' in the arch.
*/
init: function (viewInfo, params) {
var importEnabled = !!JSON.parse(this.arch.attrs.import || '1') &&
('import_enabled' in params ? params.import_enabled : true);
this.controllerParams.importEnabled = importEnabled && !config.device.isMobile;
},
};
var ImportControllerMixin = {
/**
* @override
*/
init: function (parent, model, renderer, params) {
this.importEnabled = params.importEnabled;
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Adds an event listener on the import button.
*
* @private
*/
_bindImport: function () {
if (!this.$buttons) {
return;
}
var self = this;
this.$buttons.on('click', '.o_button_import', function () {
var state = self.model.get(self.handle, {raw: true});
self.do_action({
type: 'ir.actions.client',
tag: 'import',
params: {
model: self.modelName,
context: state.getContext(),
}
});
});
}
};
// Activate 'Import' feature on List views
ListView.include({
init: function () {
this._super.apply(this, arguments);
ImportViewMixin.init.apply(this, arguments);
},
});
ListController.include({
init: function () {
this._super.apply(this, arguments);
ImportControllerMixin.init.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Extends the renderButtons function of ListView by adding an event listener
* on the import button.
*
* @override
*/
renderButtons: function () {
this._super.apply(this, arguments); // Sets this.$buttons
ImportControllerMixin._bindImport.call(this);
}
});
// Activate 'Import' feature on Kanban views
KanbanView.include({
init: function () {
this._super.apply(this, arguments);
ImportViewMixin.init.apply(this, arguments);
},
});
KanbanController.include({
init: function () {
this._super.apply(this, arguments);
ImportControllerMixin.init.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Extends the renderButtons function of ListView by adding an event listener
* on the import button.
*
* @override
*/
renderButtons: function () {
this._super.apply(this, arguments); // Sets this.$buttons
ImportControllerMixin._bindImport.call(this);
}
});
});
@@ -0,0 +1,63 @@
odoo.define('base_import.ImportMenu', function (require) {
"use strict";
const DropdownMenuItem = require('web.DropdownMenuItem');
const FavoriteMenu = require('web.FavoriteMenu');
const { useModel } = require('web.model');
/**
* Import Records menu
*
* This component is used to import the records for particular model.
*
* @extends DropdownMenuItem
*/
class ImportMenu extends DropdownMenuItem {
constructor() {
super(...arguments);
this.model = useModel('controlPanelModel');
}
//---------------------------------------------------------------------
// Handlers
//---------------------------------------------------------------------
/**
* @private
*/
_onImportClick() {
const action = {
type: 'ir.actions.client',
tag: 'import',
params: {
model: this.model.modelName,
context: this.model.actionContext,
}
};
this.trigger('do-action', {action: action});
}
//---------------------------------------------------------------------
// Static
//---------------------------------------------------------------------
/**
* @param {Object} env
* @returns {boolean}
*/
static shouldBeDisplayed(env) {
return env.view &&
['kanban', 'list'].includes(env.view.type) &&
!env.device.isMobile &&
!!JSON.parse(env.view.arch.attrs.import || '1') &&
!!JSON.parse(env.view.arch.attrs.create || '1');
}
}
ImportMenu.props = {};
ImportMenu.template = 'base_import.ImportMenu';
FavoriteMenu.registry.add('import-menu', ImportMenu, 1);
return ImportMenu;
});
@@ -1,4 +1,12 @@
<templates>
<t t-name="base_import.ImportMenu" owl="1">
<li class="o_menu_item o_import_menu" role="menuitem">
<button type="button" class="dropdown-item" t-on-click="_onImportClick">
Import Records
</button>
</li>
</t>
<t t-name="ImportView">
<t t-set="_id" t-value="_.uniqueId('export')"/>
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
@@ -217,19 +225,4 @@
<t t-if="error.rows" t-esc="at(error.rows)"/>
<t t-if="error.moreinfo" t-raw="info(error.moreinfo)"/>
</t>
<t t-name="ImportView.import_button">
<button t-if='widget and widget.importEnabled' type="button" class="btn btn-secondary o_button_import">
Import
</button>
</t>
<t t-extend="ListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<t t-call="ImportView.import_button"/>
</t>
</t>
<t t-extend="KanbanView.buttons">
<t t-jquery="button" t-operation="after">
<t t-call="ImportView.import_button"/>
</t>
</t>
</templates>
@@ -1,56 +0,0 @@
odoo.define('web.base_import_mobile_tests', function (require) {
"use strict";
var KanbanView = require('web.KanbanView');
var ListView = require('web.ListView');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
QUnit.module('Base Import Mobile Tests', {
beforeEach: function () {
this.data = {
foo: {
fields: {
foo: {string: "Foo", type: "char"},
},
},
};
}
});
QUnit.test('import button should be hidden in list on mobile screens', async function (assert) {
assert.expect(1);
var list = await createView({
View: ListView,
model: 'foo',
data: this.data,
arch: '<tree><field name="foo"/></tree>',
});
assert.notOk(list.$buttons.find('.o_button_import').is(':visible'),
"import button should be hidden");
list.destroy();
});
QUnit.test('import button should be hidden in kanban on mobile screens', async function (assert) {
assert.expect(1);
var kanban = await createView({
View: KanbanView,
model: 'foo',
data: this.data,
arch: '<kanban><templates><t t-name="kanban-box">' +
'<div>' +
'<field name="foo"/>' +
'</div>' +
'</t></templates></kanban>',
});
assert.notOk(kanban.$buttons.find('.o_button_import').is(':visible'),
"import button should be hidden");
kanban.destroy();
});
});
@@ -1,14 +1,15 @@
odoo.define('web.base_import_tests', function (require) {
"use strict";
var KanbanView = require('web.KanbanView');
var ListView = require('web.ListView');
var testUtils = require('web.test_utils');
const KanbanView = require('web.KanbanView');
const ListView = require('web.ListView');
const PivotView = require('web.PivotView');
const testUtils = require('web.test_utils');
var createView = testUtils.createView;
const createView = testUtils.createView;
QUnit.module('Base Import Tests', {
beforeEach: function() {
beforeEach: function () {
this.data = {
foo: {
fields: {
@@ -22,119 +23,148 @@ QUnit.module('Base Import Tests', {
}
});
QUnit.test('add import button in list', async function(assert) {
QUnit.test('import in favorite dropdown in list', async function (assert) {
assert.expect(2);
var list = await createView({
const list = await createView({
View: ListView,
model: 'foo',
data: this.data,
arch: '<tree><field name="foo"/></tree>',
});
assert.isVisible(list.$buttons.find('.o_button_import:contains(Import)'),
"should have a visible Import button");
testUtils.mock.intercept(list, 'do_action', function() {
testUtils.mock.intercept(list, 'do_action', function () {
assert.ok(true, "should have triggered a do_action");
});
await testUtils.dom.click(list.$buttons.find('.o_button_import:contains(Import)'));
await testUtils.dom.click(list.$('.o_favorite_menu button'));
assert.containsOnce(list, '.o_import_menu');
await testUtils.dom.click(list.$('.o_import_menu button'));
list.destroy();
});
QUnit.test('list without import button', async function(assert) {
QUnit.test('import favorite dropdown item should not in list with create="0"', async function (assert) {
assert.expect(1);
var list = await createView({
const list = await createView({
View: ListView,
model: 'foo',
data: this.data,
arch: '<tree><field name="foo"/></tree>',
viewOptions: {
import_enabled: false,
}
arch: '<tree create="0"><field name="foo"/></tree>',
});
assert.containsNone(list.$buttons, '.o_button_import', 'should not have an Import button');
await testUtils.dom.click(list.$('.o_favorite_menu button'));
assert.containsNone(list, '.o_import_menu');
list.destroy();
});
QUnit.test('add import button in kanban', async function(assert) {
assert.expect(2);
var kanban = await createView({
View: KanbanView,
model: 'foo',
data: this.data,
arch: '<kanban><templates><t t-name="kanban-box">' +
'<div>' +
'<field name="foo"/>' +
'</div>' +
'</t></templates></kanban>',
});
assert.isVisible(kanban.$buttons.find('.o_button_import:contains(Import)'),
"should have a visible Import button");
testUtils.mock.intercept(kanban, 'do_action', function() {
assert.ok(true, "should have triggered a do_action");
});
await testUtils.dom.click(kanban.$buttons.find('.o_button_import:contains(Import)'));
kanban.destroy();
});
QUnit.test('kanban without import button', async function(assert) {
QUnit.test('import favorite dropdown item should not in list with import="0"', async function (assert) {
assert.expect(1);
var kanban = await createView({
View: KanbanView,
model: 'foo',
data: this.data,
arch: '<kanban><templates><t t-name="kanban-box">' +
'<div>' +
'<field name="foo"/>' +
'</div>' +
'</t></templates></kanban>',
viewOptions: {
import_enabled: false,
}
});
assert.containsNone(kanban.$buttons, '.o_button_import', "should not have an Import button");
kanban.destroy();
});
QUnit.test('import attrs in list views', async function (assert) {
assert.expect(1);
var list = await createView({
const list = await createView({
View: ListView,
model: 'foo',
data: this.data,
arch: '<tree import="0"><field name="foo"/></tree>',
});
assert.containsNone(list.$buttons, '.o_button_import');
await testUtils.dom.click(list.$('.o_favorite_menu button'));
assert.containsNone(list, '.o_import_menu');
list.destroy();
});
QUnit.test('import attrs in kanban views', async function (assert) {
assert.expect(1);
QUnit.test('import in favorite dropdown in kanban', async function (assert) {
assert.expect(2);
var kanban = await createView({
const kanban = await createView({
View: KanbanView,
model: 'foo',
data: this.data,
arch: '<kanban import="0">' +
'<templates><t t-name="kanban-box">' +
'<div><field name="foo"/></div>' +
'</t></templates>' +
'</kanban>',
arch: `<kanban>
<templates>
<t t-name="kanban-box">
<div><field name="foo"/></div>
</t>
</templates>
</kanban>`,
});
assert.containsNone(kanban.$buttons, '.o_button_import');
testUtils.mock.intercept(kanban, 'do_action', function () {
assert.ok(true, "should have triggered a do_action");
});
await testUtils.dom.click(kanban.$('.o_favorite_menu button'));
assert.containsOnce(kanban, '.o_import_menu');
await testUtils.dom.click(kanban.$('.o_import_menu button'));
kanban.destroy();
});
QUnit.test('import favorite dropdown item should not in list with create="0"', async function (assert) {
assert.expect(1);
const kanban = await createView({
View: KanbanView,
model: 'foo',
data: this.data,
arch: `<kanban create="0">
<templates>
<t t-name="kanban-box">
<div><field name="foo"/></div>
</t>
</templates>
</kanban>`,
});
await testUtils.dom.click(kanban.$('.o_favorite_menu button'));
assert.containsNone(kanban, '.o_import_menu');
kanban.destroy();
});
QUnit.test('import dropdown favorite should not in kanban with import="0"', async function (assert) {
assert.expect(1);
const kanban = await createView({
View: KanbanView,
model: 'foo',
data: this.data,
arch: `<kanban import="0">
<templates>
<t t-name="kanban-box">
<div><field name="foo"/></div>
</t>
</templates>
</kanban>`,
});
await testUtils.dom.click(kanban.$('.o_favorite_menu button'));
assert.containsNone(kanban, '.o_import_menu');
kanban.destroy();
});
QUnit.test('import should not available in favorite dropdown in pivot (other than kanban or list)', async function (assert) {
assert.expect(1);
this.data.foo.fields.foobar = { string: "Fubar", type: "integer", group_operator: 'sum' };
const pivot = await createView({
View: PivotView,
model: 'foo',
data: this.data,
arch: '<pivot><field name="foobar" type="measure"/></pivot>',
});
await testUtils.dom.click(pivot.$('.o_favorite_menu button'));
assert.containsNone(pivot, '.o_import_menu');
pivot.destroy();
});
});
@@ -6,7 +6,7 @@
<link rel="stylesheet" type="text/scss" href="/base_import/static/src/scss/base_import.scss"/>
<script type="text/javascript" src="/base_import/static/lib/javascript-state-machine/state-machine.js"></script>
<script type="text/javascript" src="/base_import/static/src/js/import_action.js"></script>
<script type="text/javascript" src="/base_import/static/src/js/import_buttons.js"></script>
<script type="text/javascript" src="/base_import/static/src/js/import_menu.js"></script>
</xpath>
</template>
@@ -15,11 +15,5 @@
<script type="text/javascript" src="/base_import/static/tests/import_buttons_tests.js"></script>
</xpath>
</template>
<template id="qunit_mobile_suite" name="base_import_mobile_tests" inherit_id="web.qunit_mobile_suite_tests">
<xpath expr="." position="inside">
<script type="text/javascript" src="/base_import/static/tests/import_buttons_mobile_tests.js"></script>
</xpath>
</template>
</data>
</odoo>
@@ -10,22 +10,12 @@
<t t-extend="ListView.buttons" t-name="LeadMiningRequestListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<t t-call="LeadMiningRequest.generate_leads_button"/>
<t t-js="ctx">
if (window.odoo._modules.indexOf("base_import") >= 0) {
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
};
</t>
</t>
</t>
<t t-extend="KanbanView.buttons" t-name="LeadMiningRequestKanbanView.buttons">
<t t-jquery="button" t-operation="after">
<t t-call="LeadMiningRequest.generate_leads_button"/>
<t t-js="ctx">
if (window.odoo._modules.indexOf("base_import") >= 0) {
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
};
</t>
</t>
</t>
</templates>
@@ -15,11 +15,6 @@
<t t-extend="ListView.buttons" t-name="ExpensesListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<t t-js="ctx">
if (window.odoo._modules.indexOf("base_import") >= 0) {
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
};
</t>
<button type="button" class="btn btn-secondary o_button_upload_expense">
Upload
</button>
@@ -28,11 +23,6 @@
<t t-extend="KanbanView.buttons" t-name="ExpensesKanbanView.buttons">
<t t-jquery="button" t-operation="after">
<t t-js="ctx">
if (window.odoo._modules.indexOf("base_import") >= 0) {
r.push(context.engine.tools.call(context, 'ImportView.import_button', dict));
};
</t>
<button type="button" class="btn btn-secondary o_button_upload_expense">
Upload
</button>