diff options
30 files changed, 777 insertions, 840 deletions
diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js index 72c4eee1eca..568a6e2babd 100644 --- a/addons/board/static/src/js/dashboard.js +++ b/addons/board/static/src/js/dashboard.js @@ -90,13 +90,14 @@ var DashBoard = form_common.FormWidget.extend({ var qdict = { current_layout : this.$el.find('.oe_dashboard').attr('data-layout') }; - var $dialog = new Dialog(this, { - title: _t("Edit Layout"), - }, QWeb.render('DashBoard.layouts', qdict)).open(); - $dialog.$el.find('li').click(function() { + var dialog = new Dialog(this, { + title: _t("Edit Layout"), + $content: QWeb.render('DashBoard.layouts', qdict) + }).open(); + dialog.$el.find('li').click(function() { var layout = $(this).attr('data-layout'); self.do_change_layout(layout); - $dialog.$dialog_box.modal('hide'); + dialog.close(); }); }, do_change_layout: function(new_layout) { diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index e29feecf414..21ac9d5e171 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1266,18 +1266,17 @@ var ComposeMessage = Attachment.extend ({ var partner_id = partner_info.partner_id; var parsed_email = mail_utils.parse_email(partner_name); - var pop = new form_common.FormOpenPopup(this); - pop.show_element( - 'res.partner', - partner_id, - { 'force_email': true, + var pop = new form_common.FormViewDialog(this, { + res_model: 'res.partner', + res_id: partner_id, + context: { + 'force_email': true, 'ref': "compound_context", 'default_name': parsed_email[0], 'default_email': parsed_email[1], - }, { - title: _t("Please complete partner's informations"), - } - ); + }, + title: _t("Please complete partner's informations"), + }).open(); pop.on('closed', self, function () { deferred.resolve(); }); diff --git a/addons/mail/static/src/js/many2many_tags_email.js b/addons/mail/static/src/js/many2many_tags_email.js index 604c1662579..2250935e1da 100644 --- a/addons/mail/static/src/js/many2many_tags_email.js +++ b/addons/mail/static/src/js/many2many_tags_email.js @@ -61,15 +61,12 @@ var FieldMany2ManyTagsEmail = form_relational.FieldMany2ManyTags.extend({ // unvalid partner _.each(record_ids, function (id) { - var pop = new form_common.FormOpenPopup(self); - pop.show_element( - 'res.partner', - id, - self.build_context(), - { - title: _t("Please complete partner's informations and Email"), - } - ); + var pop = new form_common.FormViewDialog(self, { + res_model: 'res.partner', + res_id: id, + context: self.build_context(), + title: _t("Please complete partner's informations and Email"), + }).open(); pop.on('write_completed', self, function () { this.values.push(id); this.values_checking = _.without(this.values_checking, id); diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 81a1460b0bd..440c83cd14b 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1105,21 +1105,6 @@ .openerp .oe-control-panel .oe-pager-buttons { min-height: 30px; } -.openerp .o-modal-header > div { - margin-left: 45%; -} -.openerp .oe_popup_form { - display: none; -} -.openerp .oe_popup_form .oe_formview .oe_form_pager { - display: none !important; -} -.openerp .oe_popup_form table label { - font-weight: normal; -} -.openerp .oe_popup_list_pager { - float: right; -} .openerp .oe_searchview { cursor: text; position: relative; @@ -3189,49 +3174,6 @@ body.oe_single_form .oe_single_form_container { background-image: url("/web/static/lib/jquery.ui/images/ui-icons_ffffff_256x240.png"); } -.modal .modal-header button.close { - border: none; - background: none; - padding: 1px; - height: 18px; - font-size: 20px; -} -.modal .modal-body { - overflow: auto; - padding: 0; -} -.modal .modal-body .oe_application { - width: 100%; -} -.modal .modal-body .oe_popup_list { - display: none; - min-height: 150px; -} -.modal .modal-body .oe-view-manager { - min-height: 150px; -} -.modal .modal-body .oe_form_sheetbg .oe_form_sheet { - padding: 0; -} -.modal .modal-footer { - text-align: left; -} -.modal .oe_button { - margin: 0 4px 0 0; -} -.modal .oe_act_window.modal-body { - padding: 0; -} -.modal .oe-view-manager-content { - position: static !important; -} - -@media (min-width: 768px) { - .modal .modal-body { - max-height: -webkit-calc(100vh - 170px); - max-height: calc(100vh - 170px); - } -} .ui-datepicker { z-index: 1500 !important; } diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 1f7a0c1560f..4ecea186b4b 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -954,21 +954,6 @@ $sheet-padding: 16px min-height: 30px // }}} - // FormPopup {{{ - .o-modal-header - > div - margin-left: 45% - .oe_popup_form - display: none - .oe_formview .oe_form_pager - display: none !important - // Customize label weight for popup wizard appear from another wizard according bootstrap3 - table label - font-weight: normal - // End of customize - .oe_popup_list_pager - float: right - // }}} // SearchView {{{ .oe_searchview cursor: text @@ -2628,41 +2613,6 @@ body.oe_single_form background-image: url("/web/static/lib/jquery.ui/images/ui-icons_ffffff_256x240.png") // End jquery-ui override}}} -// Customized modal according bootstrap3 -.modal - .modal-header button.close - border: none - background: none - padding: 1px - height: 18px - font-size: 20px - .modal-body - overflow: auto - padding: 0 - .oe_application - width: 100% - .oe_popup_list - display: none - min-height: 150px - .oe-view-manager - min-height: 150px - .oe_form_sheetbg - .oe_form_sheet - padding: 0 - .modal-footer - text-align: left - .oe_button - margin: 0 4px 0 0 - .oe_act_window.modal-body - padding: 0 - .oe-view-manager-content - position: static !important - -@media (min-width: 768px) - .modal .modal-body - max-height: -webkit-calc(100vh - 170px) - max-height: calc(100vh - 170px) - .ui-datepicker z-index: 1500 !important diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js index 6700932b4bc..68a81a9dc68 100644 --- a/addons/web/static/src/js/action_manager.js +++ b/addons/web/static/src/js/action_manager.js @@ -529,14 +529,13 @@ var ActionManager = Widget.extend({ * @return {*} */ ir_actions_common: function(executor, options) { - var widget; if (executor.action.target === 'new') { var pre_dialog = (this.dialog && !this.dialog.isDestroyed()) ? this.dialog : null; if (pre_dialog){ // prevent previous dialog to consider itself closed, // right now, as we're opening a new one (prevents // reload of original form view) - pre_dialog.off('closing', null, pre_dialog.on_close); + pre_dialog.off('closed', null, pre_dialog.on_close); } if (this.dialog_widget && !this.dialog_widget.isDestroyed()) { this.dialog_widget.destroy(); @@ -547,6 +546,7 @@ var ActionManager = Widget.extend({ this.dialog = new Dialog(this, { title: executor.action.name, dialogClass: executor.klass, + buttons: [] }); // chain on_close triggers with previous dialog, if any @@ -560,34 +560,32 @@ var ActionManager = Widget.extend({ pre_dialog.on_close(); } }; - this.dialog.on("closing", null, this.dialog.on_close); - widget = executor.widget(); - if (widget instanceof ViewManager) { - _.extend(widget.flags, { - $buttons: this.dialog.$buttons, + this.dialog.on("closed", null, this.dialog.on_close); + this.dialog_widget = executor.widget(); + if (this.dialog_widget instanceof ViewManager) { + _.extend(this.dialog_widget.flags, { + $buttons: this.dialog.$footer, footer_to_buttons: true, }); - if (widget.action.view_mode === 'form') { - widget.flags.headless = true; + if (this.dialog_widget.action.view_mode === 'form') { + this.dialog_widget.flags.headless = true; } } - if (widget.need_control_panel) { + if (this.dialog_widget.need_control_panel) { // Set a fake bus to Dialogs needing a ControlPanel as they should not // communicate with the main ControlPanel - widget.set_cp_bus(new core.Bus()); + this.dialog_widget.set_cp_bus(new core.Bus()); } - this.dialog_widget = widget; this.dialog_widget.setParent(this.dialog); - var initialized = this.dialog_widget.appendTo(this.dialog.$el); this.dialog.open(); - return $.when(initialized); + + return this.dialog_widget.appendTo(this.dialog.$el); } if (this.inner_widget && this.webclient.has_uncommitted_changes()) { return $.Deferred().reject(); } - widget = executor.widget(); this.dialog_stop(executor.action); - return this.push_action(widget, executor.action, options); + return this.push_action(executor.widget(), executor.action, options); }, ir_actions_act_window: function (action, options) { var self = this; @@ -596,7 +594,7 @@ var ActionManager = Widget.extend({ return new ViewManager(self, null, null, null, action); }, action: action, - klass: 'oe_act_window', + klass: 'o_act_window', }, options); }, ir_actions_client: function (action, options) { diff --git a/addons/web/static/src/js/framework/crash_manager.js b/addons/web/static/src/js/framework/crash_manager.js index 303cd66a4a3..4ab40f456bc 100644 --- a/addons/web/static/src/js/framework/crash_manager.js +++ b/addons/web/static/src/js/framework/crash_manager.js @@ -118,23 +118,17 @@ var CrashManager = core.Class.extend({ size: 'medium', title: "Odoo " + (_.str.capitalize(error.type) || _t("Warning")), subtitle: error.data.title, - buttons: [ - {text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }} - ], - }, $('<div>' + QWeb.render('CrashManager.warning', {error: error}) + '</div>')).open(); + $content: $('<div>').html(QWeb.render('CrashManager.warning', {error: error})) + }).open(); }, show_error: function(error) { if (!this.active) { return; } - var buttons = {}; - buttons[_t("Ok")] = function() { - this.parents('.modal').modal('hide'); - }; new Dialog(this, { title: "Odoo " + _.str.capitalize(error.type), - buttons: buttons - }, QWeb.render('CrashManager.error', {session: session, error: error})).open(); + $content: QWeb.render('CrashManager.error', {session: session, error: error}) + }).open(); }, show_message: function(exception) { this.show_error({ @@ -181,16 +175,14 @@ var RedirectWarningHandler = Dialog.extend(ExceptionHandler, { size: 'medium', title: "Odoo " + (_.str.capitalize(error.type) || "Warning"), buttons: [ - {text: error.data.arguments[2], - oe_link_class : 'oe_highlight', - post_text : _t("or"), - click: function() { - window.location.href='#action='+error.data.arguments[1]; - self.destroy(); - }}, - {text: _t("Cancel"), oe_link_class: 'oe_link', click: function() { self.$el.parents('.modal').modal('hide'); self.destroy();}} + {text: error.data.arguments[2], classes : "btn-primary", click: function() { + window.location.href = '#action='+error.data.arguments[1]; + self.destroy(); + }}, + {text: _t("Cancel"), click: function() { self.destroy(); }, close: true} ], - }, QWeb.render('CrashManager.warning', {error: error})).open(); + $content: QWeb.render('CrashManager.warning', {error: error}) + }).open(); } }); diff --git a/addons/web/static/src/js/framework/data.js b/addons/web/static/src/js/framework/data.js index efbce3a5056..597af06118d 100644 --- a/addons/web/static/src/js/framework/data.js +++ b/addons/web/static/src/js/framework/data.js @@ -542,8 +542,8 @@ var DataSet = Class.extend(mixins.PropertiesMixin, { /** * @param name */ - name_create: function(name) { - return this._model.call('name_create', [name], {context: this.get_context()}); + name_create: function(name, context) { + return this._model.call('name_create', [name], {context: this.get_context(context)}); }, exec_workflow: function (id, signal) { return this._model.exec_workflow(id, signal); diff --git a/addons/web/static/src/js/framework/dialog.js b/addons/web/static/src/js/framework/dialog.js index 81d8860d4c3..45a00bcaa60 100644 --- a/addons/web/static/src/js/framework/dialog.js +++ b/addons/web/static/src/js/framework/dialog.js @@ -5,190 +5,167 @@ var core = require('web.core'); var Widget = require('web.Widget'); var QWeb = core.qweb; -var opened_modals = []; +var _t = core._t; /** A useful class to handle dialogs. Attributes: - - $buttons: A jQuery element targeting a dom part where buttons can be added. It always exists + - $footer: A jQuery element targeting a dom part where buttons can be added. It always exists during the lifecycle of the dialog. */ var Dialog = Widget.extend({ - dialog_title: "", /** Constructor. @param {Widget} parent - @param {dictionary} options A dictionary that will be forwarded to jQueryUI Dialog. Additionaly, that - dictionary can contain the following keys: + @param {dictionary} options + - title + - subtitle - size: one of the following: 'large', 'medium', 'small' - - dialogClass: class to add to the body of dialog - - buttons: Deprecated. The buttons key is not propagated to jQueryUI Dialog. It must be a dictionary (key = button - label, value = click handler) or a list of dictionaries (each element in the dictionary is send to the - corresponding method of a jQuery element targeting the <button> tag). It is deprecated because all dialogs - in OpenERP must be personalized in some way (button in red, link instead of button, ...) and this - feature does not allow that kind of personalization. - - destroy_on_close: Default true. If true and the dialog is closed, it is automatically destroyed. - @param {jQuery object} content Some content to replace this.$el . + - dialogClass: class to add to the modal-body + - buttons: It must be a list of dictionaries -> text, classes, close, click, disabled + -> If no buttons, a "ok" primary button is added with close = true + -> By default: close = false and classes = 'btn-primary' if only one button and 'btn-default' if many buttons + - $content: Some content to replace this.$el . */ - init: function (parent, options, content) { + init: function (parent, options) { this._super(parent); - this.content_to_set = content; - this.dialog_options = { - destroy_on_close: true, - size: 'large', //'medium', 'small' - buttons: null, - }; - if (options) { - _.extend(this.dialog_options, options); + + options = _.defaults(options || {}, { + title: _t('Odoo'), subtitle: '', + size: 'large', + dialogClass: '', + $content: false, + buttons: [{text: _t("Ok"), close: true}] + }); + + this.$content = options.$content; + + this.title = options.title; + this.subtitle = options.subtitle; + this.$modal = $(QWeb.render('Dialog', {title: this.title, subtitle: this.subtitle})); + + switch(options.size) { + case 'large': + this.$modal.find('.modal-dialog').addClass('modal-lg'); + break; + case 'small': + this.$modal.find('.modal-dialog').addClass('modal-sm'); + break; } - this.on("closing", this, this._closing); - this.$buttons = $('<div class="modal-footer"><span class="oe_dialog_custom_buttons"/></div>'); + + this.dialogClass = options.dialogClass; + this.$footer = this.$modal.find(".modal-footer"); + + this.set_buttons(options.buttons); + + this.$modal.on('hidden.bs.modal', _.bind(this.destroy, this)); }, + renderElement: function() { - if (this.content_to_set) { - this.setElement(this.content_to_set); - } else if (this.template) { - this._super(); + this._super(); + if(this.$content) { + this.setElement(this.$content); } }, - /** - Opens the popup. Inits the dialog if it is not already inited. - @return this - */ - open: function() { - if (!this.dialog_inited) { - this.init_dialog(); - } - this.$buttons.insertAfter(this.$dialog_box.find(".modal-body")); - $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal is opened - //add to list of currently opened modal - opened_modals.push(this.$dialog_box); - return this; - }, - _add_buttons: function(buttons) { + set_buttons: function(buttons) { var self = this; - var $customButons = this.$buttons.find('.oe_dialog_custom_buttons').empty(); - _.each(buttons, function(fn, text) { - // buttons can be object or array - var pre_text = fn.pre_text || ""; - var post_text = fn.post_text || ""; - var oe_link_class = fn.oe_link_class; - if (!_.isFunction(fn)) { - text = fn.text; - fn = fn.click; - } - var $but = $(QWeb.render('WidgetButton', { widget : { pre_text: pre_text, post_text: post_text, string: text, node: { attrs: {'class': oe_link_class} }}})); - $customButons.append($but); - $but.filter('button').on('click', function(ev) { - fn.call(self.$el, ev); + + self.$footer.empty(); + + _.each(buttons, function(b) { + var text = b.text || ""; + var classes = b.classes || ((buttons.length === 1)? "btn-primary" : "btn-default"); + + var $b = $(QWeb.render('WidgetButton', { widget : { string: text, node: { attrs: {'class': classes} }}})); + $b.prop('disabled', b.disabled); + $b.on('click', function(e) { + if(b.click) { + b.click.call(self, e); + } + if(b.close) { + self.close(); + } }); + self.$footer.append($b); }); }, - /** - Initializes the popup. - - @return The result returned by start(). - */ - init_dialog: function() { - var self = this; - var options = _.extend({}, this.dialog_options); - options.title = options.title || this.dialog_title; - if (options.buttons) { - this._add_buttons(options.buttons); - delete(options.buttons); - } - this.renderElement(); - this.$dialog_box = $(QWeb.render('Dialog', options)).appendTo("body"); - this.$el.modal({ - 'backdrop': false, - 'keyboard': true, - }); - if (options.size !== 'large'){ - var dialog_class_size = this.$dialog_box.find('.modal-lg').removeClass('modal-lg'); - if (options.size === 'small'){ - dialog_class_size.addClass('modal-sm'); - } + + set_title: function(title, subtitle) { + this.title = title || ""; + if(subtitle !== undefined) { + this.subtitle = subtitle || ""; } - this.$el.appendTo(this.$dialog_box.find(".modal-body")); - var $dialog_content = this.$dialog_box.find('.modal-content'); - if (options.dialogClass){ - $dialog_content.find(".modal-body").addClass(options.dialogClass); - } - $dialog_content.openerpClass(); + var $title = this.$modal.find('.modal-title').first(); + var $subtitle = $title.find('.o_subtitle').detach(); + $title.html(this.title); + $subtitle.html(this.subtitle).appendTo($title); - this.$dialog_box.on('hidden.bs.modal', this, function() { - self.close(); - }); - this.$dialog_box.modal('show'); + return this; + }, + + open: function() { + $('.tooltip').remove(); // remove open tooltip if any to prevent them staying when modal is opened - this.dialog_inited = true; - var res = this.start(); - return res; + var self = this; + this.replace(this.$modal.find(".modal-body")).then(function() { + self.$el.addClass('modal-body ' + self.dialogClass); + self.$modal.modal('show'); + }); + + return self; }, - /** - Closes (hide) the popup, if destroy_on_close was passed to the constructor, it will be destroyed instead. - */ - close: function(reason) { - if (this.dialog_inited && !this.__tmp_dialog_hiding) { - $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared - if (this.$el.is(":data(bs.modal)")) { // may have been destroyed by closing signal - this.__tmp_dialog_hiding = true; - this.$dialog_box.modal('hide'); - this.__tmp_dialog_hiding = undefined; - } - this.trigger("closing", reason); - } + + close: function() { + this.$modal.modal('hide'); }, - _closing: function() { - if (this.__tmp_dialog_destroying) + + destroy: function() { + if(this.isDestroyed()) return; - if (this.dialog_options.destroy_on_close) { - this.__tmp_dialog_closing = true; - this.destroy(); - this.__tmp_dialog_closing = undefined; - } - }, - /** - Destroys the popup, also closes it. - */ - destroy: function (reason) { - this.$buttons.remove(); - _.each(this.getChildren(), function(el) { - el.destroy(); - }); - if (! this.__tmp_dialog_closing) { - this.__tmp_dialog_destroying = true; - this.close(reason); - this.__tmp_dialog_destroying = undefined; - } - if (this.dialog_inited && !this.isDestroyed() && this.$el.is(":data(bs.modal)")) { - //we need this to put the instruction to remove modal from DOM at the end - //of the queue, otherwise it might already have been removed before the modal-backdrop - //is removed when pressing escape key - var $element = this.$dialog_box; - setTimeout(function () { - //remove modal from list of opened modal since we just destroy it - var modal_list_index = $.inArray($element, opened_modals); - if (modal_list_index > -1){ - opened_modals.splice(modal_list_index,1)[0].remove(); - } - if (opened_modals.length > 0){ - //we still have other opened modal so we should focus it - opened_modals[opened_modals.length-1].focus(); - //keep class modal-open (deleted by bootstrap hide fnct) on body - //to allow scrolling inside the modal - $('body').addClass('modal-open'); - } - },0); - } + + this.trigger("closed"); + this._super(); + + $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared + this.$modal.modal('hide'); + this.$modal.remove(); + + setTimeout(function () { // Keep class modal-open (deleted by bootstrap hide fnct) on body to allow scrolling inside the modal + var modals = $('body > .modal'); + if(modals.length) { + modals.last().focus(); + $('body').addClass('modal-open'); + } + }, 0); } }); + +// static method to open simple confirm dialog +Dialog.confirm = function (owner, message, confirm_callback) { + var buttons = [ + { + text: _t("Ok"), + classes: 'btn-primary', + close: true, + click: confirm_callback + }, + {text: _t("Cancel"), close: true} + ]; + return new Dialog(owner, { + size: 'medium', + buttons: buttons, + $content: $('<div>', { + text: message, + }), + }).open(); +} + return Dialog; }); diff --git a/addons/web/static/src/js/view_manager.js b/addons/web/static/src/js/view_manager.js index d5ca65b5d61..19c645d314d 100644 --- a/addons/web/static/src/js/view_manager.js +++ b/addons/web/static/src/js/view_manager.js @@ -180,7 +180,7 @@ var ViewManager = Widget.extend(ControlPanelMixin, { if (view.type === "form" && ((this.action && (this.action.target === 'new' || this.action.target === 'inline')) || (view_options && view_options.mode === 'edit'))) { - options.initial_mode = 'edit'; + options.initial_mode = options.initial_mode || 'edit'; } var controller = new View(this, this.dataset, view.view_id, options); var $container = view.$container; diff --git a/addons/web/static/src/js/views/form_common.js b/addons/web/static/src/js/views/form_common.js index e365e61a0b8..7786a516894 100644 --- a/addons/web/static/src/js/views/form_common.js +++ b/addons/web/static/src/js/views/form_common.js @@ -115,7 +115,6 @@ var DefaultFieldManager = Widget.extend({ }, }); - /** * A mixin to apply on any FormWidget that has to completely re-render when its readonly state * switch. @@ -273,22 +272,19 @@ var CompletionFieldMixin = { // all search/create popup handling _search_create_popup: function(view, ids, context) { var self = this; - var pop = new SelectCreatePopup(this); - pop.select_element( - self.field.relation, - { - title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string, - initial_ids: ids ? _.map(ids, function(x) {return x[0];}) : undefined, - initial_view: view, - disable_multiple_selection: true - }, - self.build_domain(), - new data.CompoundContext(self.build_context(), context || {}) - ); - pop.on("elements_selected", self, function(element_ids) { - self.add_id(element_ids[0]); - self.focus(); - }); + new SelectCreateDialog(this, { + res_model: self.field.relation, + domain: self.build_domain(), + context: new data.CompoundContext(self.build_context(), context || {}), + title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string, + initial_ids: ids ? _.map(ids, function(x) {return x[0];}) : undefined, + initial_view: view, + disable_multiple_selection: true, + on_selected: function(element_ids) { + self.add_id(element_ids[0]); + self.focus(); + } + }).open(); }, /** * To implement. @@ -305,8 +301,6 @@ var CompletionFieldMixin = { }, }; - - /** * Must be applied over an class already possessing the PropertiesMixin. * @@ -389,7 +383,6 @@ var NotebookInvisibilityChanger = InvisibilityChanger.extend({ }, }); - /** Base class for all fields, custom widgets and buttons to be displayed in the form view. @@ -779,10 +772,9 @@ var AbstractField = FormWidget.extend(FieldInterface, { }); /** - * Class with everything which is common between FormOpenPopup and SelectCreatePopup. + * Class with everything which is common between FormViewDialog and SelectCreateDialog. */ -var AbstractFormPopup = Widget.extend({ - template: "AbstractFormPopup.render", +var ViewDialog = Dialog.extend({ // FIXME should use ViewManager /** * options: * -readonly: only applicable when not in creation mode, default to false @@ -795,18 +787,27 @@ var AbstractFormPopup = Widget.extend({ * - child_name * - form_view_options */ - init_popup: function(model, row_id, domain, context, options) { - this.row_id = row_id; - this.model = model; - this.domain = domain || []; - this.context = context || {}; - this.options = options; - _.defaults(this.options, {}); + init: function(parent, options) { + options = options || {}; + options.dialogClass = options.dialogClass || ''; + options.dialogClass += ' o_act_window'; + + this._super(parent, _.clone(options)); + + this.res_model = options.res_model || null; + this.res_id = options.res_id || null; + this.domain = options.domain || []; + this.context = options.context || {}; + this.options = _.extend(this.options || {}, options || {}); + + this.on('closed', this, this.select); + this.on_selected = options.on_selected || (function() {}); }, + init_dataset: function() { var self = this; this.created_elements = []; - this.dataset = new data.ProxyDataSet(this, this.model, this.context); + this.dataset = new data.ProxyDataSet(this, this.res_model, this.context); this.dataset.read_function = this.options.read_function; this.dataset.create_function = function(data, options, sup) { var fct = self.options.create_function || sup; @@ -824,114 +825,102 @@ var AbstractFormPopup = Widget.extend({ this.dataset.parent_view = this.options.parent_view; this.dataset.child_name = this.options.child_name; }, - display_popup: function() { + + select: function() { + if (this.created_elements.length > 0) { + this.on_selected(this.created_elements); + this.created_elements = []; + } + } +}); + +/** + * Create and edit dialog (displays a form view record and leave once saved) + */ +var FormViewDialog = ViewDialog.extend({ + init: function(parent, options) { var self = this; - this.renderElement(); - var dialog = new Dialog(this, { - dialogClass: 'oe_act_window', - title: this.options.title || "", - }, this.$el).open(); - dialog.on('closing', this, function (e){ - self.check_exit(true); - }); - this.$buttonpane = dialog.$buttons; - this.start(); + + var multi_select = options.res_id === null && ! options.disable_multiple_selection; + var readonly = options.res_id !== null && options.readonly; + + if(!options || !options.buttons) { + options = options || {}; + options.buttons = [ + {text: (readonly ? _t("Close") : _t("Discard")), classes: "btn-default o_form_button_cancel", close: true, click: function() { + self.view_form.trigger('on_button_cancel'); + }} + ]; + + if(!readonly) { + options.buttons.splice(0, 0, {text: _t("Save") + ((multi_select)? _t(" & Close") : ""), classes: "btn-primary", click: function() { + $.when(self.view_form.save()).done(function() { + self.view_form.reload_mutex.exec(function() { + self.trigger('record_saved'); + self.close(); + }); + }); + } + }); + + if(multi_select) { + options.buttons.splice(1, 0, {text: _t("Save & New"), classes: "btn-primary", click: function() { + $.when(self.view_form.save()).done(function() { + self.view_form.reload_mutex.exec(function() { + self.view_form.on_button_new(); + }); + }); + }}); + } + } + } + + this._super(parent, options); }, - setup_form_view: function() { + + open: function() { var self = this; - if (this.row_id) { - this.dataset.ids = [this.row_id]; - this.dataset.index = 0; + self._super(); + self.init_dataset(); + + if (self.res_id) { + self.dataset.ids = [self.res_id]; + self.dataset.index = 0; } else { - this.dataset.index = null; + self.dataset.index = null; } var options = _.clone(self.options.form_view_options) || {}; - if (this.row_id !== null) { - options.initial_mode = this.options.readonly ? "view" : "edit"; + if (self.res_id !== null) { + options.initial_mode = self.options.readonly ? "view" : "edit"; } _.extend(options, { - $buttons: this.$buttonpane, + $buttons: self.$buttons, }); var FormView = core.view_registry.get('form'); - this.view_form = new FormView(this, this.dataset, this.options.view_id || false, options); - if (this.options.alternative_form_view) { - this.view_form.set_embedded_view(this.options.alternative_form_view); + self.view_form = new FormView(self, self.dataset, self.options.view_id || false, options); + if (self.options.alternative_form_view) { + self.view_form.set_embedded_view(self.options.alternative_form_view); } - this.view_form.appendTo(this.$(".oe_popup_form").show()); - this.view_form.on("form_view_loaded", self, function() { - var multi_select = self.row_id === null && ! self.options.disable_multiple_selection; - self.$buttonpane.html(QWeb.render("AbstractFormPopup.buttons", { - multi_select: multi_select, - readonly: self.row_id !== null && self.options.readonly, - })); - var $snbutton = self.$buttonpane.find(".oe_abstractformpopup-form-save-new"); - $snbutton.click(function() { - $.when(self.view_form.save()).done(function() { - self.view_form.reload_mutex.exec(function() { - self.view_form.on_button_new(); - }); - }); - }); - var $sbutton = self.$buttonpane.find(".oe_abstractformpopup-form-save"); - $sbutton.click(function() { - $.when(self.view_form.save()).done(function() { - self.view_form.reload_mutex.exec(function() { - self.check_exit(); - }); - }); - }); - var $cbutton = self.$buttonpane.find(".oe_abstractformpopup-form-close"); - $cbutton.click(function() { - self.view_form.trigger('on_button_cancel'); - self.check_exit(); + + self.$el.hide(); + self.view_form.appendTo(self.$el); + self.view_form.on("form_view_loaded", self, function() { + self.view_form.do_show().then(function() { + self.$el.show(); }); - self.view_form.do_show(); }); - }, - select_elements: function(element_ids) { - this.trigger("elements_selected", element_ids); - }, - check_exit: function(no_destroy) { - if (this.created_elements.length > 0) { - this.select_elements(this.created_elements); - this.created_elements = []; - } - this.trigger('closed'); - this.destroy(); - }, - destroy: function () { - this.trigger('closed'); - if (this.$el.is(":data(bs.modal)")) { - this.$el.parents('.modal').modal('hide'); - } - this._super(); - }, -}); -/** - * Class to display a popup containing a form view. - */ -var FormOpenPopup = AbstractFormPopup.extend({ - show_element: function(model, row_id, context, options) { - this.init_popup(model, row_id, [], context, options); - _.defaults(this.options, { - }); - this.display_popup(); - }, - start: function() { - this._super(); - this.init_dataset(); - this.setup_form_view(); + return this; }, }); var SelectCreateListView = ListView.extend({ do_add_record: function () { - this.popup.new_object(); + this.popup.create_edit_record(); }, select_record: function(index) { - this.popup.select_elements([this.dataset.ids[index]]); - this.popup.destroy(); + this.popup.on_selected([this.dataset.ids[index]]); + this.popup.close(); }, do_select: function(ids, records) { this._super(ids, records); @@ -940,10 +929,9 @@ var SelectCreateListView = ListView.extend({ }); /** - * Class to display a popup to display a list to search a row. It also allows - * to switch to a form view to create a new row. + * Search dialog (displays a list of records and permits to create a new one by switching to a form view) */ -var SelectCreatePopup = AbstractFormPopup.extend({ +var SelectCreateDialog = ViewDialog.extend({ /** * options: * - initial_ids @@ -951,15 +939,15 @@ var SelectCreatePopup = AbstractFormPopup.extend({ * - disable_multiple_selection * - list_view_options */ - select_element: function(model, options, domain, context) { - this.init_popup(model, null, domain, context, options); - _.defaults(this.options, { - initial_view: "search", - }); + init: function(parent, options) { + this._super(parent, options); + + _.defaults(this.options, { initial_view: "search" }); this.initial_ids = this.options.initial_ids; - this.display_popup(); }, - start: function() { + + open: function() { + this._super(); this.init_dataset(); if (this.options.initial_view == "search") { var context = pyeval.sync_eval_domains_and_contexts({ @@ -973,19 +961,21 @@ var SelectCreatePopup = AbstractFormPopup.extend({ search_defaults[match[1]] = value_; } }); - this.setup_search_view(search_defaults); + this.setup(search_defaults); } else { // "form" - this.new_object(); + this.create_edit_record(); } + return this; }, - setup_search_view: function(search_defaults) { + + setup: function(search_defaults) { var self = this; if (this.searchview) { this.searchview.destroy(); } - var $buttons = this.$('.o-search-options'); - this.searchview = new SearchView(this, - this.dataset, false, search_defaults, {$buttons: $buttons}); + var $header = $('<div/>').addClass('o_modal_header').appendTo(this.$el); + var $buttons = $('<div/>').addClass('o_search_options').appendTo($header); + this.searchview = new SearchView(this, this.dataset, false, search_defaults, {$buttons: $buttons}); this.searchview.on('search_data', self, function(domains, contexts, groupbys) { if (self.initial_ids) { self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]), @@ -995,22 +985,22 @@ var SelectCreatePopup = AbstractFormPopup.extend({ self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys); } }); - this.searchview.appendTo(this.$(".o-popup-search")).done(function() { + this.searchview.prependTo($header).done(function() { self.searchview.toggle_visibility(true); self.view_list = new SelectCreateListView(self, - self.dataset, false, - _.extend({'deletable': false, - 'selectable': !self.options.disable_multiple_selection, - 'import_enabled': false, - '$buttons': self.$buttonpane, - 'disable_editable_mode': true, - '$pager': self.$('.oe_popup_list_pager'), - }, self.options.list_view_options || {})); + self.dataset, false, + _.extend({'deletable': false, + 'selectable': !self.options.disable_multiple_selection, + 'import_enabled': false, + '$buttons': self.$footer, + 'disable_editable_mode': true, + '$pager': self.$('.o_popup_list_pager'), + }, self.options.list_view_options || {})); self.view_list.on('edit:before', self, function (e) { e.cancel = true; }); self.view_list.popup = self; - self.view_list.appendTo(self.$(".oe_popup_list").show()).then(function() { + self.view_list.appendTo(self.$el).then(function() { self.view_list.do_show(); }).then(function() { if (self.options.initial_facet) { @@ -1020,23 +1010,22 @@ var SelectCreatePopup = AbstractFormPopup.extend({ } self.searchview.do_search(); }); - self.view_list.on("list_view_loaded", self, function() { - self.$buttonpane.html(QWeb.render("SelectCreatePopup.search.buttons", {widget:self})); - var $cbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-close"); - $cbutton.click(function() { - self.destroy(); - }); - var $sbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-select"); - $sbutton.click(function() { - self.select_elements(self.selected_ids); - self.destroy(); - }); - $cbutton = self.$buttonpane.find(".oe_selectcreatepopup-search-create"); - $cbutton.click(function() { - self.new_object(); - }); - }); - }); + + var buttons = [ + {text: _t("Cancel"), classes: "btn-default o_form_button_cancel", close: true} + ]; + if(!self.options.no_create) { + buttons.splice(0, 0, {text: _t("Create"), classes: "btn-primary", click: function() { + self.create_edit_record(); + }}); + } + if(!self.options.disable_multiple_selection) { + buttons.splice(0, 0, {text: _t("Select"), classes: "btn-primary o_selectcreatepopup_search_select", disabled: true, close: true, click: function() { + self.on_selected(self.selected_ids); + }}); + } + self.set_buttons(buttons); + }); }, do_search: function(domains, contexts, groupbys) { var results = pyeval.sync_eval_domains_and_contexts({ @@ -1047,43 +1036,35 @@ var SelectCreatePopup = AbstractFormPopup.extend({ this.view_list.do_search(results.domain, results.context, results.group_by); }, on_click_element: function(ids) { - var self = this; this.selected_ids = ids || []; - if(this.selected_ids.length > 0) { - self.$buttonpane.find(".oe_selectcreatepopup-search-select").removeAttr('disabled'); - } else { - self.$buttonpane.find(".oe_selectcreatepopup-search-select").attr('disabled', "disabled"); - } + this.$footer.find(".o_selectcreatepopup_search_select").prop('disabled', this.selected_ids.length <= 0); }, - new_object: function() { - if (this.searchview) { - this.searchview.toggle_visibility(false); - } - if (this.view_list) { - this.view_list.do_hide(); - this.view_list.$el.parent().hide(); - } - this.setup_form_view(); + create_edit_record: function() { + new FormViewDialog(this.getParent(), this.options).open(); + this.close(); }, }); -var DomainEditorPopup = SelectCreatePopup.extend({ - select_element: function (model, options, domain, context) { +var DomainEditorDialog = SelectCreateDialog.extend({ + init: function(parent, options) { if (options.readonly) { - return this._super(model, options, domain, context); + this._super(parent, options); + return; } - options.initial_facet = { + options = _.defaults(options, {initial_facet: { category: _t("Custom Filter"), icon: 'fa-star', field: { - get_context: function () { return context; }, + get_context: function () { return options.context; }, get_groupby: function () { return []; }, - get_domain: function () { return domain; }, + get_domain: function () { return options.default_domain; }, }, values: [{label: _t("Selected domain"), value: null}], - }; - this._super(model, options, [], context); + }}); + + this._super(parent, options); }, + get_domain: function (selected_ids) { var group_domain = [], domain; @@ -1125,11 +1106,11 @@ return { commands: commands, AbstractField: AbstractField, - // popup dialogs - AbstractFormPopup: AbstractFormPopup, - FormOpenPopup: FormOpenPopup, - SelectCreatePopup: SelectCreatePopup, - DomainEditorPopup: DomainEditorPopup, + // Dialogs + ViewDialog: ViewDialog, + FormViewDialog: FormViewDialog, + SelectCreateDialog: SelectCreateDialog, + DomainEditorDialog: DomainEditorDialog, }; });
\ No newline at end of file diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js index df8e0150aa1..f2e3d77fff4 100644 --- a/addons/web/static/src/js/views/form_relational_widgets.js +++ b/addons/web/static/src/js/views/form_relational_widgets.js @@ -144,20 +144,17 @@ var FieldMany2One = common.AbstractField.extend(common.CompletionFieldMixin, com self.focus(); return; } - var pop = new common.FormOpenPopup(self); var context = self.build_context().eval(); var model_obj = new Model(self.field.relation); model_obj.call('get_formview_id', [self.get("value"), context]).then(function(view_id){ - pop.show_element( - self.field.relation, - self.get("value"), - self.build_context(), - { - title: _t("Open: ") + self.string, - view_id: view_id, - readonly: !self.can_write - } - ); + var pop = new common.FormViewDialog(self, { + res_model: self.field.relation, + res_id: self.get("value"), + context: self.build_context(), + title: _t("Open: ") + self.string, + view_id: view_id, + readonly: !self.can_write + }).open(); pop.on('write_completed', self, function(){ self.display_value = {}; self.display_value_backup = {}; @@ -261,7 +258,7 @@ var FieldMany2One = common.AbstractField.extend(common.CompletionFieldMixin, com // autocomplete open if (ignore_blur) { $(this).focus(); return; } if (_(self.getChildren()).any(function (child) { - return child instanceof common.AbstractFormPopup; + return child instanceof common.ViewDialog; })) { return; } self.trigger('blurred'); } @@ -997,35 +994,34 @@ var One2ManyListView = ListView.extend({ this._super.apply(this, arguments); } else { var self = this; - var pop = new common.SelectCreatePopup(this); - pop.select_element( - self.o2m.field.relation, - { - title: _t("Create: ") + self.o2m.string, - initial_view: "form", - alternative_form_view: self.o2m.field.views ? self.o2m.field.views.form : undefined, - create_function: function(data, options) { - return self.o2m.data_create(data, options); - }, - read_function: function(ids, fields, options) { - return self.o2m.data_read(ids, fields, options); - }, - parent_view: self.o2m.view, - child_name: self.o2m.name, - form_view_options: {'not_interactible_on_create':true} + new common.SelectCreateDialog(this, { + res_model: self.o2m.field.relation, + domain: self.o2m.build_domain(), + context: self.o2m.build_context(), + title: _t("Create: ") + self.o2m.string, + initial_view: "form", + alternative_form_view: self.o2m.field.views ? self.o2m.field.views.form : undefined, + create_function: function(data, options) { + return self.o2m.data_create(data, options); }, - self.o2m.build_domain(), - self.o2m.build_context() - ); - pop.on("elements_selected", self, function() { - self.o2m.reload_current_view(); - }); + read_function: function(ids, fields, options) { + return self.o2m.data_read(ids, fields, options); + }, + parent_view: self.o2m.view, + child_name: self.o2m.name, + form_view_options: {'not_interactible_on_create':true}, + on_selected: function() { + self.o2m.reload_current_view(); + } + }).open(); } }, do_activate_record: function(index, id) { var self = this; - var pop = new common.FormOpenPopup(self); - pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), { + new common.FormViewDialog(self, { + res_model: self.o2m.field.relation, + res_id: id, + context: self.o2m.build_context(), title: _t("Open: ") + self.o2m.string, write_function: function(id, data) { return self.o2m.data_update(id, data, {}).done(function() { @@ -1040,7 +1036,7 @@ var One2ManyListView = ListView.extend({ }, form_view_options: {'not_interactible_on_create':true}, readonly: !this.is_action_enabled('edit') || self.o2m.get("effective_readonly") - }); + }).open(); }, do_button_action: function (name, id, callback) { if (!_.isNumber(id)) { @@ -1201,8 +1197,11 @@ var One2ManyViewManager = ViewManager.extend({ } var self = this; var id = self.o2m.dataset.index !== null ? self.o2m.dataset.ids[self.o2m.dataset.index] : null; - var pop = new common.FormOpenPopup(this); - pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), { + var pop = new common.FormViewDialog(this, { + res_model: self.o2m.field.relation, + res_id: id, + context: self.o2m.build_context(), + title: _t("Open: ") + self.o2m.string, create_function: function(data, options) { return self.o2m.data_create(data, options); @@ -1220,7 +1219,7 @@ var One2ManyViewManager = ViewManager.extend({ }, form_view_options: {'not_interactible_on_create':true}, readonly: self.o2m.get("effective_readonly") - }); + }).open(); pop.on("elements_selected", self, function() { self.o2m.reload_current_view(); }); @@ -1466,30 +1465,30 @@ var Many2ManyListView = ListView.extend(/** @lends instance.web.form.Many2ManyLi })); }, do_add_record: function () { - var pop = new common.SelectCreatePopup(this); - pop.select_element( - this.model, - { - title: _t("Add: ") + this.m2m_field.string, - alternative_form_view: this.m2m_field.field.views ? this.m2m_field.field.views.form : undefined, - no_create: this.m2m_field.options.no_create, - }, - new data.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]), - this.m2m_field.build_context() - ); var self = this; - pop.on("elements_selected", self, function(element_ids) { - return self.dataset.o2m.data_link_multi(element_ids); - }); + + new common.SelectCreateDialog(this, { + res_model: this.model, + domain: new data.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]), + context: this.m2m_field.build_context(), + title: _t("Add: ") + this.m2m_field.string, + alternative_form_view: this.m2m_field.field.views ? this.m2m_field.field.views.form : undefined, + no_create: this.m2m_field.options.no_create, + on_selected: function(element_ids) { + return self.dataset.o2m.data_link_multi(element_ids); + } + }).open(); }, do_activate_record: function(index, id) { var self = this; - var pop = new common.FormOpenPopup(this); - pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), { + var pop = new common.FormViewDialog(this, { + res_model: this.dataset.model, + res_id: id, + context: this.m2m_field.build_context(), title: _t("Open: ") + this.m2m_field.string, alternative_form_view: this.m2m_field.field.views ? this.m2m_field.field.views.form : undefined, readonly: this.getParent().get("effective_readonly") - }); + }).open(); pop.on('write_completed', self, function () { self.dataset.evict_record(id); self.reload_content(); @@ -1579,22 +1578,21 @@ var FieldMany2ManyKanban = AbstractManyField.extend(common.CompletionFieldMixin, var self = this; var pop; if (this.dataset.index === null) { - pop = new common.SelectCreatePopup(this); - pop.select_element( - this.field.relation, - { - title: _t("Add: ") + this.string - }, - new data.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]), - this.build_context() - ); - pop.on("elements_selected", self, function(element_ids) { - return self.data_link_multi(element_ids); - }); + new common.SelectCreateDialog(this, { + res_model: this.field.relation, + domain: new data.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]), + context: this.build_context(), + title: _t("Add: ") + this.string, + on_selected: function(element_ids) { + return self.data_link_multi(element_ids); + } + }).open(); } else { var id = self.dataset.ids[self.dataset.index]; - pop = new common.FormOpenPopup(this); - pop.show_element(self.field.relation, id, self.build_context(), { + pop = new common.FormViewDialog(this, { + res_model: self.field.relation, + res_id: id, + context: self.build_context(), title: _t("Open: ") + self.string, write_function: function(id, data, options) { return self.data_update(id, data, {}).done(function() { @@ -1605,7 +1603,7 @@ var FieldMany2ManyKanban = AbstractManyField.extend(common.CompletionFieldMixin, parent_view: self.view, child_name: self.name, readonly: self.get("effective_readonly") - }); + }).open(); } }, add_id: function(id) { diff --git a/addons/web/static/src/js/views/form_view.js b/addons/web/static/src/js/views/form_view.js index df570967f94..35aa0223a13 100644 --- a/addons/web/static/src/js/views/form_view.js +++ b/addons/web/static/src/js/views/form_view.js @@ -583,10 +583,8 @@ var FormView = View.extend(common.FieldManagerMixin, { new Dialog(this, { size: 'medium', title:result.warning.title, - buttons: [ - {text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }} - ] - }, QWeb.render("CrashManager.warning", result.warning)).open(); + $content: QWeb.render("CrashManager.warning", result.warning) + }).open(); } return $.Deferred().resolve(); @@ -1081,12 +1079,8 @@ var FormView = View.extend(common.FieldManagerMixin, { .value(); var d = new Dialog(this, { title: _t("Set Default"), - args: { - fields: fields, - conditions: conditions - }, buttons: [ - {text: _t("Close"), click: function () { d.close(); }}, + {text: _t("Close"), close: true}, {text: _t("Save default"), click: function () { var $defaults = d.$el.find('#formview_default_fields'); var field_to_set = $defaults.val(); @@ -1108,6 +1102,10 @@ var FormView = View.extend(common.FieldManagerMixin, { }} ] }); + d.args = { + fields: fields, + conditions: conditions + }; d.template = 'FormView.set_default'; d.open(); }, diff --git a/addons/web/static/src/js/views/form_widgets.js b/addons/web/static/src/js/views/form_widgets.js index 2358ea88dec..49d909af041 100644 --- a/addons/web/static/src/js/views/form_widgets.js +++ b/addons/web/static/src/js/views/form_widgets.js @@ -62,10 +62,7 @@ var WidgetButton = common.FormWidget.extend({ var dialog = new Dialog(this, { title: _t('Confirm'), buttons: [ - {text: _t("Cancel"), click: function() { - this.parents('.modal').modal('hide'); - } - }, + {text: _t("Cancel"), close: true}, {text: _t("Ok"), click: function() { var self2 = this; self.on_confirmed().always(function() { @@ -74,8 +71,9 @@ var WidgetButton = common.FormWidget.extend({ } } ], - }, $('<div/>').text(self.node.attrs.confirm)).open(); - dialog.on("closing", null, function() {def.resolve();}); + $content: $('<div/>').text(self.node.attrs.confirm) + }).open(); + dialog.on("closed", null, function() {def.resolve();}); return def.promise(); } else { return self.on_confirmed(); @@ -439,22 +437,20 @@ var FieldCharDomain = common.AbstractField.extend(common.ReinitializeFieldMixin, on_click: function(event) { event.preventDefault(); var self = this; - var model = this.options.model || this.field_manager.get_field_value(this.options.model_field); - var options = { - title: this.get('effective_readonly') ? 'Selected records' : 'Select records...', - readonly: this.get('effective_readonly'), - disable_multiple_selection: this.get('effective_readonly'), - no_create: this.get('effective_readonly'), - }; - var domain = this.get('value'); - var popup = new common.DomainEditorPopup(this); - popup.select_element(model, options, domain, {}); - popup.on("elements_selected", self, function(selected_ids) { - if (!self.get('effective_readonly')) { - self.set_value(popup.get_domain(selected_ids)); + new common.DomainEditorDialog(this, { + model: this.options.model || this.field_manager.get_field_value(this.options.model_field), + domain: this.get('value'), + title: this.get('effective_readonly') ? 'Selected records' : 'Select records...', + readonly: this.get('effective_readonly'), + disable_multiple_selection: this.get('effective_readonly'), + no_create: this.get('effective_readonly'), + on_selected: function(selected_ids) { + if (!self.get('effective_readonly')) { + self.set_value(popup.get_domain(selected_ids)); + } } - }); + }).open(); }, }); diff --git a/addons/web/static/src/js/widgets/change_password.js b/addons/web/static/src/js/widgets/change_password.js index 0ddfb20c4df..cded9dc9a4d 100644 --- a/addons/web/static/src/js/widgets/change_password.js +++ b/addons/web/static/src/js/widgets/change_password.js @@ -7,11 +7,11 @@ var Widget = require('web.Widget'); var _t = core._t; -var ChangePassword = Widget.extend({ +var ChangePassword = Widget.extend({ // FIXME template: "ChangePassword", start: function() { var self = this; - this.getParent().dialog_title = _t("Change Password"); + this.getParent().set_title(_t("Change Password")); var $button = self.$el.find('.oe_form_button'); $button.appendTo(this.getParent().$buttons); $button.eq(2).click(function(){ @@ -34,10 +34,8 @@ var ChangePassword = Widget.extend({ return new Dialog(this, { size: 'medium', title: error.title, - buttons: [ - {text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }} - ] - }, $('<div>').html(error.error)).open(); + $content: $('<div>').html(error.error) + }).open(); }, }); diff --git a/addons/web/static/src/js/widgets/data_export.js b/addons/web/static/src/js/widgets/data_export.js index 946862d7102..57159732ad6 100644 --- a/addons/web/static/src/js/widgets/data_export.js +++ b/addons/web/static/src/js/widgets/data_export.js @@ -12,7 +12,6 @@ var _t = core._t; var DataExport = Dialog.extend({ template: 'ExportTreeView', - dialog_title: {toString: function () { return _t("Export Data"); }}, events: { 'click #add_field': function () { var self = this; @@ -48,6 +47,7 @@ var DataExport = Dialog.extend({ this.dataset = dataset; this.exports = new data.DataSetSearch( this, 'ir.exports', this.dataset.get_context()); + this.set_title(_t("Export Data")); }, start: function() { var self = this; diff --git a/addons/web/static/src/js/widgets/database_manager.js b/addons/web/static/src/js/widgets/database_manager.js index 180d42b59b6..cbffa5117dc 100644 --- a/addons/web/static/src/js/widgets/database_manager.js +++ b/addons/web/static/src/js/widgets/database_manager.js @@ -99,10 +99,8 @@ var DataBaseManager = Widget.extend({ return new Dialog(this, { size: 'medium', title: error.title, - buttons: [ - {text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }} - ] - }, $('<div>').html(error.error)).open(); + $content: $('<div>').html(error.error) + }).open(); }, do_create: function(form) { var fields = $(form).serializeArray(); diff --git a/addons/web/static/src/js/widgets/debug_manager.js b/addons/web/static/src/js/widgets/debug_manager.js index 01db3ff71ef..b529e155fd9 100644 --- a/addons/web/static/src/js/widgets/debug_manager.js +++ b/addons/web/static/src/js/widgets/debug_manager.js @@ -131,12 +131,9 @@ if (core.debug) { }); }); new Dialog(self, { - title: _.str.sprintf(_t("Model %s fields"), - self.dataset.model), - buttons: { - Ok: function() { this.parents('.modal').modal('hide');} - }, - }, $root).open(); + title: _.str.sprintf(_t("Model %s fields"), self.dataset.model), + $content: $root + }).open(); }); }, fvg: function() { diff --git a/addons/web/static/src/js/widgets/sidebar.js b/addons/web/static/src/js/widgets/sidebar.js index 5dc6c147f39..9f7c46bf48d 100644 --- a/addons/web/static/src/js/widgets/sidebar.js +++ b/addons/web/static/src/js/widgets/sidebar.js @@ -121,7 +121,7 @@ var Sidebar = Widget.extend({ domain = $.Deferred().resolve(undefined); } if (ids.length === 0) { - new Dialog(this, { title: _t("Warning"), size: 'medium',}, $("<div />").text(_t("You must choose at least one record."))).open(); + new Dialog(this, {title: _t("Warning"), size: 'medium', $content: $("<div/>").html(_t("You must choose at least one record."))}).open(); return false; } var dataset = self.getParent().dataset; diff --git a/addons/web/static/src/js/widgets/user_menu.js b/addons/web/static/src/js/widgets/user_menu.js index dba1704c719..3d360c1eae6 100644 --- a/addons/web/static/src/js/widgets/user_menu.js +++ b/addons/web/static/src/js/widgets/user_menu.js @@ -101,9 +101,10 @@ var SystrayMenu = Widget.extend({ }); new Dialog(this, { size: 'medium', - dialogClass: 'oe_act_window', + dialogClass: 'o_act_window', title: _t("About"), - }, $help).open(); + $content: $help + }).open(); }); }, }); diff --git a/addons/web/static/src/less/modal.less b/addons/web/static/src/less/modal.less new file mode 100644 index 00000000000..784fb47aaf8 --- /dev/null +++ b/addons/web/static/src/less/modal.less @@ -0,0 +1,51 @@ +.modal { + + .modal-content { + border-radius: 0; + + .modal-body { + &.o_act_window { + padding: 0; + } + + .o_modal_header { + .o-webclient-padding(@top: 10px, @bottom: 10px); + + .o_popup_list_pager { // FIXME : should check where it is used (o_modal_header ~= control panel) + float: right; + } + } + + .oe-view-manager-content { + position: static; // Reset position for view managers in modals (default value: absolute) + } + } + + .modal-footer { + text-align: left; + } + } + + + @media (min-width: @screen-sm-min) { + .modal-dialog { + height: 100%; + padding: 30px 0; + margin: 0 auto; + + .modal-content { + max-height: 100%; + .o-flex-display(); + .o-flex-flow(column, nowrap); + + .modal-header, .modal-footer { + .o-flex(0, 0, auto); + } + + .modal-body { + overflow: auto; + } + } + } + } +} diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 52a7c8130a6..814ef171032 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -25,38 +25,30 @@ </t> <t t-name="Dialog"> <div class="modal" tabindex="-1" data-backdrop="static" role="dialog" aria-hidden="true"> - <div class="modal-dialog modal-lg"> - <div class="modal-content"> + <div class="modal-dialog"> + <div class="modal-content openerp"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> - <h3 class="modal-title"><t t-raw="title"/><span class="text-muted"><t t-esc="subtitle"/></span></h3> - </div> - <div class="modal-body"> + <h4 class="modal-title"><t t-raw="title"/><span class="o_subtitle text-muted"><t t-esc="subtitle"/></span></h4> </div> + <div class="modal-body"/> + <div class="modal-footer"/> </div> </div> </div> </t> <t t-name="CrashManager.warning"> - <table cellspacing="0" cellpadding="0" border="0" class="oe_dialog_warning"> - <tr> - <td> - <p> - <t t-js="d"> - var message = d.message ? d.message : d.error.data.message; - d.html_error = context.engine.tools.html_escape(message) - .replace(/\n/g, '<br/>'); - </t> - <t t-raw="html_error"/> - </p> - </td> - </tr> - </table> + <div class="o_dialog_warning"> + <t t-js="d"> + var message = d.message ? d.message : d.error.data.message; + d.html_error = context.engine.tools.html_escape(message).replace(/\n/g, '<br/>'); + </t> + <t t-raw="html_error"/> + </div> </t> <t t-name="CrashManager.error"> - <div class="oe_error_detail"> + <div class="o_error_detail"> <pre><t t-esc="error.message"/></pre> - <hr/> <pre><t t-esc="error.data.debug"/></pre> </div> </t> @@ -330,7 +322,6 @@ <tr> <td colspan="2" align="right"> <button class='oe_button oe_form_button'>Change Password</button> - <span class="oe_fade oe_form_button"> or </span> <button type="button" class="oe_button oe_form_button_cancel oe_form_button oe_link" href="javascript:void(0)"><span>Cancel</span></button> </td> </tr> @@ -815,7 +806,7 @@ <span class="oe_form_pager_state"></span> </t> <form t-name="FormView.set_default"> - <t t-set="args" t-value="widget.dialog_options.args"/> + <t t-set="args" t-value="widget.args"/> <table style="width: 100%"> <tr> <td> @@ -1497,8 +1488,7 @@ </div> </t> <t t-name="WidgetButton"> - <span t-if="widget.pre_text"> <t t-esc="widget.pre_text"/> </span> - <button type="button" t-att-class="widget.is_stat_button ? 'oe_stat_button btn btn-default' : 'oe_button oe_form_button ' + (widget.node.attrs.class ? widget.node.attrs.class : '')" + <button type="button" t-attf-class="btn btn-sm #{widget.node.attrs.class or ''}" t-att-style="widget.node.attrs.style" t-att-tabindex="widget.node.attrs.tabindex" t-att-autofocus="widget.node.attrs.autofocus" @@ -1508,7 +1498,6 @@ <span t-if="widget.string and !widget.is_stat_button"><t t-esc="widget.string"/></span> <div t-if="widget.string and widget.is_stat_button"><t t-esc="widget.string"/></div> </button> - <span t-if="widget.post_text"> <t t-esc="widget.post_text"/> </span> </t> <t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip"> <t t-jquery="div.oe_tooltip_string" t-operation="replace"> @@ -1542,51 +1531,13 @@ </t> </t> -<t t-name="AbstractFormPopup.render"> - <div> - <div class="o-modal-header"> - <div class="o-popup-search"/> - <div class="o-search-options oe-search-options"/> - <div class="oe_popup_list_pager"/> - </div> - <div class="oe_popup_list"/> - <div class="oe_popup_form"/> - </div> -</t> -<t t-name="SelectCreatePopup.search.buttons"> - <t t-if="! widget.options.disable_multiple_selection"> - <button type="button" class="oe_button oe_selectcreatepopup-search-select oe_highlight" disabled="disabled">Select</button> - </t> - <t t-if="!widget.options.no_create"> - <button type="button" class="oe_button oe_selectcreatepopup-search-create">Create</button> - or </t><a class="oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a> -</t> -<t t-name="AbstractFormPopup.buttons"> - <t t-if="! readonly"> - <t t-if="! multi_select"> - <button type="button" class="oe_button oe_abstractformpopup-form-save oe_highlight">Save</button> - </t> - <t t-if="multi_select"> - <button type="button" class="oe_button oe_abstractformpopup-form-save oe_highlight">Save & Close</button> - <button type="button" class="oe_button oe_abstractformpopup-form-save-new oe_highlight">Save & New</button> - </t> - or - </t> - <a class="oe_abstractformpopup-form-close oe_bold oe_form_button_cancel" href="javascript:void(0)"> - <t t-if="! readonly"> - Discard - </t> - <t t-if="readonly"> - Close - </t> - </a> -</t> <t t-name="One2Many.formview" t-extend="FormView"> <t t-jquery=".oe_form_buttons" t-operation="inner"> <button type="button" class="oe_button oe_form_button_create">Add</button> </t> </t> + <t t-name="One2Many.listview" t-extend="ListView"> <t t-jquery="thead > tr:first"> this.removeAttr('t-if'); diff --git a/addons/web/static/test/menu.js b/addons/web/static/test/menu.js index 78c006fa8ba..8f183481bb5 100644 --- a/addons/web/static/test/menu.js +++ b/addons/web/static/test/menu.js @@ -249,10 +249,10 @@ Tour.register({ { title: "Select next action", onload: function () { - if ($(".oe_error_detail").size()) { + if ($(".o_error_detail").size()) { console.log("Tour 'test_menu' has detected an error."); } - if ($(".oe_dialog_warning").size()) { + if ($(".o_dialog_warning").size()) { console.log("Tour 'test_menu' has detected a warning."); } diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 2cc1f28641a..690b56b044c 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -75,6 +75,7 @@ <link rel="stylesheet" href='/website/static/src/less/import_bootstrap.less'/> <link rel="stylesheet" href="/web/static/src/less/enterprise_compatibility.less"/> <link rel="stylesheet" href="/web/static/src/less/utils.less"/> + <link rel="stylesheet" href="/web/static/src/less/modal.less"/> <script src="/web/static/lib/bootstrap/js/affix.js"></script> <script src="/web/static/lib/bootstrap/js/alert.js"></script> <script src="/web/static/lib/bootstrap/js/button.js"></script> diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js index 088d7cdbedf..d2a57bab06a 100644 --- a/addons/web_calendar/static/src/js/web_calendar.js +++ b/addons/web_calendar/static/src/js/web_calendar.js @@ -375,9 +375,9 @@ var CalendarView = View.extend({ get_quick_create_class: function () { return widgets.QuickCreate; }, - open_quick_create: function(data_template) { + open_quick_create: function(data_template) { // FIXME if (!isNullOrUndef(this.quick)) { - return this.quick.trigger('close'); + return this.quick.close(); } var QuickCreate = this.get_quick_create_class(); @@ -385,14 +385,16 @@ var CalendarView = View.extend({ this.quick = new QuickCreate(this, this.dataset, true, this.options, data_template); this.quick.on('added', this, this.quick_created) .on('slowadded', this, this.slow_created) - .on('close', this, function() { - this.quick.destroy(); + .on('closed', this, function() { delete this.quick; this.$calendar.fullCalendar('unselect'); }); - this.quick.replace(this.$el.find('.oe_calendar_qc_placeholder')); - if (!this.options.disable_quick_create) { + + if(!this.options.disable_quick_create) { + this.quick.open(); this.quick.focus(); + } else { + this.quick.start(); } }, @@ -874,38 +876,26 @@ var CalendarView = View.extend({ } } else { - var pop = new form_common.FormOpenPopup(this); - var id_cast = parseInt(id).toString() == id ? parseInt(id) : id; - pop.show_element(this.dataset.model, id_cast, this.dataset.get_context(), { - title: _.str.sprintf(_t("View: %s"),title), + var dialog = new form_common.FormViewDialog(this, { + res_model: this.dataset.model, + res_id: parseInt(id).toString() == id ? parseInt(id) : id, + context: this.dataset.get_context(), + title: title, view_id: +this.open_popup_action, - res_id: id_cast, - target: 'new', - readonly:true - }); - - var form_controller = pop.view_form; - form_controller.on("load_record", self, function(){ - var button_delete = _.str.sprintf("<button class='oe_button oe_bold delme'><span> %s </span></button>",_t("Delete")); - var button_edit = _.str.sprintf("<button class='oe_button oe_bold editme oe_highlight'><span> %s </span></button>",_t("Edit Event")); - - pop.$el.closest(".modal").find(".modal-footer").prepend(button_delete); - pop.$el.closest(".modal").find(".modal-footer").prepend(button_edit); - - $('.delme').click( - function() { - $('.oe_form_button_cancel').trigger('click'); - self.remove_event(id); - } - ); - $('.editme').click( - function() { - $('.oe_form_button_cancel').trigger('click'); + readonly: true, + buttons: [ + {text: _t("Edit"), classes: 'btn-primary', close: true, click: function() { self.dataset.index = self.dataset.get_id_index(id); self.do_switch_view('form', null, { mode: "edit" }); - } - ); - }); + }}, + + {text: _t("Delete"), close: true, click: function() { + self.remove_event(id); + }}, + + {text: _t("Close"), close: true} + ] + }).open(); } return false; }, diff --git a/addons/web_calendar/static/src/js/widgets.js b/addons/web_calendar/static/src/js/widgets.js index 24189868bb7..09165d4d9dd 100644 --- a/addons/web_calendar/static/src/js/widgets.js +++ b/addons/web_calendar/static/src/js/widgets.js @@ -19,9 +19,8 @@ var QWeb = core.qweb; * @class * @type {*} */ -var QuickCreate = Widget.extend({ +var QuickCreate = Dialog.extend({ init: function(parent, dataset, buttons, options, data_template) { - this._super(parent); this.dataset = dataset; this._buttons = buttons || false; this.options = options; @@ -29,6 +28,23 @@ var QuickCreate = Widget.extend({ // Can hold data pre-set from where you clicked on agenda this.data_template = data_template || {}; this.$input = $(); + + var self = this; + this._super(parent, { + title: this.get_title(), + size: 'small', + buttons: this._buttons ? [ + {text: _t("Create event"), classes: 'btn-primary', click: function (e) { + if (!self.quick_add()) { + self.focus(); + } + }}, + {text: _t("Edit event"), click: function (e) { + self.slow_add(); + }} + ] : [], + $content: QWeb.render('CalendarView.quick_create', {widged: this}) + }); }, get_title: function () { var parent = this.getParent(); @@ -47,38 +63,22 @@ var QuickCreate = Widget.extend({ this.slow_create(); return; } - self.on('added', self, function() { - self.trigger('close'); + this.on('added', this, function() { + self.close(); }); - this.$dialog = new Dialog(this, { - title: this.get_title(), - size: 'small', - buttons: this._buttons ? [ - {text: _t("Create event"), oe_link_class: 'oe_highlight', click: function (e) { - if (!self.quick_add()) { - self.focus(); - } - }}, - {text: _t("Edit event"), oe_link_class: 'oe_link', click: function (e) { - self.slow_add(); - }} - ] : [] - }, QWeb.render('CalendarView.quick_create', {widget: this})) - .on('closed', self, function() { - self.trigger('close'); - }) - .open(); - this.$input = this.$dialog.$('input').keyup(function enterHandler (e) { - if(e.keyCode == $.ui.keyCode.ENTER){ + this.$input = this.$('input').keyup(function enterHandler (e) { + if(e.keyCode == $.ui.keyCode.ENTER) { self.$input.off('keyup', enterHandler); if (!self.quick_add()){ self.$input.on('keyup', enterHandler); } } else if (e.keyCode == $.ui.keyCode.ESCAPE && self._buttons) { - self.trigger('close'); + self.close(); } }); + + return this._super(); }, focus: function() { this.$input.focus(); @@ -140,9 +140,10 @@ var QuickCreate = Widget.extend({ }); var pop_infos = self.get_form_popup_infos(); - var pop = new form_common.FormOpenPopup(this); var context = new data.CompoundContext(this.dataset.context, defaults); - pop.show_element(this.dataset.model, null, this.dataset.get_context(defaults), { + var pop = new form_common.FormViewDialog(this, { + res_model: this.dataset.model, + context: this.dataset.get_context(defaults), title: this.get_title(), disable_multiple_selection: true, view_id: pop_infos.view_id, @@ -162,12 +163,9 @@ var QuickCreate = Widget.extend({ throw new Error(r); } }); - }, - }); + } + }).open(); pop.on('closed', self, function() { - // ``self.trigger('close')`` would itself destroy all child element including - // the slow create popup, which would then re-trigger recursively the 'closed' signal. - // Thus, here, we use a deferred and its state to cut the endless recurrence. if (def.state() === "pending") { def.resolve(); } @@ -181,7 +179,8 @@ var QuickCreate = Widget.extend({ var parent = self.getParent(); parent.$calendar.fullCalendar('refetchEvents'); } - self.trigger('close'); + self.close(); + self.trigger("closed"); }); return def; }, diff --git a/addons/web_calendar/static/src/less/web_calendar.less b/addons/web_calendar/static/src/less/web_calendar.less new file mode 100644 index 00000000000..a5c0da53d35 --- /dev/null +++ b/addons/web_calendar/static/src/less/web_calendar.less @@ -0,0 +1,147 @@ + +.o_calendar_container { + @nb-calendar-colors: 24; + + .calendar_color_loop(@index) when (@index < @nb-calendar-colors+1) { + .o_calendar_color_@{index} { + color: #0D0D0D; + background-color: spin(rgb(255, 192, 192), 360/(@nb-calendar-colors+1) * @index); + border-color: spin(rgb(255, 192, 192), 360/(@nb-calendar-colors+1) * @index); + opacity: 0.7; + } + .calendar_color_loop(@index + 1); + } + .calendar_color_loop(1); + + .underline_color_loop(@index) when (@index < @nb-calendar-colors+1) { + .o_underline_color_@{index} { + border-bottom: 4px solid spin(rgba(255, 192, 192, 0.7), 360/(@nb-calendar-colors+1) * @index); + } + .underline_color_loop(@index + 1); + } + .underline_color_loop(1); + + .o_calendar_view { + padding: 8px; + + .o_calendar_widget { + background-color: @odoo-view-background-color; + * { + z-index: 0; // FIXME + } + .fc-week-number, .fc-widget-header { + background-color: lighten(@odoo-brand-secondary, 30%); + } + .o_attendee_head { + float: right; + margin-left: 1px; + width: 18px; + height: 18px; + } + } + } + + .o_calendar_sidebar_container { + padding: 8px; + padding-left: 0; + + .ui-datepicker { + width: 100%; + font-size: 8pt; + font-family: Roboto, "Nimbus Sans L"; + + .ui-widget-header { + background: none; + background-color: lighten(@odoo-brand-secondary, 30%); + + .ui-corner-all { + position: static; + cursor: pointer; + text-align: center; + &:hover { + color: @odoo-view-background-color; + background: none; + background-color: @odoo-brand-secondary; + border: none; + text-decoration: none; + } + .ui-icon { + display: none; + } + } + .ui-datepicker-prev { + float: left; + &::after { + font-family: FontAwesome; + content: ""; + } + } + .ui-datepicker-next { + float: right; + &::before { + font-family: FontAwesome; + content: ""; + } + } + } + table { + td { + padding: 0 2px 2px 0; + background-color: @odoo-view-background-color; + a { + border: none; + background: none; + background-color: lighten(@odoo-brand-secondary, 40%); + } + } + .ui-state-default { + color: @odoo-brand-primary; + &:hover { + background: none; + background-color: fade(@odoo-brand-primary, 50%); + border-color: @odoo-brand-primary; + color: @odoo-view-background-color; + }; + } + .ui-state-active { + background: none; + background-color: @odoo-brand-primary; + color: @odoo-view-background-color; + } + } + } + .o_calendar_filter { + padding: 8px; + background: @odoo-view-background-color; + } + .o_cal_avatar { + height: 24px; + width: 24px; + } + } +} + +.o_calendar_invitation { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 5px; + + &.accepted { + background-color: @brand-success; // FIXME brand-success in green badge ... + } + + &.needsAction { + background-color: @odoo-brand-secondary; + } +} + +.o-dashboard { + .o_calendar_container .o_calendar_sidebar_container { + display: none; + } + + .o_calendar_container .o_calendar_view { + width: 100%; + } +} diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js index 285991e29b2..8fdcf077b38 100644 --- a/addons/web_diagram/static/src/js/diagram.js +++ b/addons/web_diagram/static/src/js/diagram.js @@ -241,54 +241,45 @@ var DiagramView = View.extend({ edit_node: function(node_id){ var self = this; var title = _t('Activity'); - var pop = new form_common.FormOpenPopup(self); - - pop.show_element( - self.node, - node_id, - self.context || self.dataset.context, - { - title: _t("Open: ") + title - } - ); + var pop = new form_common.FormViewDialog(self, { + res_model: self.node, + res_id: node_id, + context: self.context || self.dataset.context, + title: _t("Open: ") + title + }).open(); pop.on('write_completed', self, function() { self.dataset.read_index(_.keys(self.fields_view.fields)).then(self.on_diagram_loaded); - }); + }); var form_fields = [self.parent_field]; var form_controller = pop.view_form; - form_controller.on("load_record", self, function(){ + form_controller.on("load_record", self, function(){ _.each(form_fields, function(fld) { if (!(fld in form_controller.fields)) { return; } var field = form_controller.fields[fld]; field.$input.prop('disabled', true); field.$drop_down.unbind(); }); - }); - - + }); }, // Creates a popup to add a node to the diagram add_node: function(){ var self = this; var title = _t('Activity'); - var pop = new form_common.SelectCreatePopup(self); - pop.select_element( - self.node, - { - title: _t("Create:") + title, - initial_view: 'form', - disable_multiple_selection: true - }, - self.dataset.domain, - self.context || self.dataset.context - ); - pop.on("elements_selected", self, function(element_ids) { - self.dataset.read_index(_.keys(self.fields_view.fields)).then(self.on_diagram_loaded); - }); + var pop = new form_common.SelectCreateDialog(self, { + res_model: self.node, + domain: self.dataset.domain, + context: self.context || self.dataset.context, + title: _t("Create:") + title, + initial_view: 'form', + disable_multiple_selection: true, + on_selected: function(element_ids) { + self.dataset.read_index(_.keys(self.fields_view.fields)).then(self.on_diagram_loaded); + } + }).open(); var form_controller = pop.view_form; var form_fields = [this.parent_field]; @@ -307,15 +298,12 @@ var DiagramView = View.extend({ edit_connector: function(connector_id){ var self = this; var title = _t('Transition'); - var pop = new form_common.FormOpenPopup(self); - pop.show_element( - self.connector, - parseInt(connector_id,10), //FIXME Isn't connector_id supposed to be an int ? - self.context || self.dataset.context, - { - title: _t("Open: ") + title - } - ); + var pop = new form_common.FormViewDialog(self, { + res_model: self.connector, + res_id: parseInt(connector_id, 10), //FIXME Isn't connector_id supposed to be an int ? + context: self.context || self.dataset.context, + title: _t("Open: ") + title + }).open(); pop.on('write_completed', self, function() { self.dataset.read_index(_.keys(self.fields_view.fields)).then(self.on_diagram_loaded); }); @@ -326,21 +314,18 @@ var DiagramView = View.extend({ add_connector: function(node_source_id, node_dest_id, dummy_cuteedge){ var self = this; var title = _t('Transition'); - var pop = new form_common.SelectCreatePopup(self); - - pop.select_element( - self.connector, - { - title: _t("Create:") + title, - initial_view: 'form', - disable_multiple_selection: true - }, - this.dataset.domain, - this.context || this.dataset.context - ); - pop.on("elements_selected", self, function(element_ids) { - self.dataset.read_index(_.keys(self.fields_view.fields)).then(self.on_diagram_loaded); - }); + var pop = new form_common.SelectCreateDialog(self, { + res_model: self.connector, + domain: this.dataset.domain, + context: this.context || this.dataset.context, + title: _t("Create:") + title, + initial_view: 'form', + disable_multiple_selection: true, + on_selected: function(element_ids) { + self.dataset.read_index(_.keys(self.fields_view.fields)).then(self.on_diagram_loaded); + } + }).open(); + // We want to destroy the dummy edge after a creation cancel. This destroys it even if we save the changes. // This is not a problem since the diagram is completely redrawn on saved changes. pop.$el.parents('.modal').on('hidden.bs.modal', function (e){ @@ -350,14 +335,12 @@ var DiagramView = View.extend({ }); var form_controller = pop.view_form; - - - form_controller.on("load_record", self, function(){ + form_controller.on("load_record", self, function(){ form_controller.fields[self.connectors.attrs.source].set_value(node_source_id); form_controller.fields[self.connectors.attrs.source].dirty = true; form_controller.fields[self.connectors.attrs.destination].set_value(node_dest_id); form_controller.fields[self.connectors.attrs.destination].dirty = true; - }); + }); }, /** diff --git a/addons/web_gantt/static/src/js/gantt.js b/addons/web_gantt/static/src/js/gantt.js index ed9a49fa8c1..556167f7229 100644 --- a/addons/web_gantt/static/src/js/gantt.js +++ b/addons/web_gantt/static/src/js/gantt.js @@ -237,28 +237,20 @@ var GanttView = View.extend({ this.dataset.write(itask.id, data); }, on_task_display: function(task) { - var self = this; - var pop = new form_common.FormOpenPopup(self); - pop.on('write_completed',self,self.reload); - pop.show_element( - self.dataset.model, - task.id, - null, - {} - ); + var pop = new form_common.FormViewDialog(this, { + res_model: this.dataset.model, + res_id: task.id, + }).open(); + pop.on('write_completed', this, this.reload); }, on_task_create: function() { var self = this; - var pop = new form_common.SelectCreatePopup(this); - pop.on("elements_selected", self, function() { - self.reload(); - }); - pop.select_element( - self.dataset.model, - { - initial_view: "form", + new form_common.FormViewDialog(this, { + res_model: self.dataset.model, + on_selected: function() { + self.reload(); } - ); + }).open(); }, }); diff --git a/addons/web_view_editor/static/src/js/view_editor.js b/addons/web_view_editor/static/src/js/view_editor.js index 16013e1b031..d45216ed19a 100644 --- a/addons/web_view_editor/static/src/js/view_editor.js +++ b/addons/web_view_editor/static/src/js/view_editor.js @@ -72,10 +72,10 @@ var ViewEditor = Widget.extend({ {text: _t("Create"), click: function() { self.on_create_view(); }}, {text: _t("Edit"), click: function() { self.xml_element_id = 0; self.get_arch(); }}, {text: _t("Remove"), click: function() { self.do_delete_view(); }}, - {text: _t("Close"), click: function() { self.view_edit_dialog.close(); window.location.reload(); }} + {text: _t("Close"), click: function() { window.location.reload(); }, close: true} ] }).open(); - this.view_edit_dialog.on("closing", this, function(){window.location.reload();}); + this.view_edit_dialog.on("closed", this, function(){window.location.reload();}); this.main_view_id = this.parent.fields_view.view_id; this.action_manager = new ActionManager(this); this.action_manager.appendTo(this.view_edit_dialog.$el); |
