diff --git a/sign_oca/README.rst b/sign_oca/README.rst
index d0486362..73ca58b6 100644
--- a/sign_oca/README.rst
+++ b/sign_oca/README.rst
@@ -17,13 +17,13 @@ Sign Oca
     :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
     :alt: License: AGPL-3
 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github
-    :target: https://github.com/OCA/sign/tree/16.0/sign_oca
+    :target: https://github.com/OCA/sign/tree/17.0/sign_oca
     :alt: OCA/sign
 .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
-    :target: https://translation.odoo-community.org/projects/sign-16-0/sign-16-0-sign_oca
+    :target: https://translation.odoo-community.org/projects/sign-17-0/sign-17-0-sign_oca
     :alt: Translate me on Weblate
 .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
-    :target: https://runboat.odoo-community.org/builds?repo=OCA/sign&target_branch=16.0
+    :target: https://runboat.odoo-community.org/builds?repo=OCA/sign&target_branch=17.0
     :alt: Try me on Runboat
 
 |badge1| |badge2| |badge3| |badge4| |badge5|
@@ -128,7 +128,7 @@ Bug Tracker
 Bugs are tracked on `GitHub Issues <https://github.com/OCA/sign/issues>`_.
 In case of trouble, please check there if your issue has already been reported.
 If you spotted it first, help us to smash it by providing a detailed and welcomed
-`feedback <https://github.com/OCA/sign/issues/new?body=module:%20sign_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
+`feedback <https://github.com/OCA/sign/issues/new?body=module:%20sign_oca%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
 
 Do not contact contributors directly about support or help with technical issues.
 
@@ -169,6 +169,6 @@ Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
 
 |maintainer-etobella| 
 
-This module is part of the `OCA/sign <https://github.com/OCA/sign/tree/16.0/sign_oca>`_ project on GitHub.
+This module is part of the `OCA/sign <https://github.com/OCA/sign/tree/17.0/sign_oca>`_ project on GitHub.
 
 You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/sign_oca/__manifest__.py b/sign_oca/__manifest__.py
index 1b4a58b5..abd930c5 100644
--- a/sign_oca/__manifest__.py
+++ b/sign_oca/__manifest__.py
@@ -43,10 +43,7 @@
             "sign_oca/static/src/elements/signature.esm.js",
             "sign_oca/static/src/elements/check.esm.js",
             "sign_oca/static/src/components/sign_oca_pdf/sign_oca_pdf.esm.js",
-            "sign_oca/static/src/components/sign_oca_pdf/sign_oca_pdf_action.esm.js",
-            "sign_oca/static/src/components/"
-            "sign_oca_pdf_common/sign_oca_pdf_common_action.esm.js",
-            "sign_oca/static/src/js/*.js",
+            "sign_oca/static/src/components/" "sign_oca/static/src/js/*.js",
             "sign_oca/static/src/xml/*.xml",
         ],
         "web.assets_frontend": [
diff --git a/sign_oca/controllers/main.py b/sign_oca/controllers/main.py
index 45033a7c..4d61d537 100644
--- a/sign_oca/controllers/main.py
+++ b/sign_oca/controllers/main.py
@@ -51,6 +51,11 @@ def get_sign_oca_access(self, signer_id, access_token, **kwargs):
                 "partner": signer_sudo.partner_id,
                 "signer": signer_sudo,
                 "access_token": access_token,
+                "sign_oca_backend_info": {
+                    "access_token": access_token,
+                    "signer_id": signer_sudo.id,
+                    "lang": signer_sudo.partner_id.lang,
+                },
             },
         )
 
diff --git a/sign_oca/i18n/it.po b/sign_oca/i18n/it.po
index 3c90c700..fec08304 100644
--- a/sign_oca/i18n/it.po
+++ b/sign_oca/i18n/it.po
@@ -1391,6 +1391,3 @@ msgstr "Verrà cancellata la richiesta e tutti gli accessi. Si è sicuri?"
 #: model_terms:ir.ui.view,arch_db:sign_oca.portal_sign_document_signed
 msgid "has already been signed"
 msgstr "è già stato firmato"
-
-#~ msgid "sign.oca.request.log"
-#~ msgstr "sign.oca.request.log"
diff --git a/sign_oca/models/sign_oca_request.py b/sign_oca/models/sign_oca_request.py
index adaa0fa9..811fd148 100644
--- a/sign_oca/models/sign_oca_request.py
+++ b/sign_oca/models/sign_oca_request.py
@@ -51,8 +51,6 @@ class SignOcaRequest(models.Model):
         inverse_name="request_id",
         auto_join=True,
         copy=True,
