diff --git a/addons/web/__manifest__.py b/addons/web/__manifest__.py
index f697e076..ba16382c 100644
--- a/addons/web/__manifest__.py
+++ b/addons/web/__manifest__.py
@@ -25,6 +25,8 @@ This module provides the core of the Odoo Web Client.
"static/src/xml/rainbow_man.xml",
"static/src/xml/report.xml",
"static/src/xml/web_calendar.xml",
+ "static/src/xml/backend_theme.xml",
+ "static/src/xml/backend_theme_customizer.xml",
],
'bootstrap': True, # load translations for login screen
}
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index 49b530dc..4c547f44 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -450,6 +450,9 @@ class Home(http.Controller):
request.uid = request.session.uid
try:
context = request.env['ir.http'].webclient_rendering_context()
+ res_company = request.env['res.company'].sudo().search(
+ [('id', '=', json.loads(context['session_info'])['company_id'])])
+ context.update({'company_name': res_company.name})
response = request.render('web.webclient_bootstrap', qcontext=context)
response.headers['X-Frame-Options'] = 'DENY'
return response
@@ -502,6 +505,49 @@ class Home(http.Controller):
response.headers['X-Frame-Options'] = 'DENY'
return response
+ def get_view_ids(self, xml_ids):
+ ids = []
+ for xml_id in xml_ids:
+ if "." in xml_id:
+ record_id = request.env.ref(xml_id).id
+ else:
+ record_id = int(xml_id)
+ ids.append(record_id)
+ return ids
+
+ @http.route(['/web/theme_customize_backend_get'], type='json', website=True, auth="public")
+ def theme_customize_backend_get(self, xml_ids):
+ enable = []
+ disable = []
+ ids = self.get_view_ids(xml_ids)
+ for view in request.env['ir.ui.view'].with_context(
+ active_test=True).browse(ids):
+ if view.active:
+ enable.append(view.xml_id)
+ else:
+ disable.append(view.xml_id)
+ return [enable, disable]
+
+ @http.route(['/web/theme_customize_backend'], type='json', website=True, auth="public")
+ def theme_customize_backend(self, enable, disable, get_bundle=False):
+ """ enable or Disable lists of ``xml_id`` of the inherit templates """
+
+ def set_active(ids, active):
+ if ids:
+ real_ids = self.get_view_ids(ids)
+ request.env['ir.ui.view'].with_context(
+ active_test=True).browse(real_ids).write(
+ {'active': active})
+
+ set_active(disable, False)
+ set_active(enable, True)
+
+ if get_bundle:
+ context = dict(request.context, active_test=True)
+ return request.env["ir.qweb"]._get_asset('web.assets_backend',
+ options=context)
+ return True
+
class WebClient(http.Controller):
diff --git a/addons/web/static/lib/jquery.nav-tabs-to-accordion/jquery.nav-tabs-to-accordion.js b/addons/web/static/lib/jquery.nav-tabs-to-accordion/jquery.nav-tabs-to-accordion.js
new file mode 100755
index 00000000..f2f0235b
--- /dev/null
+++ b/addons/web/static/lib/jquery.nav-tabs-to-accordion/jquery.nav-tabs-to-accordion.js
@@ -0,0 +1,238 @@
+!function ($) {
+ "use strict";
+
+ // TABCOLLAPSE CLASS DEFINITION
+ // Ref Link : https://gist.github.com/timramseyjr/b6a898ec03f217ebe09d897c185a0311
+ // ======================
+
+ var TabCollapse = function (el, options) {
+ this.options = options;
+ this.$tabs = $(el);
+
+ this._accordionVisible = false; //content is attached to tabs at first
+ this._initAccordion();
+ this._checkStateOnResize();
+
+
+ // checkState() has gone to setTimeout for making it possible to attach listeners to
+ // shown-accordion.bs.tabcollapse event on page load.
+ // See https://github.com/flatlogic/bootstrap-tabcollapse/issues/23
+ var that = this;
+ setTimeout(function () {
+ that.checkState();
+ }, 0);
+ };
+
+ TabCollapse.DEFAULTS = {
+ accordionClass: 'visible-xs',
+ tabsClass: 'hidden-xs',
+ accordionTemplate: function (heading, groupId, parentId, active) {
+ return '
' +
+ '
' +
+ '
' +
+ '
' +
+ ' ' +
+ '
' +
+ '
'
+
+ }
+ };
+
+ TabCollapse.prototype.checkState = function () {
+ if (this.$tabs.is(':visible') && this._accordionVisible) {
+ this.showTabs();
+ this._accordionVisible = false;
+ } else if (this.$accordion.is(':visible') && !this._accordionVisible) {
+ this.showAccordion();
+ this._accordionVisible = true;
+ }
+ };
+
+ TabCollapse.prototype.showTabs = function () {
+ var view = this;
+ this.$tabs.trigger($.Event('show-tabs.bs.tabcollapse'));
+
+ var $panelHeadings = this.$accordion.find('.js-tabcollapse-panel-heading').detach();
+
+ $panelHeadings.each(function () {
+ var $panelHeading = $(this),
+ $parentLi = $panelHeading.data('bs.tabcollapse.parentLi');
+
+ var $oldHeading = view._panelHeadingToTabHeading($panelHeading);
+
+ $parentLi.removeClass('active');
+ if ($parentLi.parent().hasClass('dropdown-menu') && !$parentLi.siblings('li').hasClass('active')) {
+ $parentLi.parent().parent().removeClass('active');
+ }
+
+ if (!$oldHeading.hasClass('collapsed')) {
+ $parentLi.addClass('active');
+ if ($parentLi.parent().hasClass('dropdown-menu')) {
+ $parentLi.parent().parent().addClass('active');
+ }
+ } else {
+ $oldHeading.removeClass('collapsed');
+ }
+
+ $parentLi.append($panelHeading);
+ });
+
+ if (!$('li').hasClass('active')) {
+ $('li').first().addClass('active')
+ }
+
+ var $panelBodies = this.$accordion.find('.js-tabcollapse-panel-body');
+ $panelBodies.each(function () {
+ var $panelBody = $(this),
+ $tabPane = $panelBody.data('bs.tabcollapse.tabpane');
+ $tabPane.append($panelBody.contents().detach());
+ });
+ this.$accordion.html('');
+
+ if (this.options.updateLinks) {
+ var $tabContents = this.getTabContentElement();
+ $tabContents.find('[data-toggle-was="tab"], [data-toggle-was="pill"]').each(function () {
+ var $el = $(this);
+ var href = $el.attr('href').replace(/-collapse$/g, '');
+ $el.attr({
+ 'data-toggle': $el.attr('data-toggle-was'),
+ 'data-toggle-was': '',
+ 'data-parent': '',
+ href: href
+ });
+ });
+ }
+
+ this.$tabs.trigger($.Event('shown-tabs.bs.tabcollapse'));
+ };
+
+ TabCollapse.prototype.getTabContentElement = function () {
+ var $tabContents = $(this.options.tabContentSelector);
+ if ($tabContents.length === 0) {
+ $tabContents = this.$tabs.siblings('.tab-content');
+ }
+ return $tabContents;
+ };
+
+ TabCollapse.prototype.showAccordion = function () {
+ this.$tabs.trigger($.Event('show-accordion.bs.tabcollapse'));
+
+ var $headings = this.$tabs.find('li:not(.dropdown) [data-toggle="tab"], li:not(.dropdown) [data-toggle="pill"]'),
+ view = this;
+ $headings.each(function () {
+ var $heading = $(this),
+ $parentLi = $heading.parent();
+ if (("" + $parentLi.attr('class')).toString().indexOf('o_invisible_modifier') !== -1) {
+ return;
+ }
+ $heading.data('bs.tabcollapse.parentLi', $parentLi);
+ view.$accordion.append(view._createAccordionGroup(view.$accordion.attr('id'), $heading.detach()));
+ });
+
+ if (this.options.updateLinks) {
+ var parentId = this.$accordion.attr('id');
+ var $selector = this.$accordion.find('.js-tabcollapse-panel-body');
+ $selector.find('[data-toggle="tab"], [data-toggle="pill"]').each(function () {
+ var $el = $(this);
+ var href = $el.attr('href') + '-collapse';
+ $el.attr({
+ 'data-toggle-was': $el.attr('data-toggle'),
+ 'data-toggle': 'collapse',
+ 'data-parent': '#' + parentId,
+ href: href
+ });
+ });
+ }
+
+ this.$tabs.trigger($.Event('shown-accordion.bs.tabcollapse'));
+ };
+
+ TabCollapse.prototype._panelHeadingToTabHeading = function ($heading) {
+ var href = $heading.attr('href').replace(/-collapse$/g, '');
+ $heading.attr({
+ 'data-toggle': 'tab',
+ 'href': href,
+ 'data-parent': ''
+ });
+ return $heading;
+ };
+
+ TabCollapse.prototype._tabHeadingToPanelHeading = function ($heading, groupId, parentId, active) {
+ $heading.addClass('js-tabcollapse-panel-heading ' + (active ? '' : 'collapsed'));
+ $heading.attr({
+ 'data-toggle': 'collapse',
+ 'data-parent': '#' + parentId,
+ 'href': '#' + groupId
+ });
+ return $heading;
+ };
+
+ TabCollapse.prototype._checkStateOnResize = function () {
+ var view = this;
+ $(window).resize(function () {
+ clearTimeout(view._resizeTimeout);
+ view._resizeTimeout = setTimeout(function () {
+ view.checkState();
+ }, 100);
+ });
+ };
+
+ TabCollapse.prototype._initAccordion = function () {
+ var randomString = function () {
+ var result = "",
+ possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ for (var i = 0; i < 5; i++) {
+ result += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return result;
+ };
+
+ var srcId = this.$tabs.attr('id'),
+ accordionId = (srcId ? srcId : randomString()) + '-accordion';
+
+ this.$accordion = $('');
+ this.$tabs.after(this.$accordion);
+ this.$tabs.addClass(this.options.tabsClass);
+ this.getTabContentElement().addClass(this.options.tabsClass);
+ };
+
+ TabCollapse.prototype._createAccordionGroup = function (parentId, $heading) {
+ var tabSelector = $heading.attr('data-target'),
+ active = $heading.data('bs.tabcollapse.parentLi').is('.active');
+
+ if (!tabSelector) {
+ tabSelector = $heading.attr('href');
+ tabSelector = tabSelector && tabSelector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7
+ }
+
+ var $tabPane = $(tabSelector),
+ groupId = $tabPane.attr('id') + '-collapse',
+ $panel = $(this.options.accordionTemplate($heading, groupId, parentId, active));
+ $panel.find('.panel-heading > .panel-title').append(this._tabHeadingToPanelHeading($heading, groupId, parentId, active));
+ $panel.find('.panel-body').append($tabPane.contents().detach())
+ .data('bs.tabcollapse.tabpane', $tabPane);
+
+ return $panel;
+ };
+
+ // TABCOLLAPSE PLUGIN DEFINITION
+ // =======================
+
+ $.fn.tabCollapse = function (option) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data('bs.tabcollapse');
+ var options = $.extend({}, TabCollapse.DEFAULTS, $this.data(), typeof option === 'object' && option);
+
+ if (!data) $this.data('bs.tabcollapse', new TabCollapse(this, options));
+ });
+ };
+
+ $.fn.tabCollapse.Constructor = TabCollapse;
+
+}(window.jQuery);
+
+//$('ul.nav-tabs').tabCollapse();
diff --git a/addons/web/static/src/fonts/google-fonts/AveriaLibre-Regular.ttf b/addons/web/static/src/fonts/google-fonts/AveriaLibre-Regular.ttf
new file mode 100755
index 00000000..6a821459
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/AveriaLibre-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/BarlowSemiCondensed-Regular.ttf b/addons/web/static/src/fonts/google-fonts/BarlowSemiCondensed-Regular.ttf
new file mode 100755
index 00000000..ccdebedc
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/BarlowSemiCondensed-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/Cairo-Regular.ttf b/addons/web/static/src/fonts/google-fonts/Cairo-Regular.ttf
new file mode 100755
index 00000000..7be096b9
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/Cairo-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/ExpletusSans-Regular.ttf b/addons/web/static/src/fonts/google-fonts/ExpletusSans-Regular.ttf
new file mode 100755
index 00000000..4b29fa3c
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/ExpletusSans-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/Philosopher-Regular.ttf b/addons/web/static/src/fonts/google-fonts/Philosopher-Regular.ttf
new file mode 100755
index 00000000..de5d78b2
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/Philosopher-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/Tillana-Regular.ttf b/addons/web/static/src/fonts/google-fonts/Tillana-Regular.ttf
new file mode 100755
index 00000000..600939b8
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/Tillana-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/TitilliumWeb-Regular.ttf b/addons/web/static/src/fonts/google-fonts/TitilliumWeb-Regular.ttf
new file mode 100755
index 00000000..4fd6b7fb
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/TitilliumWeb-Regular.ttf differ
diff --git a/addons/web/static/src/fonts/google-fonts/WorkSans-Regular.ttf b/addons/web/static/src/fonts/google-fonts/WorkSans-Regular.ttf
new file mode 100755
index 00000000..ba11a2de
Binary files /dev/null and b/addons/web/static/src/fonts/google-fonts/WorkSans-Regular.ttf differ
diff --git a/addons/web/static/src/img/checked.svg b/addons/web/static/src/img/checked.svg
new file mode 100755
index 00000000..8e948ddc
--- /dev/null
+++ b/addons/web/static/src/img/checked.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/addons/web/static/src/img/gears.svg b/addons/web/static/src/img/gears.svg
new file mode 100755
index 00000000..0d25c11c
--- /dev/null
+++ b/addons/web/static/src/img/gears.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/addons/web/static/src/js/backend_theme_customizer/backend_theme_customizer.js b/addons/web/static/src/js/backend_theme_customizer/backend_theme_customizer.js
new file mode 100755
index 00000000..0599f014
--- /dev/null
+++ b/addons/web/static/src/js/backend_theme_customizer/backend_theme_customizer.js
@@ -0,0 +1,27 @@
+flectra.define('web.BackendThemeCustomizer', function (require) {
+"use strict";
+
+var SystrayMenu = require('web.SystrayMenu');
+var Widget = require('web.Widget');
+var Theme = require('web.CustomizeSwitcher');
+var session = require('web.session');
+
+/**
+ * Menu item appended in the systray part of the navbar, redirects to the Inbox in Discuss
+ * Also displays the needaction counter (= Inbox counter)
+ */
+
+var CustomizeMenu = Widget.extend({
+ template: 'web.customize_menu',
+ start: function () {
+ this._super.apply(this, arguments);
+ this.theme = new Theme();
+ this.theme.appendTo("#theme_customize_backend ul");
+ },
+});
+
+if (session.is_superuser) {
+ SystrayMenu.Items.push(CustomizeMenu);
+}
+
+});
diff --git a/addons/web/static/src/js/backend_theme_customizer/customize_switcher.js b/addons/web/static/src/js/backend_theme_customizer/customize_switcher.js
new file mode 100755
index 00000000..ec5f4f82
--- /dev/null
+++ b/addons/web/static/src/js/backend_theme_customizer/customize_switcher.js
@@ -0,0 +1,81 @@
+flectra.define('web.CustomizeSwitcher', function (require) {
+"use strict";
+
+var core = require('web.core');
+var Widget = require('web.Widget');
+var ajax = require('web.ajax');
+
+var QWeb = core.qweb;
+
+var Theme = Widget.extend({
+ template: 'web.theme_customize_backend',
+ events: {
+ 'change input[data-xmlid]': 'change_selection',
+ 'click .theme_customizer_close': 'close',
+ },
+ start: function () {
+ this.$inputs = this.$("input[data-xmlid]");
+ this.loader = QWeb.render('web.color_palette_loading');
+ return this.load_xml_data();
+ },
+ load_xml_data: function () {
+ var self = this;
+ return ajax.jsonRpc('/web/theme_customize_backend_get', 'call', {
+ 'xml_ids': this.get_xml_ids(this.$inputs)
+ }).done(function (data) {
+ _.each(data[0], function (active_less_id) {
+ self.$inputs.filter('[data-xmlid="' + active_less_id + '"]').prop("checked", true);
+ });
+ }).fail(function (d, error) {
+ $('body').prepend($('').text(error.data.message));
+ console.log(error.data.message);
+ });
+ },
+ get_xml_ids: function ($inputs) {
+ var xml_ids = [];
+ $inputs.each(function () {
+ if ($(this).data('xmlid') && $(this).data('xmlid').length) {
+ xml_ids.push($(this).data('xmlid').trim());
+ }
+ });
+ return xml_ids;
+ },
+ change_selection: function (event) {
+ var enable = this.get_xml_ids(this.$inputs.filter('[data-xmlid]:checked'));
+ var disable = this.get_xml_ids(this.$inputs.filter('[data-xmlid]:not(:checked)'));
+
+ $('body').append(this.loader);
+ return ajax.jsonRpc('/web/theme_customize_backend', 'call', {
+ enable: enable,
+ disable: disable,
+ get_bundle: true,
+ }).then(function (bundleHTML) {
+ var $links = $('link[href*=".assets_backend"]');
+ var $newLinks = $(bundleHTML).filter('link');
+
+ var linksLoaded = $.Deferred();
+ var nbLoaded = 0;
+ $newLinks.on('load', function (e) {
+ if (++nbLoaded >= $newLinks.length) {
+ linksLoaded.resolve();
+ }
+ });
+
+ $newLinks.on('error', function (e) {
+ linksLoaded.reject();
+ window.location.hash = "theme=true";
+ window.location.reload();
+ });
+
+ $links.last().after($newLinks);
+ return linksLoaded.then(function () {
+ $links.remove();
+ $('body').find('.f_color_palette_loading').remove();
+ });
+ });
+ }
+});
+
+return Theme;
+
+});
diff --git a/addons/web/static/src/js/chrome/apps.js b/addons/web/static/src/js/chrome/apps.js
new file mode 100755
index 00000000..90514fff
--- /dev/null
+++ b/addons/web/static/src/js/chrome/apps.js
@@ -0,0 +1,95 @@
+flectra.define('web.AppsLauncher', function (require) {
+ "use strict";
+
+var core = require('web.core');
+var session = require('web.session');
+var Widget = require('web.Widget');
+var rpc = require('web.rpc');
+
+var QWeb = core.qweb;
+
+var Apps = Widget.extend({
+ template: 'AppsLauncher',
+ events: {
+ 'click #f_clear_apps_search': '_clearSearch',
+ 'input .f_apps_search_input': '_appsSearch',
+ 'click a[data-menu]': '_o_app_click',
+ },
+ init: function (parent) {
+ this._super.apply(this, arguments);
+ this.parent = parent;
+ },
+ start: function () {
+ var self = this;
+ this._super.apply(this, arguments);
+ var company = session.company_id;
+ var img = session.url('/web/binary/company_logo' + '?db=' + session.db + (company ? '&company=' + company : ''));
+ $(document).keyup(function (e) {
+ if (e.keyCode == 27) {
+ $('.o_web_client').removeClass('launcher_opened');
+ self.$el.parents().find('#f_apps_search').find('i').toggleClass('fa-search fa-times');
+ }
+ });
+ this._createAppDashboardWidget().then(function (apps) {
+ self.$el.find('.f_apps_content').html(QWeb.render('AppsLauncher.Menus', {
+ dashboard_apps: apps.children
+ }));
+ self.apps = apps.children;
+ });
+ this.$('.f_app_footer img').attr('src',img);
+
+ },
+ _getAction: function (menu) {
+ if (!menu.action && menu.children.length) {
+ if (menu.children[0].action) {
+ return menu.children[0].action;
+ } else {
+ return this._getAction(menu.children[0]);
+ }
+ }
+ },
+ _createAppDashboardWidget: function () {
+ var self = this;
+ return rpc.query({
+ model: 'ir.ui.menu',
+ method: 'load_menus',
+ args: [core.debug],
+ kwargs: {context: session.user_context},
+ }).then(function (menus) {
+ menus.children = _.each(menus.children, function (menu) {
+ if (!menu.action && menu.children.length) {
+ menu.action = self._getAction(menu);
+ }
+ return menu;
+ });
+ return menus;
+ });
+ },
+ _clearSearch: function (ev) {
+ this.$el.find('.f_apps_search_input').val('');
+ this.$el.find('.f_apps_content').html(QWeb.render('AppsLauncher.Menus', {
+ dashboard_apps: this.apps
+ }));
+ },
+ _appsSearch: function (ev) {
+ var search_str = $(ev.currentTarget).val().trim().toLowerCase();
+ var apps = [];
+ _.each(this.apps, function (app) {
+ if (app.name.trim().toLowerCase().indexOf(search_str) !== -1) {
+ apps.push(app);
+ }
+ });
+ this.$el.find('.f_apps_content').html(QWeb.render('AppsLauncher.Menus', {
+ dashboard_apps: apps
+ }));
+ },
+ _o_app_click: function (ev) {
+ ev.preventDefault();
+ this.parent._isMainMenuClick = true;
+ this.parent.menu_click($(ev.currentTarget).data('menu'));
+ }
+});
+
+return Apps;
+
+});
diff --git a/addons/web/static/src/js/chrome/menu.js b/addons/web/static/src/js/chrome/menu.js
index aecf245d..68b52863 100644
--- a/addons/web/static/src/js/chrome/menu.js
+++ b/addons/web/static/src/js/chrome/menu.js
@@ -4,16 +4,22 @@ flectra.define('web.Menu', function (require) {
var core = require('web.core');
var session = require('web.session');
var Widget = require('web.Widget');
+var config = require('web.config');
+var Apps = require('web.AppsLauncher');
var Menu = Widget.extend({
init: function() {
this._super.apply(this, arguments);
this.is_bound = $.Deferred();
+ this._isMainMenuClick = false;
this.data = {data:{children:[]}};
+ this.isLoadflag = true;
core.bus.on('change_menu_section', this, this.on_change_top_menu);
},
start: function() {
this._super.apply(this, arguments);
+ this.apps = new Apps(this);
+ this.apps.appendTo(this.$el.parents().find('.o_main'));
return this.bind_menu();
},
do_reload: function() {
@@ -22,7 +28,7 @@ var Menu = Widget.extend({
},
bind_menu: function() {
var self = this;
- this.$secondary_menus = this.$el.parents().find('.o_sub_menu');
+ this.$secondary_menus = this.$el.parents().find('.f_launcher');
this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
this.$el.on('click', 'a[data-menu]', function (event) {
event.preventDefault();
@@ -30,6 +36,57 @@ var Menu = Widget.extend({
core.bus.trigger('change_menu_section', menu_id);
});
+ function toggleIcon(e) {
+ $(e.target).prev().find('.more-less i').toggleClass('fa-chevron-down fa-chevron-up');
+ }
+
+ this.$secondary_menus.find('[data-toggle="tooltip"]').tooltip({
+ trigger: "hover",
+ delay: "500ms"
+ });
+
+ this.$secondary_menus.find('#menu_launcher')
+ .on('hidden.bs.collapse', toggleIcon)
+ .on('shown.bs.collapse', toggleIcon);
+
+ this.$el.parents().find('li#f_menu_toggle a').click(function (event) {
+ event.preventDefault();
+ if (self.is_menus_lite_mode) {
+ window.sessionStorage.removeItem('menus_lite_mode');
+ } else {
+ window.sessionStorage.setItem('menus_lite_mode', true);
+ }
+ if (config.device.size_class < config.device.SIZES.SM) {
+ self.$secondary_menus.toggleClass('f_hide');
+ } else {
+ self.$secondary_menus.toggleClass('f_launcher_close');
+ }
+ self.is_menus_lite_mode = !self.is_menus_lite_mode;
+ });
+
+ this.$el.parents().find('li#f_apps_search a').click(function (event) {
+ event.preventDefault();
+ $(this).find('i').toggleClass('fa-search fa-times');
+ self.$el.parents().find('.f_search_launcher').toggleClass('launcher_opened');
+ self.$el.parents().find('.f_search_launcher .f_apps_search_input').focus();
+ });
+
+ this.$el.parents().find('li#f_user_toggle a').click(function (event) {
+ event.preventDefault();
+ if (self.$el.parents().find('.user_profile.close_profile').length) {
+ self.$el.parents().find('.f_launcher_content').animate({
+ scrollTop: 0
+ }, 300);
+ }
+ self.$el.parents().find('.user_profile').toggleClass('close_profile');
+ if (self.$el.parents().find('.f_launcher_close').length || self.$el.parents().find('.f_launcher.f_hide').length) {
+ self.$el.parents().find('.f_launcher').removeClass('f_launcher_close').removeClass('f_hide');
+ self.$el.parents().find('.user_profile').removeClass('close_profile');
+ window.sessionStorage.removeItem('menus_lite_mode');
+ self.is_menus_lite_mode = false;
+ }
+ });
+
// Hide second level submenus
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').addClass('o_hidden');
if (self.current_menu) {
@@ -41,8 +98,15 @@ var Menu = Widget.extend({
core.bus.on('resize', this, function() {
if ($(window).width() < 768 ) {
lazyreflow('all_outside');
+ self.$secondary_menus.addClass('f_hide').removeClass('f_launcher_close');
+ self.is_menus_lite_mode = false;
} else {
lazyreflow();
+ self.$secondary_menus.removeClass('f_hide');
+ self.is_menus_lite_mode = 'menus_lite_mode' in window.sessionStorage ? true : false;
+ if (self.is_menus_lite_mode) {
+ self.$secondary_menus.addClass('f_launcher_close');
+ }
}
});
core.bus.trigger('resize');
@@ -122,9 +186,41 @@ var Menu = Widget.extend({
this.$el.find('.active').removeClass('active');
$main_menu.parent().addClass('active');
- // Show current sub menu
- this.$secondary_menus.find('.oe_secondary_menu').hide();
- $sub_menu.show();
+ if(this._isMainMenuClick || this.isLoadflag) {
+ var href_id = $sub_menu.attr('id');
+ if (href_id && $sub_menu.attr('class').indexOf('in') === -1) {
+ window.sessionStorage.removeItem('menus_lite_mode');
+ this.is_menus_lite_mode = false;
+ if (!this.is_menus_lite_mode) {
+ this.$secondary_menus.find("a[href='#" + href_id + "']").trigger('click');
+ }
+ this.$secondary_menus.find("a[href='#" + href_id + " i']")
+ .addClass('fa-chevron-up')
+ .removeClass('fa-chevron-down');
+ } else {
+ if (!this.is_menus_lite_mode) {
+ $clicked_menu.parents('li.panel').find('.oe_main_menu_container .more-less a').trigger('click');
+ }
+ this.$secondary_menus.find("a[href='#" + href_id + " i']")
+ .addClass('fa-chevron-down')
+ .removeClass('fa-chevron-up');
+ }
+ this.$el.parents().find('.f_search_launcher').removeClass('launcher_opened');
+ this.$el.parents().find('#f_apps_search').find('i').addClass('fa-search').removeClass('fa-times');
+ }
+
+ if (config.device.size_class < config.device.SIZES.SM) {
+ if(this._isMainMenuClick || !this._isActionId){
+ this.$secondary_menus.removeClass('f_hide');
+ }else{
+ this.$secondary_menus.addClass('f_hide');
+ }
+ if(this.isLoadflag){
+ this.$secondary_menus.addClass('f_hide');
+ }
+ } else {
+ this.$secondary_menus.removeClass('f_hide');
+ }
// Hide/Show the leftbar menu depending of the presence of sub-items
this.$secondary_menus.toggleClass('o_hidden', !$sub_menu.children().length);
@@ -138,11 +234,14 @@ var Menu = Widget.extend({
} else {
$clicked_menu.parent().addClass('active');
}
+ this.$secondary_menus.find('.oe_main_menu_container').removeClass('active');
+ $clicked_menu.parents('li.panel').find('.oe_main_menu_container').addClass('active');
}
// add a tooltip to cropped menu items
this.$secondary_menus.find('.oe_secondary_submenu li a span').each(function() {
$(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'right'} :'destroy');
- });
+ });
+ this.isLoadflag = false;
},
/**
* Call open_menu with the first menu_item matching an action_id
@@ -190,6 +289,7 @@ var Menu = Widget.extend({
} else {
console.log('Menu no action found web test 04 will fail');
}
+ this._isActionId = action_id === undefined ? false : true;
this.open_menu(id);
},
@@ -204,6 +304,8 @@ var Menu = Widget.extend({
},
on_menu_click: function(ev) {
ev.preventDefault();
+ if(!parseInt($(ev.currentTarget).data('menu'))) return;
+ this._isMainMenuClick = $(ev.currentTarget).attr('class').indexOf('oe_main_menu') !== -1 ? true : false;
this.menu_click($(ev.currentTarget).data('menu'));
},
});
diff --git a/addons/web/static/src/js/chrome/user_logout.js b/addons/web/static/src/js/chrome/user_logout.js
new file mode 100755
index 00000000..a35f7941
--- /dev/null
+++ b/addons/web/static/src/js/chrome/user_logout.js
@@ -0,0 +1,30 @@
+flectra.define('web.UserLogout', function (require) {
+"use strict";
+
+var SystrayMenu = require('web.SystrayMenu');
+var Widget = require('web.Widget');
+
+var UserLogout = Widget.extend({
+ template:"UserLogout.Action",
+ events: {
+ "click": "on_click",
+ },
+ init: function () {
+ this._super.apply(this, arguments);
+ },
+ start: function () {
+ return this._super();
+ },
+ on_click:function (e) {
+ this.trigger_up('clear_uncommitted_changes', {
+ callback: this.do_action.bind(this, 'logout'),
+ });
+ }
+});
+
+SystrayMenu.Items.push(UserLogout);
+
+return {
+ UserLogout: UserLogout,
+};
+});
diff --git a/addons/web/static/src/js/chrome/user_menu.js b/addons/web/static/src/js/chrome/user_menu.js
index 0be36c7b..a0d9f491 100644
--- a/addons/web/static/src/js/chrome/user_menu.js
+++ b/addons/web/static/src/js/chrome/user_menu.js
@@ -116,3 +116,113 @@ var UserMenu = Widget.extend({
return UserMenu;
});
+
+flectra.define('web.UserProfile', function (require) {
+"use strict";
+
+var framework = require('web.framework');
+var Widget = require('web.Widget');
+
+var UserProfile = Widget.extend({
+ template: 'UserProfile',
+
+ /**
+ * @override
+ * @returns {Deferred}
+ */
+ start: function () {
+ var self = this;
+ var session = this.getSession();
+ this.$el.on('click', 'li a[data-menu]', function (ev) {
+ ev.preventDefault();
+ var menu = $(this).data('menu');
+ self['_onMenu' + menu.charAt(0).toUpperCase() + menu.slice(1)]();
+ });
+ return this._super.apply(this, arguments).then(function () {
+ var $avatar = self.$('.profile_pic img');
+ if (!session.uid) {
+ $avatar.attr('src', $avatar.data('default-src'));
+ return $.when();
+ }
+ self.$('.profile_name').text(session.name);
+ if (session.debug) {
+ self.$el.addClass('debug')
+ self.$('.db_name').text('(' + session.db + ')');
+ }
+ var avatar_src = session.url('/web/image', {
+ model:'res.users',
+ field: 'image_small',
+ id: session.uid,
+ });
+ $avatar.attr('src', avatar_src);
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ _onMenuAccount: function () {
+ var self = this;
+ this.trigger_up('clear_uncommitted_changes', {
+ callback: function () {
+ self._rpc({route: '/web/session/account'})
+ .then(function (url) {
+ framework.redirect(url);
+ })
+ .fail(function (result, ev){
+ ev.preventDefault();
+ framework.redirect('https://accounts.flectrahq.com/account');
+ });
+ },
+ });
+ },
+ /**
+ * @private
+ */
+ _onMenuDocumentation: function () {
+ window.open('https://www.flectrahq.com/documentation/user', '_blank');
+ },
+ /**
+ * @private
+ */
+ _onMenuLogout: function () {
+ this.trigger_up('clear_uncommitted_changes', {
+ callback: this.do_action.bind(this, 'logout'),
+ });
+ },
+ /**
+ * @private
+ */
+ _onMenuSettings: function () {
+ var self = this;
+ var session = this.getSession();
+ this.trigger_up('clear_uncommitted_changes', {
+ callback: function () {
+ self._rpc({
+ route: "/web/action/load",
+ params: {
+ action_id: "base.action_res_users_my",
+ },
+ })
+ .done(function (result) {
+ result.res_id = session.uid;
+ self.do_action(result);
+ });
+ },
+ });
+ },
+ /**
+ * @private
+ */
+ _onMenuSupport: function () {
+ window.open('https://www.flectrahq.com/buy', '_blank');
+ },
+});
+
+return UserProfile;
+
+});
diff --git a/addons/web/static/src/js/chrome/web_client.js b/addons/web/static/src/js/chrome/web_client.js
index 895fb2ec..51304823 100644
--- a/addons/web/static/src/js/chrome/web_client.js
+++ b/addons/web/static/src/js/chrome/web_client.js
@@ -9,6 +9,8 @@ var Menu = require('web.Menu');
var session = require('web.session');
var SystrayMenu = require('web.SystrayMenu');
var UserMenu = require('web.UserMenu');
+var UserProfile = require('web.UserProfile');
+var config = require('web.config');
return AbstractWebClient.extend({
events: {
@@ -34,11 +36,19 @@ return AbstractWebClient.extend({
this.menu = new Menu(this);
this.menu.setElement(this.$el.parents().find('.oe_application_menu_placeholder'));
this.menu.on('menu_click', this, this.on_menu_action);
+ if (config.device.size_class < config.device.SIZES.SM) {
+ this.menu.is_menus_lite_mode = false;
+ }else{
+ this.menu.is_menus_lite_mode = 'menus_lite_mode' in window.sessionStorage ? true : false;
+ }
// Create the user menu (rendered client-side)
this.user_menu = new UserMenu(this);
+ this.user_profile = new UserProfile(this);
var $user_menu_placeholder = $('body').find('.oe_user_menu_placeholder').show();
+ var $oe_application_menu_placeholder = $('body').find('.f_launcher_content');
var user_menu_loaded = this.user_menu.appendTo($user_menu_placeholder);
+ this.user_profile.prependTo($oe_application_menu_placeholder);
// Create the systray menu (rendered server-side)
this.systray_menu = new SystrayMenu(this);
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index f986fdf2..f7225f9f 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -838,6 +838,7 @@ var FormRenderer = BasicRenderer.extend({
widget.renderWithLabel($label);
}
});
+ this.$el.find('.o_notebook ul.nav-tabs').tabCollapse();
},
/**
* Sets id attribute of given widget to idForLabel
diff --git a/addons/web/static/src/js/views/list/list_renderer.js b/addons/web/static/src/js/views/list/list_renderer.js
index e161e81e..218b6a0b 100644
--- a/addons/web/static/src/js/views/list/list_renderer.js
+++ b/addons/web/static/src/js/views/list/list_renderer.js
@@ -636,7 +636,7 @@ var ListRenderer = BasicRenderer.extend({
return this._super();
}
- var $table = $('').addClass('o_list_view table table-condensed table-striped');
+ var $table = $('').addClass('o_list_view table table-condensed table-hover');
this.$el
.addClass('table-responsive')
.append($table);
diff --git a/addons/web/static/src/less/backend_theme/bootswatch_dark.less b/addons/web/static/src/less/backend_theme/bootswatch_dark.less
new file mode 100755
index 00000000..6f978f10
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/bootswatch_dark.less
@@ -0,0 +1,348 @@
+// Superhero 3.3.7
+// Bootswatch
+// -----------------------------------------------------
+
+// Navbar =====================================================================
+
+.navbar {
+ .box-shadow(none);
+ border: none;
+ font-size: @font-size-small;
+
+ &-default {
+
+ .badge {
+ background-color: #fff;
+ color: @navbar-default-bg;
+ }
+ }
+
+ &-inverse {
+
+ .badge {
+ background-color: #fff;
+ color: @navbar-inverse-bg;
+ }
+ }
+}
+
+// Buttons ====================================================================
+
+.btn {
+
+ &-default {
+ &:hover {
+ background-color: darken(@btn-default-bg, 3%);
+ }
+ }
+
+ &-sm,
+ &-xs {
+ font-size: @font-size-small;
+ }
+}
+
+// Typography =================================================================
+
+.text-primary,
+.text-primary:hover {
+ color: @brand-primary;
+}
+
+.text-success,
+.text-success:hover {
+ color: @brand-success;
+}
+
+.text-danger,
+.text-danger:hover {
+ color: @brand-danger;
+}
+
+.text-warning,
+.text-warning:hover {
+ color: @brand-warning;
+}
+
+.text-info,
+.text-info:hover {
+ color: @brand-info;
+}
+
+.page-header {
+ border-bottom-color: @table-border-color;
+}
+
+.dropdown-menu {
+ border-radius: 0;
+ margin: 2px 0 0;
+
+ > li > a {
+ font-size: @font-size-small;
+ }
+}
+
+.btn-group.open .dropdown-toggle {
+ .box-shadow(none);
+}
+
+.dropdown-header {
+ font-size: @font-size-small;
+}
+
+// Tables =====================================================================
+
+table,
+.table {
+ font-size: @font-size-small;
+
+ a:not(.btn) {
+ //color: #fff;
+ text-decoration: underline;
+ }
+
+ .dropdown-menu a {
+ text-decoration: none;
+ }
+
+ .text-muted {
+ color: @text-muted;
+ }
+
+ > thead > tr > th,
+ > tbody > tr > th,
+ > tfoot > tr > th,
+ > thead > tr > td,
+ > tbody > tr > td,
+ > tfoot > tr > td {
+ border-color: transparent;
+ }
+}
+
+// Forms ======================================================================
+
+input,
+textarea {
+ color: @input-color;
+}
+
+label,
+.radio label,
+.checkbox label,
+.help-block {
+ font-size: @font-size-small;
+}
+
+.input-addon,
+.input-group-addon {
+ color: @text-color;
+}
+
+.has-warning {
+ .help-block,
+ .control-label,
+ .radio,
+ .checkbox,
+ .radio-inline,
+ .checkbox-inline,
+ &.radio label,
+ &.checkbox label,
+ &.radio-inline label,
+ &.checkbox-inline label,
+ .form-control-feedback {
+ color: @brand-warning;
+ }
+
+ .form-control,
+ .form-control:focus {
+ border: 4px solid @brand-warning;
+ }
+
+ .input-group-addon {
+ border: none;
+ }
+}
+
+.has-error {
+ .help-block,
+ .control-label,
+ .radio,
+ .checkbox,
+ .radio-inline,
+ .checkbox-inline,
+ &.radio label,
+ &.checkbox label,
+ &.radio-inline label,
+ &.checkbox-inline label,
+ .form-control-feedback {
+ color: @brand-danger;
+ }
+
+ .form-control,
+ .form-control:focus {
+ border: 4px solid @brand-danger;
+ }
+
+ .input-group-addon {
+ border: none;
+ }
+}
+
+.has-success {
+ .help-block,
+ .control-label,
+ .radio,
+ .checkbox,
+ .radio-inline,
+ .checkbox-inline,
+ &.radio label,
+ &.checkbox label,
+ &.radio-inline label,
+ &.checkbox-inline label,
+ .form-control-feedback {
+ color: @brand-success;
+ }
+
+ .form-control,
+ .form-control:focus {
+ border: 4px solid @brand-success;
+ }
+
+ .input-group-addon {
+ border: none;
+ }
+}
+
+.form-control:focus {
+ .box-shadow(none);
+}
+
+.has-warning,
+.has-error,
+.has-success {
+ .form-control:focus {
+ .box-shadow(none);
+ }
+}
+
+// Navs =======================================================================
+
+.nav {
+ .open > a,
+ .open > a:hover,
+ .open > a:focus {
+ border-color: transparent;
+ }
+}
+
+.nav-tabs {
+ > li > a {
+ color: @text-color;
+ }
+}
+
+.nav-pills {
+ > li > a {
+ color: @text-color;
+ }
+}
+
+.pager {
+ a {
+ color: @text-color;
+ }
+}
+
+.close {
+ opacity: 0.4;
+
+ &:hover,
+ &:focus {
+ opacity: 1;
+ }
+}
+
+// Progress bars ==============================================================
+
+// Containers =================================================================
+
+.well {
+ .box-shadow(none);
+}
+
+a.list-group-item {
+
+ &.active,
+ &.active:hover,
+ &.active:focus {
+ border: none;
+ }
+
+ &-success {
+ &.active {
+ background-color: @state-success-bg;
+ }
+
+ &.active:hover,
+ &.active:focus {
+ background-color: darken(@state-success-bg, 5%);
+ }
+ }
+
+ &-warning {
+ &.active {
+ background-color: @state-warning-bg;
+ }
+
+ &.active:hover,
+ &.active:focus {
+ background-color: darken(@state-warning-bg, 5%);
+ }
+ }
+
+ &-danger {
+ &.active {
+ background-color: @state-danger-bg;
+ }
+
+ &.active:hover,
+ &.active:focus {
+ background-color: darken(@state-danger-bg, 5%);
+ }
+ }
+}
+
+.panel {
+ border: none;
+
+ &-default > .panel-heading {
+ background-color: @table-bg-hover;
+ color: @text-color;
+ }
+
+ .text-muted {
+ color: rgba(255, 255, 255, 0.4);
+ }
+}
+
+.thumbnail {
+ background-color: @well-bg;
+ border: none;
+}
+
+.modal {
+ padding: 0;
+
+ &-header,
+ &-footer {
+ background-color: @table-bg-hover;
+ border: none;
+ border-radius: 0;
+ }
+}
+
+.popover {
+ &-title {
+ border: none;
+ }
+}
diff --git a/addons/web/static/src/less/backend_theme/control_panel.less b/addons/web/static/src/less/backend_theme/control_panel.less
new file mode 100755
index 00000000..f3eec80c
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/control_panel.less
@@ -0,0 +1,46 @@
+.o_control_panel {
+ > .o_cp_searchview {
+ .f-search-view();
+ }
+ > .o_cp_right {
+ .o_cp_switch_buttons {
+ .btn {
+ color: @flectra-main-text-color;
+ background-color: transparent;
+ .box-shadow(none);
+ padding: 3px 6px;
+ &.active {
+ color: @brand-primary;
+ }
+ }
+ }
+ > .o_cp_pager {
+ .btn {
+ color: @brand-primary;
+ background-color: transparent;
+ }
+ }
+ }
+
+ > .o_cp_left {
+ > .o_cp_sidebar {
+ .o_hidden_input_file {
+ .o_form_binary_form span {
+ color: @flectra-brand-primary;
+ }
+ }
+ }
+ }
+}
+
+@media (max-width: @screen-xs-max) {
+ .o_control_panel {
+ > .o_cp_searchview, > .breadcrumb, > .o_cp_left, > .o_cp_right {
+ width: 100%;
+ }
+ .o_cp_left .o_cp_sidebar ul.dropdown-menu {
+ left: unset;
+ right: 0;
+ }
+ }
+}
diff --git a/addons/web/static/src/less/backend_theme/flectra_style.less b/addons/web/static/src/less/backend_theme/flectra_style.less
new file mode 100755
index 00000000..ddb766cf
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/flectra_style.less
@@ -0,0 +1,135 @@
+body {
+ width: 100%;
+ height: 100%;
+ .o_main_content {
+ overflow: auto;
+ }
+ @media (max-width: @screen-sm-max) {
+ overflow: inherit;
+ .o_main {
+ .oe-view-manager {
+ overflow: inherit;
+ }
+ }
+ }
+ a {
+ text-decoration: none !important;
+ }
+}
+
+.o_web_client {
+ background-color: #ffffff;
+}
+
+main {
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+> label {
+ color: rgba(51, 51, 51, 0.66) !important;
+}
+
+.btn {
+ border-radius: 0 !important;
+}
+
+.badge {
+ border-radius: 0;
+}
+
+.o_tooltip {
+ border-color: @flectra-brand-primary;
+ background-color: @flectra-brand-primary;
+ &.right::before {
+ border-right-color: @flectra-brand-primary;
+ }
+ &.top::before {
+ border-top-color: @flectra-brand-primary;
+ }
+ &.left::before {
+ border-left-color: @flectra-brand-primary;
+ }
+ &.bottom::before {
+ border-bottom-color: @flectra-brand-primary;
+ }
+
+ &::after {
+ border-color: @flectra-brand-primary;
+ background: radial-gradient(lighten(@flectra-brand-primary, 7%), @flectra-brand-primary);
+ }
+
+ &.active {
+ &.right {
+ &::before {
+ border-right-color: @flectra-brand-primary;
+ }
+ }
+ &.top {
+ &::before {
+ border-top-color: @flectra-brand-primary;
+ }
+ }
+ &.left {
+ &::before {
+ border-left-color: @flectra-brand-primary;
+ }
+ }
+ &.bottom {
+ &::before {
+ border-bottom-color: @flectra-brand-primary;
+ }
+ }
+ }
+}
+
+div.o_checkbox {
+ display: inline-block;
+ position: relative;
+ vertical-align: sub;
+ > input {
+ width: 15px;
+ height: 15px;
+ margin: 0;
+ opacity: 0;
+ position: absolute;
+ top: auto;
+ left: auto;
+ bottom: auto;
+ right: auto;
+ cursor: pointer;
+ }
+ > input + span {
+ background-color: #fff;
+ border-radius: 1px;
+ border: 1px solid rgba(120, 130, 140, 0.75);
+ content: "";
+ display: inline-block;
+ height: 17px;
+ transition: 0.3s ease-in-out;
+ width: 17px;
+ outline: none;
+
+ }
+ > input:checked + span {
+ background-repeat: no-repeat;
+ background: @brand-primary url(/web/static/src/img/checked.svg);
+ background-position: center center;
+ }
+ > input:disabled + span {
+ opacity: 0.7;
+ border: 1px solid #e2e2e0;
+ }
+ > input:focus + span {
+ outline: 1px solid @brand-primary;
+ }
+}
+.o_dialog_error.modal-body{
+ .alert{
+ color: #8a6d3b;
+ }
+}
+.o_field_widget.o_field_many2one .o_external_button{
+ color:@brand-primary;
+}
diff --git a/addons/web/static/src/less/backend_theme/form_view.less b/addons/web/static/src/less/backend_theme/form_view.less
new file mode 100755
index 00000000..417ded00
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/form_view.less
@@ -0,0 +1,158 @@
+.f-form-view-responsive() {
+ @media (max-width: @screen-sm-max) {
+ .o_group_col_6, .o_inner_group {
+ width: 100%;
+ }
+ }
+ @media (max-width: 480px) {
+ .o_group_col_6, .o_inner_group {
+ tr {
+ .o-flex-display();
+ .o-flex-flow(row, wrap);
+ td {
+ .o-flex(1, 0, auto);
+ max-width: 100%;
+ width: auto !important;
+ display: block;
+ &.o_td_label {
+ width: 90% !important;
+ border: none;
+ }
+ .o_input_dropdown {
+ width: auto;
+ max-width: 100%;
+ }
+ .o_field_widget.o_field_many2one.o_with_button {
+ display: flex;
+ }
+ }
+ .o_td_label + td {
+ padding: 3px 5px 3px 5px;
+ }
+ .o_field_widget.o_text_overflow {
+ width: auto !important;
+ }
+ }
+ }
+ }
+}
+
+.o_form_view {
+ background-color: @flectra-color-silver;
+ .o_control_panel {
+ .o_panel {
+ .o_setting_search {
+ input {
+ background-color: transparent;
+ }
+ }
+ }
+ }
+ .o_form_sheet_bg {
+ background: transparent;
+ .o_form_sheet {
+ min-width: unset;
+ max-width: 1024px;
+ .oe_title {
+ width: auto;
+ }
+ .oe_button_box {
+ width: 100%;
+ margin-bottom: 20px;
+ }
+ @media (max-width: @screen-xs-max) {
+ margin: 24px 10px;
+ }
+ .f-form-view-responsive();
+ }
+ .oe_button_box {
+ .oe_stat_button {
+ .o_button_icon {
+ color: @flectra-brand-primary;
+ }
+ &:hover {
+ color: @flectra-main-text-color;
+ }
+ }
+ }
+ }
+ .o_form_statusbar {
+ > .o_statusbar_status {
+ > .o_arrow_button {
+ background-color: #ffffff;
+ &.disabled {
+ background-color: #ffffff;
+ }
+ &:before, &:after {
+ border-left: @flectra-statusbar-arrow-width solid #ffffff;
+ }
+ &:before {
+ right: -@flectra-statusbar-arrow-width;
+ border-left-color: @gray-lighter-dark;
+ }
+ &.btn-primary.disabled {
+ color: @flectra-brand-primary;
+ background-color: mix(@brand-primary, #ffffff, 8%);
+
+ &:after {
+ border-left-color: mix(@brand-primary, #ffffff, 8%);
+ }
+ }
+ }
+ > ul > li > .btn-default {
+ color: @btn-default-bg;
+ background-color: #ffffff;
+ &:hover {
+ color: @brand-primary;
+ background-color: @flectra-color-silver;
+ }
+ }
+ }
+ }
+ .oe_chatter {
+ background-color: #ffffff;
+ min-width: unset;
+ max-width: 1024px;
+ .o_mail_activity .o_thread_date:hover {
+ color: inherit;
+ }
+ }
+ .o_input, .o_input .o_input {
+ background-color: transparent;
+ border: none;
+ border-radius: 0;
+ border-bottom: 1px solid @flectra-main-text-color;
+
+ background-position: center bottom, center calc(100% - 1px);
+ background-repeat: no-repeat;
+ background-size: 0 2px, 100% 1px;
+ transition: background 0s ease-out 0s;
+ padding: 3px 0;
+ &:focus, &.focus {
+ background-image: linear-gradient(@brand-primary, @brand-primary), linear-gradient(#d9d9d9, #d9d9d9);
+ border: 0 none !important;
+ border-radius: 0;
+ box-shadow: none;
+ float: none;
+ background-size: 100% 2px, 100% 1px;
+ outline: 0 none;
+ transition-duration: 0.4s;
+ }
+ }
+ .o_required_modifier.o_input,
+ .o_required_modifier .o_input {
+ background-color: transparent !important;
+ border-bottom: 3px solid @flectra-main-text-color;
+ &:focus, &.focus {
+ background-size: 100% 3px, 100% 1px;
+ }
+ }
+}
+
+.modal-dialog {
+ .modal-content {
+ .o_form_view {
+ .f-form-view-responsive();
+ }
+ }
+}
diff --git a/addons/web/static/src/less/backend_theme/list_view.less b/addons/web/static/src/less/backend_theme/list_view.less
new file mode 100755
index 00000000..6bffeb3c
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/list_view.less
@@ -0,0 +1,13 @@
+.o_list_view {
+ > thead, tfoot {
+ background-color: #ffffff;
+ }
+ tbody > tr.o_group_header {
+ background-color: @flectra-control-panel-background-color;
+ background-image: none;
+ border-bottom: 2px solid #ffffff;
+ }
+ > tfoot {
+ border-top: 0;
+ }
+}
diff --git a/addons/web/static/src/less/backend_theme/login_form.less b/addons/web/static/src/less/backend_theme/login_form.less
new file mode 100755
index 00000000..382eacdc
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/login_form.less
@@ -0,0 +1,85 @@
+.oe_website_login_container {
+ vertical-align: middle;
+ position: relative;
+ height: 100%;
+}
+
+.oe_login_form {
+ vertical-align: middle;
+ padding: 50px !important;
+ border: 1px solid #DDD;
+ border-radius: 5px;
+ background-color: #FFF;
+ opacity: 0.9;
+ margin: 40px auto !important;
+ top: 20%;
+ min-width: 40%;
+ position: static !important;
+
+ .flectra-button(@color, @color-bg) {
+ border-radius: 0;
+ font-weight: bold;
+ color: @color-bg;
+ background-color: @color;
+ border-color: @color-bg;
+
+ &:hover, &:focus {
+ color: @color;
+ background-color: @color-bg;
+ border-color: darken(@color-bg, 30%);
+ }
+ }
+
+ .btn-default {
+ .flectra-button(@btn-default-bg, @btn-default-color);
+ }
+
+ .btn-primary {
+ .flectra-button(@btn-primary-color, @btn-primary-bg);
+ }
+
+ .btn-success {
+ .flectra-button(@btn-success-color, @btn-success-bg);
+ }
+
+ .btn-info {
+ .flectra-button(@btn-info-color, @btn-info-bg);
+ }
+
+ .btn-warning {
+ .flectra-button(@btn-warning-color, @btn-warning-bg);
+ }
+
+ .btn-danger {
+ .flectra-button(@btn-danger-color, @btn-danger-bg);
+ }
+
+ .field-db {
+ .input-group {
+ border-bottom: 1px solid #CCC;
+ input#db {
+ border: none;
+ }
+ }
+ }
+ input,
+ select {
+ background-color: transparent !important;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #CCC;
+ border-radius: 0;
+ color: @brand-primary;
+ font-size: 18px;
+ font-weight: 300;
+ transition: border-color 0.7s ease;
+ box-shadow: none !important;
+ }
+
+ input:focus,
+ select:focus {
+ border-bottom: 1px solid @brand-primary;
+ outline: 0 none;
+ }
+}
diff --git a/addons/web/static/src/less/backend_theme/menu_launcher.less b/addons/web/static/src/less/backend_theme/menu_launcher.less
new file mode 100755
index 00000000..513369f2
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/menu_launcher.less
@@ -0,0 +1,400 @@
+.o_web_client {
+ > .o_main {
+ .o_content {
+ background-color: @flectra-color-silver;
+ .o_view_manager_content {
+ background-color: @flectra-color-silver;
+ }
+ }
+ .f_launcher_close {
+ .f_launcher_content {
+ width: 0 !important;
+ }
+ }
+
+ .f_hide {
+ z-index: -1 !important;
+ .f_launcher_content {
+ width: 0 !important;
+ }
+ }
+
+ .f_launcher {
+ border-right: 1px solid @launcher-menu-border;
+ background-color: @launcher-menu-bg;
+ .f_launcher_content::-webkit-scrollbar {
+ display: none;
+ }
+ .f_launcher_content {
+ height: 100%;
+ width: 200px;
+ .o-transition(all, 300ms);
+ overflow-y: auto;
+ padding-bottom: 30px;
+
+ .user_profile {
+ padding: 10px;
+ position: relative;
+ height: 110px;
+ border-bottom: @flectra-main-color-muted;
+ background: linear-gradient(320deg, mix(@flectra-brand-primary, #000000, 70%) 35%, transparent 0%),
+ linear-gradient(250deg, mix(@flectra-brand-primary, #000000, 80%) 40%, transparent 0%),
+ linear-gradient(190deg, mix(@flectra-brand-primary, #000000, 50%) 30%, transparent 0%),
+ linear-gradient(10deg, mix(@flectra-brand-primary, #000000, 90%) 30%, transparent 100%),
+ linear-gradient(0deg, black 100%, transparent 0%);
+ background-size: 100%;
+ .o-transition(all, 0.5s);
+ .profile_pic {
+ text-align: center;
+ img {
+ max-width: 60px;
+ max-height: 100%;
+ }
+ }
+ .profile_info {
+ width: 100%;
+ text-align: center;
+ padding: 6px 0;
+ > .dropdown {
+ > a {
+ cursor: pointer;
+ font-size: 15px;
+ color: #ffffff;
+ font-weight: bold;
+ .db_name {
+ font-size: 10px;
+ display: block;
+ text-align: center;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ }
+ > ul {
+ right: 0;
+ > li {
+ text-align: center;
+ margin: 5px;
+ }
+ }
+ }
+ }
+ &.close_profile {
+ height: 0 !important;
+ padding: 0;
+ position: relative;
+ .o-transition(all, 0.3s);
+ }
+ &.debug {
+ height: 118px;
+ }
+ }
+ > ul {
+ list-style-type: none;
+ position: relative;
+ padding: 0;
+ > li.panel {
+ background-color: #ffffff;
+ margin: 0;
+ border-radius: 0;
+ &:first-child > .oe_main_menu_container {
+ border-top: 1px solid @launcher-menu-border;
+ }
+ > .oe_main_menu_container {
+ display: flex;
+ width: 100%;
+ background-color: @launcher-menu-bg;
+ border-bottom: 1px solid @launcher-menu-border;
+ height: 45px;
+ > a {
+ display: flex;
+ width: 100%;
+ position: relative;
+ .app_icon, .app_name {
+ padding: 8px 5px 8px 10px;
+ }
+ .app_icon {
+ width: 45px;
+ > img {
+ width: 28px;
+ height: 28px;
+ object-fit: cover;
+ }
+ }
+ .app_name {
+ font-size: 15px;
+ color: @flectra-main-text-color;
+ margin: 4px 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 122px;
+ font-weight: bold;
+ }
+ }
+ .more-less {
+ margin: 13px;
+ > a {
+ cursor: pointer;
+ color: @flectra-main-text-color;
+ }
+ }
+ &.active {
+ background-color: mix(@brand-primary, #ffffff, 30%);
+ &:hover {
+ background-color: mix(@brand-primary, #ffffff, 30%);
+ }
+ }
+ &:hover {
+ background-color: #ffffff;
+ }
+ }
+ }
+ }
+ .oe_secondary_menu_section {
+ font-weight: bold;
+ text-align: left;
+ font-size: 14px;
+ text-transform: uppercase;
+ padding: 8px 0 8px 8px;
+ border-bottom: 1px solid @launcher-menu-border;
+ > a, > a:hover {
+ color: @flectra-main-text-color;
+ }
+ &.active > a {
+ color: @brand-primary;
+ }
+ }
+ .oe_secondary_submenu {
+ line-height: 1.1em;
+ > li {
+ > a {
+ padding: 10px 4px 10px 18px;
+ color: @flectra-main-text-color;
+ &:hover, &:focus {
+ color: @flectra-main-text-color;
+ background-color: @flectra-color-silver;
+ }
+ }
+ &.active > a {
+ color: @brand-primary;
+ background-color: @launcher-menu-bg;
+ }
+ }
+ .oe_secondary_submenu {
+ > li > a {
+ padding-left: 30px;
+ }
+ .oe_secondary_submenu > li > a {
+ padding-left: 42px;
+ }
+ }
+ .oe_menu_text {
+ max-width: 85%;
+ margin-top: 1px;
+ }
+ .oe_menu_toggler:before {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ content: "&darr";
+ opacity: 0.5;
+ text-indent: -99999px;
+ vertical-align: top;
+ margin-left: -12px;
+ margin-top: 4px;
+ margin-right: 4px;
+ border-top: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ border-left: 4px solid @flectra-main-color-muted;
+ }
+ .oe_menu_opened:before {
+ margin-top: 6px;
+ margin-left: -16px;
+ margin-right: 4px;
+ border-left: 4px solid transparent;
+ border-right: 4px solid transparent;
+ border-top: 4px solid @flectra-main-color-muted;
+ }
+ }
+ }
+ .oe_secondary_menu {
+ li {
+ border: none !important;
+ }
+ }
+ &.f_hide {
+ border: none;
+ }
+ }
+ .f_search_launcher {
+ width: calc(~"100% - 400px");
+ height: 0;
+ position: fixed;
+ z-index: 999;
+ top: 62px;
+ left: 266px;
+ background-color: @launcher-menu-bg;
+ overflow: hidden;
+ .box-shadow(inset 0 -15px 15px -18px #000000);
+ .o-transition(all, 300ms);
+ .f_search_launcher_content {
+ position: relative;
+ width: 100%;
+ .f_apps_search_box {
+ align-items: center;
+ display: flex;
+ height: 56px;
+ border-bottom: 1px solid @launcher-menu-border;
+ .f_apps_search_icon {
+ padding: 8px;
+ font-size: 20px;
+ color: @flectra-main-text-color;
+ }
+ #f_clear_apps_search {
+ cursor: pointer;
+ }
+ input {
+ cursor: default;
+ }
+ .f_apps_search_input {
+ border: none;
+ padding: 5px;
+ color: @flectra-main-text-color;
+ font-size: 20px;
+ background-color: transparent;
+
+ .f-input-placeholder() {
+ color: @flectra-main-text-color;
+ opacity: 0.4;
+ }
+
+ &::-webkit-input-placeholder { /* Chrome/Opera/Safari */
+ .f-input-placeholder()
+ }
+ &::-moz-placeholder { /* Firefox 19+ */
+ .f-input-placeholder()
+ }
+ &:-ms-input-placeholder { /* IE 10+ */
+ .f-input-placeholder()
+ }
+ &:-moz-placeholder { /* Firefox 18- */
+ .f-input-placeholder()
+ }
+ &:focus {
+ outline: none;
+ border-bottom: none;
+ }
+ }
+ }
+ .f_apps_container {
+ .o-flex-display();
+ .o-flex-flow(column, nowrap);
+ .o-align-items(center);
+ .o-flex(1, 0, auto);
+ width: 100%;
+ overflow-y: auto;
+ .f_apps_content {
+ .o-flex(0, 0, auto);
+ width: 100%;
+ .clearfix();
+ margin: 10px 0;
+ .f_app {
+ width: 25%;
+ text-align: center;
+ padding: 20px;
+ float: left;
+ @media (min-width: @screen-xs-min) {
+ width: 25%;
+ }
+ @media (max-width: @screen-xs-max) {
+ padding: 10px;
+ .f_app_label {
+ font-size: small;
+ }
+ }
+ @media (min-width: 882px) {
+ width: 20%;
+ }
+ @media (min-width: @screen-md-min) {
+ width: 16.66%;
+ }
+ @media (min-width: @screen-lg-min) {
+ width: 12.5%;
+ }
+ @media (min-width: 1440px) {
+ width: 10%;
+ }
+ .f_app_icon {
+ max-width: 45px;
+ max-height: 100%;
+ width: 100%;
+ }
+ .f_app_label {
+ color: #000000;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding-top: 5px;
+ }
+ &:hover {
+ background-color: fade(@brand-primary, 60%);
+ }
+ }
+ }
+ .f_app_footer {
+ .o-flex-display();
+ .o-flex(1, 0, auto);
+ align-items: flex-end;
+ margin: 10px 0;
+ > img {
+ max-width: 100px;
+ }
+ }
+ }
+ }
+ &.launcher_opened {
+ border: 1px solid @launcher-menu-border;
+ border-top: 0;
+ height: 356px;
+ .f_apps_container {
+ height: 300px;
+ }
+ @media (max-width: @screen-xs-max) {
+ height: 100%;
+ width: 100%;
+ left: auto;
+ .f_apps_container {
+ height: 100%;
+ }
+
+ @media (max-width: 480px) {
+ top: 46px;
+ }
+ }
+ }
+ }
+ .o_mail_chat .o_mail_chat_sidebar .o_mail_sidebar_title h4 {
+ color: #777777;
+ }
+ }
+ .o_loading {
+ background-color: darken(@brand-primary, 13.5%) !important;
+ top: inherit;
+ bottom: 0;
+ right: 0;
+ padding: 5px 50px;
+ border-radius: 0 !important;
+ opacity: 0.8;
+ }
+}
+
+@media (max-width: 767px) {
+ .o_main {
+ .f_launcher {
+ position: absolute;
+ z-index: 3 !important;
+ height: 100%;
+ }
+ }
+}
diff --git a/addons/web/static/src/less/backend_theme/navbar.less b/addons/web/static/src/less/backend_theme/navbar.less
new file mode 100755
index 00000000..cd91d397
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/navbar.less
@@ -0,0 +1,143 @@
+nav#oe_main_menu_navbar {
+ background-color: transparent;
+ border-bottom: 1px solid @launcher-menu-border;
+ @media (max-width: @screen-xs-max) {
+ display: flex;
+ }
+ .color-line {
+ width: 100%;
+ display: flex;
+ @media (max-width: @screen-xs-max) {
+ position: absolute;
+ }
+ .color {
+ width: 20%;
+ height: 5px;
+ }
+ .color-1 {
+ background-color: @brand-primary;
+ }
+ .color-2 {
+ background-color: @brand-success;
+ }
+ .color-3 {
+ background-color: @brand-info;
+ }
+ .color-4 {
+ background-color: @brand-warning;
+ }
+ .color-5 {
+ background-color: @brand-danger;
+ }
+ }
+ .f_menu_systray {
+ width: 100%;
+ > ul {
+ @media (max-width: @screen-xs-max) {
+ display: flex;
+ margin: 0;
+ margin-top: 5px;
+ > li.open .dropdown-menu {
+ top: 62px;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ position: fixed;
+ width: auto;
+ background-color: #ffffff;
+ }
+
+ ul.dropdown-menu > li > a {
+ color: @flectra-main-text-color;
+ }
+ }
+ > li {
+ > a {
+ padding: 15px 20px;
+ font-size: 20px;
+ height: 56px;
+ margin: 0;
+ color: lighten(@flectra-main-text-color, 30%);
+ > .badge {
+ top: 5px;
+ right: 5px;
+ padding: 2px 5px;
+ font-size: 11px;
+ font-weight: bold;
+ }
+ &:hover, &:focus {
+ background-color: lighten(@flectra-main-text-color, 65%);
+ }
+ }
+ > ul {
+ left: auto;
+ right: 0;
+ }
+ }
+ }
+ }
+ .f_toggle_buttons {
+ > ul {
+ @media (max-width: @screen-xs-max) {
+ display: flex;
+ margin: 0;
+ margin-top: 5px;
+ }
+ > li > a {
+ padding: 17px 24px;
+ font-size: 20px;
+ height: 56px;
+ color: @flectra-main-text-color;
+ margin: 0;
+ border-right: 1px solid @launcher-menu-border;
+ background-color: @launcher-menu-bg;
+ &:hover {
+ background-color: darken(@launcher-menu-bg, 1%);
+ }
+ }
+ }
+ > ul > li.f_company_name {
+ width: 201px;
+ > a {
+ padding: 3px;
+ text-align: center;
+ img {
+ max-height: 50px;
+ max-width: 100%;
+
+ }
+ }
+ }
+ }
+ @media (max-width: 480px) {
+ min-height: 45px;
+ .f_menu_systray {
+ > ul {
+ > li.open .dropdown-menu {
+ top: 46px;
+ }
+ > li {
+ > a {
+ padding: 10px 15px;
+ font-size: 15px;
+ height: 40px;
+ > .badge {
+ padding: 1px 3px;
+ font-size: 9px;
+ }
+ }
+ }
+ }
+ }
+
+ .f_toggle_buttons {
+ > ul > li {
+ > a {
+ padding: 10px 15px;
+ font-size: 10px;
+ height: 40px;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/addons/web/static/src/less/backend_theme/search_view.less b/addons/web/static/src/less/backend_theme/search_view.less
new file mode 100755
index 00000000..d1d39681
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme/search_view.less
@@ -0,0 +1,22 @@
+.f-search-view() {
+ .o_searchview {
+ border: none;
+ background-color: transparent;
+ > .o_searchview_facet {
+ > .o_searchview_facet_label {
+ color: @brand-primary;
+ background-color: #ffffff;
+ font-weight: bold;
+ }
+ > .o_facet_values {
+ background-color: #ffffff;
+ }
+ }
+ > .o_searchview_input {
+ border-bottom: 1px solid @flectra-main-text-color;
+ background-color: transparent;
+ }
+ }
+}
+
+.f-search-view();
diff --git a/addons/web/static/src/less/backend_theme_customizer/color_options/dark_nostalgia.less b/addons/web/static/src/less/backend_theme_customizer/color_options/dark_nostalgia.less
new file mode 100755
index 00000000..30d959d0
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/color_options/dark_nostalgia.less
@@ -0,0 +1,9 @@
+/* ==========================================================================
+ Dark Nostalgia Color
+ ========================================================================== */
+
+@brand-primary: @dark-nostalgia-primary;
+@brand-success: @dark-nostalgia-success;
+@brand-info: @dark-nostalgia-info;
+@brand-warning: @dark-nostalgia-warning;
+@brand-danger: @dark-nostalgia-danger;
diff --git a/addons/web/static/src/less/backend_theme_customizer/color_options/lapine.less b/addons/web/static/src/less/backend_theme_customizer/color_options/lapine.less
new file mode 100755
index 00000000..0ce62b56
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/color_options/lapine.less
@@ -0,0 +1,9 @@
+/* ==========================================================================
+ Lapine Colors
+ ========================================================================== */
+
+@brand-primary: @lapine-primary;
+@brand-success: @lapine-success;
+@brand-info: @lapine-info;
+@brand-warning: @lapine-warning;
+@brand-danger: @lapine-danger;
diff --git a/addons/web/static/src/less/backend_theme_customizer/color_options/muddy_rainbow.less b/addons/web/static/src/less/backend_theme_customizer/color_options/muddy_rainbow.less
new file mode 100755
index 00000000..df708bc9
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/color_options/muddy_rainbow.less
@@ -0,0 +1,9 @@
+/* ==========================================================================
+ Muddy Rainbow Color
+ ========================================================================== */
+
+@brand-primary: @muddy-rainbow-primary;
+@brand-success: @muddy-rainbow-success;
+@brand-info: @muddy-rainbow-info;
+@brand-warning: @muddy-rainbow-warning;
+@brand-danger: @muddy-rainbow-danger;
diff --git a/addons/web/static/src/less/backend_theme_customizer/color_options/peaches_plums.less b/addons/web/static/src/less/backend_theme_customizer/color_options/peaches_plums.less
new file mode 100755
index 00000000..b9e34b8d
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/color_options/peaches_plums.less
@@ -0,0 +1,9 @@
+/* ==========================================================================
+ Peaches and Plums Colors
+ ========================================================================== */
+
+@brand-primary: @peaches-plums-primary;
+@brand-success: @peaches-plums-success;
+@brand-info: @peaches-plums-info;
+@brand-warning: @peaches-plums-warning;
+@brand-danger: @peaches-plums-danger;
diff --git a/addons/web/static/src/less/backend_theme_customizer/color_options/sunset_dunes.less b/addons/web/static/src/less/backend_theme_customizer/color_options/sunset_dunes.less
new file mode 100755
index 00000000..495d4b12
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/color_options/sunset_dunes.less
@@ -0,0 +1,9 @@
+/* ==========================================================================
+ Sunset Dunes Colors
+ ========================================================================== */
+
+@brand-primary: @sunset-dunes-primary;
+@brand-success: @sunset-dunes-success;
+@brand-info: @sunset-dunes-info;
+@brand-warning: @sunset-dunes-warning;
+@brand-danger: @sunset-dunes-danger;
diff --git a/addons/web/static/src/less/backend_theme_customizer/color_options/warm_sunset.less b/addons/web/static/src/less/backend_theme_customizer/color_options/warm_sunset.less
new file mode 100755
index 00000000..22815bd7
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/color_options/warm_sunset.less
@@ -0,0 +1,9 @@
+/* ==========================================================================
+ Warm Sunset Color
+ ========================================================================== */
+
+@brand-primary: @warm-sunset-primary;
+@brand-success: @warm-sunset-success;
+@brand-info: @warm-sunset-info;
+@brand-warning: @warm-sunset-warning;
+@brand-danger: @warm-sunset-danger;
diff --git a/addons/web/static/src/less/backend_theme_customizer/colors.less b/addons/web/static/src/less/backend_theme_customizer/colors.less
new file mode 100755
index 00000000..7b2695e0
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/colors.less
@@ -0,0 +1,61 @@
+.text-primary {
+ color: @brand-primary;
+}
+
+.text-success {
+ color: @brand-success;
+}
+
+.text-info {
+ color: @brand-info;
+}
+
+.text-warning {
+ color: @brand-warning;
+}
+
+.text-danger {
+ color: @brand-danger;
+}
+
+//Muddy Rainbow
+@muddy-rainbow-primary: #009efb;
+@muddy-rainbow-success: #37ad7e;
+@muddy-rainbow-info: #84cc33;
+@muddy-rainbow-warning: #c69817;
+@muddy-rainbow-danger: #e13d14;
+
+//Dark Nostalgia
+@dark-nostalgia-primary: #a16358;
+@dark-nostalgia-success: #b8945b;
+@dark-nostalgia-info: #b1ba61;
+@dark-nostalgia-warning: #70b061;
+@dark-nostalgia-danger: #63a2b0;
+
+//Warm Sunset
+@warm-sunset-primary: #ff9300;
+@warm-sunset-success: #fb5f02;
+@warm-sunset-info: #b83709;
+@warm-sunset-warning: #fbf23d;
+@warm-sunset-danger: #ffaf04;
+
+//Peaches and Plums
+@peaches-plums-primary: #657248;
+@peaches-plums-success: #789a58;
+@peaches-plums-info: #582736;
+@peaches-plums-warning: #e39573;
+@peaches-plums-danger: #b25757;
+
+//Lapine
+@lapine-primary: #784418;
+@lapine-success: #db9e1d;
+@lapine-info: #810038;
+@lapine-warning: #51001f;
+@lapine-danger: #e39573;
+
+//Sunset Dunes
+@sunset-dunes-primary: #dd5d32;
+@sunset-dunes-success: #d44025;
+@sunset-dunes-info: #0a3536;
+@sunset-dunes-warning: #1e675a;
+@sunset-dunes-danger: #d8b45d;
diff --git a/addons/web/static/src/less/backend_theme_customizer/customize_model.less b/addons/web/static/src/less/backend_theme_customizer/customize_model.less
new file mode 100755
index 00000000..08869b78
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/customize_model.less
@@ -0,0 +1,109 @@
+/* CUSTOMIZE THEME - MODAL */
+
+#theme_customize_backend {
+ .backend_theme_customizer_content {
+ background-color: #333333;
+ padding: 10px;
+ width: 220px;
+ .color_box {
+ input[type="radio"] {
+ display: none;
+ }
+
+ input[type="radio"] + label {
+ cursor: pointer;
+ display: block;
+ }
+
+ input[type="radio"] + label {
+ display: inline-block;
+ width: 25px;
+ height: 25px;
+ vertical-align: middle;
+ border-radius: 5px;
+ cursor: pointer;
+ }
+
+ input[type="radio"]:checked + label {
+ border: 3px solid mix(@brand-primary, #ffffff, 30%);
+ }
+ .color_box_header {
+ color: mix(@brand-primary, #ffffff, 30%);
+ }
+ .color_box_content {
+ display: flex;
+ .color_radio {
+ padding: 4px;
+ }
+ }
+ }
+ .font_box {
+ .font_box_header {
+ color: mix(@brand-primary, #ffffff, 30%);
+ }
+ .font_box_content {
+ .font_radio {
+ padding: 0 5px;
+ color: mix(@brand-primary, #ffffff, 30%);
+ display: inline-block;
+ width: 45%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ > * {
+ cursor: pointer;
+ }
+ &:hover, &:focus {
+ color: #ffffff;
+ }
+ }
+ }
+ }
+ }
+
+ //Custom Color Settings
+
+ /* Muddy Rainbow */
+ .muddy-rainbow-primary {
+ background-color: @muddy-rainbow-primary;
+ }
+
+ /* Dark Nostalgia */
+ .dark-nostalgia-primary {
+ background-color: @dark-nostalgia-primary;
+ }
+
+ /* Warm Sunset */
+ .warm-sunset-primary {
+ background-color: @warm-sunset-primary;
+ }
+
+ /* Peaches And Plums */
+ .peaches-plums-primary {
+ background-color: @peaches-plums-primary;
+ }
+
+ /* Lapine */
+ .lapine-primary {
+ background-color: @lapine-primary;
+ }
+
+ /* Sunset Dunes */
+ .sunset-dunes-primary {
+ background-color: @sunset-dunes-primary;
+ }
+
+ .dropdown-menu {
+ padding: 0;
+ }
+}
+
+.f_color_palette_loading {
+ background-color: rgba(0, 0, 0, 0.5);
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 1060;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font.less b/addons/web/static/src/less/backend_theme_customizer/font.less
new file mode 100755
index 00000000..3fd9b4ea
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font.less
@@ -0,0 +1,35 @@
+/* Work Sans */
+@font-face {
+ font-family: 'Work Sans';
+ src: local('Work Sans'), url('/web/static/src/fonts/google-fonts/WorkSans-Regular.ttf') format('truetype');
+}
+
+/* Expletus Sans */
+@font-face {
+ font-family: 'Expletus Sans';
+ src: local('Expletus Sans'), url('/web/static/src/fonts/google-fonts/ExpletusSans-Regular.ttf') format('truetype');
+}
+
+/* Philosopher */
+@font-face {
+ font-family: 'Philosopher';
+ src: local('Philosopher'), url('/web/static/src/fonts/google-fonts/Philosopher-Regular.ttf') format('truetype');
+}
+
+/* Titillium Web */
+@font-face {
+ font-family: 'Titillium Web';
+ src: local('Titillium Web'), url('/web/static/src/fonts/google-fonts/TitilliumWeb-Regular.ttf') format('truetype');
+}
+
+/* Averia Libre */
+@font-face {
+ font-family: 'Averia Libre';
+ src: local('Averia Libre'), url('/web/static/src/fonts/google-fonts/AveriaLibre-Regular.ttf') format('truetype');
+}
+
+/* Tillana */
+@font-face {
+ font-family: 'Tillana';
+ src: local('Tillana'), url('/web/static/src/fonts/google-fonts/Tillana-Regular.ttf') format('truetype');
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font_options/averia_libre.less b/addons/web/static/src/less/backend_theme_customizer/font_options/averia_libre.less
new file mode 100755
index 00000000..f548aed0
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font_options/averia_libre.less
@@ -0,0 +1,3 @@
+body {
+ font-family: 'Averia Libre', cursive;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font_options/expletus_sans.less b/addons/web/static/src/less/backend_theme_customizer/font_options/expletus_sans.less
new file mode 100755
index 00000000..c708acab
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font_options/expletus_sans.less
@@ -0,0 +1,3 @@
+body {
+ font-family: 'Expletus Sans', cursive;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font_options/philosopher.less b/addons/web/static/src/less/backend_theme_customizer/font_options/philosopher.less
new file mode 100755
index 00000000..f6714c1d
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font_options/philosopher.less
@@ -0,0 +1,3 @@
+body {
+ font-family: 'Philosopher', sans-serif;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font_options/tillana.less b/addons/web/static/src/less/backend_theme_customizer/font_options/tillana.less
new file mode 100755
index 00000000..74ec6b90
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font_options/tillana.less
@@ -0,0 +1,3 @@
+body {
+ font-family: 'Tillana', cursive;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font_options/titillium_web.less b/addons/web/static/src/less/backend_theme_customizer/font_options/titillium_web.less
new file mode 100755
index 00000000..1c3c6d1a
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font_options/titillium_web.less
@@ -0,0 +1,3 @@
+body {
+ font-family: 'Titillium Web', sans-serif;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/font_options/work_sans.less b/addons/web/static/src/less/backend_theme_customizer/font_options/work_sans.less
new file mode 100755
index 00000000..1e844e9b
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/font_options/work_sans.less
@@ -0,0 +1,3 @@
+body {
+ font-family: 'Work Sans', sans-serif;
+}
diff --git a/addons/web/static/src/less/backend_theme_customizer/variables.less b/addons/web/static/src/less/backend_theme_customizer/variables.less
new file mode 100755
index 00000000..475081de
--- /dev/null
+++ b/addons/web/static/src/less/backend_theme_customizer/variables.less
@@ -0,0 +1,12 @@
+@flectra-brand-primary: @brand-primary;
+@flectra-brand-optional: @brand-primary;
+@flectra-brand-secondary: #f0eeee;
+@flectra-brand-lightsecondary: #e2e2e0;
+
+@flectra-color-pink: @brand-primary;
+@flectra-main-color-muted: #a8a8a8;
+@flectra-main-text-color: #4c4c4c;
+
+@flectra-view-background-color: white;
+@flectra-shadow-color: #303030;
+@custom-text-color: #54667a;
diff --git a/addons/web/static/src/less/bootstrap_overridden.less b/addons/web/static/src/less/bootstrap_overridden.less
index d45abea4..e07f767b 100644
--- a/addons/web/static/src/less/bootstrap_overridden.less
+++ b/addons/web/static/src/less/bootstrap_overridden.less
@@ -6,9 +6,14 @@
@grid-gutter-width: @flectra-horizontal-padding*2;
//== Colors
-@brand-primary: @flectra-brand-primary;
@gray-lighter: @flectra-color-silver;
+@brand-primary: #009efb;
+@brand-success: #5cb85c;
+@brand-info: #31708f;
+@brand-warning: orange;
+@brand-danger: #d9534f;
+
//== Titles
@font-size-h1: @flectra-font-size-base + 13px;
@font-size-h2: @flectra-font-size-base + 7px;
@@ -38,6 +43,9 @@
@badge-line-height: @line-height-base;
@badge-font-weight: normal;
+//== Control Panel
+@flectra-control-panel-background-color: @flectra-color-silver;
+
//== Breadcrumbs
@breadcrumb-active-color: #777777;
@breadcrumb-bg: @flectra-control-panel-background-color;
@@ -96,17 +104,21 @@
@nav-tabs-active-link-hover-bg: white;
//== Navbar
-@navbar-height: @flectra-navbar-height - 2;
+@navbar-height: @flectra-navbar-height + 28;
@navbar-margin-bottom: 0;
-@navbar-inverse-bg: #222222;
-@navbar-inverse-link-color: #9d9d9d;
-@navbar-inverse-link-hover-bg: #222222;
+@navbar-inverse-bg: @brand-primary;
+@navbar-inverse-link-color: #ffffff;
+@navbar-inverse-link-hover-bg: darken(@brand-primary, 5%);
@navbar-inverse-toggle-hover-bg: #222222;
@navbar-border-radius: 0;
//== Tables
@table-bg-accent: #efeff8; // FIXME: expose
+//== menu launcher
+@launcher-menu-bg : #f7f9fa;
+@launcher-menu-border : #eaeaea;
+
// ------------------------------------------------------------------
// Bootstrap components rules (non exposed features variables)
// ------------------------------------------------------------------
@@ -163,3 +175,27 @@
overflow-x: initial;
}
}
+
+@btn-default-color: #fff;
+@btn-default-bg: @gray-light;
+@btn-default-border: transparent;
+
+@btn-primary-color: #fff;
+@btn-primary-bg: @brand-success;
+@btn-primary-border: transparent;
+
+@btn-success-color: #fff;
+@btn-success-bg: @brand-success;
+@btn-success-border: transparent;
+
+@btn-info-color: #fff;
+@btn-info-bg: @brand-info;
+@btn-info-border: transparent;
+
+@btn-warning-color: #fff;
+@btn-warning-bg: @brand-warning;
+@btn-warning-border: transparent;
+
+@btn-danger-color: #fff;
+@btn-danger-bg: @brand-danger;
+@btn-danger-border: transparent;
diff --git a/addons/web/static/src/less/fields_extra.less b/addons/web/static/src/less/fields_extra.less
index 32083fab..2961a61f 100644
--- a/addons/web/static/src/less/fields_extra.less
+++ b/addons/web/static/src/less/fields_extra.less
@@ -27,6 +27,7 @@
font-size: 19px;
color: #7C7BAD;
border: none;
+ background-color: transparent !important;
&:hover {
background-color: transparent;
}
diff --git a/addons/web/static/src/less/variables.less b/addons/web/static/src/less/variables.less
index 1e595510..ab08bb7e 100644
--- a/addons/web/static/src/less/variables.less
+++ b/addons/web/static/src/less/variables.less
@@ -7,11 +7,11 @@
@flectra-font-size-base: 13px;
// Colors
-@flectra-brand-primary: #7c7bad;
-@flectra-brand-optional: #7c7bad;
+@flectra-brand-primary: #009efb;
+@flectra-brand-optional: #009efb;
@flectra-brand-secondary: #f0eeee;
@flectra-brand-lightsecondary: #e2e2e0;
-@flectra-color-silver: #F9F9F9;
+@flectra-color-silver: #f1f3f6;
@flectra-color-silver-dark: #E5E5E5;
@flectra-color-silver-darker: #d9d7d7;
diff --git a/addons/web/static/src/xml/backend_theme.xml b/addons/web/static/src/xml/backend_theme.xml
new file mode 100755
index 00000000..0bbaf73d
--- /dev/null
+++ b/addons/web/static/src/xml/backend_theme.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Sorry, unable to find your content!
+
+
+
diff --git a/addons/web/static/src/xml/backend_theme_customizer.xml b/addons/web/static/src/xml/backend_theme_customizer.xml
new file mode 100755
index 00000000..eecaf4bb
--- /dev/null
+++ b/addons/web/static/src/xml/backend_theme_customizer.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Loading...
+
+
+
+
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 2dce0ab9..ba63cb2d 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -376,7 +376,7 @@
-
+
@@ -1272,8 +1272,8 @@
-
-
+
+
@@ -1352,7 +1352,7 @@