diff --git a/source/app/models/db.py b/source/app/models/db.py index 291b315..7d19605 100644 --- a/source/app/models/db.py +++ b/source/app/models/db.py @@ -62,7 +62,7 @@ class StorageEngine(object): return main.NivelesEducativos.get_all() def _get_titlelogin(self, values): - return main.get_title_app(2) + return main.get_title_app() def _get_canopenpre(self, values): return main.PreFacturasDetalle.can_open(values['id']) diff --git a/source/app/models/main.py b/source/app/models/main.py index 48d806e..8c19a7a 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -10800,10 +10800,11 @@ def get_sat_productos(key): def get_title_app(by=1): html = { 1: '{}', - 2: 'Bienvenido a {}', + 2: '{}', 3: '{}', } - return html[by].format(TITLE_APP) + # ~ return html[by].format(TITLE_APP) + return TITLE_APP def test_correo(values): diff --git a/source/app/settings.py b/source/app/settings.py index 7058581..371dd36 100644 --- a/source/app/settings.py +++ b/source/app/settings.py @@ -30,11 +30,6 @@ try: except ImportError: DEFAULT_PASSWORD = 'salgueiro3.3' -try: - from conf import TITLE_APP -except ImportError: - TITLE_APP = 'Empresa Libre' - try: from conf import NO_HTTPS except ImportError: @@ -42,10 +37,11 @@ except ImportError: DEBUG = DEBUG +TITLE = 'Empresa Libre' VERSION = '2.0.0' EMAIL_SUPPORT = ('soporte@empresalibre.mx',) -TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION) +TITLE_APP = f'{TITLE} v{VERSION}' BASE_DIR = os.path.abspath(os.path.dirname(__file__)) COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db')) diff --git a/source/static/js/controller/languages.json b/source/static/js/controller/languages.json new file mode 100644 index 0000000..473a149 --- /dev/null +++ b/source/static/js/controller/languages.json @@ -0,0 +1,32 @@ +{ + "en": { + "test": "Test", + "languages": "Languages", + "welcome": "Welcome to ", + "access": "Access to system", + "user": "User", + "password": "Password", + "login": "Login", + "start": "Home" + }, + "es": { + "test": "Prueba", + "languages": "Idiomas", + "welcome": "Bienvenido a ", + "access": "Acceso al sistema", + "user": "Usuario", + "password": "Contraseña", + "login": "Iniciar Sesión", + "start": "Inicio" + }, + "zh": { + "test": "测试", + "languages": "语言", + "welcome": "欢迎来到 ", + "access": "进入系统", + "user": "用户", + "password": "密码", + "login": "登录", + "start": "首页" + } +} diff --git a/source/static/js/controller/multilang.js b/source/static/js/controller/multilang.js new file mode 100644 index 0000000..bd2d9fb --- /dev/null +++ b/source/static/js/controller/multilang.js @@ -0,0 +1,85 @@ +// MultiLang - BdR 2016 +// JavaScript object to handle multilanguage, load phrases from JSON etc. + +var MultiLang = function(url, lang, onload) +{ + // variables + this.phrases = {}; + + // language code from parameter or if null then default to browser language preference + // Keep only first two characters, for example 'en-US' -> 'en', or 'nl-NL' -> 'nl' etc. + this.selectedLanguage = (lang || navigator.language || navigator.userLanguage).substring(0, 2); + + // onLoad callback function, call after loading JSON + this.onLoad = onload; + + // load json from url + if (typeof url !== 'undefined') { + var obj = this; + var req = new XMLHttpRequest(); + + // NOTE: will load asynchronously! + req.open("GET", url, true); + //req.setRequestHeader("User-Agent", navigator.userAgent); + req.onreadystatechange = function (evt) { + if (evt.target.readyState == 4 && evt.target.status == 200) // status == 200, do not allow "Cross origin requests" + //if (evt.target.readyState == 4)// TESTING allow "Cross origin requests" to load from local harddisk + { + // load translations + this.phrases = JSON.parse( evt.target.responseText ); + + // verify that the currently selected language exists in the translations + this.setLanguage(this.selectedLanguage); + + // do callback when loading JSON is ready + if (this.onLoad) { + this.onLoad(); + } + + }; + }.bind(obj); // NOTE: bind onreadyfunction to MultiLang instead of XMLHttpRequest, so MultiLang.phrases will be set instead of added to XMLHttpRequest + req.addEventListener("error", function(e) { + console.log('MultiLang.js: Error reading json file.'); + }, false); + + req.send(null); + }; + + this.setLanguage = function(langcode) { + // check if language code does not exist in available translations in json file + // For example, available translated texts in json are 'en' and 'fr', but client language is 'es' + if (!this.phrases.hasOwnProperty(langcode)) { + // doesn't exist so default to the first available language, i.e. the top-most language in json file + + // NOTE: the order of properties in a JSON object are not *guaranteed* to be the same as loading time, + // however in practice all browsers do return them in order + for (var key in this.phrases) { + if (this.phrases.hasOwnProperty(key)) { + langcode = key; // take the first language code + break; + }; + }; + }; + + // set as selected language code + this.selectedLanguage = langcode; + }; + + this.get = function(key) { + // get key phrase + var str; + + // check if any languages were loaded + if (this.phrases[this.selectedLanguage]) str = this.phrases[this.selectedLanguage][key]; + + // if key does not exist, return the literal key + str = (str || key); + + return str; + }; + + this.get_default = function(){ + var lang = (navigator.language || navigator.userLanguage).substring(0, 2); + return lang + }; +} diff --git a/source/static/js/ui/login.js b/source/static/js/ui/login.js index a9f7271..efa39a6 100644 --- a/source/static/js/ui/login.js +++ b/source/static/js/ui/login.js @@ -1,4 +1,10 @@ +var opt_languages = [ + {id: 'es', value: 'Español'}, + {id: 'en', value: 'English'}, + {id: 'zh', value: '繁体中文'}, +] + var msg_rfc = 'El RFC es requerido' var msg_user = 'El usuario es requerido' var msg_pass = 'La contraseña es requerida' @@ -11,20 +17,23 @@ var form_controls = [ {view: 'text', label: 'Contraseña', id: 'txt_contra', name: 'contra', type: 'password', required: true, labelPosition: 'top', invalidMessage: msg_pass}, - {margin: 10, cols:[{}, {view: 'button', value: 'Iniciar Sesión', + {margin: 10, cols:[{}, {view: 'button', value: 'Iniciar Sesión', id: 'cmd_login', click: 'validate_login', hotkey: 'enter'}, {}]} ] var ui_login = { rows: [ - {maxHeight: 50}, + {maxHeight: 25}, + {cols: [{}, {}, {view: 'richselect', id: 'lst_languages', label: 'Idiomas', + width: 200, labelAlign: "right", options: opt_languages} ]}, + {maxHeight: 25}, {view: 'template', id: 'title_login', template: '', maxHeight: 50, css: 'login_header'}, {maxHeight: 50}, {cols: [{}, {type: 'space', padding: 5, rows: [ - {view: 'template', type: 'header', + {view: 'template', type: 'header', id: 'header_access', template: 'Acceso al sistema'}, { container: 'form_login', diff --git a/source/templates/base.html b/source/templates/base.html index 5e58d40..e2b2c07 100644 --- a/source/templates/base.html +++ b/source/templates/base.html @@ -8,6 +8,7 @@ + @@ -22,6 +23,7 @@ <%block name="content"/> diff --git a/source/templates/login.html b/source/templates/login.html index 8df91de..f998afb 100644 --- a/source/templates/login.html +++ b/source/templates/login.html @@ -34,12 +34,37 @@ function validate_login(){ }); }; -webix.ready(function(){ - webix.ui(ui_login); +function lst_languages_change(nv, ov){ + multilang.setLanguage(nv) + var html_font = '' + var html_font_close = '' + webix.ajax().get("/values/titlelogin", function(text, data, xhr){ var value = data.json(); - $$("title_login").setHTML(value); + + $$('lst_languages').define('label', multilang.get('languages')) + $$('lst_languages').refresh() + + var html = html_font + multilang.get('welcome') + value + html_font_close + $$('title_login').setHTML(html); + + html = html_font + multilang.get('access') + html_font_close + $$('header_access').setHTML(html) + + $$('txt_usuario').define('label', multilang.get('user')) + $$('txt_usuario').refresh() + $$('txt_contra').define('label', multilang.get('password')) + $$('txt_contra').refresh() + $$('cmd_login').setValue(multilang.get('login')) }) +} + +webix.ready(function(){ + webix.ui(ui_login); + + $$('lst_languages').attachEvent('onChange', lst_languages_change) + $$('lst_languages').setValue(multilang.get_default()) + $$("txt_rfc").focus(); });