[REF] *: adapt all client actions
to ControlPanel/Search view refactoring. The ControlPanel being now inside the DOM of client actions, those existing widgets needed to be adapted (in the way they define if and how they want a ControlPanel, and in the way the manipulate their DOM as it slightly changed). Tests needed to be adapted as well. Part of task 1893568 Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com> Co-authored-by: Martin Geubelle <mge@odoo.com>
This commit is contained in:
committed by
Géry Debongnie
co-authored by
Mathieu Duckerts-Antoine
Martin Geubelle
parent
40dd121938
commit
b1ef0001f6
@@ -4,18 +4,16 @@ odoo.define('account.ReconciliationClientAction', function (require) {
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var ReconciliationModel = require('account.ReconciliationModel');
|
||||
var ReconciliationRenderer = require('account.ReconciliationRenderer');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var Widget = require('web.Widget');
|
||||
var core = require('web.core');
|
||||
var _t = core._t;
|
||||
|
||||
|
||||
/**
|
||||
* Widget used as action for 'account.bank.statement' reconciliation
|
||||
*/
|
||||
var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
var StatementAction = AbstractAction.extend({
|
||||
hasControlPanel: true,
|
||||
title: core._t('Bank Reconciliation'),
|
||||
template: 'reconciliation',
|
||||
contentTemplate: 'reconciliation',
|
||||
custom_events: {
|
||||
change_mode: '_onAction',
|
||||
change_filter: '_onAction',
|
||||
@@ -34,7 +32,7 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
load_more: '_onLoadMore',
|
||||
reload: 'reload',
|
||||
},
|
||||
config: {
|
||||
config: _.extend({}, AbstractAction.prototype.config, {
|
||||
// used to instantiate the model
|
||||
Model: ReconciliationModel.StatementModel,
|
||||
// used to instantiate the action interface
|
||||
@@ -47,7 +45,7 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
defaultDisplayQty: 10,
|
||||
// number of moves lines displayed in 'match' mode
|
||||
limitMoveLines: 15,
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -65,9 +63,6 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
limitMoveLines: params.params && params.params.limitMoveLines || this.config.limitMoveLines,
|
||||
});
|
||||
this.widgets = [];
|
||||
if (!this.action_manager) {
|
||||
this.set_cp_bus(new Widget());
|
||||
}
|
||||
// Adding values from the context is necessary to put this information in the url via the action manager so that
|
||||
// you can retrieve it if the person shares his url or presses f5
|
||||
_.each(params.params, function (value, name) {
|
||||
@@ -90,13 +85,14 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
var self = this;
|
||||
var def = this.model.load(this.params.context).then(this._super.bind(this));
|
||||
return def.then(function () {
|
||||
self.title = self.model.bank_statement_id ? self.model.bank_statement_id.display_name : self.title;
|
||||
var title = self.model.bank_statement_id && self.model.bank_statement_id.display_name;
|
||||
self._setTitle(title);
|
||||
self.renderer = new self.config.ActionRenderer(self, self.model, {
|
||||
'bank_statement_id': self.model.bank_statement_id,
|
||||
'valuenow': self.model.valuenow,
|
||||
'valuemax': self.model.valuemax,
|
||||
'defaultDisplayQty': self.model.defaultDisplayQty,
|
||||
'title': self.title,
|
||||
'title': title,
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -124,9 +120,6 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
start: function () {
|
||||
var self = this;
|
||||
|
||||
this.set("title", this.title);
|
||||
this.update_control_panel({search_view_hidden: true}, {clear: true});
|
||||
|
||||
this.renderer.prependTo(self.$('.o_form_sheet'));
|
||||
this._renderLines();
|
||||
|
||||
@@ -141,6 +134,8 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
this.renderer._renderNotifications(this.model.statement.notifications);
|
||||
this._openFirstLine();
|
||||
}
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -151,7 +146,7 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
do_show: function () {
|
||||
this._super.apply(this, arguments);
|
||||
if (this.action_manager) {
|
||||
this.update_control_panel({search_view_hidden: true}, {clear: true});
|
||||
this.updateControlPanel({clear: true});
|
||||
this.action_manager.do_push_state({
|
||||
action: this.params.tag,
|
||||
active_id: this.params.res_id,
|
||||
@@ -354,14 +349,14 @@ var StatementAction = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
var ManualAction = StatementAction.extend({
|
||||
title: core._t('Journal Items to Reconcile'),
|
||||
config: {
|
||||
config: _.extend({}, StatementAction.prototype.config, {
|
||||
Model: ReconciliationModel.ManualModel,
|
||||
ActionRenderer: ReconciliationRenderer.ManualRenderer,
|
||||
LineRenderer: ReconciliationRenderer.ManualLineRenderer,
|
||||
params: ['company_ids', 'mode', 'partner_ids', 'account_ids'],
|
||||
defaultDisplayQty: 30,
|
||||
limitMoveLines: 15,
|
||||
},
|
||||
}),
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
|
||||
@@ -700,7 +700,7 @@ QUnit.module('account', {
|
||||
assert.ok(clientAction.widgets[1].$('.match div.load-more a:visible').length, "should display the 'load more' button");
|
||||
assert.equal(clientAction.widgets[1].$('.match div.load-more span').text(), 3, "should display 3 items remaining");
|
||||
clientAction.widgets[1].$('.match div.load-more a').trigger('click');
|
||||
assert.containsN(clientAction.widgets[1], '.mv_line', 8, "should load 3 more records"),
|
||||
assert.containsN(clientAction.widgets[1], '.mv_line', 8, "should load 3 more records");
|
||||
assert.notOk(clientAction.widgets[1].$('.match div.load-more a:visible').length, "should not display the 'load more' button anymore");
|
||||
|
||||
assert.ok(clientAction.widgets[0].$('caption button.btn-secondary:visible').length, "should display the 'validate' button");
|
||||
|
||||
@@ -2,7 +2,6 @@ odoo.define('base_import.import', function (require) {
|
||||
"use strict";
|
||||
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var time = require('web.time');
|
||||
@@ -72,8 +71,9 @@ function dataFilteredQuery(q) {
|
||||
q.callback({results: suggestions});
|
||||
}
|
||||
|
||||
var DataImport = AbstractAction.extend(ControlPanelMixin, {
|
||||
template: 'ImportView',
|
||||
var DataImport = AbstractAction.extend({
|
||||
hasControlPanel: true,
|
||||
contentTemplate: 'ImportView',
|
||||
opts: [
|
||||
{name: 'encoding', label: _lt("Encoding:"), value: ''},
|
||||
{name: 'separator', label: _lt("Separator:"), value: ''},
|
||||
@@ -137,7 +137,7 @@ var DataImport = AbstractAction.extend(ControlPanelMixin, {
|
||||
// import object id
|
||||
this.id = null;
|
||||
this.session = session;
|
||||
action.display_name = _t('Import a File'); // Displayed in the breadcrumbs
|
||||
this._title = _t('Import a File'); // Displayed in the breadcrumbs
|
||||
this.do_not_change_match = false;
|
||||
},
|
||||
/**
|
||||
@@ -145,13 +145,14 @@ var DataImport = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
return this._rpc({
|
||||
var def = this._rpc({
|
||||
model: this.res_model,
|
||||
method: 'get_import_templates',
|
||||
context: this.parent_context,
|
||||
}).then(function (result) {
|
||||
self.importTemplates = result;
|
||||
});
|
||||
return $.when(this._super.apply(this, arguments), def);
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
@@ -170,7 +171,7 @@ var DataImport = AbstractAction.extend(ControlPanelMixin, {
|
||||
var status = {
|
||||
cp_content: {$buttons: self.$buttons},
|
||||
};
|
||||
self.update_control_panel(status);
|
||||
self.updateControlPanel(status);
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -189,7 +190,7 @@ var DataImport = AbstractAction.extend(ControlPanelMixin, {
|
||||
this.$buttons.filter('.o_import_import').on('click', this.import.bind(this));
|
||||
this.$buttons.filter('.o_import_file_reload').on('click', this.loaded_file.bind(this));
|
||||
this.$buttons.filter('.oe_import_file').on('click', function () {
|
||||
self.$('.oe_import_file').click();
|
||||
self.$('.o_content .oe_import_file').click();
|
||||
});
|
||||
this.$buttons.filter('.o_import_cancel').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -8,7 +8,7 @@ var _t = core._t;
|
||||
|
||||
|
||||
var GreetingMessage = AbstractAction.extend({
|
||||
template: 'HrAttendanceGreetingMessage',
|
||||
contentTemplate: 'HrAttendanceGreetingMessage',
|
||||
|
||||
events: {
|
||||
"click .o_hr_attendance_button_dismiss": function() { this.do_action(this.next_action, {clear_breadcrumbs: true}); },
|
||||
@@ -61,6 +61,7 @@ var GreetingMessage = AbstractAction.extend({
|
||||
if (this.activeBarcode) {
|
||||
core.bus.on('barcode_scanned', this, this._onBarcodeScanned);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
welcome_message: function() {
|
||||
|
||||
@@ -4,11 +4,9 @@ odoo.define('hr_attendance.my_attendances', function (require) {
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var core = require('web.core');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
|
||||
|
||||
var MyAttendances = AbstractAction.extend({
|
||||
contentTemplate: 'HrAttendanceMyMainMenu',
|
||||
events: {
|
||||
"click .o_hr_attendance_sign_in_out_icon": function() {
|
||||
this.$('.o_hr_attendance_sign_in_out_icon').attr("disabled", "disabled");
|
||||
@@ -16,7 +14,7 @@ var MyAttendances = AbstractAction.extend({
|
||||
},
|
||||
},
|
||||
|
||||
start: function () {
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
|
||||
var def = this._rpc({
|
||||
@@ -26,7 +24,6 @@ var MyAttendances = AbstractAction.extend({
|
||||
})
|
||||
.then(function (res) {
|
||||
self.employee = res.length && res[0];
|
||||
self.$el.html(QWeb.render("HrAttendanceMyMainMenu", {widget: self}));
|
||||
});
|
||||
|
||||
return $.when(def, this._super.apply(this, arguments));
|
||||
|
||||
@@ -57,7 +57,7 @@ QUnit.module('HR Attendance', {
|
||||
assert.expect(1);
|
||||
|
||||
var $target = $('#qunit-fixture');
|
||||
var clientAction = new MyAttendances(null);
|
||||
var clientAction = new MyAttendances(null, {});
|
||||
testUtils.mock.addMockEnvironment(clientAction, {
|
||||
data: this.data,
|
||||
session: {
|
||||
@@ -78,7 +78,7 @@ QUnit.module('HR Attendance', {
|
||||
var $target = $('#qunit-fixture');
|
||||
var self = this;
|
||||
var rpcCount = 0;
|
||||
var clientAction = new KioskMode(null);
|
||||
var clientAction = new KioskMode(null, {});
|
||||
testUtils.mock.addMockEnvironment(clientAction, {
|
||||
data: this.data,
|
||||
session: {
|
||||
@@ -121,7 +121,7 @@ QUnit.module('HR Attendance', {
|
||||
},
|
||||
next_action: "hr_attendance.hr_attendance_action_kiosk_mode",
|
||||
barcode: barcode,
|
||||
}
|
||||
};
|
||||
var clientAction = new GreetingMessage(null, action);
|
||||
testUtils.mock.addMockEnvironment(clientAction, {
|
||||
data: self.data,
|
||||
@@ -146,7 +146,7 @@ QUnit.module('HR Attendance', {
|
||||
clientAction.appendTo(target);
|
||||
|
||||
clientActions.push(clientAction);
|
||||
};
|
||||
}
|
||||
|
||||
// init - mock coming from kiosk
|
||||
createGreetingMessage ($target, 1);
|
||||
|
||||
@@ -7,13 +7,9 @@ var ThreadWidget = require('mail.widget.Thread');
|
||||
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var config = require('web.config');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var core = require('web.core');
|
||||
var data = require('web.data');
|
||||
var Dialog = require('web.Dialog');
|
||||
var dom = require('web.dom');
|
||||
var pyUtils = require('web.py_utils');
|
||||
var SearchView = require('web.SearchView');
|
||||
var session = require('web.session');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
@@ -240,8 +236,8 @@ var ModeratorRejectMessageDialog = Dialog.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
template: 'mail.discuss',
|
||||
var Discuss = AbstractAction.extend({
|
||||
contentTemplate: 'mail.discuss',
|
||||
custom_events: {
|
||||
discard_extended_composer: '_onDiscardExtendedComposer',
|
||||
message_moderation: '_onMessageModeration',
|
||||
@@ -258,6 +254,11 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
'click .o_mail_partner_unpin': '_onUnpinChannel',
|
||||
'input .o_discuss_sidebar_quick_search input': '_onInputSidebarQuickSearchInput',
|
||||
},
|
||||
hasControlPanel: true,
|
||||
loadControlPanel: true,
|
||||
withSearchBar: true,
|
||||
searchMenuTypes: ['filter', 'favorite'],
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} [options]
|
||||
@@ -268,8 +269,8 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.action = action;
|
||||
this.context = action.context;
|
||||
this.action_manager = parent;
|
||||
this.dataset = new data.DataSetSearch(this, 'mail.message');
|
||||
this.domain = [];
|
||||
this.options = options || {};
|
||||
|
||||
@@ -286,21 +287,14 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
this._selectedMessage = null;
|
||||
this._throttledUpdateThreads = _.throttle(
|
||||
this._updateThreads.bind(this), 100, { leading: false });
|
||||
|
||||
this.controlPanelParams.modelName = 'mail.message';
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
var viewID = this.action &&
|
||||
this.action.search_view_id &&
|
||||
this.action.search_view_id[0];
|
||||
var def = this
|
||||
.loadFieldView(this.dataset, viewID, 'search')
|
||||
.then(function (fieldsView) {
|
||||
self.fields_view = fieldsView;
|
||||
});
|
||||
return $.when(this._super(), this.call('mail_service', 'isReady'), def);
|
||||
return $.when(this._super(), this.call('mail_service', 'isReady'));
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -332,11 +326,11 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
this._basicComposer.appendTo(this.$('.o_mail_discuss_content')));
|
||||
defs.push(
|
||||
this._extendedComposer.appendTo(this.$('.o_mail_discuss_content')));
|
||||
defs.push(this._renderSearchView());
|
||||
defs.push(this._super.apply(this, arguments));
|
||||
|
||||
return this.alive($.when.apply($, defs))
|
||||
return $.when.apply($, defs)
|
||||
.then(function () {
|
||||
return self.alive(self._setThread(self._defaultThreadID));
|
||||
return self._setThread(self._defaultThreadID);
|
||||
})
|
||||
.then(function () {
|
||||
self._initThreads();
|
||||
@@ -742,26 +736,6 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
.on('click', '.o_mail_discuss_button_select_all', this._onSelectAllClicked.bind(this))
|
||||
.on('click', '.o_mail_discuss_button_unselect_all', this._onUnselectAllClicked.bind(this));
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
_renderSearchView: function () {
|
||||
var self = this;
|
||||
var options = {
|
||||
$buttons: $('<div>'),
|
||||
action: this.action,
|
||||
disable_groupby: true,
|
||||
};
|
||||
this.searchview = new SearchView(this, this.dataset, this.fields_view, options);
|
||||
return this.alive(this.searchview.appendTo($('<div>')))
|
||||
.then(function () {
|
||||
self.$searchview_buttons = self.searchview.$buttons;
|
||||
// manually call do_search to generate the initial domain and filter
|
||||
// the messages in the default thread
|
||||
self.searchview.do_search();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Render the sidebar of discuss app
|
||||
*
|
||||
@@ -982,7 +956,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
|
||||
// Update control panel before focusing the composer, otherwise
|
||||
// focus is on the searchview
|
||||
self.set("title", self._thread.getTitle());
|
||||
self._setTitle('#' + self._thread.getName());
|
||||
self._updateControlPanel();
|
||||
self._updateControlPanelButtons(self._thread);
|
||||
|
||||
@@ -1106,13 +1080,10 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
* @private
|
||||
*/
|
||||
_updateControlPanel: function () {
|
||||
this.update_control_panel({
|
||||
this.updateControlPanel({
|
||||
cp_content: {
|
||||
$buttons: this.$buttons,
|
||||
$searchview: this.searchview.$el,
|
||||
$searchview_buttons: this.$searchview_buttons,
|
||||
},
|
||||
searchview: this.searchview,
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -1532,12 +1503,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
_onSearch: function (ev) {
|
||||
ev.stopPropagation();
|
||||
var session = this.getSession();
|
||||
var result = pyUtils.eval_domains_and_contexts({
|
||||
domains: ev.data.domains,
|
||||
contexts: [session.user_context],
|
||||
});
|
||||
this.domain = result.domain;
|
||||
this.domain = ev.data.domain;
|
||||
if (this._thread) {
|
||||
// initially (when _onSearch is called manually), there is no
|
||||
// thread set yet, so don't try to fetch and render the thread as
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
odoo.define('mail.discuss_test', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Discuss = require('mail.Discuss');
|
||||
var mailTestUtils = require('mail.testUtils');
|
||||
|
||||
var concurrency = require('web.concurrency');
|
||||
var SearchView = require('web.SearchView');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
var createDiscuss = mailTestUtils.createDiscuss;
|
||||
@@ -108,7 +106,7 @@ QUnit.test('basic rendering', function (assert) {
|
||||
});
|
||||
|
||||
QUnit.test('searchview options visibility', function (assert) {
|
||||
assert.expect(4);
|
||||
assert.expect(5);
|
||||
var done = assert.async();
|
||||
|
||||
createDiscuss({
|
||||
@@ -119,17 +117,17 @@ QUnit.test('searchview options visibility', function (assert) {
|
||||
services: this.services,
|
||||
})
|
||||
.then(function (discuss) {
|
||||
var $searchviewOptions = $('.o_search_options > div');
|
||||
var $searchviewOptionsToggler = $('.o_searchview_more.fa.fa-search-minus');
|
||||
assert.strictEqual($searchviewOptions.length, 1,
|
||||
assert.containsOnce(discuss, '.o_control_panel .o_search_options',
|
||||
"should have search options");
|
||||
assert.strictEqual($searchviewOptionsToggler.length, 1,
|
||||
assert.hasClass(discuss.$('.o_control_panel .o_searchview_more.fa'), 'fa-search-minus',
|
||||
"should have a button to toggle search options");
|
||||
assert.strictEqual($searchviewOptions.css('display'), 'block',
|
||||
"search options should be visible by default");
|
||||
|
||||
testUtils.dom.click($searchviewOptionsToggler);
|
||||
assert.strictEqual($searchviewOptions.css('display'), 'none',
|
||||
assert.isVisible(discuss.$('.o_control_panel .o_search_options'),
|
||||
"search options should be visible by default");
|
||||
testUtils.dom.click(discuss.$('.o_control_panel .o_searchview_more.fa'));
|
||||
assert.hasClass(discuss.$('.o_control_panel .o_searchview_more.fa'), 'fa-search-plus',
|
||||
"should have a button to toggle search options");
|
||||
assert.isNotVisible(discuss.$('.o_control_panel .o_search_options'),
|
||||
"search options should be hidden after clicking on search option toggler");
|
||||
|
||||
discuss.destroy();
|
||||
@@ -181,7 +179,7 @@ QUnit.test('searchview filter messages', function (assert) {
|
||||
|
||||
// interact with searchview so that there is only once message
|
||||
$('.o_searchview_input').val("ab").trigger('keyup');
|
||||
$('.o_searchview').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
$('.o_searchview_input_container').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
|
||||
assert.strictEqual($('.o_searchview_facet').length, 1,
|
||||
"the searchview should have a facet");
|
||||
@@ -193,7 +191,7 @@ QUnit.test('searchview filter messages', function (assert) {
|
||||
// interact with search view so that there are no matching messages
|
||||
testUtils.dom.click($('.o_facet_remove'));
|
||||
$('.o_searchview_input').val("abcd").trigger('keyup');
|
||||
$('.o_searchview').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
$('.o_searchview_input_container').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER }));
|
||||
|
||||
assert.strictEqual($('.o_searchview_facet').length, 1,
|
||||
"the searchview should have a facet");
|
||||
@@ -798,87 +796,6 @@ QUnit.test('"Unstar all" button should reset the starred counter', function (ass
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('do not crash when destroyed before start is completed', function (assert) {
|
||||
assert.expect(3);
|
||||
var discuss;
|
||||
|
||||
testUtils.mock.patch(Discuss, {
|
||||
init: function () {
|
||||
discuss = this;
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
createDiscuss({
|
||||
id: 1,
|
||||
context: {},
|
||||
params: {},
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method) {
|
||||
assert.step(args.method);
|
||||
}
|
||||
var result = this._super.apply(this, arguments);
|
||||
if (args.method === 'message_fetch') {
|
||||
discuss.destroy();
|
||||
}
|
||||
return result;
|
||||
},
|
||||
});
|
||||
|
||||
assert.verifySteps([
|
||||
"load_views",
|
||||
"message_fetch"
|
||||
]);
|
||||
|
||||
testUtils.mock.unpatch(Discuss);
|
||||
});
|
||||
|
||||
QUnit.test('do not crash when destroyed between start en end of _renderSearchView', function (assert) {
|
||||
assert.expect(2);
|
||||
var discuss;
|
||||
|
||||
testUtils.mock.patch(Discuss, {
|
||||
init: function () {
|
||||
discuss = this;
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
var def = $.Deferred();
|
||||
|
||||
testUtils.mock.patch(SearchView, {
|
||||
willStart: function () {
|
||||
var result = this._super.apply(this, arguments);
|
||||
return def.then($.when(result));
|
||||
},
|
||||
});
|
||||
|
||||
createDiscuss({
|
||||
id: 1,
|
||||
context: {},
|
||||
params: {},
|
||||
data: this.data,
|
||||
services: this.services,
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method) {
|
||||
assert.step(args.method);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
discuss.destroy();
|
||||
def.resolve();
|
||||
assert.verifySteps([
|
||||
"load_views",
|
||||
]);
|
||||
|
||||
testUtils.mock.unpatch(Discuss);
|
||||
testUtils.mock.unpatch(SearchView);
|
||||
});
|
||||
|
||||
QUnit.test('confirm dialog when administrator leave (not chat) channel', function (assert) {
|
||||
assert.expect(2);
|
||||
var done = assert.async();
|
||||
|
||||
@@ -8,7 +8,7 @@ var MailService = require('mail.Service');
|
||||
|
||||
var AbstractStorageService = require('web.AbstractStorageService');
|
||||
var Class = require('web.Class');
|
||||
var ControlPanel = require('web.ControlPanel');
|
||||
var ControlPanelView = require('web.ControlPanelView');
|
||||
var RamStorage = require('web.RamStorage');
|
||||
var testUtils = require('web.test_utils');
|
||||
var Widget = require('web.Widget');
|
||||
@@ -37,10 +37,7 @@ function createDiscuss(params) {
|
||||
};
|
||||
testUtils.mock.addMockEnvironment(parent, params);
|
||||
var discuss = new Discuss(parent, params);
|
||||
discuss.set_cp_bus(new Widget());
|
||||
var selector = params.debug ? 'body' : '#qunit-fixture';
|
||||
var controlPanel = new ControlPanel(parent);
|
||||
controlPanel.appendTo($(selector));
|
||||
|
||||
// override 'destroy' of discuss so that it calls 'destroy' on the parent
|
||||
// instead, which is the parent of discuss and the mockServer.
|
||||
@@ -51,9 +48,6 @@ function createDiscuss(params) {
|
||||
parent.destroy();
|
||||
};
|
||||
|
||||
// link the view to the control panel
|
||||
discuss.set_cp_bus(controlPanel.get_bus());
|
||||
|
||||
return discuss.appendTo($(selector)).then(function () {
|
||||
return discuss;
|
||||
});
|
||||
|
||||
@@ -493,7 +493,7 @@ QUnit.test('do not autofocus chat window on receiving new direct message', funct
|
||||
}
|
||||
});
|
||||
|
||||
var $formInput = form.$('input');
|
||||
var $formInput = form.$('input[name=display_name]');
|
||||
$formInput.focus();
|
||||
|
||||
assert.equal(document.activeElement, $formInput[0],
|
||||
|
||||
@@ -34,7 +34,7 @@ var MrpBomReport = stock_report_generic.extend({
|
||||
set_html: function() {
|
||||
var self = this;
|
||||
return this._super().then(function () {
|
||||
self.$el.html(self.data.lines);
|
||||
self.$('.o_content').html(self.data.lines);
|
||||
self.renderSearch();
|
||||
self.update_cp();
|
||||
});
|
||||
@@ -103,7 +103,7 @@ var MrpBomReport = stock_report_generic.extend({
|
||||
$searchview_buttons: this.$searchView
|
||||
},
|
||||
};
|
||||
return this.update_control_panel(status);
|
||||
return this.updateControlPanel(status);
|
||||
},
|
||||
renderSearch: function () {
|
||||
this.$buttonPrint = $(QWeb.render('mrp.button'));
|
||||
@@ -187,7 +187,7 @@ var MrpBomReport = stock_report_generic.extend({
|
||||
_reload: function () {
|
||||
var self = this;
|
||||
return this.get_html().then(function () {
|
||||
self.$el.html(self.data.lines);
|
||||
self.$('.o_content').html(self.data.lines);
|
||||
self._reload_report_type();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -2,16 +2,15 @@ odoo.define('sale_timesheet.ProjectPlan', function (require) {
|
||||
'use strict';
|
||||
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var core = require('web.core');
|
||||
var data = require('web.data');
|
||||
var pyUtils = require('web.py_utils');
|
||||
var SearchView = require('web.SearchView');
|
||||
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
|
||||
var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
var ProjectPlan = AbstractAction.extend({
|
||||
custom_events: {
|
||||
search: '_onSearch',
|
||||
},
|
||||
events: {
|
||||
"click a[type='action']": "_onClickAction",
|
||||
"click .o_timesheet_plan_redirect": '_onRedirect',
|
||||
@@ -19,64 +18,31 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
"click .o_timesheet_plan_non_billable_task": "_onClickNonBillableTask",
|
||||
"click .o_timesheet_plan_sale_timesheet_people_time .progress-bar": '_onClickEmployeeProgressbar',
|
||||
},
|
||||
hasControlPanel: true,
|
||||
loadControlPanel: true,
|
||||
withSearchBar: true,
|
||||
searchMenuTypes: ['filter', 'favorite'],
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function (parent, action) {
|
||||
init: function (parent, action) {
|
||||
this._super.apply(this, arguments);
|
||||
this.action = action;
|
||||
this.context = action.context;
|
||||
this.action_manager = parent;
|
||||
this.set('title', action.name || _t('Overview'));
|
||||
this._title = action.name || _t('Overview');
|
||||
this.project_ids = [];
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
var view_id = this.action && this.action.search_view_id && this.action.search_view_id[0];
|
||||
var def = this
|
||||
.loadViews('project.project', this.action.context || {}, [[view_id, 'search']])
|
||||
.then(function (result) {
|
||||
self.fields_view = result.search;
|
||||
});
|
||||
return $.when(this._super(), def);
|
||||
|
||||
this.controlPanelParams.modelName = 'project.project';
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var self = this;
|
||||
|
||||
// find default search from context
|
||||
var search_defaults = {};
|
||||
var context = this.action.context || [];
|
||||
_.each(context, function (value, key) {
|
||||
var match = /^search_default_(.*)$/.exec(key);
|
||||
if (match) {
|
||||
search_defaults[match[1]] = value;
|
||||
}
|
||||
});
|
||||
|
||||
// create searchview
|
||||
var options = {
|
||||
$buttons: $("<div>"),
|
||||
action: this.action,
|
||||
disable_groupby: true,
|
||||
search_defaults: search_defaults,
|
||||
};
|
||||
|
||||
var dataset = new data.DataSetSearch(this, 'project.project');
|
||||
this.searchview = new SearchView(this, dataset, this.fields_view, options);
|
||||
this.searchview.on('search', this, this._onSearch);
|
||||
|
||||
var def1 = this._super.apply(this, arguments);
|
||||
var def2 = this.searchview.appendTo($("<div>")).then(function () {
|
||||
self.$searchview_buttons = self.searchview.$buttons.contents();
|
||||
});
|
||||
|
||||
return $.when(def1, def2).then(function(){
|
||||
self.searchview.do_search();
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
// TODO: maybe not the correct way
|
||||
return self._controlPanel._reportNewQueryAndRender();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -89,7 +55,7 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
do_show: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.searchview.do_search();
|
||||
this._updateControlPanel();
|
||||
this.action_manager.do_push_state({
|
||||
action: this.action.id,
|
||||
active_id: this.action.context.active_id,
|
||||
@@ -107,7 +73,7 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
* @param {string|html} dom
|
||||
*/
|
||||
_refreshPlan: function (dom) {
|
||||
this.$el.html(dom);
|
||||
this.$('.o_content').html(dom);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -136,17 +102,14 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
if (this.$buttons) {
|
||||
this.$buttons.off().destroy();
|
||||
}
|
||||
var buttons = buttons || [];
|
||||
buttons = buttons || [];
|
||||
this.$buttons = $(QWeb.render("project.plan.ControlButtons", {'buttons': buttons}));
|
||||
this.$buttons.on('click', '.o_timesheet_plan_btn_action', this._onClickControlButton.bind(this));
|
||||
// refresh control panel
|
||||
this.update_control_panel({
|
||||
this.updateControlPanel({
|
||||
cp_content: {
|
||||
$buttons: this.$buttons,
|
||||
$searchview: this.searchview.$el,
|
||||
$searchview_buttons: this.$searchview_buttons,
|
||||
},
|
||||
searchview: this.searchview,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -245,9 +208,9 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
var parameters = {
|
||||
domain: data.domain || [],
|
||||
res_model: data.resModel,
|
||||
}
|
||||
};
|
||||
if (data.resId) {
|
||||
parameters['res_id'] = data.resId;
|
||||
parameters.res_id = data.resId;
|
||||
}
|
||||
return this._rpc({
|
||||
route:"/timesheet/plan/action",
|
||||
@@ -260,8 +223,7 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
* @private
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
_onClickNonBillableTask: function (event) {
|
||||
var self = this;
|
||||
_onClickNonBillableTask: function () {
|
||||
this.do_action({
|
||||
name: _t('Non Billable Tasks'),
|
||||
type: 'ir.actions.act_window',
|
||||
@@ -299,14 +261,7 @@ var ProjectPlan = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
_onSearch: function (event) {
|
||||
event.stopPropagation();
|
||||
var session = this.getSession();
|
||||
// group by are disabled, so we don't take care of them
|
||||
var result = pyUtils.eval_domains_and_contexts({
|
||||
domains: event.data.domains,
|
||||
contexts: [session.user_context].concat(event.data.contexts)
|
||||
});
|
||||
|
||||
this._fetchPlan(result.domain);
|
||||
this._fetchPlan(event.data.domain);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ QUnit.module('Timesheet Plan', {
|
||||
"/web/dataset/call_kw/project.project",
|
||||
"/timesheet/plan"
|
||||
]);
|
||||
assert.strictEqual(plan.$el.text(), 'Banach-Tarski', 'should have rendered html content');
|
||||
assert.strictEqual(plan.get('title'), 'Overview',
|
||||
assert.strictEqual(plan.$('.o_content').text(), 'Banach-Tarski', 'should have rendered html content');
|
||||
assert.strictEqual(plan.$('.o_control_panel .breadcrumb-item').text(), 'Overview',
|
||||
'default title should be set');
|
||||
plan.destroy();
|
||||
});
|
||||
@@ -86,7 +86,7 @@ QUnit.module('Timesheet Plan', {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
assert.strictEqual(plan.get('title'), 'Fibonacci',
|
||||
assert.strictEqual(plan.$('.o_control_panel .breadcrumb-item').text(), 'Fibonacci',
|
||||
'title should be set from the action name');
|
||||
plan.destroy();
|
||||
});
|
||||
|
||||
@@ -4,17 +4,18 @@ odoo.define('stock.stock_report_generic', function (require) {
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var session = require('web.session');
|
||||
var ReportWidget = require('stock.ReportWidget');
|
||||
var framework = require('web.framework');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
|
||||
var stock_report_generic = AbstractAction.extend(ControlPanelMixin, {
|
||||
var stock_report_generic = AbstractAction.extend({
|
||||
hasControlPanel: true,
|
||||
|
||||
// Stores all the parameters of the action.
|
||||
init: function(parent, action) {
|
||||
this._super.apply(this, arguments);
|
||||
this.actionManager = parent;
|
||||
this.given_context = session.user_context;
|
||||
this.controller_url = action.context.url;
|
||||
@@ -26,17 +27,16 @@ var stock_report_generic = AbstractAction.extend(ControlPanelMixin, {
|
||||
this.given_context.ttype = action.context.ttype || false;
|
||||
this.given_context.auto_unfold = action.context.auto_unfold || false;
|
||||
this.given_context.lot_name = action.context.lot_name || false;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
willStart: function() {
|
||||
return this.get_html();
|
||||
return $.when(this._super.apply(this, arguments), this.get_html());
|
||||
},
|
||||
set_html: function() {
|
||||
var self = this;
|
||||
var def = $.when();
|
||||
if (!this.report_widget) {
|
||||
this.report_widget = new ReportWidget(this, this.given_context);
|
||||
def = this.report_widget.appendTo(this.$el);
|
||||
def = this.report_widget.appendTo(this.$('.o_content'));
|
||||
}
|
||||
return def.then(function () {
|
||||
self.report_widget.$el.html(self.html);
|
||||
@@ -78,7 +78,7 @@ var stock_report_generic = AbstractAction.extend(ControlPanelMixin, {
|
||||
var status = {
|
||||
cp_content: {$buttons: this.$buttons},
|
||||
};
|
||||
return this.update_control_panel(status);
|
||||
return this.updateControlPanel(status);
|
||||
},
|
||||
renderButtons: function() {
|
||||
var self = this;
|
||||
|
||||
@@ -11,7 +11,7 @@ var _t = core._t;
|
||||
var apps_client = null;
|
||||
|
||||
var Apps = AbstractAction.extend({
|
||||
template: 'EmptyComponent',
|
||||
contentTemplate: 'EmptyComponent',
|
||||
remote_action_tag: 'loempia.embed',
|
||||
failback_action_id: 'base.open_module_tree',
|
||||
|
||||
@@ -141,7 +141,7 @@ var Apps = AbstractAction.extend({
|
||||
self.on('message:unblockUI', self, function() { framework.unblockUI(); });
|
||||
self.on('message:warn', self, function(m) {self.do_warn(m.title, m.message, m.sticky); });
|
||||
|
||||
self.$ifr.appendTo(self.$el).css(css).addClass('apps-client');
|
||||
self.$ifr.appendTo(self.$('.o_content')).css(css).addClass('apps-client');
|
||||
|
||||
def.resolve();
|
||||
}, function() {
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
}
|
||||
|
||||
.o_control_panel {
|
||||
flex: 0 0 auto;
|
||||
|
||||
.o_panel {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
|
||||
@@ -5,14 +5,13 @@ var AbstractAction = require('web.AbstractAction');
|
||||
var config = require('web.config');
|
||||
var core = require('web.core');
|
||||
var framework = require('web.framework');
|
||||
var session = require('web.session');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
|
||||
var Dashboard = AbstractAction.extend({
|
||||
template: 'DashboardMain',
|
||||
contentTemplate: 'DashboardMain',
|
||||
|
||||
init: function(){
|
||||
this.all_dashboards = ['apps', 'invitations', 'share', 'translations', 'company'];
|
||||
@@ -20,7 +19,8 @@ var Dashboard = AbstractAction.extend({
|
||||
},
|
||||
|
||||
start: function(){
|
||||
return this.load(this.all_dashboards);
|
||||
var superDef = this._super.apply(this, arguments);
|
||||
return $.when(superDef, this.load(this.all_dashboards));
|
||||
},
|
||||
|
||||
load: function(dashboards){
|
||||
|
||||
@@ -10,7 +10,9 @@ var Dashboard = webSettingsDashboard.Dashboard;
|
||||
|
||||
function createDashboard(params) {
|
||||
var widget = new Widget();
|
||||
var dashboard = new Dashboard(widget);
|
||||
// action content not used in tests apparently
|
||||
var action = {};
|
||||
var dashboard = new Dashboard(widget, action);
|
||||
dashboard.all_dashboards = params.dashboards || ['invitations']; // test only user invitations
|
||||
|
||||
testUtils.mock.addMockEnvironment(widget, params);
|
||||
|
||||
@@ -3,7 +3,6 @@ odoo.define('website.backend.dashboard', function (require) {
|
||||
|
||||
var AbstractAction = require('web.AbstractAction');
|
||||
var ajax = require('web.ajax');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var field_utils = require('web.field_utils');
|
||||
@@ -13,8 +12,9 @@ var web_client = require('web.web_client');
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
|
||||
var Dashboard = AbstractAction.extend(ControlPanelMixin, {
|
||||
template: 'website.WebsiteDashboardMain',
|
||||
var Dashboard = AbstractAction.extend({
|
||||
hasControlPanel: true,
|
||||
contentTemplate: 'website.WebsiteDashboardMain',
|
||||
cssLibs: [
|
||||
'/web/static/lib/nvd3/nv.d3.css'
|
||||
],
|
||||
@@ -55,7 +55,6 @@ var Dashboard = AbstractAction.extend(ControlPanelMixin, {
|
||||
return this._super().then(function() {
|
||||
self.update_cp();
|
||||
self.render_graphs();
|
||||
self.$el.parent().addClass('oe_background_grey');
|
||||
});
|
||||
},
|
||||
|
||||
@@ -320,7 +319,7 @@ var Dashboard = AbstractAction.extend(ControlPanelMixin, {
|
||||
self.on_website_button($(ev.target).data('website-id'));
|
||||
});
|
||||
}
|
||||
this.update_control_panel({
|
||||
this.updateControlPanel({
|
||||
cp_content: {
|
||||
$searchview: this.$searchview,
|
||||
$buttons: QWeb.render("website.GoToButtons"),
|
||||
|
||||
Reference in New Issue
Block a user