# Saturday, September 9, 2017¶

## A new way for disabling actions per row¶

It is now possible to disable an action by adding its name to the set returned by disabled_fields.

This approach can be more intuitive to write and less costly to run. For example the three actions on lino_xl.lib.stars.Starrable are now implemented using this new possibility.

Here is a fictive example

1. Using get_action_permission method of the action:

class DoOne(dd.Action):
...
def get_action_permission(self, ar, obj, st):
for x in obj.foos.all():
if x.bar:
return False
return super(DoOne, self).get_action_permission(ar, obj, st)

class Foo(dd.Model):
do_one = DoOne()

2. Using the disabled_fields method of the model which defines the action:

class DoOne(dd.Action):
...
# no get_action_permission()

class Foo(dd.Model):

do_one = DoOne()

def disabled_fields(self, ar):
s = super(Foo, self).disabled_fields(ar)
for x in self.foos.all():
if x.bar:
return s


No more method disabled_actions : actions share the same namespace as fields, so there was no need to separate them. A side effect of this is that in readonly tables it is no longer possible to disable individual actions. Which AFAICS is correct.

In linoweb.js, I replaced “disabled_actions” by “disabled_fields”. For example:

var da = record.data.disabled_actions;


becomes:

var da = record.data.disabled_fields;


One challenge were actions with an allowed_states. These are now handled more efficiently. Lino analyses the situation once at startup and creates per actor a dict _state_to_disabled_actions which is then being used for disabling these actions based on the row’s state.