changeset 45787f01dc3e in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=45787f01dc3e
description:
        Add link button

        issue9051
        review280841002
diffstat:

 CHANGELOG                       |   1 +
 doc/topics/views/index.rst      |  18 ++++++++++++
 trytond/ir/ui/board.rnc         |  12 ++++++++
 trytond/ir/ui/board.rng         |  61 +++++++++++++++++++++++++++++++++++++++++
 trytond/ir/ui/form.rnc          |  11 +++++++
 trytond/ir/ui/form.rng          |  60 ++++++++++++++++++++++++++++++++++++++++
 trytond/model/modelview.py      |  16 ++++++++++
 trytond/tests/modelview.py      |  12 ++++++++
 trytond/tests/modelview.xml     |  17 +++++++++++
 trytond/tests/test_modelview.py |  35 +++++++++++++++++++++++
 10 files changed, 243 insertions(+), 0 deletions(-)

diffs (480 lines):

diff -r 38b32161f535 -r 45787f01dc3e CHANGELOG
--- a/CHANGELOG Sun Apr 12 23:53:02 2020 +0200
+++ b/CHANGELOG Mon Apr 13 12:21:55 2020 +0200
@@ -1,3 +1,4 @@
+* Add link button on form
 * Support explicit delete and remove for saving and on_change xxx2Many
 * Add export_data_domain to ModelStorage
 * Add route to export CSV data
diff -r 38b32161f535 -r 45787f01dc3e doc/topics/views/index.rst
--- a/doc/topics/views/index.rst        Sun Apr 12 23:53:02 2020 +0200
+++ b/doc/topics/views/index.rst        Mon Apr 13 12:21:55 2020 +0200
@@ -384,6 +384,24 @@
     value of the ``string``, ``confirm`` and ``help`` attributes can be can be
     defined.
 
+.. _form-link:
+
+link
+^^^^
+
+Display an `ir.action.act_window` as a button with a counter or one counter per
+tab. When clicked it opens the window.
+
+    * ``name``: The XML id of `ir.action.act_window`.
+
+    * ``colspan``: see in common-attributes-colspan_.
+
+    * ``states``: see in common-attributes-states_.
+
+    * ``icon``: The name of the icon to display.
+
+    * ``empty``: If set to `hide` the button is not displayed if the counter is
+      zero. The default is ``show``.
 
 notebook
 ^^^^^^^^
diff -r 38b32161f535 -r 45787f01dc3e trytond/ir/ui/board.rnc
--- a/trytond/ir/ui/board.rnc   Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/ir/ui/board.rnc   Mon Apr 13 12:21:55 2020 +0200
@@ -7,6 +7,7 @@
      | separator
      | label
      | newline
+     | link
      | notebook
      | group
      | hpaned
@@ -58,6 +59,13 @@
 attlist.label &= attribute help { text }?
 newline = element newline { attlist.newline, empty }
 attlist.newline &= attribute id { text }
+link = element link { attlist.link, empty }
+attlist.link &= attribute name { text }
+attlist.link &= attribute id { text }?
+attlist.link &= [ a:defaultValue = "1" ] attribute colspan { text }?
+attlist.link &= attribute states { text }?
+attlist.link &= attribute icon { text }?
+attlist.link &= [ a:defaultValue = "show" ] attribute empty { "show" | "hide" 
}?
 notebook = element notebook { attlist.notebook, page* }
 attlist.notebook &= [ a:defaultValue = "4" ] attribute colspan { text }?
 page =
@@ -67,6 +75,7 @@
      | separator
      | label
      | newline
+     | link
      | notebook
      | group
      | hpaned
@@ -85,6 +94,7 @@
      | separator
      | label
      | newline
+     | link
      | notebook
      | group
      | hpaned
@@ -120,6 +130,7 @@
      | separator
      | label
      | newline
+     | link
      | notebook
      | group
      | hpaned
@@ -137,6 +148,7 @@
     | separator
     | label
     | newline
+    | link
     | notebook
     | group
     | hpaned
diff -r 38b32161f535 -r 45787f01dc3e trytond/ir/ui/board.rng
--- a/trytond/ir/ui/board.rng   Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/ir/ui/board.rng   Mon Apr 13 12:21:55 2020 +0200
@@ -11,6 +11,7 @@
           <ref name="separator"/>
           <ref name="label"/>
           <ref name="newline"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -336,6 +337,62 @@
       <text/>
     </attribute>
   </define>
