diff options
Diffstat (limited to 'addons/web/static')
| -rw-r--r-- | addons/web/static/lib/qweb/qweb-test-extend.xml | 8 | ||||
| -rw-r--r-- | addons/web/static/lib/qweb/qweb2.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_controller.js | 16 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_model.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/control_panel/search/search_bar.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/auto_complete.js | 12 | ||||
| -rw-r--r-- | addons/web/static/src/scss/form_view.scss | 4 | ||||
| -rw-r--r-- | addons/web/static/src/scss/layout_background.scss | 3 | ||||
| -rw-r--r-- | addons/web/static/src/scss/list_view.scss | 1 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/relational_fields_tests.js | 36 | ||||
| -rw-r--r-- | addons/web/static/tests/views/calendar_tests.js | 1 | ||||
| -rw-r--r-- | addons/web/static/tests/views/form_tests.js | 39 |
12 files changed, 113 insertions, 12 deletions
diff --git a/addons/web/static/lib/qweb/qweb-test-extend.xml b/addons/web/static/lib/qweb/qweb-test-extend.xml index 007caefe383..dfd0ec46940 100644 --- a/addons/web/static/lib/qweb/qweb-test-extend.xml +++ b/addons/web/static/lib/qweb/qweb-test-extend.xml @@ -18,13 +18,19 @@ <t t-jquery="ul">this.attr('class', 'main');</t> </t> <t t-extend="jquery-extend"> + <t t-jquery="ul" t-operation="attributes"><attribute name="title" value="Main Title" /></t> + </t> + <t t-extend="jquery-extend"> + <t t-jquery="ul" t-operation="attributes"><attribute name="name">main-ul</attribute></t> + </t> + <t t-extend="jquery-extend"> <t t-jquery="hr:eq(1)" t-operation="replace"><footer></footer></t> </t> <t t-extend="jquery-extend"> <t t-jquery="footer" t-operation="inner"><b>[[end]]</b></t> </t> <result id="jquery-extend"><![CDATA[ - <hr/><ul class="main"><li>1</li><li>2</li><li>3</li></ul><footer><b>[[end]]</b></footer> + <hr/><ul class="main" title="Main Title" name="main-ul"><li>1</li><li>2</li><li>3</li></ul><footer><b>[[end]]</b></footer> ]]></result> <t t-name="jquery-extend-clone" t-extend="jquery-extend"> diff --git a/addons/web/static/lib/qweb/qweb2.js b/addons/web/static/lib/qweb/qweb2.js index d0297ee12e5..72e65f985a8 100644 --- a/addons/web/static/lib/qweb/qweb2.js +++ b/addons/web/static/lib/qweb/qweb2.js @@ -513,7 +513,7 @@ QWeb2.Engine = (function() { if (operation === 'attributes') { jQuery('attribute', child).each(function () { var attrib = jQuery(this); - target.attr(attrib.attr('name'), attrib.text()); + target.attr(attrib.attr('name'), attrib.text() || attrib.attr('value')); }); } else { target[operation](child.cloneNode(true).childNodes); diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js index f26a9cbe737..07646c83273 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -188,12 +188,18 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { // mutex-protected as commitChanges function of x2m has to be aware of // all final changes made to a row. var self = this; - this.savingDef = this.mutex.getUnlockedDef().then(function () { - return self.renderer.commitChanges(recordID || self.handle).then(function () { + var savingDef = $.Deferred(); + this.savingDef = savingDef; + + return this.mutex.getUnlockedDef() + .then(function () { + return self.renderer.commitChanges(recordID || self.handle); + }) + .then(function () { return self.mutex.exec(self._saveRecord.bind(self, recordID, options)); - }); - }); - return this.savingDef; + }) + .then(savingDef.resolve.bind(savingDef)) + .fail(savingDef.resolve.bind(savingDef)); }, /** * @override diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 1bd0782bd36..3e20035734d 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -2480,7 +2480,7 @@ var BasicModel = AbstractModel.extend({ if (field.type === 'many2one' && !record.fieldsInfo[record.viewType][name].__no_fetch) { var localId = (record._changes && record._changes[name]) || record.data[name]; var relatedRecord = self.localData[localId]; - if (!relatedRecord) { + if (!relatedRecord || relatedRecord.data.display_name) { return; } toBeFetched.push({ diff --git a/addons/web/static/src/js/views/control_panel/search/search_bar.js b/addons/web/static/src/js/views/control_panel/search/search_bar.js index 7f0feda4516..77d6d7fa5e9 100644 --- a/addons/web/static/src/js/views/control_panel/search/search_bar.js +++ b/addons/web/static/src/js/views/control_panel/search/search_bar.js @@ -142,6 +142,7 @@ var SearchBar = Widget.extend({ var self = this; this._setupAutoCompletionWidgets(); this.autoComplete = new AutoComplete(this, { + $input: this.$('input'), source: this._getAutoCompleteSources.bind(this), select: this._onAutoCompleteSelected.bind(this), get_search_string: function () { diff --git a/addons/web/static/src/js/widgets/auto_complete.js b/addons/web/static/src/js/widgets/auto_complete.js index 33405aa4196..6dd78f8f730 100644 --- a/addons/web/static/src/js/widgets/auto_complete.js +++ b/addons/web/static/src/js/widgets/auto_complete.js @@ -19,7 +19,7 @@ return Widget.extend({ // to obtain the current search string. init: function (parent, options) { this._super(parent); - this.$input = parent.$el; + this.$input = options.$input; this.source = options.source; this.select = options.select; this.get_search_string = options.get_search_string; @@ -90,14 +90,24 @@ return Widget.extend({ ev.preventDefault(); break; case $.ui.keyCode.RIGHT: + if(self.$input[0].selectionStart < self.search_string.length) { + ev.stopPropagation(); + return; + } self.searching = false; var current = self.current_result; if (current && current.expand && !current.expanded) { self.expand(); self.searching = true; + ev.stopPropagation(); } ev.preventDefault(); break; + case $.ui.keyCode.LEFT: + if(self.$input[0].selectionStart > 0) { + ev.stopPropagation(); + } + break; case $.ui.keyCode.ESCAPE: self.close(); self.searching = false; diff --git a/addons/web/static/src/scss/form_view.scss b/addons/web/static/src/scss/form_view.scss index 697ec4dcd12..5642e656dea 100644 --- a/addons/web/static/src/scss/form_view.scss +++ b/addons/web/static/src/scss/form_view.scss @@ -378,8 +378,8 @@ clear: both; // For the notebook not to have alongside floating elements margin-top: $o-form-spacing-unit * 2; - .nav-tabs > .tab-pane { - min-height: 100px; + .tab-content > .tab-pane { + padding: $o-horizontal-padding 0; } } diff --git a/addons/web/static/src/scss/layout_background.scss b/addons/web/static/src/scss/layout_background.scss index 9c47ac72a27..9b137fde8c1 100644 --- a/addons/web/static/src/scss/layout_background.scss +++ b/addons/web/static/src/scss/layout_background.scss @@ -18,6 +18,9 @@ } } .o_background_footer { + .list-inline-item { + white-space: nowrap; + } ul { border-top: 1px solid $o-brand-odoo; border-bottom: 1px solid $o-brand-odoo; diff --git a/addons/web/static/src/scss/list_view.scss b/addons/web/static/src/scss/list_view.scss index 770508ac1b8..85b9b9f6f07 100644 --- a/addons/web/static/src/scss/list_view.scss +++ b/addons/web/static/src/scss/list_view.scss @@ -52,7 +52,6 @@ } &:not(:empty)::after { margin-left: 6px; - position: absolute; } &.o-sort-up { cursor: n-resize; diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 463effad124..faf3df6f2e8 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -205,6 +205,42 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('do not call name_get if display_name already known', function (assert) { + // default_get only returns the id for many2one fields + // onchange returns an array with the id and the display_name + // thus, when an onchange is performed, there is no need to call + // name_get as the display_name is alreay available + assert.expect(6); + + this.data.partner.fields.product_id.default = 37; + this.data.partner.onchanges = { + trululu: function (obj) { + obj.trululu = [1, 'first record']; + }, + }; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form><field name="trululu"/><field name="product_id"/></form>', + mockRPC: function (route, args) { + assert.step(args.method + ' on ' + args.model); + return this._super.apply(this, arguments); + }, + }); + + assert.strictEqual(form.$('.o_field_widget[name=trululu] input').val(), 'first record'); + assert.strictEqual(form.$('.o_field_widget[name=product_id] input').val(), 'xphone'); + assert.verifySteps([ + 'default_get on partner', + 'onchange on partner', + 'name_get on product', + ]); + + form.destroy(); + }); + QUnit.test('x2many default_order multiple fields', function (assert) { assert.expect(7); diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js index debba8d550c..9e0e7dc1e84 100644 --- a/addons/web/static/tests/views/calendar_tests.js +++ b/addons/web/static/tests/views/calendar_tests.js @@ -7,6 +7,7 @@ var Dialog = require('web.Dialog'); var fieldUtils = require('web.field_utils'); var mixins = require('web.mixins'); var testUtils = require('web.test_utils'); +var time = require('web.time'); var session = require('web.session'); var createActionManager = testUtils.createActionManager; diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 480f42a3587..a8dc874a5ae 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -105,6 +105,14 @@ QUnit.module('Views', { ] }, }; + + this.actions = [{ + id: 1, + name: 'Partners Action 1', + res_model: 'partner', + type: 'ir.actions.act_window', + views: [[false, 'kanban'], [false, 'form']], + }]; } }, function () { @@ -7406,6 +7414,37 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('discard after a failed save', function (assert) { + assert.expect(2); + + var actionManager = createActionManager({ + data: this.data, + archs: { + 'partner,false,form': '<form>' + + '<field name="date" required="true"/>' + + '<field name="foo" required="true"/>' + + '</form>', + 'partner,false,kanban': '<kanban><templates><t t-name="kanban-box">' + + '</t></templates></kanban>', + 'partner,false,search': '<search></search>', + }, + actions: this.actions, + }); + + actionManager.doAction(1); + + testUtils.dom.click('.o_control_panel .o-kanban-button-new'); + + //cannot save because there is a required field + testUtils.dom.click('.o_control_panel .o_form_button_save'); + testUtils.dom.click('.o_control_panel .o_form_button_cancel'); + + assert.containsNone(actionManager, '.o_form_view'); + assert.containsOnce(actionManager, '.o_kanban_view'); + + actionManager.destroy(); + }); + QUnit.test("one2many create record dialog shouldn't have a 'remove' button", function (assert) { assert.expect(2); |
