mirror of
https://github.com/guohuadeng/app-odoo.git
synced 2025-02-23 04:11:36 +02:00
update odoo customize set lang
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
'name': 'odoo 16 Customize OEM(Boost, Data reset)',
|
'name': 'odoo 16 Customize OEM(Boost, Data reset)',
|
||||||
'version': '16.23.02.17',
|
'version': '16.23.02.19',
|
||||||
'author': 'Sunpop.cn',
|
'author': 'Sunpop.cn',
|
||||||
'category': 'Productivity',
|
'category': 'Productivity',
|
||||||
'website': 'https://www.sunpop.cn',
|
'website': 'https://www.sunpop.cn',
|
||||||
@@ -75,6 +75,7 @@
|
|||||||
'app_odoo_customize/static/src/js/user_menu.js',
|
'app_odoo_customize/static/src/js/user_menu.js',
|
||||||
'app_odoo_customize/static/src/js/ribbon.js',
|
'app_odoo_customize/static/src/js/ribbon.js',
|
||||||
'app_odoo_customize/static/src/js/dialog.js',
|
'app_odoo_customize/static/src/js/dialog.js',
|
||||||
|
'app_odoo_customize/static/src/webclient/**/*.xml',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
'pre_init_hook': 'pre_init_hook',
|
'pre_init_hook': 'pre_init_hook',
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ class IrHttp(models.AbstractModel):
|
|||||||
result['app_support_url'] = config_parameter.get_param('app_support_url')
|
result['app_support_url'] = config_parameter.get_param('app_support_url')
|
||||||
result['app_account_title'] = config_parameter.get_param('app_account_title')
|
result['app_account_title'] = config_parameter.get_param('app_account_title')
|
||||||
result['app_account_url'] = config_parameter.get_param('app_account_url')
|
result['app_account_url'] = config_parameter.get_param('app_account_url')
|
||||||
|
result['app_show_lang'] = config_parameter.get_param('app_show_lang')
|
||||||
result['app_show_debug'] = config_parameter.get_param('app_show_debug')
|
result['app_show_debug'] = config_parameter.get_param('app_show_debug')
|
||||||
result['app_show_documentation'] = config_parameter.get_param('app_show_documentation')
|
result['app_show_documentation'] = config_parameter.get_param('app_show_documentation')
|
||||||
result['app_show_documentation_dev'] = config_parameter.get_param('app_show_documentation_dev')
|
result['app_show_documentation_dev'] = config_parameter.get_param('app_show_documentation_dev')
|
||||||
result['app_show_support'] = config_parameter.get_param('app_show_support')
|
result['app_show_support'] = config_parameter.get_param('app_show_support')
|
||||||
result['app_show_account'] = config_parameter.get_param('app_show_account')
|
result['app_show_account'] = config_parameter.get_param('app_show_account')
|
||||||
result['app_show_poweredby'] = config_parameter.get_param('app_show_poweredby')
|
result['app_show_poweredby'] = config_parameter.get_param('app_show_poweredby')
|
||||||
|
# 增加多语言
|
||||||
|
result['app_lang_list'] = self.env['res.lang'].search_read([], ['id', 'code', 'name'])
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||||
|
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||||
|
import { useService } from "@web/core/utils/hooks";
|
||||||
|
import { registry } from "@web/core/registry";
|
||||||
|
import { browser } from "@web/core/browser/browser";
|
||||||
|
import { symmetricalDifference } from "@web/core/utils/arrays";
|
||||||
|
|
||||||
|
import { Component, useState } from "@odoo/owl";
|
||||||
|
|
||||||
|
export class SwitchLangMenu extends Component {
|
||||||
|
setup() {
|
||||||
|
this.LangService = useService("Lang");
|
||||||
|
this.currentLang = this.LangService.currentLang;
|
||||||
|
this.state = useState({ langToSet: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
setLang(LangId) {
|
||||||
|
this.state.langToSet = symmetricalDifference(this.state.langToSet, [
|
||||||
|
LangId,
|
||||||
|
]);
|
||||||
|
browser.clearTimeout(this.toggleTimer);
|
||||||
|
this.toggleTimer = browser.setTimeout(() => {
|
||||||
|
this.LangService.set2Lang("toggle", ...this.state.langToSet);
|
||||||
|
}, this.constructor.toggleDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
logIntoLang(LangId) {
|
||||||
|
browser.clearTimeout(this.toggleTimer);
|
||||||
|
this.LangService.set2Lang("loginto", LangId);
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedCompanies() {
|
||||||
|
return symmetricalDifference(
|
||||||
|
this.LangService.allowedLangIds,
|
||||||
|
this.state.langToSet
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SwitchLangMenu.template = "web.SwitchLangMenu";
|
||||||
|
SwitchLangMenu.components = { Dropdown, DropdownItem };
|
||||||
|
SwitchLangMenu.toggleDelay = 1000;
|
||||||
|
|
||||||
|
export const systrayItem = {
|
||||||
|
Component: SwitchLangMenu,
|
||||||
|
isDisplayed(env) {
|
||||||
|
const { availableCompanies } = env.services.Lang;
|
||||||
|
return Object.keys(availableCompanies).length > 1;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
registry.category("systray").add("SwitchLangMenu", systrayItem, { sequence: 1 });
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
|
||||||
|
<t t-name="web.SwitchLangMenu" owl="1">
|
||||||
|
<Dropdown class="'o_switch_Lang_menu d-none d-md-block'" position="'bottom-end'">
|
||||||
|
<t t-set-slot="toggler">
|
||||||
|
<i class="fa fa-building d-lg-none"/>
|
||||||
|
<span class="oe_topbar_name d-none d-lg-block" t-esc="currentLang.name"/>
|
||||||
|
</t>
|
||||||
|
<t t-foreach="Object.values(LangService.availableCompanies).sort((c1, c2) => c1.sequence - c2.sequence)" t-as="Lang" t-key="Lang.id">
|
||||||
|
<t t-call="web.SwitchLangItem">
|
||||||
|
<t t-set="Lang" t-value="Lang" />
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</Dropdown>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
|
||||||
|
<t t-name="web.SwitchLangItem" owl="1">
|
||||||
|
<DropdownItem class="'p-0 bg-white'">
|
||||||
|
<t t-set="isLangSelected" t-value="selectedCompanies.includes(Lang.id)"/>
|
||||||
|
<t t-set="isCurrent" t-value="Lang.id === LangService.currentLang.id"/>
|
||||||
|
<div class="d-flex" data-menu="Lang" t-att-data-Lang-id="Lang.id">
|
||||||
|
<div
|
||||||
|
role="menuitemcheckbox"
|
||||||
|
t-att-aria-checked="isLangSelected ? 'true' : 'false'"
|
||||||
|
t-att-aria-label="Lang.name"
|
||||||
|
t-att-title="(isLangSelected ? 'Hide ' : 'Show ') + Lang.name + ' content.'"
|
||||||
|
tabindex="0"
|
||||||
|
class="border-end toggle_Lang"
|
||||||
|
t-attf-class="{{isCurrent ? 'border-primary' : ''}}"
|
||||||
|
t-on-click.stop="() => this.setLang(Lang.id)">
|
||||||
|
|
||||||
|
<span class="btn btn-light border-0 p-2">
|
||||||
|
<i class="fa fa-fw py-2" t-att-class="isLangSelected ? 'fa-check-square text-primary' : 'fa-square-o'"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
t-att-aria-pressed="isCurrent ? 'true' : 'false'"
|
||||||
|
t-att-aria-label="'Switch to ' + Lang.name "
|
||||||
|
t-att-title="'Switch to ' + Lang.name "
|
||||||
|
tabindex="0"
|
||||||
|
class="d-flex flex-grow-1 align-items-center py-0 log_into ps-2"
|
||||||
|
t-att-class="isCurrent ? 'alert-primary ms-1 me-2' : 'btn btn-light fw-normal border-0'"
|
||||||
|
t-on-click="() => this.logIntoLang(Lang.id)">
|
||||||
|
|
||||||
|
<span
|
||||||
|
class='Lang_label pe-3'
|
||||||
|
t-att-class="isCurrent ? 'text-900 fw-bold' : 'ms-1'">
|
||||||
|
<t t-esc="Lang.name"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DropdownItem>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</templates>
|
||||||
@@ -12,15 +12,21 @@ const userMenuRegistry = registry.category("user_menuitems");
|
|||||||
patch(UserMenu.prototype, "app_odoo_customize.UserMenu", {
|
patch(UserMenu.prototype, "app_odoo_customize.UserMenu", {
|
||||||
setup() {
|
setup() {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
userMenuRegistry.remove("debug");
|
// this.companyService = useService("company");
|
||||||
userMenuRegistry.remove("asset_asset");
|
this.rpc = useService("rpc");
|
||||||
userMenuRegistry.remove("leave_debug");
|
this.orm = useService("orm");
|
||||||
userMenuRegistry.remove("separator0");
|
this.app_show_lang = session.app_show_lang;
|
||||||
|
this.app_lang_list = session.app_lang_list;
|
||||||
|
//todo: 演习 shortCutsItem 中的用法,当前是直接 xml 写了展现
|
||||||
|
|
||||||
|
if (session.app_show_lang) {
|
||||||
|
userMenuRegistry.add("separator1", separator1)
|
||||||
|
}
|
||||||
if (session.app_show_debug) {
|
if (session.app_show_debug) {
|
||||||
userMenuRegistry.add("debug", debugItem)
|
userMenuRegistry.add("debug", debugItem, {'force': true})
|
||||||
.add("asset_asset", activateAssetsDebugging)
|
.add("asset_asset", activateAssetsDebugging, {'force': true})
|
||||||
.add("leave_debug", leaveDebugMode)
|
.add("leave_debug", leaveDebugMode, {'force': true})
|
||||||
.add("separator0", separator8)
|
.add("separator10", separator10)
|
||||||
}
|
}
|
||||||
userMenuRegistry.remove("documentation");
|
userMenuRegistry.remove("documentation");
|
||||||
if (session.app_show_documentation) {
|
if (session.app_show_documentation) {
|
||||||
@@ -34,46 +40,23 @@ patch(UserMenu.prototype, "app_odoo_customize.UserMenu", {
|
|||||||
if (session.app_show_account) {
|
if (session.app_show_account) {
|
||||||
userMenuRegistry.add("odoo_account", odooAccountItem);
|
userMenuRegistry.add("odoo_account", odooAccountItem);
|
||||||
}
|
}
|
||||||
// this.rpc = useService("rpc");
|
|
||||||
// todo: 处理语言列表,rpc取值,同上处理 userMenuRegistry.add("slang_"+语言代码, debugItem(语言代码), env)
|
|
||||||
// todo: 语言图片的处理,正常直接参考 Shortcuts 的处理,直接生成 html代码即可。
|
|
||||||
// Shortcuts不成就可以扩展 @web/webclient/user_menu/user_menu, 参考 CheckBox 的处理。建议直接CheckBox这个类型改,增加个 element.img的处理,选中的语言就是 ischecked的
|
|
||||||
//
|
|
||||||
// return env.services.rpc("/web/action/load", {
|
|
||||||
// action_id: actionID,
|
|
||||||
// additional_context: context,
|
|
||||||
// });
|
|
||||||
/*
|
|
||||||
|
|
||||||
self._rpc({
|
|
||||||
model: 'res.lang',
|
|
||||||
method: 'search_read',
|
|
||||||
domain: [],
|
|
||||||
fields: ['name', 'code'],
|
|
||||||
lazy: false,
|
|
||||||
}).then(function (res) {
|
|
||||||
_.each(res, function (lang) {
|
|
||||||
var a = '';
|
|
||||||
if (lang['code'] === session.user_context.lang) {
|
|
||||||
a = '<i class="fa fa-check"></i>';
|
|
||||||
} else {
|
|
||||||
a = '';
|
|
||||||
}
|
|
||||||
lang_list += '<a role="menuitem" href="#" class="dropdown-item" data-lang-menu="lang" data-lang-id="' + lang['code']
|
|
||||||
+ '"><img class="flag" src="app_odoo_customize/static/src/img/flags/' + lang['code'] + '.png"/>' + lang['name'] + a + '</a>';
|
|
||||||
});
|
|
||||||
lang_list += '<div role="separator" class="dropdown-divider"/>';
|
|
||||||
setTimeout( function() {
|
|
||||||
$('switch-lang').replaceWith(lang_list);
|
|
||||||
}, 1000);
|
|
||||||
})
|
|
||||||
|
|
||||||
*/
|
|
||||||
},
|
},
|
||||||
// getElements() {
|
|
||||||
// var ret = this._super.apply(this, arguments);
|
async setLang(lang_code) {
|
||||||
// return ret;
|
// alert(lang_code);
|
||||||
// },
|
browser.clearTimeout(this.toggleTimer);
|
||||||
|
if (this.user.lang != lang_code) {
|
||||||
|
const res = await this.orm.call("res.users", "write", [
|
||||||
|
session.uid, {'lang': lang_code}
|
||||||
|
]);
|
||||||
|
location.reload();
|
||||||
|
// 调用 action , 要先定义 this.action = useService("action")
|
||||||
|
// this.action.action({
|
||||||
|
// type: 'ir.actions.client',
|
||||||
|
// tag: 'reload_context',
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function debugItem(env) {
|
function debugItem(env) {
|
||||||
@@ -114,12 +97,20 @@ function leaveDebugMode(env) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function separator8() {
|
function separator1() {
|
||||||
return {
|
return {
|
||||||
type: "separator",
|
type: "separator",
|
||||||
sequence: 8,
|
sequence: 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function separator10() {
|
||||||
|
return {
|
||||||
|
type: "separator",
|
||||||
|
sequence: 10,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function documentationItem(env) {
|
function documentationItem(env) {
|
||||||
const documentationURL = session.app_documentation_url;
|
const documentationURL = session.app_documentation_url;
|
||||||
return {
|
return {
|
||||||
@@ -130,7 +121,7 @@ function documentationItem(env) {
|
|||||||
callback: () => {
|
callback: () => {
|
||||||
browser.open(documentationURL, "_blank");
|
browser.open(documentationURL, "_blank");
|
||||||
},
|
},
|
||||||
sequence: 10,
|
sequence: 21,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,10 +132,10 @@ function supportItem(env) {
|
|||||||
id: "support",
|
id: "support",
|
||||||
description: env._t("Support"),
|
description: env._t("Support"),
|
||||||
href: url,
|
href: url,
|
||||||
callback: () => {
|
callback: (ev) => {
|
||||||
browser.open(url, "_blank");
|
browser.open(url, "_blank");
|
||||||
},
|
},
|
||||||
sequence: 20,
|
sequence: 22,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
app_odoo_customize/static/src/webclient/user_menu.xml
Normal file
16
app_odoo_customize/static/src/webclient/user_menu.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
<t t-name="app_odoo_customize.UserMenu" t-inherit="web.UserMenu" t-inherit-mode="extension">
|
||||||
|
<xpath expr="//t[@t-key='element_index']" position="before">
|
||||||
|
<t t-if="app_show_lang">
|
||||||
|
<t t-foreach="app_lang_list" t-as="lang" t-key="lang.id">
|
||||||
|
<DropdownItem dataset="{ lang: lang.id, code: lang.code }" onSelected="() => this.setLang(lang.code)">
|
||||||
|
<img class="flag" t-att-src="'/app_odoo_customize/static/src/img/flags/' + lang['code'] + '.png'"/>
|
||||||
|
<t t-out="lang.name"/>
|
||||||
|
<i class="fa fa-check" t-if="user.lang == lang.code"></i>
|
||||||
|
</DropdownItem>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</xpath>
|
||||||
|
</t>
|
||||||
|
</templates>
|
||||||
@@ -64,6 +64,7 @@
|
|||||||
('after', 'web/static/src/views/**/*', 'app_web_enterprise/static/src/scss/views_style.scss'),
|
('after', 'web/static/src/views/**/*', 'app_web_enterprise/static/src/scss/views_style.scss'),
|
||||||
'app_web_enterprise/static/src/components/*/*.xml',
|
'app_web_enterprise/static/src/components/*/*.xml',
|
||||||
'app_web_enterprise/static/src/webclient/**/*.xml',
|
'app_web_enterprise/static/src/webclient/**/*.xml',
|
||||||
|
'app_web_enterprise/static/src/xml/**/*.xml',
|
||||||
# 'app_web_enterprise/static/src/xml/base.xml',
|
# 'app_web_enterprise/static/src/xml/base.xml',
|
||||||
],
|
],
|
||||||
# 这里是改样式,要 after处理
|
# 这里是改样式,要 after处理
|
||||||
|
|||||||
10
app_web_enterprise/static/src/xml/form_label.xml
Normal file
10
app_web_enterprise/static/src/xml/form_label.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
<t t-name="app_web_enterprise.FormLabel" t-inherit="web.FormLabel" t-inherit-mode="extension">
|
||||||
|
<xpath expr="//label" position="replace">
|
||||||
|
<label class="o_form_label" t-att-for="props.id" t-att-class="className" >
|
||||||
|
<t t-esc="props.string"/><sup class="btn-link p-1" t-if="hasTooltip" t-att="{'data-tooltip-template': 'web.FieldTooltip', 'data-tooltip-info': tooltipInfo, 'data-tooltip-touch-tap-to-show': 'true'}">*</sup>
|
||||||
|
</label>
|
||||||
|
</t>
|
||||||
|
|
||||||
|
</templates>
|
||||||
Reference in New Issue
Block a user