+  <define name="link">
+    <element>
+      <name ns="">link</name>
+      <ref name="attlist.link"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <attribute>
+      <name ns="">name</name>
+      <text/>
+    </attribute>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute>
+        <name ns="">id</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute a:defaultValue="1">
+        <name ns="">colspan</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute>
+        <name ns="">states</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute>
+        <name ns="">icon</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute a:defaultValue="show">
+        <name ns="">empty</name>
+        <choice>
+          <value>show</value>
+          <value>hide</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
   <define name="notebook">
     <element>
       <name ns="">notebook</name>
@@ -363,6 +420,7 @@
           <ref name="separator"/>
           <ref name="label"/>
           <ref name="newline"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -418,6 +476,7 @@
           <ref name="separator"/>
           <ref name="label"/>
           <ref name="newline"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -575,6 +634,7 @@
           <ref name="separator"/>
           <ref name="label"/>
           <ref name="newline"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -612,6 +672,7 @@
           <ref name="separator"/>
           <ref name="label"/>
           <ref name="newline"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
diff -r 38b32161f535 -r 45787f01dc3e trytond/ir/ui/form.rnc
--- a/trytond/ir/ui/form.rnc    Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/ir/ui/form.rnc    Mon Apr 13 12:21:55 2020 +0200
@@ -9,6 +9,7 @@
      | separator
      | newline
      | button
+     | link
      | notebook
      | group
      | hpaned
@@ -152,6 +153,13 @@
 attlist.button &= [ a:defaultValue = "0" ] attribute rule { "0" | "1" }?
 attlist.button &= attribute change { text }?
 attlist.button &= attribute type { "class" | "instance" }?
+link = element link { attlist.link, empty }
+attlist.link &= attribute name { text }
+attlist.link &= attribute id { text }?
+attlist.link &= [ a:defaultValue = "1" ] attribute colspan { text }?
+attlist.link &= attribute states { text }?
+attlist.link &= attribute icon { text }?
+attlist.link &= [ a:defaultValue = "show" ] attribute empty { "show" | "hide" 
}?
 notebook = element notebook { attlist.notebook, page* }
 attlist.notebook &= [ a:defaultValue = "4" ] attribute colspan { text }?
 attlist.notebook &= [ a:defaultValue = "1" ] attribute yexpand { "0" | "1" }?
@@ -189,6 +197,7 @@
      | separator
      | newline
      | button
+     | link
      | notebook
      | group
      | hpaned
@@ -228,6 +237,7 @@
      | separator
      | newline
      | button
+     | link
      | notebook
      | group
      | hpaned
@@ -246,6 +256,7 @@
     | separator
     | newline
     | button
+    | link
     | notebook
     | group
     | hpaned
diff -r 38b32161f535 -r 45787f01dc3e trytond/ir/ui/form.rng
--- a/trytond/ir/ui/form.rng    Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/ir/ui/form.rng    Mon Apr 13 12:21:55 2020 +0200
@@ -13,6 +13,7 @@
           <ref name="separator"/>
           <ref name="newline"/>
           <ref name="button"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -780,6 +781,62 @@
       </attribute>
     </optional>
   </define>
+  <define name="link">
+    <element>
+      <name ns="">link</name>
+      <ref name="attlist.link"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <attribute>
+      <name ns="">name</name>
+      <text/>
+    </attribute>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute>
+        <name ns="">id</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute a:defaultValue="1">
+        <name ns="">colspan</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute>
+        <name ns="">states</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute>
+        <name ns="">icon</name>
+        <text/>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.link" combine="interleave">
+    <optional>
+      <attribute a:defaultValue="show">
+        <name ns="">empty</name>
+        <choice>
+          <value>show</value>
+          <value>hide</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
   <define name="notebook">
     <element>
       <name ns="">notebook</name>
@@ -927,6 +984,7 @@
           <ref name="separator"/>
           <ref name="newline"/>
           <ref name="button"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -1121,6 +1179,7 @@
           <ref name="separator"/>
           <ref name="newline"/>
           <ref name="button"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
@@ -1159,6 +1218,7 @@
           <ref name="separator"/>
           <ref name="newline"/>
           <ref name="button"/>
+          <ref name="link"/>
           <ref name="notebook"/>
           <ref name="group"/>
           <ref name="hpaned"/>
diff -r 38b32161f535 -r 45787f01dc3e trytond/model/modelview.py
--- a/trytond/model/modelview.py        Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/model/modelview.py        Mon Apr 13 12:21:55 2020 +0200
@@ -526,6 +526,7 @@
         ModelAccess = pool.get('ir.model.access')
         Button = pool.get('ir.model.button')
         User = pool.get('res.user')
+        ActionWindow = pool.get('ir.action.act_window')
 
         if fields_width is None:
             fields_width = {}
