diff --git a/web_action_conditionable/__openerp__.py b/web_action_conditionable/__openerp__.py index 8ab32d345..8f479094c 100644 --- a/web_action_conditionable/__openerp__.py +++ b/web_action_conditionable/__openerp__.py @@ -2,7 +2,7 @@ { "name": 'web_action_conditionable', - "version": "8.0.1.1.0", + "version": "8.0.1.1.1", "category": "Web", "website": "https://github.com/OCA/web", "development_status": "Beta", @@ -11,6 +11,9 @@ 'web', ], "license": "AGPL-3", + "demo": [ + "demo/ir_ui_view.xml", + ], 'data': [ 'views/view.xml' ], diff --git a/web_action_conditionable/demo/ir_ui_view.xml b/web_action_conditionable/demo/ir_ui_view.xml new file mode 100644 index 000000000..ec2c73c23 --- /dev/null +++ b/web_action_conditionable/demo/ir_ui_view.xml @@ -0,0 +1,19 @@ + + + + + res.groups + + + + name == 'Access Rights' + name != 'Access Rights' + + + name == 'Access Rights' + name != 'Access Rights' + + + + + diff --git a/web_action_conditionable/readme/DESCRIPTION.rst b/web_action_conditionable/readme/DESCRIPTION.rst index 8c4852a4f..18067147b 100644 --- a/web_action_conditionable/readme/DESCRIPTION.rst +++ b/web_action_conditionable/readme/DESCRIPTION.rst @@ -1,5 +1,7 @@ -This module was written to extend the functionality of actions in tree views. -Odoo by default support: +This module was written to allow developers to fine tune available actions in +form and tree views. + +Odoo by default supports: :: @@ -11,10 +13,19 @@ with this module you can do: -you can use `_group_refs` to make a condition based on the user's groups: +Further, you can use `_group_refs` to make a condition based on the user's +groups: :: - +
-It works in any tree view, so you can use it in One2many. +You also have access to ``_context`` for the current context. This way, you can +for example craft actions that pass a context key which decides if some of the +action buttons are shown. + +Note that for tree views, this will not work on a per record base, and the +values you have access to are the values of the form the x2many field is in. + +You do however have access to ``_context`` and ``_group_refs`` in for the +actions of standalone tree views. diff --git a/web_action_conditionable/static/src/js/views.js b/web_action_conditionable/static/src/js/views.js index 650e1d3f5..dd9a90ffa 100644 --- a/web_action_conditionable/static/src/js/views.js +++ b/web_action_conditionable/static/src/js/views.js @@ -1,6 +1,7 @@ -/*global openerp, _, $ */ +/* global openerp, py, jQuery, _, _t, $ */ openerp.web_action_conditionable = function (instance) { + 'use strict'; instance.web.View.include({ /** * @override @@ -13,15 +14,120 @@ openerp.web_action_conditionable = function (instance) { } catch(error) { var expr = attrs[action]; var expression = py.parse(py.tokenize(expr)); - var cxt = this.dataset.get_context().__eval_context; - cxt = cxt ? cxt.__contexts[1] : {}; - cxt['_group_refs'] = instance.session.group_refs; + var cxt = new instance.web.CompoundContext( + this.get_fields_values && !_.isEmpty(this.fields) + // We're on a form that has loaded its fields + ? this.get_fields_values() + // This always exists + : this.dataset.get_context().get_eval_context() || + {} + ).eval(); + + if (_.isEmpty(cxt) && + this instanceof instance.web.FormView + ) { + // Short circuit if there's nothing to eval for form + // views, as this is also called before any fields are + // loaded + return true; + } + + this._is_action_enabled_eval_context(cxt); return py.evaluate(expression, cxt).toJSON(); } } else { return true; } - } + }, + _is_action_enabled_eval_context: function(cxt) { + cxt._group_refs = instance.session.group_refs; + cxt._context = this.dataset.get_context().eval(); + }, + }); -} + instance.web.form.Many2ManyListView.include({ + is_action_enabled: function(action) { + if (action in this.fields_view.arch.attrs) { + return (new instance.web.View()).is_action_enabled.apply( + this, arguments + ); + } + return true; + }, + }); + instance.web.FormView.include({ + init: function() { + this._super.apply(this, arguments); + this.on( + 'load_record', this, this._load_record_web_action_conditionable + ); + }, + _load_record_web_action_conditionable: function() { + var self = this; + // Set correct classes + this.$el.toggleClass( + 'oe_cannot_create', !this.is_action_enabled('create') + ); + this.$el.toggleClass( + 'oe_cannot_edit', !this.is_action_enabled('edit') + ); + this.$el.toggleClass( + 'oe_cannot_delete', !this.is_action_enabled('delete') + ); + var $footer = this.$buttons.find('footer'); + this.$buttons = jQuery( + instance.web.qweb.render('FormView.buttons', {'widget': this}) + ); + this.$buttons.append($footer); + // Update buttons + if (this.options.$buttons) { + var $existing = this.options.$buttons.find('.oe_form_buttons'); + if ($existing.length) { + $existing.remove(); + this.options.$buttons.append(this.$buttons); + } + } else { + this.$('.oe_form_buttons').replaceWith(this.$buttons); + } + this.$buttons.on( + 'click', '.oe_form_button_create', + this.guard_active(this.on_button_create) + ); + this.$buttons.on( + 'click', '.oe_form_button_edit', + this.guard_active(this.on_button_edit) + ); + this.$buttons.on( + 'click', '.oe_form_button_save', + this.guard_active(this.on_button_save) + ); + this.$buttons.on( + 'click', '.oe_form_button_cancel', + this.guard_active(this.on_button_cancel) + ); + this.check_actual_mode(); + // Update sidebar menu + if (this.sidebar) { + this.sidebar.items.other = _.filter( + this.sidebar.items.other, function(item) { + return ( + item.callback !== self.on_button_delete && + item.callback !== self.on_button_duplicate + ); + } + ); + this.sidebar.add_items('other', _.compact([ + self.is_action_enabled('delete') && { + label: _t('Delete'), + callback: self.on_button_delete, + }, + self.is_action_enabled('create') && { + label: _t('Duplicate'), + callback: self.on_button_duplicate, + }, + ])); + } + }, + }); +}; diff --git a/web_action_conditionable/tests/test_action_conditionable.py b/web_action_conditionable/tests/test_action_conditionable.py index eec2b6ca4..8c02552a4 100644 --- a/web_action_conditionable/tests/test_action_conditionable.py +++ b/web_action_conditionable/tests/test_action_conditionable.py @@ -2,8 +2,7 @@ from mock import patch from openerp.tests.common import TransactionCase -from openerp.addons.web_action_conditionable.controllers.main \ - import MainController +from ..controllers.main import MainController class TestActionConditionable(TransactionCase):