diff --git a/backend_theme_infinito_plus/README.rst b/backend_theme_infinito_plus/README.rst new file mode 100644 index 000000000..199f62dfa --- /dev/null +++ b/backend_theme_infinito_plus/README.rst @@ -0,0 +1,47 @@ +.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 + +Infinito Plus Backend Theme +=========================== +* Infinito Plus Backend Theme module for Odoo 16 community editions + +Installation +============ +- www.odoo.com/documentation/16.0/setup/install.html +- Install our custom addon + +License +------- +General Public License, Version 3 (LGPL v3). +(https://www.odoo.com/documentation/user/16.0/legal/licenses/licenses.html) + +Company +------- +* 'Cybrosys Techno Solutions '__ + +Credits +------- +* 'Cybrosys Techno Solutions '__ + Author : Farseen, Musthafa @Cybrosys + Author : Sigha CK @Cybrosys + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com + +Further information +=================== +HTML Description: ``__ diff --git a/backend_theme_infinito_plus/__init__.py b/backend_theme_infinito_plus/__init__.py new file mode 100644 index 000000000..330eb9550 --- /dev/null +++ b/backend_theme_infinito_plus/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import controllers +from . import models diff --git a/backend_theme_infinito_plus/__manifest__.py b/backend_theme_infinito_plus/__manifest__.py new file mode 100644 index 000000000..a87920d0e --- /dev/null +++ b/backend_theme_infinito_plus/__manifest__.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +{ + 'name': "Infinito Plus Backend Theme", + 'description': """Utmost and dynamic backend theme for Odoo 16""", + 'summary': """The Backend Theme Infinito Is A Dynamic And Ultimate Theme + For Your Odoo V16. This Theme Will Give You A New Experience + With Odoo.Main Highlight Of The Theme Is You Can Dynamically + Change The Fonts,Animations, Languages,Chatbox Layouts...Etc""", + 'category': "Themes/Backend", + 'version': "16.0.1.0.0", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['backend_theme_infinito', 'web'], + "data": [ + 'security/ir.model.access.csv' + ], + 'assets': { + 'web.assets_backend': { + '/backend_theme_infinito_plus/static/src/xml/theme_editor.xml', + '/backend_theme_infinito_plus/static/src/xml/ListViewRefresh.xml', + '/backend_theme_infinito_plus/static/src/xml/systray.xml', + '/backend_theme_infinito_plus/static/src/xml/AddGoogleFonts.xml', + '/backend_theme_infinito_plus/static/src/xml/font.xml', + '/backend_theme_infinito_plus/static/src/css/font.css', + '/backend_theme_infinito_plus/static/src/css/chatter.css', + '/backend_theme_infinito_plus/static/src/scss/animation.scss', + '/backend_theme_infinito_plus/static/src/js/navbar.js', + '/backend_theme_infinito_plus/static/src/js/AdvancedFeatures.js', + '/backend_theme_infinito_plus/static/src/js/systray.js', + '/backend_theme_infinito_plus/static/src/js/ThemeStudioMenu.js', + }, + }, + 'images': [ + 'static/description/banner.png', + 'static/description/theme_screenshot.png', + ], + 'license': 'LGPL-3', + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/backend_theme_infinito_plus/controllers/__init__.py b/backend_theme_infinito_plus/controllers/__init__.py new file mode 100644 index 000000000..79cc24ed8 --- /dev/null +++ b/backend_theme_infinito_plus/controllers/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import main diff --git a/backend_theme_infinito_plus/controllers/main.py b/backend_theme_infinito_plus/controllers/main.py new file mode 100644 index 000000000..f46776613 --- /dev/null +++ b/backend_theme_infinito_plus/controllers/main.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +import json +import os + +from odoo.addons.backend_theme_infinito.controllers.main import ThemeStudio +from odoo.addons.backend_theme_infinito.controllers.main import minify_css + +from odoo import http +from odoo.http import request + + +class ThemeStudioPlus(ThemeStudio): + """ Class for adding new features""" + + @http.route(['/theme_studio/save_styles_plus'], type="json") + def save_styles_plus(self, new_style): + """Create Dynamic Styles css file for chat box layout""" + changed_styles = json.loads(new_style) + working_dir = os.path.dirname(os.path.realpath(__file__)) + working_dir = working_dir.replace('/controllers', '') + file_path = working_dir + '/static/src/css/chatter.css' + style_file = open(file_path, 'a') + style_file.truncate(0) + if os.stat(file_path).st_size == 0: + style_file.write('/* This file is generated automatically by ' + 'Theme Infinito Plus */\n') + style_file.write('.o_ChatWindow' + ' {\n') + for i in changed_styles[0]: + style_file.write('\t' + i + ':' + changed_styles[0][i] + ';\n') + style_file.write('}\n') + style_file.close() + minify_css(file_path) + return True + + @http.route(['/theme_studio/animation_styles'], type="json") + def animation_styles(self, style): + """create the Dynamic css file for animation""" + animated = json.loads(style) + saved_style = animated[0] + working_dir = os.path.dirname(os.path.realpath(__file__)) + file_path = working_dir.replace('/controllers', + '/static/src/scss/animation.scss') + read_file = open(file_path, 'r') + css = read_file.read() + write_file = open(file_path, 'w') + for line in css.split('\n'): + if 'ease-in' in line: + write_file.write(css.replace(line.strip(), + 'animation:' + saved_style + '#{' + '$tr * .1}s ease-in !important;')) + write_file.close() + read_file.close() + + @http.route(['/theme_studio/set_advanced_data_plus'], type="json") + def set_advanced_data_plus(self, vals): + """save the features from theme studio""" + set_param = request.env['ir.config_parameter'].sudo().set_param + set_param('backend_theme_infinito_plus.is_refresh', + vals['infinitoRefresh']) + set_param('backend_theme_infinito_plus.chatbox_position', + vals['chatBoxPosition']) + set_param('backend_theme_infinito_plus.chatbox_position', + vals['chatBoxPosition']) + vals.get('chatBoxPosition') + vals.get('infinitoAnimation') + font = vals.get('infinitoGoogleFont') + font_obj = request.env['infinito.google.font'] + if font == 0: + font_obj.remove_fonts() + elif font: + font_obj.browse(font).set_css() + + @http.route(['/theme_studio/set_advanced_data_user_plus'], type="json") + def set_advanced_data_user_plus(self, vals): + """Update the 'is_refresh' field of the current user""" + request.env.user.write({ + 'is_refresh': vals['infinitoRefresh'], + }) + return True + + @http.route(['/theme_studio_plus/reset_to_default_style'], type="json") + def reset_to_default_style(self): + """rest to default styles""" + working_dir = os.path.dirname(os.path.realpath(__file__)) + style_file_path = working_dir.replace('controllers', + 'static/src/css/font.css') + animation_file_path = working_dir.replace('controllers', + 'static/src/scss/animation.scss') + chat_file_path = working_dir.replace('controllers', + 'static/src/css/chatter.css') + style_file = open(style_file_path, 'w') + style_file.write('') + animation_file = open(animation_file_path, 'w') + animation_file.write('') + chat_file = open(chat_file_path, 'w') + chat_file.write('') + return True diff --git a/backend_theme_infinito_plus/doc/RELEASE_NOTES.md b/backend_theme_infinito_plus/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..577e9e7ee --- /dev/null +++ b/backend_theme_infinito_plus/doc/RELEASE_NOTES.md @@ -0,0 +1,6 @@ +## Module + +#### 05.05.2023 +#### Version 16.0.1.0.0 +#### ADD +- Initial Commit for Infinito Plus Backend Theme diff --git a/backend_theme_infinito_plus/models/__init__.py b/backend_theme_infinito_plus/models/__init__.py new file mode 100644 index 000000000..559d34ca9 --- /dev/null +++ b/backend_theme_infinito_plus/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from . import add_google_fonts +from . import ir_http +from . import res_config_settings +from . import res_users diff --git a/backend_theme_infinito_plus/models/add_google_fonts.py b/backend_theme_infinito_plus/models/add_google_fonts.py new file mode 100644 index 000000000..f64ffbf60 --- /dev/null +++ b/backend_theme_infinito_plus/models/add_google_fonts.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +import os + +import requests + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class GoogleFont(models.Model): + """Used for adding google fonts""" + _name = 'infinito.google.font' + _description = 'Add Google Fonts' + + name = fields.Char(string='Font Name', help="Name of the font") + font_url = fields.Text(string='Font URL', help="Store the font URL") + font = fields.Text(string='Font', help="Font style") + + @api.model + def save_google_fonts(self, g_font): + """Function to store fonts in database""" + record = self.search([('font_url', '=', g_font[1])]) + if record: + # TODO: Raise warning + raise ValidationError(_('Font already existing')) + else: + font = self.get_css(g_font[0]) + rec = self.create({ + 'name': g_font[0], + 'font_url': g_font[1], + 'font': font + }) + rec.set_css() + + def get_css(self, name): + """get the css file of selected google font""" + headers_woff2 = { + 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ' + '(KHTML, like Gecko)' + 'Chrome/101.0.4951.41 Safari/537.36', + } + url = f'https://fonts.googleapis.com/css?family={name}&display=swap' + req = requests.get(url, timeout=5, headers=headers_woff2) + return req.content + + def set_css(self): + """open the file write the style in to the css file""" + working_dir = os.path.dirname(os.path.realpath(__file__)) + working_dir = working_dir.replace('/models', '/static/src/css/font.css') + # open the file in write mode + with open(working_dir, 'w') as file: + style = f""" + {self.font} + * {{ + font-family: '{self.name}' !important; + }} + .fa {{ + font: normal normal normal 14px/1 FontAwesome !important;}} + .oi {{ + font-family: 'odoo_ui_icons' !important;}} + """ + file.write(style) + + @staticmethod + def remove_fonts(): + """remove the style when changing the font""" + working_dir = os.path.dirname(os.path.realpath(__file__)) + working_dir = working_dir.replace('/models', '/static/src/css/font.css') + with open(working_dir, 'w') as file: + file.write('') diff --git a/backend_theme_infinito_plus/models/ir_http.py b/backend_theme_infinito_plus/models/ir_http.py new file mode 100644 index 000000000..3bb8d1fdd --- /dev/null +++ b/backend_theme_infinito_plus/models/ir_http.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import models + + +class IrHttp(models.AbstractModel): + """Class for session information""" + _inherit = 'ir.http' + + def session_info(self): + """pass the session information """ + res = super(IrHttp, self).session_info() + get_param = self.env['ir.config_parameter'].sudo().get_param + all_langs = self.env['res.lang'].get_installed() + res['currentLang'] = \ + list(filter(lambda x: x[0] == self.env.user.lang, all_langs))[0] + res['availableLanguages'] = all_langs + if self.env.user.has_group('base.group_user'): + user_edit = get_param( + 'backend_theme_infinito_plus.is_user_edit', default=False) + res['userEdit'] = user_edit + if user_edit: + res['infinitoRefresh'] = self.env.user.is_refresh + else: + res['infinitoRefresh'] = get_param( + 'backend_theme_infinito_plus.is_refresh', default=False) + res['chatBoxPosition'] = get_param( + 'backend_theme_infinito_plus.chatbox_position', + default=False) + res['infinitoAnimation'] = get_param( + 'backend_theme_infinito_plus.animation_plus', + default=False) + return res diff --git a/backend_theme_infinito_plus/models/res_config_settings.py b/backend_theme_infinito_plus/models/res_config_settings.py new file mode 100644 index 000000000..7b9b88849 --- /dev/null +++ b/backend_theme_infinito_plus/models/res_config_settings.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import api, fields, models + + +class ResConfigSettings(models.TransientModel): + """Class for adding new fields in configuration settings""" + _inherit = 'res.config.settings' + + is_refresh = fields.Boolean(string='Refresh', help='Tree,Kanban Refresh ' + 'mode Enabled', + default=False) + chatbox_position = fields.Char(string="ChatBox position", + help="different layouts for chatBox") + animation_plus = fields.Char(stirng="Animation", + help="Different Animations") + + @api.model + def get_values(self): + """Get the current values for the configuration settings""" + res = super(ResConfigSettings, self).get_values() + get_param = self.env['ir.config_parameter'].sudo().get_param + res['is_refresh'] = get_param('backend_theme_infinito_plus.is_refresh', + default=False) + res['chatbox_position'] = get_param('backend_theme_infinito_plus' + '.chatbox_position') + res['animation_plus'] = get_param('backend_theme_infinito_plus' + '.animation_plus') + return res + + @api.model + def set_values(self): + """Update the values of the configuration settings""" + set_param = self.env['ir.config_parameter'].sudo().set_param + set_param('backend_theme_infinito_plus.is_refresh', self.is_refresh) + set_param('backend_theme_infinito_plus.chatbox_position', + self.chatbox_position) + set_param('backend_theme_infinito_plus.animation_plus', + self.animation_plus) + super(ResConfigSettings, self).set_values() diff --git a/backend_theme_infinito_plus/models/res_users.py b/backend_theme_infinito_plus/models/res_users.py new file mode 100644 index 000000000..e345e3243 --- /dev/null +++ b/backend_theme_infinito_plus/models/res_users.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2023-TODAY Cybrosys Technologies() +# Author: Sigha CK (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# (LGPL v3) along with this program. +# If not, see . +# +############################################################################### +from odoo import fields, models + + +class User(models.Model): + """class for user specific datas""" + _inherit = 'res.users' + + is_refresh = fields.Boolean(string='Tree,Kanban Refresh mode Enabled', + help="Refreshing feature for specific users", + default=False) diff --git a/backend_theme_infinito_plus/security/ir.model.access.csv b/backend_theme_infinito_plus/security/ir.model.access.csv new file mode 100644 index 000000000..09b411e3a --- /dev/null +++ b/backend_theme_infinito_plus/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_infinito_google_font,access_infinito_google_font,model_infinito_google_font,base.group_user,1,1,1,1 diff --git a/backend_theme_infinito_plus/static/description/assets/banner.png b/backend_theme_infinito_plus/static/description/assets/banner.png new file mode 100644 index 000000000..c872ce289 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/banner.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/hero.png b/backend_theme_infinito_plus/static/description/assets/hero.png new file mode 100644 index 000000000..a65f511e5 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/hero.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/check.png b/backend_theme_infinito_plus/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/check.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/chevron.png b/backend_theme_infinito_plus/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/chevron.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/cogs.png b/backend_theme_infinito_plus/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/cogs.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/consultation.png b/backend_theme_infinito_plus/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/consultation.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/ecom-black.png b/backend_theme_infinito_plus/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/ecom-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/education-black.png b/backend_theme_infinito_plus/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/education-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/hotel-black.png b/backend_theme_infinito_plus/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/hotel-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/license.png b/backend_theme_infinito_plus/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/license.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/lifebuoy.png b/backend_theme_infinito_plus/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/lifebuoy.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/manufacturing-black.png b/backend_theme_infinito_plus/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/manufacturing-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/pos-black.png b/backend_theme_infinito_plus/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/pos-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/puzzle.png b/backend_theme_infinito_plus/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/puzzle.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/restaurant-black.png b/backend_theme_infinito_plus/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/restaurant-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/service-black.png b/backend_theme_infinito_plus/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/service-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/trading-black.png b/backend_theme_infinito_plus/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/trading-black.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/training.png b/backend_theme_infinito_plus/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/training.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/update.png b/backend_theme_infinito_plus/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/update.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/user.png b/backend_theme_infinito_plus/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/user.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/icons/wrench.png b/backend_theme_infinito_plus/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/icons/wrench.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/screenshots/chatbox_layout.png b/backend_theme_infinito_plus/static/description/assets/screenshots/chatbox_layout.png new file mode 100644 index 000000000..e6058191f Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/screenshots/chatbox_layout.png differ diff --git a/backend_theme_infinito_plus/static/description/assets/screenshots/gif/animation.gif b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/animation.gif new file mode 100644 index 000000000..439796908 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/animation.gif differ diff --git a/backend_theme_infinito_plus/static/description/assets/screenshots/gif/google_fonts.gif b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/google_fonts.gif new file mode 100644 index 000000000..a2a28148b Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/google_fonts.gif differ diff --git a/backend_theme_infinito_plus/static/description/assets/screenshots/gif/refresh_icon.gif b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/refresh_icon.gif new file mode 100644 index 000000000..be76468c5 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/refresh_icon.gif differ diff --git a/backend_theme_infinito_plus/static/description/assets/screenshots/gif/swtich_languages.gif b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/swtich_languages.gif new file mode 100644 index 000000000..bb8286056 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/assets/screenshots/gif/swtich_languages.gif differ diff --git a/backend_theme_infinito_plus/static/description/banner.png b/backend_theme_infinito_plus/static/description/banner.png new file mode 100644 index 000000000..c872ce289 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/banner.png differ diff --git a/backend_theme_infinito_plus/static/description/icon.png b/backend_theme_infinito_plus/static/description/icon.png new file mode 100644 index 000000000..ce81ff658 Binary files /dev/null and b/backend_theme_infinito_plus/static/description/icon.png differ diff --git a/backend_theme_infinito_plus/static/description/index.html b/backend_theme_infinito_plus/static/description/index.html new file mode 100644 index 000000000..d80509569 --- /dev/null +++ b/backend_theme_infinito_plus/static/description/index.html @@ -0,0 +1,512 @@ + +
+
+
+

+ INFINITO PLUSBackend Theme +

+

+ Utmost and dynamic backend theme for Odoo 16

+
+
+ +
+
+
+ + + +
+
+
+

+ The Backend Theme Infinito Is A Dynamic And Ultimate Theme For + Your Odoo V16. + This Theme Will Give You A New Experience + With Odoo. Main Highlight Of The Theme Is You Can Dynamically + Change The Fonts, animation, Chatbox Layout,...Etc. + Moreover It Act As A Studio Based Theme. It Also Provides + Language switching feature. + It Is A Perfect Choice For Your Odoo Backend And An Attractive + Theme For Your Odoo 16. +

+
+
+ +
+
+
+ + + +
+
+
+

+ Features

+
+
+ + +
+
+
+ +
+
+
+
+ New +
+

View Refresh

+
+
+
+
+
+
+ + + +
+
+
+

Infinito Animation

+
+ The significant and attractive feature of the Backend Theme + Infinito is its dynamic and powerful styling. + The user can select different animation. The new Backend + Theme Infinito V16 delivers you an entirely redesigned + Kanban view + and Kanban Group View. The animated view provides a + comfortable experience for the users. +
+
+
+
+ +

Dynamic Styles

+
+
+ +

Clean Layout

+
+
+
+
+
+ +
+
+
+ + + +
+
+

+ ChatBox Layout Customization

+
+ Backend Theme Infinito V16 ensures stunning themes for your Odoo + 16 platform. + The new chatbox layout with more customization options provides + a better experience. + The system encompasses the Left, Right, Top, Bottom positions, + user can select position from these positions. +
+
+
+ +

Bottom Left

+
+
+ +

Bottom Right

+
+
+ +

Top Right

+
+
+ +

Top Left

+
+
+
+
+ +
+
+
+ +
+
+
+

Google Font

+
+ User can customize fonts.This customization options provides a + better experience. +
+
+
+ +
+
+
+ + + +
+
+
+

Language Switching

+
+ You can switch languages easily. All added languages will be + visible on systray option from where you can select the + language. +
+
+
+ +
+
+
+ + + + +
+
+
+

+ Our Services

+
+
+
+ +
+
+ Odoo + Customization
+
+
+
+ +
+
+ Odoo + Implementation
+
+
+
+ +
+
+ Odoo + Support
+
+
+
+ +
+
+ Hire + Odoo + Developer
+
+
+
+ +
+
+ Odoo + Integration
+
+
+
+ +
+
+ Odoo + Migration
+
+
+
+ +
+
+ Odoo + Consultancy
+
+
+
+ +
+
+ Odoo + Implementation
+
+
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+
+ + + +
+
+
+

+ Our Industries

+
+
+
+ +
+ Trading +
+

+ Easily + procure + and + sell your products

+
+
+
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+
+
+ +
+ Education +
+

+ A + platform for + educational management

+
+
+
+
+ +
+ Manufacturing +
+

+ Plan, + track and + schedule your operations

+
+
+
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+
+
+ +
+ Service Management +
+

+ Keep + track of + services and invoice

+
+
+
+
+ +
+ Restaurant +
+

+ Run + your bar or + restaurant methodically

+
+
+
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+
+
+ + + + +
+
+
+

+ Need Help?

+
+
+ + + +
+ +
+
+ +
+ +
+ +
+
+ diff --git a/backend_theme_infinito_plus/static/description/theme_screenshot.png b/backend_theme_infinito_plus/static/description/theme_screenshot.png new file mode 100644 index 000000000..c768586be Binary files /dev/null and b/backend_theme_infinito_plus/static/description/theme_screenshot.png differ diff --git a/backend_theme_infinito_plus/static/src/css/chatter.css b/backend_theme_infinito_plus/static/src/css/chatter.css new file mode 100644 index 000000000..6a5da15ad --- /dev/null +++ b/backend_theme_infinito_plus/static/src/css/chatter.css @@ -0,0 +1,2 @@ +/* This Styles are generated automatically by Theme Studio */ + .o_ChatWindow {top:10px !important;left:10px !important;right:auto !important;} \ No newline at end of file diff --git a/backend_theme_infinito_plus/static/src/css/font.css b/backend_theme_infinito_plus/static/src/css/font.css new file mode 100644 index 000000000..81d9a5567 --- /dev/null +++ b/backend_theme_infinito_plus/static/src/css/font.css @@ -0,0 +1,55 @@ +/* This Styles are generated automatically by Theme Studio */ + /* cyrillic-ext */ +@font-face { + font-family: 'Rubik Iso'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/rubikiso/v2/x3dickHUfr-S4VAI4sAxdvoDjy8.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Rubik Iso'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/rubikiso/v2/x3dickHUfr-S4VAI4sAxf_oDjy8.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* hebrew */ +@font-face { + font-family: 'Rubik Iso'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/rubikiso/v2/x3dickHUfr-S4VAI4sAxefoDjy8.woff2) format('woff2'); + unicode-range: U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F; +} +/* latin-ext */ +@font-face { + font-family: 'Rubik Iso'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/rubikiso/v2/x3dickHUfr-S4VAI4sAxdfoDjy8.woff2) format('woff2'); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Rubik Iso'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/rubikiso/v2/x3dickHUfr-S4VAI4sAxe_oD.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + + * { + font-family: 'Rubik Iso' !important; + } + .fa { + font: normal normal normal 14px/1 FontAwesome !important;} + .oi { + font-family: 'odoo_ui_icons' !important;} + \ No newline at end of file diff --git a/backend_theme_infinito_plus/static/src/js/AdvancedFeatures.js b/backend_theme_infinito_plus/static/src/js/AdvancedFeatures.js new file mode 100644 index 000000000..4be976827 --- /dev/null +++ b/backend_theme_infinito_plus/static/src/js/AdvancedFeatures.js @@ -0,0 +1,204 @@ +odoo.define('backend_theme_infinito_plus.AdvancedFeatures', function(require) { + "use strict"; + const {mount} = owl; + var AdvancedFeatures = require('backend_theme_infinito.AdvancedFeatures'); + var ajax = require('web.ajax'); + var session = require('web.session'); + var Dialog = require('web.Dialog'); + var core = require('web.core'); + var _t = core._t; + var qweb = core.qweb; + var rpc = require('web.rpc'); + // includes newly added features + AdvancedFeatures.include({ + events: _.extend ({}, AdvancedFeatures.prototype.events, { + 'click #infinito_font_select': '_onAddGoogleFontClick', + 'change #infinito_font_select': 'onFontChange', + 'change #chatbox_position': 'onPositionChange', + 'change #animated_view': 'onAnimationChange', + }), + init: function(parent, type) { + this._super.apply(this, arguments); + this.chatBoxPosition = ['Top Right', 'Top Left', 'Bottom Right', 'Bottom Left'] + this.infinitoAnimation = ['Default', 'Scale', 'Slide in'] + }, + // function works when changing animations + onAnimationChange: function(ev) { + let options = ev.target.value + if (options == 'Scale') { + this.animated_id = 1 + } else if (options == 'Slide in') { + this.animated_id = -1 + } else { + this.animated_id = 0 + } + }, + // function works when changing fonts + onFontChange: function(ev) { + let options = ev.target.options + let selected = this.$(options[options.selectedIndex]) + if (selected.hasClass('add-font')) { + return + } else if (selected.hasClass('system-font')) { + this.font_id = 0 + } else { + this.font_id = parseInt(selected.data('id')) + } + }, + //render all the features while opening theme studio + async renderData() { + this.font_id = false + this.chat_style = [] + this._super.apply(this, arguments); + this.$el.find('#navbarRefreshToggler').attr('checked', session.infinitoRefresh); + rpc.query({ + model: "infinito.google.font", + method: 'search_read', + args: [], + }).then((data) => { + this.$el.find('.infinito_font_select').html(qweb.render('theme_editor_sidebar_advanced_fonts', { + data + })) + }); + let position_content = ''; + for (let position of this.chatBoxPosition) { //append different positions to the selection as option + position_content += ``; + } + this.$el.find('#chatbox_position').html(position_content); + this.$el.find('#chatbox_position').val(session.chatBoxPosition); + let animation_content = ''; + for (let animation of this.infinitoAnimation) { //append different animations to the selection as option + animation_content += ``; + } + this.$el.find('#animated_view').html(animation_content); + this.$el.find('#animated_view').val(session.infinitoAnimation); + }, + // save the changes + async _SaveChanges() { + this._super.apply(this, arguments); + let vals = { + 'infinitoRefresh': this.$el.find('#navbarRefreshToggler')[0].checked, + 'infinitoGoogleFont': this.font_id, + 'chatBoxPosition': this.$el.find('#chatbox_position').val(), + 'animations': this.animated_id, + 'infinitoAnimation': this.$el.find("#animated_view").val() + } + var chat_style = this.chat_style + session.infinitoRefresh = vals.infinitoRefresh; + session.chatBoxPosition = vals.chatBoxPosition; + session.infinitoAnimation = vals.infinitoAnimation; + // save animation from the selection + var style = []; + if (vals.animations == 1) { + style = []; + style.push('infinito_kanban_scale'); + } else if (vals.animations == 0) { + style = []; + style.push('infinito_kanban_shake'); + } else if (vals.animations == -1) { + style = []; + style.push('infinito_kanban_slide_in'); + } + if (style.length != 0) { + await ajax.jsonRpc('/theme_studio/animation_styles', 'call', { + 'style': JSON.stringify(style) + }); + } + if (chat_style.length != 0) { + await ajax.jsonRpc('/theme_studio/save_styles_plus', 'call', { + 'new_style': JSON.stringify(chat_style) + }); + } + if (this.type == 'global') { + await ajax.jsonRpc('/theme_studio/set_advanced_data_plus', 'call', { + vals + }).then((_) => { + this._Close(); + }) + } else { + await ajax.jsonRpc('/theme_studio/set_advanced_data_user_plus', 'call', { + vals + }).then((_) => { + this._Close(); + }) + } + }, + // on changing chatbox position + async onPositionChange(ev) { + let val = ev.target.value; + var new_style = []; + if (val == 'Top Right') { + new_style = []; + new_style.push({ + 'top': '10px', + 'left': 'auto' + }); + } + if (val == 'Top Left') { + new_style = []; + new_style.push({ + 'top': '10px', + 'left': '10px', + 'right': 'auto' + }); + } + if (val == 'Bottom Left') { + new_style = []; + new_style.push({ + 'left': '10px', + 'bottom': '10px', + 'top': 'auto', + 'right': 'auto' + }); + } + if (val == 'Bottom Right') { + new_style = []; + new_style.push({ + 'right': '10px', + 'bottom': '10px', + 'top': 'auto', + 'left': 'auto' + }); + } + this.chat_style = new_style + }, + // function works when clicking google font + _onAddGoogleFontClick: function(ev) { + var val = ev.target.value + if (val == "Add a Google Font") { + const dialog = new Dialog(this, { + title: _t("Add a Google Font"), + $content: $(core.qweb.render('backend_theme_infinito_plus.dialog.addGoogleFont')), + // open a wizard for selecting google font + buttons: [{ + text: _t("Save & Reload"), + classes: 'btn-primary', + click: async () => { + const inputEl = dialog.el.querySelector('.o_input_google_font'); + let m = inputEl.value.match(/\bfamily=([\w+]+)/); + // validation of link + if (m) { + const font = m[1].replace(/\+/g, ' '); + var self = this; + rpc.query({ + model: "infinito.google.font", + method: 'save_google_fonts', + args: [ + [font, m.input] + ], + }).then(function(data) {}); + window.location.reload(); + } + }, + }, + { + text: _t("Discard"), + close: true, + }, + ], + }); + dialog.open(); + } + } + }); +}); diff --git a/backend_theme_infinito_plus/static/src/js/ThemeStudioMenu.js b/backend_theme_infinito_plus/static/src/js/ThemeStudioMenu.js new file mode 100644 index 000000000..755849f7f --- /dev/null +++ b/backend_theme_infinito_plus/static/src/js/ThemeStudioMenu.js @@ -0,0 +1,13 @@ +odoo.define('backend_theme_infinito_plus.ThemeStudioMenu', function (require) { +"use strict"; + var core = require('web.core'); + var ThemeStudioMenu = require('backend_theme_infinito.ThemeStudioMenu'); + var ajax = require('web.ajax'); + ThemeStudioMenu.include({ + // reset all the features + _onResetClick: async function(ev){ + this._super.apply(this, arguments); + await ajax.jsonRpc('/theme_studio_plus/reset_to_default_style', 'call', {}); + }, + }) +}); diff --git a/backend_theme_infinito_plus/static/src/js/navbar.js b/backend_theme_infinito_plus/static/src/js/navbar.js new file mode 100644 index 000000000..ca1972f85 --- /dev/null +++ b/backend_theme_infinito_plus/static/src/js/navbar.js @@ -0,0 +1,16 @@ +/** @odoo-module **/ +import { NavBar } from "@web/webclient/navbar/navbar"; +import { WebClient } from "@web/webclient/webclient"; +import { ControlPanel } from "@web/search/control_panel/control_panel"; +import { patch } from "@web/core/utils/patch"; +import session from 'web.session'; +patch(ControlPanel.prototype, 'backend_theme_infinito_plus/static/src/js/navbar.ControlPanel.js', { +// works when clicking refresh icon + onRefresh(ev) { + this.env.searchModel._notify(); + }, + // check whether the refresh feature is enabled or disabled + get RefreshOn() { + return session.infinitoRefresh; + }, +}); diff --git a/backend_theme_infinito_plus/static/src/js/systray.js b/backend_theme_infinito_plus/static/src/js/systray.js new file mode 100644 index 000000000..c8f9fb6c9 --- /dev/null +++ b/backend_theme_infinito_plus/static/src/js/systray.js @@ -0,0 +1,27 @@ +/** @odoo-module **/ +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 { useService } from "@web/core/utils/hooks"; +import { Component } from "@odoo/owl"; +export class LanguageSwitch extends Component { + setup() { + this.currentLang = session.currentLang; + this.availableLanguages = session.availableLanguages; + this.orm = useService("orm"); + } + toggleLang(lang) { + this.orm.write('res.users', [session.uid], {lang}).then(async () => { + await this.env.bus.trigger("MENUS:APP-CHANGED"); + location.reload(); + }); + } +} +LanguageSwitch.template = "LanguageSwitch"; +LanguageSwitch.components = { Dropdown, DropdownItem }; +LanguageSwitch.toggleDelay = 1000; +export const systrayItem = { + Component: LanguageSwitch, +}; +registry.category("systray").add("LanguageSwitch", systrayItem, { sequence: 1 }); diff --git a/backend_theme_infinito_plus/static/src/scss/animation.scss b/backend_theme_infinito_plus/static/src/scss/animation.scss new file mode 100644 index 000000000..0fe7ff975 --- /dev/null +++ b/backend_theme_infinito_plus/static/src/scss/animation.scss @@ -0,0 +1,49 @@ +.o_kanban_view { + .oe_kanban_card, .o_kanban_record { + @for $tr from 1 through 80 { + &:nth-child(#{$tr}) { + animation:infinito_kanban_shake #{$tr * .1}s ease-in !important; + } + } + } +} + +@keyframes infinito_kanban_slide_in { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(0); } +} +@keyframes infinito_kanban_scale { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} +@keyframes infinito_kanban_shake { + 0% { + transform: rotate(-5deg); + opacity: 0; + } + + 20% { + transform: rotate(5deg); + } + + 40% { + transform: rotate(-3deg); + } + + 60% { + transform: rotate(3deg); + } + + 80% { + transform: rotate(-1deg); + } + + 90% { + transform: rotate(1deg); + } + + 100% { + transform: rotate(0deg); + opacity: 1; + } +} diff --git a/backend_theme_infinito_plus/static/src/xml/AddGoogleFonts.xml b/backend_theme_infinito_plus/static/src/xml/AddGoogleFonts.xml new file mode 100644 index 000000000..39aa45831 --- /dev/null +++ b/backend_theme_infinito_plus/static/src/xml/AddGoogleFonts.xml @@ -0,0 +1,20 @@ + + + +
+
+ +
+