details:   https://code.tryton.org/tryton/commit/3bccf6f3ed9c
branch:    default
user:      Cédric Krier <[email protected]>
date:      Mon Aug 31 13:45:03 2026 +0200
description:
        Add editable state on field
diffstat:

 sao/src/model.js                                  |   4 ++++
 tryton/tryton/gui/window/view_form/model/field.py |   2 ++
 trytond/CHANGELOG                                 |   1 +
 trytond/doc/ref/fields.rst                        |   7 ++++++-
 trytond/trytond/model/fields/field.py             |  11 +++++++----
 5 files changed, 20 insertions(+), 5 deletions(-)

diffs (82 lines):

diff -r e6d7121c620c -r 3bccf6f3ed9c sao/src/model.js
--- a/sao/src/model.js  Mon Aug 31 13:43:41 2026 +0200
+++ b/sao/src/model.js  Mon Aug 31 13:45:03 2026 +0200
@@ -1701,6 +1701,10 @@
                     this.get_state_attrs(record)[state] =
                         this.description[state];
                 }
+                if ((state == 'readonly') &&
+                    !(Object.hasOwn(state_changes, 'editable') ? 
state_changes.editable : true)) {
+                    this.get_state_attrs(record).readonly = true;
+                }
             }
             if (record.group.readonly ||
                 this.get_state_attrs(record).domain_readonly ||
diff -r e6d7121c620c -r 3bccf6f3ed9c 
tryton/tryton/gui/window/view_form/model/field.py
--- a/tryton/tryton/gui/window/view_form/model/field.py Mon Aug 31 13:43:41 
2026 +0200
+++ b/tryton/tryton/gui/window/view_form/model/field.py Mon Aug 31 13:45:03 
2026 +0200
@@ -194,6 +194,8 @@
                 self.get_state_attrs(record)[key] = state_changes[key]
             elif key in self.attrs:
                 self.get_state_attrs(record)[key] = self.attrs[key]
+            if key == 'readonly' and not state_changes.get('editable', True):
+                self.get_state_attrs(record)['readonly'] = True
         if (record.group.readonly
                 or self.get_state_attrs(record).get('domain_readonly')
                 or record.parent_name == self.name):
diff -r e6d7121c620c -r 3bccf6f3ed9c trytond/CHANGELOG
--- a/trytond/CHANGELOG Mon Aug 31 13:43:41 2026 +0200
+++ b/trytond/CHANGELOG Mon Aug 31 13:45:03 2026 +0200
@@ -1,3 +1,4 @@
+* Add editable state on field
 * Enforce readonly on field when checking access
 * Add the icon parameter to register_authentication_service
 * Add routes for sao custom in base router
diff -r e6d7121c620c -r 3bccf6f3ed9c trytond/doc/ref/fields.rst
--- a/trytond/doc/ref/fields.rst        Mon Aug 31 13:43:41 2026 +0200
+++ b/trytond/doc/ref/fields.rst        Mon Aug 31 13:45:03 2026 +0200
@@ -61,10 +61,15 @@
    A dictionary that defines dynamic states of the field and overrides the
    static one.
 
-   Possible keys are ``required``, ``readonly`` and ``invisible``.
+   Possible keys are ``required``, ``readonly``, ``editable`` and
+   ``invisible``.
    The values are :class:`~trytond.pyson.PYSON` statements that is evaluated
    with the values of the record.
 
+   .. note::
+
+      ``editable`` is not enforced but only used for the UI.
+
 .. attribute:: Field.on_change
 
    A set of field names.
diff -r e6d7121c620c -r 3bccf6f3ed9c trytond/trytond/model/fields/field.py
--- a/trytond/trytond/model/fields/field.py     Mon Aug 31 13:43:41 2026 +0200
+++ b/trytond/trytond/model/fields/field.py     Mon Aug 31 13:45:03 2026 +0200
@@ -50,10 +50,12 @@
 
 def states_validate(value):
     assert isinstance(value, dict), 'states must be a dict'
-    assert set(value).issubset({'required', 'readonly', 'invisible'}), (
-        'extra keys "%(keys)s" in states' % {
-            'keys': set(value) - {'required', 'readonly', 'invisible'},
-            })
+    assert set(value).issubset(
+        {'required', 'readonly', 'editable', 'invisible'}), (
+            'extra keys "%(keys)s" in states' % {
+                'keys': set(value) - {
+                    'required', 'readonly', 'editable', 'invisible'},
+                })
     for state in value:
         assert isinstance(value[state], (bool, PYSON)), \
             'values of states must be PYSON'
@@ -413,6 +415,7 @@
     def edition_depends(self):
         depends = get_eval_fields(self.domain)
         depends |= get_eval_fields(self.states.get('readonly'))
+        depends |= get_eval_fields(self.states.get('editable'))
         depends |= get_eval_fields(self.states.get('required'))
         return self.depends | depends
 

Reply via email to