diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-11-10 14:15:02 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-11-10 14:15:02 +0100 |
| commit | ebb6d1e7402e7360f84730a400983d513e0d8607 (patch) | |
| tree | a135d3b130f4dadbf721b8bbbc31c14c8d0b93f2 /addons/web/static/src | |
| parent | d86da5de53ab8ffc089b7d86a920e536bd65dff9 (diff) | |
| parent | 350973ff36619bec129a3dace312ec0ae561c55e (diff) | |
[MERGE] forward port branch 11.0 up to 350973ff366
Diffstat (limited to 'addons/web/static/src')
11 files changed, 61 insertions, 30 deletions
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 2d2a5d5ea4d..e5a7cc3da2f 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -503,9 +503,11 @@ var FieldMany2One = AbstractField.extend({ title: _t("Open: ") + self.string, view_id: view_id, readonly: !self.can_write, - on_saved: function () { - self._setValue(self.value.data, {forceChange: true}); - self.trigger_up('reload', {db_id: self.value.id}); + on_saved: function (record, changed) { + if (changed) { + self._setValue(self.value.data, {forceChange: true}); + self.trigger_up('reload', {db_id: self.value.id}); + } }, }).open(); }); diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js index 32d526e160d..e99f9ebb6f2 100644 --- a/addons/web/static/src/js/services/data_manager.js +++ b/addons/web/static/src/js/services/data_manager.js @@ -424,7 +424,7 @@ return core.Class.extend({ var deps = fieldsInfo[node.attrs.name].fieldDependencies; for (var dependency_name in deps) { if (!(dependency_name in fieldsInfo)) { - fieldsInfo[dependency_name] = {'name': dependency_name, 'type': deps[dependency_name].type}; + fieldsInfo[dependency_name] = {'name': dependency_name, 'type': deps[dependency_name].type, 'options': deps[dependency_name].options || {}}; } } } 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 4412d29c455..4028bff322a 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -896,6 +896,9 @@ var BasicModel = AbstractModel.extend({ return def.resolve(changedFields); } + def.then(function () { + record._isDirty = false; + }); // in the case of a write, only perform the RPC if there are changes to save if (method === 'create' || changedFields.length) { var args = method === 'write' ? [[record.data.id], changes] : [changes]; @@ -917,7 +920,6 @@ var BasicModel = AbstractModel.extend({ // Erase changes as they have been applied record._changes = {}; - record._isDirty = false; // Update the data directly or reload them if (shouldReload) { @@ -947,8 +949,8 @@ var BasicModel = AbstractModel.extend({ */ addFieldsInfo: function (recordID, viewInfo) { var record = this.localData[recordID]; - record.fields = _.defaults(record.fields, viewInfo.fields); - record.fieldsInfo = _.defaults(record.fieldsInfo, viewInfo.fieldsInfo); + record.fields = _.extend({}, record.fields, viewInfo.fields); + record.fieldsInfo = _.extend({}, record.fieldsInfo, viewInfo.fieldsInfo); }, /** * Manually sets a resource as dirty. This is used to notify that a field diff --git a/addons/web/static/src/js/views/basic/basic_view.js b/addons/web/static/src/js/views/basic/basic_view.js index bdc250011f0..8a91e2b90c7 100644 --- a/addons/web/static/src/js/views/basic/basic_view.js +++ b/addons/web/static/src/js/views/basic/basic_view.js @@ -47,7 +47,10 @@ var BasicView = AbstractView.extend({ this.loadParams.context = params.context || {}; this.loadParams.limit = parseInt(viewInfo.arch.attrs.limit, 10) || params.limit; this.loadParams.viewType = this.viewType; + this.loadParams.parentID = params.parentID; this.recordID = params.recordID; + + this.model = params.model; }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/views/calendar/calendar_renderer.js b/addons/web/static/src/js/views/calendar/calendar_renderer.js index f011a24a32e..6283a3539f3 100644 --- a/addons/web/static/src/js/views/calendar/calendar_renderer.js +++ b/addons/web/static/src/js/views/calendar/calendar_renderer.js @@ -355,7 +355,7 @@ return AbstractRenderer.extend({ }, // Dirty hack to ensure a correct first render eventAfterAllRender: function () { - window.dispatchEvent(new Event('resize')); + $(window).trigger('resize'); }, viewRender: function (view) { // compute mode from view.name which is either 'month', 'agendaWeek' or 'agendaDay' 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 b48a5488848..42cf5de12e4 100644 --- a/addons/web/static/src/js/views/form/form_view.js +++ b/addons/web/static/src/js/views/form/form_view.js @@ -27,7 +27,6 @@ var FormView = BasicView.extend({ var mode = params.mode || (params.currentId ? 'readonly' : 'edit'); this.loadParams.type = 'record'; - this.loadParams.parentID = params.parentID; this.controllerParams.disableAutofocus = params.disable_autofocus; this.controllerParams.hasSidebar = params.sidebar; @@ -41,7 +40,6 @@ var FormView = BasicView.extend({ this.controllerParams.mode = mode; this.rendererParams.mode = mode; - this.model = params.model; }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js index 460ad5de100..67cc6271509 100644 --- a/addons/web/static/src/js/views/list/list_controller.js +++ b/addons/web/static/src/js/views/list/list_controller.js @@ -355,8 +355,8 @@ var ListController = BasicController.extend({ // trigger a click on the main bus, which would be then caught by the // list editable renderer and would unselect the newly created row event.stopPropagation(); - - if (this.editable) { + var state = this.model.get(this.handle, {raw: true}); + if (this.editable && !state.groupedBy.length) { this._addRecord(); } else { this.trigger_up('switch_view', {view_type: 'form', res_id: undefined}); diff --git a/addons/web/static/src/js/views/view_dialogs.js b/addons/web/static/src/js/views/view_dialogs.js index fe38fae753e..a33f6f740b8 100644 --- a/addons/web/static/src/js/views/view_dialogs.js +++ b/addons/web/static/src/js/views/view_dialogs.js @@ -81,9 +81,9 @@ var FormViewDialog = ViewDialog.extend({ * @param {Object} [options.fields_view] optional form fields_view * @param {boolean} [options.readonly=false] only applicable when not in * creation mode - * @param {function} [options.on_save] callback to execute when clicking on - * 'Save' (form view's 'saveRecord' by default) - * @param {function} [options.on_saved] callback executed after on_save + * @param {function} [options.on_saved] callback executed after saving a + * record. It will be called with the record data, and a boolean which + * indicates if something was changed * @param {BasicModel} [options.model] if given, it will be used instead of * a new form view model * @param {string} [options.recordID] if given, the model has to be given as @@ -214,24 +214,16 @@ var FormViewDialog = ViewDialog.extend({ _save: function () { var self = this; - var def; - if (this.options.on_save) { - if (this.form_view.canBeSaved()) { - return $.Deferred().reject(); - } - def = this.options.on_save(this.form_view.model.get(this.form_view.handle)); - } else { - def = this.form_view.saveRecord(this.form_view.handle, { + return this.form_view.saveRecord(this.form_view.handle, { stayInEdit: true, reload: false, savePoint: this.shouldSaveLocally, viewType: 'form', - }); - } - return $.when(def).then(function () { + }).then(function (changedFields) { // record might have been changed by the save (e.g. if this was a new record, it has an // id now), so don't re-use the copy obtained before the save - self.on_saved(self.form_view.model.get(self.form_view.handle)); + var record = self.form_view.model.get(self.form_view.handle); + self.on_saved(record, !!changedFields.length); }); }, }); @@ -402,7 +394,8 @@ var SelectCreateDialog = ViewDialog.extend({ var results = pyeval.eval_domains_and_contexts({ domains: [this.domain].concat(domains), contexts: [this.context].concat(contexts), - group_by_seq: groupbys || [] + group_by_seq: groupbys || [], + eval_context: this.getSession().user_context, }); var context = _.omit(results.context, function (value, key) { return key.indexOf('search_default_') === 0; }); return { diff --git a/addons/web/static/src/js/widgets/debug_manager.js b/addons/web/static/src/js/widgets/debug_manager.js index a0edf9dba28..4160d6f554b 100644 --- a/addons/web/static/src/js/widgets/debug_manager.js +++ b/addons/web/static/src/js/widgets/debug_manager.js @@ -7,7 +7,6 @@ var config = require('web.config'); var core = require('web.core'); var Dialog = require('web.Dialog'); var field_utils = require('web.field_utils'); -var framework = require('web.framework'); var session = require('web.session'); var SystrayMenu = require('web.SystrayMenu'); var utils = require('web.utils'); @@ -190,6 +189,9 @@ var DebugManager = Widget.extend({ } }).open(); }, + /** + * Runs the JS (desktop) tests + */ perform_js_tests: function () { this.do_action({ name: _t("JS Tests"), @@ -198,6 +200,17 @@ var DebugManager = Widget.extend({ url: '/web/tests?mod=*' }); }, + /** + * Runs the JS mobile tests + */ + perform_js_mobile_tests: function () { + this.do_action({ + name: _t("JS Mobile Tests"), + target: 'new', + type: 'ir.actions.act_url', + url: '/web/tests/mobile?mod=*' + }); + }, split_assets: function() { window.location = $.param.querystring(window.location.href, 'debug=assets'); }, diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js index 782128994db..0619cf613c6 100644 --- a/addons/web/static/src/js/widgets/domain_selector.js +++ b/addons/web/static/src/js/widgets/domain_selector.js @@ -179,7 +179,16 @@ var DomainTree = DomainNode.extend({ */ init: function (parent, model, domain, options) { this._super.apply(this, arguments); - this._initialize(Domain.prototype.stringToArray(domain)); + try { + domain = Domain.prototype.stringToArray(domain); + } catch (err) { + // TODO: domain could contain `parent` for example, which is + // currently not handled by the DomainSelector + this.invalidDomain = true; + this.children = []; + return; + } + this._initialize(domain); }, /** * @see DomainNode.start @@ -443,6 +452,16 @@ var DomainSelector = DomainTree.extend({ domain_changed: "_onDomainChange", }), + start: function () { + var self = this; + return this._super.apply(this, arguments).then(function () { + if (self.invalidDomain) { + var msg = _t("This domain is not supported."); + self.$el.html(msg); + } + }); + }, + //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 7da3f448378..f1af2e7d762 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -220,6 +220,7 @@ </t> <t t-name="WebClient.DebugManager.Global"> <li><a href="#" data-action="perform_js_tests">Run JS Tests</a></li> + <li><a href="#" data-action="perform_js_mobile_tests">Run JS Mobile Tests</a></li> <li><a href="#" data-action="select_view">Open View</a></li> <t t-if="manager._events"> <li class="divider"/> |