@@ -637,6 +638,21 @@
             for depend in states.get('depends', []):
                 fields_attrs.setdefault(depend, {})
 
+        if element.tag == 'link':
+            link_name = element.attrib['name']
+            action_id = ModelData.get_id(*link_name.split('.'))
+            action = ActionWindow(action_id)
+            if (not action.res_model
+                    or not ModelAccess.check(
+                        action.res_model, 'read', raise_exception=False)):
+                element.tag = 'label'
+                colspan = element.attrib.get('colspan')
+                element.attrib.clear()
+                if colspan is not None:
+                    element.attrib['colspan'] = colspan
+            else:
+                element.attrib['id'] = str(action.action.id)
+
         # translate view
         if Transaction().language != 'en':
             for attr in ('string', 'sum', 'confirm', 'help'):
diff -r 38b32161f535 -r 45787f01dc3e trytond/tests/modelview.py
--- a/trytond/tests/modelview.py        Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/tests/modelview.py        Mon Apr 13 12:21:55 2020 +0200
@@ -99,6 +99,16 @@
         return {'url': 'http://www.tryton.org/'}
 
 
+class ModelViewLink(ModelView):
+    "ModelView Link"
+    __name__ = 'test.modelview.link'
+
+
+class ModelViewLinkTarget(ModelSQL):
+    "ModelView Link Target"
+    __name__ = 'test.modelview.link.target'
+
+
 class ModelViewRPC(ModelView):
     'ModelView RPC'
     __name__ = 'test.modelview.rpc'
@@ -202,6 +212,8 @@
         ModelViewButton,
         ModelViewButtonDepends,
         ModelViewButtonAction,
+        ModelViewLink,
+        ModelViewLinkTarget,
         ModelViewRPC,
         ModelViewEmptyPage,
         ModelViewCircularDepends,
diff -r 38b32161f535 -r 45787f01dc3e trytond/tests/modelview.xml
--- a/trytond/tests/modelview.xml       Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/tests/modelview.xml       Mon Apr 13 12:21:55 2020 +0200
@@ -35,6 +35,23 @@
         <field name="url">http://www.example.com/</field>
     </record>
 
+    <record model="ir.ui.view" id="test_modelview_link">
+        <field name="model">test.modelview.link</field>
+        <field name="type">form</field>
+        <field name="arch" type="xml">
+            <![CDATA[
+            <form>
+                <link name="tests.test_modelview_link_action"/>
+            </form>
+            ]]>
+        </field>
+    </record>
+
+    <record model="ir.action.act_window" id="test_modelview_link_action">
+        <field name="name">Link</field>
+        <field name="res_model">test.modelview.link.target</field>
+    </record>
+
     <record model="ir.ui.view" id="test_modelview_view_attributes">
         <field name="model">test.modelview.view_attributes</field>
         <field name="type">form</field>
diff -r 38b32161f535 -r 45787f01dc3e trytond/tests/test_modelview.py
--- a/trytond/tests/test_modelview.py   Sun Apr 12 23:53:02 2020 +0200
+++ b/trytond/tests/test_modelview.py   Mon Apr 13 12:21:55 2020 +0200
@@ -385,6 +385,41 @@
         self.assertEqual(action['url'], 'http://www.tryton.org/')
 
     @with_transaction()
+    def test_link(self):
+        "Test link in view"
+        pool = Pool()
+        TestModel = pool.get('test.modelview.link')
+
+        arch = TestModel.fields_view_get()['arch']
+        parser = etree.XMLParser()
+        tree = etree.fromstring(arch, parser=parser)
+        link, = tree.xpath('//link')
+
+        self.assertTrue(link.attrib['id'])
+        self.assertIsInstance(int(link.attrib['id']), int)
+
+    @with_transaction()
+    def test_link_without_read_access(self):
+        "Test link in view without read access"
+        pool = Pool()
+        TestModel = pool.get('test.modelview.link')
+        Model = pool.get('ir.model')
+        ModelAccess = pool.get('ir.model.access')
+
+        model, = Model.search([('model', '=', 'test.modelview.link.target')])
+        access = ModelAccess(model=model, group=None, perm_read=False)
+        access.save()
+
+        arch = TestModel.fields_view_get()['arch']
+        parser = etree.XMLParser()
+        tree = etree.fromstring(arch, parser=parser)
+        links = tree.xpath('//link')
+        labels = tree.xpath('//label')
+
+        self.assertFalse(links)
+        self.assertTrue(labels)
+
+    @with_transaction()
     def test_rpc_setup(self):
         "Testing the computation of the RPC methods"
         pool = Pool()

Reply via email to