diff --git a/addons/account/static/src/js/reconciliation/reconciliation_action.js b/addons/account/static/src/js/reconciliation/reconciliation_action.js index 4b097c79d5b..e43667be0e4 100644 --- a/addons/account/static/src/js/reconciliation/reconciliation_action.js +++ b/addons/account/static/src/js/reconciliation/reconciliation_action.js @@ -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 diff --git a/addons/account/static/tests/reconciliation_tests.js b/addons/account/static/tests/reconciliation_tests.js index c97dd86adb3..01645d5c97e 100644 --- a/addons/account/static/tests/reconciliation_tests.js +++ b/addons/account/static/tests/reconciliation_tests.js @@ -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"); diff --git a/addons/base_import/static/src/js/import_action.js b/addons/base_import/static/src/js/import_action.js index c093987bc8e..83259b30252 100644 --- a/addons/base_import/static/src/js/import_action.js +++ b/addons/base_import/static/src/js/import_action.js @@ -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(); diff --git a/addons/hr_attendance/static/src/js/greeting_message.js b/addons/hr_attendance/static/src/js/greeting_message.js index ac5762d7788..064ac919f08 100644 --- a/addons/hr_attendance/static/src/js/greeting_message.js +++ b/addons/hr_attendance/static/src/js/greeting_message.js @@ -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() { diff --git a/addons/hr_attendance/static/src/js/my_attendances.js b/addons/hr_attendance/static/src/js/my_attendances.js index 228f35c1813..4ea44093949 100644 --- a/addons/hr_attendance/static/src/js/my_attendances.js +++ b/addons/hr_attendance/static/src/js/my_attendances.js @@ -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)); diff --git a/addons/hr_attendance/static/tests/hr_attendance_tests.js b/addons/hr_attendance/static/tests/hr_attendance_tests.js index 4038212e8d7..a2bc6d6a6b9 100644 --- a/addons/hr_attendance/static/tests/hr_attendance_tests.js +++ b/addons/hr_attendance/static/tests/hr_attendance_tests.js @@ -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); diff --git a/addons/mail/static/src/js/discuss.js b/addons/mail/static/src/js/discuss.js index 6c2d4b58d26..4370ffb0fd4 100644 --- a/addons/mail/static/src/js/discuss.js +++ b/addons/mail/static/src/js/discuss.js @@ -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: $('
'), - action: this.action, - disable_groupby: true, - }; - this.searchview = new SearchView(this, this.dataset, this.fields_view, options); - return this.alive(this.searchview.appendTo($('
'))) - .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 diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js index 63a498e56d0..2feb23a3c8b 100644 --- a/addons/mail/static/tests/discuss_tests.js +++ b/addons/mail/static/tests/discuss_tests.js @@ -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(); diff --git a/addons/mail/static/tests/helpers/test_utils.js b/addons/mail/static/tests/helpers/test_utils.js index 3b998a88b00..cf63c281c58 100644 --- a/addons/mail/static/tests/helpers/test_utils.js +++ b/addons/mail/static/tests/helpers/test_utils.js @@ -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; }); diff --git a/addons/mail/static/tests/thread_window/basic_thread_window_tests.js b/addons/mail/static/tests/thread_window/basic_thread_window_tests.js index c44df3e8e91..3fc942b506f 100644 --- a/addons/mail/static/tests/thread_window/basic_thread_window_tests.js +++ b/addons/mail/static/tests/thread_window/basic_thread_window_tests.js @@ -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], diff --git a/addons/mrp/static/src/js/mrp_bom_report.js b/addons/mrp/static/src/js/mrp_bom_report.js index 77d57dcf01e..76cd0b53fd8 100644 --- a/addons/mrp/static/src/js/mrp_bom_report.js +++ b/addons/mrp/static/src/js/mrp_bom_report.js @@ -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(); }); }, diff --git a/addons/sale_timesheet/static/src/js/timesheet_plan.js b/addons/sale_timesheet/static/src/js/timesheet_plan.js index 90cbcd98379..7a6de7a3cfe 100644 --- a/addons/sale_timesheet/static/src/js/timesheet_plan.js +++ b/addons/sale_timesheet/static/src/js/timesheet_plan.js @@ -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: $("
"), - 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($("
")).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); }, }); diff --git a/addons/sale_timesheet/static/tests/timesheet_plan_tests.js b/addons/sale_timesheet/static/tests/timesheet_plan_tests.js index ca63776ab6b..c54b892d20e 100644 --- a/addons/sale_timesheet/static/tests/timesheet_plan_tests.js +++ b/addons/sale_timesheet/static/tests/timesheet_plan_tests.js @@ -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(); }); diff --git a/addons/stock/static/src/js/stock_traceability_report_backend.js b/addons/stock/static/src/js/stock_traceability_report_backend.js index 8895243eea4..aee712a38b3 100644 --- a/addons/stock/static/src/js/stock_traceability_report_backend.js +++ b/addons/stock/static/src/js/stock_traceability_report_backend.js @@ -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; diff --git a/addons/web/static/src/js/apps.js b/addons/web/static/src/js/apps.js index c49e4741093..aadcc700984 100644 --- a/addons/web/static/src/js/apps.js +++ b/addons/web/static/src/js/apps.js @@ -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() { diff --git a/addons/web/static/src/scss/base_settings.scss b/addons/web/static/src/scss/base_settings.scss index 436298872da..82137b00948 100644 --- a/addons/web/static/src/scss/base_settings.scss +++ b/addons/web/static/src/scss/base_settings.scss @@ -23,6 +23,8 @@ } .o_control_panel { + flex: 0 0 auto; + .o_panel { display: flex; flex-flow: row wrap; diff --git a/addons/web_settings_dashboard/static/src/js/dashboard.js b/addons/web_settings_dashboard/static/src/js/dashboard.js index 01af7071c09..a51b5c173b5 100644 --- a/addons/web_settings_dashboard/static/src/js/dashboard.js +++ b/addons/web_settings_dashboard/static/src/js/dashboard.js @@ -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){ diff --git a/addons/web_settings_dashboard/static/tests/dashboard_tests.js b/addons/web_settings_dashboard/static/tests/dashboard_tests.js index f19e98e8420..46c85126541 100644 --- a/addons/web_settings_dashboard/static/tests/dashboard_tests.js +++ b/addons/web_settings_dashboard/static/tests/dashboard_tests.js @@ -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); diff --git a/addons/website/static/src/js/backend/dashboard.js b/addons/website/static/src/js/backend/dashboard.js index 1a83e8dc39a..1cf4ef94c71 100644 --- a/addons/website/static/src/js/backend/dashboard.js +++ b/addons/website/static/src/js/backend/dashboard.js @@ -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"),