diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-08-30 17:20:28 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-08-30 17:20:28 +0200 |
| commit | 545e6d20344f37081ccd6c6e788ea1c5383717af (patch) | |
| tree | 7786f6001919ea18792c35c4f769336ef991fd3a /addons/web/static | |
| parent | 513545cdbdf95ae61c068270ab61eec8b81c9bd8 (diff) | |
| parent | 52f6e38cea8ff9d16ab3432b3ccf032472e5a666 (diff) | |
[MERGE] forward port branch 12.0 up to 52f6e38cea8
Diffstat (limited to 'addons/web/static')
| -rw-r--r-- | addons/web/static/src/js/fields/relational_fields.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_view.js | 4 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/graph/graph_view.js | 3 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/auto_complete.js | 12 | ||||
| -rw-r--r-- | addons/web/static/src/scss/ui.scss | 8 | ||||
| -rw-r--r-- | addons/web/static/tests/helpers/mock_server.js | 15 | ||||
| -rw-r--r-- | addons/web/static/tests/views/form_tests.js | 35 | ||||
| -rw-r--r-- | addons/web/static/tests/views/graph_tests.js | 21 | ||||
| -rw-r--r-- | addons/web/static/tests/views/view_dialogs_tests.js | 6 |
9 files changed, 98 insertions, 8 deletions
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 13e58095d40..8155f9d56f1 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -2418,7 +2418,7 @@ var FieldStatus = AbstractField.extend({ var FieldSelection = AbstractField.extend({ template: 'FieldSelection', specialData: "_fetchSpecialRelation", - supportedFieldTypes: ['selection', 'many2one'], + supportedFieldTypes: ['selection'], events: _.extend({}, AbstractField.prototype.events, { 'change': '_onChange', }), diff --git a/addons/web/static/src/js/views/form/form_view.js b/addons/web/static/src/js/views/form/form_view.js index 0703d9713d5..4889a27f9e5 100644 --- a/addons/web/static/src/js/views/form/form_view.js +++ b/addons/web/static/src/js/views/form/form_view.js @@ -127,6 +127,10 @@ var FormView = BasicView.extend({ var refinedContext = _.pick(self.loadParams.context, function (value, key) { return key.indexOf('_view_ref') === -1; }); + // Specify the main model to prevent access rights defined in the context + // (e.g. create: 0) to apply to subviews. We use here the same logic as + // the one applied by the server for inline views. + refinedContext.base_model_name = self.controllerParams.modelName; defs.push(parent.loadViews( field.relation, new Context(context, self.userContext, refinedContext).eval(), diff --git a/addons/web/static/src/js/views/graph/graph_view.js b/addons/web/static/src/js/views/graph/graph_view.js index f953c488a09..2e622d9a47a 100644 --- a/addons/web/static/src/js/views/graph/graph_view.js +++ b/addons/web/static/src/js/views/graph/graph_view.js @@ -48,6 +48,9 @@ var GraphView = AbstractView.extend({ this.arch.children.forEach(function (field) { var fieldName = field.attrs.name; + if (fieldName === "id") { + return; + } var interval = field.attrs.interval; if (interval) { fieldName = fieldName + ':' + interval; diff --git a/addons/web/static/src/js/widgets/auto_complete.js b/addons/web/static/src/js/widgets/auto_complete.js index 4da54cf8b5c..1bb00be8d38 100644 --- a/addons/web/static/src/js/widgets/auto_complete.js +++ b/addons/web/static/src/js/widgets/auto_complete.js @@ -140,12 +140,22 @@ return Widget.extend({ var $item = self.make_list_item(result).appendTo($list); result.$el = $item; }); + // IE9 doesn't support addEventListener with option { once: true } + this.el.onmousemove = function (ev) { + self.$('li').each(function (index, li) { + li.onmouseenter = self.focus_element.bind(self, $(li)); + }); + var targetFocus = ev.target.tagName === 'LI' ? + ev.target : + ev.target.closest('li'); + self.focus_element($(targetFocus)); + self.el.onmousemove = null; + }; this.show(); }, make_list_item: function (result) { var self = this; var $li = $('<li>') - .hover(function () {self.focus_element($li);}) .mousedown(function (ev) { if (ev.button === 0) { // left button self.select(ev, {item: {facet: result.facet}}); diff --git a/addons/web/static/src/scss/ui.scss b/addons/web/static/src/scss/ui.scss index 44d639805be..9ab1729a4ac 100644 --- a/addons/web/static/src/scss/ui.scss +++ b/addons/web/static/src/scss/ui.scss @@ -83,3 +83,11 @@ .o_debounce_disabled { pointer-events: none; } + +span.o_force_ltr { + display: inline-block; +} +.o_force_ltr, .o_field_phone { + /*rtl:ignore*/ + direction: ltr; +} diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index e276b5da5b6..f373cd710e5 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -85,7 +85,7 @@ var MockServer = Class.extend({ throw new Error('Model ' + model + ' was not defined in mock server data'); } var fields = $.extend(true, {}, this.data[model].fields); - var fvg = this._fieldsViewGet(params.arch, model, fields, viewOptions.context); + var fvg = this._fieldsViewGet(params.arch, model, fields, viewOptions.context || {}); if (toolbar) { fvg.toolbar = toolbar; } @@ -214,6 +214,17 @@ var MockServer = Class.extend({ var inTreeView = (doc.tagName === 'tree'); + // mock _postprocess_access_rights + const isBaseModel = !context.base_model_name || (model === context.base_model_name); + var views = ['kanban', 'tree', 'form', 'gantt', 'activity']; + if (isBaseModel && views.indexOf(doc.tagName) !== -1) { + for (let action of ['create', 'delete', 'edit', 'write']) { + if (!doc.getAttribute(action) && action in context && !context[action]) { + doc.setAttribute(action, 'false'); + } + } + } + this._traverse(doc, function (node) { if (node.nodeType === Node.TEXT_NODE) { return false; @@ -318,7 +329,7 @@ var MockServer = Class.extend({ relModel = field.relation; relFields = $.extend(true, {}, self.data[relModel].fields); field.views[children.tagName] = self._fieldsViewGet(children, relModel, - relFields, context); + relFields, _.extend({}, context, {base_model_name: model})); }); } diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index 2c5eaa3e627..d89bffac31b 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -459,8 +459,10 @@ QUnit.module('Views', { 'The correct _view_ref should have been sent to the server, first time'); } if (args.model === 'partner_type') { - assert.deepEqual(context, {tree_view_ref: 'some_other_tree_view'}, - 'The correct _view_ref should have been sent to the server for the subview'); + assert.deepEqual(context, { + base_model_name: 'product', + tree_view_ref: 'some_other_tree_view', + }, 'The correct _view_ref should have been sent to the server for the subview'); } } return this._super.apply(this, arguments); @@ -4568,6 +4570,35 @@ QUnit.module('Views', { }); }); + QUnit.test('non inline subview and create=0 in action context', async function (assert) { + // the create=0 should apply on the main view (form), but not on subviews + assert.expect(2); + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form><field name="product_ids" mode="kanban"/></form>', + archs: { + "product,false,kanban": `<kanban> + <templates><t t-name="kanban-box"> + <div><field name="name"/></div> + </t></templates> + </kanban>`, + }, + res_id: 1, + viewOptions: { + context: {create: false}, + mode: 'edit', + }, + }); + + assert.containsNone(form, '.o_form_button_create'); + assert.containsOnce(form, '.o-kanban-button-new'); + + form.destroy(); + }); + QUnit.test('readonly fields with modifiers may be saved', async function (assert) { // the readonly property on the field description only applies on view, // this is not a DB constraint. It should be seen as a default value, diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js index ca969fb9ac9..a179c265ca1 100644 --- a/addons/web/static/tests/views/graph_tests.js +++ b/addons/web/static/tests/views/graph_tests.js @@ -176,6 +176,27 @@ QUnit.module('Views', { graph.destroy(); }); + QUnit.test('field id not in groupBy', async function (assert) { + assert.expect(1); + + var graph = await createView({ + View: GraphView, + model: "foo", + data: this.data, + arch: '<graph string="Partners">' + + '<field name="id"/>' + + '</graph>', + mockRPC: function (route, args) { + if (args.method === 'read_group') { + assert.deepEqual(args.kwargs.groupby, [], + 'groupby should not contain id field'); + } + return this._super.apply(this, arguments); + } + }); + graph.destroy(); + }); + QUnit.test('switching mode', async function (assert) { assert.expect(6); diff --git a/addons/web/static/tests/views/view_dialogs_tests.js b/addons/web/static/tests/views/view_dialogs_tests.js index 9dd78f3b724..8e64c191467 100644 --- a/addons/web/static/tests/views/view_dialogs_tests.js +++ b/addons/web/static/tests/views/view_dialogs_tests.js @@ -411,8 +411,10 @@ QUnit.module('Views', { 'The correct _view_ref should have been sent to the server, first time'); } if (ev.data.modelName === 'badassery') { - assert.deepEqual(evaluatedContext, {tree_view_ref: 'some_other_tree_view'}, - 'The correct _view_ref should have been sent to the server for the subview'); + assert.deepEqual(evaluatedContext, { + base_model_name: 'instrument', + tree_view_ref: 'some_other_tree_view', + }, 'The correct _view_ref should have been sent to the server for the subview'); } }, }, |
