3
0
Fork 0

Merge pull request #1205 from hbrunn/8.0-web_action_conditionable-form

[ADD][web_action_conditionable] support forms
8.0
Pedro M. Baeza 2019-04-22 13:11:16 +02:00 committed by GitHub
commit a836458f78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 14 deletions

View File

@ -2,7 +2,7 @@
{ {
"name": 'web_action_conditionable', "name": 'web_action_conditionable',
"version": "8.0.1.1.0", "version": "8.0.1.1.1",
"category": "Web", "category": "Web",
"website": "https://github.com/OCA/web", "website": "https://github.com/OCA/web",
"development_status": "Beta", "development_status": "Beta",
@ -11,6 +11,9 @@
'web', 'web',
], ],
"license": "AGPL-3", "license": "AGPL-3",
"demo": [
"demo/ir_ui_view.xml",
],
'data': [ 'data': [
'views/view.xml' 'views/view.xml'
], ],

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="view_res_groups_form" model="ir.ui.view">
<field name="model">res.groups</field>
<field name="inherit_id" ref="base.view_groups_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='model_access']/tree" position="attributes">
<attribute name="create">name == 'Access Rights'</attribute>
<attribute name="delete">name != 'Access Rights'</attribute>
</xpath>
<xpath expr="." position="attributes">
<attribute name="edit">name == 'Access Rights'</attribute>
<attribute name="delete">name != 'Access Rights'</attribute>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -1,5 +1,7 @@
This module was written to extend the functionality of actions in tree views. This module was written to allow developers to fine tune available actions in
Odoo by default support: form and tree views.
Odoo by default supports:
:: ::
@ -11,10 +13,19 @@ with this module you can do:
<tree delete="state=='draft'"> <tree delete="state=='draft'">
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:
:: ::
<tree delete="'base.group_user' in _group_refs"> <form delete="'base.group_user' in _group_refs">
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.

View File

@ -1,6 +1,7 @@
/*global openerp, _, $ */ /* global openerp, py, jQuery, _, _t, $ */
openerp.web_action_conditionable = function (instance) { openerp.web_action_conditionable = function (instance) {
'use strict';
instance.web.View.include({ instance.web.View.include({
/** /**
* @override * @override
@ -13,15 +14,120 @@ openerp.web_action_conditionable = function (instance) {
} catch(error) { } catch(error) {
var expr = attrs[action]; var expr = attrs[action];
var expression = py.parse(py.tokenize(expr)); var expression = py.parse(py.tokenize(expr));
var cxt = this.dataset.get_context().__eval_context; var cxt = new instance.web.CompoundContext(
cxt = cxt ? cxt.__contexts[1] : {}; this.get_fields_values && !_.isEmpty(this.fields)
cxt['_group_refs'] = instance.session.group_refs; // 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(); return py.evaluate(expression, cxt).toJSON();
} }
} else { } else {
return true; 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,
},
]));
}
},
});
};

View File

@ -2,8 +2,7 @@
from mock import patch from mock import patch
from openerp.tests.common import TransactionCase from openerp.tests.common import TransactionCase
from openerp.addons.web_action_conditionable.controllers.main \ from ..controllers.main import MainController
import MainController
class TestActionConditionable(TransactionCase): class TestActionConditionable(TransactionCase):