summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/chrome/search_menus.js8
-rw-r--r--addons/web/static/src/js/chrome/search_view.js2
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js34
-rw-r--r--addons/web/static/src/js/services/data_manager.js2
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js36
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js15
-rw-r--r--addons/web/static/src/less/form_view.less21
-rw-r--r--addons/web/static/src/xml/base_common.xml49
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>