From 6b377db8918e335d52f1baa5f8f929ec0319dc51 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Thu, 16 Jul 2015 17:03:00 +0200 Subject: [PATCH 01/57] [WIP] port without changes from 7.0 branch. Instable version. --- web_dashboard_tile/__init__.py | 26 ++ web_dashboard_tile/__openerp__.py | 92 +++++++ web_dashboard_tile/demo/res_groups.yml | 25 ++ web_dashboard_tile/demo/tile_tile.yml | 33 +++ web_dashboard_tile/i18n/fr.po | 220 +++++++++++++++++ .../i18n/web_dashboard_tile.pot | 232 ++++++++++++++++++ .../7.0.1.0/post-migration-color.py | 48 ++++ .../security/ir.model.access.csv | 2 + web_dashboard_tile/security/rules.xml | 13 + web_dashboard_tile/static/src/css/tile.css | 44 ++++ web_dashboard_tile/static/src/img/avg.png | Bin 0 -> 340 bytes web_dashboard_tile/static/src/img/icon.png | Bin 0 -> 1044 bytes web_dashboard_tile/static/src/img/max.png | Bin 0 -> 264 bytes web_dashboard_tile/static/src/img/median.png | Bin 0 -> 287 bytes web_dashboard_tile/static/src/img/min.png | Bin 0 -> 283 bytes .../src/img/screenshot_action_click.png | Bin 0 -> 24751 bytes .../static/src/img/screenshot_dashboard.png | Bin 0 -> 45633 bytes web_dashboard_tile/static/src/img/sum.png | Bin 0 -> 305 bytes web_dashboard_tile/static/src/js/custom_js.js | 105 ++++++++ .../static/src/xml/custom_xml.xml | 12 + web_dashboard_tile/tile.py | 209 ++++++++++++++++ web_dashboard_tile/view/tile.xml | 120 +++++++++ 22 files changed, 1181 insertions(+) create mode 100644 web_dashboard_tile/__init__.py create mode 100644 web_dashboard_tile/__openerp__.py create mode 100644 web_dashboard_tile/demo/res_groups.yml create mode 100644 web_dashboard_tile/demo/tile_tile.yml create mode 100644 web_dashboard_tile/i18n/fr.po create mode 100644 web_dashboard_tile/i18n/web_dashboard_tile.pot create mode 100644 web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py create mode 100644 web_dashboard_tile/security/ir.model.access.csv create mode 100644 web_dashboard_tile/security/rules.xml create mode 100644 web_dashboard_tile/static/src/css/tile.css create mode 100644 web_dashboard_tile/static/src/img/avg.png create mode 100644 web_dashboard_tile/static/src/img/icon.png create mode 100644 web_dashboard_tile/static/src/img/max.png create mode 100644 web_dashboard_tile/static/src/img/median.png create mode 100644 web_dashboard_tile/static/src/img/min.png create mode 100644 web_dashboard_tile/static/src/img/screenshot_action_click.png create mode 100644 web_dashboard_tile/static/src/img/screenshot_dashboard.png create mode 100644 web_dashboard_tile/static/src/img/sum.png create mode 100644 web_dashboard_tile/static/src/js/custom_js.js create mode 100644 web_dashboard_tile/static/src/xml/custom_xml.xml create mode 100644 web_dashboard_tile/tile.py create mode 100644 web_dashboard_tile/view/tile.xml diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py new file mode 100644 index 000000000..9ad11b3e4 --- /dev/null +++ b/web_dashboard_tile/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2013 OpenERP s.a. (). +# Copyright (C) 2014 initOS GmbH & Co. KG (). +# Copyright (C) 2015-Today GRAP +# Author Markus Schneider +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import tile diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py new file mode 100644 index 000000000..d0f8cf416 --- /dev/null +++ b/web_dashboard_tile/__openerp__.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2013 OpenERP s.a. (). +# Copyright (C) 2014 initOS GmbH & Co. KG (). +# Author Markus Schneider +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + "name": "Dashboard Tile", + "summary": "Add Tiles to Dashboard", + "version": "1.0", + "depends": [ + 'web', + 'board', + 'mail', + 'web_widget_color', + ], + 'author': "initOS GmbH & Co. KG,GRAP,Odoo Community Association (OCA)", + "category": "", + 'license': 'AGPL-3', + "description": """ +Add Tiles to Dashboard +====================== +Features: +--------- +module to give you a dashboard where you can configure tile from any view +and add them as short cut. + +* Tile can be: + * displayed only for a user; + * global for all users (In that case, some tiles will be hidden if + the current user doesn't have access to the given model); +* The tile displays items count of a given model restricted to a given domain; +* Optionnaly, the tile can display the result of a function of a field; + * Function is one of sum/avg/min/max/median; + * Field must be integer or float; + +Screenshot: +----------- +* Dashboad sample, displaying Sale Orders to invoice: +.. image:: web_dashboard_tile/static/src/img/screenshot_dashboard.png +* Tree view displayed when user click on the tile: +.. image:: web_dashboard_tile/static/src/img/screenshot_action_click.png + + +Kown issues/limits: +------------------- +* can not edit tile from dashboard (color, sequence, function, ...); +* context are ignored; +* date filter can not be relative; +* combine domain of menue and filter so can not restore origin filter; + +possible future improvments: +---------------------------- +* support context_today; +* add icons; +* support client side action (like inbox); + """, + 'data': [ + 'view/tile.xml', + 'security/ir.model.access.csv', + 'security/rules.xml', + ], + 'css': [ + 'static/src/css/tile.css', + ], + 'demo': [ + 'demo/res_groups.yml', + 'demo/tile_tile.yml', + ], + 'js': [ + 'static/src/js/custom_js.js', + ], + 'qweb': [ + 'static/src/xml/custom_xml.xml', + ], +} diff --git a/web_dashboard_tile/demo/res_groups.yml b/web_dashboard_tile/demo/res_groups.yml new file mode 100644 index 000000000..735437c5c --- /dev/null +++ b/web_dashboard_tile/demo/res_groups.yml @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +- !record {model: res.groups, id: base.group_no_one}: + users: + - base.user_root diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml new file mode 100644 index 000000000..c40b5903d --- /dev/null +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +- !record {model: tile.tile, id: installed_modules}: + name: Installed Modules + model_id: base.model_ir_module_module + domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']]] + action_id: base.open_module_tree + +- !record {model: tile.tile, id: installed_OCA_modules}: + name: Installed OCA Modules + model_id: base.model_ir_module_module + domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']], ['author', 'ilike', 'Odoo Community Association (OCA)']] + action_id: base.open_module_tree diff --git a/web_dashboard_tile/i18n/fr.po b/web_dashboard_tile/i18n/fr.po new file mode 100644 index 000000000..6bb700fa3 --- /dev/null +++ b/web_dashboard_tile/i18n/fr.po @@ -0,0 +1,220 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-04-10 01:04+0000\n" +"PO-Revision-Date: 2015-04-10 01:04+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_dashboard_tile +#: field:tile.tile,action_id:0 +msgid "Action" +msgstr "Action" + +#. module: web_dashboard_tile +#: field:tile.tile,active:0 +msgid "Active" +msgstr "Actif" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Average" +msgstr "Moyenne" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:82 +#, python-format +msgid "Average value of '%s'" +msgstr "Valeur moyenne du champ '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,color:0 +msgid "Background color" +msgstr "Couleur de fond" + +#. module: web_dashboard_tile +#: field:tile.tile,computed_value:0 +msgid "Computed Value" +msgstr "Valeur calculée" + +#. module: web_dashboard_tile +#: field:tile.tile,count:0 +msgid "Count" +msgstr "Quantité" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "Créer" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "Tableau de bord" + +#. module: web_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "Indicateur de tableau de bord" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Dashboard tiles" +msgstr "Indicateurs de tableau de bord" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Delete" +msgstr "Supprimer" + +#. module: web_dashboard_tile +#: field:tile.tile,domain:0 +msgid "Domain" +msgstr "Domaine" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Edit..." +msgstr "Editer..." + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#, python-format +msgid "Error" +msgstr "Erreur" + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please select a field of the selected model." +msgstr "Erreur ! Veuillez sélectioner un champ qui correspond au modèle." + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please set both fields: 'Field' and 'Function'." +msgstr "Erreur ! Veuillez renseigner les deux champs : 'Champ' et 'Fonction'." + +#. module: web_dashboard_tile +#: field:tile.tile,field_id:0 +msgid "Field" +msgstr "Champ" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#, python-format +msgid "Filter name is required." +msgstr "Le nom du filtre est requis." + +#. module: web_dashboard_tile +#: field:tile.tile,font_color:0 +msgid "Font Color" +msgstr "Couleur du texte" + +#. module: web_dashboard_tile +#: field:tile.tile,field_function:0 +msgid "Function" +msgstr "Fonction" + +#. module: web_dashboard_tile +#: field:tile.tile,helper:0 +msgid "Helper Text" +msgstr "Texte Descriptif" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Maximum" +msgstr "Maximum" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:76 +#, python-format +msgid "Maximum value of '%s'" +msgstr "Valeur maximale du champ '%s'" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Median" +msgstr "Médiane" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:85 +#, python-format +msgid "Median value of '%s'" +msgstr "Valeur médian du champ '%s'" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Minimum" +msgstr "Minimum" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:73 +#, python-format +msgid "Minimum value of '%s'" +msgstr "Valeur minimale du champ '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,model_id:0 +msgid "Model" +msgstr "Modèle" + +#. module: web_dashboard_tile +#: field:tile.tile,sequence:0 +msgid "Sequence" +msgstr "Séquence" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#, python-format +msgid "Success" +msgstr "Succès" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Sum" +msgstr "Somme" + +#. module: web_dashboard_tile +#: field:tile.tile,name:0 +msgid "Tile Name" +msgstr "Nom de l'indicateur" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#, python-format +msgid "Tile is created" +msgstr "L'indicateur a été créé" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "Indicateur :" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:79 +#, python-format +msgid "Total value of '%s'" +msgstr "Somme du champ '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,user_id:0 +msgid "User" +msgstr "Utilisateur" diff --git a/web_dashboard_tile/i18n/web_dashboard_tile.pot b/web_dashboard_tile/i18n/web_dashboard_tile.pot new file mode 100644 index 000000000..0e89f8cae --- /dev/null +++ b/web_dashboard_tile/i18n/web_dashboard_tile.pot @@ -0,0 +1,232 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-04-10 01:03+0000\n" +"PO-Revision-Date: 2015-04-10 01:03+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_dashboard_tile +#: field:tile.tile,action_id:0 +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,active:0 +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:82 +#, python-format +msgid "Average value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,color:0 +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,computed_value:0 +msgid "Computed Value" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,count:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Delete" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,domain:0 +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Edit..." +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please select a field of the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please set both fields: 'Field' and 'Function'." +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,field_id:0 +msgid "Field" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,font_color:0 +msgid "Font Color" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,field_function:0 +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,helper:0 +msgid "Helper Text" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:76 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:85 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:73 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,model_id:0 +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,name:0 +msgid "Tile Name" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:79 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: field:tile.tile,user_id:0 +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: code:_description:0 +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#, python-format +msgid "tile.tile" +msgstr "" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "í" +msgstr "" diff --git a/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py b/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py new file mode 100644 index 000000000..f8c33840e --- /dev/null +++ b/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +COLOR_NUMERIC_TO_RVB = { + 0: '#006015', + 1: '#CD2513', + 2: '#CDC713', + 3: '#57158A', + 4: '#0E9B2D', + 5: '#7F0C00', + 6: '#7F7B00', + 7: '#320455', + 8: '#CD6E13', + 9: '#0E6C7E', +} + + +def migrate_color(cr): + for old, new in COLOR_NUMERIC_TO_RVB.iteritems(): + cr.execute(""" + UPDATE tile_tile + SET color='%s', font_color='#FFFFFF' + WHERE color='%s' + """ % (new, old)) + + +def migrate(cr, installed_version): + migrate_color(cr) diff --git a/web_dashboard_tile/security/ir.model.access.csv b/web_dashboard_tile/security/ir.model.access.csv new file mode 100644 index 000000000..3229b4ea2 --- /dev/null +++ b/web_dashboard_tile/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +tile_user,tile_user,model_tile_tile,base.group_user,1,1,1,1 diff --git a/web_dashboard_tile/security/rules.xml b/web_dashboard_tile/security/rules.xml new file mode 100644 index 000000000..8d653b70c --- /dev/null +++ b/web_dashboard_tile/security/rules.xml @@ -0,0 +1,13 @@ + + + + + + tile.owner + + + [('user_id','in',[False,user.id])] + + + + diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css new file mode 100644 index 000000000..1d057ceea --- /dev/null +++ b/web_dashboard_tile/static/src/css/tile.css @@ -0,0 +1,44 @@ +.openerp .oe_kanban_view .oe_dashbaord_tile{ + width: 150px; + height: 150px; + border: 0; + border-radius: 0; +} + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label, +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value, +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value, +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value { + width: 140px; + text-align: center; +} + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ + padding: 5px; + font-size: 15px; +} + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ + font-size: 52px; + font-weight: bold; + position: absolute; + left: 5px; + bottom: 5px; +} + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ + font-size: 38px; + font-weight: bold; + position: absolute; + left: 5px; + bottom: 30px; +} + +.openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value{ + font-size: 18px; + font-weight: bold; + position: absolute; + right: 10px; + bottom: 5px; + font-style: italic; +} diff --git a/web_dashboard_tile/static/src/img/avg.png b/web_dashboard_tile/static/src/img/avg.png new file mode 100644 index 0000000000000000000000000000000000000000..2f534e932c820d634b47bd8f97312d9329204001 GIT binary patch literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m=s)o-U3d9-U7^4+=IJ2*gO--_~HV!2e>uS%PF#Guu4HsE%_hVl#Mu zg>hXFI?(RdBEZ!7@!^j3(K|M5ub#~Kqts%Xor~t#Bk6%6mb%eQ3<7P6>mOUNG3+p7 zP5H5_q0nX1nYCODpU$}cxyUywEl-Dmp+z9h_?Xn(%$mtF*>l-d8W(SEmb{zvh+Sga zX`8v1)W84wW4oYZMbRUZ;9|y8vS;))*N6W*y+(V9RuSW=j(4+d&pl@B+Zz)-mpL$A zQ-5~AWyby!7M~|IFG@&c?|!|z@@C-^;kr%Dx2xJOYaCcO+j_}shX+q(GyEd1pPzZs jcP+E$o4=p6KQb(z=J|E&+*QoL5Mc0h^>bP0l+XkKyXJ@& literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/src/img/icon.png b/web_dashboard_tile/static/src/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fb6b1b2987d393c31aab5be90542687029ca8223 GIT binary patch literal 1044 zcmeAS@N?(olHy`uVBq!ia0vp^eIU%i1|*;VHQ)eJY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP~6Tb+HMO2(&6i`UA#5JPCIX^cyHLrxhxhOTUBsE2$ zJhLQ2!QIn0AiR-JoPmM4#?!?yq~g}wyS^DRr4k1omZxu?oi}Oe#)IugmyDL zRFG+DE^x5mU6zM_0ek>)%)Oa@Fnc)3_$8nBP01 zFo(C~ckK2f7ay-b!rcGP=<$Yao6l@^W>0!?_xYmygzkqkR_}iNZf@b19|3PFpTwOm zytXXhO{cQ_o*h{xQ#XFhFuir?;irS!B$obrs_(nmxcK8!_2rK~_wVa1tG>9j>vUP1 zzul*wOOMA*OEa{p(cAa)&G8lg!n#j9YTNCuJSRJ6lbLLM{V(S^vj0r89t#`V8cIiR z=auM-j9Y!PZ@&NB-uL??`naF}@9N|hPtGe-y!G~|=z9t7<=sm&#h$y>_g_|bd-O-Y z-es+oWW9fEm)qV<%X6n@^@h!{_*SdpsrPT@Kl5k$SCxG)znk&?&(G_EetSiO>(9AN zOPgKvRAo+I?5ay1vopj0y?gf<9M%GSkg!Gy^+Sn|D<)*yy2nmB;+=1|_tojT-)!4l z7Vh|zSNG$-%eemmlBv zcX#-oU;gUu$v>WCToGTlp8Y}Ws%w&dlit74d!sA5_(HV7~}yde<+`pLkw9 zd{0z}MMP*~=us(C>9-Y+AGB|LeC=T09@*%{_j;mAm2RzdeVC(Gy!msWHg z2CB#UBqy#D{Q9%4z-)5ZW?AFOo6}?j_zpRO5>P_{m<9FaAx2<|TDLc5o8*6P@pB;g z3tx@T&8*&5{4nJ z@ErkR#;MwT(m=sgo-U3d9-YYv60aI2MzL)@Y5d1se09}{11Fqxxg~%=>)rq6&DJ6_ zL2QW`D>4u6Ub}>5aS7mj+4!+_N2QL``(Pu9bejH=Gnb^no z;V5GykZOySIZ!#}7^Co-9d1ma{42wsKW1Slo^Q_AzJ0=HpsN`?UHx3vIVCg!0IU#M AU;qFB literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/src/img/median.png b/web_dashboard_tile/static/src/img/median.png new file mode 100644 index 0000000000000000000000000000000000000000..61d5dd7c264544941b4de07c7c19da7391b485b9 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m=t3o-U3d9-YYv60aI2MzL+(vgMDv`0AA_6H^vWW90#Yt5>fUlx1gY zGlPJzsqO)`j6BAhjxD-pR%S6WGk-I1XIIwXyY)me;BZYDFEewHKwu6~oZ0#4-}-{G zcBR63>Y5$*bYqVeTs=7H;RL&nw>C7&v9&-crN|A!;5+s)%rtX1_le3eJ-29 zs`9Jhi-OWc_AlMcNvFlS9yQF^lqzwAv6JClyi?%;7Vl*q58|`9;|^zMWvvK%{+NY9 Y4nJ z@ErkR#;MwT(m=tzo-U3d9-UXG8uBqI3b@|S+0*X6VcTb;dj~g6IpCXP(^kIW8{0Rt zZrQ@fNv<1rJu=XNd^C^60O! zL;j>i8&aRu1Tih)nV5w&0^IwjKl-Pe_ss_f z5$PWY?~5mbQRw@3L|Z8h2Pi1i-hZsniS($1?+5W6#nl~EY)l+o4D5}eOs#Ez#*7Yz z_QuB64rVrv=dd6_C@3;0X))m+t{EqpE}lQc7ksl@Ibva?4~X+aasg6GozXB!xE^l| zp*mft&U*BmC+!h`$!LDzib2!*Ph0v6?2otO`Tn5^&;3XH9@PyUo0<6CKzYX3SXfglv_>REl`P1j%`g&^lCB2Ycup3pqh8wDV$HRgxW=^V@+B(;o3tyM=!*X{K;zs` zJNsjgQFV3f(Zsg=L$tI8Gp{c_jb$3mk&)Jty>i0;9*Xd0qsz{qit8-1&$j^^? zE*z^v9GNT5?><&rhVW9ZN+-8`w^=3=JXITqS*ptUUF~XEF6QfsGlO9kp}a>j1it4x zLVl!CY9yT6sH_4=Qkkz zy(h^CnW*25+B9~rZv1pjFmcMob9nxa>*DG_mx6c^%i%z=A&B{`Ii1-#kO#cOpXF)9 z62$=L&akcie0WZFr5;`|F{>a+RU&ZZ93ntxFf>Gqg^NoZD}tR+efnI4cf06nQobHl zD~{VzUoLam4@$Y4&WwcU)4D0$6&c{|VsmtIU&LABNw~$fq}zbg`l(_z>3f)0OnO2^ zc@jr<{tQ*1VgqAEB*2gxp+a2z+wY4tMg+|3e9;<9CJB#k#J5V2ASpybkY~zDc4jwe z>a&!^N>l~oiIv_RA!b%fGS}Pa_BZX8ELyKo>Im-o;3`=WpJOPH|H% zc6B zC(JnZ65Vtpp6oB&$C*E*_RvT#AhT{pXY@U((-}Pq9kC;D1y>H(gl*wCeBRqLXhj## zN5ngP%H~VAuH)^lEIKnp3FQ&qqjwdiA$a{pG(veVItW3j5sM#YN!^*zbY?M%5Ncdd znFR&?Q24$s?E@7UJxDA;Zj~iMgwEWw*yy=7(Qy|Jk?|~?Jlp|+^_6xrKBflF_`|GO z8l&2Y3a9h!+{eQszwWO8c{dH^b07BaMUxVL;f8aKeX=~yLJ@T1As*j8saujwZw<@c zX&~}hipubr^;<((iD_pFL2FGT2XaRKHs%M};yZ+Eu|AX>A1KMN$YIXhC?{aMYdgy< z4dr|I_g~iH>Oa%=wqe#}J34W7h_NPpkAJY1P4L12s5W^8CMWlghp+9UjgwKfa2ygy zYOC!S$`O)$@!72`yZI(EF~VJ|f>AgSFtFV>b)e29n8#Wb@_5~_S^X%YJ#iJ|cHWrD zt)fzO`WR%V;60wp$iz!J6G5c~+I$9LPYYKGu%0DMn*tH(e^)e`0Rq(8gmC5 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 literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/src/img/screenshot_dashboard.png b/web_dashboard_tile/static/src/img/screenshot_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..9cbdeecd3d601ffbea9c197ed5c71d2480371613 GIT binary patch literal 45633 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 literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js new file mode 100644 index 000000000..53a2bd0e0 --- /dev/null +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -0,0 +1,105 @@ +// @@@ web_dashboard_tile custom JS @@@ +//############################################################################# +// +// Copyright (C) 2010-2013 OpenERP s.a. () +// Copyright (C) 2014 initOS GmbH & Co. KG () +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//############################################################################# + +openerp.web_dashboard_tile = function (instance) +{ +var QWeb = instance.web.qweb, + _t = instance.web._t, + _lt = instance.web._lt; +_.mixin({ + sum: function (obj) { return _.reduce(obj, function (a, b) { return a + b; }, 0); } +}); + var module = instance.board.AddToDashboard; + + module.include({ + start: function () { + this._super(); + var self = this; + this.$('#add_dashboard_tile').on('click', this, function (){ + self.save_tile(); + }) + }, + render_data: function(dashboard_choices){ + var selection = instance.web.qweb.render( + "SearchView.addtodashboard.selection", { + selections: dashboard_choices}); + this.$("form input").before(selection) + }, + save_tile: function () { + var self = this; + var getParent = this.getParent(); + var view_parent = this.getParent().getParent(); + if (! view_parent.action || ! this.$el.find("select").val()) { + this.do_warn("Can't find dashboard action"); + return; + } + + var $name = this.$('#dashboard_tile_new_name'); + + this.tile = new instance.web.Model('tile.tile'); + + var private_filter = !this.$('#oe_searchview_custom_public').prop('checked'); + if (_.isEmpty($name.val())){ + this.do_warn(_t("Error"), _t("Filter name is required.")); + return false; + } + var search = this.view.build_search_data(); + var context = new instance.web.CompoundContext(getParent.dataset.get_context() || []); + var domain = new instance.web.CompoundDomain(getParent.dataset.get_domain() || []); + _.each(search.contexts, context.add, context); + _.each(search.domains, domain.add, domain); + + var c = instance.web.pyeval.eval('context', context); + for(var k in c) { + if (c.hasOwnProperty(k) && /^search_default_/.test(k)) { + delete c[k]; + } + } + // TODO: replace this 6.1 workaround by attribute on + c.dashboard_merge_domains_contexts = false; + var d = instance.web.pyeval.eval('domain', domain); + + context.add({ + group_by: instance.web.pyeval.eval('groupbys', search.groupbys || []) + }); + // Don't save user_context keys in the custom filter, otherwise end + // up with e.g. wrong uid or lang stored *and used in subsequent + // reqs* + var ctx = context; + _(_.keys(instance.session.user_context)).each(function (key) { + delete ctx[key]; + }); + var filter = { + name: $name.val(), + user_id: private_filter ? instance.session.uid : false, + model_id: self.view.model, + //context: context, + domain: d, + action_id: view_parent.action.id, + }; + // FIXME: current context? + return self.tile.call('add', [filter]).done(function (id) { + self.do_warn(_t("Success"), _t("Tile is created")); + }); + + } + }); +} diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml new file mode 100644 index 000000000..3e0c23167 --- /dev/null +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -0,0 +1,12 @@ + + + + +
+ + + +
+
+
+
diff --git a/web_dashboard_tile/tile.py b/web_dashboard_tile/tile.py new file mode 100644 index 000000000..922438750 --- /dev/null +++ b/web_dashboard_tile/tile.py @@ -0,0 +1,209 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010-2013 OpenERP s.a. (). +# Copyright (C) 2014 initOS GmbH & Co. KG (). +# Copyright (C) 2015-Today GRAP +# Author Markus Schneider +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields +from openerp.tools.translate import _ + + +class tile(orm.Model): + _name = 'tile.tile' + _order = 'sequence, name' + + def median(self, aList): + # https://docs.python.org/3/library/statistics.html#statistics.median + # TODO : refactor, using statistics.median when Odoo will be available + # in Python 3.4 + even = (0 if len(aList) % 2 else 1) + 1 + half = (len(aList) - 1) / 2 + return sum(sorted(aList)[half:half + even]) / float(even) + + def _get_tile_info(self, cr, uid, ids, fields, args, context=None): + ima_obj = self.pool['ir.model.access'] + res = {} + records = self.browse(cr, uid, ids, context=context) + for r in records: + res[r.id] = { + 'active': False, + 'count': 0, + 'computed_value': 0, + 'helper': '', + } + if ima_obj.check( + cr, uid, r.model_id.model, 'read', False, context): + # Compute count item + model = self.pool.get(r.model_id.model) + count = model.search_count( + cr, uid, eval(r.domain), context=context) + res[r.id].update({ + 'active': True, + 'count': count, + }) + + # Compute datas for field_id depending of field_function + if r.field_function and r.field_id and count != 0: + ids = model.search( + cr, uid, eval(r.domain), context=context) + vals = [x[r.field_id.name] for x in model.read( + cr, uid, ids, [r.field_id.name], context=context)] + desc = r.field_id.field_description + if r.field_function == 'min': + value = min(vals) + helper = _("Minimum value of '%s'") % desc + elif r.field_function == 'max': + value = max(vals) + helper = _("Maximum value of '%s'") % desc + elif r.field_function == 'sum': + value = sum(vals) + helper = _("Total value of '%s'") % desc + elif r.field_function == 'avg': + value = sum(vals) / len(vals) + helper = _("Average value of '%s'") % desc + elif r.field_function == 'median': + value = self.median(vals) + helper = _("Median value of '%s'") % desc + res[r.id].update({ + 'computed_value': value, + 'helper': helper, + }) + return res + + def _search_active(self, cr, uid, obj, name, arg, context=None): + ima_obj = self.pool['ir.model.access'] + ids = [] + cr.execute(""" + SELECT tt.id, im.model + FROM tile_tile tt + INNER JOIN ir_model im + ON tt.model_id = im.id""") + for result in cr.fetchall(): + if (ima_obj.check(cr, uid, result[1], 'read', False) == + arg[0][2]): + ids.append(result[0]) + return [('id', 'in', ids)] + + _columns = { + 'name': fields.char('Tile Name'), + 'model_id': fields.many2one('ir.model', 'Model', required=True), + 'user_id': fields.many2one('res.users', 'User'), + 'domain': fields.text('Domain'), + 'action_id': fields.many2one('ir.actions.act_window', 'Action'), + 'count': fields.function( + _get_tile_info, type='int', string='Count', + multi='tile_info', readonly=True), + 'computed_value': fields.function( + _get_tile_info, type='float', string='Computed Value', + multi='tile_info', readonly=True), + 'helper': fields.function( + _get_tile_info, type='char', string='Helper Text', + multi='tile_info', readonly=True), + 'field_function': fields.selection([ + ('min', 'Minimum'), + ('max', 'Maximum'), + ('sum', 'Sum'), + ('avg', 'Average'), + ('median', 'Median'), + ], 'Function'), + 'field_id': fields.many2one( + 'ir.model.fields', 'Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'int'])]"), + 'active': fields.function( + _get_tile_info, type='boolean', string='Active', + multi='tile_info', readonly=True, fnct_search=_search_active), + 'color': fields.char('Background color'), + 'font_color': fields.char('Font Color'), + 'sequence': fields.integer( + 'Sequence', required=True), + } + + # Constraint Section + def _check_model_id_field_id(self, cr, uid, ids, context=None): + for t in self.browse(cr, uid, ids, context=context): + if t.field_id and t.field_id.model_id.id != t.model_id.id: + return False + return True + + def _check_field_id_field_function(self, cr, uid, ids, context=None): + for t in self.browse(cr, uid, ids, context=context): + if t.field_id and not t.field_function or\ + t.field_function and not t.field_id: + return False + return True + + _constraints = [ + ( + _check_model_id_field_id, + "Error ! Please select a field of the selected model.", + ['model_id', 'field_id']), + ( + _check_field_id_field_function, + "Error ! Please set both fields: 'Field' and 'Function'.", + ['field_id', 'field_function']), + ] + + _defaults = { + 'domain': '[]', + 'color': '#0E6C7E', + 'font_color': '#FFFFFF', + 'sequence': 0, + } + + def open_link(self, cr, uid, ids, context=None): + + tile_id = ids[0] + tile_object = self.browse(cr, uid, tile_id, context=context) + + if tile_object.action_id: + act_obj = self.pool.get('ir.actions.act_window') + result = act_obj.read(cr, uid, [tile_object.action_id.id], + context=context)[0] + # FIXME: restore original Domain + Filter would be better + result['domain'] = tile_object.domain + return result + + # we have no action_id stored, + # so try to load a default tree view + return { + 'name': tile_object.name, + 'view_type': 'form', + 'view_mode': 'tree', + 'view_id': [False], + 'res_model': tile_object.model_id.model, + 'type': 'ir.actions.act_window', + 'context': context, + 'nodestroy': True, + 'target': 'current', + 'domain': tile_object.domain, + } + + def add(self, cr, uid, vals, context=None): + # TODO: check if string + if 'model_id' in vals: + # need to replace model_name with its id + model_ids = self.pool.get('ir.model').search(cr, uid, + [('model', '=', + vals['model_id'])]) + vals['model_id'] = model_ids[0] + return self.create(cr, uid, vals, context) diff --git a/web_dashboard_tile/view/tile.xml b/web_dashboard_tile/view/tile.xml new file mode 100644 index 000000000..154efd902 --- /dev/null +++ b/web_dashboard_tile/view/tile.xml @@ -0,0 +1,120 @@ + + + + + tile.tile.tree + tile.tile + + + + + + + + + + + + + + + tile.tile.form + tile.tile + +
+ + + + + + + + + + + +
+
+
+ + + + tile.tile.kanban + tile.tile + + + + + + + + + + + + + + +
+ + + + + + + + Dashboard + tile.tile + form + tree,kanban,form + + + + + + + Dashboard + tile.tile + form + kanban + ['|',('user_id','=',False),('user_id','=',uid)] + + + + + Dashboard + + + + + + + From 11a6a7061efaa6093ec4626ec64496dd41fb21d2 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 09:43:34 +0200 Subject: [PATCH 02/57] [PORT][WIP] New kind of call for js and css files; --- web_dashboard_tile/__openerp__.py | 7 +----- web_dashboard_tile/view/templates.xml | 33 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 web_dashboard_tile/view/templates.xml diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index d0f8cf416..bd33b9597 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -73,19 +73,14 @@ possible future improvments: """, 'data': [ 'view/tile.xml', + 'view/templates.xml', 'security/ir.model.access.csv', 'security/rules.xml', ], - 'css': [ - 'static/src/css/tile.css', - ], 'demo': [ 'demo/res_groups.yml', 'demo/tile_tile.yml', ], - 'js': [ - 'static/src/js/custom_js.js', - ], 'qweb': [ 'static/src/xml/custom_xml.xml', ], diff --git a/web_dashboard_tile/view/templates.xml b/web_dashboard_tile/view/templates.xml new file mode 100644 index 000000000..e7a68b213 --- /dev/null +++ b/web_dashboard_tile/view/templates.xml @@ -0,0 +1,33 @@ + + + + + + + + From 4a64a30408308455c56eeb0c5211ddd3944cbeb1 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:20:56 +0200 Subject: [PATCH 03/57] PORT][FIX] minor change in js file due to changes in arch of the page; --- web_dashboard_tile/static/src/js/custom_js.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index 53a2bd0e0..c192ef293 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -45,25 +45,20 @@ _.mixin({ }, save_tile: function () { var self = this; - var getParent = this.getParent(); var view_parent = this.getParent().getParent(); - if (! view_parent.action || ! this.$el.find("select").val()) { - this.do_warn("Can't find dashboard action"); - return; - } - + var $name = this.$('#dashboard_tile_new_name'); - + this.tile = new instance.web.Model('tile.tile'); - + var private_filter = !this.$('#oe_searchview_custom_public').prop('checked'); if (_.isEmpty($name.val())){ this.do_warn(_t("Error"), _t("Filter name is required.")); return false; } var search = this.view.build_search_data(); - var context = new instance.web.CompoundContext(getParent.dataset.get_context() || []); - var domain = new instance.web.CompoundDomain(getParent.dataset.get_domain() || []); + var context = new instance.web.CompoundContext(view_parent.dataset.get_context() || []); + var domain = new instance.web.CompoundDomain(view_parent.dataset.get_domain() || []); _.each(search.contexts, context.add, context); _.each(search.domains, domain.add, domain); From e51469266fd906e7cc51c2ca771a30e3b5c62dfb Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:21:31 +0200 Subject: [PATCH 04/57] [PORT] 7.0 -> 8.0 API; --- web_dashboard_tile/tile.py | 199 ++++++++++++++++--------------------- 1 file changed, 86 insertions(+), 113 deletions(-) diff --git a/web_dashboard_tile/tile.py b/web_dashboard_tile/tile.py index 922438750..3b4a2218d 100644 --- a/web_dashboard_tile/tile.py +++ b/web_dashboard_tile/tile.py @@ -23,11 +23,13 @@ # ############################################################################## -from openerp.osv import orm, fields +from openerp import api, fields +from openerp.models import Model +from openerp.exceptions import except_orm from openerp.tools.translate import _ -class tile(orm.Model): +class TileTile(Model): _name = 'tile.tile' _order = 'sequence, name' @@ -39,58 +41,49 @@ class tile(orm.Model): half = (len(aList) - 1) / 2 return sum(sorted(aList)[half:half + even]) / float(even) - def _get_tile_info(self, cr, uid, ids, fields, args, context=None): - ima_obj = self.pool['ir.model.access'] + def _get_tile_info(self): + ima_obj = self.env['ir.model.access'] res = {} - records = self.browse(cr, uid, ids, context=context) - for r in records: - res[r.id] = { - 'active': False, - 'count': 0, - 'computed_value': 0, - 'helper': '', - } - if ima_obj.check( - cr, uid, r.model_id.model, 'read', False, context): + for r in self: + r.active = False + r.count = 0 + r.computed_value = 0 + helper = '' + if ima_obj.check(r.model_id.model, 'read', False): # Compute count item - model = self.pool.get(r.model_id.model) - count = model.search_count( - cr, uid, eval(r.domain), context=context) - res[r.id].update({ - 'active': True, - 'count': count, - }) + model = self.env[r.model_id.model] + r.count = model.search_count(eval(r.domain)) + r.active = True # Compute datas for field_id depending of field_function - if r.field_function and r.field_id and count != 0: - ids = model.search( - cr, uid, eval(r.domain), context=context) - vals = [x[r.field_id.name] for x in model.read( - cr, uid, ids, [r.field_id.name], context=context)] + if r.field_function and r.field_id and r.count != 0: + records = model.search(eval(r.domain)) + vals = [x[r.field_id.name] for x in records] desc = r.field_id.field_description if r.field_function == 'min': - value = min(vals) - helper = _("Minimum value of '%s'") % desc + r.computed_value = min(vals) + r.helper = _("Minimum value of '%s'") % desc elif r.field_function == 'max': - value = max(vals) - helper = _("Maximum value of '%s'") % desc + r.computed_value = max(vals) + r.helper = _("Maximum value of '%s'") % desc elif r.field_function == 'sum': - value = sum(vals) - helper = _("Total value of '%s'") % desc + r.computed_value = sum(vals) + r.helper = _("Total value of '%s'") % desc elif r.field_function == 'avg': - value = sum(vals) / len(vals) - helper = _("Average value of '%s'") % desc + r.computed_value = sum(vals) / len(vals) + r.helper = _("Average value of '%s'") % desc elif r.field_function == 'median': - value = self.median(vals) - helper = _("Median value of '%s'") % desc - res[r.id].update({ - 'computed_value': value, - 'helper': helper, - }) + r.computed_value = self.median(vals) + r.helper = _("Median value of '%s'") % desc return res - def _search_active(self, cr, uid, obj, name, arg, context=None): - ima_obj = self.pool['ir.model.access'] + def _search_active(self, operator, value): + cr = self.env.cr + if operator != '=': + raise except_orm( + 'Unimplemented Feature', + 'Search on Active field disabled.') + ima_obj = self.env['ir.model.access'] ids = [] cr.execute(""" SELECT tt.id, im.model @@ -98,45 +91,41 @@ class tile(orm.Model): INNER JOIN ir_model im ON tt.model_id = im.id""") for result in cr.fetchall(): - if (ima_obj.check(cr, uid, result[1], 'read', False) == - arg[0][2]): + if (ima_obj.check(result[1], 'read', False) == value): ids.append(result[0]) return [('id', 'in', ids)] - _columns = { - 'name': fields.char('Tile Name'), - 'model_id': fields.many2one('ir.model', 'Model', required=True), - 'user_id': fields.many2one('res.users', 'User'), - 'domain': fields.text('Domain'), - 'action_id': fields.many2one('ir.actions.act_window', 'Action'), - 'count': fields.function( - _get_tile_info, type='int', string='Count', - multi='tile_info', readonly=True), - 'computed_value': fields.function( - _get_tile_info, type='float', string='Computed Value', - multi='tile_info', readonly=True), - 'helper': fields.function( - _get_tile_info, type='char', string='Helper Text', - multi='tile_info', readonly=True), - 'field_function': fields.selection([ - ('min', 'Minimum'), - ('max', 'Maximum'), - ('sum', 'Sum'), - ('avg', 'Average'), - ('median', 'Median'), - ], 'Function'), - 'field_id': fields.many2one( - 'ir.model.fields', 'Field', - domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'int'])]"), - 'active': fields.function( - _get_tile_info, type='boolean', string='Active', - multi='tile_info', readonly=True, fnct_search=_search_active), - 'color': fields.char('Background color'), - 'font_color': fields.char('Font Color'), - 'sequence': fields.integer( - 'Sequence', required=True), - } + # Column Section + name=fields.Char(required=True) + model_id=fields.Many2one( + comodel_name='ir.model', string='Model', required=True) + user_id=fields.Many2one( + comodel_name='res.users', string='User') + domain=fields.Text(default='[]') + action_id=fields.Many2one( + comodel_name='ir.actions.act_window', string='Action') + count=fields.Integer( + compute='_get_tile_info', readonly=True) #readonly usefull ? + computed_value=fields.Float( + compute='_get_tile_info', readonly=True) #readonly usefull ? + helper=fields.Char( + compute='_get_tile_info', readonly=True) #readonly usefull ? + field_function=fields.Selection(selection=[ + ('min', 'Minimum'), + ('max', 'Maximum'), + ('sum', 'Sum'), + ('avg', 'Average'), + ('median', 'Median'), + ], string='Function') + field_id=fields.Many2one( + comodel_name='ir.model.fields', string='Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'int'])]") + active=fields.Boolean( + compute='_get_tile_info', readonly=True, search='_search_active') + color=fields.Char(default='#0E6C7E', string='Background Color') + font_color=fields.Char(default='#FFFFFF') + sequence=fields.Integer(default=0, required=True) # Constraint Section def _check_model_id_field_id(self, cr, uid, ids, context=None): @@ -163,47 +152,31 @@ class tile(orm.Model): ['field_id', 'field_function']), ] - _defaults = { - 'domain': '[]', - 'color': '#0E6C7E', - 'font_color': '#FFFFFF', - 'sequence': 0, - } - - def open_link(self, cr, uid, ids, context=None): - - tile_id = ids[0] - tile_object = self.browse(cr, uid, tile_id, context=context) - - if tile_object.action_id: - act_obj = self.pool.get('ir.actions.act_window') - result = act_obj.read(cr, uid, [tile_object.action_id.id], - context=context)[0] - # FIXME: restore original Domain + Filter would be better - result['domain'] = tile_object.domain - return result - - # we have no action_id stored, - # so try to load a default tree view - return { - 'name': tile_object.name, + # View / action Section + @api.multi + def open_link(self): + res = { + 'name': self.name, 'view_type': 'form', 'view_mode': 'tree', 'view_id': [False], - 'res_model': tile_object.model_id.model, + 'res_model': self.model_id.model, 'type': 'ir.actions.act_window', - 'context': context, + 'context': self.env.context, 'nodestroy': True, 'target': 'current', - 'domain': tile_object.domain, + 'domain': self.domain, } + if self.action_id: + res.update(self.action_id.read( + ['view_type', 'view_mode', 'view_id', 'type'])[0]) + # FIXME: restore original Domain + Filter would be better + return res - def add(self, cr, uid, vals, context=None): - # TODO: check if string - if 'model_id' in vals: + @api.model + def add(self, vals): + if 'model_id' in vals and not vals['model_id'].isdigit(): # need to replace model_name with its id - model_ids = self.pool.get('ir.model').search(cr, uid, - [('model', '=', - vals['model_id'])]) - vals['model_id'] = model_ids[0] - return self.create(cr, uid, vals, context) + vals['model_id'] = self.env['ir.model'].search( + [('model', '=', vals['model_id'])]).id + self.create(vals) From bd07e42e56e6b89cff0deec50ce601f4d8a07b37 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:30:58 +0200 Subject: [PATCH 05/57] [PORT][REF] new description and icon for 'web_dashboard_tile'; --- web_dashboard_tile/README.rst | 68 ++++++++++++++++++ web_dashboard_tile/__openerp__.py | 40 +---------- .../static/{src/img => description}/icon.png | Bin 3 files changed, 69 insertions(+), 39 deletions(-) create mode 100644 web_dashboard_tile/README.rst rename web_dashboard_tile/static/{src/img => description}/icon.png (100%) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst new file mode 100644 index 000000000..bf4bb220e --- /dev/null +++ b/web_dashboard_tile/README.rst @@ -0,0 +1,68 @@ +Add Tiles to Dashboard +====================== + +module to give you a dashboard where you can configure tile from any view +and add them as short cut. + +* Tile can be: + * displayed only for a user; + * global for all users (In that case, some tiles will be hidden if + the current user doesn't have access to the given model); +* The tile displays items count of a given model restricted to a given domain; +* Optionnaly, the tile can display the result of a function of a field; + * Function is one of sum/avg/min/max/median; + * Field must be integer or float; + +Usage +===== + +After installation, a dashboard has a `Maximize`-button that loads the dashboard's action in a normal view. + +* Dashboad sample, displaying Sale Orders to invoice: +.. image:: web_dashboard_tile/static/src/img/screenshot_dashboard.png +* Tree view displayed when user click on the tile: +.. image:: web_dashboard_tile/static/src/img/screenshot_action_click.png + +Kown issues/limits +================== +* can not edit tile from dashboard (color, sequence, function, ...); +* context are ignored; +* date filter can not be relative; +* combine domain of menue and filter so can not restore origin filter; + +possible future improvments +=========================== +* support context_today; +* add icons; +* support client side action (like inbox); + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 +`here `_. + + +Credits +======= + +Contributors +------------ + +* Markus Schneider +* Sylvain Le Gal (https://twitter.com/legalsylvain) + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +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. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index bd33b9597..ab6afc6f5 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -31,46 +31,8 @@ 'web_widget_color', ], 'author': "initOS GmbH & Co. KG,GRAP,Odoo Community Association (OCA)", - "category": "", + "category": "web", 'license': 'AGPL-3', - "description": """ -Add Tiles to Dashboard -====================== -Features: ---------- -module to give you a dashboard where you can configure tile from any view -and add them as short cut. - -* Tile can be: - * displayed only for a user; - * global for all users (In that case, some tiles will be hidden if - the current user doesn't have access to the given model); -* The tile displays items count of a given model restricted to a given domain; -* Optionnaly, the tile can display the result of a function of a field; - * Function is one of sum/avg/min/max/median; - * Field must be integer or float; - -Screenshot: ------------ -* Dashboad sample, displaying Sale Orders to invoice: -.. image:: web_dashboard_tile/static/src/img/screenshot_dashboard.png -* Tree view displayed when user click on the tile: -.. image:: web_dashboard_tile/static/src/img/screenshot_action_click.png - - -Kown issues/limits: -------------------- -* can not edit tile from dashboard (color, sequence, function, ...); -* context are ignored; -* date filter can not be relative; -* combine domain of menue and filter so can not restore origin filter; - -possible future improvments: ----------------------------- -* support context_today; -* add icons; -* support client side action (like inbox); - """, 'data': [ 'view/tile.xml', 'view/templates.xml', diff --git a/web_dashboard_tile/static/src/img/icon.png b/web_dashboard_tile/static/description/icon.png similarity index 100% rename from web_dashboard_tile/static/src/img/icon.png rename to web_dashboard_tile/static/description/icon.png From cb8956f7690b9ad9b2d3da432974489773663bfd Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:34:42 +0200 Subject: [PATCH 06/57] [PORT][REF] OCA conventions; --- web_dashboard_tile/__init__.py | 2 +- web_dashboard_tile/__openerp__.py | 4 ++-- web_dashboard_tile/models/__init__.py | 23 +++++++++++++++++++ .../{tile.py => models/tile_tile.py} | 0 .../{view => views}/templates.xml | 0 web_dashboard_tile/{view => views}/tile.xml | 0 6 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 web_dashboard_tile/models/__init__.py rename web_dashboard_tile/{tile.py => models/tile_tile.py} (100%) rename web_dashboard_tile/{view => views}/templates.xml (100%) rename web_dashboard_tile/{view => views}/tile.xml (100%) diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py index 9ad11b3e4..35d8f47b1 100644 --- a/web_dashboard_tile/__init__.py +++ b/web_dashboard_tile/__init__.py @@ -23,4 +23,4 @@ # ############################################################################## -from . import tile +from . import models diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index ab6afc6f5..66cc75448 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -34,8 +34,8 @@ "category": "web", 'license': 'AGPL-3', 'data': [ - 'view/tile.xml', - 'view/templates.xml', + 'views/tile.xml', + 'views/templates.xml', 'security/ir.model.access.csv', 'security/rules.xml', ], diff --git a/web_dashboard_tile/models/__init__.py b/web_dashboard_tile/models/__init__.py new file mode 100644 index 000000000..fc23e732e --- /dev/null +++ b/web_dashboard_tile/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import tile_tile diff --git a/web_dashboard_tile/tile.py b/web_dashboard_tile/models/tile_tile.py similarity index 100% rename from web_dashboard_tile/tile.py rename to web_dashboard_tile/models/tile_tile.py diff --git a/web_dashboard_tile/view/templates.xml b/web_dashboard_tile/views/templates.xml similarity index 100% rename from web_dashboard_tile/view/templates.xml rename to web_dashboard_tile/views/templates.xml diff --git a/web_dashboard_tile/view/tile.xml b/web_dashboard_tile/views/tile.xml similarity index 100% rename from web_dashboard_tile/view/tile.xml rename to web_dashboard_tile/views/tile.xml From d4fcdbe29d0e5cac643148ae1ff42869c01f2450 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:46:50 +0200 Subject: [PATCH 07/57] [PORT][REF] change name of field; --- web_dashboard_tile/models/tile_tile.py | 2 +- web_dashboard_tile/views/tile.xml | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 3b4a2218d..83a33167d 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -123,7 +123,7 @@ class TileTile(Model): " ('ttype', 'in', ['float', 'int'])]") active=fields.Boolean( compute='_get_tile_info', readonly=True, search='_search_active') - color=fields.Char(default='#0E6C7E', string='Background Color') + background_color=fields.Char(default='#0E6C7E', oldname='color') font_color=fields.Char(default='#FFFFFF') sequence=fields.Integer(default=0, required=True) diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 154efd902..f7234319a 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -13,6 +13,7 @@ + @@ -30,7 +31,7 @@ - + @@ -48,14 +49,14 @@ - + -
+
From 7e3df5fbca4c75c5e2787ab7d81fccd3e1e82c1a Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:47:03 +0200 Subject: [PATCH 08/57] [ADD] Extra demo data; --- web_dashboard_tile/demo/tile_tile.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml index c40b5903d..6b23b71bd 100644 --- a/web_dashboard_tile/demo/tile_tile.yml +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -31,3 +31,10 @@ model_id: base.model_ir_module_module domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']], ['author', 'ilike', 'Odoo Community Association (OCA)']] action_id: base.open_module_tree + +- !record {model: tile.tile, id: all_currency_with_rate}: + name: Currencies (Max Rate) + model_id: base.model_res_currency + domain: [] + field_function: max + field_id: base.field_res_currency_rate From 52fe77ee5b1641d41637fdfd9f942a0ed6ce6941 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 11:47:20 +0200 Subject: [PATCH 09/57] [REF] remove obsolete migration file for V7 udpate; --- .../7.0.1.0/post-migration-color.py | 48 ------------------- 1 file changed, 48 deletions(-) delete mode 100644 web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py diff --git a/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py b/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py deleted file mode 100644 index f8c33840e..000000000 --- a/web_dashboard_tile/migrations/7.0.1.0/post-migration-color.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2015-Today GRAP -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - - -COLOR_NUMERIC_TO_RVB = { - 0: '#006015', - 1: '#CD2513', - 2: '#CDC713', - 3: '#57158A', - 4: '#0E9B2D', - 5: '#7F0C00', - 6: '#7F7B00', - 7: '#320455', - 8: '#CD6E13', - 9: '#0E6C7E', -} - - -def migrate_color(cr): - for old, new in COLOR_NUMERIC_TO_RVB.iteritems(): - cr.execute(""" - UPDATE tile_tile - SET color='%s', font_color='#FFFFFF' - WHERE color='%s' - """ % (new, old)) - - -def migrate(cr, installed_version): - migrate_color(cr) From 2bb3af2f7b859ca1dce002d6e7b9da1e6e4247e3 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 12:17:22 +0200 Subject: [PATCH 10/57] [FIX] flake8; --- web_dashboard_tile/models/tile_tile.py | 33 ++++++++++++-------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 83a33167d..4743afcb5 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -48,7 +48,7 @@ class TileTile(Model): r.active = False r.count = 0 r.computed_value = 0 - helper = '' + r.helper = '' if ima_obj.check(r.model_id.model, 'read', False): # Compute count item model = self.env[r.model_id.model] @@ -96,36 +96,33 @@ class TileTile(Model): return [('id', 'in', ids)] # Column Section - name=fields.Char(required=True) - model_id=fields.Many2one( + name = fields.Char(required=True) + model_id = fields.Many2one( comodel_name='ir.model', string='Model', required=True) - user_id=fields.Many2one( + user_id = fields.Many2one( comodel_name='res.users', string='User') - domain=fields.Text(default='[]') - action_id=fields.Many2one( + domain = fields.Text(default='[]') + action_id = fields.Many2one( comodel_name='ir.actions.act_window', string='Action') - count=fields.Integer( - compute='_get_tile_info', readonly=True) #readonly usefull ? - computed_value=fields.Float( - compute='_get_tile_info', readonly=True) #readonly usefull ? - helper=fields.Char( - compute='_get_tile_info', readonly=True) #readonly usefull ? - field_function=fields.Selection(selection=[ + count = fields.Integer(compute='_get_tile_info') + computed_value = fields.Float(compute='_get_tile_info') + helper = fields.Char(compute='_get_tile_info') + field_function = fields.Selection(selection=[ ('min', 'Minimum'), ('max', 'Maximum'), ('sum', 'Sum'), ('avg', 'Average'), ('median', 'Median'), ], string='Function') - field_id=fields.Many2one( + field_id = fields.Many2one( comodel_name='ir.model.fields', string='Field', domain="[('model_id', '=', model_id)," " ('ttype', 'in', ['float', 'int'])]") - active=fields.Boolean( + active = fields.Boolean( compute='_get_tile_info', readonly=True, search='_search_active') - background_color=fields.Char(default='#0E6C7E', oldname='color') - font_color=fields.Char(default='#FFFFFF') - sequence=fields.Integer(default=0, required=True) + background_color = fields.Char(default='#0E6C7E', oldname='color') + font_color = fields.Char(default='#FFFFFF') + sequence = fields.Integer(default=0, required=True) # Constraint Section def _check_model_id_field_id(self, cr, uid, ids, context=None): From ab89352b581e72c3dee8de70c53d2d3fafeb1367 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 12:17:31 +0200 Subject: [PATCH 11/57] [FIX] incorrect description; --- web_dashboard_tile/README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index bf4bb220e..c19bcdfac 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -16,8 +16,6 @@ and add them as short cut. Usage ===== -After installation, a dashboard has a `Maximize`-button that loads the dashboard's action in a normal view. - * Dashboad sample, displaying Sale Orders to invoice: .. image:: web_dashboard_tile/static/src/img/screenshot_dashboard.png * Tree view displayed when user click on the tile: From 3d49560d7411b8dcbc748b0943ee971dcf18220f Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 17 Jul 2015 12:17:55 +0200 Subject: [PATCH 12/57] [REF] tile form display; --- web_dashboard_tile/views/tile.xml | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index f7234319a..36411ad84 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -2,7 +2,6 @@ - tile.tile.tree tile.tile @@ -19,28 +18,34 @@ - tile.tile.form tile.tile -
- - - - - - - - - - - + + +

+ +

+ + + + + + + + + + + + + + +
- tile.tile.kanban tile.tile From 0f28b46b2e4fbce10cbba324c4003110b7ded3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matja=C5=BE=20Mozeti=C4=8D?= Date: Sun, 2 Aug 2015 10:18:26 +0200 Subject: [PATCH 13/57] Added slovene translation --- web_dashboard_tile/i18n/sl.po | 233 ++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 web_dashboard_tile/i18n/sl.po diff --git a/web_dashboard_tile/i18n/sl.po b/web_dashboard_tile/i18n/sl.po new file mode 100644 index 000000000..8e8632413 --- /dev/null +++ b/web_dashboard_tile/i18n/sl.po @@ -0,0 +1,233 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-08-02 10:08+0200\n" +"PO-Revision-Date: 2015-08-02 10:17+0200\n" +"Last-Translator: Matjaz Mozetic \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" +"X-Generator: Poedit 1.8.2\n" +"Language: sl\n" + +#. module: web_dashboard_tile +#: field:tile.tile,action_id:0 +msgid "Action" +msgstr "Dejanje" + +#. module: web_dashboard_tile +#: field:tile.tile,active:0 +msgid "Active" +msgstr "Aktivno" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Average" +msgstr "Povprečje" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:82 +#, python-format +msgid "Average value of '%s'" +msgstr "Povprečna vrednost '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,color:0 +msgid "Background color" +msgstr "Barva ozadja" + +#. module: web_dashboard_tile +#: field:tile.tile,computed_value:0 +msgid "Computed Value" +msgstr "Izračunana vrednost" + +#. module: web_dashboard_tile +#: field:tile.tile,count:0 +msgid "Count" +msgstr "Štetje" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "Ustvari" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "Nadzorna plošča" + +#. module: web_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "Okvir nadzorne plošče" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Dashboard tiles" +msgstr "Okvirji nadzorne plošče" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Delete" +msgstr "Izbris" + +#. module: web_dashboard_tile +#: field:tile.tile,domain:0 +msgid "Domain" +msgstr "Domena" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "Edit..." +msgstr "Urejanje..." + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#, python-format +msgid "Error" +msgstr "Napaka" + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please select a field of the selected model." +msgstr "Napaka! Izberite polje izbranega modela." + +#. module: web_dashboard_tile +#: constraint:tile.tile:0 +msgid "Error ! Please set both fields: 'Field' and 'Function'." +msgstr "Napaka! Določite obe polji: 'Polje' in 'Funkcija'." + +#. module: web_dashboard_tile +#: field:tile.tile,field_id:0 +msgid "Field" +msgstr "Polje" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#, python-format +msgid "Filter name is required." +msgstr "Zahtevan je naziv filtra." + +#. module: web_dashboard_tile +#: field:tile.tile,font_color:0 +msgid "Font Color" +msgstr "Barva pisave" + +#. module: web_dashboard_tile +#: field:tile.tile,field_function:0 +msgid "Function" +msgstr "Funkcija" + +#. module: web_dashboard_tile +#: field:tile.tile,helper:0 +msgid "Helper Text" +msgstr "Besedilo pomoči" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Maximum" +msgstr "Maksimum" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:76 +#, python-format +msgid "Maximum value of '%s'" +msgstr "Maksimalna vrednost '%s'" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Median" +msgstr "Sredina" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:85 +#, python-format +msgid "Median value of '%s'" +msgstr "Srednja vrednost '%s'" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Minimum" +msgstr "Minimum" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:73 +#, python-format +msgid "Minimum value of '%s'" +msgstr "Minimalna vrednost '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,model_id:0 +msgid "Model" +msgstr "Model" + +#. module: web_dashboard_tile +#: field:tile.tile,sequence:0 +msgid "Sequence" +msgstr "Zaporedje" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#, python-format +msgid "Success" +msgstr "Uspeh" + +#. module: web_dashboard_tile +#: selection:tile.tile,field_function:0 +msgid "Sum" +msgstr "Vsota" + +#. module: web_dashboard_tile +#: field:tile.tile,name:0 +msgid "Tile Name" +msgstr "Naziv okvirja" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#, python-format +msgid "Tile is created" +msgstr "Okvir je ustvarjen" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "Okvir:" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/tile.py:79 +#, python-format +msgid "Total value of '%s'" +msgstr "Skupna vrednost '%s'" + +#. module: web_dashboard_tile +#: field:tile.tile,user_id:0 +msgid "User" +msgstr "Uporabnik" + +#. module: web_dashboard_tile +#: code:_description:0 model:ir.model,name:web_dashboard_tile.model_tile_tile +#, python-format +msgid "tile.tile" +msgstr "tile.tile" + +#. module: web_dashboard_tile +#: view:tile.tile:0 +msgid "í" +msgstr "í" From d8e8e268e69d4c8b851f974167c2a2e59b5d6c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 9 Oct 2015 10:03:39 +0200 Subject: [PATCH 14/57] [UPD] prefix versions with 8.0 --- web_dashboard_tile/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index 66cc75448..c401c30af 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -23,7 +23,7 @@ { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", - "version": "1.0", + "version": "8.0.1.0.0", "depends": [ 'web', 'board', From 38cd9401d15cade9d0ccf1759d699f83dc6b9079 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 14 Oct 2015 02:57:05 +0200 Subject: [PATCH 15/57] [MIG] Make modules uninstallable --- web_dashboard_tile/__openerp__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index c401c30af..3e636b152 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -46,4 +46,5 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], + 'installable': False, } From 9ad2e198dc552c33b87d49061f07079631a425e1 Mon Sep 17 00:00:00 2001 From: David Beal Date: Fri, 1 Apr 2016 11:03:04 +0200 Subject: [PATCH 16/57] [FIX] preview image in README --- web_dashboard_tile/README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index c19bcdfac..8b30c5422 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -17,9 +17,9 @@ Usage ===== * Dashboad sample, displaying Sale Orders to invoice: -.. image:: web_dashboard_tile/static/src/img/screenshot_dashboard.png +.. image:: /web_dashboard_tile/static/src/img/screenshot_dashboard.png * Tree view displayed when user click on the tile: -.. image:: web_dashboard_tile/static/src/img/screenshot_action_click.png +.. image:: /web_dashboard_tile/static/src/img/screenshot_action_click.png Kown issues/limits ================== From 678b24b3fb80c80eeacedd598c6678094fb0424b Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Sat, 2 Apr 2016 00:34:06 +0200 Subject: [PATCH 17/57] [IMP] web_dashboard_tile: README --- web_dashboard_tile/README.rst | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 8b30c5422..c87fb47d6 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -21,18 +21,16 @@ Usage * Tree view displayed when user click on the tile: .. image:: /web_dashboard_tile/static/src/img/screenshot_action_click.png -Kown issues/limits -================== -* can not edit tile from dashboard (color, sequence, function, ...); -* context are ignored; -* date filter can not be relative; -* combine domain of menue and filter so can not restore origin filter; +Known issues / Roadmap +====================== -possible future improvments -=========================== -* support context_today; -* add icons; -* support client side action (like inbox); +* Can not edit tile from dashboard (color, sequence, function, ...); +* Context are ignored; +* Date filter can not be relative; +* Combine domain of menue and filter so can not restore origin filter; +* Support context_today; +* Add icons; +* Support client side action (like inbox); Bug Tracker =========== @@ -40,7 +38,10 @@ Bug Tracker Bugs are tracked on `GitHub 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 -`here `_. +`here `_. Credits From 243902a274afbdec01c0a0efbed9489fec1d8deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Wed, 23 Nov 2016 13:12:43 -0300 Subject: [PATCH 18/57] [8.0][FIX] web_dashboard_tile security rule Rule was not being updated because of ``, hence the groups field of the tile was not working. Conflicts: web_dashboard_tile/__openerp__.py --- web_dashboard_tile/__openerp__.py | 4 +-- .../migrations/8.0.4.0/post-migration.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 web_dashboard_tile/migrations/8.0.4.0/post-migration.py diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index 3e636b152..f84fd1b37 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -23,7 +23,7 @@ { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", - "version": "8.0.1.0.0", + "version": "9.0.1.0.0", "depends": [ 'web', 'board', @@ -46,5 +46,5 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], - 'installable': False, + 'installable': True, } diff --git a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py new file mode 100644 index 000000000..fd7ddd773 --- /dev/null +++ b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# © 2016 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def migrate(cr, version): + if version is None: + return + + # Update ir.rule + cr.execute(""" + SELECT res_id FROM ir_model_data + WHERE name = 'model_tile_rule' + AND module = 'web_dashboard_tile'""") + rule_id = cr.fetchone()[0] + new_domain = """[ + "|", + ("user_id","=",user.id), + ("user_id","=",False), + "|", + ("group_ids","=",False), + ("group_ids","in",[g.id for g in user.groups_id]), + ]""" + cr.execute(""" + UPDATE ir_rule SET domain_force = '%(domain)s' + WHERE id = '%(id)s' """ % {'domain': new_domain, 'id': rule_id}) From ce43859ab0558a52b7b420d07573746f1ae8c820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Sat, 19 Nov 2016 14:07:01 -0300 Subject: [PATCH 19/57] [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Conflicts: web_dashboard_tile/README.rst web_dashboard_tile/__openerp__.py web_dashboard_tile/models/tile_tile.py web_dashboard_tile/static/src/css/tile.css --- web_dashboard_tile/README.rst | 36 +++ web_dashboard_tile/demo/tile_tile.yml | 4 +- .../migrations/8.0.3.0/post-migration.py | 13 + web_dashboard_tile/models/tile_tile.py | 237 ++++++++++++++++++ web_dashboard_tile/security/rules.xml | 11 +- web_dashboard_tile/static/src/css/tile.css | 52 +++- .../static/src/img/screenshot_dashboard.png | Bin 45633 -> 20441 bytes web_dashboard_tile/tests/__init__.py | 6 + web_dashboard_tile/tests/test_tile.py | 52 ++++ web_dashboard_tile/views/tile.xml | 93 ++++--- 10 files changed, 471 insertions(+), 33 deletions(-) create mode 100644 web_dashboard_tile/migrations/8.0.3.0/post-migration.py create mode 100644 web_dashboard_tile/tests/__init__.py create mode 100644 web_dashboard_tile/tests/test_tile.py diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index c87fb47d6..0337037b1 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,6 +1,7 @@ Add Tiles to Dashboard ====================== +<<<<<<< HEAD module to give you a dashboard where you can configure tile from any view and add them as short cut. @@ -12,6 +13,24 @@ and add them as short cut. * Optionnaly, the tile can display the result of a function of a field; * Function is one of sum/avg/min/max/median; * Field must be integer or float; +======= +Adds a dashboard where you can configure tiles from any view and add them as short cut. + +By default, the tile displays items count of a given model restricted to a given domain. + +Optionally, the tile can display the result of a function on a field. + +- Function is one of `sum`, `avg`, `min`, `max` or `median`. +- Field must be integer or float. + +Tile can be: + +- Displayed only for a user. +- Global for all users. +- Restricted to some groups. + +*Note: The tile will be hidden if the current user doesn't have access to the given model.* +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Usage ===== @@ -24,6 +43,7 @@ Usage Known issues / Roadmap ====================== +<<<<<<< HEAD * Can not edit tile from dashboard (color, sequence, function, ...); * Context are ignored; * Date filter can not be relative; @@ -31,6 +51,22 @@ Known issues / Roadmap * Support context_today; * Add icons; * Support client side action (like inbox); +======= +Known issues +============ +* Can not edit tile from dashboard (color, sequence, function, ...). +* Original context is ignored. +* Original domain and filter are not restored. +* To preserve a relative date domain, you have to manually edit the tile's domain from `Configuration > User Interface > Dashboard Tile`. You can use the same variables available in filters (`uid`, `context_today()`, `current_date`, `time`, `datetime`, `relativedelta`). + +Roadmap +======= +* Add icons. +* Support client side action (like inbox). +* Restore original Domain + Filter when an action is set. +* Posibility to hide the tile based on a field expression. +* Posibility to set the background color based on a field expression. +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Bug Tracker =========== diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml index 6b23b71bd..dd9da0165 100644 --- a/web_dashboard_tile/demo/tile_tile.yml +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -36,5 +36,5 @@ name: Currencies (Max Rate) model_id: base.model_res_currency domain: [] - field_function: max - field_id: base.field_res_currency_rate + secondary_function: max + secondary_field_id: base.field_res_currency_rate diff --git a/web_dashboard_tile/migrations/8.0.3.0/post-migration.py b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py new file mode 100644 index 000000000..c19f1870c --- /dev/null +++ b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# © 2016 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + + +def migrate(cr, version): + if version is None: + return + + # Rename old fields + cr.execute("""UPDATE tile_tile SET primary_function = 'count'""") + cr.execute("""UPDATE tile_tile SET secondary_function = field_function""") + cr.execute("""UPDATE tile_tile SET secondary_field_id = field_id""") diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 4743afcb5..498d365bb 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +<<<<<<< HEAD ############################################################################## # # OpenERP, Open Source Management Solution @@ -26,13 +27,74 @@ from openerp import api, fields from openerp.models import Model from openerp.exceptions import except_orm +======= +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +import datetime +import time +from dateutil.relativedelta import relativedelta +from collections import OrderedDict + +from openerp import api, fields, models +from openerp.tools.safe_eval import safe_eval as eval +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) from openerp.tools.translate import _ +<<<<<<< HEAD class TileTile(Model): +======= +def median(vals): + # https://docs.python.org/3/library/statistics.html#statistics.median + # TODO : refactor, using statistics.median when Odoo will be available + # in Python 3.4 + even = (0 if len(vals) % 2 else 1) + 1 + half = (len(vals) - 1) / 2 + return sum(sorted(vals)[half:half + even]) / float(even) + + +FIELD_FUNCTIONS = OrderedDict([ + ('count', { + 'name': 'Count', + 'func': False, # its hardcoded in _compute_data + 'help': _('Number of records')}), + ('min', { + 'name': 'Minimum', + 'func': min, + 'help': _("Minimum value of '%s'")}), + ('max', { + 'name': 'Maximum', + 'func': max, + 'help': _("Maximum value of '%s'")}), + ('sum', { + 'name': 'Sum', + 'func': sum, + 'help': _("Total value of '%s'")}), + ('avg', { + 'name': 'Average', + 'func': lambda vals: sum(vals)/len(vals), + 'help': _("Minimum value of '%s'")}), + ('median', { + 'name': 'Median', + 'func': median, + 'help': _("Median value of '%s'")}), +]) + + +FIELD_FUNCTION_SELECTION = [ + (k, FIELD_FUNCTIONS[k].get('name')) for k in FIELD_FUNCTIONS] + + +class TileTile(models.Model): +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) _name = 'tile.tile' + _description = 'Dashboard Tile' _order = 'sequence, name' +<<<<<<< HEAD def median(self, aList): # https://docs.python.org/3/library/statistics.html#statistics.median # TODO : refactor, using statistics.median when Odoo will be available @@ -76,6 +138,154 @@ class TileTile(Model): r.computed_value = self.median(vals) r.helper = _("Median value of '%s'") % desc return res +======= + def _get_eval_context(self): + def _context_today(): + return fields.Date.from_string(fields.Date.context_today(self)) + context = self.env.context.copy() + context.update({ + 'time': time, + 'datetime': datetime, + 'relativedelta': relativedelta, + 'context_today': _context_today, + 'current_date': fields.Date.today(), + }) + return context + + # Column Section + name = fields.Char(required=True) + sequence = fields.Integer(default=0, required=True) + user_id = fields.Many2one('res.users', 'User') + background_color = fields.Char(default='#0E6C7E', oldname='color') + font_color = fields.Char(default='#FFFFFF') + + group_ids = fields.Many2many( + 'res.groups', + string='Groups', + help='If this field is set, only users of this group can view this ' + 'tile. Please note that it will only work for global tiles ' + '(that is, when User field is left empty)') + + model_id = fields.Many2one('ir.model', 'Model', required=True) + domain = fields.Text(default='[]') + action_id = fields.Many2one('ir.actions.act_window', 'Action') + + active = fields.Boolean( + compute='_compute_active', + search='_search_active', + readonly=True) + + # Primary Value + primary_function = fields.Selection( + FIELD_FUNCTION_SELECTION, + string='Function', + default='count') + primary_field_id = fields.Many2one( + 'ir.model.fields', + string='Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'integer'])]") + primary_format = fields.Char( + string='Format', + help='Python Format String valid with str.format()\n' + 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + primary_value = fields.Char( + string='Value', + compute='_compute_data') + primary_helper = fields.Char( + string='Helper', + compute='_compute_helper') + + # Secondary Value + secondary_function = fields.Selection( + FIELD_FUNCTION_SELECTION, + string='Secondary Function') + secondary_field_id = fields.Many2one( + 'ir.model.fields', + string='Secondary Field', + domain="[('model_id', '=', model_id)," + " ('ttype', 'in', ['float', 'integer'])]") + secondary_format = fields.Char( + string='Secondary Format', + help='Python Format String valid with str.format()\n' + 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + secondary_value = fields.Char( + string='Secondary Value', + compute='_compute_data') + secondary_helper = fields.Char( + string='Secondary Helper', + compute='_compute_helper') + + error = fields.Char( + string='Error Details', + compute='_compute_data') + + @api.one + def _compute_data(self): + if not self.active: + return + model = self.env[self.model_id.model] + eval_context = self._get_eval_context() + domain = self.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + self.primary_value = self.secondary_value = 'ERR!' + self.error = str(e) + return + if any([ + self.primary_function and + self.primary_function != 'count', + self.secondary_function and + self.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f+'function' + f_field_id = f+'field_id' + f_format = f+'format' + f_value = f+'value' + value = 0 + if self[f_function] == 'count': + value = count + elif self[f_function]: + func = FIELD_FUNCTIONS[self[f_function]]['func'] + if func and self[f_field_id] and count: + vals = [x[self[f_field_id].name] for x in records] + value = func(vals) + if self[f_function]: + try: + self[f_value] = (self[f_format] or '{:,}').format(value) + except ValueError as e: + self[f_value] = 'F_ERR!' + self.error = str(e) + return + else: + self[f_value] = False + + @api.one + @api.onchange('primary_function', 'primary_field_id', + 'secondary_function', 'secondary_field_id') + def _compute_helper(self): + for f in ['primary_', 'secondary_']: + f_function = f+'function' + f_field_id = f+'field_id' + f_helper = f+'helper' + self[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(self[f_function], {}) + help = field_func.get('help', False) + if help: + if self[f_function] != 'count' and self[f_field_id]: + desc = self[f_field_id].field_description + self[f_helper] = help % desc + else: + self[f_helper] = help + + @api.one + def _compute_active(self): + ima = self.env['ir.model.access'] + self.active = ima.check(self.model_id.model, 'read', False) +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) def _search_active(self, operator, value): cr = self.env.cr @@ -95,6 +305,7 @@ class TileTile(Model): ids.append(result[0]) return [('id', 'in', ids)] +<<<<<<< HEAD # Column Section name = fields.Char(required=True) model_id = fields.Many2one( @@ -123,6 +334,32 @@ class TileTile(Model): background_color = fields.Char(default='#0E6C7E', oldname='color') font_color = fields.Char(default='#FFFFFF') sequence = fields.Integer(default=0, required=True) +======= + # Constraints and onchanges + @api.one + @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') + def _check_model_id_field_id(self): + if any([ + self.primary_field_id and + self.primary_field_id.model_id.id != self.model_id.id, + self.secondary_field_id and + self.secondary_field_id.model_id.id != self.model_id.id + ]): + raise ValidationError( + _("Please select a field from the selected model.")) + + @api.onchange('model_id') + def _onchange_model_id(self): + self.primary_field_id = False + self.secondary_field_id = False + + @api.onchange('primary_function', 'secondary_function') + def _onchange_function(self): + if self.primary_function in [False, 'count']: + self.primary_field_id = False + if self.secondary_function in [False, 'count']: + self.secondary_field_id = False +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) # Constraint Section def _check_model_id_field_id(self, cr, uid, ids, context=None): diff --git a/web_dashboard_tile/security/rules.xml b/web_dashboard_tile/security/rules.xml index 8d653b70c..05637bfdc 100644 --- a/web_dashboard_tile/security/rules.xml +++ b/web_dashboard_tile/security/rules.xml @@ -6,7 +6,16 @@ tile.owner - [('user_id','in',[False,user.id])] + + [ + '|', + ('user_id','=',user.id), + ('user_id','=',False), + '|', + ('group_ids','=',False), + ('group_ids','in',[g.id for g in user.groups_id]), + ] +
diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 1d057ceea..4ec483d72 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -5,35 +5,71 @@ border-radius: 0; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_label, .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value, .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value, .openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value { width: 140px; - text-align: center; +======= +/* Disable default kanban style */ +.openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { + margin-right: inherit!important; } +.openerp .oe_kanban_view .oe_dashboard_tile .tile_label, +.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, +.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) + text-align: center; + font-weight: bold; +} + +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_label { +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) padding: 5px; font-size: 15px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ font-size: 52px; font-weight: bold; +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ + font-size: 54px; +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; + right: 5px; bottom: 5px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ font-size: 38px; font-weight: bold; +======= +.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ + display: none; + font-size: 18px; + font-style: italic; +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; + right: 5px; + bottom: 5px; +} + +.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_primary_value{ + font-size: 38px; bottom: 30px; } +<<<<<<< HEAD .openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value{ font-size: 18px; font-weight: bold; @@ -42,3 +78,17 @@ bottom: 5px; font-style: italic; } +======= +.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_secondary_value{ + display: block; +} + +/* SearchView Drawer */ +.openerp .oe_searchview_drawer .oe_searchview_dashboard .oe_dashboard_tile_form { + display: none; +} + +.openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { + display: block; +} +>>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) diff --git a/web_dashboard_tile/static/src/img/screenshot_dashboard.png b/web_dashboard_tile/static/src/img/screenshot_dashboard.png index 9cbdeecd3d601ffbea9c197ed5c71d2480371613..65cfc12753e9f451d432ff0cb54c85d3ff459a1f 100644 GIT binary patch literal 20441 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 GGywqSdE~|b literal 45633 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 +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# flake8: noqa + +from . import test_tile diff --git a/web_dashboard_tile/tests/test_tile.py b/web_dashboard_tile/tests/test_tile.py new file mode 100644 index 000000000..90604ab9a --- /dev/null +++ b/web_dashboard_tile/tests/test_tile.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# © 2016 Antonio Espinosa - +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests.common import TransactionCase + + +class TestTile(TransactionCase): + def test_tile(self): + tile_obj = self.env['tile.tile'] + model_id = self.env['ir.model'].search([ + ('model', '=', 'tile.tile')]) + field_id = self.env['ir.model.fields'].search([ + ('model_id', '=', model_id.id), + ('name', '=', 'sequence')]) + self.tile1 = tile_obj.create({ + 'name': 'Count / Sum', + 'sequence': 1, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'secondary_function': 'sum', + 'secondary_field_id': field_id.id}) + self.tile2 = tile_obj.create({ + 'name': 'Min / Max', + 'sequence': 2, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'primary_function': 'min', + 'primary_field_id': field_id.id, + 'secondary_function': 'max', + 'secondary_field_id': field_id.id}) + self.tile3 = tile_obj.create({ + 'name': 'Avg / Median', + 'sequence': 3, + 'model_id': model_id.id, + 'domain': "[('model_id', '=', %d)]" % model_id.id, + 'primary_function': 'avg', + 'primary_field_id': field_id.id, + 'secondary_function': 'median', + 'secondary_field_id': field_id.id}) + # count + self.assertEqual(self.tile1.primary_value, '3') + # sum + self.assertEqual(self.tile1.secondary_value, '6') + # min + self.assertEqual(self.tile2.primary_value, '1') + # max + self.assertEqual(self.tile2.secondary_value, '3') + # average + self.assertEqual(self.tile3.primary_value, '2') + # median + self.assertEqual(self.tile3.secondary_value, '2.0') diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 36411ad84..cf9a003f4 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -9,8 +9,10 @@ - - + + + + @@ -34,11 +36,50 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -53,37 +94,31 @@ - - - - + + + + +
-
From cf717edd2df3ea6dc5cb53f408b43442459bb495 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:04:14 -0300 Subject: [PATCH 20/57] FIX --- web_dashboard_tile/README.rst | 44 +---- web_dashboard_tile/__init__.py | 27 +-- web_dashboard_tile/__openerp__.py | 14 +- web_dashboard_tile/models/__init__.py | 24 +-- web_dashboard_tile/models/tile_tile.py | 175 ++---------------- web_dashboard_tile/static/src/css/tile.css | 39 +--- web_dashboard_tile/static/src/js/custom_js.js | 8 +- .../static/src/xml/custom_xml.xml | 4 +- web_dashboard_tile/views/templates.xml | 2 +- web_dashboard_tile/views/tile.xml | 6 +- 10 files changed, 60 insertions(+), 283 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 0337037b1..523dcadb5 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,19 +1,6 @@ -Add Tiles to Dashboard -====================== +Dashboard Tiles +=============== -<<<<<<< HEAD -module to give you a dashboard where you can configure tile from any view -and add them as short cut. - -* Tile can be: - * displayed only for a user; - * global for all users (In that case, some tiles will be hidden if - the current user doesn't have access to the given model); -* The tile displays items count of a given model restricted to a given domain; -* Optionnaly, the tile can display the result of a function of a field; - * Function is one of sum/avg/min/max/median; - * Field must be integer or float; -======= Adds a dashboard where you can configure tiles from any view and add them as short cut. By default, the tile displays items count of a given model restricted to a given domain. @@ -30,28 +17,18 @@ Tile can be: - Restricted to some groups. *Note: The tile will be hidden if the current user doesn't have access to the given model.* ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Usage ===== * Dashboad sample, displaying Sale Orders to invoice: -.. image:: /web_dashboard_tile/static/src/img/screenshot_dashboard.png + +.. image:: ./static/src/img/screenshot_dashboard.png + * Tree view displayed when user click on the tile: -.. image:: /web_dashboard_tile/static/src/img/screenshot_action_click.png -Known issues / Roadmap -====================== +.. image:: ./static/src/img/screenshot_action_click.png -<<<<<<< HEAD -* Can not edit tile from dashboard (color, sequence, function, ...); -* Context are ignored; -* Date filter can not be relative; -* Combine domain of menue and filter so can not restore origin filter; -* Support context_today; -* Add icons; -* Support client side action (like inbox); -======= Known issues ============ * Can not edit tile from dashboard (color, sequence, function, ...). @@ -66,7 +43,6 @@ Roadmap * Restore original Domain + Filter when an action is set. * Posibility to hide the tile based on a field expression. * Posibility to set the background color based on a field expression. ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Bug Tracker =========== @@ -74,10 +50,7 @@ Bug Tracker Bugs are tracked on `GitHub 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 -`here `_. +`here `_. Credits @@ -88,6 +61,7 @@ Contributors * Markus Schneider * Sylvain Le Gal (https://twitter.com/legalsylvain) +* Iván Todorovich Maintainer ---------- @@ -100,4 +74,4 @@ This module is maintained by the OCA. 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. -To contribute to this module, please visit http://odoo-community.org. +To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py index 35d8f47b1..1d098b583 100644 --- a/web_dashboard_tile/__init__.py +++ b/web_dashboard_tile/__init__.py @@ -1,26 +1,7 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Copyright (C) 2015-Today GRAP -# Author Markus Schneider -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from . import models diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index f84fd1b37..bcba4eb5d 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -20,6 +20,10 @@ # along with this program. If not, see . # ############################################################################## +# -*- coding: utf-8 -*- +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", @@ -30,9 +34,16 @@ 'mail', 'web_widget_color', ], - 'author': "initOS GmbH & Co. KG,GRAP,Odoo Community Association (OCA)", + 'author': 'initOS GmbH & Co. KG, ' + 'GRAP, ' + 'Odoo Community Association (OCA)', "category": "web", 'license': 'AGPL-3', + 'contributors': [ + 'initOS GmbH & Co. KG', + 'GRAP', + 'Iván Todorovich ' + ], 'data': [ 'views/tile.xml', 'views/templates.xml', @@ -46,5 +57,4 @@ 'qweb': [ 'static/src/xml/custom_xml.xml', ], - 'installable': True, } diff --git a/web_dashboard_tile/models/__init__.py b/web_dashboard_tile/models/__init__.py index fc23e732e..97fec216c 100644 --- a/web_dashboard_tile/models/__init__.py +++ b/web_dashboard_tile/models/__init__.py @@ -1,23 +1,7 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2015-Today GRAP -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# © 2010-2013 OpenERP s.a. (). +# © 2014 initOS GmbH & Co. KG (). +# © 2015-Today GRAP +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html from . import tile_tile diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 498d365bb..bc304b691 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,33 +1,4 @@ # -*- coding: utf-8 -*- -<<<<<<< HEAD -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Copyright (C) 2015-Today GRAP -# Author Markus Schneider -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from openerp import api, fields -from openerp.models import Model -from openerp.exceptions import except_orm -======= # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # © 2015-Today GRAP @@ -40,13 +11,10 @@ from collections import OrderedDict from openerp import api, fields, models from openerp.tools.safe_eval import safe_eval as eval ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) from openerp.tools.translate import _ +from openerp.exceptions import ValidationError, except_orm -<<<<<<< HEAD -class TileTile(Model): -======= def median(vals): # https://docs.python.org/3/library/statistics.html#statistics.median # TODO : refactor, using statistics.median when Odoo will be available @@ -75,7 +43,7 @@ FIELD_FUNCTIONS = OrderedDict([ 'help': _("Total value of '%s'")}), ('avg', { 'name': 'Average', - 'func': lambda vals: sum(vals)/len(vals), + 'func': lambda vals: sum(vals) / len(vals), 'help': _("Minimum value of '%s'")}), ('median', { 'name': 'Median', @@ -89,56 +57,10 @@ FIELD_FUNCTION_SELECTION = [ class TileTile(models.Model): ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) _name = 'tile.tile' _description = 'Dashboard Tile' _order = 'sequence, name' -<<<<<<< HEAD - def median(self, aList): - # https://docs.python.org/3/library/statistics.html#statistics.median - # TODO : refactor, using statistics.median when Odoo will be available - # in Python 3.4 - even = (0 if len(aList) % 2 else 1) + 1 - half = (len(aList) - 1) / 2 - return sum(sorted(aList)[half:half + even]) / float(even) - - def _get_tile_info(self): - ima_obj = self.env['ir.model.access'] - res = {} - for r in self: - r.active = False - r.count = 0 - r.computed_value = 0 - r.helper = '' - if ima_obj.check(r.model_id.model, 'read', False): - # Compute count item - model = self.env[r.model_id.model] - r.count = model.search_count(eval(r.domain)) - r.active = True - - # Compute datas for field_id depending of field_function - if r.field_function and r.field_id and r.count != 0: - records = model.search(eval(r.domain)) - vals = [x[r.field_id.name] for x in records] - desc = r.field_id.field_description - if r.field_function == 'min': - r.computed_value = min(vals) - r.helper = _("Minimum value of '%s'") % desc - elif r.field_function == 'max': - r.computed_value = max(vals) - r.helper = _("Maximum value of '%s'") % desc - elif r.field_function == 'sum': - r.computed_value = sum(vals) - r.helper = _("Total value of '%s'") % desc - elif r.field_function == 'avg': - r.computed_value = sum(vals) / len(vals) - r.helper = _("Average value of '%s'") % desc - elif r.field_function == 'median': - r.computed_value = self.median(vals) - r.helper = _("Median value of '%s'") % desc - return res -======= def _get_eval_context(self): def _context_today(): return fields.Date.from_string(fields.Date.context_today(self)) @@ -238,13 +160,13 @@ class TileTile(models.Model): self.primary_function != 'count', self.secondary_function and self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) + ]): + records = model.search(eval(domain, eval_context)) for f in ['primary_', 'secondary_']: - f_function = f+'function' - f_field_id = f+'field_id' - f_format = f+'format' - f_value = f+'value' + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' value = 0 if self[f_function] == 'count': value = count @@ -268,9 +190,9 @@ class TileTile(models.Model): 'secondary_function', 'secondary_field_id') def _compute_helper(self): for f in ['primary_', 'secondary_']: - f_function = f+'function' - f_field_id = f+'field_id' - f_helper = f+'helper' + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' self[f_helper] = '' field_func = FIELD_FUNCTIONS.get(self[f_function], {}) help = field_func.get('help', False) @@ -285,15 +207,13 @@ class TileTile(models.Model): def _compute_active(self): ima = self.env['ir.model.access'] self.active = ima.check(self.model_id.model, 'read', False) ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) def _search_active(self, operator, value): cr = self.env.cr if operator != '=': raise except_orm( - 'Unimplemented Feature', - 'Search on Active field disabled.') - ima_obj = self.env['ir.model.access'] + _('Unimplemented Feature. Search on Active field disabled.')) + ima = self.env['ir.model.access'] ids = [] cr.execute(""" SELECT tt.id, im.model @@ -301,40 +221,10 @@ class TileTile(models.Model): INNER JOIN ir_model im ON tt.model_id = im.id""") for result in cr.fetchall(): - if (ima_obj.check(result[1], 'read', False) == value): + if (ima.check(result[1], 'read', False) == value): ids.append(result[0]) return [('id', 'in', ids)] -<<<<<<< HEAD - # Column Section - name = fields.Char(required=True) - model_id = fields.Many2one( - comodel_name='ir.model', string='Model', required=True) - user_id = fields.Many2one( - comodel_name='res.users', string='User') - domain = fields.Text(default='[]') - action_id = fields.Many2one( - comodel_name='ir.actions.act_window', string='Action') - count = fields.Integer(compute='_get_tile_info') - computed_value = fields.Float(compute='_get_tile_info') - helper = fields.Char(compute='_get_tile_info') - field_function = fields.Selection(selection=[ - ('min', 'Minimum'), - ('max', 'Maximum'), - ('sum', 'Sum'), - ('avg', 'Average'), - ('median', 'Median'), - ], string='Function') - field_id = fields.Many2one( - comodel_name='ir.model.fields', string='Field', - domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'int'])]") - active = fields.Boolean( - compute='_get_tile_info', readonly=True, search='_search_active') - background_color = fields.Char(default='#0E6C7E', oldname='color') - font_color = fields.Char(default='#FFFFFF') - sequence = fields.Integer(default=0, required=True) -======= # Constraints and onchanges @api.one @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') @@ -344,9 +234,9 @@ class TileTile(models.Model): self.primary_field_id.model_id.id != self.model_id.id, self.secondary_field_id and self.secondary_field_id.model_id.id != self.model_id.id - ]): - raise ValidationError( - _("Please select a field from the selected model.")) + ]): + raise ValidationError( + _("Please select a field from the selected model.")) @api.onchange('model_id') def _onchange_model_id(self): @@ -359,34 +249,8 @@ class TileTile(models.Model): self.primary_field_id = False if self.secondary_function in [False, 'count']: self.secondary_field_id = False ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) - # Constraint Section - def _check_model_id_field_id(self, cr, uid, ids, context=None): - for t in self.browse(cr, uid, ids, context=context): - if t.field_id and t.field_id.model_id.id != t.model_id.id: - return False - return True - - def _check_field_id_field_function(self, cr, uid, ids, context=None): - for t in self.browse(cr, uid, ids, context=context): - if t.field_id and not t.field_function or\ - t.field_function and not t.field_id: - return False - return True - - _constraints = [ - ( - _check_model_id_field_id, - "Error ! Please select a field of the selected model.", - ['model_id', 'field_id']), - ( - _check_field_id_field_function, - "Error ! Please set both fields: 'Field' and 'Function'.", - ['field_id', 'field_function']), - ] - - # View / action Section + # Action methods @api.multi def open_link(self): res = { @@ -403,8 +267,7 @@ class TileTile(models.Model): } if self.action_id: res.update(self.action_id.read( - ['view_type', 'view_mode', 'view_id', 'type'])[0]) - # FIXME: restore original Domain + Filter would be better + ['view_type', 'view_mode', 'type'])[0]) return res @api.model diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 4ec483d72..73b811d3f 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -1,17 +1,10 @@ -.openerp .oe_kanban_view .oe_dashbaord_tile{ +.openerp .oe_kanban_view .oe_dashboard_tile { width: 150px; height: 150px; border: 0; border-radius: 0; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label, -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value, -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value, -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value { - width: 140px; -======= /* Disable default kanban style */ .openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { margin-right: inherit!important; @@ -20,44 +13,27 @@ .openerp .oe_kanban_view .oe_dashboard_tile .tile_label, .openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, .openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) text-align: center; font-weight: bold; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_label{ -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_label { ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) padding: 5px; font-size: 15px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_without_computed_value{ - font-size: 52px; - font-weight: bold; -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ font-size: 54px; ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; right: 5px; bottom: 5px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_count_with_computed_value{ - font-size: 38px; - font-weight: bold; -======= .openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ display: none; font-size: 18px; font-style: italic; ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) position: absolute; left: 5px; right: 5px; @@ -69,16 +45,6 @@ bottom: 30px; } -<<<<<<< HEAD -.openerp .oe_kanban_view .oe_dashbaord_tile .tile_computed_value{ - font-size: 18px; - font-weight: bold; - position: absolute; - right: 10px; - bottom: 5px; - font-style: italic; -} -======= .openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_secondary_value{ display: block; } @@ -90,5 +56,4 @@ .openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { display: block; -} ->>>>>>> 3ab676d... [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) +} \ No newline at end of file diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index c192ef293..9015f9a9d 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -19,7 +19,7 @@ // //############################################################################# -openerp.web_dashboard_tile = function (instance) +odoo.web_dashboard_tile = function (instance) { var QWeb = instance.web.qweb, _t = instance.web._t, @@ -35,13 +35,13 @@ _.mixin({ var self = this; this.$('#add_dashboard_tile').on('click', this, function (){ self.save_tile(); - }) + }); }, render_data: function(dashboard_choices){ var selection = instance.web.qweb.render( "SearchView.addtodashboard.selection", { selections: dashboard_choices}); - this.$("form input").before(selection) + this.$("form input").before(selection); }, save_tile: function () { var self = this; @@ -97,4 +97,4 @@ _.mixin({ } }); -} +}; diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 3e0c23167..11ecb179c 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -2,11 +2,11 @@ -
+
- + \ No newline at end of file diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index e7a68b213..1fe51f0d1 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ - + \ No newline at end of file diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index cf9a003f4..a42d952f8 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -103,7 +103,7 @@ -
+
@@ -152,9 +152,9 @@ Dashboard - + - + From 5054de3fda3211731e0f100801cabb46b102b53f Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:34:23 -0300 Subject: [PATCH 21/57] FIX __openerp__ --- web_dashboard_tile/__openerp__.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index bcba4eb5d..dbda3d3b7 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -1,26 +1,4 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2010-2013 OpenERP s.a. (). -# Copyright (C) 2014 initOS GmbH & Co. KG (). -# Author Markus Schneider -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html From 31e2d00110600077df63bf18ab319e16ce600277 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 15:44:42 -0300 Subject: [PATCH 22/57] FIX --- web_dashboard_tile/README.rst | 2 +- web_dashboard_tile/static/src/xml/custom_xml.xml | 2 +- web_dashboard_tile/views/templates.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 523dcadb5..daa3a2ebf 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -74,4 +74,4 @@ This module is maintained by the OCA. 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. -To contribute to this module, please visit http://odoo-community.org. \ No newline at end of file +To contribute to this module, please visit http://odoo-community.org. diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 11ecb179c..38a0e3e96 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -9,4 +9,4 @@
- \ No newline at end of file + diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index 1fe51f0d1..e7a68b213 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -30,4 +30,4 @@ - \ No newline at end of file + From 18676f3dbfe46cf419dfdc42273b0c5e49e1a9f5 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 16:02:54 -0300 Subject: [PATCH 23/57] FIX remove api.one --- web_dashboard_tile/models/tile_tile.py | 136 +++++++++++++------------ 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index bc304b691..38ce5c66c 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -142,71 +142,74 @@ class TileTile(models.Model): string='Error Details', compute='_compute_data') - @api.one + @api.multi def _compute_data(self): - if not self.active: - return - model = self.env[self.model_id.model] - eval_context = self._get_eval_context() - domain = self.domain or '[]' - try: - count = model.search_count(eval(domain, eval_context)) - except Exception as e: - self.primary_value = self.secondary_value = 'ERR!' - self.error = str(e) - return - if any([ - self.primary_function and - self.primary_function != 'count', - self.secondary_function and - self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_format = f + 'format' - f_value = f + 'value' - value = 0 - if self[f_function] == 'count': - value = count - elif self[f_function]: - func = FIELD_FUNCTIONS[self[f_function]]['func'] - if func and self[f_field_id] and count: - vals = [x[self[f_field_id].name] for x in records] - value = func(vals) - if self[f_function]: - try: - self[f_value] = (self[f_format] or '{:,}').format(value) - except ValueError as e: - self[f_value] = 'F_ERR!' - self.error = str(e) - return - else: - self[f_value] = False + for rec in self: + if not rec.active: + return + model = self.env[rec.model_id.model] + eval_context = self._get_eval_context() + domain = rec.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + rec.primary_value = rec.secondary_value = 'ERR!' + rec.error = str(e) + return + if any([ + rec.primary_function and + rec.primary_function != 'count', + rec.secondary_function and + rec.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' + value = 0 + if rec[f_function] == 'count': + value = count + elif rec[f_function]: + func = FIELD_FUNCTIONS[rec[f_function]]['func'] + if func and rec[f_field_id] and count: + vals = [x[rec[f_field_id].name] for x in records] + value = func(vals) + if rec[f_function]: + try: + rec[f_value] = (rec[f_format] or '{:,}').format(value) + except ValueError as e: + rec[f_value] = 'F_ERR!' + rec.error = str(e) + return + else: + rec[f_value] = False - @api.one + @api.multi @api.onchange('primary_function', 'primary_field_id', 'secondary_function', 'secondary_field_id') def _compute_helper(self): - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_helper = f + 'helper' - self[f_helper] = '' - field_func = FIELD_FUNCTIONS.get(self[f_function], {}) - help = field_func.get('help', False) - if help: - if self[f_function] != 'count' and self[f_field_id]: - desc = self[f_field_id].field_description - self[f_helper] = help % desc - else: - self[f_helper] = help + for rec in self: + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' + rec[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(rec[f_function], {}) + help = field_func.get('help', False) + if help: + if rec[f_function] != 'count' and rec[f_field_id]: + desc = rec[f_field_id].field_description + rec[f_helper] = help % desc + else: + rec[f_helper] = help - @api.one + @api.multi def _compute_active(self): ima = self.env['ir.model.access'] - self.active = ima.check(self.model_id.model, 'read', False) + for rec in self: + rec.active = ima.check(rec.model_id.model, 'read', False) def _search_active(self, operator, value): cr = self.env.cr @@ -226,17 +229,18 @@ class TileTile(models.Model): return [('id', 'in', ids)] # Constraints and onchanges - @api.one + @api.multi @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') def _check_model_id_field_id(self): - if any([ - self.primary_field_id and - self.primary_field_id.model_id.id != self.model_id.id, - self.secondary_field_id and - self.secondary_field_id.model_id.id != self.model_id.id - ]): - raise ValidationError( - _("Please select a field from the selected model.")) + for rec in self: + if any([ + rec.primary_field_id and + rec.primary_field_id.model_id.id != rec.model_id.id, + rec.secondary_field_id and + rec.secondary_field_id.model_id.id != rec.model_id.id + ]): + raise ValidationError( + _("Please select a field from the selected model.")) @api.onchange('model_id') def _onchange_model_id(self): From 132beefd4bc8e2454d52f34a7af38c15f8de434d Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 13 Dec 2016 16:45:28 -0300 Subject: [PATCH 24/57] IMP implementation of iteration --- web_dashboard_tile/models/tile_tile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 38ce5c66c..0ee69ef62 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -144,12 +144,12 @@ class TileTile(models.Model): @api.multi def _compute_data(self): + eval_context = self._get_eval_context() for rec in self: if not rec.active: return - model = self.env[rec.model_id.model] - eval_context = self._get_eval_context() domain = rec.domain or '[]' + model = rec.env[rec.model_id.model] try: count = model.search_count(eval(domain, eval_context)) except Exception as e: From 6f94b6144ee4758b8b590670b92bda4a8d49b3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Sat, 19 Nov 2016 14:07:01 -0300 Subject: [PATCH 25/57] [IMP][8.0][web_dashboard_tile] Refactor (see changes in description) (#476) Conflicts: web_dashboard_tile/__openerp__.py web_dashboard_tile/models/tile_tile.py --- web_dashboard_tile/models/tile_tile.py | 112 ++++++++++----------- web_dashboard_tile/static/src/css/tile.css | 2 +- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 0ee69ef62..7f4866bca 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -142,70 +142,68 @@ class TileTile(models.Model): string='Error Details', compute='_compute_data') - @api.multi + @api.one def _compute_data(self): + if not self.active: + return + model = self.env[self.model_id.model] eval_context = self._get_eval_context() - for rec in self: - if not rec.active: - return - domain = rec.domain or '[]' - model = rec.env[rec.model_id.model] - try: - count = model.search_count(eval(domain, eval_context)) - except Exception as e: - rec.primary_value = rec.secondary_value = 'ERR!' - rec.error = str(e) - return - if any([ - rec.primary_function and - rec.primary_function != 'count', - rec.secondary_function and - rec.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_format = f + 'format' - f_value = f + 'value' - value = 0 - if rec[f_function] == 'count': - value = count - elif rec[f_function]: - func = FIELD_FUNCTIONS[rec[f_function]]['func'] - if func and rec[f_field_id] and count: - vals = [x[rec[f_field_id].name] for x in records] - value = func(vals) - if rec[f_function]: - try: - rec[f_value] = (rec[f_format] or '{:,}').format(value) - except ValueError as e: - rec[f_value] = 'F_ERR!' - rec.error = str(e) - return - else: - rec[f_value] = False + domain = self.domain or '[]' + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + self.primary_value = self.secondary_value = 'ERR!' + self.error = str(e) + return + if any([ + self.primary_function and + self.primary_function != 'count', + self.secondary_function and + self.secondary_function != 'count' + ]): + records = model.search(eval(domain, eval_context)) + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_format = f + 'format' + f_value = f + 'value' + value = 0 + if self[f_function] == 'count': + value = count + elif self[f_function]: + func = FIELD_FUNCTIONS[self[f_function]]['func'] + if func and self[f_field_id] and count: + vals = [x[self[f_field_id].name] for x in records] + value = func(vals) + if self[f_function]: + try: + self[f_value] = (self[f_format] or '{:,}').format(value) + except ValueError as e: + self[f_value] = 'F_ERR!' + self.error = str(e) + return + else: + self[f_value] = False - @api.multi + @api.one @api.onchange('primary_function', 'primary_field_id', 'secondary_function', 'secondary_field_id') def _compute_helper(self): - for rec in self: - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_helper = f + 'helper' - rec[f_helper] = '' - field_func = FIELD_FUNCTIONS.get(rec[f_function], {}) - help = field_func.get('help', False) - if help: - if rec[f_function] != 'count' and rec[f_field_id]: - desc = rec[f_field_id].field_description - rec[f_helper] = help % desc - else: - rec[f_helper] = help + for f in ['primary_', 'secondary_']: + f_function = f + 'function' + f_field_id = f + 'field_id' + f_helper = f + 'helper' + self[f_helper] = '' + field_func = FIELD_FUNCTIONS.get(self[f_function], {}) + help = field_func.get('help', False) + if help: + if self[f_function] != 'count' and self[f_field_id]: + desc = self[f_field_id].field_description + self[f_helper] = help % desc + else: + self[f_helper] = help - @api.multi + @api.one def _compute_active(self): ima = self.env['ir.model.access'] for rec in self: diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 73b811d3f..0620a9c65 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -56,4 +56,4 @@ .openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { display: block; -} \ No newline at end of file +} From e47da159d7bf9d2bf8adf71caf7cea6b693e85b9 Mon Sep 17 00:00:00 2001 From: Nicolas Mac Rouillon Date: Tue, 27 Dec 2016 16:57:47 -0300 Subject: [PATCH 26/57] FIX --- web_dashboard_tile/models/tile_tile.py | 4 ++-- web_dashboard_tile/static/src/js/custom_js.js | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 7f4866bca..218cec406 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -106,7 +106,7 @@ class TileTile(models.Model): 'ir.model.fields', string='Field', domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'integer'])]") + " ('ttype', 'in', ['float', 'integer', 'monetary'])]") primary_format = fields.Char( string='Format', help='Python Format String valid with str.format()\n' @@ -126,7 +126,7 @@ class TileTile(models.Model): 'ir.model.fields', string='Secondary Field', domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'integer'])]") + " ('ttype', 'in', ['float', 'integer', 'monetary'])]") secondary_format = fields.Char( string='Secondary Format', help='Python Format String valid with str.format()\n' diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index 9015f9a9d..615a74d6b 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -19,11 +19,12 @@ // //############################################################################# -odoo.web_dashboard_tile = function (instance) +odoo.web_dashboard_tile = function (require) { -var QWeb = instance.web.qweb, - _t = instance.web._t, - _lt = instance.web._lt; +var QWeb = require('web.qweb') +var _t = require('web._t') +var _lt = require('web._lt') + _.mixin({ sum: function (obj) { return _.reduce(obj, function (a, b) { return a + b; }, 0); } }); From 0ba68061497d498611ef47f375ae4e6a543af5e1 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sat, 27 Jan 2018 16:38:38 +0100 Subject: [PATCH 27/57] OCA Transbot updated translations from Transifex --- web_dashboard_tile/i18n/ar.po | 332 ++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/ca.po | 332 ++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/de.po | 333 +++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/es.po | 333 +++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/fi.po | 332 ++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/fr.po | 251 ++++++++++++++++------- web_dashboard_tile/i18n/it.po | 332 ++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/nl.po | 332 ++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/pt_BR.po | 333 +++++++++++++++++++++++++++++++ web_dashboard_tile/i18n/sl.po | 259 ++++++++++++++++-------- web_dashboard_tile/i18n/tr.po | 332 ++++++++++++++++++++++++++++++ 11 files changed, 3352 insertions(+), 149 deletions(-) create mode 100644 web_dashboard_tile/i18n/ar.po create mode 100644 web_dashboard_tile/i18n/ca.po create mode 100644 web_dashboard_tile/i18n/de.po create mode 100644 web_dashboard_tile/i18n/es.po create mode 100644 web_dashboard_tile/i18n/fi.po create mode 100644 web_dashboard_tile/i18n/it.po create mode 100644 web_dashboard_tile/i18n/nl.po create mode 100644 web_dashboard_tile/i18n/pt_BR.po create mode 100644 web_dashboard_tile/i18n/tr.po diff --git a/web_dashboard_tile/i18n/ar.po b/web_dashboard_tile/i18n/ar.po new file mode 100644 index 000000000..baec909fe --- /dev/null +++ b/web_dashboard_tile/i18n/ar.po @@ -0,0 +1,332 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Arabic (https://www.transifex.com/oca/teams/23907/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "الحقل" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/ca.po b/web_dashboard_tile/i18n/ca.po new file mode 100644 index 000000000..c8f94eb99 --- /dev/null +++ b/web_dashboard_tile/i18n/ca.po @@ -0,0 +1,332 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# Marc Tormo i Bochaca , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: Marc Tormo i Bochaca , 2018\n" +"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "Creat per" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "Creat a " + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "Nom a mostrar" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "ID" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "Última modificació a" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "Última actualització per" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "Última actualització a " + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/de.po b/web_dashboard_tile/i18n/de.po new file mode 100644 index 000000000..a1a769569 --- /dev/null +++ b/web_dashboard_tile/i18n/de.po @@ -0,0 +1,333 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# Rudolf Schnapka , 2018 +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "Anlegen" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "Angelegt durch" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "Angelegt am" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "Anzeigebezeichnung" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Feld" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "ID" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "Zuletzt geändert am" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "Zuletzt geändert durch" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "Zuletzt aktualisiert am" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/es.po b/web_dashboard_tile/i18n/es.po new file mode 100644 index 000000000..b3feb292b --- /dev/null +++ b/web_dashboard_tile/i18n/es.po @@ -0,0 +1,333 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 +# Pedro M. Baeza , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: Pedro M. Baeza , 2018\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "Crear" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Campo" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/fi.po b/web_dashboard_tile/i18n/fi.po new file mode 100644 index 000000000..ac240f69d --- /dev/null +++ b/web_dashboard_tile/i18n/fi.po @@ -0,0 +1,332 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Kenttä" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/fr.po b/web_dashboard_tile/i18n/fr.po index 6bb700fa3..efd8077ce 100644 --- a/web_dashboard_tile/i18n/fr.po +++ b/web_dashboard_tile/i18n/fr.po @@ -1,53 +1,48 @@ -# Translation of OpenERP Server. +# Translation of Odoo Server. # This file contains the translation of the following modules: -# * web_dashboard_tile -# +# * web_dashboard_tile +# +# Translators: +# leemannd , 2018 +# OCA Transbot , 2018 msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-10 01:04+0000\n" -"PO-Revision-Date: 2015-04-10 01:04+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" #. module: web_dashboard_tile -#: field:tile.tile,action_id:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id msgid "Action" msgstr "Action" #. module: web_dashboard_tile -#: field:tile.tile,active:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active msgid "Active" msgstr "Actif" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Average" msgstr "Moyenne" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:82 -#, python-format -msgid "Average value of '%s'" -msgstr "Valeur moyenne du champ '%s'" - -#. module: web_dashboard_tile -#: field:tile.tile,color:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color msgid "Background color" msgstr "Couleur de fond" #. module: web_dashboard_tile -#: field:tile.tile,computed_value:0 -msgid "Computed Value" -msgstr "Valeur calculée" - -#. module: web_dashboard_tile -#: field:tile.tile,count:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Count" msgstr "Quantité" @@ -58,6 +53,16 @@ msgstr "Quantité" msgid "Create" msgstr "Créer" +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "Créé le" + #. module: web_dashboard_tile #: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile #: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile @@ -66,137 +71,234 @@ msgid "Dashboard" msgstr "Tableau de bord" #. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile #: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile msgid "Dashboard Tile" msgstr "Indicateur de tableau de bord" #. module: web_dashboard_tile -#: view:tile.tile:0 +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view msgid "Dashboard tiles" msgstr "Indicateurs de tableau de bord" #. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Delete" -msgstr "Supprimer" +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" #. module: web_dashboard_tile -#: field:tile.tile,domain:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain msgid "Domain" msgstr "Domaine" -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Edit..." -msgstr "Editer..." - #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 #, python-format msgid "Error" msgstr "Erreur" #. module: web_dashboard_tile -#: constraint:tile.tile:0 -msgid "Error ! Please select a field of the selected model." -msgstr "Erreur ! Veuillez sélectioner un champ qui correspond au modèle." +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" #. module: web_dashboard_tile -#: constraint:tile.tile:0 -msgid "Error ! Please set both fields: 'Field' and 'Function'." -msgstr "Erreur ! Veuillez renseigner les deux champs : 'Champ' et 'Fonction'." - -#. module: web_dashboard_tile -#: field:tile.tile,field_id:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id msgid "Field" msgstr "Champ" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 #, python-format msgid "Filter name is required." msgstr "Le nom du filtre est requis." #. module: web_dashboard_tile -#: field:tile.tile,font_color:0 -msgid "Font Color" -msgstr "Couleur du texte" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" #. module: web_dashboard_tile -#: field:tile.tile,field_function:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function msgid "Function" msgstr "Fonction" #. module: web_dashboard_tile -#: field:tile.tile,helper:0 -msgid "Helper Text" -msgstr "Texte Descriptif" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "ID" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "Mis à jour par" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "Mis à jour le" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Maximum" msgstr "Maximum" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:76 +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 #, python-format msgid "Maximum value of '%s'" msgstr "Valeur maximale du champ '%s'" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Median" msgstr "Médiane" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:85 +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 #, python-format msgid "Median value of '%s'" msgstr "Valeur médian du champ '%s'" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Minimum" msgstr "Minimum" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:73 +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 #, python-format msgid "Minimum value of '%s'" msgstr "Valeur minimale du champ '%s'" #. module: web_dashboard_tile -#: field:tile.tile,model_id:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id msgid "Model" msgstr "Modèle" #. module: web_dashboard_tile -#: field:tile.tile,sequence:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence msgid "Sequence" msgstr "Séquence" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 #, python-format msgid "Success" msgstr "Succès" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Sum" msgstr "Somme" #. module: web_dashboard_tile -#: field:tile.tile,name:0 -msgid "Tile Name" -msgstr "Nom de l'indicateur" +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 #, python-format msgid "Tile is created" msgstr "L'indicateur a été créé" @@ -209,12 +311,23 @@ msgid "Tile:" msgstr "Indicateur :" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:79 +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 #, python-format msgid "Total value of '%s'" msgstr "Somme du champ '%s'" #. module: web_dashboard_tile -#: field:tile.tile,user_id:0 +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id msgid "User" msgstr "Utilisateur" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/it.po b/web_dashboard_tile/i18n/it.po new file mode 100644 index 000000000..07e8fdbf3 --- /dev/null +++ b/web_dashboard_tile/i18n/it.po @@ -0,0 +1,332 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Campo" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/nl.po b/web_dashboard_tile/i18n/nl.po new file mode 100644 index 000000000..a2699d59c --- /dev/null +++ b/web_dashboard_tile/i18n/nl.po @@ -0,0 +1,332 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: nl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Veld" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/pt_BR.po b/web_dashboard_tile/i18n/pt_BR.po new file mode 100644 index 000000000..2254f37a4 --- /dev/null +++ b/web_dashboard_tile/i18n/pt_BR.po @@ -0,0 +1,333 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# Armando Vulcano Junior , 2018 +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/teams/23907/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "Criar" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "Criado em" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "Mostrar Nome" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Campo" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "ID" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "Última Modificação em" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "Última Atualização por" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "Última Atualização em" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/sl.po b/web_dashboard_tile/i18n/sl.po index 8e8632413..41c6e417f 100644 --- a/web_dashboard_tile/i18n/sl.po +++ b/web_dashboard_tile/i18n/sl.po @@ -1,55 +1,47 @@ -# Translation of OpenERP Server. +# Translation of Odoo Server. # This file contains the translation of the following modules: -# * web_dashboard_tile -# +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 msgid "" msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" +"Project-Id-Version: Odoo Server 9.0c\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-08-02 10:08+0200\n" -"PO-Revision-Date: 2015-08-02 10:17+0200\n" -"Last-Translator: Matjaz Mozetic \n" -"Language-Team: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" -"X-Generator: Poedit 1.8.2\n" +"Content-Transfer-Encoding: \n" "Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" #. module: web_dashboard_tile -#: field:tile.tile,action_id:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id msgid "Action" msgstr "Dejanje" #. module: web_dashboard_tile -#: field:tile.tile,active:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active msgid "Active" msgstr "Aktivno" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Average" msgstr "Povprečje" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:82 -#, python-format -msgid "Average value of '%s'" -msgstr "Povprečna vrednost '%s'" - -#. module: web_dashboard_tile -#: field:tile.tile,color:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color msgid "Background color" msgstr "Barva ozadja" #. module: web_dashboard_tile -#: field:tile.tile,computed_value:0 -msgid "Computed Value" -msgstr "Izračunana vrednost" - -#. module: web_dashboard_tile -#: field:tile.tile,count:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Count" msgstr "Štetje" @@ -60,6 +52,16 @@ msgstr "Štetje" msgid "Create" msgstr "Ustvari" +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "Ustvaril" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "Ustvarjeno" + #. module: web_dashboard_tile #: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile #: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile @@ -68,137 +70,234 @@ msgid "Dashboard" msgstr "Nadzorna plošča" #. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile #: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile msgid "Dashboard Tile" msgstr "Okvir nadzorne plošče" #. module: web_dashboard_tile -#: view:tile.tile:0 +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view msgid "Dashboard tiles" msgstr "Okvirji nadzorne plošče" #. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Delete" -msgstr "Izbris" +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" #. module: web_dashboard_tile -#: field:tile.tile,domain:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain msgid "Domain" msgstr "Domena" -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Edit..." -msgstr "Urejanje..." - #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 #, python-format msgid "Error" msgstr "Napaka" #. module: web_dashboard_tile -#: constraint:tile.tile:0 -msgid "Error ! Please select a field of the selected model." -msgstr "Napaka! Izberite polje izbranega modela." +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" #. module: web_dashboard_tile -#: constraint:tile.tile:0 -msgid "Error ! Please set both fields: 'Field' and 'Function'." -msgstr "Napaka! Določite obe polji: 'Polje' in 'Funkcija'." - -#. module: web_dashboard_tile -#: field:tile.tile,field_id:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id msgid "Field" msgstr "Polje" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 #, python-format msgid "Filter name is required." msgstr "Zahtevan je naziv filtra." #. module: web_dashboard_tile -#: field:tile.tile,font_color:0 -msgid "Font Color" -msgstr "Barva pisave" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" #. module: web_dashboard_tile -#: field:tile.tile,field_function:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function msgid "Function" msgstr "Funkcija" #. module: web_dashboard_tile -#: field:tile.tile,helper:0 -msgid "Helper Text" -msgstr "Besedilo pomoči" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "ID" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "Zadnjič posodobil" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "Zadnjič posodobljeno" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Maximum" msgstr "Maksimum" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:76 +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 #, python-format msgid "Maximum value of '%s'" msgstr "Maksimalna vrednost '%s'" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Median" msgstr "Sredina" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:85 +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 #, python-format msgid "Median value of '%s'" msgstr "Srednja vrednost '%s'" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Minimum" msgstr "Minimum" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:73 +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 #, python-format msgid "Minimum value of '%s'" msgstr "Minimalna vrednost '%s'" #. module: web_dashboard_tile -#: field:tile.tile,model_id:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id msgid "Model" msgstr "Model" #. module: web_dashboard_tile -#: field:tile.tile,sequence:0 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence msgid "Sequence" msgstr "Zaporedje" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 #, python-format msgid "Success" msgstr "Uspeh" #. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 msgid "Sum" msgstr "Vsota" #. module: web_dashboard_tile -#: field:tile.tile,name:0 -msgid "Tile Name" -msgstr "Naziv okvirja" +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 #, python-format msgid "Tile is created" msgstr "Okvir je ustvarjen" @@ -211,23 +310,23 @@ msgid "Tile:" msgstr "Okvir:" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:79 +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 #, python-format msgid "Total value of '%s'" msgstr "Skupna vrednost '%s'" #. module: web_dashboard_tile -#: field:tile.tile,user_id:0 +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id msgid "User" msgstr "Uporabnik" #. module: web_dashboard_tile -#: code:_description:0 model:ir.model,name:web_dashboard_tile.model_tile_tile -#, python-format -msgid "tile.tile" -msgstr "tile.tile" - -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "í" -msgstr "í" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" diff --git a/web_dashboard_tile/i18n/tr.po b/web_dashboard_tile/i18n/tr.po new file mode 100644 index 000000000..39362c361 --- /dev/null +++ b/web_dashboard_tile/i18n/tr.po @@ -0,0 +1,332 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dashboard_tile +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 03:54+0000\n" +"PO-Revision-Date: 2018-01-25 03:54+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: tr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +msgid "Action" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +msgid "Active" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Average" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color +msgid "Background color" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Count" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +msgid "Created by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +msgid "Created on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard +msgid "Dashboard" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model,name:web_dashboard_tile.model_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile +msgid "Dashboard Tile" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view +msgid "Dashboard tiles" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Display" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +msgid "Display Name" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +msgid "Domain" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +msgid "Error Details" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id +msgid "Field" +msgstr "Alan" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#, python-format +msgid "Filter name is required." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color +msgid "Font color" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format +msgid "Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function +msgid "Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Groups" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper +msgid "Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +msgid "ID" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids +msgid "" +"If this field is set, only users of this group can view this tile. Please " +"note that it will only work for global tiles (that is, when User field is " +"left empty)" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +msgid "Last Updated on" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Main Value" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Maximum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#, python-format +msgid "Maximum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Median" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#, python-format +msgid "Median value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Minimum" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:35 +#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#, python-format +msgid "Minimum value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +msgid "Model" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name +msgid "Name" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#, python-format +msgid "Number of records" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#, python-format +msgid "Please select a field from the selected model." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format +msgid "" +"Python Format String valid with str.format()\n" +"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +msgid "Secondary Field" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +msgid "Secondary Format" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +msgid "Secondary Function" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +msgid "Secondary Helper" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Secondary Value" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +msgid "Sequence" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Success" +msgstr "" + +#. module: web_dashboard_tile +#: selection:tile.tile,primary_function:0 +#: selection:tile.tile,secondary_function:0 +msgid "Sum" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +msgid "Technical Informations" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 +#, python-format +msgid "Tile is created" +msgstr "" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 +#, python-format +msgid "Tile:" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#, python-format +msgid "Total value of '%s'" +msgstr "" + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#, python-format +msgid "Unimplemented Feature. Search on Active field disabled." +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +msgid "User" +msgstr "" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value +msgid "Value" +msgstr "" From 9683b3f117fde904de3202f766c12ebf1df746a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 12 Feb 2018 13:49:52 -0300 Subject: [PATCH 28/57] Fix styles (MIG 9.0) --- web_dashboard_tile/static/src/css/tile.css | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 0620a9c65..623a28136 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -1,28 +1,32 @@ -.openerp .oe_kanban_view .oe_dashboard_tile { +/* custom kanban style */ +.o_kanban_view .oe_dashboard_tile { width: 150px; height: 150px; - border: 0; - border-radius: 0; } -/* Disable default kanban style */ -.openerp .oe_kanban_view .oe_dashboard_tile .oe_kanban_content div:first-child { - margin-right: inherit!important; +.o_kanban_view.o_kanban_ungrouped .o_kanban_record.oe_dashboard_tile { + /* override max-width rules */ + margin: 4px !important; + /* flex width */ + -ms-flex: 1 1 150px; + -moz-flex: 1 1 150px; + -webkit-flex: 1 1 150px; + flex: 1 1 150px; } -.openerp .oe_kanban_view .oe_dashboard_tile .tile_label, -.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value, -.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value { +.o_kanban_view .oe_dashboard_tile .tile_label, +.o_kanban_view .oe_dashboard_tile .tile_primary_value, +.o_kanban_view .oe_dashboard_tile .tile_secondary_value { text-align: center; font-weight: bold; } -.openerp .oe_kanban_view .oe_dashboard_tile .tile_label { +.o_kanban_view .oe_dashboard_tile .tile_label { padding: 5px; font-size: 15px; } -.openerp .oe_kanban_view .oe_dashboard_tile .tile_primary_value{ +.o_kanban_view .oe_dashboard_tile .tile_primary_value{ font-size: 54px; position: absolute; left: 5px; @@ -30,7 +34,7 @@ bottom: 5px; } -.openerp .oe_kanban_view .oe_dashboard_tile .tile_secondary_value{ +.o_kanban_view .oe_dashboard_tile .tile_secondary_value{ display: none; font-size: 18px; font-style: italic; @@ -40,20 +44,20 @@ bottom: 5px; } -.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_primary_value{ +.o_kanban_view .oe_dashboard_tile .with_secondary .tile_primary_value{ font-size: 38px; bottom: 30px; } -.openerp .oe_kanban_view .oe_dashboard_tile .with_secondary .tile_secondary_value{ +.o_kanban_view .oe_dashboard_tile .with_secondary .tile_secondary_value{ display: block; } /* SearchView Drawer */ -.openerp .oe_searchview_drawer .oe_searchview_dashboard .oe_dashboard_tile_form { +.oe_searchview_drawer .oe_searchview_dashboard .oe_dashboard_tile_form { display: none; } -.openerp .oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { +.oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { display: block; } From 08c6bc53291cf7fdc2fef50d3e31bd8f703a1b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 12 Feb 2018 19:58:01 -0300 Subject: [PATCH 29/57] Fix 'Add to Dashboard Tile' menu (MIG 9.0) --- web_dashboard_tile/static/src/css/tile.css | 15 +- web_dashboard_tile/static/src/js/custom_js.js | 192 +++++++++++------- .../static/src/xml/custom_xml.xml | 25 +-- 3 files changed, 135 insertions(+), 97 deletions(-) diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 623a28136..7f9b61d5a 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -5,8 +5,8 @@ } .o_kanban_view.o_kanban_ungrouped .o_kanban_record.oe_dashboard_tile { - /* override max-width rules */ - margin: 4px !important; + /* override max-width rules */ + margin: 4px !important; /* flex width */ -ms-flex: 1 1 150px; -moz-flex: 1 1 150px; @@ -53,11 +53,8 @@ display: block; } -/* SearchView Drawer */ -.oe_searchview_drawer .oe_searchview_dashboard .oe_dashboard_tile_form { - display: none; -} - -.oe_searchview_drawer .oe_opened .oe_dashboard_tile_form { - display: block; +/* Favorites menu in control panel */ +.o_add_to_dashboard_tile { + /* hidden by default */ + display: none; } diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js index 615a74d6b..66094df85 100644 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ b/web_dashboard_tile/static/src/js/custom_js.js @@ -3,6 +3,7 @@ // // Copyright (C) 2010-2013 OpenERP s.a. () // Copyright (C) 2014 initOS GmbH & Co. KG () +// Copyright (C) 2018 Iván Todorovich () // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published @@ -19,83 +20,122 @@ // //############################################################################# -odoo.web_dashboard_tile = function (require) -{ -var QWeb = require('web.qweb') -var _t = require('web._t') -var _lt = require('web._lt') +odoo.define('web_dashboard_tile', function (require) { +"use strict"; -_.mixin({ - sum: function (obj) { return _.reduce(obj, function (a, b) { return a + b; }, 0); } -}); - var module = instance.board.AddToDashboard; +var core = require('web.core'); +var data = require('web.data'); +var FavoriteMenu = require('web.FavoriteMenu'); +var ActionManager = require('web.ActionManager'); +var ViewManager = require('web.ViewManager'); +var Model = require('web.DataModel'); +var session = require('web.session'); +var pyeval = require('web.pyeval'); +var _t = core._t; +var QWeb = core.qweb; - module.include({ - start: function () { - this._super(); - var self = this; - this.$('#add_dashboard_tile').on('click', this, function (){ - self.save_tile(); + +FavoriteMenu.include({ + + prepare_dropdown_menu: function (filters) { + var self = this; + this._super(filters); + var am = this.findAncestor(function (a) { + return a instanceof ActionManager; + }); + if (am && am.get_inner_widget() instanceof ViewManager) { + this.view_manager = am.get_inner_widget(); + this.add_to_dashboard_tile_available = true; + this.$('.o_favorites_menu').append(QWeb.render('SearchView.addtodashboardtile')); + this.$add_to_dashboard_tile = this.$('.o_add_to_dashboard_tile'); + this.$add_dashboard_tile_btn = this.$add_to_dashboard_tile.eq(1).find('button'); + this.$add_dashboard_tile_input = this.$add_to_dashboard_tile.eq(0).find('input'); + this.$add_dashboard_tile_link = this.$('.o_add_to_dashboard_tile_link'); + var title = this.searchview.get_title(); + this.$add_dashboard_tile_input.val(title); + this.$add_dashboard_tile_link.click(function (e) { + e.preventDefault(); + self.toggle_dashboard_tile_menu(); }); - }, - render_data: function(dashboard_choices){ - var selection = instance.web.qweb.render( - "SearchView.addtodashboard.selection", { - selections: dashboard_choices}); - this.$("form input").before(selection); - }, - save_tile: function () { - var self = this; - var view_parent = this.getParent().getParent(); - - var $name = this.$('#dashboard_tile_new_name'); - - this.tile = new instance.web.Model('tile.tile'); - - var private_filter = !this.$('#oe_searchview_custom_public').prop('checked'); - if (_.isEmpty($name.val())){ - this.do_warn(_t("Error"), _t("Filter name is required.")); - return false; - } - var search = this.view.build_search_data(); - var context = new instance.web.CompoundContext(view_parent.dataset.get_context() || []); - var domain = new instance.web.CompoundDomain(view_parent.dataset.get_domain() || []); - _.each(search.contexts, context.add, context); - _.each(search.domains, domain.add, domain); - - var c = instance.web.pyeval.eval('context', context); - for(var k in c) { - if (c.hasOwnProperty(k) && /^search_default_/.test(k)) { - delete c[k]; - } - } - // TODO: replace this 6.1 workaround by attribute on - c.dashboard_merge_domains_contexts = false; - var d = instance.web.pyeval.eval('domain', domain); - - context.add({ - group_by: instance.web.pyeval.eval('groupbys', search.groupbys || []) - }); - // Don't save user_context keys in the custom filter, otherwise end - // up with e.g. wrong uid or lang stored *and used in subsequent - // reqs* - var ctx = context; - _(_.keys(instance.session.user_context)).each(function (key) { - delete ctx[key]; - }); - var filter = { - name: $name.val(), - user_id: private_filter ? instance.session.uid : false, - model_id: self.view.model, - //context: context, - domain: d, - action_id: view_parent.action.id, - }; - // FIXME: current context? - return self.tile.call('add', [filter]).done(function (id) { - self.do_warn(_t("Success"), _t("Tile is created")); - }); - + this.$add_dashboard_tile_btn.click(this.proxy('add_dashboard_tile')); } - }); -}; + }, + + toggle_dashboard_tile_menu: function (is_open) { + this.$add_dashboard_tile_link + .toggleClass('o_closed_menu', !(_.isUndefined(is_open)) ? !is_open : undefined) + .toggleClass('o_open_menu', is_open); + this.$add_to_dashboard_tile.toggle(is_open); + if (this.$add_dashboard_tile_link.hasClass('o_open_menu')) { + this.$add_dashboard_tile_input.focus(); + } + }, + + close_menus: function () { + if (this.add_to_dashboard_tile_available) { + this.toggle_dashboard_tile_menu(false); + } + this._super(); + }, + + add_dashboard_tile: function () { + var self = this; + + var search_data = this.searchview.build_search_data(), + context = new data.CompoundContext(this.searchview.dataset.get_context() || []), + domain = new data.CompoundDomain(this.searchview.dataset.get_domain() || []); + _.each(search_data.contexts, context.add, context); + _.each(search_data.domains, domain.add, domain); + + context.add({ + group_by: pyeval.eval('groupbys', search_data.groupbys || []) + }); + + context.add(this.view_manager.active_view.controller.get_context()); + + var c = pyeval.eval('context', context); + for(var k in c) { + if (c.hasOwnProperty(k) && /^search_default_/.test(k)) { + delete c[k]; + } + } + + this.toggle_dashboard_tile_menu(false); + + c.dashboard_merge_domains_contexts = false; + var d = pyeval.eval('domain', domain), + tile = new Model('tile.tile'), + name = self.$add_dashboard_tile_input.val(); + + var private_filter = !this.$('#oe_searchview_custom_public').prop('checked'); + if (_.isEmpty(name)){ + this.do_warn(_t("Error"), _t("Filter name is required.")); + return false; + } + + // Don't save user_context keys in the custom filter, otherwise end + // up with e.g. wrong uid or lang stored *and used in subsequent + // reqs* + var ctx = context; + _(_.keys(session.user_context)).each(function (key) { + delete ctx[key]; + }); + + var vals = { + name: name, + user_id: private_filter ? session.uid : false, + model_id: self.view_manager.active_view.controller.model, + //context: context, + domain: d, + action_id: self.action_id || false, + }; + + // FIXME: current context? + return tile.call('add', [vals]).done(function (id) { + self.do_notify(_t("Success"), _t("Tile is created")); + }); + }, +}); + +}); + diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml index 38a0e3e96..ba60a2447 100644 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ b/web_dashboard_tile/static/src/xml/custom_xml.xml @@ -1,12 +1,13 @@ - - - - -
- - - -
-
-
-
+ From 96fdaa61a66a7ef13a88d7e0fbe49b1315c3c021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 12 Feb 2018 20:24:10 -0300 Subject: [PATCH 30/57] Use o_kanban_small_column for grouping --- web_dashboard_tile/views/tile.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index a42d952f8..d427ea810 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -89,7 +89,7 @@ tile.tile - + From 0337d636a13a4747eddd684f4886ea02c0c17e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 12 Feb 2018 20:38:09 -0300 Subject: [PATCH 31/57] Use more pixels for title --- web_dashboard_tile/static/src/css/tile.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 7f9b61d5a..61045f6f8 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -22,7 +22,7 @@ } .o_kanban_view .oe_dashboard_tile .tile_label { - padding: 5px; + padding: 5px 0px; font-size: 15px; } From 75110f5bfc8c095795ac4bfeb7c5a2fbfc18f171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 12 Feb 2018 21:02:10 -0300 Subject: [PATCH 32/57] Added 'dropdown' menu for Technical Features only (debug mode) --- web_dashboard_tile/README.rst | 3 ++- web_dashboard_tile/static/src/css/tile.css | 7 +++++++ web_dashboard_tile/views/tile.xml | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index daa3a2ebf..84b8015b0 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -31,7 +31,8 @@ Usage Known issues ============ -* Can not edit tile from dashboard (color, sequence, function, ...). +* Can not edit color from dashboard +* Can not edit sequence from dashboard * Original context is ignored. * Original domain and filter are not restored. * To preserve a relative date domain, you have to manually edit the tile's domain from `Configuration > User Interface > Dashboard Tile`. You can use the same variables available in filters (`uid`, `context_today()`, `current_date`, `time`, `datetime`, `relativedelta`). diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 61045f6f8..723cb51f9 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -58,3 +58,10 @@ /* hidden by default */ display: none; } + +/* Make dropdown menu button not affect text flow */ +.o_kanban_view .oe_dashboard_tile .o_dropdown_kanban { + float: none; + position: absolute; + right: 8px; +} diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index d427ea810..5221aa410 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -89,7 +89,7 @@ tile.tile - + @@ -104,6 +104,19 @@
+ + +
@@ -145,7 +158,7 @@ Dashboard tile.tile form - kanban + kanban,form ['|',('user_id','=',False),('user_id','=',uid)] From 488a43e836becbc539f54b3e3caac0e1a0f39b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Mon, 12 Feb 2018 22:01:35 -0300 Subject: [PATCH 33/57] Added tile categories. --- web_dashboard_tile/__openerp__.py | 1 + web_dashboard_tile/demo/tile_category.yml | 29 +++++++++++++++++ web_dashboard_tile/demo/tile_tile.yml | 3 ++ web_dashboard_tile/models/__init__.py | 2 +- web_dashboard_tile/models/tile_category.py | 17 ++++++++++ web_dashboard_tile/models/tile_tile.py | 1 + .../security/ir.model.access.csv | 1 + web_dashboard_tile/views/tile.xml | 32 +++++++++++++++++-- 8 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 web_dashboard_tile/demo/tile_category.yml create mode 100644 web_dashboard_tile/models/tile_category.py diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index dbda3d3b7..321d7491e 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -30,6 +30,7 @@ ], 'demo': [ 'demo/res_groups.yml', + 'demo/tile_category.yml', 'demo/tile_tile.yml', ], 'qweb': [ diff --git a/web_dashboard_tile/demo/tile_category.yml b/web_dashboard_tile/demo/tile_category.yml new file mode 100644 index 000000000..5fe1b632b --- /dev/null +++ b/web_dashboard_tile/demo/tile_category.yml @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2015-Today GRAP +# @author Sylvain LE GAL (https://twitter.com/legalsylvain) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +- !record {model: tile.category, id: modules}: + name: Modules + sequence: 0 + +- !record {model: tile.category, id: finance}: + name: Finance + sequence: 1 \ No newline at end of file diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml index dd9da0165..50cd7b69f 100644 --- a/web_dashboard_tile/demo/tile_tile.yml +++ b/web_dashboard_tile/demo/tile_tile.yml @@ -22,18 +22,21 @@ - !record {model: tile.tile, id: installed_modules}: name: Installed Modules + category_id: modules model_id: base.model_ir_module_module domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']]] action_id: base.open_module_tree - !record {model: tile.tile, id: installed_OCA_modules}: name: Installed OCA Modules + category_id: modules model_id: base.model_ir_module_module domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']], ['author', 'ilike', 'Odoo Community Association (OCA)']] action_id: base.open_module_tree - !record {model: tile.tile, id: all_currency_with_rate}: name: Currencies (Max Rate) + category_id: finance model_id: base.model_res_currency domain: [] secondary_function: max diff --git a/web_dashboard_tile/models/__init__.py b/web_dashboard_tile/models/__init__.py index 97fec216c..3a5158325 100644 --- a/web_dashboard_tile/models/__init__.py +++ b/web_dashboard_tile/models/__init__.py @@ -4,4 +4,4 @@ # © 2015-Today GRAP # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from . import tile_tile +from . import tile_tile, tile_category diff --git a/web_dashboard_tile/models/tile_category.py b/web_dashboard_tile/models/tile_category.py new file mode 100644 index 000000000..5e4d9b2cd --- /dev/null +++ b/web_dashboard_tile/models/tile_category.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# © 2018 Iván Todorovich +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import fields, models + + +class TileCategory(models.Model): + _name = 'tile.category' + _description = 'Dashboard Tile Category' + _order = 'sequence asc' + + name = fields.Char(required=True) + sequence = fields.Integer( + help="Used to order the tile categories", + default=0) + fold = fields.Boolean('Folded by default') diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 218cec406..e9e992808 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -77,6 +77,7 @@ class TileTile(models.Model): # Column Section name = fields.Char(required=True) sequence = fields.Integer(default=0, required=True) + category_id = fields.Many2one('tile.category', 'Category') user_id = fields.Many2one('res.users', 'User') background_color = fields.Char(default='#0E6C7E', oldname='color') font_color = fields.Char(default='#FFFFFF') diff --git a/web_dashboard_tile/security/ir.model.access.csv b/web_dashboard_tile/security/ir.model.access.csv index 3229b4ea2..06448cc99 100644 --- a/web_dashboard_tile/security/ir.model.access.csv +++ b/web_dashboard_tile/security/ir.model.access.csv @@ -1,2 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink tile_user,tile_user,model_tile_tile,base.group_user,1,1,1,1 +tile_user_category,tile_user,model_tile_category,base.group_user,1,1,1,1 diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 5221aa410..fa299d12c 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -27,11 +27,14 @@

+ + + + - @@ -85,12 +88,13 @@ - + tile.tile - + + @@ -142,6 +146,28 @@ + + tile.category + +
+ + + +
+
+
+ + + tile.category + + + + + + + + + Dashboard tile.tile From 414474783a1689ae08260471a977abddc8f7e5ec Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Wed, 31 Jan 2018 15:09:35 +0100 Subject: [PATCH 34/57] [IMP] web_dashboard_tile: reduce computation time --- web_dashboard_tile/models/tile_tile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index e9e992808..8c4d18c11 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -174,7 +174,10 @@ class TileTile(models.Model): elif self[f_function]: func = FIELD_FUNCTIONS[self[f_function]]['func'] if func and self[f_field_id] and count: - vals = [x[self[f_field_id].name] for x in records] + field_name = self[f_field_id].name + read_vals = records.search_read( + [('id', 'in', records.ids)], [field_name]) + vals = [x[field_name] for x in read_vals] value = func(vals) if self[f_function]: try: From d1a309df16804a00627862d7decb512af93d8d2d Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Fri, 9 Feb 2018 11:53:40 +0100 Subject: [PATCH 35/57] [IMP] make one search_read call instead of two calls --- web_dashboard_tile/models/tile_tile.py | 30 ++++++++++---------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 8c4d18c11..0f5450d9f 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -156,38 +156,30 @@ class TileTile(models.Model): self.primary_value = self.secondary_value = 'ERR!' self.error = str(e) return - if any([ - self.primary_function and - self.primary_function != 'count', - self.secondary_function and - self.secondary_function != 'count' - ]): - records = model.search(eval(domain, eval_context)) + fields = [f.name for f in [ + self.primary_field_id, self.secondary_field_id] if f] + read_vals = model.search_read(eval(domain, eval_context), fields) for f in ['primary_', 'secondary_']: f_function = f + 'function' f_field_id = f + 'field_id' f_format = f + 'format' f_value = f + 'value' value = 0 - if self[f_function] == 'count': - value = count - elif self[f_function]: - func = FIELD_FUNCTIONS[self[f_function]]['func'] - if func and self[f_field_id] and count: - field_name = self[f_field_id].name - read_vals = records.search_read( - [('id', 'in', records.ids)], [field_name]) - vals = [x[field_name] for x in read_vals] + if not self[f_function]: + self[f_value] = False + else: + if self[f_function] == 'count': + value = count + else: + func = FIELD_FUNCTIONS[self[f_function]]['func'] + vals = [x[self[f_field_id].name] for x in read_vals] value = func(vals) - if self[f_function]: try: self[f_value] = (self[f_format] or '{:,}').format(value) except ValueError as e: self[f_value] = 'F_ERR!' self.error = str(e) return - else: - self[f_value] = False @api.one @api.onchange('primary_function', 'primary_field_id', From 5d743ef8e5eba3d01677297e8ac5e3684398c285 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Thu, 15 Feb 2018 15:11:13 +0100 Subject: [PATCH 36/57] [IMP] do not call search_read if no fields are set --- web_dashboard_tile/models/tile_tile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 0f5450d9f..59936e7f1 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -158,7 +158,8 @@ class TileTile(models.Model): return fields = [f.name for f in [ self.primary_field_id, self.secondary_field_id] if f] - read_vals = model.search_read(eval(domain, eval_context), fields) + read_vals = fields and\ + model.search_read(eval(domain, eval_context), fields) or [] for f in ['primary_', 'secondary_']: f_function = f + 'function' f_field_id = f + 'field_id' From 8e79f3e8c6586b0107c3c45c06ca45984fd3422d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Thu, 15 Feb 2018 16:15:22 -0300 Subject: [PATCH 37/57] Added Known Issues --- web_dashboard_tile/README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 84b8015b0..c1c57fd40 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -31,6 +31,8 @@ Usage Known issues ============ +* Reordering the Kanban Tile will result in a rendering bug where the tile loses it's `style` attribute, where the `background-color` is set, rendering the tile background as white. Refreshing the view solves it. +* Tile sequence is not saved after reordering the tiles from the Kanban view. Sequence is only saved when reordering from the tree view. * Can not edit color from dashboard * Can not edit sequence from dashboard * Original context is ignored. From b0d4c1b61755248afa3328f928df3f82150854d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Thu, 15 Feb 2018 16:50:14 -0300 Subject: [PATCH 38/57] Fixed - sequence not being saved when reordering kanban --- web_dashboard_tile/README.rst | 1 - web_dashboard_tile/views/tile.xml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index c1c57fd40..edc9e0c39 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -32,7 +32,6 @@ Usage Known issues ============ * Reordering the Kanban Tile will result in a rendering bug where the tile loses it's `style` attribute, where the `background-color` is set, rendering the tile background as white. Refreshing the view solves it. -* Tile sequence is not saved after reordering the tiles from the Kanban view. Sequence is only saved when reordering from the tree view. * Can not edit color from dashboard * Can not edit sequence from dashboard * Original context is ignored. diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index fa299d12c..1cf50d5b1 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -94,6 +94,7 @@ + From f5976626a45ac60db8129609c28a36305dbb8a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Thu, 15 Feb 2018 20:02:16 -0300 Subject: [PATCH 39/57] Fix white background when reordering tile --- web_dashboard_tile/README.rst | 2 -- web_dashboard_tile/demo/tile_category.yml | 2 +- web_dashboard_tile/static/src/css/tile.css | 16 +++++++--------- web_dashboard_tile/views/tile.xml | 4 +++- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index edc9e0c39..22bef2394 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -31,9 +31,7 @@ Usage Known issues ============ -* Reordering the Kanban Tile will result in a rendering bug where the tile loses it's `style` attribute, where the `background-color` is set, rendering the tile background as white. Refreshing the view solves it. * Can not edit color from dashboard -* Can not edit sequence from dashboard * Original context is ignored. * Original domain and filter are not restored. * To preserve a relative date domain, you have to manually edit the tile's domain from `Configuration > User Interface > Dashboard Tile`. You can use the same variables available in filters (`uid`, `context_today()`, `current_date`, `time`, `datetime`, `relativedelta`). diff --git a/web_dashboard_tile/demo/tile_category.yml b/web_dashboard_tile/demo/tile_category.yml index 5fe1b632b..01bf0aeab 100644 --- a/web_dashboard_tile/demo/tile_category.yml +++ b/web_dashboard_tile/demo/tile_category.yml @@ -26,4 +26,4 @@ - !record {model: tile.category, id: finance}: name: Finance - sequence: 1 \ No newline at end of file + sequence: 1 diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/tile.css index 723cb51f9..9fe5aec72 100644 --- a/web_dashboard_tile/static/src/css/tile.css +++ b/web_dashboard_tile/static/src/css/tile.css @@ -1,17 +1,15 @@ /* custom kanban style */ .o_kanban_view .oe_dashboard_tile { - width: 150px; height: 150px; } -.o_kanban_view.o_kanban_ungrouped .o_kanban_record.oe_dashboard_tile { - /* override max-width rules */ - margin: 4px !important; - /* flex width */ - -ms-flex: 1 1 150px; - -moz-flex: 1 1 150px; - -webkit-flex: 1 1 150px; - flex: 1 1 150px; +/* Fix bug where draggin a tile results in the element losing its style */ +.o_kanban_view .oe_dashboard_tile { + padding: 0px !important; +} +.o_kanban_view .oe_dashboard_tile .tile_background { + padding: 8px; + height: 100%; } .o_kanban_view .oe_dashboard_tile .tile_label, diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 1cf50d5b1..24e5b6a04 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -108,7 +108,8 @@ -
+ From 49d7c7e026491c43bdbe592aed7f63f72d716155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Fri, 16 Feb 2018 12:18:10 -0300 Subject: [PATCH 40/57] Improved tile.category form view --- web_dashboard_tile/views/tile.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml index 24e5b6a04..4a629eb17 100644 --- a/web_dashboard_tile/views/tile.xml +++ b/web_dashboard_tile/views/tile.xml @@ -152,11 +152,15 @@ tile.category -
- + + + + + +
From 5c781dbb585fd3c695c93015897d62f89a227859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Fri, 16 Feb 2018 18:39:22 -0300 Subject: [PATCH 41/57] [9.0][web_dashboard_tile] Update version number --- web_dashboard_tile/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index 321d7491e..53e32271d 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -5,7 +5,7 @@ { "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", - "version": "9.0.1.0.0", + "version": "9.0.1.1.0", "depends": [ 'web', 'board', From 9e6ec079067b5ce86017c32fd5d1376a47109dc3 Mon Sep 17 00:00:00 2001 From: Katherine Zaoral Date: Mon, 26 Mar 2018 09:19:10 -0300 Subject: [PATCH 42/57] [FIX] web_dashboard_tile clean group_by from tile view Be able to open a title without getting context group_by garbage from the title view. --- web_dashboard_tile/models/tile_tile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 59936e7f1..7a0c36954 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -259,7 +259,7 @@ class TileTile(models.Model): 'view_id': [False], 'res_model': self.model_id.model, 'type': 'ir.actions.act_window', - 'context': self.env.context, + 'context': dict(self.env.context, group_by=False), 'nodestroy': True, 'target': 'current', 'domain': self.domain, From 3960f5149909531e1630fc4a0f2eda474098d64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul=20=28ACSONE=29?= Date: Fri, 15 Jun 2018 23:52:40 +0200 Subject: [PATCH 43/57] remove obsolete .pot files [ci skip] --- .../i18n/web_dashboard_tile.pot | 232 ------------------ 1 file changed, 232 deletions(-) delete mode 100644 web_dashboard_tile/i18n/web_dashboard_tile.pot diff --git a/web_dashboard_tile/i18n/web_dashboard_tile.pot b/web_dashboard_tile/i18n/web_dashboard_tile.pot deleted file mode 100644 index 0e89f8cae..000000000 --- a/web_dashboard_tile/i18n/web_dashboard_tile.pot +++ /dev/null @@ -1,232 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 7.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-10 01:03+0000\n" -"PO-Revision-Date: 2015-04-10 01:03+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: web_dashboard_tile -#: field:tile.tile,action_id:0 -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,active:0 -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:82 -#, python-format -msgid "Average value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,color:0 -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,computed_value:0 -msgid "Computed Value" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,count:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Delete" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,domain:0 -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "Edit..." -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: constraint:tile.tile:0 -msgid "Error ! Please select a field of the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: constraint:tile.tile:0 -msgid "Error ! Please set both fields: 'Field' and 'Function'." -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,field_id:0 -msgid "Field" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:61 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,font_color:0 -msgid "Font Color" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,field_function:0 -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,helper:0 -msgid "Helper Text" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:76 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:85 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:73 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,model_id:0 -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,sequence:0 -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,field_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,name:0 -msgid "Tile Name" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:100 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/tile.py:79 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: field:tile.tile,user_id:0 -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: code:_description:0 -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#, python-format -msgid "tile.tile" -msgstr "" - -#. module: web_dashboard_tile -#: view:tile.tile:0 -msgid "í" -msgstr "" From b63327ef4b0b9dd2d49c46415fc6f2e4b22b0450 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 4 Nov 2019 17:52:42 +0100 Subject: [PATCH 44/57] [REF] web_dashboard_tile: Black python code --- web_dashboard_tile/__openerp__.py | 45 +-- .../migrations/8.0.4.0/post-migration.py | 13 +- web_dashboard_tile/models/tile_category.py | 12 +- web_dashboard_tile/models/tile_tile.py | 329 ++++++++++-------- web_dashboard_tile/tests/test_tile.py | 82 +++-- 5 files changed, 265 insertions(+), 216 deletions(-) diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__openerp__.py index 53e32271d..7d78e47ea 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__openerp__.py @@ -6,34 +6,27 @@ "name": "Dashboard Tile", "summary": "Add Tiles to Dashboard", "version": "9.0.1.1.0", - "depends": [ - 'web', - 'board', - 'mail', - 'web_widget_color', - ], - 'author': 'initOS GmbH & Co. KG, ' - 'GRAP, ' - 'Odoo Community Association (OCA)', + "depends": ["web", "board", "mail", "web_widget_color"], + "author": "initOS GmbH & Co. KG, " + "GRAP, " + "Odoo Community Association (OCA)", "category": "web", - 'license': 'AGPL-3', - 'contributors': [ - 'initOS GmbH & Co. KG', - 'GRAP', - 'Iván Todorovich ' + "license": "AGPL-3", + "contributors": [ + "initOS GmbH & Co. KG", + "GRAP", + "Iván Todorovich ", ], - 'data': [ - 'views/tile.xml', - 'views/templates.xml', - 'security/ir.model.access.csv', - 'security/rules.xml', + "data": [ + "views/tile.xml", + "views/templates.xml", + "security/ir.model.access.csv", + "security/rules.xml", ], - 'demo': [ - 'demo/res_groups.yml', - 'demo/tile_category.yml', - 'demo/tile_tile.yml', - ], - 'qweb': [ - 'static/src/xml/custom_xml.xml', + "demo": [ + "demo/res_groups.yml", + "demo/tile_category.yml", + "demo/tile_tile.yml", ], + "qweb": ["static/src/xml/custom_xml.xml"], } diff --git a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py index fd7ddd773..674121edc 100644 --- a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py +++ b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py @@ -8,10 +8,12 @@ def migrate(cr, version): return # Update ir.rule - cr.execute(""" + cr.execute( + """ SELECT res_id FROM ir_model_data WHERE name = 'model_tile_rule' - AND module = 'web_dashboard_tile'""") + AND module = 'web_dashboard_tile'""" + ) rule_id = cr.fetchone()[0] new_domain = """[ "|", @@ -21,6 +23,9 @@ def migrate(cr, version): ("group_ids","=",False), ("group_ids","in",[g.id for g in user.groups_id]), ]""" - cr.execute(""" + cr.execute( + """ UPDATE ir_rule SET domain_force = '%(domain)s' - WHERE id = '%(id)s' """ % {'domain': new_domain, 'id': rule_id}) + WHERE id = '%(id)s' """ + % {"domain": new_domain, "id": rule_id} + ) diff --git a/web_dashboard_tile/models/tile_category.py b/web_dashboard_tile/models/tile_category.py index 5e4d9b2cd..e7b8d843c 100644 --- a/web_dashboard_tile/models/tile_category.py +++ b/web_dashboard_tile/models/tile_category.py @@ -6,12 +6,12 @@ from openerp import fields, models class TileCategory(models.Model): - _name = 'tile.category' - _description = 'Dashboard Tile Category' - _order = 'sequence asc' + _name = "tile.category" + _description = "Dashboard Tile Category" + _order = "sequence asc" name = fields.Char(required=True) sequence = fields.Integer( - help="Used to order the tile categories", - default=0) - fold = fields.Boolean('Folded by default') + help="Used to order the tile categories", default=0 + ) + fold = fields.Boolean("Folded by default") diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 7a0c36954..eeacb9bc6 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -21,127 +21,150 @@ def median(vals): # in Python 3.4 even = (0 if len(vals) % 2 else 1) + 1 half = (len(vals) - 1) / 2 - return sum(sorted(vals)[half:half + even]) / float(even) + return sum(sorted(vals)[half : half + even]) / float(even) -FIELD_FUNCTIONS = OrderedDict([ - ('count', { - 'name': 'Count', - 'func': False, # its hardcoded in _compute_data - 'help': _('Number of records')}), - ('min', { - 'name': 'Minimum', - 'func': min, - 'help': _("Minimum value of '%s'")}), - ('max', { - 'name': 'Maximum', - 'func': max, - 'help': _("Maximum value of '%s'")}), - ('sum', { - 'name': 'Sum', - 'func': sum, - 'help': _("Total value of '%s'")}), - ('avg', { - 'name': 'Average', - 'func': lambda vals: sum(vals) / len(vals), - 'help': _("Minimum value of '%s'")}), - ('median', { - 'name': 'Median', - 'func': median, - 'help': _("Median value of '%s'")}), -]) +FIELD_FUNCTIONS = OrderedDict( + [ + ( + "count", + { + "name": "Count", + "func": False, # its hardcoded in _compute_data + "help": _("Number of records"), + }, + ), + ( + "min", + { + "name": "Minimum", + "func": min, + "help": _("Minimum value of '%s'"), + }, + ), + ( + "max", + { + "name": "Maximum", + "func": max, + "help": _("Maximum value of '%s'"), + }, + ), + ( + "sum", + {"name": "Sum", "func": sum, "help": _("Total value of '%s'")}, + ), + ( + "avg", + { + "name": "Average", + "func": lambda vals: sum(vals) / len(vals), + "help": _("Minimum value of '%s'"), + }, + ), + ( + "median", + { + "name": "Median", + "func": median, + "help": _("Median value of '%s'"), + }, + ), + ] +) FIELD_FUNCTION_SELECTION = [ - (k, FIELD_FUNCTIONS[k].get('name')) for k in FIELD_FUNCTIONS] + (k, FIELD_FUNCTIONS[k].get("name")) for k in FIELD_FUNCTIONS +] class TileTile(models.Model): - _name = 'tile.tile' - _description = 'Dashboard Tile' - _order = 'sequence, name' + _name = "tile.tile" + _description = "Dashboard Tile" + _order = "sequence, name" def _get_eval_context(self): def _context_today(): return fields.Date.from_string(fields.Date.context_today(self)) + context = self.env.context.copy() - context.update({ - 'time': time, - 'datetime': datetime, - 'relativedelta': relativedelta, - 'context_today': _context_today, - 'current_date': fields.Date.today(), - }) + context.update( + { + "time": time, + "datetime": datetime, + "relativedelta": relativedelta, + "context_today": _context_today, + "current_date": fields.Date.today(), + } + ) return context # Column Section name = fields.Char(required=True) sequence = fields.Integer(default=0, required=True) - category_id = fields.Many2one('tile.category', 'Category') - user_id = fields.Many2one('res.users', 'User') - background_color = fields.Char(default='#0E6C7E', oldname='color') - font_color = fields.Char(default='#FFFFFF') + category_id = fields.Many2one("tile.category", "Category") + user_id = fields.Many2one("res.users", "User") + background_color = fields.Char(default="#0E6C7E", oldname="color") + font_color = fields.Char(default="#FFFFFF") group_ids = fields.Many2many( - 'res.groups', - string='Groups', - help='If this field is set, only users of this group can view this ' - 'tile. Please note that it will only work for global tiles ' - '(that is, when User field is left empty)') + "res.groups", + string="Groups", + help="If this field is set, only users of this group can view this " + "tile. Please note that it will only work for global tiles " + "(that is, when User field is left empty)", + ) - model_id = fields.Many2one('ir.model', 'Model', required=True) - domain = fields.Text(default='[]') - action_id = fields.Many2one('ir.actions.act_window', 'Action') + model_id = fields.Many2one("ir.model", "Model", required=True) + domain = fields.Text(default="[]") + action_id = fields.Many2one("ir.actions.act_window", "Action") active = fields.Boolean( - compute='_compute_active', - search='_search_active', - readonly=True) + compute="_compute_active", search="_search_active", readonly=True + ) # Primary Value primary_function = fields.Selection( - FIELD_FUNCTION_SELECTION, - string='Function', - default='count') + FIELD_FUNCTION_SELECTION, string="Function", default="count" + ) primary_field_id = fields.Many2one( - 'ir.model.fields', - string='Field', + "ir.model.fields", + string="Field", domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'integer', 'monetary'])]") + " ('ttype', 'in', ['float', 'integer', 'monetary'])]", + ) primary_format = fields.Char( - string='Format', - help='Python Format String valid with str.format()\n' - 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') - primary_value = fields.Char( - string='Value', - compute='_compute_data') - primary_helper = fields.Char( - string='Helper', - compute='_compute_helper') + string="Format", + help="Python Format String valid with str.format()\n" + "ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000.", + ) + primary_value = fields.Char(string="Value", compute="_compute_data") + primary_helper = fields.Char(string="Helper", compute="_compute_helper") # Secondary Value secondary_function = fields.Selection( - FIELD_FUNCTION_SELECTION, - string='Secondary Function') + FIELD_FUNCTION_SELECTION, string="Secondary Function" + ) secondary_field_id = fields.Many2one( - 'ir.model.fields', - string='Secondary Field', + "ir.model.fields", + string="Secondary Field", domain="[('model_id', '=', model_id)," - " ('ttype', 'in', ['float', 'integer', 'monetary'])]") + " ('ttype', 'in', ['float', 'integer', 'monetary'])]", + ) secondary_format = fields.Char( - string='Secondary Format', - help='Python Format String valid with str.format()\n' - 'ie: \'{:,} Kgs\' will output \'1,000 Kgs\' if value is 1000.') + string="Secondary Format", + help="Python Format String valid with str.format()\n" + "ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000.", + ) secondary_value = fields.Char( - string='Secondary Value', - compute='_compute_data') + string="Secondary Value", compute="_compute_data" + ) secondary_helper = fields.Char( - string='Secondary Helper', - compute='_compute_helper') + string="Secondary Helper", compute="_compute_helper" + ) - error = fields.Char( - string='Error Details', - compute='_compute_data') + error = fields.Char(string="Error Details", compute="_compute_data") @api.one def _compute_data(self): @@ -149,52 +172,62 @@ class TileTile(models.Model): return model = self.env[self.model_id.model] eval_context = self._get_eval_context() - domain = self.domain or '[]' + domain = self.domain or "[]" try: count = model.search_count(eval(domain, eval_context)) except Exception as e: - self.primary_value = self.secondary_value = 'ERR!' + self.primary_value = self.secondary_value = "ERR!" self.error = str(e) return - fields = [f.name for f in [ - self.primary_field_id, self.secondary_field_id] if f] - read_vals = fields and\ - model.search_read(eval(domain, eval_context), fields) or [] - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_format = f + 'format' - f_value = f + 'value' + fields = [ + f.name + for f in [self.primary_field_id, self.secondary_field_id] + if f + ] + read_vals = ( + fields + and model.search_read(eval(domain, eval_context), fields) + or [] + ) + for f in ["primary_", "secondary_"]: + f_function = f + "function" + f_field_id = f + "field_id" + f_format = f + "format" + f_value = f + "value" value = 0 if not self[f_function]: self[f_value] = False else: - if self[f_function] == 'count': + if self[f_function] == "count": value = count else: - func = FIELD_FUNCTIONS[self[f_function]]['func'] + func = FIELD_FUNCTIONS[self[f_function]]["func"] vals = [x[self[f_field_id].name] for x in read_vals] value = func(vals) try: - self[f_value] = (self[f_format] or '{:,}').format(value) + self[f_value] = (self[f_format] or "{:,}").format(value) except ValueError as e: - self[f_value] = 'F_ERR!' + self[f_value] = "F_ERR!" self.error = str(e) return @api.one - @api.onchange('primary_function', 'primary_field_id', - 'secondary_function', 'secondary_field_id') + @api.onchange( + "primary_function", + "primary_field_id", + "secondary_function", + "secondary_field_id", + ) def _compute_helper(self): - for f in ['primary_', 'secondary_']: - f_function = f + 'function' - f_field_id = f + 'field_id' - f_helper = f + 'helper' - self[f_helper] = '' + for f in ["primary_", "secondary_"]: + f_function = f + "function" + f_field_id = f + "field_id" + f_helper = f + "helper" + self[f_helper] = "" field_func = FIELD_FUNCTIONS.get(self[f_function], {}) - help = field_func.get('help', False) + help = field_func.get("help", False) if help: - if self[f_function] != 'count' and self[f_field_id]: + if self[f_function] != "count" and self[f_field_id]: desc = self[f_field_id].field_description self[f_helper] = help % desc else: @@ -202,77 +235,87 @@ class TileTile(models.Model): @api.one def _compute_active(self): - ima = self.env['ir.model.access'] + ima = self.env["ir.model.access"] for rec in self: - rec.active = ima.check(rec.model_id.model, 'read', False) + rec.active = ima.check(rec.model_id.model, "read", False) def _search_active(self, operator, value): cr = self.env.cr - if operator != '=': + if operator != "=": raise except_orm( - _('Unimplemented Feature. Search on Active field disabled.')) - ima = self.env['ir.model.access'] + _("Unimplemented Feature. Search on Active field disabled.") + ) + ima = self.env["ir.model.access"] ids = [] - cr.execute(""" + cr.execute( + """ SELECT tt.id, im.model FROM tile_tile tt INNER JOIN ir_model im - ON tt.model_id = im.id""") + ON tt.model_id = im.id""" + ) for result in cr.fetchall(): - if (ima.check(result[1], 'read', False) == value): + if ima.check(result[1], "read", False) == value: ids.append(result[0]) - return [('id', 'in', ids)] + return [("id", "in", ids)] # Constraints and onchanges @api.multi - @api.constrains('model_id', 'primary_field_id', 'secondary_field_id') + @api.constrains("model_id", "primary_field_id", "secondary_field_id") def _check_model_id_field_id(self): for rec in self: - if any([ - rec.primary_field_id and - rec.primary_field_id.model_id.id != rec.model_id.id, - rec.secondary_field_id and - rec.secondary_field_id.model_id.id != rec.model_id.id - ]): + if any( + [ + rec.primary_field_id + and rec.primary_field_id.model_id.id != rec.model_id.id, + rec.secondary_field_id + and rec.secondary_field_id.model_id.id != rec.model_id.id, + ] + ): raise ValidationError( - _("Please select a field from the selected model.")) + _("Please select a field from the selected model.") + ) - @api.onchange('model_id') + @api.onchange("model_id") def _onchange_model_id(self): self.primary_field_id = False self.secondary_field_id = False - @api.onchange('primary_function', 'secondary_function') + @api.onchange("primary_function", "secondary_function") def _onchange_function(self): - if self.primary_function in [False, 'count']: + if self.primary_function in [False, "count"]: self.primary_field_id = False - if self.secondary_function in [False, 'count']: + if self.secondary_function in [False, "count"]: self.secondary_field_id = False # Action methods @api.multi def open_link(self): res = { - 'name': self.name, - 'view_type': 'form', - 'view_mode': 'tree', - 'view_id': [False], - 'res_model': self.model_id.model, - 'type': 'ir.actions.act_window', - 'context': dict(self.env.context, group_by=False), - 'nodestroy': True, - 'target': 'current', - 'domain': self.domain, + "name": self.name, + "view_type": "form", + "view_mode": "tree", + "view_id": [False], + "res_model": self.model_id.model, + "type": "ir.actions.act_window", + "context": dict(self.env.context, group_by=False), + "nodestroy": True, + "target": "current", + "domain": self.domain, } if self.action_id: - res.update(self.action_id.read( - ['view_type', 'view_mode', 'type'])[0]) + res.update( + self.action_id.read(["view_type", "view_mode", "type"])[0] + ) return res @api.model def add(self, vals): - if 'model_id' in vals and not vals['model_id'].isdigit(): + if "model_id" in vals and not vals["model_id"].isdigit(): # need to replace model_name with its id - vals['model_id'] = self.env['ir.model'].search( - [('model', '=', vals['model_id'])]).id + vals["model_id"] = ( + self.env["ir.model"] + .search([("model", "=", vals["model_id"])]) + .id + ) self.create(vals) diff --git a/web_dashboard_tile/tests/test_tile.py b/web_dashboard_tile/tests/test_tile.py index 90604ab9a..ec6b309b1 100644 --- a/web_dashboard_tile/tests/test_tile.py +++ b/web_dashboard_tile/tests/test_tile.py @@ -7,46 +7,54 @@ from openerp.tests.common import TransactionCase class TestTile(TransactionCase): def test_tile(self): - tile_obj = self.env['tile.tile'] - model_id = self.env['ir.model'].search([ - ('model', '=', 'tile.tile')]) - field_id = self.env['ir.model.fields'].search([ - ('model_id', '=', model_id.id), - ('name', '=', 'sequence')]) - self.tile1 = tile_obj.create({ - 'name': 'Count / Sum', - 'sequence': 1, - 'model_id': model_id.id, - 'domain': "[('model_id', '=', %d)]" % model_id.id, - 'secondary_function': 'sum', - 'secondary_field_id': field_id.id}) - self.tile2 = tile_obj.create({ - 'name': 'Min / Max', - 'sequence': 2, - 'model_id': model_id.id, - 'domain': "[('model_id', '=', %d)]" % model_id.id, - 'primary_function': 'min', - 'primary_field_id': field_id.id, - 'secondary_function': 'max', - 'secondary_field_id': field_id.id}) - self.tile3 = tile_obj.create({ - 'name': 'Avg / Median', - 'sequence': 3, - 'model_id': model_id.id, - 'domain': "[('model_id', '=', %d)]" % model_id.id, - 'primary_function': 'avg', - 'primary_field_id': field_id.id, - 'secondary_function': 'median', - 'secondary_field_id': field_id.id}) + tile_obj = self.env["tile.tile"] + model_id = self.env["ir.model"].search([("model", "=", "tile.tile")]) + field_id = self.env["ir.model.fields"].search( + [("model_id", "=", model_id.id), ("name", "=", "sequence")] + ) + self.tile1 = tile_obj.create( + { + "name": "Count / Sum", + "sequence": 1, + "model_id": model_id.id, + "domain": "[('model_id', '=', %d)]" % model_id.id, + "secondary_function": "sum", + "secondary_field_id": field_id.id, + } + ) + self.tile2 = tile_obj.create( + { + "name": "Min / Max", + "sequence": 2, + "model_id": model_id.id, + "domain": "[('model_id', '=', %d)]" % model_id.id, + "primary_function": "min", + "primary_field_id": field_id.id, + "secondary_function": "max", + "secondary_field_id": field_id.id, + } + ) + self.tile3 = tile_obj.create( + { + "name": "Avg / Median", + "sequence": 3, + "model_id": model_id.id, + "domain": "[('model_id', '=', %d)]" % model_id.id, + "primary_function": "avg", + "primary_field_id": field_id.id, + "secondary_function": "median", + "secondary_field_id": field_id.id, + } + ) # count - self.assertEqual(self.tile1.primary_value, '3') + self.assertEqual(self.tile1.primary_value, "3") # sum - self.assertEqual(self.tile1.secondary_value, '6') + self.assertEqual(self.tile1.secondary_value, "6") # min - self.assertEqual(self.tile2.primary_value, '1') + self.assertEqual(self.tile2.primary_value, "1") # max - self.assertEqual(self.tile2.secondary_value, '3') + self.assertEqual(self.tile2.secondary_value, "3") # average - self.assertEqual(self.tile3.primary_value, '2') + self.assertEqual(self.tile3.primary_value, "2") # median - self.assertEqual(self.tile3.secondary_value, '2.0') + self.assertEqual(self.tile3.secondary_value, "2.0") From 8128f242dbeff8b3e186689b8e9ae09a1ebf739f Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Wed, 6 Nov 2019 10:39:54 +0100 Subject: [PATCH 45/57] [MIG][12.0] web_dashboard_tile - refactor tile category - improve description - add legalsylvain as maintainer - update code and translation --- web_dashboard_tile/README.rst | 132 ++++- web_dashboard_tile/__init__.py | 7 +- .../{__openerp__.py => __manifest__.py} | 23 +- web_dashboard_tile/controllers/__init__.py | 1 + web_dashboard_tile/controllers/main.py | 15 + web_dashboard_tile/demo/res_groups.yml | 25 - web_dashboard_tile/demo/tile_category.xml | 16 + web_dashboard_tile/demo/tile_category.yml | 29 - web_dashboard_tile/demo/tile_tile.xml | 29 + web_dashboard_tile/demo/tile_tile.yml | 43 -- web_dashboard_tile/i18n/ar.po | 332 ------------ web_dashboard_tile/i18n/ca.po | 332 ------------ web_dashboard_tile/i18n/de.po | 333 ------------ web_dashboard_tile/i18n/es.po | 333 ------------ web_dashboard_tile/i18n/fi.po | 332 ------------ web_dashboard_tile/i18n/fr.po | 396 ++++++++------ web_dashboard_tile/i18n/it.po | 332 ------------ web_dashboard_tile/i18n/nl.po | 332 ------------ web_dashboard_tile/i18n/pt_BR.po | 333 ------------ web_dashboard_tile/i18n/sl.po | 332 ------------ web_dashboard_tile/i18n/tr.po | 332 ------------ .../migrations/12.0.1.0.0/post-migration.py | 29 + .../migrations/8.0.3.0/post-migration.py | 13 - .../migrations/8.0.4.0/post-migration.py | 31 -- web_dashboard_tile/models/__init__.py | 9 +- web_dashboard_tile/models/tile_category.py | 98 +++- web_dashboard_tile/models/tile_tile.py | 280 ++++++---- web_dashboard_tile/readme/CONFIGURE.rst | 33 ++ web_dashboard_tile/readme/CONTRIBUTORS.rst | 3 + web_dashboard_tile/readme/DESCRIPTION.rst | 16 + web_dashboard_tile/readme/ROADMAP.rst | 15 + web_dashboard_tile/readme/USAGE.rst | 17 + .../security/{rules.xml => ir_rule.xml} | 6 +- .../description/favorite_menu_create_tile.png | Bin 0 -> 50632 bytes .../favorite_menu_create_tile_result.png | Bin 0 -> 20434 bytes .../static/description/index.html | 495 ++++++++++++++++++ .../static/description/tile_category_form.png | Bin 0 -> 15542 bytes .../description/tile_tile_2_tree_view.png | Bin 0 -> 135180 bytes .../static/description/tile_tile_form.png | Bin 0 -> 50516 bytes .../tile_tile_form_secondary_value.png | Bin 0 -> 29548 bytes .../static/description/tile_tile_kanban.png | Bin 0 -> 8243 bytes .../css/{tile.css => web_dashboard_tile.css} | 0 web_dashboard_tile/static/src/img/avg.png | Bin 340 -> 0 bytes web_dashboard_tile/static/src/img/max.png | Bin 264 -> 0 bytes web_dashboard_tile/static/src/img/median.png | Bin 287 -> 0 bytes web_dashboard_tile/static/src/img/min.png | Bin 283 -> 0 bytes .../src/img/screenshot_action_click.png | Bin 24751 -> 0 bytes .../static/src/img/screenshot_dashboard.png | Bin 20441 -> 0 bytes web_dashboard_tile/static/src/img/sum.png | Bin 305 -> 0 bytes web_dashboard_tile/static/src/js/custom_js.js | 141 ----- .../static/src/js/web_dashboard_tile.js | 112 ++++ .../static/src/xml/custom_xml.xml | 13 - .../static/src/xml/web_dashboard_tile.xml | 19 + web_dashboard_tile/tests/__init__.py | 5 - web_dashboard_tile/tests/test_tile.py | 27 +- web_dashboard_tile/views/menu.xml | 14 + web_dashboard_tile/views/templates.xml | 39 +- web_dashboard_tile/views/tile.xml | 207 -------- web_dashboard_tile/views/tile_category.xml | 63 +++ web_dashboard_tile/views/tile_tile.xml | 158 ++++++ 60 files changed, 1698 insertions(+), 4184 deletions(-) rename web_dashboard_tile/{__openerp__.py => __manifest__.py} (60%) create mode 100644 web_dashboard_tile/controllers/__init__.py create mode 100644 web_dashboard_tile/controllers/main.py delete mode 100644 web_dashboard_tile/demo/res_groups.yml create mode 100644 web_dashboard_tile/demo/tile_category.xml delete mode 100644 web_dashboard_tile/demo/tile_category.yml create mode 100644 web_dashboard_tile/demo/tile_tile.xml delete mode 100644 web_dashboard_tile/demo/tile_tile.yml delete mode 100644 web_dashboard_tile/i18n/ar.po delete mode 100644 web_dashboard_tile/i18n/ca.po delete mode 100644 web_dashboard_tile/i18n/de.po delete mode 100644 web_dashboard_tile/i18n/es.po delete mode 100644 web_dashboard_tile/i18n/fi.po delete mode 100644 web_dashboard_tile/i18n/it.po delete mode 100644 web_dashboard_tile/i18n/nl.po delete mode 100644 web_dashboard_tile/i18n/pt_BR.po delete mode 100644 web_dashboard_tile/i18n/sl.po delete mode 100644 web_dashboard_tile/i18n/tr.po create mode 100644 web_dashboard_tile/migrations/12.0.1.0.0/post-migration.py delete mode 100644 web_dashboard_tile/migrations/8.0.3.0/post-migration.py delete mode 100644 web_dashboard_tile/migrations/8.0.4.0/post-migration.py create mode 100644 web_dashboard_tile/readme/CONFIGURE.rst create mode 100644 web_dashboard_tile/readme/CONTRIBUTORS.rst create mode 100644 web_dashboard_tile/readme/DESCRIPTION.rst create mode 100644 web_dashboard_tile/readme/ROADMAP.rst create mode 100644 web_dashboard_tile/readme/USAGE.rst rename web_dashboard_tile/security/{rules.xml => ir_rule.xml} (91%) create mode 100644 web_dashboard_tile/static/description/favorite_menu_create_tile.png create mode 100644 web_dashboard_tile/static/description/favorite_menu_create_tile_result.png create mode 100644 web_dashboard_tile/static/description/index.html create mode 100644 web_dashboard_tile/static/description/tile_category_form.png create mode 100644 web_dashboard_tile/static/description/tile_tile_2_tree_view.png create mode 100644 web_dashboard_tile/static/description/tile_tile_form.png create mode 100644 web_dashboard_tile/static/description/tile_tile_form_secondary_value.png create mode 100644 web_dashboard_tile/static/description/tile_tile_kanban.png rename web_dashboard_tile/static/src/css/{tile.css => web_dashboard_tile.css} (100%) delete mode 100644 web_dashboard_tile/static/src/img/avg.png delete mode 100644 web_dashboard_tile/static/src/img/max.png delete mode 100644 web_dashboard_tile/static/src/img/median.png delete mode 100644 web_dashboard_tile/static/src/img/min.png delete mode 100644 web_dashboard_tile/static/src/img/screenshot_action_click.png delete mode 100644 web_dashboard_tile/static/src/img/screenshot_dashboard.png delete mode 100644 web_dashboard_tile/static/src/img/sum.png delete mode 100644 web_dashboard_tile/static/src/js/custom_js.js create mode 100644 web_dashboard_tile/static/src/js/web_dashboard_tile.js delete mode 100644 web_dashboard_tile/static/src/xml/custom_xml.xml create mode 100644 web_dashboard_tile/static/src/xml/web_dashboard_tile.xml create mode 100644 web_dashboard_tile/views/menu.xml delete mode 100644 web_dashboard_tile/views/tile.xml create mode 100644 web_dashboard_tile/views/tile_category.xml create mode 100644 web_dashboard_tile/views/tile_tile.xml diff --git a/web_dashboard_tile/README.rst b/web_dashboard_tile/README.rst index 22bef2394..c0262f641 100644 --- a/web_dashboard_tile/README.rst +++ b/web_dashboard_tile/README.rst @@ -1,5 +1,23 @@ -Dashboard Tiles -=============== +========================== +Overview Dashboard (Tiles) +========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-legalsylvain%2Fweb-lightgray.png?logo=github + :target: https://github.com/legalsylvain/web/tree/12.0-mig-web_dashboard_tile/web_dashboard_tile + :alt: legalsylvain/web + +|badge1| |badge2| |badge3| Adds a dashboard where you can configure tiles from any view and add them as short cut. @@ -7,7 +25,7 @@ By default, the tile displays items count of a given model restricted to a given Optionally, the tile can display the result of a function on a field. -- Function is one of `sum`, `avg`, `min`, `max` or `median`. +- Function is one of ``sum``, ``avg``, ``min``, ``max`` or ``median``. - Field must be integer or float. Tile can be: @@ -18,60 +36,126 @@ Tile can be: *Note: The tile will be hidden if the current user doesn't have access to the given model.* +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +First, you have to create tile categories. + +* Go to "Dashboards > Settings > Dashboard Categories" + +* Click on Create + +* Set a name, and save. + +Odoo menu and action are automatically created. +You should refresh your browser to see new menu items. + +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_category_form.png + +Then you can create tiles. + +* go to "Dashboards > Settings > Dashboard Tiles" + +* create a new tile, set a name, a category and a model. + +* You can optionally define colors, domain a specific action to use. + +* Setting a user, or a group in "Security" tab will restrict the display of the tile. + +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_form.png + +You can optionanaly define a secondary value, for that purpose : + +* Select a field, a function to apply. + +* You can define a specific format. (``.format()`` python syntax) + +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_form_secondary_value.png + + Usage ===== -* Dashboad sample, displaying Sale Orders to invoice: +* Go to "Dashboard > Overview" and select a category -.. image:: ./static/src/img/screenshot_dashboard.png +* The tile configured is displayed with the up to date count and average values of the selected domain. -* Tree view displayed when user click on the tile: +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_kanban.png -.. image:: ./static/src/img/screenshot_action_click.png +* By clicking on the item, you'll navigate to the tree view of the according model. + +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_2_tree_view.png + +**Note** + +When you are in a tree view, with a domain, you can save it in the favorite menu, but the configuration is limited. + +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/favorite_menu_create_tile.png + + +.. image:: https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/favorite_menu_create_tile_result.png + +Known issues / Roadmap +====================== + +**Known issues** -Known issues -============ * Can not edit color from dashboard * Original context is ignored. * Original domain and filter are not restored. -* To preserve a relative date domain, you have to manually edit the tile's domain from `Configuration > User Interface > Dashboard Tile`. You can use the same variables available in filters (`uid`, `context_today()`, `current_date`, `time`, `datetime`, `relativedelta`). +* To preserve a relative date domain, you have to manually edit the tile's domain from "Configuration > User Interface > Dashboard Tile". You can use the same variables available in filters (``uid``, ``context_today()``, ``current_date``, ``time``, ``datetime``, `relativedelta`). + +**Roadmap** -Roadmap -======= * Add icons. * Support client side action (like inbox). * Restore original Domain + Filter when an action is set. * Posibility to hide the tile based on a field expression. * Posibility to set the background color based on a field expression. + Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +Bugs are tracked on `GitHub 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 -`here `_. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* initOS GmbH & Co. KG +* GRAP + Contributors ------------- +~~~~~~~~~~~~ * Markus Schneider * Sylvain Le Gal (https://twitter.com/legalsylvain) * Iván Todorovich -Maintainer ----------- +Maintainers +~~~~~~~~~~~ -.. image:: http://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: http://odoo-community.org +.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px + :target: https://github.com/legalsylvain + :alt: legalsylvain -This module is maintained by the OCA. +Current maintainer: -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-legalsylvain| -To contribute to this module, please visit http://odoo-community.org. +This module is part of the `legalsylvain/web `_ project on GitHub. + +You are welcome to contribute. diff --git a/web_dashboard_tile/__init__.py b/web_dashboard_tile/__init__.py index 1d098b583..91c5580fe 100644 --- a/web_dashboard_tile/__init__.py +++ b/web_dashboard_tile/__init__.py @@ -1,7 +1,2 @@ -# -*- coding: utf-8 -*- -# © 2010-2013 OpenERP s.a. (). -# © 2014 initOS GmbH & Co. KG (). -# © 2015-Today GRAP -# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html - +from . import controllers from . import models diff --git a/web_dashboard_tile/__openerp__.py b/web_dashboard_tile/__manifest__.py similarity index 60% rename from web_dashboard_tile/__openerp__.py rename to web_dashboard_tile/__manifest__.py index 7d78e47ea..8b990f891 100644 --- a/web_dashboard_tile/__openerp__.py +++ b/web_dashboard_tile/__manifest__.py @@ -1,15 +1,15 @@ -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html { - "name": "Dashboard Tile", - "summary": "Add Tiles to Dashboard", - "version": "9.0.1.1.0", + "name": "Overview Dashboard (Tiles)", + "summary": "Add Overview Dashboards with Tiles", + "version": "12.0.1.0.0", "depends": ["web", "board", "mail", "web_widget_color"], "author": "initOS GmbH & Co. KG, " "GRAP, " "Odoo Community Association (OCA)", + "maintainers": ["legalsylvain"], "category": "web", "license": "AGPL-3", "contributors": [ @@ -18,15 +18,16 @@ "Iván Todorovich ", ], "data": [ - "views/tile.xml", - "views/templates.xml", "security/ir.model.access.csv", - "security/rules.xml", + "security/ir_rule.xml", + "views/menu.xml", + "views/tile_tile.xml", + "views/tile_category.xml", + "views/templates.xml", ], "demo": [ - "demo/res_groups.yml", - "demo/tile_category.yml", - "demo/tile_tile.yml", + "demo/tile_category.xml", + "demo/tile_tile.xml", ], - "qweb": ["static/src/xml/custom_xml.xml"], + "qweb": ["static/src/xml/web_dashboard_tile.xml"], } diff --git a/web_dashboard_tile/controllers/__init__.py b/web_dashboard_tile/controllers/__init__.py new file mode 100644 index 000000000..12a7e529b --- /dev/null +++ b/web_dashboard_tile/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/web_dashboard_tile/controllers/main.py b/web_dashboard_tile/controllers/main.py new file mode 100644 index 000000000..1f29fe29a --- /dev/null +++ b/web_dashboard_tile/controllers/main.py @@ -0,0 +1,15 @@ +# Copyright (C) 2019-Today: GTRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.http import Controller, route, request + + +class WebDashboardTile(Controller): + + @route('/web_dashboard_tile/create_tile', type='json', auth='user') + def create_tile(self, model_name, *args, **kwargs): + IrModel = request.env['ir.model'] + model = IrModel.search([('model', '=', model_name)]) + kwargs.update({'model_id': model.id}) + return request.env['tile.tile'].create(kwargs) diff --git a/web_dashboard_tile/demo/res_groups.yml b/web_dashboard_tile/demo/res_groups.yml deleted file mode 100644 index 735437c5c..000000000 --- a/web_dashboard_tile/demo/res_groups.yml +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2015-Today GRAP -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -- !record {model: res.groups, id: base.group_no_one}: - users: - - base.user_root diff --git a/web_dashboard_tile/demo/tile_category.xml b/web_dashboard_tile/demo/tile_category.xml new file mode 100644 index 000000000..c8be7c677 --- /dev/null +++ b/web_dashboard_tile/demo/tile_category.xml @@ -0,0 +1,16 @@ + + + + + Modules + 1 + + + + + Currencies + 2 + + + + diff --git a/web_dashboard_tile/demo/tile_category.yml b/web_dashboard_tile/demo/tile_category.yml deleted file mode 100644 index 01bf0aeab..000000000 --- a/web_dashboard_tile/demo/tile_category.yml +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2015-Today GRAP -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -- !record {model: tile.category, id: modules}: - name: Modules - sequence: 0 - -- !record {model: tile.category, id: finance}: - name: Finance - sequence: 1 diff --git a/web_dashboard_tile/demo/tile_tile.xml b/web_dashboard_tile/demo/tile_tile.xml new file mode 100644 index 000000000..aca1a2d34 --- /dev/null +++ b/web_dashboard_tile/demo/tile_tile.xml @@ -0,0 +1,29 @@ + + + + + Installed Modules + + + + [['state', 'in', ['installed', 'to upgrade', 'to remove']]] + + + + Installed OCA Modules + + + + [['state', 'in', ['installed', 'to upgrade', 'to remove']], ['author', 'ilike', 'Odoo Community Association (OCA)']] + + + + Currencies (Max Rate) + + + max + + [] + + + diff --git a/web_dashboard_tile/demo/tile_tile.yml b/web_dashboard_tile/demo/tile_tile.yml deleted file mode 100644 index 50cd7b69f..000000000 --- a/web_dashboard_tile/demo/tile_tile.yml +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2015-Today GRAP -# @author Sylvain LE GAL (https://twitter.com/legalsylvain) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -- !record {model: tile.tile, id: installed_modules}: - name: Installed Modules - category_id: modules - model_id: base.model_ir_module_module - domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']]] - action_id: base.open_module_tree - -- !record {model: tile.tile, id: installed_OCA_modules}: - name: Installed OCA Modules - category_id: modules - model_id: base.model_ir_module_module - domain: [['state', 'in', ['installed', 'to upgrade', 'to remove']], ['author', 'ilike', 'Odoo Community Association (OCA)']] - action_id: base.open_module_tree - -- !record {model: tile.tile, id: all_currency_with_rate}: - name: Currencies (Max Rate) - category_id: finance - model_id: base.model_res_currency - domain: [] - secondary_function: max - secondary_field_id: base.field_res_currency_rate diff --git a/web_dashboard_tile/i18n/ar.po b/web_dashboard_tile/i18n/ar.po deleted file mode 100644 index baec909fe..000000000 --- a/web_dashboard_tile/i18n/ar.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Arabic (https://www.transifex.com/oca/teams/23907/ar/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: ar\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "الحقل" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/ca.po b/web_dashboard_tile/i18n/ca.po deleted file mode 100644 index c8f94eb99..000000000 --- a/web_dashboard_tile/i18n/ca.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# Marc Tormo i Bochaca , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: Marc Tormo i Bochaca , 2018\n" -"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: ca\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "Creat per" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "Creat a " - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "Nom a mostrar" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "ID" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "Última modificació a" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "Última actualització per" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "Última actualització a " - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/de.po b/web_dashboard_tile/i18n/de.po deleted file mode 100644 index a1a769569..000000000 --- a/web_dashboard_tile/i18n/de.po +++ /dev/null @@ -1,333 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# Rudolf Schnapka , 2018 -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: de\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "Anlegen" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "Angelegt durch" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "Angelegt am" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "Anzeigebezeichnung" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Feld" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "ID" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "Zuletzt geändert am" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "Zuletzt geändert durch" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "Zuletzt aktualisiert am" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/es.po b/web_dashboard_tile/i18n/es.po deleted file mode 100644 index b3feb292b..000000000 --- a/web_dashboard_tile/i18n/es.po +++ /dev/null @@ -1,333 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -# Pedro M. Baeza , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: Pedro M. Baeza , 2018\n" -"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "Crear" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Campo" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/fi.po b/web_dashboard_tile/i18n/fi.po deleted file mode 100644 index ac240f69d..000000000 --- a/web_dashboard_tile/i18n/fi.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fi\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Kenttä" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/fr.po b/web_dashboard_tile/i18n/fr.po index efd8077ce..84dca759d 100644 --- a/web_dashboard_tile/i18n/fr.po +++ b/web_dashboard_tile/i18n/fr.po @@ -1,34 +1,52 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# leemannd , 2018 -# OCA Transbot , 2018 +# * web_dashboard_tile +# msgid "" msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"POT-Creation-Date: 2021-08-02 15:38+0000\n" +"PO-Revision-Date: 2021-08-02 15:38+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Plural-Forms: \n" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/web_dashboard_tile.js:99 +#, python-format +msgid "'%s' added to the overview dashboard" +msgstr "'%s' a été ajouté au tableau de bord synthétique" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__action_id msgid "Action" -msgstr "Action" +msgstr "" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__active +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__active msgid "Active" msgstr "Actif" +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml:15 +#, python-format +msgid "Add" +msgstr "Ajouter" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml:4 +#, python-format +msgid "Add to the Overview Dashboard" +msgstr "Ajouter au tableau de bord synthétique" + #. module: web_dashboard_tile #: selection:tile.tile,primary_function:0 #: selection:tile.tile,secondary_function:0 @@ -36,10 +54,25 @@ msgid "Average" msgstr "Moyenne" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__background_color +msgid "Background Color" msgstr "Couleur de fond" +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml:9 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__category_id +#, python-format +msgid "Category" +msgstr "Catégorie" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/web_dashboard_tile.js:104 +#, python-format +msgid "Could not add new element to the overview dashboard" +msgstr "Impossible d'ajouter un nouvel élément au tableau de bord synthétique" + #. module: web_dashboard_tile #: selection:tile.tile,primary_function:0 #: selection:tile.tile,secondary_function:0 @@ -47,147 +80,147 @@ msgid "Count" msgstr "Quantité" #. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "Créer" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__create_uid +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__create_uid msgid "Created by" msgstr "Créé par" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__create_date +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__create_date msgid "Created on" msgstr "Créé le" #. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "Tableau de bord" +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tile_category +#: model:ir.ui.menu,name:web_dashboard_tile.menu_tile_category +msgid "Dashboard Categories" +msgstr "Catégorie de tableau de bord" + +#. module: web_dashboard_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_category_2_tile +#: model:ir.actions.act_window,name:web_dashboard_tile.action_tile_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menu_tile_tile +msgid "Dashboard Items" +msgstr "Elément de tableau de bord" #. module: web_dashboard_tile #: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile msgid "Dashboard Tile" msgstr "Indicateur de tableau de bord" #. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "Indicateurs de tableau de bord" +#: model:ir.model,name:web_dashboard_tile.model_tile_category +msgid "Dashboard Tile Category" +msgstr "Catégorie de tableau de bord" #. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_tile_form msgid "Display" -msgstr "" +msgstr "Afficher" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__display_name +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__display_name msgid "Display Name" msgstr "Nom affiché" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__domain msgid "Domain" msgstr "Domaine" #. module: web_dashboard_tile #. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 +#: code:addons/web_dashboard_tile/models/tile_tile.py:202 +#: code:addons/web_dashboard_tile/models/tile_tile.py:240 +#: code:addons/web_dashboard_tile/static/src/js/web_dashboard_tile.js:75 #, python-format msgid "Error" msgstr "Erreur" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__error msgid "Error Details" -msgstr "" +msgstr "Détails de l'erreur" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Champ" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__font_color +msgid "Font Color" +msgstr "Couleur de la police" #. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "Le nom du filtre est requis." - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "Fonction" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__group_ids msgid "Groups" -msgstr "" +msgstr "Groupes" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__hidden +msgid "Hidden" +msgstr "Masqué" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__hide_if_null +msgid "Hide if null" +msgstr "Cacher si non défini" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__id +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__id msgid "ID" -msgstr "ID" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" msgstr "" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile__hide_if_null +msgid "If checked, the item will be hidden if the primary value is null." +msgstr "Si la case est cochée, l'élément sera cachée si la valeur principale n'est pas définie." + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile__group_ids +msgid "If this field is set, only users of this group can view this tile. Please note that it will only work for global tiles (that is, when User field is left empty)" +msgstr "Si ce champ est renseigné, les utilisateurs de ce groupe seulement pourront voir cet élément. Cette restriction ne fonctionne que s'il s'agit d'un élément global. (quand le champ Utilisateur n'est pas renseigné)\"" + +#. module: web_dashboard_tile +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_category_form +msgid "Items" +msgstr "Éléments" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category____last_update +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile____last_update msgid "Last Modified on" msgstr "Dernière modification le" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__write_uid +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__write_uid msgid "Last Updated by" -msgstr "Mis à jour par" +msgstr "Dernière mise à jour par" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__write_date +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__write_date msgid "Last Updated on" -msgstr "Mis à jour le" +msgstr "Dernière mise à jour le" #. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile__action_id +msgid "Let empty to use the default action related to the selected model." +msgstr "Laisser libre pour utiliser l'action par défaut liée au modèle sélectionné." + +#. module: web_dashboard_tile +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_tile_form msgid "Main Value" -msgstr "" +msgstr "Valeur principale" #. module: web_dashboard_tile #: selection:tile.tile,primary_function:0 #: selection:tile.tile,secondary_function:0 msgid "Maximum" -msgstr "Maximum" +msgstr "" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 +#: code:addons/web_dashboard_tile/models/tile_tile.py:41 #, python-format msgid "Maximum value of '%s'" msgstr "Valeur maximale du champ '%s'" @@ -199,7 +232,7 @@ msgid "Median" msgstr "Médiane" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 +#: code:addons/web_dashboard_tile/models/tile_tile.py:61 #, python-format msgid "Median value of '%s'" msgstr "Valeur médian du champ '%s'" @@ -208,82 +241,160 @@ msgstr "Valeur médian du champ '%s'" #: selection:tile.tile,primary_function:0 #: selection:tile.tile,secondary_function:0 msgid "Minimum" -msgstr "Minimum" +msgstr "" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 +#: code:addons/web_dashboard_tile/models/tile_tile.py:33 +#: code:addons/web_dashboard_tile/models/tile_tile.py:53 #, python-format msgid "Minimum value of '%s'" msgstr "Valeur minimale du champ '%s'" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__model_id msgid "Model" msgstr "Modèle" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__model_name +msgid "Model name" +msgstr "Nom du modèle" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml:5 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__name +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__name +#, python-format +msgid "Name" +msgstr "Nom" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/web_dashboard_tile.js:75 +#, python-format +msgid "Name Field is required." +msgstr "Le nom du champ est requis." + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:25 #, python-format msgid "Number of records" -msgstr "" +msgstr "Nombre d'enregistrement" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__action_id +msgid "Odoo Action" +msgstr "Action Odoo" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__menu_id +msgid "Odoo Menu" +msgstr "Menu Odoo" + +#. module: web_dashboard_tile +#: model:ir.ui.menu,name:web_dashboard_tile.menu_dashboard_tile +msgid "Overview" +msgstr "Vue d'ensemble" + +#. module: web_dashboard_tile +#. openerp-web +#: code:addons/web_dashboard_tile/static/src/js/web_dashboard_tile.js:100 +#, python-format +msgid "Please refresh your browser for the changes to take effect." +msgstr "Veuillez rafraichir votre navigateur pour que les changements prennent effets." + +#. module: web_dashboard_tile +#: code:addons/web_dashboard_tile/models/tile_tile.py:317 #, python-format msgid "Please select a field from the selected model." -msgstr "" +msgstr "Veuillez sélectionner un champ correspondant au modèle sélectionné" #. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__primary_field_id +msgid "Primary Field" +msgstr "Champ principal" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__primary_format +msgid "Primary Format" +msgstr "Format principal" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__primary_formated_value +msgid "Primary Formated Value" +msgstr "Valeur principale formatée" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__primary_function +msgid "Primary Function" +msgstr "Fonction principale" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__primary_helper +msgid "Primary Helper" +msgstr "Assistant principal" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__primary_value +msgid "Primary value" +msgstr "Valeur principale" + +#. module: web_dashboard_tile +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile__primary_format +#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile__secondary_format +msgid "Python Format String valid with str.format()\n" "ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" +msgstr "Chaine de format python valide, avec str.format()\n" +"par exemple: {:,} Kgs' affichera '1000 Kgs' si la valeur est 1000." #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__secondary_field_id msgid "Secondary Field" -msgstr "" +msgstr "champ secondaire" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__secondary_format msgid "Secondary Format" -msgstr "" +msgstr "Format secondaire" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__secondary_formated_value +msgid "Secondary Formated Value" +msgstr "Valeur formatée secondaire" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__secondary_function msgid "Secondary Function" -msgstr "" +msgstr "Fonction secondaire" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__secondary_helper msgid "Secondary Helper" -msgstr "" +msgstr "Aide secondaire" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__secondary_value +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_tile_form msgid "Secondary Value" -msgstr "" +msgstr "Valeur secondaire" #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_tile_form +msgid "Security" +msgstr "Sécurité" + +#. module: web_dashboard_tile +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__sequence +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__sequence msgid "Sequence" msgstr "Séquence" #. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "Succès" +#: model:ir.ui.menu,name:web_dashboard_tile.menu_dashboard_tile_settings +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_tile_form +msgid "Settings" +msgstr "Configuration" #. module: web_dashboard_tile #: selection:tile.tile,primary_function:0 @@ -292,42 +403,35 @@ msgid "Sum" msgstr "Somme" #. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_category_form +#: model_terms:ir.ui.view,arch_db:web_dashboard_tile.view_tile_tile_form msgid "Technical Informations" -msgstr "" +msgstr "Informations techniques" #. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "L'indicateur a été créé" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__tile_ids +msgid "Tiles" +msgstr "Elements" #. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "Indicateur :" +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_category__tile_qty +msgid "Tiles Quantity" +msgstr "Nombre d'éléments" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 +#: code:addons/web_dashboard_tile/models/tile_tile.py:46 #, python-format msgid "Total value of '%s'" msgstr "Somme du champ '%s'" #. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 +#: code:addons/web_dashboard_tile/models/tile_tile.py:288 #, python-format msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" +msgstr "Fonctionnalité non implémenté. La recherche sur le champ 'Actif' est désactivé." #. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id +#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile__user_id msgid "User" msgstr "Utilisateur" -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/it.po b/web_dashboard_tile/i18n/it.po deleted file mode 100644 index 07e8fdbf3..000000000 --- a/web_dashboard_tile/i18n/it.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Campo" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/nl.po b/web_dashboard_tile/i18n/nl.po deleted file mode 100644 index a2699d59c..000000000 --- a/web_dashboard_tile/i18n/nl.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: nl\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Veld" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/pt_BR.po b/web_dashboard_tile/i18n/pt_BR.po deleted file mode 100644 index 2254f37a4..000000000 --- a/web_dashboard_tile/i18n/pt_BR.po +++ /dev/null @@ -1,333 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# Armando Vulcano Junior , 2018 -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/teams/23907/pt_BR/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: pt_BR\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "Criar" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "Criado por" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "Criado em" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "Mostrar Nome" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Campo" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "ID" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "Última Modificação em" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "Última Atualização por" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "Última Atualização em" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/sl.po b/web_dashboard_tile/i18n/sl.po deleted file mode 100644 index 41c6e417f..000000000 --- a/web_dashboard_tile/i18n/sl.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: sl\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "Dejanje" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "Aktivno" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "Povprečje" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "Barva ozadja" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "Štetje" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "Ustvari" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "Ustvaril" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "Ustvarjeno" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "Nadzorna plošča" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "Okvir nadzorne plošče" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "Okvirji nadzorne plošče" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "Domena" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "Napaka" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Polje" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "Zahtevan je naziv filtra." - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "Funkcija" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "ID" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "Zadnjič posodobil" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "Zadnjič posodobljeno" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "Maksimum" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "Maksimalna vrednost '%s'" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "Sredina" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "Srednja vrednost '%s'" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "Minimum" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "Minimalna vrednost '%s'" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "Model" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "Zaporedje" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "Uspeh" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "Vsota" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "Okvir je ustvarjen" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "Okvir:" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "Skupna vrednost '%s'" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "Uporabnik" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/i18n/tr.po b/web_dashboard_tile/i18n/tr.po deleted file mode 100644 index 39362c361..000000000 --- a/web_dashboard_tile/i18n/tr.po +++ /dev/null @@ -1,332 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_dashboard_tile -# -# Translators: -# OCA Transbot , 2018 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-01-25 03:54+0000\n" -"PO-Revision-Date: 2018-01-25 03:54+0000\n" -"Last-Translator: OCA Transbot , 2018\n" -"Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: tr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_action_id -msgid "Action" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_active -msgid "Active" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Average" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_background_color -msgid "Background color" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Count" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:8 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_uid -msgid "Created by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_create_date -msgid "Created on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_kanban_dashboard_tile -#: model:ir.actions.act_window,name:web_dashboard_tile.action_tree_dashboard_tile -#: model:ir.ui.menu,name:web_dashboard_tile.mail_dashboard -msgid "Dashboard" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model,name:web_dashboard_tile.model_tile_tile -#: model:ir.ui.menu,name:web_dashboard_tile.menue_dashboard_tile -msgid "Dashboard Tile" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_tree_view -msgid "Dashboard tiles" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Display" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_display_name -msgid "Display Name" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_domain -msgid "Domain" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Error" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_error -msgid "Error Details" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_field_id -msgid "Field" -msgstr "Alan" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:57 -#, python-format -msgid "Filter name is required." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_font_color -msgid "Font color" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_format -msgid "Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_function -msgid "Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_group_ids -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Groups" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_helper -msgid "Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_id -msgid "ID" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_group_ids -msgid "" -"If this field is set, only users of this group can view this tile. Please " -"note that it will only work for global tiles (that is, when User field is " -"left empty)" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile___last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_uid -msgid "Last Updated by" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_write_date -msgid "Last Updated on" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Main Value" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Maximum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:39 -#, python-format -msgid "Maximum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Median" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:51 -#, python-format -msgid "Median value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Minimum" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:35 -#: code:addons/web_dashboard_tile/models/tile_tile.py:47 -#, python-format -msgid "Minimum value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_model_id -msgid "Model" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_name -msgid "Name" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:31 -#, python-format -msgid "Number of records" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:241 -#, python-format -msgid "Please select a field from the selected model." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_primary_format -#: model:ir.model.fields,help:web_dashboard_tile.field_tile_tile_secondary_format -msgid "" -"Python Format String valid with str.format()\n" -"ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_field_id -msgid "Secondary Field" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_format -msgid "Secondary Format" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_function -msgid "Secondary Function" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_helper -msgid "Secondary Helper" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_secondary_value -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Secondary Value" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_sequence -msgid "Sequence" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Success" -msgstr "" - -#. module: web_dashboard_tile -#: selection:tile.tile,primary_function:0 -#: selection:tile.tile,secondary_function:0 -msgid "Sum" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.ui.view,arch_db:web_dashboard_tile.dashboard_tile_tile_form_view -msgid "Technical Informations" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/js/custom_js.js:96 -#, python-format -msgid "Tile is created" -msgstr "" - -#. module: web_dashboard_tile -#. openerp-web -#: code:addons/web_dashboard_tile/static/src/xml/custom_xml.xml:6 -#, python-format -msgid "Tile:" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:43 -#, python-format -msgid "Total value of '%s'" -msgstr "" - -#. module: web_dashboard_tile -#: code:addons/web_dashboard_tile/models/tile_tile.py:216 -#, python-format -msgid "Unimplemented Feature. Search on Active field disabled." -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_user_id -msgid "User" -msgstr "" - -#. module: web_dashboard_tile -#: model:ir.model.fields,field_description:web_dashboard_tile.field_tile_tile_primary_value -msgid "Value" -msgstr "" diff --git a/web_dashboard_tile/migrations/12.0.1.0.0/post-migration.py b/web_dashboard_tile/migrations/12.0.1.0.0/post-migration.py new file mode 100644 index 000000000..118657c6d --- /dev/null +++ b/web_dashboard_tile/migrations/12.0.1.0.0/post-migration.py @@ -0,0 +1,29 @@ +# Copyright (C) 2019-Today: GTRAP () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import odoo + + +def migrate(cr, version): + if not version: + return + + with odoo.api.Environment.manage(): + env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {}) + + # categories was optional in previous versions + # affecting all tiles without categories + tiles_without_category = env["tile.tile"].search( + [('category_id', '=', False)]) + if tiles_without_category: + default_category = env["tile.category"].create({ + "name": "Default Category", + }) + tiles_without_category.write({ + 'category_id': default_category.id + }) + + # Enable all categories, to generate actions and menus + categories = env['tile.category'].with_context( + active_test=False).search([]) + categories.write({'active': True}) diff --git a/web_dashboard_tile/migrations/8.0.3.0/post-migration.py b/web_dashboard_tile/migrations/8.0.3.0/post-migration.py deleted file mode 100644 index c19f1870c..000000000 --- a/web_dashboard_tile/migrations/8.0.3.0/post-migration.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2016 Iván Todorovich -# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html - - -def migrate(cr, version): - if version is None: - return - - # Rename old fields - cr.execute("""UPDATE tile_tile SET primary_function = 'count'""") - cr.execute("""UPDATE tile_tile SET secondary_function = field_function""") - cr.execute("""UPDATE tile_tile SET secondary_field_id = field_id""") diff --git a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py b/web_dashboard_tile/migrations/8.0.4.0/post-migration.py deleted file mode 100644 index 674121edc..000000000 --- a/web_dashboard_tile/migrations/8.0.4.0/post-migration.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2016 Iván Todorovich -# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html - - -def migrate(cr, version): - if version is None: - return - - # Update ir.rule - cr.execute( - """ - SELECT res_id FROM ir_model_data - WHERE name = 'model_tile_rule' - AND module = 'web_dashboard_tile'""" - ) - rule_id = cr.fetchone()[0] - new_domain = """[ - "|", - ("user_id","=",user.id), - ("user_id","=",False), - "|", - ("group_ids","=",False), - ("group_ids","in",[g.id for g in user.groups_id]), - ]""" - cr.execute( - """ - UPDATE ir_rule SET domain_force = '%(domain)s' - WHERE id = '%(id)s' """ - % {"domain": new_domain, "id": rule_id} - ) diff --git a/web_dashboard_tile/models/__init__.py b/web_dashboard_tile/models/__init__.py index 3a5158325..aaaf277fe 100644 --- a/web_dashboard_tile/models/__init__.py +++ b/web_dashboard_tile/models/__init__.py @@ -1,7 +1,2 @@ -# -*- coding: utf-8 -*- -# © 2010-2013 OpenERP s.a. (). -# © 2014 initOS GmbH & Co. KG (). -# © 2015-Today GRAP -# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html - -from . import tile_tile, tile_category +from . import tile_tile +from . import tile_category diff --git a/web_dashboard_tile/models/tile_category.py b/web_dashboard_tile/models/tile_category.py index e7b8d843c..d412fa939 100644 --- a/web_dashboard_tile/models/tile_category.py +++ b/web_dashboard_tile/models/tile_category.py @@ -1,8 +1,8 @@ -# -*- coding: utf-8 -*- # © 2018 Iván Todorovich +# © 2019-Today GRAP # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from openerp import fields, models +from odoo import api, fields, models class TileCategory(models.Model): @@ -11,7 +11,95 @@ class TileCategory(models.Model): _order = "sequence asc" name = fields.Char(required=True) - sequence = fields.Integer( - help="Used to order the tile categories", default=0 + + sequence = fields.Integer(required=True, default=10) + + active = fields.Boolean(default=True) + + action_id = fields.Many2one( + string='Odoo Action', comodel_name='ir.actions.act_window', + readonly=True) + + menu_id = fields.Many2one( + string='Odoo Menu', comodel_name='ir.ui.menu', readonly=True) + + tile_ids = fields.One2many( + string='Tiles', comodel_name='tile.tile', + inverse_name='category_id') + + tile_qty = fields.Integer( + string='Tiles Quantity', + compute='_compute_tile_qty', + store=True, ) - fold = fields.Boolean("Folded by default") + + @api.depends('tile_ids') + def _compute_tile_qty(self): + for category in self: + category.tile_qty = len(category.tile_ids) + + def _prepare_action(self): + self.ensure_one() + return { + 'name': self.name, + 'res_model': 'tile.tile', + 'type': 'ir.actions.act_window', + 'view_mode': 'kanban', + 'domain': "[" + "('hidden', '=', False)," + "'|', ('user_id', '=', False), ('user_id', '=', uid)," + "('category_id', '=', %d)" + "]" % self.id, + } + + def _prepare_menu(self): + self.ensure_one() + return { + 'name': self.name, + 'parent_id': self.env.ref( + 'web_dashboard_tile.menu_dashboard_tile').id, + 'action': 'ir.actions.act_window,%d' % self.action_id.id, + 'sequence': self.sequence, + } + + def _create_ui(self): + IrUiMenu = self.env['ir.ui.menu'] + IrActionsActWindows = self.env['ir.actions.act_window'] + for category in self: + if not category.action_id: + category.action_id = IrActionsActWindows.create( + category._prepare_action()) + if not category.menu_id: + category.menu_id = IrUiMenu.create(category._prepare_menu()) + + def _delete_ui(self): + for category in self: + if category.menu_id: + category.menu_id.unlink() + if category.action_id: + category.action_id.unlink() + + @api.model + def create(self, vals): + category = super().create(vals) + if category.active: + category._create_ui() + return category + + def write(self, vals): + res = super().write(vals) + if 'active' in vals.keys(): + if vals.get('active'): + self._create_ui() + else: + self._delete_ui() + if 'sequence' in vals.keys(): + self.mapped('menu_id').write({'sequence': vals['sequence']}) + if 'name' in vals.keys(): + self.mapped('menu_id').write({'name': vals['name']}) + self.mapped('action_id').write({'name': vals['name']}) + return res + + def unlink(self): + self._delete_ui() + super().unlink() diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index eeacb9bc6..599464e54 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2010-2013 OpenERP s.a. (). # © 2014 initOS GmbH & Co. KG (). # © 2015-Today GRAP @@ -6,22 +5,14 @@ import datetime import time +from statistics import median from dateutil.relativedelta import relativedelta from collections import OrderedDict -from openerp import api, fields, models -from openerp.tools.safe_eval import safe_eval as eval -from openerp.tools.translate import _ -from openerp.exceptions import ValidationError, except_orm - - -def median(vals): - # https://docs.python.org/3/library/statistics.html#statistics.median - # TODO : refactor, using statistics.median when Odoo will be available - # in Python 3.4 - even = (0 if len(vals) % 2 else 1) + 1 - half = (len(vals) - 1) / 2 - return sum(sorted(vals)[half : half + even]) / float(even) +from odoo import api, fields, models +from odoo.tools.safe_eval import safe_eval as eval +from odoo.tools.translate import _ +from odoo.exceptions import ValidationError, except_orm FIELD_FUNCTIONS = OrderedDict( @@ -59,7 +50,7 @@ FIELD_FUNCTIONS = OrderedDict( { "name": "Average", "func": lambda vals: sum(vals) / len(vals), - "help": _("Minimum value of '%s'"), + "help": _("Average value of '%s'"), }, ), ( @@ -84,160 +75,211 @@ class TileTile(models.Model): _description = "Dashboard Tile" _order = "sequence, name" - def _get_eval_context(self): - def _context_today(): - return fields.Date.from_string(fields.Date.context_today(self)) - - context = self.env.context.copy() - context.update( - { - "time": time, - "datetime": datetime, - "relativedelta": relativedelta, - "context_today": _context_today, - "current_date": fields.Date.today(), - } - ) - return context - # Column Section name = fields.Char(required=True) + sequence = fields.Integer(default=0, required=True) - category_id = fields.Many2one("tile.category", "Category") - user_id = fields.Many2one("res.users", "User") - background_color = fields.Char(default="#0E6C7E", oldname="color") + + category_id = fields.Many2one( + string="Category", comodel_name="tile.category", required=True, + ondelete="CASCADE") + + user_id = fields.Many2one(string="User", comodel_name="res.users") + + background_color = fields.Char(default="#0E6C7E") + font_color = fields.Char(default="#FFFFFF") group_ids = fields.Many2many( - "res.groups", + comodel_name="res.groups", string="Groups", help="If this field is set, only users of this group can view this " "tile. Please note that it will only work for global tiles " "(that is, when User field is left empty)", ) - model_id = fields.Many2one("ir.model", "Model", required=True) + model_id = fields.Many2one( + comodel_name="ir.model", string="Model", required=True + ) + + model_name = fields.Char(string="Model name", related="model_id.model") + domain = fields.Text(default="[]") - action_id = fields.Many2one("ir.actions.act_window", "Action") + + action_id = fields.Many2one( + comodel_name="ir.actions.act_window", + string="Action", help="Let empty to use the default action related to" + " the selected model.", + domain="[('res_model', '=', model_name)]") active = fields.Boolean( compute="_compute_active", search="_search_active", readonly=True ) + hide_if_null = fields.Boolean( + string="Hide if null", help="If checked, the item will be hidden" + " if the primary value is null.") + + hidden = fields.Boolean( + string="Hidden", compute="_compute_data", + search="_search_hidden") + # Primary Value primary_function = fields.Selection( - FIELD_FUNCTION_SELECTION, string="Function", default="count" + string="Primary Function", required=True, + selection=FIELD_FUNCTION_SELECTION, default="count", ) + primary_field_id = fields.Many2one( - "ir.model.fields", - string="Field", + comodel_name="ir.model.fields", + string="Primary Field", domain="[('model_id', '=', model_id)," " ('ttype', 'in', ['float', 'integer', 'monetary'])]", ) + primary_format = fields.Char( - string="Format", + string="Primary Format", help="Python Format String valid with str.format()\n" "ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000.", ) - primary_value = fields.Char(string="Value", compute="_compute_data") - primary_helper = fields.Char(string="Helper", compute="_compute_helper") + + primary_value = fields.Float( + string="Primary Value", compute="_compute_data") + + primary_formated_value = fields.Char( + string="Primary Formated Value", compute="_compute_data") + + primary_helper = fields.Char( + string="Primary Helper", compute="_compute_helper", + store=True) # Secondary Value secondary_function = fields.Selection( - FIELD_FUNCTION_SELECTION, string="Secondary Function" + string="Secondary Function", selection=FIELD_FUNCTION_SELECTION, ) + secondary_field_id = fields.Many2one( - "ir.model.fields", + comodel_name="ir.model.fields", string="Secondary Field", domain="[('model_id', '=', model_id)," " ('ttype', 'in', ['float', 'integer', 'monetary'])]", ) + secondary_format = fields.Char( string="Secondary Format", help="Python Format String valid with str.format()\n" "ie: '{:,} Kgs' will output '1,000 Kgs' if value is 1000.", ) - secondary_value = fields.Char( - string="Secondary Value", compute="_compute_data" + + secondary_value = fields.Float( + string="Secondary Value", compute="_compute_data") + + secondary_formated_value = fields.Char( + string="Secondary Formated Value", compute="_compute_data" ) + secondary_helper = fields.Char( - string="Secondary Helper", compute="_compute_helper" + string="Secondary Helper", compute="_compute_helper", + store=True ) error = fields.Char(string="Error Details", compute="_compute_data") - @api.one + # Compute Section + @api.depends("primary_format", "secondary_format", "model_id", "domain") def _compute_data(self): - if not self.active: - return - model = self.env[self.model_id.model] - eval_context = self._get_eval_context() - domain = self.domain or "[]" - try: - count = model.search_count(eval(domain, eval_context)) - except Exception as e: - self.primary_value = self.secondary_value = "ERR!" - self.error = str(e) - return - fields = [ - f.name - for f in [self.primary_field_id, self.secondary_field_id] - if f - ] - read_vals = ( - fields - and model.search_read(eval(domain, eval_context), fields) - or [] - ) - for f in ["primary_", "secondary_"]: - f_function = f + "function" - f_field_id = f + "field_id" - f_format = f + "format" - f_value = f + "value" - value = 0 - if not self[f_function]: - self[f_value] = False - else: - if self[f_function] == "count": - value = count + for tile in self: + if not tile.model_id or not tile.active: + return + model = self.env[tile.model_id.model] + eval_context = self._get_eval_context() + domain = tile.domain or "[]" + try: + count = model.search_count(eval(domain, eval_context)) + except Exception as e: + tile.primary_value = 0.0 + tile.primary_formated_value =\ + tile.secondary_formated_value = _("Error") + tile.error = str(e) + return + fields = [ + f.name + for f in [tile.primary_field_id, tile.secondary_field_id] + if f + ] + read_vals = ( + fields + and model.search_read(eval(domain, eval_context), fields) + or [] + ) + for f in ["primary_", "secondary_"]: + f_function = f + "function" + f_field_id = f + "field_id" + f_format = f + "format" + f_value = f + "value" + f_formated_value = f + "formated_value" + value = 0 + if not tile[f_function]: + tile[f_value] = 0.0 + tile[f_formated_value] = False else: - func = FIELD_FUNCTIONS[self[f_function]]["func"] - vals = [x[self[f_field_id].name] for x in read_vals] - value = func(vals) - try: - self[f_value] = (self[f_format] or "{:,}").format(value) - except ValueError as e: - self[f_value] = "F_ERR!" - self.error = str(e) - return + if tile[f_function] == "count": + value = count + else: + func = FIELD_FUNCTIONS[tile[f_function]]["func"] + vals = [x[tile[f_field_id].name] for x in read_vals] + value = func(vals or [0.0]) + try: + tile[f_value] = value + tile[f_formated_value] = ( + tile[f_format] or "{:,}").format(value) + if tile.hide_if_null and not value: + tile.hidden = True + except ValueError as e: + tile[f_value] = 0.0 + tile[f_formated_value] = _("Error") + tile.error = str(e) - @api.one - @api.onchange( + @api.depends( "primary_function", "primary_field_id", "secondary_function", "secondary_field_id", ) def _compute_helper(self): - for f in ["primary_", "secondary_"]: - f_function = f + "function" - f_field_id = f + "field_id" - f_helper = f + "helper" - self[f_helper] = "" - field_func = FIELD_FUNCTIONS.get(self[f_function], {}) - help = field_func.get("help", False) - if help: - if self[f_function] != "count" and self[f_field_id]: - desc = self[f_field_id].field_description - self[f_helper] = help % desc - else: - self[f_helper] = help + for tile in self: + for f in ["primary_", "secondary_"]: + f_function = f + "function" + f_field_id = f + "field_id" + f_helper = f + "helper" + tile[f_helper] = "" + field_func = FIELD_FUNCTIONS.get(tile[f_function], {}) + help = field_func.get("help", False) + if help: + if tile[f_function] != "count" and tile[f_field_id]: + desc = tile[f_field_id].field_description + tile[f_helper] = help % desc + else: + tile[f_helper] = help - @api.one def _compute_active(self): ima = self.env["ir.model.access"] - for rec in self: - rec.active = ima.check(rec.model_id.model, "read", False) + for tile in self: + if tile.model_id: + tile.active = ima.check(tile.model_id.model, "read", False) + else: + tile.active = True + + # Search Sections + def _search_hidden(self, operator, operand): + items = self.search([]) + hidden_tile_ids = [x.id for x in items if x.hidden] + if (operator == "=" and operand is False) or\ + (operator == "!=" and operand is True): + domain = [("id", "not in", hidden_tile_ids)] + else: + domain = [("id", "in", hidden_tile_ids)] + return domain def _search_active(self, operator, value): cr = self.env.cr @@ -259,8 +301,7 @@ class TileTile(models.Model): ids.append(result[0]) return [("id", "in", ids)] - # Constraints and onchanges - @api.multi + # Constraints Sections @api.constrains("model_id", "primary_field_id", "secondary_field_id") def _check_model_id_field_id(self): for rec in self: @@ -276,10 +317,12 @@ class TileTile(models.Model): _("Please select a field from the selected model.") ) + # Onchange Sections @api.onchange("model_id") def _onchange_model_id(self): self.primary_field_id = False self.secondary_field_id = False + self.action_id = False @api.onchange("primary_function", "secondary_function") def _onchange_function(self): @@ -319,3 +362,20 @@ class TileTile(models.Model): .id ) self.create(vals) + + @api.model + def _get_eval_context(self): + def _context_today(): + return fields.Date.from_string(fields.Date.context_today(self)) + + context = self.env.context.copy() + context.update( + { + "time": time, + "datetime": datetime, + "relativedelta": relativedelta, + "context_today": _context_today, + "current_date": fields.Date.today(), + } + ) + return context diff --git a/web_dashboard_tile/readme/CONFIGURE.rst b/web_dashboard_tile/readme/CONFIGURE.rst new file mode 100644 index 000000000..858db81f8 --- /dev/null +++ b/web_dashboard_tile/readme/CONFIGURE.rst @@ -0,0 +1,33 @@ +First, you have to create tile categories. + +* Go to "Dashboards > Settings > Dashboard Categories" + +* Click on Create + +* Set a name, and save. + +Odoo menu and action are automatically created. +You should refresh your browser to see new menu items. + +.. image:: ../static/description/tile_category_form.png + +Then you can create tiles. + +* go to "Dashboards > Settings > Dashboard Tiles" + +* create a new tile, set a name, a category and a model. + +* You can optionally define colors, domain a specific action to use. + +* Setting a user, or a group in "Security" tab will restrict the display of the tile. + +.. image:: ../static/description/tile_tile_form.png + +You can optionally define a secondary value, for that purpose : + +* Select a field, a function to apply. + +* You can define a specific format. (``.format()`` python syntax) + +.. image:: ../static/description/tile_tile_form_secondary_value.png + diff --git a/web_dashboard_tile/readme/CONTRIBUTORS.rst b/web_dashboard_tile/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..9af10b4f5 --- /dev/null +++ b/web_dashboard_tile/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Markus Schneider +* Sylvain Le Gal (https://twitter.com/legalsylvain) +* Iván Todorovich diff --git a/web_dashboard_tile/readme/DESCRIPTION.rst b/web_dashboard_tile/readme/DESCRIPTION.rst new file mode 100644 index 000000000..23ada038f --- /dev/null +++ b/web_dashboard_tile/readme/DESCRIPTION.rst @@ -0,0 +1,16 @@ +Adds a dashboard where you can configure tiles from any view and add them as short cut. + +By default, the tile displays items count of a given model restricted to a given domain. + +Optionally, the tile can display the result of a function on a field. + +- Function is one of ``sum``, ``avg``, ``min``, ``max`` or ``median``. +- Field must be integer or float. + +Tile can be: + +- Displayed only for a user. +- Global for all users. +- Restricted to some groups. + +*Note: The tile will be hidden if the current user doesn't have access to the given model.* diff --git a/web_dashboard_tile/readme/ROADMAP.rst b/web_dashboard_tile/readme/ROADMAP.rst new file mode 100644 index 000000000..b6bc023e7 --- /dev/null +++ b/web_dashboard_tile/readme/ROADMAP.rst @@ -0,0 +1,15 @@ +**Known issues** + +* Can not edit color from dashboard +* Original context is ignored. +* Original domain and filter are not restored. +* To preserve a relative date domain, you have to manually edit the tile's domain from "Configuration > User Interface > Dashboard Tile". You can use the same variables available in filters (``uid``, ``context_today()``, ``current_date``, ``time``, ``datetime``, `relativedelta`). + +**Roadmap** + +* Add icons. +* Support client side action (like inbox). +* Restore original Domain + Filter when an action is set. +* Posibility to hide the tile based on a field expression. +* Posibility to set the background color based on a field expression. + diff --git a/web_dashboard_tile/readme/USAGE.rst b/web_dashboard_tile/readme/USAGE.rst new file mode 100644 index 000000000..9b0134408 --- /dev/null +++ b/web_dashboard_tile/readme/USAGE.rst @@ -0,0 +1,17 @@ +* Go to "Dashboard > Overview" and select a category + +* The tile configured is displayed with the up to date count and average values of the selected domain. + +.. image:: ../static/description/tile_tile_kanban.png + +* By clicking on the item, you'll navigate to the tree view of the according model. + +.. image:: ../static/description/tile_tile_2_tree_view.png + +**Note** + +When you are in a tree view, with a domain, you can save it in the favorite menu, but the configuration is limited. + +.. image:: ../static/description/favorite_menu_create_tile.png + +.. image:: ../static/description/favorite_menu_create_tile_result.png diff --git a/web_dashboard_tile/security/rules.xml b/web_dashboard_tile/security/ir_rule.xml similarity index 91% rename from web_dashboard_tile/security/rules.xml rename to web_dashboard_tile/security/ir_rule.xml index 05637bfdc..f30705e35 100644 --- a/web_dashboard_tile/security/rules.xml +++ b/web_dashboard_tile/security/ir_rule.xml @@ -1,6 +1,5 @@ - - + tile.owner @@ -18,5 +17,4 @@ - - + diff --git a/web_dashboard_tile/static/description/favorite_menu_create_tile.png b/web_dashboard_tile/static/description/favorite_menu_create_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..b56c840f581c4677379125645387f860472e4b8b GIT binary patch literal 50632 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 literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/description/index.html b/web_dashboard_tile/static/description/index.html new file mode 100644 index 000000000..f69d4f7f6 --- /dev/null +++ b/web_dashboard_tile/static/description/index.html @@ -0,0 +1,495 @@ + + + + + + +Overview Dashboard (Tiles) + + + +
+

Overview Dashboard (Tiles)

+ + +

Beta License: AGPL-3 legalsylvain/web

+

Adds a dashboard where you can configure tiles from any view and add them as short cut.

+

By default, the tile displays items count of a given model restricted to a given domain.

+

Optionally, the tile can display the result of a function on a field.

+
    +
  • Function is one of sum, avg, min, max or median.
  • +
  • Field must be integer or float.
  • +
+

Tile can be:

+
    +
  • Displayed only for a user.
  • +
  • Global for all users.
  • +
  • Restricted to some groups.
  • +
+

Note: The tile will be hidden if the current user doesn’t have access to the given model.

+

Table of contents

+ +
+

Configuration

+

First, you have to create tile categories.

+
    +
  • Go to “Dashboards > Settings > Dashboard Categories”
  • +
  • Click on Create
  • +
  • Set a name, and save.
  • +
+

Odoo menu and action are automatically created. +You should refresh your browser to see new menu items.

+https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_category_form.png +

Then you can create tiles.

+
    +
  • go to “Dashboards > Settings > Dashboard Tiles”
  • +
  • create a new tile, set a name, a category and a model.
  • +
  • You can optionally define colors, domain a specific action to use.
  • +
  • Setting a user, or a group in “Security” tab will restrict the display of the tile.
  • +
+https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_form.png +

You can optionanaly define a secondary value, for that purpose :

+
    +
  • Select a field, a function to apply.
  • +
  • You can define a specific format. (.format() python syntax)
  • +
+https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_form_secondary_value.png +
+
+

Usage

+
    +
  • Go to “Dashboard > Overview” and select a category
  • +
  • The tile configured is displayed with the up to date count and average values of the selected domain.
  • +
+https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_kanban.png +
    +
  • By clicking on the item, you’ll navigate to the tree view of the according model.
  • +
+https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/tile_tile_2_tree_view.png +

Note

+

When you are in a tree view, with a domain, you can save it in the favorite menu, but the configuration is limited.

+https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/favorite_menu_create_tile.png +https://raw.githubusercontent.com/legalsylvain/web/12.0-mig-web_dashboard_tile/web_dashboard_tile/static/description/favorite_menu_create_tile_result.png +
+
+

Known issues / Roadmap

+

Known issues

+
    +
  • Can not edit color from dashboard
  • +
  • Original context is ignored.
  • +
  • Original domain and filter are not restored.
  • +
  • To preserve a relative date domain, you have to manually edit the tile’s domain from “Configuration > User Interface > Dashboard Tile”. You can use the same variables available in filters (uid, context_today(), current_date, time, datetime, relativedelta).
  • +
+

Roadmap

+
    +
  • Add icons.
  • +
  • Support client side action (like inbox).
  • +
  • Restore original Domain + Filter when an action is set.
  • +
  • Posibility to hide the tile based on a field expression.
  • +
  • Posibility to set the background color based on a field expression.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • initOS GmbH & Co. KG
  • +
  • GRAP
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

Current maintainer:

+

legalsylvain

+

This module is part of the legalsylvain/web project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/web_dashboard_tile/static/description/tile_category_form.png b/web_dashboard_tile/static/description/tile_category_form.png new file mode 100644 index 0000000000000000000000000000000000000000..be602a88facf77d7f46bda5ea4ecf651ae97d1e3 GIT binary patch literal 15542 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 Vk}y0ihJ(lmspoRfGDS7r{~P0R%9Q{B literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/description/tile_tile_2_tree_view.png b/web_dashboard_tile/static/description/tile_tile_2_tree_view.png new file mode 100644 index 0000000000000000000000000000000000000000..2737a8cc28ba442e7d102e04cc78e5de52aaec4a GIT binary patch literal 135180 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 z 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
Q^9zu)oI#0glD!!at71s&B{2 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�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
)=_o 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 literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/description/tile_tile_kanban.png b/web_dashboard_tile/static/description/tile_tile_kanban.png new file mode 100644 index 0000000000000000000000000000000000000000..200f2a652f14c4f886d8526cc3c92bab28ffe328 GIT binary patch literal 8243 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 literal 0 HcmV?d00001 diff --git a/web_dashboard_tile/static/src/css/tile.css b/web_dashboard_tile/static/src/css/web_dashboard_tile.css similarity index 100% rename from web_dashboard_tile/static/src/css/tile.css rename to web_dashboard_tile/static/src/css/web_dashboard_tile.css diff --git a/web_dashboard_tile/static/src/img/avg.png b/web_dashboard_tile/static/src/img/avg.png deleted file mode 100644 index 2f534e932c820d634b47bd8f97312d9329204001..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m=s)o-U3d9-U7^4+=IJ2*gO--_~HV!2e>uS%PF#Guu4HsE%_hVl#Mu zg>hXFI?(RdBEZ!7@!^j3(K|M5ub#~Kqts%Xor~t#Bk6%6mb%eQ3<7P6>mOUNG3+p7 zP5H5_q0nX1nYCODpU$}cxyUywEl-Dmp+z9h_?Xn(%$mtF*>l-d8W(SEmb{zvh+Sga zX`8v1)W84wW4oYZMbRUZ;9|y8vS;))*N6W*y+(V9RuSW=j(4+d&pl@B+Zz)-mpL$A zQ-5~AWyby!7M~|IFG@&c?|!|z@@C-^;kr%Dx2xJOYaCcO+j_}shX+q(GyEd1pPzZs jcP+E$o4=p6KQb(z=J|E&+*QoL5Mc0h^>bP0l+XkKyXJ@& diff --git a/web_dashboard_tile/static/src/img/max.png b/web_dashboard_tile/static/src/img/max.png deleted file mode 100644 index ff33ee437159ee65f4aaab262dffff800bf5a3df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m=sgo-U3d9-YYv60aI2MzL)@Y5d1se09}{11Fqxxg~%=>)rq6&DJ6_ zL2QW`D>4u6Ub}>5aS7mj+4!+_N2QL``(Pu9bejH=Gnb^no z;V5GykZOySIZ!#}7^Co-9d1ma{42wsKW1Slo^Q_AzJ0=HpsN`?UHx3vIVCg!0IU#M AU;qFB diff --git a/web_dashboard_tile/static/src/img/median.png b/web_dashboard_tile/static/src/img/median.png deleted file mode 100644 index 61d5dd7c264544941b4de07c7c19da7391b485b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m=t3o-U3d9-YYv60aI2MzL+(vgMDv`0AA_6H^vWW90#Yt5>fUlx1gY zGlPJzsqO)`j6BAhjxD-pR%S6WGk-I1XIIwXyY)me;BZYDFEewHKwu6~oZ0#4-}-{G zcBR63>Y5$*bYqVeTs=7H;RL&nw>C7&v9&-crN|A!;5+s)%rtX1_le3eJ-29 zs`9Jhi-OWc_AlMcNvFlS9yQF^lqzwAv6JClyi?%;7Vl*q58|`9;|^zMWvvK%{+NY9 Y4nJ z@ErkR#;MwT(m=tzo-U3d9-UXG8uBqI3b@|S+0*X6VcTb;dj~g6IpCXP(^kIW8{0Rt zZrQ@fNv<1rJu=XNd^C^60O! zL;j>i8&aRu1Tih)nV5w&0^IwjKl-Pe_ss_f z5$PWY?~5mbQRw@3L|Z8h2Pi1i-hZsniS($1?+5W6#nl~EY)l+o4D5}eOs#Ez#*7Yz z_QuB64rVrv=dd6_C@3;0X))m+t{EqpE}lQc7ksl@Ibva?4~X+aasg6GozXB!xE^l| zp*mft&U*BmC+!h`$!LDzib2!*Ph0v6?2otO`Tn5^&;3XH9@PyUo0<6CKzYX3SXfglv_>REl`P1j%`g&^lCB2Ycup3pqh8wDV$HRgxW=^V@+B(;o3tyM=!*X{K;zs` zJNsjgQFV3f(Zsg=L$tI8Gp{c_jb$3mk&)Jty>i0;9*Xd0qsz{qit8-1&$j^^? zE*z^v9GNT5?><&rhVW9ZN+-8`w^=3=JXITqS*ptUUF~XEF6QfsGlO9kp}a>j1it4x zLVl!CY9yT6sH_4=Qkkz zy(h^CnW*25+B9~rZv1pjFmcMob9nxa>*DG_mx6c^%i%z=A&B{`Ii1-#kO#cOpXF)9 z62$=L&akcie0WZFr5;`|F{>a+RU&ZZ93ntxFf>Gqg^NoZD}tR+efnI4cf06nQobHl zD~{VzUoLam4@$Y4&WwcU)4D0$6&c{|VsmtIU&LABNw~$fq}zbg`l(_z>3f)0OnO2^ zc@jr<{tQ*1VgqAEB*2gxp+a2z+wY4tMg+|3e9;<9CJB#k#J5V2ASpybkY~zDc4jwe z>a&!^N>l~oiIv_RA!b%fGS}Pa_BZX8ELyKo>Im-o;3`=WpJOPH|H% zc6B zC(JnZ65Vtpp6oB&$C*E*_RvT#AhT{pXY@U((-}Pq9kC;D1y>H(gl*wCeBRqLXhj## zN5ngP%H~VAuH)^lEIKnp3FQ&qqjwdiA$a{pG(veVItW3j5sM#YN!^*zbY?M%5Ncdd znFR&?Q24$s?E@7UJxDA;Zj~iMgwEWw*yy=7(Qy|Jk?|~?Jlp|+^_6xrKBflF_`|GO z8l&2Y3a9h!+{eQszwWO8c{dH^b07BaMUxVL;f8aKeX=~yLJ@T1As*j8saujwZw<@c zX&~}hipubr^;<((iD_pFL2FGT2XaRKHs%M};yZ+Eu|AX>A1KMN$YIXhC?{aMYdgy< z4dr|I_g~iH>Oa%=wqe#}J34W7h_NPpkAJY1P4L12s5W^8CMWlghp+9UjgwKfa2ygy zYOC!S$`O)$@!72`yZI(EF~VJ|f>AgSFtFV>b)e29n8#Wb@_5~_S^X%YJ#iJ|cHWrD zt)fzO`WR%V;60wp$iz!J6G5c~+I$9LPYYKGu%0DMn*tH(e^)e`0Rq(8gmC5 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 diff --git a/web_dashboard_tile/static/src/img/screenshot_dashboard.png b/web_dashboard_tile/static/src/img/screenshot_dashboard.png deleted file mode 100644 index 65cfc12753e9f451d432ff0cb54c85d3ff459a1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20441 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 GGywqSdE~|b diff --git a/web_dashboard_tile/static/src/img/sum.png b/web_dashboard_tile/static/src/img/sum.png deleted file mode 100644 index 90908e8bb3abda50e07a972588ae5730535c8922..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m=t>o-U3d9-UXGZsa{=AmBP*`5S{+gOzL!t0aR23)c;%v<4|7h8_Wp z2|_hDZk*fsaMg*Re?Rvx*ZA;0xrlXbo6Xb6&}6oqVhlR#e1Gqe6lV~z6t^j3*V{bl z@|NziyB^HV2!7vt;;2l+F}pC!0>kONAssPiQknNM7e2nnmo#&=%n^fd%Z|i#i3n$<-Cv4-^i-E0O&miPgg&ebxsLQ06?H_C;$Ke diff --git a/web_dashboard_tile/static/src/js/custom_js.js b/web_dashboard_tile/static/src/js/custom_js.js deleted file mode 100644 index 66094df85..000000000 --- a/web_dashboard_tile/static/src/js/custom_js.js +++ /dev/null @@ -1,141 +0,0 @@ -// @@@ web_dashboard_tile custom JS @@@ -//############################################################################# -// -// Copyright (C) 2010-2013 OpenERP s.a. () -// Copyright (C) 2014 initOS GmbH & Co. KG () -// Copyright (C) 2018 Iván Todorovich () -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//############################################################################# - -odoo.define('web_dashboard_tile', function (require) { -"use strict"; - -var core = require('web.core'); -var data = require('web.data'); -var FavoriteMenu = require('web.FavoriteMenu'); -var ActionManager = require('web.ActionManager'); -var ViewManager = require('web.ViewManager'); -var Model = require('web.DataModel'); -var session = require('web.session'); -var pyeval = require('web.pyeval'); -var _t = core._t; -var QWeb = core.qweb; - - -FavoriteMenu.include({ - - prepare_dropdown_menu: function (filters) { - var self = this; - this._super(filters); - var am = this.findAncestor(function (a) { - return a instanceof ActionManager; - }); - if (am && am.get_inner_widget() instanceof ViewManager) { - this.view_manager = am.get_inner_widget(); - this.add_to_dashboard_tile_available = true; - this.$('.o_favorites_menu').append(QWeb.render('SearchView.addtodashboardtile')); - this.$add_to_dashboard_tile = this.$('.o_add_to_dashboard_tile'); - this.$add_dashboard_tile_btn = this.$add_to_dashboard_tile.eq(1).find('button'); - this.$add_dashboard_tile_input = this.$add_to_dashboard_tile.eq(0).find('input'); - this.$add_dashboard_tile_link = this.$('.o_add_to_dashboard_tile_link'); - var title = this.searchview.get_title(); - this.$add_dashboard_tile_input.val(title); - this.$add_dashboard_tile_link.click(function (e) { - e.preventDefault(); - self.toggle_dashboard_tile_menu(); - }); - this.$add_dashboard_tile_btn.click(this.proxy('add_dashboard_tile')); - } - }, - - toggle_dashboard_tile_menu: function (is_open) { - this.$add_dashboard_tile_link - .toggleClass('o_closed_menu', !(_.isUndefined(is_open)) ? !is_open : undefined) - .toggleClass('o_open_menu', is_open); - this.$add_to_dashboard_tile.toggle(is_open); - if (this.$add_dashboard_tile_link.hasClass('o_open_menu')) { - this.$add_dashboard_tile_input.focus(); - } - }, - - close_menus: function () { - if (this.add_to_dashboard_tile_available) { - this.toggle_dashboard_tile_menu(false); - } - this._super(); - }, - - add_dashboard_tile: function () { - var self = this; - - var search_data = this.searchview.build_search_data(), - context = new data.CompoundContext(this.searchview.dataset.get_context() || []), - domain = new data.CompoundDomain(this.searchview.dataset.get_domain() || []); - _.each(search_data.contexts, context.add, context); - _.each(search_data.domains, domain.add, domain); - - context.add({ - group_by: pyeval.eval('groupbys', search_data.groupbys || []) - }); - - context.add(this.view_manager.active_view.controller.get_context()); - - var c = pyeval.eval('context', context); - for(var k in c) { - if (c.hasOwnProperty(k) && /^search_default_/.test(k)) { - delete c[k]; - } - } - - this.toggle_dashboard_tile_menu(false); - - c.dashboard_merge_domains_contexts = false; - var d = pyeval.eval('domain', domain), - tile = new Model('tile.tile'), - name = self.$add_dashboard_tile_input.val(); - - var private_filter = !this.$('#oe_searchview_custom_public').prop('checked'); - if (_.isEmpty(name)){ - this.do_warn(_t("Error"), _t("Filter name is required.")); - return false; - } - - // Don't save user_context keys in the custom filter, otherwise end - // up with e.g. wrong uid or lang stored *and used in subsequent - // reqs* - var ctx = context; - _(_.keys(session.user_context)).each(function (key) { - delete ctx[key]; - }); - - var vals = { - name: name, - user_id: private_filter ? session.uid : false, - model_id: self.view_manager.active_view.controller.model, - //context: context, - domain: d, - action_id: self.action_id || false, - }; - - // FIXME: current context? - return tile.call('add', [vals]).done(function (id) { - self.do_notify(_t("Success"), _t("Tile is created")); - }); - }, -}); - -}); - diff --git a/web_dashboard_tile/static/src/js/web_dashboard_tile.js b/web_dashboard_tile/static/src/js/web_dashboard_tile.js new file mode 100644 index 000000000..1458eb009 --- /dev/null +++ b/web_dashboard_tile/static/src/js/web_dashboard_tile.js @@ -0,0 +1,112 @@ +/* +Copyright (C) 2010-2013 OpenERP s.a. () +Copyright (C) 2014 initOS GmbH & Co. KG () +Copyright (C) 2018 Iván Todorovich () +Copyright (C) 2019-Today GRAP (http://www.grap.coop) +@author: Sylvain LE GAL (https://twitter.com/legalsylvain) +License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +*/ + + +odoo.define('web_dashboard_tile', function (require) { + 'use strict'; + var core = require('web.core'); + var FavoriteMenu = require('web.FavoriteMenu'); + var Domain = require('web.Domain'); + var qweb = core.qweb; + var _t = core._t; + + FavoriteMenu.include({ + + start: function () { + var self = this; + if (this.action_id === undefined) { + return this._super(); + } + if (this.action.type === 'ir.actions.act_window') { + this.add_to_dashboard_available = true; + this.$('.o_favorites_menu').append(qweb.render('SearchView.addtodashboardtile')); + this.$add_to_dashboard_tile = this.$('.o_add_to_dashboard_tile'); + this.$add_to_dashboard_tile_name = this.$('.o_add_to_dashboard_tile_name')[0]; + + // Add event on button and link clicks + this.$add_to_dashboard_tile_link = this.$('.o_add_to_dashboard_tile_link'); + this.$add_to_dashboard_tile_link.click(function (e) { + e.preventDefault(); + self._toggleDashboardTileMenu(); + }); + this.$add_to_dashboard_tile_button = this.$('.o_add_to_dashboard_tile_button'); + this.$add_to_dashboard_tile_button.click(this.proxy('_addDashboardTile')); + + // Add categories to the select list + this.$add_to_dashboard_tile_category = this.$('.o_add_to_dashboard_tile_category')[0]; + this._rpc({ + model: 'tile.category', + method: 'search_read', + args: [[], ['id', 'name']], + }).then(function (res) { + res.forEach(function(item){ + var newOption = document.createElement("option"); + newOption.text = item.name; + newOption.value = item.id; + self.$add_to_dashboard_tile_category.appendChild(newOption); + }); + }); + } + return this._super(); + }, + + _toggleDashboardTileMenu: function (isOpen) { + this.$add_to_dashboard_tile_link + .toggleClass('o_closed_menu', !(_.isUndefined(isOpen)) ? !isOpen : undefined) + .toggleClass('o_open_menu', isOpen); + this.$add_to_dashboard_tile.toggle(isOpen); + if (this.$add_to_dashboard_tile_link.hasClass('o_open_menu')) { + this.$add_to_dashboard_tile_name.focus(); + } + }, + + _addDashboardTile: function () { + var self = this; + var tile_name = this.$add_to_dashboard_tile_name.value; + var tile_category_id = this.$add_to_dashboard_tile_category.value; + + if (!tile_name.length){ + this.do_warn(_t("Error"), _t("Name Field is required.")); + this.$add_to_dashboard_tile_name.focus(); + return; + } + + var search_data = this.searchview.build_search_data(); + var domain = this.action.domain ? this.action.domain.slice(0) : []; + + _.each(search_data.domains, function (d) { + domain.push.apply(domain, Domain.prototype.stringToArray(d)); + }); + + return this._rpc({ + route: '/web_dashboard_tile/create_tile', + params: { + model_name: self.action.res_model, + name: tile_name, + category_id: tile_category_id, + domain: domain, + action_id: this.action_id, + }, + }).then(function (res) { + if (res) { + self.do_notify( + _.str.sprintf(_t("'%s' added to the overview dashboard"), tile_name), + _t('Please refresh your browser for the changes to take effect.') + ); + self._toggleDashboardTileMenu(false); + } else { + self.do_warn(_t("Could not add new element to the overview dashboard")); + } + }); + + }, + + }); + +}); diff --git a/web_dashboard_tile/static/src/xml/custom_xml.xml b/web_dashboard_tile/static/src/xml/custom_xml.xml deleted file mode 100644 index ba60a2447..000000000 --- a/web_dashboard_tile/static/src/xml/custom_xml.xml +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml b/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml new file mode 100644 index 000000000..aefcccc45 --- /dev/null +++ b/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml @@ -0,0 +1,19 @@ + diff --git a/web_dashboard_tile/tests/__init__.py b/web_dashboard_tile/tests/__init__.py index 4f8c7e8bf..474a84ea1 100644 --- a/web_dashboard_tile/tests/__init__.py +++ b/web_dashboard_tile/tests/__init__.py @@ -1,6 +1 @@ -# -*- coding: utf-8 -*- -# © 2016 Antonio Espinosa - -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -# flake8: noqa - from . import test_tile diff --git a/web_dashboard_tile/tests/test_tile.py b/web_dashboard_tile/tests/test_tile.py index ec6b309b1..84602b35a 100644 --- a/web_dashboard_tile/tests/test_tile.py +++ b/web_dashboard_tile/tests/test_tile.py @@ -1,31 +1,33 @@ -# -*- coding: utf-8 -*- # © 2016 Antonio Espinosa - # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.tests.common import TransactionCase +from odoo.tests.common import TransactionCase class TestTile(TransactionCase): def test_tile(self): - tile_obj = self.env["tile.tile"] + TileTile = self.env["tile.tile"] model_id = self.env["ir.model"].search([("model", "=", "tile.tile")]) + category_id = self.env.ref("web_dashboard_tile.category_module").id field_id = self.env["ir.model.fields"].search( [("model_id", "=", model_id.id), ("name", "=", "sequence")] ) - self.tile1 = tile_obj.create( + self.tile1 = TileTile.create( { "name": "Count / Sum", "sequence": 1, + "category_id": category_id, "model_id": model_id.id, "domain": "[('model_id', '=', %d)]" % model_id.id, "secondary_function": "sum", "secondary_field_id": field_id.id, } ) - self.tile2 = tile_obj.create( + self.tile2 = TileTile.create( { "name": "Min / Max", "sequence": 2, + "category_id": category_id, "model_id": model_id.id, "domain": "[('model_id', '=', %d)]" % model_id.id, "primary_function": "min", @@ -34,10 +36,11 @@ class TestTile(TransactionCase): "secondary_field_id": field_id.id, } ) - self.tile3 = tile_obj.create( + self.tile3 = TileTile.create( { "name": "Avg / Median", "sequence": 3, + "category_id": category_id, "model_id": model_id.id, "domain": "[('model_id', '=', %d)]" % model_id.id, "primary_function": "avg", @@ -47,14 +50,14 @@ class TestTile(TransactionCase): } ) # count - self.assertEqual(self.tile1.primary_value, "3") + self.assertEqual(self.tile1.primary_value, 3.0) # sum - self.assertEqual(self.tile1.secondary_value, "6") + self.assertEqual(self.tile1.secondary_value, 6.0) # min - self.assertEqual(self.tile2.primary_value, "1") + self.assertEqual(self.tile2.primary_value, 1.0) # max - self.assertEqual(self.tile2.secondary_value, "3") + self.assertEqual(self.tile2.secondary_value, 3.0) # average - self.assertEqual(self.tile3.primary_value, "2") + self.assertEqual(self.tile3.primary_value, 2.0) # median - self.assertEqual(self.tile3.secondary_value, "2.0") + self.assertEqual(self.tile3.secondary_value, 2.0) diff --git a/web_dashboard_tile/views/menu.xml b/web_dashboard_tile/views/menu.xml new file mode 100644 index 000000000..a2dd84a61 --- /dev/null +++ b/web_dashboard_tile/views/menu.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml index e7a68b213..4dc0dfe57 100644 --- a/web_dashboard_tile/views/templates.xml +++ b/web_dashboard_tile/views/templates.xml @@ -1,33 +1,14 @@ - - - - - - - + diff --git a/web_dashboard_tile/views/tile.xml b/web_dashboard_tile/views/tile.xml deleted file mode 100644 index 4a629eb17..000000000 --- a/web_dashboard_tile/views/tile.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - tile.tile - - - - - - - - - - - - - - - - - - tile.tile - -
- -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - - - tile.tile - - - - - - - - - - - - - - - - - -
- - - - - - - - tile.category - -
- - - - - -
- - -
-
- - - tile.category - - - - - - - - - - - Dashboard - tile.tile - form - tree,kanban,form - - - - - - - Dashboard - tile.tile - form - kanban,form - ['|',('user_id','=',False),('user_id','=',uid)] - - - - - Dashboard - - - - - - - diff --git a/web_dashboard_tile/views/tile_category.xml b/web_dashboard_tile/views/tile_category.xml new file mode 100644 index 000000000..b8c8eab58 --- /dev/null +++ b/web_dashboard_tile/views/tile_category.xml @@ -0,0 +1,63 @@ + + + + + Dashboard Items + tile.tile + form + tree,form + {'search_default_category_id': active_id} + + + + tile.category + +
+ +
+ + +
+
+
+ + + + +
+
+
+
+ + + tile.category + + + + + + + + + + + + Dashboard Categories + tile.category + form + tree,kanban,form + {'active_test': False} + + + + +
diff --git a/web_dashboard_tile/views/tile_tile.xml b/web_dashboard_tile/views/tile_tile.xml new file mode 100644 index 000000000..f8a85745d --- /dev/null +++ b/web_dashboard_tile/views/tile_tile.xml @@ -0,0 +1,158 @@ + + + + + tile.tile + + + + + + + + + tile.tile + + + + + + + + + + + + + + + + + + + tile.tile + +
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + tile.tile + + + + + + + + + + + + + + + + + + + + + + + + + Dashboard Items + tile.tile + form + tree,form,kanban + + + + +
From 1ba8b5fc03e4bed2d0d057b7526dd3983531893b Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Sun, 15 Aug 2021 21:49:43 +0200 Subject: [PATCH 46/57] Update web_dashboard_tile/models/tile_category.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Iván Todorovich --- web_dashboard_tile/__manifest__.py | 6 +----- web_dashboard_tile/models/tile_category.py | 10 +++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/web_dashboard_tile/__manifest__.py b/web_dashboard_tile/__manifest__.py index 8b990f891..b4b82d2ee 100644 --- a/web_dashboard_tile/__manifest__.py +++ b/web_dashboard_tile/__manifest__.py @@ -8,15 +8,11 @@ "depends": ["web", "board", "mail", "web_widget_color"], "author": "initOS GmbH & Co. KG, " "GRAP, " + "Iván Todorovich , " "Odoo Community Association (OCA)", "maintainers": ["legalsylvain"], "category": "web", "license": "AGPL-3", - "contributors": [ - "initOS GmbH & Co. KG", - "GRAP", - "Iván Todorovich ", - ], "data": [ "security/ir.model.access.csv", "security/ir_rule.xml", diff --git a/web_dashboard_tile/models/tile_category.py b/web_dashboard_tile/models/tile_category.py index d412fa939..f43c96369 100644 --- a/web_dashboard_tile/models/tile_category.py +++ b/web_dashboard_tile/models/tile_category.py @@ -45,11 +45,11 @@ class TileCategory(models.Model): 'res_model': 'tile.tile', 'type': 'ir.actions.act_window', 'view_mode': 'kanban', - 'domain': "[" - "('hidden', '=', False)," - "'|', ('user_id', '=', False), ('user_id', '=', uid)," - "('category_id', '=', %d)" - "]" % self.id, + 'domain': """[ + ('hidden', '=', False), + '|', ('user_id', '=', False), ('user_id', '=', uid), + ('category_id', '=', {self.id}) + ]""".format(self=self), } def _prepare_menu(self): From b68d5ca3dd9ca0f832f4c95c206962569251876d Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Thu, 21 Oct 2021 19:52:34 +0200 Subject: [PATCH 47/57] [IMP] use correct tree_view_id if defined in the action_id ; [IMP] and name and category_id in the tile search view --- web_dashboard_tile/models/tile_tile.py | 34 ++++++++++++++------------ web_dashboard_tile/views/tile_tile.xml | 2 ++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/web_dashboard_tile/models/tile_tile.py b/web_dashboard_tile/models/tile_tile.py index 599464e54..3eb408c58 100644 --- a/web_dashboard_tile/models/tile_tile.py +++ b/web_dashboard_tile/models/tile_tile.py @@ -334,23 +334,25 @@ class TileTile(models.Model): # Action methods @api.multi def open_link(self): - res = { - "name": self.name, - "view_type": "form", - "view_mode": "tree", - "view_id": [False], - "res_model": self.model_id.model, - "type": "ir.actions.act_window", - "context": dict(self.env.context, group_by=False), - "nodestroy": True, - "target": "current", - "domain": self.domain, - } if self.action_id: - res.update( - self.action_id.read(["view_type", "view_mode", "type"])[0] - ) - return res + action = self.action_id.read()[0] + else: + action = { + "view_type": "form", + "view_mode": "tree", + "view_id": False, + "res_model": self.model_id.model, + "type": "ir.actions.act_window", + "target": "current", + "domain": self.domain, + } + action.update({ + "name": self.name, + "display_name": self.name, + "context": dict(self.env.context, group_by=False), + "domain": self.domain, + }) + return action @api.model def add(self, vals): diff --git a/web_dashboard_tile/views/tile_tile.xml b/web_dashboard_tile/views/tile_tile.xml index f8a85745d..2d2ecb247 100644 --- a/web_dashboard_tile/views/tile_tile.xml +++ b/web_dashboard_tile/views/tile_tile.xml @@ -5,7 +5,9 @@ tile.tile + + From 5faa0bb858367667e5f9f5f3f69d6501c14393eb Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Tue, 2 Nov 2021 15:33:18 +0100 Subject: [PATCH 48/57] [REF] remove half developed functionality that allowed to create on the fly tiles, but that was limited regarding configuration --- web_dashboard_tile/__manifest__.py | 1 - .../static/src/css/web_dashboard_tile.css | 6 - .../static/src/js/web_dashboard_tile.js | 112 ------------------ .../static/src/xml/web_dashboard_tile.xml | 19 --- web_dashboard_tile/views/templates.xml | 14 --- 5 files changed, 152 deletions(-) delete mode 100644 web_dashboard_tile/static/src/js/web_dashboard_tile.js delete mode 100644 web_dashboard_tile/static/src/xml/web_dashboard_tile.xml delete mode 100644 web_dashboard_tile/views/templates.xml diff --git a/web_dashboard_tile/__manifest__.py b/web_dashboard_tile/__manifest__.py index b4b82d2ee..cbada6744 100644 --- a/web_dashboard_tile/__manifest__.py +++ b/web_dashboard_tile/__manifest__.py @@ -19,7 +19,6 @@ "views/menu.xml", "views/tile_tile.xml", "views/tile_category.xml", - "views/templates.xml", ], "demo": [ "demo/tile_category.xml", diff --git a/web_dashboard_tile/static/src/css/web_dashboard_tile.css b/web_dashboard_tile/static/src/css/web_dashboard_tile.css index 9fe5aec72..e9a3d962a 100644 --- a/web_dashboard_tile/static/src/css/web_dashboard_tile.css +++ b/web_dashboard_tile/static/src/css/web_dashboard_tile.css @@ -51,12 +51,6 @@ display: block; } -/* Favorites menu in control panel */ -.o_add_to_dashboard_tile { - /* hidden by default */ - display: none; -} - /* Make dropdown menu button not affect text flow */ .o_kanban_view .oe_dashboard_tile .o_dropdown_kanban { float: none; diff --git a/web_dashboard_tile/static/src/js/web_dashboard_tile.js b/web_dashboard_tile/static/src/js/web_dashboard_tile.js deleted file mode 100644 index 1458eb009..000000000 --- a/web_dashboard_tile/static/src/js/web_dashboard_tile.js +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright (C) 2010-2013 OpenERP s.a. () -Copyright (C) 2014 initOS GmbH & Co. KG () -Copyright (C) 2018 Iván Todorovich () -Copyright (C) 2019-Today GRAP (http://www.grap.coop) -@author: Sylvain LE GAL (https://twitter.com/legalsylvain) -License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -*/ - - -odoo.define('web_dashboard_tile', function (require) { - 'use strict'; - var core = require('web.core'); - var FavoriteMenu = require('web.FavoriteMenu'); - var Domain = require('web.Domain'); - var qweb = core.qweb; - var _t = core._t; - - FavoriteMenu.include({ - - start: function () { - var self = this; - if (this.action_id === undefined) { - return this._super(); - } - if (this.action.type === 'ir.actions.act_window') { - this.add_to_dashboard_available = true; - this.$('.o_favorites_menu').append(qweb.render('SearchView.addtodashboardtile')); - this.$add_to_dashboard_tile = this.$('.o_add_to_dashboard_tile'); - this.$add_to_dashboard_tile_name = this.$('.o_add_to_dashboard_tile_name')[0]; - - // Add event on button and link clicks - this.$add_to_dashboard_tile_link = this.$('.o_add_to_dashboard_tile_link'); - this.$add_to_dashboard_tile_link.click(function (e) { - e.preventDefault(); - self._toggleDashboardTileMenu(); - }); - this.$add_to_dashboard_tile_button = this.$('.o_add_to_dashboard_tile_button'); - this.$add_to_dashboard_tile_button.click(this.proxy('_addDashboardTile')); - - // Add categories to the select list - this.$add_to_dashboard_tile_category = this.$('.o_add_to_dashboard_tile_category')[0]; - this._rpc({ - model: 'tile.category', - method: 'search_read', - args: [[], ['id', 'name']], - }).then(function (res) { - res.forEach(function(item){ - var newOption = document.createElement("option"); - newOption.text = item.name; - newOption.value = item.id; - self.$add_to_dashboard_tile_category.appendChild(newOption); - }); - }); - } - return this._super(); - }, - - _toggleDashboardTileMenu: function (isOpen) { - this.$add_to_dashboard_tile_link - .toggleClass('o_closed_menu', !(_.isUndefined(isOpen)) ? !isOpen : undefined) - .toggleClass('o_open_menu', isOpen); - this.$add_to_dashboard_tile.toggle(isOpen); - if (this.$add_to_dashboard_tile_link.hasClass('o_open_menu')) { - this.$add_to_dashboard_tile_name.focus(); - } - }, - - _addDashboardTile: function () { - var self = this; - var tile_name = this.$add_to_dashboard_tile_name.value; - var tile_category_id = this.$add_to_dashboard_tile_category.value; - - if (!tile_name.length){ - this.do_warn(_t("Error"), _t("Name Field is required.")); - this.$add_to_dashboard_tile_name.focus(); - return; - } - - var search_data = this.searchview.build_search_data(); - var domain = this.action.domain ? this.action.domain.slice(0) : []; - - _.each(search_data.domains, function (d) { - domain.push.apply(domain, Domain.prototype.stringToArray(d)); - }); - - return this._rpc({ - route: '/web_dashboard_tile/create_tile', - params: { - model_name: self.action.res_model, - name: tile_name, - category_id: tile_category_id, - domain: domain, - action_id: this.action_id, - }, - }).then(function (res) { - if (res) { - self.do_notify( - _.str.sprintf(_t("'%s' added to the overview dashboard"), tile_name), - _t('Please refresh your browser for the changes to take effect.') - ); - self._toggleDashboardTileMenu(false); - } else { - self.do_warn(_t("Could not add new element to the overview dashboard")); - } - }); - - }, - - }); - -}); diff --git a/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml b/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml deleted file mode 100644 index aefcccc45..000000000 --- a/web_dashboard_tile/static/src/xml/web_dashboard_tile.xml +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/web_dashboard_tile/views/templates.xml b/web_dashboard_tile/views/templates.xml deleted file mode 100644 index 4dc0dfe57..000000000 --- a/web_dashboard_tile/views/templates.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - -