diff options
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/js/chrome/search_menus.js | 8 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome/search_view.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/relational_fields.js | 34 | ||||
| -rw-r--r-- | addons/web/static/src/js/services/data_manager.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_model.js | 36 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_renderer.js | 15 | ||||
| -rw-r--r-- | addons/web/static/src/less/form_view.less | 21 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base_common.xml | 49 |
8 files changed, 123 insertions, 44 deletions
diff --git a/addons/web/static/src/js/chrome/search_menus.js b/addons/web/static/src/js/chrome/search_menus.js index 1da7800b049..eee7303ffbd 100644 --- a/addons/web/static/src/js/chrome/search_menus.js +++ b/addons/web/static/src/js/chrome/search_menus.js @@ -122,6 +122,7 @@ return Widget.extend({ model_id: this.target_model, context: results.context, domain: results.domain, + sort: JSON.stringify(this.searchview.dataset._sort), is_default: default_filter, action_id: this.action_id, }; @@ -243,6 +244,13 @@ return Widget.extend({ } this.query.reset([this.facet_for(filter)], { preventSearch: preventSearch || false}); + + // Load sort settings on view + if (!_.isUndefined(filter.sort)){ + var sort_items = JSON.parse(filter.sort); + this.searchview.dataset.set_sort(sort_items); + } + this.$filters[this.key_for(filter)].addClass('selected'); }, remove_filter: function (filter, $filter, key) { diff --git a/addons/web/static/src/js/chrome/search_view.js b/addons/web/static/src/js/chrome/search_view.js index 26305817e55..6c3adcafcca 100644 --- a/addons/web/static/src/js/chrome/search_view.js +++ b/addons/web/static/src/js/chrome/search_view.js @@ -232,7 +232,7 @@ var SearchView = Widget.extend({ 'click .o_searchview_more': function (e) { $(e.target).toggleClass('fa-search-plus fa-search-minus'); var visibleSearchMenu = this.call('local_storage', 'getItem', 'visible_search_menu'); - this.call('local_storage', 'setItem', visibleSearchMenu !== 'true'); + this.call('local_storage', 'setItem', 'visible_search_menu', visibleSearchMenu !== 'true'); this.toggle_buttons(); }, 'keydown .o_searchview_input, .o_searchview_facet': function (e) { diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 7522bb3bc37..1935e5804dd 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -99,7 +99,7 @@ var FieldMany2One = AbstractField.extend({ this.nodeOptions = _.defaults(this.nodeOptions, { quick_create: true, }); - this.m2o_value = field_utils.format.many2one(this.value); + this.m2o_value = this._formatValue(this.value); // 'recordParams' is a dict of params used when calling functions // 'getDomain' and 'getContext' on this.record this.recordParams = {fieldName: this.name, viewType: this.viewType}; @@ -838,8 +838,10 @@ var FieldX2Many = AbstractField.extend({ */ _onDeleteRecord: function (ev) { ev.stopPropagation(); + var shouldForget = this.attrs.widget === 'many2many' || this.field.type === 'many2many'; + var operation = shouldForget ? 'FORGET' : 'DELETE'; this._setValue({ - operation: 'REMOVE', + operation: operation, ids: [ev.data.id], }); }, @@ -1290,7 +1292,7 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({ var record = _.findWhere(this.value.data, {res_id: fileID}); if (record) { this._setValue({ - operation: 'REMOVE', + operation: 'FORGET', ids: [record.id], }); var metadata = this.metadata[record.id]; @@ -1469,7 +1471,7 @@ var FieldMany2ManyTags = AbstractField.extend({ _removeTag: function (id) { var record = _.findWhere(this.value.data, {res_id: id}); this._setValue({ - operation: 'REMOVE', + operation: 'FORGET', ids: [record.id], }); }, @@ -2029,7 +2031,20 @@ var FieldReference = FieldMany2One.extend({ // needs to be copied as it is an unmutable object this.field = _.extend({}, this.field); if (this.value) { - this._setRelation(this.value.model); + var model = null; + // The value of a Reference field can either be a string in the form + // of model,record_id or an object + if (typeof this.value === "string") { + var value = this.value.split(','); + model = value[0]; + this.value = { + res_id: parseInt(value[1]), + }; + } else { + model = this.value.model; + } + + this._setRelation(model); } }, /** @@ -2045,6 +2060,15 @@ var FieldReference = FieldMany2One.extend({ //-------------------------------------------------------------------------- /** + * Get the encompassing record's display_name + * + * @override + */ + _formatValue: function () { + return this.recordData.display_name; + }, + + /** * Add a select in edit mode (for the model). * * @override diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js index c1e69a72ce3..999a9d8df01 100644 --- a/addons/web/static/src/js/services/data_manager.js +++ b/addons/web/static/src/js/services/data_manager.js @@ -349,7 +349,7 @@ return core.Class.extend({ } if (attrs.Widget.prototype.fieldsToFetch) { attrs.viewType = 'default'; - attrs.relatedFields = attrs.Widget.prototype.fieldsToFetch; + attrs.relatedFields = _.extend({}, attrs.Widget.prototype.fieldsToFetch); attrs.fieldsInfo = { default: _.mapObject(attrs.Widget.prototype.fieldsToFetch, function () { return {}; 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 75a0ad02971..8f679207f00 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -509,6 +509,7 @@ var BasicModel = AbstractModel.extend({ } if (params.type === 'record' && params.res_id === undefined) { + params.allowWarning = true; return this._makeDefaultRecord(params.modelName, params); } var dataPoint = this._makeDataPoint(params); @@ -1294,9 +1295,12 @@ var BasicModel = AbstractModel.extend({ defs.push(this._applyChange(command.id, command.data)); } break; - case 'REMOVE': + case 'FORGET': + // Unlink the record of list. + list._forceM2MUnlink = true; + case 'DELETE': // filter out existing operations involving the current - // dataPoint, and add a 'REMOVE' operation only if there is + // dataPoint, and add a 'DELETE' or 'FORGET' operation only if there is // no 'ADD' operation for that dataPoint, as it would mean // that the record wasn't in the relation yet var idsToRemove = command.ids; @@ -1308,7 +1312,8 @@ var BasicModel = AbstractModel.extend({ return idInCommands; }); _.each(idsToRemove, function (id) { - list._changes.push({operation: 'REMOVE', id: id}); + var operation = list._forceM2MUnlink ? 'FORGET': 'DELETE'; + list._changes.push({operation: operation, id: id}); }); break; case 'REPLACE_WITH': @@ -1332,7 +1337,7 @@ var BasicModel = AbstractModel.extend({ return self.localData[localId]; }); removedDef = this._applyX2ManyChange(record, fieldName, { - operation: 'REMOVE', + operation: 'DELETE', ids: _.map(removedIds, function (resID) { return _.findWhere(listData, {res_id: resID}).id; }), @@ -1349,7 +1354,7 @@ var BasicModel = AbstractModel.extend({ }, /** * In dataPoints of type list for x2manys, the changes are stored as a list - * of operations (being of type 'ADD', 'REMOVE', 'UPDATE' or 'REMOVE_ALL'). + * of operations (being of type 'ADD', 'DELETE', 'FORGET', UPDATE' or 'REMOVE_ALL'). * This function applies the operation of such a dataPoint without altering * the original dataPoint. It returns a copy of the dataPoint in which the * 'count', 'data' and 'res_ids' keys have been updated. @@ -1383,7 +1388,8 @@ var BasicModel = AbstractModel.extend({ list.res_ids.push(resID); } break; - case 'REMOVE': + case 'FORGET': + case 'DELETE': list.count--; list.res_ids = _.without(list.res_ids, relRecord.res_id); break; @@ -2348,7 +2354,11 @@ var BasicModel = AbstractModel.extend({ } // add delete commands for (i = 0; i < removedIds.length; i++) { - commands[fieldName].push(x2ManyCommands.delete(removedIds[i])); + if (list._forceM2MUnlink) { + commands[fieldName].push(x2ManyCommands.forget(removedIds[i])); + } else { + commands[fieldName].push(x2ManyCommands.delete(removedIds[i])); + } } } } @@ -2601,7 +2611,9 @@ var BasicModel = AbstractModel.extend({ var isValid = true; var element = this.localData[id]; _.each(element._changes, function (command) { - if (command.operation === 'REMOVE' || command.operation === 'REMOVE_ALL') { + if (command.operation === 'DELETE' || + command.operation === 'FORGET' || + command.operation === 'REMOVE_ALL') { return; } var recordData = self.get(command.id, {raw: true}).data; @@ -2735,6 +2747,8 @@ var BasicModel = AbstractModel.extend({ * @private * @param {any} params * @param {string} modelName model name + * @param {boolean} [params.allowWarning=false] if true, the default record + * operation can complete, even if a warning is raised * @param {Object} params.context the context for the new record * @param {Object} params.fieldsInfo contains the fieldInfo of each view, * for each field @@ -2887,7 +2901,11 @@ var BasicModel = AbstractModel.extend({ .then(function () { return self._performOnChange(record, fields_key).then(function () { if (record._warning) { - return $.Deferred().reject(); + if (params.allowWarning) { + delete record._warning; + } else { + return $.Deferred().reject(); + } } }); }) diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index f7c4861dd2a..fe53bb6cf8a 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -335,12 +335,27 @@ var FormRenderer = BasicRenderer.extend({ * @returns {jQueryElement} */ _renderHeaderButton: function (node) { + var self = this; var $button = $('<button>') .text(node.attrs.string) .addClass('btn btn-sm btn-default'); this._addOnClickAction($button, node); this._handleAttributes($button, node); this._registerModifiers(node, this.state, $button); + + // Display tooltip + if (config.debug || node.attrs.help) { + $button.tooltip({ + delay: { show: 1000, hide: 0 }, + title: function () { + return qweb.render('WidgetButton.tooltip', { + debug: config.debug, + state: self.state, + node: node, + }); + }, + }); + } return $button; }, /** diff --git a/addons/web/static/src/less/form_view.less b/addons/web/static/src/less/form_view.less index 34ce34e6ad8..c4990e6c824 100644 --- a/addons/web/static/src/less/form_view.less +++ b/addons/web/static/src/less/form_view.less @@ -86,18 +86,19 @@ display: inline-block; } - .o_form_uri { // FIXME maybe global? - display: inline-block; + } - color: @odoo-main-text-color; + .o_form_uri { + display: inline-block; + + color: @odoo-main-text-color; + &:first-line { + color: @link-color; + } + &:hover { + color: darken(@odoo-main-text-color, 1%); // hack required on chrome &:first-line { - color: @link-color; - } - &:hover { - color: darken(@odoo-main-text-color, 1%); // hack required on chrome - &:first-line { - color: darken(@link-color, 15%); - } + color: darken(@link-color, 15%); } } } diff --git a/addons/web/static/src/xml/base_common.xml b/addons/web/static/src/xml/base_common.xml index 0e1824bb022..8f858532855 100644 --- a/addons/web/static/src/xml/base_common.xml +++ b/addons/web/static/src/xml/base_common.xml @@ -93,36 +93,49 @@ </li> </ul> </t> -<t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip"> - <t t-jquery="div.oe_tooltip_string" t-operation="replace"> - <div class="oe_tooltip_string" t-if="debug || widget.string"> - <t t-if="debug"> - Button - <t t-if="widget.string">: </t> - <t t-if="!widget.string"> (no string)</t> - </t> - <t t-esc="widget.string"/> - </div> - </t> - <t t-jquery="ul.oe_tooltip_technical" t-operation="append"> - <li t-if="widget.node.attrs.special" data-item="special"> +<t t-name="WidgetButton.tooltip"> + <div class="oe_tooltip_string" t-if="debug || node.attrs.string"> + <t t-if="debug"> + Button + <t t-if="node.attrs.string">: </t> + <t t-if="!node.attrs.string"> (no string)</t> + </t> + <t t-esc="node.attrs.string"/> + </div> + <p t-if="node.attrs.help" class="oe_tooltip_help"> + <t t-esc="node.attrs.help"/> + </p> + <ul t-if="debug" class="oe_tooltip_technical"> + <li data-item="object"> + <span class="oe_tooltip_technical_title">Object:</span> + <t t-esc="state.model"/> + </li> + <li t-if="node.attrs.context" data-item="context"> + <span class="oe_tooltip_technical_title">Context:</span> + <t t-esc="node.attrs.context || widget.field.context"/> + </li> + <li t-if="node.attrs.modifiers and node.attrs.modifiers != '{}'" data-item="modifiers"> + <span class="oe_tooltip_technical_title">Modifiers:</span> + <t t-esc="node.attrs.modifiers"/> + </li> + <li t-if="node.attrs.special" data-item="special"> <span class="oe_tooltip_technical_title">Special:</span> - <t t-esc="widget.node.attrs.special"/> + <t t-esc="node.attrs.special"/> </li> - <t t-set="button_type" t-value="widget.node.attrs.type"/> + <t t-set="button_type" t-value="node.attrs.type"/> <li t-if="button_type" data-item="button_type"> <span class="oe_tooltip_technical_title">Button Type:</span> <t t-esc="button_type"/> </li> <li t-if="button_type === 'object'" data-item="button_method"> <span class="oe_tooltip_technical_title">Method:</span> - <t t-esc="widget.node.attrs.name"/> + <t t-esc="node.attrs.name"/> </li> <li t-if="button_type === 'action'" data-item="button_action"> <span class="oe_tooltip_technical_title">Action ID:</span> - <t t-esc="widget.node.attrs.name"/> + <t t-esc="node.attrs.name"/> </li> - </t> + </ul> </t> </templates> |
