mirror of https://github.com/OCA/web.git
[MIG] web_widget_color: Migration to 13.0
parent
e3e6bcd570
commit
4d48b3fb8c
|
@ -8,7 +8,7 @@
|
||||||
"version": "13.0.1.0.0",
|
"version": "13.0.1.0.0",
|
||||||
"author": "Alexandre Díaz, " "Odoo Community Association (OCA)",
|
"author": "Alexandre Díaz, " "Odoo Community Association (OCA)",
|
||||||
"website": "https://github.com/OCA/web",
|
"website": "https://github.com/OCA/web",
|
||||||
"depends": ["web", "base_sparse_field", "web_widget_color"],
|
"depends": ["web", "base_sparse_field"],
|
||||||
"data": ["view/assets.xml", "view/res_company.xml"],
|
"data": ["view/assets.xml", "view/res_company.xml"],
|
||||||
"uninstall_hook": "uninstall_hook",
|
"uninstall_hook": "uninstall_hook",
|
||||||
"post_init_hook": "post_init_hook",
|
"post_init_hook": "post_init_hook",
|
||||||
|
|
|
@ -7,7 +7,7 @@ from .models.res_company import URL_BASE
|
||||||
|
|
||||||
def uninstall_hook(cr, registry):
|
def uninstall_hook(cr, registry):
|
||||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||||
env["ir.attachment"].search([("url", "like", "%s%%" % URL_BASE)]).unlink()
|
env["ir.attachment"].search([("url", "=like", "%s%%" % URL_BASE)]).unlink()
|
||||||
|
|
||||||
|
|
||||||
def post_init_hook(cr, registry):
|
def post_init_hook(cr, registry):
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from . import assetsbundle
|
||||||
from . import res_company
|
from . import res_company
|
||||||
|
from . import ir_qweb
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Copyright 2020 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
from odoo.addons.base.models.assetsbundle import AssetsBundle, ScssStylesheetAsset
|
||||||
|
|
||||||
|
|
||||||
|
class AssetsBundleCompanyColor(AssetsBundle):
|
||||||
|
def get_company_color_asset_node(self):
|
||||||
|
""" Process the user active company scss and returns the node to inject """
|
||||||
|
company_id = self.env["res.company"].browse(
|
||||||
|
self.env.context.get("active_company_id", 0)
|
||||||
|
)
|
||||||
|
asset = ScssStylesheetAsset(self, url=company_id.scss_get_url())
|
||||||
|
compiled = self.compile_css(asset.compile, asset.get_source())
|
||||||
|
return ("style", {}, compiled)
|
|
@ -0,0 +1,86 @@
|
||||||
|
# Copyright 2020 Alexandre Díaz <dev@redneboa.es>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
from inspect import unwrap
|
||||||
|
|
||||||
|
from odoo import api, models, tools
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
from odoo.addons.base.models.ir_qweb import IrQWeb
|
||||||
|
|
||||||
|
from .assetsbundle import AssetsBundleCompanyColor
|
||||||
|
|
||||||
|
# Monkey Patch to change the ormcache_context decorator of '_get_asset_nodes' to
|
||||||
|
# add 'active_company_id' context key. This is done to avoid "clear_caches" usage
|
||||||
|
# that works in a more aggressive way to the LRU cache.
|
||||||
|
|
||||||
|
_orig_get_asset_nodes = unwrap(IrQWeb._get_asset_nodes)
|
||||||
|
|
||||||
|
|
||||||
|
@tools.conditional(
|
||||||
|
"xml" not in tools.config["dev_mode"],
|
||||||
|
tools.ormcache_context(
|
||||||
|
"xmlid",
|
||||||
|
'options.get("lang", "en_US")',
|
||||||
|
"css",
|
||||||
|
"js",
|
||||||
|
"debug",
|
||||||
|
"async_load",
|
||||||
|
"defer_load",
|
||||||
|
"lazy_load",
|
||||||
|
keys=("website_id", "active_company_id"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def _get_asset_nodes__mp(
|
||||||
|
self,
|
||||||
|
xmlid,
|
||||||
|
options,
|
||||||
|
css=True,
|
||||||
|
js=True,
|
||||||
|
debug=False,
|
||||||
|
async_load=False,
|
||||||
|
defer_load=False,
|
||||||
|
lazy_load=False,
|
||||||
|
values=None,
|
||||||
|
):
|
||||||
|
return _orig_get_asset_nodes(
|
||||||
|
self,
|
||||||
|
xmlid,
|
||||||
|
options,
|
||||||
|
css=css,
|
||||||
|
js=js,
|
||||||
|
debug=debug,
|
||||||
|
async_load=async_load,
|
||||||
|
defer_load=defer_load,
|
||||||
|
lazy_load=lazy_load,
|
||||||
|
values=values,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
IrQWeb._get_asset_nodes = _get_asset_nodes__mp
|
||||||
|
|
||||||
|
|
||||||
|
class QWeb(models.AbstractModel):
|
||||||
|
_inherit = "ir.qweb"
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def render(self, id_or_xml_id, values=None, **options):
|
||||||
|
""" Adds the active company to the context """
|
||||||
|
try:
|
||||||
|
active_company_id = int(
|
||||||
|
request.httprequest.cookies.get("cids", "").split(",")[0]
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
active_company_id = False
|
||||||
|
company_id = (
|
||||||
|
self.env["res.company"].browse(active_company_id)
|
||||||
|
or self.env.user.company_id
|
||||||
|
)
|
||||||
|
self = self.with_context(active_company_id=company_id.id)
|
||||||
|
return super().render(id_or_xml_id, values=values, **options)
|
||||||
|
|
||||||
|
def _get_asset_content(self, xmlid, options):
|
||||||
|
""" Handle 'special' web_company_color xmlid """
|
||||||
|
if xmlid == "web_company_color.company_color_assets":
|
||||||
|
asset = AssetsBundleCompanyColor(xmlid, [], env=self.env)
|
||||||
|
return ([], [asset.get_company_color_asset_node()])
|
||||||
|
return super()._get_asset_content(xmlid, options)
|
|
@ -1,7 +1,6 @@
|
||||||
# Copyright 2019 Alexandre Díaz <dev@redneboa.es>
|
# Copyright 2019 Alexandre Díaz <dev@redneboa.es>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
import base64
|
import base64
|
||||||
import time
|
|
||||||
from colorsys import hls_to_rgb, rgb_to_hls
|
from colorsys import hls_to_rgb, rgb_to_hls
|
||||||
|
|
||||||
from odoo import api, fields, models
|
from odoo import api, fields, models
|
||||||
|
@ -9,7 +8,7 @@ from odoo import api, fields, models
|
||||||
from ..utils import convert_to_image, image_to_rgb, n_rgb_to_hex
|
from ..utils import convert_to_image, image_to_rgb, n_rgb_to_hex
|
||||||
|
|
||||||
URL_BASE = "/web_company_color/static/src/scss/"
|
URL_BASE = "/web_company_color/static/src/scss/"
|
||||||
URL_SCSS_GEN_TEMPLATE = URL_BASE + "custom_colors.%d.%s.gen.scss"
|
URL_SCSS_GEN_TEMPLATE = URL_BASE + "custom_colors.%d.gen.scss"
|
||||||
|
|
||||||
|
|
||||||
class ResCompany(models.Model):
|
class ResCompany(models.Model):
|
||||||
|
@ -53,7 +52,6 @@ class ResCompany(models.Model):
|
||||||
"Navbar Background Color Hover", sparse="company_colors"
|
"Navbar Background Color Hover", sparse="company_colors"
|
||||||
)
|
)
|
||||||
color_navbar_text = fields.Char("Navbar Text Color", sparse="company_colors")
|
color_navbar_text = fields.Char("Navbar Text Color", sparse="company_colors")
|
||||||
scss_modif_timestamp = fields.Char("SCSS Modif. Timestamp")
|
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
|
@ -61,17 +59,14 @@ class ResCompany(models.Model):
|
||||||
records.scss_create_or_update_attachment()
|
records.scss_create_or_update_attachment()
|
||||||
return records
|
return records
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
result = super().unlink()
|
|
||||||
IrAttachmentObj = self.env["ir.attachment"]
|
IrAttachmentObj = self.env["ir.attachment"]
|
||||||
for record in self:
|
for record in self:
|
||||||
IrAttachmentObj.sudo().search(
|
IrAttachmentObj.sudo().search(
|
||||||
[("url", "like", "%s%%" % record._scss_get_url_simplified())]
|
[("url", "=", record.scss_get_url()), ("company_id", "=", record.id)]
|
||||||
).sudo().unlink()
|
).sudo().unlink()
|
||||||
return result
|
return super().unlink()
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def write(self, values):
|
def write(self, values):
|
||||||
if not self.env.context.get("ignore_company_color", False):
|
if not self.env.context.get("ignore_company_color", False):
|
||||||
fields_to_check = (
|
fields_to_check = (
|
||||||
|
@ -107,7 +102,6 @@ class ResCompany(models.Model):
|
||||||
result = super().write(values)
|
result = super().write(values)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def _scss_get_sanitized_values(self):
|
def _scss_get_sanitized_values(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
# Clone company_color as dictionary to avoid ORM operations
|
# Clone company_color as dictionary to avoid ORM operations
|
||||||
|
@ -126,7 +120,6 @@ class ResCompany(models.Model):
|
||||||
)
|
)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def _scss_generate_content(self):
|
def _scss_generate_content(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
# ir.attachment need files with content to work
|
# ir.attachment need files with content to work
|
||||||
|
@ -134,41 +127,28 @@ class ResCompany(models.Model):
|
||||||
return "// No Web Company Color SCSS Content\n"
|
return "// No Web Company Color SCSS Content\n"
|
||||||
return self.SCSS_TEMPLATE % self._scss_get_sanitized_values()
|
return self.SCSS_TEMPLATE % self._scss_get_sanitized_values()
|
||||||
|
|
||||||
# URL to scss related with this company, without timestamp
|
def scss_get_url(self):
|
||||||
# /web_company_color/static/src/scss/custom_colors.<company_id>
|
|
||||||
def _scss_get_url_simplified(self):
|
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
NTEMPLATE = ".".join(URL_SCSS_GEN_TEMPLATE.split(".")[:2])
|
return URL_SCSS_GEN_TEMPLATE % self.id
|
||||||
return NTEMPLATE % self.id
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def scss_get_url(self, timestamp=None):
|
|
||||||
self.ensure_one()
|
|
||||||
return URL_SCSS_GEN_TEMPLATE % (self.id, timestamp or self.scss_modif_timestamp)
|
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def scss_create_or_update_attachment(self):
|
def scss_create_or_update_attachment(self):
|
||||||
IrAttachmentObj = self.env["ir.attachment"]
|
IrAttachmentObj = self.env["ir.attachment"]
|
||||||
# The time window is 1 second
|
|
||||||
# This mean that all modifications realized in that second will
|
|
||||||
# have the same timestamp
|
|
||||||
modif_timestamp = str(int(time.time()))
|
|
||||||
for record in self:
|
for record in self:
|
||||||
datas = base64.b64encode(record._scss_generate_content().encode("utf-8"))
|
datas = base64.b64encode(record._scss_generate_content().encode("utf-8"))
|
||||||
|
custom_url = record.scss_get_url()
|
||||||
custom_attachment = IrAttachmentObj.sudo().search(
|
custom_attachment = IrAttachmentObj.sudo().search(
|
||||||
[("url", "like", "%s%%" % record._scss_get_url_simplified())]
|
[("url", "=", custom_url), ("company_id", "=", record.id)]
|
||||||
)
|
)
|
||||||
custom_url = record.scss_get_url(timestamp=modif_timestamp)
|
|
||||||
values = {
|
values = {
|
||||||
"datas": datas,
|
"datas": datas,
|
||||||
|
"db_datas": datas,
|
||||||
"url": custom_url,
|
"url": custom_url,
|
||||||
"name": custom_url,
|
"name": custom_url,
|
||||||
"datas_fname": custom_url.split("/")[-1],
|
"company_id": record.id,
|
||||||
}
|
}
|
||||||
if custom_attachment:
|
if custom_attachment:
|
||||||
custom_attachment.sudo().write(values)
|
custom_attachment.sudo().write(values)
|
||||||
else:
|
else:
|
||||||
values.update({"type": "binary", "mimetype": "text/scss"})
|
values.update({"type": "binary", "mimetype": "text/scss"})
|
||||||
IrAttachmentObj.sudo().create(values)
|
IrAttachmentObj.sudo().create(values)
|
||||||
self.write({"scss_modif_timestamp": modif_timestamp})
|
|
||||||
self.env["ir.qweb"].sudo().clear_caches()
|
self.env["ir.qweb"].sudo().clear_caches()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
* Jordi Ballester Alomar <jordi.ballester@eficent.com> (Eficent)
|
* Jordi Ballester Alomar <jordi.ballester@forgeflow.com> (ForgeFlow)
|
||||||
* Lois Rilo <lois.rilo@eficent.com> (Eficent)
|
* Lois Rilo <lois.rilo@forgefloww.com> (ForgeFlow)
|
||||||
* Simone Orsi <simone.orsi@camptocamp.com>
|
* Simone Orsi <simone.orsi@camptocamp.com>
|
||||||
* Jairo Llopis <jairo.llopis@tecnativa.com>
|
* Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||||
|
|
|
@ -4,22 +4,16 @@
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
-->
|
-->
|
||||||
<odoo>
|
<odoo>
|
||||||
|
<!-- Workarround to use custom assets bundle
|
||||||
|
This specific 't-call-assets' xmlid will be handled in a 'special' way
|
||||||
|
-->
|
||||||
<template
|
<template
|
||||||
id="assets_backend"
|
id="webclient_bootstrap"
|
||||||
name="web_company_color assets"
|
name="web_company_color assets"
|
||||||
inherit_id="web.assets_backend"
|
inherit_id="web.webclient_bootstrap"
|
||||||
>
|
>
|
||||||
<xpath expr=".">
|
<xpath expr="//t[@t-set='head_web']">
|
||||||
<t
|
<t t-call-assets="web_company_color.company_color_assets" />
|
||||||
t-set="company_id"
|
|
||||||
t-value="request.env.user and request.env.user.company_id"
|
|
||||||
/>
|
|
||||||
<link
|
|
||||||
t-if="company_id"
|
|
||||||
rel="stylesheet"
|
|
||||||
type="text/scss"
|
|
||||||
t-att-href="company_id.scss_get_url()"
|
|
||||||
/>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
Loading…
Reference in New Issue