[IMP] base: rework the ir.actions.server views
- inline configuration/display for 'update record' action type - don't use notebook when there's a single page that gets displayed - remove default field when updating a record Task-3450200 Part-of: odoo/odoo#138804
This commit is contained in:
@@ -122,7 +122,7 @@
|
||||
name="action_server_ids"
|
||||
widget="one2many"
|
||||
class="o_base_automation_actions_field"
|
||||
context="{'default_model_id': model_id, 'default_state': False, 'form_view_ref': 'base_automation.ir_actions_server_view_form_automation'}"
|
||||
context="{'default_model_id': model_id, 'form_view_ref': 'base_automation.ir_actions_server_view_form_automation'}"
|
||||
>
|
||||
<kanban>
|
||||
<control>
|
||||
|
||||
@@ -439,25 +439,6 @@ class IrActionsServer(models.Model):
|
||||
# - Command: x2many commands namespace
|
||||
# To return an action, assign: action = {...}\n\n\n\n"""
|
||||
|
||||
@api.model
|
||||
def _default_update_field_id(self):
|
||||
if self.model_id:
|
||||
model_id = self.model_id.id
|
||||
elif 'default_model_id' in self.env.context:
|
||||
model_id = self.env.context['default_model_id']
|
||||
else:
|
||||
return False
|
||||
|
||||
ir_model = self.env["ir.model"].browse(model_id)
|
||||
if ir_model:
|
||||
fields = self.env[ir_model.model]._fields
|
||||
if 'state' in fields:
|
||||
return ir_model.field_id.filtered(lambda ir_field: ir_field.name == 'state')
|
||||
elif 'stage_id' in fields:
|
||||
return ir_model.field_id.filtered(lambda ir_field: ir_field.name == 'stage_id')
|
||||
elif 'priority' in fields:
|
||||
return ir_model.field_id.filtered(lambda ir_field: ir_field.name == 'priority')
|
||||
|
||||
name = fields.Char(compute='_compute_name', store=True, readonly=False, required=True)
|
||||
type = fields.Char(default='ir.actions.server')
|
||||
usage = fields.Selection([
|
||||
@@ -508,7 +489,7 @@ class IrActionsServer(models.Model):
|
||||
groups_id = fields.Many2many('res.groups', 'ir_act_server_group_rel',
|
||||
'act_id', 'gid', string='Allowed Groups', help='Groups that can execute the server action. Leave empty to allow everybody.')
|
||||
|
||||
update_field_id = fields.Many2one('ir.model.fields', string='Field to Update', default=_default_update_field_id, ondelete='cascade')
|
||||
update_field_id = fields.Many2one('ir.model.fields', string='Field to Update', ondelete='cascade')
|
||||
update_related_model_id = fields.Many2one('ir.model', compute='_compute_update_related_model_id')
|
||||
|
||||
value = fields.Text(help="For Python expressions, this field may hold a Python expression "
|
||||
@@ -518,8 +499,8 @@ class IrActionsServer(models.Model):
|
||||
"For Static values, the value will be used directly without evaluation, e.g."
|
||||
"`42` or `My custom name` or the selected record.")
|
||||
evaluation_type = fields.Selection([
|
||||
('value', 'Custom Value'),
|
||||
('equation', 'Python expression')
|
||||
('value', 'Update'),
|
||||
('equation', 'Compute')
|
||||
], 'Value Type', default='value', change_default=True)
|
||||
resource_ref = fields.Reference(
|
||||
string='Record', selection='_selection_target_model', inverse='_set_resource_ref')
|
||||
|
||||
@@ -331,27 +331,52 @@
|
||||
</h1>
|
||||
<div class="d-flex flex-column">
|
||||
<label for="state"/>
|
||||
<field name="state" widget="selection_badge"/>
|
||||
<field name="state" widget="selection_badge" options="{'size': 'sm'}"/>
|
||||
</div>
|
||||
<group string="Technical Settings" groups="base.group_no_one">
|
||||
<group>
|
||||
<field name="model_id" options="{'no_create': True, 'no_open': True}" />
|
||||
<field name="groups_id" widget="many2many_tags" />
|
||||
</group>
|
||||
</group>
|
||||
<separator string="Action Details" groups="base.group_no_one" />
|
||||
<div class="d-flex flex-row flex-wrap gap-2" invisible="state != 'object_write'">
|
||||
<field name="evaluation_type" class="oe_inline"/>
|
||||
<field name="update_field_id"
|
||||
placeholder="Select a field..."
|
||||
options="{'no_create': True, 'no_open': True}" context="{'hide_model': True}"
|
||||
domain="[('store', '=', True), '|', ('model_id', '=', crud_model_id), ('model_id', '=', model_id)]"/>
|
||||
<field name="value_field_to_show" invisible="1"/>
|
||||
<field name="update_related_model_id" invisible="1"/>
|
||||
<span invisible="evaluation_type != 'value'">to</span>
|
||||
<field name="value" class="oe_inline" placeholder="Set a value..." invisible="update_field_id == False or value_field_to_show != 'value' or evaluation_type != 'value'" string="Custom Value"/>
|
||||
<field name="resource_ref" class="oe_inline" placeholder="Choose a value..." string="Custom Value" options="{'model_field': 'update_related_model_id', 'no_create': True, 'no_open': True}" invisible=" update_field_id == False or value_field_to_show != 'resource_ref' or evaluation_type == 'equation'"/>
|
||||
<field name="selection_value" class="oe_inline" placeholder="Choose a value..." options="{'no_create': True, 'no_open': True}" invisible=" update_field_id == False or value_field_to_show != 'selection_value' or evaluation_type == 'equation'"/>
|
||||
<span invisible="update_field_id != False or evaluation_type == 'equation'" class="text-muted">Set a value...</span>
|
||||
<span invisible="evaluation_type != 'equation'">
|
||||
to this Python expression:
|
||||
</span>
|
||||
<div class="w-100 d-flex flex-row gap-3" invisible="evaluation_type != 'equation'">
|
||||
<field name="value" class="w-50" widget="code" options="{'mode': 'python'}" string="Expression"/>
|
||||
<div class="w-50 opacity-75">
|
||||
<span colspan="2" class="text-muted"> Available variables: </span>
|
||||
<ul colspan="2" class="text-muted">
|
||||
<li><code>env</code>: environment on which the action is triggered</li>
|
||||
<li><code>model</code>: model of the record on which the action is triggered; is a void recordset</li>
|
||||
<li><code>record</code>: record on which the action is triggered</li>
|
||||
<li><code>records</code>: recordset of all records on which the action is triggered in multi mode</li>
|
||||
<li><code>time</code>, <code>datetime</code>, <code>dateutil</code>, <code>timezone</code>: useful Python libraries</li>
|
||||
<li><code>float_compare()</code>: utility function to compare floats based on a specific precision</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<group name="action_wrapper">
|
||||
<group name="action_content">
|
||||
<field name="model_name" invisible="1"/>
|
||||
<field name="available_model_ids" invisible="1"/>
|
||||
<field name="model_id" options="{'no_create': True, 'no_open': True}" groups="base.group_no_one"
|
||||
domain="[('id', 'in', available_model_ids)]"/>
|
||||
<field name="model_id" options="{'no_create': True, 'no_open': True}" groups="!base.group_no_one" invisible="context.get('default_model_id')"
|
||||
domain="[('id', 'in', available_model_ids)]"/>
|
||||
<field name="groups_id" widget="many2many_tags" groups="base.group_no_one" />
|
||||
<field name="update_field_id" invisible="state != 'object_write'"
|
||||
options="{'no_create': True, 'no_open': True}" context="{'hide_model': True}"/>
|
||||
domain="['|', ('model_id', '=', crud_model_id), ('model_id', '=', model_id)]"/>
|
||||
<field name="evaluation_type" invisible="state != 'object_write'" widget="radio" options="{'horizontal': True}"/>
|
||||
<field name="value_field_to_show" invisible="1"/>
|
||||
<field name="update_related_model_id" invisible="1"/>
|
||||
<field name="value" invisible="state != 'object_write' or value_field_to_show != 'value' or evaluation_type != 'value'" string="Custom Value"/>
|
||||
<field name="value" widget="code" options="{'mode': 'python'}" invisible="state != 'object_write' or evaluation_type != 'equation'" string="Expression"/>
|
||||
<field name="resource_ref" string="Custom Value" options="{'model_field': 'update_related_model_id', 'no_create': True, 'no_open': True}" invisible="state != 'object_write' or value_field_to_show != 'resource_ref' or evaluation_type == 'equation'"/>
|
||||
<field name="selection_value" options="{'no_create': True, 'no_open': True}" invisible="state != 'object_write' or value_field_to_show != 'selection_value' or evaluation_type == 'equation'"/>
|
||||
|
||||
<field name="type" invisible="1"/>
|
||||
<field name="crud_model_id"
|
||||
@@ -367,61 +392,39 @@
|
||||
invisible="state != 'object_create'"
|
||||
context="{'default_model_id': model_id, 'default_relation': crud_model_name}"/>
|
||||
</group>
|
||||
<group invisible="evaluation_type != 'equation' or state != 'object_write'">
|
||||
<span colspan="2" class="text-muted"> Available variables: </span>
|
||||
<ul colspan="2" class="text-muted">
|
||||
<li><code>env</code>: environment on which the action is triggered</li>
|
||||
<li><code>model</code>: model of the record on which the action is triggered; is a void recordset</li>
|
||||
<li><code>record</code>: record on which the action is triggered</li>
|
||||
<li><code>records</code>: recordset of all records on which the action is triggered in multi mode</li>
|
||||
<li><code>time</code>, <code>datetime</code>, <code>dateutil</code>, <code>timezone</code>: useful Python libraries</li>
|
||||
<li><code>float_compare()</code>: utility function to compare floats based on a specific precision</li>
|
||||
</ul>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Python Code" name='code'
|
||||
invisible="state != 'code'">
|
||||
<field name="code" widget="code" options="{'mode': 'python'}" placeholder="Enter Python code here. Help about Python expression is available in the help tab of this document."/>
|
||||
</page>
|
||||
|
||||
<page string="Actions" name="actions"
|
||||
invisible="state != 'multi'">
|
||||
<field name="child_ids" domain="[('model_id', '=', model_id)]"/>
|
||||
<p class="oe_grey">
|
||||
If several child actions return an action, only the last one will be executed.
|
||||
This may happen when having server actions executing code that returns an action, or server actions returning a client action.
|
||||
</p>
|
||||
</page>
|
||||
|
||||
<page string="Help" name="help_info"
|
||||
invisible="state != 'code'">
|
||||
<div style="margin-top: 4px;">
|
||||
<h3>Help with Python expressions</h3>
|
||||
<p>Various fields may use Python code or Python expressions. The following variables can be used:</p>
|
||||
<ul>
|
||||
<li><code>env</code>: environment on which the action is triggered</li>
|
||||
<li><code>model</code>: model of the record on which the action is triggered; is a void recordset</li>
|
||||
<li><code>record</code>: record on which the action is triggered; may be be void</li>
|
||||
<li><code>records</code>: recordset of all records on which the action is triggered in multi mode; may be void</li>
|
||||
<li><code>time</code>, <code>datetime</code>, <code>dateutil</code>, <code>timezone</code>: useful Python libraries</li>
|
||||
<li><code>float_compare()</code>: utility function to compare floats based on a specific precision</li>
|
||||
<li><code>log(message, level='info')</code>: logging function to record debug information in <code>ir.logging</code> table</li>
|
||||
<li><code>_logger.info(message)</code>: logger to emit messages in server logs</li>
|
||||
<li><code>UserError</code>: exception class for raising user-facing warning messages</li>
|
||||
<li><code>Command</code>: x2many commands namespace</li>
|
||||
<li>To return an action, assign: <code>action = {...}</code></li>
|
||||
</ul>
|
||||
<div invisible="state != 'code'">
|
||||
<p>Example of Python code</p>
|
||||
<pre style='white-space: pre-wrap'>
|
||||
partner_name = record.name + '_code'
|
||||
<field name="child_ids" domain="[('model_id', '=', model_id)]" invisible="state != 'multi'"/>
|
||||
<p class="oe_grey" invisible="state != 'multi'">
|
||||
If several child actions return an action, only the last one will be executed.
|
||||
This may happen when having server actions executing code that returns an action, or server actions returning a client action.
|
||||
</p>
|
||||
<label for="code" invisible="state != 'code'"/>
|
||||
<field name="code" invisible="state != 'code'" widget="code" options="{'mode': 'python'}" placeholder="Enter Python code here. Help about Python expression is available in the help tab of this document."/>
|
||||
<div class="mb-3 opacity-75" invisible="state != 'code'">
|
||||
<button class="btn btn-sm btn-secondary" data-bs-toggle="collapse" data-bs-target="#code-help-collapse" aria-expanded="false" aria-controls="code-help-collapse">Available variables and libraries</button>
|
||||
<div class="collapse ps-3" id="code-help-collapse">
|
||||
<p>The following variables can be used:</p>
|
||||
<ul>
|
||||
<li><code>env</code>: environment on which the action is triggered</li>
|
||||
<li><code>model</code>: model of the record on which the action is triggered; is a void recordset</li>
|
||||
<li><code>record</code>: record on which the action is triggered; may be be void</li>
|
||||
<li><code>records</code>: recordset of all records on which the action is triggered in multi mode; may be void</li>
|
||||
<li><code>time</code>, <code>datetime</code>, <code>dateutil</code>, <code>timezone</code>: useful Python libraries</li>
|
||||
<li><code>float_compare()</code>: utility function to compare floats based on a specific precision</li>
|
||||
<li><code>log(message, level='info')</code>: logging function to record debug information in <code>ir.logging</code> table</li>
|
||||
<li><code>_logger.info(message)</code>: logger to emit messages in server logs</li>
|
||||
<li><code>UserError</code>: exception class for raising user-facing warning messages</li>
|
||||
<li><code>Command</code>: x2many commands namespace</li>
|
||||
<li>To return an action, assign: <code>action = {...}</code></li>
|
||||
</ul>
|
||||
<div >
|
||||
<p>Example of Python code:</p>
|
||||
<pre style='white-space: pre-wrap'>partner_name = record.name + '_code'
|
||||
env['res.partner'].create({'name': partner_name})
|
||||
</pre>
|
||||
</div>
|
||||
</pre>
|
||||
</div>
|
||||
</page>
|
||||
</notebook>
|
||||
</div>
|
||||
</div>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
Reference in New Issue
Block a user