-        readonly=True,
-        states={"draft": [("readonly", False)]},
         string="Signers",
     )
     signer_id = fields.Many2one(
@@ -385,10 +383,7 @@ def _compute_is_allow_signature(self):
     def _compute_access_url(self):
         result = super()._compute_access_url()
         for record in self:
-            record.access_url = "/sign_oca/document/%s/%s" % (
-                record.id,
-                record.access_token,
-            )
+            record.access_url = f"/sign_oca/document/{record.id}/{record.access_token}"
         return result
 
     @api.onchange("role_id")
@@ -613,7 +608,9 @@ def _get_new_hash(self, secure_seq_number):
 
     def _compute_hash(self, previous_hash):
         """Computes the hash of the browse_record given as self, based on the hash
-        of the previous record in the company's securisation sequence given as parameter"""
+        of the previous record in the company's securisation sequence given as
+        parameter
+        """
         self.ensure_one()
         hash_string = sha256((previous_hash + self._string_to_hash()).encode("utf-8"))
         return hash_string.hexdigest()
diff --git a/sign_oca/models/sign_oca_role.py b/sign_oca/models/sign_oca_role.py
index 0006142d..319a7f31 100644
--- a/sign_oca/models/sign_oca_role.py
+++ b/sign_oca/models/sign_oca_role.py
@@ -20,7 +20,8 @@ class SignOcaRole(models.Model):
         default="empty",
         help="This field is used to define how the partner"
         " will be calculated in the different roles of "
-        "a request. This field will be used when the 'Sign from Template' action is triggered.",
+        "a request. This field will be used when the 'Sign from Template' "
+        "action is triggered.",
     )
     default_partner_id = fields.Many2one(
         comodel_name="res.partner", string="Default partner"
diff --git a/sign_oca/models/sign_oca_template.py b/sign_oca/models/sign_oca_template.py
index 18fc6a59..23c96592 100644
--- a/sign_oca/models/sign_oca_template.py
+++ b/sign_oca/models/sign_oca_template.py
@@ -20,7 +20,9 @@ class SignOcaTemplate(models.Model):
         string="Model",
         domain=[("transient", "=", False), ("model", "not like", "sign.oca")],
     )
-    model = fields.Char(compute="_compute_model", compute_sudo=True, store=True)
+    model = fields.Char(
+        compute="_compute_model", string="Model name", compute_sudo=True, store=True
+    )
     active = fields.Boolean(default=True)
     request_ids = fields.One2many("sign.oca.request", inverse_name="template_id")
 
@@ -112,7 +114,7 @@ def _prepare_sign_oca_request_vals_from_record(self, record):
         return {
             "name": self.name,
             "template_id": self.id,
-            "record_ref": "%s,%s" % (record._name, record.id),
+            "record_ref": f"{record._name},{record.id}",
             "signatory_data": self._get_signatory_data(),
             "data": self.data,
             "signer_ids": [
diff --git a/sign_oca/security/security.xml b/sign_oca/security/security.xml
index 424902d8..d59777fa 100644
--- a/sign_oca/security/security.xml
+++ b/sign_oca/security/security.xml
@@ -37,6 +37,19 @@
         <field name="perm_write" eval="0" />
         <field name="perm_unlink" eval="0" />
     </record>
+    <!-- Company Record Rules -->
+    <record id="sign_oca_request_rule_company" model="ir.rule">
+        <field name="name">Sign Request Company</field>
+        <field name="model_id" ref="model_sign_oca_request" />
+        <field name="domain_force">[('company_id', 'in', company_ids)]</field>
+    </record>
+    <record id="sign_oca_request_signer_rule_company" model="ir.rule">
+        <field name="name">Sign Request Signer Company</field>
+        <field name="model_id" ref="model_sign_oca_request_signer" />
+        <field
+            name="domain_force"
+        >[('request_id.company_id', 'in', company_ids)]</field>
+    </record>
     <!-- User Record Rules -->
     <record id="sign_oca_request_rule_user_read" model="ir.rule">
         <field name="name">Sign Request user: read</field>
diff --git a/sign_oca/static/description/index.html b/sign_oca/static/description/index.html
index c7ac703d..05956e14 100644
--- a/sign_oca/static/description/index.html
+++ b/sign_oca/static/description/index.html
@@ -8,11 +8,10 @@
 
 /*
 :Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
+:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
 :Copyright: This stylesheet has been placed in the public domain.
 
 Default cascading style sheet for the HTML output of Docutils.
-Despite the name, some widely supported CSS2 features are used.
 
 See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
 customize this style sheet.
@@ -275,7 +274,7 @@
   margin-left: 2em ;
   margin-right: 2em }
 
-pre.code .ln { color: gray; } /* line numbers */
+pre.code .ln { color: grey; } /* line numbers */
 pre.code, code { background-color: #eeeeee }
 pre.code .comment, code .comment { color: #5C6576 }
 pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +300,7 @@
 span.pre {
   white-space: pre }
 
-span.problematic, pre.problematic {
+span.problematic {
   color: red }
 
 span.section-subtitle {
@@ -369,7 +368,7 @@ <h1 class="title">Sign Oca</h1>
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !! source digest: sha256:4cd44f4785da01198064822b367bcbe928fe915080976d5b1f5f2d8671812e51
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sign/tree/16.0/sign_oca"><img alt="OCA/sign" src="https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sign-16-0/sign-16-0-sign_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sign&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
+<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sign/tree/17.0/sign_oca"><img alt="OCA/sign" src="https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sign-17-0/sign-17-0-sign_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sign&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
 <p>This module allows to create documents for signature inside Odoo using
 OWL.</p>
 <p><strong>Table of contents</strong></p>
@@ -493,7 +492,7 @@ <h1><a class="toc-backref" href="#toc-entry-10">Bug Tracker</a></h1>
 <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/sign/issues">GitHub Issues</a>.
 In case of trouble, please check there if your issue has already been reported.
 If you spotted it first, help us to smash it by providing a detailed and welcomed
-<a class="reference external" href="https://github.com/OCA/sign/issues/new?body=module:%20sign_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
+<a class="reference external" href="https://github.com/OCA/sign/issues/new?body=module:%20sign_oca%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
 <p>Do not contact contributors directly about support or help with technical issues.</p>
 </div>
 <div class="section" id="credits">
@@ -517,15 +516,13 @@ <h2><a class="toc-backref" href="#toc-entry-13">Contributors</a></h2>
 <div class="section" id="maintainers">
 <h2><a class="toc-backref" href="#toc-entry-14">Maintainers</a></h2>
 <p>This module is maintained by the OCA.</p>
-<a class="reference external image-reference" href="https://odoo-community.org">
-<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
-</a>
+<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
 <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
 mission is to support the collaborative development of Odoo features and
 promote its widespread use.</p>
 <p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
 <p><a class="reference external image-reference" href="https://github.com/etobella"><img alt="etobella" src="https://github.com/etobella.png?size=40px" /></a></p>
-<p>This module is part of the <a class="reference external" href="https://github.com/OCA/sign/tree/16.0/sign_oca">OCA/sign</a> project on GitHub.</p>
+<p>This module is part of the <a class="reference external" href="https://github.com/OCA/sign/tree/17.0/sign_oca">OCA/sign</a> project on GitHub.</p>
 <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
 </div>
 </div>
diff --git a/sign_oca/static/src/components/sign_oca_configure/sign_oca_configure.esm.js b/sign_oca/static/src/components/sign_oca_configure/sign_oca_configure.esm.js
index ace400de..dfb5c103 100644
--- a/sign_oca/static/src/components/sign_oca_configure/sign_oca_configure.esm.js
+++ b/sign_oca/static/src/components/sign_oca_configure/sign_oca_configure.esm.js
@@ -1,9 +1,8 @@
 /** @odoo-module QWeb **/
 
-import {Component} from "@odoo/owl";
 import {ControlPanel} from "@web/search/control_panel/control_panel";
 import {Dialog} from "@web/core/dialog/dialog";
-import {FormRenderer} from "@web/views/form/form_renderer";
+import {isMobileOS} from "@web/core/browser/feature_detection";
 import SignOcaPdfCommon from "../sign_oca_pdf_common/sign_oca_pdf_common.esm.js";
 import {_t} from "@web/core/l10n/translation";
 import {registry} from "@web/core/registry";
@@ -11,16 +10,18 @@ import {renderToString} from "@web/core/utils/render";
 
 export class SignOcaConfigureControlPanel extends ControlPanel {}
 SignOcaConfigureControlPanel.template = "sign_oca.SignOcaConfigureControlPanel";
-export class SignOcaConfigure extends SignOcaPdfCommon {
+export default class SignOcaConfigure extends SignOcaPdfCommon {
     setup() {
+        this.res_id =
+            this.props.action.params.res_id || this.props.action.context.active_id;
         super.setup(...arguments);
         this.field_template = "sign_oca.sign_iframe_field_configure";
         this.contextMenu = undefined;
-        this.isMobile = this.env.device.isMobile || this.env.device.isMobileDevice;
+        this.isMobile = isMobileOS;
     }
     postIframeFields() {
         super.postIframeFields(...arguments);
-        _.each(
+        $.each(
             this.iframe.el.contentDocument.getElementsByClassName("page"),
             (page) => {
                 page.addEventListener("mousedown", (e) => {
@@ -56,26 +57,22 @@ export class SignOcaConfigure extends SignOcaPdfCommon {
                 if (this.contextMenu && !this.creatingItem) {
                     if (this.contextMenu[0].contains(ev.target)) {
                         this.creatingItem = true;
-                        this.env.services
-                            .rpc({
-                                model: this.props.model,
-                                method: "add_item",
-                                args: [
-                                    [this.props.res_id],
-                                    {
-                                        field_id: parseInt(ev.target.dataset.field, 10),
-                                        page: parseInt(ev.target.dataset.page, 10),
-                                        position_x: parseFloat(
-                                            ev.target.parentElement.style.left
-                                        ),
-                                        position_y: parseFloat(
-                                            ev.target.parentElement.style.top
-                                        ),
-                                        width: 20,
-                                        height: 1.5,
-                                    },
-                                ],
-                            })
+                        this.orm
+                            .call(this.model, "add_item", [
+                                [this.res_id],
+                                {
+                                    field_id: parseInt(ev.target.dataset.field, 10),
+                                    page: parseInt(ev.target.dataset.page, 10),
+                                    position_x: parseFloat(
+                                        ev.target.parentElement.style.left
+                                    ),
+                                    position_y: parseFloat(
+                                        ev.target.parentElement.style.top
+                                    ),
+                                    width: 20,
+                                    height: 1.5,
+                                },
+                            ])
                             .then((data) => {
                                 this.info.items[data.id] = data;
                                 this.postIframeField(data);
@@ -139,21 +136,17 @@ export class SignOcaConfigure extends SignOcaPdfCommon {
                                 var placeholder = dialog.$el
                                     .find("input[name='placeholder']")
                                     .val();
-                                this.env.services
-                                    .rpc({
-                                        model: this.props.model,
-                                        method: "set_item_data",
-                                        args: [
-                                            [this.props.res_id],
-                                            item.id,
-                                            {
-                                                field_id,
-                                                role_id,
-                                                required,
-                                                placeholder,
-                                            },
-                                        ],
-                                    })
+                                this.orm
+                                    .call(this.model, "set_item_data", [
+                                        [this.res_id],
+                                        item.id,
+                                        {
+                                            field_id,
+                                            role_id,
+                                            required,
+                                            placeholder,
+                                        },
+                                    ])
                                     .then(() => {
                                         item.field_id = field_id;
                                         item.name = _.filter(
@@ -173,12 +166,11 @@ export class SignOcaConfigure extends SignOcaPdfCommon {
                             classes: "btn-danger",
                             close: true,
                             click: () => {
-                                this.env.services
-                                    .rpc({
-                                        model: this.props.model,
-                                        method: "delete_item",
-                                        args: [[this.props.res_id], item.id],
-                                    })
+                                this.orm
+                                    .call(this.model, "delete_item", [
+                                        [this.res_id],
+                                        item.id,
+                                    ])
                                     .then(() => {
                                         delete this.info.items[item.id];
                                         target.remove();
@@ -239,24 +231,21 @@ export class SignOcaConfigure extends SignOcaPdfCommon {
                     target.css("top", top + "%");
                     item.position_x = left;
                     item.position_y = top;
-                    this.env.services.rpc({
-                        model: this.props.model,
-                        method: "set_item_data",
-                        args: [
-                            [this.props.res_id],
-                            item.id,
-                            {
-                                position_x: left,
-                                position_y: top,
-                            },
-                        ],
-                    });
+
+                    this.orm.call(this.model, "set_item_data", [
+                        [this.res_id],
+                        item.id,
+                        {
+                            position_x: left,
+                            position_y: top,
+                        },
+                    ]);
                     this.movingItem = undefined;
                 },
                 {once: true}
             );
         });
-        _.each(resizeItems, (resizeItem) => {
+        $.each(resizeItems, (resizeItem) => {
             resizeItem.addEventListener(startFunction, (mousedownEvent) => {
                 mousedownEvent.preventDefault();
                 var parentPage = mousedownEvent.target.parentElement.parentElement;
@@ -304,18 +293,14 @@ export class SignOcaConfigure extends SignOcaPdfCommon {
                         target.css("height", height + "%");
                         item.width = width;
                         item.height = height;
-                        this.env.services.rpc({
-                            model: this.props.model,
-                            method: "set_item_data",
-                            args: [
-                                [this.props.res_id],
-                                item.id,
-                                {
-                                    width: width,
-                                    height: height,
-                                },
-                            ],
-                        });
+                        this.orm.call(this.model, "set_item_data", [
+                            [this.res_id],
+                            item.id,
+                            {
+                                width: width,
+                                height: height,
+                            },
+                        ]);
                     },
                     {once: true}
                 );
@@ -368,34 +353,10 @@ export class SignOcaConfigure extends SignOcaPdfCommon {
         target.css("top", top + "%");
     }
 }
-
-export class SignOcaConfigureAction extends Component {
-    init(parent, action) {
-        this._super.apply(this, arguments);
-        this.model =
-            (action.params.res_model !== undefined && action.params.res_model) ||
-            action.context.params.res_model;
-        this.res_id =
-            (action.params.res_id !== undefined && action.params.res_id) ||
-            action.context.params.id;
-    }
-    async start() {
-        await this._super(...arguments);
-        this.component = new FormRenderer(this, SignOcaConfigure, {
-            model: this.model,
-            res_id: this.res_id,
-        });
-        this.$el.addClass("o_sign_oca_action");
-        return this.component.mount(this.$(".o_content")[0]);
-    }
-    getState() {
-        var result = this._super(...arguments);
-        result = _.extend({}, result, {
-            res_model: this.model,
-            res_id: this.res_id,
-        });
-        return result;
-    }
-}
 SignOcaConfigure.template = "sign_oca.SignOcaConfigure";
-registry.category("actions").add("sign_oca_configure", SignOcaConfigureAction);
+SignOcaConfigure.props = [];
+SignOcaConfigure.props = {
+    action: Object,
+    "*": {optional: true},
+};
+registry.category("actions").add("sign_oca_configure", SignOcaConfigure);
diff --git a/sign_oca/static/src/components/sign_oca_pdf/sign_oca_pdf.esm.js b/sign_oca/static/src/components/sign_oca_pdf/sign_oca_pdf.esm.js
index d15a14a4..fed42860 100644
--- a/sign_oca/static/src/components/sign_oca_pdf/sign_oca_pdf.esm.js
+++ b/sign_oca/static/src/components/sign_oca_pdf/sign_oca_pdf.esm.js
@@ -2,12 +2,14 @@
 
 import SignOcaPdfCommon from "../sign_oca_pdf_common/sign_oca_pdf_common.esm.js";
 import {registry} from "@web/core/registry";
-const SignRegistry = registry.category("sign_oca");
 import {renderToString} from "@web/core/utils/render";
+const SignRegistry = registry.category("sign_oca");
+import {useService} from "@web/core/utils/hooks";
 
 export default class SignOcaPdf extends SignOcaPdfCommon {
     setup() {
         super.setup(...arguments);
+        this.orm = useService("orm");
         this.to_sign = false;
     }
     async willStart() {
@@ -63,15 +65,15 @@ export default class SignOcaPdf extends SignOcaPdfCommon {
     }
     async signOca() {
         const position = await this.getLocation();
-        await this.env.services.rpc({
-            model: this.props.model,
-            method: "action_sign",
-            args: [[this.props.res_id], this.info.items],
-            kwargs: {
+        await this.orm.call(
+            this.model,
+            "action_sign",
+            [[this.res_id], this.info.items],
+            {
                 latitude: position && position.coords && position.coords.latitude,
                 longitude: position && position.coords && position.coords.longitude,
-            },
-        });
+            }
+        );
         this.props.trigger("history_back");
     }
     _trigger_up(ev) {
@@ -127,3 +129,7 @@ export default class SignOcaPdf extends SignOcaPdfCommon {
         this.checkToSign();
     }
 }
+SignOcaPdf.props = {
+    to_sign: {type: Boolean, optional: true},
+};
+registry.category("actions").add("sign_oca", SignOcaPdf);
diff --git a/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js b/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js
index 1adf6bc1..42b1ed74 100644
--- a/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js
+++ b/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js
@@ -1,14 +1,16 @@
 /** @odoo-module QWeb **/
+import {_t} from "@web/core/l10n/translation";
 import {Component, onMounted, onWillStart, onWillUnmount, useRef} from "@odoo/owl";
 import {Dialog} from "@web/core/dialog/dialog";
-import {_t} from "@web/core/l10n/translation";
 import {renderToString} from "@web/core/utils/render";
+import {useService} from "@web/core/utils/hooks";
 
 export default class SignOcaPdfCommon extends Component {
     setup() {
         super.setup(...arguments);
+        this.model = "sign.oca.template";
+        this.orm = useService("orm");
         this.field_template = "sign_oca.sign_iframe_field";
-        console.log(this.props);
         this.pdf_url = this.getPdfUrl();
         this.viewer_url = "/web/static/lib/pdfjs/web/viewer.html?file=" + this.pdf_url;
         this.iframe = useRef("sign_oca_iframe");
@@ -30,14 +32,10 @@ export default class SignOcaPdfCommon extends Component {
         });
     }
     getPdfUrl() {
-        return "/web/content/" + this.props.model + "/" + this.props.res_id + "/data";
+        return "/web/content/" + this.model + "/" + this.res_id + "/data";
     }
-    async willStart() {
-        this.info = await this.env.services.rpc({
-            model: this.props.model,
-            method: "get_info",
-            args: [[this.props.res_id]],
-        });
+    willStart() {
+        this.info = this.orm.call(this.model, "get_info", [[this.res_id]]);
     }
     waitIframeLoaded() {
         var error = this.iframe.el.contentDocument.getElementById("errorWrapper");
@@ -92,7 +90,7 @@ export default class SignOcaPdfCommon extends Component {
             .getElementsByTagName("head")[0]
             .append(iframeCss);
         this.iframe.el.contentDocument.getElementsByTagName("head")[0].append(iframeJs);
-        _.each(this.info.items, (item) => {
+        $.each(this.info.items, (item) => {
             this.postIframeField(item);
         });
         $(this.iframe.el.contentDocument.getElementsByClassName("page")[0]).append(
@@ -123,3 +121,4 @@ export default class SignOcaPdfCommon extends Component {
     }
 }
 SignOcaPdfCommon.template = "sign_oca.SignOcaPdfCommon";
+SignOcaPdfCommon.props = [];
diff --git a/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common_action.esm.js b/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common_action.esm.js
deleted file mode 100644
index 91166329..00000000
--- a/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common_action.esm.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/** @odoo-module **/
-
-import {Component} from "@odoo/owl";
-import {FormRenderer} from "@web/views/form/form_renderer";
-import SignOcaPdfCommon from "./sign_oca_pdf_common.esm.js";
-import {registry} from "@web/core/registry";
-
-export class SignOcaPdfCommonAction extends Component {
-    init(parent, action) {
-        this._super.apply(this, arguments);
-        this.model =
-            (action.params.res_model !== undefined && action.params.res_model) ||
-            action.context.params.res_model;
-        this.res_id =
-            (action.params.res_id !== undefined && action.params.res_id) ||
-            action.context.params.id;
-    }
-    async start() {
-        await this._super(...arguments);
-        this.component = new FormRenderer(this, SignOcaPdfCommon, {
-            model: this.model,
-            res_id: this.res_id,
-        });
-        this.$el.addClass("o_sign_oca_action");
-        return this.component.mount(this.$(".o_content")[0]);
-    }
-    getState() {
-        var result = this._super(...arguments);
-        result = _.extend({}, result, {
-            res_model: this.model,
-            res_id: this.res_id,
-        });
-        return result;
-    }
-}
-registry.category("actions").add("sign_oca_preview", SignOcaPdfCommonAction);
diff --git a/sign_oca/static/src/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm.js b/sign_oca/static/src/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm.js
index a663cd3e..bf19cc66 100644
--- a/sign_oca/static/src/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm.js
+++ b/sign_oca/static/src/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm.js
@@ -1,31 +1,27 @@
 /** @odoo-module **/
 
-const {App, mount, useRef} = owl;
+const {App, whenReady, useRef} = owl;
+import {_t} from "@web/core/l10n/translation";
+import {makeEnv, startServices} from "@web/env";
 import SignOcaPdf from "../sign_oca_pdf/sign_oca_pdf.esm.js";
-import {makeEnv} from "@web/env";
-import {renderToString} from "@web/core/utils/render";
-import {session} from "@web/session";
 import {templates} from "@web/core/assets";
+import {useService} from "@web/core/utils/hooks";
 
 export class SignOcaPdfPortal extends SignOcaPdf {
     setup() {
         super.setup(...arguments);
+        this.rpc = useService("rpc");
         this.signOcaFooter = useRef("sign_oca_footer");
+        this.signer_id = this.props.signer_id;
+        this.access_token = this.props.access_token;
     }
     async willStart() {
-        this.info = await this.env.services.rpc({
-            route:
-                "/sign_oca/info/" +
-                this.props.signer_id +
-                "/" +
-                this.props.access_token,
-        });
+        this.info = await this.rpc(
+            "/sign_oca/info/" + this.signer_id + "/" + this.access_token
+        );
     }
-
     getPdfUrl() {
-        return (
-            "/sign_oca/content/" + this.props.signer_id + "/" + this.props.access_token
-        );
+        return "/sign_oca/content/" + this.signer_id + "/" + this.access_token;
     }
     checkToSign() {
         this.to_sign = this.to_sign_update;
@@ -41,49 +37,43 @@ export class SignOcaPdfPortal extends SignOcaPdf {
     }
     async _onClickSign() {
         const position = await this.getLocation();
-        this.env.services
-            .rpc({
-                route:
-                    "/sign_oca/sign/" +
-                    this.props.signer_id +
-                    "/" +
-                    this.props.access_token,
-                params: {
-                    items: this.info.items,
-                    latitude: position && position.coords && position.coords.latitude,
-                    longitude: position && position.coords && position.coords.longitude,
-                },
-            })
-            .then((action) => {
-                // As we are on frontend env, it is not possible to use do_action(), so we
-                // redirect to the corresponding URL or reload the page if the action is not
-                // an url.
-                if (action.type === "ir.actions.act_url") {
-                    window.location = action.url;
-                } else {
-                    window.location.reload();
-                }
-            });
+        this.rpc("/sign_oca/sign/" + this.signer_id + "/" + this.access_token, {
+            items: this.info.items,
+            latitude: position && position.coords && position.coords.latitude,
+            longitude: position && position.coords && position.coords.longitude,
+        }).then((action) => {
+            // As we are on frontend env, it is not possible to use do_action(), so we
+            // redirect to the corresponding URL or reload the page if the action is not
+            // an url.
+            if (action.type === "ir.actions.act_url") {
+                window.location = action.url;
+            } else {
+                window.location.reload();
+            }
+        });
     }
 }
 SignOcaPdfPortal.template = "sign_oca.SignOcaPdfPortal";
 SignOcaPdfPortal.props = {
-    access_token: {type: String},
-    signer_id: {type: Number},
+    access_token: String,
+    signer_id: Number,
 };
-export function initDocumentToSign(properties) {
-    return session.session_bind(session.origin).then(function () {
-        return Promise.all([
-            session.load_translations(["web", "portal", "sign_oca"]),
-        ]).then(async function () {
-            var app = new App(null, {templates, test: true});
-            renderToString.app = app;
-            const env = makeEnv();
-            mount(SignOcaPdfPortal, document.body, {
-                env,
-                props: properties,
-                templates: templates,
-            });
-        });
+
+export async function initDocumentToSign(document, sign_oca_backend_info) {
+    await whenReady();
+    const env = makeEnv();
+    await startServices(env);
+    const app = new App(SignOcaPdfPortal, {
+        templates,
+        env: env,
+        dev: env.debug,
+        props: {
+            access_token: sign_oca_backend_info.access_token,
+            signer_id: sign_oca_backend_info.signer_id,
+        },
+        translateFn: _t,
+        translatableAttributes: ["data-tooltip"],
     });
+    return app.mount(document.body);
 }
+export default {SignOcaPdfPortal, initDocumentToSign};
diff --git a/sign_oca/static/src/js/ir_model.esm.js b/sign_oca/static/src/js/ir_model.esm.js
deleted file mode 100644
index 6c47804f..00000000
--- a/sign_oca/static/src/js/ir_model.esm.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/** @odoo-module */
-
-import {Component} from "@odoo/owl";
-import {registry} from "@web/core/registry";
-import {standardWidgetProps} from "@web/views/widgets/standard_widget_props";
-
-
-export class IRModelRequest extends Component {
-    setup() {
-        super.setup();
-    }
-}
-IRModelRequest.props = {
-    ...standardWidgetProps,
-};
-IRModelRequest.template = "sign_oca.IrModelRequest";
-
-export const irModelRequest = {
-    component: IRModelRequest,
-};
-registry.category("view_widgets").add("sign_oca_ir_model_request", irModelRequest);
diff --git a/sign_oca/static/src/js/request_group_view.esm.js b/sign_oca/static/src/js/request_group_view.esm.js
deleted file mode 100644
index 1f9b357d..00000000
--- a/sign_oca/static/src/js/request_group_view.esm.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* @odoo-module */
-
-import {Component, onWillUpdateProps, useEffect, useRef, useState} from "@odoo/owl";
-
-
-/**
- * @typedef {Object} Props
- * @property {number} threadId
- * @property {string} threadModel
- * @extends {Component<Props, Env>}
- */
-export class RequestGroupView extends Component {
-    static template = "sign_oca.RequestGroupView";
-    static components = {};
-    static props = [];
-
-    setup() {}
-
-    onClickFilterButton(ev) {
-        this.requestMenuViewOwner.update({isOpen: false});
-        // Fetch the data from the button otherwise fetch the ones from the parent (.o_ActivityMenuView_activityGroup).
-        const data = _.extend({}, $(ev.currentTarget).data(), $(ev.target).data());
-        const context = {};
-        console.log(data);
-
-        this.env.services.action.doAction(
-            {
-                context,
-                name: data.model_name,
-                res_model: "sign.oca.request.signer",
-                search_view_id: [false],
-                type: "ir.actions.act_window",
-                domain: [
-                    ["request_id.state", "=", "sent"],
-                    ["partner_id", "child_of", [session.partner_id]],
-                    ["signed_on", "=", false],
-                ],
-                views: [
-                    [false, "list"],
-                    [false, "form"],
-                ],
-            },
-            {
-                clearBreadcrumbs: true,
-            }
-        );
-    }
-}
diff --git a/sign_oca/static/src/js/request_groups.esm.js b/sign_oca/static/src/js/request_groups.esm.js
deleted file mode 100644
index a59cf415..00000000
--- a/sign_oca/static/src/js/request_groups.esm.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* @odoo-module */
-
-import {Record} from "@mail/core/common/record";
-
-export class RequestGroup extends Record {
-    static pending_count = 0;
-    /** @returns {import("models").RequestGroup} */
-    static get(data) {
-        return super.get(data);
-    }
-    /** @returns {import("models").RequestGroup|import("models").RequestGroup[]} */
-    static insert(data) {
-        return super.insert(...arguments);
-    }
-
-    /** @type {number} */
-    domain;
-    /** @type {string} */
-    type;
-    /** @type {number} */
-    pending_count;
-
-    _onChangePendingCount() {
-        if (this.pending_count === 0) {
-            this.delete();
-        }
-    }
-}
-
-RequestGroup.register();
diff --git a/sign_oca/static/src/js/sign_oca.esm.js b/sign_oca/static/src/js/sign_oca.esm.js
index 59eeabe6..a384cf3f 100644
--- a/sign_oca/static/src/js/sign_oca.esm.js
+++ b/sign_oca/static/src/js/sign_oca.esm.js
@@ -7,63 +7,65 @@ import {patch} from "@web/core/utils/patch";
 const {onWillStart} = owl;
 import {useService} from "@web/core/utils/hooks";
 
-export const patchControllerSignOca = {
-    setup() {
-        this._super(...arguments);
-        this.userService = useService("user");
-        this.orm = useService("orm");
-        this.action = useService("action");
-        this.showSignOcaTemplateGenerateMulti = false;
-        onWillStart(async () => {
-            return Promise.all([this._showSignOcaTemplateGenerateMulti()]);
-        });
-    },
-
-    async _showSignOcaTemplateGenerateMulti() {
-        var sign_oca_group_user = await this.userService.hasGroup(
-            "sign_oca.sign_oca_group_user"
-        );
-        if (sign_oca_group_user) {
-            await this.orm
-                .call("sign.oca.template", "search_count", [
-                    [["model", "=", this.props.resModel]],
-                ])
-                .then((templateCount) => {
-                    this.showSignOcaTemplateGenerateMulti = templateCount !== 0;
+export function patchControllerSignOca() {
+    return {
+        setup() {
+            super.setup(...arguments);
+            this.userService = useService("user");
+            this.orm = useService("orm");
+            this.action = useService("action");
+            this.showSignOcaTemplateGenerateMulti = false;
+            onWillStart(async () => {
+                return Promise.all([this._showSignOcaTemplateGenerateMulti()]);
+            });
+        },
+        async _showSignOcaTemplateGenerateMulti() {
+            var sign_oca_group_user = await this.userService.hasGroup(
+                "sign_oca.sign_oca_group_user"
+            );
+            if (sign_oca_group_user) {
+                await this.orm
+                    .call("sign.oca.template", "search_count", [
+                        [["model", "=", this.props.resModel]],
+                    ])
+                    .then((templateCount) => {
+                        this.showSignOcaTemplateGenerateMulti = templateCount !== 0;
+                    });
+            }
+        },
+        async _actionSignOcaTemplateGenerateMulti() {
+            var resIds = "";
+            if (this.getSelectedResIds) resIds = await this.getSelectedResIds();
+            else resIds = this.model.root.data.id;
+            this.action.doAction(
+                "sign_oca.sign_oca_template_generate_multi_act_window",
+                {
+                    additionalContext: {
+                        model: this.props.resModel,
+                        active_ids: resIds,
+                    },
+                    on_close: () => {
+                        this.update({}, {reload: false});
+                    },
+                }
+            );
+        },
+        getActionMenuItems() {
+            const menuItems = this._super.apply(this, arguments);
+            const otherActionItems = menuItems.other;
+            if (menuItems && this.showSignOcaTemplateGenerateMulti) {
+                otherActionItems.push({
+                    key: "sign",
+                    description: _t("Sign from template"),
+                    callback: () => this._actionSignOcaTemplateGenerateMulti(),
                 });
-        }
-    },
-
-    async _actionSignOcaTemplateGenerateMulti() {
-        var resIds = "";
-        if (this.getSelectedResIds) resIds = await this.getSelectedResIds();
-        else resIds = this.model.root.data.id;
-        this.action.doAction("sign_oca.sign_oca_template_generate_multi_act_window", {
-            additionalContext: {
-                model: this.props.resModel,
-                active_ids: resIds,
-            },
-            on_close: () => {
-                this.update({}, {reload: false});
-            },
-        });
-    },
-
-    getActionMenuItems() {
-        const menuItems = this._super.apply(this, arguments);
-        const otherActionItems = menuItems.other;
-        if (menuItems && this.showSignOcaTemplateGenerateMulti) {
-            otherActionItems.push({
-                key: "sign",
-                description: _t("Sign from template"),
-                callback: () => this._actionSignOcaTemplateGenerateMulti(),
+            }
+            return Object.assign({}, this.props.info.actionMenus, {
+                other: otherActionItems,
             });
-        }
-        return Object.assign({}, this.props.info.actionMenus, {
-            other: otherActionItems,
-        });
-    },
-};
+        },
+    };
+}
 
-patch(ListController.prototype, patchControllerSignOca);
-patch(FormController.prototype, patchControllerSignOca);
+patch(ListController.prototype, patchControllerSignOca());
+patch(FormController.prototype, patchControllerSignOca());
diff --git a/sign_oca/static/src/js/signer_menu_container.esm.js b/sign_oca/static/src/js/signer_menu_container.esm.js
deleted file mode 100644
index 9aa8f207..00000000
--- a/sign_oca/static/src/js/signer_menu_container.esm.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/** @odoo-module **/
-
-import {registry} from "@web/core/registry";
-/* eslint-disable */
-import SignerMenuView from "./signer_menu_view.esm";
-/* eslint-enable */
-
-const {Component} = owl;
-
-export class SignerMenuContainer extends Component {
-    /**
-     * @override
-     */
-    setup() {
-        super.setup();
-        this.env.services.messaging.modelManager.messagingCreatedPromise.then(() => {
-            this.signerMenuView =
-                this.env.services.messaging.modelManager.messaging.models.SignerMenuView.insert();
-            this.render();
-        });
-    }
-}
-
-SignerMenuContainer.template = "sign_oca.SignerMenuContainer";
-registry.category("menu").add("SignerMenuContainer", {
-    Component: SignerMenuView,
-    props: {record: Object},
-});
diff --git a/sign_oca/static/src/js/signer_menu_view.esm.js b/sign_oca/static/src/js/signer_menu_view.esm.js
deleted file mode 100644
index e7b96548..00000000
--- a/sign_oca/static/src/js/signer_menu_view.esm.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/** @odoo-module **/
-
-import {registry} from "@web/core/registry";
-const {Component} = owl;
-
-export class SignerMenuView extends Component {
-    /**
-     * @override
-     */
-    setup() {
-        super.setup();
-    }
-    /**
-     * @returns {SignerMenuView}
-     */
-    get signerMenuView() {
-        return this.props.record;
-    }
-}
-
-SignerMenuView.template = "sign_oca.SignerMenuView";
-registry.category("menu").add("SignerMenuView", {
-    Component: SignerMenuView,
-    props: {record: Object},
-});
diff --git a/sign_oca/static/src/js/systray.esm.js b/sign_oca/static/src/js/systray.esm.js
deleted file mode 100644
index 4d334d20..00000000
--- a/sign_oca/static/src/js/systray.esm.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/** @odoo-module **/
-
-import {attr, many} from "@mail/model/model_field";
-import {registerModel} from "@mail/model/model_core";
-import {session} from "@web/session";
-
-registerModel({
-    name: "SignerMenuView",
-    lifecycleHooks: {
-        _created() {
-            this.fetchData();
-            document.addEventListener("click", this._onClickCaptureGlobal, true);
-        },
-        _willDelete() {
-            document.removeEventListener("click", this._onClickCaptureGlobal, true);
-        },
-    },
-    recordMethods: {
-        close() {
-            this.update({isOpen: false});
-        },
-        async fetchData() {
-            const data = await this.messaging.rpc({
-                model: "res.users",
-                method: "sign_oca_request_user_count",
-                args: [],
-                kwargs: {context: session.user_context},
-            });
-
-            this.update({
-                requestGroups: data.map((vals) =>
-                    this.messaging.models.RequestGroup.convertData(vals)
-                ),
-                extraCount: 0,
-            });
-        },
-        /**
-         * @param {MouseEvent} ev
-         */
-        onClickDropdownToggle(ev) {
-            ev.preventDefault();
-            if (this.isOpen) {
-                this.update({isOpen: false});
-            } else {
-                this.update({isOpen: true});
-                this.fetchData();
-            }
-        },
-        /**
-         * Closes the menu when clicking outside, if appropriate.
-         *
-         * @private
-         * @param {MouseEvent} ev
-         */
-        _onClickCaptureGlobal(ev) {
-            if (!this.exists()) {
-                return;
-            }
-            if (!this.component || !this.component.root.el) {
-                return;
-            }
-            if (this.component.root.el.contains(ev.target)) {
-                return;
-            }
-            this.close();
-        },
-    },
-    fields: {
-        requestGroups: many("RequestGroup", {
-            sort: [["smaller-first", "irModel.id"]],
-        }),
-        requestGroupViews: many("RequestGroupView", {
-            compute() {
-                return this.requestGroups.map((requestGroup) => {
-                    return {
-                        requestGroup,
-                    };
-                });
-            },
-            inverse: "requestMenuViewOwner",
-        }),
-        component: attr(),
-        counter: attr({
-            compute() {
-                return this.requestGroups.reduce(
-                    (total, group) => total + group.pending_count,
-                    this.extraCount
-                );
-            },
-        }),
-        /**
-         * Determines the number of activities that have been added in the
-         * system but not yet taken into account in each activity group counter.
-         *
-         * @deprecated this field should be replaced by directly updating the
-         * counter of each group.
-         */
-        extraCount: attr(),
-        isOpen: attr({
-            default: false,
-        }),
-    },
-});
diff --git a/sign_oca/static/src/js/systray.js b/sign_oca/static/src/js/systray.js
deleted file mode 100644
index 752593f3..00000000
--- a/sign_oca/static/src/js/systray.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* @odoo-module */
-
-import {Component, onWillUpdateProps, useEffect, useRef, useState} from "@odoo/owl";
-
-import {useService} from "@web/core/utils/hooks";
-import {hidePDFJSButtons} from "@web/libs/pdfjs";
-
-/**
- * @typedef {Object} Props
- * @property {number} threadId
- * @property {string} threadModel
- * @extends {Component<Props, Env>}
- */
-export class AttachmentView extends Component {
-    static template = "mail.AttachmentView";
-    static components = {};
-    static props = [];
-
-    setup() {
-    }
-
-    close() {
-        this.update({isOpen: false});
-    }
-    async fetchData() {
-        const data = await this.messaging.rpc({
-            model: "res.users",
-            method: "sign_oca_request_user_count",
-            args: [],
-            kwargs: {context: session.user_context},
-        });
-
-        this.update({
-            requestGroups: data.map((vals) =>
-                this.messaging.models.RequestGroup.convertData(vals)
-            ),
-            extraCount: 0,
-        });
-    }
-    /**
-     * @param {MouseEvent} ev
-     */
-    onClickDropdownToggle(ev) {
-        ev.preventDefault();
-        if (this.isOpen) {
-            this.update({isOpen: false});
-        } else {
-            this.update({isOpen: true});
-            this.fetchData();
-        }
-    }
-    /**
-     * Closes the menu when clicking outside, if appropriate.
-     *
-     * @private
-     * @param {MouseEvent} ev
-     */
-    onClickCaptureGlobal(ev) {
-        if (!this.exists()) {
-            return;
-        }
-        if (!this.component || !this.component.root.el) {
-            return;
-        }
-        if (this.component.root.el.contains(ev.target)) {
-            return;
-        }
-        this.close();
-    }
-}
diff --git a/sign_oca/static/src/js/systray_service.esm.js b/sign_oca/static/src/js/systray_service.esm.js
index 548640c2..67f98b77 100644
--- a/sign_oca/static/src/js/systray_service.esm.js
+++ b/sign_oca/static/src/js/systray_service.esm.js
@@ -1,18 +1,68 @@
-/** @odoo-module **/
-
-import {SignerMenuContainer} from "./signer_menu_container.esm";
-
+/* @odoo-module */
+import {Component, useState} from "@odoo/owl";
+import {Dropdown} from "@web/core/dropdown/dropdown";
+import {DropdownItem} from "@web/core/dropdown/dropdown_item";
 import {registry} from "@web/core/registry";
-
+import {session} from "@web/session";
+import {useDiscussSystray} from "@mail/utils/common/hooks";
+import {useService} from "@web/core/utils/hooks";
 const systrayRegistry = registry.category("systray");
-
-export const systrayService = {
-    start() {
-        systrayRegistry.add(
-            "sign_oca.SignerMenu",
-            {Component: SignerMenuContainer},
-            {sequence: 99}
+export class SignerMenuView extends Component {
+    setup() {
+        this.discussSystray = useDiscussSystray();
+        this.orm = useService("orm");
+        this.store = useState(useService("mail.store"));
+        this.action = useService("action");
+        this.fetchSystraySigner();
+    }
+    async fetchSystraySigner() {
+        const groups = await this.orm.call("res.users", "sign_oca_request_user_count");
+        let total = 0;
+        for (const group of groups) {
+            total += group.total_records || 0;
+        }
+        this.store.signerCounter = total;
+        this.store.signerGroups = groups;
+    }
+    onBeforeOpen() {
+        this.fetchSystraySigner();
+    }
+    availableViews() {
+        return [
+            [false, "kanban"],
+            [false, "list"],
+            [false, "form"],
+            [false, "activity"],
+        ];
+    }
+    onClickFilterButton(group) {
+        document.body.click(); // Hack to close dropdown
+        const context = {};
+        const views = this.availableViews();
+        var domain = [
+            ["request_id.state", "=", "sent"],
+            ["partner_id", "child_of", [session.partner_id]],
+            ["signed_on", "=", false],
+        ];
+        this.action.doAction(
+            {
+                context,
+                domain,
+                name: group.name,
+                res_model: "sign.oca.request.signer",
+                search_view_id: [false],
+                type: "ir.actions.act_window",
+                views,
+            },
+            {
+                clearBreadcrumbs: true,
+            }
         );
-    },
-};
-systrayRegistry.add("request_systray_service", systrayService);
+    }
+}
+
+SignerMenuView.template = "sign_oca.SignerMenu";
+SignerMenuView.components = {Dropdown, DropdownItem};
+SignerMenuView.props = [];
+export const systrayItem = {Component: SignerMenuView};
+systrayRegistry.add("sign_oca.SignerMenuView", systrayItem, {sequence: 99});
diff --git a/sign_oca/static/src/xml/signer_menu_container.xml b/sign_oca/static/src/xml/signer_menu_container.xml
deleted file mode 100644
index 12b78e9a..00000000
--- a/sign_oca/static/src/xml/signer_menu_container.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<templates xml:space="preserve">
-    <t t-name="sign_oca.SignerMenuContainer">
-        <t t-if="signerMenuView">
-            <SignerMenuView record="signerMenuView" />
-        </t>
-    </t>
-</templates>
diff --git a/sign_oca/static/src/xml/systray.xml b/sign_oca/static/src/xml/systray.xml
index d840bab8..f71df469 100644
--- a/sign_oca/static/src/xml/systray.xml
+++ b/sign_oca/static/src/xml/systray.xml
@@ -1,86 +1,53 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <templates>
-    <t t-name="sign_oca.SignerMenuView">
-        <div class="o_ActivityMenuView dropdown" t-ref="root">
-            <a
-                class="o_ActivityMenuView_dropdownToggle dropdown-toggle o-no-caret o-dropdown--narrow"
-                t-att-aria-expanded="signerMenuView.isOpen ? 'true' : 'false'"
-                title="Sign Requests"
-                href="#"
-                role="button"
-                t-on-click="signerMenuView.onClickDropdownToggle"
-            >
-                <i class="fa fa-pencil" role="img" aria-label="Sign Requests" /> <span
-                    t-if="signerMenuView.counter > 0"
-                    class="o_ActivityMenuView_counter badge"
-                    t-esc="signerMenuView.counter"
+    <t t-name="sign_oca.SignerMenu">
+        <Dropdown
+            position="'bottom-end'"
+            beforeOpen.bind="onBeforeOpen"
+            autoOpen="false"
+            menuClass="discussSystray.menuClass"
+            class="discussSystray.class"
+        >
+        <t t-set-slot="toggler">
+            <i class="fa fa-pencil" role="img" aria-label="Sign Requests" />
+            <span
+                    t-if="store.signerCounter > 0"
+                    class="o-mail-ActivityMenu-counter badge rounded-pill"
+                    t-out="store.signerCounter"
                 />
-            </a>
-            <div
-                t-if="signerMenuView.isOpen"
-                class="o_ActivityMenuView_dropdownMenu o-dropdown-menu dropdown-menu-end show bg-view"
-                role="menu"
-            >
-                <div class="o_ActivityMenuView_activityGroups">
-                    <t t-if="signerMenuView.requestGroupViews.length === 0">
-                        <div
-                            class="o_ActivityMenuView_noActivity dropdown-item-text text-center d-flex justify-content-center"
-                        >
-                            <span>No requests to sign.</span>
-                        </div>
-                    </t>
-                    <t
-                        t-foreach="signerMenuView.requestGroupViews"
-                        t-as="requestGroupView"
-                        t-key="requestGroupView.localId"
-                        name="activityGroupLoop"
+        </t>
+        <t t-set-slot="default">
+            <div t-att-class="`${discussSystray.contentClass} o-mail-ActivityMenu`">
+                <div
+                        t-if="store.signerCounter === 0"
+                        class="o-mail-ActivityMenu-empty align-items-center text-muted p-2 opacity-50 d-flex justify-content-center"
                     >
-                        <div
-                            class="o_ActivityMenuView_activityGroup"
-                            t-att-data-res_model="requestGroupView.requestGroup.irModel.model"
-                            t-att-data-model_name="requestGroupView.requestGroup.irModel.name"
-                            t-att-data-active_field="requestGroupView.requestGroup.irModel.active_field"
-                            t-att-data-domain="requestGroupView.requestGroup.domain"
-                            data-filter='my'
-                            t-att-data-activity-group-view-local-id="requestGroupView.localId"
-                            t-on-click="requestGroupView.onClickFilterButton"
+                    <span>No requests to sign.</span>
+                </div>
+                <div class="d-flex flex-column list-group-flush" name="activityGroups">
+                    <t
+                            t-foreach="store.signerGroups"
+                            t-as="group"
+                            t-key="group_index"
+                            name="activityGroupLoop"
                         >
-                            <div
-                                t-if="requestGroupView.requestGroup.irModel.iconUrl"
-                                class="o_ActivityMenuView_activityGroupIconContainer"
+                        <div
+                                class="o-mail-ActivityGroup list-group-item list-group-item-action d-flex p-2 cursor-pointer"
+                                t-att-data-model_name="group.model"
+                                t-on-click="() => this.onClickFilterButton(group)"
                             >
-                                <img
-                                    t-att-src="requestGroupView.requestGroup.irModel.iconUrl"
-                                    alt="Requests"
-                                />
-                            </div>
-                            <div class="o_ActivityMenuView_activityGroupInfo">
-                                <div class="o_ActivityMenuView_activityGroupTitle">
-                                    <span class="o_ActivityMenuView_activityGroupName">
-                                        <t
-                                            t-esc="requestGroupView.requestGroup.irModel.name"
-                                        />
-                                    </span>
-                                </div>
-                                <div>
-                                    <button
-                                        t-if="requestGroupView.requestGroup.pending_count"
-                                        type="button"
-                                        class="btn btn-link o_activity_filter_button mr16"
-                                        t-att-data-res_model="requestGroupView.requestGroup.irModel.model"
-                                        t-att-data-model_name="requestGroupView.requestGroup.irModel.name"
-                                        data-filter="pending_count"
-                                    >
-                                        <t
-                                            t-esc="requestGroupView.requestGroup.pending_count"
-                                        />
-                                        Pending
-                                    </button>
+                            <img alt="Requests" t-att-src="group.icon" />
+                            <div class="flex-grow-1 overflow-hidden">
+                                <div
+                                        class="d-flex px-2"
+                                        name="activityTitle"
+                                        t-out="group.name"
+                                    />
+                                <div class="d-flex">
                                     <span
-                                        t-if="!requestGroupView.requestGroup.pending_count"
-                                        class="o_no_activity mr16"
-                                    >
-                                        0 Pending
+                                            t-attf-class="#{group.total_records ? '' : 'text-muted'} py-0 px-2"
+                                        >
+                                        <t t-out="group.total_records" /> Pending
                                     </span>
                                 </div>
                             </div>
@@ -88,6 +55,7 @@
                     </t>
                 </div>
             </div>
-        </div>
+        </t>
+        </Dropdown>
     </t>
 </templates>
diff --git a/sign_oca/templates/assets.xml b/sign_oca/templates/assets.xml
index 43626804..4111eb39 100644
--- a/sign_oca/templates/assets.xml
+++ b/sign_oca/templates/assets.xml
@@ -2,23 +2,32 @@
 <odoo>
     <template id="portal_sign_document">
         <t t-call="web.layout">
+            <t t-set="html_data" t-value="{'lang': sign_oca_backend_info['lang']}" />
             <t t-set="head">
                 <meta
                     name="viewport"
                     content="width=device-width, initial-scale=1, user-scalable=no"
                 />
+                <input
+                    type="hidden"
+                    name="csrf_token"
+                    t-att-value="request.csrf_token()"
+                />
                 <t t-call-assets="web.assets_frontend" t-js="false" />
                 <t t-call-assets="web.assets_frontend" t-css="false" />
                 <script type="text/javascript">
-                    odoo.define("sign.document_portal", function(require) {
-                        var ajax = require("web.ajax");
-                        var document_signing = require("@sign_oca/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm");
-                        document_signing.initDocumentToSign(<t
-                        t-out="json.dumps({'access_token': access_token, 'signer_id': signer.id})"
+                    odoo.define("sign.document_portal", ["@sign_oca/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm"], function (require) {
+                    var { initDocumentToSign } = require("@sign_oca/components/sign_oca_pdf_portal/sign_oca_pdf_portal.esm");
+                    initDocumentToSign(document, <t
+                        t-out="json.dumps(sign_oca_backend_info)"
                     />);
                     });
                 </script>
             </t>
+            <t t-set="body">
+            </t>
+            <body class="o_web_client o_portal_sign_document_body">
+            </body>
         </t>
     </template>
     <template id="portal_sign_document_signed">
diff --git a/sign_oca/tests/test_sign.py b/sign_oca/tests/test_sign.py
index cf977435..6c44dd8f 100644
--- a/sign_oca/tests/test_sign.py
+++ b/sign_oca/tests/test_sign.py
@@ -5,18 +5,20 @@
 
 import requests
 
-from odoo.modules.module import get_module_resource
-from odoo.tests.common import Form, TransactionCase
+from odoo.tests.common import Form
+from odoo.tools import misc
 
+from odoo.addons.base.tests.common import BaseCommon
 
-class TestSign(TransactionCase):
+
+class TestSign(BaseCommon):
     @classmethod
     def setUpClass(cls):
         cls._super_send = requests.Session.send
         super().setUpClass()
         cls.data = base64.b64encode(
             open(
-                get_module_resource("sign_oca", "tests", "empty.pdf"),
+                misc.file_path(f"{cls.test_module}/tests/empty.pdf"),
                 "rb",
             ).read()
         )
@@ -179,10 +181,7 @@ def test_sign_request_role_with_default(self):
 
     def test_sign_request_role_with_expression(self):
         request_form = Form(self.env["sign.oca.request"])
-        request_form.record_ref = "%s,%s" % (
-            self.partner_child._name,
-            self.partner_child.id,
-        )
+        request_form.record_ref = f"{self.partner_child._name},{self.partner_child.id}"
         with request_form.signer_ids.new() as signer:
             signer.role_id = self.role_child_partner
             self.assertEqual(signer.partner_id, self.partner)
diff --git a/sign_oca/tests/test_sign_portal.py b/sign_oca/tests/test_sign_portal.py
index 84a10da6..a14ea51a 100644
--- a/sign_oca/tests/test_sign_portal.py
+++ b/sign_oca/tests/test_sign_portal.py
@@ -5,19 +5,19 @@
 
 import requests
 
-from odoo.modules.module import get_module_resource
 from odoo.tests.common import HttpCase, tagged
+from odoo.tools import misc
 
 
 @tagged("post_install", "-at_install")
-class TestSign(HttpCase):
+class TestSignPortal(HttpCase):
     @classmethod
     def setUpClass(cls):
         cls._super_send = requests.Session.send
         super().setUpClass()
         cls.data = base64.b64encode(
             open(
-                get_module_resource("sign_oca", "tests", "empty.pdf"),
+                misc.file_path(f"{cls.test_module}/tests/empty.pdf"),
                 "rb",
             ).read()
         )
@@ -62,14 +62,16 @@ def test_portal(self):
         self.assertEqual(
             base64.b64decode(self.data),
             self.url_open(
-                "/sign_oca/content/%s/%s"
-                % (self.request.signer_ids.id, self.request.signer_ids.access_token)
+                "/sign_oca/content/{}/{}".format(
+                    self.request.signer_ids.id, self.request.signer_ids.access_token
+                )
             ).content,
         )
         self.assertEqual(
             self.url_open(
-                "/sign_oca/info/%s/%s"
-                % (self.request.signer_ids.id, self.request.signer_ids.access_token),
+                "/sign_oca/info/{}/{}".format(
+                    self.request.signer_ids.id, self.request.signer_ids.access_token
+                ),
                 data="{}",
                 headers={"Content-Type": "application/json"},
             ).json()["result"]["items"][str(self.item["id"])],
diff --git a/sign_oca/wizards/sign_oca_template_generate.xml b/sign_oca/wizards/sign_oca_template_generate.xml
index f5d0f1cd..8b570d7c 100644
--- a/sign_oca/wizards/sign_oca_template_generate.xml
+++ b/sign_oca/wizards/sign_oca_template_generate.xml
@@ -37,7 +37,7 @@
         <field name="name">Sign Oca Template Generate</field> <!-- TODO -->
         <field name="res_model">sign.oca.template.generate</field>
         <field name="view_mode">form</field>
-        <field name="context">{'default_template_id': id}</field>
+        <field name="context">{'default_template_id': active_id}</field>
         <field name="target">new</field>
     </record>