Browse Source

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

[ADD][web_action_conditionable] support forms
pull/581/merge
Pedro M. Baeza 6 years ago
committed by GitHub
parent
commit
a836458f78
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      web_action_conditionable/__openerp__.py
  2. 19
      web_action_conditionable/demo/ir_ui_view.xml
  3. 21
      web_action_conditionable/readme/DESCRIPTION.rst
  4. 116
      web_action_conditionable/static/src/js/views.js
  5. 3
      web_action_conditionable/tests/test_action_conditionable.py

5
web_action_conditionable/__openerp__.py

@ -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'
], ],

19
web_action_conditionable/demo/ir_ui_view.xml

@ -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>

21
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:
<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">
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.
It works in any tree view, so you can use it in One2many.
You do however have access to ``_context`` and ``_group_refs`` in for the
actions of standalone tree views.

116
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) { 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;
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(); 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,
},
]));
} }
},
}); });
}
};

3
web_action_conditionable/tests/test_action_conditionable.py

@ -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 \
import MainController
from ..controllers.main import MainController
class TestActionConditionable(TransactionCase): class TestActionConditionable(TransactionCase):

Loading…
Cancel
Save