diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-03-11 14:42:34 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-03-11 14:42:34 +0100 |
| commit | 71faa19af06d5002be627adbfd92dc25941c69c6 (patch) | |
| tree | c6abaadf36cea49d1b2a2779cf487974ca1c650f /addons/web/static/src | |
| parent | 0c1eff0d95869b9b4eab8b34e65be770e49fdd2b (diff) | |
| parent | 2b3296bbf8b5d08fad20a4ca8d83ebb0aa7303b3 (diff) | |
[MERGE] forward port branch saas-12.1 up to 2b3296bbf8b
Diffstat (limited to 'addons/web/static/src')
15 files changed, 87 insertions, 64 deletions
diff --git a/addons/web/static/src/js/chrome/action_manager_act_window.js b/addons/web/static/src/js/chrome/action_manager_act_window.js index 106f9f2aa47..d36ec9371de 100644 --- a/addons/web/static/src/js/chrome/action_manager_act_window.js +++ b/addons/web/static/src/js/chrome/action_manager_act_window.js @@ -535,6 +535,9 @@ ActionManager.include({ return newController(controller.jsID); } else { return $.when(controller.widget.willRestore()).then(function () { + viewOptions = _.extend({}, viewOptions, { + breadcrumbs: self._getBreadcrumbs(self.controllerStack.slice(0, index)), + }); return controller.widget.reload(viewOptions).then(function () { return controller; }); diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index c6df3885a86..fa2b904eeb9 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1331,7 +1331,9 @@ var CopyClipboard = { */ destroy: function () { this._super.apply(this, arguments); - this.clipboard.destroy(); + if (this.clipboard) { + this.clipboard.destroy(); + } }, //-------------------------------------------------------------------------- @@ -1346,8 +1348,8 @@ var CopyClipboard = { var $clipboardBtn = this.$('.o_clipboard_button'); $clipboardBtn.tooltip({title: _t('Copied !'), trigger: 'manual', placement: 'right'}); this.clipboard = new ClipboardJS($clipboardBtn[0], { - text: function (_) { - return self.value.trim(); + text: function () { + return self.value.trim(); }, // Container added because of Bootstrap modal that give the focus to another element. // We need to give to correct focus to ClipboardJS (see in ClipboardJS doc) @@ -1363,40 +1365,31 @@ var CopyClipboard = { }); }); }, -}; - -var TextCopyClipboard = FieldText.extend(CopyClipboard, { - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - /** * @override */ - _render: function() { + _render: function () { this._super.apply(this, arguments); this.$el.addClass('o_field_copy'); - this.$el.append($(qweb.render('CopyClipboardText'))); - this._initClipboard(); - } -}); - -var CharCopyClipboard = FieldChar.extend(CopyClipboard, { - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - + }, /** * @override */ - _render: function() { + _renderReadonly: function () { this._super.apply(this, arguments); - this.$el.addClass('o_field_copy'); - this.$el.append($(qweb.render('CopyClipboardChar'))); - this._initClipboard(); + if (this.value) { + this.$el.append($(qweb.render(this.clipboardTemplate))); + this._initClipboard(); + } } +}; + +var TextCopyClipboard = FieldText.extend(CopyClipboard, { + clipboardTemplate: 'CopyClipboardText', +}); + +var CharCopyClipboard = FieldChar.extend(CopyClipboard, { + clipboardTemplate: 'CopyClipboardChar', }); var AbstractFieldBinary = AbstractField.extend({ diff --git a/addons/web/static/src/js/fields/field_registry.js b/addons/web/static/src/js/fields/field_registry.js index 35d10c5a5e4..1617bfae24c 100644 --- a/addons/web/static/src/js/fields/field_registry.js +++ b/addons/web/static/src/js/fields/field_registry.js @@ -44,8 +44,9 @@ registry .add('priority', basic_fields.PriorityWidget) .add('attachment_image', basic_fields.AttachmentImage) .add('label_selection', basic_fields.LabelSelection) + .add('kanban_label_selection', basic_fields.LabelSelection) // deprecated, use label_selection .add('state_selection', basic_fields.StateSelectionWidget) - .add('kanban_state_selection', basic_fields.StateSelectionWidget) + .add('kanban_state_selection', basic_fields.StateSelectionWidget) // deprecated, use state_selection .add('boolean_favorite', basic_fields.FavoriteWidget) .add('boolean_button', basic_fields.FieldBooleanButton) .add('boolean_toggle', basic_fields.BooleanToggle) diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index bd46faf1e08..ec777c2e12c 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -242,7 +242,7 @@ var FieldMany2One = AbstractField.extend({ _bindAutoComplete: function () { var self = this; // avoid ignoring autocomplete="off" by obfuscating placeholder, see #30439 - if (this.$input.attr('placeholder')) { + if ($.browser.chrome && this.$input.attr('placeholder')) { this.$input.attr('placeholder', function (index, val) { return val.split('').join('\ufeff'); }); @@ -1886,6 +1886,7 @@ var FieldMany2ManyTags = AbstractField.extend({ } this.colorField = this.nodeOptions.color_field; + this.hasDropdown = false; }, //-------------------------------------------------------------------------- @@ -1952,6 +1953,7 @@ var FieldMany2ManyTags = AbstractField.extend({ return { colorField: this.colorField, elements: elements, + hasDropdown: this.hasDropdown, readonly: this.mode === "readonly", }; }, @@ -2063,6 +2065,14 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({ 'mousedown .o_colorpicker a': '_onUpdateColor', 'mousedown .o_colorpicker .o_hide_in_kanban': '_onUpdateColor', }), + /** + * @override + */ + init: function () { + this._super.apply(this, arguments); + + this.hasDropdown = !!this.colorField; + }, //-------------------------------------------------------------------------- // Handlers diff --git a/addons/web/static/src/js/views/abstract_controller.js b/addons/web/static/src/js/views/abstract_controller.js index b5d7c8fe8b3..53afb4a1fbd 100644 --- a/addons/web/static/src/js/views/abstract_controller.js +++ b/addons/web/static/src/js/views/abstract_controller.js @@ -246,7 +246,7 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { return; } self.renderer.setLocalState(localState); - return self._update(state); + return self._update(state, params); }); }); }, @@ -402,12 +402,15 @@ var AbstractController = mvc.Controller.extend(ActionMixin, { * * @private * @param {Object} state the state given by the model + * @param {Object} [params] + * @param {Object[]} [params.breadcrumbs] * @returns {Deferred} */ - _update: function () { + _update: function (state, params) { // AAB: update the control panel -> this will be moved elsewhere at some point var cpContent = _.extend({}, this.controlPanelElements); this.updateControlPanel({ + breadcrumbs: params && params.breadcrumbs, cp_content: cpContent, title: this.getTitle(), }); diff --git a/addons/web/static/src/js/views/control_panel/control_panel_controller.js b/addons/web/static/src/js/views/control_panel/control_panel_controller.js index 40b1c45b9c7..f6967a6fb5a 100644 --- a/addons/web/static/src/js/views/control_panel/control_panel_controller.js +++ b/addons/web/static/src/js/views/control_panel/control_panel_controller.js @@ -17,6 +17,7 @@ var ControlPanelController = mvc.Controller.extend({ activate_time_range: '_onActivateTimeRange', autocompletion_filter: '_onAutoCompletionFilter', reload: '_onReload', + reset: '_onReset', }, /** @@ -244,6 +245,15 @@ var ControlPanelController = mvc.Controller.extend({ ev.stopPropagation(); this.trigger_up('search', this.model.getQuery()); }, + /** + * @private + * @param {OdooEvent} ev + */ + _onReset: function (ev) { + ev.stopPropagation(); + var state = this.model.get(); + this.renderer.updateState(state); + }, }); return ControlPanelController; diff --git a/addons/web/static/src/js/views/control_panel/search/search_bar.js b/addons/web/static/src/js/views/control_panel/search/search_bar.js index 77d6d7fa5e9..45004fd04ef 100644 --- a/addons/web/static/src/js/views/control_panel/search/search_bar.js +++ b/addons/web/static/src/js/views/control_panel/search/search_bar.js @@ -184,10 +184,16 @@ var SearchBar = Widget.extend({ */ _onAutoCompleteSelected: function (e, ui) { e.preventDefault(); - var filter = ui.item.facet.filter; + var facet = ui.item.facet; + if (!facet) { + // this happens when selecting "(no result)" item + this.trigger_up('reset'); + return; + } + var filter = facet.filter; if (filter.type === 'field') { var values = filter.autoCompleteValues; - values.push(ui.item.facet.values[0]); + values.push(facet.values[0]); this.trigger_up('autocompletion_filter', { filterId: filter.id, autoCompleteValues: values, diff --git a/addons/web/static/src/js/views/kanban/kanban_record.js b/addons/web/static/src/js/views/kanban/kanban_record.js index 3dc1d6788bf..48f1aacf4ad 100644 --- a/addons/web/static/src/js/views/kanban/kanban_record.js +++ b/addons/web/static/src/js/views/kanban/kanban_record.js @@ -300,6 +300,7 @@ var KanbanRecord = Widget.extend({ // field's widgets point of view // that dict being shared between records, we don't modify it // in place + var self = this; var attrs = Object.create(null); _.each(this.fieldsInfo[field_name], function (value, key) { if (_.str.startsWith(key, 't-att-')) { @@ -310,11 +311,12 @@ var KanbanRecord = Widget.extend({ }); var options = _.extend({}, this.options, {attrs: attrs}); var widget = new Widget(this, field_name, this.state, options); - var def = widget.replace($field); + var def = widget.replace($field).then(function () { + self._setFieldDisplay(widget.$el, field_name); + }); if (def.state() === 'pending') { this.defs.push(def); } - this._setFieldDisplay(widget.$el, field_name); return widget; }, _processWidgets: function () { @@ -324,12 +326,13 @@ var KanbanRecord = Widget.extend({ var Widget = widgetRegistry.get($field.attr('name')); var widget = new Widget(self, self.state); - var def = widget._widgetRenderAndInsert(function () {}); + var def = widget._widgetRenderAndInsert(function () {}).then(function () { + widget.$el.addClass('o_widget'); + $field.replaceWith(widget.$el); + }); if (def.state() === 'pending') { self.defs.push(def); } - widget.$el.addClass('o_widget'); - $field.replaceWith(widget.$el); }); }, /** diff --git a/addons/web/static/src/js/views/kanban/kanban_renderer.js b/addons/web/static/src/js/views/kanban/kanban_renderer.js index 252b4587af6..347de352503 100644 --- a/addons/web/static/src/js/views/kanban/kanban_renderer.js +++ b/addons/web/static/src/js/views/kanban/kanban_renderer.js @@ -249,7 +249,6 @@ var KanbanRenderer = BasicRenderer.extend({ */ updateState: function (state) { this._setState(state); - this._toggleNoContentHelper(); return this._super.apply(this, arguments); }, @@ -398,11 +397,8 @@ var KanbanRenderer = BasicRenderer.extend({ var self = this; var oldWidgets = this.widgets; this.widgets = []; - this.$el.empty(); var isGrouped = !!this.state.groupedBy.length; - this.$el.toggleClass('o_kanban_grouped', isGrouped); - this.$el.toggleClass('o_kanban_ungrouped', !isGrouped); var fragment = document.createDocumentFragment(); // render the kanban view this.defs = []; @@ -411,15 +407,19 @@ var KanbanRenderer = BasicRenderer.extend({ } else { this._renderUngrouped(fragment); } - this.$el.append(fragment); - this._toggleNoContentHelper(); var defs = this.defs; - return this._super.apply(this, arguments).then(function () { + delete this.defs; + defs.push(this._super.apply(this, arguments)); + return $.when.apply($, defs).then(function () { _.invoke(oldWidgets, 'destroy'); + self.$el.empty(); + self.$el.toggleClass('o_kanban_grouped', isGrouped); + self.$el.toggleClass('o_kanban_ungrouped', !isGrouped); + self.$el.append(fragment); + self._toggleNoContentHelper(); if (self._isInDom) { _.invoke(self.widgets, 'on_attach_callback'); } - return $.when.apply(null, defs); }); }, /** diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index ab5e5036dfa..185a385a812 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -278,6 +278,8 @@ ListRenderer.include({ this.currentRow = null; } + // destroy widgets first + this._destroyFieldWidgets(recordID); // remove the row var $row = this.$('.o_data_row:nth(' + rowIndex + ')'); if (this.state.count >= 4) { @@ -285,8 +287,6 @@ ListRenderer.include({ } else { $row.replaceWith(this._renderEmptyRow()); } - - this._destroyFieldWidgets(recordID); }, /** * Updates the already rendered row associated to the given recordID so that diff --git a/addons/web/static/src/js/views/pivot/pivot_model.js b/addons/web/static/src/js/views/pivot/pivot_model.js index 3f195c1ea24..88d0aee83b8 100644 --- a/addons/web/static/src/js/views/pivot/pivot_model.js +++ b/addons/web/static/src/js/views/pivot/pivot_model.js @@ -993,7 +993,6 @@ var PivotModel = AbstractModel.extend({ var groupBys; var m; - for (var i = 0; i < rowGroupBys.length + 1; i++) { for (var j = 0; j < colGroupBys.length + 1; j++) { for (var k = 0; k < data[index].length; k++) { diff --git a/addons/web/static/src/js/widgets/auto_complete.js b/addons/web/static/src/js/widgets/auto_complete.js index 6dd78f8f730..4da54cf8b5c 100644 --- a/addons/web/static/src/js/widgets/auto_complete.js +++ b/addons/web/static/src/js/widgets/auto_complete.js @@ -201,10 +201,8 @@ return Widget.extend({ this.current_result = $li.data('result'); }, select_item: function (ev) { - if (this.current_result.facet) { - this.select(ev, {item: {facet: this.current_result.facet}}); - this.close(); - } + this.select(ev, {item: {facet: this.current_result.facet}}); + this.close(); }, show: function () { this.$el.show(); diff --git a/addons/web/static/src/scss/fields.scss b/addons/web/static/src/scss/fields.scss index 27d0d13770e..55559546e74 100644 --- a/addons/web/static/src/scss/fields.scss +++ b/addons/web/static/src/scss/fields.scss @@ -178,7 +178,7 @@ } } } - } + } .o_tag_error { box-shadow: inset 0 0 0 2px #FF0000; @@ -443,7 +443,10 @@ } } } +} +span.o_field_copy:empty { + border: none; } button.o_field_float_toggle { diff --git a/addons/web/static/src/scss/form_view.scss b/addons/web/static/src/scss/form_view.scss index 0645e00544e..812e6cbd6cc 100644 --- a/addons/web/static/src/scss/form_view.scss +++ b/addons/web/static/src/scss/form_view.scss @@ -81,16 +81,10 @@ .o_form_uri { display: inline-block; + color: $link-color; - color: $o-main-text-color; - &:first-line { - color: $link-color; - } &:hover { - color: darken($o-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.xml b/addons/web/static/src/xml/base.xml index 8126fcf11c4..7a6bca6aa7a 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -846,11 +846,11 @@ <t t-foreach="elements" t-as="el"> <t t-set="color" t-value="el[colorField] || 0"/> <t t-set="colornames" t-value="['No color', 'Red', 'Orange', 'Yellow', 'Light blue', 'Dark purple', 'Salmon pink', 'Medium blue', 'Dark blue', 'Fushia', 'Green', 'Purple']"/> - <div t-attf-class="badge badge-pill dropdown o_tag_color_#{color}" t-att-data-color="color" t-att-data-index="el_index" t-att-data-id="el.id" t-attf-title="Tag color: #{colornames[color]}"> + <div t-attf-class="badge badge-pill #{hasDropdown ? 'dropdown' : ''} o_tag_color_#{color}" t-att-data-color="color" t-att-data-index="el_index" t-att-data-id="el.id" t-attf-title="Tag color: #{colornames[color]}"> <t t-set="_badge_text"> <span class="o_badge_text" t-att-title="el.display_name"><span role="img" t-attf-aria-label="Tag color: #{colornames[color]}"/><t t-esc="el.display_name"/></span> </t> - <t t-if="colorField"> + <t t-if="hasDropdown"> <a role="button" href="#" class="dropdown-toggle o-no-caret" data-toggle="dropdown" aria-expanded="false"> <t t-raw="_badge_text"/> </a> |
