forked from Techsystech/web
Merge pull request #1205 from hbrunn/8.0-web_action_conditionable-form
[ADD][web_action_conditionable] support forms8.0
commit
a836458f78
|
@ -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'
|
||||||
],
|
],
|
||||||
|
|
|
@ -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>
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue