Commit f608f07b by Kunto Bregananta Adi

custom theme

1 parent f4f515af
Showing 153 changed files with 1363 additions and 0 deletions
# -*- coding: utf-8 -*-
from .hooks import test_pre_init_hook, test_post_init_hook
# from . import wizard
# -*- coding: utf-8 -*-
{
"name": "IDG Backend Theme V14",
"description": """Odoo V14 backend theme for Indonesia Government""",
"summary": "Odoo V14 backend theme for Indonesia Government",
"category": "Themes/Backend",
"version": "1.0",
'author': 'bregananta',
'company': 'bregananta',
'maintainer': 'bregananta',
'website': "https://www.bregananta.id",
"depends": ['base', 'web', 'mail', 'web_responsive'],
'images': [],
"data": [
# 'security/ir.model.access.csv',
'views/assets.xml',
'views/icons.xml',
'views/layout.xml',
# 'views/theme.xml',
# 'data/theme_data.xml',
],
"qweb": [
'static/src/xml/sidebar.xml',
'static/src/xml/styles.xml',
'static/src/xml/top_bar.xml',
# 'static/src/xml/systray.xml',
],
'installable': True,
'application': False,
'auto_install': False,
}
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="theme_data_stored" model="theme.data.stored">
<field name="name">default</field>
</record>
</data>
</odoo>
# -*- coding: utf-8 -*-
import base64
from odoo import api, SUPERUSER_ID
from odoo.modules import get_module_resource
def test_pre_init_hook(cr):
"""pre init hook"""
env = api.Environment(cr, SUPERUSER_ID, {})
menu_item = env['ir.ui.menu'].search([('parent_id', '=', False)])
for menu in menu_item:
if menu.name == 'PDL Kab/Kota':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons', 'idg_pdl.png')
menu.write({'web_icon_data': base64.b64encode(open(img_path, "rb").read())})
if menu.name == 'BPHTB':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons', 'idg_bphtb.png')
menu.write({'web_icon_data': base64.b64encode(open(img_path, "rb").read())})
def test_post_init_hook(cr, registry):
"""post init hook"""
env = api.Environment(cr, SUPERUSER_ID, {})
menu_item = env['ir.ui.menu'].search([('parent_id', '=', False)])
for menu in menu_item:
if menu.name == 'PDL Kab/Kota':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons',
'idg_pdl.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'BPHTB':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons',
'idg_bphtb.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_theme_data,access.theme.data,model_theme_data,,1,1,1,1
<!-- HERO SECTION -->
<div class="contianer">
<div class="row position-relative"
style="background-color: #2f3542 !important; height: 400px; margin-bottom: 6rem; border-radius: 1rem !important;">
<div class="col-lg-12 d-flex flex-column justify-content-start align-items-center">
<h1 class="display-1 text-white" style="padding-top: 5rem;">SDN Theme</h1>
<p class="text-light small font-weight-bold" style="letter-spacing: 2px; text-transform: uppercase;">Backend Theme for
Odoo 14</p>
</div>
</div>
</div>
<!-- END OF HERO SECTION -->
\ No newline at end of file \ No newline at end of file
odoo.define('idg_theme.SideBar', function (require) {
"use strict";
var Widget = require('web.Widget');
var SideBar = Widget.extend({
events: _.extend({}, Widget.prototype.events, {
'click .nav-link': '_onAppsMenuItemClicked',
}),
template: "idg_theme.Sidebar",
init: function (parent, menuData) {
this._super.apply(this, arguments);
this._apps = _.map(menuData.children, function (appMenuData) {
return {
actionID: parseInt(appMenuData.action.split(',')[1]),
menuID: appMenuData.id,
name: appMenuData.name,
xmlID: appMenuData.xmlid,
web_icon_data: appMenuData.web_icon_data,
};
});
},
getApps: function () {
return this._apps;
},
_openApp: function (app) {
this.trigger_up('app_clicked', {
action_id: app.actionID,
menu_id: app.menuID,
});
},
_onAppsMenuItemClicked: function (ev) {
var $target = $(ev.currentTarget);
var actionID = $target.data('action-id');
var menuID = $target.data('menu-id');
var app = _.findWhere(this._apps, { actionID: actionID, menuID: menuID });
this._openApp(app);
},
});
return SideBar;
});
\ No newline at end of file \ No newline at end of file
odoo.define('idg_theme.SidebarMenu', function (require) {
"use strict";
const config = require("web.config");
const Menu = require("web.Menu");
const SideBar = require("idg_theme.SideBar");
Menu.include({
start() {
var res = this._super.apply(this, arguments);
this.sidebar_apps = this.$('.sidebar_panel');
this._sideBar = new SideBar(this, this.menu_data);
var sideBar = this._sideBar.appendTo(this.sidebar_apps);
return res, sideBar
},
});
function showSidebar(){
$("#sidebar_panel").css({'display':'block'});
$(".o_action_manager").css({'margin-left': '90px','transition':'all .1s linear'});
$(".top_heading").css({'margin-left': '78px','transition':'all .1s linear'});
$("#dotsWhite").toggleClass("d-block d-none");
$("#dotsPrimary").toggleClass("d-block d-none");
//add class in navbar
var navbar = $(".o_main_navbar");
var navbar_id = navbar.data("id");
$("nav").addClass(navbar_id);
navbar.addClass("small_nav");
//add class in action-manager
var action_manager = $(".o_action_manager");
var action_manager_id = action_manager.data("id");
$("div").addClass(action_manager_id);
action_manager.addClass("sidebar_margin");
//add class in top_heading
var top_head = $(".top_heading");
var top_head_id = top_head.data("id");
$("div").addClass(top_head_id);
top_head.addClass("sidebar_margin");
}
function hideSidebar(){
$("#sidebar_panel").css({'display':'none'});
$(".o_action_manager").css({'margin-left': '0px'});
$(".top_heading").css({'margin-left': '0px'});
$("#dotsWhite").toggleClass("d-block d-none");
$("#dotsPrimary").toggleClass("d-block d-none");
//remove class in navbar
var navbar = $(".o_main_navbar");
var navbar_id = navbar.data("id");
$("nav").removeClass(navbar_id);
navbar.removeClass("small_nav");
//remove class in action-manager
var action_manager = $(".o_action_manager");
var action_manager_id = action_manager.data("id");
$("div").removeClass(action_manager_id);
action_manager.removeClass("sidebar_margin");
//remove class in top_heading
var top_head = $(".top_heading");
var top_head_id = top_head.data("id");
$("div").removeClass(top_head_id);
top_head.removeClass("sidebar_margin");
}
var showBar = false;
$(document).on("click", "#triggerSidebar", function(event){
if(showBar){
hideSidebar();
}else{
showSidebar();
}
$("#triggerSidebar").toggleClass('c_sidebar_active c_sidebar_passive');
$('#dotsMenuContainer').toggleClass('c_dots_menu c_dots_menu_toggled');
showBar = !showBar;
});
/* $(document).on("click", ".sidebar a", function(event){
var menu = $(".sidebar a");
var $this = $(this);
var id = $this.data("id");
$("header").removeClass().addClass(id);
menu.removeClass("active");
$this.addClass("active");
//sidebar close on menu-item click
$("#sidebar_panel").css({'display':'none'});
$(".o_action_manager").css({'margin-left': '0px'});
$(".top_heading").css({'margin-left': '0px'});
$("#closeSidebar").hide();
$("#openSidebar").show();
//remove class in navbar
var navbar = $(".o_main_navbar");
var navbar_id = navbar.data("id");
$("nav").removeClass(navbar_id);
navbar.removeClass("small_nav");
//remove class in action-manager
var action_manager = $(".o_action_manager");
var action_manager_id = action_manager.data("id");
$("div").removeClass(action_manager_id);
action_manager.removeClass("sidebar_margin");
//remove class in top_heading
var top_head = $(".top_heading");
var top_head_id = top_head.data("id");
$("div").removeClass(top_head_id);
top_head.removeClass("sidebar_margin");
});*/
});
\ No newline at end of file \ No newline at end of file
odoo.define('idg_theme.Load', function (require) {
"use strict";
var rpc = require('web.rpc');
var session = require('web.session');
$(document).ready(function () {
rpc.query({
model: 'theme.data',
method: 'action_apply',
args: [this]
});
});
});
\ No newline at end of file \ No newline at end of file
odoo.define('idg_theme.theme', function (require) {
"use strict";
var SystrayMenu = require('web.SystrayMenu');
var Widget = require('web.Widget');
var Session = require('web.session');
var ThemeWidget = Widget.extend({
template: 'theme_systray',
events: {
'click #theme_sdn': '_onClick',
},
is_admin: false,
willStart: function () {
this.is_admin = Session.is_admin;
return this._super.apply(this, arguments);
},
_onClick: function(){
var menu = $('.o_menu_sections');
this.do_action({
type: 'ir.actions.act_window',
name: 'theme data',
res_model: 'theme.data',
view_mode: 'form',
views: [[false, 'form']],
target: 'new'
});
},
});
SystrayMenu.Items.push(ThemeWidget);
return ThemeWidget;
});
.datepicker{
z-index: 9999 !important;
}
div.dropdown-menu.bootstrap-datetimepicker-widget {
width: 28rem !important;
}
.datepicker .table-sm > thead,
.datepicker > div > table > tbody > tr > td.active{
background-color: $one__primary;
}
.datepicker .table-sm > thead > tr:first-child th:hover {
background-color: $one__primary-dark;
}
.datepicker .table-sm > tbody > tr > td.today::before{
border-bottom-color: $one__primary;
}
.c_login_container{
background: $one__light !important;
width: 100% !important;
.card-body{
background-color: transparent !important;
}
}
.input-group-prepend{
.input-group-text{
border-radius: 0px !important;
border-right: 0px !important;
background: transparent !important;
}
}
.form-control{
border-radius: 0px !important;
border-color: $one__border-light;
background-color: none;
&:focus{
box-shadow: none !important;
}
}
//Buttons
.btn{
border-radius: 0px;
&:hover{
filter: brightness(90%) !important;
box-shadow: none;
transition: $transition-normal;
}
}
.btn-primary{
background-color: $one__primary !important;
border-color: $one__primary !important;
color: $one__light !important;
&:hover{
background-color: $one__primary-dark !important;
}
&:focus{
box-shadow: 0 0 0 0.2rem rgba(235,240,253, 0.8);
}
}
//Links
a, .btn-link {
color: $one__primary;
text-decoration: none;
background-color: transparent;
&:hover{
color: $one__primary-dark;
text-decoration: none !important;
transition: $transition-normal;
}
}
\ No newline at end of file \ No newline at end of file
#sidebar_panel {
height: 100%;
position: fixed;
top: 0px;
background-color: $one__sidebar-color;
border-right: 1px solid $one__sidebar-border;
display: none;
width: 80px;
overflow-y: scroll;
-ms-overflow-style: none; /* Hide scrollbar for IE and Edge */
scrollbar-width: none; /* Hide scrollbar for Firefox */
z-index: 999;
}
#sidebar_panel::-webkit-scrollbar {
display: none; /* Hide scrollbar for Chrome, Safari and Opera */
}
.sidebar_menu{
margin-top: 20px !important;
}
.sidebar_title{
color: $one__sidebar_text;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 0.9rem;
margin-left: auto;
margin-right: auto;
width: 38px;
display: block;
margin-top: 18px !important;
}
.sidebar_panel .sidebar {
padding: 0;
white-space: nowrap;
padding-bottom: 20px;
padding-top: 5px;
}
.sidebar_panel .sidebar_close {
text-align: end;
display: none;
position: sticky;
height: 35px;
padding-top: 5px;
top: 0;
background: #2a3042;
z-index: 1;
}
.sidebar_panel .sidebar_close a#closeSidebar {
font-size: 18px;
margin-right: 10px;
color: #ffffff;
opacity: .3;
}
.sidebar_panel .sidebar_close a#closeSidebar img {
width: 15px;
}
.sidebar_panel .sidebar .sidebar_logo {
padding-top: 20px;
text-align: center;
padding-bottom: 20px;
}
.sidebar_panel .sidebar .sidebar_logo img {
max-width: 150px;
}
.sidebar_panel .sidebar .sidebar_head {
padding-top: 20px;
padding-left: 15px;
color: #6a7187;
font-size: 14px;
}
.sidebar_panel .sidebar .sidebar_menu {
list-style: none;
margin: 0;
padding: 0;
}
.sidebar_panel .sidebar .sidebar_menu li {
margin: 0;
padding: 0;
border: 0px;
display: block;
}
.sidebar_panel .sidebar .sidebar_menu li a {
margin: 0;
border: 0px;
display: block;
cursor: pointer;
overflow: hidden;
padding: 8px 10px 8px 25px;
color: #ffffff;
font-size: 13px;
transition:.3s all;
}
.sidebar_panel .sidebar .sidebar_menu li:hover a {
background: $one__sidebar-color-hover;
color: $one__light;
}
.sidebar_panel .nav-link {
opacity: 1 !important;
transition:.3s all;
}
.sidebar_panel .sidebar a.nav-link.active {
color: $one__light !important;
border-left: 4px solid $one__light;
img{
margin-left: -0.5rem !important;
}
}
.sidebar_panel .sidebar .sidebar_menu li a .sidebar_img {
width: 32px;
height: 32px;
margin: 8px 8px 8px 0;
}
.sidebar_panel .sidebar .sidebar_menu li a {
transition: $transition-fast;
&:hover{
transform: scale(1.1);
transition: $transition-fast;
}
}
\ No newline at end of file \ No newline at end of file
//Variables
//Fonts
$one__font: "Odoo Unicode Support Noto", "Lucida Grande", Helvetica, Verdana, Arial, sans-serif;
//Colors
$one__light: #FFF !default;
$one__primary: #386aeb !default;
$one__sidebar-color-hover: #274aa5 !important;
$one__sidebar-border: #386aeb !important;
$one__sidebar-color: #386aeb !important;
$one__sidebar_text: #fff !default;
$one__primary-light: #ebf0fd !default;
$one__primary-dark: #274aa5 !important;
$one__light-font-primary: #1f2631 !important;
$one__light-font-secondary: #575757 !important;
$one__hover-bkg-light: #f5f5f5 !important;
$one__border-light: #d4d4d4 !important;
$one__info: #454555 !important;
//Border Style
$one__border: 0px;
$one__button-padding: auto;
//Misc
$transition-normal: all 0.4s linear !default;
$transition-fast: all 0.2s linear !default;
//Paths
$dots_menu_toggled: url('/idg_theme/static/src/img/icons/dots-menu-primary.png');
//Animations
@mixin c_fadeBackgroundOut($name, $s_opacity, $e_opacity, $r, $g, $b){
@keyframes #{$name}{
0%{
background-color: rgba($r, $g, $b, $s_opacity);
}
100%{
background-color: rgba($r, $g, $b, $e_opacity);
}
}
}
\ No newline at end of file \ No newline at end of file
//Variables
//Fonts
$one__font: 'Nunito', Helvetica, Verdana, Arial, sans-serif !important;
//Colors
$one__light: #fff !default;
$one__primary: #1F2631 !default;
$one__sidebar-color: #1F2631 !important;
$one__sidebar-color-hover: #1c222c !default;
$one__sidebar-border: #1F2631 !important;
$one__sidebar_text: #fff !default;
$one__primary-light: #e9e9ea !default;
$one__primary-dark: #1c222c !important;
$one__light-font-primary: #030405 !important;
$one__light-font-secondary: #575757 !important;
$one__hover-bkg-light: #f5f5f5 !important;
$one__border-light: #d4d4d4 !important;
$one__info: #454555 !important;
//Border Style
$one__border: 100px;
$one__button-padding: 20px;
//Misc
$transition-normal: all 0.4s linear !default;
$transition-fast: all 0.2s linear !default;
//Paths
$dots_menu_toggled: url('/idg_theme/static/src/img/icons/dots-menu-navy.png');
//Animations
@mixin c_fadeBackgroundOut($name, $s_opacity, $e_opacity, $r, $g, $b){
@keyframes #{$name}{
0%{
background-color: rgba($r, $g, $b, $s_opacity);
}
100%{
background-color: rgba($r, $g, $b, $e_opacity);
}
}
}
//Variables
//Fonts
$one__font: 'Poppins', Helvetica, Verdana, Arial, sans-serif !important;
//Colors
$one__light: #fff !default;
$one__primary: #00A97F !default;
$one__sidebar-color: #fff !important;
$one__sidebar-color-hover: #e6f6f2 !default;
$one__sidebar-border: #E9E9E9 !important;
$one__sidebar_text: #00A97F !default;
$one__primary-light: #e6f6f2 !default;
$one__primary-dark: #009872 !important;
$one__light-font-primary: #575757 !important;
$one__light-font-secondary: #575757 !important;
$one__hover-bkg-light: #f5f5f5 !important;
$one__border-light: #d4d4d4 !important;
$one__info: #454555 !important;
//Border Style
$one__border: 3px;
$one__button-padding: auto;
//Misc
$transition-normal: all 0.4s linear !default;
$transition-fast: all 0.2s linear !default;
//Paths
$dots_menu_toggled: url('/idg_theme/static/src/img/icons/dots-menu-green.png');
//Animations
@mixin c_fadeBackgroundOut($name, $s_opacity, $e_opacity, $r, $g, $b){
@keyframes #{$name}{
0%{
background-color: rgba($r, $g, $b, $s_opacity);
}
100%{
background-color: rgba($r, $g, $b, $e_opacity);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="Menu">
<t t-jquery=".o_main_navbar" t-operation="after">
<div class="sidebar_panel" id="sidebar_panel"/>
</t>
</t>
<t t-name="idg_theme.Sidebar">
<div class="sidebar">
<div class="sidebar_close">
<a id="closeSidebar" style="cursor: pointer;">
<img src="/idg_theme/static/src/img/icons/close.png"/>
</a>
</div>
<!-- <div class="sidebar_logo">-->
<!-- <img src="/web/binary/company_logo" class="logo_img"/>-->
<!-- </div>-->
<span class="sidebar_title">
Menu
</span>
<ul class="sidebar_menu">
<t t-foreach="widget.getApps()" t-as="app">
<li data-toggle="tooltip" data-placement="right" t-att-title="app.name">
<a role="menuitem" t-attf-href="#menu_id=#{app.menuID}"
class="nav-link" t-att-data-menu-id="app.menuID"
t-att-data-menu-xmlid="app.xmlID"
t-att-data-action-id="app.actionID">
<img class="sidebar_img"
t-attf-src="data:image/svg;base64,#{app.web_icon_data}"/>
</a>
</li>
</t>
</ul>
</div>
</t>
</templates>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<!--Align Invite Button in Settings-->
<t t-inherit="base_setup.res_config_invite_users" t-inherit-mode="extension" owl="1">
<xpath expr="//div[hasclass('d-flex')]" position="attributes">
<attribute name="class">d-flex align-items-center</attribute>
</xpath>
</t>
<!--Remove App Icon in Settings-->
<t t-inherit="web.BaseSetting.Tabs" t-inherit-mode="extension" owl="1">
<xpath expr="//div[hasclass('tab')]" position="replace">
<div class="tab" t-attf-data-key="#{tab.key}" role="tab">
<span class="app_name"><t t-esc="tab.string"/></span>
</div>
</xpath>
</t>
<!--Active Color for App Counter-->
<t t-inherit="web.SearchPanel.Category" t-inherit-mode="extension" owl="1">
<xpath expr="//span[hasclass('o_search_panel_counter')]" position="attributes">
<attribute name="class">o_search_panel_counter ml-2 small</attribute>
</xpath>
</t>
</templates>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<templates>
<t t-name="theme_systray">
<li class="new_icon">
<label class="theme_sdn" style="margin-bottom:0px;" title="Change backend theme">
<t t-if="widget.is_admin">
<div class="icon_div sdn_systray_icon" groups="base.group_system">
<div class="toggle-icon"
style="font-size: 1.9rem !important; margin: auto 11px !important;">
<i id='theme_sdn' class="fa fa-paint-brush" role="img" aria-label="Theme"/>
</div>
</div>
</t>
</label>
</li>
</t>
</templates>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<t t-inherit="web.Menu" t-inherit-mode="extension" owl="1">
<xpath expr="//nav[hasclass('o_main_navbar')]" position="replace">
<nav class="o_main_navbar">
<div class="c_navbar_container">
<div class="top_heading d-flex align-items-center">
<ul class="o_menu_apps"/>
<a class="o_menu_brand" role="button"/>
<!-- Current App Sections -->
<div class="d-none d-md-block">
<ul class="o_menu_sections mb-0 pl-4" role="menu"/>
</div>
</div>
<div class="d-flex justify-content-between c_responsive_tray">
<ul class="o_menu_systray topbar_icon" role="menu"/>
</div>
</div>
</nav>
</xpath>
</t>
<t t-inherit="web.AppsMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//li[hasclass('dropdown')]" position="replace">
<li class="dropdown">
<a id="triggerSidebar" class="c_sidebar_active" style="display: block; cursor: pointer;">
<!-- <i class="fa fa-th-large fa-lg"/> -->
<div id="dotsMenuContainer" class="c_dots_menu"/>
</a>
</li>
</xpath>
</t>
<t t-inherit="web.UserMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//span[hasclass('oe_topbar_name')]" position="replace">
<div class="oe_topbar_name"/>
</xpath>
</t>
<t t-inherit="mail.MessagingMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//i[hasclass('o_MessagingMenu_icon')]" position="replace">
<img src="/idg_theme/static/src/img/icons/speech-bubble.png" width="22" height="22" aria-label="Messages"/>
</xpath>
</t>
<t t-inherit="mail.systray.ActivityMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//i[hasclass('fa-clock-o')]" position="replace">
<img src="/idg_theme/static/src/img/icons/bell.png" width="22" height="22" aria-label="Activities"/>
</xpath>
</t>
</templates>
\ No newline at end of file \ No newline at end of file
<odoo>
<data>
<template id="idg_theme_assets" name="SDN Theme Assets" inherit_id="web.assets_backend">
<xpath expr=".">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600&amp;display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/theme_accent.scss"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/datetimepicker.scss"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/theme.scss"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/sidebar.scss"/>
<script type="application/javascript" src="/idg_theme/static/src/js/chrome/sidebar.js"/>
<script type="application/javascript" src="/idg_theme/static/src/js/chrome/sidebar_menu.js"/>
<!-- <script type="application/javascript" src="/idg_theme/static/src/js/systray.js"/> -->
<!-- <script type="application/javascript" src="/idg_theme/static/src/js/load.js"/> -->
</xpath>
</template>
<template id="idg_theme_assets_frontend" inherit_id="web.assets_frontend">
<xpath expr="//link[last()]" position="after">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600&amp;display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/theme_accent.scss"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/login.scss"/>
</xpath>
</template>
</data>
</odoo>
<odoo>
<data>
<template>
<t t-name="DashBoard.action">
<div t-att-data-id="action.attrs.id" class="oe_action">
<h2 t-attf-class="oe_header #{action.attrs.string ? '' : 'oe_header_empty'}">
<span class="oe_header_txt"> <t t-esc="action.attrs.string"/> </span>
<input class = "oe_header_text" type="text"/>
<t t-if="!action.attrs.string">&amp;nbsp;</t>
<span class='oe_icon oe_minimize oe_fold' t-if="!action.attrs.fold"></span>
<span class='oe_icon oe_maximize oe_fold' t-if="action.attrs.fold"></span>
</h2>
<div t-att-class="'oe_content' + (action.attrs.fold ? ' oe_folded' : '')"/>
</div>
</t>
<t t-name="DashBoard.NoContent">
<div class="o_view_nocontent">
<div class="o_nocontent_help">
<p class="o_view_nocontent_neutral_face">
Your personal dashboard is empty
</p><p>
To add your first report into this dashboard, go to any
menu, switch to list or graph view, and click <i>"Add to
Dashboard"</i> in the extended search options.
</p><p>
You can filter and group data before inserting into the
dashboard using the search options.
</p>
</div>
</div>
</t>
</template>
</data>
</odoo>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<menuitem id="base.menu_administration" name="Settings"
web_icon="idg_theme,static/src/img/icons/settinga.png"/>
<menuitem id="base.menu_management" name="Apps" web_icon="idg_theme,static/src/img/icons/apps.png"/>
<menuitem id="mail.menu_root_discuss" name="Discuss"
web_icon="idg_theme,static/src/img/icons/discuss.png"/>
</data>
</odoo>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="code_custom_layout" inherit_id="web.layout"
name="Custom Layout">
<xpath expr="//meta[@content='IE=edge,chrome=1']" position="after">
<meta name="viewport"
content="width=device-width, initial-scale=1, user-scalable=no"/>
</xpath>
</template>
<template id="code_custom_login" inherit_id="web.login"
name="Custom Layout">
<xpath expr="//t[@t-call='web.login_layout']" position="replace">
<t t-call="web.login_layout">
<form class="oe_login_form" role="form"
t-attf-action="/web/login" method="post"
onsubmit="this.action = '/web/login' + location.hash">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<div class="form-group field-db"
t-if="databases and len(databases) &gt; 1">
<label for="db" class="col-form-label">Database</label>
<div t-attf-class="input-group {{'input-group-sm' if form_small else ''}}">
<input type="text" name="db"
t-att-value="request.db" id="db"
t-attf-class="form-control #{'form-control-sm' if form_small else ''}"
required="required" readonly="readonly"/>
<span class="input-group-append">
<a role="button" href="/web/database/selector"
class="btn btn-secondary">Select
<i class="fa fa-database" role="img"
aria-label="Database"
title="Database"></i>
</a>
</span>
</div>
</div>
<div class="form-group field-login">
<label class="sr-only" for="login">Email</label>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fa fa-envelope"></i>
</div>
</div>
<input type="text" placeholder="Email" name="login"
t-att-value="login" id="login"
t-attf-class="form-control border-left-0 #{'form-control-sm' if form_small else ''}"
required="required" autofocus="autofocus"
autocapitalize="off"/>
</div>
</div>
<div class="form-group field-password">
<label for="password" class="sr-only">Password</label>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fa fa-asterisk"></i>
</div>
</div>
<input type="password" placeholder="Password"
name="password" id="password"
t-attf-class="form-control border-left-0 #{'form-control-sm' if form_small else ''}"
required="required"
autocomplete="current-password"
t-att-autofocus="'autofocus' if login else None"
maxlength="4096"/>
</div>
</div>
<p class="alert alert-danger" t-if="error" role="alert">
<t t-esc="error"/>
</p>
<p class="alert alert-success" t-if="message" role="status">
<t t-esc="message"/>
</p>
<div t-attf-class="clearfix oe_login_buttons text-center mb-1 {{'pt-2' if form_small else 'pt-3'}}">
<button type="submit" class="btn btn-primary btn-block">
Log in
</button>
<t t-if="debug">
<button type="submit" name="redirect"
value="/web/become"
class="btn btn-link btn-sm btn-block">Log in
as superuser
</button>
</t>
<div class="o_login_auth"/>
</div>
<input type="hidden" name="redirect"
t-att-value="redirect"/>
</form>
</t>
</xpath>
</template>
</odoo>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="idg_theme_data" model="ir.ui.view">
<field name="name">them.data.form</field>
<field name="model">theme.data</field>
<field name="arch" type="xml">
<form create="0">
<footer>
<button name="action_apply" id="jsxj" type="object" string="Apply" class="btn btn-primary"/>
</footer>
<sheet>
<group>
<group>
<field name="name"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
</odoo>
\ No newline at end of file \ No newline at end of file
from . import theme
# -*- coding: utf-8 -*-
import base64
from odoo import models, fields, api
from odoo.modules import get_module_resource
class Theme(models.TransientModel):
_name = "theme.data"
def _get_current_theme(self):
return self.env['theme.data.stored'].sudo().search([], limit=1).name
name = fields.Selection([
('default', 'Default'),
('two', 'Green'),
('three', 'Black'),
], 'Theme', required=True, default=_get_current_theme)
@api.onchange('name')
def onchange_name(self):
theme = self.sudo().env.ref('idg_theme.theme_data_stored')
if theme:
theme.name = self.name
else:
theme.create({
'name': self.name
})
def action_apply(self):
name = self.env['theme.data.stored'].sudo().search([], limit=1).name
if name == 'two':
link = '<link rel="stylesheet" href="/idg_theme/static/src/scss/theme_two.scss"/>'
self.icon_change_theme_green()
elif name == 'three':
link = '<link rel="stylesheet" href="/idg_theme/static/src/scss/theme_three.scss"/>'
self.icon_change_theme_default()
else:
link = '<link rel="stylesheet" href="/idg_theme/static/src/scss/theme_accent.scss"/>'
self.icon_change_theme_default()
theme = self.sudo().env.ref('idg_theme.idg_theme_assets')
login = self.sudo().env.ref(
'idg_theme.idg_theme_assets_frontend')
theme.arch_base = '''
<data name="SDN Theme Assets" inherit_id="web.assets_backend">
<xpath expr=".">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600&amp;display=swap" rel="stylesheet"/>
%s
<link rel="stylesheet" href="/idg_theme/static/src/scss/datetimepicker.scss"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/theme.scss"/>
<link rel="stylesheet" href="/idg_theme/static/src/scss/sidebar.scss"/>
<script type="application/javascript" src="/idg_theme/static/src/js/chrome/sidebar.js"/>
<script type="application/javascript" src="/idg_theme/static/src/js/chrome/sidebar_menu.js"/>
<script type="application/javascript" src="/idg_theme/static/src/js/systray.js"/>
<script type="application/javascript" src="/idg_theme/static/src/js/load.js"/>
</xpath>
</data>
''' % link
login.arch_base = '''
<data name="idg_theme_assets_frontend" inherit_id="web.assets_backend">
<xpath expr=".">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;600&amp;display=swap" rel="stylesheet"/>
%s
<link rel="stylesheet" href="/idg_theme/static/src/scss/login.scss"/>
</xpath>
</data>
''' % link
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
def icon_change_theme_default(self):
menu_item = self.env['ir.ui.menu'].sudo().search([('parent_id', '=', False)])
for menu in menu_item:
if menu.name == 'PDL Kab/Kota':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons',
'idg_pdl.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'BPHTB':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons',
'idg_bphtb.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'IDG Account':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons',
'idg_account.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'ID Dashboard':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img', 'icons',
'idg_board.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
def icon_change_theme_green(self):
menu_item = self.env['ir.ui.menu'].sudo().search([('parent_id', '=', False)])
for menu in menu_item:
if menu.name == 'PDL Kab/Kota':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img',
'icons_light',
'idg_pdl.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'BPHTB':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img',
'icons_light',
'idg_bphtb.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'IDG Account':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img',
'icons_light',
'idg_account.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
if menu.name == 'ID Dashboard':
img_path = get_module_resource(
'idg_theme', 'static', 'src', 'img',
'icons_light',
'idg_board.png')
menu.write({'web_icon_data': base64.b64encode(
open(img_path, "rb").read())})
class ThemeStored(models.Model):
_name = "theme.data.stored"
name = fields.Selection([
('default', 'Default'),
('two', 'Green'),
('three', 'Black'),
], 'Theme', default='default')
==============
Web Responsive
==============
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/14.0/web_responsive
:alt: OCA/web
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_responsive
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/162/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module adds responsiveness to web backend.
Features for all devices:
* New navigation with an app drawer
.. image:: https://user-images.githubusercontent.com/973709/48417193-09a1e080-e74a-11e8-8a0c-e73eb689b2fb.gif
* Quick menu search from the app drawer
.. image:: https://user-images.githubusercontent.com/973709/48417213-17576600-e74a-11e8-846a-57691e82636b.gif
* Increase the size of the labels in extra large screens
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/label_size_small.png
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/label_size_large.png
Features for mobile:
* App-specific submenus are shown on full screen when toggling them from the
"hamburger" menu
.. image:: https://user-images.githubusercontent.com/973709/48417297-51286c80-e74a-11e8-9a47-22c810b18c43.gif
* View type picker dropdown displays confortably
.. image:: https://user-images.githubusercontent.com/973709/50964322-e3d55580-14c6-11e9-8249-48db9539600f.gif
* Top app bar is always visible, but the control panel is hidden when
scrolling down, to save some vaulable vertical space
.. image:: https://user-images.githubusercontent.com/973709/50964496-5cd4ad00-14c7-11e9-9261-fd223a329d02.gif
* Form status bar action and status buttons are collapsed in dropdowns.
Other control panel buttons use icons to save space.
.. image:: https://user-images.githubusercontent.com/973709/50965446-e08f9900-14c9-11e9-92d6-dda472cb6557.gif
* Breadcrumbs navigation is collapsed with a "back arrow" button.
.. image:: https://user-images.githubusercontent.com/973709/50965168-1d0ec500-14c9-11e9-82a0-dfee82ed0861.gif
* Search panel is hidden on small screens.
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/search_panel.gif
Features for computers:
* Keyboard shortcuts for easier navigation, **using ``Alt + Shift + [key]``**
combination instead of just ``Alt + [key]``.
See https://github.com/odoo/odoo/issues/30068 to understand why.
.. image:: https://user-images.githubusercontent.com/973709/48417578-ff341680-e74a-11e8-8881-017709e912bc.png
* Autofocus on search menu box when opening the drawer
.. image:: https://user-images.githubusercontent.com/973709/48417213-17576600-e74a-11e8-846a-57691e82636b.gif
* Set chatter on the side of the screen, optional per user
.. image:: https://user-images.githubusercontent.com/973709/48417270-41108d00-e74a-11e8-9172-cba825d027ed.gif
* Full width form sheets
.. image:: https://user-images.githubusercontent.com/973709/48417428-ac5a5f00-e74a-11e8-8839-5bc538c54c1d.png
* Sticky chatter topbar
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/chatter_topbar.gif
* AppMenu waits for action finished to show the view
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/appmenu.gif
* Sticky header & footer in list view
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/listview.gif
* Sticky statusbar in form view
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/formview.gif
* Followers and send button is displayed on mobile. Avatar is hidden.
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/chatter.gif
* When the chatter is configured on the side part, the document viewer fills that
part for side-by-side reading instead of full screen. You can still put it on full
width preview clicking on the new maximize button.
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/document_viewer.gif
* Bigger checkboxes in list view
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/big_checkboxes.gif
* Scrollable dropdowns
.. image:: https://raw.githubusercontent.com/OCA/web/14.0/web_responsive/static/img/dropdown_scroll.gif
**Table of contents**
.. contents::
:local:
Usage
=====
The following keyboard shortcuts are implemented:
* Navigate app search results - Arrow keys
* Choose app result - ``Enter``
* ``Esc`` to close app drawer
Known issues / Roadmap
======================
* To view the full experience in a device, the page must be loaded with the
device screen size. This means that, if you change the size of your browser,
you should reload the web client to get the full experience for that
new size. This is Odoo's own limitation.
* App navigation with keyboard.
* Handle long titles on forms in a better way
* Standard sticky headers seems to not work properly on iOS Safari/Chrome (see #1626).
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_responsive%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* LasLabs
* Tecnativa
Contributors
~~~~~~~~~~~~
* Dave Lasley <dave@laslabs.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Sergio Teruel <sergio.teruel@tecnativa.com>
* Alexandre Díaz <dev@redneboa.es>
* Mathias Markl <mathias.markl@mukit.at>
* Iván Todorovich <ivan.todorovich@gmail.com>
* Sergey Shebanin <sergey@shebanin.ru>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-Yajo| image:: https://github.com/Yajo.png?size=40px
:target: https://github.com/Yajo
:alt: Yajo
.. |maintainer-Tardo| image:: https://github.com/Tardo.png?size=40px
:target: https://github.com/Tardo
:alt: Tardo
Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-Yajo| |maintainer-Tardo|
This module is part of the `OCA/web <https://github.com/OCA/web/tree/14.0/web_responsive>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
from . import models
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2017-2018 Tecnativa - Jairo Llopis
# Copyright 2018-2019 Tecnativa - Alexandre Díaz
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
"name": "Web Responsive",
"summary": "Responsive web client, community-supported",
"version": "14.0.1.2.0",
"category": "Website",
"website": "https://github.com/OCA/web",
"author": "LasLabs, Tecnativa, " "Odoo Community Association (OCA)",
"license": "LGPL-3",
"installable": True,
"depends": ["web", "mail"],
"development_status": "Production/Stable",
"maintainers": ["Yajo", "Tardo"],
"data": ["views/assets.xml", "views/res_users.xml", "views/web.xml"],
"qweb": [
"static/src/xml/apps.xml",
"static/src/xml/form_buttons.xml",
"static/src/xml/menu.xml",
"static/src/xml/navbar.xml",
"static/src/xml/attachment_viewer.xml",
"static/src/xml/discuss.xml",
"static/src/xml/control_panel.xml",
"static/src/xml/search_panel.xml",
],
"sequence": 1,
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!