From 34f1bca55b62d364813748260593e70ed2b91f62 Mon Sep 17 00:00:00 2001 From: KKamaa Date: Thu, 8 Jul 2021 05:10:18 +0300 Subject: [PATCH] [MIG] support_branding: Migration to 14.0 --- setup/support_branding/odoo/__init__.py | 1 - .../support_branding/odoo/addons/__init__.py | 1 - support_branding/README.rst | 106 ++--- support_branding/__init__.py | 7 + support_branding/__manifest__.py | 19 +- support_branding/data/ir_config_parameter.xml | 25 - .../demo/ir_config_parameter_data.xml | 25 + support_branding/models/__init__.py | 4 + .../models/res_config_settings.py | 36 ++ support_branding/readme/CONTRIBUTORS.rst | 4 + support_branding/readme/DESCRIPTION.rst | 4 + support_branding/static/description/icon.png | Bin 13573 -> 9455 bytes .../static/description/index.html | 426 ++++++++++++++++++ .../static/src/css/support_branding.css | 4 + .../static/src/js/res_config_edition.js | 33 ++ .../static/src/js/support_branding.js | 210 ++++++--- support_branding/static/src/js/user_menu.js | 27 ++ support_branding/static/src/xml/base.xml | 62 ++- support_branding/views/asset.xml | 28 ++ support_branding/views/qweb.xml | 43 -- .../views/res_config_settings.xml | 96 ++++ 21 files changed, 932 insertions(+), 229 deletions(-) delete mode 100644 setup/support_branding/odoo/__init__.py delete mode 100644 setup/support_branding/odoo/addons/__init__.py delete mode 100644 support_branding/data/ir_config_parameter.xml create mode 100644 support_branding/demo/ir_config_parameter_data.xml create mode 100644 support_branding/models/__init__.py create mode 100644 support_branding/models/res_config_settings.py create mode 100644 support_branding/readme/CONTRIBUTORS.rst create mode 100644 support_branding/readme/DESCRIPTION.rst create mode 100644 support_branding/static/description/index.html create mode 100644 support_branding/static/src/js/res_config_edition.js create mode 100644 support_branding/static/src/js/user_menu.js create mode 100644 support_branding/views/asset.xml delete mode 100644 support_branding/views/qweb.xml create mode 100644 support_branding/views/res_config_settings.xml diff --git a/setup/support_branding/odoo/__init__.py b/setup/support_branding/odoo/__init__.py deleted file mode 100644 index de40ea7ca..000000000 --- a/setup/support_branding/odoo/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/support_branding/odoo/addons/__init__.py b/setup/support_branding/odoo/addons/__init__.py deleted file mode 100644 index de40ea7ca..000000000 --- a/setup/support_branding/odoo/addons/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) diff --git a/support_branding/README.rst b/support_branding/README.rst index 588c3523f..18faf9ab0 100644 --- a/support_branding/README.rst +++ b/support_branding/README.rst @@ -1,92 +1,80 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License: AGPL-3 - -Support branding ================ +Support Branding +================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/14.0/support_branding + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-14-0/web-14-0-support_branding + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/162/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| If you run an Odoo support company and you support customers without an OPW, you can brand the Odoo instance accordingly using this module. This module will -add a line `Supported by $yourcompany` in the menu footer and add a button to -mail exception messages to your support email address. +add a support company url to profile menu under, `Support`. Moreover, +it will add a button to mail exception messages to your support email address. +**Table of contents** -Configuration -============= - -This module is controlled by config parameters: - -support_branding.company_name - Your company's name - -support_branding.company_url - Your company's website - -support_branding.company_color - The color to show your company's name in (CSS syntax) - -support_branding.support_email - The (optional) mailaddress to contact for support - -support_branding.release - The (optional) version number of your deployment - -You probably want to depend on this module in your customer specific module and -add the following XML:: - - - Your company - - - https://yourwebsite.com - - - #000 - - - support@yourwebsite.com - - - 42 - Configuration - -Note that the email button is only visible if you configure an email address, -the default is empty! +.. contents:: + :local: Bug Tracker =========== Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Therp BV +* Sunflower IT + Contributors ------------- +~~~~~~~~~~~~ * Holger Brunn * Stefan Rijnhart * Robert Rottermann +* Kevin Kamau -Icon ----- +Maintainers +~~~~~~~~~~~ -* https://commons.wikimedia.org/wiki/File:Crystal_Clear_app_khelpcenter.png - -Maintainer ----------- +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - 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. -To contribute to this module, please visit http://odoo-community.org. +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/support_branding/__init__.py b/support_branding/__init__.py index e69de29bb..9416c2a04 100644 --- a/support_branding/__init__.py +++ b/support_branding/__init__.py @@ -0,0 +1,7 @@ +# Copyright 2012-2015 Therp BV () +# Copyright 2016 - Tecnativa - Angel Moya +# Copyright 2017 - redO2oo - Robert Rottermann +# Copyright 2021 Sunflower IT +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models diff --git a/support_branding/__manifest__.py b/support_branding/__manifest__.py index 341ea4a44..94c4d76b4 100644 --- a/support_branding/__manifest__.py +++ b/support_branding/__manifest__.py @@ -1,25 +1,24 @@ # Copyright 2012-2015 Therp BV () # Copyright 2016 - Tecnativa - Angel Moya # Copyright 2017 - redO2oo - Robert Rottermann +# Copyright 2021 Sunflower IT () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - "name": "Support branding", + "name": "Support Branding", "summary": "Adds your branding to an Odoo instance", - "category": "Dependecy/Hidden", - "version": "10.0.1.0.0", + "category": "Hidden/Tools", + "version": "14.0.1.0.0", "license": "AGPL-3", - "author": "Therp BV,Odoo Community Association (OCA)", + "author": "Therp BV,Sunflower IT,Odoo Community Association (OCA)", "website": "https://github.com/OCA/web", - "depends": [ - "web", - ], + "depends": ["web", "base_setup"], "qweb": [ "static/src/xml/base.xml", ], - "data": [ - "data/ir_config_parameter.xml", - "views/qweb.xml", + "data": ["views/asset.xml", "views/res_config_settings.xml"], + "demo": [ + "demo/ir_config_parameter_data.xml", ], "installable": True, } diff --git a/support_branding/data/ir_config_parameter.xml b/support_branding/data/ir_config_parameter.xml deleted file mode 100644 index 73bd8bf35..000000000 --- a/support_branding/data/ir_config_parameter.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - support_branding.company_name - Odoo Community Association (OCA) - - - support_branding.company_url - https://odoo-community.org - - - support_branding.company_color - #b163a3 - - - support_branding.support_email - - - - support_branding.release - - - - diff --git a/support_branding/demo/ir_config_parameter_data.xml b/support_branding/demo/ir_config_parameter_data.xml new file mode 100644 index 000000000..df026f89d --- /dev/null +++ b/support_branding/demo/ir_config_parameter_data.xml @@ -0,0 +1,25 @@ + + + + + support_company + Sunflower IT + + + support_company_url + https://www.sunflowerweb.nl + + + support_branding_color + #fff + + + support_email + info@sunflowerweb.nl + + + support_release + 14.0 + + + diff --git a/support_branding/models/__init__.py b/support_branding/models/__init__.py new file mode 100644 index 000000000..4124bd743 --- /dev/null +++ b/support_branding/models/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2021 Sunflower IT +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import res_config_settings diff --git a/support_branding/models/res_config_settings.py b/support_branding/models/res_config_settings.py new file mode 100644 index 000000000..a07ecccea --- /dev/null +++ b/support_branding/models/res_config_settings.py @@ -0,0 +1,36 @@ +# Copyright 2021 Sunflower IT +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + def get_values(self): + res = super(ResConfigSettings, self).get_values() + param_obj = self.env["ir.config_parameter"].sudo() + res.update( + support_company=param_obj.get_param("support_company"), + support_company_url=param_obj.get_param("support_company_url"), + support_email=param_obj.get_param("support_email"), + support_release=param_obj.get_param("support_release"), + support_branding_color=param_obj.get_param("support_branding_color"), + ) + return res + + def set_values(self): + res = super(ResConfigSettings, self).set_values() + param_obj = self.env["ir.config_parameter"].sudo() + param_obj.set_param("support_company", self.support_company) + param_obj.set_param("support_company_url", self.support_company_url) + param_obj.set_param("support_email", self.support_email) + param_obj.set_param("support_release", self.support_release) + param_obj.set_param("support_branding_color", self.support_branding_color) + return res + + support_company = fields.Char(string="Company Name") + support_company_url = fields.Char(string="Company URL") + support_branding_color = fields.Char(string="Branding color") + support_email = fields.Char(string="Support email") + support_release = fields.Char(string="Support release") diff --git a/support_branding/readme/CONTRIBUTORS.rst b/support_branding/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..697abcab5 --- /dev/null +++ b/support_branding/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Holger Brunn +* Stefan Rijnhart +* Robert Rottermann +* Kevin Kamau diff --git a/support_branding/readme/DESCRIPTION.rst b/support_branding/readme/DESCRIPTION.rst new file mode 100644 index 000000000..1191583f6 --- /dev/null +++ b/support_branding/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +If you run an Odoo support company and you support customers without an OPW, +you can brand the Odoo instance accordingly using this module. This module will +add a support company url to profile menu under, `Support`. Moreover, +it will add a button to mail exception messages to your support email address. diff --git a/support_branding/static/description/icon.png b/support_branding/static/description/icon.png index f181838db7a2a1d937738f69d8219d0529a131fd..3a0328b516c4980e8e44cdb63fd945757ddd132d 100644 GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 13573 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
    r! zDh}V2T2zqz3I(Xv3CPC4Vrak*p6NK(0h+miO^%M@^m3SG$WiL!$5Szb3I07wE1E1r zFFJ@Jwj30>@khnJk0Rx^R7DB^i3-D3vM+>KS$3E=vVm7lKOwcW5;{p_KFdZ|6ACnJ zVn${ad%1~ZZK=THQ1HalPP!Qz@3e`0e-qP7EAU(;KxHC6~6 z3x8VoSD^*zkT;Q&Nl6gu!%kX#P&0h?bvCRi;JFp>2Bvm@eC|gIv=<$e+)KAs~@v40@fLz9D+oV^n9Yfg$A7^EddR zKAbC#7%=9{`q5Kw9q^&AATU*eF1`fpjtULzxG$i2IeGV$Kwe_Si0x``Boxsv5*kV! z`Recq6RR((wH$G|H}*$!!0uc54P*P-s(OHg$LXwgg9NWDzFQoLkgoBQlz+e1ag!CI z_Uq&``aDWVW>svvn{R0wZPHC;nE`oVCcBh|a%SE7%0Dq(4@6L%h8uO+jL4mvj6a3Y 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 ARsaA1 diff --git a/support_branding/static/description/index.html b/support_branding/static/description/index.html new file mode 100644 index 000000000..def712433 --- /dev/null +++ b/support_branding/static/description/index.html @@ -0,0 +1,426 @@ + + + + + + +Support Branding + + + +
    +

    Support Branding

    + + +

    Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runbot

    +

    If you run an Odoo support company and you support customers without an OPW, +you can brand the Odoo instance accordingly using this module. This module will +add a support company url to profile menu under, Support. Moreover, +it will add a button to mail exception messages to your support email address.

    +

    Table of contents

    + +
    +

    Bug Tracker

    +

    Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

    +

    Do not contact contributors directly about support or help with technical issues.

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • Therp BV
    • +
    • Sunflower IT
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    +Odoo Community Association +

    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.

    +

    This module is part of the OCA/web project on GitHub.

    +

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    +
    +
    +
    + + diff --git a/support_branding/static/src/css/support_branding.css b/support_branding/static/src/css/support_branding.css index 21b25d33d..68a68a8e5 100644 --- a/support_branding/static/src/css/support_branding.css +++ b/support_branding/static/src/css/support_branding.css @@ -2,3 +2,7 @@ display: inline; margin: 0px; } + +.support-statement { + margin: 10px 0 10px 0; +} diff --git a/support_branding/static/src/js/res_config_edition.js b/support_branding/static/src/js/res_config_edition.js new file mode 100644 index 000000000..48ac99cc3 --- /dev/null +++ b/support_branding/static/src/js/res_config_edition.js @@ -0,0 +1,33 @@ +odoo.define("support_branding.ResConfigEdition", function (require) { + "use strict"; + + var ResConfigEdition = require("base_setup.ResConfigEdition"); + + ResConfigEdition.include({ + willStart: function () { + var self = this; + var def_1 = this._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_company"], + }).then(function (name) { + self.support_cp_name = name; + }); + var def_2 = this._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_company_url"], + }).then(function (url) { + self.support_cp_url = url; + }); + var def_3 = this._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_email"], + }).then(function (email) { + self.support_cp_email = email; + }); + return $.when(this._super.apply(this, arguments), def_1, def_2, def_3); + }, + }); +}); diff --git a/support_branding/static/src/js/support_branding.js b/support_branding/static/src/js/support_branding.js index c567cfd00..0aa4f558e 100644 --- a/support_branding/static/src/js/support_branding.js +++ b/support_branding/static/src/js/support_branding.js @@ -2,105 +2,169 @@ * Copyright 2016 - Tecnativa - Angel Moya * Copyright 2017 - redO2oo - Robert Rottermann * Copyright 2018 - Therp BV + * Copyright 2021 - Sunflower IT * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ -odoo.define("web.support_branding", function (require) { - var CrashManager = require("web.CrashManager"); - var core = require("web.core"); - var Model = require("web.Model"); +odoo.define("support_branding.CrashManager", function (require) { + "use strict"; + var CrashManager = require("web.CrashManager").CrashManager; var session = require("web.session"); + var core = require("web.core"); + var _t = core._t; + CrashManager.include({ init: function () { - var self = this, - ir_config_parameter = new Model("ir.config_parameter"); - ir_config_parameter - .call("get_param", ["support_branding.support_email"]) - .then(function (email) { - self.support_branding_support_email = email; + var self = this; + $.when(this._super.apply(this, arguments)).then(function () { + self._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_company"], + }).then(function (name) { + self.support_cp_name = name; }); - ir_config_parameter - .call("get_param", ["support_branding.company_name"]) - .then(function (name) { - self.support_branding_company_name = name; + + self._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_company_url"], + }).then(function (url) { + self.support_cp_url = url; }); - return this._super(this, arguments); + + self._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_email"], + }).then(function (email) { + self.support_cp_email = email; + }); + + self._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_release"], + }).then(function (release) { + self.support_cp_release = release; + }); + + self._rpc({ + model: "ir.config_parameter", + method: "get_param", + args: ["support_branding_color"], + }).then(function (color) { + self.support_cp_color = color; + }); + }); }, show_error: function (error) { var self = this; - error._session = session; - this._super.apply(this, arguments); - jQuery(".support-branding-submit-form").each(function () { - var $form = jQuery(this), - $button = $form.find("button"), - $description = $form.find('textarea[name="description"]'), - $subject = $form.find('input[name="subject"]'), - $body = $form.find('input[name="body"]'); - if (self.support_branding_support_email) { - $form.attr( - "action", - "mailto:" + self.support_branding_support_email - ); + var dialog = this._super.apply(this, arguments); + var subject = + session.username + + "@" + + session.db + + "[" + + session.server + + "]:" + + error.message; + var body = error.data.debug; + var inputs = + "" + + '"; + dialog.opened(function () { + var $form = $(".support-branding-submit-form"); + var $statement = $(".support-statement"); + var $description = $(".support-desc"); + var $button = $(".support-btn"); + var $body = $(".sp-body"); + var $header = $form.parents(".modal-dialog").find(".modal-header"); + var $footer = $form.parents(".modal-dialog").find(".modal-footer"); + + $statement.prepend(inputs); + if (self.support_cp_email) { + if (self.support_cp_name) { + var title = "Support By " + self.support_cp_name; + $('

    ' + title + "

    ").insertBefore( + ".support-branding-submit-form" + ); + $button.text( + _.str.sprintf(_t("Email to %s"), self.support_cp_name) + ); + } + $form.attr("action", "mailto:" + self.support_cp_email); $form .parents(".modal") .find(".modal-body") .css("max-height", "70vh"); - $button.click(function (ev) { - var mail_mail = new Model("mail.mail"); + $button.on("click", function (ev) { + var $btn = $(this); if (!$description.val()) { $description.parent().addClass("oe_form_invalid"); ev.preventDefault(); return; } - mail_mail - .call("create", [ - { - state: "outgoing", - auto_delete: true, - email_to: self.support_branding_support_email, - subject: $subject.val(), - body_html: jQuery("
    ") - .append( - jQuery("
    ").text($description.val()), - jQuery("
    ").text($body.val())
    -                                        )
    -                                        .html(),
    -                                },
    -                            ])
    -                            .then(
    -                                function (mail_id) {
    -                                    return mail_mail.call("send", [[mail_id]]);
    -                                },
    -                                function () {
    -                                    // If the call failed, fire the mailto link
    -                                    // hoping there is a properly configured email
    -                                    // client
    -                                    $body.val($description.val() + "\n" + $body.val());
    -                                    $button.unbind("click");
    -                                    $button.click();
    -                                }
    -                            )
    -                            .then(function () {
    -                                $form.parents(".modal").modal("hide");
    -                            });
                             ev.preventDefault();
    +                        var desc = $description.val();
    +                        var params = {
    +                            state: "outgoing",
    +                            auto_delete: true,
    +                            email_to: self.support_cp_email,
    +                            subject: subject,
    +                            body_html: jQuery("
    ") + .append( + jQuery("
    ").text(desc), + jQuery("
    ").text(body)
    +                                )
    +                                .html(),
    +                        };
    +                        self._rpc({
    +                            model: "mail.mail",
    +                            method: "create",
    +                            args: [params],
    +                        }).then(
    +                            function (mail_id) {
    +                                if (mail_id) {
    +                                    self._rpc({
    +                                        model: "mail.mail",
    +                                        method: "send",
    +                                        args: [mail_id],
    +                                    }).then(function (res) {
    +                                        if (res) {
    +                                            self.do_notify(
    +                                                "Success",
    +                                                "Support mail created!"
    +                                            );
    +                                        }
    +                                    });
    +                                }
    +                            },
    +                            function () {
    +                                $body.val(desc + "\n" + $body.val());
    +                                $btn.unbind("click");
    +                                $btn.click();
    +                            }
    +                        );
                         });
                     } else {
    -                    $description.hide();
    -                    $button.hide();
    +                    $description.css({display: "none"});
    +                    $button.css({display: "none"});
                     }
    -                if (self.support_branding_company_name) {
    -                    $button.text(
    -                        _.str.sprintf(
    -                            _t("Email to %s"),
    -                            self.support_branding_company_name
    -                        )
    -                    );
    +                $form.prependTo($footer);
    +                if (self.support_cp_color) {
    +                    $header.css({background: self.support_cp_color});
    +                    $footer.css({background: self.support_cp_color});
    +                } else {
    +                    $header.css({background: ""});
    +                    $footer.css({background: ""});
                     }
    -                $form.prependTo($form.parents(".modal-dialog").find(".modal-footer"));
                 });
             },
         });
    -    // This is already instantiated, so we need to call init manually
    -    require("web.crash_manager").init();
     });
    diff --git a/support_branding/static/src/js/user_menu.js b/support_branding/static/src/js/user_menu.js
    new file mode 100644
    index 000000000..f0c76ba45
    --- /dev/null
    +++ b/support_branding/static/src/js/user_menu.js
    @@ -0,0 +1,27 @@
    +odoo.define("support_branding.UserMenu", function (require) {
    +    "use strict";
    +
    +    var user_menu = require("web.UserMenu");
    +
    +    user_menu.include({
    +        _onMenuSupport: function () {
    +            var url = this.support_url || "https://www.odoo.com/buy";
    +            window.open(url, "_blank");
    +        },
    +        willStart: function () {
    +            var self = this;
    +            var def = self
    +                ._rpc({
    +                    model: "ir.config_parameter",
    +                    method: "get_param",
    +                    args: ["support_company_url"],
    +                })
    +                .then(function (site) {
    +                    if (site && site !== "") {
    +                        self.support_url = site;
    +                    }
    +                });
    +            return $.when(this._super.apply(this, arguments), def);
    +        },
    +    });
    +});
    diff --git a/support_branding/static/src/xml/base.xml b/support_branding/static/src/xml/base.xml
    index bdc0f6528..416f3afc9 100644
    --- a/support_branding/static/src/xml/base.xml
    +++ b/support_branding/static/src/xml/base.xml
    @@ -1,36 +1,64 @@
     
     
         
    -        
    -            
    + +
    - - -
    +