diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-01-10 13:52:44 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-01-10 13:52:44 +0100 |
| commit | a2c1df8b9ca731107dd2d67cc0b2dd39d0c7ad64 (patch) | |
| tree | 5de4c414a1c137c674ca004fbec6a29fc1a10db5 /addons/web/static | |
| parent | d38e00031f975db4a3d3e80250d5142444a3239b (diff) | |
| parent | 557feb950cb74656c92e59a62847c9e414c9b41f (diff) | |
[MERGE] forward port branch saas-14 up to 557feb950cb
Diffstat (limited to 'addons/web/static')
| -rw-r--r-- | addons/web/static/src/js/framework/domain_utils.js | 19 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form_widgets.js | 19 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/list_view_editable.js | 3 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/search_view.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/domain_selector.js | 17 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/domain_selector_dialog.js | 48 | ||||
| -rw-r--r-- | addons/web/static/src/less/domain_selector.less | 5 | ||||
| -rw-r--r-- | addons/web/static/src/less/form_view_layout.less | 16 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 17 |
9 files changed, 124 insertions, 22 deletions
diff --git a/addons/web/static/src/js/framework/domain_utils.js b/addons/web/static/src/js/framework/domain_utils.js new file mode 100644 index 00000000000..8cefb7cabbe --- /dev/null +++ b/addons/web/static/src/js/framework/domain_utils.js @@ -0,0 +1,19 @@ +odoo.define("web.domainUtils", function (require) { +"use strict"; + +var pyeval = require("web.pyeval"); + +function domainToString(domain) { + if (_.isString(domain)) return domain; + return JSON.stringify(domain || []).replace(/false/g, "False").replace(/true/g, "True"); +} +function stringToDomain(domain) { + if (!_.isString(domain)) return domain; + return pyeval.eval("domain", domain || "[]"); +} + +return { + domainToString: domainToString, + stringToDomain: stringToDomain, +}; +}); diff --git a/addons/web/static/src/js/views/form_widgets.js b/addons/web/static/src/js/views/form_widgets.js index a3c7bcaaff3..78d8ea7c5d1 100644 --- a/addons/web/static/src/js/views/form_widgets.js +++ b/addons/web/static/src/js/views/form_widgets.js @@ -11,6 +11,7 @@ var Priority = require('web.Priority'); var ProgressBar = require('web.ProgressBar'); var Dialog = require('web.Dialog'); var DomainSelector = require("web.DomainSelector"); +var DomainSelectorDialog = require("web.DomainSelectorDialog"); var common = require('web.form_common'); var formats = require('web.formats'); var framework = require('web.framework'); @@ -400,11 +401,19 @@ var FieldDomain = common.AbstractField.extend(common.ReinitializeFieldMixin).ext e.preventDefault(); this._showSelection(); }, + "click .o_form_field_domain_dialog_button": function (e) { + e.preventDefault(); + this.openDomainDialog(); + }, }, custom_events: { "domain_changed": function (e) { + if (this.options.in_dialog) return; this.set_value(this.domainSelector.getDomain(), true); }, + "domain_selected": function (e) { + this.set_value(e.data.domain); + }, }, init: function () { this._super.apply(this, arguments); @@ -412,6 +421,7 @@ var FieldDomain = common.AbstractField.extend(common.ReinitializeFieldMixin).ext this.valid = true; this.debug = session.debug; this.options = _.defaults(this.options || {}, { + in_dialog: false, model: undefined, // this option is mandatory ! fs_filters: {}, // Field selector filters (to only show a subset of available fields @see FieldSelector) }); @@ -457,7 +467,7 @@ var FieldDomain = common.AbstractField.extend(common.ReinitializeFieldMixin).ext this.domainSelector.destroy(); } this.domainSelector = new DomainSelector(this, this.model, domain, { - readonly: this.get("effective_readonly"), + readonly: this.get("effective_readonly") || this.options.in_dialog, fs_filters: this.options.fs_filters, debugMode: session.debug, }); @@ -492,6 +502,13 @@ var FieldDomain = common.AbstractField.extend(common.ReinitializeFieldMixin).ext disable_multiple_selection: true, }).open(); }, + openDomainDialog: function () { + new DomainSelectorDialog(this, this.model, this.get("value"), { + readonly: this.get("effective_readonly"), + fs_filters: this.options.fs_filters, + debugMode: session.debug, + }).open(); + }, }); var FieldDate = common.AbstractField.extend(common.ReinitializeFieldMixin, { diff --git a/addons/web/static/src/js/views/list_view_editable.js b/addons/web/static/src/js/views/list_view_editable.js index 3f5d39e60e1..ef9bf1a6062 100644 --- a/addons/web/static/src/js/views/list_view_editable.js +++ b/addons/web/static/src/js/views/list_view_editable.js @@ -641,7 +641,8 @@ ListView.include(/** @lends instance.web.ListView# */{ if (saveInfo.created) { return self.start_edition(); } - var record = self.records[next_record](saveInfo.record); + var options = { wraparound: !self.is_action_enabled('create') }; + var record = self.records[next_record](saveInfo.record, options); if (record === undefined) { return self.start_edition(); } diff --git a/addons/web/static/src/js/views/search_view.js b/addons/web/static/src/js/views/search_view.js index 9f985fc3f49..65dbb4557e7 100644 --- a/addons/web/static/src/js/views/search_view.js +++ b/addons/web/static/src/js/views/search_view.js @@ -466,7 +466,7 @@ var SearchView = View.extend({ */ select_completion: function (e, ui) { e.preventDefault(); - if(ui.item.facet.values && ui.item.facet.values.length && String(ui.item.facet.values[0].value).trim() !== "") { + if(ui.item.facet && ui.item.facet.values && ui.item.facet.values.length && String(ui.item.facet.values[0].value).trim() !== "") { this.query.add(ui.item.facet); } else { this.query.trigger('add'); diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js index 5f4287a8d8d..15e967ff4d4 100644 --- a/addons/web/static/src/js/widgets/domain_selector.js +++ b/addons/web/static/src/js/widgets/domain_selector.js @@ -3,9 +3,9 @@ odoo.define("web.DomainSelector", function (require) { var core = require("web.core"); var datepicker = require("web.datepicker"); +var domainUtils = require("web.domainUtils"); var formats = require ("web.formats"); var ModelFieldSelector = require("web.ModelFieldSelector"); -var pyeval = require("web.pyeval"); var Widget = require("web.Widget"); var _t = core._t; @@ -55,7 +55,7 @@ var DomainNode = Widget.extend({ }, /// A DomainNode needs a model and domain to work. It can also receives a set of options /// @param model - a string with the model name - /// @param domain - an array of the prefix representation of the domain + /// @param domain - an array of the prefix representation of the domain (or a string which represents it) /// @param options - an object with possible values: /// - readonly, a boolean to indicate if the widget is readonly or not (default to true) /// - fs_filters, an object with a series of filters to use for the field selector (see @FieldSelector) @@ -109,7 +109,7 @@ var DomainTree = DomainNode.extend({ /// @see DomainTree._addFlattenedChildren init: function (parent, model, domain, options) { this._super.apply(this, arguments); - this._initialize(domain); + this._initialize(domainUtils.stringToDomain(domain)); }, /// @see DomainTree.init _initialize: function (domain) { @@ -265,8 +265,9 @@ var DomainSelector = DomainTree.extend({ /// the widget is re-rendered and notifies the parents. If not, a warning is shown to the /// user and the input is ignored. "change .o_domain_debug_input": function (e) { + var domain; try { - var domain = pyeval.eval("domain", $(e.currentTarget).val() || "[]"); + domain = domainUtils.stringToDomain($(e.currentTarget).val()); } catch (err) { this.do_warn(_t("Syntax error"), _t("The domain you entered is not properly formed")); return; @@ -292,12 +293,7 @@ var DomainSelector = DomainTree.extend({ // Display technical domain if in debug mode this.$debugInput = this.$(".o_domain_debug_input"); if (this.$debugInput.length) { - var strValue = this.getDomain() || "[]"; - if (!_.isString(strValue)) { // TODO there is no "pyuneval" function - strValue = JSON.stringify(strValue); - strValue = strValue.replace(/false/g, "False").replace(/true/g, "True"); - } - this.$debugInput.val(strValue); + this.$debugInput.val(domainUtils.domainToString(this.getDomain())); } }, }); @@ -328,6 +324,7 @@ var DomainLeaf = DomainNode.extend({ init: function (parent, model, domain, options) { this._super.apply(this, arguments); + domain = domainUtils.stringToDomain(domain); this.chain = domain[0][0]; this.operator = domain[0][1]; this.value = domain[0][2]; diff --git a/addons/web/static/src/js/widgets/domain_selector_dialog.js b/addons/web/static/src/js/widgets/domain_selector_dialog.js new file mode 100644 index 00000000000..47bfa4e1359 --- /dev/null +++ b/addons/web/static/src/js/widgets/domain_selector_dialog.js @@ -0,0 +1,48 @@ +odoo.define("web.DomainSelectorDialog", function (require) { +"use strict"; + +var core = require("web.core"); +var Dialog = require("web.Dialog"); +var DomainSelector = require("web.DomainSelector"); + +var _t = core._t; + +return Dialog.extend({ + init: function (parent, model, domain, options) { + this.model = model; + this.options = _.extend({ + readonly: true, + fs_filters: {}, + debugMode: false, + }, options || {}); + + var buttons; + if (this.options.readonly) { + buttons = [ + {text: _t("Close"), close: true}, + ]; + } else { + buttons = [ + {text: _t("Save"), classes: "btn-primary", close: true, click: function () { + this.trigger_up("domain_selected", {domain: this.domainSelector.getDomain()}); + }}, + {text: _t("Discard"), close: true}, + ]; + } + + this._super(parent, _.extend({}, { + title: _t("Domain"), + buttons: buttons, + }, options || {})); + + this.domainSelector = new DomainSelector(this, model, domain, options); + }, + start: function () { + this.$el.css("overflow", "visible").closest(".modal-dialog").css("height", "auto"); // This restores default modal height (bootstrap) and allows field selector to overflow + return $.when( + this._super.apply(this, arguments), + this.domainSelector.appendTo(this.$el) + ); + }, +}); +}); diff --git a/addons/web/static/src/less/domain_selector.less b/addons/web/static/src/less/domain_selector.less index 7dced900b21..f3917526ec5 100644 --- a/addons/web/static/src/less/domain_selector.less +++ b/addons/web/static/src/less/domain_selector.less @@ -24,7 +24,10 @@ &.o_domain_selector { &.o_edit_mode { position: relative; - padding-right: @o-domain-selector-panel-space; + + > .o_domain_node_children_container { + padding-right: @o-domain-selector-panel-space; + } } > .o_domain_node_children_container { diff --git a/addons/web/static/src/less/form_view_layout.less b/addons/web/static/src/less/form_view_layout.less index 281cf0d217e..fc5522035e5 100644 --- a/addons/web/static/src/less/form_view_layout.less +++ b/addons/web/static/src/less/form_view_layout.less @@ -91,7 +91,7 @@ // Title .oe_title { > h1, > h2, > h3 { - width: 100%; // Needed because inline-block when is a hx.o_row + width: 100%; // Needed because inline-block when is a hx.o_row margin-top: 0; margin-bottom: 0; line-height: inherit; @@ -276,6 +276,20 @@ padding: 0 1em; } } + + .o_form_field_domain { + > .o_form_field_domain_panel { + margin-top: 8px; + } + &.o_inline_mode.o_edit_mode { + position: relative; + + > .o_form_field_domain_panel { + .o-position-absolute(0, 0); + margin-top: 0; + } + } + } } // Overriden style when form view in modal diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index f6ac60c4d7e..2ee261a3bdd 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -670,13 +670,16 @@ t-att-maxlength="widget.field.size"/> </t> -<div t-name="FieldDomain" class="o_form_field_domain"> +<div t-name="FieldDomain" t-attf-class="o_form_field_domain#{widget.get('effective_readonly') ? '' : ' o_edit_mode'}#{widget.options.in_dialog ? '' : ' o_inline_mode'}"> <!-- domain selector will be instantiated here --> - <div class="mt8"> + <div class="o_form_field_domain_panel"> <i class="fa fa-arrow-right"/> - <span><span class="o_domain_records_count"/> Records Selected</span> - <button class="btn btn-default btn-xs o_domain_show_selection_button" type="button">See selection</button> + <button class="btn btn-xs btn-default o_domain_show_selection_button" type="button"> + <span class="o_domain_records_count"/> record(s) + </button> <span class="text-warning o_domain_error_message hidden"><i class="fa fa-exclamation-triangle"/> Invalid domain</span> + <button t-if="widget.options.in_dialog && !widget.get('effective_readonly')" + class="btn btn-sm btn-primary o_form_field_domain_dialog_button">Edit domain</button> </div> </div> @@ -684,7 +687,7 @@ <div t-if="!widget.readonly && !widget.noControlPanel" class="btn-group btn-group-sm pull-right o_domain_node_control_panel"> <button class="btn btn-default o_domain_delete_node_button"><i class="fa fa-minus"/></button> <button class="btn btn-default o_domain_add_node_button"><i class="fa fa-plus"/></button> - <button class="btn btn-default o_domain_add_node_button" t-att-data-branch="1"><i class="fa fa-ellipsis-h"/></button> + <button class="btn btn-default o_domain_add_node_button" data-branch="1"><i class="fa fa-ellipsis-h"/></button> </div> </t> <t t-name="DomainTree.OperatorSelector"> @@ -712,9 +715,9 @@ </t> <t t-else=""> <div> - <t t-if="widget.children.length === 1">Match the records with the following rule:</t> + <t t-if="widget.children.length === 1">Match records with the following rule:</t> <t t-else=""> - <span>Match the records with</span> + <span>Match records with</span> <t t-call="DomainTree.OperatorSelector"/> <span>of the following rules:</span> </t> |
