[IMP] base: allow to add country flags on module kanban
The icons made for localization require tedious manual work where it could be done easily with some css. task-3166075 Part-of: odoo/odoo#108617
This commit is contained in:
@@ -2,11 +2,7 @@ from importlib import import_module
|
||||
from inspect import getmembers, ismodule, isclass, isfunction
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
def get_flag(country_code):
|
||||
# get the sequence of 2 regional indicator emoji forming the flag linked to the country code
|
||||
return "".join(chr(int(f"1f1{ord(c)+165:02x}", base=16)) for c in country_code)
|
||||
from odoo.tools import get_flag
|
||||
|
||||
|
||||
def templ(env, code, name=None, country='', **kwargs):
|
||||
|
||||
@@ -30,7 +30,7 @@ from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
|
||||
from odoo.exceptions import AccessDenied, UserError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools.parse_version import parse_version
|
||||
from odoo.tools.misc import topological_sort
|
||||
from odoo.tools.misc import topological_sort, get_flag
|
||||
from odoo.tools.translate import TranslationImporter
|
||||
from odoo.http import request
|
||||
from odoo.modules import get_module_path, get_module_resource
|
||||
@@ -239,6 +239,9 @@ class Module(models.Model):
|
||||
if path:
|
||||
with tools.file_open(path, 'rb') as image_file:
|
||||
module.icon_image = base64.b64encode(image_file.read())
|
||||
countries = self.get_module_info(module.name).get('countries', [])
|
||||
country_code = len(countries) == 1 and countries[0]
|
||||
module.icon_flag = get_flag(country_code.upper()) if country_code else ''
|
||||
|
||||
name = fields.Char('Technical Name', readonly=True, required=True)
|
||||
category_id = fields.Many2one('ir.module.category', string='Category', readonly=True, index=True)
|
||||
@@ -289,6 +292,7 @@ class Module(models.Model):
|
||||
application = fields.Boolean('Application', readonly=True)
|
||||
icon = fields.Char('Icon URL')
|
||||
icon_image = fields.Binary(string='Icon', compute='_get_icon_image')
|
||||
icon_flag = fields.Char(string='Flag', compute='_get_icon_image')
|
||||
to_buy = fields.Boolean('Odoo Enterprise Module', default=False)
|
||||
has_iap = fields.Boolean(compute='_compute_has_iap')
|
||||
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
float: left;
|
||||
}
|
||||
|
||||
.oe_module_flag {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: calc(50% - 35px);
|
||||
font: 27px icon;
|
||||
text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.oe_module_desc {
|
||||
font-size: 13px;
|
||||
padding-left: 10px;
|
||||
|
||||
@@ -41,6 +41,7 @@ class TestModuleManifest(BaseCase):
|
||||
'auto_install': False,
|
||||
'bootstrap': False,
|
||||
'category': 'Uncategorized',
|
||||
'countries': [],
|
||||
'data': [],
|
||||
'demo': [],
|
||||
'demo_xml': [],
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<kanban create="false" class="o_modules_kanban">
|
||||
<field name="icon"/>
|
||||
<field name="icon_flag"/>
|
||||
<field name="to_buy"/>
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
@@ -171,7 +172,10 @@
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_module_vignette">
|
||||
<t t-set="installed" t-value="record.state.raw_value == 'installed'"/>
|
||||
<img t-attf-src="#{record.icon.value}" class="oe_module_icon" alt="Icon"/>
|
||||
<div class="oe_module_icon">
|
||||
<img t-attf-src="#{record.icon.value}" class="w-100" alt="Icon"/>
|
||||
<span t-if="record.icon_flag" class="oe_module_flag"><t t-out="record.icon_flag.raw_value"/></span>
|
||||
</div>
|
||||
<div class="oe_module_desc" t-att-title="record.shortdesc.value">
|
||||
<h4 class="o_kanban_record_title">
|
||||
<field name="shortdesc"/>&nbsp;
|
||||
|
||||
@@ -53,6 +53,11 @@ class ManifestLinter(BaseCase):
|
||||
# todo installable ?
|
||||
]
|
||||
|
||||
if 'countries' in manifest_data and 'l10n' not in module:
|
||||
_logger.warning(
|
||||
"Module %s specific to certain countries %s should contain `l10n` in their name.",
|
||||
module, manifest_data['countries'])
|
||||
|
||||
for key in manifest_data:
|
||||
value = manifest_data[key]
|
||||
if key in _DEFAULT_MANIFEST:
|
||||
@@ -75,6 +80,9 @@ class ManifestLinter(BaseCase):
|
||||
_logger.warning(
|
||||
"Wrong type for manifest value %s in module %s, expected bool or list",
|
||||
key, module)
|
||||
else:
|
||||
if key == 'countries':
|
||||
self._test_manifest_countries_value(module, value)
|
||||
elif key == 'icon':
|
||||
self._test_manifest_icon_value(module, value)
|
||||
|
||||
@@ -103,3 +111,11 @@ class ManifestLinter(BaseCase):
|
||||
"Icon value specified in manifest of module %s wasn't found in given path."
|
||||
" Please specify a correct value or remove this key from the manifest.",
|
||||
module)
|
||||
|
||||
def _test_manifest_countries_value(self, module, values):
|
||||
for value in values:
|
||||
if value and len(value) != 2:
|
||||
_logger.warning(
|
||||
"Country value %s specified for the icon in manifest of module %s doesn't look like a country code"
|
||||
"Please specify a correct value or remove this key from the manifest.",
|
||||
value, module)
|
||||
|
||||
@@ -30,6 +30,7 @@ _DEFAULT_MANIFEST = {
|
||||
'author': 'Odoo S.A.',
|
||||
'auto_install': False,
|
||||
'category': 'Uncategorized',
|
||||
'countries': [],
|
||||
'data': [],
|
||||
'demo': [],
|
||||
'demo_xml': [],
|
||||
|
||||
@@ -1729,3 +1729,10 @@ def has_list_types(values, types):
|
||||
isinstance(values, (list, tuple)) and len(values) == len(types)
|
||||
and all(isinstance(item, type_) for item, type_ in zip(values, types))
|
||||
)
|
||||
|
||||
def get_flag(country_code: str) -> str:
|
||||
"""Get the emoji representing the flag linked to the country code.
|
||||
|
||||
This emoji is composed of the two regional indicator emoji of the country code.
|
||||
"""
|
||||
return "".join(chr(int(f"1f1{ord(c)+165:02x}", base=16)) for c in country_code)
|
||||
|
||||
Reference in New Issue
Block a user